From 9d7eb0d767f6c0af119ec24d5fd38739efb210ad Mon Sep 17 00:00:00 2001 From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com> Date: Fri, 3 Jan 2025 14:16:10 +0530 Subject: [PATCH 1/7] added loader for transactions --- .../widget/components/TransactionLoader.jsx | 39 ++++++++++++ .../widget/components/VoteActions.jsx | 36 ++++++++++- .../widget/components/templates/AppLayout.jsx | 10 ++- .../pages/payments/CreatePaymentRequest.jsx | 32 +++++++++- .../widget/pages/payments/Table.jsx | 53 +++++++++------- .../widget/pages/proposals-feed/Table.jsx | 53 +++++++++------- .../settings/DeleteModalConfirmation.jsx | 29 ++++++++- .../widget/pages/settings/MembersEditor.jsx | 30 ++++++++- .../widget/pages/settings/MembersPage.jsx | 2 +- .../widget/pages/settings/Theme.jsx | 32 +++++++++- .../widget/pages/settings/Thresholds.jsx | 35 ++++++++++- .../pages/settings/VotingDurationPage.jsx | 61 +++++++++++++------ .../widget/pages/settings/feed/Table.jsx | 55 ++++++++++------- .../stake-delegation/CreateStakeRequest.jsx | 31 +++++++++- .../stake-delegation/CreateUnstakeRequest.jsx | 31 +++++++++- .../CreateWithdrawRequest.jsx | 30 ++++++++- .../widget/pages/stake-delegation/Table.jsx | 53 +++++++++------- 17 files changed, 487 insertions(+), 125 deletions(-) create mode 100644 instances/treasury-devdao.near/widget/components/TransactionLoader.jsx diff --git a/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx b/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx new file mode 100644 index 00000000..166f66ad --- /dev/null +++ b/instances/treasury-devdao.near/widget/components/TransactionLoader.jsx @@ -0,0 +1,39 @@ +function TransactionLoader({ showInProgress, showError, toggleToast }) { + return showInProgress || showError ? ( +
+
+
+ Just Now + {showError && ( + toggleToast(false)} + > + )} +
+
+ {showInProgress ? ( +
+ +
+ Processing your request ... +
+
+ ) : ( +
+ +
+ Something went wrong. Please try resubmitting the request. +
+
+ )} +
+
+
+ ) : null; +} +return { TransactionLoader }; diff --git a/instances/treasury-devdao.near/widget/components/VoteActions.jsx b/instances/treasury-devdao.near/widget/components/VoteActions.jsx index 1ecaadcc..1f35290c 100644 --- a/instances/treasury-devdao.near/widget/components/VoteActions.jsx +++ b/instances/treasury-devdao.near/widget/components/VoteActions.jsx @@ -4,6 +4,9 @@ if (!instance) { } const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`); +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const votes = props.votes ?? {}; const proposalId = props.proposalId; @@ -37,6 +40,7 @@ const [isInsufficientBalance, setInsufficientBal] = useState(false); const [showWarning, setShowWarning] = useState(false); const [isReadyToBeWithdrawn, setIsReadyToBeWithdrawn] = useState(true); const [showConfirmModal, setConfirmModal] = useState(null); +const [showErrorToast, setShowErrorToast] = useState(false); useEffect(() => { if (!avoidCheckForBalance) { @@ -74,20 +78,36 @@ function getProposalData() { (result) => result ); } - useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForVoteOnProposal = () => { getProposalData().then((proposal) => { if (JSON.stringify(proposal.votes) !== JSON.stringify(votes)) { checkProposalStatus(); + clearTimeout(errorTimeout); setTxnCreated(false); } else { - setTimeout(() => checkForVoteOnProposal(), 1000); + checkTxnTimeout = setTimeout(checkForVoteOnProposal, 1000); } }); }; + checkForVoteOnProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -134,7 +154,10 @@ const InsufficientBalanceWarning = () => {
Just Now - setShowWarning(false)}> + setShowWarning(false)} + >
The request cannot be approved because the treasury balance is @@ -144,8 +167,15 @@ const InsufficientBalanceWarning = () => {
) : null; }; + return ( + setShowErrorToast(false)} + /> + {} }; +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; + const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url") || { href: () => {}, }; @@ -45,6 +49,7 @@ const [selectedTokensAvailable, setSelectedTokensAvailable] = useState(null); const [isReceiverRegistered, setReceiverRegister] = useState(false); const [isLoadingProposals, setLoadingProposals] = useState(false); const [showCancelModal, setShowCancelModal] = useState(false); +const [showErrorToast, setShowErrorToast] = useState(false); useEffect(() => { if (!showProposalSelection) { @@ -150,19 +155,36 @@ function cleanInputs() { // close canvas after proposal is submitted useEffect(() => { if (isTxnCreated) { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { cleanInputs(); onCloseCanvas(); + clearTimeout(errorTimeout); refreshData(); setTxnCreated(false); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; + checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated]); @@ -373,6 +395,11 @@ useEffect(() => { return ( + setShowErrorToast(false)} + /> { } return (
- {content} -
- {showToastStatus !== "InProgress" && showToastStatus !== "Removed" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -205,7 +213,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx b/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx index 234c2ea1..37d72e5f 100644 --- a/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx +++ b/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx @@ -150,26 +150,34 @@ const ToastStatusContent = () => { } return (
- {content} -
- {showToastStatus !== "InProgress" && ( - - View in History - - )} +
+ {showToastStatus === "Approved" && ( + + )} +
+ {content} +
+ {showToastStatus !== "InProgress" && + showToastStatus !== "Removed" && ( + + View in History + + )} +
+
); }; @@ -182,7 +190,10 @@ const VoteSuccessToast = () => {
Just Now - setToastStatus(null)}> + setToastStatus(null)} + >
diff --git a/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx b/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx index 8e7a0192..578ebd02 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx @@ -1,6 +1,9 @@ const { encodeToMarkdown } = VM.require( "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common" ); +const { TransactionLoader } = VM.require( + `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader` +) || { TransactionLoader: () => <> }; const instance = props.instance; if (!instance) { @@ -21,6 +24,7 @@ const onRefresh = props.onRefresh; const [isTxnCreated, setTxnCreated] = useState(false); const [lastProposalId, setLastProposalId] = useState(null); +const [showErrorToast, setShowErrorToast] = useState(false); function getLastProposalId() { return Near.asyncView(treasuryDaoID, "get_last_proposal_id").then( @@ -35,17 +39,33 @@ useEffect(() => { // show toast after proposal is submitted useEffect(() => { if (isTxnCreated && typeof onRefresh === "function") { + let checkTxnTimeout = null; + let errorTimeout = null; + const checkForNewProposal = () => { getLastProposalId().then((id) => { if (lastProposalId !== id) { setToastStatus(true); setTxnCreated(false); + clearTimeout(errorTimeout); } else { - setTimeout(() => checkForNewProposal(), 1000); + checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000); } }); }; checkForNewProposal(); + + // if in 20 seconds there is no change, show error condition + errorTimeout = setTimeout(() => { + setShowErrorToast(true); + setTxnCreated(false); + clearTimeout(checkTxnTimeout); + }, 20000); + + return () => { + clearTimeout(checkTxnTimeout); + clearTimeout(errorTimeout); + }; } }, [isTxnCreated, onRefresh]); @@ -205,6 +225,13 @@ const NoButton = styled.button` return ( <> + {onRefresh && ( + setShowErrorToast(false)} + /> + )}
diff --git a/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx b/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx index d5e971e7..5dc25d02 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx @@ -502,17 +502,22 @@ return ( >
-
Voting duration change request submitted.
- - View it - +
+ +
+
Voting duration change request submitted.
+ + View it + +
+
diff --git a/playwright-tests/tests/settings/voting-duration.spec.js b/playwright-tests/tests/settings/voting-duration.spec.js index 48ad3a77..92ff2991 100644 --- a/playwright-tests/tests/settings/voting-duration.spec.js +++ b/playwright-tests/tests/settings/voting-duration.spec.js @@ -154,7 +154,6 @@ test.describe("User is logged in", function () { return new Promise((resolve) => { wallet.signAndSendTransaction = async (transaction) => { - console.log("transactions", JSON.stringify(transaction)); resolve(transaction); return await new Promise( (transactionSentPromiseResolve) => @@ -179,7 +178,7 @@ test.describe("User is logged in", function () { await page.evaluate((transactionResult) => { window.transactionSentPromiseResolve(transactionResult); }, transactionResult); - await expect(page.locator(".toast-header")).toBeVisible(); + await expect(page.getByText("Processing your request ...")).toBeVisible(); await expect( page.getByText("Voting duration change request submitted") ).toBeVisible(); From 530ccd0b0f0f1ff9156a686d9ff4bd75da2604dc Mon Sep 17 00:00:00 2001 From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:05:43 +0530 Subject: [PATCH 7/7] refactor --- .../treasury-devdao.near/widget/pages/settings/feed/Table.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx b/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx index 0873221a..8f720c14 100644 --- a/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx +++ b/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx @@ -161,13 +161,11 @@ const ToastStatusContent = () => { case "InProgress": content = "Your vote is counted, the request is highlighted."; break; - case "Approved": case "Approved": content = "The request has been successfully executed." + (showRefreshPageText ? " Refresh the page to see the updates." : ""); break; - break; case "Rejected": content = "The request has been rejected."; break;