@alexandreamormino/plugin-entity-manager
v1.0.4
Published
Frontend plugin for managing Backstage catalog entities through a Monaco YAML editor
Maintainers
Readme
Entity Manager Frontend Plugin
Frontend plugin for creating and editing Backstage catalog entities through a YAML editor.
Installation
cd packages/app
yarn add @alexandreamormino/plugin-entity-managerReplace the Catalog Import Page
Entity Manager can replace Backstage's default catalog import page while preserving the existing /catalog-import route and permission behavior.
Replace the default route:
<Route
path="/catalog-import"
element={
<RequirePermission permission={catalogEntityCreatePermission}>
<CatalogImportPage />
</RequirePermission>
}
/>With:
<Route
path="/catalog-import"
element={
<RequirePermission permission={catalogEntityCreatePermission}>
<EntityManagerCreatePage />
</RequirePermission>
}
/>After this change, users who access /catalog-import will see the Entity Manager creation page instead of the default Backstage catalog import page.
Remove the
CatalogImportPageimport fromApp.tsxwhen it is no longer used anywhere else in the application.
Configure Catalog External Routes
Locate the catalog external routes binding in packages/app/src/App.tsx:
bind(catalogPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
viewTechDoc: techdocsPlugin.routes.docRoot,
createFromTemplate: scaffolderPlugin.routes.selectedTemplate,
});Replace it with:
bind(catalogPlugin.externalRoutes, {
createComponent: entityManagerPlugin.routes.root,
viewTechDoc: techdocsPlugin.routes.docRoot,
createFromTemplate: scaffolderPlugin.routes.selectedTemplate,
});This redirects catalog actions that create entities from templates to the Entity Manager plugin.
Register the Entity Manager API
In packages/app/src/apis.ts, import the Entity Manager API factory:
import { entityManagerApiFactory } from '@alexandreamormino/plugin-entity-manager';Add entityManagerApiFactory to the apis array:
export const apis: AnyApiFactory[] = [
entityManagerApiFactory,
createApiFactory({
api: scmIntegrationsApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
}),
ScmAuth.createDefaultApiFactory(),
];This registers the Entity Manager API factory in the Backstage frontend application.
Replace Catalog Entity Components
In packages/app/src/components/catalog/EntityPage.tsx, replace the default Backstage components with the Entity Manager equivalents.
Add the imports:
import {
EntityManagerAboutCard,
EntityManagerLayout,
} from '@alexandreamormino/plugin-entity-manager';Replace:
<EntityAboutCard />With:
<EntityManagerAboutCard />Replace:
<EntityLayout>
{/* Entity page content */}
</EntityLayout>With:
<EntityManagerLayout>
{/* Entity page content */}
</EntityManagerLayout>EntityManagerAboutCard is a drop-in replacement for EntityAboutCard.
- Adds Edit and Delete actions for entities managed by Entity Manager
- Renders the default Backstage entity card for all other entities
EntityManagerLayout is a drop-in replacement for EntityLayout.
- Hides the Unregister entity option for entities managed by Entity Manager
- Preserves the default layout behavior for all other entities
Custom button integration
If you want to build your own card or toolbar, you can use the buttons directly. They are re-exported from entity-manager-react so a separate install is not required.
import {
EditEntityButton,
DeleteEntityButton,
isEntityManagerManaged,
} from '@alexandreamormino/plugin-entity-manager';
import { usePermission } from '@backstage/plugin-permission-react';
import {
entityManagerUpdatePermission,
entityManagerDeletePermission,
} from '@alexandreamormino/plugin-entity-manager-common';
const { allowed: canEdit } = usePermission({ permission: entityManagerUpdatePermission });
const { allowed: canDelete } = usePermission({ permission: entityManagerDeletePermission });
<EditEntityButton
entityKind={entity.kind}
entityName={entity.metadata.name}
onLoadEntity={async () => {
const { entity: loaded } = await api.getEntity(entity.kind, entity.metadata.name);
return loaded;
}}
onSave={async (updated) => {
await api.updateEntity(entity.kind, entity.metadata.name, updated);
}}
disabled={!canEdit}
asIconButton
/>
<DeleteEntityButton
entityKind={entity.kind}
entityName={entity.metadata.name}
onDelete={async () => {
await api.deleteEntity(entity.kind, entity.metadata.name);
}}
disabled={!canDelete}
asIconButton
/>isEntityManagerManaged(entity) returns true when the entity's backstage.io/managed-by-location annotation starts with entity-manager-provider:.
Development
yarn workspace @alexandreamormino/plugin-entity-manager start
yarn workspace @alexandreamormino/plugin-entity-manager test
yarn workspace @alexandreamormino/plugin-entity-manager lint