Compare commits

...

1 Commits

Author SHA1 Message Date
Chris Farhood 95af329523 chore: release v0.2.1
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-19 13:31:07 -05:00
4 changed files with 53 additions and 8 deletions
+12 -1
View File
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.2.1] - 2026-02-19
### Fixed
- **Duplicate columns** — Protocol and Pool columns on mixed-driver clusters (rook-ceph + tns-csi) are now merged into a single shared column rather than duplicated; whichever plugin loads first owns the column and the second merges into it
### Changed
- **Sidebar label** — top-level navigation entry renamed from `Rook-Ceph` to `Rook`
## [0.2.0] - 2026-02-19 ## [0.2.0] - 2026-02-19
### Changed ### Changed
@@ -56,7 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- TypeScript strict mode with zero `any` types - TypeScript strict mode with zero `any` types
- ESLint + Prettier code quality tooling - ESLint + Prettier code quality tooling
[Unreleased]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.2.0...HEAD [Unreleased]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.2.1...HEAD
[0.2.1]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.3...v0.2.0 [0.2.0]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.3...v0.2.0
[0.1.3]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.2...v0.1.3 [0.1.3]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.1...v0.1.2 [0.1.2]: https://github.com/cpfarhood/headlamp-rook-plugin/compare/v0.1.1...v0.1.2
+9 -3
View File
@@ -1,4 +1,4 @@
version: "0.1.3" version: "0.2.1"
name: headlamp-rook-plugin name: headlamp-rook-plugin
displayName: Rook Plugin displayName: Rook Plugin
createdAt: "2026-02-18T00:00:00Z" createdAt: "2026-02-18T00:00:00Z"
@@ -22,8 +22,14 @@ maintainers:
email: privilegedescalation@users.noreply.github.com email: privilegedescalation@users.noreply.github.com
provider: provider:
name: privilegedescalation name: privilegedescalation
changes:
- kind: fixed
description: "Duplicate Protocol/Pool columns on mixed-driver clusters now merged into a single shared column"
- kind: changed
description: "Sidebar navigation label renamed from Rook-Ceph to Rook"
annotations: annotations:
headlamp/plugin/archive-url: "https://github.com/privilegedescalation/headlamp-rook-plugin/releases/download/v0.1.3/headlamp-rook-plugin-0.1.3.tar.gz" headlamp/plugin/archive-url: "https://github.com/privilegedescalation/headlamp-rook-plugin/releases/download/v0.2.1/headlamp-rook-plugin-0.2.1.tar.gz"
headlamp/plugin/archive-checksum: "sha256:01611912597b4739ca62cd1f4ae0dd42755bb8e3541dafa5dedbfdcf1202072e" headlamp/plugin/archive-checksum: "sha256:6cfe751bc06cf77cf1b96013fdb83d4e1db9ac3793e9aca82316546debd3e846"
headlamp/plugin/distro-compat: "" headlamp/plugin/distro-compat: ""
headlamp/plugin/version-compat: ">=0.20" headlamp/plugin/version-compat: ">=0.20"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "headlamp-rook-plugin", "name": "headlamp-rook-plugin",
"version": "0.1.3", "version": "0.2.1",
"description": "Headlamp plugin for Rook-Ceph cluster visibility and CSI driver monitoring", "description": "Headlamp plugin for Rook-Ceph cluster visibility and CSI driver monitoring",
"repository": { "repository": {
"type": "git", "type": "git",
+31 -3
View File
@@ -32,7 +32,7 @@ import VolumesPage from './components/VolumesPage';
registerSidebarEntry({ registerSidebarEntry({
parent: null, parent: null,
name: 'rook-ceph', name: 'rook-ceph',
label: 'Rook-Ceph', label: 'Rook',
url: '/rook-ceph', url: '/rook-ceph',
icon: 'mdi:database-cog', icon: 'mdi:database-cog',
}); });
@@ -202,12 +202,40 @@ registerDetailsViewSection(({ resource }) => {
// Table column processors — native StorageClass and PV tables // Table column processors — native StorageClass and PV tables
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Merges incoming columns into existing ones by label.
// If a column with the same label already exists, the incoming getValue/render
// takes priority and falls back to the existing one (for mixed-driver tables).
function mergeColumns<T>(
existing: T[],
incoming: Array<{ label: string; getValue: (r: unknown) => unknown; render: (r: unknown) => React.ReactNode }>
): T[] {
type ObjCol = { label: string; getValue: (r: unknown) => unknown; render: (r: unknown) => React.ReactNode };
const isObjCol = (c: unknown): c is ObjCol =>
typeof c === 'object' && c !== null && 'label' in c;
const result = [...existing];
const toAppend: typeof incoming = [];
for (const col of incoming) {
const idx = result.findIndex(c => isObjCol(c) && (c as ObjCol).label === col.label);
if (idx !== -1) {
const prev = result[idx] as ObjCol;
result[idx] = {
label: col.label,
getValue: (r: unknown) => col.getValue(r) ?? prev.getValue(r),
render: (r: unknown) => col.getValue(r) !== null ? col.render(r) : prev.render(r),
} as unknown as T;
} else {
toAppend.push(col);
}
}
return [...result, ...(toAppend as unknown as T[])];
}
registerResourceTableColumnsProcessor(({ id, columns }) => { registerResourceTableColumnsProcessor(({ id, columns }) => {
if (id === 'headlamp-storageclasses') { if (id === 'headlamp-storageclasses') {
return [...columns, ...buildStorageClassColumns()]; return mergeColumns(columns, buildStorageClassColumns());
} }
if (id === 'headlamp-persistentvolumes') { if (id === 'headlamp-persistentvolumes') {
return [...columns, ...buildPVColumns()]; return mergeColumns(columns, buildPVColumns());
} }
return columns; return columns;
}); });