-
Notifications
You must be signed in to change notification settings - Fork 188
Spatial type attributes #2338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spatial type attributes #2338
Changes from all commits
5b211bf
80c2ef5
608a55e
3c2802d
b6596db
83d9258
b10916c
a019c99
76d49ae
86a4c85
85c1a14
89a3323
966bc6b
0a03c56
8a5eca9
fe7ea41
90fd508
f543fd3
ae7c57b
c9f2395
fb68793
36cf38b
2530966
64ec31f
cd9f328
3eb3c2c
74129b2
e532775
a13b009
5f0facd
45f0ace
372d5a7
4b1bc65
f081620
bf83c00
8a42ce8
2feb2dd
0fe444a
4f7949a
20815ad
afce403
324a5ed
b6835e9
0d43ca0
b102b8c
a335ecd
211649d
7640efd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,10 +6,11 @@ | |
InputText, | ||
InputTags, | ||
InputSelectCheckbox, | ||
InputDateTime | ||
InputDateTime, | ||
InputPoint | ||
} from '$lib/elements/forms'; | ||
import { onMount, createEventDispatcher } from 'svelte'; | ||
import { operators, addFilter, queries, tags } from './store'; | ||
import { operators, addFilter, queries, tags, ValidOperators } from './store'; | ||
import type { Column } from '$lib/helpers/types'; | ||
import type { Writable } from 'svelte/store'; | ||
import { TagList } from '.'; | ||
|
@@ -18,6 +19,7 @@ | |
let { | ||
value = $bindable(null), | ||
distanceValue = $bindable(null), | ||
columns, | ||
columnId = $bindable(null), | ||
arrayValues = $bindable([]), | ||
|
@@ -27,6 +29,7 @@ | |
// We cast to any to not cause type errors in the input components | ||
/* eslint @typescript-eslint/no-explicit-any: 'off' */ | ||
value?: any; | ||
distanceValue?: number | null; | ||
columns: Writable<Column[]>; | ||
columnId?: string | null; | ||
arrayValues?: string[]; | ||
|
@@ -61,21 +64,57 @@ | |
})); | ||
}); | ||
// Check if the current operator is a distance-based operator | ||
let isDistanceOperator = $derived( | ||
operatorKey && | ||
[ | ||
ValidOperators.DistanceEqual, | ||
ValidOperators.DistanceNotEqual, | ||
ValidOperators.DistanceGreaterThan, | ||
ValidOperators.DistanceLessThan | ||
].includes(operatorKey as ValidOperators) | ||
); | ||
onMount(() => { | ||
value = column?.array ? [] : null; | ||
if (column?.type === 'datetime') { | ||
const now = new Date(); | ||
value = now.toISOString().slice(0, 16); | ||
} | ||
// Initialize spatial data with default values | ||
if (column?.type === 'point') { | ||
value = [0, 0]; | ||
} else if (column?.type === 'linestring') { | ||
value = [ | ||
[0, 0], | ||
[1, 1] | ||
]; | ||
} else if (column?.type === 'polygon') { | ||
value = [ | ||
[ | ||
[0, 0], | ||
[1, 1], | ||
[2, 2], | ||
[0, 0] | ||
] | ||
]; | ||
} | ||
}); | ||
const dispatch = createEventDispatcher<{ clear: void; apply: { applied: number } }>(); | ||
function addFilterAndReset() { | ||
addFilter(columnsArray, columnId, operatorKey, value, arrayValues); | ||
// For distance operators, pass the distance as a separate parameter | ||
if (isDistanceOperator && distanceValue !== null && value !== null) { | ||
addFilter(columnsArray, columnId, operatorKey, value, arrayValues, distanceValue); | ||
} else { | ||
addFilter(columnsArray, columnId, operatorKey, value, arrayValues); | ||
} | ||
Comment on lines
106
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Don’t add distance filters without a geometry; guard the call to As written, distance operators fall back to the non-distance call when - // For distance operators, pass the distance as a separate parameter
- if (isDistanceOperator && distanceValue !== null && value !== null) {
- addFilter(columnsArray, columnId, operatorKey, value, arrayValues, distanceValue);
- } else {
- addFilter(columnsArray, columnId, operatorKey, value, arrayValues);
- }
+ // For distance operators, require both geometry and distance
+ if (isDistanceOperator) {
+ if (distanceValue == null || value == null) return;
+ addFilter(columnsArray, columnId, operatorKey, value, arrayValues, distanceValue);
+ } else {
+ addFilter(columnsArray, columnId, operatorKey, value, arrayValues);
+ } Optional UX: also disable the submit button when missing inputs: <!-- change at the Button below -->
<Button text disabled={isDisabled || (isDistanceOperator && (distanceValue == null || value == null))} class="u-margin-block-start-4" submit> Also applies to: 117-118 🤖 Prompt for AI Agents
|
||
columnId = null; | ||
operatorKey = null; | ||
value = null; | ||
distanceValue = null; | ||
arrayValues = []; | ||
dispatch('apply', { applied: appliedTags.length }); | ||
if (singleCondition) { | ||
|
@@ -143,11 +182,29 @@ | |
{#key value} | ||
<InputDateTime id="value" bind:value step={60} type="datetime-local" /> | ||
{/key} | ||
{:else if column.type === 'point' || column.type === 'linestring' || column.type === 'polygon'} | ||
<InputPoint | ||
values={value || [0, 0]} | ||
onChangePoint={(index, newValue) => { | ||
if (!value) value = [0, 0]; | ||
value[index] = newValue; | ||
}} /> | ||
Comment on lines
+185
to
+191
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainWrong input component for linestring/polygon and non-reactive mutation
- {:else if column.type === 'point' || column.type === 'linestring' || column.type === 'polygon'}
- <InputPoint
- values={value || [0, 0]}
- onChangePoint={(index, newValue) => {
- if (!value) value = [0, 0];
- value[index] = newValue;
- }} />
+ {:else if column.type === 'point'}
+ <InputPoint
+ values={value ?? [0, 0]}
+ onChangePoint={(index, newValue) => {
+ const next = [...(value ?? [0, 0])];
+ next[index] = newValue;
+ value = next;
+ }} />
+ {:else if column.type === 'linestring'}
+ <InputLine
+ values={value ?? [[0, 0], [1, 0]]}
+ onChangeLine={(next) => {
+ value = next;
+ }} />
+ {:else if column.type === 'polygon'}
+ <InputPolygon
+ values={value ?? [[[0, 0],[1, 0],[1, 1],[0, 1],[0, 0]]]}
+ onChangePolygon={(next) => {
+ value = next;
+ }} /> Run to confirm the event/prop API for these inputs (adjust handlers/bindings accordingly): 🏁 Script executed: #!/bin/bash
# Inspect spatial input components for prop and event names
fd -t f 'input(point|line|polygon).svelte' src | xargs -I{} sh -c 'echo "---- {} ----"; rg -n "export let|createEventDispatcher|dispatch|onChange" -n {} -C2' Length of output: 2774 Use correct spatial inputs and reassign arrays for reactivity (content.svelte:172-178)
Ensures correct component shapes and triggers Svelte reactivity by assigning new arrays. 🤖 Prompt for AI Agents
|
||
{:else} | ||
<InputText id="value" bind:value placeholder="Enter value" /> | ||
{/if} | ||
</ul> | ||
{/if} | ||
|
||
{#if isDistanceOperator} | ||
<div class="u-margin-block-start-8"> | ||
<InputNumber | ||
id="distance" | ||
bind:value={distanceValue} | ||
placeholder="Enter distance" | ||
step={0.001} | ||
required /> | ||
</div> | ||
{/if} | ||
{/if} | ||
{#if !singleCondition} | ||
<Button text disabled={isDisabled} class="u-margin-block-start-4" submit> | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -36,6 +36,7 @@ | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
/* eslint @typescript-eslint/no-explicit-any: 'off' */ | ||||||||||||||||||||||||||||||||||
let value: any = null; | ||||||||||||||||||||||||||||||||||
let distanceValue: number | null = null; | ||||||||||||||||||||||||||||||||||
let selectedColumn: string | null = null; | ||||||||||||||||||||||||||||||||||
let operatorKey: string | null = null; | ||||||||||||||||||||||||||||||||||
let arrayValues: string[] = []; | ||||||||||||||||||||||||||||||||||
|
@@ -46,6 +47,16 @@ | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
$: filtersAppliedCount = $tags.length; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
// Check if the current operator is a distance-based operator | ||||||||||||||||||||||||||||||||||
$: isDistanceOperator = | ||||||||||||||||||||||||||||||||||
operatorKey && | ||||||||||||||||||||||||||||||||||
[ | ||||||||||||||||||||||||||||||||||
ValidOperators.DistanceEqual, | ||||||||||||||||||||||||||||||||||
ValidOperators.DistanceNotEqual, | ||||||||||||||||||||||||||||||||||
ValidOperators.DistanceGreaterThan, | ||||||||||||||||||||||||||||||||||
ValidOperators.DistanceLessThan | ||||||||||||||||||||||||||||||||||
].includes(operatorKey as ValidOperators); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
beforeNavigate(() => { | ||||||||||||||||||||||||||||||||||
showFiltersDesktop = false; | ||||||||||||||||||||||||||||||||||
showFiltersMobile = false; | ||||||||||||||||||||||||||||||||||
|
@@ -54,6 +65,8 @@ | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
function clearAll() { | ||||||||||||||||||||||||||||||||||
selectedColumn = null; | ||||||||||||||||||||||||||||||||||
value = null; | ||||||||||||||||||||||||||||||||||
distanceValue = null; | ||||||||||||||||||||||||||||||||||
queries.clearAll(); | ||||||||||||||||||||||||||||||||||
if (clearOnClick) { | ||||||||||||||||||||||||||||||||||
trackEvent(Submit.FilterClear, { source: analyticsSource }); | ||||||||||||||||||||||||||||||||||
|
@@ -73,9 +86,15 @@ | |||||||||||||||||||||||||||||||||
value || | ||||||||||||||||||||||||||||||||||
arrayValues.length) | ||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||
addFilter($columns, selectedColumn, operatorKey, value, arrayValues); | ||||||||||||||||||||||||||||||||||
// For distance operators, pass the distance as a separate parameter | ||||||||||||||||||||||||||||||||||
if (isDistanceOperator && distanceValue !== null && value !== null) { | ||||||||||||||||||||||||||||||||||
addFilter($columns, selectedColumn, operatorKey, value, arrayValues, distanceValue); | ||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||
addFilter($columns, selectedColumn, operatorKey, value, arrayValues); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
Comment on lines
+89
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Prevent adding distance filters without a distance parameter. - // For distance operators, pass the distance as a separate parameter
- if (isDistanceOperator && distanceValue !== null && value !== null) {
- addFilter($columns, selectedColumn, operatorKey, value, arrayValues, distanceValue);
- } else {
- addFilter($columns, selectedColumn, operatorKey, value, arrayValues);
- }
+ // Distance operators require both a geometry value and a distance
+ if (isDistanceOperator) {
+ if (distanceValue !== null && value !== null) {
+ addFilter($columns, selectedColumn, operatorKey, value, arrayValues, distanceValue);
+ } else {
+ return; // guard: incomplete distance filter
+ }
+ } else {
+ addFilter($columns, selectedColumn, operatorKey, value, arrayValues);
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||
selectedColumn = null; | ||||||||||||||||||||||||||||||||||
value = null; | ||||||||||||||||||||||||||||||||||
distanceValue = null; | ||||||||||||||||||||||||||||||||||
operatorKey = null; | ||||||||||||||||||||||||||||||||||
arrayValues = []; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
@@ -97,6 +116,7 @@ | |||||||||||||||||||||||||||||||||
$: if (!showFiltersDesktop && !showFiltersMobile) { | ||||||||||||||||||||||||||||||||||
selectedColumn = null; | ||||||||||||||||||||||||||||||||||
value = null; | ||||||||||||||||||||||||||||||||||
distanceValue = null; | ||||||||||||||||||||||||||||||||||
operatorKey = null; | ||||||||||||||||||||||||||||||||||
arrayValues = []; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
@@ -163,6 +183,7 @@ | |||||||||||||||||||||||||||||||||
bind:columnId={selectedColumn} | ||||||||||||||||||||||||||||||||||
bind:operatorKey | ||||||||||||||||||||||||||||||||||
bind:value | ||||||||||||||||||||||||||||||||||
bind:distanceValue | ||||||||||||||||||||||||||||||||||
bind:arrayValues | ||||||||||||||||||||||||||||||||||
Comment on lines
+186
to
187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify Content.svelte supports distanceValue two-way binding with proper typing. Also applies to: 247-248 🏁 Script executed: #!/bin/bash
rg -nP 'export\s+let\s+distanceValue' src/lib/components/filters/content.svelte -n
rg -nP 'bind:distanceValue' src/lib/components/filters -n Length of output: 177 Export and type <script lang="ts">
export let distanceValue: number | null = null;
// …
</script> Ensure the input in this component is using 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||
{columns} | ||||||||||||||||||||||||||||||||||
{singleCondition} | ||||||||||||||||||||||||||||||||||
|
@@ -225,6 +246,7 @@ | |||||||||||||||||||||||||||||||||
bind:columnId={selectedColumn} | ||||||||||||||||||||||||||||||||||
bind:operatorKey | ||||||||||||||||||||||||||||||||||
bind:value | ||||||||||||||||||||||||||||||||||
bind:distanceValue | ||||||||||||||||||||||||||||||||||
bind:arrayValues | ||||||||||||||||||||||||||||||||||
{singleCondition} | ||||||||||||||||||||||||||||||||||
on:apply={afterApply} | ||||||||||||||||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.