From fb853a2bd3b5c6e489ded5e39a9e494e9be5ffb1 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Mon, 23 Mar 2026 17:14:14 -0700 Subject: [PATCH] Add ability to select items and display in detail view --- ts/components/PlanningColumnAction.vue | 8 ++--- ts/components/PlanningColumnDetail.vue | 26 ++-------------- ts/components/PlanningColumnDetailEntry.vue | 33 +++++++++++++++++++++ ts/components/PlanningColumnList.vue | 12 ++++---- ts/view/Planning.vue | 30 ++++++++++++------- 5 files changed, 65 insertions(+), 44 deletions(-) create mode 100644 ts/components/PlanningColumnDetailEntry.vue diff --git a/ts/components/PlanningColumnAction.vue b/ts/components/PlanningColumnAction.vue index b8d67425..222daaae 100644 --- a/ts/components/PlanningColumnAction.vue +++ b/ts/components/PlanningColumnAction.vue @@ -18,7 +18,7 @@
Signal → Lead
- - - Pool - Nuisance - Water - - - - - {{ shortAddress(signal.address) }} + @@ -107,11 +86,12 @@ import MapMultipoint from "./MapMultipoint.vue"; import MapProxiedArcgisTile from "./MapProxiedArcgisTile.vue"; import { shortAddress } from "../format"; import TimeRelative from "./TimeRelative.vue"; +import PlanningColumnDetailEntry from "./PlanningColumnDetailEntry.vue"; import { useUserStore } from "../store/user"; interface Props { markers: Marker[]; - selectedSignals: Set; + selectedSignals: Array; } const props = defineProps(); const user = useUserStore(); diff --git a/ts/components/PlanningColumnDetailEntry.vue b/ts/components/PlanningColumnDetailEntry.vue new file mode 100644 index 00000000..716caf3c --- /dev/null +++ b/ts/components/PlanningColumnDetailEntry.vue @@ -0,0 +1,33 @@ + + + diff --git a/ts/components/PlanningColumnList.vue b/ts/components/PlanningColumnList.vue index 28647304..9993f968 100644 --- a/ts/components/PlanningColumnList.vue +++ b/ts/components/PlanningColumnList.vue @@ -118,13 +118,13 @@
Signals - - {{ selectedSignals.size }} + + {{ selectedSignalIDs.size }}
No signals found @@ -209,7 +209,7 @@ interface Props { leads: Lead[] | null; loading: boolean; planFollowups: Followup[] | null; - selectedSignals: Set; + selectedSignalIDs: Set; signals: Signal[] | null; } const emit = defineEmits(); @@ -220,10 +220,10 @@ const filters = ref({ sort: "newest", }); const isSelected = (id) => { - return props.selectedSignals.values().some((s) => s.id === id); + return props.selectedSignalIDs.values().some((s) => s.id === id); }; const toggleSignal = (signal: int) => { - if (props.selectedSignals.has(signal)) { + if (props.selectedSignalIDs.has(signal)) { emit("signalDeselect", signal); } else { emit("signalSelect", signal); diff --git a/ts/view/Planning.vue b/ts/view/Planning.vue index 80d6031e..869143e1 100644 --- a/ts/view/Planning.vue +++ b/ts/view/Planning.vue @@ -25,7 +25,7 @@ :loading="loading" :planFollowups="planFollowups" @refresh="refresh" - :selectedSignals="selectedSignals" + :selectedSignalIDs="selectedSignalIDs" @signalDeselect="signalDeselect" @signalSelect="signalSelect" :signals="signal.all" @@ -35,12 +35,13 @@ @@ -70,7 +71,7 @@ const leads = ref([]); const loading = ref(false); const planFollowups = ref([]); const poolLocations = ref({}); -const selectedSignals = ref(new Set([])); +const selectedSignalIDs = ref(new Set([])); const signal = useSignalStore(); const user = useUserStore(); @@ -100,6 +101,13 @@ const getBoundingBox = (points) => { const markers = computed(() => { return []; }); +const selectedSignals = computed(() => { + if (selectedSignalIDs.value.size == 0 || signal.all == null) { + return []; + } + const result = signal.all.filter((s) => selectedSignalIDs.value.has(s)); + return result; +}); const updateMap = (signals) => { const locations = signals.map((s) => s.location); const markers = locations.map((l) => @@ -151,11 +159,11 @@ const loadPlanFollowups = async () => { }; const clearSelection = () => { - selectedSignals.value.clear(); + selectedSignalIDs.value.clear(); }; const createLead = async () => { - if (selectedSignals.value.size === 0) return; + if (selectedSignalIDs.value.size === 0) return; creating.value = true; @@ -167,7 +175,7 @@ const createLead = async () => { }, body: JSON.stringify({ pool_locations: poolLocations.value, - signal_ids: selectedSignals.value.map((s) => s.id), + signal_ids: selectedSignalIDs, }), }); @@ -191,7 +199,7 @@ const createLead = async () => { }; const markAsAddressed = async () => { - if (selectedSignals.value.size === 0) return; + if (selectedSignalIDs.value.size === 0) return; try { const response = await fetch(`${apiBase.value}/signal/mark-addressed`, { @@ -200,7 +208,7 @@ const markAsAddressed = async () => { "Content-Type": "application/json", }, body: JSON.stringify({ - signal_ids: selectedSignals.value.map((s) => s.id), + signal_ids: selectedSignalIDs, }), }); @@ -209,7 +217,7 @@ const markAsAddressed = async () => { } signals.value = signals.value.filter( - (signal) => !selectedSignals.value.some((s) => s.id === signal.id), + (signal) => !selectedSignalIDs.value.has(s.id), ); clearSelection(); @@ -223,10 +231,10 @@ const refresh = () => { loadData(); }; const signalDeselect = (id: int) => { - selectedSignals.value.delete(id); + selectedSignalIDs.value.delete(id); }; const signalSelect = (id: int) => { - selectedSignals.value.add(id); + selectedSignalIDs.value.add(id); }; // Lifecycle onMounted(() => {