fix: lower role user cannot update higher role user (#1048)
* fix: user role update * chore: update project member update service type
@ -99,9 +99,9 @@ const EmojiIconPicker: React.FC<Props> = ({
|
||||
<div className="grid grid-cols-8 gap-2">
|
||||
{recentEmojis.map((emoji) => (
|
||||
<button
|
||||
key={emoji}
|
||||
type="button"
|
||||
className="flex h-4 w-4 select-none items-center justify-between text-sm"
|
||||
key={emoji}
|
||||
onClick={() => {
|
||||
onChange(emoji);
|
||||
setIsOpen(false);
|
||||
@ -147,6 +147,7 @@ const EmojiIconPicker: React.FC<Props> = ({
|
||||
"#000000",
|
||||
].map((curCol) => (
|
||||
<span
|
||||
key={curCol}
|
||||
className="h-4 w-4 cursor-pointer rounded-full"
|
||||
style={{ backgroundColor: curCol }}
|
||||
onClick={() => setActiveColor(curCol)}
|
||||
|
@ -19,7 +19,7 @@ export const TargetIcon: React.FC<Props> = ({
|
||||
<circle cx="9" cy="9" r="5.4375" stroke={color} strokeLinecap="round" />
|
||||
<path
|
||||
fill={color}
|
||||
stroke-width="0.5"
|
||||
strokeWidth="0.5"
|
||||
d="M17.6033 7.51926C18.1597 9.22867 18.1241 11.0757 17.5021 12.7624C16.8802 14.4491 15.7083 15.8771 14.1753 16.8161C12.6424 17.7551 10.8378 18.1504 9.05269 17.9382C7.26757 17.7259 5.60599 16.9185 4.33594 15.6463C3.0659 14.374 2.26145 12.711 2.05235 10.9255C1.84325 9.14002 2.24169 7.33614 3.18341 5.80485C4.12512 4.27355 5.5552 3.10411 7.24298 2.48516C8.93076 1.86621 10.7778 1.83384 12.4863 2.39326L11.4383 3.44026C11.3803 3.49726 11.3283 3.56026 11.2803 3.62526C9.91235 3.34916 8.49189 3.52063 7.22898 4.11431C5.96606 4.70799 4.92774 5.69235 4.26757 6.92182C3.6074 8.15128 3.36045 9.56057 3.56322 10.9413C3.76599 12.3219 4.40773 13.6007 5.39353 14.5884C6.37933 15.5762 7.65683 16.2204 9.03712 16.4259C10.4174 16.6314 11.8272 16.3872 13.0579 15.7295C14.2887 15.0717 15.2751 14.0353 15.8713 12.7736C16.4674 11.5118 16.6417 10.0917 16.3683 8.72326C16.4367 8.67472 16.5009 8.62053 16.5603 8.56126L17.6023 7.51926H17.6033ZM14.8983 9.00026C15.1129 10.0534 14.9826 11.1477 14.5264 12.1209C14.0703 13.0942 13.3127 13.8945 12.3659 14.4033C11.4191 14.9121 10.3336 15.1022 9.27028 14.9456C8.20695 14.7889 7.22239 14.2938 6.46258 13.5336C5.70276 12.7734 5.20814 11.7886 5.05203 10.7252C4.89593 9.66176 5.08665 8.57635 5.59593 7.62984C6.10521 6.68334 6.90593 5.92615 7.87938 5.4705C8.85284 5.01486 9.94721 4.88503 11.0003 5.10026V6.64626C10.2539 6.42346 9.45458 6.45598 8.7288 6.73866C8.00302 7.02135 7.39227 7.53806 6.99325 8.20697C6.59423 8.87589 6.42973 9.65879 6.52581 10.4317C6.62188 11.2047 6.97304 11.9235 7.52368 12.4744C8.07432 13.0252 8.79298 13.3767 9.56588 13.4731C10.3388 13.5695 11.1218 13.4053 11.7908 13.0066C12.4599 12.6079 12.9769 11.9973 13.2599 11.2717C13.5429 10.546 13.5757 9.7467 13.3533 9.00026H14.8983ZM9.99826 11.5003C10.2283 11.5004 10.4553 11.4476 10.6617 11.346C10.868 11.2443 11.0483 11.0966 11.1884 10.9142C11.3286 10.7318 11.4249 10.5196 11.47 10.294C11.515 10.0684 11.5076 9.83551 11.4483 9.61326L13.0303 8.03026L13.0603 8.00026H15.5003C15.566 8.00038 15.631 7.98754 15.6918 7.96249C15.7525 7.93744 15.8077 7.90066 15.8543 7.85426L17.8543 5.85426C17.9244 5.78433 17.9721 5.69516 17.9915 5.59805C18.0109 5.50094 18.001 5.40027 17.963 5.3088C17.9251 5.21732 17.8609 5.13917 17.7785 5.08424C17.6961 5.02931 17.5993 5.00008 17.5003 5.00026H15.0003V2.50026C15.0002 2.40144 14.9709 2.30485 14.9161 2.22268C14.8612 2.1405 14.7832 2.07643 14.6919 2.03855C14.6006 2.00068 14.5002 1.99069 14.4033 2.00986C14.3063 2.02903 14.2172 2.0765 14.1473 2.14626L12.1473 4.14626C12.1007 4.1927 12.0637 4.24787 12.0385 4.30861C12.0133 4.36936 12.0003 4.43448 12.0003 4.50026V6.94026C11.99 6.94998 11.98 6.95998 11.9703 6.97026L10.3883 8.55026C10.1658 8.49057 9.93264 8.48287 9.70675 8.52775C9.48086 8.57263 9.26833 8.66889 9.0856 8.80908C8.90288 8.94926 8.75486 9.12961 8.65302 9.33617C8.55117 9.54273 8.49821 9.76996 8.49826 10.0003C8.49826 10.3981 8.65629 10.7796 8.9376 11.0609C9.2189 11.3422 9.60043 11.5003 9.99826 11.5003Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -38,7 +38,7 @@ const SingleInvitation: React.FC<Props> = ({
|
||||
alt={invitation.workspace.name}
|
||||
/>
|
||||
) : (
|
||||
<span className="flex h-full w-full items-center justify-center rounded bg-gray-500 p-4 uppercase text-white">
|
||||
<span className="flex h-full w-full items-center justify-center rounded bg-gray-700 p-4 uppercase text-white">
|
||||
{invitation.workspace.name.charAt(0)}
|
||||
</span>
|
||||
)}
|
||||
|
@ -87,6 +87,8 @@ const MembersSettings: NextPage = () => {
|
||||
})) || []),
|
||||
];
|
||||
|
||||
const currentUser = projectMembers?.find((item) => item.member.id === user?.id);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmProjectMemberRemove
|
||||
@ -206,6 +208,14 @@ const MembersSettings: NextPage = () => {
|
||||
onChange={(value: 5 | 10 | 15 | 20 | undefined) => {
|
||||
if (!activeWorkspace || !projectDetails) return;
|
||||
|
||||
mutateMembers(
|
||||
(prevData: any) =>
|
||||
prevData.map((m: any) =>
|
||||
m.id === member.id ? { ...m, role: value } : m
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
projectService
|
||||
.updateProjectMember(
|
||||
activeWorkspace.slug,
|
||||
@ -215,32 +225,38 @@ const MembersSettings: NextPage = () => {
|
||||
role: value,
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
message: "Member role updated successfully.",
|
||||
title: "Success",
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message:
|
||||
"An error occurred while updating member role. Please try again.",
|
||||
});
|
||||
mutateMembers(
|
||||
(prevData: any) =>
|
||||
prevData.map((m: any) =>
|
||||
m.id === member.id ? { ...m, ...res, role: value } : m
|
||||
),
|
||||
false
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}}
|
||||
position="right"
|
||||
disabled={member.memberId === user?.id}
|
||||
disabled={
|
||||
member.memberId === user?.id ||
|
||||
!member.member ||
|
||||
(currentUser &&
|
||||
currentUser.role !== 20 &&
|
||||
currentUser.role < member.role)
|
||||
}
|
||||
>
|
||||
{Object.keys(ROLE).map((key) => (
|
||||
<CustomSelect.Option key={key} value={key}>
|
||||
<>{ROLE[parseInt(key) as keyof typeof ROLE]}</>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
{Object.keys(ROLE).map((key) => {
|
||||
if (
|
||||
currentUser &&
|
||||
currentUser.role !== 20 &&
|
||||
currentUser.role < parseInt(key)
|
||||
)
|
||||
return null;
|
||||
|
||||
return (
|
||||
<CustomSelect.Option key={key} value={key}>
|
||||
<>{ROLE[parseInt(key) as keyof typeof ROLE]}</>
|
||||
</CustomSelect.Option>
|
||||
);
|
||||
})}
|
||||
</CustomSelect>
|
||||
<CustomMenu ellipsis>
|
||||
<CustomMenu.MenuItem
|
||||
|
@ -80,6 +80,8 @@ const MembersSettings: NextPage = () => {
|
||||
})) || []),
|
||||
];
|
||||
|
||||
const currentUser = workspaceMembers?.find((item) => item.member?.id === user?.id);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmWorkspaceMemberRemove
|
||||
@ -204,40 +206,50 @@ const MembersSettings: NextPage = () => {
|
||||
onChange={(value: any) => {
|
||||
if (!workspaceSlug) return;
|
||||
|
||||
mutateMembers(
|
||||
(prevData) =>
|
||||
prevData?.map((m) =>
|
||||
m.id === member.id ? { ...m, role: value } : m
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
workspaceService
|
||||
.updateWorkspaceMember(workspaceSlug?.toString(), member.id, {
|
||||
role: value,
|
||||
})
|
||||
.then(() => {
|
||||
mutateMembers(
|
||||
(prevData) =>
|
||||
prevData?.map((m) =>
|
||||
m.id === member.id ? { ...m, role: value } : m
|
||||
),
|
||||
false
|
||||
);
|
||||
setToastAlert({
|
||||
title: "Success",
|
||||
type: "success",
|
||||
message: "Member role updated successfully.",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
title: "Error",
|
||||
type: "error",
|
||||
message: "An error occurred while updating member role.",
|
||||
title: "Error!",
|
||||
message:
|
||||
"An error occurred while updating member role. Please try again.",
|
||||
});
|
||||
});
|
||||
}}
|
||||
position="right"
|
||||
disabled={member.memberId === user?.id}
|
||||
disabled={
|
||||
member.memberId === currentUser?.member.id ||
|
||||
!member.status ||
|
||||
(currentUser &&
|
||||
currentUser.role !== 20 &&
|
||||
currentUser.role < member.role)
|
||||
}
|
||||
>
|
||||
{Object.keys(ROLE).map((key) => (
|
||||
<CustomSelect.Option key={key} value={key}>
|
||||
<>{ROLE[parseInt(key) as keyof typeof ROLE]}</>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
{Object.keys(ROLE).map((key) => {
|
||||
if (
|
||||
currentUser &&
|
||||
currentUser.role !== 20 &&
|
||||
currentUser.role < parseInt(key)
|
||||
)
|
||||
return null;
|
||||
|
||||
return (
|
||||
<CustomSelect.Option key={key} value={key}>
|
||||
<>{ROLE[parseInt(key) as keyof typeof ROLE]}</>
|
||||
</CustomSelect.Option>
|
||||
);
|
||||
})}
|
||||
</CustomSelect>
|
||||
<CustomMenu ellipsis>
|
||||
<CustomMenu.MenuItem
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@ -8,8 +8,8 @@
|
||||
<circle cx="103.434" cy="68.4443" r="4.51262" fill="#8CC1FF"/>
|
||||
<circle cx="95.3115" cy="68.4444" r="4.96388" fill="white"/>
|
||||
<circle cx="95.3117" cy="68.4443" r="4.51262" fill="#2C435F"/>
|
||||
<rect x="59.238" y="60.1787" width="23.984" height="16.3369" rx="2.60695" fill="white" stroke="#DEE2E6" stroke-width="0.347594"/>
|
||||
<circle cx="70.8824" cy="68.3478" r="4.86631" stroke="#FCBE1D" stroke-width="0.695187" stroke-linecap="round" stroke-dasharray="0 13.9 0 6.95"/>
|
||||
<rect x="59.238" y="60.1787" width="23.984" height="16.3369" rx="2.60695" fill="white" stroke="#DEE2E6" strokeWidth="0.347594"/>
|
||||
<circle cx="70.8824" cy="68.3478" r="4.86631" stroke="#FCBE1D" strokeWidth="0.695187" stroke-linecap="round" stroke-dasharray="0 13.9 0 6.95"/>
|
||||
<path d="M73.2007 65.3557C72.5321 64.8376 71.7093 64.5583 70.8634 64.5625C70.0176 64.5668 69.1975 64.8542 68.5341 65.379L70.8823 68.3474L73.2007 65.3557Z" fill="#FCBE1D"/>
|
||||
<path d="M68.5576 71.3396C69.2262 71.8578 70.049 72.137 70.8949 72.1328C71.7407 72.1285 72.5608 71.8411 73.2242 71.3163L70.876 68.3479L68.5576 71.3396Z" fill="#FCBE1D"/>
|
||||
<rect x="36.8181" y="60.0049" width="16.6845" height="16.6845" rx="2.78075" fill="#FFEDD5"/>
|
||||
@ -27,8 +27,8 @@
|
||||
<circle cx="81.434" cy="92.4443" r="4.51262" fill="#8CC1FF"/>
|
||||
<circle cx="73.3115" cy="92.4444" r="4.96388" fill="white"/>
|
||||
<circle cx="73.3117" cy="92.4443" r="4.51262" fill="#2C435F"/>
|
||||
<rect x="37.238" y="84.1787" width="23.984" height="16.3369" rx="2.60695" fill="white" stroke="#DEE2E6" stroke-width="0.347594"/>
|
||||
<circle cx="48.8824" cy="92.3478" r="4.86631" stroke="#FCBE1D" stroke-width="0.695187" stroke-linecap="round" stroke-dasharray="0 13.9 0 6.95"/>
|
||||
<rect x="37.238" y="84.1787" width="23.984" height="16.3369" rx="2.60695" fill="white" stroke="#DEE2E6" strokeWidth="0.347594"/>
|
||||
<circle cx="48.8824" cy="92.3478" r="4.86631" stroke="#FCBE1D" strokeWidth="0.695187" stroke-linecap="round" stroke-dasharray="0 13.9 0 6.95"/>
|
||||
<path d="M51.2007 89.3557C50.5321 88.8376 49.7093 88.5583 48.8634 88.5625C48.0176 88.5668 47.1975 88.8542 46.5341 89.379L48.8823 92.3474L51.2007 89.3557Z" fill="#FCBE1D"/>
|
||||
<path d="M46.5576 95.3396C47.2262 95.8578 48.049 96.137 48.8949 96.1328C49.7407 96.1285 50.5608 95.8411 51.2242 95.3163L48.876 92.3479L46.5576 95.3396Z" fill="#FCBE1D"/>
|
||||
<rect x="14.8181" y="84.0049" width="16.6845" height="16.6845" rx="2.78075" fill="#FFEDD5"/>
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
@ -11,7 +11,7 @@
|
||||
<circle cx="174.957" cy="155.839" r="8.12271" fill="#8CC1FF"/>
|
||||
<circle cx="160.336" cy="155.839" r="8.93498" fill="white"/>
|
||||
<circle cx="160.336" cy="155.839" r="8.12271" fill="#2C435F"/>
|
||||
<rect x="71.6288" y="140.96" width="69.4492" height="29.4064" rx="4.69251" fill="white" stroke="#DEE2E6" stroke-width="0.625668"/>
|
||||
<rect x="71.6288" y="140.96" width="69.4492" height="29.4064" rx="4.69251" fill="white" stroke="#DEE2E6" strokeWidth="0.625668"/>
|
||||
<circle cx="82.5987" cy="155.037" r="3.75401" fill="#F7AE59"/>
|
||||
<path d="M92.0831 150.29V149.117H100.274V150.29H96.8396V160.038H95.5172V150.29H92.0831ZM104.284 160.208C103.544 160.208 102.895 160.032 102.337 159.68C101.783 159.328 101.349 158.836 101.036 158.203C100.727 157.57 100.572 156.831 100.572 155.985C100.572 155.132 100.727 154.387 101.036 153.751C101.349 153.114 101.783 152.62 102.337 152.268C102.895 151.916 103.544 151.74 104.284 151.74C105.023 151.74 105.67 151.916 106.225 152.268C106.783 152.62 107.216 153.114 107.526 153.751C107.839 154.387 107.995 155.132 107.995 155.985C107.995 156.831 107.839 157.57 107.526 158.203C107.216 158.836 106.783 159.328 106.225 159.68C105.67 160.032 105.023 160.208 104.284 160.208ZM104.284 159.078C104.845 159.078 105.307 158.934 105.67 158.646C106.033 158.358 106.301 157.979 106.475 157.51C106.649 157.041 106.737 156.532 106.737 155.985C106.737 155.438 106.649 154.927 106.475 154.455C106.301 153.982 106.033 153.6 105.67 153.308C105.307 153.017 104.845 152.871 104.284 152.871C103.722 152.871 103.26 153.017 102.897 153.308C102.535 153.6 102.266 153.982 102.092 154.455C101.918 154.927 101.831 155.438 101.831 155.985C101.831 156.532 101.918 157.041 102.092 157.51C102.266 157.979 102.535 158.358 102.897 158.646C103.26 158.934 103.722 159.078 104.284 159.078ZM117.232 160.208C116.55 160.208 115.947 160.036 115.424 159.691C114.902 159.343 114.493 158.852 114.198 158.219C113.903 157.583 113.755 156.831 113.755 155.964C113.755 155.103 113.903 154.357 114.198 153.724C114.493 153.091 114.904 152.602 115.43 152.258C115.956 151.913 116.564 151.74 117.253 151.74C117.787 151.74 118.208 151.829 118.517 152.007C118.83 152.181 119.068 152.38 119.232 152.604C119.399 152.825 119.529 153.006 119.621 153.148H119.728V149.117H120.986V160.038H119.77V158.779H119.621C119.529 158.928 119.397 159.117 119.226 159.344C119.056 159.568 118.812 159.769 118.496 159.947C118.179 160.121 117.758 160.208 117.232 160.208ZM117.403 159.078C117.907 159.078 118.334 158.946 118.682 158.683C119.031 158.417 119.296 158.049 119.477 157.579C119.658 157.107 119.749 156.561 119.749 155.942C119.749 155.331 119.66 154.796 119.482 154.337C119.305 153.875 119.042 153.516 118.693 153.26C118.345 153.001 117.915 152.871 117.403 152.871C116.869 152.871 116.425 153.008 116.07 153.281C115.718 153.552 115.453 153.92 115.275 154.385C115.101 154.847 115.014 155.366 115.014 155.942C115.014 156.525 115.103 157.055 115.28 157.531C115.462 158.004 115.728 158.381 116.08 158.662C116.436 158.939 116.877 159.078 117.403 159.078ZM126.793 160.208C126.054 160.208 125.405 160.032 124.847 159.68C124.292 159.328 123.858 158.836 123.546 158.203C123.236 157.57 123.082 156.831 123.082 155.985C123.082 155.132 123.236 154.387 123.546 153.751C123.858 153.114 124.292 152.62 124.847 152.268C125.405 151.916 126.054 151.74 126.793 151.74C127.532 151.74 128.179 151.916 128.734 152.268C129.292 152.62 129.726 153.114 130.035 153.751C130.348 154.387 130.504 155.132 130.504 155.985C130.504 156.831 130.348 157.57 130.035 158.203C129.726 158.836 129.292 159.328 128.734 159.68C128.179 160.032 127.532 160.208 126.793 160.208ZM126.793 159.078C127.355 159.078 127.817 158.934 128.179 158.646C128.542 158.358 128.81 157.979 128.985 157.51C129.159 157.041 129.246 156.532 129.246 155.985C129.246 155.438 129.159 154.927 128.985 154.455C128.81 153.982 128.542 153.6 128.179 153.308C127.817 153.017 127.355 152.871 126.793 152.871C126.231 152.871 125.769 153.017 125.407 153.308C125.044 153.6 124.776 153.982 124.601 154.455C124.427 154.927 124.34 155.438 124.34 155.985C124.34 156.532 124.427 157.041 124.601 157.51C124.776 157.979 125.044 158.358 125.407 158.646C125.769 158.934 126.231 159.078 126.793 159.078Z" fill="#495057"/>
|
||||
<rect x="31.2729" y="140.647" width="30.0321" height="30.0321" rx="5.00535" fill="#FFEDD5"/>
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
@ -158,7 +158,7 @@ class ProjectServices extends APIService {
|
||||
memberId: string,
|
||||
data: Partial<IProjectMember>
|
||||
): Promise<IProjectMember> {
|
||||
return this.put(
|
||||
return this.patch(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/`,
|
||||
data
|
||||
)
|
||||
|
@ -147,7 +147,7 @@ class WorkspaceService extends APIService {
|
||||
memberId: string,
|
||||
data: Partial<IWorkspaceMember>
|
||||
): Promise<IWorkspaceMember> {
|
||||
return this.put(`/api/workspaces/${workspaceSlug}/members/${memberId}/`, data)
|
||||
return this.patch(`/api/workspaces/${workspaceSlug}/members/${memberId}/`, data)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
|