From d1e53461ac56fe2f0229a481e987248110f4ff62 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Wed, 25 Sep 2024 12:00:19 +0200 Subject: [PATCH 1/4] Feat: rm WC/TxB from dashboard - make space for recent Safe Apps --- cypress/support/localstorage_data.js | 2 +- .../dashboard/FeaturedApps/FeaturedApps.tsx | 75 ------------------- src/components/dashboard/index.tsx | 10 --- .../SafeAppsZeroResultsPlaceholder/index.tsx | 34 +-------- src/config/constants.ts | 2 - src/hooks/__tests__/useRankedSafeApps.test.ts | 14 ---- src/hooks/safe-apps/useRankedSafeApps.ts | 6 +- 7 files changed, 4 insertions(+), 139 deletions(-) delete mode 100644 src/components/dashboard/FeaturedApps/FeaturedApps.tsx diff --git a/cypress/support/localstorage_data.js b/cypress/support/localstorage_data.js index 7b0ac24805..3f8541d464 100644 --- a/cypress/support/localstorage_data.js +++ b/cypress/support/localstorage_data.js @@ -7,7 +7,7 @@ const cookieState = { updates: true, analytics: true, terms: true, - termsVersion: CURRENT_COOKIE_TERMS_VERSION + termsVersion: CURRENT_COOKIE_TERMS_VERSION, } export const batchData = { diff --git a/src/components/dashboard/FeaturedApps/FeaturedApps.tsx b/src/components/dashboard/FeaturedApps/FeaturedApps.tsx deleted file mode 100644 index fbef5f3013..0000000000 --- a/src/components/dashboard/FeaturedApps/FeaturedApps.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import type { ReactElement, SyntheticEvent } from 'react' -import { Box, Grid, Typography, Link } from '@mui/material' -import { Card, WidgetBody, WidgetContainer } from '../styled' -import NextLink from 'next/link' -import SafeAppIconCard from '@/components/safe-apps/SafeAppIconCard' -import { openWalletConnect } from '@/features/walletconnect/components' -import { useHasFeature } from '@/hooks/useChains' -import { FEATURES } from '@/utils/chains' -import { useTxBuilderApp } from '@/hooks/safe-apps/useTxBuilderApp' - -const FeaturedAppCard = ({ name, description, iconUrl }: { name: string; description: string; iconUrl: string }) => ( - - - - - - - - - {description} - - - - Use {name} - - - - -) - -const onWcWidgetClick = (e: SyntheticEvent) => { - e.preventDefault() - openWalletConnect() -} - -export const FeaturedApps = ({ stackedLayout }: { stackedLayout: boolean }): ReactElement | null => { - const txBuilder = useTxBuilderApp() - const isWcEnabled = useHasFeature(FEATURES.NATIVE_WALLETCONNECT) - - return ( - - - - Connect & transact - - - - {txBuilder?.app && ( - - - - - - )} - {isWcEnabled && ( - - - - - - )} - - - - - ) -} diff --git a/src/components/dashboard/index.tsx b/src/components/dashboard/index.tsx index 4235cacf4a..3009984244 100644 --- a/src/components/dashboard/index.tsx +++ b/src/components/dashboard/index.tsx @@ -6,10 +6,8 @@ import { Grid } from '@mui/material' import PendingTxsList from '@/components/dashboard/PendingTxs/PendingTxsList' import AssetsWidget from '@/components/dashboard/Assets' import Overview from '@/components/dashboard/Overview/Overview' -import { FeaturedApps } from '@/components/dashboard/FeaturedApps/FeaturedApps' import SafeAppsDashboardSection from '@/components/dashboard/SafeAppsDashboardSection/SafeAppsDashboardSection' import GovernanceSection from '@/components/dashboard/GovernanceSection/GovernanceSection' -import useRecovery from '@/features/recovery/hooks/useRecovery' import { useIsRecoverySupported } from '@/features/recovery/hooks/useIsRecoverySupported' import ActivityRewardsSection from '@/components/dashboard/ActivityRewardsSection' import { useHasFeature } from '@/hooks/useChains' @@ -28,8 +26,6 @@ const Dashboard = (): ReactElement => { const isSwapFeatureEnabled = useIsSwapFeatureEnabled() const isSAPBannerEnabled = useHasFeature(FEATURES.SAP_BANNER) && isSafeTokenEnabled const supportsRecovery = useIsRecoverySupported() - const [recovery] = useRecovery() - const showRecoveryWidget = supportsRecovery && !recovery return ( <> @@ -68,12 +64,6 @@ const Dashboard = (): ReactElement => { - {showSafeApps && ( - - - - )} - {showSafeApps && ( diff --git a/src/components/safe-apps/SafeAppsZeroResultsPlaceholder/index.tsx b/src/components/safe-apps/SafeAppsZeroResultsPlaceholder/index.tsx index b68a526750..bd3b411c78 100644 --- a/src/components/safe-apps/SafeAppsZeroResultsPlaceholder/index.tsx +++ b/src/components/safe-apps/SafeAppsZeroResultsPlaceholder/index.tsx @@ -1,48 +1,18 @@ -import React, { useMemo } from 'react' -import { useRouter } from 'next/router' -import Link from 'next/link' -import Button from '@mui/material/Button' import Typography from '@mui/material/Typography' -import type { LinkProps } from 'next/link' - import PagePlaceholder from '@/components/common/PagePlaceholder' import AddCustomAppIcon from '@/public/images/apps/add-custom-app.svg' -import { AppRoutes } from '@/config/routes' -import { SafeAppsTag } from '@/config/constants' -import { useRemoteSafeApps } from '@/hooks/safe-apps/useRemoteSafeApps' - -const useWCAppLink = (): LinkProps['href'] => { - const router = useRouter() - const [matchingApps] = useRemoteSafeApps(SafeAppsTag.WALLET_CONNECT) - const app = matchingApps?.[0] - - return useMemo( - () => ({ - pathname: AppRoutes.apps.open, - query: { safe: router.query.safe, appUrl: app?.url }, - }), - [app?.url, router.query.safe], - ) -} const SafeAppsZeroResultsPlaceholder = ({ searchQuery }: { searchQuery: string }) => { - const wcLink = useWCAppLink() return ( } text={ No Safe Apps found matching {searchQuery}. Connect to dApps that haven't yet been - integrated with the {'Safe{Wallet}'} using the WalletConnect Safe App. + integrated with the {'Safe{Wallet}'} using WalletConnect. } - > - - - - + /> ) } diff --git a/src/config/constants.ts b/src/config/constants.ts index f1039e0143..24b49de0b7 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -59,9 +59,7 @@ export const TENDERLY_ORG_NAME = process.env.NEXT_PUBLIC_TENDERLY_ORG_NAME || '' export enum SafeAppsTag { NFT = 'nft', TX_BUILDER = 'transaction-builder', - DASHBOARD_FEATURED = 'dashboard-widgets', SAFE_GOVERNANCE_APP = 'safe-governance-app', - WALLET_CONNECT = 'wallet-connect', ONRAMP = 'onramp', RECOVERY_SYGNUM = 'recovery-sygnum', } diff --git a/src/hooks/__tests__/useRankedSafeApps.test.ts b/src/hooks/__tests__/useRankedSafeApps.test.ts index 669a5c0fa8..a4b4f97b4e 100644 --- a/src/hooks/__tests__/useRankedSafeApps.test.ts +++ b/src/hooks/__tests__/useRankedSafeApps.test.ts @@ -32,20 +32,6 @@ describe('useRankedSafeApps', () => { expect(result.current.length).toEqual(5) }) - it('excludes featured safe apps', () => { - const mockSafeApp1 = getMockSafeApp({ id: 1, tags: [SafeAppsTag.DASHBOARD_FEATURED] }) - const mockSafeApp2 = getMockSafeApp({ id: 2, tags: [SafeAppsTag.DASHBOARD_FEATURED] }) - const mockSafeApp3 = getMockSafeApp({ id: 3 }) - const mockSafeApp4 = getMockSafeApp({ id: 4 }) - const mockSafeApp5 = getMockSafeApp({ id: 5 }) - - const { result } = renderHook(() => - useRankedSafeApps([mockSafeApp1, mockSafeApp2, mockSafeApp3, mockSafeApp4, mockSafeApp5], []), - ) - - expect(result.current.length).toEqual(3) - }) - it('returns pinned apps first', () => { const mockSafeApp1 = getMockSafeApp({ id: 1 }) const mockSafeApp2 = getMockSafeApp({ id: 2 }) diff --git a/src/hooks/safe-apps/useRankedSafeApps.ts b/src/hooks/safe-apps/useRankedSafeApps.ts index 7fe4a0849f..f598b86546 100644 --- a/src/hooks/safe-apps/useRankedSafeApps.ts +++ b/src/hooks/safe-apps/useRankedSafeApps.ts @@ -1,7 +1,6 @@ import { useMemo } from 'react' import type { SafeAppData } from '@safe-global/safe-gateway-typescript-sdk' import { rankSafeApps } from '@/services/safe-apps/track-app-usage-count' -import { SafeAppsTag } from '@/config/constants' // number of ranked Safe Apps that we want to display const NUMBER_OF_SAFE_APPS = 5 @@ -14,10 +13,7 @@ const useRankedSafeApps = (safeApps: SafeAppData[], pinnedSafeApps: SafeAppData[ const rankedPinnedApps = rankSafeApps(pinnedSafeApps) const randomApps = safeApps.slice().sort(() => Math.random() - 0.5) - const allRankedApps = rankedPinnedApps - .concat(pinnedSafeApps, mostUsedApps, randomApps) - // Filter out Featured Apps because they are in their own section - .filter((app) => !app.tags.includes(SafeAppsTag.DASHBOARD_FEATURED)) + const allRankedApps = rankedPinnedApps.concat(pinnedSafeApps, mostUsedApps, randomApps) // Use a Set to remove duplicates return [...new Set(allRankedApps)].slice(0, NUMBER_OF_SAFE_APPS) From 8f35a78b1565399db08fa952ff3fb0bf62712fa2 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Wed, 25 Sep 2024 12:09:31 +0200 Subject: [PATCH 2/4] Rm unused import --- src/hooks/__tests__/useRankedSafeApps.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/__tests__/useRankedSafeApps.test.ts b/src/hooks/__tests__/useRankedSafeApps.test.ts index a4b4f97b4e..0ce767eba3 100644 --- a/src/hooks/__tests__/useRankedSafeApps.test.ts +++ b/src/hooks/__tests__/useRankedSafeApps.test.ts @@ -1,7 +1,6 @@ import { renderHook } from '@/tests/test-utils' import { useRankedSafeApps } from '@/hooks/safe-apps/useRankedSafeApps' import type { SafeAppData } from '@safe-global/safe-gateway-typescript-sdk' -import { SafeAppsTag } from '@/config/constants' const getMockSafeApp = (props: Partial) => { return { From 3ca8ffdecbca982687ef366fcdd9e398f80096d9 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Wed, 25 Sep 2024 12:23:28 +0200 Subject: [PATCH 3/4] Fix test --- src/tests/pages/apps.test.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/pages/apps.test.tsx b/src/tests/pages/apps.test.tsx index 1349af7d11..37e0089a90 100644 --- a/src/tests/pages/apps.test.tsx +++ b/src/tests/pages/apps.test.tsx @@ -520,7 +520,6 @@ describe('AppsPage', () => { // zero results component expect(screen.getByText('No Safe Apps found', { exact: false })).toBeInTheDocument() - expect(screen.queryByText('Use WalletConnect')).toBeInTheDocument() }) }) }) From 632ba4b3be2a9c07dfcd9ffc6413082ffdce3b97 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Wed, 25 Sep 2024 14:40:08 +0200 Subject: [PATCH 4/4] Rm e2e test --- cypress/e2e/pages/dashboard.pages.js | 23 ----------------------- cypress/e2e/smoke/dashboard.cy.js | 5 ----- 2 files changed, 28 deletions(-) diff --git a/cypress/e2e/pages/dashboard.pages.js b/cypress/e2e/pages/dashboard.pages.js index 746106e154..ce1675e7c0 100644 --- a/cypress/e2e/pages/dashboard.pages.js +++ b/cypress/e2e/pages/dashboard.pages.js @@ -4,20 +4,16 @@ import * as main from './main.page.js' import * as createtx from './create_tx.pages.js' import staticSafes from '../../fixtures/safes/static.json' -const connectAndTransactStr = 'Connect & transact' const transactionQueueStr = 'Pending transactions' const noTransactionStr = 'This Safe has no queued transactions' const overviewStr = 'Total asset value' const sendStr = 'Send' const receiveStr = 'Receive' const viewAllStr = 'View all' -const transactionBuilderStr = 'Use Transaction Builder' const safeAppStr = 'Safe Apps' const exploreSafeApps = 'Explore Safe Apps' export const copiedAppUrl = 'share/safe-app?appUrl' -const txBuilder = 'a[href*="tx-builder"]' -const safeSpecificLink = 'a[href*="&appUrl=http"]' const copyShareBtn = '[data-testid="copy-btn-icon"]' const exploreAppsBtn = '[data-testid="explore-apps-btn"]' const viewAllLink = '[data-testid="view-all-link"][href^="/transactions/queue"]' @@ -108,10 +104,6 @@ export function verifyShareBtnWorks(index, data) { ) } -export function verifyConnectTransactStrIsVisible() { - cy.contains(connectAndTransactStr).should('be.visible') -} - export function verifyOverviewWidgetData() { // Alias for the Overview section cy.contains('div', overviewStr).parents('section').as('overviewSection') @@ -144,21 +136,6 @@ export function verifyTxQueueWidget() { }) } -export function verifyFeaturedAppsSection() { - // Alias for the featured Safe Apps section - cy.contains('h2', connectAndTransactStr).parents('section').as('featuredSafeAppsSection') - - // Tx Builder app - cy.get('@featuredSafeAppsSection').within(() => { - // Transaction Builder - cy.contains(transactionBuilderStr) - cy.get(txBuilder).should('exist') - - // Featured apps have a Safe-specific link - cy.get(safeSpecificLink).should('have.length', 1) - }) -} - export function verifySafeAppsSection() { cy.contains('h2', safeAppStr).parents('section').as('safeAppsSection') cy.get('@safeAppsSection').contains(exploreSafeApps) diff --git a/cypress/e2e/smoke/dashboard.cy.js b/cypress/e2e/smoke/dashboard.cy.js index 4d81e266a0..9ef1739b41 100644 --- a/cypress/e2e/smoke/dashboard.cy.js +++ b/cypress/e2e/smoke/dashboard.cy.js @@ -21,7 +21,6 @@ describe('[SMOKE] Dashboard tests', { defaultCommandTimeout: 20000 }, () => { cy.clearLocalStorage() cy.visit(constants.homeUrl + staticSafes.SEP_STATIC_SAFE_2) main.acceptCookies() - dashboard.verifyConnectTransactStrIsVisible() }) it('[SMOKE] Verify the overview widget is displayed', () => { @@ -32,10 +31,6 @@ describe('[SMOKE] Dashboard tests', { defaultCommandTimeout: 20000 }, () => { dashboard.verifyTxQueueWidget() }) - it('[SMOKE] Verify the featured Safe Apps are displayed', () => { - dashboard.verifyFeaturedAppsSection() - }) - it('[SMOKE] Verify the Safe Apps Section is displayed', () => { dashboard.verifySafeAppsSection() })