diff --git a/models/task/src/index.ts b/models/task/src/index.ts index 8a0bd4474a..846b1b6341 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -638,7 +638,8 @@ export interface FixTaskResult { export async function fixTaskTypes ( client: MigrationClient, descriptor: Ref, - dataFactory: (t: ProjectType) => Promise + dataFactory: (t: ProjectType) => Promise, + migrateTasks?: (projects: Project[], taskType: TaskType) => Promise ): Promise { const categoryObj = client.model.findObject(descriptor) if (categoryObj === undefined) { @@ -655,10 +656,6 @@ export async function fixTaskTypes ( const resultProjects: Project[] = [] for (const t of projectTypes) { - if (t.tasks?.length > 0) { - // Already migrated. - continue - } t.tasks = [...(t.tasks ?? [])] if (t.targetClass === undefined) { const targetProjectClassId: Ref> = generateId() @@ -704,12 +701,22 @@ export async function fixTaskTypes ( ) } - const dataTypes = await dataFactory(t) + const newTaskTypes = await dataFactory(t) const projects = await client.find(DOMAIN_SPACE, { type: t._id }) resultProjects.push(...projects) - for (const data of dataTypes) { + for (const data of newTaskTypes) { + // Check and skip if already had task type for same class + const tt = await client.find(DOMAIN_TASK, { + _class: task.class.TaskType, + ofClass: data.ofClass, + parent: t._id + }) + if (tt.length > 0) { + continue + } + const taskTypeId: Ref = data._id ?? generateId() const descr = client.model.getObject(data.descriptor) @@ -718,16 +725,16 @@ export async function fixTaskTypes ( _class: data.statusClass }) - const dStatuses = [...t.statuses.map((it) => it._id)] + const dStatuses: Ref[] = [] const statusAttr = findStatusAttr(client.hierarchy, data.ofClass) // Ensure we have at leas't one item in every category. for (const c of data.statusCategories) { const category = typeof c === 'string' ? c : c.category const cat = await client.model.findOne(core.class.StatusCategory, { _id: category }) - const st = statuses.find((it) => it.category === category) + const st = statuses.filter((it) => it.category === category) const newStatuses: Ref[] = [] - if (st === undefined) { + if (st.length === 0 || typeof c === 'object') { if (typeof c === 'string') { // We need to add new status into missing category const statusId: Ref = generateId() @@ -773,6 +780,8 @@ export async function fixTaskTypes ( }) newStatuses.push(statusId) dStatuses.push(statusId) + } else { + dStatuses.push(st._id) } await client.update( @@ -785,6 +794,12 @@ export async function fixTaskTypes ( t.statuses.push(...newStatuses.map((it) => ({ _id: it, taskType: taskTypeId }))) } } + } else { + for (const sss of st.map((it) => it._id)) { + if (!dStatuses.includes(sss)) { + dStatuses.push(sss) + } + } } } const taskType: TaskType = { @@ -854,11 +869,13 @@ export async function fixTaskTypes ( ) t.tasks.push(taskTypeId) // Update kind and target classId + const projectsToUpdate = projects.filter((it) => it.type === t._id) await client.update( DOMAIN_TASK, - { space: { $in: projects.map((it) => it._id) }, _class: data.ofClass }, + { space: { $in: projectsToUpdate.map((it) => it._id) }, _class: data.ofClass }, { $set: { kind: taskTypeId } } ) + await migrateTasks?.(projectsToUpdate, taskType) } // We need to fix project statuses field, for proper icon calculation. diff --git a/models/tracker/src/migration.ts b/models/tracker/src/migration.ts index 2f809244f7..9c118ff59c 100644 --- a/models/tracker/src/migration.ts +++ b/models/tracker/src/migration.ts @@ -248,7 +248,7 @@ async function restoreToDoCategory (client: MigrationClient): Promise { const taskTypes = await client.find(DOMAIN_TASK, { _class: task.class.TaskType, descriptor: tracker.descriptors.Issue, - _id: { $in: p.tasks } + _id: { $in: p.tasks ?? [] } }) for (const taskType of taskTypes) { if (taskType.statusCategories.includes(task.statusCategory.ToDo)) continue