diff --git a/ts/components/CommunicationColumnList.vue b/ts/components/CommunicationColumnList.vue index a64930b3..49b3ab88 100644 --- a/ts/components/CommunicationColumnList.vue +++ b/ts/components/CommunicationColumnList.vue @@ -1,51 +1,184 @@ + - - - + + + + + Status + + + New + + + Opened + + + Pending + + + Closed + + + + + + Source + + + All + + + Email + + + Text + + + Form + + + + + + + Type + + + All + + + Compliance + + + Nuisance + + + Water + + + + + + + {{ filteredCommunications.length }} of + {{ props.all?.length || 0 }} reports + - - - - All - - - Nuisance - - - Water - - + Loading... @@ -55,16 +188,15 @@ :isSelected="selectedID == comm.id" /> + + + No reports match the current filters + + Reset Filters + + - - - - No reports found - @@ -84,8 +216,8 @@ interface Emits { } const props = defineProps(); - const emit = defineEmits(); + const handleClick = (id: string) => { if (props.selectedID == undefined) { emit("select", id); @@ -95,23 +227,77 @@ const handleClick = (id: string) => { emit("select", id); } }; + +// Filter state const searchFilter = ref(""); const typeFilter = ref("all"); +const sourceFilter = ref("all"); +const statusFilters = ref({ + new: true, + opened: true, + pending: false, + closed: false, +}); -function selectCommunication(communication: Communication) { - // Emit both events - one for general use, one for v-model - console.log("selected", communication); - emit("select", communication.id); - //emit("update:selectedItem", communication); - //messageText.value = ""; - //updateMap(); -} +// Reset filters to default +const resetFilters = () => { + searchFilter.value = ""; + typeFilter.value = "all"; + sourceFilter.value = "all"; + statusFilters.value = { + new: true, + opened: true, + pending: false, + closed: false, + }; +}; -// Computed properties +// Count active filters +const activeFilterCount = computed(() => { + let count = 0; + if (typeFilter.value !== "all") count++; + if (sourceFilter.value !== "all") count++; + if (searchFilter.value.length > 0) count++; + return count; +}); + +// Filtered communications const filteredCommunications = computed((): Communication[] => { if (props.all == null) { return []; } - return props.all; + + return props.all.filter((comm) => { + // Status filter + const selectedStatuses = Object.entries(statusFilters.value) + .filter(([_, isSelected]) => isSelected) + .map(([status]) => status); + + if ( + selectedStatuses.length > 0 && + !selectedStatuses.includes(comm.status) + ) { + return false; + } + + // Source filter + if ( + sourceFilter.value !== "all" && + !comm.type.startsWith(sourceFilter.value) + ) { + return false; + } + + // Type filter + if ( + sourceFilter.value === "publicreport" && + typeFilter.value !== "all" && + comm.type !== typeFilter.value + ) { + return false; + } + + return true; + }); });
No reports match the current filters
No reports found