add global loading state, update to use real data for clients table

This commit is contained in:
Casey 2025-11-04 08:33:14 -06:00
parent 2cfe7ed8e6
commit 464c62d1e5
12 changed files with 1075 additions and 194 deletions

View file

@ -14,7 +14,21 @@
selectionMode="multiple"
metaKeySelection="true"
dataKey="id"
:loading="loading"
:loadingIcon="loadingIcon"
>
<template #empty>
<div class="text-center py-6">
<i class="pi pi-info-circle text-4xl text-gray-400 mb-2"></i>
<p class="text-gray-500">{{ emptyMessage || "No data available" }}</p>
</div>
</template>
<template #loading>
<div class="text-center py-6">
<i class="pi pi-spin pi-spinner text-4xl text-blue-500 mb-2"></i>
<p class="text-gray-600">{{ loadingMessage || "Loading data. Please wait..." }}</p>
</div>
</template>
<Column
v-for="col in columns"
:key="col.fieldName"
@ -28,6 +42,7 @@
type="text"
@input="handleFilterInput(col.fieldName, filterModel.value, filterCallback)"
:placeholder="`Search ${col.label}...`"
:disabled="loading"
/>
</template>
<template v-if="col.type === 'status'" #body="slotProps">
@ -57,8 +72,10 @@ import InputText from "primevue/inputtext";
import { ref } from "vue";
import { FilterMatchMode } from "@primevue/core";
import { useFiltersStore } from "../../stores/filters";
import { useLoadingStore } from "../../stores/loading";
const filtersStore = useFiltersStore();
const loadingStore = useLoadingStore();
const props = defineProps({
columns: {
@ -79,10 +96,44 @@ const props = defineProps({
type: String,
required: true,
},
loading: {
type: Boolean,
default: false,
},
loadingMessage: {
type: String,
default: "",
},
emptyMessage: {
type: String,
default: "",
},
loadingIcon: {
type: String,
default: "pi pi-spinner pi-spin",
},
// Auto-connect to global loading store
useGlobalLoading: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(["rowClick"]);
// Computed loading state that considers both prop and global store
const loading = computed(() => {
if (props.useGlobalLoading) {
return (
props.loading ||
loadingStore.getComponentLoading("dataTable") ||
loadingStore.getComponentLoading(props.tableName) ||
loadingStore.isAnyLoading
);
}
return props.loading;
});
// Initialize filters in store when component mounts
onMounted(() => {
filtersStore.initializeTableFilters(props.tableName, props.columns);
@ -97,39 +148,43 @@ const filterRef = computed({
},
set(newFilters) {
// Update store when filters change
Object.keys(newFilters).forEach(key => {
if (key !== 'global' && newFilters[key]) {
Object.keys(newFilters).forEach((key) => {
if (key !== "global" && newFilters[key]) {
const filter = newFilters[key];
filtersStore.updateTableFilter(
props.tableName,
key,
filter.value,
filter.matchMode
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
);
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 });
});
},
{ deep: true },
);
const selectedRows = ref();
@ -138,7 +193,7 @@ 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
@ -160,6 +215,12 @@ const getBadgeColor = (status) => {
};
console.log("DEBUG: - DataTable props.columns", props.columns);
console.log("DEBUG: - DataTable props.data", props.data);
// Expose loading control methods for parent components
defineExpose({
startLoading: (message) => loadingStore.setComponentLoading(props.tableName, true, message),
stopLoading: () => loadingStore.setComponentLoading(props.tableName, false),
isLoading: () => loading.value,
});
</script>
<style lang="">
</style>
<style lang=""></style>