create form and modal components, update datatable persistant filtering

This commit is contained in:
Casey 2025-10-30 03:21:41 -05:00
parent b70e08026d
commit 8d9bb81fe2
23 changed files with 3502 additions and 74 deletions

View file

@ -0,0 +1,165 @@
<template lang="html">
<DataTable
:value="data"
:rowsPerPageOptions="[5, 10, 20, 50]"
:paginator="true"
:rows="10"
sortMode="multiple"
removableSort
filterDisplay="row"
v-model:filters="filterRef"
scrollable
scrollHeight="70vh"
v-model:selection="selectedRows"
selectionMode="multiple"
metaKeySelection="true"
dataKey="id"
>
<Column
v-for="col in columns"
:key="col.fieldName"
:field="col.fieldName"
:header="col.label"
:sortable="col.sortable"
>
<template v-if="col.filterable === true" #filter="{ filterModel, filterCallback }">
<InputText
v-model="filterModel.value"
type="text"
@input="handleFilterInput(col.fieldName, filterModel.value, filterCallback)"
:placeholder="`Search ${col.label}...`"
/>
</template>
<template v-if="col.type === 'status'" #body="slotProps">
<Tag
:value="slotProps.data[col.fieldName]"
:severity="getBadgeColor(slotProps.data[col.fieldName])"
/>
</template>
<template v-if="col.type === 'button'" #body="slotProps">
<Button
:label="slotProps.data[col.fieldName]"
size="small"
severity="info"
@click="$emit('rowClick', slotProps)"
/>
</template>
</Column>
</DataTable>
</template>
<script setup>
import { defineProps, computed, onMounted, watch } from "vue";
import DataTable from "primevue/datatable";
import Column from "primevue/column";
import Tag from "primevue/tag";
import Button from "primevue/button";
import InputText from "primevue/inputtext";
import { ref } from "vue";
import { FilterMatchMode } from "@primevue/core";
import { useFiltersStore } from "../../stores/filters";
const filtersStore = useFiltersStore();
const props = defineProps({
columns: {
type: Array,
required: true,
},
data: {
type: Array,
required: true,
},
filters: {
type: Object,
default: () => ({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
}),
},
tableName: {
type: String,
required: true,
},
});
const emit = defineEmits(["rowClick"]);
// Initialize filters in store when component mounts
onMounted(() => {
filtersStore.initializeTableFilters(props.tableName, props.columns);
});
// Get filters from store, with fallback to props.filters
const filterRef = computed({
get() {
const storeFilters = filtersStore.getTableFilters(props.tableName);
// Merge store filters with any additional filters from props
return { ...props.filters, ...storeFilters };
},
set(newFilters) {
// Update store when filters change
Object.keys(newFilters).forEach(key => {
if (key !== 'global' && newFilters[key]) {
const filter = newFilters[key];
filtersStore.updateTableFilter(
props.tableName,
key,
filter.value,
filter.matchMode
);
}
});
}
});
// Watch for filter changes to sync match mode changes
watch(filterRef, (newFilters) => {
Object.keys(newFilters).forEach(key => {
if (key !== 'global' && newFilters[key]) {
const filter = newFilters[key];
const storeFilter = filtersStore.getTableFilters(props.tableName)[key];
// Only update if the match mode has actually changed
if (storeFilter && storeFilter.matchMode !== filter.matchMode) {
filtersStore.updateTableFilter(
props.tableName,
key,
filter.value,
filter.matchMode
);
}
}
});
}, { deep: true });
const selectedRows = ref();
// Handle filter input changes
const handleFilterInput = (fieldName, value, filterCallback) => {
// Get the current filter to preserve the match mode
const currentFilter = filterRef.value[fieldName];
const matchMode = currentFilter?.matchMode || FilterMatchMode.CONTAINS;
// Update the store with both value and match mode
filtersStore.updateTableFilter(props.tableName, fieldName, value, matchMode);
// Call the PrimeVue filter callback
filterCallback();
};
const getBadgeColor = (status) => {
console.log("DEBUG: - getBadgeColor status", status);
switch (status?.toLowerCase()) {
case "completed":
return "success"; // green
case "in progress":
return "warn";
case "not started":
return "danger"; // red
default:
return "info"; // blue fallback
}
};
console.log("DEBUG: - DataTable props.columns", props.columns);
console.log("DEBUG: - DataTable props.data", props.data);
</script>
<style lang="">
</style>