Skip to content

Commit 28289cb

Browse files
committed
fix(edit-unit): fix permissions of editing unit members, names and default privacy
1 parent f401dbc commit 28289cb

File tree

6 files changed

+37
-37
lines changed

6 files changed

+37
-37
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"@rjsf/utils": "5.18.3",
5353
"@rjsf/validator-ajv8": "5.18.3",
5454
"@sentry/nextjs": "7.112.2",
55-
"@squonk/account-server-client": "2.1.2",
55+
"@squonk/account-server-client": "2.1.4",
5656
"@squonk/data-manager-client": "2.0.11-rc.1",
5757
"@squonk/mui-theme": "3.0.2",
5858
"@squonk/sdf-parser": "1.3.0",

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/units/EditDefaultPrivacy.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { MenuItem, TextField } from "@mui/material";
99
import { useQueryClient } from "@tanstack/react-query";
1010

1111
import { useEnqueueError } from "../../hooks/useEnqueueStackError";
12-
import { useKeycloakUser } from "../../hooks/useKeycloakUser";
1312
import { useSelectedOrganisation } from "../../state/organisationSelection";
1413
import { useSelectedUnit } from "../../state/unitSelection";
1514
import { capitalise, shoutSnakeToLowerCase } from "../../utils/app/language";
@@ -19,8 +18,6 @@ export interface EditDefaultPrivacyProps {
1918
}
2019

2120
export const EditDefaultPrivacy = ({ unit }: EditDefaultPrivacyProps) => {
22-
const { user } = useKeycloakUser();
23-
2421
const [organisation] = useSelectedOrganisation();
2522
const [, setUnit] = useSelectedUnit();
2623

@@ -47,12 +44,11 @@ export const EditDefaultPrivacy = ({ unit }: EditDefaultPrivacyProps) => {
4744
}
4845
};
4946

50-
// const isOrganisationMember = organisation?.caller_is_member;
51-
const isUnitOwner = unit.owner_id === user.username;
47+
const isOrganisationMember = organisation?.caller_is_member;
48+
const isUnitMember = unit.caller_is_member;
5249
const isPersonalUnit = organisation?.name === process.env.NEXT_PUBLIC_DEFAULT_ORG_NAME;
5350

54-
// const allowedToEdit = !isPersonalUnit && (isUnitOwner || isOrganisationMember);
55-
const allowedToEdit = !isPersonalUnit && isUnitOwner;
51+
const allowedToEdit = !isPersonalUnit && (!!isOrganisationMember || isUnitMember);
5652

5753
const helperText = isPersonalUnit
5854
? "Default project privacy of personal units may not be changed"

src/components/units/EditUnitName.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { useQueryClient } from "@tanstack/react-query";
1414
import { type AxiosError } from "axios";
1515

1616
import { useEnqueueError } from "../../hooks/useEnqueueStackError";
17-
import { useKeycloakUser } from "../../hooks/useKeycloakUser";
1817
import { useSelectedOrganisation } from "../../state/organisationSelection";
1918
import { useSelectedUnit } from "../../state/unitSelection";
2019
import { getErrorMessage } from "../../utils/next/orvalError";
@@ -24,8 +23,6 @@ export interface EditUnitProps {
2423
}
2524

2625
export const EditUnitName = ({ unit }: EditUnitProps) => {
27-
const { user } = useKeycloakUser();
28-
2926
const [organisation] = useSelectedOrganisation();
3027
const [, setUnit] = useSelectedUnit();
3128
const [name, setName] = useState(unit.name);
@@ -74,12 +71,11 @@ export const EditUnitName = ({ unit }: EditUnitProps) => {
7471
}
7572
};
7673

77-
// const isOrganisationMember = organisation?.caller_is_member;
78-
const isUnitOwner = unit.owner_id === user.username;
74+
const isOrganisationMember = organisation?.caller_is_member;
75+
const isUnitMember = unit.caller_is_member;
7976
const isPersonalUnit = organisation?.name === process.env.NEXT_PUBLIC_DEFAULT_ORG_NAME;
8077

81-
// const allowedToEdit = !isPersonalUnit && (isUnitOwner || isOrganisationMember);
82-
const allowedToEdit = !isPersonalUnit && isUnitOwner;
78+
const allowedToEdit = !isPersonalUnit && (!!isOrganisationMember || isUnitMember);
8379

8480
const helperText = isPersonalUnit
8581
? "Names of personal units may not be changed"

src/components/units/UnitEditors.tsx renamed to src/components/units/UnitMembers.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
} from "@squonk/account-server-client/user";
88
import { type DmError } from "@squonk/data-manager-client";
99

10-
import { Typography } from "@mui/material";
1110
import { useQueryClient } from "@tanstack/react-query";
1211

1312
import { useEnqueueError } from "../../hooks/useEnqueueStackError";
@@ -16,51 +15,59 @@ import { useSelectedOrganisation } from "../../state/organisationSelection";
1615
import { CenterLoader } from "../CenterLoader";
1716
import { ManageUsers } from "../ManageUsers";
1817

19-
export interface UnitEditorsProps {
18+
export interface UnitMembersProps {
2019
/**
2120
* Unit to be edited.
2221
*/
2322
unit: UnitDetail;
2423
}
2524

2625
/**
27-
* MuiAutocomplete to manage the current editors of the selected project
26+
* MuiAutocomplete to manage the current members of the selected project
2827
*/
29-
export const UnitEditors = ({ unit }: UnitEditorsProps) => {
28+
export const UnitMembers = ({ unit }: UnitMembersProps) => {
3029
const { user: currentUser } = useKeycloakUser();
3130

3231
const [organisation] = useSelectedOrganisation();
3332

3433
const { data, isLoading: isUsersLoading } = useGetOrganisationUnitUsers(unit.id, {
3534
query: { enabled: !!unit.caller_is_member || organisation?.caller_is_member },
3635
});
37-
const users = data?.users;
38-
const { mutateAsync: addEditor, isPending: isAdding } = useAddOrganisationUnitUser();
39-
const { mutateAsync: removeEditor, isPending: isRemoving } = useDeleteOrganisationUnitUser();
36+
const users = data?.users ?? [];
37+
const { mutateAsync: addMember, isPending: isAdding } = useAddOrganisationUnitUser();
38+
const { mutateAsync: removeMember, isPending: isRemoving } = useDeleteOrganisationUnitUser();
4039
const queryClient = useQueryClient();
4140

4241
const { enqueueError, enqueueSnackbar } = useEnqueueError<DmError>();
4342

43+
const isOrganisationMember = organisation?.caller_is_member;
44+
const isUnitMember = unit.caller_is_member;
4445
const isPersonalUnit = organisation?.name === process.env.NEXT_PUBLIC_DEFAULT_ORG_NAME;
4546

47+
const helperText = isPersonalUnit
48+
? "Members of personal unit may not be changed"
49+
: !isOrganisationMember || !isUnitMember
50+
? "You must be a unit or organisation member to view and modify unit members"
51+
: undefined;
52+
4653
if (isUsersLoading) {
4754
return <CenterLoader />;
4855
}
4956

50-
if (users && currentUser.username) {
57+
if (currentUser.username) {
5158
return (
5259
<ManageUsers
53-
disabled={isPersonalUnit}
60+
disabled={!!helperText}
5461
disabledUsers={[unit.owner_id]}
55-
helperText={isPersonalUnit ? "Editors of personal unit may not be changed" : undefined}
62+
helperText={helperText}
5663
isLoading={isAdding || isRemoving || isUsersLoading}
57-
title="Unit Editors"
64+
title="Unit Members"
5865
users={users.map((user) => user.id)}
5966
onRemove={async (value) => {
60-
const user = users.find((editor) => !value.includes(editor.id));
67+
const user = users.find((member) => !value.includes(member.id));
6168
if (user) {
6269
try {
63-
await removeEditor({ unitId: unit.id, userId: user.id });
70+
await removeMember({ unitId: unit.id, userId: user.id });
6471
} catch (error) {
6572
enqueueError(error);
6673
}
@@ -76,7 +83,7 @@ export const UnitEditors = ({ unit }: UnitEditorsProps) => {
7683
const username = value.reverse().find((user) => !users.map((u) => u.id).includes(user));
7784
if (username) {
7885
try {
79-
await addEditor({ unitId: unit.id, userId: username });
86+
await addMember({ unitId: unit.id, userId: username });
8087
} catch (error) {
8188
enqueueError(error);
8289
}
@@ -91,5 +98,6 @@ export const UnitEditors = ({ unit }: UnitEditorsProps) => {
9198
/>
9299
);
93100
}
94-
return <Typography>You must be a unit or organisation member to modify unit editors</Typography>;
101+
102+
return null;
95103
};

src/features/userSettings/UserSettingsContent/ContextSection/contextActions/EditUnitListItem.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Box, ListItemButton, ListItemIcon, ListItemText, Typography } from "@mu
88
import { ModalWrapper } from "../../../../../components/modals/ModalWrapper";
99
import { EditDefaultPrivacy } from "../../../../../components/units/EditDefaultPrivacy";
1010
import { EditUnitName } from "../../../../../components/units/EditUnitName";
11-
import { UnitEditors } from "../../../../../components/units/UnitEditors";
11+
import { UnitMembers } from "../../../../../components/units/UnitMembers";
1212

1313
export interface EditUnitListItemProps {
1414
unit: UnitDetail;
@@ -43,9 +43,9 @@ export const EditUnitListItem = ({ unit }: EditUnitListItemProps) => {
4343
</Typography>
4444
<EditDefaultPrivacy unit={unit} />
4545
<Typography component="h3" variant="h4">
46-
Editors
46+
Members
4747
</Typography>
48-
<UnitEditors unit={unit} />
48+
<UnitMembers unit={unit} />
4949
</Box>
5050
</ModalWrapper>
5151
</>

0 commit comments

Comments
 (0)