diff --git a/models/task/src/migration.ts b/models/task/src/migration.ts index 81fd89df43..e5054d330b 100644 --- a/models/task/src/migration.ts +++ b/models/task/src/migration.ts @@ -23,9 +23,11 @@ import { Ref, Space, Status, + Tx, TxCollectionCUD, TxCreateDoc, TxOperations, + TxProcessor, TxUpdateDoc, toIdMap } from '@hcengineering/core' @@ -357,7 +359,7 @@ async function migrateStatuses (client: MigrationClient): Promise { const filters = JSON.parse(filter.filters) as Filter[] let changed = false for (const filter of filters) { - if (['status, doneStatus'].includes(filter.key.key)) { + if (['status', 'doneStatus'].includes(filter.key.key)) { for (let index = 0; index < filter.value.length; index++) { const val = filter.value[index] const newVal = oldStatusesMap.get(val) @@ -381,10 +383,60 @@ async function migrateStatuses (client: MigrationClient): Promise { await client.update(DOMAIN_STATUS, { space: { $ne: task.space.Statuses } }, { space: task.space.Statuses }) } +async function fixFilters (client: MigrationClient): Promise { + const currentStatuses = await client.find(DOMAIN_STATUS, {}) + const currentStatusesMap = toIdMap(currentStatuses) + const cacheMap = new Map, Ref>() + const descendants = client.hierarchy.getDescendants(task.class.Task) + const filters = await client.find(DOMAIN_VIEW, { + _class: view.class.FilteredView, + filterClass: { $in: descendants } + }) + for (const filter of filters) { + const filters = JSON.parse(filter.filters) as Filter[] + let changed = false + for (const filter of filters) { + if (['status', 'doneStatus'].includes(filter.key.key)) { + for (let index = 0; index < filter.value.length; index++) { + const val = filter.value[index] + if (!currentStatusesMap.has(val)) { + const newVal = cacheMap.get(val) + if (newVal !== undefined) { + filter.value[index] = newVal + changed = true + } else { + const ownTxes = await client.find(DOMAIN_TX, { objectId: val }) + const attachedTxes = await client.find(DOMAIN_TX, { 'tx.objectId': val }) + const txes = [...ownTxes, ...attachedTxes].sort((a, b) => a.modifiedOn - b.modifiedOn) + const oldStatus = TxProcessor.buildDoc2Doc(txes) + if (oldStatus !== undefined) { + const newStatus = currentStatuses.find( + (p) => + p.ofAttribute === oldStatus.ofAttribute && + p.name.toLowerCase().trim() === oldStatus.name.toLowerCase().trim() + ) + if (newStatus !== undefined) { + filter.value[index] = newStatus._id + cacheMap.set(val, newStatus._id) + changed = true + } + } + } + } + } + } + } + if (changed) { + await client.update(DOMAIN_VIEW, { _id: filter._id }, { filters: JSON.stringify(filters) }) + } + } +} + export const taskOperation: MigrateOperation = { async migrate (client: MigrationClient): Promise { await renameState(client) await migrateStatuses(client) + await fixFilters(client) }, async upgrade (client: MigrationUpgradeClient): Promise { const tx = new TxOperations(client, core.account.System) diff --git a/plugins/tracker-resources/src/components/issues/StatusFilterValuePresenter.svelte b/plugins/tracker-resources/src/components/issues/StatusFilterValuePresenter.svelte index 99acb81f33..9c139ccbed 100644 --- a/plugins/tracker-resources/src/components/issues/StatusFilterValuePresenter.svelte +++ b/plugins/tracker-resources/src/components/issues/StatusFilterValuePresenter.svelte @@ -16,7 +16,7 @@ import { IssueStatus, Project } from '@hcengineering/tracker' import IssueStatusIcon from './IssueStatusIcon.svelte' import { createQuery } from '@hcengineering/presentation' - import core, { IdMap, Ref, StatusCategory, toIdMap } from '@hcengineering/core' + import core, { IdMap, Ref, Status, StatusCategory, toIdMap } from '@hcengineering/core' import { statusStore } from '@hcengineering/view-resources' export let value: Ref[] @@ -30,8 +30,15 @@ categories = toIdMap(res) }) - function sort (value: IssueStatus[], categories: IdMap): IssueStatus[] { - return value.sort((a, b) => { + function sort (value: Ref[], store: IdMap, categories: IdMap): IssueStatus[] { + const result: IssueStatus[] = [] + for (const val of new Set(value)) { + const res = store.get(val) + if (res) { + result.push(res) + } + } + return result.sort((a, b) => { if (a.category === undefined) return -1 if (b.category === undefined) return 1 const aCat = categories.get(a.category) @@ -42,7 +49,7 @@ }) } - $: statuses = sort(value.map((p) => $statusStore.get(p)) as IssueStatus[], categories) + $: statuses = sort(value, $statusStore, categories)
diff --git a/plugins/view-resources/src/status.ts b/plugins/view-resources/src/status.ts index 592152bd6b..1a2774dc8a 100644 --- a/plugins/view-resources/src/status.ts +++ b/plugins/view-resources/src/status.ts @@ -18,7 +18,7 @@ import { createQuery, getClient } from '@hcengineering/presentation' import { writable } from 'svelte/store' // Issue status live query -export const statusStore = writable>() +export const statusStore = writable>(new Map()) function fillStores (): void { const client = getClient()