Add InputPolygon component and enhance spatial input handling

- Introduced InputPolygon component for polygon spatial data input.
- Updated InputLine and InputPoint components to support index-based point addition and deletion.
- Modified line and point components to handle default spatial data more effectively.
- Enhanced column components to manage spatial data types including polygon.
This commit is contained in:
ArnabChatterjee20k
2025-09-06 14:58:32 +05:30
parent 8a5eca914c
commit fe7ea4113b
9 changed files with 121 additions and 34 deletions
+1
View File
@@ -33,3 +33,4 @@ export { default as InputFilePicker } from './inputFilePicker.svelte';
export { default as Seekbar } from './Seekbar.svelte';
export { default as InputPoint } from './inputPoint.svelte';
export { default as InputLine } from './inputLine.svelte';
export { default as InputPolygon } from './inputPolygon.svelte';
+8 -7
View File
@@ -6,28 +6,29 @@
export let values: number[][];
export let nullable: boolean;
export let onAddPoint: () => void;
export let onDeletePoint: () => void = undefined;
export let disableDeletePointsCountPerLine: number = 2;
export let onAddPoint: (index: number) => void;
export let onDeletePoint: (index: number) => void = undefined;
let required = true;
$: required = nullable;
$: disableDeletePoints = !values || values.length <= 2;
let disableDeletePoints = false;
$: disableDeletePoints = !values || values.length <= disableDeletePointsCountPerLine;
</script>
<Layout.Stack alignItems="flex-start">
<Layout.Stack>
{#each values as value}
{#each values as value, index}
<InputPoint
nullable={required}
values={value}
deletePoints={true}
disableDelete={disableDeletePoints}
{onDeletePoint} />
onDeletePoint={() => onDeletePoint(index)} />
{/each}
</Layout.Stack>
<Button compact on:click={onAddPoint} disabled={nullable}>
<Button compact on:click={() => onAddPoint(-1)} disabled={nullable}>
<Icon icon={IconPlus} size="s" /> Add coordinate
</Button>
</Layout.Stack>
+12 -6
View File
@@ -7,9 +7,10 @@
export let values: NestedNumberArray;
export let nullable;
export let onAddPoint: () => void;
export let onAddLine: () => void;
export let onDeletePoint: () => void = undefined;
export let onAddPoint: (index: number) => void;
export let onAddLine: (index: number) => void;
export let onDeletePoint: (index: number) => void = undefined;
export let disableDeletePointsCountPerLine: number = 4;
let required = true;
@@ -17,12 +18,17 @@
</script>
<Layout.Stack>
{#each values as value}
<InputLine values={value as number[][]} {onAddPoint} nullable={required} {onDeletePoint} />
{#each values as value, index}
<InputLine
values={value as number[][]}
onAddPoint={() => onAddPoint(index)}
nullable={required}
onDeletePoint={() => onDeletePoint(index)}
{disableDeletePointsCountPerLine} />
{/each}
<Layout.Stack direction="row" gap="s" style="margin-top: 8px;">
<Button compact on:click={onAddLine}>
<Button compact on:click={() => onAddLine(-1)}>
<Icon icon={IconPlus} size="s" /> Add line
</Button>
</Layout.Stack>
@@ -35,19 +35,23 @@
</script>
<script lang="ts">
const defaultData = getDefaultSpatialData('linestring') as number[][];
export let data: Partial<Models.ColumnLine> = {
required: false,
default: defaultData
};
import { createConservative } from '$lib/helpers/stores';
import { Selector, Layout, Typography } from '@appwrite.io/pink-svelte';
import { InputLine } from '$lib/elements/forms';
import { getDefaultSpatialData } from '../store';
import { onMount } from 'svelte';
const defaultData = getDefaultSpatialData('linestring') as number[][];
export let data: Partial<Models.ColumnLine> = {
required: false,
default: null
};
let savedDefault = data.default;
// let showDefaultPointDummyData = false;
let showDefaultPointDummyData = false;
let disableDeletePoints = false;
onMount(() => {
data.default = data.required ? null : defaultData;
});
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
@@ -58,12 +62,12 @@
}
}
function pushCoordinate() {
(data.default as number[][]).push([0, 0]);
function pushCoordinate(_: number) {
data.default.push(getDefaultSpatialData('point') as number[]);
}
function deleteCoordinate() {
if ((data.default as number[][]).length > 2) (data.default as number[][]).pop();
function deleteCoordinate(_: number) {
if (data.default.length > 2) data.default.pop();
}
const {
@@ -78,6 +82,8 @@
$: handleDefaultState($required);
$: showDefaultPointDummyData = $required ? true : false;
$: disableDeletePoints = !data.default || data.default.length <= 2;
</script>
<Selector.Checkbox
@@ -97,5 +103,6 @@
values={data.default || defaultData}
onAddPoint={pushCoordinate}
nullable={showDefaultPointDummyData}
onDeletePoint={deleteCoordinate} />
onDeletePoint={deleteCoordinate}
{disableDeletePoints} />
</Layout.Stack>
@@ -39,12 +39,13 @@
import { getDefaultSpatialData } from '../store';
import { createConservative } from '$lib/helpers/stores';
import { Selector, Typography, Layout } from '@appwrite.io/pink-svelte';
import { onMount } from 'svelte';
const defaultData = getDefaultSpatialData('point') as number[];
export let data: Partial<Models.ColumnPoint> = {
required: false,
default: defaultData
default: null
};
let savedDefault = data.default;
@@ -68,6 +69,10 @@
});
$: listen(data);
onMount(() => {
data.default = data.required ? null : defaultData;
});
$: handleDefaultState($required);
$: showDefaultPointDummyData = $required ? true : false;
@@ -86,5 +91,5 @@
<Typography.Text variant="m-600">Default</Typography.Text>
<Typography.Caption variant="400">Optional</Typography.Caption>
</Layout.Stack>
<InputPoint values={data.default} nullable={showDefaultPointDummyData} />
<InputPoint values={data.default || defaultData} nullable={showDefaultPointDummyData} />
</Layout.Stack>
@@ -37,13 +37,14 @@
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import { Selector, Typography, Layout } from '@appwrite.io/pink-svelte';
import InputPolygon from '$lib/elements/forms/inputPolygon.svelte';
import { InputPolygon } from '$lib/elements/forms';
import { getDefaultSpatialData } from '../store';
import { onMount } from 'svelte';
const defaultData = getDefaultSpatialData('polygon');
export let data: Partial<Models.ColumnPoint> = {
required: false,
default: defaultData
default: null
};
let savedDefault = data.default;
@@ -58,6 +59,31 @@
}
}
function pushCoordinate(ringIndex: number) {
const ring = data.default?.at(ringIndex);
if (!ring) return;
const newPoint = getDefaultSpatialData('point') as number[];
ring.splice(ring.length - 1, 0, newPoint);
ring[ring.length - 1] = [...ring[0]];
}
function pushLine() {
const p1 = getDefaultSpatialData('point') as number[];
const p2 = getDefaultSpatialData('point') as number[];
const p3 = getDefaultSpatialData('point') as number[];
const ring = [p1, p2, p3, [...p1]];
data.default?.push(ring);
}
function deleteCoordinate(ringIndex: number) {
const ring = data.default?.at(ringIndex);
if (!ring || ring.length <= 4) return;
ring.splice(ring.length - 2, 1);
ring[ring.length - 1] = [...ring[0]];
}
const {
stores: { required },
listen
@@ -67,6 +93,10 @@
});
$: listen(data);
onMount(() => {
data.default = data.required ? null : defaultData;
});
$: handleDefaultState($required);
$: showDefaultPointDummyData = $required ? true : false;
@@ -88,6 +118,7 @@
<InputPolygon
values={data.default || defaultData}
nullable={showDefaultPointDummyData}
onAddLine={() => {}}
onAddPoint={() => {}} />
onAddLine={pushLine}
onAddPoint={pushCoordinate}
onDeletePoint={deleteCoordinate} />
</Layout.Stack>
@@ -9,6 +9,7 @@
import Url from './types/url.svelte';
import Point from './types/point.svelte';
import Line from './types/line.svelte';
import Polygon from './types/polygon.svelte';
export let id: string;
export let label: string;
@@ -39,7 +40,8 @@
datetime: Datetime,
relationship: Relationship,
point: Point,
linestring: Line
linestring: Line,
polygon: Polygon
};
const columnsFormatMap = {
@@ -10,6 +10,8 @@
export let limited: boolean = false;
export let column: Models.ColumnLine;
let disableDeletePoints = false;
const defaultData = getDefaultSpatialData('linestring') as number[][];
function onAddPoint() {
value = [...(value || defaultData), getDefaultSpatialData('point') as number[]];
@@ -23,7 +25,7 @@
$: value = nullable ? null : defaultData;
$: console.log({ name: column.key, column, nullable });
$: disableDeletePoints = !value || value.length <= 2;
</script>
<Layout.Stack>
@@ -34,5 +36,10 @@
>optional</Typography.Text>
{/if}
</Layout.Stack>
<InputLine values={value || defaultData} {nullable} {onAddPoint} {onDeletePoint} />
<InputLine
values={value || defaultData}
{nullable}
{onAddPoint}
{onDeletePoint}
{disableDeletePoints} />
</Layout.Stack>
@@ -0,0 +1,27 @@
<script lang="ts">
import { InputPoint } from '$lib/elements/forms';
import type { Models } from '@appwrite.io/console';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
import { getDefaultSpatialData } from '../../../store';
export let id: string;
export let label: string;
export let value: number[];
export let limited: boolean = false;
export let column: Models.ColumnInteger;
$: nullable = !limited ? !column.required : false;
$: value = nullable ? null : (getDefaultSpatialData('point') as number[]);
</script>
<Layout.Stack>
<Layout.Stack direction="row" alignItems="center" gap="s">
<Typography.Text variant="m-500">{label}</Typography.Text>
{#if nullable}
<Typography.Text variant="m-400" color="--fgcolor-neutral-tertiary"
>optional</Typography.Text>
{/if}
</Layout.Stack>
<InputPoint values={value} {nullable} />
</Layout.Stack>