From afffd4d234d551a50d1c1b41977bf8db87242a3d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 2 Nov 2023 15:37:18 +0000 Subject: [PATCH 001/296] Add initial version of new date picker without time support --- packages/bbui/package.json | 1 + .../bbui/src/Form/Core/BBDatePicker.svelte | 313 ++++++++++++++++++ packages/bbui/src/index.js | 1 + .../pages/builder/portal/apps/index.svelte | 31 ++ yarn.lock | 5 + 5 files changed, 351 insertions(+) create mode 100644 packages/bbui/src/Form/Core/BBDatePicker.svelte diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 78eed2b608..ccc59646b4 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -44,6 +44,7 @@ "@spectrum-css/avatar": "3.0.2", "@spectrum-css/button": "3.0.1", "@spectrum-css/buttongroup": "3.0.2", + "@spectrum-css/calendar": "3.0.2", "@spectrum-css/checkbox": "3.0.2", "@spectrum-css/dialog": "3.0.1", "@spectrum-css/divider": "1.0.3", diff --git a/packages/bbui/src/Form/Core/BBDatePicker.svelte b/packages/bbui/src/Form/Core/BBDatePicker.svelte new file mode 100644 index 0000000000..d159b3dcd6 --- /dev/null +++ b/packages/bbui/src/Form/Core/BBDatePicker.svelte @@ -0,0 +1,313 @@ + + +
+
+ {#if !!error} + + {/if} + +
+ +
+ + +
+
+
+ {activeMonth.format("MMMM YYYY")} +
+ + +
+
+ + + + {#each DaysOfWeek as day} + + {/each} + + + + {#each mondays as monday} + + {#each [0, 1, 2, 3, 4, 5, 6] as dayOffset} + {@const date = monday.add(dayOffset, "days")} + {@const outsideMonth = date.month() !== activeMonth.month()} + + {/each} + + {/each} + + +
+
+
+ + diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index cda6b5acbf..407a8c2cec 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -54,6 +54,7 @@ export { default as Notification } from "./Notification/Notification.svelte" export { default as SideNavigation } from "./SideNavigation/Navigation.svelte" export { default as SideNavigationItem } from "./SideNavigation/Item.svelte" export { default as DatePicker } from "./Form/DatePicker.svelte" +export { default as BBDatePicker } from "./Form/Core/BBDatePicker.svelte" export { default as Multiselect } from "./Form/Multiselect.svelte" export { default as Context } from "./context" export { default as Table } from "./Table/Table.svelte" diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 59267f37e7..828e620dba 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -10,6 +10,8 @@ Notification, Body, Search, + DatePicker, + BBDatePicker, } from "@budibase/bbui" import Spinner from "components/common/Spinner.svelte" import CreateAppModal from "components/start/CreateAppModal.svelte" @@ -202,9 +204,38 @@ notifications.error("Error getting init info") } }) + + let foo = "2023-11-14T15:00:00" +
+

Date only

+
+ (foo = e.detail)} + /> +
+

Date time

+
+ (foo = e.detail)} /> +
+

Date time no timezone

+
+ (foo = e.detail)} + /> +
+
+
+
+
+ {#each Object.keys(automationErrors || {}) as appId} Date: Thu, 2 Nov 2023 17:20:36 +0000 Subject: [PATCH 002/296] Add editable month and year picker to calendar --- packages/bbui/src/Actions/click_outside.js | 15 +-- .../bbui/src/Form/Core/BBDatePicker.svelte | 101 ++++++++++++++++-- .../pages/builder/portal/apps/index.svelte | 1 + 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.js index 1961dca47c..e2cf38953c 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.js @@ -1,8 +1,4 @@ -const ignoredClasses = [ - ".flatpickr-calendar", - ".spectrum-Popover", - ".download-js-link", -] +const ignoredClasses = [".flatpickr-calendar", ".download-js-link"] let clickHandlers = [] /** @@ -25,7 +21,14 @@ const handleClick = event => { return } - // Ignore clicks for modals, unless the handler is registered from a modal + // Ignore clicks for popovers, unless the handler is registered from one + const sourceInPopover = handler.anchor.closest(".spectrum-Popover") != null + const clickInPopover = event.target.closest(".spectrum-Popover") != null + if (clickInPopover && !sourceInPopover) { + return + } + + // Ignore clicks for modals, unless the handler is registered from one const sourceInModal = handler.anchor.closest(".spectrum-Underlay") != null const clickInModal = event.target.closest(".spectrum-Underlay") != null if (clickInModal && !sourceInModal) { diff --git a/packages/bbui/src/Form/Core/BBDatePicker.svelte b/packages/bbui/src/Form/Core/BBDatePicker.svelte index d159b3dcd6..7163314246 100644 --- a/packages/bbui/src/Form/Core/BBDatePicker.svelte +++ b/packages/bbui/src/Form/Core/BBDatePicker.svelte @@ -6,6 +6,7 @@ import Popover from "../../Popover/Popover.svelte" import dayjs from "dayjs" import { createEventDispatcher } from "svelte" + import Select from "../Select.svelte" export let id = null export let disabled = false @@ -30,22 +31,40 @@ "Saturday", "Sunday", ] + const MonthsOfYear = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ] let isOpen = false let anchor let calendar let today = dayjs() - let activeMonth + let calendarDate $: parsedValue = parseValue(value) $: displayValue = getDisplayValue(parsedValue) - $: activeMonth = dayjs(parsedValue || today).startOf("month") - $: mondays = getMondays(activeMonth) + $: calendarDate = dayjs(parsedValue || today).startOf("month") + $: mondays = getMondays(calendarDate) const clearDateOnBackspace = event => { + // Ignore if we're typing a value + if (document.activeElement?.tagName.toLowerCase() === "input") { + return + } if (["Backspace", "Clear", "Delete"].includes(event.key)) { handleChange(null) - calendar.hide() + calendar?.hide() } } @@ -129,6 +148,17 @@ dispatch("change", newValue) } + + const handleYearChange = e => { + let year = parseInt(e.target.value) + if (isNaN(year)) { + year = calendarDate.year() + } else { + year = Math.max(0, Math.min(9999, year)) + } + e.target.value = year + calendarDate = calendarDate.year(year) + }
- {activeMonth.format("MMMM YYYY")} +
+
From 1b5bb8dd044f19bbc15ac765265fd4a9f2b30271 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 2 Nov 2023 18:35:58 +0000 Subject: [PATCH 003/296] Add style improvements to new date picker --- packages/bbui/src/Form/Core/BBDatePicker.svelte | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/bbui/src/Form/Core/BBDatePicker.svelte b/packages/bbui/src/Form/Core/BBDatePicker.svelte index 7163314246..8c99caea36 100644 --- a/packages/bbui/src/Form/Core/BBDatePicker.svelte +++ b/packages/bbui/src/Form/Core/BBDatePicker.svelte @@ -69,6 +69,7 @@ } const onOpen = () => { + calendarDate = dayjs(parsedValue || today).startOf("month") isOpen = true if (useKeyboardShortcuts) { document.addEventListener("keyup", clearDateOnBackspace) @@ -307,13 +308,13 @@ aria-selected="false" aria-invalid="false" title={date.format("dddd, MMMM D, YYYY")} - on:click={outsideMonth ? null : handleChange(date)} + on:click={() => handleChange(date)} > {date.date()} @@ -350,9 +351,6 @@ .spectrum-Calendar { padding: 8px; } - .is-outsideMonth { - pointer-events: none; - } .spectrum-Calendar-title { display: flex; justify-content: center; @@ -362,6 +360,10 @@ .spectrum-Calendar-header button { border-radius: 4px; } + .spectrum-Calendar-date.is-outsideMonth { + visibility: visible; + color: var(--spectrum-global-color-gray-400); + } .month-selector :global(.spectrum-Picker), .year-selector { @@ -377,6 +379,7 @@ font-family: var(--font-sans); } .month-selector :global(.spectrum-Picker:hover), + .month-selector :global(.spectrum-Picker.is-open), .year-selector:hover { background: var(--spectrum-global-color-gray-200); } From f078039aa4d7c962d67948ddaace7b7cf2bb17b9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 2 Nov 2023 20:34:40 +0000 Subject: [PATCH 004/296] Add time field and sanitise all typeable fields to prevent errors and improve experience --- .../bbui/src/Form/Core/BBDatePicker.svelte | 144 +++++++++++++++--- 1 file changed, 121 insertions(+), 23 deletions(-) diff --git a/packages/bbui/src/Form/Core/BBDatePicker.svelte b/packages/bbui/src/Form/Core/BBDatePicker.svelte index 8c99caea36..92dbb7f18e 100644 --- a/packages/bbui/src/Form/Core/BBDatePicker.svelte +++ b/packages/bbui/src/Form/Core/BBDatePicker.svelte @@ -7,6 +7,8 @@ import dayjs from "dayjs" import { createEventDispatcher } from "svelte" import Select from "../Select.svelte" + import Icon from "../../Icon/Icon.svelte" + import ActionButton from "../../ActionButton/ActionButton.svelte" export let id = null export let disabled = false @@ -150,16 +152,50 @@ dispatch("change", newValue) } - const handleYearChange = e => { - let year = parseInt(e.target.value) - if (isNaN(year)) { - year = calendarDate.year() - } else { - year = Math.max(0, Math.min(9999, year)) - } - e.target.value = year - calendarDate = calendarDate.year(year) + const handleMinuteChange = e => { + handleChange(parsedValue.minute(parseInt(e.target.value))) } + + const handleHourChange = e => { + handleChange(parsedValue.hour(parseInt(e.target.value))) + } + + const handleDateChange = date => { + // Select this date at midnight if no current date + if (!parsedValue) { + handleChange(date) + } + // Otherwise persist selected time + else { + handleChange( + parsedValue.year(date.year()).month(date.month()).date(date.date()) + ) + } + } + + const handleCalendarYearChange = e => { + calendarDate = calendarDate.year(parseInt(e.target.value)) + } + + const cleanNumber = ({ max, pad, fallback }) => { + return e => { + if (e.target.value) { + const value = parseInt(e.target.value) + if (isNaN(value)) { + e.target.value = fallback + } else { + e.target.value = Math.min(max, value).toString().padStart(pad, "0") + } + } else { + e.target.value = fallback + } + } + } + + // Sanitization utils + const cleanYear = cleanNumber({ max: 9999, pad: 0, fallback: today.year() }) + const cleanHour = cleanNumber({ max: 23, pad: 2, fallback: "00" }) + const cleanMinute = cleanNumber({ max: 59, pad: 2, fallback: "00" })
+ {#if parsedValue && enableTime} +
+ + : + +
+ {/if} From de0f87fa324e4bf80c94cac5026f4dbd64f4a470 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 09:34:54 +0000 Subject: [PATCH 005/296] Break new datetime picker into granular components --- .../bbui/src/Form/Core/BBDatePicker.svelte | 493 ------------------ .../Form/Core/DateTimePicker/Calendar.svelte | 206 ++++++++ .../Core/DateTimePicker/DateTimeField.svelte | 98 ++++ .../Core/DateTimePicker/DateTimePicker.svelte | 170 ++++++ .../Core/DateTimePicker/TimePicker.svelte | 65 +++ .../src/Form/Core/DateTimePicker/utils.js | 14 + packages/bbui/src/index.js | 2 +- .../pages/builder/portal/apps/index.svelte | 16 +- 8 files changed, 566 insertions(+), 498 deletions(-) delete mode 100644 packages/bbui/src/Form/Core/BBDatePicker.svelte create mode 100644 packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte create mode 100644 packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte create mode 100644 packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte create mode 100644 packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte create mode 100644 packages/bbui/src/Form/Core/DateTimePicker/utils.js diff --git a/packages/bbui/src/Form/Core/BBDatePicker.svelte b/packages/bbui/src/Form/Core/BBDatePicker.svelte deleted file mode 100644 index 92dbb7f18e..0000000000 --- a/packages/bbui/src/Form/Core/BBDatePicker.svelte +++ /dev/null @@ -1,493 +0,0 @@ - - -
-
- {#if !!error} - - {/if} - -
- -
- - -
-
-
-
- -
- - -
-
- - - - {#each DaysOfWeek as day} - - {/each} - - - - {#each mondays as monday} - - {#each [0, 1, 2, 3, 4, 5, 6] as dayOffset} - {@const date = monday.add(dayOffset, "days")} - {@const outsideMonth = date.month() !== calendarDate.month()} - - {/each} - - {/each} - - -
-
- {#if parsedValue && enableTime} -
- - : - -
- {/if} - - - diff --git a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte new file mode 100644 index 0000000000..f943a63254 --- /dev/null +++ b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte @@ -0,0 +1,206 @@ + + +
+
+
+
+ +
+ + +
+
+ + + + {#each DaysOfWeek as day} + + {/each} + + + + {#each mondays as monday} + + {#each [0, 1, 2, 3, 4, 5, 6] as dayOffset} + {@const date = monday.add(dayOffset, "days")} + {@const outsideMonth = date.month() !== calendarDate.month()} + + {/each} + + {/each} + + +
+
+ + diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte b/packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte new file mode 100644 index 0000000000..cf7d141109 --- /dev/null +++ b/packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte @@ -0,0 +1,98 @@ + + +
+
+ {#if !!error} + + {/if} + +
+ +
+ + diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte new file mode 100644 index 0000000000..a0e51a38fb --- /dev/null +++ b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte @@ -0,0 +1,170 @@ + + + + + + {#if isOpen} +
+ {#if showCalendar} + + {/if} + {#if showCalendar && showTime} +
+ {/if} + {#if showTime} + + {/if} +
+ {/if} +
+ + diff --git a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte new file mode 100644 index 0000000000..60e1f313dc --- /dev/null +++ b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte @@ -0,0 +1,65 @@ + + +
+ + : + +
+ + diff --git a/packages/bbui/src/Form/Core/DateTimePicker/utils.js b/packages/bbui/src/Form/Core/DateTimePicker/utils.js new file mode 100644 index 0000000000..953c3eb6c0 --- /dev/null +++ b/packages/bbui/src/Form/Core/DateTimePicker/utils.js @@ -0,0 +1,14 @@ +export const cleanInput = ({ max, pad, fallback }) => { + return e => { + if (e.target.value) { + const value = parseInt(e.target.value) + if (isNaN(value)) { + e.target.value = fallback + } else { + e.target.value = Math.min(max, value).toString().padStart(pad, "0") + } + } else { + e.target.value = fallback + } + } +} diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 407a8c2cec..689cde05d7 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -54,7 +54,7 @@ export { default as Notification } from "./Notification/Notification.svelte" export { default as SideNavigation } from "./SideNavigation/Navigation.svelte" export { default as SideNavigationItem } from "./SideNavigation/Item.svelte" export { default as DatePicker } from "./Form/DatePicker.svelte" -export { default as BBDatePicker } from "./Form/Core/BBDatePicker.svelte" +export { default as DateTimePicker } from "./Form/Core/DateTimePicker/DateTimePicker.svelte" export { default as Multiselect } from "./Form/Multiselect.svelte" export { default as Context } from "./context" export { default as Table } from "./Table/Table.svelte" diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 5fca9fb189..dbe4b9626d 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -11,7 +11,7 @@ Body, Search, DatePicker, - BBDatePicker, + DateTimePicker, } from "@budibase/bbui" import Spinner from "components/common/Spinner.svelte" import CreateAppModal from "components/start/CreateAppModal.svelte" @@ -212,7 +212,7 @@

Date only

- (foo = e.detail)} @@ -220,17 +220,25 @@

Date time

- (foo = e.detail)} /> + (foo = e.detail)} + />

Date time no timezone

- (foo = e.detail)} />
+

Time only

+
+ (foo = e.detail)} /> +



From a6bda4fce7aacf66a8f0d0712964615ce56d1cfd Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 09:35:24 +0000 Subject: [PATCH 006/296] Remove unused props --- .../bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte index a0e51a38fb..87fbe9f70b 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte @@ -14,8 +14,6 @@ export let placeholder = null export let timeOnly = false export let ignoreTimezones = false - export let range = false - export let flatpickr export let useKeyboardShortcuts = true const dispatch = createEventDispatcher() From 819df964bc59db0ae2ec026a44153a6efd917e08 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 11:18:03 +0000 Subject: [PATCH 007/296] Fix style issues in client apps and remove extraneous dependencies --- packages/bbui/package.json | 2 +- .../Form/Core/DateTimePicker/Calendar.svelte | 16 ++++++- .../Core/DateTimePicker/DateTimeField.svelte | 12 +++--- .../Core/DateTimePicker/DateTimePicker.svelte | 3 ++ packages/client/package.json | 9 +--- yarn.lock | 42 +++---------------- 6 files changed, 30 insertions(+), 54 deletions(-) diff --git a/packages/bbui/package.json b/packages/bbui/package.json index ccc59646b4..3601af74e9 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -44,7 +44,7 @@ "@spectrum-css/avatar": "3.0.2", "@spectrum-css/button": "3.0.1", "@spectrum-css/buttongroup": "3.0.2", - "@spectrum-css/calendar": "3.0.2", + "@spectrum-css/calendar": "3.2.7", "@spectrum-css/checkbox": "3.0.2", "@spectrum-css/dialog": "3.0.1", "@spectrum-css/divider": "1.0.3", diff --git a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte index f943a63254..f8386fe6da 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte @@ -1,5 +1,4 @@ + + + + diff --git a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte index 60e1f313dc..a062c4ce0b 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte @@ -1,6 +1,7 @@
- : - @@ -45,7 +46,6 @@ diff --git a/packages/client/src/components/app/forms/NewDateTimeField.svelte b/packages/client/src/components/app/forms/NewDateTimeField.svelte new file mode 100644 index 0000000000..6bcd20d250 --- /dev/null +++ b/packages/client/src/components/app/forms/NewDateTimeField.svelte @@ -0,0 +1,53 @@ + + + + {#if fieldState} + + {/if} + From 96bc6fc789521b536e6a128da7a1f1acdb81452f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 17:05:27 +0000 Subject: [PATCH 009/296] Add better support for time only date strings --- .../Form/Core/DateTimePicker/DateTimePicker.svelte | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte index b04ae3cdb6..3ae2571166 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte @@ -56,8 +56,17 @@ } const parseValue = value => { - // Sanity check that we have a valid value - const parsedDate = dayjs(value) + let parsedDate + + // Attempt to parse as a time-only string if required + if (typeof value === "string" && timeOnly) { + parsedDate = dayjs(`0-${value}`) + } + + // Attempt to parse as normal if required + if (!parsedDate?.isValid()) { + parsedDate = dayjs(value) + } if (!parsedDate?.isValid()) { return null } From 93630b36e2a57b83d197c65d816d42eed849f2e1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 17:07:31 +0000 Subject: [PATCH 010/296] Fix small inconsistency when picker is open for multiple minutes --- packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte | 2 +- packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte index d48afa1f35..ae32190e2e 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte @@ -34,7 +34,7 @@ const now = dayjs() let calendarDate - $: calendarDate = dayjs(value || now).startOf("month") + $: calendarDate = dayjs(value || dayjs()).startOf("month") $: mondays = getMondays(calendarDate) const getMondays = monthStart => { diff --git a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte index a062c4ce0b..adf2a5e87a 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte @@ -6,9 +6,7 @@ export let value export let onChange - const now = dayjs() - - $: displayValue = value || now + $: displayValue = value || dayjs() const handleHourChange = e => { onChange(displayValue.hour(parseInt(e.target.value))) From e758582822f474aa7e2c3112fd34a8f022952b00 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 19:26:43 +0000 Subject: [PATCH 011/296] Add cross browser style improvements for datepicker --- .../Form/Core/DateTimePicker/Calendar.svelte | 13 ++++++++++--- .../Core/DateTimePicker/DateTimePicker.svelte | 18 ++++++++++++++---- .../Core/DateTimePicker/NumberInput.svelte | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte index ae32190e2e..6491ba94ab 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte @@ -61,6 +61,10 @@ onChange(base.year(date.year()).month(date.month()).date(date.date())) } + export const setDate = date => { + calendarDate = date + } + const cleanYear = cleanInput({ max: 9999, pad: 0, fallback: now.year() }) @@ -85,6 +89,7 @@ value={calendarDate.year()} min={0} max={9999} + width={64} on:change={handleCalendarYearChange} on:input={cleanYear} /> @@ -173,6 +178,9 @@ .spectrum-Calendar { width: auto; } + .spectrum-Calendar-header { + width: auto; + } .spectrum-Calendar-title { display: flex; justify-content: flex-start; @@ -196,12 +204,11 @@ background: var(--spectrum-global-color-blue-400); } .spectrum-Calendar tr { + box-sizing: content-box; height: 40px; } .spectrum-Calendar-tableCell { - height: 32px; - width: 32px; - padding: 4px; + box-sizing: content-box; } .spectrum-Calendar-nextMonth, .spectrum-Calendar-prevMonth { diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte index 3ae2571166..cccfea612c 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte @@ -25,6 +25,7 @@ let isOpen = false let anchor let popover + let calendar $: parsedValue = parseValue(value) $: showCalendar = !timeOnly @@ -107,6 +108,12 @@ dispatch("change", newValue) } + + const setToNow = () => { + const now = dayjs() + calendar?.setDate(now) + handleChange(now) + } {#if showCalendar} - + {/if} @@ -164,7 +175,7 @@ display: flex; justify-content: space-between; align-items: center; - gap: 32px; + gap: 60px; } .footer.spaced { padding-top: 14px; @@ -175,6 +186,5 @@ display: flex; justify-content: flex-end; gap: 6px; - margin-right: 4px; } diff --git a/packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte b/packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte index 5b7c6dccce..8d7c72e94e 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte +++ b/packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte @@ -34,6 +34,7 @@ font-weight: bold; font-family: var(--font-sans); -webkit-font-smoothing: antialiased; + box-sizing: content-box; } input:focus, input:hover { From 78af50bafe9956793ace3f78c3aa77a9f367879b Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 19:34:12 +0000 Subject: [PATCH 012/296] Use new datepicker except when a range is needed --- .../Calendar.svelte | 0 .../DateInput.svelte} | 0 .../Form/Core/DatePicker/DatePicker.svelte | 10 ++++ .../FlatpickrDatePicker.svelte} | 2 +- .../NumberInput.svelte | 0 .../SpectrumDatePicker.svelte} | 2 +- .../TimePicker.svelte | 0 .../{DateTimePicker => DatePicker}/utils.js | 0 packages/bbui/src/Form/Core/index.js | 2 +- packages/bbui/src/Form/DatePicker.svelte | 2 +- packages/bbui/src/index.js | 2 +- .../new/_components/componentStructure.json | 1 + .../pages/builder/portal/apps/index.svelte | 40 -------------- .../app/forms/NewDateTimeField.svelte | 53 ------------------- 14 files changed, 16 insertions(+), 98 deletions(-) rename packages/bbui/src/Form/Core/{DateTimePicker => DatePicker}/Calendar.svelte (100%) rename packages/bbui/src/Form/Core/{DateTimePicker/DateTimeField.svelte => DatePicker/DateInput.svelte} (100%) create mode 100644 packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte rename packages/bbui/src/Form/Core/{DatePicker.svelte => DatePicker/FlatpickrDatePicker.svelte} (99%) rename packages/bbui/src/Form/Core/{DateTimePicker => DatePicker}/NumberInput.svelte (100%) rename packages/bbui/src/Form/Core/{DateTimePicker/DateTimePicker.svelte => DatePicker/SpectrumDatePicker.svelte} (98%) rename packages/bbui/src/Form/Core/{DateTimePicker => DatePicker}/TimePicker.svelte (100%) rename packages/bbui/src/Form/Core/{DateTimePicker => DatePicker}/utils.js (100%) delete mode 100644 packages/client/src/components/app/forms/NewDateTimeField.svelte diff --git a/packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte similarity index 100% rename from packages/bbui/src/Form/Core/DateTimePicker/Calendar.svelte rename to packages/bbui/src/Form/Core/DatePicker/Calendar.svelte diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte b/packages/bbui/src/Form/Core/DatePicker/DateInput.svelte similarity index 100% rename from packages/bbui/src/Form/Core/DateTimePicker/DateTimeField.svelte rename to packages/bbui/src/Form/Core/DatePicker/DateInput.svelte diff --git a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte new file mode 100644 index 0000000000..ec1514718c --- /dev/null +++ b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte @@ -0,0 +1,10 @@ + + + diff --git a/packages/bbui/src/Form/Core/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte similarity index 99% rename from packages/bbui/src/Form/Core/DatePicker.svelte rename to packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte index 7ce15292be..8d92f7633d 100644 --- a/packages/bbui/src/Form/Core/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte @@ -5,7 +5,7 @@ import "@spectrum-css/textfield/dist/index-vars.css" import "@spectrum-css/picker/dist/index-vars.css" import { createEventDispatcher } from "svelte" - import { uuid } from "../../helpers" + import { uuid } from "../../../helpers" export let id = null export let disabled = false diff --git a/packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte b/packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte similarity index 100% rename from packages/bbui/src/Form/Core/DateTimePicker/NumberInput.svelte rename to packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte diff --git a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte similarity index 98% rename from packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte rename to packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte index cccfea612c..d01097d357 100644 --- a/packages/bbui/src/Form/Core/DateTimePicker/DateTimePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte @@ -7,7 +7,7 @@ import { createEventDispatcher } from "svelte" import TimePicker from "./TimePicker.svelte" import Calendar from "./Calendar.svelte" - import DateTimeInput from "./DateTimeField.svelte" + import DateTimeInput from "./DateInput.svelte" import ActionButton from "../../../ActionButton/ActionButton.svelte" export let id = null diff --git a/packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte similarity index 100% rename from packages/bbui/src/Form/Core/DateTimePicker/TimePicker.svelte rename to packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte diff --git a/packages/bbui/src/Form/Core/DateTimePicker/utils.js b/packages/bbui/src/Form/Core/DatePicker/utils.js similarity index 100% rename from packages/bbui/src/Form/Core/DateTimePicker/utils.js rename to packages/bbui/src/Form/Core/DatePicker/utils.js diff --git a/packages/bbui/src/Form/Core/index.js b/packages/bbui/src/Form/Core/index.js index b0edf52748..4af2507147 100644 --- a/packages/bbui/src/Form/Core/index.js +++ b/packages/bbui/src/Form/Core/index.js @@ -8,7 +8,7 @@ export { default as CoreTextArea } from "./TextArea.svelte" export { default as CoreCombobox } from "./Combobox.svelte" export { default as CoreSwitch } from "./Switch.svelte" export { default as CoreSearch } from "./Search.svelte" -export { default as CoreDatePicker } from "./DatePicker.svelte" +export { default as CoreDatePicker } from "./DatePicker/DatePicker.svelte" export { default as CoreDropzone } from "./Dropzone.svelte" export { default as CoreStepper } from "./Stepper.svelte" export { default as CoreRichTextField } from "./RichTextField.svelte" diff --git a/packages/bbui/src/Form/DatePicker.svelte b/packages/bbui/src/Form/DatePicker.svelte index 04ce8b5467..49a66003fc 100644 --- a/packages/bbui/src/Form/DatePicker.svelte +++ b/packages/bbui/src/Form/DatePicker.svelte @@ -1,6 +1,6 @@ -
-

Date only

-
- (foo = e.detail)} - /> -
-

Date time

-
- (foo = e.detail)} - /> -
-

Date time no timezone

-
- (foo = e.detail)} - /> -
-

Time only

-
- (foo = e.detail)} /> -
-
-
-
- -
- {#each Object.keys(automationErrors || {}) as appId} - import { CoreDatePicker } from "@budibase/bbui" - import Field from "./Field.svelte" - - export let field - export let label - export let placeholder - export let disabled = false - export let enableTime = true - export let timeOnly = false - export let time24hr = false - export let ignoreTimezones = false - export let validation - export let defaultValue - export let onChange - - let fieldState - let fieldApi - - const handleChange = e => { - const changed = fieldApi.setValue(e.detail) - if (onChange && changed) { - onChange({ value: e.detail }) - } - } - - - - {#if fieldState} - - {/if} - From b2352157cdf1cec5b136c766660539649e0a25fe Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 3 Nov 2023 20:27:30 +0000 Subject: [PATCH 013/296] Improve grid integration with new datepicker --- packages/bbui/src/Actions/position_dropdown.js | 6 ++++-- .../src/Form/Core/DatePicker/DatePicker.svelte | 5 +++++ .../Core/DatePicker/SpectrumDatePicker.svelte | 17 ++++++++++++++++- .../src/components/grid/cells/DateCell.svelte | 15 +++++---------- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/bbui/src/Actions/position_dropdown.js b/packages/bbui/src/Actions/position_dropdown.js index f2018272f6..7c4f7e8a2a 100644 --- a/packages/bbui/src/Actions/position_dropdown.js +++ b/packages/bbui/src/Actions/position_dropdown.js @@ -39,11 +39,13 @@ export default function positionDropdown(element, opts) { styles = customUpdate(anchorBounds, elementBounds, styles) } else { // Determine vertical styles + const topSpace = anchorBounds.top + const bottomSpace = window.innerHeight - anchorBounds.bottom if (align === "right-outside") { styles.top = anchorBounds.top } else if ( - window.innerHeight - anchorBounds.bottom < - (maxHeight || 100) + window.innerHeight - anchorBounds.bottom < (maxHeight || 100) && + topSpace - bottomSpace > 100 ) { styles.top = anchorBounds.top - elementBounds.height - offset styles.maxHeight = maxHeight || 240 diff --git a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte index ec1514718c..a03be24753 100644 --- a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte @@ -1,10 +1,15 @@ diff --git a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte index d01097d357..97774da51b 100644 --- a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte @@ -4,7 +4,7 @@ import "@spectrum-css/textfield/dist/index-vars.css" import Popover from "../../../Popover/Popover.svelte" import dayjs from "dayjs" - import { createEventDispatcher } from "svelte" + import { createEventDispatcher, onMount } from "svelte" import TimePicker from "./TimePicker.svelte" import Calendar from "./Calendar.svelte" import DateTimeInput from "./DateInput.svelte" @@ -19,6 +19,9 @@ export let timeOnly = false export let ignoreTimezones = false export let useKeyboardShortcuts = true + export let appendTo = null + export let api = null + export let align = "left" const dispatch = createEventDispatcher() @@ -114,6 +117,13 @@ calendar?.setDate(now) handleChange(now) } + + onMount(() => { + api = { + open: () => popover?.show(), + close: () => popover?.hide(), + } + }) {#if isOpen} diff --git a/packages/frontend-core/src/components/grid/cells/DateCell.svelte b/packages/frontend-core/src/components/grid/cells/DateCell.svelte index 53b159ee30..fae75277b4 100644 --- a/packages/frontend-core/src/components/grid/cells/DateCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DateCell.svelte @@ -10,7 +10,7 @@ export let readonly = false export let api - let flatpickr + let datePickerAPI let isOpen // Adding the 0- will turn a string like 00:00:00 into a valid ISO @@ -41,7 +41,7 @@ // Ensure we close flatpickr when unselected $: { if (!focused) { - flatpickr?.close() + datePickerAPI?.close() } } @@ -52,8 +52,8 @@ onMount(() => { api = { onKeyDown, - focus: () => flatpickr?.open(), - blur: () => flatpickr?.close(), + focus: () => datePickerAPI?.open(), + blur: () => datePickerAPI?.close(), isActive: () => isOpen, } }) @@ -75,12 +75,10 @@ onChange(e.detail)} - appendTo={document.documentElement} enableTime={!dateOnly} {timeOnly} - time24hr ignoreTimezones={schema.ignoreTimezones} - bind:flatpickr + bind:api={datePickerAPI} on:open={() => (isOpen = true)} on:close={() => (isOpen = false)} useKeyboardShortcuts={false} @@ -110,9 +108,6 @@ position: absolute; opacity: 0; } - .picker :global(.flatpickr) { - min-width: 0; - } .picker :global(.spectrum-Textfield-input) { width: 100%; } From f5369e7cddda61fde78e643309d367f24880382e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 2 Apr 2024 10:50:37 +0100 Subject: [PATCH 014/296] Update pro --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 3820c0c93a..6b62505be0 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 3820c0c93a3e448e10a60a9feb5396844b537ca8 +Subproject commit 6b62505be0c0b50a57b4f4980d86541ebdc86428 From 2e4e3eac60f7ed722df649c48d6de0105e91ec01 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 2 Apr 2024 10:59:30 +0100 Subject: [PATCH 015/296] Update styles of selected day --- packages/bbui/src/Form/Core/DatePicker/Calendar.svelte | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte index 6491ba94ab..75e8e193e6 100644 --- a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte @@ -125,7 +125,6 @@
@@ -194,11 +193,13 @@ visibility: visible; color: var(--spectrum-global-color-gray-400); } - .spectrum-Calendar-date.is-today:before { + .spectrum-Calendar-date.is-today, + .spectrum-Calendar-date.is-today::before { border-color: var(--spectrum-global-color-gray-400); } - .spectrum-Calendar-date.is-today { - border-color: var(--spectrum-global-color-gray-400); + .spectrum-Calendar-date.is-today.is-selected, + .spectrum-Calendar-date.is-today.is-selected::before { + border-color: var(--spectrum-global-color-blue-700); } .spectrum-Calendar-date.is-selected:not(.is-range-selection) { background: var(--spectrum-global-color-blue-400); From d71766b9a4624cf7cd81bfb641281bfff35bac1f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 2 Apr 2024 11:01:50 +0100 Subject: [PATCH 016/296] Revert clickoutside --- packages/bbui/src/Actions/click_outside.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.js index 305ae65ac8..7873b7fd6c 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.js @@ -1,4 +1,8 @@ -const ignoredClasses = [".flatpickr-calendar", ".download-js-link"] +const ignoredClasses = [ + ".flatpickr-calendar", + ".spectrum-Popover", + ".download-js-link", +] let clickHandlers = [] /** @@ -21,13 +25,6 @@ const handleClick = event => { return } - // Ignore clicks for popovers, unless the handler is registered from one - const sourceInPopover = handler.anchor.closest(".spectrum-Popover") != null - const clickInPopover = event.target.closest(".spectrum-Popover") != null - if (clickInPopover && !sourceInPopover) { - return - } - // Ignore clicks for modals, unless the handler is registered from one const sourceInModal = handler.anchor.closest(".spectrum-Underlay") != null const clickInModal = event.target.closest(".spectrum-Underlay") != null From 24f67617669d90442da2c4f8b2a019c8f4d59cc5 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 2 Apr 2024 11:02:10 +0100 Subject: [PATCH 017/296] Revert clickoutside --- packages/bbui/src/Actions/click_outside.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.js index 7873b7fd6c..eafca657f3 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.js @@ -25,7 +25,7 @@ const handleClick = event => { return } - // Ignore clicks for modals, unless the handler is registered from one + // Ignore clicks for modals, unless the handler is registered from a modal const sourceInModal = handler.anchor.closest(".spectrum-Underlay") != null const clickInModal = event.target.closest(".spectrum-Underlay") != null if (clickInModal && !sourceInModal) { From 4673fbeaaac1efd9b63d97b8e35001862c7e9d02 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 2 Apr 2024 11:08:37 +0100 Subject: [PATCH 018/296] Fix overflow --- packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte index 97774da51b..3a96044df4 100644 --- a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte @@ -185,6 +185,7 @@ diff --git a/packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte deleted file mode 100644 index ac163de3bb..0000000000 --- a/packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte +++ /dev/null @@ -1,268 +0,0 @@ - - -{#key redrawOptions} - -
- - -
- -
- -
-
-{/key} -{#if open} - -
-{/if} - - diff --git a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte deleted file mode 100644 index bd9fb8269e..0000000000 --- a/packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - {#if isOpen} -
- {#if showCalendar} - - {/if} - -
- {/if} -
- - diff --git a/packages/bbui/src/Form/Core/DateRangePicker.svelte b/packages/bbui/src/Form/Core/DateRangePicker.svelte new file mode 100644 index 0000000000..9084942ba7 --- /dev/null +++ b/packages/bbui/src/Form/Core/DateRangePicker.svelte @@ -0,0 +1,69 @@ + + +
+ (fromDate = e.detail)} + enableTime={false} + /> +
+ +
+ (toDate = e.detail)} + enableTime={false} + /> +
+ + diff --git a/packages/bbui/src/Form/Core/index.js b/packages/bbui/src/Form/Core/index.js index 4af2507147..533a1956c5 100644 --- a/packages/bbui/src/Form/Core/index.js +++ b/packages/bbui/src/Form/Core/index.js @@ -9,6 +9,7 @@ export { default as CoreCombobox } from "./Combobox.svelte" export { default as CoreSwitch } from "./Switch.svelte" export { default as CoreSearch } from "./Search.svelte" export { default as CoreDatePicker } from "./DatePicker/DatePicker.svelte" +export { default as CoreDateRangePicker } from "./DateRangePicker.svelte" export { default as CoreDropzone } from "./Dropzone.svelte" export { default as CoreStepper } from "./Stepper.svelte" export { default as CoreRichTextField } from "./RichTextField.svelte" diff --git a/packages/bbui/src/Form/DatePicker.svelte b/packages/bbui/src/Form/DatePicker.svelte index 5e84947f0a..cf249e5bb8 100644 --- a/packages/bbui/src/Form/DatePicker.svelte +++ b/packages/bbui/src/Form/DatePicker.svelte @@ -15,18 +15,12 @@ export let placeholder = null export let appendTo = undefined export let ignoreTimezones = false - export let range = false export let helpText = null + const dispatch = createEventDispatcher() const onChange = e => { - if (range) { - // Flatpickr cant take two dates and work out what to display, needs to be provided a string. - // Like - "Date1 to Date2". Hence passing in that specifically from the array - value = e?.detail[1] - } else { - value = e.detail - } + value = e.detail dispatch("change", e.detail) } @@ -43,7 +37,6 @@ {time24hr} {appendTo} {ignoreTimezones} - {range} on:change={onChange} /> diff --git a/packages/bbui/src/Form/DateRangePicker.svelte b/packages/bbui/src/Form/DateRangePicker.svelte new file mode 100644 index 0000000000..39c2acb96a --- /dev/null +++ b/packages/bbui/src/Form/DateRangePicker.svelte @@ -0,0 +1,34 @@ + + + + + diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 222e558675..f28e185305 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -3,13 +3,34 @@ import "./bbui.css" // Spectrum icons import "@spectrum-css/icon/dist/index-vars.css" -// Components +// Form components export { default as Input } from "./Form/Input.svelte" export { default as Stepper } from "./Form/Stepper.svelte" export { default as TextArea } from "./Form/TextArea.svelte" export { default as Select } from "./Form/Select.svelte" export { default as Combobox } from "./Form/Combobox.svelte" export { default as Dropzone } from "./Form/Dropzone.svelte" +export { default as DatePicker } from "./Form/DatePicker.svelte" +export { default as DateRangePicker } from "./Form/DateRangePicker.svelte" +export { default as Toggle } from "./Form/Toggle.svelte" +export { default as RadioGroup } from "./Form/RadioGroup.svelte" +export { default as Checkbox } from "./Form/Checkbox.svelte" +export { default as InputDropdown } from "./Form/InputDropdown.svelte" +export { default as PickerDropdown } from "./Form/PickerDropdown.svelte" +export { default as EnvDropdown } from "./Form/EnvDropdown.svelte" +export { default as Multiselect } from "./Form/Multiselect.svelte" +export { default as Search } from "./Form/Search.svelte" +export { default as RichTextField } from "./Form/RichTextField.svelte" +export { default as Slider } from "./Form/Slider.svelte" +export { default as File } from "./Form/File.svelte" + +// Core form components to be used elsewhere (standard components) +export * from "./Form/Core" + +// Fancy form components +export * from "./FancyForm" + +// Components export { default as Drawer } from "./Drawer/Drawer.svelte" export { default as DrawerContent } from "./Drawer/DrawerContent.svelte" export { default as Avatar } from "./Avatar/Avatar.svelte" @@ -21,12 +42,6 @@ export { default as ButtonGroup } from "./ButtonGroup/ButtonGroup.svelte" export { default as ClearButton } from "./ClearButton/ClearButton.svelte" export { default as Icon } from "./Icon/Icon.svelte" export { default as IconAvatar } from "./Icon/IconAvatar.svelte" -export { default as Toggle } from "./Form/Toggle.svelte" -export { default as RadioGroup } from "./Form/RadioGroup.svelte" -export { default as Checkbox } from "./Form/Checkbox.svelte" -export { default as InputDropdown } from "./Form/InputDropdown.svelte" -export { default as PickerDropdown } from "./Form/PickerDropdown.svelte" -export { default as EnvDropdown } from "./Form/EnvDropdown.svelte" export { default as DetailSummary } from "./DetailSummary/DetailSummary.svelte" export { default as Popover } from "./Popover/Popover.svelte" export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte" @@ -37,11 +52,6 @@ export { default as Page } from "./Layout/Page.svelte" export { default as Link } from "./Link/Link.svelte" export { default as Tooltip } from "./Tooltip/Tooltip.svelte" export { default as TempTooltip } from "./Tooltip/TempTooltip.svelte" -export { - default as AbsTooltip, - TooltipPosition, - TooltipType, -} from "./Tooltip/AbsTooltip.svelte" export { default as TooltipWrapper } from "./Tooltip/TooltipWrapper.svelte" export { default as Menu } from "./Menu/Menu.svelte" export { default as MenuSection } from "./Menu/Section.svelte" @@ -53,9 +63,6 @@ export { default as NotificationDisplay } from "./Notification/NotificationDispl export { default as Notification } from "./Notification/Notification.svelte" export { default as SideNavigation } from "./SideNavigation/Navigation.svelte" export { default as SideNavigationItem } from "./SideNavigation/Item.svelte" -export { default as DatePicker } from "./Form/DatePicker.svelte" -export { default as DateTimePicker } from "./Form/Core/DatePicker/SpectrumDatePicker.svelte" -export { default as Multiselect } from "./Form/Multiselect.svelte" export { default as Context } from "./context" export { default as Table } from "./Table/Table.svelte" export { default as Tabs } from "./Tabs/Tabs.svelte" @@ -65,7 +72,6 @@ export { default as Tag } from "./Tags/Tag.svelte" export { default as TreeView } from "./TreeView/Tree.svelte" export { default as TreeItem } from "./TreeView/Item.svelte" export { default as Divider } from "./Divider/Divider.svelte" -export { default as Search } from "./Form/Search.svelte" export { default as Pagination } from "./Pagination/Pagination.svelte" export { default as Badge } from "./Badge/Badge.svelte" export { default as StatusLight } from "./StatusLight/StatusLight.svelte" @@ -77,15 +83,15 @@ export { default as CopyInput } from "./Input/CopyInput.svelte" export { default as BannerDisplay } from "./Banner/BannerDisplay.svelte" export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte" export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte" -export { default as RichTextField } from "./Form/RichTextField.svelte" export { default as List } from "./List/List.svelte" export { default as ListItem } from "./List/ListItem.svelte" export { default as IconSideNav } from "./IconSideNav/IconSideNav.svelte" 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" +export { default as AbsTooltip } from "./Tooltip/AbsTooltip.svelte" +export { TooltipPosition, TooltipType } from "./Tooltip/AbsTooltip.svelte" + // Renderers export { default as BoldRenderer } from "./Table/BoldRenderer.svelte" export { default as CodeRenderer } from "./Table/CodeRenderer.svelte" @@ -97,9 +103,6 @@ export { default as Heading } from "./Typography/Heading.svelte" export { default as Detail } from "./Typography/Detail.svelte" export { default as Code } from "./Typography/Code.svelte" -// Core form components to be used elsewhere (standard components) -export * from "./Form/Core" - // Actions export { default as autoResizeTextArea } from "./Actions/autoresize_textarea" export { default as positionDropdown } from "./Actions/position_dropdown" @@ -111,6 +114,3 @@ export { banner, BANNER_TYPES } from "./Stores/banner" // Helpers export * as Helpers from "./helpers" - -// Fancy form components -export * from "./FancyForm" diff --git a/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte b/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte index bbf28b2fe8..212243aa76 100644 --- a/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte @@ -1,7 +1,7 @@ @@ -207,7 +207,7 @@ View plans
- {:else if !backupData?.length && !loading && !filterOpt && !startDate} + {:else if !backupData?.length && !loading && !filterOpt && !date}
BackupsDefault @@ -236,19 +236,19 @@ bind:value={filterOpt} />
- { - startDate = e.detail?.[0] - endDate = e.detail?.[1] + date = e.detail }} + enableTime={false} />
- +
diff --git a/packages/client/src/components/app/DateRangePicker.svelte b/packages/client/src/components/app/DateRangePicker.svelte deleted file mode 100644 index 5c710ad766..0000000000 --- a/packages/client/src/components/app/DateRangePicker.svelte +++ /dev/null @@ -1,79 +0,0 @@ - - -
- Date: Mon, 15 Apr 2024 13:46:49 +0100 Subject: [PATCH 033/296] Revert "Revert "adds sidepanel open and close actions, and gives the user the option to disable click-outside closure of sidepanel"" --- packages/bbui/src/Layout/Page.svelte | 10 +++++----- packages/client/manifest.json | 16 +++++++++++++++- packages/client/src/components/app/Layout.svelte | 5 ++++- .../client/src/components/app/SidePanel.svelte | 14 ++++++++++++++ packages/client/src/stores/sidePanel.js | 9 +++++++++ 5 files changed, 47 insertions(+), 7 deletions(-) diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte index 2169a12459..62dd9cc909 100644 --- a/packages/bbui/src/Layout/Page.svelte +++ b/packages/bbui/src/Layout/Page.svelte @@ -7,11 +7,11 @@ export let narrower = false export let noPadding = false - let sidePanelVisble = false + let sidePanelVisible = false setContext("side-panel", { - open: () => (sidePanelVisble = true), - close: () => (sidePanelVisble = false), + open: () => (sidePanelVisible = true), + close: () => (sidePanelVisible = false), }) @@ -24,9 +24,9 @@
{ - sidePanelVisble = false + sidePanelVisible = false }} > diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 40abc7a9a0..c9e28e202b 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -6723,7 +6723,21 @@ "illegalChildren": ["section", "sidepanel"], "showEmptyState": false, "draggable": false, - "info": "Side panels are hidden by default. They will only be revealed when triggered by the 'Open Side Panel' action." + "info": "Side panels are hidden by default. They will only be revealed when triggered by the 'Open Side Panel' action.", + "sendEvents": true, + "settings": [ + { + "type": "boolean", + "key": "clickOutsideToClose", + "label": "Click outside to close", + "defaultValue": true + }, + { + "type": "event", + "key": "onSidePanelClose", + "label": "On side panel close" + } + ] }, "rowexplorer": { "block": true, diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index 8508e943ff..bae2bd0faf 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -73,7 +73,10 @@ $context.device.width, $context.device.height ) - $: autoCloseSidePanel = !$builderStore.inBuilder && $sidePanelStore.open + $: autoCloseSidePanel = + !$builderStore.inBuilder && + $sidePanelStore.open && + $sidePanelStore.clickOutsideToClose $: screenId = $builderStore.inBuilder ? `${$builderStore.screen?._id}-screen` : "screen" diff --git a/packages/client/src/components/app/SidePanel.svelte b/packages/client/src/components/app/SidePanel.svelte index 825b401bb8..624617ad69 100644 --- a/packages/client/src/components/app/SidePanel.svelte +++ b/packages/client/src/components/app/SidePanel.svelte @@ -5,6 +5,9 @@ const { styleable, sidePanelStore, builderStore, dndIsDragging } = getContext("sdk") + export let sidePanelClose + export let clickOutsideToClose + // Automatically show and hide the side panel when inside the builder. // For some unknown reason, svelte reactivity breaks if we reference the // reactive variable "open" inside the following expression, or if we define @@ -26,6 +29,10 @@ } } + $: { + sidePanelStore.actions.setSidepanelState(clickOutsideToClose) + } + // Derive visibility $: open = $sidePanelStore.contentId === $component.id @@ -40,6 +47,12 @@ } } + const handleSidePanelClose = async () => { + if (sidePanelClose) { + await sidePanelClose() + } + } + const showInSidePanel = (el, visible) => { const update = visible => { const target = document.getElementById("side-panel-container") @@ -51,6 +64,7 @@ } else { if (target.contains(node)) { target.removeChild(node) + handleSidePanelClose() } } } diff --git a/packages/client/src/stores/sidePanel.js b/packages/client/src/stores/sidePanel.js index 3b3b9f5f4d..df66eca01c 100644 --- a/packages/client/src/stores/sidePanel.js +++ b/packages/client/src/stores/sidePanel.js @@ -3,6 +3,7 @@ import { writable, derived } from "svelte/store" export const createSidePanelStore = () => { const initialState = { contentId: null, + clickOutsideToClose: true, } const store = writable(initialState) const derivedStore = derived(store, $store => { @@ -32,11 +33,19 @@ export const createSidePanelStore = () => { }, 50) } + const setSidepanelState = bool => { + clearTimeout(timeout) + store.update(state => { + state.clickOutsideToClose = bool + return state + }) + } return { subscribe: derivedStore.subscribe, actions: { open, close, + setSidepanelState, }, } } From ea3cd0cd9b456af44579474e2df6393e134308dc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 11:27:27 +0100 Subject: [PATCH 034/296] Support reordering on mobile --- .../src/components/grid/cells/HeaderCell.svelte | 14 +++++++++----- .../src/components/grid/stores/reorder.js | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte index 657f618759..f0ba29b499 100644 --- a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte @@ -18,7 +18,6 @@ export let column export let idx - export let orderable = true const { reorder, @@ -66,6 +65,7 @@ $: resetSearchValue(column.name) $: searching = searchValue != null $: debouncedUpdateFilter(searchValue) + $: orderable = !column.primaryDisplay const getSortingLabels = type => { switch (type) { @@ -112,7 +112,7 @@ } const onMouseDown = e => { - if (e.button === 0 && orderable) { + if ((e.touches?.length || e.button === 0) && orderable) { timeout = setTimeout(() => { reorder.actions.startReordering(column.name, e) }, 200) @@ -120,7 +120,7 @@ } const onMouseUp = e => { - if (e.button === 0 && orderable) { + if ((e.touches?.length || e.button === 0) && orderable) { clearTimeout(timeout) } } @@ -258,6 +258,9 @@ Use as display column @@ -378,7 +382,7 @@ Move right diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index f820593174..7bf0423b23 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -40,6 +40,7 @@ export const createActions = context => { // Callback when dragging on a colum header and starting reordering const startReordering = (column, e) => { + console.log("start", column) const $visibleColumns = get(visibleColumns) const $bounds = get(bounds) const $stickyColumn = get(stickyColumn) @@ -55,6 +56,11 @@ export const createActions = context => { x: 0, column: $stickyColumn.name, }) + } else if (!$visibleColumns[0].primaryDisplay) { + breakpoints.unshift({ + x: 0, + column: null, + }) } // Update state @@ -69,6 +75,9 @@ export const createActions = context => { // Add listeners to handle mouse movement document.addEventListener("mousemove", onReorderMouseMove) document.addEventListener("mouseup", stopReordering) + document.addEventListener("touchmove", onReorderMouseMove) + document.addEventListener("touchend", stopReordering) + document.addEventListener("touchcancel", stopReordering) // Trigger a move event immediately so ensure a candidate column is chosen onReorderMouseMove(e) @@ -77,7 +86,7 @@ export const createActions = context => { // Callback when moving the mouse when reordering columns const onReorderMouseMove = e => { // Immediately handle the current position - const x = e.clientX + const x = e.clientX ?? e.touches?.[0]?.clientX reorder.update(state => ({ ...state, latestX: x, @@ -168,6 +177,9 @@ export const createActions = context => { // Remove event handlers document.removeEventListener("mousemove", onReorderMouseMove) document.removeEventListener("mouseup", stopReordering) + document.removeEventListener("touchmove", onReorderMouseMove) + document.removeEventListener("touchend", stopReordering) + document.removeEventListener("touchcancel", stopReordering) // Save column changes await columns.actions.saveChanges() @@ -185,8 +197,7 @@ export const createActions = context => { if (--targetIdx < sourceIdx) { targetIdx++ } - state.splice(targetIdx, 0, removed[0]) - return state.slice() + return state.toSpliced(targetIdx, 0, removed[0]) }) } From f8087f0fb3cc78f9846040d0a78dfbcce07930a0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 11:45:54 +0100 Subject: [PATCH 035/296] Automatically unpin the grid sticky column when available space is restricted --- .../src/components/grid/cells/GridCell.svelte | 3 + .../grid/controls/HideColumnsButton.svelte | 1 + .../grid/overlays/ResizeOverlay.svelte | 1 + .../src/components/grid/stores/columns.js | 64 +++++++++++++------ .../src/components/grid/stores/reorder.js | 19 +++--- .../src/components/grid/stores/ui.js | 2 +- 6 files changed, 59 insertions(+), 31 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/GridCell.svelte b/packages/frontend-core/src/components/grid/cells/GridCell.svelte index 74d98ec130..32a9dea83b 100644 --- a/packages/frontend-core/src/components/grid/cells/GridCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/GridCell.svelte @@ -43,6 +43,9 @@ on:mouseup on:click on:contextmenu + on:touchstart + on:touchend + on:touchcancel {style} > {#if error} diff --git a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte index 01c9dc648b..4e19e64297 100644 --- a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte @@ -81,6 +81,7 @@ size="S" value={column.visible} on:change={e => toggleVisibility(column, e.detail)} + disabled={column.primaryDisplay} /> {/each}
diff --git a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte index 1140962583..e96517a434 100644 --- a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte @@ -21,6 +21,7 @@ class="resize-slider" class:visible={activeColumn === $stickyColumn.name} on:mousedown={e => resize.actions.startResizing($stickyColumn, e)} + on:touchstart={e => resize.actions.startResizing($stickyColumn, e)} on:dblclick={() => resize.actions.resetSize($stickyColumn)} style="left:{GutterWidth + $stickyColumn.width}px;" > diff --git a/packages/frontend-core/src/components/grid/stores/columns.js b/packages/frontend-core/src/components/grid/stores/columns.js index 31638e7c79..8ceaae105f 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.js +++ b/packages/frontend-core/src/components/grid/stores/columns.js @@ -48,22 +48,28 @@ export const createStores = () => { export const deriveStores = context => { const { columns, stickyColumn } = context - // Derive if we have any normal columns - const hasNonAutoColumn = derived( + // Quick access to all columns + const allColumns = derived( [columns, stickyColumn], ([$columns, $stickyColumn]) => { let allCols = $columns || [] if ($stickyColumn) { allCols = [...allCols, $stickyColumn] } - const normalCols = allCols.filter(column => { - return !column.schema?.autocolumn - }) - return normalCols.length > 0 + return allCols } ) + // Derive if we have any normal columns + const hasNonAutoColumn = derived(allColumns, $allColumns => { + const normalCols = $allColumns.filter(column => { + return !column.schema?.autocolumn + }) + return normalCols.length > 0 + }) + return { + allColumns, hasNonAutoColumn, } } @@ -142,24 +148,26 @@ export const createActions = context => { } export const initialise = context => { - const { definition, columns, stickyColumn, enrichedSchema } = context + const { + definition, + columns, + stickyColumn, + allColumns, + enrichedSchema, + compact, + } = context // Merge new schema fields with existing schema in order to preserve widths - enrichedSchema.subscribe($enrichedSchema => { + const processColumns = $enrichedSchema => { if (!$enrichedSchema) { columns.set([]) stickyColumn.set(null) return } const $definition = get(definition) - const $columns = get(columns) + const $allColumns = get(allColumns) const $stickyColumn = get(stickyColumn) - - // Generate array of all columns to easily find pre-existing columns - let allColumns = $columns || [] - if ($stickyColumn) { - allColumns.push($stickyColumn) - } + const $compact = get(compact) // Find primary display let primaryDisplay @@ -171,7 +179,7 @@ export const initialise = context => { // Get field list let fields = [] Object.keys($enrichedSchema).forEach(field => { - if (field !== primaryDisplay) { + if ($compact || field !== primaryDisplay) { fields.push(field) } }) @@ -181,7 +189,7 @@ export const initialise = context => { fields .map(field => { const fieldSchema = $enrichedSchema[field] - const oldColumn = allColumns?.find(x => x.name === field) + const oldColumn = $allColumns?.find(x => x.name === field) return { name: field, label: fieldSchema.displayName || field, @@ -189,9 +197,18 @@ export const initialise = context => { width: fieldSchema.width || oldColumn?.width || DefaultColumnWidth, visible: fieldSchema.visible ?? true, order: fieldSchema.order ?? oldColumn?.order, + primaryDisplay: field === primaryDisplay, } }) .sort((a, b) => { + // If we don't have a pinned column then primary display will be in + // the normal columns list, and should be first + if (a.name === primaryDisplay) { + return -1 + } else if (b.name === primaryDisplay) { + return 1 + } + // Sort by order first const orderA = a.order const orderB = b.order @@ -214,12 +231,12 @@ export const initialise = context => { ) // Update sticky column - if (!primaryDisplay) { + if ($compact || !primaryDisplay) { stickyColumn.set(null) return } const stickySchema = $enrichedSchema[primaryDisplay] - const oldStickyColumn = allColumns?.find(x => x.name === primaryDisplay) + const oldStickyColumn = $allColumns?.find(x => x.name === primaryDisplay) stickyColumn.set({ name: primaryDisplay, label: stickySchema.displayName || primaryDisplay, @@ -228,6 +245,13 @@ export const initialise = context => { visible: true, order: 0, left: GutterWidth, + primaryDisplay: true, }) - }) + } + + // Process columns when schema changes + enrichedSchema.subscribe(processColumns) + + // Process columns when compact flag changes + compact.subscribe(() => processColumns(get(enrichedSchema))) } diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index 7bf0423b23..30a5c144de 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -40,7 +40,6 @@ export const createActions = context => { // Callback when dragging on a colum header and starting reordering const startReordering = (column, e) => { - console.log("start", column) const $visibleColumns = get(visibleColumns) const $bounds = get(bounds) const $stickyColumn = get(stickyColumn) @@ -167,13 +166,6 @@ export const createActions = context => { // Ensure auto-scrolling is stopped stopAutoScroll() - // Swap position of columns - let { sourceColumn, targetColumn } = get(reorder) - moveColumn(sourceColumn, targetColumn) - - // Reset state - reorder.set(reorderInitialState) - // Remove event handlers document.removeEventListener("mousemove", onReorderMouseMove) document.removeEventListener("mouseup", stopReordering) @@ -181,8 +173,15 @@ export const createActions = context => { document.removeEventListener("touchend", stopReordering) document.removeEventListener("touchcancel", stopReordering) - // Save column changes - await columns.actions.saveChanges() + // Ensure there's actually a change + let { sourceColumn, targetColumn } = get(reorder) + if (sourceColumn !== targetColumn) { + moveColumn(sourceColumn, targetColumn) + await columns.actions.saveChanges() + } + + // Reset state + reorder.set(reorderInitialState) } // Moves a column after another columns. diff --git a/packages/frontend-core/src/components/grid/stores/ui.js b/packages/frontend-core/src/components/grid/stores/ui.js index da0558bb5b..928f93f3e1 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.js +++ b/packages/frontend-core/src/components/grid/stores/ui.js @@ -98,7 +98,7 @@ export const deriveStores = context => { // Derive whether we should use the compact UI, depending on width const compact = derived([stickyColumn, width], ([$stickyColumn, $width]) => { - return ($stickyColumn?.width || 0) + $width + GutterWidth < 1100 + return ($stickyColumn?.width || 0) + $width + GutterWidth < 800 }) return { From c11139914fadeb898fde3f07fc769fc281facaea Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 11:55:44 +0100 Subject: [PATCH 036/296] Add support for resizing columns on mobile --- .../src/components/grid/lib/utils.js | 7 +++++++ .../grid/overlays/ResizeOverlay.svelte | 1 + .../grid/overlays/ScrollOverlay.svelte | 16 +++++----------- .../src/components/grid/stores/reorder.js | 3 ++- .../src/components/grid/stores/resize.js | 14 ++++++++++++-- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js index c7c618e6f8..02e6d66e0e 100644 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ b/packages/frontend-core/src/components/grid/lib/utils.js @@ -20,3 +20,10 @@ export const getColumnIcon = column => { return result || "Text" } + +export const parseEventLocation = e => { + return { + x: e.clientX ?? e.touches?.[0]?.clientX, + y: e.clientY ?? e.touches?.[0]?.clientY, + } +} diff --git a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte index e96517a434..e564108430 100644 --- a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte @@ -33,6 +33,7 @@ class="resize-slider" class:visible={activeColumn === column.name} on:mousedown={e => resize.actions.startResizing(column, e)} + on:touchstart={e => resize.actions.startResizing(column, e)} on:dblclick={() => resize.actions.resetSize(column)} style={getStyle(column, offset, $scrollLeft)} > diff --git a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte index 43a64f3fbd..e0ead3727c 100644 --- a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte @@ -2,6 +2,7 @@ import { getContext } from "svelte" import { domDebounce } from "../../../utils/utils" import { DefaultRowHeight, ScrollBarSize } from "../lib/constants" + import { parseEventLocation } from "../lib/utils" const { scroll, @@ -53,17 +54,10 @@ } } - const getLocation = e => { - return { - y: e.touches?.[0]?.clientY ?? e.clientY, - x: e.touches?.[0]?.clientX ?? e.clientX, - } - } - // V scrollbar drag handlers const startVDragging = e => { e.preventDefault() - initialMouse = getLocation(e).y + initialMouse = parseEventLocation(e).y initialScroll = $scrollTop document.addEventListener("mousemove", moveVDragging) document.addEventListener("touchmove", moveVDragging) @@ -73,7 +67,7 @@ closeMenu() } const moveVDragging = domDebounce(e => { - const delta = getLocation(e).y - initialMouse + const delta = parseEventLocation(e).y - initialMouse const weight = delta / availHeight const newScrollTop = initialScroll + weight * $maxScrollTop scroll.update(state => ({ @@ -92,7 +86,7 @@ // H scrollbar drag handlers const startHDragging = e => { e.preventDefault() - initialMouse = getLocation(e).x + initialMouse = parseEventLocation(e).x initialScroll = $scrollLeft document.addEventListener("mousemove", moveHDragging) document.addEventListener("touchmove", moveHDragging) @@ -102,7 +96,7 @@ closeMenu() } const moveHDragging = domDebounce(e => { - const delta = getLocation(e).x - initialMouse + const delta = parseEventLocation(e).x - initialMouse const weight = delta / availWidth const newScrollLeft = initialScroll + weight * $maxScrollLeft scroll.update(state => ({ diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index 30a5c144de..84b297c461 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -1,4 +1,5 @@ import { get, writable, derived } from "svelte/store" +import { parseEventLocation } from "../lib/utils" const reorderInitialState = { sourceColumn: null, @@ -85,7 +86,7 @@ export const createActions = context => { // Callback when moving the mouse when reordering columns const onReorderMouseMove = e => { // Immediately handle the current position - const x = e.clientX ?? e.touches?.[0]?.clientX + const { x } = parseEventLocation(e) reorder.update(state => ({ ...state, latestX: x, diff --git a/packages/frontend-core/src/components/grid/stores/resize.js b/packages/frontend-core/src/components/grid/stores/resize.js index 2dc9e0784c..87b3912848 100644 --- a/packages/frontend-core/src/components/grid/stores/resize.js +++ b/packages/frontend-core/src/components/grid/stores/resize.js @@ -1,5 +1,6 @@ import { writable, get, derived } from "svelte/store" import { MinColumnWidth, DefaultColumnWidth } from "../lib/constants" +import { parseEventLocation } from "../lib/utils" const initialState = { initialMouseX: null, @@ -24,6 +25,8 @@ export const createActions = context => { // Starts resizing a certain column const startResizing = (column, e) => { + const { x } = parseEventLocation(e) + // Prevent propagation to stop reordering triggering e.stopPropagation() ui.actions.blur() @@ -39,7 +42,7 @@ export const createActions = context => { width: column.width, left: column.left, initialWidth: column.width, - initialMouseX: e.clientX, + initialMouseX: x, column: column.name, columnIdx, }) @@ -47,12 +50,16 @@ export const createActions = context => { // Add mouse event listeners to handle resizing document.addEventListener("mousemove", onResizeMouseMove) document.addEventListener("mouseup", stopResizing) + document.addEventListener("touchmove", onResizeMouseMove) + document.addEventListener("touchend", stopResizing) + document.addEventListener("touchcancel", stopResizing) } // Handler for moving the mouse to resize columns const onResizeMouseMove = e => { const { initialMouseX, initialWidth, width, columnIdx } = get(resize) - const dx = e.clientX - initialMouseX + const { x } = parseEventLocation(e) + const dx = x - initialMouseX const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx)) // Ignore small changes @@ -87,6 +94,9 @@ export const createActions = context => { resize.set(initialState) document.removeEventListener("mousemove", onResizeMouseMove) document.removeEventListener("mouseup", stopResizing) + document.removeEventListener("touchmove", onResizeMouseMove) + document.removeEventListener("touchend", stopResizing) + document.removeEventListener("touchcancel", stopResizing) // Persist width if it changed if ($resize.width !== $resize.initialWidth) { From 27f7b1cc15b90ce8e1e03dce291708e1957a2aea Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 14:32:57 +0100 Subject: [PATCH 037/296] Add multiple improvements for touch events to grids --- .../src/components/grid/cells/HeaderCell.svelte | 5 +++-- packages/frontend-core/src/components/grid/stores/reorder.js | 3 ++- packages/frontend-core/src/components/grid/stores/resize.js | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte index f0ba29b499..8a10556da9 100644 --- a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte @@ -119,9 +119,10 @@ } } - const onMouseUp = e => { - if ((e.touches?.length || e.button === 0) && orderable) { + const onMouseUp = () => { + if (timeout) { clearTimeout(timeout) + timeout = null } } diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index 84b297c461..c068f82cba 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -34,6 +34,7 @@ export const createActions = context => { stickyColumn, ui, maxScrollLeft, + width, } = context let autoScrollInterval @@ -95,7 +96,7 @@ export const createActions = context => { // Check if we need to start auto-scrolling const $reorder = get(reorder) - const proximityCutoff = 140 + const proximityCutoff = Math.min(140, get(width) / 6) const speedFactor = 8 const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x) const leftProximity = Math.max(0, x - $reorder.gridLeft) diff --git a/packages/frontend-core/src/components/grid/stores/resize.js b/packages/frontend-core/src/components/grid/stores/resize.js index 87b3912848..157465e838 100644 --- a/packages/frontend-core/src/components/grid/stores/resize.js +++ b/packages/frontend-core/src/components/grid/stores/resize.js @@ -29,6 +29,7 @@ export const createActions = context => { // Prevent propagation to stop reordering triggering e.stopPropagation() + e.preventDefault() ui.actions.blur() // Find and cache index From 58b23a736fc080c997bba37fedb0e6365f060179 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 14:44:52 +0100 Subject: [PATCH 038/296] Remove add new row tooltip when caused by inline filters --- .../frontend-core/src/components/grid/layout/NewRow.svelte | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/layout/NewRow.svelte b/packages/frontend-core/src/components/grid/layout/NewRow.svelte index 66c42e5303..f5de870f7e 100644 --- a/packages/frontend-core/src/components/grid/layout/NewRow.svelte +++ b/packages/frontend-core/src/components/grid/layout/NewRow.svelte @@ -30,6 +30,7 @@ refreshing, config, filter, + inlineFilters, columnRenderMap, } = getContext("grid") @@ -157,7 +158,11 @@ {#if !visible && !selectedRowCount && $config.canAddRows} From 0f7e576f19981c3f93b3e856f9953b3849c8478d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 14:52:23 +0100 Subject: [PATCH 039/296] Revert unnecessary changes --- .../src/components/grid/stores/columns.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/columns.js b/packages/frontend-core/src/components/grid/stores/columns.js index 8ceaae105f..551eeb364f 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.js +++ b/packages/frontend-core/src/components/grid/stores/columns.js @@ -48,28 +48,22 @@ export const createStores = () => { export const deriveStores = context => { const { columns, stickyColumn } = context - // Quick access to all columns - const allColumns = derived( + // Derive if we have any normal columns + const hasNonAutoColumn = derived( [columns, stickyColumn], ([$columns, $stickyColumn]) => { let allCols = $columns || [] if ($stickyColumn) { allCols = [...allCols, $stickyColumn] } - return allCols + const normalCols = allCols.filter(column => { + return !column.schema?.autocolumn + }) + return normalCols.length > 0 } ) - // Derive if we have any normal columns - const hasNonAutoColumn = derived(allColumns, $allColumns => { - const normalCols = $allColumns.filter(column => { - return !column.schema?.autocolumn - }) - return normalCols.length > 0 - }) - return { - allColumns, hasNonAutoColumn, } } From 5df34310d4f2018569be040beb9f5f29359d07d2 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 17 Apr 2024 14:53:27 +0100 Subject: [PATCH 040/296] Redo changes --- .../src/components/grid/stores/columns.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/columns.js b/packages/frontend-core/src/components/grid/stores/columns.js index 551eeb364f..8ceaae105f 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.js +++ b/packages/frontend-core/src/components/grid/stores/columns.js @@ -48,22 +48,28 @@ export const createStores = () => { export const deriveStores = context => { const { columns, stickyColumn } = context - // Derive if we have any normal columns - const hasNonAutoColumn = derived( + // Quick access to all columns + const allColumns = derived( [columns, stickyColumn], ([$columns, $stickyColumn]) => { let allCols = $columns || [] if ($stickyColumn) { allCols = [...allCols, $stickyColumn] } - const normalCols = allCols.filter(column => { - return !column.schema?.autocolumn - }) - return normalCols.length > 0 + return allCols } ) + // Derive if we have any normal columns + const hasNonAutoColumn = derived(allColumns, $allColumns => { + const normalCols = $allColumns.filter(column => { + return !column.schema?.autocolumn + }) + return normalCols.length > 0 + }) + return { + allColumns, hasNonAutoColumn, } } From ad10679115b22f07e055a21e96d4ff2ee4aa0a75 Mon Sep 17 00:00:00 2001 From: mikesealey Date: Wed, 17 Apr 2024 16:27:23 +0100 Subject: [PATCH 041/296] saving progress based on review reccomendations --- packages/client/manifest.json | 11 +++++------ packages/client/src/components/app/Layout.svelte | 2 +- packages/client/src/components/app/SidePanel.svelte | 4 ++-- packages/client/src/stores/sidePanel.js | 9 ++++----- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index c9e28e202b..cb85768adc 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -6724,18 +6724,17 @@ "showEmptyState": false, "draggable": false, "info": "Side panels are hidden by default. They will only be revealed when triggered by the 'Open Side Panel' action.", - "sendEvents": true, "settings": [ { "type": "boolean", - "key": "clickOutsideToClose", - "label": "Click outside to close", - "defaultValue": true + "key": "ignoreClicksOutside", + "label": "Ignore clicks outside", + "defaultValue": false }, { "type": "event", - "key": "onSidePanelClose", - "label": "On side panel close" + "key": "onClose", + "label": "On close" } ] }, diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index bae2bd0faf..617658c754 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -76,7 +76,7 @@ $: autoCloseSidePanel = !$builderStore.inBuilder && $sidePanelStore.open && - $sidePanelStore.clickOutsideToClose + $sidePanelStore.ignoreClicksOutside $: screenId = $builderStore.inBuilder ? `${$builderStore.screen?._id}-screen` : "screen" diff --git a/packages/client/src/components/app/SidePanel.svelte b/packages/client/src/components/app/SidePanel.svelte index 624617ad69..8b0b395649 100644 --- a/packages/client/src/components/app/SidePanel.svelte +++ b/packages/client/src/components/app/SidePanel.svelte @@ -6,7 +6,7 @@ getContext("sdk") export let sidePanelClose - export let clickOutsideToClose + export let ignoreClicksOutside // Automatically show and hide the side panel when inside the builder. // For some unknown reason, svelte reactivity breaks if we reference the @@ -30,7 +30,7 @@ } $: { - sidePanelStore.actions.setSidepanelState(clickOutsideToClose) + sidePanelStore.actions.setIgnoreClicksOutside(ignoreClicksOutside) } // Derive visibility diff --git a/packages/client/src/stores/sidePanel.js b/packages/client/src/stores/sidePanel.js index df66eca01c..b25914c484 100644 --- a/packages/client/src/stores/sidePanel.js +++ b/packages/client/src/stores/sidePanel.js @@ -3,7 +3,7 @@ import { writable, derived } from "svelte/store" export const createSidePanelStore = () => { const initialState = { contentId: null, - clickOutsideToClose: true, + ignoreClicksOutside: true, } const store = writable(initialState) const derivedStore = derived(store, $store => { @@ -33,10 +33,9 @@ export const createSidePanelStore = () => { }, 50) } - const setSidepanelState = bool => { - clearTimeout(timeout) + const setIgnoreClicksOutside = bool => { store.update(state => { - state.clickOutsideToClose = bool + state.ignoreClicksOutside = bool return state }) } @@ -45,7 +44,7 @@ export const createSidePanelStore = () => { actions: { open, close, - setSidepanelState, + setIgnoreClicksOutside, }, } } From 6c38d32549a79f04ea00f10e21c84f2c540796ff Mon Sep 17 00:00:00 2001 From: mikesealey Date: Thu, 18 Apr 2024 10:08:48 +0100 Subject: [PATCH 042/296] reinstates actions running when sidepanel closes --- packages/client/src/components/app/SidePanel.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/app/SidePanel.svelte b/packages/client/src/components/app/SidePanel.svelte index 8b0b395649..827ed2ab95 100644 --- a/packages/client/src/components/app/SidePanel.svelte +++ b/packages/client/src/components/app/SidePanel.svelte @@ -5,7 +5,7 @@ const { styleable, sidePanelStore, builderStore, dndIsDragging } = getContext("sdk") - export let sidePanelClose + export let onClose export let ignoreClicksOutside // Automatically show and hide the side panel when inside the builder. @@ -48,8 +48,8 @@ } const handleSidePanelClose = async () => { - if (sidePanelClose) { - await sidePanelClose() + if (onClose) { + await onClose() } } From 088c210de85e260c946d2b105687cd155c16d298 Mon Sep 17 00:00:00 2001 From: mikesealey Date: Thu, 18 Apr 2024 12:11:45 +0100 Subject: [PATCH 043/296] sets ignoreClickOutside to each side panel --- packages/client/src/components/app/Layout.svelte | 2 +- packages/client/src/components/app/SidePanel.svelte | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index 617658c754..bfbac8f4f1 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -76,7 +76,7 @@ $: autoCloseSidePanel = !$builderStore.inBuilder && $sidePanelStore.open && - $sidePanelStore.ignoreClicksOutside + !$sidePanelStore.ignoreClicksOutside $: screenId = $builderStore.inBuilder ? `${$builderStore.screen?._id}-screen` : "screen" diff --git a/packages/client/src/components/app/SidePanel.svelte b/packages/client/src/components/app/SidePanel.svelte index 827ed2ab95..bff5a78837 100644 --- a/packages/client/src/components/app/SidePanel.svelte +++ b/packages/client/src/components/app/SidePanel.svelte @@ -29,9 +29,9 @@ } } - $: { - sidePanelStore.actions.setIgnoreClicksOutside(ignoreClicksOutside) - } + // $: { + + // } // Derive visibility $: open = $sidePanelStore.contentId === $component.id @@ -43,6 +43,7 @@ let renderKey = null $: { if (open) { + sidePanelStore.actions.setIgnoreClicksOutside(ignoreClicksOutside) renderKey = Math.random() } } From 6bbdf0e4744e2a42283eeeb36d2c4cd0e9d0f2bc Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 18 Apr 2024 17:04:26 +0100 Subject: [PATCH 044/296] Bindings support for views and table row searches --- .../buttons/TableFilterButton.svelte | 71 ++++++++++++------- .../controls/FilterEditor/FilterDrawer.svelte | 1 + .../controls/FilterEditor/FilterUsers.svelte | 21 +++--- .../server/src/api/controllers/row/index.ts | 15 +++- .../src/api/controllers/row/utils/utils.ts | 41 ++++++++++- .../server/src/api/controllers/row/views.ts | 14 +++- 6 files changed, 122 insertions(+), 41 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte index 91456da655..26b6624160 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte @@ -1,7 +1,9 @@ - + {text} - - dispatch("change", tempValue)} - > -
- (tempValue = e.detail)} - /> -
-
-
- + + + (tempValue = e.detail)} + {bindings} + /> + diff --git a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterDrawer.svelte b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterDrawer.svelte index 7f1ee8010d..74c081cd5b 100644 --- a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterDrawer.svelte @@ -304,6 +304,7 @@ OperatorOptions.ContainsAny.value, ].includes(filter.operator)} disabled={filter.noValue} + type={filter.valueType} /> {:else} diff --git a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterUsers.svelte b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterUsers.svelte index 88383ba170..4613b8c40f 100644 --- a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterUsers.svelte +++ b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterUsers.svelte @@ -1,7 +1,6 @@ - option.email} - getOptionValue={option => option._id} - {disabled} -/> +
+ option.email} + getOptionValue={option => option._id} + {disabled} + /> +
diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index c3d1f2cb47..7f99105ea4 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -2,7 +2,7 @@ import stream from "stream" import archiver from "archiver" import { quotas } from "@budibase/pro" -import { objectStore } from "@budibase/backend-core" +import { objectStore, context } from "@budibase/backend-core" import * as internal from "./internal" import * as external from "./external" import { isExternalTableID } from "../../../integrations/utils" @@ -198,8 +198,21 @@ export async function destroy(ctx: UserCtx) { export async function search(ctx: Ctx) { const tableId = utils.getTableId(ctx) + // Current user context for bindable search + const { _id, _rev, firstName, lastName, email, status, roleId } = ctx.user + + await context.ensureSnippetContext() + + const enrichedQuery = await utils.enrichSearchContext( + { ...ctx.request.body.query }, + { + user: { _id, _rev, firstName, lastName, email, status, roleId }, + } + ) + const searchParams: RowSearchParams = { ...ctx.request.body, + query: enrichedQuery, tableId, } diff --git a/packages/server/src/api/controllers/row/utils/utils.ts b/packages/server/src/api/controllers/row/utils/utils.ts index f387a468cf..503f139783 100644 --- a/packages/server/src/api/controllers/row/utils/utils.ts +++ b/packages/server/src/api/controllers/row/utils/utils.ts @@ -7,6 +7,8 @@ import { FieldType, RelationshipsJson, Row, + SearchRowRequest, + SearchRowResponse, Table, UserCtx, } from "@budibase/types" @@ -22,7 +24,7 @@ import { getInternalRowId, } from "./basic" import sdk from "../../../../sdk" - +import { processStringSync } from "@budibase/string-templates" import validateJs from "validate.js" validateJs.extend(validateJs.validators.datetime, { @@ -187,3 +189,40 @@ export async function sqlOutputProcessing( export function isUserMetadataTable(tableId: string) { return tableId === InternalTables.USER_METADATA } + +export async function enrichSearchContext( + fields: Record, + inputs = {}, + helpers = true +): Promise> { + const enrichedQuery: Record = {} + if (!fields || !inputs) { + return enrichedQuery + } + const parameters = { ...inputs } + // enrich the fields with dynamic parameters + for (let key of Object.keys(fields)) { + if (fields[key] == null) { + continue + } + if (typeof fields[key] === "object") { + // enrich nested fields object + enrichedQuery[key] = await enrichSearchContext( + fields[key], + parameters, + helpers + ) + } else if (typeof fields[key] === "string") { + // enrich string value as normal + enrichedQuery[key] = processStringSync(fields[key], parameters, { + noEscaping: true, + noHelpers: !helpers, + escapeNewlines: true, + }) + } else { + enrichedQuery[key] = fields[key] + } + } + + return enrichedQuery +} diff --git a/packages/server/src/api/controllers/row/views.ts b/packages/server/src/api/controllers/row/views.ts index 2644446d82..18953ebe88 100644 --- a/packages/server/src/api/controllers/row/views.ts +++ b/packages/server/src/api/controllers/row/views.ts @@ -9,7 +9,8 @@ import { } from "@budibase/types" import { dataFilters } from "@budibase/shared-core" import sdk from "../../../sdk" -import { db } from "@budibase/backend-core" +import { db, context } from "@budibase/backend-core" +import { enrichSearchContext, userSearchFromContext } from "./utils" export async function searchView( ctx: UserCtx @@ -56,10 +57,19 @@ export async function searchView( }) } + // Current user search context. + const { _id, _rev, firstName, lastName, email, status, roleId } = ctx.user + + await context.ensureSnippetContext() + + const enrichedQuery = await enrichSearchContext(query, { + user: { _id, _rev, firstName, lastName, email, status, roleId }, + }) + const searchOptions: RequiredKeys & RequiredKeys> = { tableId: view.tableId, - query, + query: enrichedQuery, fields: viewFields, ...getSortOptions(body, view), limit: body.limit, From 80a6afd54f03a6dfb37a1b3f0cce763fcace349f Mon Sep 17 00:00:00 2001 From: mikesealey Date: Fri, 19 Apr 2024 10:41:39 +0100 Subject: [PATCH 045/296] closes side panel when navigating away regardless of ignoreClicksOutside --- packages/client/src/components/app/Layout.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index bfbac8f4f1..dccb061254 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -284,7 +284,9 @@ url={navItem.url} subLinks={navItem.subLinks} internalLink={navItem.internalLink} - on:clickLink={() => (mobileOpen = false)} + on:clickLink={(() => (mobileOpen = false), + console.log("287"), + sidePanelStore.actions.close)} leftNav={navigation === "Left"} {mobile} {navStateStore} From 237bc707581900f3f9bbcfff597d88d90a344454 Mon Sep 17 00:00:00 2001 From: mikesealey Date: Fri, 19 Apr 2024 10:58:25 +0100 Subject: [PATCH 046/296] removes console.log() --- packages/client/src/components/app/Layout.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index dccb061254..363a464143 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -285,7 +285,6 @@ subLinks={navItem.subLinks} internalLink={navItem.internalLink} on:clickLink={(() => (mobileOpen = false), - console.log("287"), sidePanelStore.actions.close)} leftNav={navigation === "Left"} {mobile} From bdf15b21b1f62cea09a3c03d5e0b8c7fc9260d66 Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 19 Apr 2024 11:49:20 +0100 Subject: [PATCH 047/296] Fixes for filter drawer padding --- .../buttons/TableFilterButton.svelte | 19 ++++++++++--------- .../src/components/FilterBuilder.svelte | 1 - 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte index 0fc3fd505e..140cac1533 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte @@ -1,6 +1,6 @@ @@ -284,8 +289,7 @@ url={navItem.url} subLinks={navItem.subLinks} internalLink={navItem.internalLink} - on:clickLink={(() => (mobileOpen = false), - sidePanelStore.actions.close)} + on:clickLink={handleClickLink} leftNav={navigation === "Left"} {mobile} {navStateStore} From 4c0d3ed5f38781a5db5e024993b3e7de7e6692ad Mon Sep 17 00:00:00 2001 From: mikesealey Date: Fri, 19 Apr 2024 14:45:57 +0100 Subject: [PATCH 049/296] runs the closeSidePanel function when navigating away using a button-action --- packages/client/src/utils/buttonActions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index d883ee1b55..4ab7490ae7 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -240,6 +240,7 @@ const triggerAutomationHandler = async action => { const navigationHandler = action => { const { url, peek, externalNewTab } = action.parameters routeStore.actions.navigate(url, peek, externalNewTab) + closeSidePanelHandler() } const queryExecutionHandler = async action => { From b080821f295c2e3c77922a54972e0d4e1c2494d8 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 23 Apr 2024 10:31:18 +0100 Subject: [PATCH 050/296] Update helm charts to account for temp bucket (#13544) * update helm charts to account for temp bucket * typo * move location of vars --- charts/budibase/templates/app-service-deployment.yaml | 2 ++ .../templates/automation-worker-service-deployment.yaml | 2 ++ charts/budibase/templates/worker-service-deployment.yaml | 2 ++ charts/budibase/values.yaml | 3 +++ 4 files changed, 9 insertions(+) diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml index b380908dd1..ed7166ec5d 100644 --- a/charts/budibase/templates/app-service-deployment.yaml +++ b/charts/budibase/templates/app-service-deployment.yaml @@ -106,6 +106,8 @@ spec: value: {{ .Values.services.objectStore.globalBucketName | quote }} - name: BACKUPS_BUCKET_NAME value: {{ .Values.services.objectStore.backupsBucketName | quote }} + - name: TEMP_BUCKET_NAME + value: {{ .Values.globals.tempBucketName | quote }} - name: PORT value: {{ .Values.services.apps.port | quote }} {{ if .Values.services.worker.publicApiRateLimitPerSecond }} diff --git a/charts/budibase/templates/automation-worker-service-deployment.yaml b/charts/budibase/templates/automation-worker-service-deployment.yaml index 51fa9ee4bb..3c6f94ae9e 100644 --- a/charts/budibase/templates/automation-worker-service-deployment.yaml +++ b/charts/budibase/templates/automation-worker-service-deployment.yaml @@ -107,6 +107,8 @@ spec: value: {{ .Values.services.objectStore.globalBucketName | quote }} - name: BACKUPS_BUCKET_NAME value: {{ .Values.services.objectStore.backupsBucketName | quote }} + - name: TEMP_BUCKET_NAME + value: {{ .Values.globals.tempBucketName | quote }} - name: PORT value: {{ .Values.services.automationWorkers.port | quote }} {{ if .Values.services.worker.publicApiRateLimitPerSecond }} diff --git a/charts/budibase/templates/worker-service-deployment.yaml b/charts/budibase/templates/worker-service-deployment.yaml index e37b2bc0e4..66a9bb6c14 100644 --- a/charts/budibase/templates/worker-service-deployment.yaml +++ b/charts/budibase/templates/worker-service-deployment.yaml @@ -106,6 +106,8 @@ spec: value: {{ .Values.services.objectStore.globalBucketName | quote }} - name: BACKUPS_BUCKET_NAME value: {{ .Values.services.objectStore.backupsBucketName | quote }} + - name: TEMP_BUCKET_NAME + value: {{ .Values.globals.tempBucketName | quote }} - name: PORT value: {{ .Values.services.worker.port | quote }} - name: MULTI_TENANCY diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml index 9ace768625..27037cdaa8 100644 --- a/charts/budibase/values.yaml +++ b/charts/budibase/values.yaml @@ -121,6 +121,9 @@ globals: # to the old value for the duration of the rotation. jwtSecretFallback: "" + ## -- If using S3 the bucket name to be used for storing temporary files + tempBucketName: "" + smtp: # -- Whether to enable SMTP or not. enabled: false From 129f2c5bb965e6c5387c6a550dc97dd6d1342139 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 11:52:10 +0100 Subject: [PATCH 051/296] Remove 24 hour time setting from datetime fields --- packages/client/manifest.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 40abc7a9a0..a7d4b57f1a 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -3869,12 +3869,6 @@ "key": "timeOnly", "defaultValue": false }, - { - "type": "boolean", - "label": "24-hour time", - "key": "time24hr", - "defaultValue": false - }, { "type": "boolean", "label": "Ignore time zones", From 2e46287b7e77f3ac059a31d05b5bc0e4716f3df5 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 11:52:24 +0100 Subject: [PATCH 052/296] Remove testing code --- .../[componentId]/new/_components/componentStructure.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json index 494b2736d7..03e22acd4d 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/new/_components/componentStructure.json @@ -68,7 +68,6 @@ "jsonfield", "relationshipfield", "datetimefield", - "newdatetimefield", "multifieldselect", "s3upload", "codescanner", From 4f1220dd26bf2e246c7316923092e4086e24e4aa Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 11:54:44 +0100 Subject: [PATCH 053/296] Restore client date range picker component --- .../src/components/app/DateRangePicker.svelte | 76 +++++++++++++++++++ packages/client/src/components/app/index.js | 1 + 2 files changed, 77 insertions(+) create mode 100644 packages/client/src/components/app/DateRangePicker.svelte diff --git a/packages/client/src/components/app/DateRangePicker.svelte b/packages/client/src/components/app/DateRangePicker.svelte new file mode 100644 index 0000000000..8131f3bd89 --- /dev/null +++ b/packages/client/src/components/app/DateRangePicker.svelte @@ -0,0 +1,76 @@ + + +
+