From 8563471aeac7c6b78da7f5fde1427bc2672285d7 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Fri, 31 May 2024 16:21:21 +0100
Subject: [PATCH 1/9] Don't update text settings when editing inline unless the
value actually changes, to prevent losing HBS or JS expressions
---
.../client/src/components/app/Button.svelte | 28 ++++++++++---------
.../client/src/components/app/Heading.svelte | 7 ++++-
.../client/src/components/app/Link.svelte | 7 ++++-
.../client/src/components/app/Text.svelte | 7 ++++-
.../src/components/app/forms/Field.svelte | 12 ++++++--
5 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/packages/client/src/components/app/Button.svelte b/packages/client/src/components/app/Button.svelte
index c43face1bb..29bdd46a70 100644
--- a/packages/client/src/components/app/Button.svelte
+++ b/packages/client/src/components/app/Button.svelte
@@ -5,8 +5,6 @@
const { styleable, builderStore } = getContext("sdk")
const component = getContext("component")
- let handlingOnClick = false
-
export let disabled = false
export let text = ""
export let onClick
@@ -19,17 +17,9 @@
// For internal use only for now - not defined in the manifest
export let active = false
- const handleOnClick = async () => {
- handlingOnClick = true
-
- if (onClick) {
- await onClick()
- }
-
- handlingOnClick = false
- }
-
let node
+ let touched = false
+ let handlingOnClick = false
$: $component.editing && node?.focus()
$: componentText = getComponentText(text, $builderStore, $component)
@@ -42,7 +32,18 @@
}
const updateText = e => {
- builderStore.actions.updateProp("text", e.target.textContent)
+ if (touched) {
+ builderStore.actions.updateProp("text", e.target.textContent)
+ }
+ touched = false
+ }
+
+ const handleOnClick = async () => {
+ handlingOnClick = true
+ if (onClick) {
+ await onClick()
+ }
+ handlingOnClick = false
}
@@ -57,6 +58,7 @@
on:blur={$component.editing ? updateText : null}
bind:this={node}
class:active
+ on:input={() => (touched = true)}
>
{#if icon}
diff --git a/packages/client/src/components/app/Heading.svelte b/packages/client/src/components/app/Heading.svelte
index 4adec59e2b..103ac31a93 100644
--- a/packages/client/src/components/app/Heading.svelte
+++ b/packages/client/src/components/app/Heading.svelte
@@ -14,6 +14,7 @@
export let size
let node
+ let touched = false
$: $component.editing && node?.focus()
$: placeholder = $builderStore.inBuilder && !text && !$component.editing
@@ -47,7 +48,10 @@
// Convert contenteditable HTML to text and save
const updateText = e => {
- builderStore.actions.updateProp("text", e.target.textContent)
+ if (touched) {
+ builderStore.actions.updateProp("text", e.target.textContent)
+ }
+ touched = false
}
@@ -62,6 +66,7 @@
class:underline
class="spectrum-Heading {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
+ on:input={() => (touched = true)}
>
{componentText}
diff --git a/packages/client/src/components/app/Link.svelte b/packages/client/src/components/app/Link.svelte
index 6cabcec7df..7eddcc6fe5 100644
--- a/packages/client/src/components/app/Link.svelte
+++ b/packages/client/src/components/app/Link.svelte
@@ -16,6 +16,7 @@
export let size
let node
+ let touched = false
$: $component.editing && node?.focus()
$: externalLink = url && typeof url === "string" && !url.startsWith("/")
@@ -62,7 +63,10 @@
}
const updateText = e => {
- builderStore.actions.updateProp("text", e.target.textContent)
+ if (touched) {
+ builderStore.actions.updateProp("text", e.target.textContent)
+ }
+ touched = false
}
@@ -76,6 +80,7 @@
class:underline
class="align--{align || 'left'} size--{size || 'M'}"
on:blur={$component.editing ? updateText : null}
+ on:input={() => (touched = true)}
>
{componentText}
diff --git a/packages/client/src/components/app/Text.svelte b/packages/client/src/components/app/Text.svelte
index 1037725ff8..fa15868d0f 100644
--- a/packages/client/src/components/app/Text.svelte
+++ b/packages/client/src/components/app/Text.svelte
@@ -13,6 +13,7 @@
export let size
let node
+ let touched = false
$: $component.editing && node?.focus()
$: placeholder = $builderStore.inBuilder && !text && !$component.editing
@@ -46,7 +47,10 @@
// Convert contenteditable HTML to text and save
const updateText = e => {
- builderStore.actions.updateProp("text", e.target.textContent)
+ if (touched) {
+ builderStore.actions.updateProp("text", e.target.textContent)
+ }
+ touched = false
}
@@ -61,6 +65,7 @@
class:underline
class="spectrum-Body {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
+ on:input={() => (touched = true)}
>
{componentText}
diff --git a/packages/client/src/components/app/forms/Field.svelte b/packages/client/src/components/app/forms/Field.svelte
index 74ff5442a9..9210b6ea8f 100644
--- a/packages/client/src/components/app/forms/Field.svelte
+++ b/packages/client/src/components/app/forms/Field.svelte
@@ -26,6 +26,10 @@
// Register field with form
const formApi = formContext?.formApi
const labelPos = fieldGroupContext?.labelPosition || "above"
+
+ let touched = false
+ let labelNode
+
$: formStep = formStepContext ? $formStepContext || 1 : 1
$: formField = formApi?.registerField(
field,
@@ -36,14 +40,12 @@
validation,
formStep
)
-
$: schemaType =
fieldSchema?.type !== "formula" && fieldSchema?.type !== "bigint"
? fieldSchema?.type
: "string"
// Focus label when editing
- let labelNode
$: $component.editing && labelNode?.focus()
// Update form properties in parent component on every store change
@@ -57,7 +59,10 @@
$: labelClass = labelPos === "above" ? "" : `spectrum-FieldLabel--${labelPos}`
const updateLabel = e => {
- builderStore.actions.updateProp("label", e.target.textContent)
+ if (touched) {
+ builderStore.actions.updateProp("label", e.target.textContent)
+ }
+ touched = false
}
onDestroy(() => {
@@ -79,6 +84,7 @@
bind:this={labelNode}
contenteditable={$component.editing}
on:blur={$component.editing ? updateLabel : null}
+ on:input={() => (touched = true)}
class:hidden={!label}
class:readonly
for={fieldState?.fieldId}
From ae863a6e16efa2b7c8114155a7dd4eb04aede625 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 08:00:58 +0100
Subject: [PATCH 2/9] Only override grid column widths in table block when they
are defined
---
packages/client/src/components/app/GridBlock.svelte | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/client/src/components/app/GridBlock.svelte b/packages/client/src/components/app/GridBlock.svelte
index dbd651b533..7502dc1ba8 100644
--- a/packages/client/src/components/app/GridBlock.svelte
+++ b/packages/client/src/components/app/GridBlock.svelte
@@ -90,9 +90,11 @@
columns.forEach((column, idx) => {
overrides[column.field] = {
displayName: column.label,
- width: column.width,
order: idx,
}
+ if (column.width) {
+ overrides[column.field].width = column.width
+ }
})
return overrides
}
From 08a48a9ff91ccf10524e768874f953c35f2771c0 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 08:57:24 +0100
Subject: [PATCH 3/9] Make new schema validation errors visible to users, and
reset schema when saving fails
---
.../src/components/grid/stores/datasource.js | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/packages/frontend-core/src/components/grid/stores/datasource.js b/packages/frontend-core/src/components/grid/stores/datasource.js
index 09b8be4868..8b8ffdf2cf 100644
--- a/packages/frontend-core/src/components/grid/stores/datasource.js
+++ b/packages/frontend-core/src/components/grid/stores/datasource.js
@@ -94,6 +94,7 @@ export const createActions = context => {
nonPlus,
schemaMutations,
schema,
+ notifications,
} = context
// Gets the appropriate API for the configured datasource type
@@ -125,16 +126,25 @@ export const createActions = context => {
// Saves the datasource definition
const saveDefinition = async newDefinition => {
// Update local state
+ const originalDefinition = get(definition)
definition.set(newDefinition)
// Update server
if (get(config).canSaveSchema) {
- await getAPI()?.actions.saveDefinition(newDefinition)
+ try {
+ await getAPI()?.actions.saveDefinition(newDefinition)
- // Broadcast change so external state can be updated, as this change
- // will not be received by the builder websocket because we caused it
- // ourselves
- dispatch("updatedatasource", newDefinition)
+ // Broadcast change so external state can be updated, as this change
+ // will not be received by the builder websocket because we caused it
+ // ourselves
+ dispatch("updatedatasource", newDefinition)
+ } catch (error) {
+ const msg = error?.message || error || "Unknown error"
+ get(notifications).error(`Error saving schema: ${msg}`)
+
+ // Reset the definition if saving failed
+ definition.set(originalDefinition)
+ }
}
}
From 7566ecfac8166677018a29b95020d1a569fffdd0 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 09:40:08 +0100
Subject: [PATCH 4/9] Fix issue where grid highlighted rows are incorrect when
page is scrolled
---
.../components/grid/layout/GridBody.svelte | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/packages/frontend-core/src/components/grid/layout/GridBody.svelte b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
index 87fcfe2d32..8be56674be 100644
--- a/packages/frontend-core/src/components/grid/layout/GridBody.svelte
+++ b/packages/frontend-core/src/components/grid/layout/GridBody.svelte
@@ -23,14 +23,24 @@
0
)
+ const updateBounds = () => {
+ bounds.set(body.getBoundingClientRect())
+ }
+
onMount(() => {
// Observe and record the height of the body
- const observer = new ResizeObserver(() => {
- bounds.set(body.getBoundingClientRect())
- })
- observer.observe(body)
+ const resizeObserver = new ResizeObserver(updateBounds)
+ resizeObserver.observe(body)
+
+ // Capture any wheel events on the page to ensure our scroll offset is
+ // correct. We don't care about touch events as we only need this for
+ // hovering over rows with a mouse.
+ window.addEventListener("wheel", updateBounds, true)
+
+ // Clean up listeners
return () => {
- observer.disconnect()
+ resizeObserver.disconnect()
+ window.removeEventListener("wheel", updateBounds, true)
}
})
From 9047c54b03084dd97accd1132f83b71a04ca0e3b Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 09:52:49 +0100
Subject: [PATCH 5/9] Truncate long column names in column settings buttons
---
.../grid/controls/ColumnsSettingButton.svelte | 14 ++++++++++++--
.../grid/controls/ToggleActionButtonGroup.svelte | 1 -
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte
index ed94a01e56..f16a1183a4 100644
--- a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte
+++ b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte
@@ -116,7 +116,9 @@
{#each displayColumns as column}
- {column.label}
+
+ {column.label}
+
toggleColumn(column, e.detail)}
@@ -139,7 +141,8 @@
display: grid;
align-items: center;
grid-template-columns: 1fr auto;
- gap: 8px;
+ grid-row-gap: 8px;
+ grid-column-gap: 24px;
}
.columns :global(.spectrum-Switch) {
margin-right: 0;
@@ -148,4 +151,11 @@
display: flex;
gap: 8px;
}
+ .column-label {
+ min-width: 80px;
+ max-width: 200px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
diff --git a/packages/frontend-core/src/components/grid/controls/ToggleActionButtonGroup.svelte b/packages/frontend-core/src/components/grid/controls/ToggleActionButtonGroup.svelte
index 2e62c593d1..497e77c2c9 100644
--- a/packages/frontend-core/src/components/grid/controls/ToggleActionButtonGroup.svelte
+++ b/packages/frontend-core/src/components/grid/controls/ToggleActionButtonGroup.svelte
@@ -29,7 +29,6 @@
.permissionPicker {
display: flex;
gap: var(--spacing-xs);
- padding-left: calc(var(--spacing-xl) * 2);
}
.permissionPicker :global(.spectrum-Icon) {
From 6a859e568b17d83d8f98ca75ea1dca117b6f1439 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 13:28:04 +0100
Subject: [PATCH 6/9] Fix missing on:change event proxy from builder dropzone
component
---
packages/builder/src/components/common/Dropzone.svelte | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/builder/src/components/common/Dropzone.svelte b/packages/builder/src/components/common/Dropzone.svelte
index 37569df0d5..8cd85e2530 100644
--- a/packages/builder/src/components/common/Dropzone.svelte
+++ b/packages/builder/src/components/common/Dropzone.svelte
@@ -38,4 +38,5 @@
{processFiles}
handleFileTooLarge={$admin.cloud ? handleFileTooLarge : null}
{fileSizeLimit}
+ on:change
/>
From 4cfa02f5d2f44d8dcdd6b65bce84ec3f44b7b7f3 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Mon, 10 Jun 2024 13:59:35 +0100
Subject: [PATCH 7/9] Fix options not clearing when adding select-type columns
---
.../components/backend/DataTable/modals/CreateEditColumn.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
index 730e51bf48..17ecd8f844 100644
--- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
@@ -334,7 +334,7 @@
// Add in defaults and initial definition
const definition = fieldDefinitions[type?.toUpperCase()]
if (definition?.constraints) {
- editableColumn.constraints = definition.constraints
+ editableColumn.constraints = cloneDeep(definition.constraints)
}
editableColumn.type = definition.type
From 387b9a8ed2854931268b1b5883459aaa37a04641 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Tue, 11 Jun 2024 16:19:57 +0100
Subject: [PATCH 8/9] Ensure input fields don't exceed cell bounds in grids in
firefox
---
packages/frontend-core/src/components/grid/cells/TextCell.svelte | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/frontend-core/src/components/grid/cells/TextCell.svelte b/packages/frontend-core/src/components/grid/cells/TextCell.svelte
index d2ee0189fe..0cf0ab2004 100644
--- a/packages/frontend-core/src/components/grid/cells/TextCell.svelte
+++ b/packages/frontend-core/src/components/grid/cells/TextCell.svelte
@@ -81,6 +81,7 @@
}
input {
flex: 1 1 auto;
+ width: 0;
border: none;
padding: var(--cell-padding);
overflow: hidden;
From 783d21159abb2b930531fa24eba854185a6fcaf2 Mon Sep 17 00:00:00 2001
From: Andrew Kingston
Date: Tue, 11 Jun 2024 16:53:17 +0100
Subject: [PATCH 9/9] Lint
---
.../controls/DataSourceSelect/DataSourceSelect.svelte | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte
index a3ea677df9..d2b5174139 100644
--- a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte
+++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte
@@ -55,7 +55,9 @@
label: m.name,
tableId: m._id,
type: "table",
- datasource: $datasources.list.find(ds => ds._id === m.sourceId || m.datasourceId),
+ datasource: $datasources.list.find(
+ ds => ds._id === m.sourceId || m.datasourceId
+ ),
}))
$: viewsV1 = $viewsStore.list.map(view => ({
...view,