Add restrictions to protect the owners and change their roles

This commit is contained in:
Julián David Sánchez Gallego 2022-03-14 10:34:05 -05:00 committed by Omar López
parent 82f7779a23
commit 3234898892
3 changed files with 29 additions and 7 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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}