diff --git a/packages/backend-core/src/migrations/definitions.ts b/packages/backend-core/src/migrations/definitions.ts index 6eba56ab43..0dd57fe639 100644 --- a/packages/backend-core/src/migrations/definitions.ts +++ b/packages/backend-core/src/migrations/definitions.ts @@ -21,6 +21,10 @@ export const DEFINITIONS: MigrationDefinition[] = [ type: MigrationType.APP, name: MigrationName.EVENT_APP_BACKFILL, }, + { + type: MigrationType.APP, + name: MigrationName.TABLE_SETTINGS_LINKS_TO_ACTIONS, + }, { type: MigrationType.GLOBAL, name: MigrationName.EVENT_GLOBAL_BACKFILL, diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.js index 7fd2879071..3a08484635 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.js @@ -1,18 +1,53 @@ -export default function clickOutside(element, callbackFunction) { - function onClick(event) { - if (!element.contains(event.target)) { - callbackFunction(event) +const ignoredClasses = [".flatpickr-calendar", ".modal-container"] +let clickHandlers = [] + +/** + * Handle a body click event + */ +const handleClick = event => { + // Ignore click if needed + for (let className of ignoredClasses) { + if (event.target.closest(className)) { + return } } - document.body.addEventListener("click", onClick, true) + // Process handlers + clickHandlers.forEach(handler => { + if (!handler.element.contains(event.target)) { + handler.callback?.(event) + } + }) +} +document.documentElement.addEventListener("click", handleClick, true) - return { - update(newCallbackFunction) { - callbackFunction = newCallbackFunction - }, - destroy() { - document.body.removeEventListener("click", onClick, true) - }, +/** + * Adds or updates a click handler + */ +const updateHandler = (id, element, callback) => { + let existingHandler = clickHandlers.find(x => x.id === id) + if (!existingHandler) { + clickHandlers.push({ id, element, callback }) + } else { + existingHandler.callback = callback + } +} + +/** + * Removes a click handler + */ +const removeHandler = id => { + clickHandlers = clickHandlers.filter(x => x.id !== id) +} + +/** + * Svelte action to apply a click outside handler for a certain element + */ +export default (element, callback) => { + const id = Math.random() + updateHandler(id, element, callback) + return { + update: newCallback => updateHandler(id, element, newCallback), + destroy: () => removeHandler(id), } } diff --git a/packages/bbui/src/DetailSummary/DetailSummary.svelte b/packages/bbui/src/DetailSummary/DetailSummary.svelte index 518c615504..f7e2611792 100644 --- a/packages/bbui/src/DetailSummary/DetailSummary.svelte +++ b/packages/bbui/src/DetailSummary/DetailSummary.svelte @@ -19,13 +19,19 @@
-
-
{name}
- {#if collapsible} - - {/if} -
-
+ {#if name} +
+
{name}
+ {#if collapsible} + + {/if} +
+ {/if} +
@@ -72,6 +78,9 @@ padding: var(--spacing-s) var(--spacing-xl) var(--spacing-xl) var(--spacing-xl); } + .property-panel.no-title { + padding: var(--spacing-xl); + } .show { display: flex; diff --git a/packages/bbui/src/Form/Core/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker.svelte index a35fee1446..6996525a76 100644 --- a/packages/bbui/src/Form/Core/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker.svelte @@ -23,6 +23,15 @@ let open = false let flatpickr, flatpickrOptions + // Another classic flatpickr issue. Errors were randomly being thrown due to + // flatpickr internal code. Making sure that "destroy" is a valid function + // fixes it. The sooner we remove flatpickr the better. + $: { + if (flatpickr && !flatpickr.destroy) { + flatpickr.destroy = () => {} + } + } + const resolveTimeStamp = timestamp => { let maskedDate = new Date(`0-${timestamp}`) @@ -252,6 +261,7 @@ width: 100vw; height: 100vh; z-index: 999; + max-height: 100%; } :global(.flatpickr-calendar) { font-family: "Source Sans Pro", sans-serif; diff --git a/packages/bbui/src/Icon/Icon.svelte b/packages/bbui/src/Icon/Icon.svelte index f2cae14f0b..8290acd7cc 100644 --- a/packages/bbui/src/Icon/Icon.svelte +++ b/packages/bbui/src/Icon/Icon.svelte @@ -64,7 +64,7 @@ transition: color var(--spectrum-global-animation-duration-100, 130ms); } svg.hoverable:hover { - color: var(--spectrum-alias-icon-color-selected-hover); + color: var(--spectrum-alias-icon-color-selected-hover) !important; cursor: pointer; } diff --git a/packages/bbui/src/Table/Table.svelte b/packages/bbui/src/Table/Table.svelte index d6be0e8c9b..cec270486a 100644 --- a/packages/bbui/src/Table/Table.svelte +++ b/packages/bbui/src/Table/Table.svelte @@ -275,157 +275,159 @@ } -
- {#if loading} -
- - - -
- {:else} -
- {#if fields.length} -
- {#if showEditColumn} -
- {#if allowSelectRows} - - {:else} - Edit - {/if} -
- {/if} - {#each fields as field} -
sortBy(schema[field])} - > -
{getDisplayName(schema[field])}
- {#if schema[field]?.autocolumn} - - - - {/if} - {#if sortColumn === field} - - {/if} - {#if allowEditColumns && schema[field]?.editable !== false} - editColumn(e, field)} - > - - - {/if} -
- {/each} -
- {/if} - {#if sortedRows?.length} - {#each sortedRows as row, idx} -
+{#key fields?.length} +
+ {#if loading} +
+ + + +
+ {:else} +
+ {#if fields.length} +
{#if showEditColumn}
{ - toggleSelectRow(row) - e.stopPropagation() - }} + class:noBorderHeader={!showHeaderBorder} + class="spectrum-Table-headCell spectrum-Table-headCell--divider spectrum-Table-headCell--edit" > - selectedRow._id === row._id - ) !== -1} - onEdit={e => editRow(e, row)} - {allowSelectRows} - {allowEditRows} - /> + {#if allowSelectRows} + + {:else} + Edit + {/if}
{/if} {#each fields as field}
{ - if (!schema[field]?.preventSelectRow) { - dispatch("click", row) - toggleSelectRow(row) - } - }} + class="spectrum-Table-headCell" + class:noBorderHeader={!showHeaderBorder} + class:spectrum-Table-headCell--alignCenter={schema[field] + .align === "Center"} + class:spectrum-Table-headCell--alignRight={schema[field] + .align === "Right"} + class:is-sortable={schema[field].sortable !== false} + class:is-sorted-desc={sortColumn === field && + sortOrder === "Descending"} + class:is-sorted-asc={sortColumn === field && + sortOrder === "Ascending"} + on:click={() => sortBy(schema[field])} > - - - +
{getDisplayName(schema[field])}
+ {#if schema[field]?.autocolumn} + + + + {/if} + {#if sortColumn === field} + + {/if} + {#if allowEditColumns && schema[field]?.editable !== false} + editColumn(e, field)} + > + + + {/if}
{/each}
- {/each} - {:else} -
- {#if customPlaceholder} - - {:else} -
- - - -
{placeholderText}
+ {/if} + {#if sortedRows?.length} + {#each sortedRows as row, idx} +
+ {#if showEditColumn} +
{ + toggleSelectRow(row) + e.stopPropagation() + }} + > + selectedRow._id === row._id + ) !== -1} + onEdit={e => editRow(e, row)} + {allowSelectRows} + {allowEditRows} + /> +
+ {/if} + {#each fields as field} +
{ + if (!schema[field]?.preventSelectRow) { + dispatch("click", row) + toggleSelectRow(row) + } + }} + > + + + +
+ {/each}
- {/if} -
- {/if} -
- {/if} -
+ {/each} + {:else} +
+ {#if customPlaceholder} + + {:else} +
+ + + +
{placeholderText}
+
+ {/if} +
+ {/if} +
+ {/if} +
+{/key} diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/OpenSidePanel.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/OpenSidePanel.svelte new file mode 100644 index 0000000000..eb0c7b4db6 --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/OpenSidePanel.svelte @@ -0,0 +1,37 @@ + + +
+ +