From 8b30f3ef48a4f240813a4d4a4c469ea12d797c1e Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Thu, 24 Jul 2025 10:03:30 +0500 Subject: [PATCH] Add array manipulation functions and editors for process (#9594) Signed-off-by: Denis Bykhov --- models/process/src/index.ts | 62 ++++++++++++ models/server-process/src/index.ts | 16 +++ plugins/process-assets/lang/cs.json | 6 +- plugins/process-assets/lang/de.json | 6 +- plugins/process-assets/lang/en.json | 6 +- plugins/process-assets/lang/es.json | 4 + plugins/process-assets/lang/fr.json | 4 + plugins/process-assets/lang/it.json | 4 + plugins/process-assets/lang/ja.json | 4 + plugins/process-assets/lang/pt.json | 4 + plugins/process-assets/lang/ru.json | 4 + plugins/process-assets/lang/zh.json | 4 + .../attributeEditors/ConfigurePopup.svelte | 21 ++-- .../attributeEditors/ContextValue.svelte | 2 +- .../ArrayElementEditor.svelte | 99 +++++++++++++++++++ plugins/process-resources/src/index.ts | 2 + plugins/process-resources/src/plugin.ts | 5 + plugins/process/src/index.ts | 6 +- server-plugins/process-resources/src/index.ts | 10 +- .../process-resources/src/transform.ts | 54 ++++++++++ server-plugins/process/src/index.ts | 6 +- 21 files changed, 313 insertions(+), 16 deletions(-) create mode 100644 plugins/process-resources/src/components/transformEditors/ArrayElementEditor.svelte diff --git a/models/process/src/index.ts b/models/process/src/index.ts index 16eddc2b76..5123f2db17 100644 --- a/models/process/src/index.ts +++ b/models/process/src/index.ts @@ -653,6 +653,68 @@ export function createModel (builder: Builder): void { process.function.FirstWorkingDayAfter ) + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: core.class.ArrOf, + category: 'array', + label: process.string.Insert, + editor: process.transformEditor.ArrayElementEditor, + type: 'transform' + }, + process.function.Insert + ) + + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: core.class.ArrOf, + category: 'array', + label: process.string.Remove, + editor: process.transformEditor.ArrayElementEditor, + type: 'transform' + }, + process.function.Remove + ) + + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: core.class.ArrOf, + category: 'array', + label: process.string.RemoveFirst, + type: 'transform' + }, + process.function.RemoveFirst + ) + + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: core.class.ArrOf, + category: 'array', + label: process.string.RemoveLast, + type: 'transform' + }, + process.function.RemoveLast + ) + + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: core.class.ArrOf, + category: 'array', + label: process.string.RemoveLast, + type: 'transform' + }, + process.function.RemoveLast + ) + builder.createDoc( process.class.ProcessFunction, core.space.Model, diff --git a/models/server-process/src/index.ts b/models/server-process/src/index.ts index ab6b3b657a..4758e82ac9 100644 --- a/models/server-process/src/index.ts +++ b/models/server-process/src/index.ts @@ -182,6 +182,22 @@ export function createModel (builder: Builder): void { func: serverProcess.transform.RoleContext }) + builder.mixin(process.function.Insert, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, { + func: serverProcess.transform.Insert + }) + + builder.mixin(process.function.Remove, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, { + func: serverProcess.transform.Remove + }) + + builder.mixin(process.function.RemoveFirst, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, { + func: serverProcess.transform.RemoveFirst + }) + + builder.mixin(process.function.RemoveLast, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, { + func: serverProcess.transform.RemoveLast + }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverProcess.trigger.OnExecutionContinue, txMatch: { diff --git a/plugins/process-assets/lang/cs.json b/plugins/process-assets/lang/cs.json index 72d4f4b9c7..dd0f838ab0 100644 --- a/plugins/process-assets/lang/cs.json +++ b/plugins/process-assets/lang/cs.json @@ -91,7 +91,11 @@ "Started": "Spuštěno", "Each": "Každý", "CreateCard": "Vytvořit kartu", - "OnCardUpdate": "Při aktualizaci karty" + "OnCardUpdate": "Při aktualizaci karty", + "Insert": "Vložit", + "Remove": "Odstranit", + "RemoveFirst": "Odstranit první", + "RemoveLast": "Odstranit poslední" }, "error": { "MethodNotFound": "Metoda nenalezena: {methodId}", diff --git a/plugins/process-assets/lang/de.json b/plugins/process-assets/lang/de.json index 8f98bd14ef..7aa1b951e0 100644 --- a/plugins/process-assets/lang/de.json +++ b/plugins/process-assets/lang/de.json @@ -91,7 +91,11 @@ "Started": "Gestartet", "Each": "Jeder", "CreateCard": "Karte erstellen", - "OnCardUpdate": "Beim Aktualisieren der Karte" + "OnCardUpdate": "Beim Aktualisieren der Karte", + "Insert": "Einfügen", + "Remove": "Entfernen", + "RemoveFirst": "Erstes entfernen", + "RemoveLast": "Letztes entfernen" }, "error": { "MethodNotFound": "Methode nicht gefunden: {methodId}", diff --git a/plugins/process-assets/lang/en.json b/plugins/process-assets/lang/en.json index 4205d7b199..464555a00c 100644 --- a/plugins/process-assets/lang/en.json +++ b/plugins/process-assets/lang/en.json @@ -96,7 +96,11 @@ "ArraySizeGt": "Size greater than", "ArraySizeGte": "Size greater than or equal", "ArraySizeLt": "Size less than", - "ArraySizeLte": "Size less than or equal" + "ArraySizeLte": "Size less than or equal", + "Insert": "Insert", + "Remove": "Remove", + "RemoveFirst": "Remove first", + "RemoveLast": "Remove last" }, "error": { "MethodNotFound": "Method not found: {methodId}", diff --git a/plugins/process-assets/lang/es.json b/plugins/process-assets/lang/es.json index 3d0187f1f9..f4635422fa 100644 --- a/plugins/process-assets/lang/es.json +++ b/plugins/process-assets/lang/es.json @@ -1,6 +1,10 @@ { "string": { "Method": "Método", + "Insert": "Insertar", + "Remove": "Eliminar", + "RemoveFirst": "Quitar primero", + "RemoveLast": "Quitar último", "Execution": "Ejecución", "Process": "Proceso", "Step": "Paso", diff --git a/plugins/process-assets/lang/fr.json b/plugins/process-assets/lang/fr.json index 8d1d46696d..c53503c201 100644 --- a/plugins/process-assets/lang/fr.json +++ b/plugins/process-assets/lang/fr.json @@ -41,6 +41,10 @@ "Subtract": "Soustraire", "Offset": "Décalage", "FirstWorkingDayAfter": "Premier jour de travail après", + "Insert": "Insérer", + "Remove": "Supprimer", + "RemoveFirst": "Supprimer le premier", + "RemoveLast": "Supprimer le dernier", "FallbackValueError": "Afficher l'erreur si vide", "Required": "Requis", "ParallelExecutionForbidden": "Exécution parallèle interdite", diff --git a/plugins/process-assets/lang/it.json b/plugins/process-assets/lang/it.json index 5e28a7b14d..7c682e8dc1 100644 --- a/plugins/process-assets/lang/it.json +++ b/plugins/process-assets/lang/it.json @@ -41,6 +41,10 @@ "Subtract": "Sottrai", "Offset": "Offset", "FirstWorkingDayAfter": "Primo giorno lavorativo dopo", + "Insert": "Inserisci", + "Remove": "Rimuovi", + "RemoveFirst": "Rimuovi il primo", + "RemoveLast": "Rimuovi l'ultimo", "FallbackValueError": "Mostra errore se vuoto", "Required": "Obbligatorio", "ParallelExecutionForbidden": "Esecuzione parallela vietata", diff --git a/plugins/process-assets/lang/ja.json b/plugins/process-assets/lang/ja.json index 2f09bcd193..fddffd90ee 100644 --- a/plugins/process-assets/lang/ja.json +++ b/plugins/process-assets/lang/ja.json @@ -41,6 +41,10 @@ "Subtract": "減算", "Offset": "オフセット", "FirstWorkingDayAfter": "以降の最初の営業日", + "Insert": "挿入", + "Remove": "削除", + "RemoveFirst": "最初を削除", + "RemoveLast": "最後を削除", "FallbackValueError": "空の場合エラーを表示", "Required": "必須", "ParallelExecutionForbidden": "並列実行は禁止されています", diff --git a/plugins/process-assets/lang/pt.json b/plugins/process-assets/lang/pt.json index 377a37faf6..42f261eafe 100644 --- a/plugins/process-assets/lang/pt.json +++ b/plugins/process-assets/lang/pt.json @@ -41,6 +41,10 @@ "Subtract": "Subtrair", "Offset": "Deslocar", "FirstWorkingDayAfter": "Primeiro Dia de Trabalho Após", + "Insert": "Inserir", + "Remove": "Remover", + "RemoveFirst": "Remover Primeiro", + "RemoveLast": "Remover Último", "FallbackValueError": "Mostrar erro se vazio", "Required": "Obrigatório", "ParallelExecutionForbidden": "Execução Paralela Proibida", diff --git a/plugins/process-assets/lang/ru.json b/plugins/process-assets/lang/ru.json index 2c5c14936b..77bcbb5931 100644 --- a/plugins/process-assets/lang/ru.json +++ b/plugins/process-assets/lang/ru.json @@ -41,6 +41,10 @@ "Subtract": "Вычесть", "Offset": "Смещение", "FirstWorkingDayAfter": "Первый рабочий день после", + "Insert": "Вставить", + "Remove": "Удалить", + "RemoveFirst": "Удалить первый", + "RemoveLast": "Удалить последний", "FallbackValueError": "Показывать ошибку, если недоступно", "Required": "Обязательно", "ParallelExecutionForbidden": "Одновременное выполнение запрещено", diff --git a/plugins/process-assets/lang/zh.json b/plugins/process-assets/lang/zh.json index 00a0469a95..b1d880aeff 100644 --- a/plugins/process-assets/lang/zh.json +++ b/plugins/process-assets/lang/zh.json @@ -41,6 +41,10 @@ "Subtract": "减去", "Offset": "偏移", "FirstWorkingDayAfter": "在之后的第一个工作日", + "Insert": "插入", + "Remove": "移除", + "RemoveFirst": "移除第一个", + "RemoveLast": "移除最后一个", "FallbackValueError": "显示错误,如果为空", "Required": "必需", "ParallelExecutionForbidden": "禁止并行执行", diff --git a/plugins/process-resources/src/components/attributeEditors/ConfigurePopup.svelte b/plugins/process-resources/src/components/attributeEditors/ConfigurePopup.svelte index 066166976c..09f08fb5a4 100644 --- a/plugins/process-resources/src/components/attributeEditors/ConfigurePopup.svelte +++ b/plugins/process-resources/src/components/attributeEditors/ConfigurePopup.svelte @@ -14,7 +14,7 @@ --> + + +
+ { + value = e.detail + }} + /> +
+
+ + diff --git a/plugins/process-resources/src/index.ts b/plugins/process-resources/src/index.ts index 2ba7359d85..1b20af0dd8 100644 --- a/plugins/process-resources/src/index.ts +++ b/plugins/process-resources/src/index.ts @@ -43,6 +43,7 @@ import TriggerPresenter from './components/settings/TriggerPresenter.svelte' import UpdateCardEditor from './components/settings/UpdateCardEditor.svelte' import DateOffsetEditor from './components/transformEditors/DateOffsetEditor.svelte' import NumberEditor from './components/transformEditors/NumberEditor.svelte' +import ArrayElementEditor from './components/transformEditors/ArrayElementEditor.svelte' import LogActionPresenter from './components/LogActionPresenter.svelte' import NotifierExtension from './components/NotifierExtension.svelte' @@ -121,6 +122,7 @@ export default async (): Promise => ({ ArrayCriteria }, transformEditor: { + ArrayElementEditor, DateOffsetEditor, NumberEditor, AppendEditor, diff --git a/plugins/process-resources/src/plugin.ts b/plugins/process-resources/src/plugin.ts index ed33b485fb..2b3be4e656 100644 --- a/plugins/process-resources/src/plugin.ts +++ b/plugins/process-resources/src/plugin.ts @@ -74,6 +74,7 @@ export default mergeIds(processId, process, { RefCriteria: '' as AnyComponent }, transformEditor: { + ArrayElementEditor: '' as AnyComponent, DateOffsetEditor: '' as AnyComponent, NumberEditor: '' as AnyComponent, AppendEditor: '' as AnyComponent, @@ -138,6 +139,10 @@ export default mergeIds(processId, process, { Offset: '' as IntlString, Value: '' as IntlString, FirstWorkingDayAfter: '' as IntlString, + Insert: '' as IntlString, + Remove: '' as IntlString, + RemoveFirst: '' as IntlString, + RemoveLast: '' as IntlString, FallbackValueError: '' as IntlString, Required: '' as IntlString, ParallelExecutionForbidden: '' as IntlString, diff --git a/plugins/process/src/index.ts b/plugins/process/src/index.ts index df5971f78d..7aea0ae9f2 100644 --- a/plugins/process/src/index.ts +++ b/plugins/process/src/index.ts @@ -272,6 +272,10 @@ export default plugin(processId, { Offset: '' as Ref, FirstWorkingDayAfter: '' as Ref, RoleContext: '' as Ref, - All: '' as Ref + All: '' as Ref, + Insert: '' as Ref, + Remove: '' as Ref, + RemoveFirst: '' as Ref, + RemoveLast: '' as Ref } }) diff --git a/server-plugins/process-resources/src/index.ts b/server-plugins/process-resources/src/index.ts index 863e185b30..ec9a477007 100644 --- a/server-plugins/process-resources/src/index.ts +++ b/server-plugins/process-resources/src/index.ts @@ -75,6 +75,7 @@ import { FirstValue, FirstWorkingDayAfter, Floor, + Insert, LastValue, LowerCase, Modulo, @@ -83,11 +84,14 @@ import { Power, Prepend, Random, + Remove, Replace, ReplaceAll, Round, Split, Subtract, + RemoveFirst, + RemoveLast, Trim, UpperCase } from './transform' @@ -1046,7 +1050,11 @@ export default async () => ({ Floor, Offset, FirstWorkingDayAfter, - RoleContext + RoleContext, + Insert, + Remove, + RemoveFirst, + RemoveLast }, trigger: { OnProcessRemove, diff --git a/server-plugins/process-resources/src/transform.ts b/server-plugins/process-resources/src/transform.ts index 3ee0041b77..20702e6089 100644 --- a/server-plugins/process-resources/src/transform.ts +++ b/server-plugins/process-resources/src/transform.ts @@ -41,6 +41,60 @@ export function All (value: Doc[]): Doc[] { // #endregion +// #region Array + +export async function Insert ( + value: Doc[], + props: Record, + control: TriggerControl, + execution: Execution +): Promise { + if (!Array.isArray(value)) return value + if (props.value == null) return value + const context = parseContext(props.value) + if (context !== undefined) { + if (context.type === 'attribute') { + const addition = await getAttributeValue(control, execution, context) + value.push(addition) + } + } else { + value.push(props.value) + } + return value +} + +export async function Remove ( + value: Doc[], + props: Record, + control: TriggerControl, + execution: Execution +): Promise { + if (!Array.isArray(value)) return value + if (props.value == null) return value + const context = parseContext(props.value) + if (context !== undefined) { + if (context.type === 'attribute') { + const addition = await getAttributeValue(control, execution, context) + return value.filter((item) => item !== addition) + } + } else { + return value.filter((item) => item !== props.value) + } + return value +} + +export function RemoveFirst (value: Doc[], props: Record): Doc[] { + if (!Array.isArray(value)) return value + return value.slice(1) +} + +export function RemoveLast (value: Doc[], props: Record): Doc[] { + if (!Array.isArray(value)) return value + return value.slice(0, -1) +} + +// #endregion + // #region String export function UpperCase (value: string): string { diff --git a/server-plugins/process/src/index.ts b/server-plugins/process/src/index.ts index cfa792a8e1..f9f032773f 100644 --- a/server-plugins/process/src/index.ts +++ b/server-plugins/process/src/index.ts @@ -69,7 +69,11 @@ export default plugin(serverProcessId, { Floor: '' as Resource, Offset: '' as Resource, FirstWorkingDayAfter: '' as Resource, - RoleContext: '' as Resource + RoleContext: '' as Resource, + Insert: '' as Resource, + Remove: '' as Resource, + RemoveFirst: '' as Resource, + RemoveLast: '' as Resource }, trigger: { OnTransition: '' as Resource,