diff --git a/models/card/src/index.ts b/models/card/src/index.ts index 5814ab4693..0fca8acd8d 100644 --- a/models/card/src/index.ts +++ b/models/card/src/index.ts @@ -19,7 +19,8 @@ import { type Card, type MasterTag, type ParentInfo, - type Tag + type Tag, + type Role } from '@hcengineering/card' import chunter from '@hcengineering/chunter' import core, { @@ -47,7 +48,7 @@ import { type Builder } from '@hcengineering/model' import attachment from '@hcengineering/model-attachment' -import { TClass, TDoc, TMixin, TSpace } from '@hcengineering/model-core' +import { TAttachedDoc, TClass, TDoc, TMixin, TSpace } from '@hcengineering/model-core' import presentation from '@hcengineering/model-presentation' import setting from '@hcengineering/model-setting' import view, { createAction } from '@hcengineering/model-view' @@ -115,6 +116,13 @@ export class MasterTagEditorSection extends TDoc implements MasterTagEditorSecti component!: AnyComponent } +@Model(card.class.Role, core.class.AttachedDoc, DOMAIN_MODEL) +export class TRole extends TAttachedDoc implements Role { + name!: string + declare attachedTo: Ref + declare collection: 'roles' +} + export * from './migration' const listConfig: (BuildModelKey | string)[] = [ @@ -204,7 +212,7 @@ export function createSystemType ( } export function createModel (builder: Builder): void { - builder.createModel(TMasterTag, TTag, TCard, MasterTagEditorSection, TCardSpace) + builder.createModel(TMasterTag, TTag, TCard, MasterTagEditorSection, TCardSpace, TRole) createSystemType(builder, card.types.File, card.icon.File, attachment.string.File, attachment.string.Files) createSystemType(builder, card.types.Document, card.icon.Document, card.string.Document, card.string.Documents) @@ -681,6 +689,12 @@ export function createModel (builder: Builder): void { component: card.component.RelationsSection }) + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'roles', + label: core.string.Roles, + component: card.component.RolesSection + }) + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { id: 'views', label: card.string.Views, diff --git a/models/contact/src/index.ts b/models/contact/src/index.ts index 272ca3c397..c012135dee 100644 --- a/models/contact/src/index.ts +++ b/models/contact/src/index.ts @@ -15,11 +15,12 @@ // import activity from '@hcengineering/activity' +import card, { type Role, type Card } from '@hcengineering/card' import { AvatarType, + type UserRole, contactId, type AvatarProvider, - type SocialIdentity, type Channel, type ChannelProvider, type Contact, @@ -29,26 +30,27 @@ import { type Member, type Organization, type Person, - type Status, - type PersonSpace + type PersonSpace, + type SocialIdentity, + type Status } from '@hcengineering/contact' import { AccountRole, + ClassifierKind, DOMAIN_MODEL, DateRangeMode, IndexKind, - type Collection, + type AccountUuid, type Blob, type Class, - type MarkupBlobRef, + type Collection, type Domain, - type Ref, - type Timestamp, - type SocialIdType, - type PersonUuid, + type MarkupBlobRef, type PersonId, - type AccountUuid, - ClassifierKind + type PersonUuid, + type Ref, + type SocialIdType, + type Timestamp } from '@hcengineering/core' import { Collection as CollectionType, @@ -84,7 +86,6 @@ import setting from '@hcengineering/setting' import templates from '@hcengineering/templates' import { type AnyComponent } from '@hcengineering/ui/src/types' import { type Action } from '@hcengineering/view' -import card, { type Card } from '@hcengineering/card' import contact from './plugin' export { contactId } from '@hcengineering/contact' @@ -92,6 +93,7 @@ export { contactOperation } from './migration' export { contact as default } export const DOMAIN_CONTACT = 'contact' as Domain +export const DOMAIN_ROLE = 'role' as Domain export const DOMAIN_CHANNEL = 'channel' as Domain @Model(contact.class.AvatarProvider, core.class.Doc, DOMAIN_MODEL) @@ -272,6 +274,12 @@ export class TPersonSpace extends TSpace implements PersonSpace { person!: Ref } +@Model(contact.class.UserRole, core.class.Doc, DOMAIN_ROLE) +export class TUserRole extends TDoc implements UserRole { + user!: Ref + role!: Ref +} + function createUserProfileTag (builder: Builder): void { builder.createDoc( card.class.MasterTag, @@ -334,7 +342,8 @@ export function createModel (builder: Builder): void { TStatus, TMember, TContactsTab, - TPersonSpace + TPersonSpace, + TUserRole ) builder.mixin(contact.class.Contact, core.class.Class, activity.mixin.ActivityDoc, {}) diff --git a/models/process/src/index.ts b/models/process/src/index.ts index df4567ca2c..f6aa1ec51e 100644 --- a/models/process/src/index.ts +++ b/models/process/src/index.ts @@ -164,6 +164,7 @@ export class TProcessFunction extends TDoc implements ProcessFunction { label!: IntlString editor?: AnyComponent allowMany?: boolean + type!: 'transform' | 'reduce' | 'context' } export * from './migration' @@ -239,7 +240,8 @@ export function createModel (builder: Builder): void { { of: core.class.TypeString, category: 'attribute', - label: process.string.UpperCase + label: process.string.UpperCase, + type: 'transform' }, process.function.UpperCase ) @@ -250,7 +252,8 @@ export function createModel (builder: Builder): void { { of: core.class.TypeString, category: 'attribute', - label: process.string.LowerCase + label: process.string.LowerCase, + type: 'transform' }, process.function.LowerCase ) @@ -261,7 +264,8 @@ export function createModel (builder: Builder): void { { of: core.class.TypeString, category: 'attribute', - label: process.string.Trim + label: process.string.Trim, + type: 'transform' }, process.function.Trim ) @@ -272,7 +276,8 @@ export function createModel (builder: Builder): void { { of: core.class.ArrOf, category: undefined, - label: process.string.FirstValue + label: process.string.FirstValue, + type: 'reduce' }, process.function.FirstValue ) @@ -282,6 +287,7 @@ export function createModel (builder: Builder): void { core.space.Model, { of: core.class.ArrOf, + type: 'reduce', category: undefined, label: process.string.LastValue }, @@ -293,6 +299,7 @@ export function createModel (builder: Builder): void { core.space.Model, { of: core.class.ArrOf, + type: 'reduce', category: undefined, label: process.string.Random }, @@ -304,6 +311,7 @@ export function createModel (builder: Builder): void { core.space.Model, { of: core.class.TypeNumber, + type: 'transform', category: 'attribute', label: process.string.Add, allowMany: true, @@ -320,7 +328,8 @@ export function createModel (builder: Builder): void { category: 'attribute', label: process.string.Subtract, allowMany: true, - editor: process.component.NumberOffsetEditor + editor: process.component.NumberOffsetEditor, + type: 'transform' }, process.function.Subtract ) @@ -332,7 +341,8 @@ export function createModel (builder: Builder): void { of: core.class.TypeDate, category: 'attribute', label: process.string.Offset, - editor: process.component.DateOffsetEditor + editor: process.component.DateOffsetEditor, + type: 'transform' }, process.function.Offset ) @@ -343,11 +353,25 @@ export function createModel (builder: Builder): void { { of: core.class.TypeDate, category: 'attribute', - label: process.string.FirstWorkingDayAfter + label: process.string.FirstWorkingDayAfter, + type: 'transform' }, process.function.FirstWorkingDayAfter ) + builder.createDoc( + process.class.ProcessFunction, + core.space.Model, + { + of: contact.mixin.Employee, + editor: process.component.RoleEditor, + category: 'array', + label: core.string.Role, + type: 'context' + }, + process.function.RoleContext + ) + builder.mixin(process.class.Process, core.class.Class, view.mixin.AttributePresenter, { presenter: process.component.ProcessPresenter }) diff --git a/models/server-process/src/index.ts b/models/server-process/src/index.ts index 9c58af5b4f..22123a2a6c 100644 --- a/models/server-process/src/index.ts +++ b/models/server-process/src/index.ts @@ -95,6 +95,10 @@ export function createModel (builder: Builder): void { func: serverProcess.transform.FirstWorkingDayAfter }) + builder.mixin(process.function.RoleContext, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, { + func: serverProcess.transform.RoleContext + }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverProcess.trigger.OnExecutionContinue, txMatch: { diff --git a/plugins/card-resources/src/components/settings/CreateRolePopup.svelte b/plugins/card-resources/src/components/settings/CreateRolePopup.svelte new file mode 100644 index 0000000000..924174d1e5 --- /dev/null +++ b/plugins/card-resources/src/components/settings/CreateRolePopup.svelte @@ -0,0 +1,47 @@ + + + + 0}> + + diff --git a/plugins/card-resources/src/components/settings/EditRole.svelte b/plugins/card-resources/src/components/settings/EditRole.svelte new file mode 100644 index 0000000000..ec0c908a33 --- /dev/null +++ b/plugins/card-resources/src/components/settings/EditRole.svelte @@ -0,0 +1,186 @@ + + + + + + + +
+
+ +
+ {name} +
+
+
+
+
+ +
+ {#each users as user, index (user._id)} +
+
+ +
+ { + await removeAssignment(user._id) + }} + /> +
+
+
+ {/each} +
+
+ + diff --git a/plugins/card-resources/src/components/settings/RolesSection.svelte b/plugins/card-resources/src/components/settings/RolesSection.svelte new file mode 100644 index 0000000000..f350c92c44 --- /dev/null +++ b/plugins/card-resources/src/components/settings/RolesSection.svelte @@ -0,0 +1,72 @@ + + + +
+ + + +
+
+ {#each roles as role} + + {/each} +
diff --git a/plugins/card-resources/src/index.ts b/plugins/card-resources/src/index.ts index a458f572ab..43d310d4ae 100644 --- a/plugins/card-resources/src/index.ts +++ b/plugins/card-resources/src/index.ts @@ -47,6 +47,8 @@ import CardArrayEditor from './components/CardArrayEditor.svelte' import NewCardHeader from './components/navigator/NewCardHeader.svelte' import SpacePresenter from './components/navigator/SpacePresenter.svelte' import LabelsPresenter from './components/LabelsPresenter.svelte' +import RolesSection from './components/settings/RolesSection.svelte' +import EditRole from './components/settings/EditRole.svelte' export { default as CardSelector } from './components/CardSelector.svelte' @@ -76,7 +78,9 @@ export default async (): Promise => ({ CardArrayEditor, NewCardHeader, SpacePresenter, - LabelsPresenter + LabelsPresenter, + RolesSection, + EditRole }, completion: { CardQuery: queryCard diff --git a/plugins/card-resources/src/plugin.ts b/plugins/card-resources/src/plugin.ts index e8df8e694a..d8297cffd0 100644 --- a/plugins/card-resources/src/plugin.ts +++ b/plugins/card-resources/src/plugin.ts @@ -46,7 +46,9 @@ export default mergeIds(cardId, card, { CardArrayEditor: '' as AnyComponent, NewCardHeader: '' as AnyComponent, SpacePresenter: '' as AnyComponent, - LabelsPresenter: '' as AnyComponent + LabelsPresenter: '' as AnyComponent, + RolesSection: '' as AnyComponent, + EditRole: '' as AnyComponent }, completion: { CardQuery: '' as Resource, diff --git a/plugins/card/src/index.ts b/plugins/card/src/index.ts index c290138842..4351c265f4 100644 --- a/plugins/card/src/index.ts +++ b/plugins/card/src/index.ts @@ -11,7 +11,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Blobs, Class, Doc, Domain, MarkupBlobRef, Mixin, Rank, Ref, Space } from '@hcengineering/core' +import { + AttachedDoc, + Blobs, + Class, + CollectionSize, + Doc, + Domain, + MarkupBlobRef, + Mixin, + Rank, + Ref, + Space +} from '@hcengineering/core' import { Asset, IntlString, plugin, Plugin } from '@hcengineering/platform' import type { AnyComponent, ComponentExtensionId } from '@hcengineering/ui' @@ -20,10 +32,16 @@ export * from './analytics' export interface MasterTag extends Class { color?: number removed?: boolean + roles?: CollectionSize } export interface Tag extends MasterTag, Mixin {} +export interface Role extends AttachedDoc { + name: string + attachedTo: Ref +} + export interface Card extends Doc { _class: Ref title: string @@ -69,7 +87,8 @@ const cardPlugin = plugin(cardId, { MasterTag: '' as Ref>, Tag: '' as Ref>, MasterTagEditorSection: '' as Ref>, - CardSpace: '' as Ref> + CardSpace: '' as Ref>, + Role: '' as Ref> }, space: { Default: '' as Ref diff --git a/plugins/contact/src/index.ts b/plugins/contact/src/index.ts index 83f8e77a3a..6c51d5f9cb 100644 --- a/plugins/contact/src/index.ts +++ b/plugins/contact/src/index.ts @@ -38,7 +38,7 @@ import { TemplateField, TemplateFieldCategory } from '@hcengineering/templates' import type { AnyComponent, ColorDefinition, ResolvedLocation, Location, ComponentExtensionId } from '@hcengineering/ui' import { Action, FilterMode, Viewlet } from '@hcengineering/view' import type { Readable } from 'svelte/store' -import { Card, MasterTag } from '@hcengineering/card' +import { Card, MasterTag, Role } from '@hcengineering/card' import { PermissionsStore } from './types' /** @@ -144,6 +144,11 @@ export interface Person extends Contact, BasePerson { profile?: Ref } +export interface UserRole extends Doc { + user: Ref + role: Ref +} + /** * @public */ @@ -213,7 +218,8 @@ export const contactPlugin = plugin(contactId, { ContactsTab: '' as Ref>, PersonSpace: '' as Ref>, SocialIdentity: '' as Ref>, - UserProfile: '' as Ref + UserProfile: '' as Ref, + UserRole: '' as Ref> }, mixin: { Employee: '' as Ref> diff --git a/plugins/process-assets/lang/cs.json b/plugins/process-assets/lang/cs.json index 7c6abb1479..ed4dee5a34 100644 --- a/plugins/process-assets/lang/cs.json +++ b/plugins/process-assets/lang/cs.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Objekt nenalezen: {_id}", "EmptyRelatedObjectValue": "Prázdná hodnota {attr} souvisejícího objektu: {parent}", "InternalServerError": "Vnitřní chyba serveru, kontaktujte podporu, chybové id: {errorId}", - "ResultNotProvided": "Výsledek nebyl poskytnut" + "ResultNotProvided": "Výsledek nebyl poskytnut", + "EmptyFunctionResult": "Prázdný výsledek funkce {func}" } } diff --git a/plugins/process-assets/lang/de.json b/plugins/process-assets/lang/de.json index 2d1b9e4977..09356533f6 100644 --- a/plugins/process-assets/lang/de.json +++ b/plugins/process-assets/lang/de.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Objekt nicht gefunden: {_id}", "EmptyRelatedObjectValue": "Leerer verwandtes Objekt {parent} Wert: {attr}", "InternalServerError": "Interner Serverfehler, bitte kontaktieren Sie den Support, Fehler-ID: {errorId}", - "ResultNotProvided": "Ergebnis nicht bereitgestellt" + "ResultNotProvided": "Ergebnis nicht bereitgestellt", + "EmptyFunctionResult": "Leerer Funktionsresultat {func}" } } diff --git a/plugins/process-assets/lang/en.json b/plugins/process-assets/lang/en.json index 1e0e5677c2..5f2f3af802 100644 --- a/plugins/process-assets/lang/en.json +++ b/plugins/process-assets/lang/en.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Object not found: {_id}", "EmptyRelatedObjectValue": "Empty related object {parent} value: {attr}", "InternalServerError": "Internal server error, contact support, error id: {errorId}", - "ResultNotProvided": "Result not provided" + "ResultNotProvided": "Result not provided", + "EmptyFunctionResult": "Empty function result {func}" } } diff --git a/plugins/process-assets/lang/es.json b/plugins/process-assets/lang/es.json index 27ee6c93c3..9eb671677d 100644 --- a/plugins/process-assets/lang/es.json +++ b/plugins/process-assets/lang/es.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Objeto no encontrado: {_id}", "EmptyRelatedObjectValue": "Valor de objeto relacionado vacío: {parent} {attr}", "InternalServerError": "Error interno del servidor, contacte con el soporte, id de error: {errorId}", - "ResultNotProvided": "Resultado no proporcionado" + "ResultNotProvided": "Resultado no proporcionado", + "EmptyFunctionResult": "Resultado de función vacío {func}" } } diff --git a/plugins/process-assets/lang/fr.json b/plugins/process-assets/lang/fr.json index 07e1a40b43..c314b45f2d 100644 --- a/plugins/process-assets/lang/fr.json +++ b/plugins/process-assets/lang/fr.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Objet introuvable : {_id}", "EmptyRelatedObjectValue": "Valeur d'objet lié vide : {parent} {attr}", "InternalServerError": "Erreur interne du serveur, contactez le support, id d'erreur : {errorId}", - "ResultNotProvided": "Résultat non fourni" + "ResultNotProvided": "Résultat non fourni", + "EmptyFunctionResult": "Résultat de fonction vide {func}" } } \ No newline at end of file diff --git a/plugins/process-assets/lang/it.json b/plugins/process-assets/lang/it.json index 6f0a5fd905..8accb6135f 100644 --- a/plugins/process-assets/lang/it.json +++ b/plugins/process-assets/lang/it.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Oggetto non trovato: {_id}", "EmptyRelatedObjectValue": "Valore oggetto correlato vuoto: {parent} {attr}", "InternalServerError": "Errore interno del server, contatta il supporto, id errore: {errorId}", - "ResultNotProvided": "Risultato non fornito" + "ResultNotProvided": "Risultato non fornito", + "EmptyFunctionResult": "Risultato funzione vuoto {func}" } } diff --git a/plugins/process-assets/lang/ja.json b/plugins/process-assets/lang/ja.json index 0e9b32d1d9..65265b2977 100644 --- a/plugins/process-assets/lang/ja.json +++ b/plugins/process-assets/lang/ja.json @@ -61,6 +61,7 @@ "UserRequestedValueNotProvided": "ユーザーが要求した値が提供されていません: {attr}", "ObjectNotFound": "オブジェクトが見つかりません: {_id}", "EmptyRelatedObjectValue": "関連オブジェクト {parent} の値が空です: {attr}", - "InternalServerError": "内部サーバーエラー。サポートにお問い合わせください。エラーID: {errorId}" + "InternalServerError": "内部サーバーエラー。サポートにお問い合わせください。エラーID: {errorId}", + "EmptyFunctionResult": "関数結果が空です {func}" } } diff --git a/plugins/process-assets/lang/pt.json b/plugins/process-assets/lang/pt.json index 25ce7ae3ac..8d9754cfa1 100644 --- a/plugins/process-assets/lang/pt.json +++ b/plugins/process-assets/lang/pt.json @@ -65,6 +65,7 @@ "ObjectNotFound": "Objeto não encontrado: {_id}", "EmptyRelatedObjectValue": "Valor de objeto relacionado vazio: {parent} {attr}", "InternalServerError": "Erro interno do servidor, contate o suporte, id de erro: {errorId}", - "ResultNotProvided": "Resultado não fornecido" + "ResultNotProvided": "Resultado não fornecido", + "EmptyFunctionResult": "Resultado da função vazio {func}" } } diff --git a/plugins/process-assets/lang/ru.json b/plugins/process-assets/lang/ru.json index 553c8cae33..ab84f6e71f 100644 --- a/plugins/process-assets/lang/ru.json +++ b/plugins/process-assets/lang/ru.json @@ -65,6 +65,7 @@ "UserRequestedValueNotProvided": "Знвчение не предоставлено пользователем: {attr}", "ObjectNotFound": "Объект не найден: {_id}", "AttributeNotExists": "Атрибут не существует: {key}", - "ResultNotProvided": "Результат не предоставлен" + "ResultNotProvided": "Результат не предоставлен", + "EmptyFunctionResult": "Отсутствуют результат функции {func}" } } diff --git a/plugins/process-assets/lang/zh.json b/plugins/process-assets/lang/zh.json index 2b1bd6db8a..b6c511a110 100644 --- a/plugins/process-assets/lang/zh.json +++ b/plugins/process-assets/lang/zh.json @@ -65,6 +65,7 @@ "ObjectNotFound": "找不到对象:{_id}", "EmptyRelatedObjectValue": "空相关对象值:{parent} {attr}", "InternalServerError": "内部服务器错误,请联系支持,错误 ID:{errorId}", - "ResultNotProvided": "未提供结果" + "ResultNotProvided": "未提供结果", + "EmptyFunctionResult": "空函数结果 {func}" } } diff --git a/plugins/process-resources/src/components/ProcessAttribute.svelte b/plugins/process-resources/src/components/ProcessAttribute.svelte index 853621e88e..c943544922 100644 --- a/plugins/process-resources/src/components/ProcessAttribute.svelte +++ b/plugins/process-resources/src/components/ProcessAttribute.svelte @@ -29,7 +29,9 @@ import { createEventDispatcher } from 'svelte' import ContextSelectorPopup from './attributeEditors/ContextSelectorPopup.svelte' import ContextValue from './attributeEditors/ContextValue.svelte' + import { MasterTag, Tag } from '@hcengineering/card' + export let masterTag: Ref export let value: any export let context: Context export let presenterClass: { @@ -52,6 +54,7 @@ showPopup( ContextSelectorPopup, { + masterTag, context, attribute, onSelect @@ -78,6 +81,7 @@
{#if contextValue} { diff --git a/plugins/process-resources/src/components/ProcessEditor.svelte b/plugins/process-resources/src/components/ProcessEditor.svelte index 2244b5ae2b..6239c2a350 100644 --- a/plugins/process-resources/src/components/ProcessEditor.svelte +++ b/plugins/process-resources/src/components/ProcessEditor.svelte @@ -13,10 +13,10 @@ // limitations under the License. --> @@ -89,8 +92,38 @@