delete attached objects (introduce Collection type) (#529)

Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
Andrey Platov 2021-12-06 10:16:04 +01:00 committed by GitHub
parent c6082fdcf3
commit e5f414ac6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 15 deletions

View File

@ -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)

View File

@ -164,6 +164,13 @@ export interface RefTo<T extends Doc> extends Type<Ref<Class<T>>> {
to: Ref<Class<T>>
}
/**
* @public
*/
export interface Collection<T extends AttachedDoc> extends Type<number> {
of: Ref<Class<T>>
}
/**
* @public
*/

View File

@ -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<Class<Type<boolean>>>,
TypeTimestamp: '' as Ref<Class<Type<Timestamp>>>,
TypeDate: '' as Ref<Class<Type<Timestamp | Date>>>,
RefTo: '' as Ref<Class<RefTo<Doc>>>,
Collection: '' as Ref<Class<Collection<AttachedDoc>>>,
Bag: '' as Ref<Class<Type<Record<string, PropertyType>>>>
},
interface: {

View File

@ -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<string> {
/**
* @public
*/
export function TypeRef (_class: Ref<Class<Doc>>): Type<string> {
return { _class: _class, label: 'TypeRef' as IntlString }
export function TypeRef (_class: Ref<Class<Doc>>): RefTo<Doc> {
return { _class: core.class.RefTo, to: _class, label: 'TypeRef' as IntlString }
}
/**
* @public
*/
export function Collection<T extends AttachedDoc> (clazz: Ref<Class<T>>): TypeCollection<T> {
return { _class: core.class.Collection, of: clazz, label: 'Collection' as IntlString }
}
/**

View File

@ -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)
}
})
}

View File

@ -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<Class<Obj>>): 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<AttachedDoc>
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))
}
}