Skip to content

Commit

Permalink
Merge pull request #1159 from oasisprotocol/lw/simplify-scopes
Browse files Browse the repository at this point in the history
Simplify scopes and recover from invalid URLs
  • Loading branch information
lukaw3d authored Jan 19, 2024
2 parents 7e47e5f + 723d21a commit 719bce3
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 106 deletions.
1 change: 1 addition & 0 deletions .changelog/1159.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Simplify search scopes and fix search on error pages
2 changes: 1 addition & 1 deletion src/app/components/PageLayout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const Header: FC = () => {
showText={!scrollTrigger && !isMobile}
/>
</Grid>
{scope?.valid && (
{scope && (
<>
<Grid lg={6} xs={8}>
<NetworkSelector layer={scope.layer} network={scope.network} />
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/PageLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const PageLayout: FC<PropsWithChildren<PageLayoutProps>> = ({ children, m
<>
<BuildBanner />
<NetworkOfflineBanner />
{scope?.valid && scope.layer !== Layer.consensus && <RuntimeOfflineBanner />}
{scope && scope.layer !== Layer.consensus && <RuntimeOfflineBanner />}
<Box
sx={{
minHeight: '100vh',
Expand Down
9 changes: 6 additions & 3 deletions src/app/components/Search/search-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
import { Network } from '../../../types/network'
import { RouteUtils, SpecifiedPerEnabledRuntime } from '../../utils/route-utils'
import { AppError, AppErrors } from '../../../types/errors'
import { Layer } from '../../../oasis-nexus/api'

type LayerSuggestions = {
suggestedBlock: string
Expand All @@ -19,7 +18,7 @@ type LayerSuggestions = {
suggestedTokenFragment: string
}

export const searchSuggestionTerms: Record<Network, Partial<Record<Layer, LayerSuggestions>>> = {
export const searchSuggestionTerms = {
mainnet: {
emerald: {
suggestedBlock: '4260',
Expand All @@ -33,6 +32,8 @@ export const searchSuggestionTerms: Record<Network, Partial<Record<Layer, LayerS
suggestedAccount: '0x90adE3B7065fa715c7a150313877dF1d33e777D5',
suggestedTokenFragment: 'mock',
},
cipher: undefined,
consensus: undefined,
},
testnet: {
emerald: {
Expand All @@ -47,8 +48,10 @@ export const searchSuggestionTerms: Record<Network, Partial<Record<Layer, LayerS
suggestedAccount: '0xfA3AC9f65C9D75EE3978ab76c6a1105f03156204',
suggestedTokenFragment: 'USD',
},
cipher: undefined,
consensus: undefined,
},
} satisfies SpecifiedPerEnabledRuntime
} satisfies SpecifiedPerEnabledRuntime<LayerSuggestions>

export const textSearchMininumLength = 3

Expand Down
54 changes: 6 additions & 48 deletions src/app/hooks/useScopeParam.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,26 @@
import { useRouteLoaderData, useParams, useRouteError } from 'react-router-dom'
import { useRouteLoaderData, useParams } from 'react-router-dom'
import { Network } from '../../types/network'
import { RouteUtils } from '../utils/route-utils'
import { AppError, AppErrors } from '../../types/errors'
import { SearchScope } from '../../types/searchScope'
import { Layer } from '../../oasis-nexus/api'

export const useNetworkParam = (): Network | undefined => {
const { network } = useParams()
return network as Network | undefined
}

type ScopeInfo = SearchScope & {
valid: boolean
}

type Scope = {
layer: Layer | undefined
network: Network | undefined
}

/**
* Use this in situations where we might or might not have a scope
*/
export const useScopeParam = (): ScopeInfo | undefined => {
const runtimeScope = useRouteLoaderData('runtimeScope') as Scope
const consensusScope = useRouteLoaderData('consensusScope') as Scope
const loaderData = runtimeScope || consensusScope
const error = useRouteError()

if (loaderData?.network === undefined && loaderData?.layer === undefined) return undefined

const { network, layer } = loaderData

const scope: ScopeInfo = {
network: network as Network,
layer: layer as Layer,
valid: true,
}

if (network === undefined || layer === undefined) {
scope.valid = false
if (!error)
throw new Error(
'You must either specify both network and layer or none of them. You can not have one but not the other.',
)
}

if (!RouteUtils.getEnabledNetworks().includes(scope.network)) {
scope.valid = false
if (!error) throw new AppError(AppErrors.UnsupportedNetwork)
}

if (!RouteUtils.getEnabledLayersForNetwork(scope.network).includes(scope.layer)) {
scope.valid = false
if (!error) throw new AppError(AppErrors.UnsupportedLayer)
}

return scope
export const useScopeParam = (): SearchScope | undefined => {
const runtimeScope = useRouteLoaderData('runtimeScope') as SearchScope | undefined
const consensusScope = useRouteLoaderData('consensusScope') as SearchScope | undefined
return runtimeScope ?? consensusScope ?? undefined
}

/**
* Use this in situations where we require to have a scope
*/
export const useRequiredScopeParam = (): ScopeInfo => {
export const useRequiredScopeParam = (): SearchScope => {
const scope = useScopeParam()

if (!scope) throw new AppError(AppErrors.UnsupportedNetwork)
Expand Down
9 changes: 6 additions & 3 deletions src/app/pages/ParatimeDashboardPage/LearningMaterials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ type LayerContent = {
secondary: Content
tertiary: Content
}
type NetworkContent = Partial<Record<Layer, LayerContent>>
const getContent = (t: TFunction): Record<Network, NetworkContent> => {
const getContent = (t: TFunction) => {
const labels = getLayerLabels(t)

return {
Expand Down Expand Up @@ -84,6 +83,8 @@ const getContent = (t: TFunction): Record<Network, NetworkContent> => {
url: docs.paraTimeTransfer,
},
},
[Layer.cipher]: undefined,
[Layer.consensus]: undefined,
},
[Network.testnet]: {
[Layer.emerald]: {
Expand Down Expand Up @@ -120,8 +121,10 @@ const getContent = (t: TFunction): Record<Network, NetworkContent> => {
url: docs.sapphireTestnetHardhat,
},
},
[Layer.cipher]: undefined,
[Layer.consensus]: undefined,
},
} satisfies SpecifiedPerEnabledRuntime
} satisfies SpecifiedPerEnabledRuntime<LayerContent>
}

type LearningSectionProps = PaperProps & {
Expand Down
68 changes: 24 additions & 44 deletions src/app/utils/route-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,29 @@ import { SearchScope } from '../../types/searchScope'
import { isStableDeploy } from '../../config'

export type SpecifiedPerEnabledRuntime<T = any> = {
[N in keyof (typeof RouteUtils)['ENABLED_RUNTIMES_FOR_NETWORK']]: {
[L in keyof (typeof RouteUtils)['ENABLED_RUNTIMES_FOR_NETWORK'][N]]: T
[N in keyof (typeof RouteUtils)['ENABLED_LAYERS_FOR_NETWORK']]: {
[L in keyof (typeof RouteUtils)['ENABLED_LAYERS_FOR_NETWORK'][N]]: (typeof RouteUtils)['ENABLED_LAYERS_FOR_NETWORK'][N][L] extends true
? T
: T | undefined
}
}

export abstract class RouteUtils {
private static ENABLED_RUNTIMES_FOR_NETWORK = {
private static ENABLED_LAYERS_FOR_NETWORK = {
[Network.mainnet]: {
[Layer.emerald]: true,
[Layer.sapphire]: true,
[Layer.cipher]: false,
// Disable WIP Consensus on production an staging
[Layer.consensus]: !isStableDeploy,
},
[Network.testnet]: {
[Layer.emerald]: true,
[Layer.sapphire]: true,
[Layer.cipher]: false,
[Layer.consensus]: false,
},
} satisfies Partial<Record<Network, Partial<Record<Layer, true>>>>

private static ENABLED_CONSENSUS_FOR_NETWORK = {
// Disable WIP Consensus on production an staging
[Network.mainnet]: !isStableDeploy,
[Network.testnet]: false,
}
} satisfies Record<Network, Record<Layer, boolean>>

static getDashboardRoute = ({ network, layer }: SearchScope) => {
return `/${encodeURIComponent(network)}/${encodeURIComponent(layer)}`
Expand Down Expand Up @@ -108,9 +109,7 @@ export abstract class RouteUtils {
)}/instance/${encodeURIComponent(instanceId)}`

static getEnabledLayersForNetwork(network: Network): Layer[] {
const enabledRuntimes = Object.keys(RouteUtils.ENABLED_RUNTIMES_FOR_NETWORK[network]) as Layer[]
const enabledConsensus = RouteUtils.ENABLED_CONSENSUS_FOR_NETWORK[network] ? [Layer.consensus] : []
return [...enabledRuntimes, ...enabledConsensus]
return Object.values(Layer).filter(layer => RouteUtils.ENABLED_LAYERS_FOR_NETWORK[network][layer])
}

static getEnabledScopes(): SearchScope[] {
Expand All @@ -119,12 +118,10 @@ export abstract class RouteUtils {
)
}

static getEnabledNetworks() {
const networks = new Set([
...Object.keys(RouteUtils.ENABLED_RUNTIMES_FOR_NETWORK),
...Object.keys(RouteUtils.ENABLED_CONSENSUS_FOR_NETWORK),
])
return Array.from(networks) as Network[]
static getEnabledNetworks(): Network[] {
return Object.values(Network).filter(network => {
return RouteUtils.getEnabledLayersForNetwork(network).length > 0
})
}

static getEnabledSearchScopes(): SearchScope[] {
Expand Down Expand Up @@ -176,26 +173,13 @@ export const transactionParamLoader = async ({ params }: LoaderFunctionArgs) =>
return validateTxHashParam(params.hash!)
}

export const scopeConsensusLoader = async (args: LoaderFunctionArgs) => {
const {
params: { network },
} = args

if (!network || !RouteUtils.getEnabledNetworks().includes(network as Network)) {
throw new AppError(AppErrors.InvalidUrl)
}

return {
network: network as Network,
layer: Layer.consensus,
}
}

export const scopeRuntimeLoader = async (args: LoaderFunctionArgs) => {
const {
params: { network, layer },
} = args

export const assertEnabledScope = ({
network,
layer,
}: {
network: string | undefined
layer: string | undefined
}): SearchScope => {
if (!network || !RouteUtils.getEnabledNetworks().includes(network as Network)) {
throw new AppError(AppErrors.InvalidUrl)
}
Expand All @@ -206,9 +190,5 @@ export const scopeRuntimeLoader = async (args: LoaderFunctionArgs) => {
) {
throw new AppError(AppErrors.UnsupportedLayer)
}

return {
network: network as Network,
layer: layer as Layer,
}
return { network, layer } as SearchScope
}
17 changes: 11 additions & 6 deletions src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import {
addressParamLoader,
blockHeightParamLoader,
transactionParamLoader,
scopeConsensusLoader,
scopeRuntimeLoader,
assertEnabledScope,
} from './app/utils/route-utils'
import { searchParamLoader } from './app/components/Search/search-utils'
import { RoutingErrorPage } from './app/pages/RoutingErrorPage'
Expand All @@ -31,6 +30,8 @@ import { TokenInventoryCard } from './app/pages/TokenDashboardPage/TokenInventor
import { NFTInstanceDashboardPage, useNftDetailsProps } from './app/pages/NFTInstanceDashboardPage'
import { NFTMetadataCard } from './app/pages/NFTInstanceDashboardPage/NFTMetadataCard'
import { ConsensusDashboardPage } from 'app/pages/ConsensusDashboardPage'
import { Layer } from './oasis-nexus/api'
import { SearchScope } from './types/searchScope'

const NetworkSpecificPart = () => (
<ThemeByNetwork network={useRequiredScopeParam().network}>
Expand Down Expand Up @@ -58,10 +59,12 @@ export const routes: RouteObject[] = [
loader: searchParamLoader,
},
{
path: '/:network/consensus',
path: '/:_network/consensus',
element: <NetworkSpecificPart />,
errorElement: withDefaultTheme(<RoutingErrorPage />),
loader: scopeConsensusLoader,
loader: async ({ params }): Promise<SearchScope> => {
return assertEnabledScope({ network: params._network, layer: Layer.consensus })
},
id: 'consensusScope',
children: [
{
Expand All @@ -71,10 +74,12 @@ export const routes: RouteObject[] = [
],
},
{
path: '/:network/:layer',
path: '/:_network/:_layer',
element: <NetworkSpecificPart />,
errorElement: withDefaultTheme(<RoutingErrorPage />),
loader: scopeRuntimeLoader,
loader: async ({ params }): Promise<SearchScope> => {
return assertEnabledScope({ network: params._network, layer: params._layer })
},
id: 'runtimeScope',
children: [
{
Expand Down

0 comments on commit 719bce3

Please sign in to comment.