Skip to content

Commit

Permalink
fix: token factory modal states (#120)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Felix C. Morency <[email protected]>
  • Loading branch information
chalabi2 and fmorency authored Dec 5, 2024
1 parent df92403 commit 4f8b533
Show file tree
Hide file tree
Showing 13 changed files with 266 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ describe('ValidatorList', () => {
test('clicking on a validator row opens the modal', async () => {
renderWithProps();
fireEvent.click(screen.getByText('Validator One'));
await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
await waitFor(() => {
expect(screen.getByText('Validator Details')).toBeInTheDocument();
expect(screen.getByText('SECURITY CONTACT')).toBeInTheDocument();
expect(screen.getByText('OPERATOR ADDRESS')).toBeInTheDocument();
});
});

test('remove button works and shows the warning modal', async () => {
Expand Down
18 changes: 8 additions & 10 deletions components/admins/components/validatorList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default function ValidatorList({
const [searchTerm, setSearchTerm] = useState('');
const [selectedValidator, setSelectedValidator] = useState<ExtendedValidatorSDKType | null>(null);
const [modalId, setModalId] = useState<string | null>(null);
const [openWarningModal, setOpenWarningModal] = useState(false);
const [openValidatorModal, setOpenValidatorModal] = useState(false);

const [validatorToRemove, setValidatorToRemove] = useState<ExtendedValidatorSDKType | null>(null);
const totalvp = Array.isArray(activeValidators)
Expand All @@ -44,13 +46,6 @@ export default function ValidatorList({
}))
: [];

useEffect(() => {
if (modalId) {
const modal = document.getElementById(modalId) as HTMLDialogElement;
modal?.showModal();
}
}, [modalId]);

const filteredValidators = useMemo(() => {
const validators = active ? activeValidators : pendingValidators;
return validators.filter(validator =>
Expand All @@ -60,9 +55,7 @@ export default function ValidatorList({

const handleRemove = (validator: ExtendedValidatorSDKType) => {
setValidatorToRemove(validator);

const modal = document.getElementById(`warning-modal`) as HTMLDialogElement;
modal?.showModal();
setOpenWarningModal(true);
};

const [modalKey, setModalKey] = useState(0);
Expand All @@ -71,6 +64,7 @@ export default function ValidatorList({
setSelectedValidator(validator);
setModalKey(prevKey => prevKey + 1);
setModalId(`validator-modal-${validator.operator_address}-${Date.now()}`);
setOpenValidatorModal(true);
};

return (
Expand Down Expand Up @@ -254,13 +248,17 @@ export default function ValidatorList({
admin={admin}
totalvp={totalvp.toString()}
validatorVPArray={validatorVPArray}
openValidatorModal={openValidatorModal}
setOpenValidatorModal={setOpenValidatorModal}
/>
<WarningModal
admin={admin}
isActive={active}
address={validatorToRemove?.operator_address || ''}
moniker={validatorToRemove?.description.moniker || ''}
modalId="warning-modal"
openWarningModal={openWarningModal}
setOpenWarningModal={setOpenWarningModal}
/>
</div>
);
Expand Down
29 changes: 25 additions & 4 deletions components/admins/modals/validatorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,28 @@ export function ValidatorDetailsModal({
admin,
totalvp,
validatorVPArray,
openValidatorModal,
setOpenValidatorModal,
}: Readonly<{
validator: ExtendedValidatorSDKType | null;
modalId: string;
admin: string;
totalvp: string;
validatorVPArray: { vp: bigint; moniker: string }[];
openValidatorModal: boolean;
setOpenValidatorModal: (open: boolean) => void;
}>) {
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape' && openValidatorModal) {
handleClose();
}
};

document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, [openValidatorModal]);

const [power, setPowerInput] = useState(validator?.consensus_power?.toString() || '');

const { tx, isSigning, setIsSigning } = useTx(chainName);
Expand Down Expand Up @@ -100,12 +115,18 @@ export function ValidatorDetailsModal({
};

const handleClose = () => {
const modal = document.getElementById(modalId) as HTMLDialogElement;
modal?.close();
if (setOpenValidatorModal) {
setOpenValidatorModal(false);
}
(document.getElementById(modalId) as HTMLDialogElement)?.close();
};

return (
<dialog id={modalId} className="modal">
<dialog
id={modalId}
className={`modal ${openValidatorModal ? 'modal-open' : ''}`}
onClose={handleClose}
>
<Formik
initialValues={{ power: power, totalvp, validatorVPArray }}
validationSchema={PowerUpdateSchema}
Expand Down Expand Up @@ -243,7 +264,7 @@ export function ValidatorDetailsModal({
details={validator?.description.details ?? 'No Details'}
/>
<form method="dialog" className="modal-backdrop">
<button>close</button>
<button onClick={handleClose}>close</button>
</form>
</dialog>
);
Expand Down
39 changes: 35 additions & 4 deletions components/admins/modals/warningModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { cosmos, strangelove_ventures } from '@liftedinit/manifestjs';
import { Any } from '@liftedinit/manifestjs/dist/codegen/google/protobuf/any';
import { MsgRemoveValidator } from '@liftedinit/manifestjs/dist/codegen/strangelove_ventures/poa/v1/tx';
import { useChain } from '@cosmos-kit/react';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { PiWarning } from 'react-icons/pi';

interface WarningModalProps {
Expand All @@ -13,6 +13,8 @@ interface WarningModalProps {
address: string;
moniker: string;
modalId: string;
openWarningModal: boolean;
setOpenWarningModal: (open: boolean) => void;
}

export function WarningModal({
Expand All @@ -21,7 +23,20 @@ export function WarningModal({
modalId,
address,
isActive,
openWarningModal,
setOpenWarningModal,
}: Readonly<WarningModalProps>) {
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape' && openWarningModal) {
handleClose();
}
};

document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, [openWarningModal]);

const { tx, isSigning, setIsSigning } = useTx(chainName);
const { estimateFee } = useFeeEstimation(chainName);
const { address: userAddress } = useChain(chainName);
Expand Down Expand Up @@ -68,13 +83,29 @@ export function WarningModal({
setIsSigning(false);
};

const handleClose = () => {
if (setOpenWarningModal) {
setOpenWarningModal(false);
}
(document.getElementById(modalId) as HTMLDialogElement)?.close();
};

return (
<dialog id={modalId} className="modal">
<dialog
id={modalId}
className={`modal ${openWarningModal ? 'modal-open' : ''}`}
onClose={handleClose}
>
<form
method="dialog"
className="modal-box text-black dark:text-white dark:bg-[#1D192D] bg-[#FFFFFF]"
>
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
<button
className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
onClick={handleClose}
>
</button>
<div className="p-4 ">
<div className="flex flex-col gap-2 items-center mb-6">
<PiWarning className="text-yellow-200 text-6xl" />
Expand Down Expand Up @@ -106,7 +137,7 @@ export function WarningModal({
</div>
</form>
<form method="dialog" className="modal-backdrop">
<button>close</button>
<button onClick={handleClose}>close</button>
</form>
</dialog>
);
Expand Down
70 changes: 47 additions & 23 deletions components/factory/components/MyDenoms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ export default function MyDenoms({
}) {
const [searchQuery, setSearchQuery] = useState('');
const [currentPage, setCurrentPage] = useState(1);
const [openUpdateDenomMetadataModal, setOpenUpdateDenomMetadataModal] = useState(false);
const isMobile = useIsMobile();

const pageSize = isMobile ? 6 : 8;

const router = useRouter();
const [selectedDenom, setSelectedDenom] = useState<ExtendedMetadataSDKType | null>(null);
const [modalType, setModalType] = useState<
'mint' | 'burn' | 'multimint' | 'multiburn' | 'update' | null
'mint' | 'burn' | 'multimint' | 'multiburn' | 'update' | 'info' | null
>(null);

const filteredDenoms = useMemo(() => {
Expand All @@ -50,13 +51,9 @@ export default function MyDenoms({

const handleDenomSelect = (denom: ExtendedMetadataSDKType) => {
if (!modalType) {
// Only show denom info if no other modal is active
setSelectedDenom(denom);
setModalType(null); // Ensure no other modal type is set
const modal = document.getElementById('denom-info-modal') as HTMLDialogElement;
if (modal) {
modal.showModal();
}
setModalType('info');
router.push(`/factory?denom=${denom.base}&action=info`, undefined, { shallow: true });
}
};

Expand All @@ -73,15 +70,16 @@ export default function MyDenoms({
action === 'mint' ||
action === 'burn' ||
action === 'multimint' ||
action === 'multiburn'
action === 'multiburn' ||
action === 'update' ||
action === 'info'
) {
setModalType(action as 'mint' | 'burn' | 'multimint' | 'multiburn');
} else {
// Only show denom info if no other action is specified
const modal = document.getElementById('denom-info-modal') as HTMLDialogElement;
if (modal) {
modal.showModal();
setModalType(action as 'mint' | 'burn' | 'multimint' | 'multiburn' | 'update' | 'info');
if (action === 'update') {
setOpenUpdateDenomMetadataModal(true);
}
} else {
setModalType('info');
}
}
} else {
Expand All @@ -93,32 +91,34 @@ export default function MyDenoms({
const handleCloseModal = () => {
setSelectedDenom(null);
setModalType(null);
setOpenUpdateDenomMetadataModal(false);
router.push('/factory', undefined, { shallow: true });
};

const handleUpdateModalClose = () => {
setOpenUpdateDenomMetadataModal(false);
setModalType(null);
router.push('/factory', undefined, { shallow: true });
};

const handleUpdateModal = (denom: ExtendedMetadataSDKType, e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
setSelectedDenom(denom);
// Important: Don't show the denom info modal
setModalType('update');
const modal = document.getElementById('update-denom-metadata-modal') as HTMLDialogElement;
if (modal) {
modal.showModal();
}
setOpenUpdateDenomMetadataModal(true);
router.push(`/factory?denom=${denom.base}&action=update`, undefined, { shallow: true });
};

const handleSwitchToMultiMint = () => {
setModalType('multimint');
// Update URL
router.push(`/factory?denom=${selectedDenom?.base}&action=multimint`, undefined, {
shallow: true,
});
};

const handleSwitchToMultiBurn = () => {
setModalType('multiburn'); // Set the modal type to multiburn
// Update URL
setModalType('multiburn');
router.push(`/factory?denom=${selectedDenom?.base}&action=multiburn`, undefined, {
shallow: true,
});
Expand Down Expand Up @@ -229,11 +229,17 @@ export default function MyDenoms({
e.stopPropagation();
setSelectedDenom(denom);
setModalType('mint');
router.push(`/factory?denom=${denom.base}&action=mint`, undefined, {
shallow: true,
});
}}
onBurn={e => {
e.stopPropagation();
setSelectedDenom(denom);
setModalType('burn');
router.push(`/factory?denom=${denom.base}&action=burn`, undefined, {
shallow: true,
});
}}
onUpdate={e => handleUpdateModal(denom, e)}
/>
Expand Down Expand Up @@ -314,7 +320,16 @@ export default function MyDenoms({
</div>
</div>
</div>
<DenomInfoModal denom={selectedDenom} modalId="denom-info-modal" />
<DenomInfoModal
openDenomInfoModal={modalType === 'info'}
setOpenDenomInfoModal={open => {
if (!open) {
handleCloseModal();
}
}}
denom={selectedDenom}
modalId="denom-info-modal"
/>
<MintModal
admin={poaAdmin ?? 'manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj'}
isPoaAdminLoading={isPoaAdminLoading}
Expand Down Expand Up @@ -343,6 +358,15 @@ export default function MyDenoms({
address={address}
onSuccess={() => {
refetchDenoms();
handleUpdateModalClose();
}}
openUpdateDenomMetadataModal={openUpdateDenomMetadataModal}
setOpenUpdateDenomMetadataModal={open => {
if (!open) {
handleUpdateModalClose();
} else {
setOpenUpdateDenomMetadataModal(true);
}
}}
/>
<MultiMintModal
Expand Down
12 changes: 11 additions & 1 deletion components/factory/modals/BurnModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useEffect } from 'react';

import BurnForm from '@/components/factory/forms/BurnForm';
import { useGroupsByAdmin, usePoaGetAdmin } from '@/hooks';
Expand All @@ -23,6 +23,16 @@ export default function BurnModal({
onClose: () => void;
onSwitchToMultiBurn: () => void;
}) {
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape' && isOpen) {
onClose();
}
};

document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, [isOpen]);
const { poaAdmin, isPoaAdminLoading } = usePoaGetAdmin();
const { groupByAdmin, isGroupByAdminLoading } = useGroupsByAdmin(
poaAdmin ?? 'manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj'
Expand Down
Loading

0 comments on commit 4f8b533

Please sign in to comment.