mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
Fix master tag remove (#8239)
This commit is contained in:
parent
f03ffa7aa4
commit
21eaf38daa
@ -59,7 +59,9 @@ import card from './plugin'
|
|||||||
export { cardId } from '@hcengineering/card'
|
export { cardId } from '@hcengineering/card'
|
||||||
|
|
||||||
@Model(card.class.MasterTag, core.class.Class)
|
@Model(card.class.MasterTag, core.class.Class)
|
||||||
export class TMasterTag extends TClass implements MasterTag {}
|
export class TMasterTag extends TClass implements MasterTag {
|
||||||
|
removed?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
@Model(card.class.Tag, core.class.Mixin)
|
@Model(card.class.Tag, core.class.Mixin)
|
||||||
export class TTag extends TMixin implements Tag {}
|
export class TTag extends TMixin implements Tag {}
|
||||||
@ -120,7 +122,7 @@ export function createModel (builder: Builder): void {
|
|||||||
)
|
)
|
||||||
|
|
||||||
builder.mixin(card.types.File, card.class.MasterTag, setting.mixin.Editable, {
|
builder.mixin(card.types.File, card.class.MasterTag, setting.mixin.Editable, {
|
||||||
value: true
|
value: false
|
||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
||||||
|
@ -42,11 +42,19 @@ export function createModel (builder: Builder): void {
|
|||||||
})
|
})
|
||||||
|
|
||||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
trigger: serverCard.trigger.OnMasterTagRemove,
|
trigger: serverCard.trigger.OnTagRemove,
|
||||||
isAsync: true,
|
|
||||||
txMatch: {
|
txMatch: {
|
||||||
_class: core.class.TxRemoveDoc,
|
_class: core.class.TxRemoveDoc,
|
||||||
objectClass: { $in: [card.class.MasterTag, card.class.Tag] }
|
objectClass: card.class.Tag
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||||
|
trigger: serverCard.trigger.OnMasterTagRemove,
|
||||||
|
txMatch: {
|
||||||
|
_class: core.class.TxUpdateDoc,
|
||||||
|
objectClass: card.class.MasterTag,
|
||||||
|
'operations.removed': true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -183,6 +183,14 @@ export class Hierarchy {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findClass<T extends Obj = Obj>(_class: Ref<Class<T>>): Class<T> | undefined {
|
||||||
|
const data = this.classifiers.get(_class)
|
||||||
|
if (data === undefined || this.isInterface(data)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
hasClass<T extends Obj = Obj>(_class: Ref<Class<T>>): boolean {
|
hasClass<T extends Obj = Obj>(_class: Ref<Class<T>>): boolean {
|
||||||
const data = this.classifiers.get(_class)
|
const data = this.classifiers.get(_class)
|
||||||
|
|
||||||
@ -214,14 +222,16 @@ export class Hierarchy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public findDomain (_class: Ref<Class<Doc>>): Domain | undefined {
|
public findDomain (_class: Ref<Class<Doc>>): Domain | undefined {
|
||||||
const klazz = this.getClass(_class)
|
const klazz = this.findClass(_class)
|
||||||
|
if (klazz === undefined) return
|
||||||
if (klazz.domain !== undefined) {
|
if (klazz.domain !== undefined) {
|
||||||
return klazz.domain
|
return klazz.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
let _klazz = klazz
|
let _klazz: Class<Doc> | undefined = klazz
|
||||||
while (_klazz.extends !== undefined) {
|
while (_klazz.extends !== undefined) {
|
||||||
_klazz = this.getClass(_klazz.extends)
|
_klazz = this.findClass(_klazz.extends)
|
||||||
|
if (_klazz === undefined) return
|
||||||
if (_klazz.domain !== undefined) {
|
if (_klazz.domain !== undefined) {
|
||||||
// Cache for next requests
|
// Cache for next requests
|
||||||
klazz.domain = _klazz.domain
|
klazz.domain = _klazz.domain
|
||||||
|
@ -1196,16 +1196,13 @@ export class LiveQuery implements WithTx, Client {
|
|||||||
|
|
||||||
private async handleDocRemove (q: Query, tx: TxRemoveDoc<Doc>): Promise<void> {
|
private async handleDocRemove (q: Query, tx: TxRemoveDoc<Doc>): Promise<void> {
|
||||||
const h = this.client.getHierarchy()
|
const h = this.client.getHierarchy()
|
||||||
|
if (q._class === tx.objectClass || h.isDerived(q._class, tx.objectClass) || h.isDerived(tx.objectClass, q._class)) {
|
||||||
if (q.result instanceof Promise) {
|
if (q.result instanceof Promise) {
|
||||||
q.result = await q.result
|
q.result = await q.result
|
||||||
}
|
}
|
||||||
const index = q.result.getDocs().find((p) => p._id === tx.objectId && h.isDerived(p._class, tx.objectClass))
|
const index = q.result.getDocs().find((p) => p._id === tx.objectId)
|
||||||
if (index !== undefined) {
|
if (index !== undefined) {
|
||||||
if (
|
if (q.options?.limit !== undefined && q.options.limit === q.result.length && q.query._id !== tx.objectId) {
|
||||||
q.options?.limit !== undefined &&
|
|
||||||
q.options.limit === q.result.length &&
|
|
||||||
h.isDerived(q._class, tx.objectClass)
|
|
||||||
) {
|
|
||||||
await this.refresh(q)
|
await this.refresh(q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1217,6 +1214,7 @@ export class LiveQuery implements WithTx, Client {
|
|||||||
}
|
}
|
||||||
await this.callback(q, true)
|
await this.callback(q, true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await this.handleDocRemoveLookup(q, tx)
|
await this.handleDocRemoveLookup(q, tx)
|
||||||
await this.handleDocRemoveRelation(q, tx)
|
await this.handleDocRemoveRelation(q, tx)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,15 @@
|
|||||||
import { Panel } from '@hcengineering/panel'
|
import { Panel } from '@hcengineering/panel'
|
||||||
import { getResource } from '@hcengineering/platform'
|
import { getResource } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { Button, EditBox, FocusHandler, IconMoreH, createFocusManager } from '@hcengineering/ui'
|
import {
|
||||||
|
Button,
|
||||||
|
EditBox,
|
||||||
|
FocusHandler,
|
||||||
|
IconMoreH,
|
||||||
|
createFocusManager,
|
||||||
|
getCurrentLocation,
|
||||||
|
navigate
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
import { ParentsNavigator, RelationsEditor, getDocMixins, showMenu } from '@hcengineering/view-resources'
|
import { ParentsNavigator, RelationsEditor, getDocMixins, showMenu } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||||
@ -70,8 +78,14 @@
|
|||||||
|
|
||||||
$: _id !== undefined &&
|
$: _id !== undefined &&
|
||||||
query.query(card.class.Card, { _id }, async (result) => {
|
query.query(card.class.Card, { _id }, async (result) => {
|
||||||
|
if (result.length > 0) {
|
||||||
;[doc] = result
|
;[doc] = result
|
||||||
title = doc?.title ?? ''
|
title = doc?.title ?? ''
|
||||||
|
} else {
|
||||||
|
const loc = getCurrentLocation()
|
||||||
|
loc.path.length = 3
|
||||||
|
navigate(loc)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$: canSave = title.trim().length > 0
|
$: canSave = title.trim().length > 0
|
||||||
|
@ -13,28 +13,38 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { MasterTag } from '@hcengineering/card'
|
||||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||||
import { getClient } from '@hcengineering/presentation'
|
import { IntlString } from '@hcengineering/platform'
|
||||||
|
import { createQuery } from '@hcengineering/presentation'
|
||||||
import { Separator, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
import { Separator, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||||
import { SpecialView } from '@hcengineering/workbench-resources'
|
import { SpecialView } from '@hcengineering/workbench-resources'
|
||||||
|
import { onDestroy } from 'svelte'
|
||||||
import card from '../plugin'
|
import card from '../plugin'
|
||||||
import Navigator from './Navigator.svelte'
|
import Navigator from './Navigator.svelte'
|
||||||
import { onDestroy } from 'svelte'
|
|
||||||
import { IntlString } from '@hcengineering/platform'
|
|
||||||
|
|
||||||
export let currentSpace: Ref<Class<Doc>>
|
export let currentSpace: Ref<Class<Doc>>
|
||||||
|
|
||||||
$: _class = currentSpace
|
let classes: MasterTag[] = []
|
||||||
|
let allClasses: MasterTag[] = []
|
||||||
|
|
||||||
const client = getClient()
|
function fillClasses (tags: MasterTag[]): void {
|
||||||
|
classes = tags.filter((it) => it.extends === card.class.Card).sort((a, b) => a.label.localeCompare(b.label))
|
||||||
|
}
|
||||||
|
|
||||||
$: label = getLabel(_class)
|
const query = createQuery()
|
||||||
|
query.query(card.class.MasterTag, {}, (res) => {
|
||||||
|
const notRemoved = res.filter((it) => it.removed !== true)
|
||||||
|
allClasses = notRemoved
|
||||||
|
fillClasses(notRemoved)
|
||||||
|
})
|
||||||
|
|
||||||
function getLabel (_class: Ref<Class<Doc>> | undefined): IntlString | undefined {
|
$: clazz = allClasses.find((it) => it._id === currentSpace)
|
||||||
try {
|
|
||||||
const clazz = _class !== undefined ? client.getHierarchy().getClass(_class) : undefined
|
$: label = getLabel(clazz)
|
||||||
|
|
||||||
|
function getLabel (clazz: MasterTag | undefined): IntlString | undefined {
|
||||||
return clazz?.label
|
return clazz?.label
|
||||||
} catch {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let replacedPanel: HTMLElement
|
let replacedPanel: HTMLElement
|
||||||
@ -44,7 +54,7 @@
|
|||||||
|
|
||||||
<div class="hulyPanels-container">
|
<div class="hulyPanels-container">
|
||||||
{#if $deviceInfo.navigator.visible}
|
{#if $deviceInfo.navigator.visible}
|
||||||
<Navigator bind:_class />
|
<Navigator _class={clazz?._id} {classes} {allClasses} />
|
||||||
<Separator
|
<Separator
|
||||||
name={'workbench'}
|
name={'workbench'}
|
||||||
float={$deviceInfo.navigator.float}
|
float={$deviceInfo.navigator.float}
|
||||||
@ -56,8 +66,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="hulyComponent" bind:this={replacedPanel}>
|
<div class="hulyComponent" bind:this={replacedPanel}>
|
||||||
{#if _class !== undefined && label !== undefined}
|
{#if clazz !== undefined && label !== undefined}
|
||||||
<SpecialView {_class} {label} icon={card.icon.Card} />
|
<SpecialView _class={clazz._id} {label} icon={card.icon.Card} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { Card, CardEvents, cardId, MasterTag } from '@hcengineering/card'
|
import { Card, CardEvents, cardId, MasterTag } from '@hcengineering/card'
|
||||||
import core, { Class, Data, Doc, fillDefaults, MarkupBlobRef, Ref, SortingOrder } from '@hcengineering/core'
|
import core, { Class, Data, Doc, fillDefaults, MarkupBlobRef, Ref, SortingOrder } from '@hcengineering/core'
|
||||||
import { translate } from '@hcengineering/platform'
|
import { translate } from '@hcengineering/platform'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { makeRank } from '@hcengineering/rank'
|
import { makeRank } from '@hcengineering/rank'
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@ -31,25 +31,15 @@
|
|||||||
import card from '../plugin'
|
import card from '../plugin'
|
||||||
import TagHierarchy from './TagHierarchy.svelte'
|
import TagHierarchy from './TagHierarchy.svelte'
|
||||||
|
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>> | undefined
|
||||||
|
export let classes: MasterTag[] = []
|
||||||
|
export let allClasses: MasterTag[] = []
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
let classes: MasterTag[] = []
|
|
||||||
let allClasses: MasterTag[] = []
|
|
||||||
|
|
||||||
function fillClasses (tags: MasterTag[]): void {
|
|
||||||
classes = tags.filter((it) => it.extends === card.class.Card).sort((a, b) => a.label.localeCompare(b.label))
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = createQuery()
|
|
||||||
query.query(card.class.MasterTag, { _class: card.class.MasterTag }, (res) => {
|
|
||||||
allClasses = res
|
|
||||||
fillClasses(res)
|
|
||||||
})
|
|
||||||
|
|
||||||
async function createCard (): Promise<void> {
|
async function createCard (): Promise<void> {
|
||||||
|
if (_class === undefined) return
|
||||||
const lastOne = await client.findOne(card.class.Card, {}, { sort: { rank: SortingOrder.Descending } })
|
const lastOne = await client.findOne(card.class.Card, {}, { sort: { rank: SortingOrder.Descending } })
|
||||||
const title = await translate(card.string.Card, {})
|
const title = await translate(card.string.Card, {})
|
||||||
|
|
||||||
@ -63,7 +53,7 @@
|
|||||||
|
|
||||||
const filledData = fillDefaults(hierarchy, data, _class)
|
const filledData = fillDefaults(hierarchy, data, _class)
|
||||||
|
|
||||||
const _id = await client.createDoc(_class ?? card.class.Card, core.space.Workspace, filledData)
|
const _id = await client.createDoc(_class, core.space.Workspace, filledData)
|
||||||
|
|
||||||
Analytics.handleEvent(CardEvents.CardCreated)
|
Analytics.handleEvent(CardEvents.CardCreated)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
themeStore
|
themeStore
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { IconPicker } from '@hcengineering/view-resources'
|
import { IconPicker } from '@hcengineering/view-resources'
|
||||||
|
import setting from '@hcengineering/setting'
|
||||||
import card from '../../plugin'
|
import card from '../../plugin'
|
||||||
import { deleteMasterTag } from '../../utils'
|
import { deleteMasterTag } from '../../utils'
|
||||||
|
|
||||||
@ -67,6 +68,9 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const h = client.getHierarchy()
|
||||||
|
$: isEditable = h.hasMixin(masterTag, setting.mixin.Editable) && h.as(masterTag, setting.mixin.Editable).value
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="hulyComponent-content__column-group">
|
<div class="hulyComponent-content__column-group">
|
||||||
@ -95,6 +99,8 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ButtonIcon icon={IconDelete} size="small" kind="secondary" on:click={handleDelete} />
|
{#if isEditable}
|
||||||
|
<ButtonIcon icon={IconDelete} size={'large'} kind={'tertiary'} on:click={handleDelete} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,15 +41,9 @@
|
|||||||
|
|
||||||
let tags: MasterTag[] = []
|
let tags: MasterTag[] = []
|
||||||
const tagsQuery = createQuery()
|
const tagsQuery = createQuery()
|
||||||
$: tagsQuery.query(
|
$: tagsQuery.query(card.class.MasterTag, {}, (result) => {
|
||||||
card.class.MasterTag,
|
tags = result.filter((p) => p.removed !== true).sort((a, b) => a.label.localeCompare(b.label))
|
||||||
{
|
})
|
||||||
_class: card.class.MasterTag
|
|
||||||
},
|
|
||||||
(result) => {
|
|
||||||
tags = result.sort((a, b) => a.label.localeCompare(b.label))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
function selectProjectType (id: string): void {
|
function selectProjectType (id: string): void {
|
||||||
clearSettingsStore()
|
clearSettingsStore()
|
||||||
|
@ -39,15 +39,13 @@ import card from './plugin'
|
|||||||
export async function deleteMasterTag (tag: MasterTag | undefined, onDelete?: () => void): Promise<void> {
|
export async function deleteMasterTag (tag: MasterTag | undefined, onDelete?: () => void): Promise<void> {
|
||||||
if (tag !== undefined) {
|
if (tag !== undefined) {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const objects = await client.findOne(tag._id, {})
|
|
||||||
if (objects !== undefined) {
|
|
||||||
if (tag._class === card.class.MasterTag) {
|
if (tag._class === card.class.MasterTag) {
|
||||||
showPopup(MessageBox, {
|
showPopup(MessageBox, {
|
||||||
label: card.string.DeleteMasterTag,
|
label: card.string.DeleteMasterTag,
|
||||||
message: card.string.DeleteMasterTagConfirm,
|
message: card.string.DeleteMasterTagConfirm,
|
||||||
action: async () => {
|
action: async () => {
|
||||||
onDelete?.()
|
onDelete?.()
|
||||||
await client.remove(tag)
|
await client.update(tag, { removed: true })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -60,10 +58,6 @@ export async function deleteMasterTag (tag: MasterTag | undefined, onDelete?: ()
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
onDelete?.()
|
|
||||||
await client.remove(tag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,9 @@ import type { AnyComponent } from '@hcengineering/ui'
|
|||||||
|
|
||||||
export * from './analytics'
|
export * from './analytics'
|
||||||
|
|
||||||
export interface MasterTag extends Class<Card> {}
|
export interface MasterTag extends Class<Card> {
|
||||||
|
removed?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface Tag extends MasterTag, Mixin<Card> {}
|
export interface Tag extends MasterTag, Mixin<Card> {}
|
||||||
|
|
||||||
|
@ -42,6 +42,11 @@
|
|||||||
|
|
||||||
$: getAssociations(object)
|
$: getAssociations(object)
|
||||||
|
|
||||||
|
const q = createQuery()
|
||||||
|
$: q.query(core.class.Association, {}, () => {
|
||||||
|
getAssociations(object)
|
||||||
|
})
|
||||||
|
|
||||||
let relationsA: Record<Ref<Association>, Doc[]> = {}
|
let relationsA: Record<Ref<Association>, Doc[]> = {}
|
||||||
let relationsB: Record<Ref<Association>, Doc[]> = {}
|
let relationsB: Record<Ref<Association>, Doc[]> = {}
|
||||||
|
|
||||||
|
@ -13,10 +13,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import card, { Card, DOMAIN_CARD, MasterTag, Tag } from '@hcengineering/card'
|
import card, { Card, MasterTag, Tag } from '@hcengineering/card'
|
||||||
import core, {
|
import core, {
|
||||||
AnyAttribute,
|
AnyAttribute,
|
||||||
Class,
|
|
||||||
Data,
|
Data,
|
||||||
Doc,
|
Doc,
|
||||||
Ref,
|
Ref,
|
||||||
@ -27,8 +26,8 @@ import core, {
|
|||||||
TxUpdateDoc
|
TxUpdateDoc
|
||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import { TriggerControl } from '@hcengineering/server-core'
|
import { TriggerControl } from '@hcengineering/server-core'
|
||||||
import view from '@hcengineering/view'
|
|
||||||
import setting from '@hcengineering/setting'
|
import setting from '@hcengineering/setting'
|
||||||
|
import view from '@hcengineering/view'
|
||||||
|
|
||||||
async function OnAttribute (ctx: TxCreateDoc<AnyAttribute>[], control: TriggerControl): Promise<Tx[]> {
|
async function OnAttribute (ctx: TxCreateDoc<AnyAttribute>[], control: TriggerControl): Promise<Tx[]> {
|
||||||
const attr = TxProcessor.createDoc2Doc(ctx[0])
|
const attr = TxProcessor.createDoc2Doc(ctx[0])
|
||||||
@ -91,51 +90,83 @@ async function OnAttributeRemove (ctx: TxRemoveDoc<AnyAttribute>[], control: Tri
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
async function OnMasterTagRemove (ctx: TxRemoveDoc<MasterTag | Tag>[], control: TriggerControl): Promise<Tx[]> {
|
async function OnMasterTagRemove (ctx: TxUpdateDoc<MasterTag>[], control: TriggerControl): Promise<Tx[]> {
|
||||||
|
const updateTx = ctx[0]
|
||||||
|
if (updateTx.operations.removed !== true) return []
|
||||||
|
const res: Tx[] = []
|
||||||
|
const desc = control.hierarchy.getDescendants(updateTx.objectId)
|
||||||
|
// should remove objects if masterTag
|
||||||
|
const cards = await control.findAll<Card>(control.ctx, updateTx.objectId, {})
|
||||||
|
for (const doc of cards) {
|
||||||
|
res.push(control.txFactory.createTxRemoveDoc(card.class.Card, doc.space, doc._id))
|
||||||
|
}
|
||||||
|
for (const des of desc) {
|
||||||
|
res.push(...(await removeTagRelations(control, des)))
|
||||||
|
}
|
||||||
|
for (const des of desc) {
|
||||||
|
if (des === updateTx.objectId) continue
|
||||||
|
const _class = control.hierarchy.findClass(des)
|
||||||
|
if (_class === undefined) continue
|
||||||
|
if (_class._class === card.class.MasterTag) {
|
||||||
|
res.push(
|
||||||
|
control.txFactory.createTxUpdateDoc<MasterTag>(card.class.MasterTag, core.space.Model, des, {
|
||||||
|
removed: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
res.push(control.txFactory.createTxRemoveDoc(card.class.Tag, core.space.Model, des))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async function OnTagRemove (ctx: TxRemoveDoc<Tag>[], control: TriggerControl): Promise<Tx[]> {
|
||||||
const removeTx = ctx[0]
|
const removeTx = ctx[0]
|
||||||
const removedTag = control.removedMap.get(removeTx.objectId)
|
const removedTag = control.removedMap.get(removeTx.objectId)
|
||||||
if (removedTag === undefined) return []
|
if (removedTag === undefined) return []
|
||||||
const res: Tx[] = []
|
const res: Tx[] = []
|
||||||
// should remove objects if masterTag
|
const desc = control.hierarchy.getDescendants(removeTx.objectId)
|
||||||
if (removedTag._class === card.class.MasterTag) {
|
|
||||||
const cards = await control.lowLevel.rawFindAll(DOMAIN_CARD, { _class: removedTag._id as Ref<Class<Doc>> })
|
for (const des of desc) {
|
||||||
for (const card of cards) {
|
if (des === removeTx.objectId) continue
|
||||||
res.push(control.txFactory.createTxRemoveDoc(card._class, card.space, card._id))
|
res.push(control.txFactory.createTxRemoveDoc(card.class.Tag, core.space.Model, des))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.push(...(await removeTagRelations(control, removeTx.objectId)))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeTagRelations (control: TriggerControl, tag: Ref<Tag | MasterTag>): Promise<Tx[]> {
|
||||||
|
const res: Tx[] = []
|
||||||
const viewlets = await control.findAll(control.ctx, view.class.Viewlet, {
|
const viewlets = await control.findAll(control.ctx, view.class.Viewlet, {
|
||||||
attachTo: removeTx.objectId
|
attachTo: tag
|
||||||
})
|
})
|
||||||
for (const viewlet of viewlets) {
|
for (const viewlet of viewlets) {
|
||||||
res.push(control.txFactory.createTxRemoveDoc(viewlet._class, viewlet.space, viewlet._id))
|
res.push(control.txFactory.createTxRemoveDoc(viewlet._class, viewlet.space, viewlet._id))
|
||||||
}
|
}
|
||||||
const attributes = control.modelDb.findAllSync(core.class.Attribute, {
|
const attributes = control.modelDb.findAllSync(core.class.Attribute, {
|
||||||
attributeOf: removeTx.objectId
|
attributeOf: tag
|
||||||
})
|
})
|
||||||
for (const attribute of attributes) {
|
for (const attribute of attributes) {
|
||||||
res.push(control.txFactory.createTxRemoveDoc(attribute._class, attribute.space, attribute._id))
|
res.push(control.txFactory.createTxRemoveDoc(attribute._class, attribute.space, attribute._id))
|
||||||
}
|
}
|
||||||
const desc = control.hierarchy.getDescendants(removeTx.objectId)
|
|
||||||
for (const des of desc) {
|
|
||||||
if (des === removeTx.objectId) continue
|
|
||||||
res.push(control.txFactory.createTxRemoveDoc(card.class.MasterTag, core.space.Model, des))
|
|
||||||
}
|
|
||||||
const removedRelation = new Set()
|
const removedRelation = new Set()
|
||||||
const relationsA = control.modelDb.findAllSync(core.class.Association, {
|
const relationsA = control.modelDb.findAllSync(core.class.Association, {
|
||||||
classA: removeTx.objectId
|
classA: tag
|
||||||
})
|
})
|
||||||
for (const rel of relationsA) {
|
for (const rel of relationsA) {
|
||||||
removedRelation.add(rel._id)
|
removedRelation.add(rel._id)
|
||||||
res.push(control.txFactory.createTxRemoveDoc(core.class.Association, core.space.Model, rel._id))
|
res.push(control.txFactory.createTxRemoveDoc(core.class.Association, core.space.Model, rel._id))
|
||||||
}
|
}
|
||||||
const relationsB = control.modelDb.findAllSync(core.class.Association, {
|
const relationsB = control.modelDb.findAllSync(core.class.Association, {
|
||||||
classB: removeTx.objectId
|
classB: tag
|
||||||
})
|
})
|
||||||
for (const rel of relationsB) {
|
for (const rel of relationsB) {
|
||||||
if (removedRelation.has(rel._id)) continue
|
if (removedRelation.has(rel._id)) continue
|
||||||
res.push(control.txFactory.createTxRemoveDoc(core.class.Association, core.space.Model, rel._id))
|
res.push(control.txFactory.createTxRemoveDoc(core.class.Association, core.space.Model, rel._id))
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,6 +359,7 @@ export default async () => ({
|
|||||||
OnAttributeRemove,
|
OnAttributeRemove,
|
||||||
OnMasterTagCreate,
|
OnMasterTagCreate,
|
||||||
OnMasterTagRemove,
|
OnMasterTagRemove,
|
||||||
|
OnTagRemove,
|
||||||
OnCardRemove,
|
OnCardRemove,
|
||||||
OnCardCreate,
|
OnCardCreate,
|
||||||
OnCardUpdate
|
OnCardUpdate
|
||||||
|
@ -30,6 +30,7 @@ export default plugin(serverCardId, {
|
|||||||
OnAttribute: '' as Resource<TriggerFunc>,
|
OnAttribute: '' as Resource<TriggerFunc>,
|
||||||
OnAttributeRemove: '' as Resource<TriggerFunc>,
|
OnAttributeRemove: '' as Resource<TriggerFunc>,
|
||||||
OnMasterTagCreate: '' as Resource<TriggerFunc>,
|
OnMasterTagCreate: '' as Resource<TriggerFunc>,
|
||||||
|
OnTagRemove: '' as Resource<TriggerFunc>,
|
||||||
OnMasterTagRemove: '' as Resource<TriggerFunc>,
|
OnMasterTagRemove: '' as Resource<TriggerFunc>,
|
||||||
OnCardCreate: '' as Resource<TriggerFunc>,
|
OnCardCreate: '' as Resource<TriggerFunc>,
|
||||||
OnCardUpdate: '' as Resource<TriggerFunc>,
|
OnCardUpdate: '' as Resource<TriggerFunc>,
|
||||||
|
@ -138,7 +138,8 @@ export class DomainTxMiddleware extends BaseMiddleware implements Middleware {
|
|||||||
ctx.error('Unsupported transaction', tx)
|
ctx.error('Unsupported transaction', tx)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const domain = this.context.hierarchy.getDomain(txCUD.objectClass)
|
const domain = this.context.hierarchy.findDomain(txCUD.objectClass)
|
||||||
|
if (domain === undefined) continue
|
||||||
domains.add(domain)
|
domains.add(domain)
|
||||||
const adapterName = this.adapterManager.getAdapterName(domain)
|
const adapterName = this.adapterManager.getAdapterName(domain)
|
||||||
|
|
||||||
|
@ -293,6 +293,8 @@ export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.push(...(await this.deleteClassCollections(ctx, object._class, rtx.objectId, findAll)))
|
result.push(...(await this.deleteClassCollections(ctx, object._class, rtx.objectId, findAll)))
|
||||||
|
const _class = this.context.hierarchy.findClass(object._class)
|
||||||
|
if (_class !== undefined) {
|
||||||
const mixins = this.getMixins(object._class, object)
|
const mixins = this.getMixins(object._class, object)
|
||||||
for (const mixin of mixins) {
|
for (const mixin of mixins) {
|
||||||
result.push(...(await this.deleteClassCollections(ctx, mixin, rtx.objectId, findAll, object._class)))
|
result.push(...(await this.deleteClassCollections(ctx, mixin, rtx.objectId, findAll, object._class)))
|
||||||
@ -300,6 +302,7 @@ export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
|||||||
|
|
||||||
result.push(...(await this.deleteRelatedDocuments(ctx, object, findAll)))
|
result.push(...(await this.deleteRelatedDocuments(ctx, object, findAll)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,7 +1458,9 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
}
|
}
|
||||||
const isReverse = association[1] === -1
|
const isReverse = association[1] === -1
|
||||||
const _class = isReverse ? assoc.classA : assoc.classB
|
const _class = isReverse ? assoc.classA : assoc.classB
|
||||||
const tagetDomain = translateDomain(this.hierarchy.getDomain(_class))
|
const domain = this.hierarchy.findDomain(_class)
|
||||||
|
if (domain === undefined) continue
|
||||||
|
const tagetDomain = translateDomain(domain)
|
||||||
const keyA = isReverse ? 'docB' : 'docA'
|
const keyA = isReverse ? 'docB' : 'docA'
|
||||||
const keyB = isReverse ? 'docA' : 'docB'
|
const keyB = isReverse ? 'docA' : 'docB'
|
||||||
const wsId = vars.add(this.workspaceId, '::uuid')
|
const wsId = vars.add(this.workspaceId, '::uuid')
|
||||||
|
Loading…
Reference in New Issue
Block a user