Process fixes (#10541)

* Process fixes

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

* Some fixes

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>

---------

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2026-02-22 19:19:54 +07:00
committed by GitHub
parent f651c561b5
commit d51b68683a
19 changed files with 126 additions and 28 deletions
+20
View File
@@ -459,6 +459,26 @@ export function createModel (builder: Builder): void {
card.ids.CardNotificationGroup
)
builder.createDoc(
notification.class.NotificationType,
core.space.Model,
{
hidden: false,
generated: false,
label: card.string.CardCreated,
group: card.ids.CardNotificationGroup,
txClasses: [core.class.TxCreateDoc],
objectClass: card.class.Card,
defaultEnabled: true,
templates: {
textTemplate: '{body}',
htmlTemplate: '<p>{body}</p><p>{link}</p>',
subjectTemplate: '{title} created'
}
},
card.ids.CardCreateNotification
)
builder.createDoc(
notification.class.NotificationType,
core.space.Model,
+1
View File
@@ -55,6 +55,7 @@ export default mergeIds(cardId, card, {
ManageMasterTags: '' as Ref<Doc>,
TagRelations: '' as Ref<Doc>,
CardNotificationGroup: '' as Ref<NotificationGroup>,
CardCreateNotification: '' as Ref<NotificationType>,
CardNotification: '' as Ref<NotificationType>,
CardMessageNotification: '' as Ref<NotificationType>
},
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Které vztahy chcete zkopírovat?",
"Import": "Importovat",
"Export": "Exportovat",
"CardUpdated": "Karta aktualizována"
"CardUpdated": "Karta aktualizována",
"CardCreated": "Karta vytvořena"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Welche Beziehungen möchten Sie kopieren?",
"Import": "Importieren",
"Export": "Exportieren",
"CardUpdated": "Karte aktualisiert"
"CardUpdated": "Karte aktualisiert",
"CardCreated": "Karte erstellt"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Which relations do you want to copy?",
"Import": "Import",
"Export": "Export",
"CardUpdated": "Card updated"
"CardUpdated": "Card updated",
"CardCreated": "Card created"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "¿Qué relaciones quieres copiar?",
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Tarjeta actualizada"
"CardUpdated": "Tarjeta actualizada",
"CardCreated": "Tarjeta creada"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Quelles relations souhaitez-vous copier ?",
"Import": "Importer",
"Export": "Exporter",
"CardUpdated": "Carte mise à jour"
"CardUpdated": "Carte mise à jour",
"CardCreated": "Carte créée"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Quali relazioni vuoi copiare?",
"Import": "Importa",
"Export": "Esporta",
"CardUpdated": "Scheda aggiornata"
"CardUpdated": "Scheda aggiornata",
"CardCreated": "Scheda creata"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "どの関連をコピーしますか?",
"Import": "インポート",
"Export": "エクスポート",
"CardUpdated": "カードが更新されました"
"CardUpdated": "カードが更新されました",
"CardCreated": "カードが作成されました"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Quais relações você deseja copiar?",
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Cartão atualizado"
"CardUpdated": "Cartão atualizado",
"CardCreated": "Cartão criado"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Quais relações você deseja copiar?",
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Cartão atualizado"
"CardUpdated": "Cartão atualizado",
"CardCreated": "Cartão criado"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Какие связи вы хотите скопировать?",
"Import": "Импортировать",
"Export": "Экспортировать",
"CardUpdated": "Карточка обновлена"
"CardUpdated": "Карточка обновлена",
"CardCreated": "Карточка создана"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "Hangi ilişkileri kopyalamak istiyorsunuz?",
"Import": "İçe aktar",
"Export": "Dışa aktar",
"CardUpdated": "Kart güncellendi"
"CardUpdated": "Kart güncellendi",
"CardCreated": "Kart oluşturuldu"
}
}
+2 -1
View File
@@ -71,6 +71,7 @@
"RelationCopyDescr": "您想复制哪些关系?",
"Import": "导入",
"Export": "导出",
"CardUpdated": "卡片已更新"
"CardUpdated": "卡片已更新",
"CardCreated": "卡片已创建"
}
}
+2 -1
View File
@@ -160,6 +160,7 @@ export default mergeIds(cardId, card, {
ForbidCreateCardPermission: '' as IntlString,
ForbidAddTagPermission: '' as IntlString,
ForbidRemoveTag: '' as IntlString,
CardUpdated: '' as IntlString
CardUpdated: '' as IntlString,
CardCreated: '' as IntlString
}
})
@@ -60,9 +60,7 @@
$: selected = _id !== undefined ? items.find((it) => it.id === _id)?.id : undefined
$: processes = client
.getModel()
.findAllSync(plugin.class.Process, { masterTag: { $in: ancestors }, _id: { $ne: process._id } })
$: processes = client.getModel().findAllSync(plugin.class.Process, { masterTag: { $in: ancestors } })
function changeThis (): void {
step.params = {}
@@ -20,6 +20,7 @@ import core, {
Class,
Data,
Doc,
fillDefaults,
findProperty,
generateId,
getObjectValue,
@@ -110,6 +111,7 @@ export async function CheckSubProcessMatch (
const subExecutions = await control.client.findAll(process.class.Execution, {
parentId: execution._id,
status: { $ne: ExecutionStatus.Cancelled },
process: targetProcess
})
@@ -315,19 +317,31 @@ export async function AddTag (
const res: Tx[] = []
const _process = control.client.getModel().findObject(execution.process)
if (_process === undefined) throw processError(process.error.ObjectNotFound, { _id: execution.process })
// todo fill default for tag and set parent tags
const tx = control.client.txFactory.createTxMixin(execution.card, _process.masterTag, execution.space, tagId, props)
res.push(tx)
const card = control.cache.get(execution.card)
const cardWithMixin =
card !== undefined ? TxProcessor.updateMixin4Doc(control.client.getHierarchy().clone(card), tx) : undefined
const rollback = control.client.txFactory.createTxUpdateDoc(_process.masterTag, execution.space, execution.card, {
$unset: { [tagId]: true }
})
const rollback: Tx[] = [
control.client.txFactory.createTxUpdateDoc(_process.masterTag, execution.space, execution.card, {
$unset: { [tagId]: true }
})
]
const processes = control.client
.getModel()
.findAllSync(process.class.Process, { masterTag: _process.masterTag, autoStart: true })
for (const proc of processes) {
const [txes, rbTxes] = await createExecution(proc._id, execution.card, execution, control)
res.push(...txes)
rollback.push(...rbTxes)
}
return {
txes: res,
rollback: [rollback],
rollback,
context: [
{
_id: execution.card,
@@ -704,11 +718,10 @@ export async function CreateCard (
throw processError(process.error.RequiredParamsNotProvided, { params: key })
}
}
const masterTag = _class as Ref<MasterTag>
const _id = generateId<Card>()
const newContent =
content !== undefined && !isEmpty(content)
? await getContent(control, content, _id, _class as Ref<Class<Card>>)
: content
content !== undefined && !isEmpty(content) ? await getContent(control, content, _id, masterTag) : content
const data = {
title,
...attrs
@@ -716,9 +729,26 @@ export async function CreateCard (
if (newContent !== undefined) {
data.content = content
}
const tx = control.client.txFactory.createTxCreateDoc(_class as Ref<MasterTag>, execution.space, data, _id)
const filledData = fillDefaults(control.client.getHierarchy(), data, masterTag)
const tx = control.client.txFactory.createTxCreateDoc(masterTag, execution.space, filledData, _id)
const res: Tx[] = [tx]
const rollback: Tx[] = [control.client.txFactory.createTxRemoveDoc(_class as Ref<MasterTag>, execution.space, _id)]
const rollback: Tx[] = [control.client.txFactory.createTxRemoveDoc(masterTag, execution.space, _id)]
const ancestors = control.client
.getHierarchy()
.getAncestors(masterTag)
.filter((p) => control.client.getHierarchy().isDerived(p, cardPlugin.class.Card))
const processes = control.client.getModel().findAllSync(process.class.Process, {
masterTag: { $in: ancestors },
autoStart: true
})
for (const proc of processes) {
const [txes, rbTxes] = await createExecution(proc._id, _id, execution, control)
res.push(...txes)
rollback.push(...rbTxes)
}
return {
txes: res,
rollback,
@@ -734,3 +764,36 @@ export async function CreateCard (
function isEmpty (value: any): boolean {
return value === undefined || value === null || (typeof value === 'string' && value.trim() === '')
}
async function createExecution (
proc: Ref<Process>,
_id: Ref<Card>,
execution: Execution,
control: ProcessControl
): Promise<[Tx[], Tx[]]> {
const res: Tx[] = []
const rollback: Tx[] = []
const initTransition = control.client.getModel().findAllSync(process.class.Transition, {
process: proc,
from: null
})[0]
if (initTransition === undefined) return [res, rollback]
const execId = generateId()
const tx = control.client.txFactory.createTxCreateDoc(
process.class.Execution,
execution.space,
{
process: proc,
currentState: initTransition.to,
card: _id,
rollback: [],
context: {},
status: ExecutionStatus.Active
},
execId
)
res.push(tx)
rollback.push(control.client.txFactory.createTxRemoveDoc(process.class.Execution, execution.space, execId))
return [res, rollback]
}
@@ -39,7 +39,7 @@ export function Random (value: Doc[]): Doc {
}
export function All (value: Doc[]): Doc[] {
return value
return value ?? []
}
export async function FirstMatchValue (
@@ -178,11 +178,14 @@ async function getRelationValue (
const q = context.direction === 'A' ? { docB: execution.card } : { docA: execution.card }
const relations = await control.client.findAll(core.class.Relation, { association: assoc._id, ...q })
const name = context.direction === 'A' ? assoc.nameA : assoc.nameB
if (relations.length === 0) throw processError(process.error.RelatedObjectNotFound, { attr: name })
const shouldBeArray = assoc.type === 'N:N' || (assoc.type === '1:N' && context.direction === 'A')
if (relations.length === 0) {
if (shouldBeArray) return []
throw processError(process.error.RelatedObjectNotFound, { attr: name })
}
const ids = relations.map((it) => {
return context.direction === 'A' ? it.docA : it.docB
})
const shouldBeArray = assoc.type === 'N:N' || (assoc.type === '1:N' && context.direction === 'A')
const target = await control.client.findAll(targetClass, { _id: { $in: ids } })
if (target.length === 0) throw processError(process.error.RelatedObjectNotFound, { attr: context.name })
const attr = context.key !== '' ? control.client.getHierarchy().findAttribute(targetClass, context.key) : undefined