Fix master tag remove (#8239)

This commit is contained in:
Denis Bykhov 2025-03-15 18:52:31 +05:00 committed by GitHub
parent f03ffa7aa4
commit 21eaf38daa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 191 additions and 119 deletions

View File

@ -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, {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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[]> = {}

View File

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

View File

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

View File

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

View File

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

View File

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