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)
@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()
def get_tasks_table_data(filters={}, sortings=[], page=1, page_size=10):
"""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_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_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
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";
@ -45,7 +47,7 @@ const FRAPPE_GET_CLIENT_NAMES_METHOD = "custom_ui.api.db.clients.get_client_name
class Api {
// ============================================================================
// CORE REQUEST METHOD
// CORE REQUEST METHOPD
// ============================================================================
static async request(frappeMethod, args = {}) {
@ -401,6 +403,16 @@ class Api {
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
// ============================================================================

View file

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