Birden fazla Editor Script oluşturma
This commit is contained in:
parent
acb06587c4
commit
c1e7f8cd1d
4 changed files with 167 additions and 54 deletions
|
|
@ -163,25 +163,7 @@ function fieldLabel(value: string, fallback: string) {
|
|||
return value || fallback
|
||||
}
|
||||
|
||||
function buildScript({
|
||||
currentField,
|
||||
copyMappings,
|
||||
daysStartField,
|
||||
daysEndField,
|
||||
daysTargetField,
|
||||
selectedItemAmountEnabled,
|
||||
rowAmountEnabled,
|
||||
amountQuantityField,
|
||||
amountUnitPriceField,
|
||||
amountUomField,
|
||||
amountTotalField,
|
||||
timeDiffEnabled,
|
||||
timeStartField,
|
||||
timeEndField,
|
||||
timeTargetField,
|
||||
conditionalActions,
|
||||
serviceCall,
|
||||
}: {
|
||||
type BuildScriptArgs = {
|
||||
currentField?: string
|
||||
copyMappings: CopyMapping[]
|
||||
daysStartField: string
|
||||
|
|
@ -199,7 +181,28 @@ function buildScript({
|
|||
timeTargetField: string
|
||||
conditionalActions: ConditionalAction[]
|
||||
serviceCall: string
|
||||
}) {
|
||||
}
|
||||
|
||||
function buildScript(args: BuildScriptArgs) {
|
||||
const {
|
||||
currentField,
|
||||
copyMappings,
|
||||
daysStartField,
|
||||
daysEndField,
|
||||
daysTargetField,
|
||||
selectedItemAmountEnabled,
|
||||
rowAmountEnabled,
|
||||
amountQuantityField,
|
||||
amountUnitPriceField,
|
||||
amountUomField,
|
||||
amountTotalField,
|
||||
timeDiffEnabled,
|
||||
timeStartField,
|
||||
timeEndField,
|
||||
timeTargetField,
|
||||
conditionalActions,
|
||||
serviceCall,
|
||||
} = args
|
||||
const activeCopyMappings = copyMappings.filter((mapping) => mapping.source && mapping.target)
|
||||
const hasCopyMappings = activeCopyMappings.length > 0
|
||||
const hasDateDifference = Boolean(daysStartField && daysEndField && daysTargetField)
|
||||
|
|
@ -228,6 +231,56 @@ function buildScript({
|
|||
return ''
|
||||
}
|
||||
|
||||
const hasNonConditionalSelection =
|
||||
hasCopyMappings ||
|
||||
hasDateDifference ||
|
||||
hasSelectedItemAmount ||
|
||||
hasRowAmount ||
|
||||
hasTimeDifference ||
|
||||
hasServiceCall
|
||||
|
||||
if (
|
||||
hasConditionalActions &&
|
||||
(activeConditionalActions.length > 1 || hasNonConditionalSelection)
|
||||
) {
|
||||
const scriptBlocks: string[] = []
|
||||
|
||||
if (hasNonConditionalSelection) {
|
||||
scriptBlocks.push(
|
||||
buildScript({
|
||||
...args,
|
||||
conditionalActions: [],
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
activeConditionalActions.forEach((action) => {
|
||||
scriptBlocks.push(
|
||||
buildScript({
|
||||
...args,
|
||||
copyMappings: [],
|
||||
daysStartField: '',
|
||||
daysEndField: '',
|
||||
daysTargetField: '',
|
||||
selectedItemAmountEnabled: false,
|
||||
rowAmountEnabled: false,
|
||||
amountQuantityField: '',
|
||||
amountUnitPriceField: '',
|
||||
amountUomField: '',
|
||||
amountTotalField: '',
|
||||
timeDiffEnabled: false,
|
||||
timeStartField: '',
|
||||
timeEndField: '',
|
||||
timeTargetField: '',
|
||||
conditionalActions: [action],
|
||||
serviceCall: '',
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
return scriptBlocks.filter(Boolean).join('\n\n')
|
||||
}
|
||||
|
||||
const needsSetFormData =
|
||||
hasCopyMappings ||
|
||||
hasDateDifference ||
|
||||
|
|
@ -271,13 +324,14 @@ function buildScript({
|
|||
|
||||
const lines: string[] = ['(async () => {']
|
||||
|
||||
if (needsSetFormData || hasConditionalActions) {
|
||||
if (needsSetFormData || hasConditionalActions || hasServiceCall) {
|
||||
lines.push(
|
||||
" const currentField = (typeof editor !== 'undefined' && editor?.dataField) || e?.dataField || " +
|
||||
quote(currentField || '') +
|
||||
';',
|
||||
)
|
||||
lines.push(' const next = { ...formData, [currentField]: e?.value };')
|
||||
lines.push(' const isEditorScriptContentReady = e?.scriptEvent === "contentReady";')
|
||||
}
|
||||
|
||||
if (needsRollbackCurrentValue) {
|
||||
|
|
@ -288,7 +342,7 @@ function buildScript({
|
|||
|
||||
if (needsSelectedItem) {
|
||||
lines.push(
|
||||
' const selectedItem = e?.component?.option ? e.component.option("selectedItem") : null;',
|
||||
' const selectedItem = (() => { try { return e?.component?.option ? e.component.option("selectedItem") : null; } catch { return null; } })();',
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +371,9 @@ function buildScript({
|
|||
? `getByPath(selectedItem, ${quote(mapping.source)})`
|
||||
: `selectedItem[${quote(mapping.source)}]`
|
||||
lines.push(
|
||||
` next[${quote(mapping.target)}] = selectedItem ? ${source} : next[${quote(mapping.target)}];`,
|
||||
` if (!isEditorScriptContentReady) next[${quote(
|
||||
mapping.target,
|
||||
)}] = selectedItem ? ${source} : next[${quote(mapping.target)}];`,
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -328,31 +384,35 @@ function buildScript({
|
|||
amountTotalField
|
||||
) {
|
||||
lines.push(' {')
|
||||
lines.push(' if (!isEditorScriptContentReady) {')
|
||||
lines.push(' const p = selectedItem || {};')
|
||||
lines.push(
|
||||
` const q = Math.round((parseFloat(p[${quote(amountQuantityField)}]) || 0) * 100);`,
|
||||
` const q = Math.round((parseFloat(p[${quote(amountQuantityField)}]) || 0) * 100);`,
|
||||
)
|
||||
lines.push(
|
||||
` const u = Math.round((parseFloat(p[${quote(amountUnitPriceField)}]) || 0) * 100);`,
|
||||
` const u = Math.round((parseFloat(p[${quote(amountUnitPriceField)}]) || 0) * 100);`,
|
||||
)
|
||||
lines.push(` next[${quote(amountQuantityField)}] = q / 100;`)
|
||||
lines.push(` next[${quote(amountUnitPriceField)}] = u / 100;`)
|
||||
lines.push(` next[${quote(amountQuantityField)}] = q / 100;`)
|
||||
lines.push(` next[${quote(amountUnitPriceField)}] = u / 100;`)
|
||||
if (amountUomField) {
|
||||
lines.push(` next[${quote(amountUomField)}] = p[${quote(amountUomField)}];`)
|
||||
lines.push(` next[${quote(amountUomField)}] = p[${quote(amountUomField)}];`)
|
||||
}
|
||||
lines.push(` next[${quote(amountTotalField)}] = Math.round((q * u) / 100) / 100;`)
|
||||
lines.push(` next[${quote(amountTotalField)}] = Math.round((q * u) / 100) / 100;`)
|
||||
lines.push(' }')
|
||||
lines.push(' }')
|
||||
}
|
||||
|
||||
if (rowAmountEnabled && amountQuantityField && amountUnitPriceField && amountTotalField) {
|
||||
lines.push(' {')
|
||||
lines.push(' if (!isEditorScriptContentReady) {')
|
||||
lines.push(
|
||||
` const q = Math.round((parseFloat(next[${quote(amountQuantityField)}]) || 0) * 100);`,
|
||||
` const q = Math.round((parseFloat(next[${quote(amountQuantityField)}]) || 0) * 100);`,
|
||||
)
|
||||
lines.push(
|
||||
` const u = Math.round((parseFloat(next[${quote(amountUnitPriceField)}]) || 0) * 100);`,
|
||||
` const u = Math.round((parseFloat(next[${quote(amountUnitPriceField)}]) || 0) * 100);`,
|
||||
)
|
||||
lines.push(` next[${quote(amountTotalField)}] = Math.round((q * u) / 100) / 100;`)
|
||||
lines.push(` next[${quote(amountTotalField)}] = Math.round((q * u) / 100) / 100;`)
|
||||
lines.push(' }')
|
||||
lines.push(' }')
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +423,7 @@ function buildScript({
|
|||
lines.push(` const startDate = parseDate(next[${quote(daysStartField)}]);`)
|
||||
lines.push(` const endDate = parseDate(next[${quote(daysEndField)}]);`)
|
||||
lines.push(
|
||||
` next[${quote(
|
||||
` if (!isEditorScriptContentReady) next[${quote(
|
||||
daysTargetField,
|
||||
)}] = startDate && endDate ? Math.max(0, Math.floor((Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate()) - Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())) / (24 * 60 * 60 * 1000)) + 1) : null;`,
|
||||
)
|
||||
|
|
@ -371,18 +431,20 @@ function buildScript({
|
|||
|
||||
if (timeDiffEnabled && timeStartField && timeEndField && timeTargetField) {
|
||||
lines.push(' {')
|
||||
lines.push(' if (!isEditorScriptContentReady) {')
|
||||
lines.push(
|
||||
' const toDate = value => !value ? null : (value instanceof Date ? value : new Date(value));',
|
||||
' const toDate = value => !value ? null : (value instanceof Date ? value : new Date(value));',
|
||||
)
|
||||
lines.push(` const startTime = toDate(next[${quote(timeStartField)}]);`)
|
||||
lines.push(` const endTime = toDate(next[${quote(timeEndField)}]);`)
|
||||
lines.push(' let hours = null;')
|
||||
lines.push(' if (startTime && endTime) {')
|
||||
lines.push(' hours = (endTime - startTime) / 36e5;')
|
||||
lines.push(' if (hours < 0) hours += 24;')
|
||||
lines.push(' hours = Math.round(hours * 10) / 10;')
|
||||
lines.push(` const startTime = toDate(next[${quote(timeStartField)}]);`)
|
||||
lines.push(` const endTime = toDate(next[${quote(timeEndField)}]);`)
|
||||
lines.push(' let hours = null;')
|
||||
lines.push(' if (startTime && endTime) {')
|
||||
lines.push(' hours = (endTime - startTime) / 36e5;')
|
||||
lines.push(' if (hours < 0) hours += 24;')
|
||||
lines.push(' hours = Math.round(hours * 10) / 10;')
|
||||
lines.push(' }')
|
||||
lines.push(` next[${quote(timeTargetField)}] = hours;`)
|
||||
lines.push(' }')
|
||||
lines.push(` next[${quote(timeTargetField)}] = hours;`)
|
||||
lines.push(' }')
|
||||
}
|
||||
|
||||
|
|
@ -398,7 +460,7 @@ function buildScript({
|
|||
return
|
||||
}
|
||||
|
||||
lines.push(` if (${condition}) {`)
|
||||
lines.push(` if (!isEditorScriptContentReady && (${condition})) {`)
|
||||
|
||||
if (action.actionType === 'setField' && action.targetField) {
|
||||
lines.push(
|
||||
|
|
@ -456,11 +518,13 @@ function buildScript({
|
|||
})
|
||||
|
||||
if (needsSetFormData) {
|
||||
lines.push(' if (typeof setFormData === "function") setFormData(next);')
|
||||
lines.push(
|
||||
' if (!isEditorScriptContentReady && typeof setFormData === "function") setFormData(next);',
|
||||
)
|
||||
}
|
||||
|
||||
if (serviceCall.trim()) {
|
||||
lines.push(` ${serviceCall.trim().replace(/;?$/, ';')}`)
|
||||
lines.push(` if (!isEditorScriptContentReady) ${serviceCall.trim().replace(/;?$/, ';')}`)
|
||||
}
|
||||
|
||||
lines.push('})();')
|
||||
|
|
@ -537,6 +601,25 @@ function EditorScriptBuilderDialog({
|
|||
setTimeTargetField((current) => current || findField('TotalHours'))
|
||||
}
|
||||
|
||||
const resetBuilderSelections = () => {
|
||||
setCopyMappings([])
|
||||
setDaysStartField('')
|
||||
setDaysEndField('')
|
||||
setDaysTargetField('')
|
||||
setSelectedItemAmountEnabled(false)
|
||||
setRowAmountEnabled(false)
|
||||
setAmountQuantityField('')
|
||||
setAmountUnitPriceField('')
|
||||
setAmountUomField('')
|
||||
setAmountTotalField('')
|
||||
setTimeDiffEnabled(false)
|
||||
setTimeStartField('')
|
||||
setTimeEndField('')
|
||||
setTimeTargetField('')
|
||||
setConditionalActions([])
|
||||
setServiceCall('')
|
||||
}
|
||||
|
||||
const hydrateKnownScript = (script?: string) => {
|
||||
const source = script?.trim()
|
||||
if (!source) return false
|
||||
|
|
@ -644,6 +727,21 @@ function EditorScriptBuilderDialog({
|
|||
[generatedScript],
|
||||
)
|
||||
|
||||
const canAppendGeneratedScript = Boolean(formattedGeneratedScript.trim())
|
||||
|
||||
const appendGeneratedScriptToEditor = () => {
|
||||
const nextScriptBlock = formattedGeneratedScript.trim()
|
||||
if (!nextScriptBlock) return
|
||||
|
||||
setScriptEditorValue((current) => {
|
||||
const existingScript = current.trim()
|
||||
if (existingScript === lastGeneratedScript.trim()) return nextScriptBlock
|
||||
return existingScript ? `${existingScript}\n\n${nextScriptBlock}` : nextScriptBlock
|
||||
})
|
||||
setLastGeneratedScript('')
|
||||
resetBuilderSelections()
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return
|
||||
setScriptEditorValue((current) => {
|
||||
|
|
@ -757,7 +855,7 @@ function EditorScriptBuilderDialog({
|
|||
</div>
|
||||
|
||||
<div className="grid min-h-0 grid-cols-1 gap-4 overflow-y-auto pr-1 lg:grid-cols-2">
|
||||
<section className="flex flex-col gap-4">
|
||||
<section className="flex flex-col gap-2">
|
||||
<div className="rounded border border-gray-200 dark:border-gray-700 p-3">
|
||||
<div className="flex items-center justify-between gap-2 mb-3">
|
||||
<div>
|
||||
|
|
@ -1212,6 +1310,17 @@ function EditorScriptBuilderDialog({
|
|||
<span className="rounded bg-gray-100 px-2 py-1 text-[11px] font-medium text-gray-500 dark:bg-gray-800 dark:text-gray-300">
|
||||
TypeScript
|
||||
</span>
|
||||
<Button
|
||||
size="xs"
|
||||
type="button"
|
||||
variant="solid"
|
||||
icon={<FaPlus />}
|
||||
disabled={!canAppendGeneratedScript}
|
||||
title="Soldaki builder seçimlerinin tamamını mevcut scriptin sonuna yeni bir blok olarak ekle."
|
||||
onClick={appendGeneratedScriptToEditor}
|
||||
>
|
||||
Script olarak ekle
|
||||
</Button>
|
||||
<Button
|
||||
size="xs"
|
||||
type="button"
|
||||
|
|
@ -1225,7 +1334,7 @@ function EditorScriptBuilderDialog({
|
|||
</div>
|
||||
<div className="flex-1 min-h-[350px] overflow-hidden rounded border border-gray-200 dark:border-gray-700">
|
||||
<Editor
|
||||
height="100%"
|
||||
height="95%"
|
||||
language="typescript"
|
||||
theme="vs-dark"
|
||||
value={scriptEditorValue}
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ const FormDevExpress = (props: {
|
|||
const e = {
|
||||
component: form,
|
||||
dataField,
|
||||
scriptEvent: 'valueChanged',
|
||||
value: eventValue,
|
||||
}
|
||||
const runtimeSetEditorReadOnly = (field: string, readOnly: boolean) =>
|
||||
|
|
@ -414,6 +415,7 @@ const FormDevExpress = (props: {
|
|||
const e = {
|
||||
component: form,
|
||||
dataField: formItem.dataField,
|
||||
scriptEvent: 'contentReady',
|
||||
value: getValueByField(currentFormData, formItem.dataField),
|
||||
}
|
||||
const runtimeSetEditorReadOnly = (field: string, readOnly: boolean) =>
|
||||
|
|
@ -424,7 +426,7 @@ const FormDevExpress = (props: {
|
|||
e,
|
||||
editor,
|
||||
runtimeSetEditorReadOnly,
|
||||
setFormData: (newData: any) => applyEditorScriptFormData(form, newData),
|
||||
setFormData: undefined,
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('Script execution failed on contentReady for', formItem.name, err)
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ const Grid = (props: GridProps) => {
|
|||
|
||||
executeEditorScript(formItem.editorScript!, {
|
||||
formData,
|
||||
e,
|
||||
e: { ...e, scriptEvent: 'valueChanged' },
|
||||
editor,
|
||||
runtimeSetEditorReadOnly,
|
||||
setFormData,
|
||||
|
|
@ -1665,6 +1665,7 @@ const Grid = (props: GridProps) => {
|
|||
const e = {
|
||||
component: form,
|
||||
dataField: formItem.dataField,
|
||||
scriptEvent: 'contentReady',
|
||||
value: editorValue,
|
||||
}
|
||||
|
||||
|
|
@ -1673,7 +1674,7 @@ const Grid = (props: GridProps) => {
|
|||
e,
|
||||
editor,
|
||||
runtimeSetEditorReadOnly,
|
||||
setFormData,
|
||||
setFormData: undefined,
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(
|
||||
|
|
@ -1726,7 +1727,7 @@ const Grid = (props: GridProps) => {
|
|||
|
||||
executeEditorScript(formItem.editorScript, {
|
||||
formData,
|
||||
e,
|
||||
e: { ...e, scriptEvent: 'valueChanged' },
|
||||
editor: {
|
||||
dataField: e.dataField,
|
||||
component: grid,
|
||||
|
|
|
|||
|
|
@ -819,7 +819,7 @@ const Tree = (props: TreeProps) => {
|
|||
|
||||
executeEditorScript(formItem.editorScript!, {
|
||||
formData,
|
||||
e,
|
||||
e: { ...e, scriptEvent: 'valueChanged' },
|
||||
editor,
|
||||
runtimeSetEditorReadOnly,
|
||||
setFormData,
|
||||
|
|
@ -1326,6 +1326,7 @@ const Tree = (props: TreeProps) => {
|
|||
const e = {
|
||||
component: form,
|
||||
dataField: formItem.dataField,
|
||||
scriptEvent: 'contentReady',
|
||||
value: editorValue,
|
||||
}
|
||||
|
||||
|
|
@ -1334,7 +1335,7 @@ const Tree = (props: TreeProps) => {
|
|||
e,
|
||||
editor,
|
||||
runtimeSetEditorReadOnly,
|
||||
setFormData,
|
||||
setFormData: undefined,
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(
|
||||
|
|
@ -1387,7 +1388,7 @@ const Tree = (props: TreeProps) => {
|
|||
|
||||
executeEditorScript(formItem.editorScript, {
|
||||
formData,
|
||||
e,
|
||||
e: { ...e, scriptEvent: 'valueChanged' },
|
||||
editor: {
|
||||
dataField: e.dataField,
|
||||
component: grid,
|
||||
|
|
|
|||
Loading…
Reference in a new issue