diff --git a/packages/builder/package.json b/packages/builder/package.json index 161b3915ae..cbee5f40b6 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -66,6 +66,7 @@ "@budibase/bbui": "^1.44.1", "@budibase/client": "^0.2.5", "@budibase/colorpicker": "^1.0.1", + "@budibase/svelte-ag-grid": "^0.0.13", "@fortawesome/fontawesome-free": "^5.14.0", "@sentry/browser": "5.19.1", "@svelteschool/svelte-forms": "^0.7.0", diff --git a/packages/builder/src/components/backend/DataTable/Table.old.svelte b/packages/builder/src/components/backend/DataTable/Table.old.svelte new file mode 100644 index 0000000000..3fa42aeb7c --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/Table.old.svelte @@ -0,0 +1,233 @@ + + +
+
+

+ {title} + {#if loading} +
+ +
+ {/if} +

+
+ +
+
+ + + + {#if allowEditing} + + {/if} + {#each columns as header} + + {/each} + + + + {#if paginatedData.length === 0} + {#if allowEditing} + + {/if} + {#each columns as header, idx} + + {/each} + {/if} + {#each paginatedData as row} + + {#if allowEditing} + + {/if} + {#each columns as header} + + {/each} + + {/each} + +
+
Edit
+
+ {#if allowEditing} + + {:else} +
{header}
+ {/if} +
No data. + {#if idx === 0 && !allowEditing}No data.{/if} +
+ + + {#if schema[header].type === 'link'} +
selectRelationship(row, header)}> + {row[header] ? row[header].length : 0} + related row(s) +
+ {:else if schema[header].type === 'attachment'} + + {:else}{getOr('', header, row)}{/if} +
+ +
+ + diff --git a/packages/builder/src/components/backend/DataTable/Table.svelte b/packages/builder/src/components/backend/DataTable/Table.svelte index 3fa42aeb7c..43a6152e41 100644 --- a/packages/builder/src/components/backend/DataTable/Table.svelte +++ b/packages/builder/src/components/backend/DataTable/Table.svelte @@ -8,8 +8,6 @@ import api from "builderStore/api" import { Button, Icon } from "@budibase/bbui" import ActionButton from "components/common/ActionButton.svelte" - import AttachmentList from "./AttachmentList.svelte" - import TablePagination from "./TablePagination.svelte" import CreateEditRowModal from "./modals/CreateEditRowModal.svelte" import RowPopover from "./buttons/CreateRowButton.svelte" import ColumnPopover from "./buttons/CreateColumnButton.svelte" @@ -19,7 +17,13 @@ import CalculationPopover from "./buttons/CalculateButton.svelte" import Spinner from "components/common/Spinner.svelte" - const ITEMS_PER_PAGE = 10 + // New + import AgGrid from "@budibase/svelte-ag-grid" + import { getRenderer, editRowRenderer } from "./cells/cellRenderers"; + import TableHeader from "./TableHeader" + + // const ITEMS_PER_PAGE = 10 + export let schema = [] export let data = [] @@ -27,18 +31,61 @@ export let allowEditing = false export let loading = false - let currentPage = 0 + // New stuff + export let theme = "alpine" - $: columns = schema ? Object.keys(schema) : [] - $: sort = $backendUiStore.sort - $: sorted = sort ? fsort(data)[sort.direction](sort.column) : data - $: paginatedData = - sorted && sorted.length - ? sorted.slice( - currentPage * ITEMS_PER_PAGE, - currentPage * ITEMS_PER_PAGE + ITEMS_PER_PAGE - ) - : [] + let columnDefs = [] + + let options = { + defaultColDef: { + flex: 1, + minWidth: 150, + filter: true, + }, + rowSelection: "multiple", + suppressRowClickSelection: false, + paginationAutoPageSize: true, + } + + // let currentPage = 0 + // $: columns = schema ? Object.keys(schema) : [] + // $: sort = $backendUiStore.sort + // $: sorted = sort ? fsort(data)[sort.direction](sort.column) : data + // $: paginatedData = + // sorted && sorted.length + // ? sorted.slice( + // currentPage * ITEMS_PER_PAGE, + // currentPage * ITEMS_PER_PAGE + ITEMS_PER_PAGE + // ) + // : [] + // TODO: refactor + $: { + let result = [] + if (allowEditing) { + result.push({ + headerName: "Edit", + sortable: false, + resizable: false, + suppressMovable: true, + width: 10, + cellRenderer: editRowRenderer + }) + } + columnDefs = [...result, ...Object.keys(schema).map(key => ({ + // headerCheckboxSelection: i === 0 && canEdit, + // checkboxSelection: i === 0 && canEdit, + // valueSetter: setters.get(schema[key].type), + headerComponent: TableHeader, + headerName: key, + field: key, + // hide: shouldHideField(key), + sortable: true, + // editable: canEdit && schema[key].type !== "link", + cellRenderer: getRenderer(schema[key], true), + autoHeight: true, + resizable: true, + }))] + } $: tableId = data?.length ? data[0].tableId : null function selectRelationship(row, fieldName) { @@ -46,9 +93,24 @@ return } $goto( - `/${$params.application}/backend/table/${tableId}/relationship/${row._id}/${fieldName}` + `/${$params.application}/data/table/${tableId}/relationship/${row._id}/${fieldName}` ) } + + // New stuff + const deleteRows = async () => { + const response = await api.post(`/api/${tableId}/rows`, { + rows: selectedRows, + type: "delete", + }) + data = data.filter(row => !selectedRows.includes(row)) + selectedRows = [] + } + + const handleUpdate = ({ detail }) => { + data[detail.row] = detail.data + updateRow(detail.data) + }
@@ -65,7 +127,14 @@ - + (console.log(detail))} /> + + diff --git a/packages/builder/src/components/backend/DataTable/TableHeader/TableHeader.svelte b/packages/builder/src/components/backend/DataTable/TableHeader/TableHeader.svelte new file mode 100644 index 0000000000..690d40b19a --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/TableHeader/TableHeader.svelte @@ -0,0 +1,12 @@ + + +

Fackle

+ + diff --git a/packages/builder/src/components/backend/DataTable/TableHeader/index.js b/packages/builder/src/components/backend/DataTable/TableHeader/index.js new file mode 100644 index 0000000000..5507961657 --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/TableHeader/index.js @@ -0,0 +1,67 @@ +// // the column the header is for +// column: Column; + +// // the name to display for the column. if the column is using a headerValueGetter, +// // the displayName will take this into account. +// displayName: string; + +// // whether sorting is enabled for the column. only put sort logic into +// // your header if this is true. +// enableSorting: boolean; + +// // whether menu is enabled for the column. only display a menu button +// // in your header if this is true. +// enableMenu: boolean; + +// // callback to progress the sort for this column. +// // the grid will decide the next sort direction eg ascending, descending or 'no sort'. +// // pass multiSort=true if you want to do a multi sort (eg user has shift held down when +// // they click) +// progressSort(multiSort: boolean): void; + +// // callback to set the sort for this column. +// // pass the sort direction to use ignoring the current sort eg one of 'asc', 'desc' or null +// // (for no sort). pass multiSort=true if you want to do a multi sort (eg user has shift held +// // down when they click) +// setSort(sort: string, multiSort?: boolean): void; + +// // callback to request the grid to show the column menu. +// // pass in the html element of the column menu to have the +// // grid position the menu over the button. +// showColumnMenu(menuButton: HTMLElement): void; + +// // The grid API +// api: any; +import TableHeader from "./TableHeader.svelte" + +export default class TableHeaderWrapper { + constructor() { + // foo + } + + init(params) { + console.log("init", params) + this.agParams = params + const container = document.createElement("div") + new TableHeader({ + target: container, + props: params, + }) + this.eGui = container + } + + // can get called more than once, you should return the HTML element + getGui() { + return this.eGui + } + + // gets called when a new Column Definition has been set for this header + refresh(params) { + console.log("Refreshing", params) + } + + // optional method, gets called once, when component is destroyed + destroy() { + console.log("Destroy") + } +} diff --git a/packages/builder/src/components/backend/DataTable/AttachmentList.svelte b/packages/builder/src/components/backend/DataTable/cells/AttachmentCell.svelte similarity index 100% rename from packages/builder/src/components/backend/DataTable/AttachmentList.svelte rename to packages/builder/src/components/backend/DataTable/cells/AttachmentCell.svelte diff --git a/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_fallback.svelte b/packages/builder/src/components/backend/DataTable/cells/BooleanCell.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/[page]/[screen]/_fallback.svelte rename to packages/builder/src/components/backend/DataTable/cells/BooleanCell.svelte diff --git a/packages/builder/src/components/backend/DataTable/cells/RelationshipCell.svelte b/packages/builder/src/components/backend/DataTable/cells/RelationshipCell.svelte new file mode 100644 index 0000000000..52753463b8 --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/cells/RelationshipCell.svelte @@ -0,0 +1,69 @@ + + +
+ {#if linkedRows && linkedRows.length && displayColumn} + {#each linkedRows as linkedRow} + {#if linkedRow[displayColumn] != null && linkedRow[displayColumn] !== ''} +
{linkedRow[displayColumn]}
+ {/if} + {/each} + {:else}{count} related row(s){/if} +
+ + diff --git a/packages/builder/src/components/backend/DataTable/cells/cellRenderers.js b/packages/builder/src/components/backend/DataTable/cells/cellRenderers.js new file mode 100644 index 0000000000..f0bb07ce38 --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/cells/cellRenderers.js @@ -0,0 +1,129 @@ +import AttachmentList from "./AttachmentCell.svelte" +import EditRowPopover from "../popovers/RowPopover.svelte" +import RelationshipDisplay from "./RelationshipCell.svelte" +// import BooleanCell from "./BooleanCell.svelte" + +const renderers = { + attachment: attachmentRenderer, + link: linkedRowRenderer, + boolean: booleanRenderer, +} + +export function getRenderer(schema, editable) { + if (renderers[schema.type]) { + return renderers[schema.type](schema.options, schema.constraints, editable) + } else { + return false + } +} + +export function editRowRenderer(params) { + const container = document.createElement("div") + + new EditRowPopover({ + target: container, + props: { + row: params.data, + }, + }) + + return container +} + +/* eslint-disable no-unused-vars */ +function booleanRenderer(options, constraints) { + return params => { + let container = document.createElement("input") + + // TODO: implement + + return container + + // const toggle = e => { + // params.value = !params.value + // params.setValue(e.currentTarget.checked) + // } + // let input = document.createElement("input") + // input.style.display = "grid" + // input.style.placeItems = "center" + // input.style.height = "100%" + // input.type = "checkbox" + // input.checked = params.value + // if (editable) { + // input.addEventListener("click", toggle) + // } else { + // input.disabled = true + // } + // return input + } +} + +/* eslint-disable no-unused-vars */ +function attachmentRenderer(options, constraints, editable) { + return params => { + const container = document.createElement("div") + + const attachmentInstance = new AttachmentList({ + target: container, + props: { + files: params.value || [], + }, + }) + + // const deleteFile = event => { + // const newFilesArray = params.value.filter(file => file !== event.detail) + // params.setValue(newFilesArray) + // } + + // attachmentInstance.$on("delete", deleteFile) + + return container + } +} +/* eslint-disable no-unused-vars */ +// function dateRenderer(options, constraints, editable) { +// return function(params) { +// const container = document.createElement("div") +// const toggle = e => { +// params.setValue(e.detail[0][0]) +// } + +// // Options need to be passed in with minTime and maxTime! Needs bbui update. +// new DatePicker({ +// target: container, +// props: { +// value: params.value, +// }, +// }) + +// return container +// } +// } + +function optionsRenderer(options, constraints, editable) { + return params => { + const container = document.createElement("div") + // TODO: show a pill + return container + } +} + +/* eslint-disable no-unused-vars */ +function linkedRowRenderer(options, constraints, editable) { + return params => { + let container = document.createElement("div") + container.style.display = "grid" + container.style.placeItems = "center" + container.style.height = "100%" + + new RelationshipDisplay({ + target: container, + props: { + row: params.data, + columnName: params.column.colId, + }, + }) + + return container + } +} diff --git a/packages/builder/src/components/backend/DataTable/cells/tableCache.js b/packages/builder/src/components/backend/DataTable/cells/tableCache.js new file mode 100644 index 0000000000..01a07b42db --- /dev/null +++ b/packages/builder/src/components/backend/DataTable/cells/tableCache.js @@ -0,0 +1,20 @@ +import api from "builderStore/api" + +let cache = {} + +async function fetchTable(id) { + const FETCH_TABLE_URL = `/api/tables/${id}` + const response = await api.get(FETCH_TABLE_URL) + return await response.json() +} + +export async function getTable(tableId) { + if (!tableId) { + return null + } + if (!cache[tableId]) { + cache[tableId] = fetchTable(tableId) + cache[tableId] = await cache[tableId] + } + return await cache[tableId] +} diff --git a/packages/builder/src/pages/[application]/backend/_layout.svelte b/packages/builder/src/pages/[application]/data/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/_layout.svelte rename to packages/builder/src/pages/[application]/data/_layout.svelte diff --git a/packages/builder/src/pages/[application]/backend/index.svelte b/packages/builder/src/pages/[application]/data/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/index.svelte rename to packages/builder/src/pages/[application]/data/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/[selectedTable]/_layout.svelte b/packages/builder/src/pages/[application]/data/table/[selectedTable]/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/[selectedTable]/_layout.svelte rename to packages/builder/src/pages/[application]/data/table/[selectedTable]/_layout.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/[selectedTable]/index.svelte b/packages/builder/src/pages/[application]/data/table/[selectedTable]/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/[selectedTable]/index.svelte rename to packages/builder/src/pages/[application]/data/table/[selectedTable]/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte b/packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte rename to packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/[selectedRow]/[selectedField]/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/[selectedRow]/index.svelte b/packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/[selectedRow]/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/[selectedRow]/index.svelte rename to packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/[selectedRow]/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/index.svelte b/packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/[selectedTable]/relationship/index.svelte rename to packages/builder/src/pages/[application]/data/table/[selectedTable]/relationship/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/_layout.svelte b/packages/builder/src/pages/[application]/data/table/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/_layout.svelte rename to packages/builder/src/pages/[application]/data/table/_layout.svelte diff --git a/packages/builder/src/pages/[application]/backend/table/index.svelte b/packages/builder/src/pages/[application]/data/table/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/table/index.svelte rename to packages/builder/src/pages/[application]/data/table/index.svelte diff --git a/packages/builder/src/pages/[application]/backend/view/[selectedView]/_layout.svelte b/packages/builder/src/pages/[application]/data/view/[selectedView]/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/view/[selectedView]/_layout.svelte rename to packages/builder/src/pages/[application]/data/view/[selectedView]/_layout.svelte diff --git a/packages/builder/src/pages/[application]/backend/view/[selectedView]/index.svelte b/packages/builder/src/pages/[application]/data/view/[selectedView]/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/backend/view/[selectedView]/index.svelte rename to packages/builder/src/pages/[application]/data/view/[selectedView]/index.svelte diff --git a/packages/builder/src/pages/[application]/design/[page]/[screen]/_fallback.svelte b/packages/builder/src/pages/[application]/design/[page]/[screen]/_fallback.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte b/packages/builder/src/pages/[application]/design/[page]/[screen]/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/[page]/[screen]/_layout.svelte rename to packages/builder/src/pages/[application]/design/[page]/[screen]/_layout.svelte diff --git a/packages/builder/src/pages/[application]/frontend/[page]/_layout.svelte b/packages/builder/src/pages/[application]/design/[page]/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/[page]/_layout.svelte rename to packages/builder/src/pages/[application]/design/[page]/_layout.svelte diff --git a/packages/builder/src/pages/[application]/frontend/[page]/index.svelte b/packages/builder/src/pages/[application]/design/[page]/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/[page]/index.svelte rename to packages/builder/src/pages/[application]/design/[page]/index.svelte diff --git a/packages/builder/src/pages/[application]/frontend/_layout.svelte b/packages/builder/src/pages/[application]/design/_layout.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/_layout.svelte rename to packages/builder/src/pages/[application]/design/_layout.svelte diff --git a/packages/builder/src/pages/[application]/frontend/index.svelte b/packages/builder/src/pages/[application]/design/index.svelte similarity index 100% rename from packages/builder/src/pages/[application]/frontend/index.svelte rename to packages/builder/src/pages/[application]/design/index.svelte diff --git a/packages/builder/src/pages/[application]/index.svelte b/packages/builder/src/pages/[application]/index.svelte index 4b5dbb6a3e..553908cb2e 100644 --- a/packages/builder/src/pages/[application]/index.svelte +++ b/packages/builder/src/pages/[application]/index.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/yarn.lock b/packages/builder/yarn.lock index 5eca5c2364..41ea1e983b 100644 --- a/packages/builder/yarn.lock +++ b/packages/builder/yarn.lock @@ -718,10 +718,10 @@ svelte-flatpickr "^2.4.0" svelte-portal "^1.0.0" -"@budibase/client@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.2.4.tgz#da958faa50c59f6a9c41c692b7a19d6a6ea98bc1" - integrity sha512-MsFbWcsh3t1lyLgTb4UMccjshy6jd3A77lqs1CpXjHr+2LmXwvIriLgruycAvFrtqZzYG+dGe0rWwX0auwaaZw== +"@budibase/client@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.2.5.tgz#d4f451384e88277dad16069c1d4742d5010ac1c3" + integrity sha512-EFfy3g44fiHnzm/kqHskeXsbVXWHQbtKe4fPP0q+wwDkp1eP2ri9oJ3kMJg3A1SZPHFGmgeRvSMoLSux+7QhCw== dependencies: deep-equal "^2.0.1" mustache "^4.0.1" @@ -731,6 +731,13 @@ version "1.0.1" resolved "https://registry.yarnpkg.com/@budibase/colorpicker/-/colorpicker-1.0.1.tgz#940c180e7ebba0cb0756c4c8ef13f5dfab58e810" +"@budibase/svelte-ag-grid@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@budibase/svelte-ag-grid/-/svelte-ag-grid-0.0.13.tgz#cbb49e2c8770dd9de51bf222423d0dede3f39207" + integrity sha512-pLIUsbQ57gFQThu7/MwuPXPTI1AnDrEzw2IHeHvli4VKq7DYcXbkAFs6h8pDPvbFOC6LaiVjRCnsEpEQI1x7og== + dependencies: + ag-grid-community "^24.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1306,6 +1313,11 @@ acorn@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" +ag-grid-community@^24.0.0: + version "24.1.0" + resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-24.1.0.tgz#1e3cab51211822e08d56f03a491b7c0deaa398e6" + integrity sha512-pWnWphuDcejZ8ahf6C734EpCx3XQ6dHEZWMWTlCdHNT0mZBLJ4YKCGACX+ttAEtSX2MGM3G13JncvuratUlYag== + ajv@^6.5.5: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"