import core, { AnyAttribute, Class, Client, Doc, Ref, TxOperations } from '@anticrm/core' /** * @public */ export interface KeyedAttribute { key: string attr: AnyAttribute } export async function updateAttribute ( client: TxOperations, object: Doc, _class: Ref>, attribute: KeyedAttribute, value: any ): Promise { const doc = object const attributeKey = attribute.key if ((doc as any)[attributeKey] === value) return const attr = attribute.attr if (client.getHierarchy().isMixin(attr.attributeOf)) { await client.updateMixin(doc._id, _class, doc.space, attr.attributeOf, { [attributeKey]: value }) } else { if (client.getHierarchy().isDerived(attribute.attr.type._class, core.class.ArrOf)) { const oldvalue: any[] = (object as any)[attributeKey] ?? [] const val: any[] = value const toPull = oldvalue.filter((it: any) => !val.includes(it)) const toPush = val.filter((it) => !oldvalue.includes(it)) if (toPull.length > 0) { await client.update(object, { $pull: { [attributeKey]: { $in: toPull } } }) } if (toPush.length > 0) { await client.update(object, { $push: { [attributeKey]: { $each: toPush, $position: 0 } } }) } } else { await client.update(object, { [attributeKey]: value }) } } } export function getAttribute (client: Client, object: any, key: KeyedAttribute): any { // Check if attr is mixin and return it's value if (client.getHierarchy().isMixin(key.attr.attributeOf)) { return object[key.attr.attributeOf]?.[key.key] } else { return object[key.key] } }