chore: starting to add EntityAncestorsProcessingErrorsPanel

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2021-09-30 11:33:42 +02:00
committed by Johan Haals
parent 7d3228fefb
commit 8cb5d89e37
4 changed files with 100 additions and 16 deletions
@@ -33,6 +33,8 @@ import {
CatalogEntitiesRequest,
CatalogListResponse,
CatalogRequestOptions,
CatalogEntityAncestorsRequest,
CatalogEntityAncestorsResponse,
} from './types/api';
import { DiscoveryApi } from './types/discovery';
@@ -44,6 +46,24 @@ export class CatalogClient implements CatalogApi {
this.discoveryApi = options.discoveryApi;
}
async getEntityAncestors(
request: CatalogEntityAncestorsRequest,
options?: CatalogRequestOptions,
): Promise<CatalogEntityAncestorsResponse> {
const { kind, namespace, name } = Object.fromEntries(
Object.entries(request.entityName).map(([k, v]) => [
k,
encodeURIComponent(v),
]),
);
return await this.requestRequired(
'GET',
`/entity/by-name/${kind}/${namespace}/${name}/ancestry`,
options,
);
}
async getLocationById(
id: string,
options?: CatalogRequestOptions,
+15
View File
@@ -28,6 +28,17 @@ export type CatalogEntitiesRequest = {
fields?: string[] | undefined;
};
/** @public */
export type CatalogEntityAncestorsRequest = {
entityName: EntityName;
};
/** @public */
export type CatalogEntityAncestorsResponse = {
root: EntityName;
items: { entity: Entity; parents: EntityName[] }[];
};
/** @public */
export type CatalogListResponse<T> = {
items: T[];
@@ -45,6 +56,10 @@ export interface CatalogApi {
request?: CatalogEntitiesRequest,
options?: CatalogRequestOptions,
): Promise<CatalogListResponse<Entity>>;
getEntityAncestors(
request: CatalogEntityAncestorsRequest,
options?: CatalogRequestOptions,
): Promise<CatalogEntityAncestorsResponse>;
getEntityByName(
name: EntityName,
options?: CatalogRequestOptions,
@@ -14,20 +14,30 @@
* limitations under the License.
*/
import { Entity, UNSTABLE_EntityStatusItem } from '@backstage/catalog-model';
import { useEntity } from '@backstage/plugin-catalog-react';
import {
Entity,
getEntityName,
UNSTABLE_EntityStatusItem,
} from '@backstage/catalog-model';
import { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';
import { Box } from '@material-ui/core';
import React from 'react';
import { ResponseErrorPanel } from '@backstage/core-components';
import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client';
import { useApi } from '@backstage/core-plugin-api';
import { useAsync } from 'react-use';
const errorfilter = (i: UNSTABLE_EntityStatusItem) =>
const errorFilter = (i: UNSTABLE_EntityStatusItem) =>
i.error &&
i.level === 'error' &&
i.type === ENTITY_STATUS_CATALOG_PROCESSING_TYPE;
export const hasCatalogProcessingErrors = (entity: Entity) =>
entity?.status?.items?.filter(errorfilter).length! > 0;
export const hasCatalogProcessingErrors = async (entity: Entity) => {
return entity?.status?.items?.filter(errorFilter).length! > 0;
const catalogApi = useApi(catalogApiRef);
const { status } = await catalogApi.getEntityStatus(entity.id);
return status.some(errorFilter);
};
/**
* Displays a list of errors if the entity is invalid.
@@ -36,16 +46,55 @@ export const EntityProcessingErrorsPanel = () => {
const { entity } = useEntity();
const catalogProcessingErrors =
(entity?.status?.items?.filter(
errorfilter,
errorFilter,
) as Required<UNSTABLE_EntityStatusItem>[]) || [];
return (
<>
{catalogProcessingErrors.map(({ error }, index) => (
<Box key={index} mb={1}>
<ResponseErrorPanel error={error} />
</Box>
))}
</>
);
return catalogProcessingErrors.map(({ error }, index) => (
<Box key={index} mb={1}>
<ResponseErrorPanel error={error} />
</Box>
));
};
/**
* Displays a list of errors from the ancestors of the current entity.
*/
export const EntityAncestorsProcessingErrorsPanel = () => {
const { entity } = useEntity();
const catalogApi = useApi(catalogApiRef);
const { loading, value, error } = useAsync(() =>
catalogApi.getEntityAncestors({ entityName: getEntityName(entity) }),
);
if (loading) {
return null;
}
if (error) {
return (
<Box mb={1}>
<ResponseErrorPanel error={error} />
</Box>
);
}
const ancestorErrors =
value?.items.flatMap(({ entity: ancestor }) =>
ancestor?.status?.items?.filter?.(errorFilter),
) ?? [];
if (ancestorErrors.length === 0) {
return null;
}
const filteredAncestors = ancestorErrors.filter(
(e): e is UNSTABLE_EntityStatusItem => Boolean(e),
);
return filteredAncestors.map(({ error: ancestorError }, index) => (
<Box key={index} mb={1}>
<ResponseErrorPanel error={ancestorError!} />
</Box>
));
};
@@ -32,7 +32,7 @@ const EntitySwitchCase = (_: {
attachComponentData(EntitySwitchCase, ENTITY_SWITCH_KEY, true);
type SwitchCase = {
if?: (entity: Entity) => boolean;
if?: (entity: Entity) => boolean | Promise<boolean>;
children: JSX.Element;
};