From 99c8814533d7253f15e70f58943a2ae5f18c5063 Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Wed, 19 Feb 2020 21:38:21 +0000 Subject: [PATCH] component templates --- packages/builder/src/builderStore/store.js | 20 +++ .../builder/src/common/ConfirmDialog.svelte | 4 +- .../ComponentSelectionList.svelte | 149 +++++++++++++----- .../utilities/builder/componentLibraryInfo.js | 20 ++- packages/server/utilities/builder/index.js | 11 +- packages/standard-components/components.json | 6 + .../src/Templates/saveRecordButton.js | 23 +++ packages/standard-components/src/index.js | 1 + 8 files changed, 188 insertions(+), 46 deletions(-) create mode 100644 packages/standard-components/src/Templates/saveRecordButton.js diff --git a/packages/builder/src/builderStore/store.js b/packages/builder/src/builderStore/store.js index 9245e2c9b5..3cb400c4de 100644 --- a/packages/builder/src/builderStore/store.js +++ b/packages/builder/src/builderStore/store.js @@ -111,6 +111,7 @@ export const getStore = () => { store.moveUpComponent = moveUpComponent(store) store.moveDownComponent = moveDownComponent(store) store.copyComponent = copyComponent(store) + store.addTemplatedComponent = addTemplatedComponent(store) return store } @@ -161,6 +162,7 @@ const initialise = (store, initial) => async () => { initial.components = values(pkg.components.components).map( expandComponentDefinition ) + initial.templates = pkg.components.templates initial.builtins = [getBuiltin("##builtin/screenslot")] initial.actions = values(pkg.appDefinition.actions) initial.triggers = pkg.appDefinition.triggers @@ -735,6 +737,24 @@ const addChildComponent = store => (componentToAdd, presetName) => { }) } +/** + * @param {string} props - props to add, as child of current component + */ +const addTemplatedComponent = store => props => { + store.update(state => { + walkProps(props, p => { + p._id = uuid() + }) + state.currentComponentInfo._children = state.currentComponentInfo._children.concat( + props + ) + + _savePage(state) + + return state + }) +} + const selectComponent = store => component => { store.update(s => { const componentDef = component._component.startsWith("##") diff --git a/packages/builder/src/common/ConfirmDialog.svelte b/packages/builder/src/common/ConfirmDialog.svelte index 592b73a395..b54f971d7c 100644 --- a/packages/builder/src/common/ConfirmDialog.svelte +++ b/packages/builder/src/common/ConfirmDialog.svelte @@ -39,7 +39,9 @@ const ok = () => {

{title}

-
{body}
+
+ {body} +
- {/each} + selectedComponent = null} + onOk={onTemplateInstanceChosen}> + {#each templateInstances.map(i => i.name) as instance} +
+ +
+ {/each} +
+ diff --git a/packages/server/utilities/builder/componentLibraryInfo.js b/packages/server/utilities/builder/componentLibraryInfo.js index c180655ac4..c18ec30c17 100644 --- a/packages/server/utilities/builder/componentLibraryInfo.js +++ b/packages/server/utilities/builder/componentLibraryInfo.js @@ -31,7 +31,7 @@ module.exports.componentLibraryInfo = async (appPath, libname) => { const libDir = getLibDir(appPath, libname) const componentsPath = getComponentsFilepath(libDir) - const componentDefinitionExists = await exists(componentsPath); + const componentDefinitionExists = await exists(componentsPath) if (!componentDefinitionExists) { const e = new Error( @@ -41,18 +41,32 @@ module.exports.componentLibraryInfo = async (appPath, libname) => { throw e } + const addNamespace = name => `${libname}/${name}` + try { const componentDefinitions = await readJSON(componentsPath) const namespacedComponents = { _lib: componentDefinitions._lib } for (let componentKey in componentDefinitions) { - if (componentKey === "_lib") continue - const namespacedName = `${libname}/${componentKey}` + if (componentKey === "_lib" || componentKey === "_templates") continue + const namespacedName = addNamespace(componentKey) componentDefinitions[componentKey].name = namespacedName namespacedComponents[namespacedName] = componentDefinitions[componentKey] } + const namespacedTemplates = { _lib: componentDefinitions._lib } + for (let templateKey in componentDefinitions._templates || {}) { + const template = componentDefinitions._templates[templateKey] + if (template.component) + template.component = addNamespace(template.component) + const namespacedName = addNamespace(templateKey) + template.name = namespacedName + namespacedTemplates[namespacedName] = + componentDefinitions._templates[templateKey] + } + return { components: namespacedComponents, + templates: namespacedTemplates, libDir, componentsPath, } diff --git a/packages/server/utilities/builder/index.js b/packages/server/utilities/builder/index.js index 0421002808..b6c40a4bc8 100644 --- a/packages/server/utilities/builder/index.js +++ b/packages/server/utilities/builder/index.js @@ -130,21 +130,28 @@ const getComponentDefinitions = async (appPath, pages, componentLibrary) => { if (!pages) return [] - componentLibraries = $(pages, [values, map(p => p.componentLibraries), flatten]) + componentLibraries = $(pages, [ + values, + map(p => p.componentLibraries), + flatten, + ]) } else { componentLibraries = [componentLibrary] } const components = {} + const templates = {} for (let library of componentLibraries) { const info = await componentLibraryInfo(appPath, library) merge(components, info.components) + merge(templates, info.templates) } if (components._lib) delete components._lib + if (templates._lib) delete templates._lib - return { components } + return { components, templates } } module.exports.getComponentDefinitions = getComponentDefinitions diff --git a/packages/standard-components/components.json b/packages/standard-components/components.json index a94b5a25c6..537a11103d 100644 --- a/packages/standard-components/components.json +++ b/packages/standard-components/components.json @@ -1,5 +1,11 @@ { "_lib": "./dist/index.js", + "_templates" : { + "saveRecordButton" : { + "description": "Save record button", + "component": "button" + } + }, "button" : { "name": "Button", "description": "an html