Reading data from APIs for dials.

This commit is contained in:
rocketdebris 2026-01-24 17:12:22 -05:00
parent 5ed964b49d
commit 5e192a61e1
3 changed files with 81 additions and 24 deletions

View file

@ -15,8 +15,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Incomplete Bids" title="Incomplete Bids"
:todoNumber="bidsTodoNumber" :categories="chartData.bids"
:completedNumber="bidsCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Unapproved Estimates" title="Unapproved Estimates"
:todoNumber="estimatesTodoNumber" :categories="chartData.estimates"
:completedNumber="estimatesCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -61,8 +59,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Half Down Payments" title="Half Down Payments"
:todoNumber="halfDownTodoNumber" :categories="chartData.halfDown"
:completedNumber="halfDownCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -84,8 +81,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Jobs In Queue" title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber" :categories="chartData.jobsInQueue"
:completedNumber="jobQueueCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -132,22 +128,30 @@ import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue"; import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue"; import TodoChart from "../common/TodoChart.vue";
import { Edit, ChatBubbleQuestion, CreditCard, Hammer } from "@iconoir/vue"; import { Edit, ChatBubbleQuestion, CreditCard, Hammer } from "@iconoir/vue";
import { ref, onMounted } from "vue"; import { ref, onMounted, watch } from "vue";
import Api from "../../api"; import Api from "../../api";
import { useLoadingStore } from "../../stores/loading"; import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination"; import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters"; import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const loadingStore = useLoadingStore(); const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore(); const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore(); const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const router = useRouter(); const router = useRouter();
const tableData = ref([]); const tableData = ref([]);
const totalRecords = ref(0); const totalRecords = ref(0);
const isLoading = ref(false); const isLoading = ref(false);
const showSubmitEstimateModal = ref(true); const showSubmitEstimateModal = ref(true);
const chartData = ref({
bids: {labels: ["Unscheduled"], data: [0], colors: ['red']},
estimates: {labels: ["Draft", "Submitted"], data: [0, 0], colors: ['orange', 'blue']},
halfDown: {labels: ["Unpaid"], data: [0], colors: ['red']},
jobsInQueue: {labels: ["Queued"], data: [0], colors: ['blue']}
});
//Junk //Junk
const filteredItems= [] const filteredItems= []
@ -277,6 +281,13 @@ const handleLazyLoad = async (event) => {
} }
}; };
const loadChartData = async () => {
chartData.value.bids.data = await Api.getIncompleteBidsCount(companyStore.currentCompany);
chartData.value.estimates.data = await Api.getUnapprovedEstimatesCount(companyStore.currentCompany);
chartData.value.halfDown.data = await Api.getEstimatesHalfDownCount(companyStore.currentCompany);
chartData.value.jobsInQueue.data = await Api.getJobsInQueueCount(companyStore.currentCompany);
};
// Load initial data // Load initial data
onMounted(async () => { onMounted(async () => {
// Initialize pagination and filters // Initialize pagination and filters
@ -297,6 +308,13 @@ onMounted(async () => {
sortOrder: initialSorting.order || initialPagination.sortOrder, sortOrder: initialSorting.order || initialPagination.sortOrder,
filters: initialFilters, filters: initialFilters,
}); });
// Chart Data
await loadChartData();
});
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
}); });
</script> </script>

View file

@ -15,8 +15,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Ready To Invoice" title="Ready To Invoice"
:todoNumber="invoiceTodoNumber" :categories="chartData.jobsToInvoice"
:completedNumber="invoiceCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Late Balances" title="Late Balances"
:todoNumber="balancesTodoNumber" :categories="chartData.invoicesLate"
:completedNumber="balancesCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -65,21 +63,28 @@
import Card from "../common/Card.vue"; import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue"; import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue"; import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue"; import { ref, onMounted, watch } from "vue";
import Api from "../../api"; import Api from "../../api";
import { useLoadingStore } from "../../stores/loading"; import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination"; import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters"; import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { CardNoAccess, CalendarCheck } from "@iconoir/vue"; import { CardNoAccess, CalendarCheck } from "@iconoir/vue";
const loadingStore = useLoadingStore(); const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore(); const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore(); const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const tableData = ref([]); const tableData = ref([]);
const totalRecords = ref(0); const totalRecords = ref(0);
const isLoading = ref(false); const isLoading = ref(false);
const chartData = ref({
jobsToInvoice: {labels: ["Ready To Invoice"], data: [0], colors: ['green']},
invoicesLate: {labels: ["Due", "30 Days", "60 Days", "80 Days"], data: [0, 0, 0, 0], colors: ["blue", "yellow", "orange", "red"]}
})
const columns = [ const columns = [
{ label: "Customer Address", fieldName: "address", type: "text", sortable: true }, { label: "Customer Address", fieldName: "address", type: "text", sortable: true },
{ label: "Customer", fieldName: "customer", type: "text", sortable: true, filterable: true }, { label: "Customer", fieldName: "customer", type: "text", sortable: true, filterable: true },
@ -168,6 +173,12 @@ const handleLazyLoad = async (event) => {
} }
}; };
// Load Chart Data
const loadChartData = async () => {
chartData.value.jobsToInvoice.data = await Api.getJobsToInvoiceCount(companyStore.currentCompany);
chartData.value.invoicesLate.data = await Api.getInvoicesLateCount(companyStore.currentCompany);
};
// Load initial data // Load initial data
onMounted(async () => { onMounted(async () => {
// Initialize pagination and filters // Initialize pagination and filters
@ -188,6 +199,12 @@ onMounted(async () => {
sortOrder: initialSorting.order || initialPagination.sortOrder, sortOrder: initialSorting.order || initialPagination.sortOrder,
filters: initialFilters, filters: initialFilters,
}); });
await loadChartData();
});
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
}); });
</script> </script>

View file

@ -15,8 +15,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Jobs In Queue" title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber" :categories="chartData.jobsInQueue"
:completedNumber="jobQueueCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Jobs in Progress" title="Jobs in Progress"
:todoNumber="progressTodoNumber" :categories="chartData.jobsInProgress"
:completedNumber="progressCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -61,8 +59,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Late Jobs" title="Late Jobs"
:todoNumber="lateTodoNumber" :categories="chartData.jobsLate"
:completedNumber="lateCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -84,8 +81,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Ready To Invoice" title="Ready To Invoice"
:todoNumber="invoiceTodoNumber" :categories="chartData.jobsToInvoice"
:completedNumber="invoiceCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -112,29 +108,39 @@
import Card from "../common/Card.vue"; import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue"; import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue"; import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue"; import { ref, onMounted, watch } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import Api from "../../api"; import Api from "../../api";
import { useLoadingStore } from "../../stores/loading"; import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination"; import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters"; import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { useNotificationStore } from "../../stores/notifications-primevue"; import { useNotificationStore } from "../../stores/notifications-primevue";
import { Alarm, CalendarCheck, Hammer } from "@iconoir/vue"; import { Alarm, CalendarCheck, Hammer } from "@iconoir/vue";
const loadingStore = useLoadingStore(); const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore(); const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore(); const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const notifications = useNotificationStore(); const notifications = useNotificationStore();
const tableData = ref([]); const tableData = ref([]);
const totalRecords = ref(0); const totalRecords = ref(0);
const isLoading = ref(false); const isLoading = ref(false);
const chartData = ref({
jobsInQueue: {labels: ["Queued"], data: [0], colors: ['blue']},
jobsInProgress: {labels: ["In Progress"], data: [0], colors: ['blue']},
jobsLate: {labels: ["Late"], data: [0], colors: ['red']},
jobsToInvoice: {labels: ["Ready To Invoice"], data: [0], colors: ['green']},
})
const columns = [ const columns = [
{ label: "Job ID", fieldName: "name", type: "text", sortable: true, filterable: true }, { label: "Job ID", fieldName: "name", type: "text", sortable: true, filterable: true },
{ label: "Address", fieldName: "customInstallationAddress", type: "text", sortable: true }, { label: "Address", fieldName: "jobAddress", type: "text", sortable: true },
{ label: "Customer", fieldName: "customer", type: "text", sortable: true, filterable: true }, { label: "Customer", fieldName: "customer", type: "text", sortable: true, filterable: true },
{ label: "Overall Status", fieldName: "status", type: "status", sortable: true }, { label: "Overall Status", fieldName: "status", type: "status", sortable: true },
{ label: "Invoice Status", fieldName: "invoiceStatus", type: "text", sortable: true },
{ label: "Progress", fieldName: "percentComplete", type: "text", sortable: true } { label: "Progress", fieldName: "percentComplete", type: "text", sortable: true }
]; ];
@ -260,6 +266,13 @@ const handleRowClick = (event) => {
router.push(`/job?name=${rowData.name}`); router.push(`/job?name=${rowData.name}`);
} }
const loadChartData = async () => {
chartData.value.jobsInQueue.data = await Api.getJobsInQueueCount(companyStore.currentCompany);
chartData.value.jobsInProgress.data = await Api.getJobsInProgressCount(companyStore.currentCompany);
chartData.value.jobsLate.data = await Api.getJobsLateCount(companyStore.currentCompany);
chartData.value.jobsToInvoice.data = await Api.getJobsToInvoiceCount(companyStore.currentCompany);
}
// Load initial data // Load initial data
onMounted(async () => { onMounted(async () => {
notifications.addWarning("Jobs page coming soon"); notifications.addWarning("Jobs page coming soon");
@ -280,7 +293,16 @@ onMounted(async () => {
sortField: initialSorting.field || initialPagination.sortField, sortField: initialSorting.field || initialPagination.sortField,
sortOrder: initialSorting.order || initialPagination.sortOrder, sortOrder: initialSorting.order || initialPagination.sortOrder,
}); });
// Chart Data
await loadChartData();
}); });
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
});
</script> </script>
<style lang="css"> <style lang="css">
.widgets-grid { .widgets-grid {