1
0
forked from test/crm
jcrm/frontend/src/data/document.js
Shariq Ansari a1a44c1020 feat: implement runSequentially utility for sequential function execution
(cherry picked from commit 53c0706a3aeadf99c24724d1563a96e340c789fb)
2025-05-09 14:55:54 +00:00

137 lines
3.5 KiB
JavaScript

import { getScript } from '@/data/script'
import { createToast, runSequentially } from '@/utils'
import { createDocumentResource } from 'frappe-ui'
const documentsCache = {}
const controllersCache = {}
export function useDocument(doctype, docname) {
const { setupScript } = getScript(doctype)
documentsCache[doctype] = documentsCache[doctype] || {}
if (!documentsCache[doctype][docname]) {
documentsCache[doctype][docname] = createDocumentResource({
doctype: doctype,
name: docname,
onSuccess: () => setupFormScript(),
setValue: {
onSuccess: () => {
createToast({
title: 'Data Updated',
icon: 'check',
iconClasses: 'text-ink-green-3',
})
},
onError: (err) => {
createToast({
title: 'Error',
text: err.messages[0],
icon: 'x',
iconClasses: 'text-red-600',
})
},
},
})
}
function setupFormScript() {
if (controllersCache[doctype]) return
controllersCache[doctype] = setupScript(documentsCache[doctype][docname])
}
function getControllers(row = null) {
const _doctype = row?.doctype || doctype
return (controllersCache[doctype] || []).filter(
(c) => c.constructor.name === _doctype.replace(/\s+/g, ''),
)
}
async function triggerOnRefresh() {
const controllers = getControllers()
if (!controllers.length) return
const tasks = controllers.map((c) => async () => await c.refresh())
await runSequentially(tasks)
}
async function triggerOnChange(fieldname, row) {
const controllers = getControllers(row)
if (!controllers.length) return
const tasks = controllers.map((c) => async () => {
if (row) {
c.currentRowIdx = row.idx
c.value = row[fieldname]
c.oldValue = getOldValue(fieldname, row)
} else {
c.value = documentsCache[doctype][docname].doc[fieldname]
c.oldValue = getOldValue(fieldname)
}
await c[fieldname]?.()
})
await runSequentially(tasks)
}
async function triggerOnRowAdd(row) {
const controllers = getControllers(row)
if (!controllers.length) return
const tasks = controllers.map((c) => async () => {
c.currentRowIdx = row.idx
c.value = row
await c[row.parentfield + '_add']?.()
})
await runSequentially(tasks)
}
async function triggerOnRowRemove(selectedRows, rows) {
if (!selectedRows) return
const controllers = getControllers(rows[0])
if (!controllers.length) return
const tasks = controllers.map((c) => async () => {
if (selectedRows.size === 1) {
const selectedRow = Array.from(selectedRows)[0]
c.currentRowIdx = rows.find((r) => r.name === selectedRow).idx
} else {
delete c.currentRowIdx
}
c.selectedRows = Array.from(selectedRows)
c.rows = rows
await c[rows[0].parentfield + '_remove']?.()
})
await runSequentially(tasks)
}
function getOldValue(fieldname, row) {
if (!documentsCache[doctype][docname]) return ''
const document = documentsCache[doctype][docname]
const oldDoc = document.originalDoc
if (row?.name) {
return oldDoc?.[row.parentfield]?.find((r) => r.name === row.name)?.[
fieldname
]
}
return oldDoc?.[fieldname] || document.doc[fieldname]
}
return {
document: documentsCache[doctype][docname],
triggerOnChange,
triggerOnRowAdd,
triggerOnRowRemove,
triggerOnRefresh,
setupFormScript,
}
}