@@ -21,7 +21,10 @@ import {
|
||||
storageApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
import { createApiExtension } from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
ApiBlueprint,
|
||||
createApiExtension,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
catalogApiRef,
|
||||
entityPresentationApiRef,
|
||||
@@ -32,33 +35,42 @@ import {
|
||||
DefaultStarredEntitiesApi,
|
||||
} from '../apis';
|
||||
|
||||
export const catalogApi = createApiExtension({
|
||||
factory: createApiFactory({
|
||||
api: catalogApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
fetchApi: fetchApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, fetchApi }) =>
|
||||
new CatalogClient({ discoveryApi, fetchApi }),
|
||||
}),
|
||||
export const catalogApi = ApiBlueprint.make({
|
||||
params: {
|
||||
factory: createApiFactory({
|
||||
api: catalogApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
fetchApi: fetchApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, fetchApi }) =>
|
||||
new CatalogClient({ discoveryApi, fetchApi }),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const catalogStarredEntitiesApi = createApiExtension({
|
||||
factory: createApiFactory({
|
||||
api: starredEntitiesApiRef,
|
||||
deps: { storageApi: storageApiRef },
|
||||
factory: ({ storageApi }) => new DefaultStarredEntitiesApi({ storageApi }),
|
||||
}),
|
||||
export const catalogStarredEntitiesApi = ApiBlueprint.make({
|
||||
name: 'starred-entities',
|
||||
params: {
|
||||
factory: createApiFactory({
|
||||
api: starredEntitiesApiRef,
|
||||
deps: { storageApi: storageApiRef },
|
||||
factory: ({ storageApi }) =>
|
||||
new DefaultStarredEntitiesApi({ storageApi }),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const entityPresentationApi = createApiExtension({
|
||||
factory: createApiFactory({
|
||||
api: entityPresentationApiRef,
|
||||
deps: { catalogApiImp: catalogApiRef },
|
||||
factory: ({ catalogApiImp }) =>
|
||||
DefaultEntityPresentationApi.create({ catalogApi: catalogApiImp }),
|
||||
}),
|
||||
export const entityPresentationApi = ApiBlueprint.make({
|
||||
name: 'entity-presentation',
|
||||
params: {
|
||||
factory: createApiFactory({
|
||||
api: entityPresentationApiRef,
|
||||
deps: { catalogApiImp: catalogApiRef },
|
||||
factory: ({ catalogApiImp }) =>
|
||||
DefaultEntityPresentationApi.create({ catalogApi: catalogApiImp }),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export default [catalogApi, catalogStarredEntitiesApi, entityPresentationApi];
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { EntityMatcherFn } from './matrchers/types';
|
||||
import { createKindMatcher } from './matrchers/createKindMatcher';
|
||||
import { createTypeMatcher } from './matrchers/createTypeMatcher';
|
||||
import { createIsMatcher } from './matrchers/createIsMatcher';
|
||||
import { createHasMatcher } from './matrchers/createHasMatcher';
|
||||
import { EntityMatcherFn } from './matchers/types';
|
||||
import { createKindMatcher } from './matchers/createKindMatcher';
|
||||
import { createTypeMatcher } from './matchers/createTypeMatcher';
|
||||
import { createIsMatcher } from './matchers/createIsMatcher';
|
||||
import { createHasMatcher } from './matchers/createHasMatcher';
|
||||
|
||||
const rootMatcherFactories: Record<
|
||||
string,
|
||||
|
||||
@@ -15,97 +15,123 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { createCatalogFilterExtension } from './createCatalogFilterExtension';
|
||||
import { createSchemaFromZod } from '@backstage/frontend-plugin-api';
|
||||
import { CatalogFilterBlueprint } from './blueprints';
|
||||
|
||||
const catalogTagCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogTagCatalogFilter = CatalogFilterBlueprint.make({
|
||||
name: 'tag',
|
||||
loader: async () => {
|
||||
const { EntityTagPicker } = await import('@backstage/plugin-catalog-react');
|
||||
return <EntityTagPicker />;
|
||||
params: {
|
||||
loader: async () => {
|
||||
const { EntityTagPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityTagPicker />;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const catalogKindCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogKindCatalogFilter = CatalogFilterBlueprint.makeWithOverrides({
|
||||
name: 'kind',
|
||||
configSchema: createSchemaFromZod(z =>
|
||||
z.object({
|
||||
initialFilter: z.string().default('component'),
|
||||
}),
|
||||
),
|
||||
loader: async ({ config }) => {
|
||||
const { EntityKindPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityKindPicker initialFilter={config.initialFilter} />;
|
||||
config: {
|
||||
schema: {
|
||||
initialFilter: z => z.string().default('component'),
|
||||
},
|
||||
},
|
||||
factory(originalFactory, { config }) {
|
||||
return originalFactory({
|
||||
loader: async () => {
|
||||
const { EntityKindPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityKindPicker initialFilter={config.initialFilter} />;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const catalogTypeCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogTypeCatalogFilter = CatalogFilterBlueprint.make({
|
||||
name: 'type',
|
||||
loader: async () => {
|
||||
const { EntityTypePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityTypePicker />;
|
||||
params: {
|
||||
loader: async () => {
|
||||
const { EntityTypePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityTypePicker />;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const catalogModeCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogModeCatalogFilter = CatalogFilterBlueprint.makeWithOverrides({
|
||||
name: 'mode',
|
||||
configSchema: createSchemaFromZod(z =>
|
||||
z.object({
|
||||
mode: z.enum(['owners-only', 'all']).optional(),
|
||||
}),
|
||||
),
|
||||
loader: async ({ config }) => {
|
||||
const { EntityOwnerPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityOwnerPicker mode={config.mode} />;
|
||||
config: {
|
||||
schema: {
|
||||
mode: z => z.enum(['owners-only', 'all']).optional(),
|
||||
},
|
||||
},
|
||||
factory(originalFactory, { config }) {
|
||||
return originalFactory({
|
||||
loader: async () => {
|
||||
const { EntityOwnerPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityOwnerPicker mode={config.mode} />;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const catalogNamespaceCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogNamespaceCatalogFilter = CatalogFilterBlueprint.make({
|
||||
name: 'namespace',
|
||||
loader: async () => {
|
||||
const { EntityNamespacePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityNamespacePicker />;
|
||||
params: {
|
||||
loader: async () => {
|
||||
const { EntityNamespacePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityNamespacePicker />;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const catalogLifecycleCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogLifecycleCatalogFilter = CatalogFilterBlueprint.make({
|
||||
name: 'lifecycle',
|
||||
loader: async () => {
|
||||
const { EntityLifecyclePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityLifecyclePicker />;
|
||||
params: {
|
||||
loader: async () => {
|
||||
const { EntityLifecyclePicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityLifecyclePicker />;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const catalogProcessingStatusCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogProcessingStatusCatalogFilter = CatalogFilterBlueprint.make({
|
||||
name: 'processing-status',
|
||||
loader: async () => {
|
||||
const { EntityProcessingStatusPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityProcessingStatusPicker />;
|
||||
params: {
|
||||
loader: async () => {
|
||||
const { EntityProcessingStatusPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <EntityProcessingStatusPicker />;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const catalogListCatalogFilter = createCatalogFilterExtension({
|
||||
const catalogListCatalogFilter = CatalogFilterBlueprint.makeWithOverrides({
|
||||
name: 'list',
|
||||
configSchema: createSchemaFromZod(z =>
|
||||
z.object({
|
||||
initialFilter: z.enum(['owned', 'starred', 'all']).default('owned'),
|
||||
}),
|
||||
),
|
||||
loader: async ({ config }) => {
|
||||
const { UserListPicker } = await import('@backstage/plugin-catalog-react');
|
||||
return <UserListPicker initialFilter={config.initialFilter} />;
|
||||
config: {
|
||||
schema: {
|
||||
initialFilter: z => z.enum(['owned', 'starred', 'all']).default('owned'),
|
||||
},
|
||||
},
|
||||
factory(originalFactory, { config }) {
|
||||
return originalFactory({
|
||||
loader: async () => {
|
||||
const { UserListPicker } = await import(
|
||||
'@backstage/plugin-catalog-react'
|
||||
);
|
||||
return <UserListPicker initialFilter={config.initialFilter} />;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
|
||||
import HomeIcon from '@material-ui/icons/Home';
|
||||
import { convertLegacyRouteRef } from '@backstage/core-compat-api';
|
||||
import { createNavItemExtension } from '@backstage/frontend-plugin-api';
|
||||
import { NavItemBlueprint } from '@backstage/frontend-plugin-api';
|
||||
import { rootRouteRef } from '../routes';
|
||||
|
||||
export const catalogNavItem = createNavItemExtension({
|
||||
routeRef: convertLegacyRouteRef(rootRouteRef),
|
||||
title: 'Catalog',
|
||||
icon: HomeIcon,
|
||||
export const catalogNavItem = NavItemBlueprint.make({
|
||||
params: {
|
||||
routeRef: convertLegacyRouteRef(rootRouteRef),
|
||||
title: 'Catalog',
|
||||
icon: HomeIcon,
|
||||
},
|
||||
});
|
||||
|
||||
export default [catalogNavItem];
|
||||
|
||||
@@ -20,72 +20,86 @@ import {
|
||||
convertLegacyRouteRef,
|
||||
} from '@backstage/core-compat-api';
|
||||
import {
|
||||
createPageExtension,
|
||||
coreExtensionData,
|
||||
createExtensionInput,
|
||||
PageBlueprint,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
AsyncEntityProvider,
|
||||
entityRouteRef,
|
||||
} from '@backstage/plugin-catalog-react';
|
||||
import { catalogExtensionData } from '@backstage/plugin-catalog-react/alpha';
|
||||
import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
|
||||
import { rootRouteRef } from '../routes';
|
||||
import { useEntityFromUrl } from '../components/CatalogEntityPage/useEntityFromUrl';
|
||||
import { buildFilterFn } from './filter/FilterWrapper';
|
||||
|
||||
export const catalogPage = createPageExtension({
|
||||
defaultPath: '/catalog',
|
||||
routeRef: convertLegacyRouteRef(rootRouteRef),
|
||||
export const catalogPage = PageBlueprint.makeWithOverrides({
|
||||
inputs: {
|
||||
filters: createExtensionInput({
|
||||
element: coreExtensionData.reactElement,
|
||||
}),
|
||||
filters: createExtensionInput([coreExtensionData.reactElement]),
|
||||
},
|
||||
loader: async ({ inputs }) => {
|
||||
const { BaseCatalogPage } = await import('../components/CatalogPage');
|
||||
const filters = inputs.filters.map(filter => filter.output.element);
|
||||
return compatWrapper(<BaseCatalogPage filters={<>{filters}</>} />);
|
||||
factory(originalFactory, { inputs }) {
|
||||
return originalFactory({
|
||||
defaultPath: '/catalog',
|
||||
routeRef: convertLegacyRouteRef(rootRouteRef),
|
||||
loader: async () => {
|
||||
const { BaseCatalogPage } = await import('../components/CatalogPage');
|
||||
const filters = inputs.filters.map(filter =>
|
||||
filter.get(coreExtensionData.reactElement),
|
||||
);
|
||||
return compatWrapper(<BaseCatalogPage filters={<>{filters}</>} />);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const catalogEntityPage = createPageExtension({
|
||||
export const catalogEntityPage = PageBlueprint.makeWithOverrides({
|
||||
name: 'entity',
|
||||
defaultPath: '/catalog/:namespace/:kind/:name',
|
||||
routeRef: convertLegacyRouteRef(entityRouteRef),
|
||||
inputs: {
|
||||
contents: createExtensionInput({
|
||||
element: coreExtensionData.reactElement,
|
||||
path: coreExtensionData.routePath,
|
||||
routeRef: coreExtensionData.routeRef.optional(),
|
||||
title: catalogExtensionData.entityContentTitle,
|
||||
filterFunction: catalogExtensionData.entityFilterFunction.optional(),
|
||||
filterExpression: catalogExtensionData.entityFilterExpression.optional(),
|
||||
}),
|
||||
contents: createExtensionInput([
|
||||
coreExtensionData.reactElement,
|
||||
coreExtensionData.routePath,
|
||||
coreExtensionData.routeRef.optional(),
|
||||
EntityContentBlueprint.dataRefs.title,
|
||||
EntityContentBlueprint.dataRefs.filterFunction.optional(),
|
||||
EntityContentBlueprint.dataRefs.filterExpression.optional(),
|
||||
]),
|
||||
},
|
||||
loader: async ({ inputs }) => {
|
||||
const { EntityLayout } = await import('../components/EntityLayout');
|
||||
const Component = () => {
|
||||
return (
|
||||
<AsyncEntityProvider {...useEntityFromUrl()}>
|
||||
<EntityLayout>
|
||||
{inputs.contents.map(({ output }) => (
|
||||
<EntityLayout.Route
|
||||
key={output.path}
|
||||
path={output.path}
|
||||
title={output.title}
|
||||
if={buildFilterFn(
|
||||
output.filterFunction,
|
||||
output.filterExpression,
|
||||
)}
|
||||
>
|
||||
{output.element}
|
||||
</EntityLayout.Route>
|
||||
))}
|
||||
</EntityLayout>
|
||||
</AsyncEntityProvider>
|
||||
);
|
||||
};
|
||||
return compatWrapper(<Component />);
|
||||
factory(originalFactory, { inputs }) {
|
||||
return originalFactory({
|
||||
defaultPath: '/catalog/:namespace/:kind/:name',
|
||||
routeRef: convertLegacyRouteRef(entityRouteRef),
|
||||
loader: async () => {
|
||||
const { EntityLayout } = await import('../components/EntityLayout');
|
||||
const Component = () => {
|
||||
return (
|
||||
<AsyncEntityProvider {...useEntityFromUrl()}>
|
||||
<EntityLayout>
|
||||
{inputs.contents.map(output => {
|
||||
return (
|
||||
<EntityLayout.Route
|
||||
key={output.get(coreExtensionData.routePath)}
|
||||
path={output.get(coreExtensionData.routePath)}
|
||||
title={output.get(EntityContentBlueprint.dataRefs.title)}
|
||||
if={buildFilterFn(
|
||||
output.get(
|
||||
EntityContentBlueprint.dataRefs.filterFunction,
|
||||
),
|
||||
output.get(
|
||||
EntityContentBlueprint.dataRefs.filterExpression,
|
||||
),
|
||||
)}
|
||||
>
|
||||
{output.get(coreExtensionData.reactElement)}
|
||||
</EntityLayout.Route>
|
||||
);
|
||||
})}
|
||||
</EntityLayout>
|
||||
</AsyncEntityProvider>
|
||||
);
|
||||
};
|
||||
return compatWrapper(<Component />);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -14,14 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha';
|
||||
import { SearchResultListItemBlueprint } from '@backstage/plugin-search-react/alpha';
|
||||
|
||||
export const catalogSearchResultListItem = createSearchResultListItemExtension({
|
||||
predicate: result => result.type === 'software-catalog',
|
||||
component: () =>
|
||||
import('../components/CatalogSearchResultListItem').then(
|
||||
m => m.CatalogSearchResultListItem,
|
||||
),
|
||||
export const catalogSearchResultListItem = SearchResultListItemBlueprint.make({
|
||||
params: {
|
||||
predicate: result => result.type === 'software-catalog',
|
||||
component: () =>
|
||||
import('../components/CatalogSearchResultListItem').then(
|
||||
m => m.CatalogSearchResultListItem,
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
export default [catalogSearchResultListItem];
|
||||
|
||||
Reference in New Issue
Block a user