VfM4c$P3nBM^@8zg0!=KA5+id7w_G;d7`a>-+pA_5BT9
zpYc-eVbS9u?G2bBxwB_?VK8s|X(uhSn4aqJ_NHGz$ZiReL*F9I|MX@tO!5_ku}_5H5^
literal 0
HcmV?d00001
diff --git a/instances/treasury-devdao.near/widget/pages/asset-exchange/History.jsx b/instances/widgets.treasury-factory.near/widget/pages/asset-exchange/History.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/asset-exchange/History.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/asset-exchange/History.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/asset-exchange/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/asset-exchange/PendingRequests.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/asset-exchange/PendingRequests.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/asset-exchange/PendingRequests.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/asset-exchange/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/asset-exchange/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/asset-exchange/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/asset-exchange/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/dashboard/Chart.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/dashboard/Chart.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/dashboard/Portfolio.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/dashboard/Portfolio.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/dashboard/TransactionHistory.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/dashboard/TransactionHistory.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/dashboard/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/dashboard/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/payments/CreatePaymentRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/payments/CreatePaymentRequest.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/payments/History.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/History.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/payments/History.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/payments/History.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/payments/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/PendingRequests.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/payments/PendingRequests.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/payments/PendingRequests.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/payments/Table.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/payments/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/payments/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/payments/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/History.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/History.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/proposals-feed/History.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/proposals-feed/History.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/PendingRequests.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/proposals-feed/PendingRequests.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/proposals-feed/PendingRequests.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/proposals-feed/Table.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/proposals-feed/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/proposals-feed/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/proposals-feed/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/DeleteModalConfirmation.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/MembersEditor.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/MembersEditor.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/MembersPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/MembersPage.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/RoleSelector.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/RoleSelector.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/RoleSelector.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/RoleSelector.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/Theme.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/Thresholds.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/VotingDurationPage.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/History.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/History.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/feed/History.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/feed/History.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/PendingRequests.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/feed/PendingRequests.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/feed/PendingRequests.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/SettingsDropdown.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/feed/SettingsDropdown.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/feed/SettingsDropdown.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/feed/Table.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/feed/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/feed/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/feed/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/settings/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/settings/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/settings/index.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateButton.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/CreateButton.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/History.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/History.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/History.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/History.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/PendingRequests.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/SettingsDropdown.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/Table.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/Type.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Type.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/Type.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Type.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/Validator.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/Validator.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/WalletDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/WalletDropdown.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
diff --git a/instances/treasury-devdao.near/widget/pages/stake-delegation/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/index.jsx
similarity index 100%
rename from instances/treasury-devdao.near/widget/pages/stake-delegation/index.jsx
rename to instances/widgets.treasury-factory.near/widget/pages/stake-delegation/index.jsx
diff --git a/package.json b/package.json
index 93cb2ca7..016f2c46 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,10 @@
"bw:build:infinex": "npm run bw:build:instance --instance=treasury-infinex.near",
"bw:build:infinex-testing": "npm run bw:build:instance --instance=treasury-testing-infinex.near",
"bw:build:templar": "npm run bw:build:instance --instance=treasury-templar.near",
+ "bw:build:widgets": "npm run bw:build:instance --instance=widgets.treasury-factory.near",
+ "bw:build:test-widgets": "npm run bw:build:instance --instance=test-widgets.treasury-factory.near",
+ "bw:build:bootstrap": "npm run bw:build:instance --instance=bootstrap.treasury-factory.near",
+ "bw:build:test-bootstrap": "npm run bw:build:instance --instance=test-bootstrap.treasury-factory.near",
"build:sandbox": "cd sandboxrpc && cargo build",
"gateway": "bw ws dev -g web4/public_html",
"dry-run:instances": "cd ./build/$npm_config_instance && bos components diff $npm_config_instance network-config mainnet",
@@ -53,6 +57,14 @@
"dry-run:infinex": "npm run bw:build:infinex && npm run dry-run:instances --instance=treasury-infinex.near",
"deploy:templar": "npm run bw:build:templar && cd ./build/treasury-templar.near && bos components deploy",
"dry-run:templar": "npm run bw:build:templar && npm run dry-run:instances --instance=treasury-templar.near",
+ "deploy:test-bootstrap": "npm run bw:build:test-bootstrap && cd ./build/test-bootstrap.treasury-factory.near && bos components deploy",
+ "dry-run:test-bootstrap": "npm run bw:build:test-bootstrap && npm run dry-run:instances --instance=test-bootstrap.treasury-factory.near",
+ "deploy:bootstrap": "npm run bw:build:bootstrap && cd ./build/bootstrap.treasury-factory.near && bos components deploy",
+ "dry-run:bootstrap": "npm run bw:build:bootstrap && npm run dry-run:instances --instance=bootstrap.treasury-factory.near",
+ "deploy:test-widgets": "npm run bw:build:test-widgets && cd ./build/test-widgets.treasury-factory.near && bos components deploy",
+ "dry-run:test-widgets": "npm run bw:build:test-widgets && npm run dry-run:instances --instance=test-widgets.treasury-factory.near",
+ "deploy:widgets": "npm run bw:build:widgets && cd ./build/widgets.treasury-factory.near && bos components deploy",
+ "dry-run:widgets": "npm run bw:build:widgets && npm run dry-run:instances --instance=widgets.treasury-factory.near",
"test": "npx playwright test",
"test:watch:codespaces": "npm test -- --ui-host=0.0.0.0"
},
diff --git a/playwright-tests/tests/payments/create-payment-request.spec.js b/playwright-tests/tests/payments/create-payment-request.spec.js
index aceceed4..5f798a2b 100644
--- a/playwright-tests/tests/payments/create-payment-request.spec.js
+++ b/playwright-tests/tests/payments/create-payment-request.spec.js
@@ -761,9 +761,12 @@ test.describe("admin with function access keys", function () {
await expect(
page.getByRole("cell", { name: `${newProposalId}`, exact: true })
).toBeVisible({ timeout: 10_000 });
+ const widgetsAccount =
+ (instanceAccount.includes("testing") ? "test-widgets" : "widgets") +
+ ".treasury-factory.near";
const firstRow = page
.locator(
- 'tr[data-component="treasury-devdao.near/widget/pages.payments.Table"]'
+ `tr[data-component="${widgetsAccount}/widget/pages.payments.Table"]`
)
.nth(1);
await expect(firstRow).toContainText(
diff --git a/playwright-tests/tests/payments/vote-on-request.spec.js b/playwright-tests/tests/payments/vote-on-request.spec.js
index aedde02a..f34af3aa 100644
--- a/playwright-tests/tests/payments/vote-on-request.spec.js
+++ b/playwright-tests/tests/payments/vote-on-request.spec.js
@@ -74,10 +74,14 @@ async function voteOnProposal({
},
});
+ const widgetsAccount =
+ (instanceAccount.includes("testing") === true
+ ? "test-widgets"
+ : "widgets") + ".treasury-factory.near";
await page.goto(`/${instanceAccount}/widget/app?page=payments`);
await setDontAskAgainCacheValues({
page,
- widgetSrc: "treasury-devdao.near/widget/components.VoteActions",
+ widgetSrc: `${widgetsAccount}/widget/components.VoteActions`,
contractId,
methodName: "act_proposal",
});
diff --git a/playwright-tests/tests/settings/request-feed.spec.js b/playwright-tests/tests/settings/request-feed.spec.js
index 70574f41..fdb389a3 100644
--- a/playwright-tests/tests/settings/request-feed.spec.js
+++ b/playwright-tests/tests/settings/request-feed.spec.js
@@ -103,9 +103,14 @@ async function voteOnProposal({
});
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
+ const widgetsAccount =
+ (instanceAccount.includes("testing") === true
+ ? "test-widgets"
+ : "widgets") + ".treasury-factory.near";
+
await setDontAskAgainCacheValues({
page,
- widgetSrc: "treasury-devdao.near/widget/components.VoteActions",
+ widgetSrc: `${widgetsAccount}/widget/components.VoteActions`,
contractId,
methodName: "act_proposal",
});
diff --git a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
index 759550aa..1bae8674 100644
--- a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
+++ b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
@@ -377,13 +377,18 @@ async function voteOnProposal({
});
await page.goto(`/${instanceAccount}/widget/app?page=stake-delegation`);
+ const widgetsAccount =
+ (instanceAccount.includes("testing") === true
+ ? "test-widgets"
+ : "widgets") + ".treasury-factory.near";
await setDontAskAgainCacheValues({
page,
- widgetSrc: "treasury-devdao.near/widget/components.VoteActions",
+ widgetSrc: `${widgetsAccount}/widget/components.VoteActions`,
contractId,
methodName: "act_proposal",
});
+
await expect(
await page.locator("div").filter({ hasText: /^Stake Delegation$/ })
).toBeVisible({ timeout: 20_000 });
@@ -816,14 +821,24 @@ test.describe("Withdraw request", function () {
});
});
-async function openLockupStakingForm({ page, daoAccount, lockupContract }) {
+async function openLockupStakingForm({
+ page,
+ daoAccount,
+ lockupContract,
+ instanceAccount,
+}) {
const createRequestButton = await page.getByText("Create Request", {
exact: true,
});
await createRequestButton.click();
+ const widgetsAccount =
+ (instanceAccount.includes("testing") === true
+ ? "test-widgets"
+ : "widgets") + ".treasury-factory.near";
+
await page
.locator(
- 'div[data-component="treasury-devdao.near/widget/pages.stake-delegation.CreateButton"] .option',
+ `div[data-component="${widgetsAccount}/widget/pages.stake-delegation.CreateButton"] .option`,
{ hasText: "Stake" }
)
.first()
@@ -907,9 +922,15 @@ test.describe("Lockup staking", function () {
page,
daoAccount,
lockupContract,
+ instanceAccount,
}) => {
test.setTimeout(120_000);
- await openLockupStakingForm({ page, daoAccount, lockupContract });
+ await openLockupStakingForm({
+ page,
+ daoAccount,
+ lockupContract,
+ instanceAccount,
+ });
await fillValidatorAccount({
page,
});
@@ -1019,9 +1040,15 @@ test.describe("Lockup staking", function () {
page,
daoAccount,
lockupContract,
+ instanceAccount,
}) => {
test.setTimeout(120_000);
- await openLockupStakingForm({ page, daoAccount, lockupContract });
+ await openLockupStakingForm({
+ page,
+ daoAccount,
+ lockupContract,
+ instanceAccount,
+ });
await page.waitForTimeout(20_000);
const poolSelector = page.locator(".custom-select").first();
await expect(poolSelector).toBeVisible({ timeout: 20_000 });
diff --git a/playwright-tests/tests/web4/web4.spec.js b/playwright-tests/tests/web4/web4.spec.js
index 6f798ecb..286eeaad 100644
--- a/playwright-tests/tests/web4/web4.spec.js
+++ b/playwright-tests/tests/web4/web4.spec.js
@@ -18,10 +18,15 @@ test("should go directly to app widget for instance", async ({
await route.continue({ url: baseURL });
});
await page.goto(pageOrigin);
+ const widgetsAccount =
+ (instanceAccount.includes("testing") === true
+ ? "test-widgets"
+ : "widgets") + ".treasury-factory.near";
+
await expect(
await page
.locator(
- 'div[data-component="treasury-devdao.near/widget/components.Navbar"]'
+ `div[data-component="${widgetsAccount}/widget/components.Navbar"]`
)
.first()
).toContainText(daoAccount);
From f3b9ebe3a230fb02f654415b93b97fb66ad27361 Mon Sep 17 00:00:00 2001
From: Andrew
Date: Wed, 15 Jan 2025 17:21:03 +0200
Subject: [PATCH 02/40] Fix chart gradient colors for dark theme and pagination
dropdown (#215)
- fix chart gradient colors for dark theme
- fix pagination dropdown
---
.../widget/components/DropDown.jsx | 3 ++-
.../widget/components/Pagination.jsx | 24 ++++++++++++-------
.../widget/components/templates/AppLayout.jsx | 4 ++--
.../widget/pages/dashboard/Chart.jsx | 16 +++++++++----
.../widget/pages/settings/Thresholds.jsx | 2 +-
5 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/DropDown.jsx b/instances/widgets.treasury-factory.near/widget/components/DropDown.jsx
index dc8fe7a0..cee817ff 100644
--- a/instances/widgets.treasury-factory.near/widget/components/DropDown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/DropDown.jsx
@@ -16,12 +16,13 @@ const StyledDropdown = styled.div`
width: 100%;
text-align: left;
padding-inline: 10px;
+ padding-right: 25px;
}
.dropdown-toggle:after {
position: absolute;
top: 45%;
- right: 5%;
+ right: 10px;
}
.text-sm {
diff --git a/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx b/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
index 97b2e0d5..817618e4 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
@@ -3,9 +3,13 @@ const onPrevClick = props.onPrevClick ?? (() => {});
const onRowsChange = props.onRowsChange ?? (() => {});
const totalPages = props.totalPages;
const totalLength = props.totalLength;
+const paginationOptions = [
+ { label: 10, value: 10 },
+ { label: 20, value: 20 },
+ { label: 30, value: 30 },
+];
const rowsPerPage = props.rowsPerPage;
const page = props.currentPage;
-
const currentPage = page + 1;
const currenPageLimit =
totalLength <= currentPage * rowsPerPage
@@ -16,14 +20,16 @@ return (
Rows per Page:
- onRowsChange(e.target.value)}
- value={rowsPerPage}
- >
- 10
- 20
- 30
-
+ o.value === rowsPerPage),
+ onUpdate: ({ value }) => onRowsChange(value),
+ }}
+ />
Showing: {currentPage * rowsPerPage - rowsPerPage + 1} - {currenPageLimit}{" "}
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index c8daafef..9ae74ce9 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -269,8 +269,8 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
.badge {
padding: 6px 8px;
- background: #f7dbff;
- color: var(--theme-color);
+ background: var(--grey-035);
+ color: var(--text-color);
rounded: 8px;
font-weight: 500;
font-size: 12px;
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
index 4b67294d..142bf8f4 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
@@ -54,11 +54,11 @@ const metadata = JSON.parse(atob(config.metadata ?? ""));
const isDarkTheme = metadata.theme === "dark";
const bgPageColor = isDarkTheme ? "#222222" : "#FFFFFF";
-const borderColor = isDarkTheme ? "#3B3B3B" : "#000";
+const borderColor = isDarkTheme ? "#CACACA" : "#000";
const iconColor = isDarkTheme ? "#CACACA" : "#060606";
const textColor = isDarkTheme ? "#CACACA" : "#1B1B18";
const fillStyle = isDarkTheme
- ? "rgba(27, 27, 24, 0.1)"
+ ? "rgba(34, 34, 34, 0.7)"
: "rgba(255, 255, 255, 0.7)";
const code = `
@@ -95,9 +95,15 @@ const code = `
let hoverX = null;
let gradient = ctx.createLinearGradient(0, 0, 0, 350);
- gradient.addColorStop(0, "rgba(0,0,0, 0.3)")
- gradient.addColorStop(0.3, "rgba(0,0,0, 0.1)")
- gradient.addColorStop(1, "rgba(0,0,0, 0)")
+ if (${isDarkTheme}) {
+ gradient.addColorStop(0, "rgba(255,255,255, 0.2)")
+ gradient.addColorStop(0.3, "rgba(255,255,255, 0.1)")
+ gradient.addColorStop(1, "rgba(255,255,255, 0)")
+ } else {
+ gradient.addColorStop(0, "rgba(0,0,0, 0.3)")
+ gradient.addColorStop(0.3, "rgba(0,0,0, 0.1)")
+ gradient.addColorStop(1, "rgba(0,0,0, 0)")
+ }
// Plugin for drawing the tracking line
const trackingLinePlugin = {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
index ad0f39b3..03cd2929 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
@@ -178,7 +178,7 @@ const Container = styled.div`
}
.dropdown-toggle:after {
- top: 20% !important;
+ top: 30% !important;
}
`;
From 8979aa32f4c49b63dfc53301e071608aa191820a Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 00:27:35 +0530
Subject: [PATCH 03/40] Button hover effect (#218)
- I have deleted `css.jsx` files and move the `themeColor` to config, so
we can utilise it as a constant and convert to hsl to get hover effect
cover, and also use it in theme page
- Added hover effects to all buttons
https://github.com/user-attachments/assets/eade6cfd-7feb-41db-9b6d-9885508de7bc
- Fixed some styling issues
---
instances/treasury-devdao.near/widget/app.jsx | 22 +--
.../widget/config/css.jsx | 5 -
.../widget/config/data.jsx | 1 +
.../treasury-infinex.near/widget/app.jsx | 22 +--
.../widget/config/css.jsx | 5 -
.../widget/config/data.jsx | 1 +
.../treasury-templar.near/widget/app.jsx | 22 +--
.../widget/config/css.jsx | 5 -
.../widget/config/data.jsx | 5 +
.../widget/app.jsx | 22 +--
.../widget/config/css.jsx | 5 -
.../widget/config/data.jsx | 1 +
.../treasury-testing.near/widget/app.jsx | 22 +--
.../widget/config/css.jsx | 5 -
.../widget/config/data.jsx | 1 +
.../widget/components/Modal.jsx | 4 +-
.../widget/components/Navbar.jsx | 7 +-
.../widget/components/SettingsDropdown.jsx | 6 +-
.../widget/components/templates/AppLayout.jsx | 150 +++++++++++++++---
.../pages/payments/CreatePaymentRequest.jsx | 6 +-
.../settings/DeleteModalConfirmation.jsx | 4 +-
.../widget/pages/settings/MembersEditor.jsx | 14 +-
.../widget/pages/settings/MembersPage.jsx | 2 +-
.../widget/pages/settings/Theme.jsx | 8 +-
.../widget/pages/settings/Thresholds.jsx | 2 +-
.../pages/settings/VotingDurationPage.jsx | 8 +-
.../pages/settings/feed/SettingsDropdown.jsx | 2 +-
.../stake-delegation/CreateStakeRequest.jsx | 2 +-
.../stake-delegation/CreateUnstakeRequest.jsx | 2 +-
.../CreateWithdrawRequest.jsx | 2 +-
.../stake-delegation/SettingsDropdown.jsx | 2 +-
.../payments/create-payment-request.spec.js | 6 +-
.../settings/create-member-request.spec.js | 4 +-
33 files changed, 218 insertions(+), 157 deletions(-)
delete mode 100644 instances/treasury-devdao.near/widget/config/css.jsx
delete mode 100644 instances/treasury-infinex.near/widget/config/css.jsx
delete mode 100644 instances/treasury-templar.near/widget/config/css.jsx
delete mode 100644 instances/treasury-testing-infinex.near/widget/config/css.jsx
delete mode 100644 instances/treasury-testing.near/widget/config/css.jsx
diff --git a/instances/treasury-devdao.near/widget/app.jsx b/instances/treasury-devdao.near/widget/app.jsx
index d2fcc990..593402b9 100644
--- a/instances/treasury-devdao.near/widget/app.jsx
+++ b/instances/treasury-devdao.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -84,14 +80,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/treasury-devdao.near/widget/config/css.jsx b/instances/treasury-devdao.near/widget/config/css.jsx
deleted file mode 100644
index aae9f279..00000000
--- a/instances/treasury-devdao.near/widget/config/css.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Theme = styled.div`
- --theme-color: #05a36e;
-`;
-
-return { Theme };
diff --git a/instances/treasury-devdao.near/widget/config/data.jsx b/instances/treasury-devdao.near/widget/config/data.jsx
index b749f175..c7819ecf 100644
--- a/instances/treasury-devdao.near/widget/config/data.jsx
+++ b/instances/treasury-devdao.near/widget/config/data.jsx
@@ -48,4 +48,5 @@ return {
),
+ themeColor: "#05a36e",
};
diff --git a/instances/treasury-infinex.near/widget/app.jsx b/instances/treasury-infinex.near/widget/app.jsx
index 4859aafb..116d3b6d 100644
--- a/instances/treasury-infinex.near/widget/app.jsx
+++ b/instances/treasury-infinex.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -95,14 +91,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/treasury-infinex.near/widget/config/css.jsx b/instances/treasury-infinex.near/widget/config/css.jsx
deleted file mode 100644
index f7a131f3..00000000
--- a/instances/treasury-infinex.near/widget/config/css.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Theme = styled.div`
- --theme-color: #f76218;
-`;
-
-return { Theme };
diff --git a/instances/treasury-infinex.near/widget/config/data.jsx b/instances/treasury-infinex.near/widget/config/data.jsx
index 47a3b183..ff1baf30 100644
--- a/instances/treasury-infinex.near/widget/config/data.jsx
+++ b/instances/treasury-infinex.near/widget/config/data.jsx
@@ -40,4 +40,5 @@ return {
),
lockupContract: "77fa9d86aca49e758a4cb72628972a0f3135d168.lockup.near",
+ themeColor: "#f76218",
};
diff --git a/instances/treasury-templar.near/widget/app.jsx b/instances/treasury-templar.near/widget/app.jsx
index d2fcc990..593402b9 100644
--- a/instances/treasury-templar.near/widget/app.jsx
+++ b/instances/treasury-templar.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -84,14 +80,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/treasury-templar.near/widget/config/css.jsx b/instances/treasury-templar.near/widget/config/css.jsx
deleted file mode 100644
index 42f7499e..00000000
--- a/instances/treasury-templar.near/widget/config/css.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Theme = styled.div`
- --theme-color: #8942d9;
-`;
-
-return { Theme };
diff --git a/instances/treasury-templar.near/widget/config/data.jsx b/instances/treasury-templar.near/widget/config/data.jsx
index b167d3ff..07ead66e 100644
--- a/instances/treasury-templar.near/widget/config/data.jsx
+++ b/instances/treasury-templar.near/widget/config/data.jsx
@@ -9,6 +9,10 @@ return {
title: "Payments",
href: "?page=payments",
},
+ {
+ title: "Stake Delegation",
+ href: "?page=stake-delegation",
+ },
{
title: "Settings",
href: "?page=settings",
@@ -24,4 +28,5 @@ return {
style={{ height: 40, width: 40 }}
/>
),
+ themeColor: "#8942d9",
};
diff --git a/instances/treasury-testing-infinex.near/widget/app.jsx b/instances/treasury-testing-infinex.near/widget/app.jsx
index 4859aafb..116d3b6d 100644
--- a/instances/treasury-testing-infinex.near/widget/app.jsx
+++ b/instances/treasury-testing-infinex.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -95,14 +91,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/treasury-testing-infinex.near/widget/config/css.jsx b/instances/treasury-testing-infinex.near/widget/config/css.jsx
deleted file mode 100644
index f7a131f3..00000000
--- a/instances/treasury-testing-infinex.near/widget/config/css.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Theme = styled.div`
- --theme-color: #f76218;
-`;
-
-return { Theme };
diff --git a/instances/treasury-testing-infinex.near/widget/config/data.jsx b/instances/treasury-testing-infinex.near/widget/config/data.jsx
index 54c94ffb..feff99d7 100644
--- a/instances/treasury-testing-infinex.near/widget/config/data.jsx
+++ b/instances/treasury-testing-infinex.near/widget/config/data.jsx
@@ -41,4 +41,5 @@ return {
),
isTesting: true,
+ themeColor: "#f76218",
};
diff --git a/instances/treasury-testing.near/widget/app.jsx b/instances/treasury-testing.near/widget/app.jsx
index d2fcc990..593402b9 100644
--- a/instances/treasury-testing.near/widget/app.jsx
+++ b/instances/treasury-testing.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -84,14 +80,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/treasury-testing.near/widget/config/css.jsx b/instances/treasury-testing.near/widget/config/css.jsx
deleted file mode 100644
index aae9f279..00000000
--- a/instances/treasury-testing.near/widget/config/css.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Theme = styled.div`
- --theme-color: #05a36e;
-`;
-
-return { Theme };
diff --git a/instances/treasury-testing.near/widget/config/data.jsx b/instances/treasury-testing.near/widget/config/data.jsx
index 9c5673ca..7df3c557 100644
--- a/instances/treasury-testing.near/widget/config/data.jsx
+++ b/instances/treasury-testing.near/widget/config/data.jsx
@@ -49,4 +49,5 @@ return {
),
+ themeColor: "#05a36e",
};
diff --git a/instances/widgets.treasury-factory.near/widget/components/Modal.jsx b/instances/widgets.treasury-factory.near/widget/components/Modal.jsx
index a058c59c..89ab9c35 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Modal.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Modal.jsx
@@ -129,7 +129,9 @@ return (
))}
-
-
+
+
setShowMenu(!showMenu)}>
diff --git a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
index 60a76ce8..9502d144 100644
--- a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
@@ -130,12 +130,12 @@ return (
tabIndex="0"
onBlur={() => setIsOpen(false)}
>
-
-
+
{isOpen && (
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index 9ae74ce9..b04aca7d 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -2,6 +2,96 @@ const { BalanceBanner } = VM.require(
`${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.BalanceBanner`
) || { BalanceBanner: () => <>> };
+function hexToHsl(hex) {
+ // Remove # if present
+ hex = hex.startsWith("#") ? hex.slice(1) : hex;
+
+ // Extract RGB components
+ const r = parseInt(hex.slice(0, 2), 16);
+ const g = parseInt(hex.slice(2, 4), 16);
+ const b = parseInt(hex.slice(4, 6), 16);
+
+ // Normalize RGB values
+ const rNorm = r / 255;
+ const gNorm = g / 255;
+ const bNorm = b / 255;
+
+ const max = Math.max(rNorm, gNorm, bNorm);
+ const min = Math.min(rNorm, gNorm, bNorm);
+ const delta = max - min;
+
+ let h = 0;
+ let s = 0;
+ const l = (max + min) / 2;
+
+ if (delta !== 0) {
+ s = l < 0.5 ? delta / (max + min) : delta / (2 - max - min);
+
+ if (max === rNorm) {
+ h = (gNorm - bNorm) / delta + (gNorm < bNorm ? 6 : 0);
+ } else if (max === gNorm) {
+ h = (bNorm - rNorm) / delta + 2;
+ } else {
+ h = (rNorm - gNorm) / delta + 4;
+ }
+
+ h *= 60;
+ }
+
+ return [Math.round(h), Math.round(s * 100), Math.round(l * 100)];
+}
+
+// Function to convert HSL to HEX
+function hslToHex(h, s, l) {
+ s /= 100;
+ l /= 100;
+
+ const c = (1 - Math.abs(2 * l - 1)) * s;
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
+ const m = l - c / 2;
+
+ let r = 0,
+ g = 0,
+ b = 0;
+
+ if (h >= 0 && h < 60) {
+ r = c;
+ g = x;
+ b = 0;
+ } else if (h >= 60 && h < 120) {
+ r = x;
+ g = c;
+ b = 0;
+ } else if (h >= 120 && h < 180) {
+ r = 0;
+ g = c;
+ b = x;
+ } else if (h >= 180 && h < 240) {
+ r = 0;
+ g = x;
+ b = c;
+ } else if (h >= 240 && h < 300) {
+ r = x;
+ g = 0;
+ b = c;
+ } else if (h >= 300 && h < 360) {
+ r = c;
+ g = 0;
+ b = x;
+ }
+
+ r = Math.round((r + m) * 255);
+ g = Math.round((g + m) * 255);
+ b = Math.round((b + m) * 255);
+
+ const toHex = (value) => {
+ const hex = value.toString(16);
+ return hex.length === 1 ? `0${hex}` : hex;
+ };
+
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
+}
+
const AppHeader = ({ page, instance }) => (
(
);
function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
+ const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
+ themeColor: "",
+ };
+
+ // Convert HEX to HSL
+ const [h, s, l] = hexToHsl(themeColor);
+
+ // Calculate hover color (darken by reducing lightness)
+ const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+
const config = treasuryDaoID
? useCache(
() => Near.asyncView(treasuryDaoID, "get_config"),
@@ -26,8 +126,9 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
const gatewayURL = data?.body?.headers?.Origin ?? "";
const isDarkTheme = metadata.theme === "dark";
- const getColors = (isDarkTheme) => `
- ${metadata.primaryColor ? `--theme-color: ${metadata.primaryColor};` : ""}
+ const getColors = (isDarkTheme, themeColor, hoverColor) => `
+ --theme-color: ${metadata?.primaryColor ?? themeColor};
+ --theme-color-dark: ${hoverColor};
--bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
--bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
--bg-system-color: ${isDarkTheme ? "#131313" : "#f4f4f4"};
@@ -54,7 +155,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
`;
const ParentContainer = styled.div`
- ${() => getColors(isDarkTheme)}
+ ${() => getColors(isDarkTheme, themeColor, hoverColor)}
width: 100%;
background: var(--bg-system-color) !important;
${() =>
@@ -149,7 +250,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
border: none !important;
&:hover {
- background: var(--theme-color-dark);
+ background: var(--theme-color-dark) !important;
}
i {
@@ -215,6 +316,23 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
.theme-btn.btn:hover {
color: white !important;
+ background: var(--theme-color-dark) !important;
+ }
+
+ .btn-outline-secondary {
+ border-color: var(--border-color) !important;
+ color: var(--text-color) !important;
+ border-width: 1px !important;
+
+ i {
+ color: var(--text-color) !important;
+ }
+
+ &:hover {
+ color: var(--text-color) !important;
+ border-color: var(--border-color) !important;
+ background: var(--grey-035) !important;
+ }
}
.toast-container {
@@ -291,18 +409,12 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
}
}
- h6,
- .h6,
- h5,
- .h5,
- h4,
- .h4,
- h3,
- .h3,
- h2,
- .h2,
h1,
- .h1 {
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
color: var(--text-color) !important;
}
@@ -384,12 +496,8 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
color: inherit !important;
}
- .text-delete {
+ .text-red {
color: var(--other-red) !important;
-
- i {
- color: var(--other-red) !important;
- }
}
.btn-outline.btn:hover {
@@ -421,7 +529,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
}
`;
- return !config ? (
+ return !config || themeColor === null ? (
<>>
) : (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
index 7457706c..92c09ba6 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
@@ -227,10 +227,6 @@ const Container = styled.div`
color: var(--theme-color) !important;
}
- .btn:hover {
- color: black !important;
- }
-
.warning {
background-color: rgba(255, 158, 0, 0.1);
color: #ff9e00;
@@ -631,7 +627,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
index 015993fa..d7c5579c 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
@@ -249,7 +249,9 @@ return (
-
+
{(selectedMember || memberAlreadyExists) && (
-
- Delete
-
- ),
+ label: "Delete",
+
onClick: () => setShowDeleteModal(true),
disabled: isTxnCreated || !username,
}}
@@ -313,7 +309,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
index 9468485e..0d2761f3 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
@@ -217,7 +217,7 @@ const Members = () => {
src={`${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.InsufficientBannerModal`}
props={{
ActionButton: () => (
-
+
),
checkForDeposit: true,
treasuryDaoID,
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
index 0d0e67ae..2b7545db 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
@@ -14,7 +14,9 @@ if (!instance) {
return <>>;
}
-const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`);
+const { treasuryDaoID, themeColor } = VM.require(
+ `${instance}/widget/config.data`
+);
const hasCreatePermission = hasPermission(
treasuryDaoID,
@@ -329,7 +331,7 @@ function onSubmitClick() {
function setDefault() {
setImage(metadata?.flagLogo ?? defaultImage);
- setColor(metadata?.primaryColor ?? defaultColor);
+ setColor(metadata?.primaryColor ?? themeColor ?? defaultColor);
setSelectedTheme(
ThemeOptions.find((i) => i.value === metadata?.theme) ?? ThemeOptions[0]
);
@@ -437,7 +439,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: setDefault,
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
index 03cd2929..de123747 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
@@ -472,7 +472,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
index b31f7237..f04437f1 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
@@ -449,7 +449,9 @@ return (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
index d3b7b933..89397aa3 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
@@ -608,7 +608,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
index 9fa39ba2..16b050db 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
@@ -591,7 +591,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
index 4196a40f..09e4aae4 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
@@ -477,7 +477,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn-outline shadow-none border-0",
+ root: "btn btn-outline-secondary shadow-none no-transparent",
},
label: "Cancel",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx
index cc4be62b..4f2582fd 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/SettingsDropdown.jsx
@@ -115,7 +115,7 @@ return (
onBlur={() => setIsOpen(false)}
>
diff --git a/playwright-tests/tests/payments/create-payment-request.spec.js b/playwright-tests/tests/payments/create-payment-request.spec.js
index 5f798a2b..634a6556 100644
--- a/playwright-tests/tests/payments/create-payment-request.spec.js
+++ b/playwright-tests/tests/payments/create-payment-request.spec.js
@@ -626,9 +626,9 @@ test.describe("admin with function access keys", function () {
await totalAmountField.pressSequentially("20");
await totalAmountField.blur();
}
- const submitBtn = page.getByRole("button", { name: "Submit" });
- await expect(submitBtn).toBeAttached({ timeout: 10_000 });
- await submitBtn.scrollIntoViewIfNeeded({ timeout: 10_000 });
+ const submitBtn = await page.getByRole("button", { name: "Submit" });
+ await expect(submitBtn).toBeEnabled({ timeout: 20_000 });
+ await submitBtn.scrollIntoViewIfNeeded({ timeout: 20_000 });
await submitBtn.click();
const expectedTransactionModalObject = instanceConfig.showProposalSelection
diff --git a/playwright-tests/tests/settings/create-member-request.spec.js b/playwright-tests/tests/settings/create-member-request.spec.js
index 8e64d5f5..abe80642 100644
--- a/playwright-tests/tests/settings/create-member-request.spec.js
+++ b/playwright-tests/tests/settings/create-member-request.spec.js
@@ -441,7 +441,7 @@ test.describe("User is logged in", function () {
accountInput.fill("megha19.near");
await accountInput.blur();
await expect(page.getByText("This user is already a member")).toBeVisible();
- await expect(page.getByRole("button", { name: " Delete" })).toBeVisible();
+ await expect(page.getByRole("button", { name: "Delete" })).toBeVisible();
});
test("should update existing member permissions", async ({ page }) => {
@@ -610,7 +610,7 @@ test.describe("User is logged in", function () {
.locator(".offcanvas-body")
.getByText("Create Requests", { exact: true })
).toBeVisible();
- await page.getByRole("button", { name: " Delete" }).click();
+ await page.getByRole("button", { name: "Delete" }).click();
await expect(
page.getByRole("heading", { name: "Are you sure?" })
).toBeVisible();
From d275a199714f90ab2bd91b16160edf558d68dffc Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 00:31:48 +0530
Subject: [PATCH 04/40] minor css change
---
.../widget/components/Navbar.jsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx b/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
index e7aefb8f..78b58a5c 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
@@ -55,6 +55,10 @@ const Navbar = styled.div`
font-size: 13px;
color: #999999;
}
+
+ .page-title {
+ color: var(--text-color);
+ }
`;
const LinksContainer = styled.div`
@@ -148,7 +152,7 @@ return (
)}
-
{getTitle(page ?? "dashboard")}
+
{getTitle(page ?? "dashboard")}
{isTesting &&
Testing }
From ae9b40a4a33348d78a3c4328e00c38838df0c18c Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 00:42:48 +0530
Subject: [PATCH 05/40] fix the theme color
---
.../widget/components/templates/AppLayout.jsx | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index b04aca7d..b7096f29 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -4,6 +4,7 @@ const { BalanceBanner } = VM.require(
function hexToHsl(hex) {
// Remove # if present
+ hex = hex ?? ''
hex = hex.startsWith("#") ? hex.slice(1) : hex;
// Extract RGB components
@@ -107,12 +108,6 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
themeColor: "",
};
- // Convert HEX to HSL
- const [h, s, l] = hexToHsl(themeColor);
-
- // Calculate hover color (darken by reducing lightness)
- const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
-
const config = treasuryDaoID
? useCache(
() => Near.asyncView(treasuryDaoID, "get_config"),
@@ -126,8 +121,21 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
const gatewayURL = data?.body?.headers?.Origin ?? "";
const isDarkTheme = metadata.theme === "dark";
+ if (!config) {
+ return <>>;
+ }
+
+ const primaryColor = metadata?.primaryColor
+ ? metadata?.primaryColor
+ : themeColor;
+ // Convert HEX to HSL
+ const [h, s, l] = hexToHsl(primaryColor);
+
+ // Calculate hover color (darken by reducing lightness)
+ const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+
const getColors = (isDarkTheme, themeColor, hoverColor) => `
- --theme-color: ${metadata?.primaryColor ?? themeColor};
+ --theme-color: ${themeColor};
--theme-color-dark: ${hoverColor};
--bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
--bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
@@ -155,7 +163,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
`;
const ParentContainer = styled.div`
- ${() => getColors(isDarkTheme, themeColor, hoverColor)}
+ ${() => getColors(isDarkTheme, primaryColor, hoverColor)}
width: 100%;
background: var(--bg-system-color) !important;
${() =>
@@ -529,9 +537,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
}
`;
- return !config || themeColor === null ? (
- <>>
- ) : (
+ return (
From 09c54f37e7664875f319823875ea462619fb6aa3 Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 00:44:16 +0530
Subject: [PATCH 06/40] fmt
---
.../widget/components/templates/AppLayout.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index b7096f29..e5892e0a 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -4,7 +4,7 @@ const { BalanceBanner } = VM.require(
function hexToHsl(hex) {
// Remove # if present
- hex = hex ?? ''
+ hex = hex ?? "";
hex = hex.startsWith("#") ? hex.slice(1) : hex;
// Extract RGB components
From d78124b48720126a2e63d2a27b22e047c70c8dc6 Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 01:17:30 +0530
Subject: [PATCH 07/40] vova's suggestive ui hotfixes
---
.../widget/components/Pagination.jsx | 4 +-
.../widget/components/TokenAmount.jsx | 2 +-
.../widget/components/VoteActions.jsx | 27 ++--------
.../widget/components/templates/AppLayout.jsx | 7 ++-
.../widget/pages/dashboard/Portfolio.jsx | 49 ++++++++++---------
.../widget/pages/proposals-feed/Table.jsx | 2 +-
.../widget/pages/settings/Thresholds.jsx | 2 +-
.../widget/pages/settings/feed/Table.jsx | 7 +--
8 files changed, 43 insertions(+), 57 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx b/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
index 817618e4..7c39031b 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Pagination.jsx
@@ -35,14 +35,14 @@ return (
Showing: {currentPage * rowsPerPage - rowsPerPage + 1} - {currenPageLimit}{" "}
of {totalLength}
diff --git a/instances/widgets.treasury-factory.near/widget/components/TokenAmount.jsx b/instances/widgets.treasury-factory.near/widget/components/TokenAmount.jsx
index 228ab13c..15360b1b 100644
--- a/instances/widgets.treasury-factory.near/widget/components/TokenAmount.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/TokenAmount.jsx
@@ -20,7 +20,7 @@ let amount = amountWithDecimals;
if (amountWithoutDecimals !== undefined) {
amount = Big(amountWithoutDecimals)
.div(Big(10).pow(ftMetadata.decimals ?? 1))
- .toString();
+ .toFixed(2);
}
return (
diff --git a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
index 850389b4..3acc7d09 100644
--- a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
@@ -112,32 +112,11 @@ useEffect(() => {
}, [isTxnCreated]);
const Container = styled.div`
- .reject-btn {
- background-color: var(--other-primary);
- border-radius: 5px;
- color: white;
-
- &:hover {
- background-color: var(--other-primary);
- color: white;
- }
- }
-
.remove-btn {
background: none;
border: none;
color: red;
- }
-
- .approve-btn {
- background-color: var(--other-green);
- border-radius: 5px;
- color: white;
-
- &:hover {
- background-color: var(--other-green);
- color: white;
- }
+ font-size: 24px;
}
`;
@@ -238,7 +217,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "approve-btn p-2",
+ root: "btn btn-success",
},
label: "Approve",
loading: isTxnCreated && vote === actions.APPROVE,
@@ -267,7 +246,7 @@ return (
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "reject-btn p-2",
+ root: "btn btn-secondary",
},
label: "Reject",
loading: isTxnCreated && vote === actions.REJECT,
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index e5892e0a..f0ee0f16 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -159,7 +159,6 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
// bootstrap theme color
--bs-body-bg: var(--bg-page-color);
--bs-border-color: var(--border-color);
- --bs-dropdown-link-hover-color: var(--grey-04);
`;
const ParentContainer = styled.div`
@@ -214,6 +213,12 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
color: inherit !important;
}
+ .dropdown-item:hover,
+ .dropdown-item:focus {
+ background-color: var(--grey-04) !important;
+ color: inherit !important;
+ }
+
.offcanvas {
background-color: var(--bg-page-color) !important;
color: var(--text-color) !important;
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
index 72ed2ab0..70080c2b 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
@@ -101,7 +101,12 @@ const BalanceDisplay = ({
hideBorder,
}) => {
return (
-
+
showExpand && setIsExpanded(!isExpanded)}
+ >
@@ -134,17 +139,12 @@ const BalanceDisplay = ({
{showExpand && (
-
setIsExpanded(!isExpanded)}
- >
-
-
+
)}
@@ -169,7 +169,13 @@ const PortfolioCard = ({
}) => {
return (
-
+
showExpand && setIsExpanded(!isExpanded)}
+ >
{showExpand && (
-
setIsExpanded(!isExpanded)}
- >
-
-
+
)}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
index 37d72e5f..e5db26a3 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
@@ -277,7 +277,7 @@ const ProposalsComponent = () => {
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "border p-2",
+ root: "btn btn-outline-secondary",
},
label: "Details",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
index de123747..5adf6fb6 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
@@ -381,7 +381,7 @@ return (
))}
-
+
Voting Policy
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
index 8f720c14..d8f0247b 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
@@ -54,6 +54,7 @@ const columnsVisibility = JSON.parse(
const Container = styled.div`
font-size: 13px;
min-height: 60vh;
+ display: flex;
td {
padding: 0.5rem;
@@ -305,7 +306,7 @@ const ProposalsComponent = () => {
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "border p-2",
+ root: "btn btn-outline-secondary",
},
label: "Details",
onClick: () => {
@@ -395,13 +396,13 @@ return (
proposals === null ||
settingsApproverGroup === null ||
policy === null ? (
-
+
) : (
-
+
{showDetailsProposalKind && (
Date: Thu, 16 Jan 2025 01:19:31 +0530
Subject: [PATCH 08/40] fix href missing error
---
.../widget/pages/settings/Theme.jsx | 3 +++
1 file changed, 3 insertions(+)
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
index 2b7545db..f551b297 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
@@ -5,6 +5,9 @@ const { encodeToMarkdown, hasPermission } = VM.require(
hasPermission: () => {},
};
+const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url") || {
+ href: () => {},
+};
const { TransactionLoader } = VM.require(
`${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.TransactionLoader`
) || { TransactionLoader: () => <>> };
From cf5044f8a42a1e4519ba1f01fb57ed5655f24d05 Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 01:30:01 +0530
Subject: [PATCH 09/40] more css fixes
---
.../widget/components/VoteActions.jsx | 5 ++---
.../widget/pages/dashboard/TransactionHistory.jsx | 10 ++--------
.../widget/pages/proposals-feed/Table.jsx | 2 +-
.../widget/pages/settings/feed/Table.jsx | 2 +-
4 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
index 3acc7d09..f1dde8a5 100644
--- a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
@@ -116,7 +116,6 @@ const Container = styled.div`
background: none;
border: none;
color: red;
- font-size: 24px;
}
`;
@@ -273,12 +272,12 @@ return (
props={{
ActionButton: () => (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
index dd08c948..c7526d3e 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
@@ -229,12 +229,6 @@ const Container = styled.div`
table {
overflow-x: auto;
}
-
- .show-more-btn {
- border: 1px solid var(--border-color) !important;
- text-align: center;
- background: none;
- }
`;
function formatAccount(text) {
@@ -397,13 +391,13 @@ return (
{showMoreLoading ? (
loader
) : (
-
+
{!hideViewMore && (
{
setPage(page + 1);
}}
- className="show-more-btn py-3 w-100 fw-semi-bold rounded-3"
+ className="btn btn-outline-secondary w-100"
>
Show More
diff --git a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
index e5db26a3..2a8e0b79 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
@@ -277,7 +277,7 @@ const ProposalsComponent = () => {
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn btn-outline-secondary",
+ root: "btn btn-outline-secondary shadow-none",
},
label: "Details",
onClick: () => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
index d8f0247b..05e1c96a 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
@@ -306,7 +306,7 @@ const ProposalsComponent = () => {
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.Button`}
props={{
classNames: {
- root: "btn btn-outline-secondary",
+ root: "btn btn-outline-secondary shadow-none",
},
label: "Details",
onClick: () => {
From 842faf779299dd52dbcbe3a6d2e4a82a026bdc42 Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 01:34:36 +0530
Subject: [PATCH 10/40] reduce image size
---
.../widget/components/VoteActions.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
index f1dde8a5..7b9edd2b 100644
--- a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
@@ -277,7 +277,7 @@ return (
disabled={isTxnCreated}
>
From 5fa379a5b752d80737bea7e72b5df47f5e27cfcf Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 16 Jan 2025 01:50:14 +0530
Subject: [PATCH 11/40] fix stake btn
---
.../widget/pages/stake-delegation/CreateButton.jsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
index ae9dff9e..9f2be3b2 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
@@ -189,11 +189,11 @@ const CreateBtn = () => {
tabIndex="0"
onBlur={() => setCreateBtnOpen(false)}
>
-
+
Date: Thu, 16 Jan 2025 22:49:38 +0200
Subject: [PATCH 12/40] Web4 typo in url (#220)
---
.../widget/components/create-treasury/SummaryStep.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
index 43e010a8..88a25562 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
@@ -372,7 +372,7 @@ return (
/>
From 7bc10f3039798274eeca96644544e5104ce9a142 Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Sun, 19 Jan 2025 21:43:13 +0530
Subject: [PATCH 13/40] Fix the bootstrap setup (#222)
Fix the `instance` and `treasuryDaoID` assignment.
---
.../aliases.mainnet.json | 3 ++-
.../bootstrap.treasury-factory.near/widget/app.jsx | 13 ++++++++++---
.../widget/config/data.jsx | 12 ++++++++----
.../aliases.mainnet.json | 3 ++-
.../widget/components/SidebarAndMainLayout.jsx | 1 +
.../tests/settings/create-member-request.spec.js | 2 +-
.../tests/settings/create-threshold-request.spec.js | 2 +-
playwright-tests/tests/settings/theme.spec.js | 2 +-
.../tests/settings/voting-duration.spec.js | 2 +-
9 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/instances/bootstrap.treasury-factory.near/aliases.mainnet.json b/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
index b1b322aa..62a0d392 100644
--- a/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
+++ b/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
@@ -1,3 +1,4 @@
{
- "REPL_BASE_DEPLOYMENT_ACCOUNT": "widgets.treasury-factory.near"
+ "REPL_BASE_DEPLOYMENT_ACCOUNT": "widgets.treasury-factory.near",
+ "REPL_BOOTSTRAP_ACCOUNT": "bootstrap.treasury-factory.near"
}
diff --git a/instances/bootstrap.treasury-factory.near/widget/app.jsx b/instances/bootstrap.treasury-factory.near/widget/app.jsx
index 8afd242e..a25fe7fd 100644
--- a/instances/bootstrap.treasury-factory.near/widget/app.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/app.jsx
@@ -10,9 +10,16 @@ const { AppLayout } = VM.require(
"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.templates.AppLayout"
) || { AppLayout: () => <>> };
-const instance = context.widgetSrc?.split("/")[0] ?? "treasury-testing.near";
-const treasuryDaoID =
- instance.split(".near")[0] ?? "testing-astradao" + "sputnik-dao.near";
+const widgetSrc = (
+ context?.widgetSrc ?? `${REPL_BOOTSTRAP_ACCOUNT}/widget/app`
+).split("/app")[0];
+
+const { instance, treasuryDaoID } = VM.require(`${widgetSrc}/config.data`);
+
+if (!instance || !treasuryDaoID) {
+ return <>>;
+}
+
const { Theme } = VM.require(`${instance}/widget/config.css`) || {
Theme: () => <>>,
};
diff --git a/instances/bootstrap.treasury-factory.near/widget/config/data.jsx b/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
index f056ef20..200bfc36 100644
--- a/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
@@ -1,6 +1,9 @@
-const sputnikAccount =
- context.widgetSrc?.split("/")[0].split(".near")[0] ??
- "testing-astradao" + "sputnik-dao.near";
+const widgetSrc = context.widgetSrc
+ ? context.widgetSrc
+ : "testing-app2.near/widget/app";
+const instance = widgetSrc.split("/")[0];
+const treasuryDaoID = instance.split(".near")[0] + ".sputnik-dao.near";
+
return {
navbarLinks: [
{
@@ -20,7 +23,8 @@ return {
href: "?page=settings",
},
],
- treasuryDaoID: sputnikAccount,
+ treasuryDaoID,
+ instance,
showProposalSelection: false,
showKYC: false,
showReferenceProposal: false,
diff --git a/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json b/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
index 46f4af04..164462e5 100644
--- a/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
+++ b/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
@@ -1,3 +1,4 @@
{
- "REPL_BASE_DEPLOYMENT_ACCOUNT": "test-widgets.treasury-factory.near"
+ "REPL_BASE_DEPLOYMENT_ACCOUNT": "test-widgets.treasury-factory.near",
+ "REPL_BOOTSTRAP_ACCOUNT": "test-bootstrap.treasury-factory.near"
}
diff --git a/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
index 95df9862..4a77ecf4 100644
--- a/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
@@ -49,6 +49,7 @@ return (
currentTab.title === title ? "active" : "",
].join(" ")}
key={title}
+ data-testid={title}
>
{title}
diff --git a/playwright-tests/tests/settings/create-member-request.spec.js b/playwright-tests/tests/settings/create-member-request.spec.js
index abe80642..8f706da1 100644
--- a/playwright-tests/tests/settings/create-member-request.spec.js
+++ b/playwright-tests/tests/settings/create-member-request.spec.js
@@ -37,7 +37,7 @@ async function updateLastProposalId(page) {
async function navigateToMembersPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Members").click();
+ await page.getByTestId("Members").click();
await expect(page.getByText("All Members")).toBeVisible({ timeout: 10_000 });
}
diff --git a/playwright-tests/tests/settings/create-threshold-request.spec.js b/playwright-tests/tests/settings/create-threshold-request.spec.js
index 8a00f76c..2d48319c 100644
--- a/playwright-tests/tests/settings/create-threshold-request.spec.js
+++ b/playwright-tests/tests/settings/create-threshold-request.spec.js
@@ -56,7 +56,7 @@ test.afterEach(async ({ page }, testInfo) => {
async function navigateToThresholdPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Voting Threshold").click();
+ await page.getByTestId("Voting Thresholds").click();
await expect(page.getByText("Permission Groups")).toBeVisible({
timeout: 10_000,
});
diff --git a/playwright-tests/tests/settings/theme.spec.js b/playwright-tests/tests/settings/theme.spec.js
index 622e9592..2cc39da2 100644
--- a/playwright-tests/tests/settings/theme.spec.js
+++ b/playwright-tests/tests/settings/theme.spec.js
@@ -52,7 +52,7 @@ async function navigateToThemePage({ page, instanceAccount }) {
await updateDaoPolicyMembers({ page });
await updateDaoConfig({ page });
await page.waitForTimeout(5_000);
- await page.getByText("Theme & Logo", { exact: true }).click();
+ await page.getByTestId("Theme & Logo", { exact: true }).click();
await expect(page.getByText("Theme & Logo").nth(1)).toBeVisible();
}
diff --git a/playwright-tests/tests/settings/voting-duration.spec.js b/playwright-tests/tests/settings/voting-duration.spec.js
index f84b09cb..b05590c0 100644
--- a/playwright-tests/tests/settings/voting-duration.spec.js
+++ b/playwright-tests/tests/settings/voting-duration.spec.js
@@ -17,7 +17,7 @@ test.afterEach(async ({ page }, testInfo) => {
async function navigateToVotingDurationPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Voting Duration").click();
+ await page.getByTestId("Voting Duration").click();
await expect(
page.getByText("Set the number of days a vote is active.")
).toBeVisible({
From 7ff651e8e015fd84e3f1e03b6f276032bb5682bd Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Sun, 19 Jan 2025 21:53:47 +0530
Subject: [PATCH 14/40] remove from app.jsx
---
.../widget/app.jsx | 22 +++++++------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/instances/bootstrap.treasury-factory.near/widget/app.jsx b/instances/bootstrap.treasury-factory.near/widget/app.jsx
index a25fe7fd..9aae4641 100644
--- a/instances/bootstrap.treasury-factory.near/widget/app.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/app.jsx
@@ -20,10 +20,6 @@ if (!instance || !treasuryDaoID) {
return <>>;
}
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -102,14 +98,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
From 6075350e4615799697111fd5a42499faf15d13e7 Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Tue, 21 Jan 2025 00:12:59 +0530
Subject: [PATCH 15/40] Fix UI issues with using existing daos (#223)
- since existing proposals doesn't have title/summary/notes since they
created the request using other UI/CLI, we should show the description
(as it is), as that usually explains what the request is
- in settings it doesn't show the voting threshold
- w/o theme color the buttons look blank white
- unnecessary hover on roles (since they don't have any description for
it)
- fix navbar in different theme
- hide spam tokens ( symbol >30 length), in create payment request
- Fix css recipient and voters hover of implicit accounts
---
.../widget/components/Approvers.jsx | 2 +-
.../widget/components/Navbar.jsx | 14 +-----
.../widget/components/ReceiverAccount.jsx | 46 +++++++++----------
.../widget/components/SettingsDropdown.jsx | 4 +-
.../widget/components/TokensDropdown.jsx | 4 +-
.../widget/components/templates/AppLayout.jsx | 7 ++-
.../widget/lib/common.jsx | 22 +++++----
.../widget/pages/dashboard/index.jsx | 6 +--
.../widget/pages/payments/Table.jsx | 43 ++++++++++-------
.../widget/pages/settings/MembersPage.jsx | 31 ++++++++-----
10 files changed, 96 insertions(+), 83 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
index aa2b9605..98f8fdd1 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
@@ -127,7 +127,7 @@ return (
)}
-
{name ?? acc}
+
{name ?? acc}
{voted ? (
-
+
{(navbarLinks ?? []).map((link, idx) => (
diff --git a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
index 14e41517..4b970d5b 100644
--- a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
@@ -47,18 +47,21 @@ useEffect(() => {
const HoverCard = () => {
return (
-
-
- {verificationStatus === "Verified" ? (
-
- ) : (
-
- )}
-
-
Fractal
-
{verificationStatus}
+
+
@{receiverAccount}
+ {verificationStatus && (
+
+ {verificationStatus === "Verified" ? (
+
+ ) : (
+
+ )}
+
+
Fractal
+
{verificationStatus}
+
-
+ )}
);
};
@@ -77,7 +80,6 @@ const ReceiverAccountComponent = (
style={{ textAlign: "left", width: "150px" }}
>
{name}
-
@{receiverAccount}
@@ -85,17 +87,13 @@ const ReceiverAccountComponent = (
return (
- {verificationStatus ? (
- ,
- children: ReceiverAccountComponent,
- instance: props.instance,
- }}
- />
- ) : (
- ReceiverAccountComponent
- )}
+ ,
+ children: ReceiverAccountComponent,
+ instance: props.instance,
+ }}
+ />
);
diff --git a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
index 9502d144..ac348624 100644
--- a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
@@ -36,7 +36,7 @@ const [settingsOptions, setSettingsOptions] = useState(
},
{
title: "Summary",
- show: true,
+ show: false,
},
{
title: "Recipient",
@@ -44,7 +44,7 @@ const [settingsOptions, setSettingsOptions] = useState(
},
{
title: "Requested Token",
- show: true,
+ show: false,
},
{
title: "Funding Ask",
diff --git a/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx b/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
index ba6ff9f3..28b544dc 100644
--- a/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
@@ -55,9 +55,11 @@ if (
const [options, setOptions] = useState([]);
const [nearStakedTokens, setNearStakedTokens] = useState(null);
+// remove near storage, spam tokens
const tokensWithBalance =
ftTokensResp?.body.filter(
- (i) => parseFloat(i.amount) > 0 && i.contract !== "Near"
+ (i) =>
+ parseFloat(i.amount) > 0 && i.contract !== "Near" && i.symbol.length < 30
) ?? [];
useEffect(() => {
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index f0ee0f16..9b04c267 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -127,7 +127,12 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
const primaryColor = metadata?.primaryColor
? metadata?.primaryColor
- : themeColor;
+ : themeColor
+ ? themeColor
+ : isDarkTheme
+ ? "#01BF7A"
+ : "#01BF7A";
+
// Convert HEX to HSL
const [h, s, l] = hexToHsl(primaryColor);
diff --git a/instances/widgets.treasury-factory.near/widget/lib/common.jsx b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
index 8ec3cc59..33fb9814 100644
--- a/instances/widgets.treasury-factory.near/widget/lib/common.jsx
+++ b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
@@ -63,22 +63,24 @@ function getApproversAndThreshold(treasuryDaoID, kind, isDeleteCheck) {
function getRoleWiseData(treasuryDaoID) {
return Near.asyncView(treasuryDaoID, "get_policy", {}).then((daoPolicy) => {
const data = [];
+ const defaultPolicy = daoPolicy.default_vote_policy;
(daoPolicy.roles ?? []).map((role) => {
- const isRatio = Array.isArray(role?.vote_policy?.["vote"]?.threshold);
+ // if there is no role.vote_policy, default is applied
+ const threshold = Object.keys(role?.vote_policy ?? {}).length
+ ? role?.vote_policy?.["vote"]?.threshold
+ : defaultPolicy.threshold;
+ const isRatio = Array.isArray(threshold);
+
data.push({
roleName: role.name,
members: role.kind?.Group ?? [],
isRatio,
- threshold: isRatio
- ? role?.vote_policy?.["vote"]?.threshold[0]
- : role?.vote_policy?.["vote"].threshold,
+ threshold: isRatio ? threshold[0] : threshold,
requiredVotes: isRatio
? Math.floor(
- (role?.vote_policy?.["vote"]?.threshold[0] /
- role?.vote_policy?.["vote"]?.threshold[1]) *
- role.kind?.Group.length
+ (threshold[0] / threshold[1]) * role.kind?.Group.length
) + 1
- : role?.vote_policy?.["vote"]?.threshold ?? 1,
+ : threshold ?? 1,
});
});
return data;
@@ -324,8 +326,8 @@ const gatewayOrigin = data?.body?.headers?.Origin ?? "";
const isNearSocial =
gatewayOrigin.includes("near.social") ||
gatewayOrigin.includes("127.0.0.1:8080") ||
- gatewayOrigin.includes("treasury-devdao.testnet.page") ||
- gatewayOrigin.includes("treasury-devdao.near.page");
+ gatewayOrigin.includes("testnet.page") ||
+ gatewayOrigin.includes("near.page");
function getMembersAndPermissions(treasuryDaoID) {
return Near.asyncView(treasuryDaoID, "get_policy", {}).then((daoPolicy) => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
index 9853e00e..c12d8256 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
@@ -240,7 +240,7 @@ return (
"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.dashboard.Portfolio"
}
props={{
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
nearStakedTokens,
nearUnStakedTokens,
nearPrice,
@@ -300,7 +300,7 @@ return (
totalBalance: formatCurrency(
Big(nearBalances?.totalParsed ?? "0").mul(nearPrice ?? 1)
),
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
instance,
accountId: treasuryDaoID,
}}
@@ -316,7 +316,7 @@ return (
totalBalance: formatCurrency(
Big(lockupNearBalances?.totalParsed ?? "0").mul(nearPrice ?? 1)
),
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
accountId: lockupContract,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 75f16ed4..1de6a783 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -148,7 +148,8 @@ const requiredVotes = transferApproversGroup?.requiredVotes;
const hideApproversCol = isPendingRequests && requiredVotes === 1;
const userFTTokens = fetch(
- `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`
+ `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`,
+ { headers: { Authorization: "Bearer ${REPL_NEARBLOCKS_KEY}" } }
);
const nearBalances = getNearBalances(treasuryDaoID);
@@ -234,6 +235,7 @@ const ProposalsComponent = () => {
const notes = decodeProposalDescription("notes", item.description);
const title = decodeProposalDescription("title", item.description);
const summary = decodeProposalDescription("summary", item.description);
+ const description = !title && !summary && item.description;
const id = decodeProposalDescription("proposalId", item.description);
const proposalId = id ? parseInt(id, 10) : null;
const args = item.kind.Transfer;
@@ -293,21 +295,25 @@ const ProposalsComponent = () => {
)}
- ,
- children: (
-
- {title}
-
- ),
- instance,
- }}
- />
+ {description ? (
+ description
+ ) : (
+ ,
+ children: (
+
+ {title}
+
+ ),
+ instance,
+ }}
+ />
+ )}
{
props={{
popup: ,
children: (
-
+
{summary ? summary : "-"}
),
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
index 0d2761f3..aeddca70 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
@@ -182,18 +182,25 @@ const Members = () => {
- {(group.roles ?? []).map((i) => (
- {i}
- ),
- instance,
- }}
- />
- ))}
+ {(group.roles ?? []).map((i) => {
+ const description = getPermissionsText(i);
+ if (!description) {
+ return {i} ;
+ } else {
+ return (
+ {i}
+ ),
+ instance,
+ }}
+ />
+ );
+ }
+ })}
{hasCreatePermission && (
From 5c53903bc4d5a2f46ff9349f1c8366187603bcb3 Mon Sep 17 00:00:00 2001
From: Andrew
Date: Mon, 20 Jan 2025 21:23:11 +0200
Subject: [PATCH 16/40] Factory creation fixes (#221)
- rebuilt "add treasury account" step
- removed sputnik dao configuration step
- resolved summary modal appearence issue
- table fixes
---------
Co-authored-by: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
---
.../create-treasury/AddMembersStep.jsx | 8 +--
.../create-treasury/CreateAppAccountStep.jsx | 38 +++++++++++++
.../CreateSputnikAccountStep.jsx | 6 +--
.../create-treasury/SummaryStep.jsx | 54 ++++++-------------
.../widget/pages/treasury/Create.jsx | 4 --
.../widget/components/TokenAmount.jsx | 4 +-
.../widget/components/TokenIcon.jsx | 6 +--
.../widget/components/templates/AppLayout.jsx | 6 ++-
.../widget/pages/dashboard/Portfolio.jsx | 7 ++-
.../widget/pages/payments/Table.jsx | 4 ++
.../widget/pages/stake-delegation/Table.jsx | 4 ++
.../tests/page.treasury-factory.near.spec.js | 7 ---
12 files changed, 85 insertions(+), 63 deletions(-)
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
index b2629b7e..98858943 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
@@ -159,13 +159,15 @@ return (
Back
0 ? "" : "disabled"
+ }`}
+ href={`/${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/app?page=create-treasury&step=3`}
>
Next
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
index 20d7848d..fd9fa404 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
@@ -2,6 +2,30 @@ const { formFields, setFormFields } = props;
const [alertMsg, setAlertMsg] = useState(null);
+const AccountDisplay = ({ label, prefix, tooltipInfo, noBorder }) => {
+ return (
+
+
+
+
+ {label}
+ {tooltipInfo}}
+ >
+
+
+
+
+
{formFields.accountName}
+
{prefix}
+
+
+
+
+ );
+};
+
return (
<>
@@ -28,6 +52,20 @@ return (
}}
/>
+
+
{(alertMsg[".near"] || alertMsg[".sputnik-dao.near"]) && (
Add Sputnik DAO Display Name
-
- Enter the display name for your treasury's Sputnik DAO account. The
- funds for your treasury will be held in{" "}
- {formFields.accountName}.sputnik-dao.near .
-
+
Enter the display name for your treasury's Sputnik DAO account.
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
index 88a25562..09786dbb 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
@@ -84,10 +84,17 @@ const PERMISSIONS = {
const storageAccountName = useMemo(() => Storage.privateGet("accountName"));
-useEffect(() => {
- if (storageAccountName) {
- setShowCongratsModal(true);
- }
+const checkAccountCreation = async () => {
+ console.log(storageAccountName);
+ const web4 = Near.view(`${storageAccountName}.near`, "web4_get", {
+ request: { path: "/" },
+ });
+
+ if (web4) setShowCongratsModal(true);
+};
+
+useEffect(async () => {
+ if (storageAccountName) checkAccountCreation();
}, [storageAccountName]);
function filterMemberByPermission(permission) {
@@ -99,8 +106,8 @@ function filterMemberByPermission(permission) {
function createDao() {
const createDaoConfig = {
config: {
- name: `${formFields.sputnikAccountName}`,
- purpose: `creating ${formFields.sputnikAccountName} treasury`,
+ name: `${formFields.accountName}`,
+ purpose: `creating ${formFields.accountName} treasury`,
metadata: "",
},
policy: {
@@ -167,9 +174,7 @@ function createDao() {
},
]);
- setTimeout(() => {
- Storage.privateSet("accountName", formFields.accountName);
- }, 1000);
+ Storage.privateSet("accountName", formFields.accountName);
}
const CongratsItem = ({ title, link }) => (
@@ -277,31 +282,13 @@ return (
-
-
-
-
-
Sputnik Account Display Name
-
- {formFields.sputnikAccountName
- ? `${formFields.sputnikAccountName}`
- : "-"}
-
-
-
-
-
-
-
Members and permissions
@@ -339,11 +326,7 @@ return (
Confirm and Create
@@ -377,10 +360,7 @@ return (
),
- onClose: () => {
- setShowCongratsModal(false);
- Storage.privateSet("accountName", null);
- },
+ onClose: () => setShowCongratsModal(false),
}}
/>
)}
diff --git a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
index c47d2c2a..6290032a 100644
--- a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
+++ b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
@@ -20,10 +20,6 @@ const STEPS = [
src={`${widgetBasePath}.CreateAppAccountStep`}
props={{ formFields, setFormFields }}
/>,
-
,
{isNEAR ? (
-
+
) : (
-
+
)}
{/* TODO later */}
diff --git a/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx b/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
index aa219e2d..e581520c 100644
--- a/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
@@ -16,11 +16,11 @@ if (!isNEAR) {
}
return (
-
+
{isNEAR ? (
-
+
) : (
-
+
)}
{ftMetadata.symbol}
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index 9b04c267..ac9b6c2e 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -294,7 +294,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
.custom-truncate {
display: -webkit-box;
- -webkit-line-clamp: 3;
+ -webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
@@ -445,6 +445,10 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
border-color: var(--border-color) !important;
color: var(--text-color) !important;
margin-bottom: 20px;
+
+ .amount {
+ font-size: 14px;
+ }
}
.table td:first-child {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
index 70080c2b..d1fe2262 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
@@ -184,7 +184,12 @@ const PortfolioCard = ({
{Icon ?
:
}
-
{symbol}
+
+ {symbol}
+
${Big(price ?? "0").toFixed(2)}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 1de6a783..1ee7481c 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -66,6 +66,10 @@ const Container = styled.div`
background: inherit;
}
+ thead td {
+ text-wrap: nowrap;
+ }
+
table {
overflow-x: auto;
}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
index 27c1a10a..4f8051a2 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
@@ -92,6 +92,10 @@ const Container = styled.div`
table {
overflow-x: auto;
+
+ thead td {
+ text-wrap: nowrap;
+ }
}
.text-warning {
diff --git a/playwright-tests/tests/page.treasury-factory.near.spec.js b/playwright-tests/tests/page.treasury-factory.near.spec.js
index 9acc009a..dc03da48 100644
--- a/playwright-tests/tests/page.treasury-factory.near.spec.js
+++ b/playwright-tests/tests/page.treasury-factory.near.spec.js
@@ -90,13 +90,6 @@ test.describe("admin connected", function () {
await page.locator(".account-field input").fill(accName);
await page.locator("a", { hasText: "Next" }).click();
- // create sputnik dao account step
- await expect(
- await page.locator("h3", { hasText: "Create Sputnik DAO Account" })
- ).toBeVisible();
- await page.locator(".account-field input").fill(accName);
- await page.locator("a", { hasText: "Next" }).click();
-
// add members step
await expect(
await page.locator("h3", { hasText: "Add Members" })
From 38a511f567d3bd8c5e609bbac233467036836b0a Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Sun, 19 Jan 2025 21:43:13 +0530
Subject: [PATCH 17/40] Fix the bootstrap setup (#222)
Fix the `instance` and `treasuryDaoID` assignment.
---
.../aliases.mainnet.json | 3 ++-
.../bootstrap.treasury-factory.near/widget/app.jsx | 13 ++++++++++---
.../widget/config/data.jsx | 12 ++++++++----
.../aliases.mainnet.json | 3 ++-
.../widget/components/SidebarAndMainLayout.jsx | 1 +
.../tests/settings/create-member-request.spec.js | 2 +-
.../tests/settings/create-threshold-request.spec.js | 2 +-
playwright-tests/tests/settings/theme.spec.js | 2 +-
.../tests/settings/voting-duration.spec.js | 2 +-
9 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/instances/bootstrap.treasury-factory.near/aliases.mainnet.json b/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
index b1b322aa..62a0d392 100644
--- a/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
+++ b/instances/bootstrap.treasury-factory.near/aliases.mainnet.json
@@ -1,3 +1,4 @@
{
- "REPL_BASE_DEPLOYMENT_ACCOUNT": "widgets.treasury-factory.near"
+ "REPL_BASE_DEPLOYMENT_ACCOUNT": "widgets.treasury-factory.near",
+ "REPL_BOOTSTRAP_ACCOUNT": "bootstrap.treasury-factory.near"
}
diff --git a/instances/bootstrap.treasury-factory.near/widget/app.jsx b/instances/bootstrap.treasury-factory.near/widget/app.jsx
index 8afd242e..a25fe7fd 100644
--- a/instances/bootstrap.treasury-factory.near/widget/app.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/app.jsx
@@ -10,9 +10,16 @@ const { AppLayout } = VM.require(
"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.templates.AppLayout"
) || { AppLayout: () => <>> };
-const instance = context.widgetSrc?.split("/")[0] ?? "treasury-testing.near";
-const treasuryDaoID =
- instance.split(".near")[0] ?? "testing-astradao" + "sputnik-dao.near";
+const widgetSrc = (
+ context?.widgetSrc ?? `${REPL_BOOTSTRAP_ACCOUNT}/widget/app`
+).split("/app")[0];
+
+const { instance, treasuryDaoID } = VM.require(`${widgetSrc}/config.data`);
+
+if (!instance || !treasuryDaoID) {
+ return <>>;
+}
+
const { Theme } = VM.require(`${instance}/widget/config.css`) || {
Theme: () => <>>,
};
diff --git a/instances/bootstrap.treasury-factory.near/widget/config/data.jsx b/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
index f056ef20..200bfc36 100644
--- a/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/config/data.jsx
@@ -1,6 +1,9 @@
-const sputnikAccount =
- context.widgetSrc?.split("/")[0].split(".near")[0] ??
- "testing-astradao" + "sputnik-dao.near";
+const widgetSrc = context.widgetSrc
+ ? context.widgetSrc
+ : "testing-app2.near/widget/app";
+const instance = widgetSrc.split("/")[0];
+const treasuryDaoID = instance.split(".near")[0] + ".sputnik-dao.near";
+
return {
navbarLinks: [
{
@@ -20,7 +23,8 @@ return {
href: "?page=settings",
},
],
- treasuryDaoID: sputnikAccount,
+ treasuryDaoID,
+ instance,
showProposalSelection: false,
showKYC: false,
showReferenceProposal: false,
diff --git a/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json b/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
index 46f4af04..164462e5 100644
--- a/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
+++ b/instances/test-bootstrap.treasury-factory.near/aliases.mainnet.json
@@ -1,3 +1,4 @@
{
- "REPL_BASE_DEPLOYMENT_ACCOUNT": "test-widgets.treasury-factory.near"
+ "REPL_BASE_DEPLOYMENT_ACCOUNT": "test-widgets.treasury-factory.near",
+ "REPL_BOOTSTRAP_ACCOUNT": "test-bootstrap.treasury-factory.near"
}
diff --git a/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
index 95df9862..4a77ecf4 100644
--- a/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/SidebarAndMainLayout.jsx
@@ -49,6 +49,7 @@ return (
currentTab.title === title ? "active" : "",
].join(" ")}
key={title}
+ data-testid={title}
>
{title}
diff --git a/playwright-tests/tests/settings/create-member-request.spec.js b/playwright-tests/tests/settings/create-member-request.spec.js
index abe80642..8f706da1 100644
--- a/playwright-tests/tests/settings/create-member-request.spec.js
+++ b/playwright-tests/tests/settings/create-member-request.spec.js
@@ -37,7 +37,7 @@ async function updateLastProposalId(page) {
async function navigateToMembersPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Members").click();
+ await page.getByTestId("Members").click();
await expect(page.getByText("All Members")).toBeVisible({ timeout: 10_000 });
}
diff --git a/playwright-tests/tests/settings/create-threshold-request.spec.js b/playwright-tests/tests/settings/create-threshold-request.spec.js
index 8a00f76c..2d48319c 100644
--- a/playwright-tests/tests/settings/create-threshold-request.spec.js
+++ b/playwright-tests/tests/settings/create-threshold-request.spec.js
@@ -56,7 +56,7 @@ test.afterEach(async ({ page }, testInfo) => {
async function navigateToThresholdPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Voting Threshold").click();
+ await page.getByTestId("Voting Thresholds").click();
await expect(page.getByText("Permission Groups")).toBeVisible({
timeout: 10_000,
});
diff --git a/playwright-tests/tests/settings/theme.spec.js b/playwright-tests/tests/settings/theme.spec.js
index 622e9592..2cc39da2 100644
--- a/playwright-tests/tests/settings/theme.spec.js
+++ b/playwright-tests/tests/settings/theme.spec.js
@@ -52,7 +52,7 @@ async function navigateToThemePage({ page, instanceAccount }) {
await updateDaoPolicyMembers({ page });
await updateDaoConfig({ page });
await page.waitForTimeout(5_000);
- await page.getByText("Theme & Logo", { exact: true }).click();
+ await page.getByTestId("Theme & Logo", { exact: true }).click();
await expect(page.getByText("Theme & Logo").nth(1)).toBeVisible();
}
diff --git a/playwright-tests/tests/settings/voting-duration.spec.js b/playwright-tests/tests/settings/voting-duration.spec.js
index f84b09cb..b05590c0 100644
--- a/playwright-tests/tests/settings/voting-duration.spec.js
+++ b/playwright-tests/tests/settings/voting-duration.spec.js
@@ -17,7 +17,7 @@ test.afterEach(async ({ page }, testInfo) => {
async function navigateToVotingDurationPage({ page, instanceAccount }) {
await page.goto(`/${instanceAccount}/widget/app?page=settings`);
await page.waitForTimeout(5_000);
- await page.getByText("Voting Duration").click();
+ await page.getByTestId("Voting Duration").click();
await expect(
page.getByText("Set the number of days a vote is active.")
).toBeVisible({
From 2ca1e5bdc5617602a45391db8c5e55cfab7cbf49 Mon Sep 17 00:00:00 2001
From: Megha-Dev-19 <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Sun, 19 Jan 2025 21:53:47 +0530
Subject: [PATCH 18/40] remove
from app.jsx
---
.../widget/app.jsx | 22 +++++++------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/instances/bootstrap.treasury-factory.near/widget/app.jsx b/instances/bootstrap.treasury-factory.near/widget/app.jsx
index a25fe7fd..9aae4641 100644
--- a/instances/bootstrap.treasury-factory.near/widget/app.jsx
+++ b/instances/bootstrap.treasury-factory.near/widget/app.jsx
@@ -20,10 +20,6 @@ if (!instance || !treasuryDaoID) {
return <>>;
}
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -102,14 +98,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
From 4878dac242c63bb5410e21bd00728886c8e0d123 Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Tue, 21 Jan 2025 00:12:59 +0530
Subject: [PATCH 19/40] Fix UI issues with using existing daos (#223)
- since existing proposals doesn't have title/summary/notes since they
created the request using other UI/CLI, we should show the description
(as it is), as that usually explains what the request is
- in settings it doesn't show the voting threshold
- w/o theme color the buttons look blank white
- unnecessary hover on roles (since they don't have any description for
it)
- fix navbar in different theme
- hide spam tokens ( symbol >30 length), in create payment request
- Fix css recipient and voters hover of implicit accounts
---
.../widget/components/Approvers.jsx | 2 +-
.../widget/components/Navbar.jsx | 14 +-----
.../widget/components/ReceiverAccount.jsx | 46 +++++++++----------
.../widget/components/SettingsDropdown.jsx | 4 +-
.../widget/components/TokensDropdown.jsx | 4 +-
.../widget/components/templates/AppLayout.jsx | 7 ++-
.../widget/lib/common.jsx | 22 +++++----
.../widget/pages/dashboard/index.jsx | 6 +--
.../widget/pages/payments/Table.jsx | 43 ++++++++++-------
.../widget/pages/settings/MembersPage.jsx | 31 ++++++++-----
10 files changed, 96 insertions(+), 83 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
index aa2b9605..98f8fdd1 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
@@ -127,7 +127,7 @@ return (
)}
-
{name ?? acc}
+
{name ?? acc}
{voted ? (
-
+
{(navbarLinks ?? []).map((link, idx) => (
diff --git a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
index 14e41517..4b970d5b 100644
--- a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
@@ -47,18 +47,21 @@ useEffect(() => {
const HoverCard = () => {
return (
-
-
- {verificationStatus === "Verified" ? (
-
- ) : (
-
- )}
-
-
Fractal
-
{verificationStatus}
+
+
@{receiverAccount}
+ {verificationStatus && (
+
+ {verificationStatus === "Verified" ? (
+
+ ) : (
+
+ )}
+
+
Fractal
+
{verificationStatus}
+
-
+ )}
);
};
@@ -77,7 +80,6 @@ const ReceiverAccountComponent = (
style={{ textAlign: "left", width: "150px" }}
>
{name}
-
@{receiverAccount}
@@ -85,17 +87,13 @@ const ReceiverAccountComponent = (
return (
- {verificationStatus ? (
- ,
- children: ReceiverAccountComponent,
- instance: props.instance,
- }}
- />
- ) : (
- ReceiverAccountComponent
- )}
+ ,
+ children: ReceiverAccountComponent,
+ instance: props.instance,
+ }}
+ />
);
diff --git a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
index 9502d144..ac348624 100644
--- a/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/SettingsDropdown.jsx
@@ -36,7 +36,7 @@ const [settingsOptions, setSettingsOptions] = useState(
},
{
title: "Summary",
- show: true,
+ show: false,
},
{
title: "Recipient",
@@ -44,7 +44,7 @@ const [settingsOptions, setSettingsOptions] = useState(
},
{
title: "Requested Token",
- show: true,
+ show: false,
},
{
title: "Funding Ask",
diff --git a/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx b/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
index ba6ff9f3..28b544dc 100644
--- a/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/TokensDropdown.jsx
@@ -55,9 +55,11 @@ if (
const [options, setOptions] = useState([]);
const [nearStakedTokens, setNearStakedTokens] = useState(null);
+// remove near storage, spam tokens
const tokensWithBalance =
ftTokensResp?.body.filter(
- (i) => parseFloat(i.amount) > 0 && i.contract !== "Near"
+ (i) =>
+ parseFloat(i.amount) > 0 && i.contract !== "Near" && i.symbol.length < 30
) ?? [];
useEffect(() => {
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index f0ee0f16..9b04c267 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -127,7 +127,12 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
const primaryColor = metadata?.primaryColor
? metadata?.primaryColor
- : themeColor;
+ : themeColor
+ ? themeColor
+ : isDarkTheme
+ ? "#01BF7A"
+ : "#01BF7A";
+
// Convert HEX to HSL
const [h, s, l] = hexToHsl(primaryColor);
diff --git a/instances/widgets.treasury-factory.near/widget/lib/common.jsx b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
index 8ec3cc59..33fb9814 100644
--- a/instances/widgets.treasury-factory.near/widget/lib/common.jsx
+++ b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
@@ -63,22 +63,24 @@ function getApproversAndThreshold(treasuryDaoID, kind, isDeleteCheck) {
function getRoleWiseData(treasuryDaoID) {
return Near.asyncView(treasuryDaoID, "get_policy", {}).then((daoPolicy) => {
const data = [];
+ const defaultPolicy = daoPolicy.default_vote_policy;
(daoPolicy.roles ?? []).map((role) => {
- const isRatio = Array.isArray(role?.vote_policy?.["vote"]?.threshold);
+ // if there is no role.vote_policy, default is applied
+ const threshold = Object.keys(role?.vote_policy ?? {}).length
+ ? role?.vote_policy?.["vote"]?.threshold
+ : defaultPolicy.threshold;
+ const isRatio = Array.isArray(threshold);
+
data.push({
roleName: role.name,
members: role.kind?.Group ?? [],
isRatio,
- threshold: isRatio
- ? role?.vote_policy?.["vote"]?.threshold[0]
- : role?.vote_policy?.["vote"].threshold,
+ threshold: isRatio ? threshold[0] : threshold,
requiredVotes: isRatio
? Math.floor(
- (role?.vote_policy?.["vote"]?.threshold[0] /
- role?.vote_policy?.["vote"]?.threshold[1]) *
- role.kind?.Group.length
+ (threshold[0] / threshold[1]) * role.kind?.Group.length
) + 1
- : role?.vote_policy?.["vote"]?.threshold ?? 1,
+ : threshold ?? 1,
});
});
return data;
@@ -324,8 +326,8 @@ const gatewayOrigin = data?.body?.headers?.Origin ?? "";
const isNearSocial =
gatewayOrigin.includes("near.social") ||
gatewayOrigin.includes("127.0.0.1:8080") ||
- gatewayOrigin.includes("treasury-devdao.testnet.page") ||
- gatewayOrigin.includes("treasury-devdao.near.page");
+ gatewayOrigin.includes("testnet.page") ||
+ gatewayOrigin.includes("near.page");
function getMembersAndPermissions(treasuryDaoID) {
return Near.asyncView(treasuryDaoID, "get_policy", {}).then((daoPolicy) => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
index 9853e00e..c12d8256 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
@@ -240,7 +240,7 @@ return (
"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.dashboard.Portfolio"
}
props={{
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
nearStakedTokens,
nearUnStakedTokens,
nearPrice,
@@ -300,7 +300,7 @@ return (
totalBalance: formatCurrency(
Big(nearBalances?.totalParsed ?? "0").mul(nearPrice ?? 1)
),
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
instance,
accountId: treasuryDaoID,
}}
@@ -316,7 +316,7 @@ return (
totalBalance: formatCurrency(
Big(lockupNearBalances?.totalParsed ?? "0").mul(nearPrice ?? 1)
),
- ftTokens: userFTTokens.fts,
+ ftTokens: userFTTokens.fts ? userFTTokens.fts : null,
accountId: lockupContract,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 75f16ed4..1de6a783 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -148,7 +148,8 @@ const requiredVotes = transferApproversGroup?.requiredVotes;
const hideApproversCol = isPendingRequests && requiredVotes === 1;
const userFTTokens = fetch(
- `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`
+ `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`,
+ { headers: { Authorization: "Bearer ${REPL_NEARBLOCKS_KEY}" } }
);
const nearBalances = getNearBalances(treasuryDaoID);
@@ -234,6 +235,7 @@ const ProposalsComponent = () => {
const notes = decodeProposalDescription("notes", item.description);
const title = decodeProposalDescription("title", item.description);
const summary = decodeProposalDescription("summary", item.description);
+ const description = !title && !summary && item.description;
const id = decodeProposalDescription("proposalId", item.description);
const proposalId = id ? parseInt(id, 10) : null;
const args = item.kind.Transfer;
@@ -293,21 +295,25 @@ const ProposalsComponent = () => {
)}
- ,
- children: (
-
- {title}
-
- ),
- instance,
- }}
- />
+ {description ? (
+ description
+ ) : (
+ ,
+ children: (
+
+ {title}
+
+ ),
+ instance,
+ }}
+ />
+ )}
{
props={{
popup: ,
children: (
-
+
{summary ? summary : "-"}
),
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
index 0d2761f3..aeddca70 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersPage.jsx
@@ -182,18 +182,25 @@ const Members = () => {
- {(group.roles ?? []).map((i) => (
- {i}
- ),
- instance,
- }}
- />
- ))}
+ {(group.roles ?? []).map((i) => {
+ const description = getPermissionsText(i);
+ if (!description) {
+ return {i} ;
+ } else {
+ return (
+ {i}
+ ),
+ instance,
+ }}
+ />
+ );
+ }
+ })}
{hasCreatePermission && (
From 3017c1c82735a139e83fe2265bda21f16afff589 Mon Sep 17 00:00:00 2001
From: Andrew
Date: Mon, 20 Jan 2025 21:23:11 +0200
Subject: [PATCH 20/40] Factory creation fixes (#221)
- rebuilt "add treasury account" step
- removed sputnik dao configuration step
- resolved summary modal appearence issue
- table fixes
---------
Co-authored-by: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
---
.../create-treasury/AddMembersStep.jsx | 8 +--
.../create-treasury/CreateAppAccountStep.jsx | 38 +++++++++++++
.../CreateSputnikAccountStep.jsx | 6 +--
.../create-treasury/SummaryStep.jsx | 54 ++++++-------------
.../widget/pages/treasury/Create.jsx | 4 --
.../widget/components/TokenAmount.jsx | 4 +-
.../widget/components/TokenIcon.jsx | 6 +--
.../widget/components/templates/AppLayout.jsx | 6 ++-
.../widget/pages/dashboard/Portfolio.jsx | 7 ++-
.../widget/pages/payments/Table.jsx | 4 ++
.../widget/pages/stake-delegation/Table.jsx | 4 ++
.../tests/page.treasury-factory.near.spec.js | 7 ---
12 files changed, 85 insertions(+), 63 deletions(-)
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
index b2629b7e..98858943 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/AddMembersStep.jsx
@@ -159,13 +159,15 @@ return (
Back
0 ? "" : "disabled"
+ }`}
+ href={`/${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/app?page=create-treasury&step=3`}
>
Next
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
index 20d7848d..fd9fa404 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/CreateAppAccountStep.jsx
@@ -2,6 +2,30 @@ const { formFields, setFormFields } = props;
const [alertMsg, setAlertMsg] = useState(null);
+const AccountDisplay = ({ label, prefix, tooltipInfo, noBorder }) => {
+ return (
+
+
+
+
+ {label}
+ {tooltipInfo}}
+ >
+
+
+
+
+
{formFields.accountName}
+
{prefix}
+
+
+
+
+ );
+};
+
return (
<>
@@ -28,6 +52,20 @@ return (
}}
/>
+
+
{(alertMsg[".near"] || alertMsg[".sputnik-dao.near"]) && (
Add Sputnik DAO Display Name
-
- Enter the display name for your treasury's Sputnik DAO account. The
- funds for your treasury will be held in{" "}
- {formFields.accountName}.sputnik-dao.near .
-
+
Enter the display name for your treasury's Sputnik DAO account.
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
index 88a25562..09786dbb 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
@@ -84,10 +84,17 @@ const PERMISSIONS = {
const storageAccountName = useMemo(() => Storage.privateGet("accountName"));
-useEffect(() => {
- if (storageAccountName) {
- setShowCongratsModal(true);
- }
+const checkAccountCreation = async () => {
+ console.log(storageAccountName);
+ const web4 = Near.view(`${storageAccountName}.near`, "web4_get", {
+ request: { path: "/" },
+ });
+
+ if (web4) setShowCongratsModal(true);
+};
+
+useEffect(async () => {
+ if (storageAccountName) checkAccountCreation();
}, [storageAccountName]);
function filterMemberByPermission(permission) {
@@ -99,8 +106,8 @@ function filterMemberByPermission(permission) {
function createDao() {
const createDaoConfig = {
config: {
- name: `${formFields.sputnikAccountName}`,
- purpose: `creating ${formFields.sputnikAccountName} treasury`,
+ name: `${formFields.accountName}`,
+ purpose: `creating ${formFields.accountName} treasury`,
metadata: "",
},
policy: {
@@ -167,9 +174,7 @@ function createDao() {
},
]);
- setTimeout(() => {
- Storage.privateSet("accountName", formFields.accountName);
- }, 1000);
+ Storage.privateSet("accountName", formFields.accountName);
}
const CongratsItem = ({ title, link }) => (
@@ -277,31 +282,13 @@ return (
-
-
-
-
-
Sputnik Account Display Name
-
- {formFields.sputnikAccountName
- ? `${formFields.sputnikAccountName}`
- : "-"}
-
-
-
-
-
-
-
Members and permissions
@@ -339,11 +326,7 @@ return (
Confirm and Create
@@ -377,10 +360,7 @@ return (
),
- onClose: () => {
- setShowCongratsModal(false);
- Storage.privateSet("accountName", null);
- },
+ onClose: () => setShowCongratsModal(false),
}}
/>
)}
diff --git a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
index c47d2c2a..6290032a 100644
--- a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
+++ b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
@@ -20,10 +20,6 @@ const STEPS = [
src={`${widgetBasePath}.CreateAppAccountStep`}
props={{ formFields, setFormFields }}
/>,
-
,
{isNEAR ? (
-
+
) : (
-
+
)}
{/* TODO later */}
diff --git a/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx b/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
index aa219e2d..e581520c 100644
--- a/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/TokenIcon.jsx
@@ -16,11 +16,11 @@ if (!isNEAR) {
}
return (
-
+
{isNEAR ? (
-
+
) : (
-
+
)}
{ftMetadata.symbol}
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index 9b04c267..ac9b6c2e 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -294,7 +294,7 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
.custom-truncate {
display: -webkit-box;
- -webkit-line-clamp: 3;
+ -webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
@@ -445,6 +445,10 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
border-color: var(--border-color) !important;
color: var(--text-color) !important;
margin-bottom: 20px;
+
+ .amount {
+ font-size: 14px;
+ }
}
.table td:first-child {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
index 70080c2b..d1fe2262 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
@@ -184,7 +184,12 @@ const PortfolioCard = ({
{Icon ?
:
}
-
{symbol}
+
+ {symbol}
+
${Big(price ?? "0").toFixed(2)}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 1de6a783..1ee7481c 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -66,6 +66,10 @@ const Container = styled.div`
background: inherit;
}
+ thead td {
+ text-wrap: nowrap;
+ }
+
table {
overflow-x: auto;
}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
index 27c1a10a..4f8051a2 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
@@ -92,6 +92,10 @@ const Container = styled.div`
table {
overflow-x: auto;
+
+ thead td {
+ text-wrap: nowrap;
+ }
}
.text-warning {
diff --git a/playwright-tests/tests/page.treasury-factory.near.spec.js b/playwright-tests/tests/page.treasury-factory.near.spec.js
index 9acc009a..dc03da48 100644
--- a/playwright-tests/tests/page.treasury-factory.near.spec.js
+++ b/playwright-tests/tests/page.treasury-factory.near.spec.js
@@ -90,13 +90,6 @@ test.describe("admin connected", function () {
await page.locator(".account-field input").fill(accName);
await page.locator("a", { hasText: "Next" }).click();
- // create sputnik dao account step
- await expect(
- await page.locator("h3", { hasText: "Create Sputnik DAO Account" })
- ).toBeVisible();
- await page.locator(".account-field input").fill(accName);
- await page.locator("a", { hasText: "Next" }).click();
-
// add members step
await expect(
await page.locator("h3", { hasText: "Add Members" })
From 6f759d03fa5fc7f539d483434d54d916899888f9 Mon Sep 17 00:00:00 2001
From: Andrew
Date: Wed, 22 Jan 2025 13:57:08 +0200
Subject: [PATCH 21/40] Change cancel creation link url (#232)
---
.../treasury-factory.near/widget/pages/treasury/Create.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
index 6290032a..9fc230a1 100644
--- a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
+++ b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
@@ -72,7 +72,7 @@ const Wrapper = ({ title, children }) => (
Cancel creation
From a6dfc24f9ab72c4a34edafd9bf43b9c241a34ebd Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Wed, 22 Jan 2025 20:08:56 +0530
Subject: [PATCH 22/40] Fix loading theme for aurora treasury (#230)
---
.../widget/pages/settings/Theme.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
index f551b297..29b480a1 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
@@ -356,7 +356,7 @@ return (
/>
Theme & Logo
- {!metadata ? (
+ {!config ? (
Date: Wed, 22 Jan 2025 20:09:21 +0530
Subject: [PATCH 23/40] Hover fixes (#231)
https://www.notion.so/17a490b283038084bbd6d98a90cfeb68?v=466c3a17456f49cb9757dd88cace649d&p=182490b2830380b0be68fb33b4d72abe&pm=s
---
.../widget/components/Approvers.jsx | 83 +-
.../widget/components/Icons.jsx | 120 +++
.../widget/components/OverlayTrigger.jsx | 15 +-
.../widget/components/Profile.jsx | 155 ++++
.../widget/components/ReceiverAccount.jsx | 99 ---
.../widget/components/templates/AppLayout.jsx | 718 +++++++++---------
.../widget/pages/payments/Table.jsx | 24 +-
.../widget/pages/proposals-feed/Table.jsx | 20 +-
.../widget/pages/settings/feed/Table.jsx | 20 +-
.../widget/pages/stake-delegation/Table.jsx | 20 +-
10 files changed, 707 insertions(+), 567 deletions(-)
create mode 100644 instances/widgets.treasury-factory.near/widget/components/Profile.jsx
delete mode 100644 instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
diff --git a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
index 98f8fdd1..435f1517 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
@@ -1,7 +1,8 @@
-const { isNearSocial } = VM.require(
- "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common"
+const { Approval, Reject } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons"
) || {
- isNearSocial: false,
+ Approval: () => <>>,
+ Reject: () => <>>,
};
const votes = props.votes ?? {};
@@ -9,11 +10,6 @@ const accounts = Object.keys(votes);
const approversGroup = props.approversGroup ?? [];
const maxShow = 1;
const showHover = accounts?.length > maxShow;
-const approve =
- "https://ipfs.near.social/ipfs/bafkreib52fq4kw7gyfsupz4mrtrexbusc2lplxnopqswa5awtnlqmenena";
-const reject =
- "https://ipfs.near.social/ipfs/bafkreihrwi2nzl7d2dyij3tstr6tdr7fnioq7vu37en3dxt4faihxreabm";
-
const maxIndex = 100;
const Container = styled.div`
@@ -28,35 +24,37 @@ function getImage(acc) {
return `https://i.near.social/magic/large/https://near.social/magic/img/account/${acc}`;
}
+const ApprovalImage = styled.div`
+ position: relative;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ height: 40px;
+ width: 40px;
+ .status {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ }
+`;
+
const ApproversComponent = (
{accounts.slice(0, maxShow).map((acc, index) => {
const imageSrc = getImage(acc);
- const voteImg = votes[acc] === "Approve" ? approve : reject;
return (
-
0 ? "-10px" : 0,
zIndex: maxIndex - index,
- position: "relative",
+ backgroundImage: `url("${imageSrc}")`,
}}
+ className="rounded-circle"
>
-
-
-
+
+ {votes[acc] === "Approve" ?
:
}
+
+
);
})}
{accounts.length > maxShow && (
@@ -108,23 +106,22 @@ return (
}}
>
-
- {voted && (
-
- )}
+ >
+ {voted && (
+
+ {votes[acc] === "Approve" ? (
+
+ ) : (
+
+ )}
+
+ )}
+
{name ?? acc}
diff --git a/instances/widgets.treasury-factory.near/widget/components/Icons.jsx b/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
index 76a7411d..65056a07 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
@@ -235,6 +235,122 @@ const NotVerfiedTick = ({ height, width }) => (
);
+const User = ({ height, width }) => (
+
+
+
+
+);
+
+const Copy = ({ height, width }) => (
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const Approval = ({ height, width }) => (
+
+
+
+
+);
+
+const Reject = ({ height, width }) => (
+
+
+
+
+
+);
+
return {
NearToken,
WithdrawIcon,
@@ -244,4 +360,8 @@ return {
Whitelist,
VerifiedTick,
NotVerfiedTick,
+ User,
+ Copy,
+ Approval,
+ Reject,
};
diff --git a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
index c68c17c4..1aa6916e 100644
--- a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
@@ -3,16 +3,18 @@ const { instance } = props;
if (!instance) {
return <>>;
}
-
+const { getColors } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.templates.AppLayout"
+) || { getColors: () => {} };
const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`);
const config = treasuryDaoID ? Near.view(treasuryDaoID, "get_config") : null;
const metadata = JSON.parse(atob(config.metadata ?? ""));
-
+const rootClose = props.rootClose ?? true;
const isDarkTheme = metadata.theme === "dark";
const showTimer = 250;
-const hideTimer = 300;
+const hideTimer = 500;
const handleOnMouseEnter = () => {
clearTimeout(state.debounce);
@@ -41,6 +43,10 @@ const overlayStyle = props.overlayStyle ?? {
fontSize: 13,
};
+const ThemeColorsContainer = styled.div`
+ ${() => getColors(isDarkTheme, "", "")}
+`;
+
const overlay = (
- {props.popup}
+ {props.popup}
);
@@ -59,6 +65,7 @@ return (
delay={{ show: showTimer, hide: hideTimer }}
placement="auto"
overlay={overlay}
+ rootClose={rootClose}
>
<>>,
+ NotVerfiedTick: () => <>>,
+ User: () => <>>,
+ Copy: () => <>>,
+};
+
+const showKYC = props.showKYC;
+const accountId = props.accountId;
+const displayName = props.displayName ?? true;
+const displayImage = props.displayImage ?? true;
+const [isVerfied, setIsVerfied] = useState(false);
+const [verificationStatus, setVerificationStatus] = useState(null);
+
+const profile = Social.getr(`${accountId}/profile`);
+const imageSrc =
+ `https://i.near.social/magic/large/https://near.social/magic/img/account/${accountId}` ??
+ "https://ipfs.near.social/ipfs/bafkreibmiy4ozblcgv3fm3gc6q62s55em33vconbavfd2ekkuliznaq3zm";
+const name = profile.name;
+
+useEffect(() => {
+ if (
+ showKYC &&
+ (accountId.length === 64 ||
+ (accountId ?? "").includes(".near") ||
+ (accountId ?? "").includes(".tg"))
+ ) {
+ asyncFetch(
+ `https://neardevhub-kyc-proxy.shuttleapp.rs/kyc/${accountId}`
+ ).then((res) => {
+ let displayableText = "";
+ switch (res.body.kyc_status) {
+ case "Approved":
+ displayableText = "Verified";
+ setIsVerfied(true);
+ break;
+ case "Pending":
+ displayableText = "Pending";
+ break;
+ case "NotSubmitted":
+ case "Rejected":
+ displayableText = "Not Verfied";
+ break;
+ default:
+ displayableText = "Failed to get status";
+ break;
+ }
+ setVerificationStatus(displayableText);
+ });
+ }
+}, [accountId]);
+
+const ProfileLink = styled.a`
+ color: var(--text-color);
+ &:hover {
+ color: var(--text-color);
+ }
+`;
+
+const HoverCard = () => {
+ return (
+
+
+
+
+
+
{name}
+
+
@{accountId}
+
+
+ {verificationStatus && (
+
+ {verificationStatus === "Verified" ? (
+
+ ) : (
+
+ )}
+
Fractal {verificationStatus}
+
+ )}
+
+
+ Open Profile
+
+
+
clipboard.writeText(accountId)}
+ >
+
+ Copy wallet address
+
+
+
+
+ );
+};
+
+const ReceiverAccountComponent = (
+
+ {displayImage && (
+
+
+
+ {verificationStatus &&
+ (isVerfied ? : )}
+
+
+ )}
+
+
+ {displayName &&
{name}
}
+
+ {displayName && "@"} {accountId}
+
+
+
+);
+
+return (
+
+ ,
+ children: ReceiverAccountComponent,
+ instance: props.instance,
+ rootClose: false,
+ }}
+ />
+
+);
diff --git a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
deleted file mode 100644
index 4b970d5b..00000000
--- a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-const { VerifiedTick, NotVerfiedTick } = VM.require(
- "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons"
-) || { VerifiedTick: () => <>>, NotVerfiedTick: () => <>> };
-
-const showKYC = props.showKYC;
-const receiverAccount = props.receiverAccount;
-const [isVerfied, setIsVerfied] = useState(false);
-const [verificationStatus, setVerificationStatus] = useState(null);
-
-const profile = Social.getr(`${receiverAccount}/profile`);
-const imageSrc =
- `https://i.near.social/magic/large/https://near.social/magic/img/account/${receiverAccount}` ??
- "https://ipfs.near.social/ipfs/bafkreibmiy4ozblcgv3fm3gc6q62s55em33vconbavfd2ekkuliznaq3zm";
-const name = profile.name;
-
-useEffect(() => {
- if (
- showKYC &&
- (receiverAccount.length === 64 ||
- (receiverAccount ?? "").includes(".near") ||
- (receiverAccount ?? "").includes(".tg"))
- ) {
- asyncFetch(
- `https://neardevhub-kyc-proxy.shuttleapp.rs/kyc/${receiverAccount}`
- ).then((res) => {
- let displayableText = "";
- switch (res.body.kyc_status) {
- case "Approved":
- displayableText = "Verified";
- setIsVerfied(true);
- break;
- case "Pending":
- displayableText = "Pending";
- break;
- case "NotSubmitted":
- case "Rejected":
- displayableText = "Not Verfied";
- break;
- default:
- displayableText = "Failed to get status";
- break;
- }
- setVerificationStatus(displayableText);
- });
- }
-}, [receiverAccount]);
-
-const HoverCard = () => {
- return (
-
-
@{receiverAccount}
- {verificationStatus && (
-
- {verificationStatus === "Verified" ? (
-
- ) : (
-
- )}
-
-
Fractal
-
{verificationStatus}
-
-
- )}
-
- );
-};
-
-const ReceiverAccountComponent = (
-
-
-
-
- {verificationStatus &&
- (isVerfied ? : )}
-
-
-
-
{name}
-
@{receiverAccount}
-
-
-);
-
-return (
-
- ,
- children: ReceiverAccountComponent,
- instance: props.instance,
- }}
- />
-
-);
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index ac9b6c2e..5037f4d5 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -103,452 +103,452 @@ const AppHeader = ({ page, instance }) => (
/>
);
-function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
- const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
- themeColor: "",
- };
-
- const config = treasuryDaoID
- ? useCache(
- () => Near.asyncView(treasuryDaoID, "get_config"),
- treasuryDaoID + "_get_config",
- { subscribe: false }
- )
- : null;
- const metadata = JSON.parse(atob(config.metadata ?? ""));
+const getColors = (isDarkTheme, themeColor, hoverColor) => `
+--theme-color: ${themeColor};
+--theme-color-dark: ${hoverColor};
+--bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
+--bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
+--bg-system-color: ${isDarkTheme ? "#131313" : "#f4f4f4"};
+--text-color: ${isDarkTheme ? "#CACACA" : "#1B1B18"};
+--text-secondary-color: ${isDarkTheme ? "#878787" : "#999999"};
+--text-alt-color: ${isDarkTheme ? "#FFFFFF" : "#FFFFFF"};
+--border-color: ${isDarkTheme ? "#3B3B3B" : "rgba(226, 230, 236, 1)"};
+--grey-01: ${isDarkTheme ? "#F4F4F4" : "#1B1B18"};
+--grey-02: ${isDarkTheme ? "#B3B3B3" : "#555555"};
+--grey-03: ${isDarkTheme ? "#555555" : "#B3B3B3"};
+--grey-035: ${isDarkTheme ? "#3E3E3E" : "#E6E6E6"};
+--grey-04: ${isDarkTheme ? "#323232" : "#F4F4F4"};
+--grey-05: ${isDarkTheme ? "#1B1B18" : "#F7F7F7"};
+--icon-color: ${isDarkTheme ? "#CACACA" : "#060606"};
+--other-primary:#2775C9;
+--other-warning:#B17108;
+--other-green:#3CB179;
+--other-red:#D95C4A;
+
+// bootstrap theme color
+--bs-body-bg: var(--bg-page-color);
+--bs-border-color: var(--border-color);
+`;
- const data = fetch(`https://httpbin.org/headers`);
- const gatewayURL = data?.body?.headers?.Origin ?? "";
- const isDarkTheme = metadata.theme === "dark";
+const Theme = styled.div`
+ padding-top: calc(-1 * var(--body-top-padding));
- if (!config) {
- return <>>;
+ // remove up/down arrow in input of type = number
+ /* For Chrome, Safari, and Edge */
+ input[type="number"]::-webkit-outer-spin-button,
+ input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
}
- const primaryColor = metadata?.primaryColor
- ? metadata?.primaryColor
- : themeColor
- ? themeColor
- : isDarkTheme
- ? "#01BF7A"
- : "#01BF7A";
-
- // Convert HEX to HSL
- const [h, s, l] = hexToHsl(primaryColor);
-
- // Calculate hover color (darken by reducing lightness)
- const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+ /* For Firefox */
+ input[type="number"] {
+ -moz-appearance: textfield;
+ }
- const getColors = (isDarkTheme, themeColor, hoverColor) => `
- --theme-color: ${themeColor};
- --theme-color-dark: ${hoverColor};
- --bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
- --bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
- --bg-system-color: ${isDarkTheme ? "#131313" : "#f4f4f4"};
- --text-color: ${isDarkTheme ? "#CACACA" : "#1B1B18"};
- --text-secondary-color: ${isDarkTheme ? "#878787" : "#999999"};
- --text-alt-color: ${isDarkTheme ? "#FFFFFF" : "#FFFFFF"};
- --border-color: ${isDarkTheme ? "#3B3B3B" : "rgba(226, 230, 236, 1)"};
- --grey-01: ${isDarkTheme ? "#F4F4F4" : "#1B1B18"};
- --grey-02: ${isDarkTheme ? "#B3B3B3" : "#555555"};
- --grey-03: ${isDarkTheme ? "#555555" : "#B3B3B3"};
- --grey-035: ${isDarkTheme ? "#3E3E3E" : "#E6E6E6"};
- --grey-04: ${isDarkTheme ? "#323232" : "#F4F4F4"};
- --grey-05: ${isDarkTheme ? "#1B1B18" : "#F7F7F7"};
- --icon-color: ${isDarkTheme ? "#CACACA" : "#060606"};
- --other-primary:#2775C9;
- --other-warning:#B17108;
- --other-green:#3CB179;
- --other-red:#D95C4A;
-
- // bootstrap theme color
- --bs-body-bg: var(--bg-page-color);
- --bs-border-color: var(--border-color);
-`;
+ .card {
+ border-color: var(--border-color) !important;
+ border-width: 1px !important;
+ border-radius: 14px;
+ background-color: var(--bg-page-color) !important;
+ }
- const ParentContainer = styled.div`
- ${() => getColors(isDarkTheme, primaryColor, hoverColor)}
- width: 100%;
- background: var(--bg-system-color) !important;
- ${() =>
- gatewayURL.includes("near.org")
- ? `
- /* Styles specific to near.org */
- position: static;
- `
- : `
- /* Styles specific to other URLs */
- position: fixed;
- inset: 73px 0px 0px;
- overflow-y: scroll;
- `}
- `;
+ .dropdown-menu {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- const Theme = styled.div`
- padding-top: calc(-1 * var(--body-top-padding));
+ .dropdown-item.active,
+ .dropdown-item:active {
+ background-color: var(--grey-04) !important;
+ color: inherit !important;
+ }
- // remove up/down arrow in input of type = number
- /* For Chrome, Safari, and Edge */
- input[type="number"]::-webkit-outer-spin-button,
- input[type="number"]::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
+ .dropdown-item:hover,
+ .dropdown-item:focus {
+ background-color: var(--grey-04) !important;
+ color: inherit !important;
+ }
- /* For Firefox */
- input[type="number"] {
- -moz-appearance: textfield;
- }
+ .offcanvas {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .card {
- border-color: var(--border-color) !important;
- border-width: 1px !important;
- border-radius: 14px;
- background-color: var(--bg-page-color) !important;
- }
+ color: var(--text-color);
+ font-weight: 500;
- .dropdown-menu {
- background-color: var(--bg-page-color) !important;
+ a {
+ text-decoration: none;
+ color: var(--text-color) !important;
+ font-weight: 500;
+ &.active {
color: var(--text-color) !important;
}
- .dropdown-item.active,
- .dropdown-item:active {
- background-color: var(--grey-04) !important;
- color: inherit !important;
- }
-
- .dropdown-item:hover,
- .dropdown-item:focus {
- background-color: var(--grey-04) !important;
- color: inherit !important;
- }
-
- .offcanvas {
- background-color: var(--bg-page-color) !important;
+ &:hover {
+ text-decoration: none;
color: var(--text-color) !important;
}
+ }
- color: var(--text-color);
+ button {
+ height: 40px;
font-weight: 500;
+ }
- a {
- text-decoration: none;
- color: var(--text-color) !important;
- font-weight: 500;
- &.active {
- color: var(--text-color) !important;
- }
+ button.primary {
+ background: var(--theme-color);
+ color: var(--text-alt-color) !important;
+ border: none !important;
+ padding-block: 0.7rem !important;
- &:hover {
- text-decoration: none;
- color: var(--text-color) !important;
- }
+ i {
+ color: var(--text-alt-color) !important;
}
+ }
+
+ .primary-button {
+ background: var(--theme-color) !important;
+ color: var(--text-alt-color) !important;
+ border: none !important;
- button {
- height: 40px;
- font-weight: 500;
+ &:hover {
+ background: var(--theme-color-dark) !important;
}
- button.primary {
- background: var(--theme-color);
+ i {
color: var(--text-alt-color) !important;
- border: none !important;
- padding-block: 0.7rem !important;
-
- i {
- color: var(--text-alt-color) !important;
- }
}
+ }
- .primary-button {
- background: var(--theme-color) !important;
- color: var(--text-alt-color) !important;
- border: none !important;
+ .text-lg {
+ font-size: 15px;
+ }
- &:hover {
- background: var(--theme-color-dark) !important;
- }
+ .fw-semi-bold {
+ font-weight: 500;
+ }
- i {
- color: var(--text-alt-color) !important;
- }
- }
+ .text-secondary {
+ color: var(--text-secondary-color) !important;
+ }
- .text-lg {
- font-size: 15px;
- }
+ .max-w-100 {
+ max-width: 100%;
+ }
- .fw-semi-bold {
- font-weight: 500;
- }
+ .custom-truncate {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: 1.5;
+ max-height: 4.5em;
+ text-align: left;
+ }
- .text-secondary {
- color: var(--text-secondary-color) !important;
- }
+ .display-none {
+ display: none;
+ }
- .max-w-100 {
- max-width: 100%;
- }
+ .text-right {
+ text-align: end;
+ }
- .custom-truncate {
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- line-height: 1.5;
- max-height: 4.5em;
- text-align: left;
- }
+ .text-left {
+ text-align: left;
+ }
+ .text-underline {
+ text-decoration: underline !important;
+ }
- .display-none {
- display: none;
- }
+ .bg-highlight {
+ background-color: rgb(185, 185, 185, 0.2);
+ }
- .text-right {
- text-align: end;
- }
+ .cursor-pointer {
+ cursor: pointer;
+ }
- .text-left {
- text-align: left;
- }
- .text-underline {
- text-decoration: underline !important;
- }
+ .theme-btn {
+ background: var(--theme-color) !important;
+ color: white !important;
+ border: none;
+ }
- .bg-highlight {
- background-color: rgb(185, 185, 185, 0.2);
- }
+ .theme-btn.btn:hover {
+ color: white !important;
+ background: var(--theme-color-dark) !important;
+ }
- .cursor-pointer {
- cursor: pointer;
- }
+ .btn-outline-secondary {
+ border-color: var(--border-color) !important;
+ color: var(--text-color) !important;
+ border-width: 1px !important;
- .theme-btn {
- background: var(--theme-color) !important;
- color: white !important;
- border: none;
+ i {
+ color: var(--text-color) !important;
}
- .theme-btn.btn:hover {
- color: white !important;
- background: var(--theme-color-dark) !important;
+ &:hover {
+ color: var(--text-color) !important;
+ border-color: var(--border-color) !important;
+ background: var(--grey-035) !important;
}
+ }
- .btn-outline-secondary {
- border-color: var(--border-color) !important;
- color: var(--text-color) !important;
- border-width: 1px !important;
+ .toast-container {
+ right: 10px !important;
+ bottom: 10px !important;
+ }
+ .toast {
+ border-radius: 10px;
+ overflow: hidden;
+ color: var(--text-color) !important;
+ background: var(--bg-page-color) !important;
+ border-color: var(--border-color) !important;
- i {
- color: var(--text-color) !important;
+ a {
+ color: inherit !important;
+ &:active {
+ color: inherit !important;
}
-
&:hover {
- color: var(--text-color) !important;
- border-color: var(--border-color) !important;
- background: var(--grey-035) !important;
+ color: inherit !important;
}
}
+ }
- .toast-container {
- right: 10px !important;
- bottom: 10px !important;
- }
- .toast {
- border-radius: 10px;
- overflow: hidden;
- color: var(--text-color) !important;
- background: var(--bg-page-color) !important;
- border-color: var(--border-color) !important;
+ .toast-header {
+ background-color: var(--bg-system-color) !important;
+ color: var(--text-secondary-color) !important;
+ }
- a {
- color: inherit !important;
- &:active {
- color: inherit !important;
- }
- &:hover {
- color: inherit !important;
- }
- }
- }
+ .text-md {
+ font-size: 15px;
+ }
- .toast-header {
- background-color: var(--bg-system-color) !important;
- color: var(--text-secondary-color) !important;
+ .primary-text-color {
+ color: var(--theme-color);
+ a {
+ color: var(--theme-color) !important;
}
- .text-md {
- font-size: 15px;
+ i {
+ color: var(--theme-color) !important;
}
+ }
- .primary-text-color {
- color: var(--theme-color);
- a {
- color: var(--theme-color) !important;
- }
+ .btn-outline.btn:hover {
+ color: inherit !important;
+ }
- i {
- color: var(--theme-color) !important;
- }
- }
+ .primary-text-color.btn:hover {
+ color: inherit !important;
+ }
- .btn-outline.btn:hover {
- color: inherit !important;
- }
+ .badge {
+ padding: 6px 8px;
+ background: var(--grey-035);
+ color: var(--text-color);
+ rounded: 8px;
+ font-weight: 500;
+ font-size: 12px;
+ }
- .primary-text-color.btn:hover {
- color: inherit !important;
- }
+ .btn-outline-plain {
+ height: 40px;
+ padding-block: 7px !important;
+ padding-inline: 10px !important;
+ border-radius: 0.375rem !important;
+ border: 1.5px solid var(--border-color) !important;
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
- .badge {
- padding: 6px 8px;
- background: var(--grey-035);
- color: var(--text-color);
- rounded: 8px;
- font-weight: 500;
- font-size: 12px;
+ &:hover {
+ background-color: white;
+ color: black;
}
+ }
- .btn-outline-plain {
- height: 40px;
- padding-block: 7px !important;
- padding-inline: 10px !important;
- border-radius: 0.375rem !important;
- border: 1.5px solid var(--border-color) !important;
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ color: var(--text-color) !important;
+ }
- &:hover {
- background-color: white;
- color: black;
- }
- }
+ .btn.disabled:not(.no-transparent),
+ fieldset:disabled:not(.no-transparent) {
+ border-color: transparent !important;
+ }
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- color: var(--text-color) !important;
- }
+ .table {
+ border-color: var(--border-color) !important;
+ color: var(--text-color) !important;
+ margin-bottom: 20px;
- .btn.disabled:not(.no-transparent),
- fieldset:disabled:not(.no-transparent) {
- border-color: transparent !important;
+ .amount {
+ font-size: 14px;
}
+ }
- .table {
- border-color: var(--border-color) !important;
- color: var(--text-color) !important;
- margin-bottom: 20px;
+ .table td:first-child {
+ padding-left: 20px;
+ }
- .amount {
- font-size: 14px;
- }
- }
+ .table td:last-child {
+ padding-right: 20px;
+ }
- .table td:first-child {
- padding-left: 20px;
- }
+ .bg-white {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .table td:last-child {
- padding-right: 20px;
- }
+ .bg-dropdown {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .bg-white {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .bg-custom-overlay {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .bg-dropdown {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .fill-accent {
+ fill: var(--theme-color);
+ }
- .bg-custom-overlay {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .use-max-bg {
+ color: #007aff;
+ cursor: pointer;
+ }
- .fill-accent {
- fill: var(--theme-color);
- }
+ .bg-validator-info {
+ background: rgba(0, 16, 61, 0.06);
+ color: #1b1b18;
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .use-max-bg {
- color: #007aff;
- cursor: pointer;
- }
+ .bg-validator-warning {
+ background: rgba(255, 158, 0, 0.1);
+ color: var(--other-warning);
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .bg-validator-info {
- background: rgba(0, 16, 61, 0.06);
- color: #1b1b18;
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .bg-withdraw-warning {
+ background: rgba(255, 158, 0, 0.1);
+ color: var(--other-warning);
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .bg-validator-warning {
- background: rgba(255, 158, 0, 0.1);
- color: var(--other-warning);
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .text-sm {
+ font-size: 13px;
+ }
- .bg-withdraw-warning {
- background: rgba(255, 158, 0, 0.1);
- color: var(--other-warning);
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .text-secondary a {
+ color: inherit !important;
+ }
- .text-sm {
- font-size: 13px;
- }
+ .text-red {
+ color: var(--other-red) !important;
+ }
- .text-secondary a {
- color: inherit !important;
- }
+ .btn-outline.btn:hover {
+ color: inherit !important;
+ }
- .text-red {
- color: var(--other-red) !important;
- }
+ .border-right {
+ border-right: 1px solid var(--border-color);
+ }
- .btn-outline.btn:hover {
- color: inherit !important;
- }
+ .cursor-pointer {
+ cursor: pointer;
+ }
- .border-right {
- border-right: 1px solid var(--border-color);
- }
+ .success-icon {
+ color: var(--other-green) !important;
+ }
- .cursor-pointer {
- cursor: pointer;
- }
+ .warning-icon {
+ color: var(--other-warning) !important;
+ }
- .success-icon {
- color: var(--other-green) !important;
- }
+ .error-icon {
+ color: var(--other-red) !important;
+ }
- .warning-icon {
- color: var(--other-warning) !important;
- }
+ .primary-icon {
+ color: var(--theme-color) !important;
+ }
+`;
- .error-icon {
- color: var(--other-red) !important;
- }
+function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
+ const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
+ themeColor: "",
+ };
- .primary-icon {
- color: var(--theme-color) !important;
- }
+ const config = treasuryDaoID
+ ? useCache(
+ () => Near.asyncView(treasuryDaoID, "get_config"),
+ treasuryDaoID + "_get_config",
+ { subscribe: false }
+ )
+ : null;
+ const metadata = JSON.parse(atob(config.metadata ?? ""));
+
+ const data = fetch(`https://httpbin.org/headers`);
+ const gatewayURL = data?.body?.headers?.Origin ?? "";
+ const isDarkTheme = metadata.theme === "dark";
+
+ if (!config) {
+ return <>>;
+ }
+
+ const primaryColor = metadata?.primaryColor
+ ? metadata?.primaryColor
+ : themeColor
+ ? themeColor
+ : isDarkTheme
+ ? "#01BF7A"
+ : "#01BF7A";
+
+ // Convert HEX to HSL
+ const [h, s, l] = hexToHsl(primaryColor);
+
+ // Calculate hover color (darken by reducing lightness)
+ const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+
+ const ParentContainer = styled.div`
+ ${() => getColors(isDarkTheme, primaryColor, hoverColor)}
+ width: 100%;
+ background: var(--bg-system-color) !important;
+ ${() =>
+ gatewayURL.includes("near.org")
+ ? `
+ /* Styles specific to near.org */
+ position: static;
+ `
+ : `
+ /* Styles specific to other URLs */
+ position: fixed;
+ inset: 73px 0px 0px;
+ overflow-y: scroll;
+ `}
`;
return (
@@ -562,4 +562,4 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
);
}
-return { AppLayout };
+return { AppLayout, getColors, Theme };
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 1ee7481c..35a249c9 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -338,9 +338,9 @@ const ProposalsComponent = () => {
{
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
index 2a8e0b79..ddad96cb 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
@@ -252,22 +252,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
index 05e1c96a..d0618dbd 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
@@ -281,22 +281,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
index 4f8051a2..4ee32de9 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
@@ -392,22 +392,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
From 930df0d15b72aeb793177afa1fdcc59c6b9ce62f Mon Sep 17 00:00:00 2001
From: Andrew
Date: Wed, 22 Jan 2025 13:57:08 +0200
Subject: [PATCH 24/40] Change cancel creation link url (#232)
---
.../treasury-factory.near/widget/pages/treasury/Create.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
index 6290032a..9fc230a1 100644
--- a/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
+++ b/instances/treasury-factory.near/widget/pages/treasury/Create.jsx
@@ -72,7 +72,7 @@ const Wrapper = ({ title, children }) => (
Cancel creation
From d8e141a20368f97aff5a4733cb61544cc9655475 Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Wed, 22 Jan 2025 20:08:56 +0530
Subject: [PATCH 25/40] Fix loading theme for aurora treasury (#230)
---
.../widget/pages/settings/Theme.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
index f551b297..29b480a1 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
@@ -356,7 +356,7 @@ return (
/>
Theme & Logo
- {!metadata ? (
+ {!config ? (
Date: Wed, 22 Jan 2025 20:09:21 +0530
Subject: [PATCH 26/40] Hover fixes (#231)
https://www.notion.so/17a490b283038084bbd6d98a90cfeb68?v=466c3a17456f49cb9757dd88cace649d&p=182490b2830380b0be68fb33b4d72abe&pm=s
---
.../widget/components/Approvers.jsx | 83 +-
.../widget/components/Icons.jsx | 120 +++
.../widget/components/OverlayTrigger.jsx | 15 +-
.../widget/components/Profile.jsx | 155 ++++
.../widget/components/ReceiverAccount.jsx | 99 ---
.../widget/components/templates/AppLayout.jsx | 718 +++++++++---------
.../widget/pages/payments/Table.jsx | 24 +-
.../widget/pages/proposals-feed/Table.jsx | 20 +-
.../widget/pages/settings/feed/Table.jsx | 20 +-
.../widget/pages/stake-delegation/Table.jsx | 20 +-
10 files changed, 707 insertions(+), 567 deletions(-)
create mode 100644 instances/widgets.treasury-factory.near/widget/components/Profile.jsx
delete mode 100644 instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
diff --git a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
index 98f8fdd1..435f1517 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Approvers.jsx
@@ -1,7 +1,8 @@
-const { isNearSocial } = VM.require(
- "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common"
+const { Approval, Reject } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons"
) || {
- isNearSocial: false,
+ Approval: () => <>>,
+ Reject: () => <>>,
};
const votes = props.votes ?? {};
@@ -9,11 +10,6 @@ const accounts = Object.keys(votes);
const approversGroup = props.approversGroup ?? [];
const maxShow = 1;
const showHover = accounts?.length > maxShow;
-const approve =
- "https://ipfs.near.social/ipfs/bafkreib52fq4kw7gyfsupz4mrtrexbusc2lplxnopqswa5awtnlqmenena";
-const reject =
- "https://ipfs.near.social/ipfs/bafkreihrwi2nzl7d2dyij3tstr6tdr7fnioq7vu37en3dxt4faihxreabm";
-
const maxIndex = 100;
const Container = styled.div`
@@ -28,35 +24,37 @@ function getImage(acc) {
return `https://i.near.social/magic/large/https://near.social/magic/img/account/${acc}`;
}
+const ApprovalImage = styled.div`
+ position: relative;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ height: 40px;
+ width: 40px;
+ .status {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ }
+`;
+
const ApproversComponent = (
{accounts.slice(0, maxShow).map((acc, index) => {
const imageSrc = getImage(acc);
- const voteImg = votes[acc] === "Approve" ? approve : reject;
return (
-
0 ? "-10px" : 0,
zIndex: maxIndex - index,
- position: "relative",
+ backgroundImage: `url("${imageSrc}")`,
}}
+ className="rounded-circle"
>
-
-
-
+
+ {votes[acc] === "Approve" ?
:
}
+
+
);
})}
{accounts.length > maxShow && (
@@ -108,23 +106,22 @@ return (
}}
>
-
- {voted && (
-
- )}
+ >
+ {voted && (
+
+ {votes[acc] === "Approve" ? (
+
+ ) : (
+
+ )}
+
+ )}
+
{name ?? acc}
diff --git a/instances/widgets.treasury-factory.near/widget/components/Icons.jsx b/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
index 76a7411d..65056a07 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Icons.jsx
@@ -235,6 +235,122 @@ const NotVerfiedTick = ({ height, width }) => (
);
+const User = ({ height, width }) => (
+
+
+
+
+);
+
+const Copy = ({ height, width }) => (
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const Approval = ({ height, width }) => (
+
+
+
+
+);
+
+const Reject = ({ height, width }) => (
+
+
+
+
+
+);
+
return {
NearToken,
WithdrawIcon,
@@ -244,4 +360,8 @@ return {
Whitelist,
VerifiedTick,
NotVerfiedTick,
+ User,
+ Copy,
+ Approval,
+ Reject,
};
diff --git a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
index c68c17c4..1aa6916e 100644
--- a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
@@ -3,16 +3,18 @@ const { instance } = props;
if (!instance) {
return <>>;
}
-
+const { getColors } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.templates.AppLayout"
+) || { getColors: () => {} };
const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`);
const config = treasuryDaoID ? Near.view(treasuryDaoID, "get_config") : null;
const metadata = JSON.parse(atob(config.metadata ?? ""));
-
+const rootClose = props.rootClose ?? true;
const isDarkTheme = metadata.theme === "dark";
const showTimer = 250;
-const hideTimer = 300;
+const hideTimer = 500;
const handleOnMouseEnter = () => {
clearTimeout(state.debounce);
@@ -41,6 +43,10 @@ const overlayStyle = props.overlayStyle ?? {
fontSize: 13,
};
+const ThemeColorsContainer = styled.div`
+ ${() => getColors(isDarkTheme, "", "")}
+`;
+
const overlay = (
- {props.popup}
+ {props.popup}
);
@@ -59,6 +65,7 @@ return (
delay={{ show: showTimer, hide: hideTimer }}
placement="auto"
overlay={overlay}
+ rootClose={rootClose}
>
<>>,
+ NotVerfiedTick: () => <>>,
+ User: () => <>>,
+ Copy: () => <>>,
+};
+
+const showKYC = props.showKYC;
+const accountId = props.accountId;
+const displayName = props.displayName ?? true;
+const displayImage = props.displayImage ?? true;
+const [isVerfied, setIsVerfied] = useState(false);
+const [verificationStatus, setVerificationStatus] = useState(null);
+
+const profile = Social.getr(`${accountId}/profile`);
+const imageSrc =
+ `https://i.near.social/magic/large/https://near.social/magic/img/account/${accountId}` ??
+ "https://ipfs.near.social/ipfs/bafkreibmiy4ozblcgv3fm3gc6q62s55em33vconbavfd2ekkuliznaq3zm";
+const name = profile.name;
+
+useEffect(() => {
+ if (
+ showKYC &&
+ (accountId.length === 64 ||
+ (accountId ?? "").includes(".near") ||
+ (accountId ?? "").includes(".tg"))
+ ) {
+ asyncFetch(
+ `https://neardevhub-kyc-proxy.shuttleapp.rs/kyc/${accountId}`
+ ).then((res) => {
+ let displayableText = "";
+ switch (res.body.kyc_status) {
+ case "Approved":
+ displayableText = "Verified";
+ setIsVerfied(true);
+ break;
+ case "Pending":
+ displayableText = "Pending";
+ break;
+ case "NotSubmitted":
+ case "Rejected":
+ displayableText = "Not Verfied";
+ break;
+ default:
+ displayableText = "Failed to get status";
+ break;
+ }
+ setVerificationStatus(displayableText);
+ });
+ }
+}, [accountId]);
+
+const ProfileLink = styled.a`
+ color: var(--text-color);
+ &:hover {
+ color: var(--text-color);
+ }
+`;
+
+const HoverCard = () => {
+ return (
+
+
+
+
+
+
{name}
+
+
@{accountId}
+
+
+ {verificationStatus && (
+
+ {verificationStatus === "Verified" ? (
+
+ ) : (
+
+ )}
+
Fractal {verificationStatus}
+
+ )}
+
+
+ Open Profile
+
+
+
clipboard.writeText(accountId)}
+ >
+
+ Copy wallet address
+
+
+
+
+ );
+};
+
+const ReceiverAccountComponent = (
+
+ {displayImage && (
+
+
+
+ {verificationStatus &&
+ (isVerfied ? : )}
+
+
+ )}
+
+
+ {displayName &&
{name}
}
+
+ {displayName && "@"} {accountId}
+
+
+
+);
+
+return (
+
+ ,
+ children: ReceiverAccountComponent,
+ instance: props.instance,
+ rootClose: false,
+ }}
+ />
+
+);
diff --git a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx b/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
deleted file mode 100644
index 4b970d5b..00000000
--- a/instances/widgets.treasury-factory.near/widget/components/ReceiverAccount.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-const { VerifiedTick, NotVerfiedTick } = VM.require(
- "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.Icons"
-) || { VerifiedTick: () => <>>, NotVerfiedTick: () => <>> };
-
-const showKYC = props.showKYC;
-const receiverAccount = props.receiverAccount;
-const [isVerfied, setIsVerfied] = useState(false);
-const [verificationStatus, setVerificationStatus] = useState(null);
-
-const profile = Social.getr(`${receiverAccount}/profile`);
-const imageSrc =
- `https://i.near.social/magic/large/https://near.social/magic/img/account/${receiverAccount}` ??
- "https://ipfs.near.social/ipfs/bafkreibmiy4ozblcgv3fm3gc6q62s55em33vconbavfd2ekkuliznaq3zm";
-const name = profile.name;
-
-useEffect(() => {
- if (
- showKYC &&
- (receiverAccount.length === 64 ||
- (receiverAccount ?? "").includes(".near") ||
- (receiverAccount ?? "").includes(".tg"))
- ) {
- asyncFetch(
- `https://neardevhub-kyc-proxy.shuttleapp.rs/kyc/${receiverAccount}`
- ).then((res) => {
- let displayableText = "";
- switch (res.body.kyc_status) {
- case "Approved":
- displayableText = "Verified";
- setIsVerfied(true);
- break;
- case "Pending":
- displayableText = "Pending";
- break;
- case "NotSubmitted":
- case "Rejected":
- displayableText = "Not Verfied";
- break;
- default:
- displayableText = "Failed to get status";
- break;
- }
- setVerificationStatus(displayableText);
- });
- }
-}, [receiverAccount]);
-
-const HoverCard = () => {
- return (
-
-
@{receiverAccount}
- {verificationStatus && (
-
- {verificationStatus === "Verified" ? (
-
- ) : (
-
- )}
-
-
Fractal
-
{verificationStatus}
-
-
- )}
-
- );
-};
-
-const ReceiverAccountComponent = (
-
-
-
-
- {verificationStatus &&
- (isVerfied ? : )}
-
-
-
-
{name}
-
@{receiverAccount}
-
-
-);
-
-return (
-
- ,
- children: ReceiverAccountComponent,
- instance: props.instance,
- }}
- />
-
-);
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index ac9b6c2e..5037f4d5 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -103,452 +103,452 @@ const AppHeader = ({ page, instance }) => (
/>
);
-function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
- const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
- themeColor: "",
- };
-
- const config = treasuryDaoID
- ? useCache(
- () => Near.asyncView(treasuryDaoID, "get_config"),
- treasuryDaoID + "_get_config",
- { subscribe: false }
- )
- : null;
- const metadata = JSON.parse(atob(config.metadata ?? ""));
+const getColors = (isDarkTheme, themeColor, hoverColor) => `
+--theme-color: ${themeColor};
+--theme-color-dark: ${hoverColor};
+--bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
+--bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
+--bg-system-color: ${isDarkTheme ? "#131313" : "#f4f4f4"};
+--text-color: ${isDarkTheme ? "#CACACA" : "#1B1B18"};
+--text-secondary-color: ${isDarkTheme ? "#878787" : "#999999"};
+--text-alt-color: ${isDarkTheme ? "#FFFFFF" : "#FFFFFF"};
+--border-color: ${isDarkTheme ? "#3B3B3B" : "rgba(226, 230, 236, 1)"};
+--grey-01: ${isDarkTheme ? "#F4F4F4" : "#1B1B18"};
+--grey-02: ${isDarkTheme ? "#B3B3B3" : "#555555"};
+--grey-03: ${isDarkTheme ? "#555555" : "#B3B3B3"};
+--grey-035: ${isDarkTheme ? "#3E3E3E" : "#E6E6E6"};
+--grey-04: ${isDarkTheme ? "#323232" : "#F4F4F4"};
+--grey-05: ${isDarkTheme ? "#1B1B18" : "#F7F7F7"};
+--icon-color: ${isDarkTheme ? "#CACACA" : "#060606"};
+--other-primary:#2775C9;
+--other-warning:#B17108;
+--other-green:#3CB179;
+--other-red:#D95C4A;
+
+// bootstrap theme color
+--bs-body-bg: var(--bg-page-color);
+--bs-border-color: var(--border-color);
+`;
- const data = fetch(`https://httpbin.org/headers`);
- const gatewayURL = data?.body?.headers?.Origin ?? "";
- const isDarkTheme = metadata.theme === "dark";
+const Theme = styled.div`
+ padding-top: calc(-1 * var(--body-top-padding));
- if (!config) {
- return <>>;
+ // remove up/down arrow in input of type = number
+ /* For Chrome, Safari, and Edge */
+ input[type="number"]::-webkit-outer-spin-button,
+ input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
}
- const primaryColor = metadata?.primaryColor
- ? metadata?.primaryColor
- : themeColor
- ? themeColor
- : isDarkTheme
- ? "#01BF7A"
- : "#01BF7A";
-
- // Convert HEX to HSL
- const [h, s, l] = hexToHsl(primaryColor);
-
- // Calculate hover color (darken by reducing lightness)
- const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+ /* For Firefox */
+ input[type="number"] {
+ -moz-appearance: textfield;
+ }
- const getColors = (isDarkTheme, themeColor, hoverColor) => `
- --theme-color: ${themeColor};
- --theme-color-dark: ${hoverColor};
- --bg-header-color: ${isDarkTheme ? "#222222" : "#2C3E50"};
- --bg-page-color: ${isDarkTheme ? "#222222" : "#FFFFFF"};
- --bg-system-color: ${isDarkTheme ? "#131313" : "#f4f4f4"};
- --text-color: ${isDarkTheme ? "#CACACA" : "#1B1B18"};
- --text-secondary-color: ${isDarkTheme ? "#878787" : "#999999"};
- --text-alt-color: ${isDarkTheme ? "#FFFFFF" : "#FFFFFF"};
- --border-color: ${isDarkTheme ? "#3B3B3B" : "rgba(226, 230, 236, 1)"};
- --grey-01: ${isDarkTheme ? "#F4F4F4" : "#1B1B18"};
- --grey-02: ${isDarkTheme ? "#B3B3B3" : "#555555"};
- --grey-03: ${isDarkTheme ? "#555555" : "#B3B3B3"};
- --grey-035: ${isDarkTheme ? "#3E3E3E" : "#E6E6E6"};
- --grey-04: ${isDarkTheme ? "#323232" : "#F4F4F4"};
- --grey-05: ${isDarkTheme ? "#1B1B18" : "#F7F7F7"};
- --icon-color: ${isDarkTheme ? "#CACACA" : "#060606"};
- --other-primary:#2775C9;
- --other-warning:#B17108;
- --other-green:#3CB179;
- --other-red:#D95C4A;
-
- // bootstrap theme color
- --bs-body-bg: var(--bg-page-color);
- --bs-border-color: var(--border-color);
-`;
+ .card {
+ border-color: var(--border-color) !important;
+ border-width: 1px !important;
+ border-radius: 14px;
+ background-color: var(--bg-page-color) !important;
+ }
- const ParentContainer = styled.div`
- ${() => getColors(isDarkTheme, primaryColor, hoverColor)}
- width: 100%;
- background: var(--bg-system-color) !important;
- ${() =>
- gatewayURL.includes("near.org")
- ? `
- /* Styles specific to near.org */
- position: static;
- `
- : `
- /* Styles specific to other URLs */
- position: fixed;
- inset: 73px 0px 0px;
- overflow-y: scroll;
- `}
- `;
+ .dropdown-menu {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- const Theme = styled.div`
- padding-top: calc(-1 * var(--body-top-padding));
+ .dropdown-item.active,
+ .dropdown-item:active {
+ background-color: var(--grey-04) !important;
+ color: inherit !important;
+ }
- // remove up/down arrow in input of type = number
- /* For Chrome, Safari, and Edge */
- input[type="number"]::-webkit-outer-spin-button,
- input[type="number"]::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
+ .dropdown-item:hover,
+ .dropdown-item:focus {
+ background-color: var(--grey-04) !important;
+ color: inherit !important;
+ }
- /* For Firefox */
- input[type="number"] {
- -moz-appearance: textfield;
- }
+ .offcanvas {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .card {
- border-color: var(--border-color) !important;
- border-width: 1px !important;
- border-radius: 14px;
- background-color: var(--bg-page-color) !important;
- }
+ color: var(--text-color);
+ font-weight: 500;
- .dropdown-menu {
- background-color: var(--bg-page-color) !important;
+ a {
+ text-decoration: none;
+ color: var(--text-color) !important;
+ font-weight: 500;
+ &.active {
color: var(--text-color) !important;
}
- .dropdown-item.active,
- .dropdown-item:active {
- background-color: var(--grey-04) !important;
- color: inherit !important;
- }
-
- .dropdown-item:hover,
- .dropdown-item:focus {
- background-color: var(--grey-04) !important;
- color: inherit !important;
- }
-
- .offcanvas {
- background-color: var(--bg-page-color) !important;
+ &:hover {
+ text-decoration: none;
color: var(--text-color) !important;
}
+ }
- color: var(--text-color);
+ button {
+ height: 40px;
font-weight: 500;
+ }
- a {
- text-decoration: none;
- color: var(--text-color) !important;
- font-weight: 500;
- &.active {
- color: var(--text-color) !important;
- }
+ button.primary {
+ background: var(--theme-color);
+ color: var(--text-alt-color) !important;
+ border: none !important;
+ padding-block: 0.7rem !important;
- &:hover {
- text-decoration: none;
- color: var(--text-color) !important;
- }
+ i {
+ color: var(--text-alt-color) !important;
}
+ }
+
+ .primary-button {
+ background: var(--theme-color) !important;
+ color: var(--text-alt-color) !important;
+ border: none !important;
- button {
- height: 40px;
- font-weight: 500;
+ &:hover {
+ background: var(--theme-color-dark) !important;
}
- button.primary {
- background: var(--theme-color);
+ i {
color: var(--text-alt-color) !important;
- border: none !important;
- padding-block: 0.7rem !important;
-
- i {
- color: var(--text-alt-color) !important;
- }
}
+ }
- .primary-button {
- background: var(--theme-color) !important;
- color: var(--text-alt-color) !important;
- border: none !important;
+ .text-lg {
+ font-size: 15px;
+ }
- &:hover {
- background: var(--theme-color-dark) !important;
- }
+ .fw-semi-bold {
+ font-weight: 500;
+ }
- i {
- color: var(--text-alt-color) !important;
- }
- }
+ .text-secondary {
+ color: var(--text-secondary-color) !important;
+ }
- .text-lg {
- font-size: 15px;
- }
+ .max-w-100 {
+ max-width: 100%;
+ }
- .fw-semi-bold {
- font-weight: 500;
- }
+ .custom-truncate {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: 1.5;
+ max-height: 4.5em;
+ text-align: left;
+ }
- .text-secondary {
- color: var(--text-secondary-color) !important;
- }
+ .display-none {
+ display: none;
+ }
- .max-w-100 {
- max-width: 100%;
- }
+ .text-right {
+ text-align: end;
+ }
- .custom-truncate {
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- line-height: 1.5;
- max-height: 4.5em;
- text-align: left;
- }
+ .text-left {
+ text-align: left;
+ }
+ .text-underline {
+ text-decoration: underline !important;
+ }
- .display-none {
- display: none;
- }
+ .bg-highlight {
+ background-color: rgb(185, 185, 185, 0.2);
+ }
- .text-right {
- text-align: end;
- }
+ .cursor-pointer {
+ cursor: pointer;
+ }
- .text-left {
- text-align: left;
- }
- .text-underline {
- text-decoration: underline !important;
- }
+ .theme-btn {
+ background: var(--theme-color) !important;
+ color: white !important;
+ border: none;
+ }
- .bg-highlight {
- background-color: rgb(185, 185, 185, 0.2);
- }
+ .theme-btn.btn:hover {
+ color: white !important;
+ background: var(--theme-color-dark) !important;
+ }
- .cursor-pointer {
- cursor: pointer;
- }
+ .btn-outline-secondary {
+ border-color: var(--border-color) !important;
+ color: var(--text-color) !important;
+ border-width: 1px !important;
- .theme-btn {
- background: var(--theme-color) !important;
- color: white !important;
- border: none;
+ i {
+ color: var(--text-color) !important;
}
- .theme-btn.btn:hover {
- color: white !important;
- background: var(--theme-color-dark) !important;
+ &:hover {
+ color: var(--text-color) !important;
+ border-color: var(--border-color) !important;
+ background: var(--grey-035) !important;
}
+ }
- .btn-outline-secondary {
- border-color: var(--border-color) !important;
- color: var(--text-color) !important;
- border-width: 1px !important;
+ .toast-container {
+ right: 10px !important;
+ bottom: 10px !important;
+ }
+ .toast {
+ border-radius: 10px;
+ overflow: hidden;
+ color: var(--text-color) !important;
+ background: var(--bg-page-color) !important;
+ border-color: var(--border-color) !important;
- i {
- color: var(--text-color) !important;
+ a {
+ color: inherit !important;
+ &:active {
+ color: inherit !important;
}
-
&:hover {
- color: var(--text-color) !important;
- border-color: var(--border-color) !important;
- background: var(--grey-035) !important;
+ color: inherit !important;
}
}
+ }
- .toast-container {
- right: 10px !important;
- bottom: 10px !important;
- }
- .toast {
- border-radius: 10px;
- overflow: hidden;
- color: var(--text-color) !important;
- background: var(--bg-page-color) !important;
- border-color: var(--border-color) !important;
+ .toast-header {
+ background-color: var(--bg-system-color) !important;
+ color: var(--text-secondary-color) !important;
+ }
- a {
- color: inherit !important;
- &:active {
- color: inherit !important;
- }
- &:hover {
- color: inherit !important;
- }
- }
- }
+ .text-md {
+ font-size: 15px;
+ }
- .toast-header {
- background-color: var(--bg-system-color) !important;
- color: var(--text-secondary-color) !important;
+ .primary-text-color {
+ color: var(--theme-color);
+ a {
+ color: var(--theme-color) !important;
}
- .text-md {
- font-size: 15px;
+ i {
+ color: var(--theme-color) !important;
}
+ }
- .primary-text-color {
- color: var(--theme-color);
- a {
- color: var(--theme-color) !important;
- }
+ .btn-outline.btn:hover {
+ color: inherit !important;
+ }
- i {
- color: var(--theme-color) !important;
- }
- }
+ .primary-text-color.btn:hover {
+ color: inherit !important;
+ }
- .btn-outline.btn:hover {
- color: inherit !important;
- }
+ .badge {
+ padding: 6px 8px;
+ background: var(--grey-035);
+ color: var(--text-color);
+ rounded: 8px;
+ font-weight: 500;
+ font-size: 12px;
+ }
- .primary-text-color.btn:hover {
- color: inherit !important;
- }
+ .btn-outline-plain {
+ height: 40px;
+ padding-block: 7px !important;
+ padding-inline: 10px !important;
+ border-radius: 0.375rem !important;
+ border: 1.5px solid var(--border-color) !important;
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
- .badge {
- padding: 6px 8px;
- background: var(--grey-035);
- color: var(--text-color);
- rounded: 8px;
- font-weight: 500;
- font-size: 12px;
+ &:hover {
+ background-color: white;
+ color: black;
}
+ }
- .btn-outline-plain {
- height: 40px;
- padding-block: 7px !important;
- padding-inline: 10px !important;
- border-radius: 0.375rem !important;
- border: 1.5px solid var(--border-color) !important;
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ color: var(--text-color) !important;
+ }
- &:hover {
- background-color: white;
- color: black;
- }
- }
+ .btn.disabled:not(.no-transparent),
+ fieldset:disabled:not(.no-transparent) {
+ border-color: transparent !important;
+ }
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- color: var(--text-color) !important;
- }
+ .table {
+ border-color: var(--border-color) !important;
+ color: var(--text-color) !important;
+ margin-bottom: 20px;
- .btn.disabled:not(.no-transparent),
- fieldset:disabled:not(.no-transparent) {
- border-color: transparent !important;
+ .amount {
+ font-size: 14px;
}
+ }
- .table {
- border-color: var(--border-color) !important;
- color: var(--text-color) !important;
- margin-bottom: 20px;
+ .table td:first-child {
+ padding-left: 20px;
+ }
- .amount {
- font-size: 14px;
- }
- }
+ .table td:last-child {
+ padding-right: 20px;
+ }
- .table td:first-child {
- padding-left: 20px;
- }
+ .bg-white {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .table td:last-child {
- padding-right: 20px;
- }
+ .bg-dropdown {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .bg-white {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .bg-custom-overlay {
+ background-color: var(--bg-page-color) !important;
+ color: var(--text-color) !important;
+ }
- .bg-dropdown {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .fill-accent {
+ fill: var(--theme-color);
+ }
- .bg-custom-overlay {
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- }
+ .use-max-bg {
+ color: #007aff;
+ cursor: pointer;
+ }
- .fill-accent {
- fill: var(--theme-color);
- }
+ .bg-validator-info {
+ background: rgba(0, 16, 61, 0.06);
+ color: #1b1b18;
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .use-max-bg {
- color: #007aff;
- cursor: pointer;
- }
+ .bg-validator-warning {
+ background: rgba(255, 158, 0, 0.1);
+ color: var(--other-warning);
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .bg-validator-info {
- background: rgba(0, 16, 61, 0.06);
- color: #1b1b18;
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .bg-withdraw-warning {
+ background: rgba(255, 158, 0, 0.1);
+ color: var(--other-warning);
+ padding-inline: 0.8rem;
+ padding-block: 0.5rem;
+ font-weight: 500;
+ font-size: 13px;
+ }
- .bg-validator-warning {
- background: rgba(255, 158, 0, 0.1);
- color: var(--other-warning);
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .text-sm {
+ font-size: 13px;
+ }
- .bg-withdraw-warning {
- background: rgba(255, 158, 0, 0.1);
- color: var(--other-warning);
- padding-inline: 0.8rem;
- padding-block: 0.5rem;
- font-weight: 500;
- font-size: 13px;
- }
+ .text-secondary a {
+ color: inherit !important;
+ }
- .text-sm {
- font-size: 13px;
- }
+ .text-red {
+ color: var(--other-red) !important;
+ }
- .text-secondary a {
- color: inherit !important;
- }
+ .btn-outline.btn:hover {
+ color: inherit !important;
+ }
- .text-red {
- color: var(--other-red) !important;
- }
+ .border-right {
+ border-right: 1px solid var(--border-color);
+ }
- .btn-outline.btn:hover {
- color: inherit !important;
- }
+ .cursor-pointer {
+ cursor: pointer;
+ }
- .border-right {
- border-right: 1px solid var(--border-color);
- }
+ .success-icon {
+ color: var(--other-green) !important;
+ }
- .cursor-pointer {
- cursor: pointer;
- }
+ .warning-icon {
+ color: var(--other-warning) !important;
+ }
- .success-icon {
- color: var(--other-green) !important;
- }
+ .error-icon {
+ color: var(--other-red) !important;
+ }
- .warning-icon {
- color: var(--other-warning) !important;
- }
+ .primary-icon {
+ color: var(--theme-color) !important;
+ }
+`;
- .error-icon {
- color: var(--other-red) !important;
- }
+function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
+ const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
+ themeColor: "",
+ };
- .primary-icon {
- color: var(--theme-color) !important;
- }
+ const config = treasuryDaoID
+ ? useCache(
+ () => Near.asyncView(treasuryDaoID, "get_config"),
+ treasuryDaoID + "_get_config",
+ { subscribe: false }
+ )
+ : null;
+ const metadata = JSON.parse(atob(config.metadata ?? ""));
+
+ const data = fetch(`https://httpbin.org/headers`);
+ const gatewayURL = data?.body?.headers?.Origin ?? "";
+ const isDarkTheme = metadata.theme === "dark";
+
+ if (!config) {
+ return <>>;
+ }
+
+ const primaryColor = metadata?.primaryColor
+ ? metadata?.primaryColor
+ : themeColor
+ ? themeColor
+ : isDarkTheme
+ ? "#01BF7A"
+ : "#01BF7A";
+
+ // Convert HEX to HSL
+ const [h, s, l] = hexToHsl(primaryColor);
+
+ // Calculate hover color (darken by reducing lightness)
+ const hoverColor = hslToHex(h, s, Math.max(l - 10, 0));
+
+ const ParentContainer = styled.div`
+ ${() => getColors(isDarkTheme, primaryColor, hoverColor)}
+ width: 100%;
+ background: var(--bg-system-color) !important;
+ ${() =>
+ gatewayURL.includes("near.org")
+ ? `
+ /* Styles specific to near.org */
+ position: static;
+ `
+ : `
+ /* Styles specific to other URLs */
+ position: fixed;
+ inset: 73px 0px 0px;
+ overflow-y: scroll;
+ `}
`;
return (
@@ -562,4 +562,4 @@ function AppLayout({ page, instance, children, treasuryDaoID, accountId }) {
);
}
-return { AppLayout };
+return { AppLayout, getColors, Theme };
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index 1ee7481c..35a249c9 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -338,9 +338,9 @@ const ProposalsComponent = () => {
{
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
index 2a8e0b79..ddad96cb 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/proposals-feed/Table.jsx
@@ -252,22 +252,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
index 05e1c96a..d0618dbd 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/feed/Table.jsx
@@ -281,22 +281,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
index 4f8051a2..4ee32de9 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
@@ -392,22 +392,12 @@ const ProposalsComponent = () => {
- ),
- children: (
-
- {item.proposer}
-
- ),
+ accountId: item.proposer,
+ showKYC: false,
+ displayImage: false,
+ displayName: false,
instance,
}}
/>
From e1c19caaac9712155871245b5d0fde4c1f54195b Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Thu, 23 Jan 2025 16:13:27 +0530
Subject: [PATCH 27/40] Minor UI fixes (#234)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[Notion link
](https://www.notion.so/17a490b283038084bbd6d98a90cfeb68?v=466c3a17456f49cb9757dd88cace649d)
- Change color for Light up raw in History Table
- Make consistent border radius
- Change Upload logo to “Secondary” Button
- Add “Beta” Label in Header for all instances
- Align “Transaction” column to the right side
---
.../widget/components/Navbar.jsx | 6 ++-
.../widget/components/templates/AppLayout.jsx | 2 +-
.../pages/dashboard/TransactionHistory.jsx | 4 +-
.../widget/pages/settings/Theme.jsx | 40 +++++++++----------
.../widget/pages/settings/Thresholds.jsx | 2 +-
5 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx b/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
index 27d7a709..9bc88a22 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Navbar.jsx
@@ -143,7 +143,11 @@ return (
{getTitle(page ?? "dashboard")}
- {isTesting &&
Testing }
+ {isTesting ? (
+
Testing
+ ) : (
+
Beta
+ )}
diff --git a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
index 5037f4d5..869ee255 100644
--- a/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/templates/AppLayout.jsx
@@ -265,7 +265,7 @@ const Theme = styled.div`
}
.bg-highlight {
- background-color: rgb(185, 185, 185, 0.2);
+ background-color: var(--grey-04) !important;
}
.cursor-pointer {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
index c7526d3e..956e6c63 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
@@ -254,7 +254,7 @@ return (
Type
From
To
- Transaction
+ Transaction
Amount
@@ -338,7 +338,7 @@ return (
}}
/>
-
+
+
Upload Logo
-
-
Upload Logo
-
SVG, PNG, or JPG (256x256 px)
+
+
Upload Logo
+
SVG, PNG, or JPG (256x256 px)
) : (
-
+
) : (
Date: Fri, 24 Jan 2025 14:29:32 -0600
Subject: [PATCH 28/40] feat: speed up chart (#250)
_Resolves #238_
- Lifted up API logic to a parent component
- Upgraded the API on the back end as well here: PR
[6](https://github.com/NEAR-DevHub/ref-sdk-api/pull/6)
---
.../widget/pages/dashboard/Chart.jsx | 92 +++++++++----------
.../widget/pages/dashboard/ChartParent.jsx | 44 +++++++++
.../widget/pages/dashboard/index.jsx | 8 +-
3 files changed, 93 insertions(+), 51 deletions(-)
create mode 100644 instances/widgets.treasury-factory.near/widget/pages/dashboard/ChartParent.jsx
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
index 142bf8f4..29603828 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Chart.jsx
@@ -1,4 +1,14 @@
-const { nearPrice, ftTokens, accountId, title, instance } = props;
+const {
+ nearPrice,
+ ftTokens,
+ accountId,
+ title,
+ instance,
+ allPeriodData,
+ isLoading,
+ selectedToken,
+ setSelectedToken,
+} = props;
if (!instance) {
return <>>;
@@ -13,16 +23,11 @@ const { Skeleton } = VM.require(
if (!Skeleton) {
return <>>;
}
-const API_HOST = "https://ref-sdk-api.fly.dev/api";
+
const [height, setHeight] = useState(350);
const [history, setHistory] = useState([]);
const [tokenAddresses, setTokenAddresses] = useState([]);
-const [selectedPeriod, setSelectedPeriod] = useState({
- value: 24 * 30,
- interval: 12,
-});
-const [selectedToken, setSelectedToken] = useState("near");
-const [isLoading, setIsLoading] = useState(true);
+const [selectedPeriod, setSelectedPeriod] = useState("1Y");
const [balanceDate, setBalanceDate] = useState({ balance: 0, date: "" });
const nearTokenInfo = {
@@ -34,14 +39,14 @@ const tokens = Array.isArray(ftTokens)
? [nearTokenInfo, ...ftTokens]
: [nearTokenInfo];
-const periodMap = [
- { period: "1H", value: 1 / 6, interval: 6 },
- { period: "1D", value: 1, interval: 12 },
- { period: "1W", value: 24, interval: 8 },
- { period: "1M", value: 24 * 2, interval: 15 },
- { period: "1Y", value: 24 * 30, interval: 12 },
- { period: "All", value: 24 * 365, interval: 10 },
-];
+const periodMap = {
+ "1H": { value: 1 / 6, interval: 6 },
+ "1D": { value: 1, interval: 12 },
+ "1W": { value: 24, interval: 8 },
+ "1M": { value: 24 * 2, interval: 15 },
+ "1Y": { value: 24 * 30, interval: 12 },
+ All: { value: 24 * 365, interval: 10 },
+};
function formatCurrency(amount) {
return Number(amount)
@@ -312,24 +317,11 @@ const RadioButton = styled.div`
}
`;
-// Function to fetch data from the API based on the selected period
-async function fetchData() {
- try {
- asyncFetch(
- `${API_HOST}/token-balance-history?account_id=${accountId}&period=${selectedPeriod.value}&interval=${selectedPeriod.interval}&token_id=${selectedToken}`
- ).then((resp) => {
- if (resp?.body) setHistory(resp.body);
- setIsLoading(false);
- });
- } catch (error) {
- console.error("Error fetching data:", error);
- }
-}
-
useEffect(() => {
- setIsLoading(true);
- fetchData();
-}, [selectedToken, selectedPeriod]);
+ if (allPeriodData[selectedPeriod]) {
+ setHistory(allPeriodData[selectedPeriod]);
+ }
+}, [selectedPeriod, allPeriodData]);
const LoadingBalance = () => {
return (
@@ -405,21 +397,23 @@ return (
- {periodMap.map(({ period, value, interval }, idx) => (
-
setSelectedPeriod({ value, interval })}
- className={
- selectedPeriod.value === value &&
- selectedPeriod.interval === interval
- ? "selected"
- : ""
- }
- >
- {period}
-
- ))}
+ {Object.entries(periodMap).map(
+ ([period, { value, interval }], idx) => (
+
setSelectedPeriod(period)}
+ className={
+ periodMap[selectedPeriod].value === value &&
+ periodMap[selectedPeriod].interval === interval
+ ? "selected"
+ : ""
+ }
+ >
+ {period}
+
+ )
+ )}
@@ -462,7 +456,7 @@ return (
)}
- {isLoading || !history.length ? (
+ {isLoading || history.length === 0 ? (
) : (
{
+ setIsLoading(true);
+ try {
+ asyncFetch(
+ `${API_HOST}/all-token-balance-history?account_id=${accountId}&token_id=${selectedToken}`
+ ).then((res) => {
+ setAllPeriodData(res.body);
+ setIsLoading(false);
+ });
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ setIsLoading(false);
+ }
+};
+
+useEffect(() => {
+ fetchAllPeriodData();
+}, [selectedToken]);
+
+return (
+
+);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
index c12d8256..6c0ca8f9 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/index.jsx
@@ -293,7 +293,9 @@ return (
Date: Sat, 25 Jan 2025 01:59:53 +0530
Subject: [PATCH 29/40] Fix the permissions issue (#246)
Resolves #242
- Added more permissions to policy for 'Manage Members'.
- Increased the 'Processing your request' timeout, since for different
wallets, it takes longer to get approved, so to not show error toast
- Fixed the issue which Vova faced where the success toast showed w/o
any transaction since `lastProposalId` was null, and disabled submit
button even after txn success/ updated the test for it
---------
Co-authored-by: Peter Salomonsen
---
.devcontainer/devcontainer.json | 3 +-
.../create-treasury/SummaryStep.jsx | 25 +-
.../widget/components/VoteActions.jsx | 2 +-
.../widget/lib/common.jsx | 2 +-
.../pages/payments/CreatePaymentRequest.jsx | 6 +-
.../settings/DeleteModalConfirmation.jsx | 4 +-
.../widget/pages/settings/MembersEditor.jsx | 6 +-
.../widget/pages/settings/Theme.jsx | 8 +-
.../widget/pages/settings/Thresholds.jsx | 8 +-
.../pages/settings/VotingDurationPage.jsx | 74 ++--
.../stake-delegation/CreateStakeRequest.jsx | 6 +-
.../stake-delegation/CreateUnstakeRequest.jsx | 6 +-
.../CreateWithdrawRequest.jsx | 6 +-
.../settings/create-member-request.spec.js | 60 ++-
.../tests/settings/voting-duration.spec.js | 21 +-
.../treasury-factory/treasury-factory.spec.js | 386 +++++++++++++-----
playwright-tests/util/rpcmock.js | 24 +-
playwright-tests/util/sandboxrpc.js | 34 +-
sandboxrpc/playground/treasuryfactory.js | 3 +-
treasury-factory/tests/test_basics.rs | 46 ++-
20 files changed, 532 insertions(+), 198 deletions(-)
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 3e9a551b..2ef6bda5 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -18,7 +18,8 @@
"extensions": [
"ms-playwright.playwright",
"github.vscode-github-actions",
- "rust-lang.rust-analyzer"
+ "rust-lang.rust-analyzer",
+ "github.copilot"
]
}
},
diff --git a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
index 09786dbb..15188df2 100644
--- a/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
+++ b/instances/treasury-factory.near/widget/components/create-treasury/SummaryStep.jsx
@@ -103,6 +103,7 @@ function filterMemberByPermission(permission) {
.map((acc) => acc.accountId);
}
+// Permissions are set using https://github.com/near-daos/sputnik-dao-contract/blob/main/sputnikdao2/src/proposals.rs#L119
function createDao() {
const createDaoConfig = {
config: {
@@ -117,11 +118,7 @@ function createDao() {
Group: filterMemberByPermission(PERMISSIONS.create),
},
name: "Create Requests",
- permissions: [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {},
},
{
@@ -134,6 +131,16 @@ function createDao() {
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {},
},
@@ -142,7 +149,13 @@ function createDao() {
Group: filterMemberByPermission(PERMISSIONS.vote),
},
name: "Vote",
- permissions: ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ permissions: [
+ "*:VoteReject",
+ "*:VoteApprove",
+ "*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
+ ],
vote_policy: {},
},
],
diff --git a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
index 7b9edd2b..e87900a8 100644
--- a/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/VoteActions.jsx
@@ -102,7 +102,7 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
diff --git a/instances/widgets.treasury-factory.near/widget/lib/common.jsx b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
index 33fb9814..c5340851 100644
--- a/instances/widgets.treasury-factory.near/widget/lib/common.jsx
+++ b/instances/widgets.treasury-factory.near/widget/lib/common.jsx
@@ -381,7 +381,7 @@ function hasPermission(treasuryDaoID, accountId, kindName, actionType) {
if (!accountId) {
return false;
}
- const isAllowed = false;
+ let isAllowed = false;
const daoPolicy = treasuryDaoID
? Near.view(treasuryDaoID, "get_policy", {})
: null;
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
index 92c09ba6..8d343a9b 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/CreatePaymentRequest.jsx
@@ -161,7 +161,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
cleanInputs();
onCloseCanvas();
clearTimeout(errorTimeout);
@@ -180,14 +180,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
useEffect(() => {
const handler = setTimeout(() => {
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
index d7c5579c..3f26edc0 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/DeleteModalConfirmation.jsx
@@ -47,7 +47,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
setToastStatus(true);
setTxnCreated(false);
clearTimeout(errorTimeout);
@@ -63,7 +63,7 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx
index f6799ea9..7ec00f5f 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/MembersEditor.jsx
@@ -57,7 +57,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
setToastStatus(true);
onCloseCanvas();
clearTimeout(errorTimeout);
@@ -74,14 +74,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
function updateDaoPolicy(rolesMap) {
const updatedPolicy = { ...daoPolicy };
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
index c64b390b..7579bdd5 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Theme.jsx
@@ -24,7 +24,7 @@ const { treasuryDaoID, themeColor } = VM.require(
const hasCreatePermission = hasPermission(
treasuryDaoID,
context.accountId,
- "config",
+ "policy",
"AddProposal"
);
@@ -266,7 +266,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
setToastStatus(true);
setTxnCreated(false);
clearTimeout(errorTimeout);
@@ -282,14 +282,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
function toBase64(json) {
return Buffer.from(JSON.stringify(json)).toString("base64");
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
index 54c50c97..9aec1355 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/Thresholds.jsx
@@ -25,7 +25,7 @@ if (typeof getRoleWiseData !== "function") {
const hasEditPermission = hasPermission(
treasuryDaoID,
context.accountId,
- "ChangeConfig",
+ "policy",
"AddProposal"
);
@@ -96,7 +96,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
setToastStatus(true);
setTxnCreated(false);
clearTimeout(errorTimeout);
@@ -112,14 +112,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
function resetForm() {
setSelectedVoteOption(selectedGroup.isRatio ? options[1] : options[0]);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx b/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
index f04437f1..b5e70097 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/settings/VotingDurationPage.jsx
@@ -26,15 +26,25 @@ const daoPolicy = treasuryDaoID
? Near.view(treasuryDaoID, "get_policy", {})
: null;
-const lastProposalId = Near.view(treasuryDaoID, "get_last_proposal_id");
-
const hasCreatePermission = hasPermission(
treasuryDaoID,
context.accountId,
- "policy",
+ "policy_update_parameters",
"AddProposal"
);
+const [lastProposalId, setLastProposalId] = useState(null);
+
+function getLastProposalId() {
+ return Near.asyncView(treasuryDaoID, "get_last_proposal_id").then(
+ (result) => result
+ );
+}
+
+useEffect(() => {
+ getLastProposalId().then((i) => setLastProposalId(i));
+}, []);
+
if (!daoPolicy || lastProposalId === null) {
return (
@@ -61,7 +71,7 @@ const [proposalsThatWillExpire, setProposalsThatWillExpire] = useState([]);
const [proposalsThatWillBeActive, setProposalsThatWillBeActive] = useState([]);
const [otherPendingRequests, setOtherPendingRequests] = useState([]);
const [showToastStatus, setToastStatus] = useState(null);
-const [isSubmittingChangeRequest, setSubmittingChangeRequest] = useState(false);
+const [isTxnCreated, setTxnCreated] = useState(false);
const [showAffectedProposalsModal, setShowAffectedProposalsModal] =
useState(false);
@@ -223,8 +233,9 @@ const findAffectedProposals = (callback) => {
};
function submitVotePolicyChangeTxn() {
+ setLoading(false);
setShowAffectedProposalsModal(false);
- setSubmittingChangeRequest(true);
+ setTxnCreated(true);
const description = {
title: "Update policy - Voting Duration",
summary: `${context.accountId} requested to change voting duration from ${currentDurationDays} to ${durationDays}.`,
@@ -265,35 +276,36 @@ const submitChangeRequest = () => {
};
useEffect(() => {
- if (isSubmittingChangeRequest) {
+ if (isTxnCreated) {
+ let checkTxnTimeout = null;
let errorTimeout = null;
- Near.asyncView(treasuryDaoID, "get_proposal", {
- id: lastProposalId - 1,
- }).then((proposal) => {
- const proposal_period =
- proposal?.kind?.ChangePolicyUpdateParameters?.parameters
- ?.proposal_period;
- if (
- proposal_period &&
- isSubmittingChangeRequest &&
- Number(proposal_period.substring(0, proposal_period.length - 9)) /
- (24 * 60 * 60) ===
- Number(durationDays)
- ) {
- setToastStatus(true);
- setSubmittingChangeRequest(false);
- clearTimeout(errorTimeout);
- }
- });
+ const checkForNewProposal = () => {
+ getLastProposalId().then((id) => {
+ if (typeof lastProposalId === "number" && lastProposalId === id) {
+ setToastStatus(true);
+ setTxnCreated(false);
+ clearTimeout(errorTimeout);
+ } else {
+ checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000);
+ }
+ });
+ };
+ checkForNewProposal();
// if in 20 seconds there is no change, show error condition
errorTimeout = setTimeout(() => {
setShowErrorToast(true);
- setSubmittingChangeRequest(false);
- }, 20000);
+ setTxnCreated(false);
+ clearTimeout(checkTxnTimeout);
+ }, 25_000);
+
+ return () => {
+ clearTimeout(checkTxnTimeout);
+ clearTimeout(errorTimeout);
+ };
}
-}, [isSubmittingChangeRequest, lastProposalId]);
+}, [isTxnCreated, lastProposalId]);
const changeDurationDays = (newDurationDays) => {
setDurationDays(newDurationDays);
@@ -305,7 +317,7 @@ const showImpactedRequests =
return (
setShowErrorToast(false)}
/>
@@ -492,12 +504,12 @@ return (
props={{
classNames: { root: "theme-btn" },
label: "Submit Request",
- loading: showLoader || isSubmittingChangeRequest,
+ loading: showLoader || isTxnCreated,
disabled:
durationDays === currentDurationDays ||
showLoader ||
!hasCreatePermission ||
- isSubmittingChangeRequest,
+ isTxnCreated,
}}
/>
),
@@ -506,7 +518,7 @@ return (
durationDays === currentDurationDays ||
showLoader ||
!hasCreatePermission ||
- isSubmittingChangeRequest,
+ isTxnCreated,
treasuryDaoID,
callbackAction: submitChangeRequest,
}}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
index 89397aa3..8ec71a08 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
@@ -135,7 +135,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
cleanInputs();
onCloseCanvas();
refreshData();
@@ -153,14 +153,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
const BalanceDisplay = ({ label, balance, tooltipInfo, noBorder }) => {
return (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
index 16b050db..58467016 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateUnstakeRequest.jsx
@@ -193,7 +193,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
cleanInputs();
onCloseCanvas();
refreshData();
@@ -211,14 +211,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
const BalanceDisplay = ({ label, balance, tooltipInfo, noBorder }) => {
return (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
index 09e4aae4..0ec81cf4 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateWithdrawRequest.jsx
@@ -123,7 +123,7 @@ useEffect(() => {
const checkForNewProposal = () => {
getLastProposalId().then((id) => {
- if (lastProposalId !== id) {
+ if (typeof lastProposalId === "number" && lastProposalId !== id) {
cleanInputs();
onCloseCanvas();
refreshData();
@@ -141,14 +141,14 @@ useEffect(() => {
setShowErrorToast(true);
setTxnCreated(false);
clearTimeout(checkTxnTimeout);
- }, 20000);
+ }, 25_000);
return () => {
clearTimeout(checkTxnTimeout);
clearTimeout(errorTimeout);
};
}
-}, [isTxnCreated]);
+}, [isTxnCreated, lastProposalId]);
const BalanceDisplay = ({ label, balance, tooltipInfo, noBorder }) => {
return (
diff --git a/playwright-tests/tests/settings/create-member-request.spec.js b/playwright-tests/tests/settings/create-member-request.spec.js
index 8f706da1..1710c1fa 100644
--- a/playwright-tests/tests/settings/create-member-request.spec.js
+++ b/playwright-tests/tests/settings/create-member-request.spec.js
@@ -214,11 +214,7 @@ test.describe("User is logged in", function () {
"testingaccount.near",
],
},
- permissions: [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {
upgrade_remote: votePolicy,
upgrade_self: votePolicy,
@@ -249,6 +245,16 @@ test.describe("User is logged in", function () {
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {
upgrade_remote: votePolicy,
@@ -280,7 +286,13 @@ test.describe("User is logged in", function () {
"test05.near",
],
},
- permissions: ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ permissions: [
+ "*:VoteReject",
+ "*:VoteApprove",
+ "*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
+ ],
vote_policy: {
transfer: votePolicy,
config: votePolicy,
@@ -492,11 +504,7 @@ test.describe("User is logged in", function () {
"petersalomonsen.near",
],
},
- permissions: [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {
transfer: votePolicy,
bounty_done: votePolicy,
@@ -527,6 +535,16 @@ test.describe("User is logged in", function () {
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {
upgrade_remote: votePolicy,
@@ -562,6 +580,8 @@ test.describe("User is logged in", function () {
"*:VoteReject",
"*:VoteApprove",
"*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
],
vote_policy: {
transfer: votePolicy,
@@ -639,11 +659,7 @@ test.describe("User is logged in", function () {
"petersalomonsen.near",
],
},
- permissions: [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {
transfer: votePolicy,
bounty_done: votePolicy,
@@ -673,6 +689,16 @@ test.describe("User is logged in", function () {
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {
upgrade_remote: votePolicy,
@@ -707,6 +733,8 @@ test.describe("User is logged in", function () {
"*:VoteReject",
"*:VoteApprove",
"*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
],
vote_policy: {
transfer: votePolicy,
diff --git a/playwright-tests/tests/settings/voting-duration.spec.js b/playwright-tests/tests/settings/voting-duration.spec.js
index b05590c0..0adbdf7f 100644
--- a/playwright-tests/tests/settings/voting-duration.spec.js
+++ b/playwright-tests/tests/settings/voting-duration.spec.js
@@ -159,7 +159,7 @@ test.describe("User is logged in", function () {
instanceAccount,
daoAccount,
}) => {
- test.setTimeout(150_000);
+ test.setTimeout(200_000);
const daoName = daoAccount.split(".")[0];
const sandbox = new SandboxRPC();
await sandbox.init();
@@ -185,7 +185,8 @@ test.describe("User is logged in", function () {
.fill(newDurationDays.toString());
await page.waitForTimeout(500);
- await page.locator("button", { hasText: "Submit" }).click();
+ const submitBtn = page.locator("button", { hasText: "Submit" });
+ await submitBtn.click();
await page
.locator(".modalfooter button", { hasText: "Yes, proceed" })
@@ -210,7 +211,6 @@ test.describe("User is logged in", function () {
});
await page.getByRole("button", { name: "Confirm" }).click();
-
const transactionToSend = await transactionToSendPromise;
const transactionResult = await sandbox.account.functionCall({
@@ -219,15 +219,24 @@ test.describe("User is logged in", function () {
args: transactionToSend.actions[0].params.args,
attachedDeposit: transactionToSend.actions[0].params.deposit,
});
-
+ const lastProposalId = await sandbox.getLastProposalId(daoName);
await page.evaluate((transactionResult) => {
window.transactionSentPromiseResolve(transactionResult);
}, transactionResult);
- await expect(page.getByText("Processing your request ...")).toBeVisible();
+ await mockRpcRequest({
+ page,
+ filterParams: {
+ method_name: "get_last_proposal_id",
+ },
+ modifyOriginalResultFunction: () => {
+ return lastProposalId;
+ },
+ });
+
await expect(
page.getByText("Voting duration change request submitted")
).toBeVisible();
-
+ await expect(submitBtn).toBeEnabled();
await sandbox.quitSandbox();
});
diff --git a/playwright-tests/tests/treasury-factory/treasury-factory.spec.js b/playwright-tests/tests/treasury-factory/treasury-factory.spec.js
index e7ad5467..75eae26a 100644
--- a/playwright-tests/tests/treasury-factory/treasury-factory.spec.js
+++ b/playwright-tests/tests/treasury-factory/treasury-factory.spec.js
@@ -1,100 +1,304 @@
-import { test, expect } from '@playwright/test';
-import { SandboxRPC } from '../../util/sandboxrpc';
-import { getLocalWidgetSource } from '../../util/bos-workspace';
-import nearApi from 'near-api-js';
+import { test, expect } from "@playwright/test";
+import { SandboxRPC } from "../../util/sandboxrpc";
+import { getLocalWidgetSource } from "../../util/bos-workspace";
+import nearApi from "near-api-js";
-test("should be able to create a treasury instance with sandbox", async () => {
- const sandbox = new SandboxRPC();
- await sandbox.init();
+async function approveProposal({ daoContract, sandbox, proposalId }) {
+ // Check if the proposalId is a valid number
+ expect(Number(proposalId)).not.toBeNaN();
+ const result = await sandbox.account.functionCall({
+ contractId: daoContract,
+ methodName: "act_proposal",
+ args: {
+ id: proposalId,
+ action: "VoteApprove",
+ },
+ gas: 300000000000000,
+ });
+ // there shouldn't be any error in proposal execution
+ expect(
+ result.receipts_outcome.filter(
+ (receipt_outcome) => receipt_outcome.outcome.status.Failure,
+ ).length,
+ ).toBe(0);
+}
- const widget_reference_account_id = 'treasury-testing.near';
+function toBase64(json) {
+ return Buffer.from(JSON.stringify(json)).toString("base64");
+}
- await sandbox.setupWidgetReferenceAccount(widget_reference_account_id);
+test("should be able to create a treasury instance with sandbox, and create/execute all types of proposals", async () => {
+ test.setTimeout(200_000)
+ const sandbox = new SandboxRPC();
+ await sandbox.init();
- const instance_name = "test-factory-created-instance";
- const create_dao_args = {
- "config": {
- "name": instance_name,
- "purpose": "creating dao treasury",
- "metadata": "",
+ const widget_reference_account_id = "treasury-testing.near";
+
+ await sandbox.setupWidgetReferenceAccount(widget_reference_account_id);
+
+ const instance_name = "test-factory-created-instance";
+ const policy = {
+ roles: [
+ {
+ kind: {
+ Group: [sandbox.account.accountId],
+ },
+ name: "Create Requests",
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
+ vote_policy: {},
+ },
+ {
+ kind: {
+ Group: [sandbox.account.accountId],
},
- "policy": {
- "roles": [
- {
- "kind": {
- "Group": ["acc3.near", "acc2.near", "acc1.near"],
- },
- "name": "Create Requests",
- "permissions": [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
- "vote_policy": {},
+ name: "Manage Members",
+ permissions: [
+ "config:*",
+ "policy_update_parameters:*",
+ "add_bounty:*",
+ "remove_member_from_role:*",
+ "upgrade_self:*",
+ "policy_remove_role:*",
+ "set_vote_token:*",
+ "upgrade_remote:*",
+ "bounty_done:*",
+ "add_member_to_role:*",
+ "factory_info_update:*",
+ "policy:*",
+ "policy_add_or_update_role:*",
+ "policy_update_default_vote_policy:*",
+ ],
+ vote_policy: {},
+ },
+ {
+ kind: {
+ Group: [sandbox.account.accountId],
+ },
+ name: "Vote",
+ permissions: [
+ "*:VoteReject",
+ "*:VoteApprove",
+ "*:RemoveProposal",
+ "*:VoteRemove",
+ "*:Finalize",
+ ],
+ vote_policy: {},
+ },
+ ],
+ default_vote_policy: {
+ weight_kind: "RoleWeight",
+ quorum: "0",
+ threshold: [1, 2],
+ },
+ proposal_bond: "0",
+ proposal_period: "604800000000000",
+ bounty_bond: "100000000000000000000000",
+ bounty_forgiveness_period: "604800000000000",
+ };
+ const create_dao_args = {
+ config: {
+ name: instance_name,
+ purpose: "creating dao treasury",
+ metadata: "",
+ },
+ policy: policy,
+ };
+
+ const createInstanceResult = await sandbox.account.functionCall({
+ contractId: "treasury-factory.near",
+ methodName: "create_instance",
+ args: {
+ sputnik_dao_factory_account_id: "sputnik-dao.near",
+ social_db_account_id: "social.near",
+ widget_reference_account_id: widget_reference_account_id,
+ name: instance_name,
+ create_dao_args: Buffer.from(JSON.stringify(create_dao_args)).toString(
+ "base64",
+ ),
+ },
+ gas: 300000000000000,
+ attachedDeposit: nearApi.utils.format.parseNearAmount("9"),
+ });
+
+ expect(
+ createInstanceResult.receipts_outcome.filter(
+ (receipt_outcome) => receipt_outcome.outcome.status.Failure,
+ ).length,
+ ).toBe(0);
+
+ const web4GetResult = await sandbox.account.viewFunction({
+ contractId: `${instance_name}.near`,
+ methodName: "web4_get",
+ args: { request: { path: "/" } },
+ });
+ expect(
+ Buffer.from(web4GetResult.body, "base64")
+ .toString()
+ .substring(0, "".length),
+ ).toEqual("");
+
+ const daoGetPolicyResult = await sandbox.account.viewFunction({
+ contractId: `${instance_name}.sputnik-dao.near`,
+ methodName: "get_policy",
+ args: {},
+ });
+ expect(daoGetPolicyResult).toEqual(create_dao_args.policy);
+
+ const referenceWidgetSources = await getLocalWidgetSource(
+ widget_reference_account_id + "/widget/**",
+ );
+
+ const socialGetResult = await sandbox.account.viewFunction({
+ contractId: "social.near",
+ methodName: "get",
+ args: {
+ keys: [`${instance_name}.near/widget/**`],
+ },
+ });
+
+ expect(JSON.stringify(socialGetResult)).toEqual(
+ JSON.stringify(referenceWidgetSources).replaceAll(
+ widget_reference_account_id,
+ instance_name + ".near",
+ ),
+ );
+ const daoContract = `${instance_name}.sputnik-dao.near`;
+ // ChangeConfig proposal
+ let changeConfigProposalId = Number.parseInt(
+ Buffer.from(
+ (
+ await sandbox.account.functionCall({
+ contractId: daoContract,
+ methodName: "add_proposal",
+ args: {
+ proposal: {
+ description: "* Title: Update Config - Theme & logo",
+ kind: {
+ ChangeConfig: {
+ config: {
+ name: "Tesing DAO",
+ purpose: "Testing purpose",
+ metadata: toBase64({
+ primaryColor: "#0000",
+ flagLogo:
+ "https://ipfs.near.social/ipfs/bafkreiboarigt5w26y5jyxyl4au7r2dl76o5lrm2jqjgqpooakck5xsojq",
+ theme: "light",
+ }),
+ },
},
- {
- "kind": {
- "Group": ["acc1.near"],
- },
- "name": "Manage Members",
- "permissions": [
- "config:*",
- "policy:*",
- "add_member_to_role:*",
- "remove_member_from_role:*",
- ],
- "vote_policy": {},
+ },
+ },
+ },
+ attachedDeposit: "0",
+ gas: 300000000000000,
+ })
+ ).status.SuccessValue,
+ "base64",
+ ).toString(),
+ );
+ await approveProposal({
+ sandbox,
+ daoContract,
+ proposalId: changeConfigProposalId,
+ });
+
+ // ChangePolicy
+ let changePolicyProposalId = Number.parseInt(
+ Buffer.from(
+ (
+ await sandbox.account.functionCall({
+ contractId: daoContract,
+ methodName: "add_proposal",
+ args: {
+ proposal: {
+ description: "Update policy - Members Permissions",
+ kind: {
+ ChangePolicy: {
+ policy: policy,
},
- {
- "kind": {
- "Group": ["acc1.near", "acc2.near"],
- },
- "name": "Vote",
- "permissions": ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
- "vote_policy": {},
+ },
+ },
+ },
+ attachedDeposit: "0",
+ gas: 300000000000000,
+ })
+ ).status.SuccessValue,
+ "base64",
+ ).toString(),
+ );
+
+ await approveProposal({
+ sandbox,
+ daoContract,
+ proposalId: changePolicyProposalId,
+ });
+
+ // ChangePolicyUpdateParameters
+ let changePolicyParametersProposalId = Number.parseInt(
+ Buffer.from(
+ (
+ await sandbox.account.functionCall({
+ contractId: daoContract,
+ methodName: "add_proposal",
+ args: {
+ proposal: {
+ description:
+ "* Title: Update policy - Voting Duration * Summary: theori.near requested to change voting duration from 7 to 10",
+ kind: {
+ ChangePolicyUpdateParameters: {
+ parameters: {
+ proposal_period:
+ (60 * 60 * 24 * 10).toString() + "000000000",
+ },
},
- ],
- "default_vote_policy": {
- "weight_kind": "RoleWeight",
- "quorum": "0",
- "threshold": [1, 2],
+ },
},
- "proposal_bond": "100000000000000000000000",
- "proposal_period": "604800000000000",
- "bounty_bond": "100000000000000000000000",
- "bounty_forgiveness_period": "604800000000000",
- },
- };
-
- const createInstanceResult = await sandbox.account.functionCall({
- contractId: "treasury-factory.near", methodName: 'create_instance', args: {
- "sputnik_dao_factory_account_id": "sputnik-dao.near",
- "social_db_account_id": "social.near",
- "widget_reference_account_id": widget_reference_account_id,
- "name": instance_name,
- "create_dao_args": Buffer.from(JSON.stringify(create_dao_args)).toString('base64')
- },
- gas: 300000000000000,
- attachedDeposit: nearApi.utils.format.parseNearAmount("9")
- });
-
- expect(
- createInstanceResult.receipts_outcome.filter(receipt_outcome => receipt_outcome.outcome.status.Failure).length
- ).toBe(0);
-
- const web4GetResult = await sandbox.account.viewFunction({ contractId: `${instance_name}.near`, methodName: 'web4_get', args: { request: { path: "/" } } });
- expect(Buffer.from(web4GetResult.body, 'base64').toString().substring(0, "".length)).toEqual("");
-
- const daoGetPolicyResult = await sandbox.account.viewFunction({contractId: `${instance_name}.sputnik-dao.near`, methodName: 'get_policy', args: {}});
- expect(daoGetPolicyResult).toEqual(create_dao_args.policy);
-
- const referenceWidgetSources = await getLocalWidgetSource(widget_reference_account_id + "/widget/**");
-
- const socialGetResult = await sandbox.account.viewFunction({contractId: 'social.near', methodName: 'get', args: {
- "keys": [`${instance_name}.near/widget/**`]
- }});
-
- expect(JSON.stringify(socialGetResult)).toEqual(JSON.stringify(referenceWidgetSources).replaceAll(widget_reference_account_id, instance_name+".near"));
-
- await sandbox.quitSandbox();
-});
\ No newline at end of file
+ },
+ attachedDeposit: "0",
+ gas: 300000000000000,
+ })
+ ).status.SuccessValue,
+ "base64",
+ ).toString(),
+ );
+ await approveProposal({
+ sandbox,
+ daoContract,
+ proposalId: changePolicyParametersProposalId,
+ });
+
+ // Transfer
+ let transferProposalId = Number.parseInt(
+ Buffer.from(
+ (
+ await sandbox.account.functionCall({
+ contractId: daoContract,
+ methodName: "add_proposal",
+ args: {
+ proposal: {
+ description:
+ "* Title: Fellowship Contributor report by Matias Benary for 2024-09-09 2024-09-29 * Summary: Fellowship Contributor report by Matias Benary for 2024-09-09 2024-09-29 * Proposal Id: 215",
+ kind: {
+ Transfer: {
+ amount: nearApi.utils.format.parseNearAmount("0.5"),
+ receiver_id: daoContract,
+ token_id: "",
+ },
+ },
+ },
+ },
+ attachedDeposit: "0",
+ gas: 300000000000000,
+ })
+ ).status.SuccessValue,
+ "base64",
+ ).toString(),
+ );
+ await approveProposal({
+ sandbox,
+ daoContract,
+ proposalId: transferProposalId,
+ });
+
+ await sandbox.quitSandbox();
+});
diff --git a/playwright-tests/util/rpcmock.js b/playwright-tests/util/rpcmock.js
index 5e56e15f..0542b7d5 100644
--- a/playwright-tests/util/rpcmock.js
+++ b/playwright-tests/util/rpcmock.js
@@ -78,11 +78,7 @@ export function getMockedPolicy(
"petersalomonsen.near",
],
},
- permissions: [
- "call:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {
transfer: createRequestPolicy,
bounty_done: createRequestPolicy,
@@ -113,6 +109,16 @@ export function getMockedPolicy(
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {
upgrade_remote: membersPolicy,
@@ -144,7 +150,13 @@ export function getMockedPolicy(
"test05.near",
],
},
- permissions: ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ permissions: [
+ "*:VoteReject",
+ "*:VoteApprove",
+ "*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
+ ],
vote_policy: {
transfer: votePolicy,
config: votePolicy,
diff --git a/playwright-tests/util/sandboxrpc.js b/playwright-tests/util/sandboxrpc.js
index f97bad2b..f7c63260 100644
--- a/playwright-tests/util/sandboxrpc.js
+++ b/playwright-tests/util/sandboxrpc.js
@@ -106,6 +106,14 @@ export class SandboxRPC {
});
}
+ async getLastProposalId(daoName) {
+ return this.account.viewFunction({
+ contractId: `${daoName}.${SPUTNIK_DAO_CONTRACT_ID}`,
+ methodName: "get_last_proposal_id",
+ args: {},
+ });
+ }
+
async setupLockupContract(owner_account_id) {
await this.account.functionCall({
contractId: "lockup-whitelist.near",
@@ -204,11 +212,7 @@ export class SandboxRPC {
Group: [this.account.accountId],
},
name: "Create Requests",
- permissions: [
- "*:AddProposal",
- "transfer:AddProposal",
- "config:Finalize",
- ],
+ permissions: ["call:AddProposal", "transfer:AddProposal"],
vote_policy: {},
},
{
@@ -221,6 +225,16 @@ export class SandboxRPC {
"policy:*",
"add_member_to_role:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "upgrade_remote:*",
+ "set_vote_token:*",
+ "add_bounty:*",
+ "bounty_done:*",
+ "factory_info_update:*",
+ "policy_add_or_update_role:*",
+ "policy_remove_role:*",
+ "policy_update_default_vote_policy:*",
+ "policy_update_parameters:*",
],
vote_policy: {},
},
@@ -229,7 +243,13 @@ export class SandboxRPC {
Group: [this.account.accountId],
},
name: "Vote",
- permissions: ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ permissions: [
+ "*:VoteReject",
+ "*:VoteApprove",
+ "*:VoteRemove",
+ "*:RemoveProposal",
+ "*:Finalize",
+ ],
vote_policy: {},
},
],
@@ -253,7 +273,7 @@ export class SandboxRPC {
args: Buffer.from(JSON.stringify(createDaoConfig)).toString("base64"),
},
gas: 300000000000000,
- attachedDeposit: utils.format.parseNearAmount("6"),
+ attachedDeposit: utils.format.parseNearAmount("8"),
});
}
diff --git a/sandboxrpc/playground/treasuryfactory.js b/sandboxrpc/playground/treasuryfactory.js
index 01a64fac..e9c154ef 100644
--- a/sandboxrpc/playground/treasuryfactory.js
+++ b/sandboxrpc/playground/treasuryfactory.js
@@ -52,7 +52,6 @@ const create_dao_args = {
"permissions": [
"call:AddProposal",
"transfer:AddProposal",
- "config:Finalize",
],
"vote_policy": {},
},
@@ -74,7 +73,7 @@ const create_dao_args = {
"Group": ["acc1.near", "acc2.near"],
},
"name": "Vote",
- "permissions": ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ "permissions": ["*:VoteReject", "*:VoteApprove", "*:VoteRemove", "*:RemoveProposal", "*:Finalize"],
"vote_policy": {},
},
],
diff --git a/treasury-factory/tests/test_basics.rs b/treasury-factory/tests/test_basics.rs
index 34e15558..8f2df26c 100644
--- a/treasury-factory/tests/test_basics.rs
+++ b/treasury-factory/tests/test_basics.rs
@@ -38,6 +38,27 @@ pub struct Web4Response {
body: String,
}
+fn normalize_json(value: &mut Value) {
+ match value {
+ Value::Array(arr) => {
+ for elem in arr.iter_mut() {
+ normalize_json(elem); // Recursively normalize elements
+ }
+ arr.sort_by(|a, b| {
+ serde_json::to_string(a)
+ .unwrap()
+ .cmp(&serde_json::to_string(b).unwrap())
+ }); // Sort array without moving it
+ }
+ Value::Object(map) => {
+ for val in map.values_mut() {
+ normalize_json(val); // Recursively normalize values
+ }
+ }
+ _ => {} // Do nothing for other types
+ }
+}
+
#[tokio::test]
async fn test_web4() -> Result<(), Box> {
let sandbox = near_workspaces::sandbox().await?;
@@ -176,7 +197,6 @@ async fn test_factory() -> Result<(), Box> {
"permissions": [
"call:AddProposal",
"transfer:AddProposal",
- "config:Finalize",
],
"vote_policy": {},
},
@@ -187,9 +207,19 @@ async fn test_factory() -> Result<(), Box> {
"name": "Manage Members",
"permissions": [
"config:*",
- "policy:*",
- "add_member_to_role:*",
+ "policy_update_parameters:*",
+ "add_bounty:*",
"remove_member_from_role:*",
+ "upgrade_self:*",
+ "policy_remove_role:*",
+ "set_vote_token:*",
+ "upgrade_remote:*",
+ "bounty_done:*",
+ "add_member_to_role:*",
+ "factory_info_update:*",
+ "policy:*",
+ "policy_add_or_update_role:*",
+ "policy_update_default_vote_policy:*"
],
"vote_policy": {},
},
@@ -198,7 +228,7 @@ async fn test_factory() -> Result<(), Box> {
"Group": ["acc1.near", "acc2.near"],
},
"name": "Vote",
- "permissions": ["*:VoteReject", "*:VoteApprove", "*:VoteRemove"],
+ "permissions": ["*:VoteReject", "*:VoteApprove", "*:VoteRemove", "*:RemoveProposal", "*:Finalize"],
"vote_policy": {},
},
],
@@ -296,7 +326,13 @@ async fn test_factory() -> Result<(), Box> {
.await?;
let policy: Value = get_policy_result.json().unwrap();
- assert_eq!(create_dao_args["policy"], policy);
+ let mut create_dao_policy = create_dao_args["policy"].clone();
+ let mut expected_policy = policy.clone();
+
+ normalize_json(&mut create_dao_policy);
+ normalize_json(&mut expected_policy);
+
+ assert_eq!(create_dao_policy, expected_policy);
let deployed_widgets = socialdb
.call("get")
From 31e4303bd43ae66401548ee81ca2e44565f2884a Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Sat, 25 Jan 2025 02:05:05 +0530
Subject: [PATCH 30/40] Fix stake delegation refresh on create request (#233)
Resolves #248
- Added hover to 'Create request' dropdown
- Fix the refresh issue with create stake request, update tests to use
sandboxrpc to create proposals
[video.webm](https://github.com/user-attachments/assets/563cfb7d-5e27-42e2-b5f1-fbe8029754fa)
[video.webm](https://github.com/user-attachments/assets/d5f319d1-deb4-4fbf-b471-6fa255f1fddd)
---
.github/workflows/test.yml | 4 +
.../pages/stake-delegation/CreateButton.jsx | 66 +----
.../stake-delegation/CreateStakeRequest.jsx | 2 +-
.../stake-delegation/PendingRequests.jsx | 20 +-
.../widget/pages/stake-delegation/Table.jsx | 2 +-
.../stake-delegation/stake-delegation.spec.js | 278 +++++++++++++-----
playwright-tests/util/sandboxrpc.js | 105 ++++++-
7 files changed, 326 insertions(+), 151 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 962fbe11..97edc524 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -97,6 +97,10 @@ jobs:
npx playwright install
- name: Build project
run: npm run build
+ - name: Build sandbox
+ run: |
+ npm run build:sandbox
+ continue-on-error: false
- name: Run tests
run: |
${{ matrix.target_account.test_command }}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
index 9f2be3b2..e58680df 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateButton.jsx
@@ -108,58 +108,11 @@ const CreateBtn = () => {
border: none !important;
}
- .options-card {
- display: none;
- position: absolute;
- top: 100%;
- left: 0;
- width: 100%;
- border: 1px solid var(--border-color);
- background-color: var(--bg-page-color) !important;
- color: var(--text-color) !important;
- z-index: 99;
- opacity: 0;
- font-size: 14px;
- transform: translateY(-10px);
- transition: opacity 0.2s ease, transform 0.2s ease;
-
- &.visible {
- display: block;
- opacity: 1;
- transform: translateY(0);
- z-index:1000;
- }
- }
-
.left {
right: 0 !important;
left: auto !important;
}
-
- @media screen and (max-width: 768px) {
- .options-card {
- right: 0 !important;
- left: auto !important;
- }
- }
-
- .option {
- color: var(--text-color) !important;
- margin-block: 5px;
- padding: 10px;
- cursor: pointer;
- border-bottom: 1px solid var(--border-color);
- transition: background-color 0.3s ease;
- }
-
- .option:hover {
- background-color: var(--bs-dropdown-link-hover-bg);
- }
-
- .option:last-child {
- border-bottom: none;
- }
-
+
.selected {
background-color: var(--grey-04);
}
@@ -178,30 +131,35 @@ const CreateBtn = () => {
a:hover {
text-decoration: none;
}
-
}
`;
return (
setCreateBtnOpen(false)}
>
-
+
{btnOptions.map((option) => (
-
+
{option.icon}
{option.label}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
index 8ec71a08..03bbca78 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/CreateStakeRequest.jsx
@@ -138,8 +138,8 @@ useEffect(() => {
if (typeof lastProposalId === "number" && lastProposalId !== id) {
cleanInputs();
onCloseCanvas();
- refreshData();
clearTimeout(errorTimeout);
+ refreshData();
setTxnCreated(false);
} else {
checkTxnTimeout = setTimeout(() => checkForNewProposal(), 1000);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx
index 277397f7..96e7481c 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/PendingRequests.jsx
@@ -18,13 +18,19 @@ const [totalLength, setTotalLength] = useState(null);
const [loading, setLoading] = useState(false);
const [isPrevPageCalled, setIsPrevCalled] = useState(false);
-const refreshTableData = Storage.get(
- "REFRESH_TABLE_DATA",
- `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.payments.CreatePaymentRequest`
+const refreshStakeTableData = Storage.get(
+ "REFRESH_STAKE_TABLE_DATA",
+ `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.stake-delegation.CreateStakeRequest`
);
-const refreshVoteTableData = Storage.get(
- "REFRESH__VOTE_ACTION_TABLE_DATA",
- `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.VoteActions`
+
+const refreshUnstakeTableData = Storage.get(
+ "REFRESH_STAKE_TABLE_DATA",
+ `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.stake-delegation.CreateUnstakeRequest`
+);
+
+const refreshWithdrawTableData = Storage.get(
+ "REFRESH_STAKE_TABLE_DATA",
+ `${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.stake-delegation.CreateWithdrawRequest`
);
const fetchProposals = useCallback(() => {
@@ -62,7 +68,7 @@ useEffect(() => {
setOffset(null);
setPage(0);
fetchProposals();
-}, [refreshTableData]);
+}, [refreshStakeTableData, refreshUnstakeTableData, refreshWithdrawTableData]);
const policy = treasuryDaoID
? Near.view(treasuryDaoID, "get_policy", {})
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
index 4ee32de9..632afcf3 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Table.jsx
@@ -110,7 +110,7 @@ const Container = styled.div`
color: inherit !important;
}
`;
-div;
+
function checkProposalStatus(proposalId) {
Near.asyncView(treasuryDaoID, "get_proposal", {
id: proposalId,
diff --git a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
index 1bae8674..87e870dd 100644
--- a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
+++ b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
@@ -21,6 +21,7 @@ import {
import { setDontAskAgainCacheValues } from "../../util/cache.js";
import Big from "big.js";
import { InsufficientBalance } from "../../util/lib.js";
+import { SandboxRPC } from "../../util/sandboxrpc.js";
test.afterEach(async ({ page }, testInfo) => {
console.log(`Finished ${testInfo.title} with status ${testInfo.status}`);
@@ -242,8 +243,8 @@ async function openWithdrawForm({
lockupContract,
}) {
await expect(page.getByText("Create Request", { exact: true })).toBeVisible();
- await page.locator(".primary-button").click();
- await page.locator(".options-card > div:nth-child(3)").click();
+ await page.locator(".dropdown").first().click();
+ await page.locator(".dropdown-menu > div:nth-child(3)").click();
await expect(
page.getByRole("heading", { name: "Create Withdraw Request" })
).toBeVisible(10_000);
@@ -255,8 +256,8 @@ async function openWithdrawForm({
async function openUnstakeForm({ page, isLockup, daoAccount, lockupContract }) {
await expect(page.getByText("Create Request", { exact: true })).toBeVisible();
- await page.locator(".primary-button").click();
- await page.getByText("Unstake", { exact: true }).click();
+ await page.locator(".dropdown").first().click();
+ await page.locator(".dropdown-menu > div:nth-child(2)").click();
await expect(
page.getByRole("heading", { name: "Create Unstake Request" })
).toBeVisible(10_000);
@@ -266,6 +267,19 @@ async function openUnstakeForm({ page, isLockup, daoAccount, lockupContract }) {
}
}
+async function openStakeForm({ page, isLockup, daoAccount, lockupContract }) {
+ await expect(page.getByText("Create Request", { exact: true })).toBeVisible();
+ await page.locator(".dropdown").first().click();
+ await page.locator(".dropdown-menu > div:nth-child(1)").click();
+ await expect(
+ page.getByRole("heading", { name: "Create Stake Request" })
+ ).toBeVisible(10_000);
+ await page.waitForTimeout(10_000);
+ if (isLockup) {
+ await selectLockupAccount({ page, daoAccount, lockupContract });
+ }
+}
+
async function fillValidatorAccount({ page }) {
// validator dropdown shouldn't take more than 20 seconds
const poolSelector = await page.getByTestId("validator-dropdown");
@@ -401,6 +415,80 @@ async function voteOnProposal({
);
}
+async function checkNewProposalSubmission({
+ page,
+ sandbox,
+ checkforMultiProposals,
+ daoAccount,
+ daoName,
+}) {
+ const transactionToSendPromise = page.evaluate(async () => {
+ const selector = await document.querySelector("near-social-viewer")
+ .selectorPromise;
+
+ const wallet = await selector.wallet();
+
+ return new Promise((resolve) => {
+ wallet.signAndSendTransaction = async (transaction) => {
+ resolve(transaction);
+ return await new Promise(
+ (transactionSentPromiseResolve) =>
+ (window.transactionSentPromiseResolve =
+ transactionSentPromiseResolve)
+ );
+ };
+ });
+ });
+
+ await page.getByRole("button", { name: "Confirm" }).click();
+ const transactionToSend = await transactionToSendPromise;
+
+ const transactionResult = await sandbox.account.functionCall({
+ contractId: daoAccount,
+ methodName: "add_proposal",
+ args: transactionToSend.actions[0].params.args,
+ attachedDeposit: transactionToSend.actions[0].params.deposit,
+ });
+ const lastProposalId = await sandbox.getLastProposalId(daoName);
+
+ await page.evaluate(async (transactionResult) => {
+ window.transactionSentPromiseResolve(transactionResult);
+ }, transactionResult);
+ await mockRpcRequest({
+ page,
+ filterParams: {
+ method_name: "get_last_proposal_id",
+ },
+ modifyOriginalResultFunction: () => {
+ return lastProposalId;
+ },
+ });
+ await expect(page.locator("div.modal-body code").nth(0)).toBeAttached({
+ attached: false,
+ timeout: 10_000,
+ });
+ await expect(page.locator(".spinner-border")).toBeAttached({
+ attached: false,
+ timeout: 10_000,
+ });
+ await expect(page.locator(".offcanvas-body")).toBeVisible({
+ visible: false,
+ });
+ await expect(
+ page
+ .getByRole("cell", { name: `${lastProposalId - 1}`, exact: true })
+ .first()
+ ).toBeVisible({ timeout: 20_000 });
+
+ if (checkforMultiProposals) {
+ await expect(
+ page
+ .getByRole("cell", { name: `${lastProposalId - 2}`, exact: true })
+ .first()
+ ).toBeVisible({ timeout: 20_000 });
+ }
+}
+
test.describe("Have valid staked requests and sufficient token balance", function () {
test.beforeEach(async ({ page, instanceAccount, daoAccount }, testInfo) => {
const instanceConfig = await getInstanceConfig({ page, instanceAccount });
@@ -412,6 +500,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio
console.log("no stake delegation page configured for instance");
return test.skip();
}
+
if (
testInfo.title.includes("Should successfully parse old JSON description")
) {
@@ -468,21 +557,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio
test.describe("Admin connected", function () {
test.use({
storageState:
- "playwright-tests/storage-states/wallet-connected-admin.json",
- });
-
- const lastProposalId = 10;
- test.beforeEach(async ({ page }) => {
- await mockRpcRequest({
- page,
- filterParams: {
- method_name: "get_last_proposal_id",
- },
- modifyOriginalResultFunction: (originalResult) => {
- originalResult = lastProposalId;
- return originalResult;
- },
- });
+ "playwright-tests/storage-states/wallet-connected-admin-with-accesskey.json",
});
test("insufficient account balance should show warning modal, disallow action ", async ({
@@ -507,16 +582,18 @@ test.describe("Have valid staked requests and sufficient token balance", functio
).toBeVisible();
});
- test("Should create stake delegation request, should throw error when invalid data is provided", async ({
+ test("Should create stake delegation request, should throw error when invalid data is provided, should show in table after submission", async ({
page,
+ daoAccount,
}) => {
- test.setTimeout(100_000);
- const createRequestButton = await page.getByText("Create Request", {
- exact: true,
- });
- await createRequestButton.click();
- await page.locator(".option").first().click();
- await page.waitForTimeout(10_000);
+ test.setTimeout(200_000);
+ const daoName = daoAccount.split(".")[0];
+ const sandbox = new SandboxRPC();
+ await sandbox.init();
+ await sandbox.attachRoutes(page);
+ await sandbox.setupSandboxForSputnikDao(daoName);
+
+ await openStakeForm({ page });
await fillValidatorAccount({
page,
@@ -531,9 +608,13 @@ test.describe("Have valid staked requests and sufficient token balance", functio
.locator('input[placeholder="Enter amount"]')
.first()
.inputValue();
+ await sandbox.addStakeRequestProposal({
+ stakedPoolAccount,
+ stakingAmount,
+ daoName,
+ });
await page.getByRole("button", { name: "Submit" }).click();
- await expect(page.getByText("Processing your request ...")).toBeVisible();
- await expect(await getTransactionModalObject(page)).toEqual({
+ const expectedTransactionModalObject = {
proposal: {
description: "* Proposal Action: stake",
kind: {
@@ -550,14 +631,29 @@ test.describe("Have valid staked requests and sufficient token balance", functio
},
},
},
- });
+ };
+ await expect(await getTransactionModalObject(page)).toEqual(
+ expectedTransactionModalObject
+ );
+
+ await checkNewProposalSubmission({ page, sandbox, daoAccount, daoName });
+ await sandbox.quitSandbox();
});
- test("Should create unstake delegation request, should throw error when invalid data is provided", async ({
+ test("Should create unstake delegation request, should throw error when invalid data is provided, should show in table after submission", async ({
page,
+ daoAccount,
instanceAccount,
}) => {
- test.setTimeout(120_000);
+ test.setTimeout(200_000);
+ const daoName = daoAccount.split(".")[0];
+ const sandbox = new SandboxRPC();
+ await sandbox.init();
+ await sandbox.attachRoutes(page);
+ await sandbox.setupSandboxForSputnikDao(daoName);
+ const args = "eyJhbW91bnQiOiIzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifQ==";
+ const description = `* Proposal Action: withdraw
* Show After Proposal Id Approved: 0
* Custom Notes: Following to [#0](/${instanceAccount}/widget/app?page=stake-delegation&selectedTab=History&highlightProposalId=0) unstake request`;
+
await openUnstakeForm({ page });
await fillValidatorAccount({
page,
@@ -568,9 +664,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio
errorText: "The amount exceeds the balance you have staked.",
});
await page.getByRole("button", { name: "Submit" }).click();
- await expect(page.getByText("Processing your request ...")).toBeVisible();
-
- await expect(await getTransactionModalObject(page)).toEqual({
+ const expectedTransactionModalObject = {
proposal: {
description: "* Proposal Action: unstake",
kind: {
@@ -579,7 +673,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio
actions: [
{
method_name: "unstake",
- args: "eyJhbW91bnQiOiIzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifQ==",
+ args: args,
deposit: "0",
gas: "200000000000000",
},
@@ -587,15 +681,18 @@ test.describe("Have valid staked requests and sufficient token balance", functio
},
},
},
- });
+ };
+ await expect(await getTransactionModalObject(page)).toEqual(
+ expectedTransactionModalObject
+ );
const txnLocator = await page
.locator("div.modal-body code")
.nth(1)
.innerText();
const dataReceived = JSON.parse(txnLocator);
- expect(dataReceived).toEqual({
+ const expectedTransaction2ModalObject = {
proposal: {
- description: `* Proposal Action: withdraw
* Show After Proposal Id Approved: ${lastProposalId}
* Custom Notes: Following to [#${lastProposalId}](/${instanceAccount}/widget/app?page=stake-delegation&selectedTab=History&highlightProposalId=${lastProposalId}) unstake request`,
+ description: description,
kind: {
FunctionCall: {
receiver_id: stakedPoolAccount,
@@ -610,7 +707,28 @@ test.describe("Have valid staked requests and sufficient token balance", functio
},
},
},
+ };
+ await expect(dataReceived).toEqual(expectedTransaction2ModalObject);
+ await sandbox.addUnstakeRequestProposal({
+ stakedPoolAccount,
+ functionCallArgs: args,
+ daoName,
});
+ await sandbox.addWithdrawRequestProposal({
+ stakedPoolAccount,
+ description: description,
+ daoName,
+ });
+
+ await checkNewProposalSubmission({
+ page,
+ sandbox,
+ daoAccount,
+ daoName,
+ checkforMultiProposals: true,
+ });
+
+ await sandbox.quitSandbox();
});
});
});
@@ -669,11 +787,21 @@ test.describe("Withdraw request", function () {
await expect(page.getByRole("button", { name: "Submit" })).toBeDisabled();
});
- test("Have valid withdraw tokens from one pool", async ({
+ test("Have valid withdraw tokens from one pool, should show in table after submission", async ({
page,
daoAccount,
}) => {
- test.setTimeout(150_000);
+ test.setTimeout(200_000);
+ const daoName = daoAccount.split(".")[0];
+ const sandbox = new SandboxRPC();
+ await sandbox.init();
+ await sandbox.attachRoutes(page);
+ await sandbox.setupSandboxForSputnikDao(daoName);
+ await sandbox.addWithdrawRequestProposal({
+ stakedPoolAccount,
+ description: `* Proposal Action: withdraw`,
+ daoName,
+ });
await mockUnstakeAndWithdrawBalance({
page,
hasUnstakeBalance: true,
@@ -686,8 +814,7 @@ test.describe("Withdraw request", function () {
const submitBtn = page.getByRole("button", { name: "Submit" });
await expect(submitBtn).toBeEnabled();
await submitBtn.dblclick();
- await expect(page.getByText("Processing your request ...")).toBeVisible();
- await expect(await getTransactionModalObject(page)).toEqual({
+ const expectedTransactionModalObject = {
proposal: {
description: `* Proposal Action: withdraw`,
kind: {
@@ -704,7 +831,12 @@ test.describe("Withdraw request", function () {
},
},
},
- });
+ };
+ await expect(await getTransactionModalObject(page)).toEqual(
+ expectedTransactionModalObject
+ );
+ await checkNewProposalSubmission({ page, sandbox, daoAccount, daoName });
+ await sandbox.quitSandbox();
});
test("Have valid withdraw tokens from multiple pools", async ({
@@ -712,7 +844,24 @@ test.describe("Withdraw request", function () {
daoAccount,
instanceAccount,
}) => {
- test.setTimeout(150_000);
+ test.setTimeout(200_000);
+ const daoName = daoAccount.split(".")[0];
+ const sandbox = new SandboxRPC();
+ await sandbox.init();
+ await sandbox.attachRoutes(page);
+ await sandbox.setupSandboxForSputnikDao(daoName);
+ const description = `* Proposal Action: withdraw`;
+ await sandbox.addWithdrawRequestProposal({
+ stakedPoolAccount,
+ description,
+ daoName,
+ });
+ await sandbox.addWithdrawRequestProposal({
+ stakedPoolAccount: multiStakedPoolAccount,
+ description,
+ daoName,
+ });
+
const instanceConfig = await getInstanceConfig({
page,
instanceAccount,
@@ -744,7 +893,6 @@ test.describe("Withdraw request", function () {
const submitBtn = page.getByRole("button", { name: "Submit" });
await expect(submitBtn).toBeEnabled();
await submitBtn.dblclick();
- await expect(page.getByText("Processing your request ...")).toBeVisible();
// proposals for both the pools
await expect(await getTransactionModalObject(page)).toEqual({
proposal: {
@@ -788,6 +936,14 @@ test.describe("Withdraw request", function () {
},
},
});
+ await checkNewProposalSubmission({
+ page,
+ sandbox,
+ daoAccount,
+ daoName,
+ checkforMultiProposals: true,
+ });
+ await sandbox.quitSandbox();
});
test("Vote on withdraw request, when amount is not ready", async ({
@@ -821,34 +977,8 @@ test.describe("Withdraw request", function () {
});
});
-async function openLockupStakingForm({
- page,
- daoAccount,
- lockupContract,
- instanceAccount,
-}) {
- const createRequestButton = await page.getByText("Create Request", {
- exact: true,
- });
- await createRequestButton.click();
- const widgetsAccount =
- (instanceAccount.includes("testing") === true
- ? "test-widgets"
- : "widgets") + ".treasury-factory.near";
-
- await page
- .locator(
- `div[data-component="${widgetsAccount}/widget/pages.stake-delegation.CreateButton"] .option`,
- { hasText: "Stake" }
- )
- .first()
- .click();
- await page.waitForTimeout(10_000);
- await selectLockupAccount({
- page,
- daoAccount,
- lockupContract,
- });
+async function openLockupStakingForm({ page, daoAccount, lockupContract }) {
+ await openStakeForm({ page, isLockup: true, daoAccount, lockupContract });
await expect(
page.getByText(
"You cannot split your locked funds across multiple validators."
diff --git a/playwright-tests/util/sandboxrpc.js b/playwright-tests/util/sandboxrpc.js
index f7c63260..4f8f6365 100644
--- a/playwright-tests/util/sandboxrpc.js
+++ b/playwright-tests/util/sandboxrpc.js
@@ -106,14 +106,6 @@ export class SandboxRPC {
});
}
- async getLastProposalId(daoName) {
- return this.account.viewFunction({
- contractId: `${daoName}.${SPUTNIK_DAO_CONTRACT_ID}`,
- methodName: "get_last_proposal_id",
- args: {},
- });
- }
-
async setupLockupContract(owner_account_id) {
await this.account.functionCall({
contractId: "lockup-whitelist.near",
@@ -285,6 +277,23 @@ export class SandboxRPC {
});
}
+ async getLastProposalId(daoName) {
+ return this.account.viewFunction({
+ contractId: `${daoName}.${SPUTNIK_DAO_CONTRACT_ID}`,
+ methodName: "get_last_proposal_id",
+ args: {},
+ });
+ }
+
+ async addProposal({ daoName, args }) {
+ await this.account.functionCall({
+ contractId: `${daoName}.${SPUTNIK_DAO_CONTRACT_ID}`,
+ methodName: "add_proposal",
+ args,
+ attachedDeposit: PROPOSAL_BOND,
+ });
+ }
+
async addPaymentRequestProposal({
title,
summary,
@@ -305,14 +314,82 @@ export class SandboxRPC {
},
},
};
- await this.account.functionCall({
- contractId: `${daoName}.${SPUTNIK_DAO_CONTRACT_ID}`,
- methodName: "add_proposal",
- args,
- attachedDeposit: PROPOSAL_BOND,
- });
+ await this.addProposal({ daoName, args });
}
+ async addStakeRequestProposal({ stakedPoolAccount, stakingAmount, daoName }) {
+ const args = {
+ proposal: {
+ description: "* Proposal Action: stake",
+ kind: {
+ FunctionCall: {
+ receiver_id: stakedPoolAccount,
+ actions: [
+ {
+ method_name: "deposit_and_stake",
+ args: "",
+ deposit: utils.format.parseNearAmount(stakingAmount),
+ gas: "200000000000000",
+ },
+ ],
+ },
+ },
+ },
+ };
+ await this.addProposal({ daoName, args });
+ }
+
+ async addUnstakeRequestProposal({
+ stakedPoolAccount,
+ functionCallArgs,
+ daoName,
+ }) {
+ const args = {
+ proposal: {
+ description: "* Proposal Action: unstake",
+ kind: {
+ FunctionCall: {
+ receiver_id: stakedPoolAccount,
+ actions: [
+ {
+ method_name: "unstake",
+ args: functionCallArgs,
+ deposit: "0",
+ gas: "200000000000000",
+ },
+ ],
+ },
+ },
+ },
+ };
+ await this.addProposal({ daoName, args });
+ }
+
+ async addWithdrawRequestProposal({
+ stakedPoolAccount,
+ description,
+ daoName,
+ }) {
+ const args = {
+ proposal: {
+ description: description,
+ kind: {
+ FunctionCall: {
+ receiver_id: stakedPoolAccount,
+ actions: [
+ {
+ method_name: "withdraw_all",
+ args: "",
+ deposit: "0",
+ gas: "200000000000000",
+ },
+ ],
+ },
+ },
+ },
+ };
+ await this.addProposal({ daoName, args });
+ }
/**
* Time travel forward with the specified number of blocks
* @param {number} numBlocks
From d835a91cd35658f81b71573dd4844d4128668dfe Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Tue, 28 Jan 2025 02:51:56 +0530
Subject: [PATCH 31/40] Fix stake loading issues (#256)
Resolves #179
- Moved validators dropdown (for stake requests) to iframe for better
performance, and also switched to pikespeak API, and added real time
input validation
- Defined all colors in `common` and then using it in all widgets
---
.../widget/app.jsx | 22 +-
.../widget/components/OverlayTrigger.jsx | 8 +-
.../widget/components/StakedNearIframe.jsx | 75 +--
.../widget/components/TokensDropdown.jsx | 2 +-
.../widget/components/templates/AppLayout.jsx | 150 +-----
.../widget/lib/common.jsx | 134 ++++-
.../widget/pages/dashboard/Chart.jsx | 23 +-
.../pages/dashboard/TransactionHistory.jsx | 2 +-
.../widget/pages/payments/Table.jsx | 2 +-
.../stake-delegation/CreateStakeRequest.jsx | 241 +++------
.../stake-delegation/CreateUnstakeRequest.jsx | 183 ++-----
.../CreateWithdrawRequest.jsx | 53 +-
.../pages/stake-delegation/Validator.jsx | 2 +-
.../ValidatorsDropDownWithSearch.jsx | 507 ++++++++++++++++++
.../pages/stake-delegation/WalletDropdown.jsx | 2 +-
.../stake-delegation/stake-delegation.spec.js | 211 +++++---
16 files changed, 976 insertions(+), 641 deletions(-)
create mode 100644 instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
diff --git a/instances/widgets.treasury-factory.near/widget/app.jsx b/instances/widgets.treasury-factory.near/widget/app.jsx
index d2fcc990..593402b9 100644
--- a/instances/widgets.treasury-factory.near/widget/app.jsx
+++ b/instances/widgets.treasury-factory.near/widget/app.jsx
@@ -13,10 +13,6 @@ const { AppLayout } = VM.require(
const instance = "${REPL_INSTANCE}";
const treasuryDaoID = "${REPL_TREASURY}";
-const { Theme } = VM.require(`${instance}/widget/config.css`) || {
- Theme: () => <>>,
-};
-
if (!page) {
// If no page is specified, we default to the feed page TEMP
page = "dashboard";
@@ -84,14 +80,12 @@ function Page() {
}
return (
-
-
-
-
-
+
+
+
);
diff --git a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
index 1aa6916e..37ea2634 100644
--- a/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/OverlayTrigger.jsx
@@ -3,9 +3,9 @@ const { instance } = props;
if (!instance) {
return <>>;
}
-const { getColors } = VM.require(
- "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/components.templates.AppLayout"
-) || { getColors: () => {} };
+const { getAllColorsAsCSSVariables } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common"
+) || { getAllColorsAsCSSVariables: () => {} };
const { treasuryDaoID } = VM.require(`${instance}/widget/config.data`);
const config = treasuryDaoID ? Near.view(treasuryDaoID, "get_config") : null;
@@ -44,7 +44,7 @@ const overlayStyle = props.overlayStyle ?? {
};
const ThemeColorsContainer = styled.div`
- ${() => getColors(isDarkTheme, "", "")}
+ ${() => getAllColorsAsCSSVariables(isDarkTheme, "")}
`;
const overlay = (
diff --git a/instances/widgets.treasury-factory.near/widget/components/StakedNearIframe.jsx b/instances/widgets.treasury-factory.near/widget/components/StakedNearIframe.jsx
index e445d33f..aa2a0a60 100644
--- a/instances/widgets.treasury-factory.near/widget/components/StakedNearIframe.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/StakedNearIframe.jsx
@@ -168,42 +168,45 @@ const code = `
`;
-const iframe = (
-
);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx
index fde57b6e..c5845066 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/Validator.jsx
@@ -5,7 +5,7 @@ const { isBosGateway } = VM.require(
const validatorId = props.validatorId;
const pikespeakKey = isBosGateway()
? "${REPL_PIKESPEAK_KEY}"
- : props.pikespeakKey;
+ : props.pikespeakKey ?? "263f0c69-69e2-4919-ae02-d8ca7a696da2";
if (!pikespeakKey) {
return (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
new file mode 100644
index 00000000..558a6eab
--- /dev/null
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
@@ -0,0 +1,507 @@
+const { getAllColorsAsObject } = VM.require(
+ "${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/lib.common"
+);
+
+const treasuryDaoID = props.treasuryDaoID ?? "";
+const instance = props.instance ?? "";
+const options = props.options ?? [];
+const onSubmit = props.onSubmit ?? (() => {});
+const onCancel = props.onCancel ?? (() => {});
+const config = treasuryDaoID ? Near.view(treasuryDaoID, "get_config") : null;
+const metadata = JSON.parse(atob(config.metadata ?? ""));
+const isDarkTheme = metadata.theme === "dark";
+
+const { themeColor } = VM.require(`${instance}/widget/config.data`) || {
+ themeColor: "",
+};
+
+if (
+ !Array.isArray(options) ||
+ !options?.length ||
+ typeof getAllColorsAsObject !== "function"
+) {
+ return (
+
+
+
+ );
+}
+const primaryColor = metadata?.primaryColor
+ ? metadata?.primaryColor
+ : themeColor;
+
+const colors = getAllColorsAsObject(isDarkTheme, primaryColor);
+const code = `
+
+
+
+
+
+
Dropdown Component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Available to unstake:
+
+
+
+
+ Notes
+
+
+
+
+ Cancel
+ Submit
+
+
+
+
+
+
+`;
+
+State.init({
+ height: "350px",
+});
+
+return (
+
{
+ switch (e.handler) {
+ case "onCancel": {
+ onCancel();
+ }
+ case "onSubmit": {
+ onSubmit(e.validatorAccount, e.amount, e.notes);
+ }
+ case "updateIframeHeight": {
+ State.update({ height: e.height });
+ }
+ }
+ }}
+ />
+);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
index f6f8f396..5c7bb822 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
@@ -24,7 +24,7 @@ const nearPrice = useCache(
).then((res) => {
return res.body.near?.usd;
}),
- "price",
+ "near-price",
{ subscribe: false }
);
diff --git a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
index 87e870dd..06f56518 100644
--- a/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
+++ b/playwright-tests/tests/stake-delegation/stake-delegation.spec.js
@@ -242,7 +242,9 @@ async function openWithdrawForm({
daoAccount,
lockupContract,
}) {
- await expect(page.getByText("Create Request", { exact: true })).toBeVisible();
+ await expect(page.getByText("Create Request", { exact: true })).toBeVisible({
+ timeout: 10_000,
+ });
await page.locator(".dropdown").first().click();
await page.locator(".dropdown-menu > div:nth-child(3)").click();
await expect(
@@ -281,27 +283,46 @@ async function openStakeForm({ page, isLockup, daoAccount, lockupContract }) {
}
async function fillValidatorAccount({ page }) {
- // validator dropdown shouldn't take more than 20 seconds
- const poolSelector = await page.getByTestId("validator-dropdown");
- await expect(poolSelector).toBeVisible({ timeout: 20_000 });
+ // validator dropdown shouldn't take more than 10 seconds
+ const poolSelector = await page
+ .frameLocator("iframe")
+ .nth(1)
+ .locator("#dropdown");
+ await expect(poolSelector).toBeVisible({ timeout: 10_000 });
await poolSelector.click();
- await page.waitForTimeout(5_000);
+ await page.waitForTimeout(1_000);
- const search = await page.getByPlaceholder("Search");
+ const search = await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByPlaceholder("Search options");
search.focus();
search.fill("astro");
- await page.getByText(stakedPoolAccount).first().click();
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByText(stakedPoolAccount)
+ .first()
+ .click();
}
async function checkForStakeAmount({ page, errorText, availableBalance }) {
- const submitBtn = page.getByRole("button", { name: "Submit" });
- const stakeAmount = page.getByRole("spinbutton");
+ const submitBtn = page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" });
+ const stakeAmount = page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByPlaceholder("Enter amount");
await stakeAmount.fill((parseFloat(availableBalance) + 2).toString());
- await stakeAmount.blur();
- const amountErrorText = page.getByText(errorText);
- await expect(amountErrorText).toBeVisible();
+ const amountErrorText = page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByText(errorText);
+ await expect(amountErrorText).toBeVisible({ timeout: 10_000 });
await expect(submitBtn).toBeDisabled();
- await page.getByText("Use Max").click();
+ await page.frameLocator("iframe").nth(1).getByText("Use Max").click();
await expect(amountErrorText).toBeHidden();
}
@@ -418,51 +439,46 @@ async function voteOnProposal({
async function checkNewProposalSubmission({
page,
sandbox,
- checkforMultiProposals,
+ checkforMultiProposals = false,
daoAccount,
daoName,
}) {
- const transactionToSendPromise = page.evaluate(async () => {
+ const method = checkforMultiProposals
+ ? "signAndSendTransactions"
+ : "signAndSendTransaction";
+
+ const transactionToSendPromise = page.evaluate(async (method) => {
const selector = await document.querySelector("near-social-viewer")
.selectorPromise;
const wallet = await selector.wallet();
return new Promise((resolve) => {
- wallet.signAndSendTransaction = async (transaction) => {
+ wallet[method] = async (transaction) => {
resolve(transaction);
- return await new Promise(
- (transactionSentPromiseResolve) =>
- (window.transactionSentPromiseResolve =
- transactionSentPromiseResolve)
- );
+ return new Promise((transactionSentPromiseResolve) => {
+ window.transactionSentPromiseResolve = transactionSentPromiseResolve;
+ });
};
});
- });
+ }, method);
await page.getByRole("button", { name: "Confirm" }).click();
const transactionToSend = await transactionToSendPromise;
+ const transaction = checkforMultiProposals
+ ? transactionToSend.transactions[0]
+ : transactionToSend;
const transactionResult = await sandbox.account.functionCall({
contractId: daoAccount,
methodName: "add_proposal",
- args: transactionToSend.actions[0].params.args,
- attachedDeposit: transactionToSend.actions[0].params.deposit,
+ args: transaction.actions[0].params.args,
+ attachedDeposit: transaction.actions[0].params.deposit,
});
- const lastProposalId = await sandbox.getLastProposalId(daoName);
-
await page.evaluate(async (transactionResult) => {
window.transactionSentPromiseResolve(transactionResult);
}, transactionResult);
- await mockRpcRequest({
- page,
- filterParams: {
- method_name: "get_last_proposal_id",
- },
- modifyOriginalResultFunction: () => {
- return lastProposalId;
- },
- });
+ const lastProposalId = await sandbox.getLastProposalId(daoName);
await expect(page.locator("div.modal-body code").nth(0)).toBeAttached({
attached: false,
timeout: 10_000,
@@ -557,7 +573,7 @@ test.describe("Have valid staked requests and sufficient token balance", functio
test.describe("Admin connected", function () {
test.use({
storageState:
- "playwright-tests/storage-states/wallet-connected-admin-with-accesskey.json",
+ "playwright-tests/storage-states/wallet-connected-admin.json",
});
test("insufficient account balance should show warning modal, disallow action ", async ({
@@ -586,13 +602,17 @@ test.describe("Have valid staked requests and sufficient token balance", functio
page,
daoAccount,
}) => {
- test.setTimeout(200_000);
+ test.setTimeout(250_000);
const daoName = daoAccount.split(".")[0];
const sandbox = new SandboxRPC();
await sandbox.init();
await sandbox.attachRoutes(page);
await sandbox.setupSandboxForSputnikDao(daoName);
-
+ await sandbox.addStakeRequestProposal({
+ stakedPoolAccount,
+ stakingAmount: "11.00",
+ daoName,
+ });
await openStakeForm({ page });
await fillValidatorAccount({
@@ -605,15 +625,17 @@ test.describe("Have valid staked requests and sufficient token balance", functio
});
const stakingAmount = await page
+ .frameLocator("iframe")
+ .nth(1)
.locator('input[placeholder="Enter amount"]')
.first()
.inputValue();
- await sandbox.addStakeRequestProposal({
- stakedPoolAccount,
- stakingAmount,
- daoName,
- });
- await page.getByRole("button", { name: "Submit" }).click();
+
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" })
+ .click();
const expectedTransactionModalObject = {
proposal: {
description: "* Proposal Action: stake",
@@ -632,10 +654,10 @@ test.describe("Have valid staked requests and sufficient token balance", functio
},
},
};
+
await expect(await getTransactionModalObject(page)).toEqual(
expectedTransactionModalObject
);
-
await checkNewProposalSubmission({ page, sandbox, daoAccount, daoName });
await sandbox.quitSandbox();
});
@@ -645,15 +667,24 @@ test.describe("Have valid staked requests and sufficient token balance", functio
daoAccount,
instanceAccount,
}) => {
- test.setTimeout(200_000);
+ test.setTimeout(250_000);
const daoName = daoAccount.split(".")[0];
const sandbox = new SandboxRPC();
await sandbox.init();
await sandbox.attachRoutes(page);
await sandbox.setupSandboxForSputnikDao(daoName);
const args = "eyJhbW91bnQiOiIzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifQ==";
- const description = `* Proposal Action: withdraw * Show After Proposal Id Approved: 0 * Custom Notes: Following to [#0](/${instanceAccount}/widget/app?page=stake-delegation&selectedTab=History&highlightProposalId=0) unstake request`;
-
+ const description = `* Proposal Action: withdraw * Show After Proposal Id Approved: 2 * Custom Notes: Following to [#2](/${instanceAccount}/widget/app?page=stake-delegation&selectedTab=History&highlightProposalId=2) unstake request`;
+ await sandbox.addUnstakeRequestProposal({
+ stakedPoolAccount,
+ functionCallArgs: args,
+ daoName,
+ });
+ await sandbox.addWithdrawRequestProposal({
+ stakedPoolAccount,
+ description: description,
+ daoName,
+ });
await openUnstakeForm({ page });
await fillValidatorAccount({
page,
@@ -663,7 +694,11 @@ test.describe("Have valid staked requests and sufficient token balance", functio
availableBalance: stakedNear,
errorText: "The amount exceeds the balance you have staked.",
});
- await page.getByRole("button", { name: "Submit" }).click();
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" })
+ .click();
const expectedTransactionModalObject = {
proposal: {
description: "* Proposal Action: unstake",
@@ -709,16 +744,6 @@ test.describe("Have valid staked requests and sufficient token balance", functio
},
};
await expect(dataReceived).toEqual(expectedTransaction2ModalObject);
- await sandbox.addUnstakeRequestProposal({
- stakedPoolAccount,
- functionCallArgs: args,
- daoName,
- });
- await sandbox.addWithdrawRequestProposal({
- stakedPoolAccount,
- description: description,
- daoName,
- });
await checkNewProposalSubmission({
page,
@@ -764,7 +789,6 @@ test.describe("Withdraw request", function () {
).toBeVisible({
timeout: 10_000,
});
- await expect(page.getByRole("button", { name: "Submit" })).toBeDisabled();
});
test("Unstaked tokens are not ready to be withdrawn, show warning screen", async ({
@@ -784,14 +808,13 @@ test.describe("Withdraw request", function () {
).toBeVisible({
timeout: 10_000,
});
- await expect(page.getByRole("button", { name: "Submit" })).toBeDisabled();
});
test("Have valid withdraw tokens from one pool, should show in table after submission", async ({
page,
daoAccount,
}) => {
- test.setTimeout(200_000);
+ test.setTimeout(250_000);
const daoName = daoAccount.split(".")[0];
const sandbox = new SandboxRPC();
await sandbox.init();
@@ -844,7 +867,15 @@ test.describe("Withdraw request", function () {
daoAccount,
instanceAccount,
}) => {
- test.setTimeout(200_000);
+ test.setTimeout(250_000);
+ const instanceConfig = await getInstanceConfig({
+ page,
+ instanceAccount,
+ });
+ if (instanceConfig.lockupContract) {
+ console.log("lockup contract found for instance");
+ return test.skip();
+ }
const daoName = daoAccount.split(".")[0];
const sandbox = new SandboxRPC();
await sandbox.init();
@@ -861,17 +892,9 @@ test.describe("Withdraw request", function () {
description,
daoName,
});
-
- const instanceConfig = await getInstanceConfig({
- page,
- instanceAccount,
- });
- if (instanceConfig.lockupContract) {
- console.log("lockup contract found for instance");
- return test.skip();
- }
- await page.goto(`/${instanceAccount}/widget/app?page=stake-delegation`);
+ await updateDaoPolicyMembers({ page });
await mockStakedPools({ daoAccount, page, multiplePools: true });
+ await page.goto(`/${instanceAccount}/widget/app?page=stake-delegation`);
await mockUnstakeAndWithdrawBalance({
page,
hasUnstakeBalance: true,
@@ -980,9 +1003,12 @@ test.describe("Withdraw request", function () {
async function openLockupStakingForm({ page, daoAccount, lockupContract }) {
await openStakeForm({ page, isLockup: true, daoAccount, lockupContract });
await expect(
- page.getByText(
- "You cannot split your locked funds across multiple validators."
- )
+ page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByText(
+ "You cannot split your locked funds across multiple validators."
+ )
).toBeVisible({
timeout: 10_000,
});
@@ -1069,7 +1095,11 @@ test.describe("Lockup staking", function () {
availableBalance: formatNearAmount(sufficientAvailableBalance),
errorText: "Your account doesn't have sufficient balance.",
});
- await page.getByRole("button", { name: "Submit" }).click();
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" })
+ .click();
await expect(page.getByText("Processing your request ...")).toBeVisible();
await expect(await getTransactionModalObject(page)).toEqual({
@@ -1179,8 +1209,12 @@ test.describe("Lockup staking", function () {
lockupContract,
instanceAccount,
});
- await page.waitForTimeout(20_000);
- const poolSelector = page.locator(".custom-select").first();
+ await page.waitForTimeout(2_000);
+ const poolSelector = page
+ .frameLocator("iframe")
+ .nth(1)
+ .locator(".custom-select")
+ .first();
await expect(poolSelector).toBeVisible({ timeout: 20_000 });
const hasDisabledClassOnChild = await poolSelector
.locator(".disabled")
@@ -1191,7 +1225,11 @@ test.describe("Lockup staking", function () {
availableBalance: formatNearAmount(sufficientAvailableBalance),
errorText: "Your account doesn't have sufficient balance.",
});
- await page.getByRole("button", { name: "Submit" }).click();
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" })
+ .click();
await expect(page.getByText("Processing your request ...")).toBeVisible();
await expect(await getTransactionModalObject(page)).toEqual({
@@ -1229,8 +1267,11 @@ test.describe("Lockup staking", function () {
daoAccount,
lockupContract,
});
- await page.waitForTimeout(10_000);
- const poolSelector = await page.locator(".custom-select");
+ await page.waitForTimeout(2_000);
+ const poolSelector = await page
+ .frameLocator("iframe")
+ .nth(1)
+ .locator(".custom-select");
const hasDisabledClassOnChild = await poolSelector
.locator(".disabled")
.count();
@@ -1240,7 +1281,11 @@ test.describe("Lockup staking", function () {
availableBalance: stakedNear,
errorText: "The amount exceeds the balance you have staked.",
});
- await page.getByRole("button", { name: "Submit" }).click();
+ await page
+ .frameLocator("iframe")
+ .nth(1)
+ .getByRole("button", { name: "Submit" })
+ .click();
await expect(page.getByText("Processing your request ...")).toBeVisible();
await expect(await getTransactionModalObject(page)).toEqual({
From 356716fa67eb188d04034a0e1413ebbe79db8c86 Mon Sep 17 00:00:00 2001
From: Megha <100185149+Megha-Dev-19@users.noreply.github.com>
Date: Wed, 29 Jan 2025 15:26:55 +0530
Subject: [PATCH 32/40] Fix dashboard loading (#257)
Resolves #241
Added endpoints
[here](https://github.com/NEAR-DevHub/ref-sdk-api/pull/7)
---
.../aliases.mainnet.json | 3 +-
.../aliases.mainnet.json | 3 +-
.../widget/components/Profile.jsx | 5 +-
.../widget/pages/dashboard/ChartParent.jsx | 3 +-
.../widget/pages/dashboard/Portfolio.jsx | 5 +-
.../pages/dashboard/TransactionHistory.jsx | 139 ++++-------------
.../widget/pages/dashboard/index.jsx | 145 +++++++++++++-----
.../pages/payments/CreatePaymentRequest.jsx | 7 +-
.../widget/pages/payments/Table.jsx | 5 +-
.../pages/stake-delegation/WalletDropdown.jsx | 6 +-
.../tests/dashboard/home-page.spec.js | 23 ++-
.../payments/create-payment-request.spec.js | 4 +
playwright-tests/util/inventory.js | 58 +++----
playwright-tests/util/nearblocks.js | 19 ++-
playwright-tests/util/rpcmock.js | 57 ++++---
15 files changed, 245 insertions(+), 237 deletions(-)
diff --git a/instances/test-widgets.treasury-factory.near/aliases.mainnet.json b/instances/test-widgets.treasury-factory.near/aliases.mainnet.json
index 21939138..cce305d1 100644
--- a/instances/test-widgets.treasury-factory.near/aliases.mainnet.json
+++ b/instances/test-widgets.treasury-factory.near/aliases.mainnet.json
@@ -10,5 +10,6 @@
"REPL_RPC_URL": "https://rpc.mainnet.near.org",
"REPL_PROPOSALS_CACHE_URL": "https://devhub-cache-api-rs.fly.dev",
"REPL_PIKESPEAK_KEY": "36f2b87a-7ee6-40d8-80b9-5e68e587a5b5",
- "REPL_NEARBLOCKS_KEY": "DA2570E26C0242FF897A463F4DCAACA6"
+ "REPL_NEARBLOCKS_KEY": "DA2570E26C0242FF897A463F4DCAACA6",
+ "REPL_BACKEND_API": "https://ref-sdk-api.fly.dev/api"
}
diff --git a/instances/widgets.treasury-factory.near/aliases.mainnet.json b/instances/widgets.treasury-factory.near/aliases.mainnet.json
index d06e4301..c9f5ca5d 100644
--- a/instances/widgets.treasury-factory.near/aliases.mainnet.json
+++ b/instances/widgets.treasury-factory.near/aliases.mainnet.json
@@ -10,5 +10,6 @@
"REPL_RPC_URL": "https://rpc.mainnet.near.org",
"REPL_PROPOSALS_CACHE_URL": "https://devhub-cache-api-rs.fly.dev",
"REPL_PIKESPEAK_KEY": "36f2b87a-7ee6-40d8-80b9-5e68e587a5b5",
- "REPL_NEARBLOCKS_KEY": "DA2570E26C0242FF897A463F4DCAACA6"
+ "REPL_NEARBLOCKS_KEY": "DA2570E26C0242FF897A463F4DCAACA6",
+ "REPL_BACKEND_API": "https://ref-sdk-api.fly.dev/api"
}
diff --git a/instances/widgets.treasury-factory.near/widget/components/Profile.jsx b/instances/widgets.treasury-factory.near/widget/components/Profile.jsx
index 595cf921..ecbaea1d 100644
--- a/instances/widgets.treasury-factory.near/widget/components/Profile.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/Profile.jsx
@@ -11,6 +11,7 @@ const showKYC = props.showKYC;
const accountId = props.accountId;
const displayName = props.displayName ?? true;
const displayImage = props.displayImage ?? true;
+const width = props.width ?? null;
const [isVerfied, setIsVerfied] = useState(false);
const [verificationStatus, setVerificationStatus] = useState(null);
@@ -116,7 +117,7 @@ const HoverCard = () => {
const ReceiverAccountComponent = (
{displayImage && (
@@ -130,7 +131,7 @@ const ReceiverAccountComponent = (
{displayName &&
{name}
}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/ChartParent.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/ChartParent.jsx
index fb3aff0b..b6604dd0 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/ChartParent.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/ChartParent.jsx
@@ -1,6 +1,5 @@
const { nearPrice, ftTokens, accountId, title, instance, totalBalance } = props;
-const API_HOST = "https://ref-sdk-api.fly.dev/api";
const [allPeriodData, setAllPeriodData] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [selectedToken, setSelectedToken] = useState("near");
@@ -10,7 +9,7 @@ const fetchAllPeriodData = async () => {
setIsLoading(true);
try {
asyncFetch(
- `${API_HOST}/all-token-balance-history?account_id=${accountId}&token_id=${selectedToken}`
+ `${REPL_BACKEND_API}/all-token-balance-history?account_id=${accountId}&token_id=${selectedToken}`
).then((res) => {
setAllPeriodData(res.body);
setIsLoading(false);
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
index d1fe2262..8b9e7f77 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/Portfolio.jsx
@@ -298,10 +298,7 @@ const NearPortfolio = () => {
};
const isLoading =
- ftTokens === null ||
- nearStakedTokens === null ||
- nearBalances === null ||
- nearPrice === null;
+ ftTokens === null || nearBalances === null || nearPrice === null;
return (
diff --git a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
index e7a30001..cf998608 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/dashboard/TransactionHistory.jsx
@@ -36,20 +36,6 @@ const loading = (
);
-function sortByDate(items) {
- const groupedItems = items ? [...items] : [];
-
- // Sort by timestamp in descending order
- const sortedItems = groupedItems.sort((a, b) => {
- const timestampA = parseInt(a.timestamp, 10);
- const timestampB = parseInt(b.timestamp, 10);
-
- return timestampB - timestampA;
- });
-
- return sortedItems;
-}
-
// use BOS open API for gateway and paid for web4
const pikespeakKey = isBosGateway()
? "${REPL_PIKESPEAK_KEY}"
@@ -66,78 +52,18 @@ function setAPIError() {
useEffect(() => {
if (!showMoreLoading) {
- const options = {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- "x-api-key": pikespeakKey,
- },
- };
- const promises = [];
setShowMoreLoading(true);
- promises.push(
- asyncFetch(
- `https://api.pikespeak.ai/account/near-transfer/${treasuryDaoID}?limit=${totalTxnsPerPage}&offset=${
- totalTxnsPerPage * (page - 1)
- }`,
- options
- )
- );
-
- promises.push(
- asyncFetch(
- `https://api.pikespeak.ai/account/ft-transfer/${treasuryDaoID}?limit=${totalTxnsPerPage}&offset=${
- totalTxnsPerPage * (page - 1)
- }`,
- options
- )
- );
-
- if (lockupContract) {
- promises.push(
- asyncFetch(
- `https://api.pikespeak.ai/account/near-transfer/${lockupContract}?limit=${totalTxnsPerPage}&offset=${
- totalTxnsPerPage * (page - 1)
- }`,
- options
- )
- );
-
- promises.push(
- asyncFetch(
- `https://api.pikespeak.ai/account/ft-transfer/${lockupContract}?limit=${totalTxnsPerPage}&offset=${
- totalTxnsPerPage * (page - 1)
- }`,
- options
- )
- );
- }
- Promise.all(promises).then((i) => {
- if (!i[0].ok || !i[1].ok) {
+ asyncFetch(
+ `${REPL_BACKEND_API}/transactions-transfer-history?treasuryDaoID=${treasuryDaoID}&lockupContract=${lockupContract}&page=${page}`
+ ).then((res) => {
+ if (!res.body.data) {
setAPIError();
- return;
- }
- if (lockupContract && (!i[2].ok || !i[3].ok)) {
- setAPIError();
- return;
- }
- const nearResp = lockupContract
- ? i[0]?.body.concat(i[2]?.body)
- : i[0]?.body;
- const ftResp = lockupContract
- ? i[1]?.body.concat(i[3]?.body)
- : i[1]?.body;
- if (Array.isArray(nearResp) && Array.isArray(ftResp)) {
- if (
- nearResp.length < totalTxnsPerPage &&
- ftResp.length < totalTxnsPerPage
- ) {
+ } else {
+ if (res.body.data.length < page * totalTxnsPerPage) {
setHideViewMore(true);
}
setError(null);
- setTransactionWithBalance((prev) => {
- return [...prev, ...sortByDate(nearResp.concat(ftResp))];
- });
+ setTransactionWithBalance(res.body.data);
setShowMoreLoading(false);
}
});
@@ -229,6 +155,11 @@ const Container = styled.div`
table {
overflow-x: auto;
}
+
+ .account-cell {
+ min-width: 180px;
+ max-width: 180px;
+ }
`;
function formatAccount(text) {
@@ -252,8 +183,8 @@ return (
Type
- From
- To
+ From
+ To
Transaction
Amount
@@ -300,45 +231,33 @@ return (
-
+
- ),
- children: (
-
- {formatAccount(txn.sender)}
-
- ),
+ accountId: txn.sender,
+ showKYC: false,
instance,
+ displayImage: false,
+ displayName: false,
+ width: 150,
}}
/>
-
+
- ),
- children: (
-
- {formatAccount(txn.receiver)}
-
- ),
+ accountId: txn.receiver,
+ showKYC: false,
instance,
+ displayImage: false,
+ displayName: false,
+ width: 150,
}}
/>
-
+
{
- asyncFetch(
- `https://api.coingecko.com/api/v3/simple/price?ids=near&vs_currencies=usd`
- ).then((res) => {
- if (res.body.near?.usd) {
- setNearPrice(res.body.near?.usd);
- }
- });
-
- asyncFetch(
- `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`,
- { headers: { Authorization: "Bearer ${REPL_NEARBLOCKS_KEY}" } }
- ).then((res) => {
- let fts = res.body.inventory.fts;
- if (fts)
- fts = fts.sort(
- (a, b) => b.amount * b.ft_meta.price - a.amount * a.ft_meta.price
- );
-
- const amounts = fts.map((ft) => {
- const amount = ft.amount;
- const decimals = ft.ft_meta.decimals;
- const tokensNumber = Big(amount ?? "0")
- .div(Big(10).pow(decimals))
- .toFixed();
- const tokenPrice = ft.ft_meta.price;
- return Big(tokensNumber)
- .mul(tokenPrice ?? 0)
- .toFixed();
+ asyncFetch(`${REPL_BACKEND_API}/near-price`)
+ .then((res) => {
+ if (typeof res.body === "number") {
+ setNearPrice(res.body);
+ } else {
+ setShow404Modal(true);
+ }
+ })
+ .catch((err) => {
+ setShow404Modal(true);
});
- setFTTokens({
- totalCummulativeAmt: amounts.reduce(
- (acc, value) => acc + parseFloat(value),
- 0
- ),
- fts,
+
+ asyncFetch(`${REPL_BACKEND_API}/ft-tokens/?account_id=${treasuryDaoID}`)
+ .then((res) => {
+ if (typeof res.body.totalCumulativeAmt === "number") {
+ setFTTokens(res.body);
+ } else {
+ setShow404Modal(true);
+ }
+ })
+ .catch((err) => {
+ setShow404Modal(true);
});
- });
}, []);
+// disable refresh btn for 30 seconds
+useEffect(() => {
+ if (show404Modal) {
+ setDisableRefreshBtn(true);
+ }
+}, [show404Modal]);
+
+useEffect(() => {
+ let timer;
+
+ if (disableRefreshBtn) {
+ timer = setTimeout(() => {
+ setDisableRefreshBtn(false);
+ }, 30_000);
+ }
+
+ return () => {
+ clearTimeout(timer);
+ };
+}, [disableRefreshBtn]);
+
function formatNearAmount(amount) {
return Big(amount ?? "0")
.div(Big(10).pow(24))
@@ -174,6 +187,67 @@ function formatCurrency(amount) {
return "$" + formattedAmount;
}
+const TooManyRequestModal = () => {
+ return (
+
+
+
+
+
+ Whoa there, speedster!
+
+
setShow404Modal(false)}
+ >
+
+
+
+ You’ve been refreshing the page a bit too much, and our data provider
+ needs a moment to catch up. Some information, like token prices,
+ couldn’t load this time.
+ 🕒 Take a 30-second breather.
+ 🔄 Refresh the page afterward and continue as usual.
+ Thanks for your patience—it helps us keep things running
+ smoothly!
+
+
+
+
+
+ setShow404Modal(false),
+ }}
+ />
+
+
+
+
+
+ );
+};
+
const Loading = () => {
return (
@@ -195,6 +269,7 @@ const Loading = () => {
return (
+ {show404Modal && }
{
function fetchNearPrice() {
asyncFetch(nearPriceAPI).then((res) => {
- if (res.body.near?.usd) {
- setNearPrice(res.body.near.usd);
+ if (typeof res.body === "number") {
+ setNearPrice(res.body);
}
});
}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
index ff43d9df..be1b40b3 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/payments/Table.jsx
@@ -152,8 +152,7 @@ const requiredVotes = transferApproversGroup?.requiredVotes;
const hideApproversCol = isPendingRequests && requiredVotes === 1;
const userFTTokens = fetch(
- `https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`,
- { method: "GET", headers: { Authorization: "Bearer ${REPL_NEARBLOCKS_KEY}" } }
+ `${REPL_BACKEND_API}/ft-tokens/?account_id=${treasuryDaoID}`
);
const nearBalances = getNearBalances(treasuryDaoID);
@@ -452,7 +451,7 @@ const ProposalsComponent = () => {
hasVotingPermission,
proposalCreator: item.proposer,
tokensBalance: [
- ...(userFTTokens?.body?.inventory?.fts ?? []),
+ ...(userFTTokens?.body?.fts ?? []),
{
contract: "near",
amount: Big(nearBalances.available)
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
index 5c7bb822..5dd2bb84 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/WalletDropdown.jsx
@@ -19,10 +19,8 @@ const nearBalances = getNearBalances(treasuryDaoID);
const nearPrice = useCache(
() =>
- asyncFetch(
- `https://api.coingecko.com/api/v3/simple/price?ids=near&vs_currencies=usd`
- ).then((res) => {
- return res.body.near?.usd;
+ asyncFetch(`${REPL_BACKEND_API}/near-price`).then((res) => {
+ return res.body;
}),
"near-price",
{ subscribe: false }
diff --git a/playwright-tests/tests/dashboard/home-page.spec.js b/playwright-tests/tests/dashboard/home-page.spec.js
index a4f8059c..a8664991 100644
--- a/playwright-tests/tests/dashboard/home-page.spec.js
+++ b/playwright-tests/tests/dashboard/home-page.spec.js
@@ -15,9 +15,14 @@ test.afterEach(async ({ page }, testInfo) => {
const nearPrice = 5;
test.describe("Dashboard Page", function () {
- test.beforeEach(async ({ page, instanceAccount, daoAccount }) => {
+ test.beforeEach(async ({ page, instanceAccount, daoAccount }, testInfo) => {
+ if (testInfo.title.includes("Should see 404 modal")) {
+ await mockNearPrice({ nearPrice, page, returnError: true });
+ } else {
+ await mockNearPrice({ nearPrice, page });
+ }
+
await mockWithFTBalance({ page, daoAccount, isSufficient: true });
- await mockNearPrice({ nearPrice, page });
await page.goto(`/${instanceAccount}/widget/app`);
await expect(
page.locator("div").filter({ hasText: /^Dashboard$/ })
@@ -25,12 +30,8 @@ test.describe("Dashboard Page", function () {
});
test("Portfolio should correctly displays FT tokens", async ({ page }) => {
test.setTimeout(60_000);
- await expect(
- page.locator("div").filter({ hasText: /^USDt$/ })
- ).toBeVisible();
- await expect(
- page.locator("div").filter({ hasText: /^USDC$/ })
- ).toBeVisible();
+ await expect(page.getByText("USDt").first()).toBeVisible();
+ await expect(page.getByText("USDC").first()).toBeVisible();
});
test("Portfolio should correctly displays NEAR price", async ({ page }) => {
@@ -41,4 +42,10 @@ test.describe("Dashboard Page", function () {
.count();
expect(nearPriceElements).toBeGreaterThan(0);
});
+
+ test("Should see 404 modal", async ({ page }) => {
+ test.setTimeout(60_000);
+ await page.waitForTimeout(5_000);
+ await expect(page.getByText("Whoa there, speedster")).toBeVisible();
+ });
});
diff --git a/playwright-tests/tests/payments/create-payment-request.spec.js b/playwright-tests/tests/payments/create-payment-request.spec.js
index 634a6556..17520df9 100644
--- a/playwright-tests/tests/payments/create-payment-request.spec.js
+++ b/playwright-tests/tests/payments/create-payment-request.spec.js
@@ -146,6 +146,10 @@ test.describe("User is logged in", function () {
storageState: "playwright-tests/storage-states/wallet-connected-admin.json",
});
+ test.beforeEach(async ({ page }) => {
+ await mockNearPrice({ nearPrice: 5, page });
+ });
+
test("low account balance should show warning modal, and allow action ", async ({
page,
instanceAccount,
diff --git a/playwright-tests/util/inventory.js b/playwright-tests/util/inventory.js
index af97614d..5478f40b 100644
--- a/playwright-tests/util/inventory.js
+++ b/playwright-tests/util/inventory.js
@@ -25,39 +25,39 @@ export async function mockInventory({ page, account }) {
}
);
await page.route(
- `https://api3.nearblocks.io/v1/account/${account}/inventory`,
+ `https://ref-sdk-api.fly.dev/api/ft-tokens/?account_id=${account}`,
+
async (route, request) => {
const json = {
- inventory: {
- fts: [
- {
- contract:
- "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
- amount: "45000000000",
- ft_meta: {
- name: "USDC",
- symbol: "USDC",
- decimals: 6,
- icon: "data:image/svg+xml,%3C%3Fxml version=%221.0%22 encoding=%22utf-8%22%3F%3E%3C!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version=%221.1%22 id=%22Layer_1%22 xmlns=%22http://www.w3.org/2000/svg%22 xmlns:xlink=%22http://www.w3.org/1999/xlink%22 x=%220px%22 y=%220px%22 viewBox=%220 0 256 256%22 style=%22enable-background:new 0 0 256 256;%22 xml:space=%22preserve%22%3E%3Cstyle type=%22text/css%22%3E .st0%7Bfill:%232775CA;%7D .st1%7Bfill:%23FFFFFF;%7D%0A%3C/style%3E%3Ccircle class=%22st0%22 cx=%22128%22 cy=%22128%22 r=%22128%22/%3E%3Cpath class=%22st1%22 d=%22M104,217c0,3-2.4,4.7-5.2,3.8C60,208.4,32,172.2,32,129.3c0-42.8,28-79.1,66.8-91.5c2.9-0.9,5.2,0.8,5.2,3.8 v7.5c0,2-1.5,4.3-3.4,5C69.9,65.4,48,94.9,48,129.3c0,34.5,21.9,63.9,52.6,75.1c1.9,0.7,3.4,3,3.4,5V217z%22/%3E%3Cpath class=%22st1%22 d=%22M136,189.3c0,2.2-1.8,4-4,4h-8c-2.2,0-4-1.8-4-4v-12.6c-17.5-2.4-26-12.1-28.3-25.5c-0.4-2.3,1.4-4.3,3.7-4.3 h9.1c1.9,0,3.5,1.4,3.9,3.2c1.7,7.9,6.3,14,20.3,14c10.3,0,17.7-5.8,17.7-14.4c0-8.6-4.3-11.9-19.5-14.4c-22.4-3-33-9.8-33-27.3 c0-13.5,10.3-24.1,26.1-26.3V69.3c0-2.2,1.8-4,4-4h8c2.2,0,4,1.8,4,4v12.7c12.9,2.3,21.1,9.6,23.8,21.8c0.5,2.3-1.3,4.4-3.7,4.4 h-8.4c-1.8,0-3.3-1.2-3.8-2.9c-2.3-7.7-7.8-11.1-17.4-11.1c-10.6,0-16.1,5.1-16.1,12.3c0,7.6,3.1,11.4,19.4,13.7 c22,3,33.4,9.3,33.4,28c0,14.2-10.6,25.7-27.1,28.3V189.3z%22/%3E%3Cpath class=%22st1%22 d=%22M157.2,220.8c-2.9,0.9-5.2-0.8-5.2-3.8v-7.5c0-2.2,1.3-4.3,3.4-5c30.6-11.2,52.6-40.7,52.6-75.1 c0-34.5-21.9-63.9-52.6-75.1c-1.9-0.7-3.4-3-3.4-5v-7.5c0-3,2.4-4.7,5.2-3.8C196,50.2,224,86.5,224,129.3 C224,172.2,196,208.4,157.2,220.8z%22/%3E%3C/svg%3E%0A",
- reference: null,
- price: 0.999648,
- },
+ totalCumulativeAmt: 10,
+ fts: [
+ {
+ contract:
+ "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
+ amount: "45000000000",
+ ft_meta: {
+ name: "USDC",
+ symbol: "USDC",
+ decimals: 6,
+ icon: "data:image/svg+xml,%3C%3Fxml version=%221.0%22 encoding=%22utf-8%22%3F%3E%3C!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version=%221.1%22 id=%22Layer_1%22 xmlns=%22http://www.w3.org/2000/svg%22 xmlns:xlink=%22http://www.w3.org/1999/xlink%22 x=%220px%22 y=%220px%22 viewBox=%220 0 256 256%22 style=%22enable-background:new 0 0 256 256;%22 xml:space=%22preserve%22%3E%3Cstyle type=%22text/css%22%3E .st0%7Bfill:%232775CA;%7D .st1%7Bfill:%23FFFFFF;%7D%0A%3C/style%3E%3Ccircle class=%22st0%22 cx=%22128%22 cy=%22128%22 r=%22128%22/%3E%3Cpath class=%22st1%22 d=%22M104,217c0,3-2.4,4.7-5.2,3.8C60,208.4,32,172.2,32,129.3c0-42.8,28-79.1,66.8-91.5c2.9-0.9,5.2,0.8,5.2,3.8 v7.5c0,2-1.5,4.3-3.4,5C69.9,65.4,48,94.9,48,129.3c0,34.5,21.9,63.9,52.6,75.1c1.9,0.7,3.4,3,3.4,5V217z%22/%3E%3Cpath class=%22st1%22 d=%22M136,189.3c0,2.2-1.8,4-4,4h-8c-2.2,0-4-1.8-4-4v-12.6c-17.5-2.4-26-12.1-28.3-25.5c-0.4-2.3,1.4-4.3,3.7-4.3 h9.1c1.9,0,3.5,1.4,3.9,3.2c1.7,7.9,6.3,14,20.3,14c10.3,0,17.7-5.8,17.7-14.4c0-8.6-4.3-11.9-19.5-14.4c-22.4-3-33-9.8-33-27.3 c0-13.5,10.3-24.1,26.1-26.3V69.3c0-2.2,1.8-4,4-4h8c2.2,0,4,1.8,4,4v12.7c12.9,2.3,21.1,9.6,23.8,21.8c0.5,2.3-1.3,4.4-3.7,4.4 h-8.4c-1.8,0-3.3-1.2-3.8-2.9c-2.3-7.7-7.8-11.1-17.4-11.1c-10.6,0-16.1,5.1-16.1,12.3c0,7.6,3.1,11.4,19.4,13.7 c22,3,33.4,9.3,33.4,28c0,14.2-10.6,25.7-27.1,28.3V189.3z%22/%3E%3Cpath class=%22st1%22 d=%22M157.2,220.8c-2.9,0.9-5.2-0.8-5.2-3.8v-7.5c0-2.2,1.3-4.3,3.4-5c30.6-11.2,52.6-40.7,52.6-75.1 c0-34.5-21.9-63.9-52.6-75.1c-1.9-0.7-3.4-3-3.4-5v-7.5c0-3,2.4-4.7,5.2-3.8C196,50.2,224,86.5,224,129.3 C224,172.2,196,208.4,157.2,220.8z%22/%3E%3C/svg%3E%0A",
+ reference: null,
+ price: 0.999648,
},
- {
- contract: "usdt.tether-token.near",
- amount: "7500000",
- ft_meta: {
- name: "Tether USD",
- symbol: "USDt",
- decimals: 6,
- icon: "data:image/svg+xml,%3Csvg width='111' height='90' viewBox='0 0 111 90' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M24.4825 0.862305H88.0496C89.5663 0.862305 90.9675 1.64827 91.7239 2.92338L110.244 34.1419C111.204 35.7609 110.919 37.8043 109.549 39.1171L58.5729 87.9703C56.9216 89.5528 54.2652 89.5528 52.6139 87.9703L1.70699 39.1831C0.305262 37.8398 0.0427812 35.7367 1.07354 34.1077L20.8696 2.82322C21.6406 1.60483 23.0087 0.862305 24.4825 0.862305ZM79.8419 14.8003V23.5597H61.7343V29.6329C74.4518 30.2819 83.9934 32.9475 84.0642 36.1425L84.0638 42.803C83.993 45.998 74.4518 48.6635 61.7343 49.3125V64.2168H49.7105V49.3125C36.9929 48.6635 27.4513 45.998 27.3805 42.803L27.381 36.1425C27.4517 32.9475 36.9929 30.2819 49.7105 29.6329V23.5597H31.6028V14.8003H79.8419ZM55.7224 44.7367C69.2943 44.7367 80.6382 42.4827 83.4143 39.4727C81.0601 36.9202 72.5448 34.9114 61.7343 34.3597V40.7183C59.7966 40.8172 57.7852 40.8693 55.7224 40.8693C53.6595 40.8693 51.6481 40.8172 49.7105 40.7183V34.3597C38.8999 34.9114 30.3846 36.9202 28.0304 39.4727C30.8066 42.4827 42.1504 44.7367 55.7224 44.7367Z' fill='%23009393'/%3E%3C/svg%3E",
- reference: null,
- price: 0.999464,
- },
+ },
+ {
+ contract: "usdt.tether-token.near",
+ amount: "7500000",
+ ft_meta: {
+ name: "Tether USD",
+ symbol: "USDt",
+ decimals: 6,
+ icon: "data:image/svg+xml,%3Csvg width='111' height='90' viewBox='0 0 111 90' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M24.4825 0.862305H88.0496C89.5663 0.862305 90.9675 1.64827 91.7239 2.92338L110.244 34.1419C111.204 35.7609 110.919 37.8043 109.549 39.1171L58.5729 87.9703C56.9216 89.5528 54.2652 89.5528 52.6139 87.9703L1.70699 39.1831C0.305262 37.8398 0.0427812 35.7367 1.07354 34.1077L20.8696 2.82322C21.6406 1.60483 23.0087 0.862305 24.4825 0.862305ZM79.8419 14.8003V23.5597H61.7343V29.6329C74.4518 30.2819 83.9934 32.9475 84.0642 36.1425L84.0638 42.803C83.993 45.998 74.4518 48.6635 61.7343 49.3125V64.2168H49.7105V49.3125C36.9929 48.6635 27.4513 45.998 27.3805 42.803L27.381 36.1425C27.4517 32.9475 36.9929 30.2819 49.7105 29.6329V23.5597H31.6028V14.8003H79.8419ZM55.7224 44.7367C69.2943 44.7367 80.6382 42.4827 83.4143 39.4727C81.0601 36.9202 72.5448 34.9114 61.7343 34.3597V40.7183C59.7966 40.8172 57.7852 40.8693 55.7224 40.8693C53.6595 40.8693 51.6481 40.8172 49.7105 40.7183V34.3597C38.8999 34.9114 30.3846 36.9202 28.0304 39.4727C30.8066 42.4827 42.1504 44.7367 55.7224 44.7367Z' fill='%23009393'/%3E%3C/svg%3E",
+ reference: null,
+ price: 0.999464,
},
- ],
- nfts: [],
- },
+ },
+ ],
+ nfts: [],
};
await route.fulfill({ json });
}
diff --git a/playwright-tests/util/nearblocks.js b/playwright-tests/util/nearblocks.js
index e964d454..f0f38d00 100644
--- a/playwright-tests/util/nearblocks.js
+++ b/playwright-tests/util/nearblocks.js
@@ -5,13 +5,22 @@
* @param {import('playwright').Page} params.page - The Playwright Page instance.
* @returns {Promise} A promise that resolves when the mock is complete.
*/
-export async function mockNearPrice({ nearPrice, page }) {
+export async function mockNearPrice({ nearPrice, page, returnError }) {
await page.route(
- "https://api.coingecko.com/api/v3/simple/price?ids=near&vs_currencies=usd",
+ `https://ref-sdk-api.fly.dev/api/near-price`,
async (route) => {
- let json = { near: { usd: nearPrice } };
-
- await route.fulfill({ json });
+ if (returnError) {
+ // Simulate an error response
+ await route.fulfill({
+ status: 500, // HTTP status code for server error
+ contentType: "application/json",
+ body: JSON.stringify({ error: "Internal Server Error" }),
+ });
+ } else {
+ // Simulate a successful response
+ let json = nearPrice;
+ await route.fulfill({ json });
+ }
}
);
}
diff --git a/playwright-tests/util/rpcmock.js b/playwright-tests/util/rpcmock.js
index 0542b7d5..1a9105ac 100644
--- a/playwright-tests/util/rpcmock.js
+++ b/playwright-tests/util/rpcmock.js
@@ -226,40 +226,39 @@ export async function mockNearBalances({ page, accountId, balance, storage }) {
export async function mockWithFTBalance({ page, daoAccount, isSufficient }) {
await page.route(
- `https://api3.nearblocks.io/v1/account/${daoAccount}/inventory`,
+ `https://ref-sdk-api.fly.dev/api/ft-tokens/?account_id=${daoAccount}`,
async (route) => {
await route.fulfill({
json: {
- inventory: {
- fts: [
- {
- contract: "usdt.tether-token.near",
- amount: "4500000",
- ft_meta: {
- name: "Tether USD",
- symbol: "USDt",
- decimals: 6,
- icon: "data:image/svg+xml,%3Csvg width='111' height='90' viewBox='0 0 111 90' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M24.4825 0.862305H88.0496C89.5663 0.862305 90.9675 1.64827 91.7239 2.92338L110.244 34.1419C111.204 35.7609 110.919 37.8043 109.549 39.1171L58.5729 87.9703C56.9216 89.5528 54.2652 89.5528 52.6139 87.9703L1.70699 39.1831C0.305262 37.8398 0.0427812 35.7367 1.07354 34.1077L20.8696 2.82322C21.6406 1.60483 23.0087 0.862305 24.4825 0.862305ZM79.8419 14.8003V23.5597H61.7343V29.6329C74.4518 30.2819 83.9934 32.9475 84.0642 36.1425L84.0638 42.803C83.993 45.998 74.4518 48.6635 61.7343 49.3125V64.2168H49.7105V49.3125C36.9929 48.6635 27.4513 45.998 27.3805 42.803L27.381 36.1425C27.4517 32.9475 36.9929 30.2819 49.7105 29.6329V23.5597H31.6028V14.8003H79.8419ZM55.7224 44.7367C69.2943 44.7367 80.6382 42.4827 83.4143 39.4727C81.0601 36.9202 72.5448 34.9114 61.7343 34.3597V40.7183C59.7966 40.8172 57.7852 40.8693 55.7224 40.8693C53.6595 40.8693 51.6481 40.8172 49.7105 40.7183V34.3597C38.8999 34.9114 30.3846 36.9202 28.0304 39.4727C30.8066 42.4827 42.1504 44.7367 55.7224 44.7367Z' fill='%23009393'/%3E%3C/svg%3E",
- reference: null,
- price: 1,
- },
+ totalCumulativeAmt: 10,
+ fts: [
+ {
+ contract: "usdt.tether-token.near",
+ amount: "4500000",
+ ft_meta: {
+ name: "Tether USD",
+ symbol: "USDt",
+ decimals: 6,
+ icon: "data:image/svg+xml,%3Csvg width='111' height='90' viewBox='0 0 111 90' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M24.4825 0.862305H88.0496C89.5663 0.862305 90.9675 1.64827 91.7239 2.92338L110.244 34.1419C111.204 35.7609 110.919 37.8043 109.549 39.1171L58.5729 87.9703C56.9216 89.5528 54.2652 89.5528 52.6139 87.9703L1.70699 39.1831C0.305262 37.8398 0.0427812 35.7367 1.07354 34.1077L20.8696 2.82322C21.6406 1.60483 23.0087 0.862305 24.4825 0.862305ZM79.8419 14.8003V23.5597H61.7343V29.6329C74.4518 30.2819 83.9934 32.9475 84.0642 36.1425L84.0638 42.803C83.993 45.998 74.4518 48.6635 61.7343 49.3125V64.2168H49.7105V49.3125C36.9929 48.6635 27.4513 45.998 27.3805 42.803L27.381 36.1425C27.4517 32.9475 36.9929 30.2819 49.7105 29.6329V23.5597H31.6028V14.8003H79.8419ZM55.7224 44.7367C69.2943 44.7367 80.6382 42.4827 83.4143 39.4727C81.0601 36.9202 72.5448 34.9114 61.7343 34.3597V40.7183C59.7966 40.8172 57.7852 40.8693 55.7224 40.8693C53.6595 40.8693 51.6481 40.8172 49.7105 40.7183V34.3597C38.8999 34.9114 30.3846 36.9202 28.0304 39.4727C30.8066 42.4827 42.1504 44.7367 55.7224 44.7367Z' fill='%23009393'/%3E%3C/svg%3E",
+ reference: null,
+ price: 1,
},
- {
- contract:
- "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
- amount: isSufficient ? "1500000" : "10",
- ft_meta: {
- name: "USDC",
- symbol: "USDC",
- decimals: 6,
- icon: "",
- reference: null,
- price: 1,
- },
+ },
+ {
+ contract:
+ "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
+ amount: isSufficient ? "1500000" : "10",
+ ft_meta: {
+ name: "USDC",
+ symbol: "USDC",
+ decimals: 6,
+ icon: "",
+ reference: null,
+ price: 1,
},
- ],
- nfts: [],
- },
+ },
+ ],
+ nfts: [],
},
});
}
From cf096bd9c93dd532f9c8dde3896a59e52f45aa93 Mon Sep 17 00:00:00 2001
From: Andrew
Date: Wed, 29 Jan 2025 17:22:53 +0200
Subject: [PATCH 33/40] Offcanvas overlay and screen height fixes (#259)
---
.../widget/components/OffCanvas.jsx | 5 +++--
.../widget/components/templates/AppLayout.jsx | 7 ++++++-
.../ValidatorsDropDownWithSearch.jsx | 12 +++++++++---
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/instances/widgets.treasury-factory.near/widget/components/OffCanvas.jsx b/instances/widgets.treasury-factory.near/widget/components/OffCanvas.jsx
index 8b104421..7d4e5c2f 100644
--- a/instances/widgets.treasury-factory.near/widget/components/OffCanvas.jsx
+++ b/instances/widgets.treasury-factory.near/widget/components/OffCanvas.jsx
@@ -11,8 +11,10 @@ const children = props.children;
const Container = styled.div`
opacity: 1 !important;
+
.offcanvas.offcanvas-end {
width: 30% !important;
+ z-index: 1060;
}
@media screen and (max-width: 1200px) {
@@ -28,14 +30,13 @@ const Container = styled.div`
}
.offcanvas {
- border-top-left-radius: 1rem !important;
- border-bottom-left-radius: 1rem !important;
overflow: auto;
}
`;
return (
+
-
+
{children}
diff --git a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
index 558a6eab..19af5226 100644
--- a/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
+++ b/instances/widgets.treasury-factory.near/widget/pages/stake-delegation/ValidatorsDropDownWithSearch.jsx
@@ -45,8 +45,8 @@ const code = `