fix: cache controllers and use Promise.all for concurrent execution
(cherry picked from commit 556386e446e39d657e0bde7882924c30644b7ca8)
This commit is contained in:
parent
251a9831fd
commit
86f0f4949c
@ -3,6 +3,7 @@ import { createToast } from '@/utils'
|
||||
import { createDocumentResource } from 'frappe-ui'
|
||||
|
||||
const documentsCache = {}
|
||||
const controllersCache = {}
|
||||
|
||||
export function useDocument(doctype, docname) {
|
||||
const { setupScript } = getScript(doctype)
|
||||
@ -35,63 +36,59 @@ export function useDocument(doctype, docname) {
|
||||
}
|
||||
|
||||
function setupFormScript() {
|
||||
if (documentsCache[doctype][docname]['controllers']) return
|
||||
if (controllersCache[doctype]) return
|
||||
|
||||
const controllers = setupScript(documentsCache[doctype][docname])
|
||||
if (!controllers) return
|
||||
|
||||
documentsCache[doctype][docname]['controllers'] = controllers
|
||||
controllersCache[doctype] = setupScript(documentsCache[doctype][docname])
|
||||
}
|
||||
|
||||
function getControllers(row = null, dt = null) {
|
||||
let controllers = documentsCache[doctype][docname]?.controllers || {}
|
||||
if (Object.keys(controllers).length === 0) return
|
||||
|
||||
dt = dt || doctype
|
||||
if (!controllers[dt].length) return []
|
||||
|
||||
const _dt = row?.doctype ? row.doctype : doctype
|
||||
const _controllers = controllers[dt].filter(
|
||||
(c) => c.constructor.name === _dt.replace(/\s+/g, ''),
|
||||
function getControllers(row = null) {
|
||||
const _doctype = row?.doctype || doctype
|
||||
return (controllersCache[doctype] || []).filter(
|
||||
(c) => c.constructor.name === _doctype.replace(/\s+/g, ''),
|
||||
)
|
||||
return _controllers || []
|
||||
}
|
||||
|
||||
async function triggerOnRefresh() {
|
||||
const controllers = getControllers()
|
||||
if (!controllers.length) return
|
||||
for (const c of controllers) {
|
||||
await c.refresh()
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
controllers.map(async (c) => {
|
||||
await c.refresh()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
async function triggerOnChange(fieldname, row) {
|
||||
const controllers = getControllers(row)
|
||||
if (!controllers.length) return
|
||||
|
||||
for (const c of controllers) {
|
||||
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 Promise.all(
|
||||
controllers.map(async (c) => {
|
||||
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]?.()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
async function triggerOnRowAdd(row) {
|
||||
const controllers = getControllers(row)
|
||||
if (!controllers.length) return
|
||||
|
||||
for (const c of controllers) {
|
||||
c.currentRowIdx = row.idx
|
||||
c.value = row
|
||||
|
||||
await c[row.parentfield + '_add']?.()
|
||||
}
|
||||
await Promise.all(
|
||||
controllers.map(async (c) => {
|
||||
c.currentRowIdx = row.idx
|
||||
c.value = row
|
||||
await c[row.parentfield + '_add']?.()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
async function triggerOnRowRemove(selectedRows, rows) {
|
||||
@ -99,19 +96,21 @@ export function useDocument(doctype, docname) {
|
||||
const controllers = getControllers(rows[0])
|
||||
if (!controllers.length) return
|
||||
|
||||
for (const c of controllers) {
|
||||
if (selectedRows.size === 1) {
|
||||
const selectedRow = Array.from(selectedRows)[0]
|
||||
c.currentRowIdx = rows.find((r) => r.name === selectedRow).idx
|
||||
} else {
|
||||
delete c.currentRowIdx
|
||||
}
|
||||
await Promise.all(
|
||||
controllers.map(async (c) => {
|
||||
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
|
||||
c.selectedRows = Array.from(selectedRows)
|
||||
c.rows = rows
|
||||
|
||||
await c[rows[0].parentfield + '_remove']?.()
|
||||
}
|
||||
await c[rows[0].parentfield + '_remove']?.()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
function getOldValue(fieldname, row) {
|
||||
|
||||
@ -47,7 +47,7 @@ export function getScript(doctype, view = 'Form') {
|
||||
}
|
||||
|
||||
function setupMultipleFormControllers(scriptStrings, document, helpers) {
|
||||
const controllers = {}
|
||||
const controllers = []
|
||||
let parentInstanceIdx = null
|
||||
|
||||
for (let scriptName in scriptStrings) {
|
||||
@ -66,23 +66,19 @@ export function getScript(doctype, view = 'Form') {
|
||||
|
||||
let { doctypeMeta } = getMeta(doctype)
|
||||
|
||||
if (!controllers[doctype]) {
|
||||
controllers[doctype] = []
|
||||
}
|
||||
|
||||
// if className is not doctype name, then it is a child doctype
|
||||
let isChildDoctype = className !== doctypeName
|
||||
|
||||
if (isChildDoctype) {
|
||||
if (!controllers[doctype].length) {
|
||||
if (!controllers.length) {
|
||||
console.error(
|
||||
`⚠️ No class found for doctype: ${doctype}, it is mandatory to have a class for the parent doctype. it can be empty, but it should be present.`,
|
||||
)
|
||||
return
|
||||
}
|
||||
parentInstance = controllers[doctype][parentInstanceIdx]
|
||||
parentInstance = controllers[parentInstanceIdx]
|
||||
} else {
|
||||
parentInstanceIdx = controllers[doctype].length || 0
|
||||
parentInstanceIdx = controllers.length || 0
|
||||
}
|
||||
|
||||
const instance = setupFormController(
|
||||
@ -93,7 +89,7 @@ export function getScript(doctype, view = 'Form') {
|
||||
isChildDoctype,
|
||||
)
|
||||
|
||||
controllers[doctype].push(instance)
|
||||
controllers.push(instance)
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('Failed to load form controller:', err)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user