From dae550c21e00b4a97b74a137b743dc9c2fecc558 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 25 Oct 2024 16:24:40 +0100 Subject: [PATCH 01/20] Tidy up import data modal and change to be a detail popover --- .../DataTable/buttons/ImportButton.svelte | 92 ++++++++++-- .../DataTable/modals/ImportModal.svelte | 61 -------- .../TableNavigator/TableDataImport.svelte | 134 ++++++++---------- 3 files changed, 145 insertions(+), 142 deletions(-) delete mode 100644 packages/builder/src/components/backend/DataTable/modals/ImportModal.svelte diff --git a/packages/builder/src/components/backend/DataTable/buttons/ImportButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ImportButton.svelte index 88c57daa21..5e9850b290 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/ImportButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/ImportButton.svelte @@ -1,17 +1,91 @@ - - Import - - - - + + + + Import + + + + Import rows to an existing table from a CSV or JSON file. Only columns from + the file which exist in the table will be imported. + + + + + +
+ +
+
diff --git a/packages/builder/src/components/backend/DataTable/modals/ImportModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ImportModal.svelte deleted file mode 100644 index 1696c6ba03..0000000000 --- a/packages/builder/src/components/backend/DataTable/modals/ImportModal.svelte +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Import rows to an existing table from a CSV or JSON file. Only columns from - the file which exist in the table will be imported. - - - - - - diff --git a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte index 5804dc3172..7743762877 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableDataImport.svelte @@ -1,5 +1,5 @@ -
- - -
-{#if rawRows.length > 0 && !error} -
- {#each Object.entries(schema) as [name, column]} -
- {column.name} - +
-
+ + {#if rawRows.length > 0 && !error} +
+ {#each Object.entries(schema) as [name, column]} +
+ {column.name} + -
-{/if} + {/if} + From 271023823b351a9184dff90665a1773ba17277ac Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 25 Oct 2024 16:49:45 +0100 Subject: [PATCH 02/20] Tidy up export modal and update to be a detail popover --- .../DataTable/buttons/ExportButton.svelte | 144 +++++++++++- .../buttons/grid/GridExportButton.svelte | 28 +-- .../DataTable/modals/ExportModal.svelte | 217 ------------------ 3 files changed, 144 insertions(+), 245 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/buttons/ExportButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ExportButton.svelte index 4fa1d07abd..e9352045ea 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/ExportButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/ExportButton.svelte @@ -1,20 +1,144 @@ - - Export - - - - + + + + Export + + + + {#if selectedRows?.length} + + + {selectedRows?.length} + {`row${selectedRows?.length > 1 ? "s" : ""} will be exported.`} + + + {:else} + + + Exporting all rows. + + + {/if} + + x.name} - getOptionValue={x => x.key} - /> - - - - From 18130729b2e3fc75dd240ac3b4201c38ea878f58 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 28 Oct 2024 14:04:50 +0000 Subject: [PATCH 03/20] Remove old files --- .../DataTable/modals/ExportModal.svelte | 7 - .../DataTable/modals/ExportModal.test.js | 243 ------------------ 2 files changed, 250 deletions(-) delete mode 100644 packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte delete mode 100644 packages/builder/src/components/backend/DataTable/modals/ExportModal.test.js diff --git a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte deleted file mode 100644 index 12065412e7..0000000000 --- a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/packages/builder/src/components/backend/DataTable/modals/ExportModal.test.js b/packages/builder/src/components/backend/DataTable/modals/ExportModal.test.js deleted file mode 100644 index 4927f51a8d..0000000000 --- a/packages/builder/src/components/backend/DataTable/modals/ExportModal.test.js +++ /dev/null @@ -1,243 +0,0 @@ -import { it, expect, describe, vi } from "vitest" -import { render, screen } from "@testing-library/svelte" -import "@testing-library/jest-dom" - -import ExportModal from "./ExportModal.svelte" -import { utils } from "@budibase/shared-core" - -const labelLookup = utils.filterValueToLabel() - -const rowText = filter => { - let readableField = filter.field.split(":")[1] - let rowLabel = labelLookup[filter.operator] - let value = Array.isArray(filter.value) - ? JSON.stringify(filter.value) - : filter.value - return `${readableField}${rowLabel}${value}`.trim() -} - -const defaultFilters = [ - { - onEmptyFilter: "all", - }, -] - -vi.mock("svelte", async () => { - return { - getContext: () => { - return { - hide: vi.fn(), - cancel: vi.fn(), - } - }, - createEventDispatcher: vi.fn(), - onDestroy: vi.fn(), - tick: vi.fn(), - } -}) - -vi.mock("api", async () => { - return { - API: { - exportView: vi.fn(), - exportRows: vi.fn(), - }, - } -}) - -describe("Export Modal", () => { - it("show default messaging with no export config specified", () => { - render(ExportModal, { - props: {}, - }) - - expect(screen.getByTestId("export-all-rows")).toBeVisible() - expect(screen.getByTestId("export-all-rows")).toHaveTextContent( - "Exporting all rows" - ) - - expect(screen.queryByTestId("export-config-table")).toBe(null) - }) - - it("indicate that a filter is being applied to the export", () => { - const propsCfg = { - filters: [ - { - id: "MOQkMx9p9", - field: "1:Cost", - operator: "rangeHigh", - value: "100", - valueType: "Value", - type: "number", - noValue: false, - }, - ...defaultFilters, - ], - } - - render(ExportModal, { - props: propsCfg, - }) - - expect(propsCfg.filters[0].field).toBe("1:Cost") - - expect(screen.getByTestId("filters-applied")).toBeVisible() - expect(screen.getByTestId("filters-applied").textContent).toBe( - "Filters applied" - ) - - const ele = screen.queryByTestId("export-config-table") - expect(ele).toBeVisible() - - const rows = ele.getElementsByClassName("spectrum-Table-row") - - expect(rows.length).toBe(1) - let rowTextContent = rowText(propsCfg.filters[0]) - - //"CostLess than or equal to100" - expect(rows[0].textContent?.trim()).toEqual(rowTextContent) - }) - - it("Show only selected row messaging if rows are supplied", () => { - const propsCfg = { - filters: [ - { - id: "MOQkMx9p9", - field: "1:Cost", - operator: "rangeHigh", - value: "100", - valueType: "Value", - type: "number", - noValue: false, - }, - ...defaultFilters, - ], - sorting: { - sortColumn: "Cost", - sortOrder: "descending", - }, - selectedRows: [ - { - _id: "ro_ta_bb_expenses_57d5f6fe1b6640d8bb22b15f5eae62cd", - }, - { - _id: "ro_ta_bb_expenses_99ce5760a53a430bab4349cd70335a07", - }, - ], - } - - render(ExportModal, { - props: propsCfg, - }) - - expect(screen.queryByTestId("export-config-table")).toBeNull() - expect(screen.queryByTestId("filters-applied")).toBeNull() - - expect(screen.queryByTestId("exporting-n-rows")).toBeVisible() - expect(screen.queryByTestId("exporting-n-rows").textContent).toEqual( - "2 rows will be exported" - ) - }) - - it("Show only the configured sort when no filters are specified", () => { - const propsCfg = { - filters: [...defaultFilters], - sorting: { - sortColumn: "Cost", - sortOrder: "descending", - }, - } - render(ExportModal, { - props: propsCfg, - }) - - expect(screen.queryByTestId("export-config-table")).toBeVisible() - const ele = screen.queryByTestId("export-config-table") - const rows = ele.getElementsByClassName("spectrum-Table-row") - - expect(rows.length).toBe(1) - expect(rows[0].textContent?.trim()).toEqual( - `${propsCfg.sorting.sortColumn}Order By${propsCfg.sorting.sortOrder}` - ) - }) - - it("Display all currently configured filters and applied sort", () => { - const propsCfg = { - filters: [ - { - id: "MOQkMx9p9", - field: "1:Cost", - operator: "rangeHigh", - value: "100", - valueType: "Value", - type: "number", - noValue: false, - }, - { - id: "2ot-aB0gE", - field: "2:Expense Tags", - operator: "contains", - value: ["Equipment", "Services"], - valueType: "Value", - type: "array", - noValue: false, - }, - ...defaultFilters, - ], - sorting: { - sortColumn: "Payment Due", - sortOrder: "ascending", - }, - } - - render(ExportModal, { - props: propsCfg, - }) - - const ele = screen.queryByTestId("export-config-table") - expect(ele).toBeVisible() - - const rows = ele.getElementsByClassName("spectrum-Table-row") - expect(rows.length).toBe(3) - - let rowTextContent1 = rowText(propsCfg.filters[0]) - expect(rows[0].textContent?.trim()).toEqual(rowTextContent1) - - let rowTextContent2 = rowText(propsCfg.filters[1]) - expect(rows[1].textContent?.trim()).toEqual(rowTextContent2) - - expect(rows[2].textContent?.trim()).toEqual( - `${propsCfg.sorting.sortColumn}Order By${propsCfg.sorting.sortOrder}` - ) - }) - - it("show only the valid, configured download formats", () => { - const propsCfg = { - formats: ["badger", "json"], - } - - render(ExportModal, { - props: propsCfg, - }) - - let ele = screen.getByTestId("format-select") - expect(ele).toBeVisible() - - let formatDisplay = ele.getElementsByTagName("button")[0] - - expect(formatDisplay.textContent.trim()).toBe("JSON") - }) - - it("Load the default format config when no explicit formats are configured", () => { - render(ExportModal, { - props: {}, - }) - - let ele = screen.getByTestId("format-select") - expect(ele).toBeVisible() - - let formatDisplay = ele.getElementsByTagName("button")[0] - - expect(formatDisplay.textContent.trim()).toBe("CSV") - }) -}) From 4979cce1322c902fb2b24ca4bdcef0aa7abfcf45 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 28 Oct 2024 14:05:02 +0000 Subject: [PATCH 04/20] Udpate sort button to be a detail popover --- .../buttons/grid/GridSortButton.svelte | 79 ++++++++----------- 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/buttons/grid/GridSortButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/grid/GridSortButton.svelte index 4591b22b78..e86742e573 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/grid/GridSortButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/grid/GridSortButton.svelte @@ -1,12 +1,12 @@ -
- (open = !open)} - selected={open} - disabled={!columnOptions.length} - > - Sort - -
- - -
+ + + + Sort + + + - {#if $sort.column} - - of - + of + - -
-{#if fileName && Object.keys(validation).length === 0} -

No valid fields, try another file

-{:else if rows.length > 0 && !error} -
- {#each Object.keys(validation) as name} -
- {name} - - {:else} -

Rows will be updated based on the table's primary key.

+ +
+ + + {#if fileName && Object.keys(validation).length === 0} +
No valid fields - please try another file.
+ {:else if fileName && rows.length > 0 && !error} +
+ {#each Object.keys(validation) as name} +
+ {name} + - -
+ + +
+ + +
+
{#if rawRows.length > 0 && !error}
diff --git a/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte b/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte index 8a5484e2b2..5596ade573 100644 --- a/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte +++ b/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte @@ -1,13 +1,7 @@