From 62b8cd3883d7910b27b39b10b44686646846c118 Mon Sep 17 00:00:00 2001 From: Bart Date: Sun, 3 Sep 2023 18:23:31 +0200 Subject: [PATCH] Revamp navigation breadcrumbs (#186) * remove direct usages of useNavigation hook, minor restructuring * migrate to react-router v6, start routes restructure, rename some folders,... * restructure project routes * fix project links * refactor to data router * revamp breadcrumbs * fix active side link logic * fix referenced navigation paths, current project ID * fix scroll to storage card * fix scroll to storage card * refactoring fixes --- frontend/package.json | 4 +- frontend/src/App.tsx | 349 +++++++++++++----- .../breadcrumbs/Breadcrumbs.module.scss | 1 + .../components/breadcrumbs/Breadcrumbs.tsx | 51 ++- .../src/components/buttons/button/Button.tsx | 4 +- .../dialogs/snapshot/SnapshotDialog.tsx | 2 +- .../src/components/json-view/JsonView.tsx | 1 + .../src/components/layout/Layout.module.scss | 2 +- frontend/src/components/layout/Layout.tsx | 28 +- frontend/src/components/link/ProjectLink.tsx | 27 ++ .../side-navigation/SideNavigation.tsx | 52 ++- frontend/src/components/status/GrcpStatus.tsx | 1 - frontend/src/constants/routes.ts | 15 - frontend/src/contexts/project.context.tsx | 13 +- frontend/src/contexts/ui-state.context.tsx | 44 --- frontend/src/hooks/use-api.ts | 8 +- frontend/src/hooks/use-current-project-id.ts | 11 + frontend/src/hooks/use-navigation.ts | 53 --- .../accounts/AccountAvatar}/AccountAvatar.tsx | 2 +- .../AccountDetails.module.scss} | 46 --- .../AccountDetails/AccountDetails.tsx} | 42 +-- .../AccountKeysTable.module.scss | 34 ++ .../AccountKeysTable/AccountKeysTable.tsx} | 4 +- .../AccountLink}/AccountLink.module.scss | 0 .../accounts/AccountLink}/AccountLink.tsx | 9 +- .../accounts/AccountName}/AccountName.tsx | 0 .../AccountStorage.module.scss | 0 .../AccountStorage}/AccountStorage.tsx | 19 +- .../accounts/AccountsTable/AccountsTable.tsx} | 24 +- .../InternalStorageCard.module.scss} | 0 .../InternalStorageCard.tsx | 6 +- .../PublicPrivateStorageCard.module.scss | 0 .../PublicPrivateStorageCard.tsx | 14 +- .../StorageDomainBadge.module.scss} | 0 .../StorageDomainBadge.tsx | 4 +- .../BlockDetails/BlockDetails.module.scss} | 0 .../blocks/BlockDetails/BlockDetails.tsx} | 36 +- .../BlocksTable/BlocksTable.module.scss} | 0 .../blocks/BlocksTable/BlocksTable.tsx} | 26 +- .../ContractDetails/ContractDetails.tsx} | 26 +- .../ContractDetails}/Details.module.scss | 0 .../contracts}/ContractsTable.tsx | 16 +- .../EventsTable}/EventsTable.module.scss | 0 .../events/EventsTable}/EventsTable.tsx | 31 +- .../interactions/InteractionsPage.module.scss | 0 .../interactions/InteractionsPage.tsx | 0 .../execution/ExecutionSettings.module.scss | 0 .../execution/ExecutionSettings.tsx | 0 .../history/InteractionHistory.module.scss | 0 .../components/history/InteractionHistory.tsx | 0 .../InteractionIcon.module.scss | 0 .../interaction-icon/InteractionIcon.tsx | 0 .../InteractionLabel.module.scss | 0 .../interaction-label/InteractionLabel.tsx | 0 .../outcome/InteractionOutcome.module.scss | 0 .../components/outcome/InteractionOutcome.tsx | 2 +- .../ParamBuilder/ParamBuilder.module.scss | 0 .../parameters/ParamBuilder/ParamBuilder.tsx | 0 .../AddressBuilder/AddressBuilder.module.scss | 0 .../AddressBuilder/AddressBuilder.tsx | 4 +- .../ArrayBuilder/ArrayBuilder.module.scss | 0 .../ArrayBuilder/ArrayBuilder.tsx | 0 .../ValueBuilder/BoolBuilder/BoolBuilder.tsx | 0 .../DictionaryBuilder.module.scss | 0 .../DictionaryBuilder/DictionaryBuilder.tsx | 0 .../FixedPointNumberBuilder.tsx | 0 .../IntegerNumberBuilder.tsx | 0 .../PathBuilder/PathBuilder.module.scss | 0 .../ValueBuilder/PathBuilder/PathBuilder.tsx | 0 .../TextualBuilder/TextualBuilder.tsx | 0 .../parameters/ValueBuilder/ValueBuilder.tsx | 0 .../parameters/ValueBuilder/interface.ts | 0 .../InteractionTemplates.module.scss | 0 .../templates/InteractionTemplates.tsx | 1 - .../contexts/definition.context.tsx | 0 .../contexts/interaction-registry.context.tsx | 0 .../interactions/contexts/outcome.context.tsx | 0 .../hooks/use-transaction-name.ts | 0 .../{pages => modules}/logs/Logs.module.scss | 0 frontend/src/{pages => modules}/logs/Logs.tsx | 0 .../FormFields}/FormFields.module.scss | 0 .../projects/FormFields}/FormFields.tsx | 0 .../ProjectListPage.module.scss} | 0 .../ProjectListPage/ProjectListPage.tsx} | 35 +- .../ProjectSettings.module.scss} | 0 .../ProjectSettings/ProjectSettings.tsx} | 49 ++- .../SettingsSection.module.scss} | 0 .../SettingsSection/SettingsSection.tsx} | 4 +- .../TransactionsTable.module.scss | 0 .../TransactionsTable}/TransactionsTable.tsx | 8 +- .../transactions/details/Details.module.scss | 0 .../transactions/details/SignaturesTable.tsx | 6 +- .../details/TransactionDetails.tsx} | 28 +- .../details/TransactionOverview.tsx | 12 +- .../source/TransactionSource.module.scss | 0 .../details/source/TransactionSource.tsx | 0 frontend/src/pages/accounts/Accounts.tsx | 16 - frontend/src/pages/blocks/Blocks.tsx | 16 - frontend/src/pages/contracts/Contracts.tsx | 16 - frontend/src/pages/contracts/main/Main.tsx | 17 - frontend/src/pages/events/Events.tsx | 17 - frontend/src/pages/start/Start.tsx | 26 -- .../src/pages/transactions/Transactions.tsx | 19 - frontend/src/pages/transactions/main/Main.tsx | 17 - yarn.lock | 128 ++----- 105 files changed, 615 insertions(+), 811 deletions(-) create mode 100644 frontend/src/components/link/ProjectLink.tsx delete mode 100644 frontend/src/constants/routes.ts delete mode 100644 frontend/src/contexts/ui-state.context.tsx create mode 100644 frontend/src/hooks/use-current-project-id.ts delete mode 100644 frontend/src/hooks/use-navigation.ts rename frontend/src/{components/account/avatar => modules/accounts/AccountAvatar}/AccountAvatar.tsx (97%) rename frontend/src/{pages/accounts/details/Details.module.scss => modules/accounts/AccountDetails/AccountDetails.module.scss} (58%) rename frontend/src/{pages/accounts/details/Details.tsx => modules/accounts/AccountDetails/AccountDetails.tsx} (69%) create mode 100644 frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.module.scss rename frontend/src/{pages/accounts/details/KeysTable.tsx => modules/accounts/AccountKeysTable/AccountKeysTable.tsx} (93%) rename frontend/src/{components/account/link => modules/accounts/AccountLink}/AccountLink.module.scss (100%) rename frontend/src/{components/account/link => modules/accounts/AccountLink}/AccountLink.tsx (58%) rename frontend/src/{components/account/name => modules/accounts/AccountName}/AccountName.tsx (100%) rename frontend/src/{pages/accounts/details/storage => modules/accounts/AccountStorage}/AccountStorage.module.scss (100%) rename frontend/src/{pages/accounts/details/storage => modules/accounts/AccountStorage}/AccountStorage.tsx (81%) rename frontend/src/{pages/accounts/main/Main.tsx => modules/accounts/AccountsTable/AccountsTable.tsx} (72%) rename frontend/src/{pages/accounts/details/storage/cards/BaseStorageCard.module.scss => modules/accounts/InternalStorageCard/InternalStorageCard.module.scss} (100%) rename frontend/src/{pages/accounts/details/storage/cards => modules/accounts/InternalStorageCard}/InternalStorageCard.tsx (93%) rename frontend/src/{pages/accounts/details/storage/cards => modules/accounts/PublicPrivateStorageCard}/PublicPrivateStorageCard.module.scss (100%) rename frontend/src/{pages/accounts/details/storage/cards => modules/accounts/PublicPrivateStorageCard}/PublicPrivateStorageCard.tsx (86%) rename frontend/src/{pages/accounts/details/storage/StorageBadge.module.scss => modules/accounts/StorageDomainBadge/StorageDomainBadge.module.scss} (100%) rename frontend/src/{pages/accounts/details/storage => modules/accounts/StorageDomainBadge}/StorageDomainBadge.tsx (79%) rename frontend/src/{pages/blocks/details/Details.module.scss => modules/blocks/BlockDetails/BlockDetails.module.scss} (100%) rename frontend/src/{pages/blocks/details/Details.tsx => modules/blocks/BlockDetails/BlockDetails.tsx} (62%) rename frontend/src/{pages/blocks/main/Main.module.scss => modules/blocks/BlocksTable/BlocksTable.module.scss} (100%) rename frontend/src/{pages/blocks/main/Main.tsx => modules/blocks/BlocksTable/BlocksTable.tsx} (73%) rename frontend/src/{pages/contracts/details/Details.tsx => modules/contracts/ContractDetails/ContractDetails.tsx} (70%) rename frontend/src/{pages/contracts/details => modules/contracts/ContractDetails}/Details.module.scss (100%) rename frontend/src/{pages/contracts/main => modules/contracts}/ContractsTable.tsx (76%) rename frontend/src/{pages/events => modules/events/EventsTable}/EventsTable.module.scss (100%) rename frontend/src/{pages/events => modules/events/EventsTable}/EventsTable.tsx (84%) rename frontend/src/{pages => modules}/interactions/InteractionsPage.module.scss (100%) rename frontend/src/{pages => modules}/interactions/InteractionsPage.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/execution/ExecutionSettings.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/execution/ExecutionSettings.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/history/InteractionHistory.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/history/InteractionHistory.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/interaction-icon/InteractionIcon.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/interaction-icon/InteractionIcon.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/interaction-label/InteractionLabel.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/interaction-label/InteractionLabel.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/outcome/InteractionOutcome.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/outcome/InteractionOutcome.tsx (98%) rename frontend/src/{pages => modules}/interactions/components/parameters/ParamBuilder/ParamBuilder.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ParamBuilder/ParamBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx (95%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/BoolBuilder/BoolBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/FixedPointNumberBuilder/FixedPointNumberBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/IntegerNumberBuilder/IntegerNumberBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/TextualBuilder/TextualBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/ValueBuilder.tsx (100%) rename frontend/src/{pages => modules}/interactions/components/parameters/ValueBuilder/interface.ts (100%) rename frontend/src/{pages => modules}/interactions/components/templates/InteractionTemplates.module.scss (100%) rename frontend/src/{pages => modules}/interactions/components/templates/InteractionTemplates.tsx (98%) rename frontend/src/{pages => modules}/interactions/contexts/definition.context.tsx (100%) rename frontend/src/{pages => modules}/interactions/contexts/interaction-registry.context.tsx (100%) rename frontend/src/{pages => modules}/interactions/contexts/outcome.context.tsx (100%) rename frontend/src/{pages => modules}/interactions/hooks/use-transaction-name.ts (100%) rename frontend/src/{pages => modules}/logs/Logs.module.scss (100%) rename frontend/src/{pages => modules}/logs/Logs.tsx (100%) rename frontend/src/{pages/start/configuration => modules/projects/FormFields}/FormFields.module.scss (100%) rename frontend/src/{pages/start/configuration => modules/projects/FormFields}/FormFields.tsx (100%) rename frontend/src/{pages/start/main/Main.module.scss => modules/projects/ProjectListPage/ProjectListPage.module.scss} (100%) rename frontend/src/{pages/start/main/Main.tsx => modules/projects/ProjectListPage/ProjectListPage.tsx} (88%) rename frontend/src/{pages/start/configuration/Configuration.module.scss => modules/projects/ProjectSettings/ProjectSettings.module.scss} (100%) rename frontend/src/{pages/start/configuration/Configuration.tsx => modules/projects/ProjectSettings/ProjectSettings.tsx} (92%) rename frontend/src/{pages/start/configuration/ConfigurationSection.module.scss => modules/projects/SettingsSection/SettingsSection.module.scss} (100%) rename frontend/src/{pages/start/configuration/ConfigurationSection.tsx => modules/projects/SettingsSection/SettingsSection.tsx} (92%) rename frontend/src/{pages/transactions/main => modules/transactions/TransactionsTable}/TransactionsTable.module.scss (100%) rename frontend/src/{pages/transactions/main => modules/transactions/TransactionsTable}/TransactionsTable.tsx (92%) rename frontend/src/{pages => modules}/transactions/details/Details.module.scss (100%) rename frontend/src/{pages => modules}/transactions/details/SignaturesTable.tsx (90%) rename frontend/src/{pages/transactions/details/Details.tsx => modules/transactions/details/TransactionDetails.tsx} (75%) rename frontend/src/{pages => modules}/transactions/details/TransactionOverview.tsx (88%) rename frontend/src/{pages => modules}/transactions/details/source/TransactionSource.module.scss (100%) rename frontend/src/{pages => modules}/transactions/details/source/TransactionSource.tsx (100%) delete mode 100644 frontend/src/pages/accounts/Accounts.tsx delete mode 100644 frontend/src/pages/blocks/Blocks.tsx delete mode 100644 frontend/src/pages/contracts/Contracts.tsx delete mode 100644 frontend/src/pages/contracts/main/Main.tsx delete mode 100644 frontend/src/pages/events/Events.tsx delete mode 100644 frontend/src/pages/start/Start.tsx delete mode 100644 frontend/src/pages/transactions/Transactions.tsx delete mode 100644 frontend/src/pages/transactions/main/Main.tsx diff --git a/frontend/package.json b/frontend/package.json index 967ecef8..73facdd0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,7 +28,6 @@ "@types/node": "^12.20.27", "@types/react": "^17.0.24", "@types/react-dom": "^17.0.9", - "@types/react-router-dom": "^5.3.0", "@types/react-timeago": "^4.1.3", "@uiw/codemirror-extensions-basic-setup": "^4.12.4", "@uiw/codemirror-theme-github": "^4.12.4", @@ -53,11 +52,10 @@ "react-dom": "^17.0.2", "react-hot-toast": "^2.1.1", "react-json-view": "^1.21.3", - "react-loader-spinner": "^4.0.0", "react-modern-drawer": "^1.1.2", "react-pro-sidebar": "^0.7.1", "react-query": "^3.24.4", - "react-router-dom": "^5.3.0", + "react-router-dom": "6.15.0", "react-scripts": "5.0.0", "react-timeago": "^6.2.1", "sqlite3": "^5.0.11", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 116d99db..35ae7811 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,26 +1,16 @@ -import React, { ReactElement, useEffect } from "react"; +import React, { ReactElement, ReactNode, useEffect } from "react"; import { - BrowserRouter, - Redirect, - Route, - RouteComponentProps, - Switch, - withRouter, + createBrowserRouter, + Outlet, + RouterProvider, + useLocation, + useParams, } from "react-router-dom"; import { Toaster } from "react-hot-toast"; -import { RouteWithProjectLayout } from "./components/layout/Layout"; -import { routes } from "./constants/routes"; -import { UiStateContextProvider } from "./contexts/ui-state.context"; +import { BackButtonLayout, ProjectLayout } from "./components/layout/Layout"; import "./App.scss"; import { toastOptions } from "./config/toast"; -// pages -import Start from "./pages/start/Start"; -import Accounts from "./pages/accounts/Accounts"; -import Blocks from "./pages/blocks/Blocks"; -import Transactions from "./pages/transactions/Transactions"; -import Contracts from "./pages/contracts/Contracts"; -import Events from "./pages/events/Events"; import { ProjectProvider } from "./contexts/project.context"; import { ConfirmDialogProvider } from "./contexts/confirm-dialog.context"; import { QueryClientProvider } from "react-query"; @@ -35,35 +25,45 @@ import { ConsentDialog } from "./components/dialogs/consent/ConsentDialog"; import { useAnalyticsConsent } from "./hooks/use-analytics-consent"; import { ServiceRegistry } from "./services/service-registry"; import { AnalyticEvent } from "./services/analytics.service"; -import { InteractionsPage } from "./pages/interactions/InteractionsPage"; -import { InteractionRegistryProvider } from "pages/interactions/contexts/interaction-registry.context"; -import { Configuration } from "./pages/start/configuration/Configuration"; - -const BrowserRouterEvents = withRouter( - ({ - children, - history, - location, - }: RouteComponentProps & { children: ReactElement[] }) => { - const { analyticsService } = ServiceRegistry.getInstance(); - - useEffect(() => { - history.listen((location, action) => { - analyticsService.track(AnalyticEvent.PAGE_VIEW, { - location, - action, - }); - }); - }, []); - - useEffect(() => { - // scroll to the top on every route change - window.scrollTo(0, 0); - }, [location]); - - return <>{children}; - } -); +import { InteractionsPage } from "./modules/interactions/InteractionsPage"; +import { InteractionRegistryProvider } from "modules/interactions/contexts/interaction-registry.context"; +import { ProjectSettings } from "./modules/projects/ProjectSettings/ProjectSettings"; +import { + useGetPollingAccounts, + useGetPollingBlocks, + useGetPollingContracts, + useGetPollingEvents, + useGetPollingTransactions, +} from "./hooks/use-api"; +import { TransactionsTable } from "./modules/transactions/TransactionsTable/TransactionsTable"; +import { TransactionDetails } from "./modules/transactions/details/TransactionDetails"; +import { BlockDetails } from "./modules/blocks/BlockDetails/BlockDetails"; +import { BlocksTable } from "./modules/blocks/BlocksTable/BlocksTable"; +import { AccountDetails } from "./modules/accounts/AccountDetails/AccountDetails"; +import { AccountsTable } from "./modules/accounts/AccountsTable/AccountsTable"; +import { ProjectListPage } from "./modules/projects/ProjectListPage/ProjectListPage"; +import { ContractsTable } from "./modules/contracts/ContractsTable"; +import { ContractDetails } from "./modules/contracts/ContractDetails/ContractDetails"; +import { EventsTable } from "./modules/events/EventsTable/EventsTable"; +import { createCrumbHandle } from "./components/breadcrumbs/Breadcrumbs"; + +const BrowserRouterEvents = (props: { children: ReactNode }): ReactElement => { + const location = useLocation(); + const { analyticsService } = ServiceRegistry.getInstance(); + + useEffect(() => { + analyticsService.track(AnalyticEvent.PAGE_VIEW, { + location, + }); + }, [location]); + + useEffect(() => { + // scroll to the top on every route change + window.scrollTo(0, 0); + }, [location]); + + return <>{props.children}; +}; export type FlowserClientAppProps = { platformAdapter: PlatformAdapterState; @@ -77,57 +77,162 @@ export const FlowserClientApp = ({ return ( - - - - - - - - - - - - - + + + + + + + + + + ); }; -export const FlowserRoutes = (): ReactElement => { - return ( - - - - - - - - - - - - - - - - - ); -}; +const router = createBrowserRouter([ + { + path: "projects", + element: ( + + + + + + ), + children: [ + { + index: true, + element: , + }, + { + path: "create", + element: ( + + + + ), + }, + { + path: ":projectId", + element: ( + + + + ), + children: [ + { + path: "ProjectSettings", + element: , + }, + { + path: "accounts", + handle: createCrumbHandle({ + crumbName: "Accounts", + }), + children: [ + { + index: true, + element: , + }, + { + path: ":accountId", + element: , + handle: createCrumbHandle({ + crumbName: "Details", + }), + }, + ], + }, + { + path: "blocks", + handle: createCrumbHandle({ + crumbName: "Blocks", + }), + children: [ + { + index: true, + element: , + }, + { + path: ":blockId", + element: , + handle: createCrumbHandle({ + crumbName: "Details", + }), + }, + ], + }, + { + path: "transactions", + handle: createCrumbHandle({ + crumbName: "Transactions", + }), + children: [ + { + index: true, + element: , + }, + { + path: ":transactionId", + element: , + handle: createCrumbHandle({ + crumbName: "Details", + }), + }, + ], + }, + { + path: "contracts", + handle: createCrumbHandle({ + crumbName: "Contracts", + }), + children: [ + { + index: true, + element: , + }, + { + path: ":contractId", + element: , + handle: createCrumbHandle({ + crumbName: "Details", + }), + }, + ], + }, + { + path: "events", + handle: createCrumbHandle({ + crumbName: "Events", + }), + children: [ + { + index: true, + element: , + }, + ], + }, + { + path: "interactions", + children: [ + { + index: true, + element: , + }, + ], + }, + ], + }, + ], + }, +]); function ConsentAnalytics() { const { isConsented, setIsConsented } = useAnalyticsConsent(); @@ -136,3 +241,63 @@ function ConsentAnalytics() { } return ; } + +function ProjectSettingsPage() { + const { projectId } = useParams(); + + return ; +} + +function TransactionsTablePage() { + const { data } = useGetPollingTransactions(); + + return ; +} + +function TransactionDetailsPage() { + const { transactionId } = useParams(); + + return ; +} + +function BlocksTablePage() { + const { data } = useGetPollingBlocks(); + + return ; +} + +function BlockDetailsPage() { + const { blockId } = useParams(); + + return ; +} + +function AccountsTablePage() { + const { data } = useGetPollingAccounts(); + + return ; +} + +function AccountDetailsPage() { + const { accountId } = useParams(); + + return ; +} + +function ContractsTablePage() { + const { data } = useGetPollingContracts(); + + return ; +} + +function ContractDetailsPage() { + const { contractId } = useParams(); + + return ; +} + +function EventsTablePage() { + const { data } = useGetPollingEvents(); + + return ; +} diff --git a/frontend/src/components/breadcrumbs/Breadcrumbs.module.scss b/frontend/src/components/breadcrumbs/Breadcrumbs.module.scss index a75673f8..0af5bc5a 100644 --- a/frontend/src/components/breadcrumbs/Breadcrumbs.module.scss +++ b/frontend/src/components/breadcrumbs/Breadcrumbs.module.scss @@ -8,6 +8,7 @@ padding: $spacing-s $spacing-base; border-radius: $border-radius-card; align-items: center; + height: 40px; .backButtonWrapper { width: 40px; diff --git a/frontend/src/components/breadcrumbs/Breadcrumbs.tsx b/frontend/src/components/breadcrumbs/Breadcrumbs.tsx index 4a819e3d..8a5edfb5 100644 --- a/frontend/src/components/breadcrumbs/Breadcrumbs.tsx +++ b/frontend/src/components/breadcrumbs/Breadcrumbs.tsx @@ -1,6 +1,5 @@ -import React, { ReactElement, useCallback } from "react"; -import { NavLink, useHistory } from "react-router-dom"; -import { useNavigation } from "../../hooks/use-navigation"; +import React, { ReactElement } from "react"; +import { NavLink, useMatches, useNavigate } from "react-router-dom"; import classes from "./Breadcrumbs.module.scss"; import { ReactComponent as IconBackButton } from "../../assets/icons/back-button.svg"; import classNames from "classnames"; @@ -9,24 +8,52 @@ type BreadcrumbsProps = { className?: string; }; +type CrumbHandle = { + crumbName: string; +}; + +type Match = { pathname: string; handle: unknown }; + +type MatchWithCrumb = { + pathname: string; + handle: CrumbHandle; +}; + +type Breadcrumb = { + to: string; + label: string; +}; + +// Utility function used to create a handle with crumbs in a type-safe way. +export function createCrumbHandle(crumbHandle: CrumbHandle): CrumbHandle { + return crumbHandle; +} + +function isMatchWithCrumb(match: Match): match is MatchWithCrumb { + return match.handle instanceof Object && "crumbName" in match.handle; +} + export function Breadcrumbs(props: BreadcrumbsProps): ReactElement | null { - const { isShowBackButtonVisible, isBreadcrumbsVisible, breadcrumbs } = - useNavigation(); - const history = useHistory(); + const navigate = useNavigate(); const currentUrl = window.location.pathname; - const onBack = useCallback(() => { - history.goBack(); - }, []); + const matches: Match[] = useMatches(); + const matchesWithCrumbs: MatchWithCrumb[] = matches.filter(isMatchWithCrumb); + const breadcrumbs = matchesWithCrumbs.map( + (match): Breadcrumb => ({ + to: match.pathname, + label: match.handle.crumbName, + }) + ); - if (!isBreadcrumbsVisible) { + if (breadcrumbs.length === 0) { return null; } return (
- {isShowBackButtonVisible && ( -
+ {breadcrumbs.length > 1 && ( +
navigate(-1)}>
)} diff --git a/frontend/src/components/buttons/button/Button.tsx b/frontend/src/components/buttons/button/Button.tsx index 81b03c22..4e8064ba 100644 --- a/frontend/src/components/buttons/button/Button.tsx +++ b/frontend/src/components/buttons/button/Button.tsx @@ -1,7 +1,7 @@ import React, { FunctionComponent, HTMLAttributes } from "react"; import classes from "./Button.module.scss"; -import Loader from "react-loader-spinner"; import classNames from "classnames"; +import { Spinner } from "../../spinner/Spinner"; export type ButtonProps = React.DetailedHTMLProps< React.ButtonHTMLAttributes, @@ -41,7 +41,7 @@ const Button: FunctionComponent = ({ > {loading && (
- +
)}
+ {/* @ts-ignore */} = (props) => { - const history = useHistory(); +export const BackButtonLayout: FC<{ children: ReactNode }> = (props) => { + const navigate = useNavigate(); return (
{ - history.goBack(); - }} + onClick={() => navigate(-1)} className={classes.backButton} />
- + {props.children}
); }; -export const RouteWithProjectLayout: FC = (props) => ( - - - -); +export const scrollableElementId = "flowser-scroll"; -const ProjectLayout: FunctionComponent = ({ children }) => { +export const ProjectLayout: FunctionComponent = ({ children }) => { const location = useLocation(); - const showMargin = !location.pathname.startsWith(routes.interactions); + const showMargin = !location.pathname.endsWith("interactions"); return (
@@ -41,6 +34,7 @@ const ProjectLayout: FunctionComponent = ({ children }) => {
+ ); +} + +export function buildProjectUrl(options: { + projectId: string; + subPath: To; +}): string { + return `/projects/${options.projectId}${options.subPath}`; +} diff --git a/frontend/src/components/side-navigation/SideNavigation.tsx b/frontend/src/components/side-navigation/SideNavigation.tsx index 96b23b40..949279c2 100644 --- a/frontend/src/components/side-navigation/SideNavigation.tsx +++ b/frontend/src/components/side-navigation/SideNavigation.tsx @@ -1,12 +1,12 @@ import React, { ReactElement } from "react"; import classes from "./SideNavigation.module.scss"; -import { routes } from "../../constants/routes"; -import { NavLink } from "react-router-dom"; +import { useMatches } from "react-router-dom"; import { FlowserIcon } from "components/icons/Icons"; import { SizedBox } from "../sized-box/SizedBox"; import classNames from "classnames"; -import { useGetCurrentProject } from "../../hooks/use-api"; import { useProjectActions } from "../../contexts/project.context"; +import { buildProjectUrl, ProjectLink } from "../link/ProjectLink"; +import { useCurrentProjectId } from "hooks/use-current-project-id"; type SideNavigationProps = { className?: string; @@ -14,32 +14,21 @@ type SideNavigationProps = { export function SideNavigation(props: SideNavigationProps): ReactElement { const { switchProject } = useProjectActions(); - const { data: currentProjectData } = useGetCurrentProject(); - const { project: currentProject } = currentProjectData ?? {}; return (
- - - - - - - {currentProject && ( - - )} + + + + + + +
- +
); } @@ -49,21 +38,30 @@ function FlowserLogo() { return ; } -function ProjectLink(props: { +function Link(props: { to: string; icon: React.FunctionComponent>; onClick?: () => void; }) { + const projectId = useCurrentProjectId(); + const fullTargetUrl = buildProjectUrl({ + projectId, + subPath: props.to, + }); + const matches = useMatches(); + const isActive = matches.some((match) => match.pathname === fullTargetUrl); const Icon = props.icon; const iconSize = 20; + return ( - - + ); } diff --git a/frontend/src/components/status/GrcpStatus.tsx b/frontend/src/components/status/GrcpStatus.tsx index 3fa57614..5c1cc0d6 100644 --- a/frontend/src/components/status/GrcpStatus.tsx +++ b/frontend/src/components/status/GrcpStatus.tsx @@ -12,7 +12,6 @@ export type GrcpStatusProps = { export function GrcpStatus({ status }: GrcpStatusProps): ReactElement { const { grcpStatus } = status ?? {}; - console.log(grcpStatus); const statusName = FlowUtils.getGrcpStatusName(grcpStatus); return (
diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts deleted file mode 100644 index 0a98034c..00000000 --- a/frontend/src/constants/routes.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const routes = { - start: "/start", - configure: "/start/configure", - configureExisting: "/start/configure/:id", - configureCurrent: "/configure/:id", - accounts: "/accounts", - blocks: "/blocks", - transactions: "/transactions", - contracts: "/contracts", - events: "/events", - interactions: "/interactions", - logs: "/logs", - firstRouteAfterStart: "/accounts", - project: "/project", -}; diff --git a/frontend/src/contexts/project.context.tsx b/frontend/src/contexts/project.context.tsx index 8bb20609..761dfc98 100644 --- a/frontend/src/contexts/project.context.tsx +++ b/frontend/src/contexts/project.context.tsx @@ -7,8 +7,6 @@ import React, { useMemo, useEffect, } from "react"; -import { routes } from "../constants/routes"; -import { useHistory } from "react-router-dom"; import toast from "react-hot-toast"; import { Block, EmulatorSnapshot, Project } from "@flowser/shared"; import { useConfirmDialog } from "./confirm-dialog.context"; @@ -26,6 +24,7 @@ import { AnalyticEvent } from "../services/analytics.service"; import { FlowUtils } from "../utils/flow-utils"; import * as fcl from "@onflow/fcl"; import { SnapshotDialog } from "components/dialogs/snapshot/SnapshotDialog"; +import { useNavigate } from "react-router-dom"; export type ProjectActionsContextState = { switchProject: () => Promise; @@ -53,7 +52,7 @@ export function ProjectProvider({ const { track } = useAnalytics(); const queryClient = useQueryClient(); - const history = useHistory(); + const navigate = useNavigate(); const { handleError } = useErrorHandler(ProjectProvider.name); const { showDialog, hideDialog } = useConfirmDialog(); const { data: currentProject, refetch: refetchCurrentProject } = @@ -96,7 +95,9 @@ export function ProjectProvider({ error: `Failed to delete project "${project.name}"`, success: `Project "${project.name}" deleted!`, }); - history.replace(routes.start); + navigate("/projects", { + replace: true, + }); } catch (e) { toast.error("Something went wrong: can not delete custom emulator"); } finally { @@ -126,7 +127,9 @@ export function ProjectProvider({ // Clear the entire cache, // so that previous data isn't there when using another project queryClient.clear(); - history.replace(routes.start); + navigate("/projects", { + replace: true, + }); }; await toast.promise(execute(), { loading: "Closing project...", diff --git a/frontend/src/contexts/ui-state.context.tsx b/frontend/src/contexts/ui-state.context.tsx deleted file mode 100644 index 1a232068..00000000 --- a/frontend/src/contexts/ui-state.context.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { - createContext, - Dispatch, - FunctionComponent, - SetStateAction, - useContext, - useState, -} from "react"; -import { NavigationUiState } from "../hooks/use-navigation"; - -export interface UiState extends NavigationUiState { - placeholder: { [key: string]: string }; - searchTerm: { [key: string]: string }; - searchDisabled: boolean; -} - -export const defaultUiState: UiState = { - placeholder: { default: "Search" }, - searchTerm: { default: "" }, - searchDisabled: false, - breadcrumbs: [], - isBreadcrumbsVisible: false, - isShowBackButtonVisible: true, - isSearchBarVisible: true, -}; - -type UiStateContext = [UiState, Dispatch>]; - -const UiStateContext = createContext([ - defaultUiState, - () => undefined, -]); - -export function useUiStateContext(): UiStateContext { - return useContext(UiStateContext); -} -export const UiStateContextProvider: FunctionComponent = ({ children }) => { - const [state, setState] = useState(defaultUiState); - return ( - - {children} - - ); -}; diff --git a/frontend/src/hooks/use-api.ts b/frontend/src/hooks/use-api.ts index e9a6689b..f895718a 100644 --- a/frontend/src/hooks/use-api.ts +++ b/frontend/src/hooks/use-api.ts @@ -46,6 +46,7 @@ import { useProjectTimeoutPolling, } from "contexts/timeout-polling.context"; import { useEffect, useState } from "react"; +import { useCurrentProjectId } from "./use-current-project-id"; const { projectsService, @@ -246,11 +247,6 @@ export function useGetTransaction(transactionId: string | undefined) { ); } -export function useCurrentProjectId(): string | undefined { - const { data } = useGetCurrentProject(); - return data?.project?.id; -} - export const getCurrentProjectKey = "/projects/current"; export function useGetCurrentProject() { @@ -391,7 +387,7 @@ export function useGetFlowCliInfo() { } export function useGetPollingEmulatorSnapshots(): TimeoutPollingHook { - const projectId = useCurrentProjectId() ?? ""; + const projectId = useCurrentProjectId(); return useTimeoutPolling< EmulatorSnapshot, GetPollingEmulatorSnapshotsResponse diff --git a/frontend/src/hooks/use-current-project-id.ts b/frontend/src/hooks/use-current-project-id.ts new file mode 100644 index 00000000..fa5c62b8 --- /dev/null +++ b/frontend/src/hooks/use-current-project-id.ts @@ -0,0 +1,11 @@ +import { useParams } from "react-router-dom"; + +export function useCurrentProjectId(): string { + const { projectId } = useParams(); + + // if (!projectId) { + // throw new Error("Project ID not found in URL"); + // } + + return projectId ?? ""; +} diff --git a/frontend/src/hooks/use-navigation.ts b/frontend/src/hooks/use-navigation.ts deleted file mode 100644 index a813ba6c..00000000 --- a/frontend/src/hooks/use-navigation.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { UiState, useUiStateContext } from "../contexts/ui-state.context"; - -export interface Breadcrumb { - to?: string; - label: string; -} - -export interface NavigationUiState { - breadcrumbs: Breadcrumb[]; - isBreadcrumbsVisible: boolean; - isShowBackButtonVisible: boolean; - isSearchBarVisible: boolean; -} - -export interface UseNavigationHook extends NavigationUiState { - showNavigationDrawer: (show: boolean) => void; - showBackButton: (show: boolean) => void; - showSearchBar: (show: boolean) => void; - setBreadcrumbs: (breadcrumbs: Breadcrumb[]) => void; -} - -export const useNavigation = (): UseNavigationHook => { - const [state, setState] = useUiStateContext(); - - const showNavigationDrawer = (show: boolean) => { - setState((state: UiState) => ({ - ...state, - isBreadcrumbsVisible: show, - })); - }; - const showBackButton = (show: boolean) => { - setState((state: UiState) => ({ ...state, isShowBackButtonVisible: show })); - }; - - const showSearchBar = (show: boolean) => { - setState((state: UiState) => ({ ...state, isSearchBarVisible: show })); - }; - - const setBreadcrumbs = (breadcrumbs: Breadcrumb[]) => { - setState((state: UiState) => ({ ...state, breadcrumbs })); - }; - - return { - showNavigationDrawer, - showBackButton, - showSearchBar, - setBreadcrumbs, - breadcrumbs: state.breadcrumbs, - isBreadcrumbsVisible: state.isBreadcrumbsVisible, - isShowBackButtonVisible: state.isShowBackButtonVisible, - isSearchBarVisible: state.isSearchBarVisible, - }; -}; diff --git a/frontend/src/components/account/avatar/AccountAvatar.tsx b/frontend/src/modules/accounts/AccountAvatar/AccountAvatar.tsx similarity index 97% rename from frontend/src/components/account/avatar/AccountAvatar.tsx rename to frontend/src/modules/accounts/AccountAvatar/AccountAvatar.tsx index b52ea17e..794d17f9 100644 --- a/frontend/src/components/account/avatar/AccountAvatar.tsx +++ b/frontend/src/modules/accounts/AccountAvatar/AccountAvatar.tsx @@ -19,7 +19,7 @@ import avatar14 from "../../../assets/images/avatars/14.jpg"; import avatar15 from "../../../assets/images/avatars/15.jpg"; import avatar16 from "../../../assets/images/avatars/16.jpg"; import { useGetAddressIndex } from "../../../hooks/use-api"; -import { Spinner } from "../../spinner/Spinner"; +import { Spinner } from "../../../components/spinner/Spinner"; const avatarUrls = [ avatar1, diff --git a/frontend/src/pages/accounts/details/Details.module.scss b/frontend/src/modules/accounts/AccountDetails/AccountDetails.module.scss similarity index 58% rename from frontend/src/pages/accounts/details/Details.module.scss rename to frontend/src/modules/accounts/AccountDetails/AccountDetails.module.scss index ef9623d9..e120fb4e 100644 --- a/frontend/src/pages/accounts/details/Details.module.scss +++ b/frontend/src/modules/accounts/AccountDetails/AccountDetails.module.scss @@ -49,49 +49,3 @@ margin-bottom: $spacing-l; } } - -.storageTable { - .identifierColumn { - flex: 2; - } - .dataColumn { - flex: 5; - overflow: scroll; - &::-webkit-scrollbar { - display: none; - } - } -} - -.hash { - display: inline-block; - - max-width: 90vw; - margin: $spacing-base; -} - -.badges { - color: $color-grey; - font-family: $font-family-inter; - margin-bottom: $spacing-base; - flex-wrap: wrap; - & > * { - margin-top: $spacing-base; - margin-right: $spacing-base; - } -} - -.keysRoot { - display: flex; - flex-direction: column; - font-size: $font-size-small; - - .row { - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - } -} - - diff --git a/frontend/src/pages/accounts/details/Details.tsx b/frontend/src/modules/accounts/AccountDetails/AccountDetails.tsx similarity index 69% rename from frontend/src/pages/accounts/details/Details.tsx rename to frontend/src/modules/accounts/AccountDetails/AccountDetails.tsx index 0fe03b8a..e1a68852 100644 --- a/frontend/src/pages/accounts/details/Details.tsx +++ b/frontend/src/modules/accounts/AccountDetails/AccountDetails.tsx @@ -1,7 +1,5 @@ -import React, { FunctionComponent, useEffect } from "react"; -import { Breadcrumb, useNavigation } from "../../../hooks/use-navigation"; -import classes from "./Details.module.scss"; -import { useParams } from "react-router-dom"; +import React, { FunctionComponent } from "react"; +import classes from "./AccountDetails.module.scss"; import FullScreenLoading from "../../../components/fullscreen-loading/FullScreenLoading"; import { useGetAccount, @@ -15,39 +13,29 @@ import { } from "components/details-card/DetailsCard"; import { TextUtils } from "../../../utils/text-utils"; import { SizedBox } from "../../../components/sized-box/SizedBox"; -import { AccountAvatar } from "../../../components/account/avatar/AccountAvatar"; -import { AccountName } from "../../../components/account/name/AccountName"; +import { AccountAvatar } from "../AccountAvatar/AccountAvatar"; +import { AccountName } from "../AccountName/AccountName"; import { StyledTabs } from "../../../components/tabs/StyledTabs"; -import { AccountStorage } from "./storage/AccountStorage"; -import { TransactionsTable } from "../../transactions/main/TransactionsTable"; -import { ContractsTable } from "../../contracts/main/ContractsTable"; -import { KeysTable } from "./KeysTable"; +import { AccountStorage } from "../AccountStorage/AccountStorage"; +import { TransactionsTable } from "../../transactions/TransactionsTable/TransactionsTable"; +import { ContractsTable } from "../../contracts/ContractsTable"; +import { AccountKeysTable } from "../AccountKeysTable/AccountKeysTable"; import { CadenceEditor } from "../../../components/cadence-editor/CadenceEditor"; -export type AccountDetailsRouteParams = { +type AccountDetailsProps = { accountId: string; }; -const Details: FunctionComponent = () => { - const { accountId } = useParams(); - const { setBreadcrumbs } = useNavigation(); - const { showNavigationDrawer } = useNavigation(); +export const AccountDetails: FunctionComponent = ( + props +) => { + const { accountId } = props; const { data, isLoading } = useGetAccount(accountId); const { data: transactions } = useGetPollingTransactionsByAccount(accountId); const { data: contracts } = useGetPollingContractsByAccount(accountId); const { data: keys } = useGetPollingKeysByAccount(accountId); const { account } = data ?? {}; - const breadcrumbs: Breadcrumb[] = [ - { to: "/accounts", label: "Accounts" }, - { label: "Details" }, - ]; - - useEffect(() => { - showNavigationDrawer(true); - setBreadcrumbs(breadcrumbs); - }, []); - if (isLoading || !account) { return ; } @@ -106,7 +94,7 @@ const Details: FunctionComponent = () => { { id: "keys", label: "Keys", - content: , + content: , }, { id: "scripts", @@ -118,5 +106,3 @@ const Details: FunctionComponent = () => {
); }; - -export default Details; diff --git a/frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.module.scss b/frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.module.scss new file mode 100644 index 00000000..cb128613 --- /dev/null +++ b/frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.module.scss @@ -0,0 +1,34 @@ +@import "styles/spacings"; +@import "styles/colors"; +@import "styles/typography"; + +.keysRoot { + display: flex; + flex-direction: column; + font-size: $font-size-small; + + .row { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + } +} + +.hash { + display: inline-block; + + max-width: 90vw; + margin: $spacing-base; +} + +.badges { + color: $color-grey; + font-family: $font-family-inter; + margin-bottom: $spacing-base; + flex-wrap: wrap; + & > * { + margin-top: $spacing-base; + margin-right: $spacing-base; + } +} diff --git a/frontend/src/pages/accounts/details/KeysTable.tsx b/frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.tsx similarity index 93% rename from frontend/src/pages/accounts/details/KeysTable.tsx rename to frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.tsx index 9d85d0af..91539e32 100644 --- a/frontend/src/pages/accounts/details/KeysTable.tsx +++ b/frontend/src/modules/accounts/AccountKeysTable/AccountKeysTable.tsx @@ -2,7 +2,7 @@ import { createColumnHelper } from "@tanstack/table-core"; import { DecoratedPollingEntity } from "../../../contexts/timeout-polling.context"; import { AccountKey } from "@flowser/shared"; import Label from "../../../components/label/Label"; -import classes from "./Details.module.scss"; +import classes from "../AccountDetails/AccountDetails.module.scss"; import MiddleEllipsis from "../../../components/ellipsis/MiddleEllipsis"; import CopyButton from "../../../components/buttons/copy-button/CopyButton"; import classNames from "classnames"; @@ -46,7 +46,7 @@ type KeysTableProps = { keys: DecoratedPollingEntity[]; }; -export function KeysTable(props: KeysTableProps): ReactElement { +export function AccountKeysTable(props: KeysTableProps): ReactElement { return ( > columns={columns} diff --git a/frontend/src/components/account/link/AccountLink.module.scss b/frontend/src/modules/accounts/AccountLink/AccountLink.module.scss similarity index 100% rename from frontend/src/components/account/link/AccountLink.module.scss rename to frontend/src/modules/accounts/AccountLink/AccountLink.module.scss diff --git a/frontend/src/components/account/link/AccountLink.tsx b/frontend/src/modules/accounts/AccountLink/AccountLink.tsx similarity index 58% rename from frontend/src/components/account/link/AccountLink.tsx rename to frontend/src/modules/accounts/AccountLink/AccountLink.tsx index 39368061..553bbe7f 100644 --- a/frontend/src/components/account/link/AccountLink.tsx +++ b/frontend/src/modules/accounts/AccountLink/AccountLink.tsx @@ -1,8 +1,9 @@ import React, { ReactElement } from "react"; import { NavLink } from "react-router-dom"; -import { AccountAvatar } from "../avatar/AccountAvatar"; -import { AccountName } from "../name/AccountName"; +import { AccountAvatar } from "../AccountAvatar/AccountAvatar"; +import { AccountName } from "../AccountName/AccountName"; import classes from "./AccountLink.module.scss"; +import { ProjectLink } from "../../../components/link/ProjectLink"; type AccountLinkProps = { address: string; @@ -11,9 +12,9 @@ type AccountLinkProps = { export function AccountLink(props: AccountLinkProps): ReactElement { const { address } = props; return ( - + - + ); } diff --git a/frontend/src/components/account/name/AccountName.tsx b/frontend/src/modules/accounts/AccountName/AccountName.tsx similarity index 100% rename from frontend/src/components/account/name/AccountName.tsx rename to frontend/src/modules/accounts/AccountName/AccountName.tsx diff --git a/frontend/src/pages/accounts/details/storage/AccountStorage.module.scss b/frontend/src/modules/accounts/AccountStorage/AccountStorage.module.scss similarity index 100% rename from frontend/src/pages/accounts/details/storage/AccountStorage.module.scss rename to frontend/src/modules/accounts/AccountStorage/AccountStorage.module.scss diff --git a/frontend/src/pages/accounts/details/storage/AccountStorage.tsx b/frontend/src/modules/accounts/AccountStorage/AccountStorage.tsx similarity index 81% rename from frontend/src/pages/accounts/details/storage/AccountStorage.tsx rename to frontend/src/modules/accounts/AccountStorage/AccountStorage.tsx index 1282f5f4..93363e09 100644 --- a/frontend/src/pages/accounts/details/storage/AccountStorage.tsx +++ b/frontend/src/modules/accounts/AccountStorage/AccountStorage.tsx @@ -1,14 +1,15 @@ import { Account, AccountStorageDomain } from "@flowser/shared"; -import { useAnalytics } from "../../../../hooks/use-analytics"; -import { useUrlQuery } from "../../../../hooks/use-url-query"; -import { useGetPollingStorageByAccount } from "../../../../hooks/use-api"; +import { useAnalytics } from "../../../hooks/use-analytics"; +import { useUrlQuery } from "../../../hooks/use-url-query"; +import { useGetPollingStorageByAccount } from "../../../hooks/use-api"; import React, { ReactElement, useEffect, useState } from "react"; -import { AnalyticEvent } from "../../../../services/analytics.service"; -import { PublicPrivateStorageCard } from "./cards/PublicPrivateStorageCard"; -import { enableDetailsIntroAnimation } from "../../../../config/common"; -import { InternalStorageCard } from "./cards/InternalStorageCard"; +import { AnalyticEvent } from "../../../services/analytics.service"; +import { PublicPrivateStorageCard } from "../PublicPrivateStorageCard/PublicPrivateStorageCard"; +import { enableDetailsIntroAnimation } from "../../../config/common"; +import { InternalStorageCard } from "../InternalStorageCard/InternalStorageCard"; import classNames from "classnames"; import classes from "./AccountStorage.module.scss"; +import { scrollableElementId } from "../../../components/layout/Layout"; type AccountStorageProps = { account: Account; @@ -32,7 +33,9 @@ export function AccountStorage(props: AccountStorageProps): ReactElement { // There might be a better React way to do this. setTimeout(() => { const targetDomNode = document.getElementById(focusedStorageId); - window.scrollTo(0, targetDomNode?.offsetTop ?? 0); + document + .getElementById(scrollableElementId) + ?.scrollTo(0, targetDomNode?.offsetTop ?? 0); }); } }, [focusedStorageId, storageItems]); diff --git a/frontend/src/pages/accounts/main/Main.tsx b/frontend/src/modules/accounts/AccountsTable/AccountsTable.tsx similarity index 72% rename from frontend/src/pages/accounts/main/Main.tsx rename to frontend/src/modules/accounts/AccountsTable/AccountsTable.tsx index a991a796..ab1afd5f 100644 --- a/frontend/src/pages/accounts/main/Main.tsx +++ b/frontend/src/modules/accounts/AccountsTable/AccountsTable.tsx @@ -1,19 +1,16 @@ -import React, { FunctionComponent, useEffect } from "react"; +import React, { FunctionComponent } from "react"; import Label from "../../../components/label/Label"; import Value from "../../../components/value/Value"; -import { useNavigation } from "../../../hooks/use-navigation"; -import { useGetPollingAccounts } from "../../../hooks/use-api"; import Table from "../../../components/table/Table"; import { createColumnHelper } from "@tanstack/react-table"; import { Account } from "@flowser/shared"; import { TextUtils } from "../../../utils/text-utils"; import ReactTimeago from "react-timeago"; import { DecoratedPollingEntity } from "contexts/timeout-polling.context"; -import { AccountLink } from "../../../components/account/link/AccountLink"; +import { AccountLink } from "../AccountLink/AccountLink"; const columnHelper = createColumnHelper>(); -// ACCOUNTS TABLE const columns = [ columnHelper.accessor("address", { header: () => , @@ -47,22 +44,15 @@ const columns = [ }), ]; -const Main: FunctionComponent = () => { - const { showNavigationDrawer } = useNavigation(); - const { data: accounts, firstFetch, error } = useGetPollingAccounts(); - - useEffect(() => { - showNavigationDrawer(false); - }, []); +type AccountsTableProps = { + accounts: DecoratedPollingEntity[]; +}; +export const AccountsTable: FunctionComponent = (props) => { return ( > - isInitialLoading={firstFetch} - error={error} columns={columns} - data={accounts} + data={props.accounts} /> ); }; - -export default Main; diff --git a/frontend/src/pages/accounts/details/storage/cards/BaseStorageCard.module.scss b/frontend/src/modules/accounts/InternalStorageCard/InternalStorageCard.module.scss similarity index 100% rename from frontend/src/pages/accounts/details/storage/cards/BaseStorageCard.module.scss rename to frontend/src/modules/accounts/InternalStorageCard/InternalStorageCard.module.scss diff --git a/frontend/src/pages/accounts/details/storage/cards/InternalStorageCard.tsx b/frontend/src/modules/accounts/InternalStorageCard/InternalStorageCard.tsx similarity index 93% rename from frontend/src/pages/accounts/details/storage/cards/InternalStorageCard.tsx rename to frontend/src/modules/accounts/InternalStorageCard/InternalStorageCard.tsx index 0afa5bec..90e8a0f9 100644 --- a/frontend/src/pages/accounts/details/storage/cards/InternalStorageCard.tsx +++ b/frontend/src/modules/accounts/InternalStorageCard/InternalStorageCard.tsx @@ -1,11 +1,11 @@ import React, { ReactElement } from "react"; -import classes from "./BaseStorageCard.module.scss"; +import classes from "./InternalStorageCard.module.scss"; import { AccountStorageItem } from "@flowser/shared/dist/src/generated/entities/accounts"; import { FlowUtils } from "utils/flow-utils"; import classNames from "classnames"; -import { SimpleButton } from "../../../../../components/buttons/simple-button/SimpleButton"; +import { SimpleButton } from "../../../components/buttons/simple-button/SimpleButton"; import { DecoratedPollingEntity } from "contexts/timeout-polling.context"; -import { JsonView } from "../../../../../components/json-view/JsonView"; +import { JsonView } from "../../../components/json-view/JsonView"; type ExtendableStorageCardProps = { storageItem: DecoratedPollingEntity; diff --git a/frontend/src/pages/accounts/details/storage/cards/PublicPrivateStorageCard.module.scss b/frontend/src/modules/accounts/PublicPrivateStorageCard/PublicPrivateStorageCard.module.scss similarity index 100% rename from frontend/src/pages/accounts/details/storage/cards/PublicPrivateStorageCard.module.scss rename to frontend/src/modules/accounts/PublicPrivateStorageCard/PublicPrivateStorageCard.module.scss diff --git a/frontend/src/pages/accounts/details/storage/cards/PublicPrivateStorageCard.tsx b/frontend/src/modules/accounts/PublicPrivateStorageCard/PublicPrivateStorageCard.tsx similarity index 86% rename from frontend/src/pages/accounts/details/storage/cards/PublicPrivateStorageCard.tsx rename to frontend/src/modules/accounts/PublicPrivateStorageCard/PublicPrivateStorageCard.tsx index ea6de96a..7f96a082 100644 --- a/frontend/src/pages/accounts/details/storage/cards/PublicPrivateStorageCard.tsx +++ b/frontend/src/modules/accounts/PublicPrivateStorageCard/PublicPrivateStorageCard.tsx @@ -1,12 +1,12 @@ import React, { ReactElement } from "react"; import classes from "./PublicPrivateStorageCard.module.scss"; -import { StorageDomainBadge } from "../StorageDomainBadge"; -import { NavLink } from "react-router-dom"; -import { ReactComponent as LinkIcon } from "../../../../../assets/icons/link.svg"; +import { StorageDomainBadge } from "../StorageDomainBadge/StorageDomainBadge"; +import { ReactComponent as LinkIcon } from "../../../assets/icons/link.svg"; import { AccountStorageItem } from "@flowser/shared/dist/src/generated/entities/accounts"; import { DecoratedPollingEntity } from "contexts/timeout-polling.context"; -import gradient from "../../../../../assets/images/gradient.png"; +import gradient from "../../../assets/images/gradient.png"; import classNames from "classnames"; +import { ProjectLink } from "../../../components/link/ProjectLink"; type StorageCardProps = { currentAccountAddress: string; @@ -39,10 +39,10 @@ export function PublicPrivateStorageCard({
{storageItem.pathIdentifier}
- +
{targetPathIdentifier}
-
+ {borrowType} @@ -80,6 +80,6 @@ function getTargetStorageCardUrl(options: { // TODO(milestone-x): Navigate to a specific sub-structure of the react-json-view (research)? return borrowTypePathParts - ? `/accounts/details/${targetAccountAddress}?${params.toString()}` + ? `/accounts/${targetAccountAddress}?${params.toString()}` : "#"; } diff --git a/frontend/src/pages/accounts/details/storage/StorageBadge.module.scss b/frontend/src/modules/accounts/StorageDomainBadge/StorageDomainBadge.module.scss similarity index 100% rename from frontend/src/pages/accounts/details/storage/StorageBadge.module.scss rename to frontend/src/modules/accounts/StorageDomainBadge/StorageDomainBadge.module.scss diff --git a/frontend/src/pages/accounts/details/storage/StorageDomainBadge.tsx b/frontend/src/modules/accounts/StorageDomainBadge/StorageDomainBadge.tsx similarity index 79% rename from frontend/src/pages/accounts/details/storage/StorageDomainBadge.tsx rename to frontend/src/modules/accounts/StorageDomainBadge/StorageDomainBadge.tsx index 0b066be4..ca25c12c 100644 --- a/frontend/src/pages/accounts/details/storage/StorageDomainBadge.tsx +++ b/frontend/src/modules/accounts/StorageDomainBadge/StorageDomainBadge.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from "react"; -import classes from "./StorageBadge.module.scss"; +import classes from "./StorageDomainBadge.module.scss"; import { AccountStorageDomain } from "@flowser/shared"; -import { FlowUtils } from "../../../../utils/flow-utils"; +import { FlowUtils } from "../../../utils/flow-utils"; export type StorageBadgeProps = { pathDomain: AccountStorageDomain; diff --git a/frontend/src/pages/blocks/details/Details.module.scss b/frontend/src/modules/blocks/BlockDetails/BlockDetails.module.scss similarity index 100% rename from frontend/src/pages/blocks/details/Details.module.scss rename to frontend/src/modules/blocks/BlockDetails/BlockDetails.module.scss diff --git a/frontend/src/pages/blocks/details/Details.tsx b/frontend/src/modules/blocks/BlockDetails/BlockDetails.tsx similarity index 62% rename from frontend/src/pages/blocks/details/Details.tsx rename to frontend/src/modules/blocks/BlockDetails/BlockDetails.tsx index d42b0e7f..b33fbcc6 100644 --- a/frontend/src/pages/blocks/details/Details.tsx +++ b/frontend/src/modules/blocks/BlockDetails/BlockDetails.tsx @@ -1,7 +1,5 @@ -import React, { FunctionComponent, useEffect } from "react"; -import { NavLink, useParams } from "react-router-dom"; -import { Breadcrumb, useNavigation } from "../../../hooks/use-navigation"; -import classes from "./Details.module.scss"; +import React, { FunctionComponent } from "react"; +import classes from "./BlockDetails.module.scss"; import FullScreenLoading from "../../../components/fullscreen-loading/FullScreenLoading"; import { useGetBlock, useGetTransactionsByBlock } from "../../../hooks/use-api"; import { FlowUtils } from "../../../utils/flow-utils"; @@ -12,29 +10,17 @@ import { import { TextUtils } from "../../../utils/text-utils"; import { SizedBox } from "../../../components/sized-box/SizedBox"; import { StyledTabs } from "../../../components/tabs/StyledTabs"; -import { TransactionsTable } from "../../transactions/main/TransactionsTable"; +import { TransactionsTable } from "../../transactions/TransactionsTable/TransactionsTable"; +import { ProjectLink } from "../../../components/link/ProjectLink"; -type RouteParams = { +type BlockDetailsProps = { blockId: string; }; -const Details: FunctionComponent = () => { - const { blockId } = useParams(); - const { setBreadcrumbs } = useNavigation(); - const { showNavigationDrawer } = useNavigation(); - const breadcrumbs: Breadcrumb[] = [ - { to: "/blocks", label: "Blocks" }, - { label: "Details" }, - ]; - - const { isLoading, data } = useGetBlock(blockId); +export const BlockDetails: FunctionComponent = (props) => { + const { isLoading, data } = useGetBlock(props.blockId); const { block } = data ?? {}; - const { data: transactions } = useGetTransactionsByBlock(blockId); - - useEffect(() => { - showNavigationDrawer(true); - setBreadcrumbs(breadcrumbs); - }, []); + const { data: transactions } = useGetTransactionsByBlock(props.blockId); if (isLoading || !block) { return ; @@ -55,9 +41,9 @@ const Details: FunctionComponent = () => { value: FlowUtils.isInitialBlockId(block.parentId) ? ( block.parentId ) : ( - + {block.parentId} - + ), }, { @@ -87,5 +73,3 @@ const Details: FunctionComponent = () => {
); }; - -export default Details; diff --git a/frontend/src/pages/blocks/main/Main.module.scss b/frontend/src/modules/blocks/BlocksTable/BlocksTable.module.scss similarity index 100% rename from frontend/src/pages/blocks/main/Main.module.scss rename to frontend/src/modules/blocks/BlocksTable/BlocksTable.module.scss diff --git a/frontend/src/pages/blocks/main/Main.tsx b/frontend/src/modules/blocks/BlocksTable/BlocksTable.tsx similarity index 73% rename from frontend/src/pages/blocks/main/Main.tsx rename to frontend/src/modules/blocks/BlocksTable/BlocksTable.tsx index a5447c54..64ad8306 100644 --- a/frontend/src/pages/blocks/main/Main.tsx +++ b/frontend/src/modules/blocks/BlocksTable/BlocksTable.tsx @@ -1,26 +1,24 @@ -import React, { FunctionComponent, useEffect, useMemo } from "react"; +import React, { FunctionComponent, useMemo } from "react"; import { NavLink } from "react-router-dom"; import Label from "../../../components/label/Label"; import Value from "../../../components/value/Value"; -import classes from "./Main.module.scss"; +import classes from "./BlocksTable.module.scss"; import MiddleEllipsis from "../../../components/ellipsis/MiddleEllipsis"; -import { useNavigation } from "../../../hooks/use-navigation"; import { createColumnHelper } from "@tanstack/table-core"; import Table from "../../../components/table/Table"; import { Block } from "@flowser/shared"; -import { useGetPollingBlocks } from "../../../hooks/use-api"; import ReactTimeago from "react-timeago"; import { DecoratedPollingEntity } from "contexts/timeout-polling.context"; +import { ProjectLink } from "../../../components/link/ProjectLink"; const columnHelper = createColumnHelper>(); -const Main: FunctionComponent = () => { - const { showNavigationDrawer } = useNavigation(); - const { data: blocks, firstFetch, error } = useGetPollingBlocks(); +type BlocksTableProps = { + blocks: DecoratedPollingEntity[]; +}; - useEffect(() => { - showNavigationDrawer(false); - }, []); +export const BlocksTable: FunctionComponent = (props) => { + const { blocks } = props; const columns = useMemo( () => [ @@ -31,11 +29,11 @@ const Main: FunctionComponent = () => { }, cell: (info) => ( - + {info.getValue()} - + ), }), @@ -63,8 +61,6 @@ const Main: FunctionComponent = () => { return ( > - isInitialLoading={firstFetch} - error={error} data={blocks} columns={columns} headerRowClass={classes.tableRow} @@ -72,5 +68,3 @@ const Main: FunctionComponent = () => { /> ); }; - -export default Main; diff --git a/frontend/src/pages/contracts/details/Details.tsx b/frontend/src/modules/contracts/ContractDetails/ContractDetails.tsx similarity index 70% rename from frontend/src/pages/contracts/details/Details.tsx rename to frontend/src/modules/contracts/ContractDetails/ContractDetails.tsx index 842d7765..f7a13b14 100644 --- a/frontend/src/pages/contracts/details/Details.tsx +++ b/frontend/src/modules/contracts/ContractDetails/ContractDetails.tsx @@ -1,6 +1,5 @@ -import React, { FunctionComponent, useEffect } from "react"; +import React, { FunctionComponent } from "react"; import { NavLink, useParams } from "react-router-dom"; -import { Breadcrumb, useNavigation } from "../../../hooks/use-navigation"; import FullScreenLoading from "../../../components/fullscreen-loading/FullScreenLoading"; import { useGetContract } from "../../../hooks/use-api"; import classes from "./Details.module.scss"; @@ -12,28 +11,17 @@ import { TextUtils } from "../../../utils/text-utils"; import { SizedBox } from "../../../components/sized-box/SizedBox"; import { CadenceEditor } from "../../../components/cadence-editor/CadenceEditor"; -type RouteParams = { +type ContractDetailsProps = { contractId: string; }; -const Details: FunctionComponent = () => { - const { contractId } = useParams(); - const { setBreadcrumbs, showSearchBar } = useNavigation(); - const { showNavigationDrawer } = useNavigation(); +export const ContractDetails: FunctionComponent = ( + props +) => { + const { contractId } = props; const { isLoading, data } = useGetContract(contractId); const { contract } = data ?? {}; - const breadcrumbs: Breadcrumb[] = [ - { to: "/contracts", label: "Contracts" }, - { label: "Details" }, - ]; - - useEffect(() => { - showNavigationDrawer(true); - setBreadcrumbs(breadcrumbs); - showSearchBar(false); - }, []); - if (isLoading || !contract) { return ; } @@ -71,5 +59,3 @@ const Details: FunctionComponent = () => {
); }; - -export default Details; diff --git a/frontend/src/pages/contracts/details/Details.module.scss b/frontend/src/modules/contracts/ContractDetails/Details.module.scss similarity index 100% rename from frontend/src/pages/contracts/details/Details.module.scss rename to frontend/src/modules/contracts/ContractDetails/Details.module.scss diff --git a/frontend/src/pages/contracts/main/ContractsTable.tsx b/frontend/src/modules/contracts/ContractsTable.tsx similarity index 76% rename from frontend/src/pages/contracts/main/ContractsTable.tsx rename to frontend/src/modules/contracts/ContractsTable.tsx index 95415431..8c40a100 100644 --- a/frontend/src/pages/contracts/main/ContractsTable.tsx +++ b/frontend/src/modules/contracts/ContractsTable.tsx @@ -1,13 +1,13 @@ import { createColumnHelper } from "@tanstack/table-core"; -import { DecoratedPollingEntity } from "../../../contexts/timeout-polling.context"; +import { DecoratedPollingEntity } from "../../contexts/timeout-polling.context"; import { AccountContract } from "@flowser/shared"; -import Label from "../../../components/label/Label"; -import Value from "../../../components/value/Value"; -import { NavLink } from "react-router-dom"; -import { AccountLink } from "../../../components/account/link/AccountLink"; +import Label from "../../components/label/Label"; +import Value from "../../components/value/Value"; +import { AccountLink } from "../accounts/AccountLink/AccountLink"; import ReactTimeago from "react-timeago"; import React, { ReactElement } from "react"; -import Table from "../../../components/table/Table"; +import Table from "../../components/table/Table"; +import { ProjectLink } from "../../components/link/ProjectLink"; const columnHelper = createColumnHelper>(); @@ -17,9 +17,9 @@ const columns = [ header: () => , cell: (info) => ( - + {info.row.original.name} - + ), }), diff --git a/frontend/src/pages/events/EventsTable.module.scss b/frontend/src/modules/events/EventsTable/EventsTable.module.scss similarity index 100% rename from frontend/src/pages/events/EventsTable.module.scss rename to frontend/src/modules/events/EventsTable/EventsTable.module.scss diff --git a/frontend/src/pages/events/EventsTable.tsx b/frontend/src/modules/events/EventsTable/EventsTable.tsx similarity index 84% rename from frontend/src/pages/events/EventsTable.tsx rename to frontend/src/modules/events/EventsTable/EventsTable.tsx index 52841199..c30f3ec1 100644 --- a/frontend/src/pages/events/EventsTable.tsx +++ b/frontend/src/modules/events/EventsTable/EventsTable.tsx @@ -1,22 +1,23 @@ -import React, { useEffect, useState, useMemo, ReactElement } from "react"; +import React, { useState, useMemo, ReactElement } from "react"; import classes from "./EventsTable.module.scss"; -import tableClasses from "../../components/table/Table.module.scss"; -import Card from "../../components/card/Card"; -import Label from "../../components/label/Label"; -import Value from "../../components/value/Value"; +import tableClasses from "../../../components/table/Table.module.scss"; +import Card from "../../../components/card/Card"; +import Label from "../../../components/label/Label"; +import Value from "../../../components/value/Value"; import { NavLink } from "react-router-dom"; -import MiddleEllipsis from "../../components/ellipsis/MiddleEllipsis"; -import CaretIcon from "../../components/caret-icon/CaretIcon"; +import MiddleEllipsis from "../../../components/ellipsis/MiddleEllipsis"; +import CaretIcon from "../../../components/caret-icon/CaretIcon"; import { createColumnHelper } from "@tanstack/table-core"; import { Event } from "@flowser/shared"; -import { ComputedEventData, EventUtils } from "../../utils/event-utils"; -import CopyButton from "../../components/buttons/copy-button/CopyButton"; -import Table from "../../components/table/Table"; +import { ComputedEventData, EventUtils } from "../../../utils/event-utils"; +import CopyButton from "../../../components/buttons/copy-button/CopyButton"; +import Table from "../../../components/table/Table"; import { flexRender } from "@tanstack/react-table"; import ReactTimeago from "react-timeago"; import classNames from "classnames"; import { DecoratedPollingEntity } from "contexts/timeout-polling.context"; -import { Ellipsis } from "../../components/ellipsis/Ellipsis"; +import { Ellipsis } from "../../../components/ellipsis/Ellipsis"; +import { ProjectLink } from "../../../components/link/ProjectLink"; const subTableColumnHelper = createColumnHelper(); const subTableColumns = [ @@ -67,11 +68,11 @@ export function EventsTable(props: EventsTableProps): ReactElement { header: () => , cell: (info) => ( - + {info.getValue()} - + ), }), @@ -79,11 +80,11 @@ export function EventsTable(props: EventsTableProps): ReactElement { header: () => , cell: (info) => ( - + {info.getValue()} - + ), }), diff --git a/frontend/src/pages/interactions/InteractionsPage.module.scss b/frontend/src/modules/interactions/InteractionsPage.module.scss similarity index 100% rename from frontend/src/pages/interactions/InteractionsPage.module.scss rename to frontend/src/modules/interactions/InteractionsPage.module.scss diff --git a/frontend/src/pages/interactions/InteractionsPage.tsx b/frontend/src/modules/interactions/InteractionsPage.tsx similarity index 100% rename from frontend/src/pages/interactions/InteractionsPage.tsx rename to frontend/src/modules/interactions/InteractionsPage.tsx diff --git a/frontend/src/pages/interactions/components/execution/ExecutionSettings.module.scss b/frontend/src/modules/interactions/components/execution/ExecutionSettings.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/execution/ExecutionSettings.module.scss rename to frontend/src/modules/interactions/components/execution/ExecutionSettings.module.scss diff --git a/frontend/src/pages/interactions/components/execution/ExecutionSettings.tsx b/frontend/src/modules/interactions/components/execution/ExecutionSettings.tsx similarity index 100% rename from frontend/src/pages/interactions/components/execution/ExecutionSettings.tsx rename to frontend/src/modules/interactions/components/execution/ExecutionSettings.tsx diff --git a/frontend/src/pages/interactions/components/history/InteractionHistory.module.scss b/frontend/src/modules/interactions/components/history/InteractionHistory.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/history/InteractionHistory.module.scss rename to frontend/src/modules/interactions/components/history/InteractionHistory.module.scss diff --git a/frontend/src/pages/interactions/components/history/InteractionHistory.tsx b/frontend/src/modules/interactions/components/history/InteractionHistory.tsx similarity index 100% rename from frontend/src/pages/interactions/components/history/InteractionHistory.tsx rename to frontend/src/modules/interactions/components/history/InteractionHistory.tsx diff --git a/frontend/src/pages/interactions/components/interaction-icon/InteractionIcon.module.scss b/frontend/src/modules/interactions/components/interaction-icon/InteractionIcon.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/interaction-icon/InteractionIcon.module.scss rename to frontend/src/modules/interactions/components/interaction-icon/InteractionIcon.module.scss diff --git a/frontend/src/pages/interactions/components/interaction-icon/InteractionIcon.tsx b/frontend/src/modules/interactions/components/interaction-icon/InteractionIcon.tsx similarity index 100% rename from frontend/src/pages/interactions/components/interaction-icon/InteractionIcon.tsx rename to frontend/src/modules/interactions/components/interaction-icon/InteractionIcon.tsx diff --git a/frontend/src/pages/interactions/components/interaction-label/InteractionLabel.module.scss b/frontend/src/modules/interactions/components/interaction-label/InteractionLabel.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/interaction-label/InteractionLabel.module.scss rename to frontend/src/modules/interactions/components/interaction-label/InteractionLabel.module.scss diff --git a/frontend/src/pages/interactions/components/interaction-label/InteractionLabel.tsx b/frontend/src/modules/interactions/components/interaction-label/InteractionLabel.tsx similarity index 100% rename from frontend/src/pages/interactions/components/interaction-label/InteractionLabel.tsx rename to frontend/src/modules/interactions/components/interaction-label/InteractionLabel.tsx diff --git a/frontend/src/pages/interactions/components/outcome/InteractionOutcome.module.scss b/frontend/src/modules/interactions/components/outcome/InteractionOutcome.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/outcome/InteractionOutcome.module.scss rename to frontend/src/modules/interactions/components/outcome/InteractionOutcome.module.scss diff --git a/frontend/src/pages/interactions/components/outcome/InteractionOutcome.tsx b/frontend/src/modules/interactions/components/outcome/InteractionOutcome.tsx similarity index 98% rename from frontend/src/pages/interactions/components/outcome/InteractionOutcome.tsx rename to frontend/src/modules/interactions/components/outcome/InteractionOutcome.tsx index 4442698a..f6ea05a9 100644 --- a/frontend/src/pages/interactions/components/outcome/InteractionOutcome.tsx +++ b/frontend/src/modules/interactions/components/outcome/InteractionOutcome.tsx @@ -11,7 +11,7 @@ import classes from "./InteractionOutcome.module.scss"; import { FlowScriptOutcome, FlowTransactionOutcome, -} from "pages/interactions/contexts/interaction-registry.context"; +} from "modules/interactions/contexts/interaction-registry.context"; import { TabItem } from "../../../../components/tabs/Tabs"; import { Callout } from "../../../../components/callout/Callout"; import { useInteractionDefinitionManager } from "../../contexts/definition.context"; diff --git a/frontend/src/pages/interactions/components/parameters/ParamBuilder/ParamBuilder.module.scss b/frontend/src/modules/interactions/components/parameters/ParamBuilder/ParamBuilder.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ParamBuilder/ParamBuilder.module.scss rename to frontend/src/modules/interactions/components/parameters/ParamBuilder/ParamBuilder.module.scss diff --git a/frontend/src/pages/interactions/components/parameters/ParamBuilder/ParamBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ParamBuilder/ParamBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ParamBuilder/ParamBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ParamBuilder/ParamBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.module.scss b/frontend/src/modules/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.module.scss rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.module.scss diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx similarity index 95% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx index 8a773628..dd111d93 100644 --- a/frontend/src/pages/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx +++ b/frontend/src/modules/interactions/components/parameters/ValueBuilder/AddressBuilder/AddressBuilder.tsx @@ -2,8 +2,8 @@ import React, { ReactElement, useEffect, useMemo, useState } from "react"; import classes from "./AddressBuilder.module.scss"; import { CadenceValueBuilder } from "../interface"; import { useGetPollingAccounts } from "../../../../../../hooks/use-api"; -import { AccountAvatar } from "../../../../../../components/account/avatar/AccountAvatar"; -import { AccountName } from "../../../../../../components/account/name/AccountName"; +import { AccountAvatar } from "../../../../../accounts/AccountAvatar/AccountAvatar"; +import { AccountName } from "../../../../../accounts/AccountName/AccountName"; import { FlowserIcon } from "../../../../../../components/icons/Icons"; import classNames from "classnames"; import { ServiceRegistry } from "../../../../../../services/service-registry"; diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.module.scss b/frontend/src/modules/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.module.scss rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.module.scss diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/ArrayBuilder/ArrayBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/BoolBuilder/BoolBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/BoolBuilder/BoolBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/BoolBuilder/BoolBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/BoolBuilder/BoolBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.module.scss b/frontend/src/modules/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.module.scss rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.module.scss diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/DictionaryBuilder/DictionaryBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/FixedPointNumberBuilder/FixedPointNumberBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/FixedPointNumberBuilder/FixedPointNumberBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/FixedPointNumberBuilder/FixedPointNumberBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/FixedPointNumberBuilder/FixedPointNumberBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/IntegerNumberBuilder/IntegerNumberBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/IntegerNumberBuilder/IntegerNumberBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/IntegerNumberBuilder/IntegerNumberBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/IntegerNumberBuilder/IntegerNumberBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.module.scss b/frontend/src/modules/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.module.scss rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.module.scss diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/PathBuilder/PathBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/TextualBuilder/TextualBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/TextualBuilder/TextualBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/TextualBuilder/TextualBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/TextualBuilder/TextualBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/ValueBuilder.tsx b/frontend/src/modules/interactions/components/parameters/ValueBuilder/ValueBuilder.tsx similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/ValueBuilder.tsx rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/ValueBuilder.tsx diff --git a/frontend/src/pages/interactions/components/parameters/ValueBuilder/interface.ts b/frontend/src/modules/interactions/components/parameters/ValueBuilder/interface.ts similarity index 100% rename from frontend/src/pages/interactions/components/parameters/ValueBuilder/interface.ts rename to frontend/src/modules/interactions/components/parameters/ValueBuilder/interface.ts diff --git a/frontend/src/pages/interactions/components/templates/InteractionTemplates.module.scss b/frontend/src/modules/interactions/components/templates/InteractionTemplates.module.scss similarity index 100% rename from frontend/src/pages/interactions/components/templates/InteractionTemplates.module.scss rename to frontend/src/modules/interactions/components/templates/InteractionTemplates.module.scss diff --git a/frontend/src/pages/interactions/components/templates/InteractionTemplates.tsx b/frontend/src/modules/interactions/components/templates/InteractionTemplates.tsx similarity index 98% rename from frontend/src/pages/interactions/components/templates/InteractionTemplates.tsx rename to frontend/src/modules/interactions/components/templates/InteractionTemplates.tsx index 1e8720a4..e9998fd5 100644 --- a/frontend/src/pages/interactions/components/templates/InteractionTemplates.tsx +++ b/frontend/src/modules/interactions/components/templates/InteractionTemplates.tsx @@ -8,7 +8,6 @@ import { SearchInput } from "../../../../components/inputs/search-input/SearchIn import { useConfirmDialog } from "../../../../contexts/confirm-dialog.context"; import classNames from "classnames"; import { InteractionLabel } from "../interaction-label/InteractionLabel"; -import { SizedBox } from "../../../../components/sized-box/SizedBox"; export function InteractionTemplates(): ReactElement { return ( diff --git a/frontend/src/pages/interactions/contexts/definition.context.tsx b/frontend/src/modules/interactions/contexts/definition.context.tsx similarity index 100% rename from frontend/src/pages/interactions/contexts/definition.context.tsx rename to frontend/src/modules/interactions/contexts/definition.context.tsx diff --git a/frontend/src/pages/interactions/contexts/interaction-registry.context.tsx b/frontend/src/modules/interactions/contexts/interaction-registry.context.tsx similarity index 100% rename from frontend/src/pages/interactions/contexts/interaction-registry.context.tsx rename to frontend/src/modules/interactions/contexts/interaction-registry.context.tsx diff --git a/frontend/src/pages/interactions/contexts/outcome.context.tsx b/frontend/src/modules/interactions/contexts/outcome.context.tsx similarity index 100% rename from frontend/src/pages/interactions/contexts/outcome.context.tsx rename to frontend/src/modules/interactions/contexts/outcome.context.tsx diff --git a/frontend/src/pages/interactions/hooks/use-transaction-name.ts b/frontend/src/modules/interactions/hooks/use-transaction-name.ts similarity index 100% rename from frontend/src/pages/interactions/hooks/use-transaction-name.ts rename to frontend/src/modules/interactions/hooks/use-transaction-name.ts diff --git a/frontend/src/pages/logs/Logs.module.scss b/frontend/src/modules/logs/Logs.module.scss similarity index 100% rename from frontend/src/pages/logs/Logs.module.scss rename to frontend/src/modules/logs/Logs.module.scss diff --git a/frontend/src/pages/logs/Logs.tsx b/frontend/src/modules/logs/Logs.tsx similarity index 100% rename from frontend/src/pages/logs/Logs.tsx rename to frontend/src/modules/logs/Logs.tsx diff --git a/frontend/src/pages/start/configuration/FormFields.module.scss b/frontend/src/modules/projects/FormFields/FormFields.module.scss similarity index 100% rename from frontend/src/pages/start/configuration/FormFields.module.scss rename to frontend/src/modules/projects/FormFields/FormFields.module.scss diff --git a/frontend/src/pages/start/configuration/FormFields.tsx b/frontend/src/modules/projects/FormFields/FormFields.tsx similarity index 100% rename from frontend/src/pages/start/configuration/FormFields.tsx rename to frontend/src/modules/projects/FormFields/FormFields.tsx diff --git a/frontend/src/pages/start/main/Main.module.scss b/frontend/src/modules/projects/ProjectListPage/ProjectListPage.module.scss similarity index 100% rename from frontend/src/pages/start/main/Main.module.scss rename to frontend/src/modules/projects/ProjectListPage/ProjectListPage.module.scss diff --git a/frontend/src/pages/start/main/Main.tsx b/frontend/src/modules/projects/ProjectListPage/ProjectListPage.tsx similarity index 88% rename from frontend/src/pages/start/main/Main.tsx rename to frontend/src/modules/projects/ProjectListPage/ProjectListPage.tsx index f11a5fb7..dfa9b049 100644 --- a/frontend/src/pages/start/main/Main.tsx +++ b/frontend/src/modules/projects/ProjectListPage/ProjectListPage.tsx @@ -1,16 +1,10 @@ -import React, { - FunctionComponent, - ReactElement, - useCallback, - useState, -} from "react"; -import { Link, RouteChildrenProps, useHistory } from "react-router-dom"; -import { routes } from "../../../constants/routes"; +import React, { FunctionComponent, ReactElement, useState } from "react"; +import { Link, useNavigate, useLocation } from "react-router-dom"; import IconButton from "../../../components/buttons/icon-button/IconButton"; import longLogo from "../../../assets/images/long_logo.png"; import trash from "../../../assets/icons/trash.svg"; import newProject from "../../../assets/icons/new_project.svg"; -import classes from "./Main.module.scss"; +import classes from "./ProjectListPage.module.scss"; import { useGetAllProjects } from "../../../hooks/use-api"; import { Project } from "@flowser/shared"; import classNames from "classnames"; @@ -45,19 +39,16 @@ const tabs: ProjectTab[] = [ }, ]; -const Main: FunctionComponent = (props) => { - const history = useHistory(); +export const ProjectListPage: FunctionComponent = () => { + const navigate = useNavigate(); + const location = useLocation(); - const providedTabId = props.location.hash?.replace("#", ""); + const providedTabId = location.hash?.replace("#", ""); const providedTab = tabs.find((tab) => tab.id === providedTabId); const defaultTab = tabs.find((tab) => tab.isDefault); const fallbackTab = tabs[0]; const activeTab = providedTab ?? defaultTab ?? fallbackTab; - const onConfigure = useCallback(() => { - history.push(routes.configure); - }, []); - return (
); }; - -export default Details; diff --git a/frontend/src/pages/transactions/details/TransactionOverview.tsx b/frontend/src/modules/transactions/details/TransactionOverview.tsx similarity index 88% rename from frontend/src/pages/transactions/details/TransactionOverview.tsx rename to frontend/src/modules/transactions/details/TransactionOverview.tsx index 312bd5be..229ae86b 100644 --- a/frontend/src/pages/transactions/details/TransactionOverview.tsx +++ b/frontend/src/modules/transactions/details/TransactionOverview.tsx @@ -9,8 +9,8 @@ import { ExecutionStatusBadge } from "../../../components/status/ExecutionStatus import { GrcpStatusBadge } from "../../../components/status/GrcpStatusBadge"; import { TextUtils } from "../../../utils/text-utils"; import { Transaction } from "@flowser/shared"; -import { NavLink } from "react-router-dom"; -import { AccountLink } from "../../../components/account/link/AccountLink"; +import { AccountLink } from "../../accounts/AccountLink/AccountLink"; +import { ProjectLink } from "../../../components/link/ProjectLink"; type TransactionOverviewProps = { transaction: Transaction; @@ -27,11 +27,11 @@ export function TransactionOverview( { label: "Transaction", value: ( - + {transaction.id} - + ), }, { @@ -49,11 +49,11 @@ export function TransactionOverview( { label: "Block ID", value: ( - + {transaction.blockId} - + ), }, ], diff --git a/frontend/src/pages/transactions/details/source/TransactionSource.module.scss b/frontend/src/modules/transactions/details/source/TransactionSource.module.scss similarity index 100% rename from frontend/src/pages/transactions/details/source/TransactionSource.module.scss rename to frontend/src/modules/transactions/details/source/TransactionSource.module.scss diff --git a/frontend/src/pages/transactions/details/source/TransactionSource.tsx b/frontend/src/modules/transactions/details/source/TransactionSource.tsx similarity index 100% rename from frontend/src/pages/transactions/details/source/TransactionSource.tsx rename to frontend/src/modules/transactions/details/source/TransactionSource.tsx diff --git a/frontend/src/pages/accounts/Accounts.tsx b/frontend/src/pages/accounts/Accounts.tsx deleted file mode 100644 index 961c483b..00000000 --- a/frontend/src/pages/accounts/Accounts.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { FC } from "react"; -import { Redirect, Route, Switch } from "react-router-dom"; -import Main from "./main/Main"; -import Details from "./details/Details"; - -const Accounts: FC = () => { - return ( - - - - - - ); -}; - -export default Accounts; diff --git a/frontend/src/pages/blocks/Blocks.tsx b/frontend/src/pages/blocks/Blocks.tsx deleted file mode 100644 index ac3dadaa..00000000 --- a/frontend/src/pages/blocks/Blocks.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import { Redirect, Route, Switch } from "react-router-dom"; -import Main from "./main/Main"; -import Details from "./details/Details"; - -const Blocks = () => { - return ( - - - - - - ); -}; - -export default Blocks; diff --git a/frontend/src/pages/contracts/Contracts.tsx b/frontend/src/pages/contracts/Contracts.tsx deleted file mode 100644 index 31073f35..00000000 --- a/frontend/src/pages/contracts/Contracts.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import { Redirect, Route, Switch } from "react-router-dom"; -import Main from "./main/Main"; -import Details from "./details/Details"; - -const Contracts = () => { - return ( - - - - - - ); -}; - -export default Contracts; diff --git a/frontend/src/pages/contracts/main/Main.tsx b/frontend/src/pages/contracts/main/Main.tsx deleted file mode 100644 index e8c10c2d..00000000 --- a/frontend/src/pages/contracts/main/Main.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { FunctionComponent, useEffect } from "react"; -import { useNavigation } from "../../../hooks/use-navigation"; -import { useGetPollingContracts } from "../../../hooks/use-api"; -import { ContractsTable } from "./ContractsTable"; - -const Main: FunctionComponent = () => { - const { showNavigationDrawer } = useNavigation(); - const { data } = useGetPollingContracts(); - - useEffect(() => { - showNavigationDrawer(false); - }, []); - - return ; -}; - -export default Main; diff --git a/frontend/src/pages/events/Events.tsx b/frontend/src/pages/events/Events.tsx deleted file mode 100644 index 968c0a30..00000000 --- a/frontend/src/pages/events/Events.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { FunctionComponent, useEffect } from "react"; -import { useGetPollingEvents } from "../../hooks/use-api"; -import { useNavigation } from "../../hooks/use-navigation"; -import { EventsTable } from "./EventsTable"; - -const Events: FunctionComponent = () => { - const { showNavigationDrawer } = useNavigation(); - const { data, firstFetch, error } = useGetPollingEvents(); - - useEffect(() => { - showNavigationDrawer(false); - }, []); - - return ; -}; - -export default Events; diff --git a/frontend/src/pages/start/Start.tsx b/frontend/src/pages/start/Start.tsx deleted file mode 100644 index f0407775..00000000 --- a/frontend/src/pages/start/Start.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { FunctionComponent } from "react"; -import { Redirect, Route, Switch } from "react-router-dom"; -import Main from "./main/Main"; -import { Configuration } from "./configuration/Configuration"; -import { RouteWithBackButton } from "components/layout/Layout"; -import { routes } from "../../constants/routes"; - -const Start: FunctionComponent = () => { - return ( - - - - - - - ); -}; - -export default Start; diff --git a/frontend/src/pages/transactions/Transactions.tsx b/frontend/src/pages/transactions/Transactions.tsx deleted file mode 100644 index 53d6e2c7..00000000 --- a/frontend/src/pages/transactions/Transactions.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import { Redirect, Route, Switch } from "react-router-dom"; -import Main from "./main/Main"; -import Details from "./details/Details"; - -const Transactions = () => { - return ( - - - - - - ); -}; - -export default Transactions; diff --git a/frontend/src/pages/transactions/main/Main.tsx b/frontend/src/pages/transactions/main/Main.tsx deleted file mode 100644 index ead2ceb9..00000000 --- a/frontend/src/pages/transactions/main/Main.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { FunctionComponent, useEffect } from "react"; -import { useNavigation } from "../../../hooks/use-navigation"; -import { useGetPollingTransactions } from "../../../hooks/use-api"; -import { TransactionsTable } from "./TransactionsTable"; - -const Main: FunctionComponent = () => { - const { showNavigationDrawer } = useNavigation(); - const { data } = useGetPollingTransactions(); - - useEffect(() => { - showNavigationDrawer(false); - }, []); - - return ; -}; - -export default Main; diff --git a/yarn.lock b/yarn.lock index 7aa3c70c..e22a89d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1917,7 +1917,7 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.18.9" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz" integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== @@ -4666,6 +4666,11 @@ resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@remix-run/router@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.8.0.tgz#e848d2f669f601544df15ce2a313955e4bf0bafc" + integrity sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg== + "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -5242,11 +5247,6 @@ dependencies: "@types/node" "*" -"@types/history@^4.7.11": - version "4.7.11" - resolved "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz" - integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== - "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" @@ -5444,23 +5444,6 @@ dependencies: "@types/react" "^17" -"@types/react-router-dom@^5.3.0": - version "5.3.3" - resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz" - integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router" "*" - -"@types/react-router@*": - version "5.1.18" - resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz" - integrity sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g== - dependencies: - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-timeago@^4.1.3": version "4.1.3" resolved "https://registry.npmjs.org/@types/react-timeago/-/react-timeago-4.1.3.tgz" @@ -10947,18 +10930,6 @@ highlight.js@^10.7.1: resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== -history@^4.9.0: - version "4.10.1" - resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== - dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" - hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" @@ -10968,7 +10939,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: +hoist-non-react-statics@^3.3.0: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -11826,11 +11797,6 @@ is-yarn-global@^0.3.0: resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz" integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -13126,7 +13092,7 @@ long@^5.0.0: resolved "https://registry.npmjs.org/long/-/long-5.2.0.tgz" integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -13441,14 +13407,6 @@ min-indent@^1.0.0: resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -mini-create-react-context@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz" - integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== - dependencies: - "@babel/runtime" "^7.12.1" - tiny-warning "^1.0.3" - mini-css-extract-plugin@^2.4.5: version "2.7.6" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" @@ -14713,13 +14671,6 @@ path-to-regexp@3.2.0: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz" integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" @@ -15558,7 +15509,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -15845,7 +15796,7 @@ react-hot-toast@^2.1.1: dependencies: goober "^2.1.10" -react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: +react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -15916,34 +15867,20 @@ react-refresh@^0.9.0: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz" integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== -react-router-dom@^5.3.0: - version "5.3.3" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.3.tgz" - integrity sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng== - dependencies: - "@babel/runtime" "^7.12.13" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.3.3" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-router@5.3.3: - version "5.3.3" - resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.3.tgz" - integrity sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w== - dependencies: - "@babel/runtime" "^7.12.13" - history "^4.9.0" - hoist-non-react-statics "^3.1.0" - loose-envify "^1.3.1" - mini-create-react-context "^0.4.0" - path-to-regexp "^1.7.0" - prop-types "^15.6.2" - react-is "^16.6.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" +react-router-dom@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.15.0.tgz#6da7db61e56797266fbbef0d5e324d6ac443ee40" + integrity sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ== + dependencies: + "@remix-run/router" "1.8.0" + react-router "6.15.0" + +react-router@6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.15.0.tgz#bf2cb5a4a7ed57f074d4ea88db0d95033f39cac8" + integrity sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg== + dependencies: + "@remix-run/router" "1.8.0" react-scripts@5.0.0: version "5.0.0" @@ -16442,11 +16379,6 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - resolve-url-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" @@ -17961,12 +17893,7 @@ timsort@^0.3.0: resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz" integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A== -tiny-invariant@^1.0.2: - version "1.2.0" - resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz" - integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== - -tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: +tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== @@ -18686,11 +18613,6 @@ validator@^13.7.0: resolved "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz" integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"