config#config TypeScript Examples
The following examples show how to use
config#config.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: App.tsx From one-platform with MIT License | 6 votes |
client = createClient({
url: config.apiURL,
requestPolicy: 'cache-and-network',
maskTypename: true,
fetchOptions: () => {
const token = opcBase.auth?.jwtToken;
return {
headers: {
authorization: token ? `Bearer ${token}` : '',
},
};
},
})
Example #2
Source File: App.tsx From one-platform with MIT License | 6 votes |
App = () => {
return (
<Provider value={client}>
<RecentVisitProvider>
<BrowserRouter basename={config.baseURL}>
<BreadcrumbProvider>
<Suspense fallback={<Loader />}>
<opc-provider>
<opc-nav />
<opc-menu-drawer />
<opc-notification-drawer />
<opc-feedback />
</opc-provider>
<Router />
</Suspense>
</BreadcrumbProvider>
</BrowserRouter>
</RecentVisitProvider>
</Provider>
);
}
Example #3
Source File: others.routing.ts From matx-angular with MIT License | 6 votes |
OthersRoutes: Routes = [
{
path: '',
children: [{
path: 'blank',
canActivate: [UserRoleGuard],
component: AppBlankComponent,
data: { title: 'Blank', breadcrumb: 'Blank', roles: config.authRoles.sa }
}]
}
]
Example #4
Source File: appLayout.helper.ts From one-platform with MIT License | 6 votes |
handleBreadCrumbLinkGenerator = (url: string): BreadCrumbLink[] => {
const currentUrl = url.slice(config.baseURL.length);
const breadCrumbLinks: BreadCrumbLink[] = [];
currentUrl.split('/').forEach((urlSub) => {
if (urlSub && urlLookUpTable?.[urlSub]) {
breadCrumbLinks.push(urlLookUpTable[urlSub]);
}
});
return breadCrumbLinks;
}
Example #5
Source File: saga.ts From oasis-wallet-web with Apache License 2.0 | 6 votes |
/**
* Return the explorer APIs for the specified network
* or by default, for the currently selected network
*/
export function* getExplorerAPIs(network?: NetworkType) {
const selectedNetwork = yield* select(selectSelectedNetwork)
const url = config[selectedNetwork][backend()].explorer
return backendApi(url)
}
Example #6
Source File: saga.ts From oasis-wallet-web with Apache License 2.0 | 6 votes |
/**
* Return a nic client for the specified network,
* or by default, for the currently selected network
*/
export function* getOasisNic(network?: NetworkType) {
let selectedNetwork = network ? network : yield* select(selectSelectedNetwork)
const url = config[selectedNetwork].grpc
let nic = new oasis.client.NodeInternal(url)
return nic
}
Example #7
Source File: ApiTypeSelector.tsx From one-platform with MIT License | 6 votes |
ApiTypeSelector = ({ value, onChange, errorMsg }: Props): JSX.Element => {
return (
<FormGroup fieldId="datasource-type" label="Datasource type" isRequired>
<Split hasGutter>
{apiOptions.map(({ title, desc, image, type }) => (
<SplitItem isFilled key={type}>
<CatalogBigButton
title={title}
desc={desc}
image={`${config.baseURL}/images/${image}`}
isSelected={value === type}
onClick={callbackify(onChange, type)}
/>
</SplitItem>
))}
</Split>
{errorMsg && (
<FormAlert>
<Alert variant="danger" title={errorMsg} aria-live="polite" isInline />
</FormAlert>
)}
</FormGroup>
);
}
Example #8
Source File: ApiTypeCard.tsx From one-platform with MIT License | 6 votes |
ApiTypeCard = ({ category = ApiCategory.REST }: Props): JSX.Element => {
const getApiTypeImage = useCallback(
(apiCategory: ApiCategory) =>
apiCategory === ApiCategory.REST
? `${config.baseURL}/images/rest-logo.svg`
: `${config.baseURL}/images/graphql-logo.svg`,
[]
);
return (
<Card className="catalog-card-flat">
<CardBody>
<Split className="pf-u-align-items-center">
<SplitItem isFilled>
<Stack>
<StackItem className="pf-u-mb-xs">
<Text component={TextVariants.small}>API Type</Text>
</StackItem>
<StackItem>
<Title headingLevel="h6" size="2xl">
{category}
</Title>
</StackItem>
</Stack>
</SplitItem>
<SplitItem>
<img src={getApiTypeImage(category)} alt="api-type" />
</SplitItem>
</Split>
</CardBody>
</Card>
);
}
Example #9
Source File: environment.ts From matx-angular with MIT License | 5 votes |
environment = {
production: false,
apiURL: config.apiUrl
}
Example #10
Source File: app.ts From one-platform with MIT License | 5 votes |
startApolloServer = async (gqlSchema: GraphQLSchema, config: Config) => {
const context: ContextFunction<FastifyContext> = async ({ request }) => {
const id = request?.headers?.['x-op-user-id'];
const loaders = {
user: setupUserDataLoader(config.apiGatewayURL, config.apiGatewayToken),
subscriptionStatus: setupSubscriptionStatusLoader(),
};
return { loaders, user: { id } };
};
const app = fastify({
logger: true,
});
const server = new ApolloServer({
schema: gqlSchema,
context,
dataSources: () => {
return {
namespaceDB: new NamespaceDB(Namespace),
subscriptionDB: new SubscriptionDB(Subscription),
specStoreDB: new SpecStoreDB(SpecStore),
};
},
formatError: (error) => ({
message: error.message,
locations: error.locations,
path: error.path,
...error.extensions,
}),
plugins: [
fastifyAppClosePlugin(app),
ApolloServerPluginDrainHttpServer({ httpServer: app.server }),
],
});
await server.start();
app.register(server.createHandler());
await app.listen(config.port, '0.0.0.0');
}
Example #11
Source File: environment.prod.ts From matx-angular with MIT License | 5 votes |
environment = {
production: true,
apiURL: config.apiUrl
}
Example #12
Source File: HomePage.tsx From one-platform with MIT License | 5 votes |
REST_LOGO = `${config.baseURL}/images/rest-logo.svg`
Example #13
Source File: HomePage.tsx From one-platform with MIT License | 5 votes |
GRAPHQL_LOGO = `${config.baseURL}/images/graphql-logo.svg`
Example #14
Source File: HomePage.tsx From one-platform with MIT License | 5 votes |
OP_CONTAINER_LOGO = `${config.baseURL}/images/op-containers.svg`
Example #15
Source File: ApiEnvironmentSection.tsx From one-platform with MIT License | 5 votes |
REDOC_LOGO = `${config.baseURL}/images/redoc-logo.png`
Example #16
Source File: ApiEnvironmentSection.tsx From one-platform with MIT License | 5 votes |
PLAYGROUND_ICON = `${config.baseURL}/images/gql-playground-logo.svg`
Example #17
Source File: ApiEnvironmentSection.tsx From one-platform with MIT License | 5 votes |
SWAGGER_ICON = `${config.baseURL}/images/swagger-logo.svg`
Example #18
Source File: AppLayout.tsx From one-platform with MIT License | 5 votes |
AppLayout: FC = () => {
const { pathname } = useLocation();
const [isSidebarOpen, setIsSidebarOpen] = useToggle(true);
const { breadcrumbs } = useBreadcrumb();
const isBreadcrumbHidden = breadcrumbs.length === 0;
return (
<Page
mainContainerId="app-layout-page"
sidebar={<Sidebar isOpen={isSidebarOpen} />}
className={styles['app-layout']}
breadcrumb={
!isBreadcrumbHidden && (
<Breadcrumb className={styles['app-layout--breadcrumb']}>
<BreadcrumbItem>
<Button variant="link" className="pf-u-p-0" onClick={setIsSidebarOpen.toggle}>
<BarsIcon />
</Button>
</BreadcrumbItem>
<BreadcrumbItem to="/">One Platform</BreadcrumbItem>
<BreadcrumbItem>
{pathname === config.baseURL ? 'API Catalog Home' : <Link to="/">API Catalog</Link>}
</BreadcrumbItem>
{breadcrumbs.map(({ label, url }, index) => {
const isActive = index === breadcrumbs.length - 1;
return (
<BreadcrumbItem key={label}>
{isActive ? label : <Link to={url}>{label}</Link>}
</BreadcrumbItem>
);
})}
</Breadcrumb>
)
}
>
<PageSection
className={styles['app-layout--content']}
variant="light"
padding={{ default: 'noPadding' }}
>
<Outlet />
</PageSection>
</Page>
);
}
Example #19
Source File: BreadcrumbContext.tsx From one-platform with MIT License | 5 votes |
BreadcrumbProvider = ({ children }: Props): JSX.Element => {
// load it up
const [dynamicCrumbs, setDynamicCrumbs] = useState<Record<string, Breadcrumb>>();
const [breadcrumbs, setBreadcrumbs] = useState<Breadcrumb[]>([]);
const { pathname } = useLocation();
const handleDynamicCrumbs = useCallback((crumb: Record<string, Breadcrumb>): void => {
// save recent visit to quick link
setDynamicCrumbs((state) => ({ ...state, ...crumb }));
}, []);
useEffect(() => {
const path = pathname.replace(config.baseURL, '');
const matchedPath = (Object.keys(BREADCRUMB_USERFLOW) as ApiCatalogLinks[]).find((pattern) =>
Boolean(matchPath(pattern, path))
);
if (matchedPath) {
const crumbs = BREADCRUMB_USERFLOW[matchedPath]
.map((userflow) =>
LOOK_UP_TABLE?.[userflow] ? LOOK_UP_TABLE?.[userflow] : dynamicCrumbs?.[userflow]
)
.filter((crumb) => Boolean(crumb)) as Breadcrumb[];
setBreadcrumbs(crumbs);
} else {
setBreadcrumbs([]);
}
}, [pathname, dynamicCrumbs]);
/**
* Context value to access glabally from anywhere
* Memo to optimize at best
*/
const value = useMemo(
() => ({
breadcrumbs,
handleDynamicCrumbs,
}),
[breadcrumbs, handleDynamicCrumbs]
);
return <BreadcrumbContext.Provider value={value}>{children}</BreadcrumbContext.Provider>;
}
Example #20
Source File: App.tsx From one-platform with MIT License | 5 votes |
opcBase.configure({ apiBasePath: config.opcBase.apiBasePath, subscriptionsPath: config.opcBase.subscriptionsPath, keycloakUrl: config.opcBase.keycloakUrl, keycloakClientId: config.opcBase.keycloakClientId, keycloakRealm: config.opcBase.keycloakRealm, });
Example #21
Source File: ApiSchemaList.tsx From one-platform with MIT License | 4 votes |
ApiSchemaList = ({ schemas = [], onClick, selectedSchemaID }: Props): JSX.Element => {
const numberOfGraphqlAPI = schemas.reduce(
(prev, { category }) => (category === ApiCategory.GRAPHQL ? prev + 1 : prev),
0
);
const numberOfRestAPI = schemas.reduce(
(prev, { category }) => (category === ApiCategory.REST ? prev + 1 : prev),
0
);
return (
<Card
isCompact
isRounded
style={{ maxWidth: '320px', marginLeft: 'auto' }}
className="border-1"
>
<CardHeader>
<Stack hasGutter className="pf-u-w-100">
<StackItem className="pf-u-text-align-center">
<CardTitle>API Schemas Registered</CardTitle>
</StackItem>
<StackItem>
<Split hasGutter>
<SplitItem isFilled>
<Stack>
<StackItem>
<Text component={TextVariants.small}>Total</Text>
<Title headingLevel="h3" size="3xl">
{schemas.length}
</Title>
</StackItem>
</Stack>
</SplitItem>
<Divider isVertical />
<SplitItem isFilled>
<Stack>
<StackItem>
<Text component={TextVariants.small}>REST</Text>
<Title headingLevel="h3" size="3xl">
{numberOfRestAPI}
</Title>
</StackItem>
</Stack>
</SplitItem>
<Divider isVertical />
<SplitItem isFilled>
<Stack>
<StackItem>
<Text component={TextVariants.small}>GraphQL</Text>
<Title headingLevel="h3" size="3xl">
{numberOfGraphqlAPI}
</Title>
</StackItem>
</Stack>
</SplitItem>
</Split>
</StackItem>
</Stack>
</CardHeader>
<CardBody>
<DataList
isCompact
aria-label="schema-list"
style={{ overflowY: 'auto', maxHeight: '180px' }}
>
{schemas.map(({ id: sID, name, category, flags }) => (
<DataListItem key={sID}>
<DataListItemRow
className={css('pf-u-px-sm cursor-pointer', {
'menu-selected': selectedSchemaID === sID,
})}
onClick={() => onClick(sID)}
>
<DataListItemCells
dataListCells={[
<DataListCell key={`${sID}-category`} isFilled={false}>
<Avatar
src={`${config.baseURL}/images/${
category === 'REST' ? 'swagger-black-logo.svg' : 'graphql-logo.svg'
}`}
alt="api-type"
size="sm"
style={{ width: '1rem', height: '1rem' }}
className="pf-u-mt-sm"
/>
</DataListCell>,
<DataListCell
key={`${sID}-${name}`}
className="pf-u-display-flex pf-u-align-items-center"
>
<Text>{name}</Text>
</DataListCell>,
<DataListCell
isFilled={false}
key={`${sID}-flag`}
className="pf-u-display-flex pf-u-align-items-center"
>
<Label
color={flags.isInternal ? 'blue' : 'green'}
isCompact
className="pf-u-ml-sm"
>
{flags.isInternal ? 'Internal' : 'External'}
</Label>
</DataListCell>,
]}
/>
</DataListItemRow>
</DataListItem>
))}
</DataList>
</CardBody>
</Card>
);
}
Example #22
Source File: APIListPage.tsx From one-platform with MIT License | 4 votes |
APIListPage = (): JSX.Element => {
const navigate = useNavigate();
// query param strings
const query = useQueryParams();
const mid = query.get('mid');
const defaultSearch = query.get('search');
// filters, search, sorting
const [isSortSelectOpen, setSortSelect] = useToggle();
const [sortOption, setSortOption] = useState(SortBy.RECENTLY_ADDED);
const [filters, setFilters] = useState<{ type: null | ApiCategory; search: string }>({
type: null,
search: defaultSearch || '',
});
const { pagination, onPerPageSelect, onSetPage, onResetPagination } = usePagination({
page: 1,
perPage: 20,
});
const debouncedSearch = useDebounce(filters.search);
// graphql query hooks
const { isLoading: isApiListLoading, data: namespaceList } = useGetNamespaceList({
limit: pagination.perPage,
offset: (pagination.page - 1) * pagination.perPage,
apiCategory: filters.type,
search: debouncedSearch,
sortBy: sortOption === SortBy.RECENTLY_ADDED ? 'CREATED_ON' : 'UPDATED_ON',
mid,
});
const { isLoading: isNamespaceStatLoading, data: namespaceStats } = useGetNamespaceStats({
search: debouncedSearch,
mid,
});
const handleApiOwnersRender = useCallback((owners: ApiOwnerType[]) => {
return owners.map((owner) =>
owner.group === ApiEmailGroup.USER ? owner.user.cn : owner.email
);
}, []);
const onStatCardClick = (cardType: 'total' | 'rest' | 'graphql') => {
onResetPagination();
if (cardType === 'total') {
setFilters((state) => ({ ...state, type: null }));
} else {
setFilters((state) => ({ ...state, type: cardType.toUpperCase() as ApiCategory }));
}
};
const onSearch = (search: string) => {
setFilters((state) => ({ ...state, search }));
};
const onSortSelect = (
event: React.MouseEvent | React.ChangeEvent,
value: string | SelectOptionObject,
isPlaceholder?: boolean
) => {
if (isPlaceholder) setSortOption(SortBy.RECENTLY_ADDED);
else setSortOption(value as SortBy);
setSortSelect.off(); // close the select
};
const onCardClick = (id: string) => {
navigate(id);
};
const namespaceCount = namespaceStats?.getApiCategoryCount;
const namespaces = namespaceList?.listNamespaces?.data;
const isNamespaceEmpty = !isApiListLoading && namespaces?.length === 0;
return (
<>
<Header />
<Divider />
<PageSection variant="light" isWidthLimited className="pf-m-align-center">
<Grid hasGutter>
<Grid hasGutter span={12}>
{stats.map(({ key, type, image }) => (
<GridItem
key={`api-select-${type}`}
span={4}
className={styles['api-list--stat-card']}
type={key}
>
<StatCard
value={namespaceCount?.[key]}
category={type}
isLoading={isNamespaceStatLoading}
onClick={callbackify(onStatCardClick, key)}
isSelected={filters.type ? filters.type.toLowerCase() === key : key === 'total'}
>
<img
src={`${config.baseURL}/images/${image}`}
alt={`api-select-${type}`}
style={{ height: '48px' }}
/>
</StatCard>
</GridItem>
))}
</Grid>
<GridItem className="pf-u-my-md">
<Split hasGutter className={styles['api-list--table-filter--container']}>
<SplitItem isFilled>
<Link to={ApiCatalogLinks.AddNewApiPage}>
<Button>Add API</Button>
</Link>
</SplitItem>
<SplitItem className="pf-u-w-33">
<Form>
<FormGroup fieldId="search">
<TextInput
aria-label="Search API"
placeholder="Search for APIs"
type="search"
iconVariant="search"
value={filters.search}
onChange={onSearch}
/>
</FormGroup>
</Form>
</SplitItem>
<SplitItem style={{ width: '180px' }}>
<Select
isOpen={isSortSelectOpen}
onToggle={setSortSelect.toggle}
selections={sortOption}
onSelect={onSortSelect}
>
{[
<SelectOption key="select-sort-placeholder" value="Sort by" isDisabled />,
<SelectOption
key={`select-sort:${SortBy.RECENTLY_ADDED}`}
value={SortBy.RECENTLY_ADDED}
/>,
<SelectOption
key={`select-sort:${SortBy.RECENTLY_MODIFIED}`}
value={SortBy.RECENTLY_MODIFIED}
/>,
]}
</Select>
</SplitItem>
</Split>
</GridItem>
{isApiListLoading ? (
<Bullseye className="pf-u-mt-lg">
<Spinner size="xl" />
</Bullseye>
) : (
namespaces?.map(({ id, name, updatedOn, owners, schemas, slug }) => (
<GridItem
span={12}
key={id}
className="catalog-nav-link"
onClick={callbackify(onCardClick, slug)}
>
<ApiDetailsCard
title={name}
owners={handleApiOwnersRender(owners)}
updatedAt={updatedOn}
schemas={schemas.map(({ name: schemaName, category }) => ({
name: schemaName,
type: category,
}))}
/>
</GridItem>
))
)}
{isNamespaceEmpty && (
<EmptyState>
<EmptyStateIcon icon={CubesIcon} />
<Title headingLevel="h4" size="lg">
No API found
</Title>
<EmptyStateBody>Add an API to fill this gap</EmptyStateBody>
</EmptyState>
)}
</Grid>
</PageSection>
<PageSection variant="light" isWidthLimited className="pf-m-align-center pf-u-pb-2xl">
<Pagination
itemCount={namespaceList?.listNamespaces?.count || 0}
widgetId="pagination-options-menu-bottom"
perPage={pagination.perPage}
page={pagination.page}
onSetPage={(_, page) => onSetPage(page)}
onPerPageSelect={(_, perPage) => onPerPageSelect(perPage)}
isCompact
/>
</PageSection>
</>
);
}
Example #23
Source File: ApiDetailsCard.tsx From one-platform with MIT License | 4 votes |
ApiDetailsCard = ({
title,
owners = [],
schemas = [],
updatedAt,
}: Props): JSX.Element => {
const formatUpdatedAt = useCallback(
(apiUpdatedAt: string) => `modified on: ${dayjs(apiUpdatedAt).format('DD MMM YYYY hh:mm a')}`,
[]
);
const stopOnClickPropogation: DOMAttributes<HTMLDivElement>['onClick'] = (event) => {
event.stopPropagation();
};
return (
<Card className="catalog-card-hover-effect cursor-pointer">
<CardBody className="pf-u-px-md">
<Stack hasGutter>
<StackItem>
<Split hasGutter className="pf-l-flex pf-m-align-items-flex-end">
<SplitItem isFilled>
<Title headingLevel="h4" size={TitleSizes['2xl']}>
{title}
</Title>
</SplitItem>
<SplitItem>
<Text component={TextVariants.small} className="pf-u-color-400">
{formatUpdatedAt(updatedAt)}
</Text>
</SplitItem>
</Split>
</StackItem>
<StackItem>
<Split hasGutter>
<SplitItem>
<Split isWrappable onClick={stopOnClickPropogation}>
<SplitItem className="pf-u-mr-xs">
<Text>Owned by:</Text>
</SplitItem>
<ReadMore
limit={MAX_LOADED}
showMoreText={`+${(owners || []).length - MAX_LOADED} more`}
>
{owners.map((owner) => (
<SplitItem className="pf-u-ml-xs" key={owner}>
<Label isCompact color="cyan">
{owner}
</Label>
</SplitItem>
))}
</ReadMore>
</Split>
</SplitItem>
<SplitItem isFilled />
<SplitItem>
<Split onClick={stopOnClickPropogation} isWrappable>
<SplitItem className="pf-u-mr-sm">
<Text>Schema(s): </Text>
</SplitItem>
<ReadMore
limit={MAX_LOADED}
showMoreText={`+${(schemas || []).length - MAX_LOADED} more`}
>
{schemas.map(({ name, type }) => (
<SplitItem style={{ marginTop: '0.1rem' }} key={name}>
<Label
color="blue"
className="pf-u-mr-xs"
isCompact
icon={
<img
src={`${config.baseURL}/images/${
type === 'REST' ? 'swagger-black-logo.svg' : 'graphql-logo.svg'
}`}
alt="api-type"
className="pf-u-mt-xs"
style={{ height: '0.8rem', width: '0.8rem' }}
/>
}
>
{name}
</Label>
</SplitItem>
))}
</ReadMore>
</Split>
</SplitItem>
</Split>
</StackItem>
</Stack>
</CardBody>
</Card>
);
}
Example #24
Source File: APIDescriptionPage.tsx From one-platform with MIT License | 4 votes |
APIDescriptionPage = (): JSX.Element => {
const { slug } = useParams();
const navigate = useNavigate();
const { handleDynamicCrumbs } = useBreadcrumb();
const urlParser = useURLParser();
const [selectedSchemaIndex, setSelectedSchemaIndex] = useState(0);
const [isSubscriptionOptionOpen, setIsSubscriptionOptionOpen] = useToggle();
const [isSchemaDropdownOpen, setIsSchemaDropdownOpen] = useToggle();
const [selectedSubscriptonEnv, setSelectedSubscriptionEnv] = useState<Record<
string,
boolean
> | null>(null);
const userInfo = opcBase.auth?.getUserInfo();
const [{ fetching: isSubscribing, data: subscribedNamespace }, handleSubscribeSchemaGQL] =
useSubscribeSchema();
const { isLoading: isNamespaceLoading, data: fetchedNamespace } = useGetANamespaceBySlug({
slug,
});
const namespace = subscribedNamespace?.subscribeApiSchema || fetchedNamespace?.getNamespaceBySlug;
const id = namespace?.id;
const schemas = namespace?.schemas || [];
const selectedSchema = namespace?.schemas[selectedSchemaIndex];
// effect to add breadcrumb data
useEffect(() => {
if (!isNamespaceLoading && namespace?.name && namespace?.id) {
handleDynamicCrumbs({
'api-name': { label: namespace.name, url: `/apis/${namespace?.slug}` },
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isNamespaceLoading, namespace?.name, namespace?.id]);
const hasEditAccess = useMemo(() => {
const userUuid = userInfo?.rhatUUID;
return hasUserApiEditAccess(userUuid as string, namespace);
}, [namespace, userInfo?.rhatUUID]);
const onMenuClick = (schemaId: string) => {
const index = namespace?.schemas.findIndex(({ id: sid }) => sid === schemaId);
if (index !== -1) {
setSelectedSchemaIndex(index || 0);
}
setIsSchemaDropdownOpen.off();
};
const hasSubscribed = selectedSchema?.environments.some(({ isSubscribed }) => isSubscribed);
const handleSchemaSubscription = async (envIDs?: string[]) => {
const subscribedIds =
envIDs ||
(hasSubscribed ? [] : (selectedSchema?.environments || []).map(({ id: sID }) => sID));
const subscriptionConfig = {
namespaceID: id as string,
schemaID: selectedSchema?.id || '',
envIDs: subscribedIds,
email: userInfo?.email || '',
};
try {
const res = await handleSubscribeSchemaGQL({ config: subscriptionConfig });
if (res.error) {
opcBase.toast.danger({
subject: `Failed to ${hasSubscribed ? 'unsubscribe' : 'subscribe'} api`,
body: res?.error?.message,
});
} else {
const subject = `${hasSubscribed ? 'Unsubscribed' : 'Subscribed'} to ${namespace?.name}`;
const body = `You will ${
hasSubscribed ? 'not be' : 'be'
} be notified regarding updates on this API`;
opcBase.toast.info({ subject, body });
}
} catch (error) {
opcBase.toast.danger({
subject: `Failed to ${hasSubscribed ? 'unsubscribe' : 'subscribe'} api`,
});
}
};
const onInitializeSelect = () => {
if (!isSubscriptionOptionOpen) {
const alreadySubscripedEnv = (selectedSchema?.environments || []).reduce<
Record<string, boolean>
>(
(prev, { isSubscribed, id: eId }) =>
isSubscribed ? { ...prev, [eId]: true } : { ...prev },
{}
);
setSelectedSubscriptionEnv(alreadySubscripedEnv);
}
setIsSubscriptionOptionOpen.toggle();
};
const onEnvSelect = (env: string) => {
const isEnvPresent = Boolean(selectedSubscriptonEnv?.[env]);
const state = { ...selectedSubscriptonEnv };
if (isEnvPresent) {
delete state[env];
setSelectedSubscriptionEnv(state);
} else {
state[env] = true;
setSelectedSubscriptionEnv(state);
}
};
const onEnvSelectBlur = async () => {
if (selectedSubscriptonEnv) {
await handleSchemaSubscription(Object.keys(selectedSubscriptonEnv));
}
setIsSubscriptionOptionOpen.off();
setSelectedSubscriptionEnv(null);
};
if (isNamespaceLoading) {
return (
<Bullseye>
<Spinner size="xl" />
</Bullseye>
);
}
if (!namespace) {
return (
<Bullseye>
<EmptyState>
<EmptyStateIcon icon={CubesIcon} />
<Title headingLevel="h4" size="lg">
Sorry, Couldn't find this API
</Title>
<Button variant="primary" onClick={() => navigate('../')}>
Go Back
</Button>
</EmptyState>
</Bullseye>
);
}
return (
<Stack>
<StackItem>
<PageSection isWidthLimited isCenterAligned>
<Grid hasGutter>
<GridItem span={8}>
<DetailsSection namespace={namespace} id={slug} hasEditAccess={hasEditAccess} />
</GridItem>
<GridItem span={4}>
<ApiSchemaList
schemas={namespace?.schemas}
onClick={onMenuClick}
selectedSchemaID={selectedSchema?.id}
/>
</GridItem>
</Grid>
</PageSection>
</StackItem>
<StackItem>
<PageSection
isWidthLimited
isCenterAligned
padding={{ default: 'noPadding' }}
className="pf-u-py-sm pf-u-px-md"
>
<Text component={TextVariants.small} className="pf-u-color-400">
API Schema
</Text>
</PageSection>
</StackItem>
<StackItem>
<Divider />
</StackItem>
<StackItem>
<PageSection isWidthLimited isCenterAligned className="pf-u-pb-4xl">
<Grid hasGutter>
{selectedSchema?.flags.isDeprecated && (
<Grid span={12}>
<Alert variant="danger" isInline title={`${selectedSchema.name} is deprecated`} />
</Grid>
)}
<GridItem span={8}>
<Stack
hasGutter
style={{ '--pf-l-stack--m-gutter--MarginBottom': '1.5rem' } as CSSProperties}
>
<StackItem className={styles.schemaContainer}>
<Split>
<SplitItem isFilled>
<Button
variant="link"
icon={<CaretDownIcon />}
onClick={setIsSchemaDropdownOpen.toggle}
iconPosition="right"
style={{ color: 'black' }}
className={styles.schemaDropdownTitle}
>
{selectedSchema?.name}
</Button>
</SplitItem>
<SplitItem className="pf-u-mr-lg">
<Label color={selectedSchema?.flags?.isInternal ? 'blue' : 'green'} isCompact>
{selectedSchema?.flags?.isInternal ? 'Internal API' : 'External API'}
</Label>
</SplitItem>
</Split>
<CSSTransition
in={isSchemaDropdownOpen}
timeout={200}
classNames="fade-in"
unmountOnExit
>
<Menu className={styles.schemaMenu}>
<MenuContent>
<MenuList className="pf-u-py-0">
{schemas.map((schema, index) => (
<Fragment key={schema.id}>
<MenuItem
className={css({
'menu-selected': schema.id === selectedSchema?.id,
})}
icon={
<Avatar
src={`${config.baseURL}/images/${
schema.category === 'REST'
? 'swagger-black-logo.svg'
: 'graphql-logo.svg'
}`}
alt="api-type"
size="sm"
style={{ width: '1.25rem', height: '1.25rem' }}
className="pf-u-mt-sm"
/>
}
onClick={() => onMenuClick(schema.id)}
>
<Split>
<SplitItem isFilled>{schema.name}</SplitItem>
<SplitItem>
<Label
color={schema.flags.isInternal ? 'blue' : 'green'}
isCompact
className="pf-u-ml-sm"
>
{schema.flags.isInternal ? 'Internal' : 'External'}
</Label>
</SplitItem>
</Split>
</MenuItem>
{schemas.length - 1 !== index && (
<Divider component="li" className="pf-u-my-0" />
)}
</Fragment>
))}
</MenuList>
</MenuContent>
</Menu>
</CSSTransition>
</StackItem>
<StackItem>
<ReadMore>{selectedSchema?.description || ''}</ReadMore>
</StackItem>
<StackItem>
<Split hasGutter>
<SplitItem isFilled>
<Title headingLevel="h3">Application URL</Title>
<a href={selectedSchema?.appURL} target="_blank" rel="noopener noreferrer">
<Text className="pf-u-color-400">
{urlParser(selectedSchema?.appURL || '')}
</Text>
</a>
</SplitItem>
<SplitItem isFilled>
<Title headingLevel="h3">Documentation URL</Title>
<a href={selectedSchema?.docURL} target="_blank" rel="noopener noreferrer">
<Text className="pf-u-color-400">
{urlParser(selectedSchema?.docURL || '')}
</Text>
</a>
</SplitItem>
</Split>
</StackItem>
<StackItem className="pf-u-mt-md">
<ApiEnvironmentSection
environments={selectedSchema?.environments}
category={selectedSchema?.category}
/>
</StackItem>
</Stack>
</GridItem>
<GridItem span={1} />
<GridItem span={3}>
<Stack hasGutter>
<StackItem className={styles.subscriptionContainer}>
<Split>
<SplitItem isFilled>
<Button
icon={<BellIcon />}
variant={hasSubscribed ? 'primary' : 'secondary'}
iconPosition="right"
isBlock
isLoading={isSubscribing}
className={css(hasSubscribed ? styles.subscriptionDropdownBtn : null)}
onClick={() => handleSchemaSubscription()}
>
{hasSubscribed ? 'Subscribed' : 'Subscribe'}
</Button>
</SplitItem>
<CSSTransition
in={hasSubscribed}
timeout={200}
classNames="fade-in"
unmountOnExit
>
<SplitItem>
<Button
icon={<CaretDownIcon />}
onClick={onInitializeSelect}
className={css('ignore-blur', styles.subscriptionDropdownArrow)}
/>
</SplitItem>
</CSSTransition>
</Split>
<CSSTransition
in={isSubscriptionOptionOpen}
timeout={200}
classNames="fade-in"
unmountOnExit
>
<Menu
className={styles.subscriptionMenu}
onBlur={(e) => {
if (!e.relatedTarget?.className?.includes('ignore-blur')) {
onEnvSelectBlur();
}
}}
>
<MenuContent>
<MenuList className="pf-u-py-0">
{selectedSchema?.environments.map(({ name, isSubscribed, id: envId }) => (
<MenuItem
className="uppercase ignore-blur"
isSelected={
selectedSubscriptonEnv
? selectedSubscriptonEnv[envId]
: isSubscribed
}
key={`subscription-${envId}`}
itemId={envId}
onClick={() => onEnvSelect(envId)}
>
{name}
</MenuItem>
))}
</MenuList>
</MenuContent>
</Menu>
</CSSTransition>
</StackItem>
<StackItem>
<ApiTypeCard category={selectedSchema?.category} />
</StackItem>
</Stack>
</GridItem>
</Grid>
</PageSection>
</StackItem>
</Stack>
);
}
Example #25
Source File: index.tsx From oasis-wallet-web with Apache License 2.0 | 4 votes |
export function Transaction(props: TransactionProps) {
const { t } = useTranslation()
const transaction = props.transaction
const referenceAddress = props.referenceAddress
const amount = <AmountFormatter amount={transaction.amount!} />
let side: TransactionSide
let otherAddress = ''
if (transaction.from === referenceAddress) {
side = TransactionSide.Sent
otherAddress = transaction.to!
} else {
side = TransactionSide.Received
otherAddress = transaction.from!
}
const unrecognizedTransaction: TransactionDictionary[transactionTypes.TransactionType][TransactionSide] = {
designation: t('account.otherTransaction.designation', 'Other address'),
icon: () => <New />,
header: () => (
<Trans
i18nKey="account.otherTransaction.header"
t={t}
values={{ method: transaction.type }}
defaults="Unrecognized transaction, method '{{method}}'"
/>
),
}
// @TODO: This could probably cleverly be moved outside of the component
//for better readability and marginal performance gain, but for now
//the translation keys need to be read by i18next extraction
const transactionDictionary: TransactionDictionary = {
[transactionTypes.TransactionType.StakingTransfer]: {
[TransactionSide.Received]: {
designation: t('common.from', 'From'),
icon: () => <LinkPrevious />,
header: () => (
<Trans
i18nKey="account.transaction.transfer.received"
t={t}
components={[amount]}
defaults="Received <0></0>"
/>
),
},
[TransactionSide.Sent]: {
designation: t('common.to', 'To'),
icon: () => <LinkNext />,
header: () => (
<Trans
i18nKey="account.transaction.transfer.sent.header"
t={t}
components={[amount]}
defaults="Sent <0></0>"
/>
),
},
},
[transactionTypes.TransactionType.StakingAddEscrow]: {
[TransactionSide.Received]: {
designation: t('common.delegator', 'Delegator'),
icon: () => <LineChart />,
header: () => (
<Trans
i18nKey="account.transaction.addEscrow.received"
t={t}
components={[amount]}
defaults="Received <0></0> delegation in escrow"
/>
),
},
[TransactionSide.Sent]: {
designation: t('common.validator', 'Validator'),
icon: () => <LineChart />,
header: () => (
<Trans
i18nKey="account.transaction.addEscrow.sent"
t={t}
components={[amount]}
defaults="Delegated <0></0> to validator"
/>
),
},
},
[transactionTypes.TransactionType.StakingReclaimEscrow]: {
[TransactionSide.Received]: {
designation: t('common.delegator', 'Delegator'),
icon: () => <Money />,
header: () => (
<Trans
i18nKey="account.transaction.reclaimEscrow.received"
t={t}
components={[amount]}
defaults="<0></0> reclaimed by delegator"
/>
),
},
[TransactionSide.Sent]: {
designation: t('common.validator', 'Validator'),
icon: () => <Money />,
header: () => (
<Trans
i18nKey="account.transaction.reclaimEscrow.sent"
t={t}
components={[amount]}
defaults="Reclaimed <0></0> from validator"
/>
),
},
},
[transactionTypes.TransactionType.StakingAmendCommissionSchedule]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.StakingAllow]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.StakingWithdraw]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.RoothashExecutorCommit]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.RoothashExecutorProposerTimeout]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.RegistryRegisterEntity]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.RegistryRegisterNode]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.RegistryRegisterRuntime]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.GovernanceCastVote]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.GovernanceSubmitProposal]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.BeaconPvssCommit]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.BeaconPvssReveal]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
[transactionTypes.TransactionType.BeaconVrfProve]: {
[TransactionSide.Received]: unrecognizedTransaction,
[TransactionSide.Sent]: unrecognizedTransaction,
},
}
const isTypeRecognized = (type: string | undefined): type is transactionTypes.TransactionType =>
type ? type in transactionDictionary : false
const matchingConfiguration = isTypeRecognized(transaction.type)
? transactionDictionary[transaction.type][side]
: unrecognizedTransaction
const icon = matchingConfiguration.icon()
const header = matchingConfiguration.header()
const designation = matchingConfiguration.designation
const blockExplorerLink = config[props.network][backend()]?.blockExplorer
return (
<Card round="small" background="background-front" gap="none" elevation="xsmall">
<CardHeader pad={{ horizontal: 'medium', vertical: 'small' }} gap="none" background="brand" wrap={true}>
<Box direction="row" gap="small">
{icon}
<Text>{header}</Text>
</Box>
</CardHeader>
<CardBody pad={{ horizontal: 'none', vertical: 'none' }}>
<Grid columns={{ count: 'fit', size: 'xsmall' }} gap="none">
<InfoBox icon={<Money color="brand" />} label={t('common.amount', 'Amount')} value={amount} />
{otherAddress && (
<NavLink data-testid="external-wallet-address" to={`/account/${otherAddress}`}>
<InfoBox
icon={<ContactInfo color="brand" />}
label={designation}
value={<ShortAddress address={otherAddress} />}
/>
</NavLink>
)}
{!otherAddress && (
<InfoBox
icon={<ContactInfo color="brand" />}
label={designation}
value={t('common.unavailable', 'Unavailable')}
/>
)}
<InfoBox
icon={<Cube color="brand" />}
label={t('common.block', 'Block')}
value={transaction.level}
/>
</Grid>
</CardBody>
<CardFooter background="background-contrast" pad={{ horizontal: 'medium' }}>
<Text size="small">
<DateFormatter date={transaction.timestamp!} />
</Text>
<Box direction="row">
<Button
icon={<CircleInformation color="dark-3" />}
hoverIndicator
href={blockExplorerLink.replace('{{txHash}}', encodeURIComponent(transaction.hash))}
target="_blank"
rel="noopener"
data-testid="explorer-link"
/>
</Box>
</CardFooter>
</Card>
)
}
Example #26
Source File: APIReview.tsx From one-platform with MIT License | 4 votes |
APIReview = (): JSX.Element => {
const { getValues } = useFormContext<FormData>();
const [formData] = useState(getValues());
return (
<Stack hasGutter>
<StackItem>
<Card>
<CardTitle>
<Title headingLevel="h2">API Details</Title>
</CardTitle>
<CardBody>
<Stack hasGutter>
<StackItem>
<Description title="Name" isRequired>
<Title headingLevel="h6">{formData.name}</Title>
</Description>
</StackItem>
<StackItem>
<Description title="Description" isRequired>
<Title headingLevel="h6">
<ReadMore>{formData.description}</ReadMore>
</Title>
</Description>
</StackItem>
<StackItem>
<Description title="Owners">
<Title headingLevel="h6">
<List isPlain isBordered>
{formData.owners.map(({ email }) => (
<ListItem key={email}>{email}</ListItem>
))}
</List>
</Title>
</Description>
</StackItem>
</Stack>
</CardBody>
</Card>
</StackItem>
{formData.schemas?.map((schema, schemaIndex) => (
<StackItem key={schema.name}>
<Card>
<CardTitle>
<Title headingLevel="h2">{`API Schema #${schemaIndex + 1}`}</Title>
</CardTitle>
<CardBody>
<Stack hasGutter>
<StackItem>
<Description title="Schema Name" isRequired>
<Title headingLevel="h6">{schema.name}</Title>
</Description>
</StackItem>
<StackItem>
<Description title="Description" isRequired>
<Title headingLevel="h6">
<ReadMore>{schema.description}</ReadMore>
</Title>
</Description>
</StackItem>
<StackItem>
<Description title="Type" isRequired>
<CatalogBigButton
title={apiOptions[schema.category].title}
desc={apiOptions[schema.category].desc}
image={`${config.baseURL}/images/${apiOptions[schema.category].image}`}
/>
</Description>
</StackItem>
<StackItem>
<Split hasGutter>
<SplitItem isFilled>
<Description title="App URL" isRequired>
<Title headingLevel="h6">{schema.appURL}</Title>
</Description>
</SplitItem>
<SplitItem isFilled>
<Description title="App Documentation URL" isRequired>
<Title headingLevel="h6">{schema.docURL}</Title>
</Description>
</SplitItem>
</Split>
</StackItem>
<StackItem>
<Description title="Environments">
{schema.environments.map((env, envIndex) => (
<div
style={{ border: '1px solid #d2d2d2' }}
className="pf-u-p-lg pf-u-mb-md"
key={`schema-${schemaIndex + 1}-env-${envIndex + 1}`}
>
<Grid hasGutter>
<GridItem span={6}>
<Description title="Name" isRequired>
<Title headingLevel="h6" className="uppercase">
{env.name}
</Title>
</Description>
</GridItem>
<GridItem span={6}>
<Description title="API Base Path" isRequired>
<Title headingLevel="h6">{env.apiBasePath}</Title>
</Description>
</GridItem>
<GridItem span={6}>
<Description title="API Schema Endpoint" isRequired>
<Title headingLevel="h6">{env.schemaEndpoint}</Title>
</Description>
</GridItem>
<GridItem span={12}>
<Description title="Headers" isRequired>
<DataList aria-label="header-list" isCompact>
{env.headers?.map(
({ key }, index) =>
key && (
<DataListItem key={`${key}-${index + 1}`}>
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key={`${key}-${index + 1}-cell-1`}>
<span>{key}</span>
</DataListCell>,
<DataListCell key={`${key}-${index + 1}-cell-2`}>
<span>********</span>
</DataListCell>,
]}
/>
</DataListItemRow>
</DataListItem>
)
)}
</DataList>
</Description>
</GridItem>
<GridItem span={12}>
<Checkbox
isChecked={env.isPublic}
isDisabled
id={`schema-${schemaIndex}-env-${envIndex}-isPublic`}
label="Is this API accessible from public?"
/>
</GridItem>
</Grid>
</div>
))}
</Description>
</StackItem>
</Stack>
</CardBody>
</Card>
</StackItem>
))}
</Stack>
);
}
Example #27
Source File: Sidebar.tsx From one-platform with MIT License | 4 votes |
Sidebar = ({ isOpen }: Props): JSX.Element => {
const { pathname, search } = useLocation();
const url = pathname.replace(config.baseURL, '');
const { logs, quickLink } = useRecentVisit();
const userInfo = opcBase.auth?.getUserInfo();
const navLinks = useMemo(() => navMenuLinks(userInfo?.rhatUUID || ''), [userInfo?.rhatUUID]);
const getToolImage = useCallback((tool: string) => {
if (tool === 'playground') return `${config.baseURL}/images/gql-playground-logo.svg`;
if (tool === 'redoc') return `${config.baseURL}/images/redoc-logo.png`;
return `${config.baseURL}/images/${tool}-logo.svg`;
}, []);
const isQuickLinkActive = logs?.[0]?.url === pathname;
const isQuickLinkGraphql = logs?.[0]?.tool !== 'swagger' && logs?.[0]?.tool !== 'redoc';
const getQuickLinks = useCallback(() => {
if (isQuickLinkActive) {
const links = isQuickLinkGraphql ? graphqlQuickLinks : restQuickLinks;
return (
<NavGroup title={`${quickLink?.name} quick links`}>
{links.map(({ url: path, label, img }) => (
<NavItem key={`quick-link-${label}`}>
<Link
to={path
.replace(':id', quickLink?.id || '')
.replace(':envSlug', quickLink?.envSlug || '')}
>
<Split>
<SplitItem className="pf-u-mr-sm pf-u-display-flex pf-u-align-items-center">
<img
src={`${config.baseURL}/images/${img}`}
width="16px"
alt="quick link icon"
/>
</SplitItem>
<SplitItem>{label}</SplitItem>
</Split>
</Link>
</NavItem>
))}
</NavGroup>
);
}
return null;
}, [isQuickLinkActive, isQuickLinkGraphql, quickLink?.id, quickLink?.name, quickLink?.envSlug]);
return (
<PageSidebar
theme="light"
isNavOpen={isOpen}
className={styles['app-layout--sidebar']}
nav={
<Stack hasGutter>
<StackItem isFilled>
<Nav theme="light">
<NavList className="pf-u-mb-lg">
{navLinks.map(({ url: pattern, label, icon: Icon }, index) => (
<NavItem
key={`nav-menu-link:${label}`}
id="home-link"
itemId={index}
isActive={pattern === url + search}
>
<Link to={pattern}>
<Split>
<SplitItem className="pf-u-mr-sm">
<Icon />
</SplitItem>
<SplitItem>{label}</SplitItem>
</Split>
</Link>
</NavItem>
))}
</NavList>
{getQuickLinks()}
<NavGroup title="Recent visited">
{logs?.map(({ title, url: toolUrl, tool }) => (
<NavItem key={`nav-item-${toolUrl}`}>
<Link to={toolUrl.replace(config.baseURL, '/')}>
<Split hasGutter className="pf-u-align-items-center">
<SplitItem>
<img src={getToolImage(tool)} style={{ height: '24px' }} alt="swagger" />
</SplitItem>
<SplitItem>
<Title headingLevel="h6">{title}</Title>
<Text component={TextVariants.small} className="capitalize">
{tool}
</Text>
</SplitItem>
</Split>
</Link>
</NavItem>
))}
</NavGroup>
</Nav>
</StackItem>
<StackItem>
<Footer />
</StackItem>
</Stack>
}
/>
);
}