Skip to content

Commit

Permalink
[wallet-ext] add app categorization (MystenLabs#12519)
Browse files Browse the repository at this point in the history
## Description 


https://www.figma.com/file/xu2VnyPAuruNi74UQzGigW/02-Wallet?type=design&node-id=3036-57081&t=3nKpsSmwlPX7zhAq-0

<img width="387" alt="image"
src="https://github.com/MystenLabs/sui/assets/128089541/801b868c-d470-4b9a-9756-241f247015b8">
<img width="380" alt="image"
src="https://github.com/MystenLabs/sui/assets/128089541/d95f774c-68e0-48f7-a2f4-e952bd1981fa">
<img width="409" alt="image"
src="https://github.com/MystenLabs/sui/assets/128089541/d7a9809f-1317-4fee-bf64-4962842d6647">


## Test Plan 

Locally

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
Nikhil-Mysten authored Jun 22, 2023
1 parent cec9586 commit 06d0805
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.filter-tags {
display: flex;
gap: 8px;
overflow-x: auto;

.filter {
@include utils.typography('Primary/BodySmall-SB');
Expand Down
26 changes: 14 additions & 12 deletions apps/wallet/src/ui/app/components/filters-tags/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function activeTagsFilter({ isActive }: { isActive: boolean }) {
}

// TODO: extend this interface to include params and functions for the filter tags
interface Props {
export interface Props {
name: string;
link: string;
}
Expand All @@ -37,17 +37,19 @@ function FiltersPortal({ tags }: Tags) {
{element
? ReactDOM.createPortal(
<div className={st.filterTags}>
{tags.map((tag) => (
<NavLink
key={tag.link}
to={`/${tag.link}`}
end
className={activeTagsFilter}
title={tag.name}
>
<span className={st.title}>{tag.name}</span>
</NavLink>
))}
{tags.map((tag) => {
return (
<NavLink
key={tag.link}
to={`/${tag.link}`}
end
className={activeTagsFilter}
title={tag.name}
>
<span className={st.title}>{tag.name}</span>
</NavLink>
);
})}
</div>,
element,
)
Expand Down
5 changes: 4 additions & 1 deletion apps/wallet/src/ui/app/components/navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ function Navigation({ className }: NavigationProps) {
[st.hidden]: !isVisible,
})}
>
<div id="sui-apps-filters"></div>
<div
id="sui-apps-filters"
className="flex overflow-x-scroll whitespace-nowrap w-full justify-center"
></div>

<div className={st.navMenu}>
<NavLink data-testid="nav-tokens" to="./tokens" className={makeLinkCls} title="Tokens">
Expand Down
51 changes: 22 additions & 29 deletions apps/wallet/src/ui/app/components/sui-apps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,37 @@
// SPDX-License-Identifier: Apache-2.0

import { useFeature } from '@growthbook/growthbook-react';
import { ArrowUpRight16 } from '@mysten/icons';
import cl from 'classnames';
import { useMemo } from 'react';
import { useLocation } from 'react-router-dom';

import { useExplorerLink } from '../../hooks/useExplorerLink';
import { permissionsSelectors } from '../../redux/slices/permissions';
import { SuiApp, type DAppEntry } from './SuiApp';
import { SuiAppEmpty } from './SuiAppEmpty';
import { Button } from '_app/shared/ButtonUI';
import { Heading } from '_app/shared/heading';
import { Text } from '_app/shared/text';
import { ExplorerLinkType } from '_components/explorer-link/ExplorerLinkType';
import { useAppSelector } from '_hooks';
import { FEATURES } from '_src/shared/experimentation/features';
import { trackEvent } from '_src/shared/plausible';
import { prepareLinkToCompare } from '_src/shared/utils';

import st from './Playground.module.scss';

function AppsPlayGround() {
const ecosystemApps = useFeature<DAppEntry[]>(FEATURES.WALLET_DAPPS).value ?? [];
const ecosystemApps = useFeature<DAppEntry[]>(FEATURES.WALLET_DAPPS).value;
const location = useLocation();

const queryParams = new URLSearchParams(location.search);
const tagFilter = queryParams.get('tagFilter');

const filteredEcosystemApps = useMemo(() => {
if (!ecosystemApps) {
return [];
} else if (tagFilter) {
return ecosystemApps.filter((app) => app.tags.includes(tagFilter));
}
return ecosystemApps;
}, [ecosystemApps, tagFilter]);

const allPermissions = useAppSelector(permissionsSelectors.selectAll);
const linkToPermissionID = useMemo(() => {
const map = new Map<string, string>();
Expand All @@ -34,33 +44,16 @@ function AppsPlayGround() {
}
return map;
}, [allPermissions]);
const accountOnExplorerHref = useExplorerLink({
type: ExplorerLinkType.address,
useActiveAddress: true,
});

return (
<div className={cl(st.container)}>
<div className="flex justify-center">
<div className="flex justify-center mb-4">
<Heading variant="heading6" color="gray-90" weight="semibold">
Playground
Sui Apps
</Heading>
</div>
<div className="my-4">
<Button
variant="outline"
href={accountOnExplorerHref!}
text={
<div className="flex gap-1">
View your account on Sui Explorer <ArrowUpRight16 />
</div>
}
onClick={() => {
trackEvent('ViewExplorerAccount');
}}
/>
</div>

{ecosystemApps?.length ? (
{filteredEcosystemApps?.length ? (
<div className="p-4 bg-gray-40 rounded-xl">
<Text variant="pBodySmall" color="gray-75" weight="normal">
Apps below are actively curated but do not indicate any endorsement or relationship with
Expand All @@ -69,9 +62,9 @@ function AppsPlayGround() {
</div>
) : null}

{ecosystemApps?.length ? (
{filteredEcosystemApps?.length ? (
<div className={st.apps}>
{ecosystemApps.map((app) => (
{filteredEcosystemApps.map((app) => (
<SuiApp
key={app.link}
{...app}
Expand Down
48 changes: 41 additions & 7 deletions apps/wallet/src/ui/app/pages/home/apps/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,67 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { useFeature } from '@growthbook/growthbook-react';
import { Route, Routes } from 'react-router-dom';

import { Content } from '_app/shared/bottom-menu-layout';
import FiltersPortal from '_components/filters-tags';
import AppsPlayGround, { ConnectedAppsCard } from '_components/sui-apps';
import { FEATURES } from '_src/shared/experimentation/features';

import type { DAppEntry } from '_src/ui/app/components/sui-apps/SuiApp';

import st from './AppsPage.module.scss';

type FilterTag = {
name: string;
link: string;
};

function AppsPage() {
const filterTags = [
const defaultFilterTags: FilterTag[] = [
{
name: 'Playground',
link: 'apps',
name: 'Connections',
link: 'apps/connected',
},
{
name: 'Active Connections',
link: 'apps/connected',
name: 'All',
link: 'apps',
},
];
const ecosystemApps = useFeature<DAppEntry[]>(FEATURES.WALLET_DAPPS).value ?? [];

const uniqueAppTagNames = new Set<string>();

ecosystemApps
.flatMap((app) => app.tags)
.filter((tag) => {
if (uniqueAppTagNames.has(tag)) {
return false;
}

uniqueAppTagNames.add(tag);
return true;
});

const uniqueAppTags = Array.from(new Set(ecosystemApps.flatMap((app) => app.tags))).map(
(tag) => ({
name: tag,
// The tag subroute is used to get around the NavLink limitation with reading query params
// Enables active route highlighting without excessive overhead
link: `apps/${tag}?tagFilter=${tag}`,
}),
);

const allFilterTags = [...defaultFilterTags, ...uniqueAppTags];

return (
<div className={st.container}>
<Content>
<section>
<FiltersPortal tags={filterTags} />
<FiltersPortal tags={allFilterTags} />
<Routes>
<Route path="/" element={<AppsPlayGround />} />
<Route path="/*" element={<AppsPlayGround />} />
<Route path="/connected" element={<ConnectedAppsCard />} />
</Routes>
</section>
Expand Down

0 comments on commit 06d0805

Please sign in to comment.