utils#hasUserApiEditAccess TypeScript Examples
The following examples show how to use
utils#hasUserApiEditAccess.
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>
);
}