mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-30 12:15:51 +00:00
Relation fixes (#8167)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
655c46ef9a
commit
7bfd8403a8
@ -693,6 +693,25 @@ export function createModel (builder: Builder): void {
|
|||||||
view.action.Delete
|
view.action.Delete
|
||||||
)
|
)
|
||||||
|
|
||||||
|
createAction(
|
||||||
|
builder,
|
||||||
|
{
|
||||||
|
action: view.actionImpl.Delete,
|
||||||
|
actionProps: {
|
||||||
|
confirmation: view.string.RemoveRelationConfirmation
|
||||||
|
},
|
||||||
|
label: view.string.RemoveRelation,
|
||||||
|
icon: view.icon.Delete,
|
||||||
|
keyBinding: ['Meta + Backspace'],
|
||||||
|
category: view.category.General,
|
||||||
|
override: [view.action.Delete],
|
||||||
|
input: 'any',
|
||||||
|
target: core.class.Relation,
|
||||||
|
context: { mode: ['context', 'browser'], group: 'remove' }
|
||||||
|
},
|
||||||
|
view.action.RemoveRelation
|
||||||
|
)
|
||||||
|
|
||||||
createAction(
|
createAction(
|
||||||
builder,
|
builder,
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
let allClasses: MasterTag[] = []
|
let allClasses: MasterTag[] = []
|
||||||
|
|
||||||
function fillClasses (tags: MasterTag[]): void {
|
function fillClasses (tags: MasterTag[]): void {
|
||||||
classes = tags.filter((it) => it.extends === card.class.Card)
|
classes = tags.filter((it) => it.extends === card.class.Card).sort((a, b) => a.label.localeCompare(b.label))
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = createQuery()
|
const query = createQuery()
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
result.push(cls)
|
result.push(cls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result.sort((a, b) => a.label.localeCompare(b.label))
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillDescendants (classes: MasterTag[]): void {
|
function fillDescendants (classes: MasterTag[]): void {
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
_class: card.class.MasterTag
|
_class: card.class.MasterTag
|
||||||
},
|
},
|
||||||
(result) => {
|
(result) => {
|
||||||
tags = result
|
tags = result.sort((a, b) => a.label.localeCompare(b.label))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
function addRelation (): void {
|
function addRelation (): void {
|
||||||
showPopup(setting.component.CreateRelation, {
|
showPopup(setting.component.CreateRelation, {
|
||||||
|
aClass: masterTag._id,
|
||||||
exclude: [],
|
exclude: [],
|
||||||
_classes: [card.class.Card, contact.class.Contact]
|
_classes: [card.class.Card, contact.class.Contact]
|
||||||
})
|
})
|
||||||
|
@ -22,11 +22,14 @@
|
|||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { personRefByPersonIdStore } from '../utils'
|
import { personRefByPersonIdStore } from '../utils'
|
||||||
import { PersonRefPresenter } from '..'
|
import { PersonRefPresenter } from '..'
|
||||||
|
import { IntlString } from '@hcengineering/platform'
|
||||||
|
|
||||||
export let object: Doc | Doc[]
|
export let object: Doc | Doc[]
|
||||||
export let deleteAction: () => void | Promise<void>
|
export let deleteAction: () => void | Promise<void>
|
||||||
export let skipCheck: boolean = false
|
export let skipCheck: boolean = false
|
||||||
export let canDeleteExtra: boolean = true
|
export let canDeleteExtra: boolean = true
|
||||||
|
export let confirmation: IntlString | undefined = undefined
|
||||||
|
|
||||||
const me = getCurrentEmployee()
|
const me = getCurrentEmployee()
|
||||||
const objectArray = Array.isArray(object) ? object : [object]
|
const objectArray = Array.isArray(object) ? object : [object]
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
@ -57,7 +60,7 @@
|
|||||||
<div class="flex-grow flex-col">
|
<div class="flex-grow flex-col">
|
||||||
{#if canDelete}
|
{#if canDelete}
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<Label label={view.string.DeleteObjectConfirm} params={{ count: objectArray.length }} />
|
<Label label={confirmation ?? view.string.DeleteObjectConfirm} params={{ count: objectArray.length }} />
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
{#if objectArray.length === 1}
|
{#if objectArray.length === 1}
|
||||||
<ObjectPresenter _class={objectArray[0]._class} objectId={objectArray[0]._id} value={objectArray[0]} />
|
<ObjectPresenter _class={objectArray[0]._class} objectId={objectArray[0]._id} value={objectArray[0]} />
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
|
|
||||||
|
export let aClass: Ref<Class<Doc>> | undefined = undefined
|
||||||
export let _classes: Ref<Class<Doc>>[] = [core.class.Doc]
|
export let _classes: Ref<Class<Doc>>[] = [core.class.Doc]
|
||||||
export let exclude: Ref<Class<Doc>>[] = [cardPlugin.class.Card]
|
export let exclude: Ref<Class<Doc>>[] = [cardPlugin.class.Card]
|
||||||
|
|
||||||
@ -79,7 +80,10 @@
|
|||||||
for (const [key, value] of base) {
|
for (const [key, value] of base) {
|
||||||
try {
|
try {
|
||||||
const clazz = hierarchy.getClass(key)
|
const clazz = hierarchy.getClass(key)
|
||||||
result.push([{ id: key, label: clazz.label }, value.map((it) => ({ id: it._id, label: it.label }))])
|
result.push([
|
||||||
|
{ id: key, label: clazz.label, icon: clazz.icon },
|
||||||
|
value.map((it) => ({ id: it._id, label: it.label, icon: it.icon }))
|
||||||
|
])
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -87,7 +91,7 @@
|
|||||||
|
|
||||||
const classes = filterClasses(descendants, viewlets, exclude)
|
const classes = filterClasses(descendants, viewlets, exclude)
|
||||||
|
|
||||||
let classARef: Ref<Class<Doc>> | undefined = undefined
|
let classARef: Ref<Class<Doc>> | undefined = aClass
|
||||||
let classBRef: Ref<Class<Doc>> | undefined = undefined
|
let classBRef: Ref<Class<Doc>> | undefined = undefined
|
||||||
let nameA: string = ''
|
let nameA: string = ''
|
||||||
let nameB: string = ''
|
let nameB: string = ''
|
||||||
@ -122,6 +126,20 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
let mode: '1:1' | '1:N' | 'N:N' = 'N:N' as '1:1' | '1:N' | 'N:N'
|
let mode: '1:1' | '1:N' | 'N:N' = 'N:N' as '1:1' | '1:N' | 'N:N'
|
||||||
|
|
||||||
|
$: classA = getAClass(aClass)
|
||||||
|
|
||||||
|
function getAClass (aClass: Ref<Class<Doc>> | undefined): DropdownIntlItem | undefined {
|
||||||
|
if (aClass === undefined) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const clazz = hierarchy.getClass(aClass)
|
||||||
|
return {
|
||||||
|
id: clazz._id,
|
||||||
|
label: clazz.label,
|
||||||
|
icon: clazz.icon
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
@ -138,12 +156,16 @@
|
|||||||
<EditBox bind:value={nameA} placeholder={core.string.Name} kind={'default'} />
|
<EditBox bind:value={nameA} placeholder={core.string.Name} kind={'default'} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<NestedDropdown
|
{#if classA !== undefined}
|
||||||
items={classes}
|
<DropdownLabelsIntl items={[classA]} selected={classA.id} disabled />
|
||||||
on:selected={(e) => {
|
{:else}
|
||||||
classARef = e.detail
|
<NestedDropdown
|
||||||
}}
|
items={classes}
|
||||||
/>
|
on:selected={(e) => {
|
||||||
|
classARef = e.detail
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -127,6 +127,8 @@
|
|||||||
"Join": "Připojit se",
|
"Join": "Připojit se",
|
||||||
"Copied": "Zkopírováno",
|
"Copied": "Zkopírováno",
|
||||||
"Title": "Název",
|
"Title": "Název",
|
||||||
"HideArchived": "Skrýt archivované"
|
"HideArchived": "Skrýt archivované",
|
||||||
|
"RemoveRelation": "Odstranit vztah",
|
||||||
|
"RemoveRelationConfirmation": "Chcete odstranit vztah?"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -127,6 +127,8 @@
|
|||||||
"Join": "Beitreten",
|
"Join": "Beitreten",
|
||||||
"Copied": "Kopiert",
|
"Copied": "Kopiert",
|
||||||
"Title": "Titel",
|
"Title": "Titel",
|
||||||
"HideArchived": "Archivierte ausblenden"
|
"HideArchived": "Archivierte ausblenden",
|
||||||
|
"RemoveRelation": "Beziehung entfernen",
|
||||||
|
"RemoveRelationConfirmation": "Möchten Sie die Beziehung entfernen?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,8 @@
|
|||||||
"Join": "Join",
|
"Join": "Join",
|
||||||
"Copied": "Copied",
|
"Copied": "Copied",
|
||||||
"Title": "Title",
|
"Title": "Title",
|
||||||
"HideArchived": "Hide archived"
|
"HideArchived": "Hide archived",
|
||||||
|
"RemoveRelation": "Remove relation",
|
||||||
|
"RemoveRelationConfirmation": "Do you want to remove relation?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,8 @@
|
|||||||
"Join": "Unirse",
|
"Join": "Unirse",
|
||||||
"Copied": "Copiado",
|
"Copied": "Copiado",
|
||||||
"Title": "Título",
|
"Title": "Título",
|
||||||
"HideArchived": "Ocultar archivadas"
|
"HideArchived": "Ocultar archivadas",
|
||||||
|
"RemoveRelation": "Eliminar relación",
|
||||||
|
"RemoveRelationConfirmation": "¿Quieres eliminar la relación?"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -122,6 +122,8 @@
|
|||||||
"Join": "Rejoindre",
|
"Join": "Rejoindre",
|
||||||
"Copied": "Copié",
|
"Copied": "Copié",
|
||||||
"Title": "Titre",
|
"Title": "Titre",
|
||||||
"HideArchived": "Masquer les archives"
|
"HideArchived": "Masquer les archives",
|
||||||
|
"RemoveRelation": "Supprimer la relation",
|
||||||
|
"RemoveRelationConfirmation": "Voulez-vous supprimer la relation ?"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -122,6 +122,8 @@
|
|||||||
"Join": "Unisciti",
|
"Join": "Unisciti",
|
||||||
"Copied": "Copiato",
|
"Copied": "Copiato",
|
||||||
"Title": "Titolo",
|
"Title": "Titolo",
|
||||||
"HideArchived": "Nascondi archiviato"
|
"HideArchived": "Nascondi archiviato",
|
||||||
|
"RemoveRelation": "Rimuovere relazione",
|
||||||
|
"RemoveRelationConfirmation": "Vuoi rimuovere la relazione?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,8 @@
|
|||||||
"Join": "Ingressar",
|
"Join": "Ingressar",
|
||||||
"Copied": "Copiado",
|
"Copied": "Copiado",
|
||||||
"Title": "Título",
|
"Title": "Título",
|
||||||
"HideArchived": "Ocultar arquivado"
|
"HideArchived": "Ocultar arquivado",
|
||||||
|
"RemoveRelation": "Remover relação",
|
||||||
|
"RemoveRelationConfirmation": "Deseja remover a relação?"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -124,6 +124,8 @@
|
|||||||
"Join": "Присоединиться",
|
"Join": "Присоединиться",
|
||||||
"Copied": "Скопировано",
|
"Copied": "Скопировано",
|
||||||
"Title": "Заголовок",
|
"Title": "Заголовок",
|
||||||
"HideArchived": "Скрыть архивные"
|
"HideArchived": "Скрыть архивные",
|
||||||
|
"RemoveRelation": "Удалить связь",
|
||||||
|
"RemoveRelationConfirmation": "Вы хотите удалить связь?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,8 @@
|
|||||||
"Join": "加入",
|
"Join": "加入",
|
||||||
"Copied": "已复制",
|
"Copied": "已复制",
|
||||||
"Title": "标题",
|
"Title": "标题",
|
||||||
"HideArchived": "隱藏已存檔"
|
"HideArchived": "隱藏已存檔",
|
||||||
|
"RemoveRelation": "移除关系",
|
||||||
|
"RemoveRelationConfirmation": "您要移除关系吗?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ function Delete (
|
|||||||
props?: {
|
props?: {
|
||||||
skipCheck?: boolean
|
skipCheck?: boolean
|
||||||
afterDelete?: () => Promise<void>
|
afterDelete?: () => Promise<void>
|
||||||
|
confirmation?: IntlString
|
||||||
}
|
}
|
||||||
): void {
|
): void {
|
||||||
const skipCheck = props?.skipCheck ?? false
|
const skipCheck = props?.skipCheck ?? false
|
||||||
@ -100,6 +101,7 @@ function Delete (
|
|||||||
{
|
{
|
||||||
object,
|
object,
|
||||||
skipCheck,
|
skipCheck,
|
||||||
|
confirmation: props?.confirmation,
|
||||||
deleteAction: async () => {
|
deleteAction: async () => {
|
||||||
try {
|
try {
|
||||||
const objs = Array.isArray(object) ? object : [object]
|
const objs = Array.isArray(object) ? object : [object]
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
: { docA: doc._id, docB: object._id, association: association._id }
|
: { docA: doc._id, docB: object._id, association: association._id }
|
||||||
const relation = await client.findOne(core.class.Relation, q)
|
const relation = await client.findOne(core.class.Relation, q)
|
||||||
if (relation !== undefined) {
|
if (relation !== undefined) {
|
||||||
showMenu(ev, { object: relation, includedActions: [view.action.Delete] })
|
showMenu(ev, { object: relation, includedActions: [view.action.RemoveRelation] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,8 @@ const view = plugin(viewId, {
|
|||||||
|
|
||||||
// Edit document
|
// Edit document
|
||||||
Open: '' as Ref<Action>,
|
Open: '' as Ref<Action>,
|
||||||
OpenInNewTab: '' as Ref<Action>
|
OpenInNewTab: '' as Ref<Action>,
|
||||||
|
RemoveRelation: '' as Ref<Action>
|
||||||
},
|
},
|
||||||
viewlet: {
|
viewlet: {
|
||||||
Table: '' as Ref<ViewletDescriptor>,
|
Table: '' as Ref<ViewletDescriptor>,
|
||||||
@ -219,7 +220,9 @@ const view = plugin(viewId, {
|
|||||||
And: '' as IntlString,
|
And: '' as IntlString,
|
||||||
Title: '' as IntlString,
|
Title: '' as IntlString,
|
||||||
DeleteObject: '' as IntlString,
|
DeleteObject: '' as IntlString,
|
||||||
DeleteObjectConfirm: '' as IntlString
|
DeleteObjectConfirm: '' as IntlString,
|
||||||
|
RemoveRelationConfirmation: '' as IntlString,
|
||||||
|
RemoveRelation: '' as IntlString
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
Table: '' as Asset,
|
Table: '' as Asset,
|
||||||
|
@ -101,6 +101,11 @@ const relationSchema: Schema = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
notNull: true,
|
notNull: true,
|
||||||
index: true
|
index: true
|
||||||
|
},
|
||||||
|
association: {
|
||||||
|
type: 'text',
|
||||||
|
notNull: true,
|
||||||
|
index: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,6 +1449,7 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
ON relation."${keyB}" = assoc."_id"
|
ON relation."${keyB}" = assoc."_id"
|
||||||
AND relation."workspaceId" = ${wsId}
|
AND relation."workspaceId" = ${wsId}
|
||||||
WHERE relation."${keyA}" = ${translateDomain(baseDomain)}."_id"
|
WHERE relation."${keyA}" = ${translateDomain(baseDomain)}."_id"
|
||||||
|
AND relation.association = '${_id}'
|
||||||
AND assoc."workspaceId" = ${wsId}) AS assoc_${tagetDomain}_${association[0]}`
|
AND assoc."workspaceId" = ${wsId}) AS assoc_${tagetDomain}_${association[0]}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user