From afffd4d234d551a50d1c1b41977bf8db87242a3d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 2 Nov 2023 15:37:18 +0000 Subject: [PATCH 001/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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/179] 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 @@ From 27056990aa4f07e776bda257a9fe9eadf79d8f2f Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 9 Apr 2024 11:52:32 +0100 Subject: [PATCH 024/179] Add very early work on date range picker --- .../Form/Core/DatePicker/DatePicker.svelte | 186 +++++++++++- .../DatePicker/FlatpickrDatePicker.svelte | 268 ------------------ .../Core/DatePicker/SpectrumDatePicker.svelte | 183 ------------ .../bbui/src/Form/Core/DateRangePicker.svelte | 69 +++++ packages/bbui/src/Form/Core/index.js | 1 + packages/bbui/src/Form/DatePicker.svelte | 11 +- packages/bbui/src/Form/DateRangePicker.svelte | 34 +++ packages/bbui/src/index.js | 50 ++-- .../settings/backups/index.svelte | 12 +- 9 files changed, 313 insertions(+), 501 deletions(-) delete mode 100644 packages/bbui/src/Form/Core/DatePicker/FlatpickrDatePicker.svelte delete mode 100644 packages/bbui/src/Form/Core/DatePicker/SpectrumDatePicker.svelte create mode 100644 packages/bbui/src/Form/Core/DateRangePicker.svelte create mode 100644 packages/bbui/src/Form/DateRangePicker.svelte diff --git a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte index a03be24753..194bed7f9a 100644 --- a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte @@ -1,15 +1,183 @@ - + + + on:open={onOpen} + on:close={onClose} + {anchor} + portalTarget={appendTo} + {align} +> + {#if isOpen} +
+ {#if showCalendar} + + {/if} + +
+ {/if} +
+ + 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 038/179] 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 3cdc0525c61758c621a9f380a416c8f91990496e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 15 Apr 2024 15:29:11 +0100 Subject: [PATCH 039/179] Fix crashing when swapping conditional UI settings between invalid value types --- .../_components/Component/ConditionalUIDrawer.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte index 23e7bced93..6558ba9dc2 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte @@ -189,6 +189,7 @@ + {#if keyBindings} + { + field.name = e.detail + changed() + }} + disabled={readOnly} + value={field.name} + {allowJS} + {allowHelpers} + drawerLeft={bindingDrawerLeft} + /> + {:else} + + {/if} {#if isJsonArray(field.value)} (value = e.detail)} + /> +
diff --git a/packages/client/src/components/app/index.js b/packages/client/src/components/app/index.js index 1c5722eb40..e23e19704c 100644 --- a/packages/client/src/components/app/index.js +++ b/packages/client/src/components/app/index.js @@ -29,6 +29,7 @@ export { default as image } from "./Image.svelte" export { default as embed } from "./Embed.svelte" export { default as icon } from "./Icon.svelte" export { default as backgroundimage } from "./BackgroundImage.svelte" +export { default as daterangepicker } from "./DateRangePicker.svelte" export { default as cardstat } from "./CardStat.svelte" export { default as spectrumcard } from "./SpectrumCard.svelte" export { default as tag } from "./Tag.svelte" From f0102286295bb5f788d8db42ebbdf827b7ec5026 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 11:59:14 +0100 Subject: [PATCH 087/179] Respect app custom colour choices where possible --- packages/bbui/src/Form/Core/DatePicker/Calendar.svelte | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte index b073ac78f9..83692ff898 100644 --- a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte @@ -198,10 +198,13 @@ } .spectrum-Calendar-date.is-today.is-selected, .spectrum-Calendar-date.is-today.is-selected::before { - border-color: var(--spectrum-global-color-blue-700); + border-color: var( + --primaryColorHover, + var(--spectrum-global-color-blue-700) + ); } .spectrum-Calendar-date.is-selected:not(.is-range-selection) { - background: var(--spectrum-global-color-blue-400); + background: var(--primaryColor, var(--spectrum-global-color-blue-400)); } .spectrum-Calendar tr { box-sizing: content-box; From a99c15fb26ec1d48c3fe55deff990083c77a0e2a Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 12:05:30 +0100 Subject: [PATCH 088/179] Fix wrong class name being used to ignore grid keypresses when editing dates in modals --- .../src/components/grid/overlays/KeyboardManager.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte index 4d2ff87b5c..cef4144833 100644 --- a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte +++ b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte @@ -20,7 +20,7 @@ const ignoredOriginSelectors = [ ".spectrum-Modal", - ".spectrum-Calendar", + ".date-time-popover", "#builder-side-panel-container", "[data-grid-ignore]", ] From 4d24b2ba1c7c1ec6fac84c3eee43bdad607a47dc Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 23 Apr 2024 17:00:15 +0100 Subject: [PATCH 089/179] Refactor new datepicker so that we can use a custom grid cell, and fix issues with timezone offsets --- .../src/Form/Core/DatePicker/Calendar.svelte | 11 +- .../Form/Core/DatePicker/DatePicker.svelte | 122 ++---------------- .../DatePickerPopoverContents.svelte | 102 +++++++++++++++ .../Form/Core/DatePicker/NumberInput.svelte | 2 +- .../Form/Core/DatePicker/TimePicker.svelte | 10 +- packages/bbui/src/Form/Core/index.js | 1 + packages/bbui/src/helpers.js | 43 +++++- .../src/components/grid/cells/DateCell.svelte | 116 ++++++++++++----- .../components/grid/cells/LongFormCell.svelte | 4 +- .../components/grid/cells/OptionsCell.svelte | 4 +- .../grid/cells/RelationshipCell.svelte | 4 +- .../src/components/grid/layout/Grid.svelte | 6 +- .../src/components/grid/lib/constants.js | 3 +- .../src/components/grid/stores/viewport.js | 9 +- 14 files changed, 269 insertions(+), 168 deletions(-) create mode 100644 packages/bbui/src/Form/Core/DatePicker/DatePickerPopoverContents.svelte diff --git a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte index 83692ff898..bc06530044 100644 --- a/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/Calendar.svelte @@ -3,10 +3,11 @@ import Select from "../../Select.svelte" import dayjs from "dayjs" import NumberInput from "./NumberInput.svelte" + import { createEventDispatcher } from "svelte" export let value - export let onChange + const dispatch = createEventDispatcher() const DaysOfWeek = [ "Monday", "Tuesday", @@ -58,7 +59,10 @@ const handleDateChange = date => { const base = value || now - onChange(base.year(date.year()).month(date.month()).date(date.date())) + dispatch( + "change", + base.year(date.year()).month(date.month()).date(date.date()) + ) } export const setDate = date => { @@ -224,6 +228,9 @@ .spectrum-Calendar-date.is-selected { color: white; } + .spectrum-Calendar-dayOfWeek { + color: var(--spectrum-global-color-gray-600); + } /* Style select */ .month-selector :global(.spectrum-Picker) { diff --git a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte index a29746ee75..4587195865 100644 --- a/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/DatePicker.svelte @@ -3,13 +3,10 @@ import "@spectrum-css/inputgroup/dist/index-vars.css" import "@spectrum-css/textfield/dist/index-vars.css" import Popover from "../../../Popover/Popover.svelte" - import dayjs from "dayjs" - import { createEventDispatcher, onMount } from "svelte" - import TimePicker from "./TimePicker.svelte" - import Calendar from "./Calendar.svelte" + import { onMount } from "svelte" import DateInput from "./DateInput.svelte" - import ActionButton from "../../../ActionButton/ActionButton.svelte" import { parseDate } from "../../../helpers" + import DatePickerPopoverContents from "./DatePickerPopoverContents.svelte" export let id = null export let disabled = false @@ -25,74 +22,18 @@ export let api = null export let align = "left" - const dispatch = createEventDispatcher() - let isOpen = false let anchor let popover - let calendar - $: parsedValue = parseDate(value, { timeOnly, dateOnly: !enableTime }) - $: showCalendar = !timeOnly - $: showTime = enableTime || timeOnly - - 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) - popover?.hide() - } - } + $: parsedValue = parseDate(value, { timeOnly, enableTime }) const onOpen = () => { isOpen = true - if (useKeyboardShortcuts) { - document.addEventListener("keyup", clearDateOnBackspace) - } } const onClose = () => { isOpen = false - if (useKeyboardShortcuts) { - document.removeEventListener("keyup", clearDateOnBackspace) - } - } - - const handleChange = date => { - if (!date) { - dispatch("change", null) - return - } - let newValue = date.toISOString() - - // Time only fields always ignore timezones, otherwise they make no sense. - // For non-timezone-aware fields, create an ISO 8601 timestamp of the exact - // time picked, without timezone - const offsetForTimezone = (enableTime && ignoreTimezones) || timeOnly - if (offsetForTimezone) { - const offset = new Date().getTimezoneOffset() * 60000 - newValue = new Date(date.valueOf() - offset).toISOString().slice(0, -1) - } - - // For date-only fields, construct a manual timestamp string without a time - // or time zone - else if (!enableTime) { - const year = date.year() - const month = `${date.month() + 1}`.padStart(2, "0") - const day = `${date.date()}`.padStart(2, "0") - newValue = `${year}-${month}-${day}T00:00:00.000` - } - - dispatch("change", newValue) - } - - const setToNow = () => { - const now = dayjs() - calendar?.setDate(now) - handleChange(now) } onMount(() => { @@ -130,54 +71,13 @@ {align} > {#if isOpen} -
- {#if showCalendar} - - {/if} - -
+ {/if} - - diff --git a/packages/bbui/src/Form/Core/DatePicker/DatePickerPopoverContents.svelte b/packages/bbui/src/Form/Core/DatePicker/DatePickerPopoverContents.svelte new file mode 100644 index 0000000000..f1bb809b29 --- /dev/null +++ b/packages/bbui/src/Form/Core/DatePicker/DatePickerPopoverContents.svelte @@ -0,0 +1,102 @@ + + +
+ {#if showCalendar} + handleChange(e.detail)} + bind:this={calendar} + /> + {/if} + +
+ + diff --git a/packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte b/packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte index 91dd95ff5f..dc4886d28d 100644 --- a/packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/NumberInput.svelte @@ -33,7 +33,7 @@ font-weight: bold; font-family: var(--font-sans); -webkit-font-smoothing: antialiased; - box-sizing: content-box; + box-sizing: content-box !important; } input:focus, input:hover { diff --git a/packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte b/packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte index adf2a5e87a..047e5a4f08 100644 --- a/packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker/TimePicker.svelte @@ -2,18 +2,20 @@ import { cleanInput } from "./utils" import dayjs from "dayjs" import NumberInput from "./NumberInput.svelte" + import { createEventDispatcher } from "svelte" export let value - export let onChange + + const dispatch = createEventDispatcher() $: displayValue = value || dayjs() const handleHourChange = e => { - onChange(displayValue.hour(parseInt(e.target.value))) + dispatch("change", displayValue.hour(parseInt(e.target.value))) } const handleMinuteChange = e => { - onChange(displayValue.minute(parseInt(e.target.value))) + dispatch("change", displayValue.minute(parseInt(e.target.value))) } const cleanHour = cleanInput({ max: 23, pad: 2, fallback: "00" }) @@ -51,7 +53,7 @@ .time-picker span { font-weight: bold; font-size: 18px; - z-index: -1; + z-index: 0; margin-bottom: 1px; } diff --git a/packages/bbui/src/Form/Core/index.js b/packages/bbui/src/Form/Core/index.js index 533a1956c5..7117b90081 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 CoreDatePickerPopoverContents } from "./DatePicker/DatePickerPopoverContents.svelte" export { default as CoreDateRangePicker } from "./DateRangePicker.svelte" export { default as CoreDropzone } from "./Dropzone.svelte" export { default as CoreStepper } from "./Stepper.svelte" diff --git a/packages/bbui/src/helpers.js b/packages/bbui/src/helpers.js index c98ebad2c7..4448527fea 100644 --- a/packages/bbui/src/helpers.js +++ b/packages/bbui/src/helpers.js @@ -117,7 +117,9 @@ export const copyToClipboard = value => { }) } -export const parseDate = (value, { dateOnly } = {}) => { +// Parsed a date value. This is usually an ISO string, but can be a +// bunch of different formats and shapes depending on schema flags. +export const parseDate = (value, { enableTime = true }) => { // If empty then invalid if (!value) { return null @@ -131,7 +133,7 @@ export const parseDate = (value, { dateOnly } = {}) => { } // If date only, check for cases where we received a UTC string - else if (dateOnly && value.endsWith("Z")) { + else if (!enableTime && value.endsWith("Z")) { value = value.split("Z")[0] } } @@ -148,7 +150,42 @@ export const parseDate = (value, { dateOnly } = {}) => { return dayjs(Math.floor(parsedDate.valueOf() / 1000) * 1000) } -export const getDateDisplayValue = (value, { enableTime, timeOnly }) => { +// Stringifies a dayjs object to create an ISO string that respects the various +// schema flags +export const stringifyDate = ( + value, + { enableTime = true, timeOnly = false, ignoreTimezones = false } +) => { + if (!value) { + return null + } + + // Time only fields always ignore timezones, otherwise they make no sense. + // For non-timezone-aware fields, create an ISO 8601 timestamp of the exact + // time picked, without timezone + const offsetForTimezone = (enableTime && ignoreTimezones) || timeOnly + if (offsetForTimezone) { + // Ensure we use the correct offset for the date + const referenceDate = timeOnly ? new Date() : value.toDate() + const offset = referenceDate.getTimezoneOffset() * 60000 + return new Date(value.valueOf() - offset).toISOString().slice(0, -1) + } + + // For date-only fields, construct a manual timestamp string without a time + // or time zone + else if (!enableTime) { + const year = value.year() + const month = `${value.month() + 1}`.padStart(2, "0") + const day = `${value.date()}`.padStart(2, "0") + return `${year}-${month}-${day}T00:00:00.000` + } +} + +// Formats a dayjs date according to schema flags +export const getDateDisplayValue = ( + value, + { enableTime = true, timeOnly = false } +) => { if (!value?.isValid()) { return "" } diff --git a/packages/frontend-core/src/components/grid/cells/DateCell.svelte b/packages/frontend-core/src/components/grid/cells/DateCell.svelte index 019a0db9c2..394b6e1f43 100644 --- a/packages/frontend-core/src/components/grid/cells/DateCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DateCell.svelte @@ -1,6 +1,13 @@ -
+ + +
{displayValue}
@@ -55,17 +107,14 @@ {/if}
-{#if editable} -
- + onChange(e.detail)} - enableTime={!dateOnly} + {enableTime} {timeOnly} - ignoreTimezones={schema.ignoreTimezones} - bind:api={datePickerAPI} - on:open={() => (isOpen = true)} - on:close={() => (isOpen = false)} + {ignoreTimezones} useKeyboardShortcuts={false} />
@@ -80,6 +129,10 @@ align-items: center; flex: 1 1 auto; gap: var(--cell-spacing); + user-select: none; + } + .container.editable:hover { + cursor: pointer; } .value { flex: 1 1 auto; @@ -92,9 +145,10 @@ } .picker { position: absolute; - opacity: 0; - } - .picker :global(.spectrum-Textfield-input) { - width: 100%; + top: 100%; + left: -1px; + background: var(--grid-background-alt); + border: var(--cell-border); + border-radius: 2px; } diff --git a/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte b/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte index 0299e66e2f..b3eab24fa1 100644 --- a/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte @@ -103,8 +103,8 @@ position: absolute; top: 0; left: 0; - width: calc(100% + var(--max-cell-render-width-overflow)); - height: calc(var(--row-height) + var(--max-cell-render-height)); + width: calc(100% + var(--max-cell-render-verflow)); + height: calc(var(--row-height) + var(--max-cell-render-overflow)); z-index: 1; border-radius: 2px; resize: none; diff --git a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte index ede9bd1cff..158451c930 100644 --- a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte @@ -23,7 +23,7 @@ $: values = Array.isArray(value) ? value : [value].filter(x => x != null) $: { // Close when deselected - if (!focused) { + if (!focused && isOpen) { close() } } @@ -219,7 +219,7 @@ flex-direction: column; justify-content: flex-start; align-items: stretch; - max-height: var(--max-cell-render-height); + max-height: var(--max-cell-render-overflow); overflow-y: auto; border: var(--cell-border); box-shadow: 0 0 20px -4px rgba(0, 0, 0, 0.15); diff --git a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte index bf1fe92ef0..a52dd9d53c 100644 --- a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte @@ -35,7 +35,7 @@ $: lookupMap = buildLookupMap(value, isOpen) $: debouncedSearch(searchString) $: { - if (!focused) { + if (!focused && isOpen) { close() } } @@ -451,7 +451,7 @@ left: 0; width: 100%; max-height: calc( - var(--max-cell-render-height) + var(--row-height) - var(--values-height) + var(--max-cell-render-overflow) + var(--row-height) - var(--values-height) ); background: var(--grid-background-alt); border: var(--cell-border); diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte index b6c686fd62..468f49bdec 100644 --- a/packages/frontend-core/src/components/grid/layout/Grid.svelte +++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte @@ -22,8 +22,7 @@ import NewRow from "./NewRow.svelte" import { createGridWebsocket } from "../lib/websocket" import { - MaxCellRenderHeight, - MaxCellRenderWidthOverflow, + MaxCellRenderOverflow, GutterWidth, DefaultRowHeight, } from "../lib/constants" @@ -78,6 +77,7 @@ contentLines, gridFocused, error, + focusedCellId, } = context // Keep config store up to date with props @@ -129,7 +129,7 @@ class:quiet on:mouseenter={() => gridFocused.set(true)} on:mouseleave={() => gridFocused.set(false)} - style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-height:{MaxCellRenderHeight}px; --max-cell-render-width-overflow:{MaxCellRenderWidthOverflow}px; --content-lines:{$contentLines};" + style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-overflow:{MaxCellRenderOverflow}px; --content-lines:{$contentLines};" > {#if showControls}
diff --git a/packages/frontend-core/src/components/grid/lib/constants.js b/packages/frontend-core/src/components/grid/lib/constants.js index a6e6723463..37d829873d 100644 --- a/packages/frontend-core/src/components/grid/lib/constants.js +++ b/packages/frontend-core/src/components/grid/lib/constants.js @@ -1,5 +1,4 @@ export const Padding = 246 -export const MaxCellRenderHeight = 222 export const ScrollBarSize = 8 export const GutterWidth = 72 export const DefaultColumnWidth = 200 @@ -12,4 +11,4 @@ export const NewRowID = "new" export const BlankRowID = "blank" export const RowPageSize = 100 export const FocusedCellMinOffset = 48 -export const MaxCellRenderWidthOverflow = Padding - 3 * ScrollBarSize +export const MaxCellRenderOverflow = Padding - 3 * ScrollBarSize diff --git a/packages/frontend-core/src/components/grid/stores/viewport.js b/packages/frontend-core/src/components/grid/stores/viewport.js index 8df8acd0f4..96a5a954ee 100644 --- a/packages/frontend-core/src/components/grid/stores/viewport.js +++ b/packages/frontend-core/src/components/grid/stores/viewport.js @@ -1,7 +1,6 @@ import { derived } from "svelte/store" import { - MaxCellRenderHeight, - MaxCellRenderWidthOverflow, + MaxCellRenderOverflow, MinColumnWidth, ScrollBarSize, } from "../lib/constants" @@ -95,11 +94,11 @@ export const deriveStores = context => { // Compute the last row index with space to render popovers below it const minBottom = - $height - ScrollBarSize * 3 - MaxCellRenderHeight + offset + $height - ScrollBarSize * 3 - MaxCellRenderOverflow + offset const lastIdx = Math.floor(minBottom / $rowHeight) // Compute the first row index with space to render popovers above it - const minTop = MaxCellRenderHeight + offset + const minTop = MaxCellRenderOverflow + offset const firstIdx = Math.ceil(minTop / $rowHeight) // Use the greater of the two indices so that we prefer content below, @@ -117,7 +116,7 @@ export const deriveStores = context => { let inversionIdx = $visibleColumns.length for (let i = $visibleColumns.length - 1; i >= 0; i--, inversionIdx--) { const rightEdge = $visibleColumns[i].left + $visibleColumns[i].width - if (rightEdge + MaxCellRenderWidthOverflow <= cutoff) { + if (rightEdge + MaxCellRenderOverflow <= cutoff) { break } } From c8446fa5a6d963caeaac71c3cd42749a96f18113 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:12:24 +0000 Subject: [PATCH 090/179] Bump mysql2 from 3.5.2 to 3.9.7 in /packages/server Bumps [mysql2](https://github.com/sidorares/node-mysql2) from 3.5.2 to 3.9.7. - [Release notes](https://github.com/sidorares/node-mysql2/releases) - [Changelog](https://github.com/sidorares/node-mysql2/blob/master/Changelog.md) - [Commits](https://github.com/sidorares/node-mysql2/compare/v3.5.2...v3.9.7) --- updated-dependencies: - dependency-name: mysql2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- packages/server/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/package.json b/packages/server/package.json index b2ac4e7d43..5e25fd3fc5 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -98,7 +98,7 @@ "memorystream": "0.3.1", "mongodb": "^6.3.0", "mssql": "10.0.1", - "mysql2": "3.5.2", + "mysql2": "3.9.7", "node-fetch": "2.6.7", "object-sizeof": "2.6.1", "open": "8.4.0", From 46d8a0698190a24cab9525dd119de5dea4e15261 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 08:52:39 +0100 Subject: [PATCH 091/179] Update grid min size to accomodate new date picker --- .../src/components/app/GridBlock.svelte | 4 +-- .../src/components/grid/cells/DateCell.svelte | 25 ++++++++++--------- .../src/components/grid/layout/Grid.svelte | 5 +++- .../src/components/grid/lib/constants.js | 5 ++-- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/client/src/components/app/GridBlock.svelte b/packages/client/src/components/app/GridBlock.svelte index 55e5a2bd66..deefe6726a 100644 --- a/packages/client/src/components/app/GridBlock.svelte +++ b/packages/client/src/components/app/GridBlock.svelte @@ -149,8 +149,8 @@ border: 1px solid var(--spectrum-global-color-gray-300); border-radius: 4px; overflow: hidden; - min-height: 230px; - height: 410px; + /* min-height: 230px;*/ + /* height: 410px;*/ } div.in-builder :global(*) { pointer-events: none; diff --git a/packages/frontend-core/src/components/grid/cells/DateCell.svelte b/packages/frontend-core/src/components/grid/cells/DateCell.svelte index 394b6e1f43..04d5841f49 100644 --- a/packages/frontend-core/src/components/grid/cells/DateCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DateCell.svelte @@ -48,6 +48,10 @@ const close = () => { isOpen = false + + // Only save the changed value when closing. If the value is unchanged then + // this is handled upstream and no action is taken. + onChange(value) } const onKeyDown = e => { @@ -70,22 +74,19 @@ } const changeDate = (quantity, unit) => { + let newValue if (!value) { - value = dayjs() + newValue = dayjs() } else { - value = dayjs(value).add(quantity, unit) + newValue = dayjs(value).add(quantity, unit) } - debouncedOnChange( - Helpers.stringifyDate(value, { - enableTime, - timeOnly, - ignoreTimezones, - }) - ) + value = Helpers.stringifyDate(newValue, { + enableTime, + timeOnly, + ignoreTimezones, + }) } - const debouncedOnChange = debounce(onChange, 250) - onMount(() => { api = { onKeyDown, @@ -111,7 +112,7 @@
onChange(e.detail)} + on:change={e => (value = e.detail)} {enableTime} {timeOnly} {ignoreTimezones} diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte index 468f49bdec..d62715083a 100644 --- a/packages/frontend-core/src/components/grid/layout/Grid.svelte +++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte @@ -25,6 +25,7 @@ MaxCellRenderOverflow, GutterWidth, DefaultRowHeight, + MinHeight, } from "../lib/constants" export let API = null @@ -129,7 +130,8 @@ class:quiet on:mouseenter={() => gridFocused.set(true)} on:mouseleave={() => gridFocused.set(false)} - style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-overflow:{MaxCellRenderOverflow}px; --content-lines:{$contentLines};" + style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-overflow:{MaxCellRenderOverflow}px; --content-lines:{$contentLines}; --min-height:{MinHeight + + $rowHeight}px;" > {#if showControls}
@@ -219,6 +221,7 @@ position: relative; overflow: hidden; background: var(--grid-background); + min-height: var(--min-height); } .grid, .grid :global(*) { diff --git a/packages/frontend-core/src/components/grid/lib/constants.js b/packages/frontend-core/src/components/grid/lib/constants.js index 37d829873d..1a01c9f1bd 100644 --- a/packages/frontend-core/src/components/grid/lib/constants.js +++ b/packages/frontend-core/src/components/grid/lib/constants.js @@ -1,4 +1,4 @@ -export const Padding = 246 +export const Padding = 400 export const ScrollBarSize = 8 export const GutterWidth = 72 export const DefaultColumnWidth = 200 @@ -11,4 +11,5 @@ export const NewRowID = "new" export const BlankRowID = "blank" export const RowPageSize = 100 export const FocusedCellMinOffset = 48 -export const MaxCellRenderOverflow = Padding - 3 * ScrollBarSize +export const MaxCellRenderOverflow = 222 +export const MinHeight = Padding + SmallRowHeight From 2fc96549aa893bceef425af11237cc0914021f63 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 24 Apr 2024 12:05:06 +0000 Subject: [PATCH 092/179] Bump version to 2.23.12 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 728cddc194..94631c6820 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.23.11", + "version": "2.23.12", "npmClient": "yarn", "packages": [ "packages/*", From 4ce7162bb09ef865f641ca9fc453cd21cd9e4552 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 24 Apr 2024 15:20:10 +0100 Subject: [PATCH 093/179] wip --- .../src/api/routes/tests/search.spec.ts | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index 698ea0c10b..cc3bde3a07 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -3,6 +3,7 @@ import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import * as setup from "./utilities" import { + AutoFieldSubType, Datasource, EmptyFilterOption, FieldType, @@ -18,12 +19,12 @@ import _ from "lodash" jest.unmock("mssql") describe.each([ - ["internal", undefined], - ["internal-sqs", undefined], + // ["internal", undefined], + // ["internal-sqs", undefined], [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], - [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], - [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], - [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], + // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], + // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], + // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/api/:sourceId/search (%s)", (name, dsProvider) => { const isSqs = name === "internal-sqs" const isInternal = name === "internal" @@ -675,4 +676,27 @@ describe.each([ }).toContainExactly([{ num: SMALL }, { num: MEDIUM }])) }) }) + + isInternal && + describe.only("auto", () => { + beforeAll(async () => { + await createTable({ + auto: { + name: "auto", + type: FieldType.AUTO, + autocolumn: true, + subtype: AutoFieldSubType.AUTO_ID, + }, + }) + await createRows([{}, {}, {}]) + }) + + describe("equal", () => { + it("successfully finds a row", () => + expectQuery({ equal: { auto: 1 } }).toContainExactly([{ auto: 1 }])) + + it("fails to find nonexistent row", () => + expectQuery({ equal: { auto: 0 } }).toFindNothing()) + }) + }) }) From 849253faba49fd79917780e49bcba9de85df81d8 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 24 Apr 2024 15:37:47 +0100 Subject: [PATCH 094/179] Bringing back the old mechanism of returning the client library through a pre-signed URL, rather than always serving through the service. --- .../backend-core/src/objectStore/buckets/app.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/app.ts b/packages/backend-core/src/objectStore/buckets/app.ts index 43bc965c65..74fdd2e92a 100644 --- a/packages/backend-core/src/objectStore/buckets/app.ts +++ b/packages/backend-core/src/objectStore/buckets/app.ts @@ -13,23 +13,16 @@ export function clientLibraryPath(appId: string) { * due to issues with the domain we were unable to continue doing this - keeping * incase we are able to switch back to CDN path again in future. */ -export function clientLibraryCDNUrl(appId: string, version: string) { +export function cloudClientLibraryUrl(appId: string, version: string) { let file = clientLibraryPath(appId) - if (env.CLOUDFRONT_CDN) { - // append app version to bust the cache - if (version) { - file += `?v=${version}` - } - // don't need to use presigned for client with cloudfront - // file is public - return cloudfront.getUrl(file) - } else { - return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) - } + return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) } export function clientLibraryUrl(appId: string, version: string) { let tenantId, qsParams: { appId: string; version: string; tenantId?: string } + if (env.isProd() && !env.SELF_HOSTED) { + return cloudClientLibraryUrl(appId, version) + } try { tenantId = getTenantId() } finally { From 795991438f769fc2969d83feabed11b3af338494 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 15:47:39 +0100 Subject: [PATCH 095/179] Use new grid popover for date cells to allow overflow outside grid --- packages/bbui/src/Popover/Popover.svelte | 3 +- .../src/components/grid/cells/DataCell.svelte | 2 + .../src/components/grid/cells/DateCell.svelte | 38 +++++++++++------- .../src/components/grid/layout/Grid.svelte | 10 ++--- .../src/components/grid/layout/GridRow.svelte | 2 + .../src/components/grid/lib/constants.js | 3 +- .../grid/overlays/GridPopover.svelte | 40 +++++++++++++++++++ .../grid/overlays/PopoverOverlay.svelte | 9 +++++ .../grid/overlays/ScrollOverlay.svelte | 2 + 9 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 packages/frontend-core/src/components/grid/overlays/GridPopover.svelte create mode 100644 packages/frontend-core/src/components/grid/overlays/PopoverOverlay.svelte diff --git a/packages/bbui/src/Popover/Popover.svelte b/packages/bbui/src/Popover/Popover.svelte index 263a0b6dc6..079aee32b5 100644 --- a/packages/bbui/src/Popover/Popover.svelte +++ b/packages/bbui/src/Popover/Popover.svelte @@ -116,12 +116,11 @@ min-width: var(--spectrum-global-dimension-size-2000); border-color: var(--spectrum-global-color-gray-300); overflow: auto; - transition: opacity 260ms ease-out, transform 260ms ease-out; + transition: opacity 260ms ease-out; } .hidden { opacity: 0; pointer-events: none; - transform: translateY(-20px); } .customZindex { z-index: var(--customZindex) !important; diff --git a/packages/frontend-core/src/components/grid/cells/DataCell.svelte b/packages/frontend-core/src/components/grid/cells/DataCell.svelte index d8cff26b9d..33f74b116c 100644 --- a/packages/frontend-core/src/components/grid/cells/DataCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DataCell.svelte @@ -22,6 +22,7 @@ export let invertY = false export let contentLines = 1 export let hidden = false + export let rand const emptyError = writable(null) @@ -96,6 +97,7 @@ {invertY} {invertX} {contentLines} + {rand} /> diff --git a/packages/frontend-core/src/components/grid/cells/DateCell.svelte b/packages/frontend-core/src/components/grid/cells/DateCell.svelte index 04d5841f49..26f5653fd0 100644 --- a/packages/frontend-core/src/components/grid/cells/DateCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DateCell.svelte @@ -7,7 +7,7 @@ } from "@budibase/bbui" import { onMount } from "svelte" import dayjs from "dayjs" - import { debounce } from "../../../utils/utils" + import GridPopover from "../overlays/GridPopover.svelte" export let value export let schema @@ -15,8 +15,12 @@ export let focused = false export let readonly = false export let api + export let invertX = false + export let invertY = false + export let rand let isOpen + let anchor $: timeOnly = schema?.timeOnly $: enableTime = !schema?.dateOnly @@ -99,7 +103,12 @@ -
+
{displayValue}
@@ -109,16 +118,18 @@
{#if isOpen} -
- (value = e.detail)} - {enableTime} - {timeOnly} - {ignoreTimezones} - useKeyboardShortcuts={false} - /> -
+ +
+ (value = e.detail)} + {enableTime} + {timeOnly} + {ignoreTimezones} + useKeyboardShortcuts={false} + /> +
+
{/if} ` + + const updateInitialOffsets = open => { + if (!open) { + return + } + initialOffsetX = $scroll.left + initialOffsetY = $scroll.top % $rowHeight + } + + + +{@html markup} + + + diff --git a/packages/frontend-core/src/components/grid/overlays/PopoverOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/PopoverOverlay.svelte new file mode 100644 index 0000000000..a03ba6d927 --- /dev/null +++ b/packages/frontend-core/src/components/grid/overlays/PopoverOverlay.svelte @@ -0,0 +1,9 @@ +
+ + diff --git a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte index 43a64f3fbd..c256e0dc19 100644 --- a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte @@ -127,6 +127,7 @@ on:mousedown={startVDragging} on:touchstart={startVDragging} class:dragging={isDraggingV} + data-ignore-click-outside="true" /> {/if} {#if $showHScrollbar} @@ -137,6 +138,7 @@ on:mousedown={startHDragging} on:touchstart={startHDragging} class:dragging={isDraggingH} + data-ignore-click-outside="true" /> {/if} From f76abb0ca93434b4047f544434430046812e62a7 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 24 Apr 2024 15:59:11 +0100 Subject: [PATCH 096/179] Getting rid of linting error. --- packages/backend-core/src/objectStore/buckets/app.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/app.ts b/packages/backend-core/src/objectStore/buckets/app.ts index 74fdd2e92a..3ad575150e 100644 --- a/packages/backend-core/src/objectStore/buckets/app.ts +++ b/packages/backend-core/src/objectStore/buckets/app.ts @@ -13,7 +13,7 @@ export function clientLibraryPath(appId: string) { * due to issues with the domain we were unable to continue doing this - keeping * incase we are able to switch back to CDN path again in future. */ -export function cloudClientLibraryUrl(appId: string, version: string) { +function cloudClientLibraryUrl(appId: string) { let file = clientLibraryPath(appId) return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) } @@ -21,7 +21,7 @@ export function cloudClientLibraryUrl(appId: string, version: string) { export function clientLibraryUrl(appId: string, version: string) { let tenantId, qsParams: { appId: string; version: string; tenantId?: string } if (env.isProd() && !env.SELF_HOSTED) { - return cloudClientLibraryUrl(appId, version) + return cloudClientLibraryUrl(appId) } try { tenantId = getTenantId() From 443be4cdab85c4a6d0083f3b16d34d6cdb86dde9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 16:28:44 +0100 Subject: [PATCH 097/179] More upgrades to grids to support new popovers and use popovers for options cells --- .../backend/DataTable/TableDataTable.svelte | 2 +- .../src/components/grid/cells/DateCell.svelte | 33 ++++-------- .../components/grid/cells/OptionsCell.svelte | 51 ++++++++----------- .../grid/layout/GridScrollWrapper.svelte | 4 ++ .../grid/overlays/GridPopover.svelte | 38 +++++--------- .../grid/overlays/ScrollOverlay.svelte | 10 ++-- .../src/components/grid/stores/reorder.js | 2 +- 7 files changed, 56 insertions(+), 84 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/TableDataTable.svelte b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte index 6a5cd2f282..fe393c5268 100644 --- a/packages/builder/src/components/backend/DataTable/TableDataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/TableDataTable.svelte @@ -101,7 +101,7 @@ diff --git a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte index 158451c930..81882c867c 100644 --- a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte @@ -1,7 +1,8 @@ - -{@html markup} - +
dispatch("close")}> + +
+ + diff --git a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte index c256e0dc19..b10f245fcb 100644 --- a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte @@ -17,6 +17,7 @@ height, isDragging, menu, + focusedCellAPI, } = getContext("grid") // State for dragging bars @@ -47,10 +48,11 @@ $: barLeft = ScrollBarSize + availWidth * ($scrollLeft / $maxScrollLeft) // Helper to close the context menu if it's open - const closeMenu = () => { + const closePopovers = () => { if ($menu.visible) { menu.actions.close() } + $focusedCellAPI?.blur() } const getLocation = e => { @@ -70,7 +72,7 @@ document.addEventListener("mouseup", stopVDragging) document.addEventListener("touchend", stopVDragging) isDraggingV = true - closeMenu() + closePopovers() } const moveVDragging = domDebounce(e => { const delta = getLocation(e).y - initialMouse @@ -99,7 +101,7 @@ document.addEventListener("mouseup", stopHDragging) document.addEventListener("touchend", stopHDragging) isDraggingH = true - closeMenu() + closePopovers() } const moveHDragging = domDebounce(e => { const delta = getLocation(e).x - initialMouse @@ -127,7 +129,6 @@ on:mousedown={startVDragging} on:touchstart={startVDragging} class:dragging={isDraggingV} - data-ignore-click-outside="true" /> {/if} {#if $showHScrollbar} @@ -138,7 +139,6 @@ on:mousedown={startHDragging} on:touchstart={startHDragging} class:dragging={isDraggingH} - data-ignore-click-outside="true" /> {/if} diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index f820593174..fed9f4c6ef 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -87,7 +87,7 @@ export const createActions = context => { // Check if we need to start auto-scrolling const $reorder = get(reorder) const proximityCutoff = 140 - const speedFactor = 8 + const speedFactor = 16 const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x) const leftProximity = Math.max(0, x - $reorder.gridLeft) if (rightProximity < proximityCutoff) { From 2187d25711241bbc1525868b531f2aa683b0509c Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Wed, 24 Apr 2024 17:12:36 +0100 Subject: [PATCH 098/179] Revert "Changing client library to be retrieved via pre-signed URL for Cloud" --- .../backend-core/src/objectStore/buckets/app.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/backend-core/src/objectStore/buckets/app.ts b/packages/backend-core/src/objectStore/buckets/app.ts index 3ad575150e..43bc965c65 100644 --- a/packages/backend-core/src/objectStore/buckets/app.ts +++ b/packages/backend-core/src/objectStore/buckets/app.ts @@ -13,16 +13,23 @@ export function clientLibraryPath(appId: string) { * due to issues with the domain we were unable to continue doing this - keeping * incase we are able to switch back to CDN path again in future. */ -function cloudClientLibraryUrl(appId: string) { +export function clientLibraryCDNUrl(appId: string, version: string) { let file = clientLibraryPath(appId) - return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) + if (env.CLOUDFRONT_CDN) { + // append app version to bust the cache + if (version) { + file += `?v=${version}` + } + // don't need to use presigned for client with cloudfront + // file is public + return cloudfront.getUrl(file) + } else { + return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file) + } } export function clientLibraryUrl(appId: string, version: string) { let tenantId, qsParams: { appId: string; version: string; tenantId?: string } - if (env.isProd() && !env.SELF_HOSTED) { - return cloudClientLibraryUrl(appId) - } try { tenantId = getTenantId() } finally { From 377cd97f4b85ab63810da1ee386a1ffb350291e7 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 17:35:23 +0100 Subject: [PATCH 099/179] Update attachment cells to use popovers --- .../grid/cells/AttachmentCell.svelte | 49 ++++++++----------- .../src/components/grid/cells/DataCell.svelte | 4 +- .../src/components/grid/cells/DateCell.svelte | 4 +- .../components/grid/cells/HeaderCell.svelte | 4 +- .../components/grid/cells/OptionsCell.svelte | 4 +- .../src/components/grid/layout/Grid.svelte | 6 +-- .../src/components/grid/layout/GridRow.svelte | 4 +- .../grid/overlays/GridPopover.svelte | 6 +-- .../src/components/grid/stores/menu.js | 4 +- 9 files changed, 39 insertions(+), 46 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte index e7dc51e5d5..ac1bb464b3 100644 --- a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte @@ -1,6 +1,7 @@ @@ -14,7 +14,7 @@ bind:open {anchor} align={invertX ? "right" : "left"} - portalTarget="#grid-{rand} .grid-popover-container" + portalTarget="#{gridID} .grid-popover-container" offset={1} >
dispatch("close")}> diff --git a/packages/frontend-core/src/components/grid/stores/menu.js b/packages/frontend-core/src/components/grid/stores/menu.js index 2d11b65bd4..ea32285a95 100644 --- a/packages/frontend-core/src/components/grid/stores/menu.js +++ b/packages/frontend-core/src/components/grid/stores/menu.js @@ -13,13 +13,13 @@ export const createStores = () => { } export const createActions = context => { - const { menu, focusedCellId, rand } = context + const { menu, focusedCellId, gridID } = context const open = (cellId, e) => { e.preventDefault() // Get DOM node for grid data wrapper to compute relative position to - const gridNode = document.getElementById(`grid-${rand}`) + const gridNode = document.getElementById(gridID) const dataNode = gridNode?.getElementsByClassName("grid-data-outer")?.[0] if (!dataNode) { return From 23bd635a8bf0ee534824b04db8af31052a861eb0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 20:26:58 +0100 Subject: [PATCH 100/179] Update relationship cells to use popovers --- .../grid/cells/AttachmentCell.svelte | 9 ++- .../src/components/grid/cells/DateCell.svelte | 2 +- .../components/grid/cells/OptionsCell.svelte | 8 +-- .../grid/cells/RelationshipCell.svelte | 60 +++++-------------- .../src/components/grid/lib/constants.js | 5 ++ .../grid/overlays/GridPopover.svelte | 45 ++++++++++++-- 6 files changed, 70 insertions(+), 59 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte index ac1bb464b3..a74878467b 100644 --- a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte @@ -93,7 +93,14 @@
{#if isOpen} - +
{#if isOpen} - + {#if isOpen} - -
e.stopPropagation()}> + +
{#each options as option, idx} {@const color = optionColors[option] || getOptionColor(option)} @@ -219,10 +219,6 @@ flex-direction: column; justify-content: flex-start; align-items: stretch; - max-height: var(--max-cell-render-overflow); - overflow-y: auto; - min-width: 200px; - max-width: 400px; } .option { flex: 0 0 var(--default-row-height); diff --git a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte index a52dd9d53c..ba84316ab4 100644 --- a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte @@ -1,8 +1,9 @@ -
dispatch("close")}> +
dispatch("close")} + on:wheel={e => e.stopPropagation()} + >
@@ -26,5 +54,12 @@ :global(.grid-popover-container .spectrum-Popover) { background: var(--grid-background-alt); border: var(--cell-border); + min-width: none; + max-width: none; + overflow: hidden; + } + .grid-popover-contents { + overflow-y: auto; + overflow-x: hidden; } From 957facb99cb073d8e7f9bc41c915a9ba08255a45 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 24 Apr 2024 20:39:16 +0100 Subject: [PATCH 101/179] Update long form cells to use popovers --- .../components/grid/cells/LongFormCell.svelte | 64 +++++++++---------- .../grid/overlays/GridPopover.svelte | 2 + 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte b/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte index b3eab24fa1..6a05b4ae49 100644 --- a/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/LongFormCell.svelte @@ -1,6 +1,7 @@ -{#if isOpen} -