Skip to content

Commit

Permalink
REST API doc fixes (#1292)
Browse files Browse the repository at this point in the history
* pass API port and protocol from config to REST playground

* ENV for hidding RPC links in nav bar

* tweak styles of SwaggerUI for dark color scheme
  • Loading branch information
tom2drum authored Oct 18, 2023
1 parent 1db67c5 commit e930020
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 13 deletions.
2 changes: 2 additions & 0 deletions configs/app/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const socketEndpoint = [

const api = Object.freeze({
host: apiHost,
protocol: apiSchema,
port: apiPort,
endpoint: apiEndpoint,
socket: socketEndpoint,
basePath: stripTrailingSlash(getEnvValue('NEXT_PUBLIC_API_BASE_PATH') || ''),
Expand Down
18 changes: 17 additions & 1 deletion configs/app/ui.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import type { NavItemExternal } from 'types/client/navigation-items';
import { NAVIGATION_LINK_IDS, type NavItemExternal, type NavigationLinkId } from 'types/client/navigation-items';
import type { ChainIndicatorId } from 'types/homepage';
import type { NetworkExplorer } from 'types/networks';

import * as views from './ui/views';
import { getEnvValue, getExternalAssetFilePath, parseEnvJson } from './utils';

const hiddenLinks = (() => {
const parsedValue = parseEnvJson<Array<NavigationLinkId>>(getEnvValue('NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS')) || [];

if (!Array.isArray(parsedValue)) {
return undefined;
}

const result = NAVIGATION_LINK_IDS.reduce((result, item) => {
result[item] = parsedValue.includes(item);
return result;
}, {} as Record<NavigationLinkId, boolean>);

return result;
})();

// eslint-disable-next-line max-len
const HOMEPAGE_PLATE_BACKGROUND_DEFAULT = 'radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)';

Expand All @@ -18,6 +33,7 @@ const UI = Object.freeze({
'default': getExternalAssetFilePath('NEXT_PUBLIC_NETWORK_ICON'),
dark: getExternalAssetFilePath('NEXT_PUBLIC_NETWORK_ICON_DARK'),
},
hiddenLinks,
otherLinks: parseEnvJson<Array<NavItemExternal>>(getEnvValue('NEXT_PUBLIC_OTHER_LINKS')) || [],
featuredNetworks: getExternalAssetFilePath('NEXT_PUBLIC_FEATURED_NETWORKS'),
},
Expand Down
8 changes: 7 additions & 1 deletion deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders } from '../../../types/client/adProviders';
import type { MarketplaceAppOverview } from '../../../types/client/marketplace';
import type { NavItemExternal } from '../../../types/client/navigation-items';
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation-items';
import type { NavItemExternal, NavigationLinkId } from '../../../types/client/navigation-items';
import type { BridgedTokenChain, TokenBridge } from '../../../types/client/token';
import type { WalletType } from '../../../types/client/wallets';
import { SUPPORTED_WALLETS } from '../../../types/client/wallets';
Expand Down Expand Up @@ -354,6 +355,11 @@ const schema = yup
.transform(replaceQuotes)
.json()
.of(navItemExternalSchema),
NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS: yup
.array()
.transform(replaceQuotes)
.json()
.of(yup.string<NavigationLinkId>().oneOf(NAVIGATION_LINK_IDS)),
NEXT_PUBLIC_NETWORK_LOGO: yup.string().test(urlTest),
NEXT_PUBLIC_NETWORK_LOGO_DARK: yup.string().test(urlTest),
NEXT_PUBLIC_NETWORK_ICON: yup.string().test(urlTest),
Expand Down
1 change: 1 addition & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ The app instance could be customized by passing following variables to NodeJS en
| NEXT_PUBLIC_NETWORK_ICON_DARK | `string` | Network icon for dark color mode; if not provided, **inverted** regular icon will be used instead | - | - | `https://placekitten.com/60/60` |
| NEXT_PUBLIC_FEATURED_NETWORKS | `string` | URL of configuration file (`.json` format only) which contains list of featured networks that will be shown in the network menu. See [below](#featured-network-configuration-properties) list of available properties for particular network | - | - | `https://example.com/featured_networks_config.json` |
| NEXT_PUBLIC_OTHER_LINKS | `Array<{url: string; text: string}>` | List of links for the "Other" navigation menu | - | - | `[{'url':'https://blockscout.com','text':'Blockscout'}]` |
| NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS | `Array<LinkId>` | List of external links hidden in the navigation. Supported ids are `eth_rpc_api`, `rpc_api` | - | - | `['eth_rpc_api']` |

#### Featured network configuration properties

Expand Down
6 changes: 3 additions & 3 deletions lib/hooks/useNavItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ export default function useNavItems(): ReturnType {
icon: graphQLIcon,
isActive: pathname === '/graphiql',
} : null,
{
!config.UI.sidebar.hiddenLinks?.rpc_api && {
text: 'RPC API',
icon: rpcIcon,
url: 'https://docs.blockscout.com/for-users/api/rpc-endpoints',
},
{
!config.UI.sidebar.hiddenLinks?.eth_rpc_api && {
text: 'Eth RPC API',
icon: rpcIcon,
url: ' https://docs.blockscout.com/for-users/api/eth-rpc',
Expand Down Expand Up @@ -157,7 +157,7 @@ export default function useNavItems(): ReturnType {
icon: statsIcon,
isActive: pathname === '/stats',
} : null,
{
apiNavItems.length > 0 && {
text: 'API',
icon: apiDocsIcon,
isActive: apiNavItems.some(item => isInternalItem(item) && item.isActive),
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"lint:eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:eslint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
"lint:tsc": "tsc -p ./tsconfig.json",
"lint:envs-validator:dev": "cd ./deploy/tools/envs-validator && ./dev.sh",
"prepare": "husky install",
"format-svg": "svgo -r ./icons",
"test:pw": "./tools/scripts/pw.sh",
Expand Down
5 changes: 5 additions & 0 deletions types/client/navigation-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ export type NavGroupItem = NavItemCommon & {
isActive?: boolean;
subItems: Array<NavItem> | Array<Array<NavItem>>;
}

import type { ArrayElement } from '../utils';

export const NAVIGATION_LINK_IDS = [ 'rpc_api', 'eth_rpc_api' ] as const;
export type NavigationLinkId = ArrayElement<typeof NAVIGATION_LINK_IDS>;
76 changes: 68 additions & 8 deletions ui/apiDocs/SwaggerUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const SwaggerUIReact = dynamic(() => import('swagger-ui-react'), {
ssr: false,
});

import { Box, useColorModeValue } from '@chakra-ui/react';
import type { SystemStyleObject } from '@chakra-ui/react';
import { Box, useColorModeValue, useToken } from '@chakra-ui/react';
import dynamic from 'next/dynamic';
import React from 'react';

Expand All @@ -28,12 +29,16 @@ const NeverShowInfoPlugin = () => {
};

const SwaggerUI = () => {
const swaggerStyle = {
'.scheme-container, .opblock-tag': {
const mainColor = useColorModeValue('blackAlpha.800', 'whiteAlpha.800');
const borderColor = useToken('colors', 'divider');
const mainBgColor = useColorModeValue('blackAlpha.100', 'whiteAlpha.200');

const swaggerStyle: SystemStyleObject = {
'.swagger-ui .scheme-container, .opblock-tag': {
display: 'none',
},
'.swagger-ui': {
color: useColorModeValue('blackAlpha.800', 'whiteAlpha.800'),
color: mainColor,
},
'.swagger-ui .opblock-summary-control:focus': {
outline: 'none',
Expand All @@ -54,15 +59,70 @@ const SwaggerUI = () => {
'.swagger-ui .wrapper': {
padding: 0,
},
'.swagger-ui .prop-type': {
color: useColorModeValue('blue.600', 'blue.400'),
},
'.swagger-ui .btn.try-out__btn': {
borderColor: useToken('colors', 'link'),
color: useToken('colors', 'link'),
borderRadius: 'sm',
},
'.swagger-ui .btn.try-out__btn:hover': {
boxShadow: 'none',
borderColor: useToken('colors', 'link_hovered'),
color: useToken('colors', 'link_hovered'),
},
'.swagger-ui .btn.try-out__btn.cancel': {
borderColor: useToken('colors', 'error'),
color: useToken('colors', 'error'),
},
'.swagger-ui .btn.try-out__btn.cancel:hover': {
borderColor: useColorModeValue('red.600', 'red.500'),
color: useColorModeValue('red.500', 'red.400'),
},

// MODELS
'.swagger-ui section.models': {
borderColor: borderColor,
},
'.swagger-ui section.models h4': {
color: mainColor,
},
'.swagger-ui section.models .model-container': {
bgColor: mainBgColor,
},
'.swagger-ui .model-title': {
wordBreak: 'break-all',
color: mainColor,
},
'.swagger-ui .model': {
color: mainColor,
},
'.swagger-ui .model-box-control:focus': {
outline: 'none',
},
'.swagger-ui .model-toggle': {
bgColor: useColorModeValue('transparent', 'whiteAlpha.700'),
borderRadius: 'sm',
},
'.swagger-ui .model .property.primitive': {
color: useToken('colors', 'text_secondary'),
wordBreak: 'break-all',
},
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const reqInterceptor = React.useCallback((req: any) => {
if (!req.loadSpec) {
req.url = req.url.replace(DEFAULT_SERVER, config.api.host);
const url = new URL(req.url);
url.protocol = 'https:';
req.url = url.toString();
const newUrl = new URL(req.url.replace(DEFAULT_SERVER, config.api.host));

newUrl.protocol = config.api.protocol + ':';

if (config.api.port) {
newUrl.port = config.api.port;
}

req.url = newUrl.toString();
}
return req;
}, []);
Expand Down

0 comments on commit e930020

Please sign in to comment.