diff --git a/models/card/src/index.ts b/models/card/src/index.ts index fbb4d05c00..a8572e163d 100644 --- a/models/card/src/index.ts +++ b/models/card/src/index.ts @@ -100,6 +100,9 @@ export class TMasterTag extends TClass implements MasterTag { @Prop(TypeBoolean(), card.string.SingleColumn) singleColumn?: boolean + + @Prop(TypeBoolean(), card.string.BaseType) + baseType?: boolean } @Model(card.class.Tag, core.class.Mixin) @@ -1058,6 +1061,7 @@ export function createModel (builder: Builder): void { }) builder.mixin(card.class.Card, core.class.Class, view.mixin.ObjectFactory, { + component: card.component.CreateCard, create: card.function.CardFactory }) diff --git a/plugins/card-assets/lang/cs.json b/plugins/card-assets/lang/cs.json index a725b76d0a..bf5e21883d 100644 --- a/plugins/card-assets/lang/cs.json +++ b/plugins/card-assets/lang/cs.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Sekce {section} odemknuta", "LayoutAuto": "Auto", "SingleColumn": "Jeden sloupec", + "BaseType": "Základní typ", + "BaseTypeDescription": "Použijte tento typ pouze jako nadřazený. Karty lze vytvářet pouze z jeho podtypů.", "TwoColumns": "Dva sloupce", "Grid": "Mřížka", "RichtextProperties": "Textová pole", diff --git a/plugins/card-assets/lang/de.json b/plugins/card-assets/lang/de.json index 9bf7ff0c3f..7aa67a078c 100644 --- a/plugins/card-assets/lang/de.json +++ b/plugins/card-assets/lang/de.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Sektion {section} entsperrt", "LayoutAuto": "Auto", "SingleColumn": "Einspaltig", + "BaseType": "Basistyp", + "BaseTypeDescription": "Verwende diesen Typ nur als übergeordneten Typ. Karten können nur aus seinen Untertypen erstellt werden.", "TwoColumns": "Zwei spaltig", "Grid": "Gitter", "RichtextProperties": "Textfelder", diff --git a/plugins/card-assets/lang/en.json b/plugins/card-assets/lang/en.json index 0c94f01369..c37a048673 100644 --- a/plugins/card-assets/lang/en.json +++ b/plugins/card-assets/lang/en.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Section {section} unlocked", "LayoutAuto": "Auto", "SingleColumn": "Single column", + "BaseType": "Base type", + "BaseTypeDescription": "Use this type as a parent only. Cards can be created only from its subtypes.", "TwoColumns": "Two columns", "Grid": "Grid", "RichtextProperties": "Richtext Properties", diff --git a/plugins/card-assets/lang/es.json b/plugins/card-assets/lang/es.json index 02a6c623ef..5aafe4a27a 100644 --- a/plugins/card-assets/lang/es.json +++ b/plugins/card-assets/lang/es.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Sección {section} desbloqueada", "LayoutAuto": "Auto", "SingleColumn": "Una columna", + "BaseType": "Tipo base", + "BaseTypeDescription": "Usa este tipo solo como padre. Las tarjetas solo se pueden crear a partir de sus subtipos.", "TwoColumns": "Dos columnas", "Grid": "Cuadrícula", "RichtextProperties": "Campos de texto", diff --git a/plugins/card-assets/lang/fr.json b/plugins/card-assets/lang/fr.json index 00c20f1219..c04ebbf864 100644 --- a/plugins/card-assets/lang/fr.json +++ b/plugins/card-assets/lang/fr.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Section {section} déverrouillée", "LayoutAuto": "Auto", "SingleColumn": "Une colonne", + "BaseType": "Type de base", + "BaseTypeDescription": "Utilisez ce type uniquement comme parent. Les cartes ne peuvent être créées qu'à partir de ses sous-types.", "TwoColumns": "Deux colonnes", "Grid": "Grille", "RichtextProperties": "Champs de texte", diff --git a/plugins/card-assets/lang/it.json b/plugins/card-assets/lang/it.json index 757878562f..00ef00db48 100644 --- a/plugins/card-assets/lang/it.json +++ b/plugins/card-assets/lang/it.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Sezione {section} sbloccata", "LayoutAuto": "Auto", "SingleColumn": "Una colonna", + "BaseType": "Tipo base", + "BaseTypeDescription": "Usa questo tipo solo come tipo padre. Le schede possono essere create solo dai suoi sottotipi.", "TwoColumns": "Due colonne", "Grid": "Griglia", "RichtextProperties": "Campo di testo", diff --git a/plugins/card-assets/lang/ja.json b/plugins/card-assets/lang/ja.json index 966760b5f6..0027f0a7dc 100644 --- a/plugins/card-assets/lang/ja.json +++ b/plugins/card-assets/lang/ja.json @@ -82,6 +82,8 @@ "SectionUnlocked": "セクション {section} アンロック済み", "LayoutAuto": "自動", "SingleColumn": "1列", + "BaseType": "基本タイプ", + "BaseTypeDescription": "このタイプは親としてのみ使用します。カードはそのサブタイプからのみ作成できます。", "TwoColumns": "2列", "Grid": "グリッド", "RichtextProperties": "リッチテキストフィールド", diff --git a/plugins/card-assets/lang/ko.json b/plugins/card-assets/lang/ko.json index 74c2a4e997..68443d5b27 100644 --- a/plugins/card-assets/lang/ko.json +++ b/plugins/card-assets/lang/ko.json @@ -82,6 +82,8 @@ "SectionUnlocked": "{section} 섹션의 잠금이 해제되었습니다", "LayoutAuto": "자동", "SingleColumn": "1열", + "BaseType": "기본 유형", + "BaseTypeDescription": "이 유형은 부모 유형으로만 사용합니다. 카드는 해당 하위 유형에서만 만들 수 있습니다.", "TwoColumns": "2열", "Grid": "그리드", "RichtextProperties": "리치 텍스트 속성", diff --git a/plugins/card-assets/lang/pl.json b/plugins/card-assets/lang/pl.json index ad2534a3a4..ea9b5082d7 100644 --- a/plugins/card-assets/lang/pl.json +++ b/plugins/card-assets/lang/pl.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Sekcja {section} odblokowana", "LayoutAuto": "Automatyczny", "SingleColumn": "Jedna kolumna", + "BaseType": "Typ bazowy", + "BaseTypeDescription": "Używaj tego typu tylko jako nadrzędnego. Karty można tworzyć tylko z jego podtypów.", "TwoColumns": "Dwie kolumny", "Grid": "Siatka", "RichtextProperties": "Właściwości tekstu formatowanego", diff --git a/plugins/card-assets/lang/pt-br.json b/plugins/card-assets/lang/pt-br.json index de422b51f9..d61e2d3292 100644 --- a/plugins/card-assets/lang/pt-br.json +++ b/plugins/card-assets/lang/pt-br.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Seção {section} desbloqueada", "LayoutAuto": "Automático", "SingleColumn": "Uma coluna", + "BaseType": "Tipo base", + "BaseTypeDescription": "Use este tipo apenas como pai. Os cartões só podem ser criados a partir de seus subtipos.", "TwoColumns": "Duas colunas", "Grid": "Grade", "RichtextProperties": "Campos de texto", diff --git a/plugins/card-assets/lang/pt.json b/plugins/card-assets/lang/pt.json index dbd78c3fa9..c8aabe74ad 100644 --- a/plugins/card-assets/lang/pt.json +++ b/plugins/card-assets/lang/pt.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Seção {section} desbloqueada", "LayoutAuto": "Automático", "SingleColumn": "Uma coluna", + "BaseType": "Tipo base", + "BaseTypeDescription": "Use este tipo apenas como pai. Os cartões só podem ser criados a partir de seus subtipos.", "TwoColumns": "Duas colunas", "Grid": "Grade", "RichtextProperties": "Campo de texto", diff --git a/plugins/card-assets/lang/ru.json b/plugins/card-assets/lang/ru.json index eab9141d3b..bbab14e3c5 100644 --- a/plugins/card-assets/lang/ru.json +++ b/plugins/card-assets/lang/ru.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Секция {section} разблокирована", "LayoutAuto": "Авто", "SingleColumn": "Один столбец", + "BaseType": "Базовый тип", + "BaseTypeDescription": "Используйте этот тип только как родительский. Карточки можно создавать только из его подтипов.", "TwoColumns": "Два столбца", "Grid": "Сетка", "RichtextProperties": "Текстовые поля", diff --git a/plugins/card-assets/lang/tr.json b/plugins/card-assets/lang/tr.json index 99dd866e85..4cb8e1391b 100644 --- a/plugins/card-assets/lang/tr.json +++ b/plugins/card-assets/lang/tr.json @@ -82,6 +82,8 @@ "SectionUnlocked": "Bölüm {section} kilidi açıldı", "LayoutAuto": "Otomatik", "SingleColumn": "Tek sütun", + "BaseType": "Temel tür", + "BaseTypeDescription": "Bu türü yalnızca üst tür olarak kullanın. Kartlar yalnızca alt türlerinden oluşturulabilir.", "TwoColumns": "İki sütun", "Grid": "Izgara", "RichtextProperties": "Zengin metin alanları", diff --git a/plugins/card-assets/lang/zh.json b/plugins/card-assets/lang/zh.json index 81a0a88366..aef6c18419 100644 --- a/plugins/card-assets/lang/zh.json +++ b/plugins/card-assets/lang/zh.json @@ -82,6 +82,8 @@ "SectionUnlocked": "部分 {section} 已解锁", "LayoutAuto": "自动", "SingleColumn": "单列", + "BaseType": "基础类型", + "BaseTypeDescription": "仅将此类型用作父类型。只能从其子类型创建卡片。", "TwoColumns": "两列", "Grid": "网格", "RichtextProperties": "富文本字段", diff --git a/plugins/card-resources/src/components/ChangeType.svelte b/plugins/card-resources/src/components/ChangeType.svelte index ae4e186d50..9ba96daef1 100644 --- a/plugins/card-resources/src/components/ChangeType.svelte +++ b/plugins/card-resources/src/components/ChangeType.svelte @@ -91,5 +91,5 @@
- + diff --git a/plugins/card-resources/src/components/CreateCardButton.svelte b/plugins/card-resources/src/components/CreateCardButton.svelte index bc6b09f5da..ea7d313287 100644 --- a/plugins/card-resources/src/components/CreateCardButton.svelte +++ b/plugins/card-resources/src/components/CreateCardButton.svelte @@ -14,12 +14,14 @@ --> - + {/if} {#if (space == null || allowChangeSpace) && !(extension?.hideSpace ?? false)} diff --git a/plugins/card-resources/src/components/CreateCardPopupSimple.svelte b/plugins/card-resources/src/components/CreateCardPopupSimple.svelte index 370ddc9987..b5308d8a41 100644 --- a/plugins/card-resources/src/components/CreateCardPopupSimple.svelte +++ b/plugins/card-resources/src/components/CreateCardPopupSimple.svelte @@ -22,7 +22,7 @@ import { permissionsStore } from '@hcengineering/contact-resources' import view from '@hcengineering/view' - import { createCard } from '../utils' + import { createCard, isBaseTypeWithSubtypes } from '../utils' import { TypeSelector } from '../index' import { canCreateObject } from '@hcengineering/view-resources' @@ -90,7 +90,8 @@ label = `${createString} ${typeString}` } - $: allowed = _space != null && canCreateObject(type, _space, $permissionsStore) + $: allowed = + _space != null && canCreateObject(type, _space, $permissionsStore) && !isBaseTypeWithSubtypes(hierarchy, type) - + diff --git a/plugins/card-resources/src/components/NewCardForm.svelte b/plugins/card-resources/src/components/NewCardForm.svelte index 3dfa8b2e84..708f5f57d9 100644 --- a/plugins/card-resources/src/components/NewCardForm.svelte +++ b/plugins/card-resources/src/components/NewCardForm.svelte @@ -38,7 +38,7 @@ import { getCardDraftKey, getEmptyCardDraft, type CardDraft } from '../draft' import { TypeSelector } from '../index' import card from '../plugin' - import { createCard } from '../utils' + import { createCard, isBaseTypeWithSubtypes } from '../utils' import { permissionsStore } from '@hcengineering/contact-resources' import { canCreateObject } from '@hcengineering/view-resources' @@ -91,7 +91,8 @@ space == null || type == null || creating || - !canCreateObject(type, space, $permissionsStore) + !canCreateObject(type, space, $permissionsStore) || + isBaseTypeWithSubtypes(hierarchy, type) const account = getCurrentAccount() @@ -259,7 +260,7 @@ kind={'regular'} size={'small'} /> - +
diff --git a/plugins/card-resources/src/components/TypeSelector.svelte b/plugins/card-resources/src/components/TypeSelector.svelte index 7bf01952cd..44dd9d9e23 100644 --- a/plugins/card-resources/src/components/TypeSelector.svelte +++ b/plugins/card-resources/src/components/TypeSelector.svelte @@ -20,6 +20,7 @@ import { createEventDispatcher } from 'svelte' import card from '../plugin' import view from '@hcengineering/view' + import { getFirstCreatableSubtype, isBaseTypeWithSubtypes } from '../utils' export let value: Ref export let width: string | undefined = undefined @@ -27,9 +28,11 @@ export let size: ButtonSize | undefined = undefined export let parent: Ref = card.class.Card export let disabled: boolean = false + export let excludeBaseTypes: boolean = false const client = getClient() const hierarchy = client.getHierarchy() + const dispatch = createEventDispatcher() function filterClasses (): [DropdownIntlItem, DropdownIntlItem[]][] { const descendants = hierarchy.getDescendants(parent).filter((p) => p !== parent) @@ -41,6 +44,7 @@ if (_class.label === undefined) continue if (_class.kind !== ClassifierKind.CLASS) continue if ((_class as MasterTag).removed === true) continue + if (excludeBaseTypes && isBaseTypeWithSubtypes(hierarchy, _id as Ref)) continue added.add(_id) const descendants = hierarchy.getDescendants(_id) const toAdd: Class[] = [] @@ -50,6 +54,7 @@ if (_class.label === undefined) continue if (_class.kind !== ClassifierKind.CLASS) continue if ((_class as MasterTag).removed === true) continue + if (excludeBaseTypes && isBaseTypeWithSubtypes(hierarchy, desc as Ref)) continue added.add(desc) toAdd.push(_class) } @@ -78,7 +83,14 @@ } const classes = filterClasses() - const dispatch = createEventDispatcher() + + $: if (excludeBaseTypes && isBaseTypeWithSubtypes(hierarchy, value)) { + const nextType = getFirstCreatableSubtype(hierarchy, value) + if (nextType !== undefined) { + value = nextType + dispatch('change', value) + } + } $: selectedClass = hierarchy.getClass(value) $: selected = { diff --git a/plugins/card-resources/src/components/navigator-next/NavigatorType.svelte b/plugins/card-resources/src/components/navigator-next/NavigatorType.svelte index 0c9051737d..5a7702c5bf 100644 --- a/plugins/card-resources/src/components/navigator-next/NavigatorType.svelte +++ b/plugins/card-resources/src/components/navigator-next/NavigatorType.svelte @@ -25,6 +25,7 @@ import type { NavigatorConfig } from '../../types' import cardPlugin from '../../plugin' import CreateCardPopup from '../CreateCardPopup.svelte' + import { isBaseTypeWithSubtypes } from '../../utils' export let type: MasterTag export let level: number = -1 @@ -39,13 +40,18 @@ let activeAction: string | undefined = undefined async function handleCreateCard (): Promise { - showPopup(CreateCardPopup, { type: type._id, space: space?._id }, 'center', async (result) => { - if (result !== undefined) { - const card = await getClient().findOne(cardPlugin.class.Card, { _id: result }) - if (card === undefined) return - dispatch('selectCard', card) + showPopup( + CreateCardPopup, + { type: type._id, space: space?._id, changeType: isBaseTypeWithSubtypes(getClient().getHierarchy(), type._id) }, + 'center', + async (result) => { + if (result !== undefined) { + const card = await getClient().findOne(cardPlugin.class.Card, { _id: result }) + if (card === undefined) return + dispatch('selectCard', card) + } } - }) + ) } async function getActions (lang: string): Promise { diff --git a/plugins/card-resources/src/components/navigator/CardHeaderButton.svelte b/plugins/card-resources/src/components/navigator/CardHeaderButton.svelte index 23aa072621..f2cc5fc658 100644 --- a/plugins/card-resources/src/components/navigator/CardHeaderButton.svelte +++ b/plugins/card-resources/src/components/navigator/CardHeaderButton.svelte @@ -14,12 +14,14 @@ -->
@@ -224,6 +227,20 @@ on:change={(e) => attributeUpdated('singleColumn', e.detail)} />
+ {#if hasSubtypes} +
+
+
+ attributeUpdated('baseType', e.detail)} /> +
+ {/if}