Cards migration (#8164)

This commit is contained in:
Denis Bykhov 2025-03-07 10:24:33 +05:00 committed by GitHub
parent 6636e0acfa
commit 655c46ef9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 110 additions and 9 deletions

View File

@ -54,11 +54,13 @@ import { analyticsCollectorOperation } from '@hcengineering/model-analytics-coll
import { workbenchOperation } from '@hcengineering/model-workbench'
import { testManagementOperation } from '@hcengineering/model-test-management'
import { surveyOperation } from '@hcengineering/model-survey'
import { cardOperation } from '@hcengineering/model-card'
import { aiBotId, aiBotOperation } from '@hcengineering/model-ai-bot'
export const migrateOperations: [string, MigrateOperation][] = [
['core', coreOperation],
['activity', activityOperation],
['card', cardOperation],
['chunter', chunterOperation],
['calendar', calendarOperation],
['gmail', gmailOperation],

View File

@ -99,6 +99,8 @@ export class MasterTagEditorSection extends TDoc implements MasterTagEditorSecti
component!: AnyComponent
}
export * from './migration'
export function createModel (builder: Builder): void {
builder.createModel(TMasterTag, TTag, TCard, MasterTagEditorSection)

View File

@ -0,0 +1,95 @@
//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { DOMAIN_CARD } from '@hcengineering/card'
import { chunterId } from '@hcengineering/chunter'
import core, { type Client, type Data, type Doc, TxOperations } from '@hcengineering/core'
import {
tryMigrate,
tryUpgrade,
type MigrateOperation,
type MigrationClient,
type MigrationUpgradeClient
} from '@hcengineering/model'
import view from '@hcengineering/view'
import card from '.'
export const cardOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
await tryMigrate(client, chunterId, [
{
state: 'set-parent-info',
func: setParentInfo
}
])
},
async upgrade (state: Map<string, Set<string>>, client: () => Promise<MigrationUpgradeClient>): Promise<void> {
await tryUpgrade(state, client, chunterId, [
{
state: 'migrateViewlets',
func: migrateViewlets
}
])
}
}
async function setParentInfo (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_CARD,
{
parentInfo: { $exists: false }
},
{
parentInfo: []
}
)
}
function extractObjectProps<T extends Doc> (doc: T): Data<T> {
const data: any = {}
for (const key in doc) {
if (key === '_id') {
continue
}
data[key] = doc[key]
}
return data as Data<T>
}
async function migrateViewlets (client: Client): Promise<void> {
const txOp = new TxOperations(client, core.account.System)
const viewlets = await client.findAll(view.class.Viewlet, { attachTo: card.class.Card })
const masterTags = await client.findAll(card.class.MasterTag, {})
const currentViewlets = await client.findAll(view.class.Viewlet, { attachTo: { $in: masterTags.map((p) => p._id) } })
for (const masterTag of masterTags) {
for (const viewlet of viewlets) {
const base = extractObjectProps(viewlet)
const current = currentViewlets.find(
(p) => p.attachTo === masterTag._id && p.variant === viewlet.variant && p.descriptor === viewlet.descriptor
)
if (current === undefined) {
await txOp.createDoc(view.class.Viewlet, core.space.Model, {
...base,
attachTo: masterTag._id
})
} else {
await txOp.diffUpdate(current, {
...base,
attachTo: masterTag._id
})
}
}
}
}

View File

@ -162,6 +162,7 @@ async function OnMasterTagCreate (ctx: TxCreateDoc<MasterTag | Tag>[], control:
res.push(
control.txFactory.createTxMixin(createTx.objectId, core.class.Mixin, core.space.Model, setting.mixin.UserMixin, {})
)
if (tag._class === card.class.MasterTag) {
const viewlets = await control.findAll(control.ctx, view.class.Viewlet, { attachTo: tag.extends })
for (const viewlet of viewlets) {
const base = extractObjectProps(viewlet)
@ -172,6 +173,7 @@ async function OnMasterTagCreate (ctx: TxCreateDoc<MasterTag | Tag>[], control:
})
)
}
}
return res
}