Merge pull request #311 from hcengineering/tx-collection-cud

This commit is contained in:
Andrey Sobolev
2021-11-18 09:09:58 +07:00
committed by GitHub
23 changed files with 1218 additions and 1107 deletions
@@ -28,6 +28,7 @@ function extractBacklinks (backlinkId: Ref<Doc>, message: string, kids: NodeList
result.push({
attachedTo: kid.getAttribute('data-id') as Ref<Doc>,
attachedToClass: kid.getAttribute('data-class') as Ref<Class<Doc>>,
collection: kid.getAttribute('data-collection') ?? '',
backlinkId,
backlinkClass: chunter.class.Message,
message
File diff suppressed because it is too large Load Diff
+340 -326
View File
File diff suppressed because it is too large Load Diff
+3 -7
View File
@@ -17,7 +17,7 @@ import type { IntlString } from '@anticrm/platform'
import { Builder, Model, Prop, UX, TypeString, Index, TypeTimestamp } from '@anticrm/model'
import type { Ref, Doc, Class, Domain } from '@anticrm/core'
import { IndexKind } from '@anticrm/core'
import core, { TSpace, TDoc } from '@anticrm/model-core'
import core, { TSpace, TDoc, TAttachedDoc } from '@anticrm/model-core'
import type { Backlink, Channel, Message, Comment, Attachment } from '@anticrm/chunter'
import type { AnyComponent } from '@anticrm/ui'
@@ -42,9 +42,7 @@ export class TMessage extends TDoc implements Message {
}
@Model(chunter.class.Comment, core.class.Doc, DOMAIN_COMMENT)
export class TComment extends TDoc implements Comment {
attachedTo!: Ref<Doc>
attachedToClass!: Ref<Class<Doc>>
export class TComment extends TAttachedDoc implements Comment {
@Prop(TypeString(), 'Message' as IntlString)
@Index(IndexKind.FullText)
message!: string
@@ -58,9 +56,7 @@ export class TBacklink extends TComment implements Backlink {
@Model(chunter.class.Attachment, core.class.Doc, DOMAIN_ATTACHMENT)
@UX('File' as IntlString)
export class TAttachment extends TDoc implements Attachment {
attachedTo!: Ref<Doc>
attachedToClass!: Ref<Class<Doc>>
export class TAttachment extends TAttachedDoc implements Attachment {
@Prop(TypeString(), 'Name' as IntlString)
name!: string
+8 -1
View File
@@ -14,7 +14,7 @@
//
import type { IntlString } from '@anticrm/platform'
import type { Account, AnyAttribute, Class, ClassifierKind, Doc, Domain, Mixin, Obj, Ref, Space, Timestamp, Type } from '@anticrm/core'
import type { Account, AnyAttribute, AttachedDoc, Class, ClassifierKind, Doc, Domain, Mixin, Obj, Ref, Space, Timestamp, Type } from '@anticrm/core'
import { DOMAIN_MODEL } from '@anticrm/core'
import { Model, Prop, TypeTimestamp } from '@anticrm/model'
import core from './component'
@@ -36,6 +36,13 @@ export class TDoc extends TObj implements Doc {
modifiedBy!: Ref<Account>
}
@Model(core.class.AttachedDoc, core.class.Doc)
export class TAttachedDoc extends TDoc implements AttachedDoc {
attachedTo!: Ref<Doc>
attachedToClass!: Ref<Class<Doc>>
collection!: string
}
@Model(core.class.Class, core.class.Doc, DOMAIN_MODEL)
export class TClass extends TDoc implements Class<Obj> {
kind!: ClassifierKind
+4 -3
View File
@@ -15,9 +15,9 @@
import { Builder } from '@anticrm/model'
import core from './component'
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString, TTypeBoolean, TTypeTimestamp } from './core'
import { TAttribute, TClass, TDoc, TMixin, TObj, TType, TTypeString, TTypeBoolean, TTypeTimestamp, TAttachedDoc } from './core'
import { TSpace, TAccount, TState, TSpaceWithStates, TDocWithState } from './security'
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag, TTxRemoveDoc, TTxBulkWrite, TTxAddCollection } from './tx'
import { TTx, TTxCreateDoc, TTxMixin, TTxUpdateDoc, TTxCUD, TTxPutBag, TTxRemoveDoc, TTxBulkWrite, TTxCollectionCUD } from './tx'
export * from './core'
export * from './security'
@@ -33,7 +33,8 @@ export function createModel (builder: Builder): void {
TTx,
TTxCUD,
TTxCreateDoc,
TTxAddCollection,
TAttachedDoc,
TTxCollectionCUD,
TTxPutBag,
TTxMixin,
TTxUpdateDoc,
+1 -1
View File
@@ -47,7 +47,7 @@ export class TState extends TDoc implements State {
color!: string
}
@Model(core.class.DocWithState, core.class.Doc)
@Model(core.class.DocWithState, core.class.AttachedDoc)
export class TDocWithState extends TDoc {
@Prop(TypeString(), 'State' as IntlString)
state!: Ref<State>
+14 -15
View File
@@ -14,25 +14,25 @@
//
import type {
AttachedDoc,
Class,
Data,
Doc,
DocumentUpdate,
ExtendedAttributes,
Mixin,
PropertyType,
Ref,
Space,
Tx,
TxCUD,
TxCreateDoc,
TxRemoveDoc,
TxUpdateDoc,
TxMixin,
Mixin,
ExtendedAttributes,
PropertyType,
TxPutBag,
TxBulkWrite,
AttachedDoc,
TxAddCollection
TxCollectionCUD,
TxCreateDoc,
TxCUD,
TxMixin,
TxPutBag,
TxRemoveDoc,
TxUpdateDoc
} from '@anticrm/core'
import { DOMAIN_TX } from '@anticrm/core'
import { Model } from '@anticrm/model'
@@ -57,11 +57,10 @@ export class TTxCreateDoc<T extends Doc> extends TTxCUD<T> implements TxCreateDo
attributes!: Data<T>
}
@Model(core.class.TxAddCollection, core.class.TxCreateDoc)
export class TTxAddCollection<T extends AttachedDoc> extends TTxCreateDoc<T> implements TxAddCollection<T> {
@Model(core.class.TxCollectionCUD, core.class.TxCUD)
export class TTxCollectionCUD<T extends Doc, P extends AttachedDoc> extends TTxCUD<T> implements TxCollectionCUD<T, P> {
collection!: string
attachedTo!: Ref<Doc>
attachedToClass!: Ref<Class<Doc>>
tx!: TxCUD<P>
}
@Model(core.class.TxPutBag, core.class.TxCUD)
+1
View File
@@ -62,6 +62,7 @@ export class TApplicant extends TDocWithState implements Applicant {
attachedTo!: Ref<Candidate>
attachedToClass!: Ref<Class<Candidate>>
collection!: string
@Prop(TypeString(), 'Attachments' as IntlString)
attachments?: number
+37 -46
View File
@@ -13,7 +13,7 @@
// limitations under the License.
//
import type { Class, Obj, Ref } from '../classes'
import type { Class, Obj, Ref, Doc } from '../classes'
import core from '../component'
import { Hierarchy } from '../hierarchy'
import { ModelDb, TxDb } from '../memdb'
@@ -23,24 +23,37 @@ import { genMinModel, test, TestMixin } from './minmodel'
const txes = genMinModel()
async function createModel (): Promise<{ model: ModelDb, hierarchy: Hierarchy }> {
async function createModel (): Promise<{ model: ModelDb, hierarchy: Hierarchy, txDb: TxDb }> {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
for (const tx of txes) {
hierarchy.tx(tx)
}
const model = new ModelDb(hierarchy)
for (const tx of txes) await model.tx(tx)
return { model, hierarchy }
for (const tx of txes) {
await model.tx(tx)
}
const txDb = new TxDb(hierarchy)
for (const tx of txes) await txDb.tx(tx)
return { model, hierarchy, txDb }
}
describe('memdb', () => {
it('should save all tx', async () => {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
const txDb = new TxDb(hierarchy)
for (const tx of txes) await txDb.tx(tx)
const { txDb } = await createModel()
const result = await txDb.findAll(core.class.Tx, {})
expect(result.length).toBe(txes.filter((tx) => tx._class === core.class.TxCreateDoc).length)
})
it('should query model', async () => {
const { model } = await createModel()
const result = await model.findAll(core.class.Class, {})
expect(result.length).toBeGreaterThan(5)
const result2 = await model.findAll('class:workbench.Application' as Ref<Class<Doc>>, { _id: undefined })
expect(result2).toHaveLength(0)
})
it('should create space', async () => {
const { model } = await createModel()
@@ -65,7 +78,8 @@ describe('memdb', () => {
it('should query model', async () => {
const { model } = await createModel()
const result = await model.findAll(core.class.Class, {})
expect(result.length).toBe(10)
const names = result.map(d => d._id)
expect(names.includes(core.class.Class)).toBe(true)
const result2 = await model.findAll(core.class.Class, { _id: undefined })
expect(result2.length).toBe(0)
})
@@ -103,10 +117,7 @@ describe('memdb', () => {
})
it('should query model with params', async () => {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
const model = new ModelDb(hierarchy)
for (const tx of txes) await model.tx(tx)
const { model } = await createModel()
const first = await model.findAll(core.class.Class, {
_id: txes[1].objectId as Ref<Class<Obj>>,
kind: 0
@@ -132,10 +143,7 @@ describe('memdb', () => {
})
it('should query model like params', async () => {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
const model = new ModelDb(hierarchy)
for (const tx of txes) await model.tx(tx)
const { model } = await createModel()
const expectedLength = txes.filter((tx) => tx.objectSpace === core.space.Model).length
const without = await model.findAll(core.class.Doc, {
space: { $like: core.space.Model }
@@ -205,34 +213,17 @@ describe('memdb', () => {
expect(numberSort[0].modifiedOn).toBeLessThanOrEqual(numberSort[numberSortDesc.length - 1].modifiedOn)
})
// it('should throw error', async () => {
// expect.assertions(1)
// const errorTx: TxAddCollection<Doc, Emb> = {
// _id: '60b73133d22498e666800cd2' as Ref<TxAddCollection<Doc, Emb>>,
// _class: 'class:core.TxAddCollection' as Ref<Class<TxAddCollection<Doc, Emb>>>,
// space: core.space.Tx,
// modifiedBy: 'xxx' as Ref<Account>,
// modifiedOn: 0,
// objectId: 'class:test.MyClass' as Ref<Doc>,
// objectSpace: core.space.Model,
// itemClass: 'class:core.Attribute' as Ref<Class<Doc>>,
// collection: 'attributes',
// localId: 'name',
// attributes: {
// _class: 'class:core.Attribute' as Ref<Class<Doc>>,
// // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
// __embedded: {
// _class: 'class:core.Attribute' as Ref<Class<Doc>>
// } as Emb
// }
// }
it('should add attached document', async () => {
const { model } = await createModel()
// const hierarchy = new Hierarchy()
// for (const tx of txes) hierarchy.tx(tx)
// const model = new ModelDb(hierarchy)
const client = new TxOperations(model, core.account.System)
const result = await client.findAll(core.class.Space, {})
expect(result).toHaveLength(2)
// await model.tx(errorTx).catch((error: Error) => {
// expect(error.message).toBe('ERROR: status:core.ObjectNotFound')
// })
// })
await client.addCollection(test.class.TestComment, core.space.Model, result[0]._id, result[0]._class, 'comments', {
message: 'msg'
})
const result2 = await client.findAll(test.class.TestComment, {})
expect(result2).toHaveLength(1)
})
})
+19 -7
View File
@@ -13,12 +13,12 @@
// limitations under the License.
//
import type { Plugin, IntlString } from '@anticrm/platform'
import type { IntlString, Plugin } from '@anticrm/platform'
import { plugin } from '@anticrm/platform'
import type { Class, Data, Doc, Obj, Ref, Mixin, Arr } from '../classes'
import { ClassifierKind, DOMAIN_MODEL } from '../classes'
import type { TxCUD, TxCreateDoc } from '../tx'
import type { Arr, Class, Data, Doc, Mixin, Obj, Ref } from '../classes'
import { AttachedDoc, ClassifierKind, DOMAIN_MODEL } from '../classes'
import core from '../component'
import type { TxCreateDoc, TxCUD } from '../tx'
import { DOMAIN_TX, TxFactory } from '../tx'
const txFactory = new TxFactory(core.account.System)
@@ -35,9 +35,16 @@ export interface TestMixin extends Doc {
arr: Arr<string>
}
export interface AttachedComment extends AttachedDoc {
message: string
}
export const test = plugin('test' as Plugin, {
mixin: {
TestMixin: '' as Ref<Mixin<TestMixin>>
},
class: {
TestComment: '' as Ref<Class<AttachedComment>>
}
})
@@ -50,17 +57,22 @@ export function genMinModel (): TxCUD<Doc>[] {
// Fill Tx'es with basic model classes.
txes.push(createClass(core.class.Obj, { label: 'Obj' as IntlString, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.Doc, { label: 'Doc' as IntlString, extends: core.class.Obj, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.AttachedDoc, { label: 'AttachedDoc' as IntlString, extends: core.class.Doc, kind: ClassifierKind.MIXIN }))
txes.push(createClass(core.class.Class, { label: 'Class' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
txes.push(createClass(core.class.Space, { label: 'Space' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
txes.push(createClass(core.class.Account, { label: 'Account' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_MODEL }))
txes.push(createClass(core.class.Tx, { label: 'Tx' as IntlString, extends: core.class.Doc, kind: ClassifierKind.CLASS, domain: DOMAIN_TX }))
txes.push(createClass(core.class.TxCreateDoc, { label: 'TxCreateDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxUpdateDoc, { label: 'TxUpdateDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxRemoveDoc, { label: 'TxRemoveDoc' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxCUD, { label: 'TxCUD' as IntlString, extends: core.class.Tx, kind: ClassifierKind.CLASS, domain: DOMAIN_TX }))
txes.push(createClass(core.class.TxCreateDoc, { label: 'TxCreateDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxUpdateDoc, { label: 'TxUpdateDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxRemoveDoc, { label: 'TxRemoveDoc' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
txes.push(createClass(core.class.TxCollectionCUD, { label: 'TxCollectionCUD' as IntlString, extends: core.class.TxCUD, kind: ClassifierKind.CLASS }))
txes.push(createClass(test.mixin.TestMixin, { label: 'TestMixin' as IntlString, extends: core.class.Doc, kind: ClassifierKind.MIXIN }))
txes.push(createClass(test.class.TestComment, { label: 'TestComment' as IntlString, extends: core.class.AttachedDoc, kind: ClassifierKind.CLASS }))
txes.push(
createDoc(core.class.Space, {
name: 'Sp1',
+1
View File
@@ -67,6 +67,7 @@ export interface UXObject extends Obj {
export interface AttachedDoc extends Doc {
attachedTo: Ref<Doc>
attachedToClass: Ref<Class<Doc>>
collection: string
}
/**
+3 -2
View File
@@ -15,7 +15,7 @@
import type { Plugin, StatusCode } from '@anticrm/platform'
import { plugin } from '@anticrm/platform'
import type { Account, Class, Doc, Obj, Ref, Space, AnyAttribute, State, Type, PropertyType, SpaceWithStates, Timestamp, DocWithState, AttachedDoc } from './classes'
import type { Tx, TxAddCollection, TxBulkWrite, TxCreateDoc, TxCUD, TxMixin, TxPutBag, TxRemoveDoc, TxUpdateDoc } from './tx'
import type { Tx, TxCollectionCUD, TxBulkWrite, TxCreateDoc, TxCUD, TxMixin, TxPutBag, TxRemoveDoc, TxUpdateDoc } from './tx'
/**
* @public
@@ -26,13 +26,14 @@ export default plugin(coreId, {
class: {
Obj: '' as Ref<Class<Obj>>,
Doc: '' as Ref<Class<Doc>>,
AttachedDoc: '' as Ref<Class<AttachedDoc>>,
Class: '' as Ref<Class<Class<Obj>>>,
Attribute: '' as Ref<Class<AnyAttribute>>,
Tx: '' as Ref<Class<Tx>>,
TxBulkWrite: '' as Ref<Class<TxBulkWrite>>,
TxCUD: '' as Ref<Class<TxCUD<Doc>>>,
TxCreateDoc: '' as Ref<Class<TxCreateDoc<Doc>>>,
TxAddCollection: '' as Ref<Class<TxAddCollection<AttachedDoc>>>,
TxCollectionCUD: '' as Ref<Class<TxCollectionCUD<Doc, AttachedDoc>>>,
TxMixin: '' as Ref<Class<TxMixin<Doc, Doc>>>,
TxUpdateDoc: '' as Ref<Class<TxUpdateDoc<Doc>>>,
TxRemoveDoc: '' as Ref<Class<TxRemoveDoc<Doc>>>,
+67 -24
View File
@@ -42,12 +42,14 @@ export interface TxCreateDoc<T extends Doc> extends TxCUD<T> {
}
/**
*
* Will perform create/update/delete of attached documents.
*
* @public
*/
export interface TxAddCollection<T extends AttachedDoc> extends TxCreateDoc<T> {
export interface TxCollectionCUD<T extends Doc, P extends AttachedDoc> extends TxCUD<T> {
collection: string
attachedTo: Ref<Doc>
attachedToClass: Ref<Class<Doc>>
tx: TxCUD<P>
}
/**
@@ -193,8 +195,8 @@ export abstract class TxProcessor implements WithTx {
switch (tx._class) {
case core.class.TxCreateDoc:
return await this.txCreateDoc(tx as TxCreateDoc<Doc>)
case core.class.TxAddCollection:
return await this.txAddCollection(tx as TxAddCollection<AttachedDoc>)
case core.class.TxCollectionCUD:
return await this.txCollectionCUD(tx as TxCollectionCUD<Doc, AttachedDoc>)
case core.class.TxUpdateDoc:
return await this.txUpdateDoc(tx as TxUpdateDoc<Doc>)
case core.class.TxRemoveDoc:
@@ -209,7 +211,7 @@ export abstract class TxProcessor implements WithTx {
throw new Error('TxProcessor: unhandled transaction class: ' + tx._class)
}
static createDoc2Doc<T extends Doc> (tx: TxCreateDoc<T>): T {
static createDoc2Doc<T extends Doc>(tx: TxCreateDoc<T>): T {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return {
_id: tx.objectId,
@@ -227,15 +229,26 @@ export abstract class TxProcessor implements WithTx {
protected abstract txRemoveDoc (tx: TxRemoveDoc<Doc>): Promise<TxResult>
protected abstract txMixin (tx: TxMixin<Doc, Doc>): Promise<TxResult>
protected txAddCollection (tx: TxAddCollection<AttachedDoc>): Promise<TxResult> {
const createTx: TxCreateDoc<Doc> = { ...tx }
createTx.attributes = { ...tx.attributes, attachedTo: tx.attachedTo, attachedToClass: tx.attachedToClass }
return this.txCreateDoc(createTx)
protected txCollectionCUD (tx: TxCollectionCUD<Doc, AttachedDoc>): Promise<TxResult> {
// We need update only create transactions to contain attached, attachedToClass.
if (tx.tx._class === core.class.TxCreateDoc) {
const createTx = tx.tx as TxCreateDoc<AttachedDoc>
const d: TxCreateDoc<AttachedDoc> = {
...createTx,
attributes: {
...createTx.attributes,
attachedTo: tx.objectId,
attachedToClass: tx.objectClass,
collection: tx.collection
}
}
return this.txCreateDoc(d)
}
return this.tx(tx.tx)
}
protected async txBulkWrite (bulkTx: TxBulkWrite): Promise<TxResult> {
for (const tx of bulkTx.txes) {
console.log('bulk', tx)
await this.tx(tx)
}
return {}
@@ -275,16 +288,42 @@ export class TxOperations implements Storage {
return tx.objectId
}
async addCollection<T extends AttachedDoc> (
_class: Ref<Class<T>>,
async addCollection<T extends Doc, P extends AttachedDoc>(
_class: Ref<Class<P>>,
space: Ref<Space>,
attachedTo: Ref<Doc>,
attachedToClass: Ref<Class<Doc>>,
attachedTo: Ref<T>,
attachedToClass: Ref<Class<T>>,
collection: string,
attributes: AttachedData<T>,
id?: Ref<T>
attributes: AttachedData<P>,
id?: Ref<P>
): Promise<Ref<T>> {
const tx = this.txFactory.createTxAddCollection(_class, space, attributes, attachedTo, attachedToClass, collection, id)
const tx = this.txFactory.createTxCollectionCUD<T, P>(
attachedToClass,
attachedTo,
space,
collection,
this.txFactory.createTxCreateDoc<P>(_class, space, attributes as unknown as Data<P>, id)
)
await this.storage.tx(tx)
return tx.objectId
}
async updateCollection<T extends Doc, P extends AttachedDoc>(
_class: Ref<Class<P>>,
space: Ref<Space>,
objectId: Ref<P>,
attachedTo: Ref<T>,
attachedToClass: Ref<Class<T>>,
collection: string,
operations: DocumentUpdate<P>
): Promise<Ref<T>> {
const tx = this.txFactory.createTxCollectionCUD(
attachedToClass,
attachedTo,
space,
collection,
this.txFactory.createTxUpdateDoc(_class, space, objectId, operations)
)
await this.storage.tx(tx)
return tx.objectId
}
@@ -352,20 +391,24 @@ export class TxFactory {
}
}
createTxAddCollection<T extends AttachedDoc>(_class: Ref<Class<T>>, space: Ref<Space>, attributes: AttachedData<T>, attachedTo: Ref<Doc>, attachedToClass: Ref<Class<Doc>>, collection: string, objectId?: Ref<T>): TxAddCollection<T> {
createTxCollectionCUD<T extends Doc, P extends AttachedDoc>(
_class: Ref<Class<T>>,
objectId: Ref<T>,
space: Ref<Space>,
collection: string,
tx: TxCUD<P>
): TxCollectionCUD<T, P> {
return {
_id: generateId(),
_class: core.class.TxAddCollection,
_class: core.class.TxCollectionCUD,
space: core.space.Tx,
objectId: objectId ?? generateId(),
objectId,
objectClass: _class,
objectSpace: space,
modifiedOn: Date.now(),
modifiedBy: this.account,
attributes: attributes as Data<T>,
collection,
attachedTo,
attachedToClass
tx
}
}
+3 -5
View File
@@ -15,13 +15,13 @@
-->
<script lang="ts">
import type { IntlString, Asset } from '@anticrm/platform'
import type { Asset } from '@anticrm/platform'
import type { Doc } from '@anticrm/core'
import { SortingOrder } from '@anticrm/core'
import { getClient, createQuery, Backlink } from '@anticrm/presentation'
import type { AnySvelteComponent } from '@anticrm/ui'
import { ReferenceInput } from '@anticrm/text-editor'
import { IconClose, IconExpand, IconActivity, ScrollBox, Grid, Label, Icon, IconToDo } from '@anticrm/ui'
import { IconClose, IconExpand, IconActivity, ScrollBox, Grid, Icon, IconToDo } from '@anticrm/ui'
import type { Comment } from '@anticrm/chunter'
import ActivityMsg from './ActivityMsg.svelte'
@@ -43,9 +43,7 @@
$: query.query(chunter.class.Comment, { attachedTo: object._id }, result => { comments = result }, { sort: { modifiedOn: SortingOrder.Descending } })
function onMessage(event: CustomEvent) {
client.createDoc(chunter.class.Comment, object.space, {
attachedTo: object._id,
attachedToClass: object._class,
client.addCollection(chunter.class.Comment, object.space, object._id, object._class, 'comments', {
message: event.detail
})
console.log(event.detail)
@@ -75,9 +75,7 @@
console.log('resume name', resume.name)
if (resume.uuid !== undefined) {
client.createDoc(chunter.class.Attachment, space, {
attachedTo: id,
attachedToClass: recruit.class.Candidate,
client.addCollection(chunter.class.Attachment, space, id, recruit.class.Candidate, 'attachments', {
name: resume.name,
file: resume.uuid,
size: resume.size,
@@ -16,7 +16,7 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Ref, Class, Doc, Space, SpaceWithStates, FindOptions, State, TxBulkWrite, TxCUD } from '@anticrm/core'
import type { Ref, Class, Doc, Space, SpaceWithStates, FindOptions, State, TxBulkWrite, TxCUD, AttachedDoc } from '@anticrm/core'
import { getResource } from '@anticrm/platform'
import { buildModel } from '../utils'
import { getClient } from '@anticrm/presentation'
@@ -81,7 +81,13 @@
const txes: TxCUD<Doc>[] = []
if (dragCardInitialState !== state) {
client.updateDoc(_class, space, id, { state })
if (client.getHierarchy().isDerived(_class, core.class.AttachedDoc)) {
const adoc: AttachedDoc = dragCard as AttachedDoc
// We need to update using updateCollection
client.updateCollection(_class, space, id as Ref<AttachedDoc>, adoc.attachedTo, adoc.attachedToClass, adoc.collection, { state })
} else {
client.updateDoc(_class, space, id, { state })
}
// txes.push(client.txFactory.createTxUpdateDoc(_class, space, id, { state }))
}
+5 -1
View File
@@ -14,7 +14,7 @@
// limitations under the License.
//
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class } from '@anticrm/core'
import type { Tx, TxCreateDoc, Data, Ref, Doc, TxFactory, Class, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
import type { FindAll } from '@anticrm/server-core'
import type { Message, Backlink } from '@anticrm/chunter'
import { parse, Node, HTMLElement } from 'node-html-parser'
@@ -29,6 +29,7 @@ function extractBacklinks (backlinkId: Ref<Doc>, message: string, kids: Node[]):
result.push({
attachedTo: (kid as HTMLElement).getAttribute('data-id') as Ref<Doc>,
attachedToClass: (kid as HTMLElement).getAttribute('data-class') as Ref<Class<Doc>>,
collection: (kid as HTMLElement).getAttribute('data-collection') ?? '',
backlinkId,
backlinkClass: chunter.class.Message,
message
@@ -48,6 +49,9 @@ function getBacklinks (backlinkId: Ref<Doc>, content: string): Data<Backlink>[]
* @public
*/
export async function OnMessage (tx: Tx, txFactory: TxFactory): Promise<Tx[]> {
if (tx._class === core.class.TxCollectionCUD) {
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
}
if (tx._class === core.class.TxCreateDoc) {
const createTx = tx as TxCreateDoc<Message>
if (createTx.objectClass === chunter.class.Message) {
+11 -8
View File
@@ -14,7 +14,7 @@
// limitations under the License.
//
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite, TxResult, TxAddCollection, AttachedDoc } from '@anticrm/core'
import type { ServerStorage, Domain, Tx, TxCUD, Doc, Ref, Class, DocumentQuery, FindResult, FindOptions, Storage, TxBulkWrite, TxResult, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
import core, { Hierarchy, DOMAIN_TX, ModelDb, TxFactory } from '@anticrm/core'
import type { FullTextAdapterFactory, FullTextAdapter } from './types'
import { FullTextIndex } from './fulltext'
@@ -107,13 +107,16 @@ class TServerStorage implements ServerStorage {
}
async processCollection (tx: Tx): Promise<Tx[]> {
if (tx._class === core.class.TxAddCollection) {
const createTx = tx as TxAddCollection<AttachedDoc>
const _id = createTx.attachedTo
const _class = createTx.attachedToClass
const attachedTo = (await this.findAll(_class, { _id }))[0]
const txFactory = new TxFactory(tx.modifiedBy)
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { [createTx.collection]: 1 } })]
if (tx._class === core.class.TxCollectionCUD) {
const colTx = tx as TxCollectionCUD<Doc, AttachedDoc>
const _id = colTx.objectId
const _class = colTx.objectClass
let attachedTo: Doc | undefined
if (colTx.tx._class === core.class.TxCreateDoc) {
attachedTo = (await this.findAll(_class, { _id }))[0]
const txFactory = new TxFactory(tx.modifiedBy)
return [txFactory.createTxUpdateDoc(_class, attachedTo.space, _id, { $inc: { [colTx.collection]: 1 } })]
}
}
return []
}
+4 -1
View File
@@ -14,7 +14,7 @@
// limitations under the License.
//
import type { Tx, Doc, TxCreateDoc, Ref, Account, Hierarchy } from '@anticrm/core'
import type { Tx, Doc, TxCreateDoc, Ref, Account, Hierarchy, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
import core, { TxFactory } from '@anticrm/core'
import { getResource } from '@anticrm/platform'
@@ -29,6 +29,9 @@ export class Triggers {
private readonly triggers: TriggerFunc[] = []
async tx (tx: Tx): Promise<void> {
if (tx._class === core.class.TxCollectionCUD) {
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
}
if (tx._class === core.class.TxCreateDoc) {
const createTx = tx as TxCreateDoc<Doc>
if (createTx.objectClass === serverCore.class.Trigger) {
+2 -2
View File
@@ -19,9 +19,9 @@
"eslint":"^7.32.0"
},
"dependencies": {
"@anticrm/core": "~0.6.11",
"@anticrm/core": "~0.6.12",
"@anticrm/platform": "~0.6.5",
"@anticrm/server-core": "~0.6.0",
"@anticrm/server-core": "~0.6.1",
"@anticrm/view": "~0.6.0"
}
}
+5 -1
View File
@@ -14,7 +14,7 @@
// limitations under the License.
//
import type { Tx, TxFactory, Doc, TxCreateDoc, DocWithState, State, TxRemoveDoc } from '@anticrm/core'
import type { Tx, TxFactory, Doc, TxCreateDoc, DocWithState, State, TxRemoveDoc, TxCollectionCUD, AttachedDoc } from '@anticrm/core'
import type { FindAll } from '@anticrm/server-core'
import core, { Hierarchy } from '@anticrm/core'
@@ -24,6 +24,10 @@ import view, { Kanban } from '@anticrm/view'
* @public
*/
export async function OnDocWithState (tx: Tx, txFactory: TxFactory, findAll: FindAll<Doc>, hierarchy: Hierarchy): Promise<Tx[]> {
if (tx._class === core.class.TxCollectionCUD) {
tx = (tx as TxCollectionCUD<Doc, AttachedDoc>).tx
}
if (hierarchy.isDerived(tx._class, core.class.TxCreateDoc)) {
const createTx = tx as TxCreateDoc<DocWithState>
if (hierarchy.isDerived(createTx.objectClass, core.class.DocWithState)) {
File diff suppressed because it is too large Load Diff