hooks#useURLParser TypeScript Examples
The following examples show how to use
hooks#useURLParser.
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: 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 #2
Source File: ApiEnvironmentSection.tsx From one-platform with MIT License | 4 votes |
ApiEnvironmentSection = ({ environments = [], category }: Props): JSX.Element => {
const urlParser = useURLParser();
const getToolTip = useCallback(
(child: JSX.Element) => (
<Tooltip content="Owners didn't add schema for these environment">{child}</Tooltip>
),
[]
);
return (
<Stack hasGutter style={{ width: '85%' }}>
<StackItem>
<Title headingLevel="h3">Environments</Title>
<Divider />
</StackItem>
<StackItem>
{environments.length === 0 && (
<EmptyState>
<EmptyStateIcon icon={CubesIcon} />
<Title headingLevel="h4" size="lg">
No environments found
</Title>
</EmptyState>
)}
<DataList aria-label="environment-list" className={styles['catalog-env-list']} isCompact>
{environments.map(({ apiBasePath, name, slug, isPublic, schemaEndpoint }) => (
<DataListItem key={`${name}-${apiBasePath}`} className="pf-u-p-xs">
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell
key="stage"
className="pf-u-display-flex pf-u-align-items-center"
isFilled={false}
>
<span id="simple-item1" className="uppercase pf-u-font-weight-bold">
{name}
</span>
{!isPublic && (
<Label
isCompact
color="red"
style={{ fontSize: '0.5rem' }}
className="pf-u-ml-xs"
>
VPN
</Label>
)}
</DataListCell>,
<DataListCell
key="secondary content"
className="pf-u-display-flex pf-u-align-items-center pf-u-justify-content-center"
>
<a
href={apiBasePath}
className={styles['catalog-mailing-list']}
target="_blank"
rel="noopener noreferrer"
>
{urlParser(apiBasePath)}
</a>
</DataListCell>,
]}
/>
<ConditionalWrapper isWrapped={!schemaEndpoint} wrapper={getToolTip}>
<DataListAction
aria-labelledby="check-action-item2 check-action-action2"
id="check-action-action2"
aria-label="Actions"
className="pf-u-display-flex pf-u-align-items-center"
style={{ filter: !schemaEndpoint ? 'grayscale(100%)' : '' }}
>
{category === ApiCategory.GRAPHQL ? (
<Tooltip content="Playground">
<Link to={schemaEndpoint ? `/apis/graphql/playground/${slug}` : '#'}>
<Split style={{ whiteSpace: 'nowrap' }}>
<SplitItem style={{ height: '1.5rem', width: '1.5rem' }}>
<img
src={PLAYGROUND_ICON}
alt="playground"
style={{
height: '1.5rem',
width: '1.5rem',
borderRadius: '12px',
}}
/>
</SplitItem>
<SplitItem className="pf-u-ml-xs pf-u-display-flex pf-u-align-items-center">
<span className="pf-u-font-size-xs">Try it</span>
</SplitItem>
</Split>
</Link>
</Tooltip>
) : (
<>
<Tooltip content="Swagger">
<Link to={schemaEndpoint ? `/apis/rest/swagger/${slug}` : '#'}>
<Split style={{ whiteSpace: 'nowrap' }}>
<SplitItem style={{ height: '1.5rem', width: '1.5rem' }}>
<img
src={SWAGGER_ICON}
alt="swagger"
style={{
height: '1.5rem',
width: '1.5rem',
borderRadius: '12px',
}}
/>
</SplitItem>
<SplitItem className="pf-u-ml-xs pf-u-display-flex pf-u-align-items-center">
<span className="pf-u-font-size-xs ">Try it</span>
</SplitItem>
</Split>
</Link>
</Tooltip>
<Tooltip content="Redoc">
<Link to={schemaEndpoint ? `/apis/rest/redoc/${slug}` : '#'}>
<Split style={{ whiteSpace: 'nowrap' }}>
<SplitItem style={{ height: '1.5rem', width: '1.5rem' }}>
<img
src={REDOC_LOGO}
alt="redoc"
style={{
height: '1.5rem',
width: '1.5rem',
borderRadius: '12px',
}}
/>
</SplitItem>
<SplitItem className="pf-u-ml-xs pf-u-display-flex pf-u-align-items-center">
<span className="pf-u-font-size-xs">Try it</span>
</SplitItem>
</Split>
</Link>
</Tooltip>
</>
)}
</DataListAction>
</ConditionalWrapper>
</DataListItemRow>
</DataListItem>
))}
</DataList>
</StackItem>
</Stack>
);
}