Task Status changes, needs some TLC.

This commit is contained in:
rocketdebris 2026-01-14 15:14:34 -05:00
parent 0c52f3fc23
commit 01ff96fb74
3 changed files with 104 additions and 9 deletions

View file

@ -24,6 +24,7 @@ const FRAPPE_GET_JOB_TEMPLATES_METHOD = "custom_ui.api.db.jobs.get_job_templates
// Task methods // Task methods
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";
// 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";

View file

@ -383,18 +383,46 @@
> >
<Select <Select
v-for="action in rowActionsGrouped.select" v-for="action in rowActionsGrouped.select"
:options="action.statusOptions" :options="action.selectOptions"
:placeholder="action.label" :placeholder="action.label"
@change="handleSelectChange(action, slotProps.data, $event)" @change="handleSelectChange(action, slotProps.data, $event)"
/> />
</div> </div>
<!-- Render Generic Component -->
<div
v-if="rowActionsGrouped.menu.length > 0"
class="dt-row-actions-menu"
>
<template
v-for="action in rowActionsGrouped.menu"
:key="action.label"
>
<Button
type="button"
:label="action.menuLabel || action.label"
:icon="action.icon"
:size="action.size || 'small'"
:severity="action.style || 'secondary'"
@click="toggleMenu($event, action, slotProps.data)"
aria-haspopup="true"
:disabled="loading"
class="dt-row-btn"
outlined
/>
<Menu
:ref="defineMenuRef(action.label, slotProps.data.id)"
:model="buildMenuItems(action.menuItems || [], slotProps.data)"
:popup="true"
/>
</template>
</div>
</div> </div>
</template> </template>
</Column> </Column>
</DataTable> </DataTable>
</template> </template>
<script setup> <script setup>
import { defineProps, computed, onMounted, watch, ref } from "vue"; import { defineProps, computed, onMounted, watch, ref, reactive } from "vue";
import DataTable from "primevue/datatable"; import DataTable from "primevue/datatable";
import Column from "primevue/column"; import Column from "primevue/column";
import Tag from "primevue/tag"; import Tag from "primevue/tag";
@ -410,6 +438,16 @@ const filtersStore = useFiltersStore();
const loadingStore = useLoadingStore(); const loadingStore = useLoadingStore();
const paginationStore = usePaginationStore(); const paginationStore = usePaginationStore();
const menuRefs = reactive({});
const activeMenuKey = ref(null);
const defineMenuRef = (label, id) => {
console.log("Defining Menu Refs:", label, id);
const refName = `${label}-${id}`
menuRefs[refName] = ref();
return menuRefs[refName]
}
const props = defineProps({ const props = defineProps({
columns: { columns: {
type: Array, type: Array,
@ -715,6 +753,7 @@ const rowActionsGrouped = computed(() => {
secondary: rowActions.value.filter((action) => action.layout?.priority === "secondary"), secondary: rowActions.value.filter((action) => action.layout?.priority === "secondary"),
dropdown: rowActions.value.filter((action) => action.layout?.priority === "dropdown"), dropdown: rowActions.value.filter((action) => action.layout?.priority === "dropdown"),
select: rowActions.value.filter((action) => action.layout?.priority === "select"), select: rowActions.value.filter((action) => action.layout?.priority === "select"),
menu: rowActions.value.filter((action) => action.layout?.priority === "menu"),
}; };
return groups; return groups;
}); });
@ -1032,7 +1071,38 @@ const handleActionClick = (action, rowData = null) => {
} }
}; };
const toggleMenu = (event, action, rowData) => {
console.log("Menu button toggled");
const menuKey = `${action.label}-${rowData.id}`;
console.log(menuRefs, menuKey);
const menu = menuRefs[menuKey];
console.log(event, action, rowData, menuKey, menu);
if (menu) {
console.log("Menu:", menu);
menu.toggle(event);
activeMenuKey.value = menuKey;
} else {
console.log("Menu undefined.");
}
};
const buildMenuItems = (menuItems, rowData) => {
console.log("DEBUG: Building menuItems:", menuItems);
return menuItems.map(item => ({
...item,
command: () => {
console.log("Clicked from Datatable");
if (typeof item.command === 'function') {
item.command(rowData);
}
}
}));
};
const handleSelectChange = (action, rowData, event) => { const handleSelectChange = (action, rowData, event) => {
console.log("Action:", action);
console.log("rowData:", rowData);
console.log("event:", event);
try { try {
if (typeof action.action === "function") { if (typeof action.action === "function") {
if (rowData) { if (rowData) {
@ -1043,6 +1113,10 @@ const handleSelectChange = (action, rowData, event) => {
action.action(); action.action();
} }
} }
if (action.resetComponentOnChange) {
console.log("DEBUG: Resetting Select Component");
event.originalEvent.target.value = null;
}
} catch (error) { } catch (error) {
console.error("Error executing action:", error); console.error("Error executing action:", error);
} }

View file

@ -37,7 +37,15 @@ const tableData = ref([]);
const totalRecords = ref(0); const totalRecords = ref(0);
const isLoading = ref(false); const isLoading = ref(false);
const showCompleted = ref(false); const showCompleted = ref(false);
const statusOptions = ref([]); const statusOptions = ref([
"Open",
"Working",
"Pending",
"Review",
"Overdue",
"Completed",
"Cancelled",
]);
// Computed property to get current filters for the chart // Computed property to get current filters for the chart
const currentFilters = computed(() => { const currentFilters = computed(() => {
@ -76,15 +84,27 @@ const tableActions = [
}, },
{ {
label: "Set Status", label: "Set Status",
action: (rowData, newValue) => {
console.log("DEBUG: Row Data:", rowData);
console.log("DEBUG: New Value:", newValue);
},
rowAction: true, rowAction: true,
layout: { type: "menu",
priority: "select" menuItems: statusOptions.value.map(option => ({
label: option,
command: async (rowData) => {
console.log("Clicked on row:", rowData);
await Api.setTaskStatus(rowData.id, option);
let rowIndex = -1;
for (let i = 0; i<tableData.value.length(); i++) {
if (row.id == tableData.value[i].id) {
rowIndex = i;
}
}
if (rowIndex >= 0) {
tableData.value[rowIndex].status = option;
}
},
})),
layout: {
priority: "menu"
}, },
statusOptions: statusOptions.value
}, },
]; ];