From e5f414ac6ef463a35abc2289b4436b6951216d59 Mon Sep 17 00:00:00 2001 From: Andrey Platov <87076238+aplatoff@users.noreply.github.com> Date: Mon, 6 Dec 2021 10:16:04 +0100 Subject: [PATCH] delete attached objects (introduce `Collection` type) (#529) Signed-off-by: Andrey Platov --- models/recruit/src/index.ts | 8 ++++---- packages/core/src/classes.ts | 7 +++++++ packages/core/src/component.ts | 4 +++- packages/model/src/dsl.ts | 12 ++++++++++-- plugins/view-resources/src/index.ts | 9 ++------- plugins/view-resources/src/utils.ts | 23 ++++++++++++++++++++++- 6 files changed, 48 insertions(+), 15 deletions(-) diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 48dc81d937..48380665ef 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -15,7 +15,7 @@ import type { Employee } from '@anticrm/contact' import type { Doc, Domain, FindOptions, Ref, Timestamp } from '@anticrm/core' -import { Builder, Model, Prop, TypeBoolean, TypeDate, TypeRef, TypeString, UX } from '@anticrm/model' +import { Builder, Model, Prop, TypeBoolean, TypeDate, TypeRef, TypeString, UX, Collection } from '@anticrm/model' import chunter from '@anticrm/model-chunter' import contact, { TPerson } from '@anticrm/model-contact' import core, { TAttachedDoc, TDocWithState, TSpace, TSpaceWithStates } from '@anticrm/model-core' @@ -56,13 +56,13 @@ export class TCandidate extends TPerson implements Candidate { @Prop(TypeString(), 'Title' as IntlString) title?: string - @Prop(TypeString(), 'Attachments' as IntlString) + @Prop(Collection(chunter.class.Attachment), 'Attachments' as IntlString) attachments?: number - @Prop(TypeString(), 'Comments' as IntlString) + @Prop(Collection(chunter.class.Comment), 'Comments' as IntlString) comments?: number - @Prop(TypeString(), 'Applications' as IntlString) + @Prop(Collection(recruit.class.Applicant), 'Applications' as IntlString) applications?: number @Prop(TypeBoolean(), 'Onsite' as IntlString) diff --git a/packages/core/src/classes.ts b/packages/core/src/classes.ts index 046bdf33b6..bbca5c3907 100644 --- a/packages/core/src/classes.ts +++ b/packages/core/src/classes.ts @@ -164,6 +164,13 @@ export interface RefTo extends Type>> { to: Ref> } +/** + * @public + */ +export interface Collection extends Type { + of: Ref> +} + /** * @public */ diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index 5754615a95..b75cd9f2be 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -14,7 +14,7 @@ // import type { Plugin, StatusCode } from '@anticrm/platform' import { plugin } from '@anticrm/platform' -import type { Account, AnyAttribute, AttachedDoc, Class, Doc, DocWithState, Interface, Obj, PropertyType, Ref, Space, SpaceWithStates, State, Timestamp, Type } from './classes' +import type { Account, AnyAttribute, AttachedDoc, Class, Doc, DocWithState, Interface, Obj, PropertyType, Ref, Space, SpaceWithStates, State, Timestamp, Type, Collection, RefTo } from './classes' import type { Tx, TxBulkWrite, TxCollectionCUD, TxCreateDoc, TxCUD, TxMixin, TxPutBag, TxRemoveDoc, TxUpdateDoc } from './tx' /** @@ -47,6 +47,8 @@ export default plugin(coreId, { TypeBoolean: '' as Ref>>, TypeTimestamp: '' as Ref>>, TypeDate: '' as Ref>>, + RefTo: '' as Ref>>, + Collection: '' as Ref>>, Bag: '' as Ref>>> }, interface: { diff --git a/packages/model/src/dsl.ts b/packages/model/src/dsl.ts index 214e0e0da5..2728eda147 100644 --- a/packages/model/src/dsl.ts +++ b/packages/model/src/dsl.ts @@ -15,6 +15,7 @@ import core, { Account, + AttachedDoc, Collection as TypeCollection, RefTo, Attribute, Class, Classifier, ClassifierKind, Data, Doc, Domain, ExtendedAttributes, generateId, IndexKind, Interface, Mixin as IMixin, Obj, PropertyType, Ref, Space, Tx, TxCreateDoc, TxFactory, TxProcessor, Type } from '@anticrm/core' import type { Asset, IntlString } from '@anticrm/platform' @@ -308,8 +309,15 @@ export function TypeDate (): Type { /** * @public */ -export function TypeRef (_class: Ref>): Type { - return { _class: _class, label: 'TypeRef' as IntlString } +export function TypeRef (_class: Ref>): RefTo { + return { _class: core.class.RefTo, to: _class, label: 'TypeRef' as IntlString } +} + +/** + * @public + */ +export function Collection (clazz: Ref>): TypeCollection { + return { _class: core.class.Collection, of: clazz, label: 'Collection' as IntlString } } /** diff --git a/plugins/view-resources/src/index.ts b/plugins/view-resources/src/index.ts index 0c848ab6d9..cc17aa6267 100644 --- a/plugins/view-resources/src/index.ts +++ b/plugins/view-resources/src/index.ts @@ -30,6 +30,7 @@ import StringPresenter from './components/StringPresenter.svelte' import Table from './components/Table.svelte' import TableView from './components/TableView.svelte' import TimestampPresenter from './components/TimestampPresenter.svelte' +import { deleteObject } from './utils' export { default as ContextMenu } from './components/Menu.svelte' export { buildModel, getActions, getObjectPresenter } from './utils' @@ -41,13 +42,7 @@ function Delete (object: Doc): void { message: 'Do you want to delete this object?' }, undefined, (result) => { if (result !== undefined) { - const client = getClient() - if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) { - const adoc = object as AttachedDoc - client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err)) - } else { - client.removeDoc(object._class, object.space, object._id).catch(err => console.error(err)) - } + deleteObject(getClient(), object) } }) } diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts index 301526da29..0e8e5e8529 100644 --- a/plugins/view-resources/src/utils.ts +++ b/plugins/view-resources/src/utils.ts @@ -14,12 +14,13 @@ // limitations under the License. // -import type { Class, Client, Doc, FindOptions, FindResult, Obj, Ref } from '@anticrm/core' +import type { Class, Client, Doc, FindOptions, FindResult, Obj, Ref, AttachedDoc, TxOperations, Collection } from '@anticrm/core' import type { IntlString } from '@anticrm/platform' import { getResource } from '@anticrm/platform' import type { AnyComponent } from '@anticrm/ui' import type { Action, ActionTarget, BuildModelOptions } from '@anticrm/view' import view, { AttributeModel } from '@anticrm/view' +import core from '@anticrm/core' /** * @public @@ -132,3 +133,23 @@ export async function getActions (client: Client, _class: Ref>): Prom const targets = await client.findAll(view.class.ActionTarget, {}) return await client.findAll(view.class.Action, { _id: { $in: filterActions(client, _class, targets) } }) } + +export async function deleteObject (client: Client & TxOperations, object: Doc) { + const hierarchy = client.getHierarchy() + const attributes = hierarchy.getAllAttributes(object._class) + for (const [name, attribute] of attributes) { + if (hierarchy.isDerived(attribute.type._class, core.class.Collection)) { + const collection = attribute.type as Collection + const allAttached = await client.findAll(collection.of, { attachedTo: object._id }) + for (const attached of allAttached) { + deleteObject(client, attached) + } + } + } + if (client.getHierarchy().isDerived(object._class, core.class.AttachedDoc)) { + const adoc = object as AttachedDoc + client.removeCollection(object._class, object.space, adoc._id, adoc.attachedTo, adoc.attachedToClass, adoc.collection).catch(err => console.error(err)) + } else { + client.removeDoc(object._class, object.space, object._id).catch(err => console.error(err)) + } +} \ No newline at end of file