Updated the TodoChart to have arbitrary categories, labels, data, and colors.

This commit is contained in:
rocketdebris 2026-01-22 10:46:49 -05:00
parent c0b1f3f37a
commit f386edf769
2 changed files with 55 additions and 59 deletions

View file

@ -21,7 +21,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, watch, nextTick, computed, onUnmounted} from "vue"; import { ref, onMounted, watch, nextTick, computed, onUnmounted, toRaw} from "vue";
import { Chart, registerables } from "chart.js"; import { Chart, registerables } from "chart.js";
// Register Chart.js components // Register Chart.js components
@ -29,8 +29,7 @@ Chart.register(...registerables);
const props = defineProps({ const props = defineProps({
title: String, title: String,
todoNumber: Number, categories: Object,
completedNumber: Number,
loading: { loading: {
type: Boolean, type: Boolean,
default: false, default: false,
@ -38,7 +37,7 @@ const props = defineProps({
}); });
//Constants //Constants
const categories = ["To-do", "Completed"]; //const categories = ["To-do", "Completed"];
//Reactive data //Reactive data
const centerData = ref(null); const centerData = ref(null);
@ -56,21 +55,19 @@ const getHoveredCategoryIndex = () => {
} }
const getCategoryValue = (categoryIndex) => { const getCategoryValue = (categoryIndex) => {
if (categoryIndex === 0) { return props.categories.data[categoryIndex];
return props.todoNumber
} else {
return props.completedNumber
}
} }
const getChartData = () => { const getChartData = () => {
const categoryData = props.categories.data;
const categoryColors = props.categories.colors;
const chartData = { const chartData = {
name: props.title, name: props.title,
datasets: [ datasets: [
{ {
label: "", label: "",
data: [props.todoNumber, props.completedNumber], data: categoryData,
backgroundColor: ["#b22222", "#4caf50"] backgroundColor: categoryColors
}, },
] ]
}; };
@ -79,8 +76,11 @@ const getChartData = () => {
const updateCenterData = () => { const updateCenterData = () => {
const total = props.todoNumber + props.completedNumber; let total = 0;
const todos = props.todoNumber; for (let i=0; i<props.categories.data.length; i++) {
total += props.categories.data[i];
}
const todos = props.categories.data[0];
if (todos === 0 && total > 0) { if (todos === 0 && total > 0) {
centerData.value = { centerData.value = {
@ -107,14 +107,14 @@ const updateCenterData = () => {
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) + "%" : "0%"; const percentage = total > 0 ? ((value / total) * 100).toFixed(1) + "%" : "0%";
centerData.value = { centerData.value = {
label: categories[hoveredCategoryIndex], label: props.categories.labels[hoveredCategoryIndex],
value: value, value: value,
percentage: percentage, percentage: percentage,
}; };
} else { } else {
centerData.value = { centerData.value = {
label: "To-do", label: "To-do",
value: props.todoNumber, value: todos,
percentage: null, percentage: null,
}; };
} }
@ -180,8 +180,6 @@ const getChartOptions = () => {
const createChart = () => { const createChart = () => {
if (!chartCanvas.value || props.loading) return; if (!chartCanvas.value || props.loading) return;
console.log(`DEBUG: Creating chart for ${props.title}`);
console.log(props);
const ctx = chartCanvas.value.getContext("2d"); const ctx = chartCanvas.value.getContext("2d");
if (chartInstance.value) { if (chartInstance.value) {
@ -214,9 +212,9 @@ onMounted(() => {
createChart(); createChart();
}); });
watch(() => props.completedNumber, (newValue) => { watch(() => props.categories, (newValue) => {
updateChart(); updateChart();
}); }, {deep: true});
</script> </script>

View file

@ -15,8 +15,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Locates" title="Locates"
:todoNumber="chartData.locates.todo" :categories="chartData.locates"
:completedNumber="chartData.locates.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Locate')"> <button class="sidebar-button" @click="navigateTo('/tasks?subject=Locate')">
@ -37,8 +36,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Permits" title="Permits"
:todoNumber="chartData.permits.todo" :categories="chartData.permits"
:completedNumber="chartData.permits.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/tasks?subject=Permit')"> <button class="sidebar-button" @click="navigateTo('/tasks?subject=Permit')">
@ -59,8 +57,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Permit Finalization" title="Permit Finalization"
:todoNumber="permitFinalizationsTodoNumber" :categories="chartData.permitFinalizations"
:completedNumber="permitFinalizationsCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/jobs')"> <button class="sidebar-button" @click="navigateTo('/jobs')">
@ -81,8 +78,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Warranty Claims" title="Warranty Claims"
:todoNumber="warrantyTodoNumber" :categories="chartData.warranties"
:completedNumber="warrantyCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/jobs')"> <button class="sidebar-button" @click="navigateTo('/jobs')">
@ -103,8 +99,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"
@ -126,8 +121,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"
@ -149,8 +143,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"
@ -172,8 +165,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="15 Day Follow Ups" title="15 Day Follow Ups"
:todoNumber="fifteenDayTodoNumber" :categories="chartData.fifteenDayFollowups"
:completedNumber="fifteenDayCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -195,8 +187,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Late Balances" title="Late Balances"
:todoNumber="balancesTodoNumber" :categories="chartData.lateBalances"
:completedNumber="balancesCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -218,8 +209,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Backflow Tests" title="Backflow Tests"
:todoNumber="backflowsTodoNumber" :categories="chartData.backflows"
:completedNumber="backflowsCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -241,8 +231,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Curbing" title="Curbing"
:todoNumber="chartData.curbing.todo" :categories="chartData.curbing"
:completedNumber="chartData.curbing.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -264,8 +253,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Hydroseeding" title="Hydroseeding"
:todoNumber="chartData.hydroseed.todo" :categories="chartData.hydroseed"
:completedNumber="chartData.hydroseed.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -287,8 +275,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Machines" title="Machines"
:todoNumber="machinesTodoNumber" :categories="chartData.machines"
:completedNumber="machinesCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -310,8 +297,7 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Deliveries" title="Deliveries"
:todoNumber="deliveriesTodoNumber" :categories="chartData.deliveries"
:completedNumber="delivieriesCompletedNumber"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@ -342,6 +328,8 @@ import TodoChart from "../common/TodoChart.vue";
const router = useRouter(); const router = useRouter();
const defaultColors = ['blue', 'green', 'red'];
// Dummy data from utils // Dummy data from utils
const clientData = ref(DataUtils.dummyClientData); const clientData = ref(DataUtils.dummyClientData);
const jobData = ref(DataUtils.dummyJobData); const jobData = ref(DataUtils.dummyJobData);
@ -355,10 +343,20 @@ const warrantyTodoNumber = ref(0);
const warrantyCompletedNumber = ref(10); const warrantyCompletedNumber = ref(10);
const chartData = ref({ const chartData = ref({
locates: {todo: 0, done: 0}, locates: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
permits: {todo: 0, done: 0}, permits: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
curbing: {todo: 0, done: 0}, curbing: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
hydroseed: {todo: 0, done: 0}, hydroseed: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
permitFinalizations: {labels: ["Todo", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
warranties: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
bids: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
estimates: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
halfDown: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
fifteenDayFollowups: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
lateBalances: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
backflows: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
machines: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
deliveries: {labels: ["To-do", "Completed", "Overdue"], data: [0, 0, 0], colors: defaultColors},
}); });
const notifications = useNotificationStore(); const notifications = useNotificationStore();
@ -375,14 +373,14 @@ const navigateTo = (path) => {
}; };
onMounted(async() => { onMounted(async() => {
notifications.addWarning("Dashboard metrics are based on dummy data for demonstration purposes. UPDATES COMING SOON!"); notifications.addWarning("Dashboard metrics are based on dummy data for demonstration purposes. UPDATES COMING SOON!");
chartData.value.locates.todo = await Api.getTasksDue("Locate"); chartData.value.locates.data[0] = await Api.getTasksDue("Locate");
chartData.value.locates.done = await Api.getTasksCompleted("Locate"); chartData.value.locates.data[1] = await Api.getTasksCompleted("Locate");
chartData.value.permits.todo = await Api.getTasksDue("Permit"); chartData.value.permits.data[0] = await Api.getTasksDue("Permit");
chartData.value.permits.done = await Api.getTasksCompleted("Permit"); chartData.value.permits.data[1] = await Api.getTasksCompleted("Permit");
chartData.value.curbing.todo = await Api.getTasksDue("Curbing"); chartData.value.curbing.data[0] = await Api.getTasksDue("Curbing");
chartData.value.curbing.done = await Api.getTasksCompleted("Curbing"); chartData.value.curbing.data[1] = await Api.getTasksCompleted("Curbing");
chartData.value.hydroseed.todo = await Api.getTasksDue("Hydroseed"); chartData.value.hydroseed.data[0] = await Api.getTasksDue("Hydroseed");
chartData.value.hydroseed.done = await Api.getTasksCompleted("Hydroseed"); chartData.value.hydroseed.data[1] = await Api.getTasksCompleted("Hydroseed");
}); });
</script> </script>