Add async support to entitySwitch if statements

Co-authored-by: Fredrik Adelöw <freben@users.noreply.github.com>
Co-authored-by: Ben Lambert <ben@blam.sh>
Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2021-10-01 13:06:48 +02:00
parent a0c6ae89b1
commit 672d6ed01a
@@ -19,25 +19,35 @@ import { useEntity } from '@backstage/plugin-catalog-react';
import { PropsWithChildren, ReactNode } from 'react';
import {
attachComponentData,
useApiHolder,
useElementFilter,
ApiHolder,
} from '@backstage/core-plugin-api';
import { useAsync } from 'react-use';
const ENTITY_SWITCH_KEY = 'core.backstage.entitySwitch';
const EntitySwitchCase = (_: {
if?: (entity: Entity) => boolean;
if?: (
entity: Entity,
context: { apiRegistry: ApiHolder },
) => boolean | Promise<boolean>;
children: ReactNode;
}) => null;
attachComponentData(EntitySwitchCase, ENTITY_SWITCH_KEY, true);
type SwitchCase = {
if?: (entity: Entity) => boolean | Promise<boolean>;
if?: (
entity: Entity,
context: { apiRegistry: ApiHolder },
) => boolean | Promise<boolean>;
children: JSX.Element;
};
export const EntitySwitch = ({ children }: PropsWithChildren<{}>) => {
const { entity } = useEntity();
const apiRegistry = useApiHolder();
const switchCases = useElementFilter(children, collection =>
collection
.selectByComponentData({
@@ -51,10 +61,29 @@ export const EntitySwitch = ({ children }: PropsWithChildren<{}>) => {
}),
);
const matchingCase = switchCases.find(switchCase =>
switchCase.if ? switchCase.if(entity) : true,
);
return matchingCase?.children ?? null;
const { loading, value } = useAsync(async () => {
const promises = switchCases.map(
async ({ if: condition, children: output }) => {
if (!condition) {
return output;
}
try {
const matches = await condition(entity, { apiRegistry });
return matches ? output : null;
} catch {
return null;
}
},
);
return (await Promise.all(promises)).find(Boolean) ?? null;
}, [switchCases]);
if (loading || !value) {
return null;
}
return value;
};
EntitySwitch.Case = EntitySwitchCase;