update filter functionality
This commit is contained in:
parent
464c62d1e5
commit
9431a0502a
10 changed files with 2362 additions and 220 deletions
|
|
@ -6,7 +6,17 @@
|
|||
Add
|
||||
</button>
|
||||
</div>
|
||||
<DataTable :data="tableData" :columns="columns" :filters="filters" tableName="clients" />
|
||||
<DataTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
:filters="filters"
|
||||
tableName="clients"
|
||||
:lazy="true"
|
||||
:totalRecords="totalRecords"
|
||||
:loading="isLoading"
|
||||
:onLazyLoad="handleLazyLoad"
|
||||
@lazy-load="handleLazyLoad"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
|
@ -15,13 +25,16 @@ import DataTable from "../common/DataTable.vue";
|
|||
import Api from "../../api";
|
||||
import { FilterMatchMode } from "@primevue/core";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { usePaginationStore } from "../../stores/pagination";
|
||||
import { useFiltersStore } from "../../stores/filters";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const paginationStore = usePaginationStore();
|
||||
const filtersStore = useFiltersStore();
|
||||
|
||||
const itemCount = ref(0);
|
||||
const page = ref(0);
|
||||
const pageLength = ref(30);
|
||||
const tableData = ref([]);
|
||||
const totalRecords = ref(0);
|
||||
const isLoading = ref(false);
|
||||
|
||||
const onClick = () => {
|
||||
frappe.new_doc("Customer");
|
||||
|
|
@ -49,23 +62,114 @@ const columns = [
|
|||
{ label: "Payment Received", fieldName: "paymentStatus", type: "status", sortable: true },
|
||||
{ label: "Job Status", fieldName: "jobStatus", type: "status", sortable: true },
|
||||
];
|
||||
onMounted(async () => {
|
||||
if (tableData.value.length > 0) {
|
||||
return;
|
||||
}
|
||||
// Handle lazy loading events from DataTable
|
||||
const handleLazyLoad = async (event) => {
|
||||
console.log("Clients page - handling lazy load:", event);
|
||||
|
||||
try {
|
||||
// Use the loading store to track this API call
|
||||
const data = await loadingStore.withComponentLoading(
|
||||
isLoading.value = true;
|
||||
|
||||
// Get pagination parameters
|
||||
const paginationParams = {
|
||||
page: event.page || 0,
|
||||
pageSize: event.rows || 10,
|
||||
sortField: event.sortField,
|
||||
sortOrder: event.sortOrder,
|
||||
};
|
||||
|
||||
// Get filters (convert PrimeVue format to API format)
|
||||
const filters = {};
|
||||
if (event.filters) {
|
||||
Object.keys(event.filters).forEach((key) => {
|
||||
if (key !== "global" && event.filters[key] && event.filters[key].value) {
|
||||
filters[key] = event.filters[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
const cachedData = paginationStore.getCachedPage(
|
||||
"clients",
|
||||
() => Api.getClientDetails(),
|
||||
"Loading client data...",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
);
|
||||
tableData.value = data;
|
||||
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
tableData.value = cachedData.records;
|
||||
totalRecords.value = cachedData.totalRecords;
|
||||
paginationStore.setTotalRecords("clients", cachedData.totalRecords);
|
||||
|
||||
console.log("Loaded from cache:", {
|
||||
records: cachedData.records.length,
|
||||
total: cachedData.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Making API call with:", { paginationParams, filters });
|
||||
|
||||
// Call API with pagination and filters
|
||||
const result = await Api.getPaginatedClientDetails(paginationParams, filters);
|
||||
|
||||
// Update local state
|
||||
tableData.value = result.data;
|
||||
totalRecords.value = result.totalRecords;
|
||||
|
||||
// Update pagination store with new total
|
||||
paginationStore.setTotalRecords("clients", result.totalRecords);
|
||||
|
||||
// Cache the result
|
||||
paginationStore.setCachedPage(
|
||||
"clients",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
{
|
||||
records: result.data,
|
||||
totalRecords: result.totalRecords,
|
||||
},
|
||||
);
|
||||
|
||||
console.log("Loaded from API:", {
|
||||
records: result.data.length,
|
||||
total: result.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error loading client data:", error);
|
||||
// You could also show a toast or other error notification here
|
||||
tableData.value = [];
|
||||
totalRecords.value = 0;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Load initial data
|
||||
onMounted(async () => {
|
||||
// Initialize pagination and filters
|
||||
paginationStore.initializeTablePagination("clients", { rows: 10 });
|
||||
filtersStore.initializeTableFilters("clients", columns);
|
||||
|
||||
// Load first page
|
||||
const initialPagination = paginationStore.getTablePagination("clients");
|
||||
const initialFilters = filtersStore.getTableFilters("clients");
|
||||
|
||||
await handleLazyLoad({
|
||||
page: initialPagination.page,
|
||||
rows: initialPagination.rows,
|
||||
first: initialPagination.first,
|
||||
sortField: initialPagination.sortField,
|
||||
sortOrder: initialPagination.sortOrder,
|
||||
filters: initialFilters,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style lang="css"></style>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,34 @@
|
|||
<template>
|
||||
<div>
|
||||
<h2>Jobs</h2>
|
||||
<DataTable :data="tableData" :columns="columns" tableName="jobs" />
|
||||
<DataTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
tableName="jobs"
|
||||
:lazy="true"
|
||||
:totalRecords="totalRecords"
|
||||
:loading="isLoading"
|
||||
:onLazyLoad="handleLazyLoad"
|
||||
@lazy-load="handleLazyLoad"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import DataTable from "../common/DataTable.vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import Api from "../../api";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { usePaginationStore } from "../../stores/pagination";
|
||||
import { useFiltersStore } from "../../stores/filters";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const paginationStore = usePaginationStore();
|
||||
const filtersStore = useFiltersStore();
|
||||
|
||||
const tableData = ref([]);
|
||||
const totalRecords = ref(0);
|
||||
const isLoading = ref(false);
|
||||
|
||||
const columns = [
|
||||
{ label: "Job ID", fieldName: "jobId", type: "text", sortable: true, filterable: true },
|
||||
{ label: "Address", fieldName: "address", type: "text", sortable: true },
|
||||
|
|
@ -18,12 +37,119 @@ const columns = [
|
|||
{ label: "Progress", fieldName: "stepProgress", type: "text", sortable: true },
|
||||
];
|
||||
|
||||
onMounted(async () => {
|
||||
if (tableData.value.length > 0) {
|
||||
return;
|
||||
// Handle lazy loading events from DataTable
|
||||
const handleLazyLoad = async (event) => {
|
||||
console.log("Jobs page - handling lazy load:", event);
|
||||
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
// Get pagination parameters
|
||||
const paginationParams = {
|
||||
page: event.page || 0,
|
||||
pageSize: event.rows || 10,
|
||||
sortField: event.sortField,
|
||||
sortOrder: event.sortOrder,
|
||||
};
|
||||
|
||||
// Get filters (convert PrimeVue format to API format)
|
||||
const filters = {};
|
||||
if (event.filters) {
|
||||
Object.keys(event.filters).forEach((key) => {
|
||||
if (key !== "global" && event.filters[key] && event.filters[key].value) {
|
||||
filters[key] = event.filters[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
const cachedData = paginationStore.getCachedPage(
|
||||
"jobs",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
);
|
||||
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
tableData.value = cachedData.records;
|
||||
totalRecords.value = cachedData.totalRecords;
|
||||
paginationStore.setTotalRecords("jobs", cachedData.totalRecords);
|
||||
|
||||
console.log("Loaded from cache:", {
|
||||
records: cachedData.records.length,
|
||||
total: cachedData.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Making API call with:", { paginationParams, filters });
|
||||
|
||||
// For now, use existing API but we should create a paginated version
|
||||
// TODO: Create Api.getPaginatedJobDetails() method
|
||||
let data = await Api.getJobDetails();
|
||||
|
||||
// Simulate pagination on client side for now
|
||||
const startIndex = paginationParams.page * paginationParams.pageSize;
|
||||
const endIndex = startIndex + paginationParams.pageSize;
|
||||
const paginatedData = data.slice(startIndex, endIndex);
|
||||
|
||||
// Update local state
|
||||
tableData.value = paginatedData;
|
||||
totalRecords.value = data.length;
|
||||
|
||||
// Update pagination store with new total
|
||||
paginationStore.setTotalRecords("jobs", data.length);
|
||||
|
||||
// Cache the result
|
||||
paginationStore.setCachedPage(
|
||||
"jobs",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
{
|
||||
records: paginatedData,
|
||||
totalRecords: data.length,
|
||||
},
|
||||
);
|
||||
|
||||
console.log("Loaded from API:", {
|
||||
records: paginatedData.length,
|
||||
total: data.length,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error loading job data:", error);
|
||||
tableData.value = [];
|
||||
totalRecords.value = 0;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
let data = await Api.getJobDetails();
|
||||
tableData.value = data;
|
||||
};
|
||||
|
||||
// Load initial data
|
||||
onMounted(async () => {
|
||||
// Initialize pagination and filters
|
||||
paginationStore.initializeTablePagination("jobs", { rows: 10 });
|
||||
filtersStore.initializeTableFilters("jobs", columns);
|
||||
|
||||
// Load first page
|
||||
const initialPagination = paginationStore.getTablePagination("jobs");
|
||||
const initialFilters = filtersStore.getTableFilters("jobs");
|
||||
|
||||
await handleLazyLoad({
|
||||
page: initialPagination.page,
|
||||
rows: initialPagination.rows,
|
||||
first: initialPagination.first,
|
||||
sortField: initialPagination.sortField,
|
||||
sortOrder: initialPagination.sortOrder,
|
||||
filters: initialFilters,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style lang=""></style>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,17 @@
|
|||
|
||||
<!-- Routes Data Table -->
|
||||
<div class="routes-table-container">
|
||||
<DataTable :data="tableData" :columns="columns" tableName="routes" @row-click="viewRouteDetails" />
|
||||
<DataTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
tableName="routes"
|
||||
:lazy="true"
|
||||
:totalRecords="totalRecords"
|
||||
:loading="isLoading"
|
||||
:onLazyLoad="handleLazyLoad"
|
||||
@lazy-load="handleLazyLoad"
|
||||
@row-click="viewRouteDetails"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Route Details Modal -->
|
||||
|
|
@ -139,9 +149,7 @@
|
|||
<v-icon size="x-small" class="mr-1"
|
||||
>mdi-clock</v-icon
|
||||
>
|
||||
{{ stop.estimatedTime }} ({{
|
||||
stop.duration
|
||||
}}
|
||||
{{ stop.estimatedTime }} ({{ stop.duration }}
|
||||
min)
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -230,17 +238,33 @@
|
|||
import { ref, onMounted } from "vue";
|
||||
import DataTable from "../common/DataTable.vue";
|
||||
import Api from "../../api";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { usePaginationStore } from "../../stores/pagination";
|
||||
import { useFiltersStore } from "../../stores/filters";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const paginationStore = usePaginationStore();
|
||||
const filtersStore = useFiltersStore();
|
||||
|
||||
// Reactive data
|
||||
const tableData = ref([]);
|
||||
const totalRecords = ref(0);
|
||||
const isLoading = ref(false);
|
||||
const routeDialog = ref(false);
|
||||
const selectedRoute = ref(null);
|
||||
const fullRouteData = ref([]); // Store full route data for modal access
|
||||
|
||||
// Table columns configuration
|
||||
const columns = [
|
||||
{ label: "Route ID", fieldName: "routeId", type: "text", sortable: true },
|
||||
{ label: "Route ID", fieldName: "routeId", type: "text", sortable: true, filterable: true },
|
||||
{ label: "Route Name", fieldName: "routeName", type: "text", sortable: true },
|
||||
{ label: "Technician", fieldName: "technician", type: "text", sortable: true },
|
||||
{
|
||||
label: "Technician",
|
||||
fieldName: "technician",
|
||||
type: "text",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
},
|
||||
{ label: "Date", fieldName: "date", type: "text", sortable: true },
|
||||
{ label: "Status", fieldName: "status", type: "status", sortable: true },
|
||||
{ label: "Progress", fieldName: "progress", type: "text", sortable: true },
|
||||
|
|
@ -249,12 +273,127 @@ const columns = [
|
|||
{ label: "Actions", fieldName: "actions", type: "button", sortable: false },
|
||||
];
|
||||
|
||||
// Handle lazy loading events from DataTable
|
||||
const handleLazyLoad = async (event) => {
|
||||
console.log("Routes page - handling lazy load:", event);
|
||||
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
// Get pagination parameters
|
||||
const paginationParams = {
|
||||
page: event.page || 0,
|
||||
pageSize: event.rows || 10,
|
||||
sortField: event.sortField,
|
||||
sortOrder: event.sortOrder,
|
||||
};
|
||||
|
||||
// Get filters (convert PrimeVue format to API format)
|
||||
const filters = {};
|
||||
if (event.filters) {
|
||||
Object.keys(event.filters).forEach((key) => {
|
||||
if (key !== "global" && event.filters[key] && event.filters[key].value) {
|
||||
filters[key] = event.filters[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
const cachedData = paginationStore.getCachedPage(
|
||||
"routes",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
);
|
||||
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
tableData.value = cachedData.records;
|
||||
totalRecords.value = cachedData.totalRecords;
|
||||
fullRouteData.value = cachedData.fullData || [];
|
||||
paginationStore.setTotalRecords("routes", cachedData.totalRecords);
|
||||
|
||||
console.log("Loaded from cache:", {
|
||||
records: cachedData.records.length,
|
||||
total: cachedData.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Making API call with:", { paginationParams, filters });
|
||||
|
||||
// For now, use existing API but we should create a paginated version
|
||||
// TODO: Create Api.getPaginatedRouteData() method
|
||||
const data = await Api.getRouteData();
|
||||
|
||||
// Store full data for modal access
|
||||
fullRouteData.value = data;
|
||||
|
||||
// Simulate pagination on client side for now
|
||||
const startIndex = paginationParams.page * paginationParams.pageSize;
|
||||
const endIndex = startIndex + paginationParams.pageSize;
|
||||
|
||||
// Transform data for table display
|
||||
const transformedData = data.map((route) => ({
|
||||
routeId: route.routeId,
|
||||
routeName: route.routeName,
|
||||
technician: route.technician,
|
||||
date: route.date,
|
||||
status: route.status,
|
||||
progress: `${route.completedStops}/${route.totalStops}`,
|
||||
totalStops: route.totalStops,
|
||||
estimatedDuration: route.estimatedDuration,
|
||||
actions: "View Details",
|
||||
}));
|
||||
|
||||
const paginatedData = transformedData.slice(startIndex, endIndex);
|
||||
|
||||
// Update local state
|
||||
tableData.value = paginatedData;
|
||||
totalRecords.value = transformedData.length;
|
||||
|
||||
// Update pagination store with new total
|
||||
paginationStore.setTotalRecords("routes", transformedData.length);
|
||||
|
||||
// Cache the result
|
||||
paginationStore.setCachedPage(
|
||||
"routes",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
{
|
||||
records: paginatedData,
|
||||
totalRecords: transformedData.length,
|
||||
fullData: data,
|
||||
},
|
||||
);
|
||||
|
||||
console.log("Loaded from API:", {
|
||||
records: paginatedData.length,
|
||||
total: transformedData.length,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error loading route data:", error);
|
||||
tableData.value = [];
|
||||
totalRecords.value = 0;
|
||||
fullRouteData.value = [];
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Methods
|
||||
const viewRouteDetails = (event) => {
|
||||
const routeId = event.data.routeId;
|
||||
const route = tableData.value.find((r) => r.routeId === routeId);
|
||||
if (route && route.fullData) {
|
||||
selectedRoute.value = route.fullData;
|
||||
const route = fullRouteData.value.find((r) => r.routeId === routeId);
|
||||
if (route) {
|
||||
selectedRoute.value = route;
|
||||
routeDialog.value = true;
|
||||
}
|
||||
};
|
||||
|
|
@ -293,29 +432,24 @@ const optimizeRoute = () => {
|
|||
alert("Route optimization feature coming soon!");
|
||||
};
|
||||
|
||||
// Load data on component mount
|
||||
// Load initial data
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await Api.getRouteData();
|
||||
// Initialize pagination and filters
|
||||
paginationStore.initializeTablePagination("routes", { rows: 10 });
|
||||
filtersStore.initializeTableFilters("routes", columns);
|
||||
|
||||
// Transform data for table display and keep full data reference
|
||||
tableData.value = data.map((route) => ({
|
||||
routeId: route.routeId,
|
||||
routeName: route.routeName,
|
||||
technician: route.technician,
|
||||
date: route.date,
|
||||
status: route.status,
|
||||
progress: `${route.completedStops}/${route.totalStops}`,
|
||||
totalStops: route.totalStops,
|
||||
estimatedDuration: route.estimatedDuration,
|
||||
actions: "View Details",
|
||||
fullData: route, // Keep reference to full route data
|
||||
}));
|
||||
// Load first page
|
||||
const initialPagination = paginationStore.getTablePagination("routes");
|
||||
const initialFilters = filtersStore.getTableFilters("routes");
|
||||
|
||||
console.log("Loaded routes:", tableData.value);
|
||||
} catch (error) {
|
||||
console.error("Error loading routes:", error);
|
||||
}
|
||||
await handleLazyLoad({
|
||||
page: initialPagination.page,
|
||||
rows: initialPagination.rows,
|
||||
first: initialPagination.first,
|
||||
sortField: initialPagination.sortField,
|
||||
sortOrder: initialPagination.sortOrder,
|
||||
filters: initialFilters,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -124,10 +124,14 @@
|
|||
<!-- Main Timesheet Table -->
|
||||
<div class="timesheets-table-container">
|
||||
<DataTable
|
||||
:data="filteredTableData"
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
:filters="filters"
|
||||
tableName="timesheets"
|
||||
:lazy="true"
|
||||
:totalRecords="totalRecords"
|
||||
:loading="isLoading"
|
||||
:onLazyLoad="handleLazyLoad"
|
||||
@lazy-load="handleLazyLoad"
|
||||
@row-click="viewTimesheetDetails"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -372,12 +376,21 @@ import { ref, onMounted, computed } from "vue";
|
|||
import DataTable from "../common/DataTable.vue";
|
||||
import Api from "../../api";
|
||||
import { FilterMatchMode } from "@primevue/core";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { usePaginationStore } from "../../stores/pagination";
|
||||
import { useFiltersStore } from "../../stores/filters";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const paginationStore = usePaginationStore();
|
||||
const filtersStore = useFiltersStore();
|
||||
|
||||
// Reactive data
|
||||
const tableData = ref([]);
|
||||
const filteredTableData = ref([]);
|
||||
const totalRecords = ref(0);
|
||||
const isLoading = ref(false);
|
||||
const timesheetDialog = ref(false);
|
||||
const selectedTimesheet = ref(null);
|
||||
const allTimesheetData = ref([]); // Store all data for filtering and calculations
|
||||
|
||||
// Filter controls
|
||||
const selectedWeek = ref("current");
|
||||
|
|
@ -412,8 +425,156 @@ const columns = [
|
|||
{ label: "Actions", fieldName: "actions", type: "button", sortable: false },
|
||||
];
|
||||
|
||||
const filters = {
|
||||
employee: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||
// Handle lazy loading events from DataTable
|
||||
const handleLazyLoad = async (event) => {
|
||||
console.log("TimeSheets page - handling lazy load:", event);
|
||||
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
// Get pagination parameters
|
||||
const paginationParams = {
|
||||
page: event.page || 0,
|
||||
pageSize: event.rows || 10,
|
||||
sortField: event.sortField,
|
||||
sortOrder: event.sortOrder,
|
||||
};
|
||||
|
||||
// Get filters (convert PrimeVue format to API format)
|
||||
const filters = {};
|
||||
if (event.filters) {
|
||||
Object.keys(event.filters).forEach((key) => {
|
||||
if (key !== "global" && event.filters[key] && event.filters[key].value) {
|
||||
filters[key] = event.filters[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Apply additional filters from the controls
|
||||
const additionalFilters = {
|
||||
week: selectedWeek.value,
|
||||
employee: selectedEmployee.value,
|
||||
status: selectedStatus.value,
|
||||
};
|
||||
|
||||
// Combine filters
|
||||
const combinedFilters = { ...filters, ...additionalFilters };
|
||||
|
||||
// Check cache first
|
||||
const cacheKey = `${JSON.stringify(combinedFilters)}`;
|
||||
const cachedData = paginationStore.getCachedPage(
|
||||
"timesheets",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
combinedFilters,
|
||||
);
|
||||
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
tableData.value = cachedData.records;
|
||||
totalRecords.value = cachedData.totalRecords;
|
||||
allTimesheetData.value = cachedData.allData || [];
|
||||
paginationStore.setTotalRecords("timesheets", cachedData.totalRecords);
|
||||
|
||||
console.log("Loaded from cache:", {
|
||||
records: cachedData.records.length,
|
||||
total: cachedData.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Making API call with:", { paginationParams, combinedFilters });
|
||||
|
||||
// For now, use existing API but we should create a paginated version
|
||||
// TODO: Create Api.getPaginatedTimesheetData() method
|
||||
const data = await Api.getTimesheetData();
|
||||
|
||||
// Store all data for calculations
|
||||
allTimesheetData.value = data;
|
||||
|
||||
// Apply local filtering based on controls
|
||||
let filteredData = data;
|
||||
|
||||
// Week filter
|
||||
if (selectedWeek.value !== "all") {
|
||||
const currentWeekStart = getCurrentWeekStart();
|
||||
let weekStart;
|
||||
|
||||
switch (selectedWeek.value) {
|
||||
case "current":
|
||||
weekStart = currentWeekStart;
|
||||
break;
|
||||
case "last":
|
||||
weekStart = getWeekStart(1);
|
||||
break;
|
||||
case "last2":
|
||||
weekStart = getWeekStart(2);
|
||||
break;
|
||||
default:
|
||||
weekStart = null;
|
||||
}
|
||||
|
||||
if (weekStart) {
|
||||
filteredData = filteredData.filter((timesheet) => {
|
||||
const timesheetDate = new Date(timesheet.date);
|
||||
return timesheetDate >= weekStart;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Employee filter
|
||||
if (selectedEmployee.value) {
|
||||
filteredData = filteredData.filter((ts) => ts.employee === selectedEmployee.value);
|
||||
}
|
||||
|
||||
// Status filter
|
||||
if (selectedStatus.value) {
|
||||
filteredData = filteredData.filter((ts) => ts.status === selectedStatus.value);
|
||||
}
|
||||
|
||||
// Simulate pagination on filtered data
|
||||
const startIndex = paginationParams.page * paginationParams.pageSize;
|
||||
const endIndex = startIndex + paginationParams.pageSize;
|
||||
const paginatedData = filteredData.slice(startIndex, endIndex);
|
||||
|
||||
// Update local state
|
||||
tableData.value = paginatedData;
|
||||
totalRecords.value = filteredData.length;
|
||||
|
||||
// Update pagination store with new total
|
||||
paginationStore.setTotalRecords("timesheets", filteredData.length);
|
||||
|
||||
// Cache the result
|
||||
paginationStore.setCachedPage(
|
||||
"timesheets",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
combinedFilters,
|
||||
{
|
||||
records: paginatedData,
|
||||
totalRecords: filteredData.length,
|
||||
allData: data,
|
||||
},
|
||||
);
|
||||
|
||||
console.log("Loaded from API:", {
|
||||
records: paginatedData.length,
|
||||
total: filteredData.length,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error loading timesheet data:", error);
|
||||
tableData.value = [];
|
||||
totalRecords.value = 0;
|
||||
allTimesheetData.value = [];
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Computed properties
|
||||
|
|
@ -425,7 +586,7 @@ const totalHoursThisWeek = computed(() => {
|
|||
});
|
||||
|
||||
const pendingApprovals = computed(() => {
|
||||
return tableData.value.filter((ts) => !ts.approved).length;
|
||||
return allTimesheetData.value.filter((ts) => !ts.approved).length;
|
||||
});
|
||||
|
||||
const totalLaborCost = computed(() => {
|
||||
|
|
@ -435,7 +596,7 @@ const totalLaborCost = computed(() => {
|
|||
});
|
||||
|
||||
const activeEmployees = computed(() => {
|
||||
const uniqueEmployees = new Set(tableData.value.map((ts) => ts.employee));
|
||||
const uniqueEmployees = new Set(allTimesheetData.value.map((ts) => ts.employee));
|
||||
return uniqueEmployees.size;
|
||||
});
|
||||
|
||||
|
|
@ -444,10 +605,11 @@ const hasSelectedForApproval = computed(() => {
|
|||
return pendingApprovals.value > 0;
|
||||
});
|
||||
|
||||
// Methods
|
||||
// Methods
|
||||
const getCurrentWeekTimesheets = () => {
|
||||
const currentWeekStart = getCurrentWeekStart();
|
||||
return tableData.value.filter((timesheet) => {
|
||||
return allTimesheetData.value.filter((timesheet) => {
|
||||
const timesheetDate = new Date(timesheet.date);
|
||||
return timesheetDate >= currentWeekStart;
|
||||
});
|
||||
|
|
@ -468,15 +630,38 @@ const getWeekStart = (weeksAgo) => {
|
|||
};
|
||||
|
||||
const filterByWeek = () => {
|
||||
applyFilters();
|
||||
// Reset to first page when filters change
|
||||
paginationStore.resetToFirstPage("timesheets");
|
||||
triggerLazyLoad();
|
||||
};
|
||||
|
||||
const filterByEmployee = () => {
|
||||
applyFilters();
|
||||
// Reset to first page when filters change
|
||||
paginationStore.resetToFirstPage("timesheets");
|
||||
triggerLazyLoad();
|
||||
};
|
||||
|
||||
const filterByStatus = () => {
|
||||
applyFilters();
|
||||
// Reset to first page when filters change
|
||||
paginationStore.resetToFirstPage("timesheets");
|
||||
triggerLazyLoad();
|
||||
};
|
||||
|
||||
const triggerLazyLoad = () => {
|
||||
const paginationParams = paginationStore.getPaginationParams("timesheets");
|
||||
const filters = filtersStore.getTableFilters("timesheets");
|
||||
|
||||
const lazyEvent = {
|
||||
page: paginationParams.page,
|
||||
rows: paginationParams.pageSize,
|
||||
first: paginationParams.offset,
|
||||
sortField: paginationParams.sortField,
|
||||
sortOrder: paginationParams.sortOrder,
|
||||
filters: filters,
|
||||
};
|
||||
|
||||
console.log("Triggering lazy load with:", lazyEvent);
|
||||
handleLazyLoad(lazyEvent);
|
||||
};
|
||||
|
||||
const applyFilters = () => {
|
||||
|
|
@ -513,7 +698,7 @@ const applyFilters = () => {
|
|||
|
||||
const viewTimesheetDetails = (event) => {
|
||||
const timesheetId = event.data.timesheetId;
|
||||
const timesheet = tableData.value.find((ts) => ts.timesheetId === timesheetId);
|
||||
const timesheet = allTimesheetData.value.find((ts) => ts.timesheetId === timesheetId);
|
||||
if (timesheet) {
|
||||
selectedTimesheet.value = timesheet;
|
||||
timesheetDialog.value = true;
|
||||
|
|
@ -570,10 +755,13 @@ const formatDate = (dateString) => {
|
|||
// Load data on component mount
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const data = await Api.getTimesheetData();
|
||||
// Initialize pagination and filters
|
||||
paginationStore.initializeTablePagination("timesheets", { rows: 10 });
|
||||
filtersStore.initializeTableFilters("timesheets", columns);
|
||||
|
||||
// Transform data for table display
|
||||
tableData.value = data.map((timesheet) => ({
|
||||
// Load data to set up employee options
|
||||
const data = await Api.getTimesheetData();
|
||||
allTimesheetData.value = data.map((timesheet) => ({
|
||||
...timesheet,
|
||||
totalPayFormatted: `$${timesheet.totalPay.toLocaleString()}`,
|
||||
actions: "View Details",
|
||||
|
|
@ -583,10 +771,20 @@ onMounted(async () => {
|
|||
const uniqueEmployees = [...new Set(data.map((ts) => ts.employee))];
|
||||
employeeOptions.value = uniqueEmployees.map((emp) => ({ label: emp, value: emp }));
|
||||
|
||||
// Apply initial filters
|
||||
applyFilters();
|
||||
// Load first page
|
||||
const initialPagination = paginationStore.getTablePagination("timesheets");
|
||||
const initialFilters = filtersStore.getTableFilters("timesheets");
|
||||
|
||||
console.log("Loaded timesheets:", tableData.value);
|
||||
await handleLazyLoad({
|
||||
page: initialPagination.page,
|
||||
rows: initialPagination.rows,
|
||||
first: initialPagination.first,
|
||||
sortField: initialPagination.sortField,
|
||||
sortOrder: initialPagination.sortOrder,
|
||||
filters: initialFilters,
|
||||
});
|
||||
|
||||
console.log("Loaded timesheets:", allTimesheetData.value.length);
|
||||
} catch (error) {
|
||||
console.error("Error loading timesheets:", error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,16 @@
|
|||
Add New Warranty Claim
|
||||
</button>
|
||||
</div>
|
||||
<DataTable :data="tableData" :columns="columns" :filters="filters" tableName="warranties" />
|
||||
<DataTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
tableName="warranties"
|
||||
:lazy="true"
|
||||
:totalRecords="totalRecords"
|
||||
:loading="isLoading"
|
||||
:onLazyLoad="handleLazyLoad"
|
||||
@lazy-load="handleLazyLoad"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -15,8 +24,17 @@ import { onMounted, ref } from "vue";
|
|||
import DataTable from "../common/DataTable.vue";
|
||||
import Api from "../../api";
|
||||
import { FilterMatchMode } from "@primevue/core";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { usePaginationStore } from "../../stores/pagination";
|
||||
import { useFiltersStore } from "../../stores/filters";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const paginationStore = usePaginationStore();
|
||||
const filtersStore = useFiltersStore();
|
||||
|
||||
const tableData = ref([]);
|
||||
const totalRecords = ref(0);
|
||||
const isLoading = ref(false);
|
||||
|
||||
const addNewWarranty = () => {
|
||||
// TODO: Open modal or navigate to create warranty form
|
||||
|
|
@ -25,13 +43,6 @@ const addNewWarranty = () => {
|
|||
// For now, just log the action
|
||||
};
|
||||
|
||||
const filters = {
|
||||
customer: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||
warrantyId: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||
address: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||
assignedTechnician: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
label: "Warranty ID",
|
||||
|
|
@ -93,12 +104,119 @@ const columns = [
|
|||
},
|
||||
];
|
||||
|
||||
onMounted(async () => {
|
||||
if (tableData.value.length > 0) {
|
||||
return;
|
||||
// Handle lazy loading events from DataTable
|
||||
const handleLazyLoad = async (event) => {
|
||||
console.log("Warranties page - handling lazy load:", event);
|
||||
|
||||
try {
|
||||
isLoading.value = true;
|
||||
|
||||
// Get pagination parameters
|
||||
const paginationParams = {
|
||||
page: event.page || 0,
|
||||
pageSize: event.rows || 10,
|
||||
sortField: event.sortField,
|
||||
sortOrder: event.sortOrder,
|
||||
};
|
||||
|
||||
// Get filters (convert PrimeVue format to API format)
|
||||
const filters = {};
|
||||
if (event.filters) {
|
||||
Object.keys(event.filters).forEach((key) => {
|
||||
if (key !== "global" && event.filters[key] && event.filters[key].value) {
|
||||
filters[key] = event.filters[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
const cachedData = paginationStore.getCachedPage(
|
||||
"warranties",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
);
|
||||
|
||||
if (cachedData) {
|
||||
// Use cached data
|
||||
tableData.value = cachedData.records;
|
||||
totalRecords.value = cachedData.totalRecords;
|
||||
paginationStore.setTotalRecords("warranties", cachedData.totalRecords);
|
||||
|
||||
console.log("Loaded from cache:", {
|
||||
records: cachedData.records.length,
|
||||
total: cachedData.totalRecords,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Making API call with:", { paginationParams, filters });
|
||||
|
||||
// For now, use existing API but we should create a paginated version
|
||||
// TODO: Create Api.getPaginatedWarrantyData() method
|
||||
let data = await Api.getWarrantyData();
|
||||
|
||||
// Simulate pagination on client side for now
|
||||
const startIndex = paginationParams.page * paginationParams.pageSize;
|
||||
const endIndex = startIndex + paginationParams.pageSize;
|
||||
const paginatedData = data.slice(startIndex, endIndex);
|
||||
|
||||
// Update local state
|
||||
tableData.value = paginatedData;
|
||||
totalRecords.value = data.length;
|
||||
|
||||
// Update pagination store with new total
|
||||
paginationStore.setTotalRecords("warranties", data.length);
|
||||
|
||||
// Cache the result
|
||||
paginationStore.setCachedPage(
|
||||
"warranties",
|
||||
paginationParams.page,
|
||||
paginationParams.pageSize,
|
||||
paginationParams.sortField,
|
||||
paginationParams.sortOrder,
|
||||
filters,
|
||||
{
|
||||
records: paginatedData,
|
||||
totalRecords: data.length,
|
||||
},
|
||||
);
|
||||
|
||||
console.log("Loaded from API:", {
|
||||
records: paginatedData.length,
|
||||
total: data.length,
|
||||
page: paginationParams.page + 1,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error loading warranty data:", error);
|
||||
tableData.value = [];
|
||||
totalRecords.value = 0;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
let data = await Api.getWarrantyData();
|
||||
tableData.value = data;
|
||||
};
|
||||
|
||||
// Load initial data
|
||||
onMounted(async () => {
|
||||
// Initialize pagination and filters
|
||||
paginationStore.initializeTablePagination("warranties", { rows: 10 });
|
||||
filtersStore.initializeTableFilters("warranties", columns);
|
||||
|
||||
// Load first page
|
||||
const initialPagination = paginationStore.getTablePagination("warranties");
|
||||
const initialFilters = filtersStore.getTableFilters("warranties");
|
||||
|
||||
await handleLazyLoad({
|
||||
page: initialPagination.page,
|
||||
rows: initialPagination.rows,
|
||||
first: initialPagination.first,
|
||||
sortField: initialPagination.sortField,
|
||||
sortOrder: initialPagination.sortOrder,
|
||||
filters: initialFilters,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue