mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 12:35:02 +02:00
Server remove cascade (#1189)
Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Generated
+72
-4
@@ -74,6 +74,7 @@ specifiers:
|
||||
'@rush-temp/model-server-notification': file:./projects/model-server-notification.tgz
|
||||
'@rush-temp/model-server-recruit': file:./projects/model-server-recruit.tgz
|
||||
'@rush-temp/model-server-setting': file:./projects/model-server-setting.tgz
|
||||
'@rush-temp/model-server-tags': file:./projects/model-server-tags.tgz
|
||||
'@rush-temp/model-server-task': file:./projects/model-server-task.tgz
|
||||
'@rush-temp/model-setting': file:./projects/model-setting.tgz
|
||||
'@rush-temp/model-tags': file:./projects/model-tags.tgz
|
||||
@@ -116,6 +117,8 @@ specifiers:
|
||||
'@rush-temp/server-recruit-resources': file:./projects/server-recruit-resources.tgz
|
||||
'@rush-temp/server-setting': file:./projects/server-setting.tgz
|
||||
'@rush-temp/server-setting-resources': file:./projects/server-setting-resources.tgz
|
||||
'@rush-temp/server-tags': file:./projects/server-tags.tgz
|
||||
'@rush-temp/server-tags-resources': file:./projects/server-tags-resources.tgz
|
||||
'@rush-temp/server-task': file:./projects/server-task.tgz
|
||||
'@rush-temp/server-task-resources': file:./projects/server-task-resources.tgz
|
||||
'@rush-temp/server-token': file:./projects/server-token.tgz
|
||||
@@ -321,6 +324,7 @@ dependencies:
|
||||
'@rush-temp/model-server-notification': file:projects/model-server-notification.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-server-recruit': file:projects/model-server-recruit.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-server-setting': file:projects/model-server-setting.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-server-tags': file:projects/model-server-tags.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-server-task': file:projects/model-server-task.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-setting': file:projects/model-setting.tgz_typescript@4.5.4
|
||||
'@rush-temp/model-tags': file:projects/model-tags.tgz_typescript@4.5.4
|
||||
@@ -363,6 +367,8 @@ dependencies:
|
||||
'@rush-temp/server-recruit-resources': file:projects/server-recruit-resources.tgz
|
||||
'@rush-temp/server-setting': file:projects/server-setting.tgz
|
||||
'@rush-temp/server-setting-resources': file:projects/server-setting-resources.tgz
|
||||
'@rush-temp/server-tags': file:projects/server-tags.tgz
|
||||
'@rush-temp/server-tags-resources': file:projects/server-tags-resources.tgz
|
||||
'@rush-temp/server-task': file:projects/server-task.tgz
|
||||
'@rush-temp/server-task-resources': file:projects/server-task-resources.tgz
|
||||
'@rush-temp/server-token': file:projects/server-token.tgz
|
||||
@@ -12416,7 +12422,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/model-all.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-LprNHSPgySvlj/zl9bkeSZ7Uh1wWyPPkQBW6knjBBD3cizpFpxPGBrSQnhDe/RP0uj6azKRYWWUcAPFOYe4TvQ==, tarball: file:projects/model-all.tgz}
|
||||
resolution: {integrity: sha512-CTYZ52iBQ2S06DVd6jUK+PHCpgLDvO7lrujkMWxCO3RUn+77uyDZBGK43n+7UF1HZNSHvYAhyA8fBTvp1kOylw==, tarball: file:projects/model-all.tgz}
|
||||
id: file:projects/model-all.tgz
|
||||
name: '@rush-temp/model-all'
|
||||
version: 0.0.0
|
||||
@@ -12901,6 +12907,27 @@ packages:
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
file:projects/model-server-tags.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-TYTWiR2rFc1OE3D4m0DpKSridJKWeLfJmpK0SB0+6ibWEFUu+f9Yhs5N7j3/w1UMGKbSZ5Ere6PYVMTP3fTT5g==, tarball: file:projects/model-server-tags.tgz}
|
||||
id: file:projects/model-server-tags.tgz
|
||||
name: '@rush-temp/model-server-tags'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@rushstack/heft': 0.41.8
|
||||
'@types/heft-jest': 1.0.2
|
||||
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||
eslint: 7.32.0
|
||||
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||
prettier: 2.5.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: false
|
||||
|
||||
file:projects/model-server-task.tgz_typescript@4.5.4:
|
||||
resolution: {integrity: sha512-U7EJ1CuyupONpf97J8SfeRZT07aBNFQ3R1Wlyv7ssR6V8W4pkfjazFsfFA//pWh8ot5oWUy+8wccF7Q8TjkJWQ==, tarball: file:projects/model-server-task.tgz}
|
||||
id: file:projects/model-server-task.tgz
|
||||
@@ -13367,7 +13394,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/prod.tgz_a07ec81d4d975778878ca12202ea119e:
|
||||
resolution: {integrity: sha512-mxkGGtPp108JHMkmnEgKKPNVrihu3xVv1wZqY/HTWhZ+v8Ct5RG92+Yg6NBhEsLmqCBBPTAHY/JapGi1oF9bWg==, tarball: file:projects/prod.tgz}
|
||||
resolution: {integrity: sha512-HHCNzvjIf/tNB1Wr5Fk4HGuoP66fHONafJd6DPh4kpTC7T8Vc5Y/UlneWS3cUjhCsB9jgYejEbu1Osp0DPXCZA==, tarball: file:projects/prod.tgz}
|
||||
id: file:projects/prod.tgz
|
||||
name: '@rush-temp/prod'
|
||||
version: 0.0.0
|
||||
@@ -13897,6 +13924,47 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
file:projects/server-tags-resources.tgz:
|
||||
resolution: {integrity: sha512-XrVBmPPIJCLM2reTQorx5k+xtwc6pJApXeVSksk+DeP2+lVHQBIcJwRLUHkRNBVn7kU571mw6F6J6JvCSkYhJQ==, tarball: file:projects/server-tags-resources.tgz}
|
||||
name: '@rush-temp/server-tags-resources'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@rushstack/heft': 0.41.8
|
||||
'@types/heft-jest': 1.0.2
|
||||
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||
eslint: 7.32.0
|
||||
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||
prettier: 2.5.1
|
||||
typescript: 4.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
file:projects/server-tags.tgz:
|
||||
resolution: {integrity: sha512-iDt1UvOkk+mT3l2/R0MFjgNHnGnZztfW5nuD39yeMoTIihWIfxOTO4PBCnu3dNtRL+2xIlU4pADEdyDp9AS3lg==, tarball: file:projects/server-tags.tgz}
|
||||
name: '@rush-temp/server-tags'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@rushstack/heft': 0.41.8
|
||||
'@types/heft-jest': 1.0.2
|
||||
'@types/node': 16.11.14
|
||||
'@typescript-eslint/eslint-plugin': 5.7.0_c25e8c1f4f4f7aaed27aa6f9ce042237
|
||||
'@typescript-eslint/parser': 5.7.0_eslint@7.32.0+typescript@4.5.4
|
||||
eslint: 7.32.0
|
||||
eslint-config-standard-with-typescript: 21.0.1_ce2fa0c4dfa1c256100cababd749a13a
|
||||
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||
eslint-plugin-promise: 5.2.0_eslint@7.32.0
|
||||
prettier: 2.5.1
|
||||
typescript: 4.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
file:projects/server-task-resources.tgz:
|
||||
resolution: {integrity: sha512-OHpVWSAp1YyQ1LqJoXGRzqA8yY1BXZ5xI/P+fLUi5nk3Pz4a82H+YGw/FsNBuPWG4U25Hnnwopzl0trIXIB9jQ==, tarball: file:projects/server-task-resources.tgz}
|
||||
name: '@rush-temp/server-task-resources'
|
||||
@@ -14017,7 +14085,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/server.tgz:
|
||||
resolution: {integrity: sha512-1nC7oRGVjZGZ8I5tviFWIAu6++qbQ6k450Fe0fhi45pxMPuclCotH+NSS789RRpj2AhtiaghrpBZdc3CtgZOUw==, tarball: file:projects/server.tgz}
|
||||
resolution: {integrity: sha512-Gx/PoIoObAiRX21Fo+Z/y7tqqgHW8URVudDz8azH/0hW25pRfR03xPw7oR0GsuF2IBZ4S8nyH1U2HSPpE76W7g==, tarball: file:projects/server.tgz}
|
||||
name: '@rush-temp/server'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
@@ -14536,7 +14604,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/tool.tgz:
|
||||
resolution: {integrity: sha512-HzyyP6uYXNTmHkn7FiZJ3vf6Oq7KzAGYWsul1AT8B54rJqZ4mTZtBhnRGdVBqEmNIUNO2Ukr5ywdvAhJfDj+Mg==, tarball: file:projects/tool.tgz}
|
||||
resolution: {integrity: sha512-F3Px6/29RVwqI/G3FsImf5dKvi53Tz7R/LSRyeG81NIN0WMGEsuOB6iWE9GD8PS/W7qSnKsFC8+VWVvJN+gVeQ==, tarball: file:projects/tool.tgz}
|
||||
name: '@rush-temp/tool'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
|
||||
@@ -118,6 +118,8 @@
|
||||
"@anticrm/server-lead-resources": "~0.6.0",
|
||||
"@anticrm/server-recruit": "~0.6.0",
|
||||
"@anticrm/server-recruit-resources": "~0.6.0",
|
||||
"@anticrm/server-tags": "~0.6.0",
|
||||
"@anticrm/server-tags-resources": "~0.6.0",
|
||||
"@anticrm/server-task": "~0.6.0",
|
||||
"@anticrm/server-task-resources": "~0.6.0",
|
||||
"@anticrm/calendar": "~0.6.0",
|
||||
|
||||
@@ -26,6 +26,7 @@ import { serverInventoryId } from '@anticrm/server-inventory'
|
||||
import { serverLeadId } from '@anticrm/server-lead'
|
||||
import { serverRecruitId } from '@anticrm/server-recruit'
|
||||
import { serverTaskId } from '@anticrm/server-task'
|
||||
import { serverTagsId } from '@anticrm/server-tags'
|
||||
|
||||
import { setMetadata } from '@anticrm/platform'
|
||||
|
||||
@@ -47,6 +48,7 @@ export function configurePlatformDev() {
|
||||
addLocation(serverLeadId, () => import(/* webpackChunkName: "server-lead" */ '@anticrm/server-lead-resources'))
|
||||
addLocation(serverRecruitId, () => import(/* webpackChunkName: "server-recruit" */ '@anticrm/server-recruit-resources'))
|
||||
addLocation(serverTaskId, () => import/* webpackChunkName: "server-task" */ ('@anticrm/server-task-resources'))
|
||||
addLocation(serverTagsId, () => import/* webpackChunkName: "server-tags" */ ('@anticrm/server-tags-resources'))
|
||||
// Set devmodel to hook client to be able to present all activity
|
||||
enableDevModel()
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
"@anticrm/server-recruit-resources": "~0.6.0",
|
||||
"@anticrm/server-task": "~0.6.0",
|
||||
"@anticrm/server-task-resources": "~0.6.0",
|
||||
"@anticrm/server-tags": "~0.6.0",
|
||||
"@anticrm/server-tags-resources": "~0.6.0",
|
||||
"@anticrm/rekoni": "~0.6.0",
|
||||
"request": "~2.88.2",
|
||||
"@anticrm/tags": "~0.6.0"
|
||||
|
||||
@@ -56,6 +56,7 @@ import { serverInventoryId } from '@anticrm/server-inventory'
|
||||
import { serverLeadId } from '@anticrm/server-lead'
|
||||
import { serverRecruitId } from '@anticrm/server-recruit'
|
||||
import { serverTaskId } from '@anticrm/server-task'
|
||||
import { serverTagsId } from '@anticrm/server-tags'
|
||||
import { Client as ElasticClient } from '@elastic/elasticsearch'
|
||||
import { Client } from 'minio'
|
||||
import { Db, MongoClient } from 'mongodb'
|
||||
@@ -118,6 +119,7 @@ export class ElasticTool {
|
||||
addLocation(serverRecruitId, () => import(/* webpackChunkName: "server-recruit" */ '@anticrm/server-recruit-resources'))
|
||||
addLocation(serverSettingId, () => import(/* webpackChunkName: "server-recruit" */ '@anticrm/server-setting-resources'))
|
||||
addLocation(serverTaskId, () => import/* webpackChunkName: "server-task" */ ('@anticrm/server-task-resources'))
|
||||
addLocation(serverTagsId, () => import/* webpackChunkName: "server-tags" */ ('@anticrm/server-tags-resources'))
|
||||
this.mongoClient = new MongoClient(mongoUrl)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"@anticrm/model-server-setting": "~0.6.0",
|
||||
"@anticrm/model-server-chunter": "~0.6.0",
|
||||
"@anticrm/model-server-task": "~0.6.0",
|
||||
"@anticrm/model-server-tags": "~0.6.0",
|
||||
"@anticrm/model-server-recruit": "~0.6.0",
|
||||
"@anticrm/model-server-lead": "~0.6.0",
|
||||
"@anticrm/model-server-inventory": "~0.6.0",
|
||||
|
||||
@@ -35,6 +35,7 @@ import { createModel as serverChunterModel } from '@anticrm/model-server-chunter
|
||||
import { createModel as serverInventoryModel } from '@anticrm/model-server-inventory'
|
||||
import { createModel as serverLeadModel } from '@anticrm/model-server-lead'
|
||||
import { createModel as serverTaskModel } from '@anticrm/model-server-task'
|
||||
import { createModel as serverTagsModel } from '@anticrm/model-server-tags'
|
||||
import { createModel as serveSettingModel } from '@anticrm/model-server-setting'
|
||||
import { createModel as serverRecruitModel } from '@anticrm/model-server-recruit'
|
||||
import { createModel as serverCoreModel } from '@anticrm/model-server-core'
|
||||
@@ -82,6 +83,7 @@ const builders = [
|
||||
serverChunterModel,
|
||||
serverInventoryModel,
|
||||
serverLeadModel,
|
||||
serverTagsModel,
|
||||
serverTaskModel,
|
||||
serverRecruitModel,
|
||||
createDemo
|
||||
|
||||
@@ -18,12 +18,11 @@ import type { Backlink, Channel, Comment, Message } from '@anticrm/chunter'
|
||||
import type { Class, Doc, Domain, Ref } from '@anticrm/core'
|
||||
import { IndexKind } from '@anticrm/core'
|
||||
import { Builder, Collection, Index, Model, Prop, TypeMarkup, UX } from '@anticrm/model'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
import core, { TAttachedDoc, TDoc, TSpace } from '@anticrm/model-core'
|
||||
import view from '@anticrm/model-view'
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
import { ObjectDDParticipant } from '@anticrm/view'
|
||||
import chunter from './plugin'
|
||||
import attachment from '@anticrm/model-attachment'
|
||||
|
||||
export const DOMAIN_CHUNTER = 'chunter' as Domain
|
||||
export const DOMAIN_COMMENT = 'comment' as Domain
|
||||
@@ -104,10 +103,6 @@ export function createModel (builder: Builder): void {
|
||||
presenter: chunter.component.CommentPresenter
|
||||
})
|
||||
|
||||
builder.mixin<Class<Doc>, ObjectDDParticipant>(chunter.class.Comment, core.class.Class, view.mixin.ObjectDDParticipant, {
|
||||
collectDocs: chunter.action.CommentRemove
|
||||
})
|
||||
|
||||
builder.createDoc(activity.class.TxViewlet, core.space.Model, {
|
||||
objectClass: chunter.class.Comment,
|
||||
icon: chunter.icon.Chunter,
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
import type { TxViewlet } from '@anticrm/activity'
|
||||
import { Channel, chunterId } from '@anticrm/chunter'
|
||||
import chunter from '@anticrm/chunter-resources/src/plugin'
|
||||
import type { Doc, Ref, TxOperations } from '@anticrm/core'
|
||||
import type { IntlString, Resource } from '@anticrm/platform'
|
||||
import type { Ref } from '@anticrm/core'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { mergeIds } from '@anticrm/platform'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
import type { ViewletDescriptor } from '@anticrm/view'
|
||||
@@ -53,8 +53,5 @@ export default mergeIds(chunterId, chunter, {
|
||||
space: {
|
||||
General: '' as Ref<Channel>,
|
||||
Random: '' as Ref<Channel>
|
||||
},
|
||||
action: {
|
||||
CommentRemove: '' as Resource<(doc: Doc, client: TxOperations) => Promise<Doc[]>>
|
||||
}
|
||||
})
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
import { Builder } from '@anticrm/model'
|
||||
|
||||
import core from '@anticrm/core'
|
||||
import core, { Class, Doc } from '@anticrm/core'
|
||||
import chunter from '@anticrm/chunter'
|
||||
import view from '@anticrm/view'
|
||||
import serverCore, { ObjectDDParticipant } from '@anticrm/server-core'
|
||||
import serverChunter from '@anticrm/server-chunter'
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
@@ -28,4 +29,8 @@ export function createModel (builder: Builder): void {
|
||||
builder.mixin(chunter.class.Channel, core.class.Class, view.mixin.TextPresenter, {
|
||||
presenter: serverChunter.function.ChannelTextPresenter
|
||||
})
|
||||
|
||||
builder.mixin<Class<Doc>, ObjectDDParticipant>(chunter.class.Comment, core.class.Class, serverCore.mixin.ObjectDDParticipant, {
|
||||
collectDocs: serverChunter.function.CommentRemove
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
import { Model, Builder } from '@anticrm/model'
|
||||
import type { Resource } from '@anticrm/platform'
|
||||
import { TDoc } from '@anticrm/model-core'
|
||||
import { TClass, TDoc } from '@anticrm/model-core'
|
||||
|
||||
import type { Trigger, TriggerFunc } from '@anticrm/server-core'
|
||||
import core, { DOMAIN_MODEL } from '@anticrm/core'
|
||||
import type { ObjectDDParticipant, Trigger, TriggerFunc } from '@anticrm/server-core'
|
||||
import core, { Class, Doc, DocumentQuery, DOMAIN_MODEL, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import serverCore from '@anticrm/server-core'
|
||||
|
||||
@Model(serverCore.class.Trigger, core.class.Doc, DOMAIN_MODEL)
|
||||
@@ -27,6 +27,11 @@ export class TTrigger extends TDoc implements Trigger {
|
||||
trigger!: Resource<TriggerFunc>
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TTrigger)
|
||||
@Model(serverCore.mixin.ObjectDDParticipant, core.class.Class)
|
||||
export class TObjectDDParticipant extends TClass implements ObjectDDParticipant {
|
||||
collectDocs!: Resource<(doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc>(clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>) => Promise<Doc[]>>
|
||||
}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TTrigger, TObjectDDParticipant)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/model-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
||||
@@ -0,0 +1,18 @@
|
||||
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) The name of the rig package to inherit from.
|
||||
* It should be an NPM package name with the "-rig" suffix.
|
||||
*/
|
||||
"rigPackageName": "@anticrm/model-rig"
|
||||
|
||||
/**
|
||||
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||
* If omitted, then the "default" profile will be used."
|
||||
*/
|
||||
// "rigProfile": "your-profile-name"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@anticrm/model-server-tags",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"author": "Anticrm Platform Contributors",
|
||||
"license": "EPL-2.0",
|
||||
"scripts": {
|
||||
"build": "heft build",
|
||||
"build:watch": "tsc",
|
||||
"lint:fix": "eslint --fix src",
|
||||
"lint": "eslint src",
|
||||
"format": "prettier --write src && eslint --fix src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anticrm/model-rig": "~0.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-promise": "^5.1.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"@types/heft-jest": "^1.0.2",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||
"prettier": "^2.4.1",
|
||||
"@rushstack/heft": "^0.41.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/model": "~0.6.0",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/server-tags": "~0.6.0",
|
||||
"@anticrm/server-core": "~0.6.1",
|
||||
"@anticrm/tags": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright © 2022 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 core, { Class, Doc } from '@anticrm/core'
|
||||
import { Builder } from '@anticrm/model'
|
||||
import serverCore, { ObjectDDParticipant } from '@anticrm/server-core'
|
||||
import serverTags from '@anticrm/server-tags'
|
||||
import tags from '@anticrm/tags'
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.mixin<Class<Doc>, ObjectDDParticipant>(tags.class.TagElement, core.class.Class, serverCore.mixin.ObjectDDParticipant, {
|
||||
collectDocs: serverTags.function.TagElementRemove
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./node_modules/@anticrm/model-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,14 @@
|
||||
import { Class, Doc, Domain, IndexKind, Ref } from '@anticrm/core'
|
||||
import { Builder, Collection, Index, Model, Prop, TypeRef, TypeString, UX } from '@anticrm/model'
|
||||
import core, { TAttachedDoc, TDoc } from '@anticrm/model-core'
|
||||
import view, { ObjectDDParticipant } from '@anticrm/model-view'
|
||||
import view from '@anticrm/model-view'
|
||||
import { Asset, IntlString } from '@anticrm/platform'
|
||||
import type { TagCategory, TagElement, TagReference } from '@anticrm/tags'
|
||||
import tags from './plugin'
|
||||
|
||||
export { TagCategory, TagElement, TagReference } from '@anticrm/tags'
|
||||
export { tagsOperation } from './migration'
|
||||
export { tags as default }
|
||||
export { TagElement, TagReference, TagCategory } from '@anticrm/tags'
|
||||
|
||||
export const DOMAIN_TAGS = 'tags' as Domain
|
||||
|
||||
@@ -94,7 +94,4 @@ export function createModel (builder: Builder): void {
|
||||
builder.mixin(tags.class.TagElement, core.class.Class, view.mixin.AttributePresenter, {
|
||||
presenter: tags.component.TagElementPresenter
|
||||
})
|
||||
builder.mixin<Class<Doc>, ObjectDDParticipant>(tags.class.TagElement, core.class.Class, view.mixin.ObjectDDParticipant, {
|
||||
collectDocs: tags.dd.DeleteTagElement
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Doc, Ref, TxOperations } from '@anticrm/core'
|
||||
import { IntlString, mergeIds, Resource } from '@anticrm/platform'
|
||||
import { Ref } from '@anticrm/core'
|
||||
import { IntlString, mergeIds } from '@anticrm/platform'
|
||||
import { TagCategory, tagsId } from '@anticrm/tags'
|
||||
import tags from '@anticrm/tags-resources/src/plugin'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
@@ -42,9 +42,6 @@ export default mergeIds(tagsId, tags, {
|
||||
CategoryTagsLabel: '' as IntlString,
|
||||
DefaultLabel: '' as IntlString
|
||||
},
|
||||
dd: {
|
||||
DeleteTagElement: '' as Resource<(doc: Doc, client: TxOperations) => Promise<Doc[]>>
|
||||
},
|
||||
category: {
|
||||
Category: '' as Ref<TagCategory>
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import type {
|
||||
AttributeEditor,
|
||||
AttributePresenter,
|
||||
IgnoreActions,
|
||||
ObjectDDParticipant,
|
||||
ObjectEditor,
|
||||
ObjectEditorHeader,
|
||||
ObjectFactory,
|
||||
@@ -37,7 +36,6 @@ import type {
|
||||
} from '@anticrm/view'
|
||||
import view from './plugin'
|
||||
|
||||
export { ObjectDDParticipant } from '@anticrm/view'
|
||||
export { viewOperation } from './migration'
|
||||
|
||||
@Mixin(view.mixin.AttributeEditor, core.class.Class)
|
||||
@@ -69,10 +67,6 @@ export class TObjectValidator extends TClass implements ObjectValidator {
|
||||
export class TObjectFactory extends TClass implements ObjectFactory {
|
||||
component!: AnyComponent
|
||||
}
|
||||
@Mixin(view.mixin.ObjectDDParticipant, core.class.Class)
|
||||
export class TObjectDDParticipant extends TClass implements ObjectDDParticipant {
|
||||
collectDocs!: Resource<(doc: Doc) => Promise<Doc[]>>
|
||||
}
|
||||
|
||||
@Model(view.class.ViewletDescriptor, core.class.Doc, DOMAIN_MODEL)
|
||||
export class TViewletDescriptor extends TDoc implements ViewletDescriptor {
|
||||
@@ -128,7 +122,6 @@ export function createModel (builder: Builder): void {
|
||||
TObjectValidator,
|
||||
TObjectFactory,
|
||||
TObjectEditorHeader,
|
||||
TObjectDDParticipant,
|
||||
THTMLPresenter,
|
||||
TTextPresenter,
|
||||
TIgnoreActions
|
||||
|
||||
@@ -102,13 +102,3 @@ export async function updateBacklinks (client: TxOperations, backlinkId: Ref<Doc
|
||||
await client.addCollection(chunter.class.Backlink, chunter.space.Backlinks, attachedTo, attachedToClass, collection, adata)
|
||||
}
|
||||
}
|
||||
|
||||
export async function collectBacklinks (doc: Doc, client: TxOperations): Promise<Doc[]> {
|
||||
if (!client.getHierarchy().isDerived(doc._class, chunter.class.Comment)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const comment = doc as Comment
|
||||
const result = await client.findAll(chunter.class.Backlink, { backlinkId: comment.attachedTo, backlinkClass: comment.attachedToClass, attachedDocId: comment._id })
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -13,11 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Channel } from '@anticrm/chunter'
|
||||
import { Doc } from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { getMetadata, Resources } from '@anticrm/platform'
|
||||
import { collectBacklinks } from './backlinks'
|
||||
import { Resources } from '@anticrm/platform'
|
||||
import TxBacklinkCreate from './components/activity/TxBacklinkCreate.svelte'
|
||||
import TxBacklinkReference from './components/activity/TxBacklinkReference.svelte'
|
||||
import TxCommentCreate from './components/activity/TxCommentCreate.svelte'
|
||||
@@ -27,8 +23,6 @@ import CommentInput from './components/CommentInput.svelte'
|
||||
import CommentPresenter from './components/CommentPresenter.svelte'
|
||||
import CommentsPresenter from './components/CommentsPresenter.svelte'
|
||||
import CreateChannel from './components/CreateChannel.svelte'
|
||||
import chunter from './plugin'
|
||||
import workbench from '@anticrm/workbench'
|
||||
|
||||
export { CommentsPresenter }
|
||||
|
||||
@@ -45,8 +39,5 @@ export default async (): Promise<Resources> => ({
|
||||
TxCommentCreate,
|
||||
TxBacklinkCreate,
|
||||
TxBacklinkReference
|
||||
},
|
||||
action: {
|
||||
CommentRemove: collectBacklinks
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,10 +25,6 @@ import CategoryPresenter from './components/CategoryPresenter.svelte'
|
||||
import tags from './plugin'
|
||||
import TagsCategoryBar from './components/CategoryBar.svelte'
|
||||
|
||||
async function DeleteTagElement (doc: TagElement, client: TxOperations): Promise<Doc[]> {
|
||||
return await client.findAll(tags.class.TagReference, { tag: doc._id })
|
||||
}
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
component: {
|
||||
Tags,
|
||||
@@ -40,8 +36,5 @@ export default async (): Promise<Resources> => ({
|
||||
TagsItemPresenter,
|
||||
CategoryPresenter,
|
||||
TagsCategoryBar
|
||||
},
|
||||
dd: {
|
||||
DeleteTagElement
|
||||
}
|
||||
})
|
||||
|
||||
@@ -34,7 +34,7 @@ import type { IntlString } from '@anticrm/platform'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import { getAttributePresenterClass, KeyedAttribute } from '@anticrm/presentation'
|
||||
import { ErrorPresenter, getPlatformColorForText } from '@anticrm/ui'
|
||||
import type { Action, ActionTarget, BuildModelOptions, ObjectDDParticipant } from '@anticrm/view'
|
||||
import type { Action, ActionTarget, BuildModelOptions } from '@anticrm/view'
|
||||
import view, { AttributeModel, BuildModelKey } from '@anticrm/view'
|
||||
import plugin from './plugin'
|
||||
|
||||
@@ -220,66 +220,9 @@ export async function deleteObject (client: TxOperations, object: Doc): Promise<
|
||||
const promises: Array<Promise<any>> = []
|
||||
if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) {
|
||||
const adoc = object as AttachedDoc
|
||||
promises.push(client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err)))
|
||||
await client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err))
|
||||
} else {
|
||||
promises.push(client.removeDoc(object._class, object.space, object._id).catch(err => console.error(err)))
|
||||
}
|
||||
promises.push(deleteClassCollections(client, object._class, object))
|
||||
const mixins = getMixins(hierarchy, object._class, object)
|
||||
for (const mixin of mixins) {
|
||||
promises.push(deleteClassCollections(client, mixin, object))
|
||||
}
|
||||
|
||||
promises.push(deleteRelatedDocuments(hierarchy, object, client))
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
async function deleteClassCollections (client: TxOperations, _class: Ref<Class<Doc>>, object: Doc): Promise<void> {
|
||||
const hierarchy = client.getHierarchy()
|
||||
const attributes = hierarchy.getAllAttributes(_class)
|
||||
for (const [name, attribute] of attributes) {
|
||||
if (hierarchy.isDerived(attribute.type._class, core.class.Collection)) {
|
||||
const collection = attribute.type as Collection<AttachedDoc>
|
||||
const allAttached = await client.findAll(collection.of, { attachedTo: object._id })
|
||||
for (const attached of allAttached) {
|
||||
await deleteObject(client, attached).catch(err => console.log('failed to delete', name, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getParentClass (hierarchy: Hierarchy, _class: Ref<Class<Doc>>): Ref<Class<Doc>> {
|
||||
const baseDomain = hierarchy.getDomain(_class)
|
||||
const ancestors = hierarchy.getAncestors(_class)
|
||||
let result: Ref<Class<Doc>> = _class
|
||||
for (const ancestor of ancestors) {
|
||||
try {
|
||||
const domain = hierarchy.getClass(ancestor).domain
|
||||
if (domain === baseDomain) {
|
||||
result = ancestor
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getMixins (hierarchy: Hierarchy, _class: Ref<Class<Doc>>, object: Doc): Array<Ref<Mixin<Doc>>> {
|
||||
const parentClass = getParentClass(hierarchy, _class)
|
||||
const descendants = hierarchy.getDescendants(parentClass)
|
||||
return descendants.filter(
|
||||
(m) => hierarchy.getClass(m).kind === ClassifierKind.MIXIN && hierarchy.hasMixin(object, m)
|
||||
)
|
||||
}
|
||||
|
||||
async function deleteRelatedDocuments (hierarchy: Hierarchy, object: Doc, client: TxOperations): Promise<void> {
|
||||
const objectClass = hierarchy.getClass(object._class)
|
||||
if (hierarchy.hasMixin(objectClass, view.mixin.ObjectDDParticipant)) {
|
||||
const removeParticipand: ObjectDDParticipant = hierarchy.as(objectClass, view.mixin.ObjectDDParticipant)
|
||||
const collector = await getResource(removeParticipand.collectDocs)
|
||||
const docs = await collector(object, client)
|
||||
for (const d of docs) {
|
||||
await deleteObject(client, d)
|
||||
}
|
||||
await client.removeDoc(object._class, object.space, object._id).catch(err => console.error(err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { AnyAttribute, Class, Client, Doc, DocumentQuery, FindOptions, Mixin, Obj, Ref, Space, TxOperations, UXObject } from '@anticrm/core'
|
||||
import type { AnyAttribute, Class, Client, Doc, DocumentQuery, FindOptions, Mixin, Obj, Ref, Space, UXObject } from '@anticrm/core'
|
||||
import type { Asset, IntlString, Plugin, Resource, Status } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import type { AnyComponent, AnySvelteComponent } from '@anticrm/ui'
|
||||
@@ -167,15 +167,6 @@ export interface ObjectFactory extends Class<Obj> {
|
||||
component: AnyComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to contribute and find all derived objects for document.
|
||||
* @public
|
||||
*/
|
||||
export interface ObjectDDParticipant extends Class<Obj> {
|
||||
// Collect more items to be deleted if parent document is deleted.
|
||||
collectDocs: Resource<(doc: Doc, client: TxOperations) => Promise<Doc[]>>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@@ -187,7 +178,6 @@ const view = plugin(viewId, {
|
||||
ObjectEditorHeader: '' as Ref<Mixin<ObjectEditorHeader>>,
|
||||
ObjectValidator: '' as Ref<Mixin<ObjectValidator>>,
|
||||
ObjectFactory: '' as Ref<Mixin<ObjectFactory>>,
|
||||
ObjectDDParticipant: '' as Ref<ObjectDDParticipant>,
|
||||
IgnoreActions: '' as Ref<Mixin<IgnoreActions>>,
|
||||
HTMLPresenter: '' as Ref<Mixin<HTMLPresenter>>,
|
||||
TextPresenter: '' as Ref<Mixin<TextPresenter>>
|
||||
|
||||
@@ -1151,5 +1151,20 @@
|
||||
"projectFolder": "models/calendar",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/server-tags",
|
||||
"projectFolder": "server-plugins/tags",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/model-server-tags",
|
||||
"projectFolder": "models/server-tags",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@anticrm/server-tags-resources",
|
||||
"projectFolder": "server-plugins/tags-resources",
|
||||
"shouldPublish": true
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import chunter, { Channel } from '@anticrm/chunter'
|
||||
import { Doc } from '@anticrm/core'
|
||||
import chunter, { Comment, Channel } from '@anticrm/chunter'
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { getMetadata } from '@anticrm/platform'
|
||||
import workbench from '@anticrm/workbench'
|
||||
@@ -36,9 +36,23 @@ export function channelTextPresenter (doc: Doc): string {
|
||||
return `${channel.name}`
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function CommentRemove (doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc> (clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>): Promise<Doc[]> {
|
||||
if (!hiearachy.isDerived(doc._class, chunter.class.Comment)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const comment = doc as Comment
|
||||
const result = await findAll(chunter.class.Backlink, { backlinkId: comment.attachedTo, backlinkClass: comment.attachedToClass, attachedDocId: comment._id })
|
||||
return result
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
function: {
|
||||
CommentRemove,
|
||||
ChannelHTMLPresenter: channelHTMLPresenter,
|
||||
ChannelTextPresenter: channelTextPresenter
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Resource, Plugin } from '@anticrm/platform'
|
||||
import { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import type { Plugin, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import { Doc } from '@anticrm/core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -27,6 +27,7 @@ export const serverChunterId = 'server-chunter' as Plugin
|
||||
*/
|
||||
export default plugin(serverChunterId, {
|
||||
function: {
|
||||
CommentRemove: '' as Resource<(doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc> (clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>) => Promise<Doc[]>>,
|
||||
ChannelHTMLPresenter: '' as Resource<(doc: Doc) => string>,
|
||||
ChannelTextPresenter: '' as Resource<(doc: Doc) => string>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
||||
@@ -0,0 +1,18 @@
|
||||
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) The name of the rig package to inherit from.
|
||||
* It should be an NPM package name with the "-rig" suffix.
|
||||
*/
|
||||
"rigPackageName": "@anticrm/platform-rig"
|
||||
|
||||
/**
|
||||
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||
* If omitted, then the "default" profile will be used."
|
||||
*/
|
||||
// "rigProfile": "your-profile-name"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "@anticrm/server-tags-resources",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"author": "Anticrm Platform Contributors",
|
||||
"license": "EPL-2.0",
|
||||
"scripts": {
|
||||
"build": "heft build",
|
||||
"build:watch": "tsc",
|
||||
"lint:fix": "eslint --fix src",
|
||||
"lint": "eslint src",
|
||||
"format": "prettier --write src && eslint --fix src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anticrm/platform-rig": "~0.6.0",
|
||||
"@types/heft-jest": "^1.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-promise": "^5.1.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||
"prettier": "^2.4.1",
|
||||
"@rushstack/heft": "^0.41.1",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/server-core": "~0.6.1",
|
||||
"@anticrm/tags": "~0.6.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright © 2022 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 { Class, Doc, DocumentQuery, FindOptions, FindResult, Hierarchy, Ref } from '@anticrm/core'
|
||||
import tags, { TagElement } from '@anticrm/tags'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function TagElementRemove (doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc> (clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>): Promise<Doc[]> {
|
||||
if (hiearachy.isDerived(doc._class, tags.class.TagElement)) return []
|
||||
return await findAll(tags.class.TagReference, { tag: doc._id as Ref<TagElement> })
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export default async () => ({
|
||||
function: {
|
||||
TagElementRemove
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
||||
@@ -0,0 +1,18 @@
|
||||
// The "rig.json" file directs tools to look for their config files in an external package.
|
||||
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) The name of the rig package to inherit from.
|
||||
* It should be an NPM package name with the "-rig" suffix.
|
||||
*/
|
||||
"rigPackageName": "@anticrm/platform-rig"
|
||||
|
||||
/**
|
||||
* (Optional) Selects a config profile from the rig package. The name must consist of
|
||||
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
|
||||
* If omitted, then the "default" profile will be used."
|
||||
*/
|
||||
// "rigProfile": "your-profile-name"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "@anticrm/server-tags",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"author": "Anticrm Platform Contributors",
|
||||
"license": "EPL-2.0",
|
||||
"scripts": {
|
||||
"build": "heft build",
|
||||
"build:watch": "tsc",
|
||||
"lint:fix": "eslint --fix src",
|
||||
"lint": "eslint src",
|
||||
"format": "prettier --write src && eslint --fix src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anticrm/platform-rig": "~0.6.0",
|
||||
"@types/heft-jest": "^1.0.2",
|
||||
"@types/node": "~16.11.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-promise": "^5.1.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"eslint-config-standard-with-typescript": "^21.0.1",
|
||||
"prettier": "^2.4.1",
|
||||
"@rushstack/heft": "^0.41.1",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/platform": "~0.6.5",
|
||||
"@anticrm/server-core": "~0.6.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright © 2022 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 { Class, Doc, Hierarchy, Ref, FindResult, FindOptions, DocumentQuery } from '@anticrm/core'
|
||||
import type { Plugin, Resource } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const serverTagsId = 'server-tags' as Plugin
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export default plugin(serverTagsId, {
|
||||
function: {
|
||||
TagElementRemove: '' as Resource<(doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc> (clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>) => Promise<Doc[]>>
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import type { Plugin } from '@anticrm/platform'
|
||||
import { plugin } from '@anticrm/platform'
|
||||
|
||||
import type { Ref, Class } from '@anticrm/core'
|
||||
import type { Trigger } from './types'
|
||||
import type { ObjectDDParticipant, Trigger } from './types'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -31,6 +31,9 @@ export const serverCoreId = 'server-core' as Plugin
|
||||
const serverCore = plugin(serverCoreId, {
|
||||
class: {
|
||||
Trigger: '' as Ref<Class<Trigger>>
|
||||
},
|
||||
mixin: {
|
||||
ObjectDDParticipant: '' as Ref<ObjectDDParticipant>
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
+140
-3
@@ -17,6 +17,8 @@
|
||||
import core, {
|
||||
AttachedDoc,
|
||||
Class,
|
||||
ClassifierKind,
|
||||
Collection,
|
||||
Doc,
|
||||
DocumentQuery,
|
||||
Domain,
|
||||
@@ -25,21 +27,28 @@ import core, {
|
||||
FindOptions,
|
||||
FindResult,
|
||||
Hierarchy,
|
||||
MeasureContext, ModelDb,
|
||||
MeasureContext, Mixin, ModelDb,
|
||||
Ref,
|
||||
ServerStorage,
|
||||
Storage,
|
||||
Tx,
|
||||
TxBulkWrite,
|
||||
TxCollectionCUD,
|
||||
TxCreateDoc,
|
||||
TxCUD,
|
||||
TxFactory,
|
||||
TxResult
|
||||
TxMixin,
|
||||
TxProcessor,
|
||||
TxRemoveDoc,
|
||||
TxResult,
|
||||
TxUpdateDoc
|
||||
} from '@anticrm/core'
|
||||
import { getResource } from '@anticrm/platform'
|
||||
import type { Client as MinioClient } from 'minio'
|
||||
import { FullTextIndex } from './fulltext'
|
||||
import serverCore from './plugin'
|
||||
import { Triggers } from './triggers'
|
||||
import type { FullTextAdapter, FullTextAdapterFactory } from './types'
|
||||
import type { FullTextAdapter, FullTextAdapterFactory, ObjectDDParticipant } from './types'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -197,6 +206,133 @@ class TServerStorage implements ServerStorage {
|
||||
})
|
||||
}
|
||||
|
||||
getParentClass (_class: Ref<Class<Doc>>): Ref<Class<Doc>> {
|
||||
const baseDomain = this.hierarchy.getDomain(_class)
|
||||
const ancestors = this.hierarchy.getAncestors(_class)
|
||||
let result: Ref<Class<Doc>> = _class
|
||||
for (const ancestor of ancestors) {
|
||||
try {
|
||||
const domain = this.hierarchy.getClass(ancestor).domain
|
||||
if (domain === baseDomain) {
|
||||
result = ancestor
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
getMixins (_class: Ref<Class<Doc>>, object: Doc): Array<Ref<Mixin<Doc>>> {
|
||||
const parentClass = this.getParentClass(_class)
|
||||
const descendants = this.hierarchy.getDescendants(parentClass)
|
||||
return descendants.filter(
|
||||
(m) => this.hierarchy.getClass(m).kind === ClassifierKind.MIXIN && this.hierarchy.hasMixin(object, m)
|
||||
)
|
||||
}
|
||||
|
||||
async buildRemovedDoc (ctx: MeasureContext, tx: TxRemoveDoc<Doc>): Promise<Doc | undefined> {
|
||||
const txes = await this.findAll(ctx, core.class.TxCUD, { objectId: tx.objectId }, { sort: { modifiedOn: 1 } })
|
||||
let doc: Doc
|
||||
let createTx = txes.find((tx) => tx._class === core.class.TxCreateDoc)
|
||||
if (createTx === undefined) {
|
||||
const collectionTxes = txes.filter((tx) => tx._class === core.class.TxCollectionCUD) as TxCollectionCUD<Doc, AttachedDoc>[]
|
||||
createTx = collectionTxes.find((p) => p.tx._class === core.class.TxCreateDoc)
|
||||
}
|
||||
if (createTx === undefined) return
|
||||
doc = TxProcessor.createDoc2Doc(createTx as TxCreateDoc<Doc>)
|
||||
for (const tx of txes) {
|
||||
if (tx._class === core.class.TxUpdateDoc) {
|
||||
doc = TxProcessor.updateDoc2Doc(doc, tx as TxUpdateDoc<Doc>)
|
||||
} else if (tx._class === core.class.TxMixin) {
|
||||
const mixinTx = tx as TxMixin<Doc, Doc>
|
||||
doc = TxProcessor.updateMixin4Doc(doc, mixinTx.mixin, mixinTx.attributes)
|
||||
}
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
|
||||
extractTx (tx: Tx): Tx {
|
||||
if (tx._class === core.class.TxCollectionCUD) {
|
||||
const ctx = (tx as TxCollectionCUD<Doc, AttachedDoc>)
|
||||
return ctx.tx
|
||||
}
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
async processRemove (ctx: MeasureContext, tx: Tx): Promise<Tx[]> {
|
||||
const actualTx = this.extractTx(tx)
|
||||
if (!this.hierarchy.isDerived(actualTx._class, core.class.TxRemoveDoc)) return []
|
||||
const rtx = actualTx as TxRemoveDoc<Doc>
|
||||
const result: Tx[] = []
|
||||
const object = await this.buildRemovedDoc(ctx, rtx)
|
||||
if (object === undefined) return []
|
||||
result.push(...await this.deleteClassCollections(ctx, object._class, rtx.objectId))
|
||||
const mixins = this.getMixins(object._class, object)
|
||||
for (const mixin of mixins) {
|
||||
result.push(...await this.deleteClassCollections(ctx, mixin, rtx.objectId))
|
||||
}
|
||||
result.push(...await this.deleteRelatedDocuments(ctx, object))
|
||||
return result
|
||||
}
|
||||
|
||||
async deleteClassCollections (ctx: MeasureContext, _class: Ref<Class<Doc>>, objectId: Ref<Doc>): Promise<Tx[]> {
|
||||
const attributes = this.hierarchy.getAllAttributes(_class)
|
||||
const result: Tx[] = []
|
||||
for (const attribute of attributes) {
|
||||
if (this.hierarchy.isDerived(attribute[1].type._class, core.class.Collection)) {
|
||||
const collection = attribute[1].type as Collection<AttachedDoc>
|
||||
const allAttached = await this.findAll(ctx, collection.of, { attachedTo: objectId })
|
||||
for (const attached of allAttached) {
|
||||
result.push(...await this.deleteObject(ctx, attached))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async deleteObject (ctx: MeasureContext, object: Doc): Promise<Tx[]> {
|
||||
const result: Tx[] = []
|
||||
const factory = new TxFactory(core.account.System)
|
||||
if (this.hierarchy.isDerived(object._class, core.class.AttachedDoc)) {
|
||||
const adoc = object as AttachedDoc
|
||||
const nestedTx = factory.createTxRemoveDoc(object._class, object.space, adoc._id) as TxRemoveDoc<AttachedDoc>
|
||||
const tx = factory.createTxCollectionCUD(
|
||||
adoc.attachedToClass,
|
||||
adoc.attachedTo,
|
||||
object.space,
|
||||
adoc.collection,
|
||||
nestedTx
|
||||
)
|
||||
result.push(tx)
|
||||
} else {
|
||||
result.push(factory.createTxRemoveDoc(object._class, object.space, object._id))
|
||||
}
|
||||
result.push(...await this.deleteClassCollections(ctx, object._class, object._id))
|
||||
const mixins = this.getMixins(object._class, object)
|
||||
for (const mixin of mixins) {
|
||||
result.push(...await this.deleteClassCollections(ctx, mixin, object._id))
|
||||
}
|
||||
result.push(...await this.deleteRelatedDocuments(ctx, object))
|
||||
return result
|
||||
}
|
||||
|
||||
async deleteRelatedDocuments (ctx: MeasureContext, object: Doc): Promise<Tx[]> {
|
||||
const result: Tx[] = []
|
||||
const objectClass = this.hierarchy.getClass(object._class)
|
||||
if (this.hierarchy.hasMixin(objectClass, serverCore.mixin.ObjectDDParticipant)) {
|
||||
const removeParticipand: ObjectDDParticipant = this.hierarchy.as(objectClass, serverCore.mixin.ObjectDDParticipant)
|
||||
const collector = await getResource(removeParticipand.collectDocs)
|
||||
const docs = await collector(object, this.hierarchy, async (_class, query, options) => {
|
||||
return await this.findAll(ctx, _class, query, options)
|
||||
})
|
||||
for (const d of docs) {
|
||||
result.push(...await this.deleteObject(ctx, d))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async tx (ctx: MeasureContext, tx: Tx): Promise<[TxResult, Tx[]]> {
|
||||
// store tx
|
||||
const _class = txClass(tx)
|
||||
@@ -227,6 +363,7 @@ class TServerStorage implements ServerStorage {
|
||||
// invoke triggers and store derived objects
|
||||
derived = [
|
||||
...(await ctx.with('process-collection', { _class }, () => this.processCollection(ctx, tx))),
|
||||
...(await ctx.with('process-remove', { _class }, () => this.processRemove(ctx, tx))),
|
||||
...(await ctx.with('process-triggers', {}, (ctx) =>
|
||||
this.triggers.apply(tx.modifiedBy, tx, {
|
||||
fx: triggerFx.fx,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//
|
||||
|
||||
import type { Client as MinioClient } from 'minio'
|
||||
import type { Tx, Ref, Doc, Class, Storage, Space, Timestamp, Account, FindResult, DocumentQuery, FindOptions, TxResult, MeasureContext, ModelDb } from '@anticrm/core'
|
||||
import type { Tx, Ref, Doc, Class, Storage, Space, Timestamp, Account, FindResult, DocumentQuery, FindOptions, TxResult, MeasureContext, ModelDb, Obj } from '@anticrm/core'
|
||||
import { TxFactory, Hierarchy } from '@anticrm/core'
|
||||
import type { Resource } from '@anticrm/platform'
|
||||
|
||||
@@ -83,3 +83,12 @@ export type FullTextAdapterFactory = (url: string, workspace: string) => Promise
|
||||
export interface WithFind {
|
||||
findAll: <T extends Doc> (ctx: MeasureContext, clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to contribute and find all derived objects for document.
|
||||
* @public
|
||||
*/
|
||||
export interface ObjectDDParticipant extends Class<Obj> {
|
||||
// Collect more items to be deleted if parent document is deleted.
|
||||
collectDocs: Resource<(doc: Doc, hiearachy: Hierarchy, findAll: <T extends Doc> (clazz: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>) => Promise<Doc[]>>
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
"@anticrm/server-recruit-resources": "~0.6.0",
|
||||
"@anticrm/server-task": "~0.6.0",
|
||||
"@anticrm/server-task-resources": "~0.6.0",
|
||||
"@anticrm/server-tags": "~0.6.0",
|
||||
"@anticrm/server-tags-resources": "~0.6.0",
|
||||
"@anticrm/server-token": "~0.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import { serverInventoryId } from '@anticrm/server-inventory'
|
||||
import { serverLeadId } from '@anticrm/server-lead'
|
||||
import { serverRecruitId } from '@anticrm/server-recruit'
|
||||
import { serverTaskId } from '@anticrm/server-task'
|
||||
import { serverTagsId } from '@anticrm/server-tags'
|
||||
|
||||
import { metricsContext } from './metrics'
|
||||
|
||||
@@ -68,6 +69,7 @@ export function start (dbUrl: string, fullTextUrl: string, minioConf: MinioConfi
|
||||
addLocation(serverLeadId, () => import('@anticrm/server-lead-resources'))
|
||||
addLocation(serverRecruitId, () => import('@anticrm/server-recruit-resources'))
|
||||
addLocation(serverTaskId, () => import('@anticrm/server-task-resources'))
|
||||
addLocation(serverTagsId, () => import('@anticrm/server-tags-resources'))
|
||||
|
||||
return startJsonRpc(metricsContext, (workspace: string) => {
|
||||
const conf: DbConfiguration = {
|
||||
|
||||
Reference in New Issue
Block a user