Add restrictions to protect the owners and change their roles
This commit is contained in:
parent
82f7779a23
commit
3234898892
3 changed files with 29 additions and 7 deletions
|
@ -5,6 +5,7 @@ import React, { SyntheticEvent, useEffect } from "react";
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import Button from "@calcom/ui/Button";
|
||||
|
||||
import { TeamWithMembers } from "@lib/queries/teams";
|
||||
import { trpc } from "@lib/trpc";
|
||||
|
||||
import ModalContainer from "@components/ui/ModalContainer";
|
||||
|
@ -15,10 +16,11 @@ type MembershipRoleOption = {
|
|||
label?: string;
|
||||
};
|
||||
|
||||
const options: MembershipRoleOption[] = [{ value: "MEMBER" }, { value: "ADMIN" }];
|
||||
const options: MembershipRoleOption[] = [{ value: "MEMBER" }, { value: "ADMIN" }, { value: "OWNER" }];
|
||||
|
||||
export default function MemberChangeRoleModal(props: {
|
||||
isOpen: boolean;
|
||||
team: TeamWithMembers;
|
||||
memberId: number;
|
||||
teamId: number;
|
||||
initialRole: MembershipRole;
|
||||
|
@ -48,6 +50,8 @@ export default function MemberChangeRoleModal(props: {
|
|||
},
|
||||
});
|
||||
|
||||
const memberRole = props.team?.membership.role;
|
||||
|
||||
function changeRole(e: SyntheticEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -57,7 +61,6 @@ export default function MemberChangeRoleModal(props: {
|
|||
role: role.value,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalContainer isOpen={props.isOpen} onExit={props.onExit}>
|
||||
<>
|
||||
|
@ -76,7 +79,7 @@ export default function MemberChangeRoleModal(props: {
|
|||
{/*<option value="OWNER">{t("owner")}</option> - needs dialog to confirm change of ownership */}
|
||||
<Select
|
||||
isSearchable={false}
|
||||
options={options}
|
||||
options={memberRole !== MembershipRole.OWNER ? options.slice(0, 2) : options}
|
||||
value={role}
|
||||
onChange={(option) => option && setRole(option)}
|
||||
id="role"
|
||||
|
|
|
@ -24,7 +24,7 @@ type MembershipRoleOption = {
|
|||
label?: string;
|
||||
};
|
||||
|
||||
const _options: MembershipRoleOption[] = [{ value: "MEMBER" }, { value: "ADMIN" }];
|
||||
const _options: MembershipRoleOption[] = [{ value: "MEMBER" }, { value: "ADMIN" }, { value: "OWNER" }];
|
||||
|
||||
export default function MemberInvitationModal(props: MemberInvitationModalProps) {
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
|
@ -48,6 +48,8 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
|||
},
|
||||
});
|
||||
|
||||
const memberRole = props.team?.membership.role;
|
||||
|
||||
function inviteMember(e: SyntheticEvent) {
|
||||
e.preventDefault();
|
||||
if (!props.team) return;
|
||||
|
@ -100,7 +102,7 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
|||
</label>
|
||||
<Select
|
||||
defaultValue={options[0]}
|
||||
options={options}
|
||||
options={memberRole !== MembershipRole.OWNER ? options.slice(0, 2) : options}
|
||||
id="role"
|
||||
name="role"
|
||||
className="mt-1 block w-full rounded-sm border-gray-300 shadow-sm sm:text-sm"
|
||||
|
|
|
@ -24,6 +24,7 @@ import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogCont
|
|||
import Avatar from "@components/ui/Avatar";
|
||||
import ModalContainer from "@components/ui/ModalContainer";
|
||||
|
||||
import { useMeQuery } from "../Shell";
|
||||
import MemberChangeRoleModal from "./MemberChangeRoleModal";
|
||||
import TeamPill, { TeamRole } from "./TeamPill";
|
||||
|
||||
|
@ -49,6 +50,20 @@ export default function MemberListItem(props: Props) {
|
|||
},
|
||||
});
|
||||
|
||||
const ownersInTeam = () => {
|
||||
const { members } = props.team;
|
||||
const owners = members.filter((member) => member["role"] === "OWNER");
|
||||
return owners.length;
|
||||
};
|
||||
|
||||
const useCurrentUser = () => {
|
||||
const query = useMeQuery();
|
||||
const user = query.data;
|
||||
return user?.id;
|
||||
};
|
||||
|
||||
const currentUser = useCurrentUser();
|
||||
|
||||
const name =
|
||||
props.member.name ||
|
||||
(() => {
|
||||
|
@ -121,8 +136,9 @@ export default function MemberListItem(props: Props) {
|
|||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
||||
{(props.team.membership.role === MembershipRole.OWNER ||
|
||||
props.team.membership.role === MembershipRole.ADMIN) && (
|
||||
{((props.team.membership.role === MembershipRole.OWNER &&
|
||||
(props.member.role !== "OWNER" || (ownersInTeam() > 1 && props.member.id === currentUser))) ||
|
||||
(props.team.membership.role === MembershipRole.ADMIN && props.member.role !== "OWNER")) && (
|
||||
<>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
|
@ -165,6 +181,7 @@ export default function MemberListItem(props: Props) {
|
|||
{showChangeMemberRoleModal && (
|
||||
<MemberChangeRoleModal
|
||||
isOpen={showChangeMemberRoleModal}
|
||||
team={props.team}
|
||||
teamId={props.team?.id}
|
||||
memberId={props.member.id}
|
||||
initialRole={props.member.role as MembershipRole}
|
||||
|
|
Loading…
Reference in a new issue