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">
<TodoChart
title="Incomplete Bids"
:todoNumber="bidsTodoNumber"
:completedNumber="bidsCompletedNumber"
:categories="chartData.bids"
>
</TodoChart>
<button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content">
<TodoChart
title="Unapproved Estimates"
:todoNumber="estimatesTodoNumber"
:completedNumber="estimatesCompletedNumber"
:categories="chartData.estimates"
>
</TodoChart>
<button class="sidebar-button"
@ -61,8 +59,7 @@
<div class="widget-content">
<TodoChart
title="Half Down Payments"
:todoNumber="halfDownTodoNumber"
:completedNumber="halfDownCompletedNumber"
:categories="chartData.halfDown"
>
</TodoChart>
<button class="sidebar-button"
@ -84,8 +81,7 @@
<div class="widget-content">
<TodoChart
title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber"
:completedNumber="jobQueueCompletedNumber"
:categories="chartData.jobsInQueue"
>
</TodoChart>
<button class="sidebar-button"
@ -132,22 +128,30 @@ import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.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 { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { useRouter } from "vue-router";
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const router = useRouter();
const tableData = ref([]);
const totalRecords = ref(0);
const isLoading = ref(false);
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
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
onMounted(async () => {
// Initialize pagination and filters
@ -297,6 +308,13 @@ onMounted(async () => {
sortOrder: initialSorting.order || initialPagination.sortOrder,
filters: initialFilters,
});
// Chart Data
await loadChartData();
});
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
});
</script>

View file

@ -15,8 +15,7 @@
<div class="widget-content">
<TodoChart
title="Ready To Invoice"
:todoNumber="invoiceTodoNumber"
:completedNumber="invoiceCompletedNumber"
:categories="chartData.jobsToInvoice"
>
</TodoChart>
<button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content">
<TodoChart
title="Late Balances"
:todoNumber="balancesTodoNumber"
:completedNumber="balancesCompletedNumber"
:categories="chartData.invoicesLate"
>
</TodoChart>
<button class="sidebar-button"
@ -65,21 +63,28 @@
import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue";
import { ref, onMounted, watch } from "vue";
import Api from "../../api";
import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { CardNoAccess, CalendarCheck } from "@iconoir/vue";
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const tableData = ref([]);
const totalRecords = ref(0);
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 = [
{ label: "Customer Address", fieldName: "address", type: "text", sortable: 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
onMounted(async () => {
// Initialize pagination and filters
@ -188,6 +199,12 @@ onMounted(async () => {
sortOrder: initialSorting.order || initialPagination.sortOrder,
filters: initialFilters,
});
await loadChartData();
});
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
});
</script>

View file

@ -15,8 +15,7 @@
<div class="widget-content">
<TodoChart
title="Jobs In Queue"
:todoNumber="jobQueueTodoNumber"
:completedNumber="jobQueueCompletedNumber"
:categories="chartData.jobsInQueue"
>
</TodoChart>
<button class="sidebar-button"
@ -38,8 +37,7 @@
<div class="widget-content">
<TodoChart
title="Jobs in Progress"
:todoNumber="progressTodoNumber"
:completedNumber="progressCompletedNumber"
:categories="chartData.jobsInProgress"
>
</TodoChart>
<button class="sidebar-button"
@ -61,8 +59,7 @@
<div class="widget-content">
<TodoChart
title="Late Jobs"
:todoNumber="lateTodoNumber"
:completedNumber="lateCompletedNumber"
:categories="chartData.jobsLate"
>
</TodoChart>
<button class="sidebar-button"
@ -84,8 +81,7 @@
<div class="widget-content">
<TodoChart
title="Ready To Invoice"
:todoNumber="invoiceTodoNumber"
:completedNumber="invoiceCompletedNumber"
:categories="chartData.jobsToInvoice"
>
</TodoChart>
<button class="sidebar-button"
@ -112,29 +108,39 @@
import Card from "../common/Card.vue";
import DataTable from "../common/DataTable.vue";
import TodoChart from "../common/TodoChart.vue";
import { ref, onMounted } from "vue";
import { ref, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
import Api from "../../api";
import { useLoadingStore } from "../../stores/loading";
import { usePaginationStore } from "../../stores/pagination";
import { useFiltersStore } from "../../stores/filters";
import { useCompanyStore } from "../../stores/company.js";
import { useNotificationStore } from "../../stores/notifications-primevue";
import { Alarm, CalendarCheck, Hammer } from "@iconoir/vue";
const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore();
const filtersStore = useFiltersStore();
const companyStore = useCompanyStore();
const notifications = useNotificationStore();
const tableData = ref([]);
const totalRecords = ref(0);
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 = [
{ 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: "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 }
];
@ -260,6 +266,13 @@ const handleRowClick = (event) => {
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
onMounted(async () => {
notifications.addWarning("Jobs page coming soon");
@ -280,7 +293,16 @@ onMounted(async () => {
sortField: initialSorting.field || initialPagination.sortField,
sortOrder: initialSorting.order || initialPagination.sortOrder,
});
// Chart Data
await loadChartData();
});
watch(() => companyStore.currentCompany, async (newCompany, oldCompany) => {
await loadChartData();
});
</script>
<style lang="css">
.widgets-grid {