diff --git a/models/server-tracker/src/index.ts b/models/server-tracker/src/index.ts index e41a90d5f6..b50c5b997a 100644 --- a/models/server-tracker/src/index.ts +++ b/models/server-tracker/src/index.ts @@ -66,6 +66,14 @@ export function createModel (builder: Builder): void { } }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverTracker.trigger.OnProjectRemove, + txMatch: { + _class: core.class.TxRemoveDoc, + objectClass: tracker.class.Project + } + }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverTracker.trigger.OnWorkspaceOwnerAdded, txMatch: { diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts index b67924f248..3137774fef 100644 --- a/plugins/tracker-resources/src/index.ts +++ b/plugins/tracker-resources/src/index.ts @@ -14,17 +14,13 @@ // import { Analytics } from '@hcengineering/analytics' -import core, { - type AttachedDoc, +import { type Attribute, type Class, - ClassifierKind, type Client, type Doc, type DocManager, type DocumentQuery, - DOMAIN_CONFIGURATION, - DOMAIN_MODEL, getCurrentAccount, type Ref, type RelatedDocument, @@ -275,52 +271,7 @@ async function deleteProject (project: Project | undefined): Promise { labelProps: { name: project.name }, message: tracker.string.DeleteProjectConfirm, action: async () => { - // void client.update(project, { archived: true }) const client = getClient() - const classes = await client.findAll(core.class.Class, {}) - const h = client.getHierarchy() - for (const c of classes) { - if (c.kind !== ClassifierKind.CLASS) { - continue - } - const d = h.findDomain(c._id) - if (d !== undefined && d !== DOMAIN_MODEL && d !== DOMAIN_CONFIGURATION) { - try { - while (true) { - const docs = await client.findAll(c._id, { space: project._id }, { limit: 50 }) - if (docs.length === 0) { - break - } - const ops = client.apply(undefined, 'delete-project') - for (const object of docs) { - if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) { - const adoc = object as AttachedDoc - await ops - .removeCollection( - object._class, - object.space, - adoc._id, - adoc.attachedTo, - adoc.attachedToClass, - adoc.collection - ) - .catch((err) => { - console.error(err) - }) - } else { - await ops.removeDoc(object._class, object.space, object._id).catch((err) => { - console.error(err) - }) - } - } - await ops.commit() - } - } catch (err: any) { - console.error(err) - Analytics.handleError(err) - } - } - } await client.remove(project) } }) diff --git a/server-plugins/tracker-resources/src/index.ts b/server-plugins/tracker-resources/src/index.ts index 588b4f2e45..3249cb63ba 100644 --- a/server-plugins/tracker-resources/src/index.ts +++ b/server-plugins/tracker-resources/src/index.ts @@ -36,7 +36,7 @@ import { getMetadata, IntlString } from '@hcengineering/platform' import serverCore, { TriggerControl } from '@hcengineering/server-core' import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification' import { stripTags } from '@hcengineering/text-core' -import tracker, { Component, Issue, IssueParentInfo, TimeSpendReport, trackerId } from '@hcengineering/tracker' +import tracker, { Component, Issue, IssueParentInfo, Project, TimeSpendReport, trackerId } from '@hcengineering/tracker' import { workbenchId } from '@hcengineering/workbench' async function updateSubIssues ( @@ -151,6 +151,28 @@ export async function getIssueNotificationContent ( } } +/** + * @public + */ +export async function OnProjectRemove (txes: Tx[], control: TriggerControl): Promise { + const result: Tx[] = [] + for (const tx of txes) { + const ctx = tx as TxRemoveDoc + const classes = [tracker.class.Issue, tracker.class.Component, tracker.class.Milestone, tracker.class.IssueTemplate] + for (const cls of classes) { + const docs = await control.findAll(control.ctx, cls, { space: ctx.objectId }) + for (const doc of docs) { + const tx = control.txFactory.createTxRemoveDoc(cls, doc.space, doc._id) + result.push(tx) + } + } + } + control.ctx.contextData.broadcast.targets.projectRemove = (it) => { + return [] + } + return result +} + /** * @public */ @@ -540,6 +562,7 @@ export default async () => ({ }, trigger: { OnIssueUpdate, + OnProjectRemove, OnComponentRemove, OnWorkspaceOwnerAdded } diff --git a/server-plugins/tracker/src/index.ts b/server-plugins/tracker/src/index.ts index 783b5e7148..35f058f664 100644 --- a/server-plugins/tracker/src/index.ts +++ b/server-plugins/tracker/src/index.ts @@ -37,6 +37,7 @@ export default plugin(serverTrackerId, { trigger: { OnIssueUpdate: '' as Resource, OnComponentRemove: '' as Resource, + OnProjectRemove: '' as Resource, OnWorkspaceOwnerAdded: '' as Resource } }) diff --git a/server/middleware/src/spaceSecurity.ts b/server/middleware/src/spaceSecurity.ts index ffe6e2faa9..9b5f9512f1 100644 --- a/server/middleware/src/spaceSecurity.ts +++ b/server/middleware/src/spaceSecurity.ts @@ -331,7 +331,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar private handleRemove (tx: TxCUD): void { const removeTx = tx as TxRemoveDoc if (!this.context.hierarchy.isDerived(removeTx.objectClass, core.class.Space)) return - if (removeTx._class !== core.class.TxCreateDoc) return + if (removeTx._class !== core.class.TxRemoveDoc) return this.removeSpace(tx.objectId) } diff --git a/services/github/server-github-model/package.json b/services/github/server-github-model/package.json index 6d1078cc19..274f2c96d6 100644 --- a/services/github/server-github-model/package.json +++ b/services/github/server-github-model/package.json @@ -34,6 +34,7 @@ "@hcengineering/server-github": "^0.6.0", "@hcengineering/server-core": "^0.6.1", "@hcengineering/github": "^0.6.0", + "@hcengineering/tracker": "^0.6.24", "@hcengineering/notification": "^0.6.23", "@hcengineering/server-notification": "^0.6.1", "@hcengineering/time": "^0.6.0" diff --git a/services/github/server-github-model/src/index.ts b/services/github/server-github-model/src/index.ts index 843c8a7158..5fb7a0ff3a 100644 --- a/services/github/server-github-model/src/index.ts +++ b/services/github/server-github-model/src/index.ts @@ -8,6 +8,7 @@ import core from '@hcengineering/core' import serverCore from '@hcengineering/server-core' import serverGithub from '@hcengineering/server-github' import time from '@hcengineering/time' +import tracker from '@hcengineering/tracker' export { serverGithubId } from '@hcengineering/server-github' @@ -16,6 +17,15 @@ export function createModel (builder: Builder): void { trigger: serverGithub.trigger.OnProjectChanges, isAsync: true }) + + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverGithub.trigger.OnProjectRemove, + txMatch: { + _class: core.class.TxRemoveDoc, + objectClass: tracker.class.Project + } + }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverGithub.trigger.OnGithubBroadcast, isAsync: false diff --git a/services/github/server-github-resources/src/index.ts b/services/github/server-github-resources/src/index.ts index cee1a2f07a..a97b2c5718 100644 --- a/services/github/server-github-resources/src/index.ts +++ b/services/github/server-github-resources/src/index.ts @@ -98,10 +98,53 @@ export async function OnProjectChanges (txes: Tx[], control: TriggerControl): Pr return result } +/** + * @public + */ +export async function OnProjectRemove (txes: Tx[], control: TriggerControl): Promise { + const result: Tx[] = [] + for (const ltx of txes) { + if (ltx._class === core.class.TxRemoveDoc) { + const cud = ltx as TxCUD + if (control.hierarchy.isDerived(cud.objectClass, tracker.class.Project)) { + const project = control.removedMap.get(cud.objectId) + if (project === undefined) { + continue + } + if (control.hierarchy.hasMixin(project, github.mixin.GithubProject)) { + const repos = await control.findAll(control.ctx, github.class.GithubIntegrationRepository, { + githubProject: cud.objectId as Ref + }) + for (const repo of repos) { + result.push( + control.txFactory.createTxUpdateDoc(repo._class, repo.space, repo._id, { + enabled: false, + githubProject: null + }) + ) + } + + const syncDocs = control.modelDb.findAllSync(github.class.DocSyncInfo, { + space: cud.objectId as Ref + }) + for (const syncDoc of syncDocs) { + result.push(control.txFactory.createTxRemoveDoc(syncDoc._class, syncDoc.space, syncDoc._id)) + } + } + } + } + } + if (result.length > 0) { + await OnGithubBroadcast(txes, control) + } + return result +} + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export default async () => ({ trigger: { OnProjectChanges, + OnProjectRemove, OnGithubBroadcast }, functions: { diff --git a/services/github/server-github/src/index.ts b/services/github/server-github/src/index.ts index 95fc808418..be59986313 100644 --- a/services/github/server-github/src/index.ts +++ b/services/github/server-github/src/index.ts @@ -21,6 +21,7 @@ export const serverGithubId = 'server-github' as Plugin export default plugin(serverGithubId, { trigger: { OnProjectChanges: '' as Resource, + OnProjectRemove: '' as Resource, OnGithubBroadcast: '' as Resource }, functions: {