update: columns ai suggestions [wip].

This commit is contained in:
Darshan
2025-10-06 17:17:51 +05:30
parent 05d8689801
commit 9ec11dc9bb
17 changed files with 209 additions and 75 deletions
+9 -2
View File
@@ -14,6 +14,7 @@
onDeletePoint: (index: number) => void;
onChangePoint: (pointIndex: number, coordIndex: number, newValue: number) => void;
addLineButton?: Snippet;
disabled?: boolean;
};
let {
@@ -24,7 +25,8 @@
onAddPoint,
onDeletePoint,
onChangePoint,
addLineButton
addLineButton,
disabled
}: Props = $props();
function isDeleteDisabled(index: number) {
@@ -40,6 +42,7 @@
<Layout.Stack>
{#each values as value, index}
<InputPoint
{disabled}
{nullable}
values={value}
deletePoints
@@ -52,7 +55,11 @@
{#if values}
<Layout.Stack direction="row" gap="s" alignItems="center">
<Button size="xs" compact on:click={() => onAddPoint(-1)} disabled={nullable}>
<Button
size="xs"
compact
on:click={() => onAddPoint(-1)}
disabled={nullable || disabled}>
<Icon icon={IconPlus} size="s" /> Add coordinate
</Button>
{@render addLineButton?.()}
+5 -2
View File
@@ -10,6 +10,7 @@
deletePoints?: boolean;
onDeletePoint?: () => void;
disableDelete?: boolean;
disabled?: boolean;
onChangePoint: (index: number, newValue: number) => void;
}
@@ -21,7 +22,8 @@
deletePoints = false,
disableDelete = false,
onDeletePoint,
onChangePoint
onChangePoint,
disabled
}: Props = $props();
</script>
@@ -38,6 +40,7 @@
placeholder="Enter value"
step={0.0001}
value={values[index]}
{disabled}
on:change={(e) => onChangePoint(index, Number.parseFloat(`${e.detail}`))} />
{/each}
{/if}
@@ -45,7 +48,7 @@
<Button
size="s"
secondary
disabled={nullable || disableDelete}
disabled={nullable || disableDelete || disabled}
on:click={() => onDeletePoint?.()}>
<Icon icon={IconX} size="s" />
</Button>
+4 -1
View File
@@ -17,6 +17,7 @@
coordIndex: number,
newValue: number
) => void;
disabled?: boolean;
};
let {
@@ -26,7 +27,8 @@
onAddPoint,
onAddLine,
onDeletePoint,
onChangePoint
onChangePoint,
disabled
}: Props = $props();
</script>
@@ -34,6 +36,7 @@
{#each values as value, index}
<Layout.Stack gap="xs">
<InputLine
{disabled}
values={value}
onAddPoint={() => onAddPoint(index)}
{nullable}
@@ -39,6 +39,7 @@
import { InputSelect } from '$lib/elements/forms';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnBoolean> = {
required: false,
array: false,
@@ -67,6 +68,7 @@
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
@@ -76,24 +78,26 @@
id="default"
label="Default value"
placeholder="Select a value"
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
options={[
{ label: 'NULL', value: null },
{ label: 'True', value: true },
{ label: 'False', value: false }
]}
bind:value={data.default} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -42,13 +42,13 @@
<script lang="ts">
import { InputDateTime } from '$lib/elements/forms';
import { Selector } from '@appwrite.io/pink-svelte';
import { createConservative } from '$lib/helpers/stores';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnDatetime>;
import { createConservative } from '$lib/helpers/stores';
import { Selector } from '@appwrite.io/pink-svelte';
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
@@ -78,19 +78,21 @@
id="default"
label="Default value"
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -38,13 +38,13 @@
<script lang="ts">
import { InputEmail } from '$lib/elements/forms';
import { Selector } from '@appwrite.io/pink-svelte';
import { createConservative } from '$lib/helpers/stores';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnEmail>;
import { createConservative } from '$lib/helpers/stores';
import { Selector } from '@appwrite.io/pink-svelte';
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
@@ -74,19 +74,21 @@
label="Default value"
placeholder="Enter value"
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -39,15 +39,15 @@
</script>
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { InputSelect, InputTags } from '$lib/elements/forms';
import { Icon, Selector, Tooltip, Typography } from '@appwrite.io/pink-svelte';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnEnum>;
import { createConservative } from '$lib/helpers/stores';
import { Icon, Selector, Tooltip, Typography } from '@appwrite.io/pink-svelte';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
@@ -67,6 +67,7 @@
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
@@ -103,21 +104,23 @@
<InputSelect
id="default"
label="Default value"
disabled={data.array || data.required}
disabled={data.array || data.required || disabled}
placeholder="Select a value"
{options}
bind:value={data.default} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -42,8 +42,11 @@
<script lang="ts">
import { InputNumber } from '$lib/elements/forms';
import { createConservative } from '$lib/helpers/stores';
import { Layout, Selector } from '@appwrite.io/pink-svelte';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnFloat> = {
required: false,
min: 0,
@@ -52,9 +55,6 @@
array: false
};
import { createConservative } from '$lib/helpers/stores';
import { Layout, Selector } from '@appwrite.io/pink-svelte';
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
@@ -86,15 +86,19 @@
placeholder="Enter size"
bind:value={data.min}
step={0.1}
{disabled}
required={editing} />
<InputNumber
id="max"
label="Max"
placeholder="Enter size"
bind:value={data.max}
step={0.1}
{disabled}
required={editing} />
</Layout.Stack>
<InputNumber
id="default"
label="Default value"
@@ -102,20 +106,22 @@
min={data.min}
max={data.max}
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array}
step={0.1} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -42,9 +42,11 @@
<script lang="ts">
import { InputNumber } from '$lib/elements/forms';
import { createConservative } from '$lib/helpers/stores';
import { Layout, Selector } from '@appwrite.io/pink-svelte';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnInteger> = {
required: false,
min: 0,
@@ -53,9 +55,6 @@
array: false
};
import { createConservative } from '$lib/helpers/stores';
import { Layout, Selector } from '@appwrite.io/pink-svelte';
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
@@ -84,16 +83,20 @@
<InputNumber
id="min"
label="Min"
{disabled}
placeholder="Enter size"
bind:value={data.min}
required={editing} />
<InputNumber
id="max"
label="Max"
{disabled}
placeholder="Enter size"
bind:value={data.max}
required={editing} />
</Layout.Stack>
<InputNumber
id="default"
label="Default value"
@@ -101,19 +104,21 @@
min={data.min}
max={data.max}
bind:value={data.default}
disabled={data.required || data.array}
nullable={!data.required && !data.array} />
disabled={data.required || data.array || disabled}
nullable={(!data.required && !data.array) || disabled} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -39,6 +39,7 @@
import { InputText } from '$lib/elements/forms';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnIp>;
import { createConservative } from '$lib/helpers/stores';
@@ -73,19 +74,21 @@
label="Default value"
placeholder="Enter value"
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -42,11 +42,16 @@
import { onMount } from 'svelte';
interface Props {
data?: Partial<Models.ColumnLine>;
editing?: boolean;
disabled?: boolean;
data?: Partial<Models.ColumnLine>;
}
let { data = { required: false, default: null }, editing = false }: Props = $props();
let {
data = { required: false, default: null },
editing = false,
disabled = false
}: Props = $props();
let savedDefault = $state(data.default);
let defaultChecked = $state(!!data.default);
@@ -106,6 +111,7 @@
size="s"
id="required"
label="Required"
{disabled}
bind:checked={$required}
on:change={(e) => {
if (e.detail) defaultChecked = false;
@@ -116,6 +122,7 @@
size="s"
id="default"
label="Default value"
{disabled}
bind:checked={defaultChecked}
on:change={(e) => {
if (e.detail) {
@@ -134,11 +141,13 @@
<Typography.Caption variant="400">Optional</Typography.Caption>
</Layout.Stack>
{/if}
<InputLine
{disabled}
values={defaultChecked ? data.default : null}
onAddPoint={() => pushCoordinate()}
onDeletePoint={deleteCoordinate}
onChangePoint={(pointIndex: number, coordIndex: number, newValue: number) => {
onChangePoint={(pointIndex, coordIndex, newValue) => {
if (data.default) {
data.default[pointIndex][coordIndex] = newValue;
data.default = [...data.default];
@@ -42,11 +42,19 @@
import { onMount } from 'svelte';
interface Props {
data?: Partial<Models.ColumnPoint>;
editing?: boolean;
disabled?: boolean;
data?: Partial<Models.ColumnPoint>;
}
let { data = { required: false, default: null }, editing }: Props = $props();
let {
data = {
default: null,
required: false
},
editing = false,
disabled = false
}: Props = $props();
let savedDefault = $state(data.default);
let defaultChecked = $state(!!data.default);
@@ -96,6 +104,7 @@
size="s"
id="required"
label="Required"
{disabled}
bind:checked={$required}
on:change={(e) => {
if (e.detail) defaultChecked = false;
@@ -106,6 +115,7 @@
size="s"
id="default"
label="Default value"
{disabled}
bind:checked={defaultChecked}
on:change={(e) => {
if (e.detail) {
@@ -126,6 +136,7 @@
{/if}
<InputPoint
{disabled}
values={defaultChecked ? data.default : null}
onChangePoint={(index, newValue) => {
if (data.default) {
@@ -42,11 +42,19 @@
import { onMount } from 'svelte';
interface Props {
data?: Partial<Models.ColumnPolygon>;
editing?: boolean;
disabled?: boolean;
data?: Partial<Models.ColumnPolygon>;
}
let { data = { required: false, default: null }, editing = false }: Props = $props();
let {
data = {
default: null,
required: false
},
editing = false,
disabled = false
}: Props = $props();
let savedDefault = $state(data.default);
let defaultChecked = $state(!!data.default);
@@ -117,6 +125,7 @@
size="s"
id="required"
label="Required"
{disabled}
bind:checked={$required}
on:change={(e) => {
if (e.detail) defaultChecked = false;
@@ -128,6 +137,7 @@
size="s"
id="default"
label="Default value"
{disabled}
bind:checked={defaultChecked}
on:change={(e) => {
if (e.detail) {
@@ -148,6 +158,7 @@
{/if}
<InputPolygon
{disabled}
values={defaultChecked ? data.default : null}
onAddLine={pushLine}
onAddPoint={pushCoordinate}
@@ -69,6 +69,7 @@
// Props
export let editing = false;
export let disabled = false;
export let data: Models.ColumnRelationship;
// Constants
@@ -158,7 +159,7 @@
bind:group={way}
name="one"
value="one"
disabled={editing}
disabled={editing || disabled}
icon={IconArrowSmRight}>
One Relation column within this table
</Card.Selector>
@@ -167,7 +168,7 @@
bind:group={way}
name="two"
value="two"
disabled={editing}
disabled={editing || disabled}
icon={IconSwitchHorizontal}>
One Relation column within this table and another within the related table
</Card.Selector>
@@ -180,7 +181,7 @@
placeholder="Select a table"
bind:value={data.relatedTable}
on:change={updateKeyName}
disabled={editing}
disabled={editing || disabled}
options={tables?.map((n) => ({ value: n.$id, label: `${n.name} (${n.$id})` })) ?? []} />
{#if data?.relatedTable}
@@ -190,7 +191,8 @@
placeholder="Enter key"
bind:value={data.key}
helper="Allowed characters: a-z, A-Z, 0-9, -, ."
required />
required
{disabled} />
{#if way === 'two'}
<InputText
@@ -199,6 +201,7 @@
placeholder="Enter key"
bind:value={data.twoWayKey}
required
{disabled}
helper="Allowed characters: a-z, A-Z, 0-9, -, . Once created, column key cannot be
adjusted to maintain data integrity."
readonly={editing} />
@@ -211,7 +214,7 @@
required
placeholder="Select a relation"
options={relationshipType}
disabled={editing} />
disabled={editing || disabled} />
<div class="u-flex u-flex-vertical u-gap-16">
<Box>
@@ -251,6 +254,7 @@
label="On deleting a row"
bind:value={data.onDelete}
required
{disabled}
placeholder="Select a deletion method"
options={deleteOptions} />
{/if}
@@ -55,6 +55,7 @@
};
export let editing = false;
export let disabled = false;
let savedDefault = data.default;
@@ -88,6 +89,7 @@
id="size"
label="Size"
required
{disabled}
placeholder="Enter size"
bind:value={data.size}
min={supportsStringEncryption && data.encrypt ? 150 : undefined}
@@ -102,7 +104,7 @@
placeholder="Enter string"
maxlength={data.size}
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<Selector.Checkbox
@@ -110,7 +112,7 @@
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required." />
<Selector.Checkbox
@@ -118,28 +120,28 @@
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
<Layout.Stack gap="xs" direction="column">
<div
class="popover-holder"
class:cursor-not-allowed={editing}
class:disabled-checkbox={!supportsStringEncryption || editing}>
class:cursor-not-allowed={editing || disabled}
class:disabled-checkbox={!supportsStringEncryption || editing || disabled}>
<Layout.Stack inline gap="s" alignItems="flex-start" direction="row">
<Popover let:toggle placement="bottom-start">
<Selector.Checkbox
size="s"
id="encrypt"
bind:checked={data.encrypt}
disabled={!supportsStringEncryption || editing} />
disabled={!supportsStringEncryption || editing || disabled} />
<Layout.Stack gap="xxs" direction="column">
<button
type="button"
disabled={editing}
disabled={editing || disabled}
class:cursor-pointer={!editing}
class:cursor-not-allowed={editing}
class:cursor-not-allowed={editing || disabled}
on:click={(e) => {
if (!supportsStringEncryption) {
toggle(e);
@@ -38,12 +38,12 @@
<script lang="ts">
import { InputURL } from '$lib/elements/forms';
export let data: Partial<Models.ColumnUrl>;
export let editing = false;
import { createConservative } from '$lib/helpers/stores';
import { Selector } from '@appwrite.io/pink-svelte';
import { createConservative } from '$lib/helpers/stores';
export let editing = false;
export let disabled = false;
export let data: Partial<Models.ColumnUrl>;
let savedDefault = data.default;
@@ -74,19 +74,21 @@
label="Default value"
placeholder="Enter value"
bind:value={data.default}
disabled={data.required || data.array}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<Selector.Checkbox
size="s"
id="required"
label="Required"
bind:checked={data.required}
disabled={data.array}
disabled={data.array || disabled}
description="Indicate whether this column is required" />
<Selector.Checkbox
size="s"
id="array"
label="Array"
bind:checked={data.array}
disabled={data.required || editing}
disabled={data.required || editing || disabled}
description="Indicate whether this column is an array. Defaults to an empty array." />
@@ -1,7 +1,7 @@
<script lang="ts">
import { page } from '$app/state';
import { type Columns, type ColumnDirection } from './store';
import { invalidate } from '$app/navigation';
import { goto, invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { Layout } from '@appwrite.io/pink-svelte';
import { InputSelect, InputText } from '$lib/elements/forms';
@@ -11,6 +11,8 @@
import type { Column } from '$lib/helpers/types';
import { preferences } from '$lib/stores/preferences';
import { onMount } from 'svelte';
import { resolve } from '$app/paths';
import { Input as SuggestionsInput, tableColumnSuggestions } from '../(suggestions)/index';
let {
direction = null,
@@ -35,6 +37,9 @@
const tableId = page.params.table;
const databaseId = page.params.database;
// flow isn't complete yet!
const isSuggestionsFeatureEnabled = false;
let key: string = $state(column?.key ?? null);
let data: Partial<Columns> = $state({
required: column?.required ?? false,
@@ -47,6 +52,16 @@
columnOptions.find((option) => option.name === selectedOption).component
);
function initSuggestionsStore() {
if (!isSuggestionsFeatureEnabled) return;
$tableColumnSuggestions.table = null;
$tableColumnSuggestions.enabled = false;
$tableColumnSuggestions.context = null;
$tableColumnSuggestions.thinking = false;
}
function init() {
key = null;
$option = null;
@@ -59,6 +74,9 @@
/* default to string */
selectedOption = 'String';
$option = columnOptions[0];
/* init suggestions */
initSuggestionsStore();
}
function insertColumnInOrder() {
@@ -137,6 +155,33 @@
}
export async function submit() {
if (isSuggestionsEnabled) {
const tableInUse = page.data.table;
// TODO: confirm what flow to use!
tableColumnSuggestions.update((store) => ({
...store,
thinking: true,
table: {
id: tableInUse.$id,
name: tableInUse.name
}
}));
const { region, project, database, table } = page.params;
await goto(
resolve(
'/(console)/project-[region]-[project]/databases/database-[database]/table-[table]',
{
region,
project,
database,
table
}
)
);
return true;
}
try {
await $option.create(databaseId, tableId, key, data);
@@ -177,9 +222,17 @@
$option = columnOptions.find((option) => option.name === selectedOption);
}
});
const isSuggestionsEnabled = $derived(
isSuggestionsFeatureEnabled && $tableColumnSuggestions.enabled
);
</script>
<Layout.Stack gap="xl">
{#if isSuggestionsFeatureEnabled}
<SuggestionsInput />
{/if}
<Layout.Stack direction="row">
<InputText
id="key"
@@ -187,7 +240,7 @@
placeholder="Enter key"
bind:value={key}
autofocus
disabled={selectedOption === 'Relationship'}
disabled={selectedOption === 'Relationship' || isSuggestionsEnabled}
required
pattern="^[A-Za-z0-9][A-Za-z0-9._\-]*$" />
@@ -195,6 +248,7 @@
id="type"
label="Type"
bind:value={selectedOption}
disabled={isSuggestionsEnabled}
options={columnOptions.map((attr) => {
return {
label: attr.name,
@@ -206,6 +260,9 @@
</Layout.Stack>
{#if selectedOption}
<ColumnComponent bind:data onclose={() => ($option = null)} />
<ColumnComponent
disabled={isSuggestionsEnabled}
bind:data
onclose={() => ($option = null)} />
{/if}
</Layout.Stack>