Skip to content

Commit

Permalink
Merge pull request #79 from GBSL-Informatik/refactor/show-user-permis…
Browse files Browse the repository at this point in the history
…sion-panel-when-no-permission-exists

refactor: show user permission panel even when no permission exists yet
  • Loading branch information
lebalz authored Jan 7, 2025
2 parents 5502089 + 7360d54 commit 9af928a
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 11 deletions.
39 changes: 39 additions & 0 deletions src/components/PermissionsPanel/AccessBadge/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import clsx from 'clsx';
import styles from './styles.module.scss';
import { observer } from 'mobx-react-lite';
import { Access } from '@tdev-api/document';
import Icon from '@mdi/react';
import { ROAccess, RWAccess } from '@tdev-models/helpers/accessPolicy';
import { mdiEye, mdiEyeOff, mdiSquareEditOutline } from '@mdi/js';
const SIZE = 0.8;
const AccessIcon = (access: Access) => {
if (RWAccess.has(access)) {
return mdiSquareEditOutline;
}
if (ROAccess.has(access)) {
return mdiEye;
}
return mdiEyeOff;
};

interface Props {
access?: Access;
defaultAccess?: Access;
className?: string;
size?: number;
}

const AccessBadge = observer((props: Props) => {
return (
<div className={clsx('badge', 'badge--secondary', styles.accessBadge, props.className)}>
<Icon
path={AccessIcon(props.access || props.defaultAccess || Access.None_DocumentRoot)}
size={props.size || SIZE}
color="var(--ifm-color-blue)"
/>
</div>
);
});

export default AccessBadge;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.accessBadge {
padding: 2px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const AccessPanel = observer((props: Props) => {
if (currentPermission) {
currentPermission.setAccess(access);
} else {
permissionStore.createUserPermission(dr, user, access);
permissionStore.createUserPermission(dr.id, user, access);
}
});
}}
Expand Down
24 changes: 23 additions & 1 deletion src/components/PermissionsPanel/UserPermission/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,44 @@ import Button from '@tdev-components/shared/Button';
import { mdiAccountCircle, mdiDelete } from '@mdi/js';
import Icon from '@mdi/react';
import { Access } from '@tdev-api/document';
import { useStore } from '@tdev-hooks/useStore';

interface SingleProps {
permission: UserPermissionModel;
documentRootId?: string;
permissions?: never;
documentRootIds?: never;
}
interface MultiProps {
permissions: UserPermissionModel[];
documentRootIds?: string[];
permission?: never;
documentRootId?: never;
}
type Props = SingleProps | MultiProps;

const UserPermission = observer((props: Props) => {
const { permission, permissions } = props;
const models = permissions || [permission];
const permissionStore = useStore('permissionStore');
const docRootIds = (props.documentRootId ? [props.documentRootId] : props.documentRootIds) || [];
const userStore = useStore('userStore');
if (models.length === 0) {
return null;
const { viewedUser } = userStore;
if (docRootIds.length === 0 || !viewedUser) {
return null;
}
return (
<AccessSelector
accessTypes={[Access.RO_User, Access.RW_User, Access.None_User]}
access={undefined}
onChange={(access) => {
docRootIds.forEach((docRootId) => {
permissionStore.createUserPermission(docRootId, viewedUser, access);
});
}}
/>
);
}
const firstModel = models[0];
if (!models.every((p) => p.userId === firstModel.userId)) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/PermissionsPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const PermissionsPanel = observer((props: Props) => {
}
const firstRoot = documentRoots[0];

if (viewedUser && viewedUser !== userStore.current) {
if (viewedUser && userStore.isUserSwitched) {
const userPermissions = documentRoots
.map((dr) =>
permissionStore
Expand All @@ -71,7 +71,7 @@ const PermissionsPanel = observer((props: Props) => {
className={clsx(styles.viewedUserPermissionPanel, props.className)}
onClick={(e) => e.stopPropagation()}
>
<UserPermission permissions={userPermissions} />
<UserPermission permissions={userPermissions} documentRootIds={docRootIds} />
</div>
);
}
Expand Down
12 changes: 10 additions & 2 deletions src/components/documents/Restricted/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Access } from '@tdev-api/document';
import { useStore } from '@tdev-hooks/useStore';
import PermissionsPanel from '@tdev-components/PermissionsPanel';
import { NoneAccess } from '@tdev-models/helpers/accessPolicy';
import AccessBadge from '@tdev-components/PermissionsPanel/AccessBadge';

interface Props extends MetaInit {
id: string;
Expand Down Expand Up @@ -38,8 +39,15 @@ const Restricted = observer((props: Props) => {
)}
<div className={styles.adminControls}>
{userStore.current?.isAdmin && <PermissionsPanel documentRootId={docRoot.id} />}
{userStore.current?.isAdmin && NoneAccess.has(docRoot.permission) && (
<span className="badge badge--secondary">Hidden</span>
{userStore.current?.isAdmin && (
<AccessBadge
access={
userStore.viewedUserId
? docRoot.permissionForUser(userStore.viewedUserId)
: docRoot.permission
}
defaultAccess={docRoot.rootAccess}
/>
)}
</div>
</div>
Expand Down
12 changes: 10 additions & 2 deletions src/components/documents/Solution/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Icon from '@mdi/react';
import { mdiCheckAll } from '@mdi/js';
import PermissionsPanel from '@tdev-components/PermissionsPanel';
import { NoneAccess } from '@tdev-models/helpers/accessPolicy';
import AccessBadge from '@tdev-components/PermissionsPanel/AccessBadge';

interface Props extends MetaInit {
id: string;
Expand Down Expand Up @@ -43,8 +44,15 @@ const Solution = observer((props: Props) => {
{userStore.current?.isAdmin && (
<PermissionsPanel documentRootId={docRoot.id} />
)}
{NoneAccess.has(docRoot.permission) && (
<span className="badge badge--secondary">Hidden</span>
{userStore.current?.isAdmin && (
<AccessBadge
access={
userStore.viewedUserId
? docRoot.permissionForUser(userStore.viewedUserId)
: docRoot.permission
}
defaultAccess={docRoot.rootAccess}
/>
)}
<Icon
path={mdiCheckAll}
Expand Down
6 changes: 3 additions & 3 deletions src/stores/PermissionStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ class PermissionStore extends iStore<`update-${string}`> {
}

@action
createUserPermission(documentRoot: DocumentRoot<any>, user: User, access: Access) {
this.withAbortController(`create-${documentRoot.id}-${user.id}`, async (signal) => {
createUserPermission(documentRootId: string, user: User, access: Access) {
this.withAbortController(`create-${documentRootId}-${user.id}`, async (signal) => {
return createUserPermissionApi(
{
userId: user.id,
access: access,
documentRootId: documentRoot.id
documentRootId: documentRootId
},
signal.signal
).then(({ data }) => {
Expand Down

0 comments on commit 9af928a

Please sign in to comment.