Replace component dropdown menu with new common components
This commit is contained in:
parent
f42dc2551c
commit
26bb3ebb98
|
@ -1,4 +1,4 @@
|
||||||
<div class="dropdown-container">
|
<div class="dropdown-container" on:click>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
export let icon
|
export let icon
|
||||||
export let title
|
export let title
|
||||||
export let subtitle
|
export let subtitle
|
||||||
|
export let disabled
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="dropdown-item" on:click class:big={subtitle != null}>
|
<div class="dropdown-item" class:disabled on:click class:big={subtitle != null}>
|
||||||
{#if icon}<i class={icon} />{/if}
|
{#if icon}<i class={icon} />{/if}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="title">{title}</div>
|
<div class="title">{title}</div>
|
||||||
|
@ -22,11 +23,17 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
padding: var(--spacing-xs) var(--spacing-l);
|
padding: var(--spacing-xs) var(--spacing-l);
|
||||||
|
color: var(--ink);
|
||||||
|
}
|
||||||
|
.dropdown-item.disabled,
|
||||||
|
.dropdown-item.disabled .subtitle {
|
||||||
|
pointer-events: none;
|
||||||
|
color: var(--grey-5);
|
||||||
}
|
}
|
||||||
.dropdown-item.big {
|
.dropdown-item.big {
|
||||||
padding: var(--spacing-s) var(--spacing-l);
|
padding: var(--spacing-s) var(--spacing-l);
|
||||||
}
|
}
|
||||||
.dropdown-item:hover {
|
.dropdown-item:not(.disabled):hover {
|
||||||
background-color: var(--grey-2);
|
background-color: var(--grey-2);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +52,6 @@
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--ink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
|
@ -55,6 +61,5 @@
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--ink);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import { getComponentDefinition } from "builderStore/storeUtils"
|
import { getComponentDefinition } from "builderStore/storeUtils"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import { last, cloneDeep } from "lodash/fp"
|
import { last } from "lodash/fp"
|
||||||
import { getParent, saveCurrentPreviewItem } from "builderStore/storeUtils"
|
import { getParent, saveCurrentPreviewItem } from "builderStore/storeUtils"
|
||||||
import { uuid } from "builderStore/uuid"
|
|
||||||
import { DropdownMenu } from "@budibase/bbui"
|
import { DropdownMenu } from "@budibase/bbui"
|
||||||
|
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
|
||||||
|
|
||||||
export let component
|
export let component
|
||||||
|
|
||||||
|
@ -18,27 +18,27 @@
|
||||||
!component || !getComponentDefinition($store, component._component).children
|
!component || !getComponentDefinition($store, component._component).children
|
||||||
$: noPaste = !$store.componentToPaste
|
$: noPaste = !$store.componentToPaste
|
||||||
|
|
||||||
const lastPartOfName = c => (c ? last(c._component.split("/")) : "")
|
const lastPartOfName = (c) => (c ? last(c._component.split("/")) : "")
|
||||||
|
|
||||||
const hideDropdown = () => {
|
const hideDropdown = () => {
|
||||||
dropdown.hide()
|
dropdown.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectComponent = component => {
|
const selectComponent = (component) => {
|
||||||
store.selectComponent(component)
|
store.selectComponent(component)
|
||||||
const path = store.getPathToComponent(component)
|
const path = store.getPathToComponent(component)
|
||||||
$goto(`./:page/:screen/${path}`)
|
$goto(`./:page/:screen/${path}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveUpComponent = () => {
|
const moveUpComponent = () => {
|
||||||
store.update(s => {
|
store.update((s) => {
|
||||||
const parent = getParent(s.currentPreviewItem.props, component)
|
const parent = getParent(s.currentPreviewItem.props, component)
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const currentIndex = parent._children.indexOf(component)
|
const currentIndex = parent._children.indexOf(component)
|
||||||
if (currentIndex === 0) return s
|
if (currentIndex === 0) return s
|
||||||
|
|
||||||
const newChildren = parent._children.filter(c => c !== component)
|
const newChildren = parent._children.filter((c) => c !== component)
|
||||||
newChildren.splice(currentIndex - 1, 0, component)
|
newChildren.splice(currentIndex - 1, 0, component)
|
||||||
parent._children = newChildren
|
parent._children = newChildren
|
||||||
}
|
}
|
||||||
|
@ -50,14 +50,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveDownComponent = () => {
|
const moveDownComponent = () => {
|
||||||
store.update(s => {
|
store.update((s) => {
|
||||||
const parent = getParent(s.currentPreviewItem.props, component)
|
const parent = getParent(s.currentPreviewItem.props, component)
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const currentIndex = parent._children.indexOf(component)
|
const currentIndex = parent._children.indexOf(component)
|
||||||
if (currentIndex === parent._children.length - 1) return s
|
if (currentIndex === parent._children.length - 1) return s
|
||||||
|
|
||||||
const newChildren = parent._children.filter(c => c !== component)
|
const newChildren = parent._children.filter((c) => c !== component)
|
||||||
newChildren.splice(currentIndex + 1, 0, component)
|
newChildren.splice(currentIndex + 1, 0, component)
|
||||||
parent._children = newChildren
|
parent._children = newChildren
|
||||||
}
|
}
|
||||||
|
@ -74,11 +74,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteComponent = () => {
|
const deleteComponent = () => {
|
||||||
store.update(state => {
|
store.update((state) => {
|
||||||
const parent = getParent(state.currentPreviewItem.props, component)
|
const parent = getParent(state.currentPreviewItem.props, component)
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent._children = parent._children.filter(c => c !== component)
|
parent._children = parent._children.filter((c) => c !== component)
|
||||||
selectComponent(parent)
|
selectComponent(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
store.storeComponentForCopy(component, cut)
|
store.storeComponentForCopy(component, cut)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pasteComponent = mode => {
|
const pasteComponent = (mode) => {
|
||||||
// lives in store - also used by drag drop
|
// lives in store - also used by drag drop
|
||||||
store.pasteComponent(component, mode)
|
store.pasteComponent(component, mode)
|
||||||
}
|
}
|
||||||
|
@ -100,63 +100,51 @@
|
||||||
|
|
||||||
<div bind:this={anchor} on:click|stopPropagation={() => {}}>
|
<div bind:this={anchor} on:click|stopPropagation={() => {}}>
|
||||||
<div class="icon" on:click={dropdown.show}><i class="ri-more-line" /></div>
|
<div class="icon" on:click={dropdown.show}><i class="ri-more-line" /></div>
|
||||||
|
<DropdownMenu bind:this={dropdown} width="170px" {anchor} align="left">
|
||||||
|
<DropdownContainer on:click={hideDropdown}>
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-delete-bin-line"
|
||||||
|
title="Delete"
|
||||||
|
on:click={() => confirmDeleteDialog.show()} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-arrow-up-line"
|
||||||
|
title="Move up"
|
||||||
|
on:click={moveUpComponent} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-arrow-down-line"
|
||||||
|
title="Move down"
|
||||||
|
on:click={moveDownComponent} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-repeat-one-line"
|
||||||
|
title="Duplicate"
|
||||||
|
on:click={copyComponent} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-scissors-cut-line"
|
||||||
|
title="Cut"
|
||||||
|
on:click={() => storeComponentForCopy(true)} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-file-copy-line"
|
||||||
|
title="Copy"
|
||||||
|
on:click={() => storeComponentForCopy(false)} />
|
||||||
|
<hr class="hr-style" />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-insert-row-top"
|
||||||
|
title="Paste above"
|
||||||
|
disabled={noPaste}
|
||||||
|
on:click={() => pasteComponent('above')} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-insert-row-bottom"
|
||||||
|
title="Paste below"
|
||||||
|
disabled={noPaste}
|
||||||
|
on:click={() => pasteComponent('below')} />
|
||||||
|
<DropdownItem
|
||||||
|
icon="ri-insert-column-right"
|
||||||
|
title="Paste inside"
|
||||||
|
disabled={noPaste || noChildrenAllowed}
|
||||||
|
on:click={() => pasteComponent('inside')} />
|
||||||
|
</DropdownContainer>
|
||||||
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
<DropdownMenu
|
|
||||||
bind:this={dropdown}
|
|
||||||
on:click={hideDropdown}
|
|
||||||
width="170px"
|
|
||||||
{anchor}
|
|
||||||
align="left">
|
|
||||||
<ul>
|
|
||||||
<li class="item" on:click={() => confirmDeleteDialog.show()}>
|
|
||||||
<i class="ri-delete-bin-2-line" />
|
|
||||||
Delete
|
|
||||||
</li>
|
|
||||||
<li class="item" on:click={moveUpComponent}>
|
|
||||||
<i class="ri-arrow-up-line" />
|
|
||||||
Move up
|
|
||||||
</li>
|
|
||||||
<li class="item" on:click={moveDownComponent}>
|
|
||||||
<i class="ri-arrow-down-line" />
|
|
||||||
Move down
|
|
||||||
</li>
|
|
||||||
<li class="item" on:click={copyComponent}>
|
|
||||||
<i class="ri-repeat-one-line" />
|
|
||||||
Duplicate
|
|
||||||
</li>
|
|
||||||
<li class="item" on:click={() => storeComponentForCopy(true)}>
|
|
||||||
<i class="ri-scissors-cut-line" />
|
|
||||||
Cut
|
|
||||||
</li>
|
|
||||||
<li class="item" on:click={() => storeComponentForCopy(false)}>
|
|
||||||
<i class="ri-file-copy-line" />
|
|
||||||
Copy
|
|
||||||
</li>
|
|
||||||
<hr class="hr-style" />
|
|
||||||
<li
|
|
||||||
class="item"
|
|
||||||
class:disabled={noPaste}
|
|
||||||
on:click={() => pasteComponent('above')}>
|
|
||||||
<i class="ri-insert-row-top" />
|
|
||||||
Paste above
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="item"
|
|
||||||
class:disabled={noPaste}
|
|
||||||
on:click={() => pasteComponent('below')}>
|
|
||||||
<i class="ri-insert-row-bottom" />
|
|
||||||
Paste below
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="item"
|
|
||||||
class:disabled={noPaste || noChildrenAllowed}
|
|
||||||
on:click={() => pasteComponent('inside')}>
|
|
||||||
<i class="ri-insert-column-right" />
|
|
||||||
Paste inside
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</DropdownMenu>
|
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:this={confirmDeleteDialog}
|
bind:this={confirmDeleteDialog}
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
|
@ -165,43 +153,10 @@
|
||||||
onOk={deleteComponent} />
|
onOk={deleteComponent} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
ul {
|
hr {
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: var(--spacing-s) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: flex;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
color: var(--ink);
|
|
||||||
padding: var(--spacing-s) var(--spacing-m);
|
|
||||||
margin: auto 0;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
li:not(.disabled):hover {
|
|
||||||
background-color: var(--grey-2);
|
|
||||||
}
|
|
||||||
li:active {
|
|
||||||
color: var(--blue);
|
|
||||||
}
|
|
||||||
li i {
|
|
||||||
margin-right: 8px;
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
}
|
|
||||||
li.disabled {
|
|
||||||
color: var(--grey-4);
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon i {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hr-style {
|
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
color: var(--grey-4);
|
background-color: var(--grey-4);
|
||||||
|
height: 1px;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue