diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 59864078c6..b69e75afff 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -16,6 +16,7 @@ import { deepEqual } from 'fast-equals' import { Account, + AccountRole, AnyAttribute, AttachedData, AttachedDoc, @@ -784,3 +785,9 @@ export function reduceCalls) => Promise< } } } + +export function isOwnerOrMaintainer (): boolean { + const account = getCurrentAccount() + + return [AccountRole.Owner, AccountRole.Maintainer].includes(account.role) +} diff --git a/packages/text-editor/src/components/StyledTextBox.svelte b/packages/text-editor/src/components/StyledTextBox.svelte index bedab2148c..591f9e3b0f 100644 --- a/packages/text-editor/src/components/StyledTextBox.svelte +++ b/packages/text-editor/src/components/StyledTextBox.svelte @@ -53,6 +53,7 @@ export let enableInlineCommands: boolean = true export let isScrollable: boolean = true export let boundary: HTMLElement | undefined = undefined + export let readonly: boolean = false export let attachFile: FileAttachFunction | undefined = undefined @@ -99,6 +100,8 @@ $: if (!modified && rawValue !== content) modified = true $: dispatch('change', modified) + $: textEditor?.setEditable(!readonly) + export function submit (): void { textEditor.submit() } @@ -292,6 +295,7 @@ id="imageInput" accept="image/*" style="display: none" + disabled={readonly} on:change={fileSelected} /> @@ -302,7 +306,7 @@ class:antiIndented={kind === 'indented'} class:focusable={(mode === Mode.Edit || alwaysEdit) && focused} on:click={() => { - if (alwaysEdit && focused) { + if (alwaysEdit && focused && !readonly) { textEditor?.focus() } }} @@ -313,7 +317,7 @@ {#if label}
{/if} - {#if mode !== Mode.View || alwaysEdit} + {#if (mode !== Mode.View || alwaysEdit) && !readonly} {/if} - {#if !alwaysEdit && !hideExtraButtons} + {#if !alwaysEdit && !hideExtraButtons && !readonly}
-
dispatch('close', emoji)}> +
{ + if (disabled) return + + dispatch('close', emoji) + }} + > {emoji}
{/if} @@ -248,13 +258,19 @@ cursor: pointer; &:hover { - color: var(--theme-caption-color); - background-color: var(--theme-popup-hover); + &:not(&.disabled) { + color: var(--theme-caption-color); + background-color: var(--theme-popup-hover); + } } &.selected { background-color: var(--theme-popup-header); border: 1px solid var(--theme-popup-divider); } + + &.disabled { + cursor: default; + } } diff --git a/plugins/recruit-resources/src/components/VacancyTemplateEditor.svelte b/plugins/recruit-resources/src/components/VacancyTemplateEditor.svelte index a033896e73..99279a8e41 100644 --- a/plugins/recruit-resources/src/components/VacancyTemplateEditor.svelte +++ b/plugins/recruit-resources/src/components/VacancyTemplateEditor.svelte @@ -22,6 +22,7 @@ import recruit from '../plugin' export let type: ProjectType + export let disabled: boolean = true const client = getClient() @@ -29,6 +30,9 @@ const customKeys = getFiltredKeys(hierarchy, type._class, []).filter((key) => key.attr.isCustom) async function onDescriptionChange (value: string) { + if (disabled) { + return + } await client.diffUpdate(type, { description: value }) } @@ -45,6 +49,8 @@ maxHeight={'card'} showButtons={false} content={type.description ?? ''} + focusable={!disabled} + readonly={disabled} on:value={(evt) => onDescriptionChange(evt.detail)} /> {/key} @@ -58,18 +64,21 @@ -
-
+ {#if !disabled} +
+
+ {/if}
@@ -77,6 +86,6 @@
{#if customKeys && customKeys.length > 0}
- +
{/if} diff --git a/plugins/setting-assets/lang/en.json b/plugins/setting-assets/lang/en.json index bdfa245647..a33b1f41b6 100644 --- a/plugins/setting-assets/lang/en.json +++ b/plugins/setting-assets/lang/en.json @@ -111,6 +111,8 @@ "Roles": "Roles", "RoleName": "Role name", "Permissions": "Permissions", - "Assignees": "Assignees" + "Assignees": "Assignees", + "DeleteRole": "Delete role", + "DeleteRoleConfirmation": "Are you sure you want to delete this role? All users with this role will lose their permissions." } -} \ No newline at end of file +} diff --git a/plugins/setting-assets/lang/es.json b/plugins/setting-assets/lang/es.json index b909d75476..c3ce70c76e 100644 --- a/plugins/setting-assets/lang/es.json +++ b/plugins/setting-assets/lang/es.json @@ -102,6 +102,8 @@ "Collections": "Colecciones", "ClassColon": "Clase:", "Branding": "Marca", - "Assignees": "Atribuídos" + "Assignees": "Atribuídos", + "DeleteRole": "Eliminar función", + "DeleteRoleConfirmation": "¿Está seguro de que desea eliminar esta función? Todos los usuarios con este rol perderán sus permisos" } } \ No newline at end of file diff --git a/plugins/setting-assets/lang/pt.json b/plugins/setting-assets/lang/pt.json index 5bcf01fdc6..2f9f0dfa88 100644 --- a/plugins/setting-assets/lang/pt.json +++ b/plugins/setting-assets/lang/pt.json @@ -102,6 +102,8 @@ "Collections": "Coleções", "ClassColon": "Classe:", "Branding": "Marca", - "Assignees": "" + "Assignees": "Atribuídos", + "DeleteRole": "Eliminar função", + "DeleteRoleConfirmation": "Tem a certeza de que pretende eliminar esta função? Todos os utilizadores com esta função perderão as suas permissões." } } \ No newline at end of file diff --git a/plugins/setting-assets/lang/ru.json b/plugins/setting-assets/lang/ru.json index 7992f37384..b885a8b938 100644 --- a/plugins/setting-assets/lang/ru.json +++ b/plugins/setting-assets/lang/ru.json @@ -112,6 +112,8 @@ "Roles": "Роли", "RoleName": "Название роли", "Permissions": "Разрешения", - "Assignees": "Назначенные" + "Assignees": "Назначенные", + "DeleteRole": "Удалить роль", + "DeleteRoleConfirmation": "Вы действительно хотите удалить эту роль? Все пользователи с этой ролью потеряют имеющиеся разрешения." } } diff --git a/plugins/setting-resources/src/components/ClassAttributes.svelte b/plugins/setting-resources/src/components/ClassAttributes.svelte index 5a108ef397..2f2d14a85f 100644 --- a/plugins/setting-resources/src/components/ClassAttributes.svelte +++ b/plugins/setting-resources/src/components/ClassAttributes.svelte @@ -42,7 +42,7 @@ export let ofClass: Ref> | undefined = undefined export let showHierarchy: boolean = false export let showTitle: boolean = !showHierarchy - + export let disabled: boolean = true export let attributeMapper: | { component: AnySvelteComponent @@ -73,12 +73,20 @@ } export function createAttribute (ev: MouseEvent): void { + if (disabled) { + return + } + showPopup(TypesPopup, { _class }, getEventPositionElement(ev), (_id) => { if (_id !== undefined) $settingsStore = { component: CreateAttribute, props: { selectedType: _id, _class } } }) } function editLabel (evt: MouseEvent): void { + if (disabled) { + return + } + showPopup(EditClassLabel, { clazz }, getEventPositionElement(evt)) } @@ -113,7 +121,7 @@ const handleSelect = async (event: CustomEvent): Promise => { selected = event.detail as AnyAttribute const exist = (await client.findOne(selected.attributeOf, { [selected.name]: { $exists: true } })) !== undefined - $settingsStore = { id: selected._id, component: EditAttribute, props: { attribute: selected, exist } } + $settingsStore = { id: selected._id, component: EditAttribute, props: { attribute: selected, exist, disabled } } } onDestroy(() => { if (selected !== undefined) clearSettingsStore() @@ -128,7 +136,7 @@
{#if clazz.kind === ClassifierKind.MIXIN && hierarchy.hasMixin(clazz, settings.mixin.UserMixin)}
- +
{/if} @@ -137,7 +145,7 @@
{#if showHierarchy} - + @@ -149,6 +157,7 @@ kind={'primary'} icon={IconAdd} size={'small'} + {disabled} on:click={(ev) => { createAttribute(ev) }} diff --git a/plugins/setting-resources/src/components/EditAttribute.svelte b/plugins/setting-resources/src/components/EditAttribute.svelte index 024780e0bc..51518886f0 100644 --- a/plugins/setting-resources/src/components/EditAttribute.svelte +++ b/plugins/setting-resources/src/components/EditAttribute.svelte @@ -35,6 +35,8 @@ export let attribute: AnyAttribute export let exist: boolean + export let disabled: boolean = true + let name: string let type: Type | undefined = attribute.type let index: IndexKind | undefined = attribute.index @@ -47,6 +49,10 @@ translate(attribute.label, {}, $themeStore.language).then((p) => (name = p)) async function save (): Promise { + if (disabled) { + return + } + const update: DocumentUpdate = {} const newLabel = getEmbeddedLabel(name) if (newLabel !== attribute.label) { @@ -98,6 +104,7 @@ selectType(e.detail) } const handleChange = (e: any) => { + if (disabled) return type = e.detail?.type index = e.detail?.index defaultValue = e.detail?.defaultValue @@ -109,14 +116,16 @@ type={'type-aside'} okLabel={presentation.string.Save} okAction={save} - canSave={!(name === undefined || name.trim().length === 0)} + canSave={!(name === undefined || name.trim().length === 0) && !disabled} onCancel={() => { clearSettingsStore() }} > - - + {#if !disabled} + + + {/if}
{#if attribute.isCustom} @@ -124,7 +133,7 @@
{/if} - +
@@ -141,6 +150,7 @@ width="8rem" bind:selected={selectedType} on:selected={handleSelect} + {disabled} /> {/if}
@@ -150,10 +160,11 @@ props={{ type, defaultValue, - editable: !exist, + editable: !exist && !disabled, kind: 'regular', size: 'large' }} + {disabled} on:change={handleChange} /> {/if} diff --git a/plugins/setting-resources/src/components/spaceTypes/ManageSpaceTypeContent.svelte b/plugins/setting-resources/src/components/spaceTypes/ManageSpaceTypeContent.svelte index 3e6dfc839b..27217f0dcc 100644 --- a/plugins/setting-resources/src/components/spaceTypes/ManageSpaceTypeContent.svelte +++ b/plugins/setting-resources/src/components/spaceTypes/ManageSpaceTypeContent.svelte @@ -15,7 +15,16 @@ --> -