From c1e7f8cd1d460257699b32511c5c163503af9578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Tue, 9 Jun 2026 22:24:47 +0300 Subject: [PATCH] =?UTF-8?q?Birden=20fazla=20Editor=20Script=20olu=C5=9Ftur?= =?UTF-8?q?ma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditorScriptBuilderDialog.tsx | 203 ++++++++++++++---- ui/src/views/form/FormDevExpress.tsx | 4 +- ui/src/views/list/Grid.tsx | 7 +- ui/src/views/list/Tree.tsx | 7 +- 4 files changed, 167 insertions(+), 54 deletions(-) diff --git a/ui/src/views/admin/listForm/edit/json-row-operations/EditorScriptBuilderDialog.tsx b/ui/src/views/admin/listForm/edit/json-row-operations/EditorScriptBuilderDialog.tsx index 5a43718..c4830f6 100644 --- a/ui/src/views/admin/listForm/edit/json-row-operations/EditorScriptBuilderDialog.tsx +++ b/ui/src/views/admin/listForm/edit/json-row-operations/EditorScriptBuilderDialog.tsx @@ -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({
-
+
@@ -1212,6 +1310,17 @@ function EditorScriptBuilderDialog({ TypeScript +