- {#if !_readonly}
+ {#if !_readonly && !updatePermissionForbidden}
-
+
diff --git a/plugins/card-resources/src/components/EditCardOld.svelte b/plugins/card-resources/src/components/EditCardOld.svelte
index 7cf8cdbc39a..0b34b4ba4b7 100644
--- a/plugins/card-resources/src/components/EditCardOld.svelte
+++ b/plugins/card-resources/src/components/EditCardOld.svelte
@@ -42,6 +42,7 @@
import Childs from './Childs.svelte'
import Content from './Content.svelte'
import TagsEditor from './TagsEditor.svelte'
+ import { canChangeDoc, permissionsStore } from '@hcengineering/contact-resources'
export let _id: Ref
export let readonly: boolean = false
@@ -87,6 +88,7 @@
})
$: _readonly = (readonly || doc?.readonly) ?? false
+ $: updatePermissionForbidden = doc && !canChangeDoc(doc?._class, doc?.space, $permissionsStore)
$: canSave = title.trim().length > 0 && !_readonly
async function saveTitle (ev: Event): Promise {
@@ -161,14 +163,20 @@
- saveTitle(evt)} />
+ saveTitle(evt)}
+ />
-
+
-
+
-
+
{#if !_readonly}
diff --git a/plugins/card-resources/src/components/TagAttributes.svelte b/plugins/card-resources/src/components/TagAttributes.svelte
index f1917a45905..74271af45ae 100644
--- a/plugins/card-resources/src/components/TagAttributes.svelte
+++ b/plugins/card-resources/src/components/TagAttributes.svelte
@@ -14,13 +14,13 @@
-->
{#if contentDiv != null}
-
+
{/if}
diff --git a/plugins/contact-resources/src/utils.ts b/plugins/contact-resources/src/utils.ts
index 967117fe85e..2945a942b96 100644
--- a/plugins/contact-resources/src/utils.ts
+++ b/plugins/contact-resources/src/utils.ts
@@ -53,6 +53,7 @@ import {
import core, {
type AccountUuid,
type AggregateValue,
+ type AnyAttribute,
type Class,
type Client,
type Doc,
@@ -670,6 +671,58 @@ export function checkMyPermission (_id: Ref, space: Ref,
return (store.whitelist.has(space) || store.ps[space]?.has(_id)) ?? false
}
+export function canChangeAttribute (
+ attr: AnyAttribute,
+ space: Ref,
+ store: PermissionsStore,
+ _class?: Ref>
+): boolean {
+ const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
+ if (arePermissionsDisabled) return true
+ if (store.whitelist.has(space)) return true
+ const forbiddenId = `${attr._id}_forbidden` as Ref
+ const forbidden = store.ps[space]?.has(forbiddenId)
+ if (forbidden) {
+ return false
+ }
+ const allowedId = `${attr._id}_allowed` as Ref
+ const allowed = store.ps[space]?.has(allowedId)
+ if (allowed) {
+ return true
+ }
+
+ return canChangeDoc(_class ?? attr.attributeOf, space, store)
+}
+
+export function canChangeDoc (_class: Ref>, space: Ref, store: PermissionsStore): boolean {
+ const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
+ if (arePermissionsDisabled) return true
+ if (store.whitelist.has(space)) return true
+ if (store.ps[space] !== undefined) {
+ const client = getClient()
+ const h = client.getHierarchy()
+ const ancestors = h.getAncestors(_class)
+ const permissions = client
+ .getModel()
+ .findAllSync(core.class.Permission, { txClass: { $in: [core.class.TxUpdateDoc, core.class.TxMixin] } })
+ for (const ancestor of ancestors) {
+ const curr = permissions.filter(
+ (p) =>
+ p.objectClass === ancestor &&
+ p.txMatch === undefined &&
+ p.txClass === (h.isMixin(ancestor) ? core.class.TxMixin : core.class.TxUpdateDoc)
+ )
+ for (const permission of curr) {
+ if (store.ps[space]?.has(permission._id)) {
+ return permission.forbid !== true
+ }
+ }
+ }
+ }
+
+ return !store.restrictedSpaces.has(space)
+}
+
export function getPermittedPersons (
_id: Ref,
space: Ref,
@@ -686,6 +739,7 @@ export const permissionsStore = derived(
[spacesStore, employeeRefByAccountUuidStore],
([spaces, personRefByAccount]) => {
const whitelistedSpaces = new Set[>()
+ const restrictedSpaces = new Set][>()
const permissionsBySpace: PermissionsBySpace = {}
const employeesByPermission: PersonsByPermission = {}
const membersBySpace: MembersBySpace = {}
@@ -695,6 +749,10 @@ export const permissionsStore = derived(
for (const s of spaces) {
membersBySpace[s._id] = new Set(s.members.map((m) => personRefByAccount.get(m)).filter(notEmpty))
if (hierarchy.isDerived(s._class, core.class.TypedSpace)) {
+ const typedSpace = s as TypedSpace
+ if (typedSpace.restricted === true) {
+ restrictedSpaces.add(s._id)
+ }
const type = client.getModel().findAllSync(core.class.SpaceType, { _id: (s as TypedSpace).type })[0]
const mixin = type?.targetClass
@@ -740,7 +798,8 @@ export const permissionsStore = derived(
ps: permissionsBySpace,
ap: employeesByPermission,
ms: membersBySpace,
- whitelist: whitelistedSpaces
+ whitelist: whitelistedSpaces,
+ restrictedSpaces
}
}
)
diff --git a/plugins/contact/src/types.ts b/plugins/contact/src/types.ts
index 61962445463..c5fa89b182a 100644
--- a/plugins/contact/src/types.ts
+++ b/plugins/contact/src/types.ts
@@ -58,6 +58,7 @@ export interface PermissionsStore {
ap: PersonsByPermission
ms: MembersBySpace
whitelist: Set][>
+ restrictedSpaces: Set][>
}
export type UserProfile = Card & { person: Ref }
diff --git a/plugins/process-resources/src/components/ProcessesHeaderExtension.svelte b/plugins/process-resources/src/components/ProcessesHeaderExtension.svelte
index eb094826f4e..c549313f386 100644
--- a/plugins/process-resources/src/components/ProcessesHeaderExtension.svelte
+++ b/plugins/process-resources/src/components/ProcessesHeaderExtension.svelte
@@ -27,14 +27,13 @@
let todos: ProcessToDo[] = []
const executionQuery = createQuery()
- executionQuery.query(
+ $: executionQuery.query(
process.class.Execution,
{
card: card._id,
status: { $ne: ExecutionStatus.Cancelled }
},
(res) => {
- console.log(res)
docs = res
}
)
]