Skip to content

Commit

Permalink
Add option to transfer organization ownership
Browse files Browse the repository at this point in the history
Fixes: #58
  • Loading branch information
MrBartusek committed Jun 3, 2024
1 parent 11afa83 commit 4dab464
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ModalDialog, { ModalDialogProps } from '../../Modal/ModalDialog';
import ModalHeader from '../../Modal/ModalHeader';
import ModalTitle from '../../Modal/ModalTitle';
import ModelFooter from '../../Modal/ModelFooter';
import toast from 'react-hot-toast';

export interface ConfirmMemberDeleteModalProps extends ModalDialogProps {
organization: OrganizationDto;
Expand All @@ -38,6 +39,7 @@ function ConfirmMemberDeleteModal({ organization, rule, ...props }: ConfirmMembe
.delete(`/api/security`, { data: dto })
.then(() => {
queryClient.invalidateQueries(['security', organization.id]);
toast.success(`Removed ${user?.username} from organization`);
if (!props.handleClose) return;
props.handleClose();
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import axios from 'axios';
import { useState } from 'react';
import { useQueryClient } from 'react-query';
import {
IDeleteSecurityRuleDto,

Check warning on line 5 in apps/client/src/components/Organization/OrganizationMemberDropdown/ConfirmTransferModal.tsx

View workflow job for this annotation

GitHub Actions / Lint

'IDeleteSecurityRuleDto' is defined but never used
ITransferOrganizationDto,
OrganizationDto,
SecurityRuleDto,
} from 'shared-types';
import useUserData from '../../../hooks/useUserData';
import { Utils } from '../../../utils/utils';
import Button from '../../Button';

Check warning on line 12 in apps/client/src/components/Organization/OrganizationMemberDropdown/ConfirmTransferModal.tsx

View workflow job for this annotation

GitHub Actions / Lint

'Button' is defined but never used
import Alert from '../../Helpers/Alert';
import ModalBody from '../../Modal/ModalBody';
import ModalCloseButton from '../../Modal/ModalCloseButton';
import ModalDialog, { ModalDialogProps } from '../../Modal/ModalDialog';
import ModalHeader from '../../Modal/ModalHeader';
import ModalTitle from '../../Modal/ModalTitle';
import ModelFooter from '../../Modal/ModelFooter';
import { BsArrowRight } from 'react-icons/bs';
import IconButton from '../../IconButton';
import toast from 'react-hot-toast';

export interface ConfirmTransferModalProps extends ModalDialogProps {
organization: OrganizationDto;
rule: SecurityRuleDto;
}

function ConfirmTransferModal({ organization, rule, ...props }: ConfirmTransferModalProps) {
const { user } = useUserData(rule.user);
const queryClient = useQueryClient();

const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

function handleClick() {
setLoading(true);
setError(null);

const dto: ITransferOrganizationDto = { user: rule.user };
axios
.post(`/api/security/${organization.id}/transfer`, dto)
.then(() => {
queryClient.invalidateQueries(['security', organization.id]);
toast.success(`Transfered organization to ${user?.username}`);
if (!props.handleClose) return;
props.handleClose();
})
.catch((err) => setError(Utils.requestErrorToString(err)))
.finally(() => setLoading(false));
}

return (
<ModalDialog {...props}>
<ModalHeader closeButton>
<ModalTitle>Transfer organization ownership</ModalTitle>
</ModalHeader>

<ModalBody>
{error && <Alert>{error}</Alert>}
You are about to transfer ownership of this organization ({organization.name}) to{' '}
{user?.username || '...'}. You will immediately lose owner access, this action is not
reversible. Are you sure?
</ModalBody>

<ModelFooter>
<IconButton
icon={BsArrowRight}
variant="danger"
loading={loading}
onClick={handleClick}
>
Transfer
</IconButton>
<ModalCloseButton />
</ModelFooter>
</ModalDialog>
);
}
export default ConfirmTransferModal;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DropdownItem from '../../Dropdown/DropdownItem';
import DropdownMenu from '../../Dropdown/DropdownMenu';
import DropdownToggle from '../../Dropdown/DropdownToggle';
import RemoveMemberOption from './RemoveMemberOption';
import TransferOwnershipOption from './TransferOwnershipOption';

export interface OrganizationMemberDropdownProps {
organization: OrganizationDto;
Expand All @@ -28,12 +29,10 @@ function OrganizationMemberDropdown({
/>
</DropdownToggle>
<DropdownMenu>
<DropdownItem
icon={BsArrowRight}
disabled={true}
>
Transfer Ownership
</DropdownItem>
<TransferOwnershipOption
organization={organization}
rule={rule}
/>
<RemoveMemberOption
organization={organization}
rule={rule}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState } from 'react';
import { createPortal } from 'react-dom';
import { BsArrowRight, BsPersonXFill } from 'react-icons/bs';

Check warning on line 3 in apps/client/src/components/Organization/OrganizationMemberDropdown/TransferOwnershipOption.tsx

View workflow job for this annotation

GitHub Actions / Lint

'BsPersonXFill' is defined but never used
import { OrganizationDto, OrganizationSecurityRole, SecurityRuleDto } from 'shared-types';
import useUserRole from '../../../hooks/useUserRole';
import { SecurityUtils } from '../../../utils/securityUtils';

Check warning on line 6 in apps/client/src/components/Organization/OrganizationMemberDropdown/TransferOwnershipOption.tsx

View workflow job for this annotation

GitHub Actions / Lint

'SecurityUtils' is defined but never used
import { ActionButtonProps } from '../../ActionButton';
import DropdownItem from '../../Dropdown/DropdownItem';
import ConfirmMemberDeleteModal from './ConfirmMemberDeleteModal';

Check warning on line 9 in apps/client/src/components/Organization/OrganizationMemberDropdown/TransferOwnershipOption.tsx

View workflow job for this annotation

GitHub Actions / Lint

'ConfirmMemberDeleteModal' is defined but never used
import ConfirmTransferModal from './ConfirmTransferModal';

export interface TransferOwnershipOptionProps extends Omit<ActionButtonProps, 'icon' | 'onClick'> {
organization: OrganizationDto;
rule: SecurityRuleDto;
}

function TransferOwnershipOption({ rule, organization, ...props }: TransferOwnershipOptionProps) {
const [open, setOpen] = useState(false);

const { role } = useUserRole(organization.id);
const isOwner = role == OrganizationSecurityRole.OWNER;

return (
<>
{createPortal(
<ConfirmTransferModal
open={open}
handleClose={() => setOpen(false)}
organization={organization}
rule={rule}
/>,
document.body,
)}
<DropdownItem
icon={BsArrowRight}
title="Transfer ownership"
disabled={!isOwner || props.disabled}
onClick={() => setOpen(true)}
>
Transfer ownership
</DropdownItem>
</>
);
}
export default TransferOwnershipOption;

0 comments on commit 4dab464

Please sign in to comment.