From 31f47d35c2964df0e34998a7c150d1bae97aa4ef Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sat, 14 Feb 2026 21:40:29 +0500 Subject: [PATCH] Cancel todo action Signed-off-by: Denis Bykhov --- models/process/src/actions.ts | 14 ++++ models/server-process/src/index.ts | 4 ++ 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 | 6 +- plugins/process-assets/lang/fr.json | 6 +- plugins/process-assets/lang/it.json | 6 +- plugins/process-assets/lang/ja.json | 6 +- plugins/process-assets/lang/pt-br.json | 6 +- plugins/process-assets/lang/pt.json | 6 +- plugins/process-assets/lang/ru.json | 6 +- plugins/process-assets/lang/tr.json | 6 +- plugins/process-assets/lang/zh.json | 6 +- .../settings/CancelToDoEditor.svelte | 45 +++++++++++++ .../src/components/settings/TimeEditor.svelte | 6 +- .../settings/ToDoValuePresenter.svelte | 67 +++++++++++++++++++ plugins/process-resources/src/index.ts | 6 +- plugins/process-resources/src/plugin.ts | 5 +- plugins/process/src/index.ts | 4 +- .../process-resources/src/functions.ts | 27 ++++++++ server-plugins/process-resources/src/index.ts | 2 + server-plugins/process/src/index.ts | 3 +- 23 files changed, 224 insertions(+), 31 deletions(-) create mode 100644 plugins/process-resources/src/components/settings/CancelToDoEditor.svelte create mode 100644 plugins/process-resources/src/components/settings/ToDoValuePresenter.svelte diff --git a/models/process/src/actions.ts b/models/process/src/actions.ts index 15386b929b6..e3f8d96da3a 100644 --- a/models/process/src/actions.ts +++ b/models/process/src/actions.ts @@ -120,6 +120,20 @@ export function defineMethods (builder: Builder): void { process.method.AddTag ) + builder.createDoc( + process.class.Method, + core.space.Model, + { + label: process.string.CancelToDo, + editor: process.component.CancelToDoEditor, + presenter: process.component.ToDoValuePresenter, + objectClass: process.class.ProcessToDo, + requiredParams: ['_id'], + createdContext: null + }, + process.method.CancelToDo + ) + builder.createDoc( process.class.Method, core.space.Model, diff --git a/models/server-process/src/index.ts b/models/server-process/src/index.ts index b5268f4693b..5338f95f62e 100644 --- a/models/server-process/src/index.ts +++ b/models/server-process/src/index.ts @@ -131,6 +131,10 @@ export function createModel (builder: Builder): void { func: serverProcess.func.RequestApproval }) + builder.mixin(process.method.CancelToDo, process.class.Method, serverProcess.mixin.MethodImpl, { + func: serverProcess.func.CancelToDo + }) + builder.mixin(process.method.LockCard, process.class.Method, serverProcess.mixin.MethodImpl, { func: serverProcess.func.LockCard }) diff --git a/plugins/process-assets/lang/cs.json b/plugins/process-assets/lang/cs.json index 1b44550a365..39c6238d46f 100644 --- a/plugins/process-assets/lang/cs.json +++ b/plugins/process-assets/lang/cs.json @@ -140,7 +140,8 @@ "LockSection": "Zamknout sekci", "Approvers": "Schvalovatelé", "UnlockCard": "Odemknout kartu", - "UnlockSection": "Odemknout sekci" + "UnlockSection": "Odemknout sekci", + "CancelToDo": "Zrušit akční položku" }, "error": { "MethodNotFound": "Metoda nenalezena: {methodId}", @@ -156,6 +157,7 @@ "EmptyFunctionResult": "Prázdný výsledek funkce {func}", "ContextValueNotProvided": "Hodnota kontextu nebyla poskytnuta: {name}", "RequiredParamsNotProvided": "Chybí požadované parametry: {params}", - "TooDeepTransitionRecursion": "Příliš hluboká rekurze přechodů" + "TooDeepTransitionRecursion": "Příliš hluboká rekurze přechodů", + "ToDoAlreadyCompleted": "Akční položka již byla dokončena" } } diff --git a/plugins/process-assets/lang/de.json b/plugins/process-assets/lang/de.json index 50920b7fdf9..c3ed7445f81 100644 --- a/plugins/process-assets/lang/de.json +++ b/plugins/process-assets/lang/de.json @@ -140,7 +140,8 @@ "LockSection": "Abschnitt sperren", "Approvers": "Genehmiger", "UnlockCard": "Karte entsperren", - "UnlockSection": "Abschnitt entsperren" + "UnlockSection": "Abschnitt entsperren", + "CancelToDo": "Action Item abbrechen" }, "error": { "MethodNotFound": "Methode nicht gefunden: {methodId}", @@ -156,6 +157,7 @@ "EmptyFunctionResult": "Leerer Funktionsresultat {func}", "ContextValueNotProvided": "Kontextwert nicht bereitgestellt: {name}", "RequiredParamsNotProvided": "Erforderliche Parameter nicht bereitgestellt: {params}", - "TooDeepTransitionRecursion": "Zu tiefe Übergangsrekursion" + "TooDeepTransitionRecursion": "Zu tiefe Übergangsrekursion", + "ToDoAlreadyCompleted": "Action Item bereits abgeschlossen" } } diff --git a/plugins/process-assets/lang/en.json b/plugins/process-assets/lang/en.json index 82581c4653f..c2f03509333 100644 --- a/plugins/process-assets/lang/en.json +++ b/plugins/process-assets/lang/en.json @@ -145,7 +145,8 @@ "LockSection": "Lock section", "Approvers": "Approvers", "UnlockCard": "Unlock card", - "UnlockSection": "Unlock section" + "UnlockSection": "Unlock section", + "CancelToDo": "Cancel Action item" }, "error": { "MethodNotFound": "Method not found: {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Empty function result {func}", "ContextValueNotProvided": "Context value not provided: {name}", "RequiredParamsNotProvided": "Required parameters not provided: {params}", - "TooDeepTransitionRecursion": "Too deep transition recursion" + "TooDeepTransitionRecursion": "Too deep transition recursion", + "ToDoAlreadyCompleted": "Action item already completed" } } diff --git a/plugins/process-assets/lang/es.json b/plugins/process-assets/lang/es.json index 26fd532b23d..269b9989c94 100644 --- a/plugins/process-assets/lang/es.json +++ b/plugins/process-assets/lang/es.json @@ -145,7 +145,8 @@ "LockSection": "Bloquear sección", "Approvers": "Aprobadores", "UnlockCard": "Desbloquear tarjeta", - "UnlockSection": "Desbloquear sección" + "UnlockSection": "Desbloquear sección", + "CancelToDo": "Cancelar acción" }, "error": { "MethodNotFound": "Método no encontrado: {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Resultado de función vacío {func}", "ContextValueNotProvided": "Valor de contexto no proporcionado: {name}", "RequiredParamsNotProvided": "Faltan parámetros requeridos: {params}", - "TooDeepTransitionRecursion": "Demasiada recursión de transición" + "TooDeepTransitionRecursion": "Demasiada recursión de transición", + "ToDoAlreadyCompleted": "Acción ya completada" } } diff --git a/plugins/process-assets/lang/fr.json b/plugins/process-assets/lang/fr.json index 05623589c7e..888d8efb655 100644 --- a/plugins/process-assets/lang/fr.json +++ b/plugins/process-assets/lang/fr.json @@ -145,7 +145,8 @@ "LockSection": "Verrouiller la section", "Approvers": "Approbateurs", "UnlockCard": "Déverrouiller la carte", - "UnlockSection": "Déverrouiller la section" + "UnlockSection": "Déverrouiller la section", + "CancelToDo": "Annuler l'action" }, "error": { "MethodNotFound": "Méthode introuvable : {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Résultat de fonction vide {func}", "ContextValueNotProvided": "Valeur de contexte non fournie : {name}", "RequiredParamsNotProvided": "Paramètres requis non fournis : {params}", - "TooDeepTransitionRecursion": "Récursion de transition trop profonde" + "TooDeepTransitionRecursion": "Récursion de transition trop profonde", + "ToDoAlreadyCompleted": "Action déjà terminée" } } diff --git a/plugins/process-assets/lang/it.json b/plugins/process-assets/lang/it.json index 99d2502dd7e..9aea7e4f803 100644 --- a/plugins/process-assets/lang/it.json +++ b/plugins/process-assets/lang/it.json @@ -145,7 +145,8 @@ "LockSection": "Blocca sezione", "Approvers": "Approvatori", "UnlockCard": "Sblocca scheda", - "UnlockSection": "Sblocca sezione" + "UnlockSection": "Sblocca sezione", + "CancelToDo": "Annulla azione" }, "error": { "MethodNotFound": "Metodo non trovato: {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Risultato funzione vuoto {func}", "ContextValueNotProvided": "Valore di contesto non fornito: {name}", "RequiredParamsNotProvided": "Parametri richiesti non forniti: {params}", - "TooDeepTransitionRecursion": "Ricorsione di transizione troppo profonda" + "TooDeepTransitionRecursion": "Ricorsione di transizione troppo profonda", + "ToDoAlreadyCompleted": "Azione già completata" } } diff --git a/plugins/process-assets/lang/ja.json b/plugins/process-assets/lang/ja.json index a16f57573cd..8f8ffd4a8dc 100644 --- a/plugins/process-assets/lang/ja.json +++ b/plugins/process-assets/lang/ja.json @@ -144,7 +144,8 @@ "LockSection": "セクションをロック", "Approvers": "承認者", "UnlockCard": "カードのロックを解除", - "UnlockSection": "セクションのロックを解除" + "UnlockSection": "セクションのロックを解除", + "CancelToDo": "アクションをキャンセル" }, "error": { "MethodNotFound": "メソッドが見つかりません: {methodId}", @@ -160,6 +161,7 @@ "ContextValueNotProvided": "コンテキスト値が提供されていません: {name}", "RequiredParamsNotProvided": "必須パラメータが提供されていません: {params}", "ResultNotProvided": "結果が提供されていません", - "TooDeepTransitionRecursion": "遷移の再帰が深すぎます" + "TooDeepTransitionRecursion": "遷移の再帰が深すぎます", + "ToDoAlreadyCompleted": "アクションは既に完了しています" } } diff --git a/plugins/process-assets/lang/pt-br.json b/plugins/process-assets/lang/pt-br.json index 0d963312d20..67a8c1c9376 100644 --- a/plugins/process-assets/lang/pt-br.json +++ b/plugins/process-assets/lang/pt-br.json @@ -133,7 +133,8 @@ "Reviewers": "Revisores", "FieldIsEmpty": "Campo vazio", "UnlockCard": "Desbloquear cartão", - "UnlockSection": "Desbloquear seção" + "UnlockSection": "Desbloquear seção", + "CancelToDo": "Cancelar ação" }, "error": { "MethodNotFound": "Método não encontrado: {methodId}", @@ -149,6 +150,7 @@ "EmptyFunctionResult": "Resultado da função vazio {func}", "ContextValueNotProvided": "Valor de contexto não fornecido: {name}", "RequiredParamsNotProvided": "Parâmetros obrigatórios não fornecidos: {params}", - "TooDeepTransitionRecursion": "Recursão de transição muito profunda" + "TooDeepTransitionRecursion": "Recursão de transição muito profunda", + "ToDoAlreadyCompleted": "Ação já concluída" } } diff --git a/plugins/process-assets/lang/pt.json b/plugins/process-assets/lang/pt.json index a35b329acfc..483ddbdd1f1 100644 --- a/plugins/process-assets/lang/pt.json +++ b/plugins/process-assets/lang/pt.json @@ -145,7 +145,8 @@ "LockSection": "Bloquear seção", "Approvers": "Aprovadores", "UnlockCard": "Desbloquear cartão", - "UnlockSection": "Desbloquear seção" + "UnlockSection": "Desbloquear seção", + "CancelToDo": "Cancelar ação" }, "error": { "MethodNotFound": "Método não encontrado: {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Resultado da função vazio {func}", "ContextValueNotProvided": "Valor de contexto não fornecido: {name}", "RequiredParamsNotProvided": "Parâmetros obrigatórios não fornecidos: {params}", - "TooDeepTransitionRecursion": "Recursão de transição muito profunda" + "TooDeepTransitionRecursion": "Recursão de transição muito profunda", + "ToDoAlreadyCompleted": "Ação já concluída" } } diff --git a/plugins/process-assets/lang/ru.json b/plugins/process-assets/lang/ru.json index f8343d67ef7..f439c75f6f9 100644 --- a/plugins/process-assets/lang/ru.json +++ b/plugins/process-assets/lang/ru.json @@ -145,7 +145,8 @@ "LockSection": "Заблокировать секцию", "Approvers": "Утверждающие", "UnlockCard": "Разблокировать карточку", - "UnlockSection": "Разблокировать секцию" + "UnlockSection": "Разблокировать секцию", + "CancelToDo": "Отменить задачу" }, "error": { "MethodNotFound": "Метод не найден: {methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "Отсутствуют результат функции {func}", "ContextValueNotProvided": "Значение контекста не предоставлено: {name}", "RequiredParamsNotProvided": "Отсутствуют обязательные параметры: {params}", - "TooDeepTransitionRecursion": "Слишком глубокая рекурсия переходов" + "TooDeepTransitionRecursion": "Слишком глубокая рекурсия переходов", + "ToDoAlreadyCompleted": "Задача уже выполнена" } } diff --git a/plugins/process-assets/lang/tr.json b/plugins/process-assets/lang/tr.json index 23ef6ce9d3f..ce64b07ae39 100644 --- a/plugins/process-assets/lang/tr.json +++ b/plugins/process-assets/lang/tr.json @@ -142,7 +142,8 @@ "LockSection": "Bölümü kilitle", "Approvers": "Onaylayanlar", "UnlockCard": "Kartın kilidini aç", - "UnlockSection": "Bölümün kilidini aç" + "UnlockSection": "Bölümün kilidini aç", + "CancelToDo": "Eylem öğesini iptal et" }, "error": { "MethodNotFound": "Metod bulunamadı: {methodId}", @@ -158,6 +159,7 @@ "EmptyFunctionResult": "Boş fonksiyon sonucu {func}", "ContextValueNotProvided": "Bağlam değeri sağlanmadı: {name}", "RequiredParamsNotProvided": "Gerekli parametreler sağlanmadı: {params}", - "TooDeepTransitionRecursion": "Çok derin geçiş özyinelemesi" + "TooDeepTransitionRecursion": "Çok derin geçiş özyinelemesi", + "ToDoAlreadyCompleted": "Eylem öğesi zaten tamamlandı" } } diff --git a/plugins/process-assets/lang/zh.json b/plugins/process-assets/lang/zh.json index 04fab092524..118be0d39b2 100644 --- a/plugins/process-assets/lang/zh.json +++ b/plugins/process-assets/lang/zh.json @@ -145,7 +145,8 @@ "LockSection": "锁定部分", "Approvers": "批准人", "UnlockCard": "解锁卡片", - "UnlockSection": "解锁部分" + "UnlockSection": "解锁部分", + "CancelToDo": "取消任务" }, "error": { "MethodNotFound": "找不到方法:{methodId}", @@ -161,6 +162,7 @@ "EmptyFunctionResult": "空函数结果 {func}", "ContextValueNotProvided": "未提供上下文值:{name}", "RequiredParamsNotProvided": "未提供必需的参数:{params}", - "TooDeepTransitionRecursion": "转换递归过深" + "TooDeepTransitionRecursion": "转换递归过深", + "ToDoAlreadyCompleted": "任务已完成" } } diff --git a/plugins/process-resources/src/components/settings/CancelToDoEditor.svelte b/plugins/process-resources/src/components/settings/CancelToDoEditor.svelte new file mode 100644 index 00000000000..ae2a0412d8d --- /dev/null +++ b/plugins/process-resources/src/components/settings/CancelToDoEditor.svelte @@ -0,0 +1,45 @@ + + + + +
+
diff --git a/plugins/process-resources/src/components/settings/TimeEditor.svelte b/plugins/process-resources/src/components/settings/TimeEditor.svelte index b0d7ac7180a..d1380b9adf7 100644 --- a/plugins/process-resources/src/components/settings/TimeEditor.svelte +++ b/plugins/process-resources/src/components/settings/TimeEditor.svelte @@ -14,17 +14,17 @@ --> + +
+
+ + diff --git a/plugins/process-resources/src/index.ts b/plugins/process-resources/src/index.ts index f452a1f90f7..1b9578357d5 100644 --- a/plugins/process-resources/src/index.ts +++ b/plugins/process-resources/src/index.ts @@ -24,6 +24,7 @@ import ExecutionMyToDos from './components/ExecutionMyToDos.svelte' import ExecutonPresenter from './components/ExecutonPresenter.svelte' import ExecutonProgressPresenter from './components/ExecutonProgressPresenter.svelte' import Main from './components/Main.svelte' +import CancelToDoEditor from './components/settings/CancelToDoEditor.svelte' import ApproveRequestPresenter from './components/ApproveRequestPresenter.svelte' import SubProcessPresenter from './components/presenters/SubProcessPresenter.svelte' import ToDoPresenter from './components/presenters/ToDoPresenter.svelte' @@ -86,6 +87,7 @@ import ReplaceEditor from './components/transformEditors/ReplaceEditor.svelte' import SplitEditor from './components/transformEditors/SplitEditor.svelte' import NumberPresenter from './components/transformPresenters/NumberPresenter.svelte' import RolePresenter from './components/transformPresenters/RolePresenter.svelte' +import ToDoValuePresenter from './components/settings/ToDoValuePresenter.svelte' import { exportProcess } from './exporter' import { ProcessMiddleware } from './middleware' import { @@ -169,7 +171,9 @@ export default async (): Promise => ({ ApproveRequestTriggerPresenter, LockSectionPresenter, LockSectionEditor, - UnLockSectionPresenter + UnLockSectionPresenter, + CancelToDoEditor, + ToDoValuePresenter }, criteriaEditor: { BaseCriteria, diff --git a/plugins/process-resources/src/plugin.ts b/plugins/process-resources/src/plugin.ts index ce7282f0274..2e0b3429df4 100644 --- a/plugins/process-resources/src/plugin.ts +++ b/plugins/process-resources/src/plugin.ts @@ -87,7 +87,9 @@ export default mergeIds(processId, process, { FunctionSubmenu: '' as AnyComponent, LockSectionEditor: '' as AnyComponent, LockSectionPresenter: '' as AnyComponent, - UnLockSectionPresenter: '' as AnyComponent + UnLockSectionPresenter: '' as AnyComponent, + CancelToDoEditor: '' as AnyComponent, + ToDoValuePresenter: '' as AnyComponent }, criteriaEditor: { BaseCriteria: '' as AnyComponent, @@ -228,6 +230,7 @@ export default mergeIds(processId, process, { CancelProcessPermission: '' as IntlString, ForbidRunProcessPermission: '' as IntlString, ForbidCancelProcessPermission: '' as IntlString, + CancelToDo: '' as IntlString, RequestApproval: '' as IntlString, IsApproved: '' as IntlString, Approve: '' as IntlString, diff --git a/plugins/process/src/index.ts b/plugins/process/src/index.ts index 87b6ca6b529..91fbdf99e7e 100644 --- a/plugins/process/src/index.ts +++ b/plugins/process/src/index.ts @@ -246,6 +246,7 @@ export default plugin(processId, { AddRelation: '' as Ref>, AddTag: '' as Ref>, RequestApproval: '' as Ref>, + CancelToDo: '' as Ref>, LockCard: '' as Ref>, LockSection: '' as Ref>, UnlockCard: '' as Ref>, @@ -304,7 +305,8 @@ export default plugin(processId, { EmptyFunctionResult: '' as IntlString, ContextValueNotProvided: '' as IntlString, RequiredParamsNotProvided: '' as IntlString, - TooDeepTransitionRecursion: '' as IntlString + TooDeepTransitionRecursion: '' as IntlString, + ToDoAlreadyCompleted: '' as IntlString }, icon: { Process: '' as Asset, diff --git a/server-plugins/process-resources/src/functions.ts b/server-plugins/process-resources/src/functions.ts index 0c323641f8f..2bbe6cb70d6 100644 --- a/server-plugins/process-resources/src/functions.ts +++ b/server-plugins/process-resources/src/functions.ts @@ -604,6 +604,33 @@ export async function CreateToDo ( } } +export async function CancelToDo ( + params: MethodParams, + execution: Execution, + control: ProcessControl +): Promise { + if (params._id === undefined) throw processError(process.error.RequiredParamsNotProvided, { params: '_id' }) + const todo = await control.client.findOne(process.class.ProcessToDo, { _id: params._id as any }) + if (todo === undefined) throw processError(process.error.ObjectNotFound, { _id: params._id }) + if (todo.doneOn !== null) throw processError(process.error.ToDoAlreadyCompleted, { _id: params._id }) + const res: Tx[] = [control.client.txFactory.createTxRemoveDoc(todo._class, todo.space, todo._id)] + const rollback: Tx[] = [ + control.client.txFactory.createTxCreateDoc( + todo._class, + todo.space, + { ...todo }, + todo._id, + todo.modifiedOn, + todo.modifiedBy + ) + ] + return { + txes: res, + rollback, + context: null + } +} + async function getContent ( control: ProcessControl, source: string, diff --git a/server-plugins/process-resources/src/index.ts b/server-plugins/process-resources/src/index.ts index f76b84713f8..35c59687785 100644 --- a/server-plugins/process-resources/src/index.ts +++ b/server-plugins/process-resources/src/index.ts @@ -103,6 +103,7 @@ import { RequestApproval, ApproveRequestApproved, ApproveRequestRejected, + CancelToDo, LockCard, LockSection, UnlockCard, @@ -528,6 +529,7 @@ export default async () => ({ RequestApproval, ApproveRequestApproved, ApproveRequestRejected, + CancelToDo, LockCard, LockSection, UnlockCard, diff --git a/server-plugins/process/src/index.ts b/server-plugins/process/src/index.ts index 01ef5e3a21e..cd10f3b7d5c 100644 --- a/server-plugins/process/src/index.ts +++ b/server-plugins/process/src/index.ts @@ -68,7 +68,8 @@ export default plugin(serverProcessId, { CheckTime: '' as Resource, EventCheck: '' as Resource, ApproveRequestApproved: '' as Resource, - ApproveRequestRejected: '' as Resource + ApproveRequestRejected: '' as Resource, + CancelToDo: '' as Resource }, transform: { FirstValue: '' as Resource,