add global loading state, update to use real data for clients table
This commit is contained in:
parent
2cfe7ed8e6
commit
464c62d1e5
12 changed files with 1075 additions and 194 deletions
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue