-
Notifications
You must be signed in to change notification settings - Fork 465
Allow to override project list #3850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: allow-to-override-project-list
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,15 @@ export interface ProjectDefinition { | |||||||||||||||||||||||||||||
| clusters: string[]; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export type ProjectListProcessorFunction = ( | ||||||||||||||||||||||||||||||
| currentProjects: ProjectDefinition[] | ||||||||||||||||||||||||||||||
| ) => ProjectDefinition[]; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export interface ProjectListProcessor { | ||||||||||||||||||||||||||||||
| id?: string; | ||||||||||||||||||||||||||||||
| processor: ProjectListProcessorFunction; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** Define custom way to create new Projects */ | ||||||||||||||||||||||||||||||
| export interface CustomCreateProject { | ||||||||||||||||||||||||||||||
| id: string; | ||||||||||||||||||||||||||||||
|
|
@@ -49,22 +58,45 @@ export interface ProjectOverviewSection { | |||||||||||||||||||||||||||||
| export interface ProjectDetailsTab { | ||||||||||||||||||||||||||||||
| id: string; | ||||||||||||||||||||||||||||||
| label: string; | ||||||||||||||||||||||||||||||
| icon: string | ReactNode; | ||||||||||||||||||||||||||||||
| icon?: string | ReactNode; | ||||||||||||||||||||||||||||||
| component: (props: { project: ProjectDefinition; projectResources: KubeObject[] }) => ReactNode; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export interface ProjectsState { | ||||||||||||||||||||||||||||||
| customCreateProject: Record<string, CustomCreateProject>; | ||||||||||||||||||||||||||||||
| overviewSections: Record<string, ProjectOverviewSection>; | ||||||||||||||||||||||||||||||
| detailsTabs: Record<string, ProjectDetailsTab>; | ||||||||||||||||||||||||||||||
| projectListProcessors: ProjectListProcessor[]; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const initialState: ProjectsState = { | ||||||||||||||||||||||||||||||
| customCreateProject: {}, | ||||||||||||||||||||||||||||||
| detailsTabs: {}, | ||||||||||||||||||||||||||||||
| overviewSections: {}, | ||||||||||||||||||||||||||||||
| projectListProcessors: [], | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * Normalizes a project list processor by ensuring it has an 'id' and a processor function. | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| function _normalizeProjectListProcessor( | ||||||||||||||||||||||||||||||
| action: PayloadAction<ProjectListProcessor | ProjectListProcessorFunction> | ||||||||||||||||||||||||||||||
| ): ProjectListProcessor { | ||||||||||||||||||||||||||||||
| let processor: ProjectListProcessor = action.payload as ProjectListProcessor; | ||||||||||||||||||||||||||||||
| if (typeof action.payload === 'function') { | ||||||||||||||||||||||||||||||
| processor = { | ||||||||||||||||||||||||||||||
| id: `generated-id-${Date.now().toString(36)}`, | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| processor: action.payload, | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (!processor.id) { | ||||||||||||||||||||||||||||||
| processor.id = `generated-id-${Date.now().toString(36)}`; | ||||||||||||||||||||||||||||||
|
Comment on lines
+88
to
+94
|
||||||||||||||||||||||||||||||
| id: `generated-id-${Date.now().toString(36)}`, | |
| processor: action.payload, | |
| }; | |
| } | |
| if (!processor.id) { | |
| processor.id = `generated-id-${Date.now().toString(36)}`; | |
| id: `generated-id-${crypto.randomUUID()}`, | |
| processor: action.payload, | |
| }; | |
| } | |
| if (!processor.id) { | |
| processor.id = `generated-id-${crypto.randomUUID()}`; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,54 @@ | ||
| # 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 | ||
| 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug console.log statement should be removed from production code.