Added API methods for connecting tasks to Home page dials. Connected 'view' buttons to tasks page.

This commit is contained in:
rocketdebris 2026-01-19 21:47:04 -05:00
parent 1429f68b9e
commit 98ec082394
3 changed files with 80 additions and 18 deletions

View file

@ -42,6 +42,40 @@ def get_task_status_options():
return build_error_response(str(e), 500) return build_error_response(str(e), 500)
@frappe.whitelist()
def get_tasks_due(subject_filter):
"""Return the number of items due today of the type of subject_filter"""
try:
filters = {
'subject': ['like', f'%{subject_filter}%'],
'status': ['not in', ["Template", "Completed", "Cancelled"]]
}
count = frappe.db.count("Task", filters=filters)
return build_success_response(count)
except frappe.ValidationError as ve:
return build_error_response(str(ve), 400)
except Exception as e:
return build_error_response(str(e), 500)
@frappe.whitelist()
def get_tasks_completed(subject_filter):
"""Return the number of items due today marked complete of the type of subject_filter"""
try:
filters = {
'subject': ['like', f'%{subject_filter}%'],
'status': ['not in', ["Template", "Cancelled"]]
}
print("Completed Task filter", filters)
count = frappe.db.count("Task", filters=filters)
print("Matching Records:", count)
return build_success_response(count)
except frappe.ValidationError as ve:
return build_error_response(str(ve), 400)
except Exception as e:
return build_error_response(str(e), 500)
@frappe.whitelist() @frappe.whitelist()
def get_tasks_table_data(filters={}, sortings=[], page=1, page_size=10): def get_tasks_table_data(filters={}, sortings=[], page=1, page_size=10):
"""Get paginated task table data with filtering and sorting support.""" """Get paginated task table data with filtering and sorting support."""

View file

@ -25,6 +25,8 @@ const FRAPPE_GET_JOB_TEMPLATES_METHOD = "custom_ui.api.db.jobs.get_job_templates
const FRAPPE_GET_TASKS_METHOD = "custom_ui.api.db.tasks.get_tasks_table_data"; const FRAPPE_GET_TASKS_METHOD = "custom_ui.api.db.tasks.get_tasks_table_data";
const FRAPPE_GET_TASKS_STATUS_OPTIONS = "custom_ui.api.db.tasks.get_task_status_options"; const FRAPPE_GET_TASKS_STATUS_OPTIONS = "custom_ui.api.db.tasks.get_task_status_options";
const FRAPPE_SET_TASK_STATUS_METHOD = "custom_ui.api.db.tasks.set_task_status"; const FRAPPE_SET_TASK_STATUS_METHOD = "custom_ui.api.db.tasks.set_task_status";
const FRAPPE_GET_TASKS_DUE_METHOD = "custom_ui.api.db.tasks.get_tasks_due";
const FRAPPE_GET_TASKS_COMPLETED_METHOD = "custom_ui.api.db.tasks.get_tasks_completed";
// Invoice methods // Invoice methods
const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data"; const FRAPPE_GET_INVOICES_METHOD = "custom_ui.api.db.invoices.get_invoice_table_data";
const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice"; const FRAPPE_UPSERT_INVOICE_METHOD = "custom_ui.api.db.invoices.upsert_invoice";
@ -45,7 +47,7 @@ const FRAPPE_GET_CLIENT_NAMES_METHOD = "custom_ui.api.db.clients.get_client_name
class Api { class Api {
// ============================================================================ // ============================================================================
// CORE REQUEST METHOD // CORE REQUEST METHOPD
// ============================================================================ // ============================================================================
static async request(frappeMethod, args = {}) { static async request(frappeMethod, args = {}) {
@ -401,6 +403,16 @@ class Api {
return await this.request(FRAPPE_SET_TASK_STATUS_METHOD, { taskName, newStatus }); return await this.request(FRAPPE_SET_TASK_STATUS_METHOD, { taskName, newStatus });
} }
static async getTasksDue(subjectFilter) {
const result = await this.request(FRAPPE_GET_TASKS_DUE_METHOD, {subjectFilter});
return result;
}
static async getTasksCompleted(subjectFilter) {
const result = await this.request(FRAPPE_GET_TASKS_COMPLETED_METHOD, {subjectFilter});
return result;
}
// ============================================================================ // ============================================================================
// INVOICE / PAYMENT METHODS // INVOICE / PAYMENT METHODS
// ============================================================================ // ============================================================================

View file

@ -15,11 +15,11 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Locates" title="Locates"
:todoNumber="locatesTodoNumber" :todoNumber="chartData.locates.todo"
:completedNumber="locatesCompletedNumber" :completedNumber="chartData.locates.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/jobs')"> <button class="sidebar-button" @click="navigateTo('/tasks?subject=Locate')">
View Locates View Locates
</button> </button>
</div> </div>
@ -37,11 +37,11 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Permits" title="Permits"
:todoNumber="permitsTodoNumber" :todoNumber="chartData.permits.todo"
:completedNumber="permitsCompletedNumber" :completedNumber="chartData.permits.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" @click="navigateTo('/jobs')"> <button class="sidebar-button" @click="navigateTo('/tasks?subject=Permit')">
View Permits View Permits
</button> </button>
</div> </div>
@ -241,12 +241,12 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Curbing" title="Curbing"
:todoNumber="curbingTodoNumber" :todoNumber="chartData.curbing.todo"
:completedNumber="curbingCompletedNumber" :completedNumber="chartData.curbing.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@click="navigateTo('/jobs')"> @click="navigateTo('/tasks?subject=Curbing')">
Curbing Curbing
</button> </button>
</div> </div>
@ -264,12 +264,12 @@
<div class="widget-content"> <div class="widget-content">
<TodoChart <TodoChart
title="Hydroseeding" title="Hydroseeding"
:todoNumber="hydroseedingTodoNumber" :todoNumber="chartData.hydroseed.todo"
:completedNumber="hydroseedingCompletedNumber" :completedNumber="chartData.hydroseed.done"
> >
</TodoChart> </TodoChart>
<button class="sidebar-button" <button class="sidebar-button"
@click="navigateTo('/jobs')"> @click="navigateTo('/tasks?subject=Hydroseed')">
Hydroseeding Hydroseeding
</button> </button>
</div> </div>
@ -334,6 +334,7 @@ import Tag from "primevue/tag";
import { Calendar, Community, Hammer, PathArrowSolid, Clock, Shield, ShieldSearch, import { Calendar, Community, Hammer, PathArrowSolid, Clock, Shield, ShieldSearch,
ClipboardCheck, DoubleCheck, CreditCard, CardNoAccess, ChatBubbleQuestion, Edit, ClipboardCheck, DoubleCheck, CreditCard, CardNoAccess, ChatBubbleQuestion, Edit,
WateringSoil, Soil, Truck, SoilAlt } from "@iconoir/vue"; WateringSoil, Soil, Truck, SoilAlt } from "@iconoir/vue";
import Api from "../../api.js";
import DataUtils from "../../utils.js"; import DataUtils from "../../utils.js";
import { useNotificationStore } from "../../stores/notifications-primevue"; import { useNotificationStore } from "../../stores/notifications-primevue";
//import SimpleChart from "../common/SimpleChart.vue"; //import SimpleChart from "../common/SimpleChart.vue";
@ -344,15 +345,22 @@ const router = useRouter();
// 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);
const locatesTodoNumber = ref(45); const locatesTodoNumber = ref(0);
const locatesCompletedNumber = ref(5); const locatesCompletedNumber = ref(0);
const permitsTodoNumber = ref(24); const permitsTodoNumber = ref(0);
const permitsCompletedNumber = ref(7); const permitsCompletedNumber = ref(0);
const permitFinalizationsTodoNumber = ref(35); const permitFinalizationsTodoNumber = ref(35);
const permitFinalizationsCompletedNumber = ref(2); const permitFinalizationsCompletedNumber = ref(2);
const warrantyTodoNumber = ref(0); const warrantyTodoNumber = ref(0);
const warrantyCompletedNumber = ref(10); const warrantyCompletedNumber = ref(10);
const chartData = ref({
locates: {todo: 0, done: 0},
permits: {todo: 0, done: 0},
curbing: {todo: 0, done: 0},
hydroseed: {todo: 0, done: 0},
});
const notifications = useNotificationStore(); const notifications = useNotificationStore();
// Computed values for dashboard metrics // Computed values for dashboard metrics
@ -365,8 +373,16 @@ const avgResponseTime = computed(() => 2.3);
const navigateTo = (path) => { const navigateTo = (path) => {
router.push(path); router.push(path);
}; };
onMounted(() => { 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.done = await Api.getTasksCompleted("Locate");
chartData.value.permits.todo = await Api.getTasksDue("Permit");
chartData.value.permits.done = await Api.getTasksCompleted("Permit");
chartData.value.curbing.todo = await Api.getTasksDue("Curbing");
chartData.value.curbing.done = await Api.getTasksCompleted("Curbing");
chartData.value.hydroseed.todo = await Api.getTasksDue("Hydroseed");
chartData.value.hydroseed.done = await Api.getTasksCompleted("Hydroseed");
}); });
</script> </script>