| undefined;
+ ExtraSwimlanes?: Array<{
+ title: React.ReactNode;
+ filter: (entity: Entity) => boolean;
+ }>;
};
export const ScaffolderPageContents = ({
TemplateCardComponent,
+ ExtraSwimlanes,
}: ScaffolderPageProps) => {
const styles = useStyles();
-
const registerComponentLink = useRouteRef(registerComponentRouteRef);
return (
@@ -96,6 +100,13 @@ export const ScaffolderPageContents = ({
+ {ExtraSwimlanes &&
+ ExtraSwimlanes.map(swimlane => (
+
+ ))}
@@ -106,8 +117,12 @@ export const ScaffolderPageContents = ({
export const ScaffolderPage = ({
TemplateCardComponent,
+ ExtraSwimlanes,
}: ScaffolderPageProps) => (
-
+
);
diff --git a/plugins/scaffolder/src/components/TemplateList/TemplateList.tsx b/plugins/scaffolder/src/components/TemplateList/TemplateList.tsx
index dcf708db10..939fe7f59c 100644
--- a/plugins/scaffolder/src/components/TemplateList/TemplateList.tsx
+++ b/plugins/scaffolder/src/components/TemplateList/TemplateList.tsx
@@ -16,10 +16,13 @@
import React, { ComponentType } from 'react';
import {
+ Entity,
stringifyEntityRef,
TemplateEntityV1beta2,
} from '@backstage/catalog-model';
import {
+ Content,
+ ContentHeader,
ItemCardGrid,
Progress,
WarningPanel,
@@ -32,41 +35,84 @@ export type TemplateListProps = {
TemplateCardComponent?:
| ComponentType<{ template: TemplateEntityV1beta2 }>
| undefined;
+ Swimlane?: {
+ title: React.ReactNode;
+ filter: (entity: Entity) => boolean;
+ };
};
-export const TemplateList = ({ TemplateCardComponent }: TemplateListProps) => {
+type TemplateCardGridProps = {
+ Card: ComponentType<{ template: TemplateEntityV1beta2 }>;
+ entities: Entity[];
+};
+const TemplateCardGrid = ({ Card, entities }: TemplateCardGridProps) => {
+ return (
+
+ {entities &&
+ entities?.length > 0 &&
+ entities.map((template: Entity) => (
+
+ ))}
+
+ );
+};
+
+export const TemplateList = ({
+ TemplateCardComponent,
+ Swimlane,
+}: TemplateListProps) => {
const { loading, error, entities } = useEntityListProvider();
const Card = TemplateCardComponent || TemplateCard;
- return (
- <>
- {loading && }
+ if (Swimlane === null || Swimlane === undefined) {
+ return (
+ <>
+ {loading && }
+ {error && (
+
+ {error.message}
+
+ )}
+
+ {!error && !loading && !entities.length && (
+
+ No templates found that match your filter. Learn more about{' '}
+
+ adding templates
+
+ .
+
+ )}
+
+
+
+
+ >
+ );
+ }
+
+ const filteredEntities = entities.filter((entity: Entity) =>
+ Swimlane.filter(entity),
+ );
+
+ if (filteredEntities.length === 0) {
+ return null;
+ }
+
+ return (
+
+ {Swimlane.title}
+ {loading && }
{error && (
{error.message}
)}
- {!error && !loading && !entities.length && (
-
- No templates found that match your filter. Learn more about{' '}
-
- adding templates
-
- .
-
- )}
-
-
- {entities &&
- entities?.length > 0 &&
- entities.map(template => (
-
- ))}
-
- >
+
+
);
};