budibase/packages/builder/src/components/userInterface/ComponentDropdownMenu.svelte

156 lines
4.6 KiB
Svelte
Raw Normal View History

2020-06-01 23:16:55 +02:00
<script>
import { goto } from "@sveltech/routify"
import { get } from "svelte/store"
import { store, currentAsset } from "builderStore"
2020-06-01 13:15:44 +02:00
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { last } from "lodash/fp"
import { findComponentParent } from "builderStore/storeUtils"
2020-09-07 00:50:11 +02:00
import { DropdownMenu } from "@budibase/bbui"
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
2020-06-01 13:15:44 +02:00
export let component
let confirmDeleteDialog
let dropdown
2020-09-07 00:50:11 +02:00
let anchor
2020-06-01 13:15:44 +02:00
$: noChildrenAllowed =
2020-12-01 15:35:47 +01:00
!component ||
!store.actions.components.getDefinition(component._component)?.hasChildren
$: noPaste = !$store.componentToPaste
2020-06-01 13:15:44 +02:00
2020-10-27 16:28:13 +01:00
const lastPartOfName = c => (c ? last(c._component.split("/")) : "")
2020-06-01 13:15:44 +02:00
const hideDropdown = () => {
dropdown.hide()
}
2020-10-27 16:28:13 +01:00
const selectComponent = component => {
2020-11-04 18:09:45 +01:00
store.actions.components.select(component)
const path = store.actions.components.findRoute(component)
$goto(`./${$store.currentFrontEndType}/${path}`)
}
2020-06-01 13:15:44 +02:00
const moveUpComponent = () => {
store.update(state => {
const asset = get(currentAsset)
const parent = findComponentParent(asset.props, component)
2020-06-01 13:15:44 +02:00
if (parent) {
const currentIndex = parent._children.indexOf(component)
if (currentIndex === 0) return state
2020-06-01 13:15:44 +02:00
2020-10-27 16:28:13 +01:00
const newChildren = parent._children.filter(c => c !== component)
2020-06-01 13:15:44 +02:00
newChildren.splice(currentIndex - 1, 0, component)
parent._children = newChildren
}
state.selectedComponentId = component._id
store.actions.preview.saveSelected()
return state
2020-06-01 13:15:44 +02:00
})
}
2020-06-01 13:15:44 +02:00
const moveDownComponent = () => {
store.update(state => {
const asset = get(currentAsset)
const parent = findComponentParent(asset.props, component)
2020-06-01 13:15:44 +02:00
if (parent) {
const currentIndex = parent._children.indexOf(component)
if (currentIndex === parent._children.length - 1) return state
2020-10-27 16:28:13 +01:00
const newChildren = parent._children.filter(c => c !== component)
2020-06-01 13:15:44 +02:00
newChildren.splice(currentIndex + 1, 0, component)
parent._children = newChildren
}
state.selectedComponentId = component._id
store.actions.preview.saveSelected()
return state
})
2020-06-01 13:15:44 +02:00
}
const duplicateComponent = () => {
2020-10-07 23:30:00 +02:00
storeComponentForCopy(false)
pasteComponent("below")
2020-06-01 13:15:44 +02:00
}
2020-06-01 13:15:44 +02:00
const deleteComponent = () => {
store.actions.components.delete(component)
2020-06-01 13:15:44 +02:00
}
2020-06-01 13:15:44 +02:00
const storeComponentForCopy = (cut = false) => {
2020-08-12 17:28:19 +02:00
// lives in store - also used by drag drop
2020-11-04 18:09:45 +01:00
store.actions.components.copy(component, cut)
2020-06-01 13:15:44 +02:00
}
2020-10-27 16:28:13 +01:00
const pasteComponent = mode => {
2020-08-12 17:28:19 +02:00
// lives in store - also used by drag drop
2020-11-04 18:09:45 +01:00
store.actions.components.paste(component, mode)
2020-06-01 13:15:44 +02:00
}
2020-06-01 11:18:45 +02:00
</script>
<div bind:this={anchor} on:click|stopPropagation>
2020-11-06 13:31:47 +01:00
<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={duplicateComponent} />
<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>
2020-09-07 00:50:11 +02:00
</div>
2020-06-01 11:18:45 +02:00
<ConfirmDialog
bind:this={confirmDeleteDialog}
title="Confirm Deletion"
2020-06-01 11:18:45 +02:00
body={`Are you sure you wish to delete this '${lastPartOfName(component)}' component?`}
okText="Delete Component"
onOk={deleteComponent} />
2020-06-01 11:18:45 +02:00
<style>
hr {
2020-06-01 16:31:55 +02:00
margin: 8px 0;
background-color: var(--grey-4);
height: 1px;
border: none;
2020-06-01 16:31:55 +02:00
}
2020-06-01 13:15:44 +02:00
</style>