From 08ba1c8ccd0c2b45085fd60b2aaea5fa60907beb Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 27 Jul 2023 13:04:09 +0100 Subject: [PATCH 1/8] Added a simple histogram to the supported chart types --- .../new/_components/componentStructure.json | 10 +- packages/client/manifest.json | 186 ++++++++++++++++++ .../components/app/blocks/ChartBlock.svelte | 4 + .../app/charts/HistogramChart.svelte | 136 +++++++++++++ .../client/src/components/app/charts/index.js | 1 + 5 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 packages/client/src/components/app/charts/HistogramChart.svelte diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/componentStructure.json b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/componentStructure.json index de0270f6be..ee0f99a074 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/componentStructure.json +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/componentStructure.json @@ -75,6 +75,14 @@ { "name": "Chart", "icon": "GraphBarVertical", - "children": ["bar", "line", "area", "candlestick", "pie", "donut"] + "children": [ + "bar", + "line", + "area", + "candlestick", + "pie", + "donut", + "histogram" + ] } ] diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 1e4c443f06..934df9dacb 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -2212,6 +2212,147 @@ } ] }, + "histogram": { + "name": "Histogram Chart", + "description": "Histogram chart", + "icon": "Histogram", + "size": { + "width": 600, + "height": 400 + }, + "requiredAncestors": ["dataprovider"], + "settings": [ + { + "type": "text", + "label": "Title", + "key": "title" + }, + { + "type": "dataProvider", + "label": "Provider", + "key": "dataProvider", + "required": true + }, + { + "type": "field", + "label": "Data column", + "key": "valueColumn", + "dependsOn": "dataProvider", + "required": true + }, + { + "type": "text", + "label": "Y axis label", + "key": "yAxisLabel", + "defaultValue": "Frequency" + }, + { + "type": "text", + "label": "X axis label", + "key": "xAxisLabel" + }, + { + "type": "number", + "label": "Bucket count", + "key": "bucketCount", + "defaultValue": 10, + "min": 2 + }, + { + "type": "boolean", + "label": "Data labels", + "key": "dataLabels", + "defaultValue": false + }, + { + "type": "text", + "label": "Width", + "key": "width" + }, + { + "type": "text", + "label": "Height", + "key": "height", + "defaultValue": "400" + }, + { + "type": "select", + "label": "Colors", + "key": "palette", + "defaultValue": "Palette 1", + "options": [ + "Custom", + "Palette 1", + "Palette 2", + "Palette 3", + "Palette 4", + "Palette 5", + "Palette 6", + "Palette 7", + "Palette 8", + "Palette 9", + "Palette 10" + ] + }, + { + "type": "color", + "label": "C1", + "key": "c1", + "dependsOn": { + "setting": "palette", + "value": "Custom" + } + }, + { + "type": "color", + "label": "C2", + "key": "c2", + "dependsOn": { + "setting": "palette", + "value": "Custom" + } + }, + { + "type": "color", + "label": "C3", + "key": "c3", + "dependsOn": { + "setting": "palette", + "value": "Custom" + } + }, + { + "type": "color", + "label": "C4", + "key": "c4", + "dependsOn": { + "setting": "palette", + "value": "Custom" + } + }, + { + "type": "color", + "label": "C5", + "key": "c5", + "dependsOn": { + "setting": "palette", + "value": "Custom" + } + }, + { + "type": "boolean", + "label": "Animate", + "key": "animate", + "defaultValue": true + }, + { + "type": "boolean", + "label": "Horizontal", + "key": "horizontal", + "defaultValue": false + } + ] + }, "form": { "name": "Form", "icon": "Form", @@ -3965,6 +4106,10 @@ "label": "Bar", "value": "bar" }, + { + "label": "Histogram", + "value": "histogram" + }, { "label": "Line", "value": "line" @@ -4215,6 +4360,47 @@ } ] }, + { + "section": true, + "name": "Histogram Chart", + "icon": "Histogram", + "dependsOn": { + "setting": "chartType", + "value": "histogram" + }, + "settings": [ + { + "type": "field", + "label": "Value column", + "key": "valueColumn", + "dependsOn": "dataSource", + "required": true + }, + { + "type": "text", + "label": "Y axis label", + "key": "yAxisLabel" + }, + { + "type": "text", + "label": "X axis label", + "key": "xAxisLabel" + }, + { + "type": "boolean", + "label": "Horizontal", + "key": "horizontal", + "defaultValue": false + }, + { + "type": "number", + "label": "Bucket count", + "key": "bucketCount", + "defaultValue": 10, + "min": 2 + } + ] + }, { "section": true, "name": "Line Chart", diff --git a/packages/client/src/components/app/blocks/ChartBlock.svelte b/packages/client/src/components/app/blocks/ChartBlock.svelte index 92151ad9c0..1bbc69ce63 100644 --- a/packages/client/src/components/app/blocks/ChartBlock.svelte +++ b/packages/client/src/components/app/blocks/ChartBlock.svelte @@ -46,6 +46,9 @@ export let lowColumn export let dateColumn + // Histogram + export let bucketCount + let dataProviderId $: colors = c1 && c2 && c3 && c4 && c5 ? [c1, c2, c3, c4, c5] : null @@ -92,6 +95,7 @@ highColumn, lowColumn, dateColumn, + bucketCount, }} /> {/if} diff --git a/packages/client/src/components/app/charts/HistogramChart.svelte b/packages/client/src/components/app/charts/HistogramChart.svelte new file mode 100644 index 0000000000..26b9028550 --- /dev/null +++ b/packages/client/src/components/app/charts/HistogramChart.svelte @@ -0,0 +1,136 @@ + + + diff --git a/packages/client/src/components/app/charts/index.js b/packages/client/src/components/app/charts/index.js index b1fea9ef0d..e428b4eecf 100644 --- a/packages/client/src/components/app/charts/index.js +++ b/packages/client/src/components/app/charts/index.js @@ -4,3 +4,4 @@ export { default as pie } from "./PieChart.svelte" export { default as donut } from "./DonutChart.svelte" export { default as area } from "./AreaChart.svelte" export { default as candlestick } from "./CandleStickChart.svelte" +export { default as histogram } from "./HistogramChart.svelte" From 45c35c5c452fd36c7bb89494ed6e1bf8cc75b3d1 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 31 Jul 2023 09:56:30 +0000 Subject: [PATCH 2/8] Bump version to 2.8.29-alpha.4 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index fb1b966db4..54141fa843 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.8.29-alpha.3", + "version": "2.8.29-alpha.4", "npmClient": "yarn", "packages": [ "packages/*" From c0c5a57a993d0a9ece3616d4be0dd7e38bf6669e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 31 Jul 2023 11:50:42 +0100 Subject: [PATCH 3/8] Supress notification from form block delete row action if configured --- packages/client/manifest.json | 6 +----- .../src/components/app/blocks/form/InnerFormBlock.svelte | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 934df9dacb..b6a231917c 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -5420,11 +5420,7 @@ "type": "boolean", "label": "Hide notifications", "key": "notificationOverride", - "defaultValue": false, - "dependsOn": { - "setting": "showSaveButton", - "value": true - } + "defaultValue": false } ] } diff --git a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte index 5e4a156949..c638d58737 100644 --- a/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte +++ b/packages/client/src/components/app/blocks/form/InnerFormBlock.svelte @@ -83,6 +83,7 @@ tableId: dataSource?.tableId, rowId: `{{ ${safe(repeaterId)}.${safe("_id")} }}`, revId: `{{ ${safe(repeaterId)}.${safe("_rev")} }}`, + notificationOverride, }, }, { From 9314a85220c9d309f860826550d6a6e8b25f257f Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 31 Jul 2023 10:51:05 +0000 Subject: [PATCH 4/8] Bump version to 2.8.29-alpha.5 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 54141fa843..ea9e35877b 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.8.29-alpha.4", + "version": "2.8.29-alpha.5", "npmClient": "yarn", "packages": [ "packages/*" From 2ee7cb008b4f3dca7e42572c04f2d60bfb8a0680 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 31 Jul 2023 15:28:11 +0100 Subject: [PATCH 5/8] Reworked Column Configuration in the data section (#11379) * base work for using popover to create and edit columns * more work to enable editing column in popover * update styling of column type configs * add new option picker component * some updates to how the popover is opened and the new picker * more updates to support the popover handling correctly * update the popover to support a custom z index * some styling around the colour picker * update naming * fix lint errors * fix lint * update filename * incremental column numbers based on existing schema * move func declaration * add option color object to schema not constraints * ux / pr comment updates * undefined var * fix issue with deleting option * change background color * update popove z-index --- packages/bbui/package.json | 3 +- .../bbui/src/IconPicker/IconPicker.svelte | 1 - .../OptionSelectDnD/OptionSelectDnD.svelte | 252 +++++++++++++++++ packages/bbui/src/Popover/Popover.svelte | 8 +- packages/bbui/src/index.js | 2 +- .../backend/DataTable/DataTable.svelte | 10 +- .../DataTable/modals/CreateEditColumn.svelte | 265 +++++++++++------- .../modals/grid/GridCreateColumnModal.svelte | 13 +- .../modals/grid/GridEditColumnModal.svelte | 13 +- .../builder/src/constants/backend/index.js | 13 + .../components/grid/cells/HeaderCell.svelte | 131 +++++---- .../components/grid/cells/OptionsCell.svelte | 5 +- .../src/components/grid/layout/Grid.svelte | 15 +- .../components/grid/layout/HeaderRow.svelte | 55 +--- .../grid/layout/NewColumnButton.svelte | 79 ++++++ .../grid/layout/StickyColumn.svelte | 4 +- 16 files changed, 643 insertions(+), 226 deletions(-) create mode 100644 packages/bbui/src/OptionSelectDnD/OptionSelectDnD.svelte create mode 100644 packages/frontend-core/src/components/grid/layout/NewColumnButton.svelte diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 4d39f6330b..e5d0ad6b57 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -85,7 +85,8 @@ "dayjs": "^1.10.4", "easymde": "^2.16.1", "svelte-flatpickr": "3.2.3", - "svelte-portal": "^1.0.0" + "svelte-portal": "^1.0.0", + "svelte-dnd-action": "^0.9.8" }, "resolutions": { "loader-utils": "1.4.1" diff --git a/packages/bbui/src/IconPicker/IconPicker.svelte b/packages/bbui/src/IconPicker/IconPicker.svelte index 2b42da61b1..b3cc72daa3 100644 --- a/packages/bbui/src/IconPicker/IconPicker.svelte +++ b/packages/bbui/src/IconPicker/IconPicker.svelte @@ -1,5 +1,4 @@ + +
+
+ {#each options as option, idx (option.id)} +
+
+ +
+
+
openColorPickerPopover(idx, e.target)} + > + +
+ {#each colorsArray as color} +
handleColorChange(option.name, color, idx)} + style="--color:{color};" + class="circle circle-hover" + /> + {/each} +
+ +
+
+
+ handleNameChange(option.name, idx, e.target.value)} + value={option.name} + placeholder="Option name" + /> +
+
+ +
+
+ {/each} +
+
+ +
Add option
+
+
+ + diff --git a/packages/bbui/src/Popover/Popover.svelte b/packages/bbui/src/Popover/Popover.svelte index 9f951a6a7e..6706bf7a8b 100644 --- a/packages/bbui/src/Popover/Popover.svelte +++ b/packages/bbui/src/Popover/Popover.svelte @@ -21,6 +21,7 @@ export let offset = 5 export let customHeight export let animate = true + export let customZindex $: target = portalTarget || getContext(Context.PopoverRoot) || ".spectrum" @@ -77,8 +78,9 @@ }} on:keydown={handleEscape} class="spectrum-Popover is-open" + class:customZindex role="presentation" - style="height: {customHeight}" + style="height: {customHeight}; --customZindex: {customZindex};" transition:fly|local={{ y: -20, duration: animate ? 200 : 0 }} > @@ -92,4 +94,8 @@ border-color: var(--spectrum-global-color-gray-300); overflow: auto; } + + .customZindex { + z-index: var(--customZindex) !important; + } diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 97762d2b3a..cda6b5acbf 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -84,7 +84,7 @@ export { default as IconSideNavItem } from "./IconSideNav/IconSideNavItem.svelte export { default as Slider } from "./Form/Slider.svelte" export { default as Accordion } from "./Accordion/Accordion.svelte" export { default as File } from "./Form/File.svelte" - +export { default as OptionSelectDnD } from "./OptionSelectDnD/OptionSelectDnD.svelte" // Renderers export { default as BoldRenderer } from "./Table/BoldRenderer.svelte" export { default as CodeRenderer } from "./Table/CodeRenderer.svelte" diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/DataTable.svelte index d4c994dae5..38eb87aa73 100644 --- a/packages/builder/src/components/backend/DataTable/DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/DataTable.svelte @@ -64,6 +64,13 @@ + + + + + + + {#if isInternal} @@ -77,9 +84,8 @@ {:else} {/if} + - - {#if isUsersTable} {:else} diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 4761ccee02..7c3e13f39a 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -7,12 +7,12 @@ Toggle, RadioGroup, DatePicker, - ModalContent, - Context, Modal, notifications, + OptionSelectDnD, + Layout, } from "@budibase/bbui" - import { createEventDispatcher } from "svelte" + import { createEventDispatcher, getContext } from "svelte" import { cloneDeep } from "lodash/fp" import { tables, datasources } from "stores/backend" import { TableNames, UNEDITABLE_USER_FIELDS } from "constants" @@ -26,12 +26,10 @@ SWITCHABLE_TYPES, } from "constants/backend" import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils" - import ValuesList from "components/common/ValuesList.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte" import { truncate } from "lodash" import ModalBindableInput from "components/common/bindings/ModalBindableInput.svelte" import { getBindings } from "components/backend/DataTable/formula" - import { getContext } from "svelte" import JSONSchemaModal from "./JSONSchemaModal.svelte" import { ValidColumnNameRegex } from "@budibase/shared-core" @@ -45,11 +43,11 @@ const dispatch = createEventDispatcher() const PROHIBITED_COLUMN_NAMES = ["type", "_id", "_rev", "tableId"] - const { hide } = getContext(Context.Modal) - let fieldDefinitions = cloneDeep(FIELDS) + const { dispatch: gridDispatch } = getContext("grid") export let field + let fieldDefinitions = cloneDeep(FIELDS) let originalName let linkEditDisabled let primaryDisplay @@ -61,11 +59,10 @@ let savingColumn let deleteColName let jsonSchemaModal - + let allowedTypes = [] let editableColumn = { type: "string", constraints: fieldDefinitions.STRING.constraints, - // Initial value for column name in other table for linked records fieldName: $tables.selected.name, } @@ -83,7 +80,23 @@ primaryDisplay = $tables.selected.primaryDisplay == null || $tables.selected.primaryDisplay === editableColumn.name + } else if (!savingColumn) { + let highestNumber = 0 + Object.keys(table.schema).forEach(columnName => { + const columnNumber = extractColumnNumber(columnName) + if (columnNumber > highestNumber) { + highestNumber = columnNumber + } + return highestNumber + }) + + if (highestNumber >= 1) { + editableColumn.name = `Column 0${highestNumber + 1}` + } else { + editableColumn.name = "Column 01" + } } + allowedTypes = getAllowedTypes() } $: initialiseField(field, savingColumn) @@ -182,6 +195,8 @@ indexes, }) dispatch("updatecolumns") + gridDispatch("close-edit-column") + if ( saveColumn.type === LINK_TYPE && saveColumn.relationshipType === RelationshipType.MANY_TO_MANY @@ -203,6 +218,7 @@ function cancelEdit() { editableColumn.name = originalName + gridDispatch("close-edit-column") } async function deleteColumn() { @@ -214,8 +230,8 @@ await tables.deleteField(editableColumn) notifications.success(`Column ${editableColumn.name} deleted`) confirmDeleteDialog.hide() - hide() dispatch("updatecolumns") + gridDispatch("close-edit-column") } } catch (error) { notifications.error(`Error deleting column: ${error.message}`) @@ -251,14 +267,6 @@ required = req } - function onChangePrimaryDisplay(e) { - const isPrimary = e.detail - // primary display is always required - if (isPrimary) { - editableColumn.constraints.presence = { allowEmpty: false } - } - } - function openJsonSchemaEditor() { jsonSchemaModal.show() } @@ -272,6 +280,11 @@ deleteColName = "" } + function extractColumnNumber(columnName) { + const match = columnName.match(/Column (\d+)/) + return match ? parseInt(match[1]) : 0 + } + function getRelationshipOptions(field) { if (!field || !field.tableId) { return null @@ -402,15 +415,8 @@ } - + field.name} getOptionValue={field => field.type} + getOptionIcon={field => field.icon} isOptionEnabled={option => { if (option.type == AUTO_TYPE) { return availableAutoColumnKeys?.length > 0 @@ -433,28 +439,6 @@ }} /> - {#if canBeRequired || canBeDisplay} -
- {#if canBeRequired} - - {/if} - {#if canBeDisplay} - - {/if} -
- {/if} - {#if editableColumn.type === "string"} {:else if editableColumn.type === "options"} - {:else if editableColumn.type === "longform"}
@@ -480,19 +464,28 @@ />
{:else if editableColumn.type === "array"} - {:else if editableColumn.type === "datetime" && !editableColumn.autocolumn} - - +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
{#if datasource?.source !== "ORACLE" && datasource?.source !== "SQL_SERVER"}