bulk delete, delete column from panel
This commit is contained in:
parent
9df48c6de7
commit
50f21e61ff
Binary file not shown.
Binary file not shown.
|
@ -77,6 +77,7 @@
|
||||||
"lodash": "^4.17.13",
|
"lodash": "^4.17.13",
|
||||||
"mustache": "^4.0.1",
|
"mustache": "^4.0.1",
|
||||||
"posthog-js": "1.4.5",
|
"posthog-js": "1.4.5",
|
||||||
|
"remixicon": "^2.5.0",
|
||||||
"shortid": "^2.2.15",
|
"shortid": "^2.2.15",
|
||||||
"svelte-loading-spinners": "^0.1.1",
|
"svelte-loading-spinners": "^0.1.1",
|
||||||
"svelte-portal": "^0.1.0",
|
"svelte-portal": "^0.1.0",
|
||||||
|
|
|
@ -178,6 +178,10 @@ export default {
|
||||||
src: "node_modules/@budibase/bbui/dist/bbui.css",
|
src: "node_modules/@budibase/bbui/dist/bbui.css",
|
||||||
dest: outputpath,
|
dest: outputpath,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
src: "node_modules/remixicon/fonts/*",
|
||||||
|
dest: outputpath,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
$: title = $backendUiStore.selectedTable.name
|
$: title = $backendUiStore.selectedTable.name
|
||||||
$: schema = $backendUiStore.selectedTable.schema
|
$: schema = $backendUiStore.selectedTable.schema
|
||||||
|
$: tableId = $backendUiStore.selectedTable._id
|
||||||
$: tableView = {
|
$: tableView = {
|
||||||
schema,
|
schema,
|
||||||
name: $backendUiStore.selectedView.name,
|
name: $backendUiStore.selectedView.name,
|
||||||
|
|
|
@ -1,29 +1,39 @@
|
||||||
<script>
|
<script>
|
||||||
import { fade } from "svelte/transition"
|
import { fade } from "svelte/transition"
|
||||||
|
import { Button } from "@budibase/bbui"
|
||||||
import { goto, params } from "@sveltech/routify"
|
import { goto, params } from "@sveltech/routify"
|
||||||
import Spinner from "components/common/Spinner.svelte"
|
|
||||||
import AgGrid from "@budibase/svelte-ag-grid"
|
import AgGrid from "@budibase/svelte-ag-grid"
|
||||||
import { getRenderer, editRowRenderer } from "./cells/cellRenderers"
|
|
||||||
|
import api from "builderStore/api"
|
||||||
|
import { notifier } from "builderStore/store/notifications"
|
||||||
|
import Spinner from "components/common/Spinner.svelte"
|
||||||
|
import DeleteRowsButton from "./buttons/DeleteRowsButton.svelte"
|
||||||
|
import {
|
||||||
|
getRenderer,
|
||||||
|
editRowRenderer,
|
||||||
|
deleteRowRenderer,
|
||||||
|
} from "./cells/cellRenderers"
|
||||||
import TableLoadingOverlay from "./TableLoadingOverlay"
|
import TableLoadingOverlay from "./TableLoadingOverlay"
|
||||||
import TableHeader from "./TableHeader"
|
import TableHeader from "./TableHeader"
|
||||||
import "@budibase/svelte-ag-grid/dist/index.css"
|
import "@budibase/svelte-ag-grid/dist/index.css"
|
||||||
|
|
||||||
export let schema = {}
|
export let schema = {}
|
||||||
export let data = []
|
export let data = []
|
||||||
|
export let tableId
|
||||||
export let title
|
export let title
|
||||||
export let allowEditing = false
|
export let allowEditing = false
|
||||||
export let loading = false
|
export let loading = false
|
||||||
|
|
||||||
export let theme = "alpine"
|
export let theme = "alpine"
|
||||||
|
|
||||||
let columnDefs = []
|
let columnDefs = []
|
||||||
|
let selectedRows = []
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
defaultColDef: {
|
defaultColDef: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
filter: true,
|
filter: true,
|
||||||
},
|
},
|
||||||
rowSelection: true,
|
rowSelection: allowEditing ? "multiple" : false,
|
||||||
rowMultiSelectWithClick: true,
|
rowMultiSelectWithClick: true,
|
||||||
suppressRowClickSelection: false,
|
suppressRowClickSelection: false,
|
||||||
paginationAutoPageSize: true,
|
paginationAutoPageSize: true,
|
||||||
|
@ -39,21 +49,34 @@
|
||||||
$: {
|
$: {
|
||||||
let result = []
|
let result = []
|
||||||
if (allowEditing) {
|
if (allowEditing) {
|
||||||
result.push({
|
result = [
|
||||||
pinned: "left",
|
{
|
||||||
headerName: "Edit",
|
pinned: "left",
|
||||||
sortable: false,
|
headerName: "Edit",
|
||||||
resizable: false,
|
sortable: false,
|
||||||
suppressMovable: true,
|
resizable: false,
|
||||||
suppressMenu: true,
|
suppressMovable: true,
|
||||||
minWidth: 75,
|
suppressMenu: true,
|
||||||
width: 75,
|
minWidth: 100,
|
||||||
cellRenderer: editRowRenderer,
|
width: 100,
|
||||||
})
|
cellRenderer: editRowRenderer,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "",
|
||||||
|
checkboxSelection: true,
|
||||||
|
sortable: false,
|
||||||
|
resizable: false,
|
||||||
|
suppressMovable: true,
|
||||||
|
suppressMenu: true,
|
||||||
|
minWidth: 50,
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let key in schema) {
|
for (let key in schema) {
|
||||||
result.push({
|
result.push({
|
||||||
|
headerCheckboxSelection: false,
|
||||||
headerComponent: TableHeader,
|
headerComponent: TableHeader,
|
||||||
headerComponentParams: {
|
headerComponentParams: {
|
||||||
field: schema[key],
|
field: schema[key],
|
||||||
|
@ -83,6 +106,16 @@
|
||||||
`/${$params.application}/data/table/${row.tableId}/relationship/${row._id}/${fieldName}`
|
`/${$params.application}/data/table/${row.tableId}/relationship/${row._id}/${fieldName}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteRows = async () => {
|
||||||
|
const response = await api.post(`/api/${tableId}/rows`, {
|
||||||
|
rows: selectedRows,
|
||||||
|
type: "delete",
|
||||||
|
})
|
||||||
|
data = data.filter(row => !selectedRows.includes(row))
|
||||||
|
notifier.success(`Successfully deleted ${selectedRows.length} rows`)
|
||||||
|
selectedRows = []
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
@ -90,9 +123,19 @@
|
||||||
<h2 class="title"><span>{title}</span></h2>
|
<h2 class="title"><span>{title}</span></h2>
|
||||||
<div class="popovers">
|
<div class="popovers">
|
||||||
<slot />
|
<slot />
|
||||||
|
{#if selectedRows.length > 0}
|
||||||
|
<DeleteRowsButton {selectedRows} {deleteRows} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AgGrid {theme} {options} {data} {columnDefs} {loading} />
|
<AgGrid
|
||||||
|
{theme}
|
||||||
|
{options}
|
||||||
|
{data}
|
||||||
|
{columnDefs}
|
||||||
|
{loading}
|
||||||
|
on:select={({ detail }) => (selectedRows = detail)} />
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -164,7 +207,7 @@
|
||||||
|
|
||||||
:global(.ag-menu input) {
|
:global(.ag-menu input) {
|
||||||
color: var(--ink) !important;
|
color: var(--ink) !important;
|
||||||
font-size: var(--font-size-s);
|
font-size: var(--font-size-xs);
|
||||||
border-radius: var(--border-radius-s) !important;
|
border-radius: var(--border-radius-s) !important;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: var(--grey-2) !important;
|
background-color: var(--grey-2) !important;
|
||||||
|
@ -181,7 +224,7 @@
|
||||||
|
|
||||||
:global(.ag-picker-field-display) {
|
:global(.ag-picker-field-display) {
|
||||||
color: var(--ink) !important;
|
color: var(--ink) !important;
|
||||||
font-size: var(--font-size-s) !important;
|
font-size: var(--font-size-xs) !important;
|
||||||
border-radius: var(--border-radius-s) !important;
|
border-radius: var(--border-radius-s) !important;
|
||||||
background-color: var(--grey-2) !important;
|
background-color: var(--grey-2) !important;
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
|
@ -191,6 +234,7 @@
|
||||||
:global(.ag-picker-field-wrapper) {
|
:global(.ag-picker-field-wrapper) {
|
||||||
background: var(--grey-2) !important;
|
background: var(--grey-2) !important;
|
||||||
border: var(--border-transparent) !important;
|
border: var(--border-transparent) !important;
|
||||||
padding: var(--spacing-xs);
|
padding-top: var(--spacing-xs);
|
||||||
|
padding-bottom: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -42,9 +42,7 @@
|
||||||
<header on:click={onSort} data-cy="table-header">
|
<header on:click={onSort} data-cy="table-header">
|
||||||
<div>
|
<div>
|
||||||
<span>{displayName}</span>
|
<span>{displayName}</span>
|
||||||
{#if enableSorting && sortDirection}
|
<i class={`${SORT_ICON_MAP[sortDirection]} sort-icon`} />
|
||||||
<i class={`${SORT_ICON_MAP[sortDirection]} sort-icon`} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<script>
|
||||||
|
import { TextButton, Icon, Modal, ModalContent } from "@budibase/bbui"
|
||||||
|
import CreateEditRowModal from "../modals/CreateEditRowModal.svelte"
|
||||||
|
|
||||||
|
export let selectedRows
|
||||||
|
export let deleteRows
|
||||||
|
|
||||||
|
let modal
|
||||||
|
|
||||||
|
async function confirmDeletion() {
|
||||||
|
await deleteRows()
|
||||||
|
modal.hide()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<TextButton small text on:click={modal.show}>
|
||||||
|
<Icon name="delete" />
|
||||||
|
Delete
|
||||||
|
{selectedRows.length}
|
||||||
|
row(s)
|
||||||
|
</TextButton>
|
||||||
|
</div>
|
||||||
|
<Modal bind:this={modal}>
|
||||||
|
<ModalContent
|
||||||
|
red
|
||||||
|
confirmText="Delete"
|
||||||
|
onConfirm={confirmDeletion}
|
||||||
|
title="Confirm Row Deletion">
|
||||||
|
Are you sure you want to delete these
|
||||||
|
{selectedRows.length}
|
||||||
|
rows?
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
|
@ -1,5 +1,6 @@
|
||||||
import AttachmentList from "./AttachmentCell.svelte"
|
import AttachmentList from "./AttachmentCell.svelte"
|
||||||
import EditRowPopover from "../modals/EditRow.svelte"
|
import EditRow from "../modals/EditRow.svelte"
|
||||||
|
import DeleteRow from "../modals/DeleteRow.svelte"
|
||||||
import RelationshipDisplay from "./RelationshipCell.svelte"
|
import RelationshipDisplay from "./RelationshipCell.svelte"
|
||||||
|
|
||||||
const renderers = {
|
const renderers = {
|
||||||
|
@ -15,10 +16,23 @@ export function getRenderer(schema, editable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function deleteRowRenderer(params) {
|
||||||
|
const container = document.createElement("div")
|
||||||
|
|
||||||
|
new DeleteRow({
|
||||||
|
target: container,
|
||||||
|
props: {
|
||||||
|
row: params.data,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
export function editRowRenderer(params) {
|
export function editRowRenderer(params) {
|
||||||
const container = document.createElement("div")
|
const container = document.createElement("div")
|
||||||
|
|
||||||
new EditRowPopover({
|
new EditRow({
|
||||||
target: container,
|
target: container,
|
||||||
props: {
|
props: {
|
||||||
row: params.data,
|
row: params.data,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
$backendUiStore.selectedTable.primaryDisplay == null ||
|
$backendUiStore.selectedTable.primaryDisplay == null ||
|
||||||
$backendUiStore.selectedTable.primaryDisplay === field.name
|
$backendUiStore.selectedTable.primaryDisplay === field.name
|
||||||
let confirmDeleteDialog
|
let confirmDeleteDialog
|
||||||
|
let deletion
|
||||||
|
|
||||||
$: tableOptions = $backendUiStore.tables.filter(
|
$: tableOptions = $backendUiStore.tables.filter(
|
||||||
table => table._id !== $backendUiStore.draftTable._id
|
table => table._id !== $backendUiStore.draftTable._id
|
||||||
|
@ -47,8 +48,8 @@
|
||||||
notifier.danger("You cannot delete the display column")
|
notifier.danger("You cannot delete the display column")
|
||||||
} else {
|
} else {
|
||||||
backendUiStore.actions.tables.deleteField(field)
|
backendUiStore.actions.tables.deleteField(field)
|
||||||
notifier.success("Column deleted")
|
notifier.success(`Column ${field.name} deleted.`)
|
||||||
hideDeleteDialog()
|
onClosed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,15 +77,16 @@
|
||||||
|
|
||||||
function confirmDelete() {
|
function confirmDelete() {
|
||||||
confirmDeleteDialog.show()
|
confirmDeleteDialog.show()
|
||||||
onClosed()
|
deletion = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideDeleteDialog() {
|
function hideDeleteDialog() {
|
||||||
confirmDeleteDialog.hide()
|
confirmDeleteDialog.hide()
|
||||||
|
deletion = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions" class:hidden={deletion}>
|
||||||
<Input label="Name" thin bind:value={field.name} />
|
<Input label="Name" thin bind:value={field.name} />
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
@ -182,4 +184,8 @@
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<script>
|
||||||
|
import { backendUiStore } from "builderStore"
|
||||||
|
import { DropdownMenu, Icon, Modal } from "@budibase/bbui"
|
||||||
|
import * as api from "../api"
|
||||||
|
import { notifier } from "builderStore/store/notifications"
|
||||||
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
|
|
||||||
|
export let row
|
||||||
|
|
||||||
|
let anchor
|
||||||
|
let dropdown
|
||||||
|
let confirmDeleteDialog
|
||||||
|
|
||||||
|
function showDelete() {
|
||||||
|
confirmDeleteDialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteRow() {
|
||||||
|
await api.deleteRow(row)
|
||||||
|
notifier.success("Row deleted")
|
||||||
|
backendUiStore.actions.rows.delete(row)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div on:click={showDelete}><i class="ri-delete-row" /></div>
|
||||||
|
<ConfirmDialog
|
||||||
|
bind:this={confirmDeleteDialog}
|
||||||
|
body={`Are you sure you wish to delete this row? Your data will be deleted and this action cannot be undone.`}
|
||||||
|
okText="Delete Row"
|
||||||
|
onOk={deleteRow}
|
||||||
|
title="Confirm Delete" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ri-delete-bin-line:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,10 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import { DropdownMenu, Icon, Modal } from "@budibase/bbui"
|
import { DropdownMenu, Icon, Modal, Button } from "@budibase/bbui"
|
||||||
import CreateEditRowModal from "../modals/CreateEditRowModal.svelte"
|
import CreateEditRowModal from "../modals/CreateEditRowModal.svelte"
|
||||||
import * as api from "../api"
|
|
||||||
import { notifier } from "builderStore/store/notifications"
|
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
|
||||||
|
|
||||||
export let row
|
export let row
|
||||||
|
|
||||||
|
@ -13,34 +10,13 @@
|
||||||
let confirmDeleteDialog
|
let confirmDeleteDialog
|
||||||
let modal
|
let modal
|
||||||
|
|
||||||
function showModal() {
|
function showModal(e) {
|
||||||
|
e.stopPropagation()
|
||||||
modal.show()
|
modal.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
function showDelete() {
|
|
||||||
confirmDeleteDialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteRow() {
|
|
||||||
await api.deleteRow(row)
|
|
||||||
notifier.success("Row deleted")
|
|
||||||
backendUiStore.actions.rows.delete(row)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click={showModal}><i class="ri-more-line" /></div>
|
<Button translucent small on:click={showModal}>Edit</Button>
|
||||||
<ConfirmDialog
|
|
||||||
bind:this={confirmDeleteDialog}
|
|
||||||
body={`Are you sure you wish to delete this row? Your data will be deleted and this action cannot be undone.`}
|
|
||||||
okText="Delete Row"
|
|
||||||
onOk={deleteRow}
|
|
||||||
title="Confirm Delete" />
|
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
<CreateEditRowModal {row} />
|
<CreateEditRowModal {row} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<style>
|
|
||||||
.ri-more-line:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
<title>Budibase Builder</title>
|
<title>Budibase Builder</title>
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
|
||||||
<link rel='stylesheet' href='/_builder/bundle.css'>
|
<link rel='stylesheet' href='/_builder/bundle.css'>
|
||||||
<link rel='stylesheet' href='/_builder/external.css'>
|
<link rel='stylesheet' href='/_builder/external.css'>
|
||||||
|
|
|
@ -10,6 +10,8 @@ import "/assets/Inter-ExtraBold"
|
||||||
import "/assets/Inter-Black"
|
import "/assets/Inter-Black"
|
||||||
import "/_builder/assets/budibase-logo.png"
|
import "/_builder/assets/budibase-logo.png"
|
||||||
import "/_builder/assets/budibase-logo-only.png"
|
import "/_builder/assets/budibase-logo-only.png"
|
||||||
|
import "remixicon/fonts/remixicon.css"
|
||||||
|
|
||||||
import App from "./App.svelte"
|
import App from "./App.svelte"
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
|
@ -5310,6 +5310,11 @@ regjsparser@^0.6.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
jsesc "~0.5.0"
|
jsesc "~0.5.0"
|
||||||
|
|
||||||
|
remixicon@^2.5.0:
|
||||||
|
version "2.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/remixicon/-/remixicon-2.5.0.tgz#b5e245894a1550aa23793f95daceadbf96ad1a41"
|
||||||
|
integrity sha512-q54ra2QutYDZpuSnFjmeagmEiN9IMo56/zz5dDNitzKD23oFRw77cWo4TsrAdmdkPiEn8mxlrTqxnkujDbEGww==
|
||||||
|
|
||||||
remove-trailing-separator@^1.0.1:
|
remove-trailing-separator@^1.0.1:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue