Merge pull request #8252 from brexhq/jrusso/add-template-swimlanes

Add swimlanes to scaffolder page
This commit is contained in:
Tim Hansen
2021-11-28 20:31:43 -07:00
committed by GitHub
8 changed files with 152 additions and 20 deletions
+16 -1
View File
@@ -24,6 +24,7 @@ import { JSONSchema } from '@backstage/catalog-model';
import { JsonValue } from '@backstage/types';
import { Observable } from '@backstage/types';
import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { TemplateEntityV1beta2 } from '@backstage/catalog-model';
@@ -213,12 +214,20 @@ export const ScaffolderFieldExtensions: React_2.ComponentType;
// @public (undocumented)
export const ScaffolderPage: ({
TemplateCardComponent,
groups,
}: {
TemplateCardComponent?:
| ComponentType<{
template: TemplateEntityV1beta2;
}>
| undefined;
groups?:
| {
title?: string | undefined;
titleComponent?: ReactNode;
filter: (entity: Entity) => boolean;
}[]
| undefined;
}) => JSX.Element;
// Warning: (ae-missing-release-tag) "scaffolderPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -240,7 +249,8 @@ export { scaffolderPlugin };
// @public (undocumented)
export const TemplateList: ({
TemplateCardComponent,
}: TemplateListProps) => JSX.Element;
group,
}: TemplateListProps) => JSX.Element | null;
// Warning: (ae-missing-release-tag) "TemplateListProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -251,6 +261,11 @@ export type TemplateListProps = {
template: TemplateEntityV1beta2;
}>
| undefined;
group?: {
title?: string;
titleComponent?: React_2.ReactNode;
filter: (entity: Entity) => boolean;
};
};
// Warning: (ae-missing-release-tag) "TemplateTypePicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+11 -3
View File
@@ -16,7 +16,7 @@
import React, { ComponentType } from 'react';
import { Routes, Route, useOutlet } from 'react-router';
import { TemplateEntityV1beta2 } from '@backstage/catalog-model';
import { TemplateEntityV1beta2, Entity } from '@backstage/catalog-model';
import { ScaffolderPage } from './ScaffolderPage';
import { TemplatePage } from './TemplatePage';
import { TaskPage } from './TaskPage';
@@ -34,9 +34,14 @@ type RouterProps = {
TemplateCardComponent?:
| ComponentType<{ template: TemplateEntityV1beta2 }>
| undefined;
groups?: Array<{
title?: string;
titleComponent?: React.ReactNode;
filter: (entity: Entity) => boolean;
}>;
};
export const Router = ({ TemplateCardComponent }: RouterProps) => {
export const Router = ({ TemplateCardComponent, groups }: RouterProps) => {
const outlet = useOutlet();
const customFieldExtensions = useElementFilter(outlet, elements =>
@@ -64,7 +69,10 @@ export const Router = ({ TemplateCardComponent }: RouterProps) => {
<Route
path="/"
element={
<ScaffolderPage TemplateCardComponent={TemplateCardComponent} />
<ScaffolderPage
TemplateCardComponent={TemplateCardComponent}
groups={groups}
/>
}
/>
<Route
@@ -23,7 +23,7 @@ import {
Page,
SupportButton,
} from '@backstage/core-components';
import { TemplateEntityV1beta2 } from '@backstage/catalog-model';
import { TemplateEntityV1beta2, Entity } from '@backstage/catalog-model';
import { useRouteRef } from '@backstage/core-plugin-api';
import {
EntityKindPicker,
@@ -51,14 +51,26 @@ export type ScaffolderPageProps = {
TemplateCardComponent?:
| ComponentType<{ template: TemplateEntityV1beta2 }>
| undefined;
groups?: Array<{
title?: string;
titleComponent?: React.ReactNode;
filter: (entity: Entity) => boolean;
}>;
};
export const ScaffolderPageContents = ({
TemplateCardComponent,
groups,
}: ScaffolderPageProps) => {
const styles = useStyles();
const registerComponentLink = useRouteRef(registerComponentRouteRef);
const otherTemplatesGroup = {
title: groups ? 'Other Templates' : 'Templates',
filter: (entity: Entity) => {
const filtered = (groups ?? []).map(group => group.filter(entity));
return !filtered.some(result => result === true);
},
};
return (
<Page themeId="home">
@@ -96,7 +108,17 @@ export const ScaffolderPageContents = ({
<EntityTagPicker />
</div>
<div>
<TemplateList TemplateCardComponent={TemplateCardComponent} />
{groups &&
groups.map(group => (
<TemplateList
TemplateCardComponent={TemplateCardComponent}
group={group}
/>
))}
<TemplateList
TemplateCardComponent={TemplateCardComponent}
group={otherTemplatesGroup}
/>
</div>
</div>
</Content>
@@ -106,8 +128,12 @@ export const ScaffolderPageContents = ({
export const ScaffolderPage = ({
TemplateCardComponent,
groups,
}: ScaffolderPageProps) => (
<EntityListProvider>
<ScaffolderPageContents TemplateCardComponent={TemplateCardComponent} />
<ScaffolderPageContents
TemplateCardComponent={TemplateCardComponent}
groups={groups}
/>
</EntityListProvider>
);
@@ -16,10 +16,13 @@
import React, { ComponentType } from 'react';
import {
Entity,
stringifyEntityRef,
TemplateEntityV1beta2,
} from '@backstage/catalog-model';
import {
Content,
ContentHeader,
ItemCardGrid,
Progress,
WarningPanel,
@@ -32,11 +35,31 @@ export type TemplateListProps = {
TemplateCardComponent?:
| ComponentType<{ template: TemplateEntityV1beta2 }>
| undefined;
group?: {
title?: string;
titleComponent?: React.ReactNode;
filter: (entity: Entity) => boolean;
};
};
export const TemplateList = ({ TemplateCardComponent }: TemplateListProps) => {
export const TemplateList = ({
TemplateCardComponent,
group,
}: TemplateListProps) => {
const { loading, error, entities } = useEntityListProvider();
const Card = TemplateCardComponent || TemplateCard;
const maybeFilteredEntities = group
? entities.filter(e => group.filter(e))
: entities;
const title = group ? (
group.titleComponent || <ContentHeader title={group.title} />
) : (
<ContentHeader title="Other Templates" />
);
if (group && maybeFilteredEntities.length === 0) {
return null;
}
return (
<>
{loading && <Progress />}
@@ -57,16 +80,19 @@ export const TemplateList = ({ TemplateCardComponent }: TemplateListProps) => {
</Typography>
)}
<ItemCardGrid>
{entities &&
entities?.length > 0 &&
entities.map(template => (
<Card
key={stringifyEntityRef(template)}
template={template as TemplateEntityV1beta2}
/>
))}
</ItemCardGrid>
<Content>
{title}
<ItemCardGrid>
{maybeFilteredEntities &&
maybeFilteredEntities?.length > 0 &&
maybeFilteredEntities.map((template: Entity) => (
<Card
key={stringifyEntityRef(template)}
template={template as TemplateEntityV1beta2}
/>
))}
</ItemCardGrid>
</Content>
</>
);
};