Merge branch 'master' into feature/signature-field-and-component

This commit is contained in:
deanhannigan 2024-05-20 10:30:55 +01:00 committed by GitHub
commit f20ed14e61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 61 deletions

View File

@ -1,40 +1,28 @@
<script> <script>
import { getContext, onMount, createEventDispatcher } from "svelte" import { getContext, onDestroy } from "svelte"
import Portal from "svelte-portal" import Portal from "svelte-portal"
export let title export let title
export let icon = "" export let icon = ""
export let id export let id
const dispatch = createEventDispatcher()
let selected = getContext("tab") let selected = getContext("tab")
let tab_internal let observer
let tabInfo let ref
const setTabInfo = () => { $: isSelected = $selected.title === title
// If the tabs are being rendered inside a component which uses $: {
// a svelte transition to enter, then this initial getBoundingClientRect if (isSelected && ref) {
// will return an incorrect position. observe()
// We just need to get this off the main thread to fix this, by using } else {
// a 0ms timeout. stopObserving()
setTimeout(() => { }
tabInfo = tab_internal?.getBoundingClientRect()
if (tabInfo && $selected.title === title) {
$selected.info = tabInfo
}
}, 0)
} }
onMount(() => { const setTabInfo = () => {
setTabInfo() const tabInfo = ref?.getBoundingClientRect()
}) if (tabInfo) {
$selected.info = tabInfo
//Ensure that the underline is in the correct location
$: {
if ($selected.title === title && tab_internal) {
if ($selected.info?.left !== tab_internal.getBoundingClientRect().left) {
setTabInfo()
}
} }
} }
@ -42,10 +30,25 @@
$selected = { $selected = {
...$selected, ...$selected,
title, title,
info: tab_internal.getBoundingClientRect(), info: ref.getBoundingClientRect(),
} }
dispatch("click")
} }
const observe = () => {
if (!observer) {
observer = new ResizeObserver(setTabInfo)
observer.observe(ref)
}
}
const stopObserving = () => {
if (observer) {
observer.unobserve(ref)
observer = null
}
}
onDestroy(stopObserving)
</script> </script>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
@ -53,11 +56,12 @@
<!-- svelte-ignore a11y-no-noninteractive-tabindex --> <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div <div
{id} {id}
bind:this={tab_internal} bind:this={ref}
on:click={onClick} on:click={onClick}
class:is-selected={$selected.title === title} on:click
class="spectrum-Tabs-item" class="spectrum-Tabs-item"
class:emphasized={$selected.title === title && $selected.emphasized} class:is-selected={isSelected}
class:emphasized={isSelected && $selected.emphasized}
tabindex="0" tabindex="0"
> >
{#if icon} {#if icon}
@ -72,7 +76,8 @@
{/if} {/if}
<span class="spectrum-Tabs-itemLabel">{title}</span> <span class="spectrum-Tabs-itemLabel">{title}</span>
</div> </div>
{#if $selected.title === title}
{#if isSelected}
<Portal target=".spectrum-Tabs-content-{$selected.id}"> <Portal target=".spectrum-Tabs-content-{$selected.id}">
<slot /> <slot />
</Portal> </Portal>

View File

@ -105,10 +105,6 @@
} }
onMount(async () => { onMount(async () => {
document.fonts.onloadingdone = e => {
builderStore.loadFonts(e.fontfaces)
}
if (!hasSynced && application) { if (!hasSynced && application) {
try { try {
await API.syncApp(application) await API.syncApp(application)
@ -149,19 +145,17 @@
/> />
</span> </span>
<Tabs {selected} size="M"> <Tabs {selected} size="M">
{#key $builderStore?.fonts} {#each $layout.children as { path, title }}
{#each $layout.children as { path, title }} <TourWrap stepKeys={[`builder-${title}-section`]}>
<TourWrap stepKeys={[`builder-${title}-section`]}> <Tab
<Tab quiet
quiet selected={$isActive(path)}
selected={$isActive(path)} on:click={topItemNavigate(path)}
on:click={topItemNavigate(path)} title={capitalise(title)}
title={capitalise(title)} id={`builder-${title}-tab`}
id={`builder-${title}-tab`} />
/> </TourWrap>
</TourWrap> {/each}
{/each}
{/key}
</Tabs> </Tabs>
</div> </div>
<div class="topcenternav"> <div class="topcenternav">

View File

@ -14,7 +14,6 @@ export const INITIAL_BUILDER_STATE = {
tourKey: null, tourKey: null,
tourStepKey: null, tourStepKey: null,
hoveredComponentId: null, hoveredComponentId: null,
fonts: null,
} }
export class BuilderStore extends BudiStore { export class BuilderStore extends BudiStore {
@ -37,16 +36,6 @@ export class BuilderStore extends BudiStore {
this.websocket this.websocket
} }
loadFonts(fontFaces) {
const ff = fontFaces.map(
fontFace => `${fontFace.family}-${fontFace.weight}`
)
this.update(state => ({
...state,
fonts: [...(state.fonts || []), ...ff],
}))
}
init(app) { init(app) {
if (!app?.appId) { if (!app?.appId) {
console.error("BuilderStore: No appId supplied for websocket") console.error("BuilderStore: No appId supplied for websocket")

View File

@ -14,7 +14,7 @@ import { makeExternalQuery } from "../../../integrations/base/query"
import { Format } from "../../../api/controllers/view/exporters" import { Format } from "../../../api/controllers/view/exporters"
import sdk from "../.." import sdk from "../.."
import { isRelationshipColumn } from "../../../db/utils" import { isRelationshipColumn } from "../../../db/utils"
import { SqlClient, isSQL } from "../../../integrations/utils" import { isSQL, SqlClient } from "../../../integrations/utils"
const SQL_CLIENT_SOURCE_MAP: Record<SourceName, SqlClient | undefined> = { const SQL_CLIENT_SOURCE_MAP: Record<SourceName, SqlClient | undefined> = {
[SourceName.POSTGRES]: SqlClient.POSTGRES, [SourceName.POSTGRES]: SqlClient.POSTGRES,
@ -144,6 +144,10 @@ export async function validate({
throw new Error("Unable to fetch table for validation") throw new Error("Unable to fetch table for validation")
} }
const errors: Record<string, any> = {} const errors: Record<string, any> = {}
const disallowArrayTypes = [
FieldType.ATTACHMENT_SINGLE,
FieldType.BB_REFERENCE_SINGLE,
]
for (let fieldName of Object.keys(fetchedTable.schema)) { for (let fieldName of Object.keys(fetchedTable.schema)) {
const column = fetchedTable.schema[fieldName] const column = fetchedTable.schema[fieldName]
const constraints = cloneDeep(column.constraints) const constraints = cloneDeep(column.constraints)
@ -160,6 +164,10 @@ export async function validate({
if (type === FieldType.OPTIONS && constraints?.inclusion) { if (type === FieldType.OPTIONS && constraints?.inclusion) {
constraints.inclusion.push(null as any, "") constraints.inclusion.push(null as any, "")
} }
if (disallowArrayTypes.includes(type) && Array.isArray(row[fieldName])) {
errors[fieldName] = `Cannot accept arrays`
}
let res let res
// Validate.js doesn't seem to handle array // Validate.js doesn't seem to handle array