From c87ddade508ac056e611b7b07997afc8d95f171e Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Mon, 1 Jun 2020 10:18:45 +0100 Subject: [PATCH 1/5] component nav dropdown menu --- .../builder/src/builderStore/store/index.js | 78 ++++++++++-- .../src/components/common/Icons/More.svelte | 8 ++ .../src/components/common/Icons/index.js | 1 + .../ComponentDropdownMenu.svelte | 116 ++++++++++++++++++ .../ComponentsHierarchyChildren.svelte | 54 +------- .../[application]/frontend/_layout.svelte | 1 + 6 files changed, 197 insertions(+), 61 deletions(-) create mode 100644 packages/builder/src/components/common/Icons/More.svelte create mode 100644 packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte diff --git a/packages/builder/src/builderStore/store/index.js b/packages/builder/src/builderStore/store/index.js index f4d47064be..6755bc0a7c 100644 --- a/packages/builder/src/builderStore/store/index.js +++ b/packages/builder/src/builderStore/store/index.js @@ -64,11 +64,16 @@ export const getStore = () => { store.getPathToComponent = getPathToComponent(store) store.addTemplatedComponent = addTemplatedComponent(store) store.setMetadataProp = setMetadataProp(store) + store.storeComponentForCopy = storeComponentForCopy(store) + store.pasteComponent = pasteComponent(store) return store } export default getStore +export const getComponentDefinition = (state, name) => + name.startsWith("##") ? getBuiltin(name) : state.components[name] + const setPackage = (store, initial) => async pkg => { const [main_screens, unauth_screens] = await Promise.all([ api @@ -317,8 +322,6 @@ const setCurrentPage = store => pageName => { }) } -// const getComponentDefinition = (components, name) => components.find(c => c.name === name) - /** * @param {string} componentToAdd - name of the component to add to the application * @param {string} presetName - name of the component preset if defined @@ -344,9 +347,7 @@ const addChildComponent = store => (componentToAdd, presetName) => { return state } - const component = componentToAdd.startsWith("##") - ? getBuiltin(componentToAdd) - : state.components[componentToAdd] + const component = getComponentDefinition(componentToAdd) const presetProps = presetName ? component.presets[presetName] : {} @@ -398,14 +399,18 @@ const addTemplatedComponent = store => props => { }) } +const _selectComponent = (state, component) => { + const componentDef = component._component.startsWith("##") + ? component + : state.components[component._component] + state.currentComponentInfo = makePropsSafe(componentDef, component) + state.currentView = "component" + return state +} + const selectComponent = store => component => { store.update(state => { - const componentDef = component._component.startsWith("##") - ? component - : state.components[component._component] - state.currentComponentInfo = makePropsSafe(componentDef, component) - state.currentView = "component" - return state + return _selectComponent(state, component) }) } @@ -534,7 +539,6 @@ const copyComponent = store => component => { p._id = uuid() }) parent._children = [...parent._children, copiedComponent] - s.curren _saveCurrentPreviewItem(s) s.currentComponentInfo = copiedComponent return s @@ -572,10 +576,58 @@ const getPathToComponent = store => component => { return path } +const generateNewIdsForComponent = component => + walkProps(component, p => { + p._id = uuid() + }) + +const storeComponentForCopy = store => (component, cut = false) => { + store.update(s => { + const copiedComponent = cloneDeep(component) + s.componentToPaste = copiedComponent + if (cut) { + const parent = getParent(s.currentPreviewItem.props, component._id) + parent._children = parent._children.filter(c => c._id !== component._id) + _selectComponent(s, parent) + } + + return s + }) +} + +const pasteComponent = store => (targetComponent, mode) => { + store.update(s => { + if (!s.componentToPaste) return s + + const componentToPaste = cloneDeep(s.componentToPaste) + generateNewIdsForComponent(componentToPaste) + delete componentToPaste._cutId + + if (mode === "inside") { + targetComponent._children.push(componentToPaste) + return s + } + + const parent = getParent(s.currentPreviewItem.props, targetComponent) + + const targetIndex = parent._children.indexOf(targetComponent) + const index = mode === "above" ? targetIndex : targetIndex + 1 + parent._children.splice(index, 0, cloneDeep(componentToPaste)) + + _saveCurrentPreviewItem(s) + _selectComponent(s, componentToPaste) + + return s + }) +} + const getParent = (rootProps, child) => { let parent walkProps(rootProps, (p, breakWalk) => { - if (p._children && p._children.includes(child)) { + if ( + p._children && + (p._children.includes(child) || p._children.some(c => c._id === child)) + ) { parent = p breakWalk() } diff --git a/packages/builder/src/components/common/Icons/More.svelte b/packages/builder/src/components/common/Icons/More.svelte new file mode 100644 index 0000000000..f072c48976 --- /dev/null +++ b/packages/builder/src/components/common/Icons/More.svelte @@ -0,0 +1,8 @@ + + + + diff --git a/packages/builder/src/components/common/Icons/index.js b/packages/builder/src/components/common/Icons/index.js index 69b78421da..4e4b41082d 100644 --- a/packages/builder/src/components/common/Icons/index.js +++ b/packages/builder/src/components/common/Icons/index.js @@ -31,3 +31,4 @@ export { default as EmailIcon } from "./Email.svelte" export { default as TwitterIcon } from "./Twitter.svelte" export { default as InfoIcon } from "./Info.svelte" export { default as CloseIcon } from "./Close.svelte" +export { default as MoreIcon } from "./More.svelte" diff --git a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte new file mode 100644 index 0000000000..5a485f9680 --- /dev/null +++ b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte @@ -0,0 +1,116 @@ + + +
{}}> + + +
+ + + + store.deleteComponent(component)} /> + + \ No newline at end of file diff --git a/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte b/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte index eafc1834d0..a61d6960f2 100644 --- a/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte +++ b/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte @@ -3,6 +3,7 @@ import { store } from "builderStore" import { last } from "lodash/fp" import { pipe } from "components/common/core" + import ComponentDropdownMenu from "./ComponentDropdownMenu.svelte" import { XCircleIcon, ChevronUpIcon, @@ -51,30 +52,9 @@ class:selected={currentComponent === component} style="padding-left: {level * 20 + 53}px">
{get_capitalised_name(component._component)}
-
- {#if index > 0} - - {/if} - {#if index < components.length - 1} - - {/if} +
+
- -
{#if component._children} @@ -111,7 +91,7 @@ font-size: 13px; } - .item button { + .actions { display: none; height: 20px; width: 28px; @@ -120,37 +100,15 @@ border-style: none; background: rgba(0, 0, 0, 0); cursor: pointer; - } - - .item button.copy { - width: 26px; + position: relative; } .item:hover { background: #fafafa; cursor: pointer; } - .item:hover button { + .item:hover .actions { display: block; } - .item:hover button:hover { - color: var(--button-text); - } - - .reorder-buttons { - display: flex; - flex-direction: column; - height: 100%; - } - - .reorder-buttons > button { - flex: 1 1 auto; - width: 30px; - height: 15px; - } - - .reorder-buttons > button.solo { - padding-top: 2px; - } diff --git a/packages/builder/src/pages/[application]/frontend/_layout.svelte b/packages/builder/src/pages/[application]/frontend/_layout.svelte index 536da887d6..9b38d64f5d 100644 --- a/packages/builder/src/pages/[application]/frontend/_layout.svelte +++ b/packages/builder/src/pages/[application]/frontend/_layout.svelte @@ -103,6 +103,7 @@ overflow: scroll; display: flex; flex-direction: column; + z-index: 5; } .preview-pane { From 4934ed497d707d78a7756f686cdd750b2adbb991 Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Mon, 1 Jun 2020 10:25:12 +0100 Subject: [PATCH 2/5] removing old component actions --- .../ComponentDropdownMenu.svelte | 20 ++----------------- .../userInterface/ComponentsHierarchy.svelte | 6 +----- .../ComponentsHierarchyChildren.svelte | 18 ++--------------- .../userInterface/PageLayout.svelte | 6 +----- 4 files changed, 6 insertions(+), 44 deletions(-) diff --git a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte index 5a485f9680..e2f8943d9e 100644 --- a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte +++ b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte @@ -20,23 +20,6 @@ const showDropdown = () => { dropdown.show() } -/* -{#if index > 0} - - {/if} - {#if index < components.length - 1} - - {/if} -*/ -
{}}> @@ -77,8 +60,9 @@ const showDropdown = () => { border-style: none; border-radius: 2px; padding: 5px; - background: var(--grey); + background: transparent; cursor: pointer; + color: var(--button-text) } .menu { diff --git a/packages/builder/src/components/userInterface/ComponentsHierarchy.svelte b/packages/builder/src/components/userInterface/ComponentsHierarchy.svelte index 26929fcdce..e02874c0dd 100644 --- a/packages/builder/src/components/userInterface/ComponentsHierarchy.svelte +++ b/packages/builder/src/components/userInterface/ComponentsHierarchy.svelte @@ -72,11 +72,7 @@ {#if $store.currentPreviewItem.name === screen.title && screen.component.props._children} + currentComponent={$store.currentComponentInfo} /> {/if} {/each} diff --git a/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte b/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte index a61d6960f2..16aab64576 100644 --- a/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte +++ b/packages/builder/src/components/userInterface/ComponentsHierarchyChildren.svelte @@ -15,23 +15,13 @@ export let currentComponent export let onSelect = () => {} export let level = 0 - export let onDeleteComponent - export let onMoveUpComponent - export let onMoveDownComponent - export let onCopyComponent + const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1) const get_name = s => (!s ? "" : last(s.split("/"))) const get_capitalised_name = name => pipe(name, [get_name, capitalise]) - const moveDownComponent = component => { - const c = component - return () => { - return onMoveDownComponent(c) - } - } - const selectComponent = component => { // Set current component store.selectComponent(component) @@ -62,11 +52,7 @@ components={component._children} {currentComponent} {onSelect} - level={level + 1} - {onDeleteComponent} - {onMoveUpComponent} - {onMoveDownComponent} - {onCopyComponent} /> + level={level + 1} /> {/if} {/each} diff --git a/packages/builder/src/components/userInterface/PageLayout.svelte b/packages/builder/src/components/userInterface/PageLayout.svelte index 2a532f9624..c4b786c5b2 100644 --- a/packages/builder/src/components/userInterface/PageLayout.svelte +++ b/packages/builder/src/components/userInterface/PageLayout.svelte @@ -68,11 +68,7 @@ + currentComponent={$store.currentComponentInfo} /> {/if}
From 5b085d0640ec14ede2a8de0ad7af0229852bdc6d Mon Sep 17 00:00:00 2001 From: Michael Shanks Date: Mon, 1 Jun 2020 11:04:32 +0100 Subject: [PATCH 3/5] few bugfixes --- .../builder/src/builderStore/store/index.js | 2 +- .../userInterface/ComponentDropdownMenu.svelte | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/builderStore/store/index.js b/packages/builder/src/builderStore/store/index.js index 6755bc0a7c..a034114b02 100644 --- a/packages/builder/src/builderStore/store/index.js +++ b/packages/builder/src/builderStore/store/index.js @@ -347,7 +347,7 @@ const addChildComponent = store => (componentToAdd, presetName) => { return state } - const component = getComponentDefinition(componentToAdd) + const component = getComponentDefinition(state, componentToAdd) const presetProps = presetName ? component.presets[presetName] : {} diff --git a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte index e2f8943d9e..5672ea6f4c 100644 --- a/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte +++ b/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte @@ -11,13 +11,15 @@ export let component let confirmDeleteDialog let dropdownEl -$: dropdown = UIkit.dropdown(dropdownEl, { mode: "click", offset: 0, pos: "bottom-right" }); +$: dropdown = UIkit.dropdown(dropdownEl, { mode: "click", offset: 0, pos: "bottom-right", "delay-hide": 0, animation: false }); +$: dropdown && UIkit.util.on(dropdown, "shown", () => hidden = false) $: noChildrenAllowed = !component || getComponentDefinition($store, component._component).children === false $: noPaste = !$store.componentToPaste || $store.componentToPaste._id === component._id const lastPartOfName = c => (c ? last(c._component.split("/")) : "") -const showDropdown = () => { - dropdown.show() + +const hideDropdown = () => { + dropdown.hide() } @@ -26,7 +28,7 @@ const showDropdown = () => { -