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'
|
import { createDocumentResource } from 'frappe-ui'
|
||||||
|
|
||||||
const documentsCache = {}
|
const documentsCache = {}
|
||||||
|
const controllersCache = {}
|
||||||
|
|
||||||
export function useDocument(doctype, docname) {
|
export function useDocument(doctype, docname) {
|
||||||
const { setupScript } = getScript(doctype)
|
const { setupScript } = getScript(doctype)
|
||||||
@ -35,63 +36,59 @@ export function useDocument(doctype, docname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupFormScript() {
|
function setupFormScript() {
|
||||||
if (documentsCache[doctype][docname]['controllers']) return
|
if (controllersCache[doctype]) return
|
||||||
|
|
||||||
const controllers = setupScript(documentsCache[doctype][docname])
|
controllersCache[doctype] = setupScript(documentsCache[doctype][docname])
|
||||||
if (!controllers) return
|
|
||||||
|
|
||||||
documentsCache[doctype][docname]['controllers'] = controllers
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getControllers(row = null, dt = null) {
|
function getControllers(row = null) {
|
||||||
let controllers = documentsCache[doctype][docname]?.controllers || {}
|
const _doctype = row?.doctype || doctype
|
||||||
if (Object.keys(controllers).length === 0) return
|
return (controllersCache[doctype] || []).filter(
|
||||||
|
(c) => c.constructor.name === _doctype.replace(/\s+/g, ''),
|
||||||
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, ''),
|
|
||||||
)
|
)
|
||||||
return _controllers || []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function triggerOnRefresh() {
|
async function triggerOnRefresh() {
|
||||||
const controllers = getControllers()
|
const controllers = getControllers()
|
||||||
if (!controllers.length) return
|
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) {
|
async function triggerOnChange(fieldname, row) {
|
||||||
const controllers = getControllers(row)
|
const controllers = getControllers(row)
|
||||||
if (!controllers.length) return
|
if (!controllers.length) return
|
||||||
|
|
||||||
for (const c of controllers) {
|
await Promise.all(
|
||||||
if (row) {
|
controllers.map(async (c) => {
|
||||||
c.currentRowIdx = row.idx
|
if (row) {
|
||||||
c.value = row[fieldname]
|
c.currentRowIdx = row.idx
|
||||||
c.oldValue = getOldValue(fieldname, row)
|
c.value = row[fieldname]
|
||||||
} else {
|
c.oldValue = getOldValue(fieldname, row)
|
||||||
c.value = documentsCache[doctype][docname].doc[fieldname]
|
} else {
|
||||||
c.oldValue = getOldValue(fieldname)
|
c.value = documentsCache[doctype][docname].doc[fieldname]
|
||||||
}
|
c.oldValue = getOldValue(fieldname)
|
||||||
await c[fieldname]?.()
|
}
|
||||||
}
|
await c[fieldname]?.()
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function triggerOnRowAdd(row) {
|
async function triggerOnRowAdd(row) {
|
||||||
const controllers = getControllers(row)
|
const controllers = getControllers(row)
|
||||||
if (!controllers.length) return
|
if (!controllers.length) return
|
||||||
|
|
||||||
for (const c of controllers) {
|
await Promise.all(
|
||||||
c.currentRowIdx = row.idx
|
controllers.map(async (c) => {
|
||||||
c.value = row
|
c.currentRowIdx = row.idx
|
||||||
|
c.value = row
|
||||||
await c[row.parentfield + '_add']?.()
|
await c[row.parentfield + '_add']?.()
|
||||||
}
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function triggerOnRowRemove(selectedRows, rows) {
|
async function triggerOnRowRemove(selectedRows, rows) {
|
||||||
@ -99,19 +96,21 @@ export function useDocument(doctype, docname) {
|
|||||||
const controllers = getControllers(rows[0])
|
const controllers = getControllers(rows[0])
|
||||||
if (!controllers.length) return
|
if (!controllers.length) return
|
||||||
|
|
||||||
for (const c of controllers) {
|
await Promise.all(
|
||||||
if (selectedRows.size === 1) {
|
controllers.map(async (c) => {
|
||||||
const selectedRow = Array.from(selectedRows)[0]
|
if (selectedRows.size === 1) {
|
||||||
c.currentRowIdx = rows.find((r) => r.name === selectedRow).idx
|
const selectedRow = Array.from(selectedRows)[0]
|
||||||
} else {
|
c.currentRowIdx = rows.find((r) => r.name === selectedRow).idx
|
||||||
delete c.currentRowIdx
|
} else {
|
||||||
}
|
delete c.currentRowIdx
|
||||||
|
}
|
||||||
|
|
||||||
c.selectedRows = Array.from(selectedRows)
|
c.selectedRows = Array.from(selectedRows)
|
||||||
c.rows = rows
|
c.rows = rows
|
||||||
|
|
||||||
await c[rows[0].parentfield + '_remove']?.()
|
await c[rows[0].parentfield + '_remove']?.()
|
||||||
}
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOldValue(fieldname, row) {
|
function getOldValue(fieldname, row) {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export function getScript(doctype, view = 'Form') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupMultipleFormControllers(scriptStrings, document, helpers) {
|
function setupMultipleFormControllers(scriptStrings, document, helpers) {
|
||||||
const controllers = {}
|
const controllers = []
|
||||||
let parentInstanceIdx = null
|
let parentInstanceIdx = null
|
||||||
|
|
||||||
for (let scriptName in scriptStrings) {
|
for (let scriptName in scriptStrings) {
|
||||||
@ -66,23 +66,19 @@ export function getScript(doctype, view = 'Form') {
|
|||||||
|
|
||||||
let { doctypeMeta } = getMeta(doctype)
|
let { doctypeMeta } = getMeta(doctype)
|
||||||
|
|
||||||
if (!controllers[doctype]) {
|
|
||||||
controllers[doctype] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
// if className is not doctype name, then it is a child doctype
|
// if className is not doctype name, then it is a child doctype
|
||||||
let isChildDoctype = className !== doctypeName
|
let isChildDoctype = className !== doctypeName
|
||||||
|
|
||||||
if (isChildDoctype) {
|
if (isChildDoctype) {
|
||||||
if (!controllers[doctype].length) {
|
if (!controllers.length) {
|
||||||
console.error(
|
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.`,
|
`⚠️ 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
|
return
|
||||||
}
|
}
|
||||||
parentInstance = controllers[doctype][parentInstanceIdx]
|
parentInstance = controllers[parentInstanceIdx]
|
||||||
} else {
|
} else {
|
||||||
parentInstanceIdx = controllers[doctype].length || 0
|
parentInstanceIdx = controllers.length || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const instance = setupFormController(
|
const instance = setupFormController(
|
||||||
@ -93,7 +89,7 @@ export function getScript(doctype, view = 'Form') {
|
|||||||
isChildDoctype,
|
isChildDoctype,
|
||||||
)
|
)
|
||||||
|
|
||||||
controllers[doctype].push(instance)
|
controllers.push(instance)
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load form controller:', err)
|
console.error('Failed to load form controller:', err)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user