+ ) {
+ state.projectListProcessors.push(_normalizeProjectListProcessor(action));
+ },
},
});
-export const { addCustomCreateProject, addDetailsTab, addOverviewSection } = projectsSlice.actions;
+export const {
+ addCustomCreateProject,
+ addDetailsTab,
+ addOverviewSection,
+ addProjectListProcessor,
+} = projectsSlice.actions;
export default projectsSlice.reducer;
diff --git a/plugins/examples/projects/README.md b/plugins/examples/projects/README.md
index 376e399085d..9e51d1411a8 100644
--- a/plugins/examples/projects/README.md
+++ b/plugins/examples/projects/README.md
@@ -1,6 +1,11 @@
# Projects customization example
-This plugin demonstrates how to customize projects feature
+This plugin demonstrates how to customize projects feature including:
+
+- Custom project creation workflows
+- Custom project details tabs
+- Custom project overview sections
+- Custom project list processors (extend or modify project discovery)
```bash
cd plugins/examples/projects
@@ -8,3 +13,42 @@ npm start
```
The main code for the example plugin is in [src/index.tsx](src/index.tsx).
+
+## Project List Processors
+
+The `registerProjectListProcessor` function allows plugins to extend or modify how projects are discovered and listed. Processors receive the current list of projects (from namespaces or previous processors) and can:
+
+- Add new projects from Custom Resources, external APIs, or other sources
+- Filter existing projects based on conditions
+- Modify project properties like namespaces or clusters
+- Completely replace the project list if needed
+
+### Key Features
+
+- **Additive by default**: Processors receive existing projects and can extend the list
+- **Chainable**: Multiple processors can be registered and will run in sequence
+- **Error handling**: Failed processors don't break the application
+- **Duplicate prevention**: Easy to check for existing projects by ID
+
+### Example Usage
+
+```typescript
+// Add new projects while keeping existing ones
+registerProjectListProcessor((currentProjects) => {
+ const newProjects = [
+ {
+ id: 'my-custom-project',
+ namespaces: ['default', 'kube-system'],
+ clusters: ['cluster1']
+ }
+ ];
+
+ // Only add projects that don't already exist
+ const existingIds = currentProjects.map(p => p.id);
+ const projectsToAdd = newProjects.filter(p => !existingIds.includes(p.id));
+
+ return [...currentProjects, ...projectsToAdd];
+});
+```
+
+This approach ensures backward compatibility while providing maximum flexibility for project customization.
diff --git a/plugins/examples/projects/src/index.tsx b/plugins/examples/projects/src/index.tsx
index 5bc940b2cc9..b2d56e9854c 100644
--- a/plugins/examples/projects/src/index.tsx
+++ b/plugins/examples/projects/src/index.tsx
@@ -18,6 +18,7 @@ import {
ApiProxy,
registerCustomCreateProject,
registerProjectDetailsTab,
+ registerProjectListProcessor,
registerProjectOverviewSection,
} from '@kinvolk/headlamp-plugin/lib';
@@ -55,10 +56,34 @@ registerCustomCreateProject({
registerProjectDetailsTab({
id: 'my-tab',
label: 'Metrics',
- component: ({ project }) => Metrics for project {project.name}
,
+ icon: 'mdi:chart-line',
+ component: ({ project }) => Metrics for project {project.id}
,
});
registerProjectOverviewSection({
id: 'resource-usage',
- component: ({ project }) => Custom resource usage for project {project.name}
,
+ component: ({ project }) => Custom resource usage for project {project.id}
,
+});
+
+// Example 1: Extend the project list with additional projects
+// This keeps the existing namespace-based projects and adds new ones
+registerProjectListProcessor((currentProjects) => {
+ const newProjects = [
+ {
+ id: 'example-project-1',
+ namespaces: ['default', 'kube-system'],
+ clusters: ['cluster1']
+ },
+ {
+ id: 'example-project-2',
+ namespaces: ['example-ns'],
+ clusters: ['cluster1', 'cluster2']
+ }
+ ];
+
+ // Only add projects that don't already exist
+ const existingIds = currentProjects.map(p => p.id);
+ const projectsToAdd = newProjects.filter(p => !existingIds.includes(p.id));
+
+ return [...currentProjects, ...projectsToAdd];
});
diff --git a/plugins/headlamp-plugin/src/index.ts b/plugins/headlamp-plugin/src/index.ts
index aa865497936..5b039c5579e 100644
--- a/plugins/headlamp-plugin/src/index.ts
+++ b/plugins/headlamp-plugin/src/index.ts
@@ -38,6 +38,8 @@ import Registry, {
DetailsViewSectionProps,
getHeadlampAPIHeaders,
PluginManager,
+ ProjectListProcessor,
+ ProjectListProcessorFunction,
registerAddClusterProvider,
registerAppBarAction,
registerAppLogo,
@@ -55,6 +57,7 @@ import Registry, {
registerMapSource,
registerPluginSettings,
registerProjectDetailsTab,
+ registerProjectListProcessor,
registerProjectOverviewSection,
registerResourceTableColumnsProcessor,
registerRoute,
@@ -101,6 +104,7 @@ export {
registerKindIcon,
registerMapSource,
PluginManager,
+ registerProjectListProcessor,
registerUIPanel,
registerAppTheme,
registerKubeObjectGlance,
@@ -115,4 +119,6 @@ export type {
ClusterChooserProps,
DetailsViewSectionProps,
DefaultSidebars,
+ ProjectListProcessor,
+ ProjectListProcessorFunction,
};