#94 Remove component from hierarchy
This commit is contained in:
parent
901db64450
commit
7d9d15c783
File diff suppressed because one or more lines are too long
|
@ -115,6 +115,7 @@ export const getStore = () => {
|
|||
store.setComponentStyle = setComponentStyle(store)
|
||||
store.setComponentCode = setComponentCode(store)
|
||||
store.setScreenType = setScreenType(store)
|
||||
store.deleteComponent = deleteComponent(store)
|
||||
return store
|
||||
}
|
||||
|
||||
|
@ -837,3 +838,39 @@ const setScreenType = store => type => {
|
|||
return s
|
||||
})
|
||||
}
|
||||
|
||||
const deleteComponent = store => component => {
|
||||
store.update(s => {
|
||||
let parent
|
||||
walkProps(s.currentPreviewItem.props, (p, breakWalk) => {
|
||||
if (p._children.includes(component)) {
|
||||
parent = p
|
||||
breakWalk()
|
||||
}
|
||||
})
|
||||
|
||||
if (parent) {
|
||||
parent._children = parent._children.filter(c => c !== component)
|
||||
}
|
||||
|
||||
s.currentFrontEndType === "page"
|
||||
? _savePage(s)
|
||||
: _saveScreenApi(s.currentPreviewItem, s)
|
||||
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
||||
const walkProps = (props, action, cancelToken = null) => {
|
||||
cancelToken = cancelToken || { cancelled: false }
|
||||
action(props, () => {
|
||||
cancelToken.cancelled = true
|
||||
})
|
||||
|
||||
if (props._children) {
|
||||
for (let child of props._children) {
|
||||
if (cancelToken.cancelled) return
|
||||
walkProps(child, action, cancelToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<script>
|
||||
import Button from "./Button.svelte"
|
||||
import ButtonGroup from "./ButtonGroup.svelte"
|
||||
import UIkit from "uikit"
|
||||
|
||||
export let title=""
|
||||
export let body=""
|
||||
export let okText = "OK"
|
||||
export let cancelText = "Cancel"
|
||||
export let onOk = ()=> {}
|
||||
export let onCancel = ()=> {}
|
||||
|
||||
export const show = () => {
|
||||
UIkit.modal(theModal).show()
|
||||
}
|
||||
|
||||
export const hide = () => {
|
||||
UIkit.modal(theModal).hide()
|
||||
}
|
||||
|
||||
let theModal;
|
||||
|
||||
const cancel = () => {
|
||||
hide()
|
||||
onCancel()
|
||||
}
|
||||
|
||||
const ok = () => {
|
||||
hide()
|
||||
onOk()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div id="my-id" uk-modal bind:this={theModal}>
|
||||
<div class="uk-modal-dialog">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-header">
|
||||
<h2 class="uk-modal-title">{title}</h2>
|
||||
</div>
|
||||
<div class="uk-modal-body">{body}</div>
|
||||
<div class="uk-modal-footer">
|
||||
<ButtonGroup>
|
||||
<Button grouped color="primary" on:click={ok}>
|
||||
{okText}
|
||||
</Button>
|
||||
<Button grouped color="secondary" on:click={cancel}>
|
||||
{cancelText}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="feather feather-x-circle">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<line x1="15" y1="9" x2="9" y2="15"/>
|
||||
<line x1="9" y1="9" x2="15" y2="15"/>
|
||||
</svg>
|
||||
|
||||
|
||||
<style>
|
||||
svg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
After Width: | Height: | Size: 454 B |
|
@ -7,3 +7,4 @@ export { default as ArrowDownIcon } from "./ArrowDown.svelte"
|
|||
export { default as CircleIndicator } from "./CircleIndicator.svelte"
|
||||
export { default as PencilIcon } from "./Pencil.svelte"
|
||||
export { default as EventsIcon } from "./Events.svelte"
|
||||
export { default as XCircleIcon } from "./XCircle.svelte"
|
||||
|
|
|
@ -2,13 +2,16 @@
|
|||
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte"
|
||||
|
||||
import { last, sortBy, map, trimCharsStart, trimChars, join } from "lodash/fp"
|
||||
|
||||
import ConfirmDialog from "../common/ConfirmDialog.svelte"
|
||||
import { pipe } from "../common/core"
|
||||
import { store } from "../builderStore"
|
||||
import { ArrowDownIcon } from "../common/Icons/"
|
||||
|
||||
export let screens = []
|
||||
|
||||
let confirmDeleteDialog
|
||||
let componentToDelete = ""
|
||||
|
||||
const joinPath = join("/")
|
||||
|
||||
const normalizedName = name =>
|
||||
|
@ -23,6 +26,7 @@
|
|||
)
|
||||
|
||||
const lastPartOfName = c =>
|
||||
c &&
|
||||
last(c.name ? c.name.split("/") : c._component.split("/"))
|
||||
|
||||
const isComponentSelected = (current, comp) => current === comp
|
||||
|
@ -38,6 +42,12 @@
|
|||
component.component &&
|
||||
$store.currentPreviewItem &&
|
||||
component.component.name === $store.currentPreviewItem.name
|
||||
|
||||
const confirmDeleteComponent = component => {
|
||||
componentToDelete = component
|
||||
confirmDeleteDialog.show()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
@ -63,12 +73,20 @@
|
|||
<ComponentsHierarchyChildren
|
||||
components={screen.component.props._children}
|
||||
currentComponent={$store.currentComponentInfo}
|
||||
onSelect={store.selectComponent} />
|
||||
onSelect={store.selectComponent}
|
||||
onDeleteComponent={confirmDeleteComponent}/>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
title="Confirm Delete"
|
||||
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete._component)}' component`}
|
||||
okText="Delete Component"
|
||||
onOk={() => store.deleteComponent(componentToDelete)}/>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
font-weight: 500;
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
<script>
|
||||
import { last } from "lodash/fp"
|
||||
import { pipe } from "../common/core"
|
||||
import { XCircleIcon } from "../common/Icons"
|
||||
|
||||
export let components = []
|
||||
export let currentComponent
|
||||
export let onSelect = () => {}
|
||||
export let level = 0
|
||||
export let onDeleteComponent
|
||||
|
||||
|
||||
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
|
||||
const get_name = s => last(s.split("/"))
|
||||
const get_name = s => !s ? "" : last(s.split("/"))
|
||||
|
||||
const get_capitalised_name = name =>
|
||||
pipe(
|
||||
name,
|
||||
[get_name, capitalise]
|
||||
)
|
||||
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
|
@ -24,7 +28,12 @@
|
|||
class="item"
|
||||
class:selected={currentComponent === component}
|
||||
style="padding-left: {level * 20 + 67}px">
|
||||
{get_capitalised_name(component._component)}
|
||||
<span class="item-name">{get_capitalised_name(component._component)}</span>
|
||||
<button
|
||||
class="delete-component"
|
||||
on:click={() => onDeleteComponent(component)}>
|
||||
<XCircleIcon />
|
||||
</button>
|
||||
</span>
|
||||
|
||||
{#if component._children}
|
||||
|
@ -32,7 +41,8 @@
|
|||
components={component._children}
|
||||
{currentComponent}
|
||||
{onSelect}
|
||||
level={level + 1} />
|
||||
level={level + 1}
|
||||
{onDeleteComponent} />
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
|
@ -45,14 +55,39 @@
|
|||
margin: 0;
|
||||
}
|
||||
.item {
|
||||
display: block;
|
||||
padding: 11px 67px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 11px 5px 11px 67px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.item > span {
|
||||
width: 1px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.item > button {
|
||||
display: none;
|
||||
height: 20px;
|
||||
color: var(--slate)
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
|
||||
background: #fafafa;
|
||||
cursor: pointer;
|
||||
}
|
||||
.item:hover > button {
|
||||
border-style: none;
|
||||
background: rgba(0,0,0,0);
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item:hover > button:hover {
|
||||
color: var(--button-text);
|
||||
}
|
||||
|
||||
.selected {
|
||||
color: var(--button-text);
|
||||
background: var(--background-button) !important;
|
||||
|
|
|
@ -10,8 +10,12 @@
|
|||
import SettingsView from "./SettingsView.svelte"
|
||||
import PageView from "./PageView.svelte"
|
||||
import ComponentsPaneSwitcher from "./ComponentsPaneSwitcher.svelte"
|
||||
import ConfirmDialog from "../common/ConfirmDialog.svelte"
|
||||
import { last } from "lodash/fp"
|
||||
|
||||
let newComponentPicker
|
||||
let confirmDeleteDialog
|
||||
let componentToDelete = ""
|
||||
|
||||
const newComponent = () => {
|
||||
newComponentPicker.show()
|
||||
|
@ -21,6 +25,14 @@
|
|||
const settings = () => {
|
||||
settingsView.show()
|
||||
}
|
||||
|
||||
const confirmDeleteComponent = component => {
|
||||
componentToDelete = component
|
||||
confirmDeleteDialog.show()
|
||||
}
|
||||
|
||||
const lastPartOfName = c => c ? c.split("/") : ""
|
||||
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
|
@ -53,6 +65,7 @@
|
|||
<ComponentsHierarchyChildren
|
||||
components={$store.currentPreviewItem.props._children}
|
||||
currentComponent={$store.currentComponentInfo}
|
||||
onDeleteComponent={confirmDeleteComponent}
|
||||
onSelect={store.selectComponent}
|
||||
level={-2} />
|
||||
{/if}
|
||||
|
@ -101,6 +114,13 @@
|
|||
<NewComponent bind:this={newComponentPicker} />
|
||||
<SettingsView bind:this={settingsView} />
|
||||
|
||||
<ConfirmDialog
|
||||
bind:this={confirmDeleteDialog}
|
||||
title="Confirm Delete"
|
||||
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete._component)}' component`}
|
||||
okText="Delete Component"
|
||||
onOk={() => store.deleteComponent(componentToDelete)}/>
|
||||
|
||||
<style>
|
||||
button {
|
||||
cursor: pointer;
|
||||
|
|
Loading…
Reference in New Issue