@freelensapp/kafka-extension 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/common/kafka-persistent-state-store.ts","../../src/renderer/icon.tsx","../../src/renderer/kafka-acl-availability.ts","../../src/renderer/kafka-overview.scss?inline","../../src/renderer/kafka-page-shell.tsx","../../src/common/aggregate-health-snapshot.ts","../../src/common/constants.ts","../../src/common/reachability.ts","../../src/renderer/kafka-cluster-catalog.ts","../../src/common/kafka-target.ts","../../src/renderer/kafka-manual-endpoints.ts","../../src/renderer/kafka-navigation.ts","../../src/common/kafka-phase-progress.ts","../../src/renderer/kafka-view-model.ts","../../src/renderer/kafka-overview.tsx","../../src/renderer/kafka-snapshot-cache.ts","../../src/renderer/kafka-resource-cache.ts","../../src/renderer/kafka-resource-pages.tsx","../../src/renderer/kafka-write-policy.ts","../../src/renderer/kafka-acl-pages.tsx","../../src/renderer/kafka-connect-pages.tsx","../../src/renderer/kafka-connect-settings.ts","../../src/renderer/kafka-connection-settings.ts","../../src/renderer/kafka-list-window.ts","../../src/renderer/kafka-write-settings.ts","../../src/renderer/kafka-group-pages.tsx","../../src/common/ipc.ts","../../src/renderer/kafka-ipc-deduper.ts","../../src/renderer/kafka-ipc.ts","../../src/renderer/kafka-overview-settings.ts","../../src/renderer/kafka-page-manifest.ts","../../src/renderer/kafka-pages.tsx","../../src/renderer/kafka-reload-route-restorer.tsx","../../src/renderer/kafka-schema-registry-pages.tsx","../../src/renderer/kafka-schema-registry-settings.ts","../../src/renderer/kafka-messages.tsx","../../src/renderer/kafka-topic-pages.tsx","../../src/renderer/index.tsx"],"sourcesContent":["import { Common } from \"@freelensapp/extensions\";\nimport { makeObservable, observable, toJS } from \"mobx\";\n\nexport interface KafkaPersistentStateModel {\n values: Record<string, string>;\n}\n\ninterface LegacyStorage {\n getItem(key: string): string | null;\n}\n\n/** Durable host-managed storage for non-secret Kafka catalog and selection state. */\nexport class KafkaPersistentStateStore extends Common.Store.ExtensionStore<KafkaPersistentStateModel> {\n values: Record<string, string> = {};\n\n constructor() {\n super({\n configName: \"freelens-kafka-state-store\",\n defaults: { values: {} },\n });\n makeObservable(this, { values: observable });\n }\n\n getItem(key: string): string | null {\n return this.values[key] ?? null;\n }\n\n setItem(key: string, value: string): void {\n this.values = { ...this.values, [key]: value };\n }\n\n removeItem(key: string): void {\n if (!(key in this.values)) return;\n const { [key]: _removed, ...remaining } = this.values;\n this.values = remaining;\n }\n\n migrateLegacy(storage: LegacyStorage, keys: readonly string[]): string[] {\n const migrated: string[] = [];\n let values = this.values;\n for (const key of keys) {\n if (values[key] !== undefined) continue;\n try {\n const value = storage.getItem(key);\n if (value === null) continue;\n values = { ...values, [key]: value };\n migrated.push(key);\n } catch {\n // Legacy browser storage is best-effort and may be unavailable.\n }\n }\n if (migrated.length > 0) this.values = values;\n return migrated;\n }\n\n fromStore(model: Partial<KafkaPersistentStateModel>): void {\n const values = model.values;\n if (!values || typeof values !== \"object\" || Array.isArray(values)) {\n this.values = {};\n return;\n }\n this.values = Object.fromEntries(\n Object.entries(values).filter((entry): entry is [string, string] => typeof entry[1] === \"string\"),\n );\n }\n\n toJSON(): KafkaPersistentStateModel {\n return { values: toJS(this.values) };\n }\n}\n\nexport function kafkaPersistentStateStore(): KafkaPersistentStateStore {\n return KafkaPersistentStateStore.getInstanceOrCreate<KafkaPersistentStateStore>();\n}\n","import { Renderer } from \"@freelensapp/extensions\";\n\nexport function KafkaIcon(props: Renderer.Component.IconProps) {\n return <Renderer.Component.Icon {...props} material=\"hub\" tooltip=\"Kafka\" />;\n}\n","import { observable, runInAction } from \"mobx\";\n\n/**\n * Records which Kafka targets answered the DescribeAcls probe, so the ACL page is\n * offered only where it can actually work instead of as a permanent placeholder.\n */\nexport class KafkaAclAvailabilityStore {\n private readonly available = observable.map<string, boolean>();\n\n get(targetId: string): boolean {\n return this.available.get(targetId) ?? false;\n }\n\n hasAny(): boolean {\n return [...this.available.values()].some(Boolean);\n }\n\n set(targetId: string, value: boolean): void {\n if (!targetId || this.available.get(targetId) === value) return;\n runInAction(() => {\n this.available.set(targetId, value);\n });\n }\n}\n",".KafkaOverviewPage {\n --kafka-border: var(--borderColor, rgba(127, 127, 127, 0.22));\n --kafka-muted: var(--textColorSecondary, rgba(127, 127, 127, 0.92));\n --kafka-panel: var(--contentColor, rgba(127, 127, 127, 0.06));\n\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 16px;\n height: 100%;\n min-width: 0;\n padding: 20px 24px;\n color: var(--textColorPrimary);\n\n * {\n box-sizing: border-box;\n }\n\n .KafkaPageHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 44px;\n gap: 16px;\n\n h1 {\n margin: 0;\n font-size: 22px;\n font-weight: 600;\n letter-spacing: 0;\n line-height: 1.2;\n }\n\n > div > span {\n display: block;\n margin-top: 3px;\n color: var(--kafka-muted);\n font-size: 12px;\n }\n }\n\n .KafkaRefreshButton,\n .KafkaHeaderActions .Button,\n .KafkaManualEndpoint .Button,\n .KafkaRemoveEndpoint,\n .KafkaIconButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n }\n\n .KafkaHeaderActions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .KafkaCacheStatus {\n display: inline-flex;\n min-width: max-content;\n align-items: center;\n gap: 4px;\n color: var(--kafka-muted);\n font-size: 11px;\n\n &.refreshing,\n &.loading {\n color: var(--primary);\n }\n\n .Icon {\n font-size: 15px;\n }\n }\n\n .KafkaClusterSelector {\n display: grid;\n min-width: 240px;\n grid-template-columns: auto minmax(150px, 1fr);\n align-items: center;\n gap: 8px;\n\n > span {\n color: var(--kafka-muted);\n font-size: 11px;\n font-weight: 600;\n }\n }\n\n .KafkaResourcePage {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n overflow: auto;\n }\n\n .KafkaMetrics {\n display: grid !important;\n width: 100%;\n min-width: 0;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n flex: 0 0 auto;\n margin: 16px 0 18px;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n &[data-metric-count=\"4\"] {\n grid-template-columns: repeat(4, minmax(0, 1fr));\n }\n }\n\n .KafkaMetric {\n display: flex;\n min-width: 0;\n min-height: 66px;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 10px 8px;\n\n + .KafkaMetric {\n border-left: 1px solid var(--kafka-border);\n }\n\n &.warning .KafkaMetricValue {\n color: var(--colorWarning, #f9a825);\n }\n\n &.error .KafkaMetricValue {\n color: var(--colorError, #ef5350);\n }\n }\n\n .KafkaMetricValue,\n .KafkaMetricLabel {\n display: block;\n max-width: 100%;\n overflow: hidden;\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .KafkaMetricValue {\n font-size: 18px;\n font-weight: 600;\n line-height: 1.2;\n }\n\n .KafkaMetricLabel {\n margin-top: 4px;\n color: var(--kafka-muted);\n font-size: 10px;\n font-weight: 500;\n line-height: 1.25;\n text-transform: uppercase;\n }\n\n .KafkaResourceMetricStrip {\n margin-top: 0;\n }\n\n .KafkaTopicMetricStrip {\n margin: 12px 0 14px;\n }\n\n .KafkaResourceDetails {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n border-top: 1px solid var(--kafka-border);\n\n > div {\n display: grid;\n min-width: 0;\n min-height: 54px;\n grid-template-columns: 112px minmax(0, 1fr);\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-right: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n > span:first-child {\n color: var(--kafka-muted);\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n }\n\n strong,\n code {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n .KafkaProgressMeasure {\n flex: 0 0 auto;\n align-items: flex-end;\n white-space: nowrap;\n\n strong {\n color: var(--primary);\n font-size: 14px;\n }\n }\n }\n\n .KafkaBrokerPageTable {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n flex: 1 1 auto;\n overflow: hidden;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n .TableHead,\n .TableRow {\n width: 100%;\n min-width: 0;\n min-height: 42px;\n }\n\n .brokerIdCell {\n flex: 0 0 90px;\n }\n\n .brokerRoleCell {\n flex: 0 0 130px;\n }\n\n .brokerHostCell {\n flex: 1 1 0;\n width: 0;\n min-width: 0;\n }\n\n .brokerPortCell {\n flex: 0 0 90px;\n }\n\n .KafkaEllipsis {\n display: block;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n .KafkaBrokerWorkspace {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 16px;\n }\n\n .KafkaBrokerConfigSection {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 10px;\n\n h2 {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n letter-spacing: 0;\n }\n\n > .KafkaOperationProgress {\n margin-top: 4px;\n }\n }\n\n .KafkaBrokerConfigTable {\n height: 360px;\n\n .configNameCell,\n .configValueCell,\n .configSourceCell,\n .configFlagsCell {\n box-sizing: border-box;\n }\n }\n\n .KafkaControllerBadge {\n color: var(--primary);\n border: 1px solid currentColor;\n }\n\n .KafkaResourceFootnote {\n padding: 10px 4px;\n color: var(--kafka-muted);\n font-size: 11px;\n }\n\n .KafkaTopicsPage {\n .KafkaTopicSearch {\n flex: 0 0 auto;\n }\n\n .KafkaTopicPageTable {\n height: auto;\n min-height: 220px;\n flex: 1 1 auto;\n }\n }\n\n .KafkaTopicWorkspace {\n overflow: hidden;\n\n .KafkaTopicMetadata {\n display: flex;\n min-height: 0;\n flex: 1 1 auto;\n flex-direction: column;\n margin-top: 0;\n padding-top: 14px;\n overflow: auto;\n }\n\n .KafkaPartitionTable {\n min-height: 220px;\n flex: 1 1 auto;\n }\n }\n\n .KafkaEntityTabs {\n display: flex;\n min-height: 42px;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: 4px;\n border-bottom: 1px solid var(--kafka-border);\n\n .Button {\n min-width: 112px;\n padding: 10px 14px;\n border-bottom: 2px solid transparent;\n border-radius: 0;\n\n &[aria-selected=\"true\"] {\n border-bottom-color: var(--primary);\n color: var(--primary);\n }\n }\n }\n\n .KafkaTopicInlineError {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--colorError);\n color: var(--colorError);\n }\n\n .KafkaManualEndpoint {\n display: grid;\n grid-template-columns: minmax(260px, 1fr) auto auto auto;\n align-items: center;\n gap: 10px;\n padding: 12px 0;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n }\n\n .KafkaManualBootstrap {\n min-width: 0;\n }\n\n .KafkaTlsSwitch {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 32px;\n color: var(--kafka-muted);\n font-size: 12px;\n }\n\n .KafkaManualError {\n grid-column: 1 / -1;\n color: var(--colorError);\n font-size: 12px;\n }\n\n .KafkaIconButton {\n width: 32px;\n min-width: 32px;\n height: 32px;\n padding: 0;\n }\n\n .KafkaToolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 10px 0;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n }\n\n .KafkaSearchInput {\n flex: 1 1 420px;\n max-width: 620px;\n min-width: 220px;\n }\n\n .KafkaFilterGroup {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 2px;\n padding: 3px;\n background: var(--kafka-panel);\n border: 1px solid var(--kafka-border);\n border-radius: 6px;\n\n .Button {\n min-height: 28px;\n padding: 4px 10px;\n font-size: 12px;\n white-space: nowrap;\n }\n }\n\n .KafkaMessagesBrowser {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1 1 auto;\n flex-direction: column;\n padding-top: 14px;\n overflow: hidden;\n }\n\n .KafkaMessageControls {\n display: flex;\n min-width: 0;\n flex: 0 0 auto;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: 10px;\n padding: 12px 14px 14px;\n margin-bottom: 10px;\n border: 1px solid var(--kafka-border);\n background: color-mix(in srgb, var(--contentColor, transparent) 70%, transparent);\n\n > label {\n display: grid;\n min-width: 112px;\n gap: 4px;\n\n > span {\n color: var(--kafka-muted);\n font-size: 11px;\n font-weight: 600;\n }\n\n &.KafkaMessagePartitionField {\n min-width: 150px;\n max-width: 150px;\n flex: 0 0 150px;\n width: 150px;\n\n .Select {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n }\n\n .Select__control,\n .Select__value-container {\n min-width: 0;\n }\n\n // Keep the partition picker visually aligned with the 34px start-mode filter group.\n .Select__control {\n min-height: 34px;\n height: 34px;\n }\n\n .Select__value-container {\n height: 34px;\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 0;\n padding-bottom: 0;\n }\n\n .Select__indicators {\n height: 34px;\n }\n }\n\n .Input {\n width: 150px;\n }\n }\n\n > .Button {\n display: inline-flex;\n min-width: 96px;\n min-height: 34px;\n align-items: center;\n justify-content: center;\n gap: 6px;\n }\n }\n\n .KafkaMessageFilters {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 10px;\n margin: 0;\n padding: 10px 12px;\n border: 1px solid var(--kafka-border);\n background: var(--kafka-panel);\n\n legend {\n padding: 0 4px;\n color: var(--kafka-muted);\n font-size: 11px;\n font-weight: 600;\n }\n\n label {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 4px;\n\n > span {\n color: var(--kafka-muted);\n font-size: 11px;\n }\n }\n }\n\n .KafkaMessageStartField {\n display: grid;\n min-width: 0;\n max-width: 100%;\n flex: 0 0 auto;\n margin: 0;\n padding: 0;\n gap: 4px;\n border: 0;\n\n legend {\n padding: 0;\n color: var(--kafka-muted);\n font-size: 11px;\n font-weight: 600;\n }\n\n &:focus-within {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n }\n }\n\n .KafkaMessageStartModes {\n display: grid;\n width: max-content;\n max-width: 100%;\n min-height: 34px;\n grid-template-columns: repeat(4, max-content);\n border: 1px solid var(--kafka-border);\n overflow: visible;\n\n .Button {\n position: relative;\n display: inline-flex;\n min-width: max-content;\n min-height: 32px;\n align-items: center;\n justify-content: center;\n padding: 8px 10px;\n border-right: 1px solid var(--kafka-border);\n border-radius: 0;\n line-height: 1.2;\n white-space: nowrap;\n\n &::before,\n &::after {\n display: none !important;\n content: none !important;\n }\n\n &:last-child {\n border-right: 0;\n }\n\n &[aria-pressed=\"true\"] {\n color: var(--primary);\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n\n &:focus-visible {\n outline: none;\n }\n }\n }\n\n .KafkaMessageError {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 8px;\n padding: 11px 12px;\n border: 1px solid color-mix(in srgb, var(--colorError) 35%, transparent);\n background: color-mix(in srgb, var(--colorError) 8%, transparent);\n color: var(--colorError);\n }\n\n .KafkaMessageTailStatus {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 10px;\n padding: 11px 12px;\n margin-bottom: 10px;\n border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);\n background: color-mix(in srgb, var(--primary) 8%, transparent);\n\n > .Icon {\n color: var(--primary);\n }\n\n > div {\n display: grid;\n gap: 2px;\n min-width: 0;\n\n span {\n color: var(--kafka-muted);\n font-family: monospace;\n font-size: 11px;\n }\n }\n }\n\n .KafkaMessageIdle {\n display: flex;\n min-height: 150px;\n flex: 1 1 auto;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 18px;\n border: 1px dashed var(--kafka-border);\n background: color-mix(in srgb, var(--contentColor, transparent) 55%, transparent);\n color: var(--kafka-muted);\n\n > div {\n display: grid;\n gap: 2px;\n }\n }\n\n .KafkaMessageRange {\n display: flex;\n min-width: 0;\n flex: 0 0 auto;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 14px;\n margin-bottom: 10px;\n border: 1px solid var(--kafka-border);\n background: color-mix(in srgb, var(--contentColor, transparent) 70%, transparent);\n\n > div {\n display: grid;\n min-width: 0;\n gap: 3px;\n\n strong {\n font-size: 13px;\n font-weight: 600;\n }\n\n span {\n overflow: hidden;\n color: var(--kafka-muted);\n font-family: monospace;\n font-size: 11px;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n > .Button {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 5px;\n }\n }\n\n .KafkaMessageWorkspace {\n display: grid;\n min-width: 0;\n min-height: 280px;\n flex: 1 1 auto;\n grid-template-columns: minmax(360px, 0.9fr) minmax(320px, 1.1fr);\n border-top: 1px solid var(--kafka-border);\n overflow: hidden;\n }\n\n .KafkaInteractiveRow[role=\"button\"] {\n cursor: pointer;\n\n &:hover {\n background: var(--tableBgcSelected) !important;\n }\n\n &:focus-visible {\n z-index: 1;\n outline: 2px solid var(--primary);\n outline-offset: -2px;\n }\n }\n\n .KafkaMessageTable {\n width: 100%;\n min-width: 0;\n min-height: 280px;\n height: auto;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n overflow: hidden;\n\n .TableHead,\n .TableRow {\n width: 100%;\n min-width: 0;\n min-height: 38px;\n }\n\n .TableHead {\n border-bottom: 1px solid var(--kafka-border);\n background: color-mix(in srgb, var(--contentColor, transparent) 80%, transparent);\n }\n\n .TableCell {\n min-width: 0;\n }\n\n .messageOffsetCell {\n flex: 0 0 78px;\n min-width: 78px;\n font-family: monospace;\n }\n\n .messageTimeCell {\n flex: 0 0 156px;\n min-width: 156px;\n color: var(--textColorSecondary);\n }\n\n .messageKeyCell,\n .messageValueCell {\n flex: 1 1 130px;\n width: 0;\n min-width: 92px;\n\n .KafkaEllipsis {\n font-family: monospace;\n font-size: 11px;\n }\n }\n\n .messageActionCell {\n flex: 0 0 44px;\n min-width: 44px;\n text-align: right;\n\n .Button {\n width: 28px;\n height: 28px;\n padding: 0;\n\n &:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n }\n }\n }\n\n .KafkaWorkspace {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n }\n\n .KafkaListPane {\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n }\n\n .KafkaClusterTable {\n height: 100%;\n border-bottom: 1px solid var(--kafka-border);\n\n .TableHead {\n min-height: 38px;\n }\n\n .TableRow {\n min-height: 46px;\n border-bottom: 1px solid var(--kafka-border);\n\n &:not(.disabled) {\n cursor: pointer;\n }\n\n &[role=\"button\"]:focus-visible {\n z-index: 1;\n outline: 2px solid var(--primary);\n outline-offset: -2px;\n }\n }\n\n .TableCell {\n min-width: 0;\n }\n\n .nameCell {\n flex: 1 1 190px;\n min-width: 155px;\n }\n\n .usageCell {\n flex: 0 1 165px;\n min-width: 125px;\n }\n\n .sourceCell {\n flex: 0 1 145px;\n min-width: 110px;\n }\n\n .bootstrapCell {\n flex: 1.6 1 270px;\n min-width: 180px;\n }\n\n .securityCell {\n flex: 0 0 128px;\n gap: 5px;\n }\n\n .reachCell,\n .podsCell {\n flex: 0 0 108px;\n }\n\n .actionCell {\n flex: 0 0 46px;\n justify-content: center;\n }\n }\n\n .KafkaClusterName {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n font-weight: 500;\n\n .Icon {\n flex: 0 0 auto;\n color: var(--primary);\n }\n\n span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n .KafkaUsageCell {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 2px;\n\n > span,\n > small {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n > span {\n font-weight: 500;\n }\n\n > small {\n color: var(--kafka-muted);\n font-size: 10px;\n }\n }\n\n .KafkaEllipsis {\n display: block;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .KafkaStatusBadge,\n .KafkaSourceBadge,\n .KafkaTlsBadge,\n .KafkaStrategyBadge {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n gap: 4px;\n border: 1px solid transparent;\n\n .Icon {\n font-size: 14px;\n }\n\n > span,\n > .Icon,\n > div {\n flex: 0 0 auto;\n }\n }\n\n .KafkaStatusBadge {\n &.reachable {\n color: var(--colorOk, #4caf50);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n &.unreachable {\n color: var(--colorError, #ef5350);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n &.checking {\n color: var(--kafka-muted);\n }\n\n &.unknown {\n color: var(--kafka-muted);\n border-color: var(--kafka-border);\n }\n }\n\n .KafkaSourceBadge {\n color: var(--textColorPrimary);\n\n &.source-workload {\n border-color: var(--primary);\n }\n }\n\n .KafkaTlsBadge.enabled,\n .KafkaStrategyBadge.strategy-direct {\n color: var(--primary);\n border-color: var(--primary);\n }\n\n .KafkaPageState,\n .KafkaNoMatches {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 130px;\n gap: 12px;\n color: var(--kafka-muted);\n\n &.error {\n color: var(--colorError);\n }\n\n > div {\n display: flex;\n flex-direction: column;\n gap: 3px;\n }\n }\n}\n\n.KafkaOperationProgress {\n width: 100%;\n padding: 16px 18px;\n border: 1px solid var(--borderColor, rgba(127, 127, 127, 0.22));\n border-radius: 6px;\n background: var(--contentColor, rgba(127, 127, 127, 0.06));\n\n &.error {\n border-color: color-mix(in srgb, var(--colorError) 55%, transparent);\n }\n\n .KafkaProgressHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 12px;\n\n > div {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 3px;\n }\n\n span {\n color: var(--textColorSecondary);\n font-size: 11px;\n line-height: 1.4;\n }\n\n > strong {\n color: var(--primary);\n font-size: 14px;\n }\n }\n\n .KafkaProgressLine {\n height: 6px;\n color: var(--primary);\n\n &.indeterminate {\n overflow: hidden;\n\n .line {\n position: absolute;\n left: -40%;\n width: 40% !important;\n animation: kafka-progress-indeterminate 1.2s ease-in-out infinite;\n }\n }\n }\n\n .KafkaProgressCount {\n margin-top: 7px;\n color: var(--textColorSecondary);\n font-size: 11px;\n text-align: right;\n }\n\n .KafkaProgressSteps {\n display: grid;\n grid-template-columns: repeat(4, minmax(0, 1fr));\n gap: 8px;\n margin: 14px 0 0;\n padding: 0;\n list-style: none;\n\n li {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 4px;\n color: var(--textColorSecondary);\n font-size: 10px;\n\n .Icon {\n flex: 0 0 auto;\n font-size: 13px;\n }\n\n span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &.complete,\n &.current {\n color: var(--primary);\n }\n\n &.current {\n font-weight: 600;\n }\n }\n }\n\n .KafkaProgressError {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n margin-top: 12px;\n color: var(--colorError);\n font-size: 12px;\n }\n}\n\n.KafkaHealthProgress {\n margin: 10px 0 14px;\n\n .KafkaOperationProgress {\n padding: 12px 16px;\n }\n}\n\n.KafkaHealthProgressSlot {\n display: flow-root;\n min-height: 66px;\n}\n\n.KafkaHealthProgressCompact {\n border: 1px solid var(--borderColor, rgba(127, 127, 127, 0.22));\n border-radius: 6px;\n background: var(--contentColor, rgba(127, 127, 127, 0.06));\n\n > summary {\n display: grid;\n min-height: 40px;\n box-sizing: border-box;\n grid-template-columns: auto minmax(120px, 1fr) auto auto auto auto;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n cursor: pointer;\n list-style: none;\n\n &::-webkit-details-marker {\n display: none;\n }\n\n > span,\n > strong {\n white-space: nowrap;\n }\n\n > span:not(.KafkaHealthProgressLabel) {\n color: var(--textColorSecondary);\n font-size: 11px;\n }\n\n > strong {\n color: var(--primary);\n font-size: 12px;\n }\n\n .KafkaHealthProgressLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 600;\n }\n }\n\n &[open] > summary > .Icon:last-child {\n transform: rotate(180deg);\n }\n\n > .KafkaOperationProgress {\n border-width: 1px 0 0;\n border-radius: 0 0 6px 6px;\n }\n}\n\n.KafkaProgressLiveStatus {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.KafkaHealthNotice {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin: 10px 0 14px;\n padding: 10px 14px;\n border: 1px solid color-mix(in srgb, var(--colorWarning, #f9a825) 45%, transparent);\n background: color-mix(in srgb, var(--colorWarning, #f9a825) 8%, transparent);\n color: var(--textColorPrimary);\n\n > .Icon {\n margin-top: 1px;\n color: var(--colorWarning, #f9a825);\n }\n\n > div {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 2px;\n }\n\n span {\n color: var(--textColorSecondary);\n font-size: 11px;\n line-height: 1.4;\n }\n}\n\n@keyframes kafka-progress-indeterminate {\n from {\n left: -40%;\n }\n\n to {\n left: 100%;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .KafkaOperationProgress .KafkaProgressLine.indeterminate .line {\n left: 30%;\n animation: none;\n }\n}\n\n.KafkaDiscoveryError {\n display: flex;\n align-items: flex-end;\n gap: 12px;\n\n .KafkaOperationProgress {\n flex: 1 1 auto;\n }\n}\n\n.Drawer.KafkaConnectionSettingsDrawer {\n --kafka-border: var(--borderColor, rgba(127, 127, 127, 0.22));\n --kafka-muted: var(--textColorSecondary, rgba(127, 127, 127, 0.92));\n\n * {\n box-sizing: border-box;\n }\n\n .KafkaConnectionSettingsBody {\n padding: 16px 20px 24px;\n overflow-x: hidden;\n }\n\n .DrawerItem {\n padding: 9px 0;\n }\n\n .KafkaDetailContext {\n margin-bottom: 10px;\n color: var(--kafka-muted);\n font-size: 12px;\n }\n\n .KafkaDetailBadges {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-bottom: 12px;\n }\n\n .KafkaStatusBadge,\n .KafkaSourceBadge,\n .KafkaTlsBadge,\n .KafkaStrategyBadge {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n gap: 4px;\n border: 1px solid transparent;\n\n .Icon {\n font-size: 14px;\n }\n }\n\n .KafkaStatusBadge.reachable {\n color: var(--colorOk, #4caf50);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n .KafkaStatusBadge.unreachable {\n color: var(--colorError, #ef5350);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n .KafkaStatusBadge.checking,\n .KafkaStatusBadge.unknown {\n color: var(--kafka-muted);\n }\n\n .KafkaStatusBadge.unknown {\n border-color: var(--kafka-border);\n }\n\n .KafkaTlsBadge.enabled,\n .KafkaStrategyBadge.strategy-direct {\n color: var(--primary);\n border-color: var(--primary);\n }\n\n .KafkaRemoveEndpoint {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin: 12px 0 2px;\n color: var(--colorError);\n }\n\n .KafkaConnectionSettings {\n margin: 14px 0;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n h2 {\n margin: 0;\n padding: 12px 0 8px;\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0;\n }\n }\n\n .KafkaSecurityForm {\n display: grid;\n gap: 12px;\n padding: 4px 0 14px;\n\n > label {\n display: grid;\n grid-template-columns: 118px minmax(0, 1fr);\n align-items: center;\n gap: 10px;\n\n > span {\n color: var(--kafka-muted);\n font-size: 12px;\n }\n }\n\n > p {\n margin: 0;\n color: var(--kafka-muted);\n font-size: 11px;\n line-height: 1.45;\n }\n\n > .Button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n justify-self: end;\n gap: 6px;\n }\n }\n\n .KafkaSecurityError {\n color: var(--colorError);\n font-size: 12px;\n }\n\n .KafkaConnectionVerified {\n display: flex;\n align-items: center;\n gap: 9px;\n margin-top: 14px;\n padding: 11px 12px;\n border: 1px solid color-mix(in srgb, var(--colorOk, #4caf50) 45%, transparent);\n color: var(--colorOk, #4caf50);\n\n > .Icon {\n flex: 0 0 auto;\n }\n\n > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n\n span {\n color: var(--kafka-muted);\n font-size: 11px;\n }\n }\n }\n\n .KafkaBootstrapDetail {\n display: block;\n max-height: 90px;\n overflow: auto;\n overflow-wrap: anywhere;\n white-space: normal;\n }\n\n .KafkaReferences {\n margin: 14px 0;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n summary {\n padding: 10px 0;\n cursor: pointer;\n font-weight: 500;\n }\n\n ul {\n max-height: 180px;\n margin: 0 0 12px;\n padding-left: 20px;\n overflow: auto;\n color: var(--kafka-muted);\n font-family: monospace;\n font-size: 11px;\n }\n }\n}\n\n.Drawer.KafkaMessageDetailDrawer {\n --kafka-border: var(--borderColor, rgba(127, 127, 127, 0.22));\n --kafka-muted: var(--textColorSecondary, rgba(127, 127, 127, 0.92));\n --kafka-panel: var(--contentColor, rgba(127, 127, 127, 0.06));\n\n * {\n box-sizing: border-box;\n }\n\n .KafkaMessageDetailBody {\n padding: 16px 20px 24px;\n overflow-x: hidden;\n overflow-y: auto;\n }\n\n .DrawerItem {\n padding: 9px 0;\n }\n\n .KafkaMessageInspector {\n min-width: 0;\n }\n\n // Monospace inline value (offset, header content)\n .KafkaMsgMono {\n font-family: monospace;\n font-size: 12px;\n }\n\n // Timestamp with epoch sub-line\n .KafkaMsgTimestamp {\n display: flex;\n flex-direction: column;\n gap: 2px;\n\n > small {\n font-family: monospace;\n font-size: 10px;\n color: var(--kafka-muted);\n }\n }\n\n // Wrapper under each DrawerTitle (badge + code block)\n .KafkaMsgBytesBody {\n padding-bottom: 4px;\n }\n\n // Colored format + size badge\n .KafkaMsgFormatBadge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n margin-bottom: 8px;\n border: 1px solid transparent;\n border-radius: 10px;\n font-size: 11px;\n font-family: monospace;\n line-height: 1.6;\n\n &.format-json {\n color: var(--colorOk, #4caf50);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n &.format-text {\n color: var(--textColorSecondary);\n border-color: var(--kafka-border);\n }\n\n &.format-binary {\n color: var(--colorWarning, #f9a825);\n border-color: color-mix(in srgb, currentColor 35%, transparent);\n }\n\n &.format-null {\n color: var(--kafka-muted);\n border-color: var(--kafka-border);\n }\n }\n\n // Scrollable code block for Key/Value content\n .KafkaMsgCodeBlock {\n display: block;\n max-height: 320px;\n overflow: auto;\n margin: 0 0 4px;\n padding: 12px 14px;\n background: var(--kafka-panel);\n font-family: monospace;\n font-size: 11px;\n line-height: 1.5;\n border: 1px solid var(--kafka-border);\n border-radius: 4px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--textColorPrimary);\n\n &[data-format=\"binary\"] {\n color: var(--colorWarning, #f9a825);\n }\n }\n\n // Base64 fallback details block\n .KafkaMsgBase64 {\n margin: 6px 0 4px;\n\n > summary {\n cursor: pointer;\n font-size: 10px;\n color: var(--kafka-muted);\n padding: 2px 0;\n }\n\n > code {\n display: block;\n margin-top: 6px;\n padding: 8px 10px;\n background: var(--kafka-panel);\n border: 1px solid var(--kafka-border);\n border-radius: 3px;\n font-family: monospace;\n font-size: 10px;\n line-height: 1.45;\n overflow-wrap: break-word;\n word-break: break-all;\n color: var(--textColorPrimary);\n }\n }\n\n // Headers list with divider rows\n .KafkaMsgHeaderList {\n margin-top: 4px;\n border-top: 1px solid var(--kafka-border);\n\n .DrawerItem {\n border-bottom: 1px solid var(--kafka-border);\n padding: 8px 0;\n }\n }\n\n // Header row value: badge + truncated code\n .KafkaMsgHeaderValue {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n\n .KafkaMsgFormatBadge {\n margin-bottom: 0;\n }\n\n .KafkaMsgMono {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n // \"No headers\" empty state\n .KafkaMsgEmpty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n color: var(--kafka-muted);\n font-size: 12px;\n\n .Icon {\n font-size: 16px;\n }\n }\n}\n\n.KafkaOverviewPage {\n .KafkaTopicSection,\n .KafkaTopicMetadata {\n width: 100%;\n min-width: 0;\n }\n\n .KafkaTopicSearch {\n width: 100%;\n margin-bottom: 10px;\n }\n\n .KafkaTopicTable,\n .KafkaPartitionTable {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n overflow-x: hidden;\n overflow-y: auto !important;\n border-top: 1px solid var(--kafka-border);\n border-bottom: 1px solid var(--kafka-border);\n\n .TableHead,\n .TableRow {\n width: 100%;\n min-width: 0;\n min-height: 38px;\n }\n\n .TableRow[role=\"button\"] {\n cursor: pointer;\n }\n }\n\n .KafkaTopicTable {\n height: 240px;\n\n .topicNameCell {\n display: flex;\n align-items: center;\n gap: 7px;\n\n > .content {\n min-width: 0;\n padding-right: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n > .KafkaEllipsis {\n min-width: 0;\n flex: 1 1 auto;\n }\n\n .Icon {\n flex: 0 0 auto;\n color: var(--primary);\n }\n }\n\n .topicActionCell {\n justify-content: center;\n }\n }\n\n .KafkaInternalTopicBadge {\n color: var(--kafka-muted);\n border: 1px solid var(--kafka-border);\n }\n\n .KafkaTopicType {\n color: var(--kafka-muted);\n font-size: 11px;\n }\n\n .KafkaTopicPrompt {\n display: flex;\n min-height: 92px;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: var(--kafka-muted);\n text-align: center;\n }\n\n .KafkaTopicMetadata {\n margin-top: 18px;\n padding-top: 14px;\n border-top: 1px solid var(--kafka-border);\n\n > .KafkaOperationProgress {\n margin-bottom: 14px;\n }\n }\n\n .KafkaTopicMetadataHeader {\n display: flex;\n min-width: 0;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 10px;\n\n > div {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n }\n\n .DrawerTitle {\n min-width: 0;\n margin: 0;\n padding: 0;\n overflow: hidden;\n background: transparent;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Button {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 5px;\n }\n }\n\n .KafkaPartitionTable {\n height: 320px;\n\n .TableHead .TableCell > .content {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .TableHead .partitionIdCell > .content {\n padding-right: 24px;\n }\n\n .partitionIdCell,\n .partitionLeaderCell,\n .partitionReplicasCell,\n .partitionIsrCell,\n .partitionHealthCell {\n box-sizing: border-box;\n }\n }\n\n .KafkaTopicConfigTable {\n height: 320px;\n\n .configNameCell,\n .configValueCell,\n .configSourceCell,\n .configFlagsCell {\n box-sizing: border-box;\n }\n }\n\n .KafkaTopicConsumersTable {\n height: 320px;\n\n .consumerGroupCell,\n .consumerStateCell,\n .consumerMembersCell,\n .consumerLagCell,\n .consumerActionCell {\n box-sizing: border-box;\n }\n\n .consumerGroupCell {\n gap: 8px;\n\n .Icon {\n flex: 0 0 auto;\n color: var(--primary);\n }\n }\n\n .consumerMembersCell,\n .consumerLagCell {\n justify-content: flex-end;\n text-align: right;\n }\n\n .consumerActionCell {\n justify-content: center;\n }\n }\n\n .KafkaConfigSource {\n color: var(--kafka-muted);\n font-size: 11px;\n letter-spacing: 0.02em;\n }\n\n .KafkaConfigFlags {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n\n > span {\n color: var(--kafka-muted);\n font-size: 11px;\n }\n }\n\n .KafkaMono {\n font-family: monospace;\n font-size: 11px;\n }\n\n .KafkaReplicaSet {\n display: block;\n min-width: 0;\n overflow: hidden;\n font-family: monospace;\n font-size: 11px;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .KafkaPartitionHealth {\n display: flex;\n min-width: 0;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n\n small {\n max-width: 100%;\n overflow: hidden;\n color: var(--kafka-muted);\n font-size: 9px;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n .KafkaPartitionBadge {\n display: inline-flex;\n max-width: 100%;\n align-items: center;\n gap: 4px;\n border: 1px solid currentColor;\n\n .Icon {\n font-size: 13px;\n }\n\n &.healthy {\n color: var(--colorOk, #4caf50);\n }\n\n &.underreplicated {\n color: var(--colorWarning, #f9a825);\n }\n\n &.unavailable {\n color: var(--colorError, #ef5350);\n }\n }\n}\n\n@media (max-width: 1180px) {\n .KafkaOverviewPage {\n .KafkaClusterTable .usageCell,\n .KafkaClusterTable .podsCell {\n display: none;\n }\n }\n}\n\n@media (max-width: 820px) {\n .KafkaOverviewPage {\n padding: 16px;\n\n .KafkaToolbar {\n align-items: stretch;\n flex-direction: column;\n }\n\n .KafkaPageHeader {\n align-items: flex-start;\n }\n\n .KafkaHeaderActions {\n width: 100%;\n flex-wrap: wrap;\n justify-content: space-between;\n }\n\n .KafkaClusterSelector {\n min-width: 0;\n flex: 1 1 260px;\n grid-template-columns: auto minmax(120px, 1fr);\n }\n\n .KafkaMetrics {\n &,\n &[data-metric-count=\"4\"] {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n\n .KafkaMetric:nth-child(odd) {\n border-left: 0;\n }\n\n .KafkaMetric:nth-child(n + 3) {\n border-top: 1px solid var(--kafka-border);\n }\n\n .KafkaMetric:nth-child(odd):last-child {\n grid-column: 1 / -1;\n }\n }\n\n .KafkaResourceDetails {\n grid-template-columns: minmax(0, 1fr);\n\n > div {\n border-right: 0;\n }\n }\n\n .KafkaHealthProgressCompact > summary {\n grid-template-columns: auto minmax(0, 1fr) auto auto;\n\n > span:not(.KafkaHealthProgressLabel):not(.KafkaProgressLiveStatus) {\n display: none;\n }\n }\n\n .KafkaEntityTabs {\n max-width: 100%;\n overflow-x: auto;\n }\n\n .KafkaTopicWorkspace {\n overflow: auto;\n\n .KafkaTopicMetadata {\n overflow: visible;\n }\n }\n\n .KafkaMessagesBrowser {\n min-height: 520px;\n overflow: visible;\n }\n\n .KafkaMessageControls {\n align-items: stretch;\n padding: 12px;\n\n > label,\n > label.KafkaMessagePartitionField {\n width: calc(50% - 5px);\n\n .Input {\n width: 100%;\n }\n }\n\n > label.KafkaMessagePartitionField {\n min-width: 0;\n max-width: none;\n flex: 1 1 calc(50% - 5px);\n }\n\n .KafkaMessageStartField,\n .KafkaMessageStartModes {\n width: 100%;\n }\n\n .KafkaMessageStartField {\n flex-basis: 100%;\n }\n\n .KafkaMessageStartModes {\n grid-template-columns: repeat(4, minmax(max-content, 1fr));\n }\n\n > .Button {\n margin-left: auto;\n }\n }\n\n .KafkaMessageFilters {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n\n .KafkaMessageRange {\n align-items: flex-start;\n flex-direction: column;\n padding: 12px;\n\n > div span {\n white-space: normal;\n }\n }\n\n .KafkaMessageWorkspace {\n min-height: 620px;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: minmax(260px, 42vh) minmax(300px, auto);\n overflow: visible;\n }\n\n .KafkaMessageTable {\n border-right: 0;\n border-bottom: 1px solid var(--kafka-border);\n\n .messageOffsetCell {\n flex-basis: 64px;\n min-width: 64px;\n }\n\n .messageTimeCell {\n flex-basis: 128px;\n min-width: 128px;\n }\n\n .messageActionCell {\n flex-basis: 38px;\n min-width: 38px;\n }\n\n .messageKeyCell,\n .messageValueCell {\n min-width: 78px;\n }\n }\n\n .KafkaTopicPageTable,\n .KafkaPartitionTable {\n .TableCell {\n padding-right: 8px;\n padding-left: 8px;\n }\n }\n\n .KafkaBrokerPageTable {\n .brokerRoleCell {\n flex-basis: 106px;\n }\n\n .brokerIdCell,\n .brokerPortCell {\n flex-basis: 70px;\n }\n }\n\n .KafkaManualEndpoint {\n grid-template-columns: minmax(0, 1fr) auto;\n\n .KafkaManualBootstrap {\n grid-column: 1 / -1;\n }\n }\n\n .KafkaSearchInput {\n flex-basis: auto;\n width: 100%;\n max-width: none;\n }\n\n .KafkaFilterGroup {\n align-self: flex-start;\n max-width: 100%;\n overflow-x: auto;\n }\n\n .KafkaClusterTable .sourceCell,\n .KafkaClusterTable .securityCell,\n .KafkaClusterTable .actionCell {\n display: none;\n }\n\n .KafkaClusterTable {\n .TableCell {\n padding-right: 8px;\n padding-left: 8px;\n }\n\n .nameCell {\n flex: 1 1 120px;\n min-width: 105px;\n }\n\n .bootstrapCell {\n flex: 1.2 1 150px;\n min-width: 125px;\n }\n\n .reachCell {\n flex: 0 0 90px;\n }\n }\n }\n\n .KafkaDiscoveryError {\n align-items: stretch;\n flex-direction: column;\n }\n\n .KafkaOverviewPage {\n .KafkaPartitionTable {\n .partitionIdCell {\n flex: 0 0 96px !important;\n width: 96px !important;\n min-width: 96px !important;\n }\n\n .partitionLeaderCell {\n flex: 0 0 64px !important;\n width: 64px !important;\n min-width: 64px !important;\n }\n\n .partitionReplicasCell,\n .partitionIsrCell {\n flex: 1 1 82px !important;\n width: 0 !important;\n min-width: 72px !important;\n }\n\n .partitionHealthCell {\n flex: 0 0 112px !important;\n width: 112px !important;\n min-width: 112px !important;\n }\n }\n }\n\n .Drawer.KafkaConnectionSettingsDrawer {\n .KafkaSecurityForm > label {\n grid-template-columns: minmax(0, 1fr);\n gap: 4px;\n }\n }\n\n // ─── Consumer Groups ──────────────────────────────────────────────────────\n\n .KafkaGroupWorkspace {\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n\n .KafkaGroupOffsetSection {\n display: flex;\n flex-direction: column;\n gap: 20px;\n }\n\n .KafkaGroupTopicSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .KafkaGroupTopicHeader {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n\n .KafkaGroupTopicName {\n flex: 1 1 0;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .KafkaGroupTopicLag {\n color: var(--kafka-muted);\n font-size: 12px;\n font-weight: 400;\n white-space: nowrap;\n\n strong {\n color: var(--textColorPrimary);\n font-weight: 600;\n }\n }\n }\n\n .KafkaGroupMemberSection {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .KafkaGroupTopicsSection {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 12px;\n }\n\n .KafkaGroupTopicsTable {\n height: 320px;\n\n .groupTopicNameCell,\n .groupTopicPartitionsCell,\n .groupTopicLagCell,\n .groupTopicActionCell {\n box-sizing: border-box;\n }\n\n .groupTopicNameCell {\n gap: 8px;\n overflow: hidden;\n\n .Icon {\n flex: 0 0 auto;\n color: var(--primary);\n }\n }\n\n .groupTopicPartitionsCell,\n .groupTopicLagCell {\n justify-content: flex-end;\n font-variant-numeric: tabular-nums;\n text-align: right;\n }\n\n .groupTopicActionCell {\n justify-content: center;\n }\n }\n\n .KafkaLagZero {\n color: var(--colorSuccess, #3dc43d);\n }\n .KafkaLagLow {\n color: var(--colorWarning, #f0a500);\n }\n .KafkaLagHigh {\n color: var(--colorError, #e05454);\n }\n .KafkaLagUnknown {\n color: var(--kafka-muted);\n }\n\n .KafkaGroupProtocol {\n color: var(--kafka-muted);\n font-size: 12px;\n }\n\n .KafkaGroupsPage,\n .KafkaGroupWorkspace {\n .groupNameCell {\n overflow: hidden;\n }\n .groupMembersCell {\n font-variant-numeric: tabular-nums;\n }\n }\n\n .KafkaHealthyBadge {\n --badge-bg: var(--colorSuccess, #3dc43d);\n }\n .KafkaWarningBadge {\n --badge-bg: var(--colorWarning, #f0a500);\n }\n .KafkaErrorBadge {\n --badge-bg: var(--colorError, #e05454);\n }\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect } from \"react\";\nimport kafkaStyles from \"./kafka-overview.scss?inline\";\n\nimport type { ReactNode } from \"react\";\n\nimport type { DiscoveredKafkaInfo } from \"../common/ipc\";\n\ninterface KafkaPageShellProps {\n title: string;\n subtitle: string;\n actions?: ReactNode;\n children: ReactNode;\n}\n\ninterface KafkaClusterSelectorProps {\n clusters: DiscoveredKafkaInfo[];\n selectedTargetId?: string;\n onChange: (targetId: string) => void;\n disabled?: boolean;\n}\n\nexport interface KafkaMetric {\n label: string;\n value: ReactNode;\n tone?: \"warning\" | \"error\";\n}\n\ninterface KafkaMetricStripProps {\n ariaLabel: string;\n className?: string;\n metrics: KafkaMetric[];\n}\n\nconst KAFKA_STYLE_ID = \"freelens-kafka-extension-styles\";\n\nfunction ensureKafkaStyles(): void {\n let style = document.getElementById(KAFKA_STYLE_ID) as HTMLStyleElement | null;\n if (!style) {\n style = document.createElement(\"style\");\n style.id = KAFKA_STYLE_ID;\n document.head.append(style);\n }\n if (style.textContent !== kafkaStyles) style.textContent = kafkaStyles;\n}\n\nexport function KafkaPageShell({ title, subtitle, actions, children }: KafkaPageShellProps) {\n useEffect(() => ensureKafkaStyles(), []);\n\n return (\n <div className=\"KafkaOverviewPage KafkaPageShell\">\n <header className=\"KafkaPageHeader\">\n <div>\n <h1>{title}</h1>\n <span>{subtitle}</span>\n </div>\n {actions && <div className=\"KafkaHeaderActions\">{actions}</div>}\n </header>\n {children}\n </div>\n );\n}\n\nexport function KafkaMetricStrip({ ariaLabel, className = \"\", metrics }: KafkaMetricStripProps) {\n return (\n <section className={`KafkaMetrics ${className}`.trim()} aria-label={ariaLabel} data-metric-count={metrics.length}>\n {metrics.map((metric) => (\n <div key={metric.label} className={`KafkaMetric ${metric.tone ?? \"\"}`.trim()}>\n <strong className=\"KafkaMetricValue\">{metric.value}</strong>\n <span className=\"KafkaMetricLabel\">{metric.label}</span>\n </div>\n ))}\n </section>\n );\n}\n\nexport function KafkaClusterSelector({ clusters, selectedTargetId, onChange, disabled }: KafkaClusterSelectorProps) {\n const options: Renderer.Component.SelectOption<string>[] = clusters.map((cluster) => ({\n value: cluster.targetId,\n label: cluster.name,\n }));\n\n return (\n <label className=\"KafkaClusterSelector\">\n <span>Kafka cluster</span>\n <Renderer.Component.Select\n options={options}\n value={selectedTargetId}\n onChange={(option: Renderer.Component.SelectOption<string> | null) => {\n if (option) onChange(option.value);\n }}\n isDisabled={disabled || options.length === 0}\n placeholder={options.length === 0 ? \"No Kafka clusters\" : \"Select a Kafka cluster\"}\n themeName=\"lens\"\n menuPosition=\"fixed\"\n />\n </label>\n );\n}\n","import type { ClusterOverviewHealthDto } from \"./ipc\";\n\nconst AGGREGATE_HEALTH_SNAPSHOT_PREFIX = \"freelens-kafka.aggregate-health.v1\";\n\nexport interface PersistedAggregateHealthSnapshot {\n data: ClusterOverviewHealthDto;\n lastComplete?: ClusterOverviewHealthDto;\n updatedAt: number;\n}\n\nfunction nonNegativeInteger(value: unknown): number | undefined {\n return Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : undefined;\n}\n\nfunction healthDto(value: unknown): ClusterOverviewHealthDto | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const candidate = value as Record<string, unknown>;\n const onlineBrokers = nonNegativeInteger(candidate.onlineBrokers);\n const unavailablePartitions = nonNegativeInteger(candidate.unavailablePartitions);\n const underReplicatedPartitions = nonNegativeInteger(candidate.underReplicatedPartitions);\n const consumerGroupLag = candidate.consumerGroupLag;\n if (\n onlineBrokers === undefined ||\n unavailablePartitions === undefined ||\n underReplicatedPartitions === undefined ||\n typeof consumerGroupLag !== \"string\" ||\n !/^(?:≥)?\\d+$|^Unavailable$|^—$/.test(consumerGroupLag)\n ) {\n return undefined;\n }\n\n const unavailableTopics = nonNegativeInteger(candidate.consumerGroupLagUnavailableTopics);\n const unavailableGroups = nonNegativeInteger(candidate.consumerGroupLagUnavailableGroups);\n const topologyMeasuredAt = nonNegativeInteger(candidate.topologyMeasuredAt);\n const rawCoverage = candidate.consumerGroupLagCoverage;\n let coverage: ClusterOverviewHealthDto[\"consumerGroupLagCoverage\"];\n if (rawCoverage && typeof rawCoverage === \"object\") {\n const raw = rawCoverage as Record<string, unknown>;\n const resolvedGroups = nonNegativeInteger(raw.resolvedGroups);\n const totalGroups = nonNegativeInteger(raw.totalGroups);\n const coverageUnavailableGroups = nonNegativeInteger(raw.unavailableGroups);\n const startedAt = nonNegativeInteger(raw.startedAt);\n const completedAt = nonNegativeInteger(raw.completedAt);\n if (\n typeof raw.complete === \"boolean\" &&\n resolvedGroups !== undefined &&\n totalGroups !== undefined &&\n coverageUnavailableGroups !== undefined &&\n resolvedGroups + coverageUnavailableGroups <= totalGroups &&\n (!raw.complete ||\n (/^\\d+$/.test(consumerGroupLag) &&\n resolvedGroups === totalGroups &&\n coverageUnavailableGroups === 0 &&\n (unavailableGroups ?? 0) === 0 &&\n (unavailableTopics ?? 0) === 0))\n ) {\n coverage = {\n complete: raw.complete,\n resolvedGroups,\n totalGroups,\n unavailableGroups: coverageUnavailableGroups,\n ...(startedAt === undefined ? {} : { startedAt }),\n ...(completedAt === undefined ? {} : { completedAt }),\n };\n }\n }\n\n return {\n onlineBrokers,\n unavailablePartitions,\n underReplicatedPartitions,\n consumerGroupLag,\n ...(topologyMeasuredAt === undefined ? {} : { topologyMeasuredAt }),\n ...(unavailableTopics === undefined || unavailableTopics === 0\n ? {}\n : { consumerGroupLagUnavailableTopics: unavailableTopics }),\n ...(unavailableGroups === undefined || unavailableGroups === 0\n ? {}\n : { consumerGroupLagUnavailableGroups: unavailableGroups }),\n ...(coverage ? { consumerGroupLagCoverage: coverage } : {}),\n };\n}\n\nexport function isExactAggregateHealth(\n data: Partial<ClusterOverviewHealthDto> | undefined,\n): data is ClusterOverviewHealthDto {\n return Boolean(\n data &&\n typeof data.consumerGroupLag === \"string\" &&\n /^\\d+$/.test(data.consumerGroupLag) &&\n !data.consumerGroupLagUnavailableGroups &&\n !data.consumerGroupLagUnavailableTopics &&\n data.consumerGroupLagCoverage?.complete === true &&\n data.consumerGroupLagCoverage.unavailableGroups === 0 &&\n data.consumerGroupLagCoverage.resolvedGroups === data.consumerGroupLagCoverage.totalGroups,\n );\n}\n\nfunction exactHealthDto(value: unknown): ClusterOverviewHealthDto | undefined {\n const data = healthDto(value);\n return isExactAggregateHealth(data) ? data : undefined;\n}\n\nexport function aggregateHealthSnapshotKey(contextId: string, targetId: string): string {\n return `${AGGREGATE_HEALTH_SNAPSHOT_PREFIX}:${encodeURIComponent(contextId)}:${encodeURIComponent(targetId)}`;\n}\n\nexport function encodeAggregateHealthSnapshot(snapshot: PersistedAggregateHealthSnapshot): string {\n const data = healthDto(snapshot.data);\n const lastComplete = exactHealthDto(snapshot.lastComplete);\n const updatedAt = nonNegativeInteger(snapshot.updatedAt);\n if (!data || updatedAt === undefined) throw new Error(\"Aggregate health snapshot is invalid\");\n return JSON.stringify({\n schemaVersion: 1,\n updatedAt,\n data,\n ...(lastComplete ? { lastComplete } : {}),\n });\n}\n\nexport function decodeAggregateHealthSnapshot(raw: string | null): PersistedAggregateHealthSnapshot | undefined {\n if (!raw || raw.length > 4_096) return undefined;\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (parsed.schemaVersion !== 1) return undefined;\n const data = healthDto(parsed.data);\n const lastComplete = exactHealthDto(parsed.lastComplete);\n const updatedAt = nonNegativeInteger(parsed.updatedAt);\n if (!data || updatedAt === undefined) return undefined;\n return { data, updatedAt, ...(lastComplete ? { lastComplete } : {}) };\n } catch {\n return undefined;\n }\n}\n","/** Shared Kafka runtime constants. */\n\nexport const KAFKA_ADMIN_TIMEOUT_MS = 30_000;\nexport const KAFKA_CLUSTER_HEALTH_TIMEOUT_MS = 300_000;\nexport const KAFKA_CLUSTER_HEALTH_CACHE_TTL_MS = 5 * 60_000;\nexport const KAFKA_TOPIC_CONSUMERS_TIMEOUT_MS = 120_000;\nexport const KAFKA_RESOURCE_CACHE_TTL_MS = 60_000;\n\nexport const DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS = 30_000;\nexport const MIN_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS = 10_000;\n\nexport const KAFKA_OVERVIEW_AUTO_REFRESH_OPTIONS = [\n { value: \"10000\", label: \"10 sec\" },\n { value: \"30000\", label: \"30 sec\" },\n { value: \"60000\", label: \"60 sec\" },\n { value: \"300000\", label: \"5 min\" },\n] as const;\n","/** Reachability + connection-strategy helpers shared by Main and Renderer (pure, no Node deps). */\n\n/** Normalize a bootstrap (comma list, optional `scheme://`, optional port) into kafkajs `host:port`\n * brokers. A missing port defaults to `defaultPort` — some workloads set the host without a port. Pure. */\nexport function splitBootstrap(bootstrap: string, defaultPort = 9092): string[] {\n return bootstrap\n .split(\",\")\n .map((part) => part.trim().replace(/^[a-z]+:\\/\\//i, \"\"))\n .filter(Boolean)\n .map((hostPort) => {\n const i = hostPort.lastIndexOf(\":\");\n if (i < 0) return `${hostPort}:${defaultPort}`;\n return Number.isFinite(Number(hostPort.slice(i + 1))) ? hostPort : `${hostPort.slice(0, i)}:${defaultPort}`;\n });\n}\n\n/** Host + port of the first entry of a (possibly comma-separated, possibly `scheme://`) bootstrap. Pure. */\nexport function firstBrokerAddress(bootstrap: string): { host: string; port: number } {\n const first = splitBootstrap(bootstrap)[0];\n if (!first) return { host: \"\", port: 9092 };\n const i = first.lastIndexOf(\":\");\n return { host: first.slice(0, i), port: Number(first.slice(i + 1)) };\n}\n\n/** Connection strategy for a discovered Kafka, from its source + whether this machine can reach it. Pure.\n *\n * - `portForward` — Strimzi (brokers are pods): tunnel each broker (works whether or not the PC can reach it).\n * - `direct` — reachable from this machine (public / VPN, e.g. MSK): kafkajs straight to the bootstrap.\n * - `relay` — reachable only from the cluster's pods: needs an in-cluster relay (not available yet, P3.2 i).\n */\nexport function chooseStrategy(source: string, pcReachable: boolean): \"portForward\" | \"direct\" | \"relay\" {\n if (source === \"strimzi\") return \"portForward\";\n if (pcReachable) return \"direct\";\n return \"relay\";\n}\n","import type { DiscoveredKafkaInfo } from \"../common/ipc\";\nimport type { KafkaSelectionStorage } from \"./kafka-navigation\";\n\nexport const KAFKA_CLUSTER_CATALOG_KEY = \"freelens-kafka.cluster-catalog.v1\";\n\nexport interface KafkaClusterCatalog {\n discovered: DiscoveredKafkaInfo[];\n missing: DiscoveredKafkaInfo[];\n lastScanAt?: number;\n autoScan: boolean;\n}\n\ninterface StoredCatalog extends KafkaClusterCatalog {}\n\nfunction emptyCatalog(): KafkaClusterCatalog {\n return { discovered: [], missing: [], autoScan: false };\n}\n\nexport class KafkaClusterCatalogStore {\n private readonly catalogs = new Map<string, KafkaClusterCatalog>();\n\n constructor(private readonly storage: KafkaSelectionStorage) {\n this.load();\n }\n\n get(contextId: string): KafkaClusterCatalog {\n const catalog = this.catalogs.get(contextId) ?? emptyCatalog();\n return { ...catalog, discovered: [...catalog.discovered], missing: [...catalog.missing] };\n }\n\n targets(contextId: string): DiscoveredKafkaInfo[] {\n const catalog = this.get(contextId);\n return [...catalog.discovered, ...catalog.missing];\n }\n\n setDiscovered(contextId: string, discovered: DiscoveredKafkaInfo[], scannedAt = Date.now()): void {\n const current = this.get(contextId);\n const previous = [...current.discovered, ...current.missing];\n const nextIds = new Set(discovered.map((entry) => entry.targetId));\n this.catalogs.set(contextId, {\n discovered: [...new Map(discovered.map((entry) => [entry.targetId, entry])).values()],\n missing: previous.filter((entry) => !nextIds.has(entry.targetId)),\n lastScanAt: scannedAt,\n autoScan: current.autoScan,\n });\n this.persist();\n }\n\n setAutoScan(contextId: string, enabled: boolean): void {\n const current = this.get(contextId);\n this.catalogs.set(contextId, { ...current, autoScan: enabled });\n this.persist();\n }\n\n clear(contextId?: string): void {\n if (contextId) this.catalogs.delete(contextId);\n else this.catalogs.clear();\n this.persist();\n }\n\n private load(): void {\n try {\n const raw = this.storage.getItem(KAFKA_CLUSTER_CATALOG_KEY);\n if (!raw) return;\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return;\n for (const [contextId, value] of Object.entries(parsed)) {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) continue;\n const candidate = value as Partial<StoredCatalog>;\n const discovered = Array.isArray(candidate.discovered)\n ? candidate.discovered.filter((entry): entry is DiscoveredKafkaInfo =>\n Boolean(\n entry &&\n typeof entry === \"object\" &&\n typeof (entry as DiscoveredKafkaInfo).targetId === \"string\" &&\n typeof (entry as DiscoveredKafkaInfo).bootstrap === \"string\",\n ),\n )\n : [];\n this.catalogs.set(contextId, {\n discovered,\n missing: Array.isArray(candidate.missing)\n ? candidate.missing.filter((entry): entry is DiscoveredKafkaInfo =>\n Boolean(\n entry &&\n typeof entry === \"object\" &&\n typeof (entry as DiscoveredKafkaInfo).targetId === \"string\" &&\n typeof (entry as DiscoveredKafkaInfo).bootstrap === \"string\",\n ),\n )\n : [],\n lastScanAt: typeof candidate.lastScanAt === \"number\" ? candidate.lastScanAt : undefined,\n autoScan: candidate.autoScan === true,\n });\n }\n } catch {\n this.catalogs.clear();\n }\n }\n\n private persist(): void {\n try {\n this.storage.setItem(KAFKA_CLUSTER_CATALOG_KEY, JSON.stringify(Object.fromEntries(this.catalogs)));\n } catch {\n // Catalog persistence is best effort; the current renderer keeps working in memory.\n }\n }\n}\n","import { splitBootstrap } from \"./reachability\";\n\nfunction hashIdentity(value: string): string {\n let first = 0x811c9dc5;\n let second = 0x9e3779b9;\n\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n first = Math.imul(first ^ code, 0x01000193);\n second = Math.imul(second ^ code, 0x85ebca6b);\n }\n\n return [first, second].map((part) => (part >>> 0).toString(16).padStart(8, \"0\")).join(\"\");\n}\n\nexport function canonicalKafkaBootstrap(bootstrap: string): string {\n const brokers = splitBootstrap(bootstrap).map((broker) => {\n const separator = broker.lastIndexOf(\":\");\n const host = broker.slice(0, separator).trim().toLowerCase().replace(/\\.$/, \"\");\n const port = broker.slice(separator + 1);\n return `${host}:${port}`;\n });\n\n return [...new Set(brokers)].sort().join(\",\");\n}\n\nexport function createKafkaTargetId(bootstrap: string): string {\n const identity = canonicalKafkaBootstrap(bootstrap);\n if (!identity) throw new Error(\"Kafka bootstrap is required to create a target ID\");\n return `kafka-${hashIdentity(identity)}`;\n}\n","import { createKafkaTargetId } from \"../common/kafka-target\";\n\nimport type { DiscoveredKafkaInfo } from \"../common/ipc\";\nimport type { KafkaSelectionStorage } from \"./kafka-navigation\";\n\nexport const MANUAL_ENDPOINTS_KEY = \"freelens-kafka.manual-endpoints.v1\";\n\nexport function loadManualKafkaEndpoints(storage: KafkaSelectionStorage): DiscoveredKafkaInfo[] {\n try {\n const stored = storage.getItem(MANUAL_ENDPOINTS_KEY);\n if (!stored) return [];\n const parsed = JSON.parse(stored) as unknown;\n if (!Array.isArray(parsed)) return [];\n\n const migrated = parsed\n .filter((entry): entry is Partial<DiscoveredKafkaInfo> & { bootstrap: string } =>\n Boolean(entry && typeof entry === \"object\" && typeof entry.bootstrap === \"string\"),\n )\n .map((entry) => ({ ...entry, targetId: createKafkaTargetId(entry.bootstrap) }) as DiscoveredKafkaInfo);\n\n return [...new Map(migrated.map((entry) => [entry.targetId, entry])).values()];\n } catch {\n return [];\n }\n}\n\nexport function saveManualKafkaEndpoints(storage: KafkaSelectionStorage, endpoints: DiscoveredKafkaInfo[]): void {\n try {\n storage.setItem(MANUAL_ENDPOINTS_KEY, JSON.stringify(endpoints));\n } catch {\n // A locked-down renderer may disable storage; endpoints still work for this session.\n }\n}\n\nexport function mergeKafkaClusters(\n discovered: DiscoveredKafkaInfo[],\n manual: DiscoveredKafkaInfo[],\n): DiscoveredKafkaInfo[] {\n const merged = new Map(discovered.map((cluster) => [cluster.targetId, cluster]));\n for (const cluster of manual) {\n if (!merged.has(cluster.targetId)) merged.set(cluster.targetId, cluster);\n }\n return [...merged.values()];\n}\n","export const KAFKA_PAGE_IDS = {\n clusters: \"kafka-clusters\",\n overview: \"kafka-overview\",\n topics: \"kafka-topics\",\n groups: \"kafka-groups\",\n brokers: \"kafka-brokers\",\n schemas: \"kafka-schema-registry\",\n connect: \"kafka-connect\",\n acls: \"kafka-acls\",\n} as const;\n\nexport const KAFKA_RELOAD_ROUTE_KEY = \"freelens-kafka.reload-route.v1\";\nconst KAFKA_RELOAD_ROUTE_MAX_AGE_MS = 5 * 60_000;\nconst kafkaRendererSessionId = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\nexport interface KafkaReloadRoute {\n pageId: KafkaPageId;\n params: Record<string, string>;\n}\n\ninterface KafkaReloadRouteSnapshot extends KafkaReloadRoute {\n rendererSessionId: string;\n savedAt: number;\n}\n\ninterface KafkaReloadRouteStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nexport function saveKafkaReloadRoute(\n route: KafkaReloadRoute,\n storage: KafkaReloadRouteStorage = window.localStorage,\n rendererSessionId = kafkaRendererSessionId,\n savedAt = Date.now(),\n): void {\n try {\n storage.setItem(KAFKA_RELOAD_ROUTE_KEY, JSON.stringify({ ...route, rendererSessionId, savedAt }));\n } catch {\n // Route restoration is best effort when storage is unavailable.\n }\n}\n\nexport function readKafkaReloadRoute(\n storage: KafkaReloadRouteStorage = window.localStorage,\n rendererSessionId = kafkaRendererSessionId,\n now = Date.now(),\n): KafkaReloadRoute | undefined {\n try {\n const value = storage.getItem(KAFKA_RELOAD_ROUTE_KEY);\n if (!value) return undefined;\n const route = JSON.parse(value) as KafkaReloadRouteSnapshot;\n if (\n !route ||\n typeof route.pageId !== \"string\" ||\n !route.params ||\n typeof route.params !== \"object\" ||\n typeof route.rendererSessionId !== \"string\" ||\n typeof route.savedAt !== \"number\" ||\n route.rendererSessionId === rendererSessionId ||\n now - route.savedAt > KAFKA_RELOAD_ROUTE_MAX_AGE_MS\n ) {\n storage.removeItem(KAFKA_RELOAD_ROUTE_KEY);\n return undefined;\n }\n return { pageId: route.pageId, params: route.params };\n } catch {\n return undefined;\n }\n}\n\nexport function clearKafkaReloadRoute(storage: KafkaReloadRouteStorage = window.localStorage): void {\n try {\n storage.removeItem(KAFKA_RELOAD_ROUTE_KEY);\n } catch {\n // Route restoration is best effort when storage is unavailable.\n }\n}\n\nexport type KafkaPageId = (typeof KAFKA_PAGE_IDS)[keyof typeof KAFKA_PAGE_IDS];\nexport type KafkaTopicView = \"overview\" | \"messages\" | \"partitions\" | \"consumers\" | \"configuration\";\nexport type ImplementedKafkaTopicView = Extract<\n KafkaTopicView,\n \"overview\" | \"messages\" | \"partitions\" | \"consumers\" | \"configuration\"\n>;\n\nexport interface KafkaNavigationTarget {\n pageId: KafkaPageId;\n params: Record<string, string>;\n}\n\nexport interface KafkaTargetReference {\n targetId: string;\n}\n\nexport type KafkaClusterSelection<T extends KafkaTargetReference> =\n | { state: \"empty\" }\n | { state: \"required\" }\n | { state: \"selected\"; target: T; source: \"requested\" | \"remembered\" | \"single\" };\n\nexport interface KafkaSelectionStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport interface KafkaQueryParam {\n set(value: string, options: { replaceHistory: boolean }): void;\n}\n\nexport const KAFKA_SELECTIONS_KEY = \"freelens-kafka.selected-clusters.v1\";\n\nfunction readSelections(storage: KafkaSelectionStorage): Record<string, string> {\n try {\n const value = storage.getItem(KAFKA_SELECTIONS_KEY);\n if (!value) return {};\n const parsed = JSON.parse(value) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n return Object.fromEntries(\n Object.entries(parsed).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\" && /^kafka-[a-f0-9]{16}$/.test(entry[1]),\n ),\n );\n } catch {\n return {};\n }\n}\n\nfunction writeSelections(storage: KafkaSelectionStorage, selections: Record<string, string>): void {\n try {\n storage.setItem(KAFKA_SELECTIONS_KEY, JSON.stringify(selections));\n } catch {\n // Selection persistence is optional; current-session navigation remains usable.\n }\n}\n\nexport function rememberedKafkaTargetId(\n storage: KafkaSelectionStorage,\n kubernetesClusterId: string,\n): string | undefined {\n return readSelections(storage)[kubernetesClusterId];\n}\n\nexport function rememberKafkaClusterSelection(\n storage: KafkaSelectionStorage,\n kubernetesClusterId: string,\n target: KafkaTargetReference,\n): void {\n if (!kubernetesClusterId || !/^kafka-[a-f0-9]{16}$/.test(target.targetId)) return;\n writeSelections(storage, { ...readSelections(storage), [kubernetesClusterId]: target.targetId });\n}\n\nexport function forgetKafkaClusterSelection(\n storage: KafkaSelectionStorage,\n kubernetesClusterId: string,\n expectedTargetId?: string,\n): void {\n const selections = readSelections(storage);\n if (!(kubernetesClusterId in selections)) return;\n if (expectedTargetId && selections[kubernetesClusterId] !== expectedTargetId) return;\n const { [kubernetesClusterId]: _removed, ...remaining } = selections;\n writeSelections(storage, remaining);\n}\n\nexport function resolveKafkaClusterSelection<T extends KafkaTargetReference>(\n targets: T[],\n requestedTargetId?: string,\n rememberedTargetId?: string,\n): KafkaClusterSelection<T> {\n if (targets.length === 0) return { state: \"empty\" };\n\n const requested = targets.find((target) => target.targetId === requestedTargetId);\n if (requested) return { state: \"selected\", target: requested, source: \"requested\" };\n\n const remembered = targets.find((target) => target.targetId === rememberedTargetId);\n if (remembered) return { state: \"selected\", target: remembered, source: \"remembered\" };\n\n const uniqueTargets = [...new Map(targets.map((target) => [target.targetId, target])).values()];\n if (uniqueTargets.length === 1) return { state: \"selected\", target: uniqueTargets[0], source: \"single\" };\n return { state: \"required\" };\n}\n\nexport function openKafkaCluster(targetId: string): KafkaNavigationTarget {\n return { pageId: KAFKA_PAGE_IDS.overview, params: { target: targetId } };\n}\n\nexport function openKafkaTopic(targetId: string, topic: string, view: KafkaTopicView): KafkaNavigationTarget {\n return { pageId: KAFKA_PAGE_IDS.topics, params: { target: targetId, topic, view } };\n}\n\nexport function implementedKafkaTopicView(view?: string): ImplementedKafkaTopicView {\n return view === \"messages\" || view === \"partitions\" || view === \"consumers\" || view === \"configuration\"\n ? view\n : \"overview\";\n}\n\nexport function switchKafkaCluster(pageId: KafkaPageId, targetId: string): KafkaNavigationTarget {\n if (pageId === KAFKA_PAGE_IDS.clusters) return openKafkaCluster(targetId);\n return { pageId, params: { target: targetId } };\n}\n\nexport function updateKafkaClusterQuery(param: KafkaQueryParam | undefined, query: string): void {\n param?.set(query, { replaceHistory: true });\n}\n","export type KafkaEtaStatus = \"complete\" | \"ready\" | \"stalled\" | \"unavailable\" | \"warming\";\n\nexport interface KafkaEtaEstimatorState {\n firstAt?: number;\n lastAt?: number;\n lastCompleted?: number;\n lastProgressAt?: number;\n phase?: string;\n positiveSamples: number;\n smoothedRatePerMs?: number;\n total?: number;\n}\n\nexport interface KafkaEtaSample {\n at: number;\n completed?: number;\n phase: string;\n total?: number;\n}\n\nexport interface KafkaEtaEstimate {\n etaMs?: number;\n state: KafkaEtaEstimatorState;\n status: KafkaEtaStatus;\n}\n\nexport interface KafkaEtaOptions {\n alpha?: number;\n minElapsedMs?: number;\n minFraction?: number;\n minPositiveSamples?: number;\n stallMs?: number;\n}\n\nexport function kafkaPhasePercent(options: {\n completed?: number;\n complete?: boolean;\n total?: number;\n}): number | undefined {\n if (options.complete) return 100;\n if (options.total === undefined || options.completed === undefined) return undefined;\n if (options.total <= 0) return 100;\n const ratio = options.completed / options.total;\n return Math.max(0, Math.min(100, Math.round(ratio * 100)));\n}\n\nexport function updateKafkaEta(\n previous: KafkaEtaEstimatorState,\n sample: KafkaEtaSample,\n {\n alpha = 0.35,\n minElapsedMs = 1_000,\n minFraction = 0.2,\n minPositiveSamples = 2,\n stallMs = 10_000,\n }: KafkaEtaOptions = {},\n): KafkaEtaEstimate {\n const completed = sample.completed;\n const total = sample.total;\n if (completed === undefined || total === undefined || total <= 0) {\n return {\n state: { phase: sample.phase, positiveSamples: 0, total },\n status: total === 0 ? \"complete\" : \"unavailable\",\n ...(total === 0 ? { etaMs: 0 } : {}),\n };\n }\n\n const reset =\n previous.phase !== sample.phase ||\n previous.total !== total ||\n previous.lastAt === undefined ||\n previous.lastCompleted === undefined ||\n sample.at < previous.lastAt ||\n completed < previous.lastCompleted;\n if (reset) {\n return {\n state: {\n firstAt: sample.at,\n lastAt: sample.at,\n lastCompleted: completed,\n lastProgressAt: sample.at,\n phase: sample.phase,\n positiveSamples: 0,\n total,\n },\n status: completed >= total ? \"complete\" : \"warming\",\n ...(completed >= total ? { etaMs: 0 } : {}),\n };\n }\n\n const previousLastAt = previous.lastAt as number;\n const previousLastCompleted = previous.lastCompleted as number;\n const deltaMs = sample.at - previousLastAt;\n const deltaCompleted = completed - previousLastCompleted;\n let smoothedRatePerMs = previous.smoothedRatePerMs;\n let positiveSamples = previous.positiveSamples;\n let lastProgressAt = previous.lastProgressAt ?? previousLastAt;\n if (deltaMs > 0 && deltaCompleted > 0) {\n const instantRate = deltaCompleted / deltaMs;\n smoothedRatePerMs =\n smoothedRatePerMs === undefined\n ? instantRate\n : Math.max(0, Math.min(1, alpha)) * instantRate + (1 - Math.max(0, Math.min(1, alpha))) * smoothedRatePerMs;\n positiveSamples++;\n lastProgressAt = sample.at;\n }\n\n const state: KafkaEtaEstimatorState = {\n ...previous,\n lastAt: sample.at,\n lastCompleted: completed,\n lastProgressAt,\n positiveSamples,\n smoothedRatePerMs,\n };\n if (completed >= total) return { etaMs: 0, state, status: \"complete\" };\n if (sample.at - lastProgressAt >= stallMs) return { state, status: \"stalled\" };\n\n const elapsedMs = sample.at - (previous.firstAt ?? sample.at);\n const fraction = completed / total;\n if (\n elapsedMs < minElapsedMs ||\n fraction < minFraction ||\n positiveSamples < minPositiveSamples ||\n smoothedRatePerMs === undefined ||\n smoothedRatePerMs <= 0\n ) {\n return { state, status: \"warming\" };\n }\n\n return {\n etaMs: Math.max(0, Math.round((total - completed) / smoothedRatePerMs)),\n state,\n status: \"ready\",\n };\n}\n\nexport function formatKafkaEta(etaMs: number): string {\n if (etaMs < 1_000) return \"<1s remaining\";\n const seconds = Math.ceil(etaMs / 1_000);\n if (seconds < 60) return `${seconds}s remaining`;\n const minutes = Math.ceil(seconds / 60);\n return `${minutes}m remaining`;\n}\n","import { isExactAggregateHealth } from \"../common/aggregate-health-snapshot\";\nimport { kafkaPhasePercent } from \"../common/kafka-phase-progress\";\n\nimport type {\n ClusterOverviewHealthDto,\n DiscoveredKafkaInfo,\n KafkaMessageBytesDto,\n KafkaProgressEvent,\n KafkaProgressOperation,\n KafkaRecordDto,\n TopicPartitionDto,\n} from \"../common/ipc\";\n\nexport interface KafkaUsageSummary {\n primary: string;\n secondary: string;\n title: string;\n sortValue: string;\n workloadCount: number;\n namespaceCount: number;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? \"\" : \"s\"}`;\n}\n\nexport function kafkaUsageSummary(kafka: DiscoveredKafkaInfo): KafkaUsageSummary {\n if (kafka.source === \"manual\") {\n return {\n primary: \"Manual endpoint\",\n secondary: \"Not Kubernetes-owned\",\n title: \"Added manually; no Kubernetes workload usage is known.\",\n sortValue: \"manual\",\n workloadCount: 0,\n namespaceCount: 0,\n };\n }\n\n if (kafka.source === \"workload\" && kafka.referencedBy?.length) {\n const namespaces = [\n ...new Set(kafka.referencedBy.map((reference) => reference.split(\"/\")[0]).filter(Boolean)),\n ].sort();\n const workloadCount = kafka.referencedBy.length;\n return {\n primary: plural(workloadCount, \"workload\"),\n secondary: plural(namespaces.length, \"namespace\"),\n title: `Used across: ${namespaces.join(\", \")}`,\n sortValue: `${String(namespaces.length).padStart(5, \"0\")}/${String(workloadCount).padStart(5, \"0\")}`,\n workloadCount,\n namespaceCount: namespaces.length,\n };\n }\n\n const namespace = kafka.namespace || \"default\";\n const source = kafka.source === \"strimzi\" ? \"Strimzi resource\" : kafka.source === \"service\" ? \"Service\" : \"Resource\";\n return {\n primary: namespace,\n secondary: `${source} namespace`,\n title: `${source} is defined in Kubernetes namespace ${namespace}.`,\n sortValue: namespace.toLowerCase(),\n workloadCount: 0,\n namespaceCount: 1,\n };\n}\n\nexport function kafkaUsageContext(kafka: DiscoveredKafkaInfo): string {\n const usage = kafkaUsageSummary(kafka);\n if (kafka.source === \"workload\") return `Used by ${usage.primary} across ${usage.secondary}`;\n if (kafka.source === \"manual\") return \"Manual endpoint · not referenced by Kubernetes\";\n return `${usage.secondary}: ${usage.primary}`;\n}\n\nexport function createOperationId(operation: KafkaProgressOperation): string {\n return `${operation}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function clusterHealthMetricValue<T extends number | string>(\n state: { loading: boolean; error?: string },\n measured: T | undefined,\n progressive = false,\n): T | \"Updating\" | \"Unavailable\" | \"—\" {\n if (progressive && measured !== undefined) return measured;\n if (state.loading) return \"Updating\";\n if (state.error) return \"Unavailable\";\n return measured ?? \"—\";\n}\n\nexport function kafkaProgressPhasePercent(\n progress: Pick<KafkaProgressEvent, \"completed\" | \"phasePercent\" | \"total\" | \"value\">,\n): number | undefined {\n return (\n progress.phasePercent ??\n kafkaPhasePercent({\n completed: progress.completed,\n complete: progress.value >= 100,\n total: progress.total,\n })\n );\n}\n\nexport function kafkaProgressIsDeterminate(\n progress: Pick<KafkaProgressEvent, \"completed\" | \"phasePercent\" | \"total\" | \"value\">,\n): boolean {\n return kafkaProgressPhasePercent(progress) !== undefined;\n}\n\nexport function kafkaProgressCount(progress: Pick<KafkaProgressEvent, \"completed\" | \"total\">): string | undefined {\n return progress.total === undefined ? undefined : `${progress.completed ?? 0}/${progress.total}`;\n}\n\nexport function kafkaHealthCompletionMetadata(\n current: { source?: \"cache\" | \"network\" | \"persisted\"; updatedAt?: number },\n fallbackUpdatedAt?: number,\n): { source: \"cache\" | \"network\" | \"persisted\"; updatedAt?: number } {\n return {\n source: current.source ?? \"network\",\n updatedAt: current.updatedAt ?? fallbackUpdatedAt,\n };\n}\n\nexport function kafkaHealthProgressIsCompact(\n progress: Pick<KafkaProgressEvent, \"operation\" | \"phase\">,\n error?: string,\n hasSnapshot = false,\n): boolean {\n return (\n !error &&\n progress.operation === \"health\" &&\n (hasSnapshot || [\"topology\", \"groups\", \"watermarks\"].includes(progress.phase))\n );\n}\n\nexport function kafkaHealthCoverageLabel(health: ClusterOverviewHealthDto | undefined): string {\n if (!health) return \"Waiting for first result\";\n const coverage = health.consumerGroupLagCoverage;\n if (!coverage) return \"Coverage unavailable\";\n const exact = isExactAggregateHealth(health);\n const unavailableTopics = health.consumerGroupLagUnavailableTopics ?? 0;\n const unavailableGroups = health.consumerGroupLagUnavailableGroups ?? coverage.unavailableGroups;\n const unavailable = [\n unavailableGroups > 0 ? `${unavailableGroups} group${unavailableGroups === 1 ? \"\" : \"s\"} unavailable` : undefined,\n unavailableTopics > 0 ? `${unavailableTopics} topic${unavailableTopics === 1 ? \"\" : \"s\"} unavailable` : undefined,\n ].filter((value): value is string => Boolean(value));\n return `${exact ? \"Exact\" : \"Lower bound\"} · ${coverage.resolvedGroups}/${coverage.totalGroups} groups${\n unavailable.length > 0 ? ` · ${unavailable.join(\", \")}` : \"\"\n }`;\n}\n\nexport function kafkaHealthCoverageState(\n health: Partial<ClusterOverviewHealthDto> | undefined,\n): \"exact\" | \"lower-bound\" | \"unavailable\" {\n if (!health?.consumerGroupLagCoverage) return \"unavailable\";\n return isExactAggregateHealth(health) ? \"exact\" : \"lower-bound\";\n}\n\nexport function kafkaHealthNeedsCoverageNotice(health: Partial<ClusterOverviewHealthDto> | undefined): boolean {\n if (!health?.consumerGroupLag || health.consumerGroupLag === \"—\") return false;\n return !isExactAggregateHealth(health);\n}\n\nexport function filterTopicNames(topics: string[], query: string): string[] {\n const normalizedQuery = query.trim().toLowerCase();\n return topics\n .filter((topic) => !normalizedQuery || topic.toLowerCase().includes(normalizedQuery))\n .sort((left, right) => left.localeCompare(right));\n}\n\nexport function kafkaDecimalSortKey(value: string): [number, string] {\n return value === \"—\" ? [-1, \"\"] : [value.length, value];\n}\n\nfunction messageBytesSearchText(bytes: KafkaMessageBytesDto): string {\n return [bytes.text, bytes.base64].filter((value): value is string => value !== undefined).join(\" \");\n}\n\nfunction matchesFilter(value: string, filter: string): boolean {\n const trimmed = filter.trim();\n if (!trimmed) return true;\n if (!trimmed.startsWith(\"/\") || trimmed.lastIndexOf(\"/\") <= 0) {\n return value.toLowerCase().includes(trimmed.toLowerCase());\n }\n\n const lastSlash = trimmed.lastIndexOf(\"/\");\n try {\n return new RegExp(trimmed.slice(1, lastSlash), trimmed.slice(lastSlash + 1)).test(value);\n } catch {\n return false;\n }\n}\n\nexport interface KafkaMessageFilters {\n key: string;\n value: string;\n headerKey: string;\n headerValue: string;\n}\n\nexport function matchesKafkaMessageFilters(message: KafkaRecordDto, filters: KafkaMessageFilters): boolean {\n if (!matchesFilter(messageBytesSearchText(message.key), filters.key)) return false;\n if (!matchesFilter(messageBytesSearchText(message.value), filters.value)) return false;\n\n const headerKey = filters.headerKey.trim().toLowerCase();\n if (!headerKey) return true;\n return message.headers.some(\n (header) =>\n header.name.toLowerCase() === headerKey &&\n matchesFilter(messageBytesSearchText(header.value), filters.headerValue),\n );\n}\n\nexport function topicPartitionHealth(partition: TopicPartitionDto): \"Healthy\" | \"Under-replicated\" | \"Unavailable\" {\n if (partition.unavailable) return \"Unavailable\";\n if (partition.underReplicated) return \"Under-replicated\";\n return \"Healthy\";\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { aggregateHealthSnapshotKey } from \"../common/aggregate-health-snapshot\";\nimport { kafkaPersistentStateStore } from \"../common/kafka-persistent-state-store\";\nimport { formatKafkaEta } from \"../common/kafka-phase-progress\";\nimport { createKafkaTargetId } from \"../common/kafka-target\";\nimport { chooseStrategy, firstBrokerAddress } from \"../common/reachability\";\nimport { KafkaClusterCatalogStore } from \"./kafka-cluster-catalog\";\nimport { loadManualKafkaEndpoints, mergeKafkaClusters, saveManualKafkaEndpoints } from \"./kafka-manual-endpoints\";\nimport { forgetKafkaClusterSelection, rememberKafkaClusterSelection } from \"./kafka-navigation\";\nimport { KafkaMetricStrip, KafkaPageShell } from \"./kafka-page-shell\";\nimport {\n createOperationId,\n kafkaHealthProgressIsCompact,\n kafkaProgressCount,\n kafkaProgressIsDeterminate,\n kafkaProgressPhasePercent,\n kafkaUsageContext,\n kafkaUsageSummary,\n topicPartitionHealth,\n} from \"./kafka-view-model\";\n\nimport type { CSSProperties, HTMLAttributes } from \"react\";\n\nimport type {\n ClusterOverviewDto,\n DiscoveredKafkaInfo,\n DiscoverRequest,\n KafkaAuthMode,\n KafkaProgressEvent,\n KafkaProgressOperation,\n KafkaSecurityHint,\n KafkaSecurityOverride,\n KafkaTlsMode,\n OverviewRequest,\n TopicDetailDto,\n TopicPartitionDto,\n} from \"../common/ipc\";\nimport type { KafkaConnectSettingsStore } from \"./kafka-connect-settings\";\nimport type { KafkaConnectionSettingsStore } from \"./kafka-connection-settings\";\nimport type { KafkaResourceCache } from \"./kafka-resource-cache\";\nimport type { KafkaSchemaRegistrySettingsStore } from \"./kafka-schema-registry-settings\";\nimport type { KafkaWriteSettingsStore } from \"./kafka-write-settings\";\n\nexport interface KafkaOverviewPageProps {\n connectionSettings: KafkaConnectionSettingsStore;\n writeSettings: KafkaWriteSettingsStore;\n schemaRegistrySettings: KafkaSchemaRegistrySettingsStore;\n connectSettings: KafkaConnectSettingsStore;\n kubernetesClusterId?: string;\n resourceCache: KafkaResourceCache;\n query?: string;\n onQueryChange?: (query: string) => void;\n onOpenCluster: (cluster: DiscoveredKafkaInfo) => void;\n discover: (request?: DiscoverRequest) => Promise<DiscoveredKafkaInfo[]>;\n overview: (request: OverviewRequest) => Promise<ClusterOverviewDto>;\n invalidateHealth: (\n targetId: string,\n options: { closeSessions?: boolean; removePersisted?: boolean },\n ) => Promise<void>;\n reachability: (bootstraps: string[]) => Promise<Record<string, boolean>>;\n subscribeProgress: (listener: (progress: KafkaProgressEvent) => void) => () => void;\n}\n\ninterface DiscoveryState {\n loading: boolean;\n error?: string;\n kafkas: DiscoveredKafkaInfo[];\n}\n\ninterface DetailState {\n loading: boolean;\n error?: string;\n data?: ClusterOverviewDto;\n progress?: KafkaProgressEvent;\n}\n\nexport interface TopicState {\n name?: string;\n loading: boolean;\n error?: string;\n data?: TopicDetailDto;\n progress?: KafkaProgressEvent;\n}\n\ntype ReachabilityFilter = \"all\" | \"pc\" | \"pods\";\n\nconst TLS_MODE_OPTIONS: Renderer.Component.SelectOption<KafkaTlsMode>[] = [\n { value: \"auto\", label: \"Automatic\" },\n { value: \"enabled\", label: \"TLS enabled\" },\n { value: \"disabled\", label: \"TLS disabled\" },\n];\n\nconst AUTH_MODE_OPTIONS: Renderer.Component.SelectOption<KafkaAuthMode>[] = [\n { value: \"auto\", label: \"Automatic\" },\n { value: \"none\", label: \"No authentication\" },\n { value: \"plain\", label: \"SASL/PLAIN\" },\n { value: \"scram-sha-256\", label: \"SCRAM-SHA-256\" },\n { value: \"scram-sha-512\", label: \"SCRAM-SHA-512\" },\n];\n\nconst sourceLabel = (kafka: DiscoveredKafkaInfo): string => kafka.provider ?? kafka.source;\n\nexport function ReachabilityBadge({ value, label }: { value?: boolean; label?: boolean }) {\n if (value === undefined) {\n return (\n <Renderer.Component.Badge\n className=\"KafkaStatusBadge checking\"\n small\n label={\n <>\n <Renderer.Component.Icon material=\"schedule\" />\n <span>Checking</span>\n </>\n }\n />\n );\n }\n\n const text = label ? (value ? \"Reachable\" : \"Unavailable\") : value ? \"Yes\" : \"No\";\n return (\n <Renderer.Component.Badge\n className={`KafkaStatusBadge ${value ? \"reachable\" : \"unreachable\"}`}\n small\n label={\n <>\n <Renderer.Component.Icon material={value ? \"check_circle\" : \"cancel\"} />\n <span>{text}</span>\n </>\n }\n />\n );\n}\n\nfunction PodReachabilityBadge({ kafka, label }: { kafka: DiscoveredKafkaInfo; label?: boolean }) {\n if (kafka.source === \"manual\") {\n return (\n <Renderer.Component.Badge\n className=\"KafkaStatusBadge unknown\"\n small\n label={\n <>\n <Renderer.Component.Icon material=\"help_outline\" />\n <span>Unknown</span>\n </>\n }\n />\n );\n }\n return <ReachabilityBadge value={true} label={label} />;\n}\n\nexport function SourceBadge({ kafka }: { kafka: DiscoveredKafkaInfo }) {\n const icon =\n kafka.source === \"manual\" ? \"add_link\" : kafka.external ? \"cloud\" : kafka.source === \"strimzi\" ? \"hub\" : \"dns\";\n return (\n <Renderer.Component.Badge\n className={`KafkaSourceBadge source-${kafka.source}`}\n small\n label={\n <>\n <Renderer.Component.Icon material={icon} />\n <span>{sourceLabel(kafka)}</span>\n </>\n }\n title={kafka.external ? \"External Kafka\" : \"Kubernetes cluster Kafka\"}\n />\n );\n}\n\nfunction securityLabel(security: KafkaSecurityHint): string {\n if (security.auth === \"mtls\") return \"mTLS\";\n if (security.auth === \"none\") return security.tls ? \"TLS\" : \"PLAINTEXT\";\n const auth = security.auth === \"plain\" ? \"PLAIN\" : security.auth.toUpperCase();\n return security.tls ? `${auth} · TLS` : auth;\n}\n\nexport function SecurityBadge({ security }: { security: KafkaSecurityHint }) {\n const icon = security.auth === \"mtls\" ? \"verified_user\" : security.tls ? \"lock\" : \"lock_open\";\n return (\n <Renderer.Component.Badge\n className={`KafkaTlsBadge ${security.tls ? \"enabled\" : \"disabled\"}`}\n small\n label={\n <>\n <Renderer.Component.Icon material={icon} />\n <span>{securityLabel(security)}</span>\n </>\n }\n />\n );\n}\n\nconst PROGRESS_STEPS = {\n discovery: [\"Cluster\", \"Resources\", \"Workloads\", \"Merge\"],\n overview: [\"Security\", \"Connection\", \"Brokers\", \"Topics\"],\n health: [\"Connection\", \"Topology\", \"Groups\", \"Lag\"],\n topic: [\"Security\", \"Connection\", \"Metadata\", \"Ready\"],\n topicConfig: [\"Security\", \"Connection\", \"Configuration\", \"Ready\"],\n topicConsumers: [\"Security\", \"Connection\", \"Groups\", \"Ready\"],\n brokerConfig: [\"Security\", \"Connection\", \"Configuration\", \"Ready\"],\n messagesBrowse: [\"Security\", \"Connection\", \"Offsets\", \"Records\"],\n groups: [\"Security\", \"Connection\", \"Groups\", \"Ready\"],\n groupDetail: [\"Security\", \"Connection\", \"Offsets\", \"Ready\"],\n} as const satisfies Record<KafkaProgressOperation, readonly string[]>;\n\nfunction progressStep(progress: KafkaProgressEvent): number {\n if (progress.operation === \"discovery\") {\n if (progress.value >= 97) return 3;\n if (progress.value >= 23) return 2;\n if (progress.value >= 13) return 1;\n return 0;\n }\n if (progress.operation === \"topic\") {\n if (progress.value >= 98) return 3;\n if (progress.value >= 78) return 2;\n if (progress.value >= 46) return 1;\n return 0;\n }\n if (progress.operation === \"messagesBrowse\") {\n if (progress.value >= 100) return 3;\n if (progress.value >= 62) return 2;\n if (progress.value >= 46) return 1;\n return 0;\n }\n if (progress.operation === \"health\") {\n if (progress.phase === \"complete\" || progress.phase === \"watermarks\") return 3;\n if (progress.phase === \"groups\") return 2;\n if (progress.phase === \"topology\" || progress.phase === \"health\") return 1;\n return 0;\n }\n if (\n progress.operation === \"topicConfig\" ||\n progress.operation === \"topicConsumers\" ||\n progress.operation === \"brokerConfig\" ||\n progress.operation === \"groups\" ||\n progress.operation === \"groupDetail\"\n ) {\n if (progress.value >= 100) return 3;\n if (progress.value >= 62) return 2;\n if (progress.value >= 46) return 1;\n return 0;\n }\n if (progress.value >= 88) return 3;\n if (progress.value >= 72) return 2;\n if (progress.value >= 46) return 1;\n return 0;\n}\n\nexport function OperationProgress({ progress, error }: { progress: KafkaProgressEvent; error?: string }) {\n const activeStep = progressStep(progress);\n const phasePercent = kafkaProgressPhasePercent(progress);\n const determinate = kafkaProgressIsDeterminate(progress);\n const steps = PROGRESS_STEPS[progress.operation];\n const progressUnit =\n progress.operation === \"discovery\" || progress.phase === \"security\"\n ? \"workloads\"\n : progress.operation === \"health\" && (progress.phase === \"topology\" || progress.phase === \"watermarks\")\n ? \"topics\"\n : \"groups\";\n return (\n <div\n className={`KafkaOperationProgress ${error ? \"error\" : \"\"}`}\n role=\"status\"\n aria-live=\"polite\"\n data-operation={progress.operation}\n data-phase={progress.phase}\n data-operation-state={progress.label}\n data-progress={phasePercent}\n data-progress-mode={determinate ? \"determinate\" : \"indeterminate\"}\n data-eta-ms={progress.etaMs}\n data-eta-state={progress.etaStatus ?? \"unavailable\"}\n data-elapsed-ms={progress.elapsedMs}\n data-phase-elapsed-ms={progress.phaseElapsedMs}\n data-stage-duration-ms={progress.stageDurationMs}\n data-completed={progress.completed}\n data-total={progress.total}\n >\n <div className=\"KafkaProgressHeader\">\n <div>\n <strong>{progress.label}</strong>\n {progress.detail && <span>{progress.detail}</span>}\n </div>\n <div className=\"KafkaProgressMeasure\">\n <strong>{determinate ? `${phasePercent}% of phase` : \"Updating\"}</strong>\n {progress.etaStatus === \"ready\" && progress.etaMs !== undefined && (\n <span data-testid=\"kafka-progress-eta\">{formatKafkaEta(progress.etaMs)}</span>\n )}\n </div>\n </div>\n <Renderer.Component.LineProgress\n className={`KafkaProgressLine ${determinate ? \"\" : \"indeterminate\"}`.trim()}\n min={0}\n max={100}\n value={determinate ? (phasePercent ?? 100) : 100}\n aria-label={`${progress.label} phase progress`}\n aria-valuetext={determinate ? `${phasePercent}% of phase` : \"Updating\"}\n />\n {progress.total !== undefined && (\n <div className=\"KafkaProgressCount\">\n {progress.completed ?? 0} / {progress.total} {progressUnit}\n </div>\n )}\n <ol className=\"KafkaProgressSteps\">\n {steps.map((step, index) => (\n <li key={step} className={index < activeStep ? \"complete\" : index === activeStep ? \"current\" : \"pending\"}>\n <Renderer.Component.Icon\n material={\n index < activeStep\n ? \"check_circle\"\n : index === activeStep\n ? \"radio_button_checked\"\n : \"radio_button_unchecked\"\n }\n />\n <span>{step}</span>\n </li>\n ))}\n </ol>\n {error && (\n <div className=\"KafkaProgressError\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <span>{error}</span>\n </div>\n )}\n </div>\n );\n}\n\nexport function HealthProgress({\n progress,\n error,\n hasSnapshot = false,\n}: {\n progress: KafkaProgressEvent;\n error?: string;\n hasSnapshot?: boolean;\n}) {\n const compact = kafkaHealthProgressIsCompact(progress, error, hasSnapshot);\n if (!compact) {\n return (\n <div className=\"KafkaHealthProgress\" data-testid=\"kafka-health-progress\" data-compact=\"false\">\n <OperationProgress progress={progress} error={error} />\n </div>\n );\n }\n\n const phasePercent = kafkaProgressPhasePercent(progress);\n const count = kafkaProgressCount(progress);\n const percent = phasePercent === undefined ? \"Updating\" : `${phasePercent}%`;\n const eta =\n progress.etaStatus === \"ready\" && progress.etaMs !== undefined ? formatKafkaEta(progress.etaMs) : undefined;\n const liveStatus = [progress.label, count, percent, eta]\n .filter((value): value is string => Boolean(value))\n .join(\", \");\n return (\n <details\n className=\"KafkaHealthProgress KafkaHealthProgressCompact\"\n data-testid=\"kafka-health-progress\"\n data-compact=\"true\"\n >\n <summary>\n <Renderer.Component.Icon material=\"sync\" />\n <span className=\"KafkaHealthProgressLabel\">{progress.label}</span>\n {count && <span aria-hidden=\"true\">{count}</span>}\n <strong aria-hidden=\"true\">{percent}</strong>\n {eta && <span aria-hidden=\"true\">{eta}</span>}\n <Renderer.Component.Icon material=\"expand_more\" />\n <span className=\"KafkaProgressLiveStatus\" role=\"status\" aria-live=\"polite\">\n {liveStatus}\n </span>\n </summary>\n <OperationProgress progress={progress} />\n </details>\n );\n}\n\nfunction UsageCell({ kafka }: { kafka: DiscoveredKafkaInfo }) {\n const usage = kafkaUsageSummary(kafka);\n return (\n <div className=\"KafkaUsageCell\" title={usage.title}>\n <span>{usage.primary}</span>\n <small>{usage.secondary}</small>\n </div>\n );\n}\n\nfunction PartitionHealthBadge({ partition }: { partition: TopicPartitionDto }) {\n const health = topicPartitionHealth(partition);\n const className = health.toLowerCase().replace(\"-\", \"\");\n const icon = health === \"Healthy\" ? \"check_circle\" : health === \"Under-replicated\" ? \"warning_amber\" : \"error\";\n return (\n <div className=\"KafkaPartitionHealth\">\n <Renderer.Component.Badge\n className={`KafkaPartitionBadge ${className}`}\n small\n label={\n <>\n <Renderer.Component.Icon material={icon} />\n <span>{health}</span>\n </>\n }\n />\n {partition.offlineReplicas.length > 0 && <small>Offline: {partition.offlineReplicas.join(\", \")}</small>}\n {partition.errorCode !== 0 && <small>Error code: {partition.errorCode}</small>}\n </div>\n );\n}\n\nfunction TopicMetricStrip({ data }: { data: TopicDetailDto }) {\n return (\n <KafkaMetricStrip\n ariaLabel=\"Kafka topic metadata summary\"\n className=\"KafkaTopicMetricStrip\"\n metrics={[\n { label: \"Partitions\", value: data.partitionCount },\n { label: \"Replication\", value: data.replicationFactor },\n {\n label: \"Under-replicated\",\n value: data.underReplicatedPartitions,\n tone: data.underReplicatedPartitions > 0 ? \"warning\" : undefined,\n },\n {\n label: \"Unavailable\",\n value: data.unavailablePartitions,\n tone: data.unavailablePartitions > 0 ? \"error\" : undefined,\n },\n ]}\n />\n );\n}\n\nconst PARTITION_ID_COLUMN_STYLE: CSSProperties = { flex: \"0 0 112px\", minWidth: 112, width: 112 };\nconst PARTITION_LEADER_COLUMN_STYLE: CSSProperties = { flex: \"0 0 84px\", minWidth: 84, width: 84 };\nconst PARTITION_REPLICAS_COLUMN_STYLE: CSSProperties = { flex: \"1 1 160px\", minWidth: 120, width: 0 };\nconst PARTITION_ISR_COLUMN_STYLE: CSSProperties = { flex: \"1 1 160px\", minWidth: 120, width: 0 };\nconst PARTITION_STATE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 156px\", minWidth: 156, width: 156 };\n\nfunction TopicPartitions({ data }: { data: TopicDetailDto }) {\n if (data.partitions.length === 0) {\n return <div className=\"KafkaTopicPrompt\">Kafka returned no partitions for this topic.</div>;\n }\n\n return (\n <Renderer.Component.Table<TopicPartitionDto>\n className=\"KafkaPartitionTable\"\n tableId=\"kafka-topic-partitions\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"partition\", orderBy: \"asc\" }}\n sortable={{ partition: (partition) => partition.partitionId }}\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell className=\"partitionIdCell\" sortBy=\"partition\" style={PARTITION_ID_COLUMN_STYLE}>\n Partition\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionLeaderCell\" style={PARTITION_LEADER_COLUMN_STYLE}>\n Leader\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionReplicasCell\" style={PARTITION_REPLICAS_COLUMN_STYLE}>\n Replicas\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionIsrCell\" style={PARTITION_ISR_COLUMN_STYLE}>\n ISR\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionHealthCell\" style={PARTITION_STATE_COLUMN_STYLE}>\n State\n </Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {data.partitions.map((partition) => (\n <Renderer.Component.TableRow key={partition.partitionId} sortItem={partition} nowrap>\n <Renderer.Component.TableCell className=\"partitionIdCell\" style={PARTITION_ID_COLUMN_STYLE}>\n {partition.partitionId}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionLeaderCell\" style={PARTITION_LEADER_COLUMN_STYLE}>\n {partition.leader < 0 ? \"—\" : partition.leader}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionReplicasCell\" style={PARTITION_REPLICAS_COLUMN_STYLE}>\n <span className=\"KafkaReplicaSet\">{partition.replicas.join(\", \") || \"—\"}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionIsrCell\" style={PARTITION_ISR_COLUMN_STYLE}>\n <span className=\"KafkaReplicaSet\">{partition.isr.join(\", \") || \"—\"}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"partitionHealthCell\" style={PARTITION_STATE_COLUMN_STYLE}>\n <PartitionHealthBadge partition={partition} />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n ))}\n </Renderer.Component.Table>\n );\n}\n\nexport function TopicMetadata({\n state,\n onRetry,\n view = \"all\",\n showHeader = true,\n}: {\n state: TopicState;\n onRetry: () => void;\n view?: \"all\" | \"overview\" | \"partitions\";\n showHeader?: boolean;\n}) {\n if (!state.name) {\n return (\n <div className=\"KafkaTopicPrompt\">\n <Renderer.Component.Icon material=\"topic\" />\n <span>Select a topic to inspect partition topology.</span>\n </div>\n );\n }\n\n return (\n <section className=\"KafkaTopicMetadata\" aria-label={`Topic details for ${state.name}`}>\n {showHeader && (\n <div className=\"KafkaTopicMetadataHeader\">\n <div>\n <Renderer.Component.DrawerTitle size=\"sub-title\">{state.name}</Renderer.Component.DrawerTitle>\n {state.data?.internal && (\n <Renderer.Component.Badge small className=\"KafkaInternalTopicBadge\" label=\"Internal\" />\n )}\n </div>\n {state.error && (\n <Renderer.Component.Button outlined onClick={onRetry}>\n <Renderer.Component.Icon material=\"refresh\" />\n Retry\n </Renderer.Component.Button>\n )}\n </div>\n )}\n\n {!showHeader && state.error && (\n <div className=\"KafkaTopicInlineError\" role=\"alert\">\n <span>{state.error}</span>\n <Renderer.Component.Button outlined onClick={onRetry}>\n <Renderer.Component.Icon material=\"refresh\" />\n Retry\n </Renderer.Component.Button>\n </div>\n )}\n\n {(state.loading || state.error) && state.progress && (\n <OperationProgress progress={state.progress} error={state.error} />\n )}\n\n {state.data && view !== \"partitions\" && <TopicMetricStrip data={state.data} />}\n {state.data && view !== \"overview\" && <TopicPartitions data={state.data} />}\n </section>\n );\n}\n\nfunction ConnectionSettingsDrawer({\n kafka,\n pcReachable,\n detail,\n securityOverride,\n writeSettings,\n schemaRegistrySettings,\n connectSettings,\n onApplySecurity,\n onClose,\n onRemove,\n}: {\n kafka: DiscoveredKafkaInfo;\n pcReachable?: boolean;\n detail: DetailState;\n securityOverride?: KafkaSecurityOverride;\n writeSettings: KafkaWriteSettingsStore;\n schemaRegistrySettings: KafkaSchemaRegistrySettingsStore;\n connectSettings: KafkaConnectSettingsStore;\n onApplySecurity: (security?: KafkaSecurityOverride) => void;\n onClose: () => void;\n onRemove?: () => void;\n}) {\n const [tlsMode, setTlsMode] = useState<KafkaTlsMode>(securityOverride?.tlsMode ?? \"auto\");\n const [authMode, setAuthMode] = useState<KafkaAuthMode>(securityOverride?.authMode ?? \"auto\");\n const [username, setUsername] = useState(securityOverride?.username ?? \"\");\n const [password, setPassword] = useState(securityOverride?.password ?? \"\");\n const [settingsError, setSettingsError] = useState<string>();\n const [writeModeEnabled, setWriteModeEnabled] = useState<boolean>(writeSettings.get(kafka.targetId));\n const [registryUrl, setRegistryUrl] = useState(() => schemaRegistrySettings.get(kafka.targetId)?.registryUrl ?? \"\");\n const [registryTls, setRegistryTls] = useState(() => schemaRegistrySettings.get(kafka.targetId)?.tls ?? false);\n const [registryUsername, setRegistryUsername] = useState(\n () => schemaRegistrySettings.get(kafka.targetId)?.username ?? \"\",\n );\n const [connectUrl, setConnectUrl] = useState(() => connectSettings.get(kafka.targetId)?.connectUrl ?? \"\");\n const [connectUsername, setConnectUsername] = useState(() => connectSettings.get(kafka.targetId)?.username ?? \"\");\n\n useEffect(() => {\n setTlsMode(securityOverride?.tlsMode ?? \"auto\");\n setAuthMode(securityOverride?.authMode ?? \"auto\");\n setUsername(securityOverride?.username ?? \"\");\n setPassword(securityOverride?.password ?? \"\");\n setWriteModeEnabled(writeSettings.get(kafka.targetId));\n const registry = schemaRegistrySettings.get(kafka.targetId);\n setRegistryUrl(registry?.registryUrl ?? \"\");\n setRegistryTls(registry?.tls ?? false);\n setRegistryUsername(registry?.username ?? \"\");\n const connect = connectSettings.get(kafka.targetId);\n setConnectUrl(connect?.connectUrl ?? \"\");\n setConnectUsername(connect?.username ?? \"\");\n setSettingsError(undefined);\n }, [connectSettings, kafka, schemaRegistrySettings, securityOverride, writeSettings]);\n\n const strategy = pcReachable === undefined ? undefined : chooseStrategy(kafka.source, pcReachable);\n const strategyLabel =\n strategy === \"direct\" ? \"Direct\" : strategy === \"portForward\" ? \"Port-forward\" : \"Relay required\";\n const security = detail.data?.security ?? kafka.securityHint ?? { tls: kafka.tls, auth: \"none\" };\n const explicitAuth = authMode !== \"auto\" && authMode !== \"none\";\n\n const applySettings = (): void => {\n if (explicitAuth && (!username.trim() || !password)) {\n setSettingsError(\"Username and password are required for explicit SASL authentication.\");\n return;\n }\n setSettingsError(undefined);\n if (tlsMode === \"auto\" && authMode === \"auto\") {\n onApplySecurity(undefined);\n return;\n }\n onApplySecurity({\n tlsMode,\n authMode,\n ...(explicitAuth ? { username: username.trim(), password } : {}),\n });\n };\n\n return (\n <Renderer.Component.Drawer\n className=\"KafkaConnectionSettingsDrawer\"\n contentClass=\"KafkaConnectionSettingsBody\"\n open\n usePortal\n size=\"min(520px, calc(100vw - 24px))\"\n title={`Connection settings: ${kafka.name}`}\n onClose={onClose}\n data-testid=\"kafka-connection-settings\"\n >\n <div className=\"KafkaDetailContext\">{kafkaUsageContext(kafka)}</div>\n <div className=\"KafkaDetailBadges\">\n <SourceBadge kafka={kafka} />\n <SecurityBadge security={security} />\n {writeSettings.get(kafka.targetId) && <Renderer.Component.Badge small label=\"Write mode\" />}\n </div>\n\n <Renderer.Component.DrawerItem name=\"Bootstrap\" title={kafka.bootstrap}>\n <code className=\"KafkaBootstrapDetail\">{kafka.bootstrap}</code>\n </Renderer.Component.DrawerItem>\n <Renderer.Component.DrawerItem name=\"From PC\">\n <ReachabilityBadge value={pcReachable} label />\n </Renderer.Component.DrawerItem>\n <Renderer.Component.DrawerItem name=\"From pods\">\n <PodReachabilityBadge kafka={kafka} label />\n </Renderer.Component.DrawerItem>\n <Renderer.Component.DrawerItem name=\"Connection\">\n <Renderer.Component.Badge\n className={`KafkaStrategyBadge strategy-${strategy ?? \"checking\"}`}\n small\n label={strategyLabel}\n />\n </Renderer.Component.DrawerItem>\n\n <section className=\"KafkaConnectionSettings\" aria-label=\"Kafka connection settings\">\n <h2>Write mode</h2>\n <div className=\"KafkaWriteModeRow\">\n <div>\n <strong>Enable write actions for this Kafka target</strong>\n <span>Write actions stay disabled unless this cluster is explicitly enabled.</span>\n </div>\n <Renderer.Component.Switch\n aria-label=\"Enable write mode for this Kafka target\"\n data-testid=\"kafka-write-mode-toggle\"\n checked={writeModeEnabled}\n onChange={(value) => {\n writeSettings.set(kafka.targetId, value);\n setWriteModeEnabled(value);\n }}\n />\n </div>\n </section>\n\n <section className=\"KafkaConnectionSettings\" aria-label=\"Schema Registry settings\">\n <h2>Schema Registry</h2>\n <Renderer.Component.Input\n value={registryUrl}\n onChange={setRegistryUrl}\n placeholder=\"http://127.0.0.1:18081\"\n aria-label=\"Schema Registry URL\"\n />\n <Renderer.Component.Input\n value={registryUsername}\n onChange={setRegistryUsername}\n placeholder=\"Username (optional)\"\n aria-label=\"Schema Registry username\"\n />\n <Renderer.Component.Switch\n checked={registryTls}\n onChange={setRegistryTls}\n aria-label=\"Enable Schema Registry TLS\"\n />\n <Renderer.Component.Button\n outlined\n onClick={() =>\n schemaRegistrySettings.set(kafka.targetId, {\n registryUrl,\n tls: registryTls,\n ...(registryUsername.trim() ? { username: registryUsername.trim() } : {}),\n })\n }\n >\n Save Schema Registry settings\n </Renderer.Component.Button>\n </section>\n\n <section className=\"KafkaConnectionSettings\" aria-label=\"Kafka Connect settings\">\n <h2>Kafka Connect</h2>\n <Renderer.Component.Input\n value={connectUrl}\n onChange={setConnectUrl}\n placeholder=\"http://127.0.0.1:18083\"\n aria-label=\"Kafka Connect URL\"\n />\n <Renderer.Component.Input\n value={connectUsername}\n onChange={setConnectUsername}\n placeholder=\"Username (optional)\"\n aria-label=\"Kafka Connect username\"\n />\n <Renderer.Component.Button\n outlined\n onClick={() =>\n connectSettings.set(kafka.targetId, {\n connectUrl,\n tls: false,\n ...(connectUsername.trim() ? { username: connectUsername.trim() } : {}),\n })\n }\n >\n Save Kafka Connect settings\n </Renderer.Component.Button>\n </section>\n\n <section className=\"KafkaConnectionSettings\" aria-label=\"Kafka connection settings\">\n <h2>Security override</h2>\n <form\n className=\"KafkaSecurityForm\"\n onSubmit={(event) => {\n event.preventDefault();\n applySettings();\n }}\n >\n <label>\n <span>TLS</span>\n <Renderer.Component.Select\n options={TLS_MODE_OPTIONS}\n value={tlsMode}\n onChange={(option: Renderer.Component.SelectOption<KafkaTlsMode> | null) => {\n setTlsMode(option?.value ?? \"auto\");\n setSettingsError(undefined);\n }}\n isDisabled={detail.loading}\n themeName=\"lens\"\n menuPosition=\"fixed\"\n />\n </label>\n <label>\n <span>Authentication</span>\n <Renderer.Component.Select\n options={AUTH_MODE_OPTIONS}\n value={authMode}\n onChange={(option: Renderer.Component.SelectOption<KafkaAuthMode> | null) => {\n setAuthMode(option?.value ?? \"auto\");\n setSettingsError(undefined);\n }}\n isDisabled={detail.loading}\n themeName=\"lens\"\n menuPosition=\"fixed\"\n />\n </label>\n {explicitAuth && (\n <>\n <label>\n <span>Username</span>\n <Renderer.Component.Input\n value={username}\n onChange={(value) => {\n setUsername(value);\n setSettingsError(undefined);\n }}\n disabled={detail.loading}\n autoComplete=\"username\"\n aria-label=\"Kafka SASL username\"\n aria-required=\"true\"\n />\n </label>\n <label>\n <span>Password</span>\n <Renderer.Component.Input\n type=\"password\"\n value={password}\n onChange={(value) => {\n setPassword(value);\n setSettingsError(undefined);\n }}\n disabled={detail.loading}\n autoComplete=\"current-password\"\n aria-label=\"Kafka SASL password\"\n aria-required=\"true\"\n />\n </label>\n </>\n )}\n <p>\n Automatic mode reads matching workload env, ConfigMaps and Secrets. Password overrides stay in memory only.\n </p>\n {settingsError && (\n <div className=\"KafkaSecurityError\" role=\"alert\">\n {settingsError}\n </div>\n )}\n <Renderer.Component.Button primary type=\"submit\" waiting={detail.loading}>\n <Renderer.Component.Icon material=\"sync\" />\n Apply and reconnect\n </Renderer.Component.Button>\n </form>\n </section>\n\n {onRemove && (\n <Renderer.Component.Button outlined className=\"KafkaRemoveEndpoint\" onClick={onRemove}>\n <Renderer.Component.Icon material=\"delete_outline\" />\n Remove endpoint\n </Renderer.Component.Button>\n )}\n\n {kafka.referencedBy?.length ? (\n <details className=\"KafkaReferences\">\n <summary>\n Used by {kafka.referencedBy.length} workload{kafka.referencedBy.length === 1 ? \"\" : \"s\"}\n </summary>\n <ul>\n {kafka.referencedBy.map((reference) => (\n <li key={reference}>{reference}</li>\n ))}\n </ul>\n </details>\n ) : null}\n\n {(detail.loading || detail.error) && detail.progress && (\n <OperationProgress progress={detail.progress} error={detail.error} />\n )}\n {detail.data && !detail.loading && !detail.error && (\n <div className=\"KafkaConnectionVerified\" role=\"status\">\n <Renderer.Component.Icon material=\"check_circle\" />\n <div>\n <strong>Connection verified</strong>\n <span>The effective settings are active for this session.</span>\n </div>\n </div>\n )}\n </Renderer.Component.Drawer>\n );\n}\n\nexport function KafkaOverviewPage({\n connectionSettings,\n writeSettings,\n schemaRegistrySettings,\n connectSettings,\n kubernetesClusterId,\n resourceCache,\n invalidateHealth,\n query: controlledQuery,\n onQueryChange,\n onOpenCluster,\n discover,\n overview,\n reachability,\n subscribeProgress,\n}: KafkaOverviewPageProps) {\n const catalogContext = kubernetesClusterId ?? \"active\";\n const [persistentState] = useState(() => kafkaPersistentStateStore());\n const [catalogStore] = useState(() => new KafkaClusterCatalogStore(persistentState));\n const savedCatalog = catalogStore.get(catalogContext);\n const [state, setState] = useState<DiscoveryState>(() => ({\n loading: false,\n kafkas: catalogStore.targets(catalogContext),\n }));\n const [autoScanEnabled, setAutoScanEnabled] = useState(savedCatalog.autoScan);\n const [manualKafkas, setManualKafkas] = useState<DiscoveredKafkaInfo[]>(() =>\n loadManualKafkaEndpoints(persistentState),\n );\n const [settingsTarget, setSettingsTarget] = useState<DiscoveredKafkaInfo | null>(null);\n const [detail, setDetail] = useState<DetailState>({ loading: false });\n const [reach, setReach] = useState<Record<string, boolean>>({});\n const [discoveryProgress, setDiscoveryProgress] = useState<KafkaProgressEvent>();\n const [detailProgress, setDetailProgress] = useState<KafkaProgressEvent>();\n const discoveryOperationId = useRef<string>();\n const detailOperationId = useRef<string>();\n const [localQuery, setLocalQuery] = useState(\"\");\n const [reachabilityFilter, setReachabilityFilter] = useState<ReachabilityFilter>(\"all\");\n const [manualOpen, setManualOpen] = useState(false);\n const [manualBootstrap, setManualBootstrap] = useState(\"\");\n const [manualTls, setManualTls] = useState(false);\n const [manualError, setManualError] = useState<string>();\n const [reconnectRequest, setReconnectRequest] = useState<{ revision: number; targetId: string }>();\n const query = controlledQuery ?? localQuery;\n const setQuery = onQueryChange ?? setLocalQuery;\n\n const selectKafkaCluster = useCallback(\n (kafka: DiscoveredKafkaInfo) => {\n if (kubernetesClusterId) rememberKafkaClusterSelection(persistentState, kubernetesClusterId, kafka);\n onOpenCluster(kafka);\n },\n [kubernetesClusterId, onOpenCluster],\n );\n\n const openConnectionSettings = useCallback((kafka: DiscoveredKafkaInfo) => {\n setReconnectRequest(undefined);\n setDetail({ loading: false });\n setDetailProgress(undefined);\n setSettingsTarget(kafka);\n }, []);\n\n useEffect(\n () =>\n subscribeProgress((progress) => {\n if (progress.operation === \"discovery\" && progress.operationId === discoveryOperationId.current) {\n setDiscoveryProgress(progress);\n } else if (progress.operation === \"overview\" && progress.operationId === detailOperationId.current) {\n setDetailProgress(progress);\n }\n }),\n [subscribeProgress],\n );\n\n const loadDiscovery = useCallback(\n (force = false) => {\n if (force) resourceCache.invalidateDiscovery(kubernetesClusterId ?? \"active\");\n let cancelled = false;\n const operationId = createOperationId(\"discovery\");\n discoveryOperationId.current = operationId;\n setDiscoveryProgress({\n operationId,\n operation: \"discovery\",\n value: 1,\n phase: \"starting\",\n label: \"Starting Kafka discovery\",\n detail: \"Preparing the active Kubernetes cluster connection.\",\n });\n setState((current) => ({ loading: true, kafkas: current.kafkas }));\n discover({ operationId })\n .then((kafkas) => {\n if (cancelled) return;\n catalogStore.setDiscovered(catalogContext, kafkas);\n setState({ loading: false, kafkas: catalogStore.targets(catalogContext) });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : String(error);\n setState((current) => ({ loading: false, kafkas: current.kafkas, error: message }));\n setDiscoveryProgress((current) =>\n current ? { ...current, label: \"Discovery stopped\", detail: current.label } : current,\n );\n }\n });\n return () => {\n cancelled = true;\n };\n },\n [catalogContext, catalogStore, discover, kubernetesClusterId, reachability, resourceCache],\n );\n\n useEffect(() => {\n const catalog = catalogStore.get(catalogContext);\n setState({ loading: false, kafkas: catalogStore.targets(catalogContext) });\n setAutoScanEnabled(catalog.autoScan);\n setReach({});\n }, [catalogContext, catalogStore]);\n\n useEffect(() => {\n if (!catalogStore.get(catalogContext).autoScan) return;\n return loadDiscovery();\n }, [catalogContext, catalogStore, loadDiscovery]);\n\n useEffect(() => {\n saveManualKafkaEndpoints(persistentState, manualKafkas);\n\n const bootstraps = manualKafkas.map((kafka) => kafka.bootstrap);\n if (bootstraps.length === 0) return;\n let cancelled = false;\n reachability(bootstraps)\n .then((result) => {\n if (!cancelled) setReach((current) => ({ ...current, ...result }));\n })\n .catch(() => undefined);\n return () => {\n cancelled = true;\n };\n }, [manualKafkas, persistentState, reachability]);\n\n useEffect(() => {\n const bootstraps = [...new Set(state.kafkas.map((kafka) => kafka.bootstrap))];\n if (bootstraps.length === 0) return;\n let cancelled = false;\n reachability(bootstraps)\n .then((result) => {\n if (!cancelled) setReach((current) => ({ ...current, ...result }));\n })\n .catch(() => undefined);\n return () => {\n cancelled = true;\n };\n }, [reachability, state.kafkas]);\n\n useEffect(() => {\n if (!settingsTarget || reconnectRequest?.targetId !== settingsTarget.targetId) {\n setDetail({ loading: false });\n setDetailProgress(undefined);\n return;\n }\n let cancelled = false;\n const operationId = createOperationId(\"overview\");\n detailOperationId.current = operationId;\n const initialProgress: KafkaProgressEvent = {\n operationId,\n operation: \"overview\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing cluster details\",\n detail: \"Selecting a safe read-only connection path.\",\n };\n setDetailProgress(initialProgress);\n setDetail({ loading: true, progress: initialProgress });\n overview({\n operationId,\n targetId: settingsTarget.targetId,\n namespace: settingsTarget.namespace,\n clusterName: settingsTarget.name,\n source: settingsTarget.source,\n bootstrap: settingsTarget.bootstrap,\n tls: settingsTarget.tls,\n sourceLocator: settingsTarget.sourceLocator,\n security: connectionSettings.get(kubernetesClusterId ?? \"active\", settingsTarget.targetId),\n })\n .then((data) => {\n if (!cancelled) setDetail({ loading: false, data });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : String(error);\n setDetail((current) => ({ loading: false, error: message, progress: current.progress }));\n }\n });\n return () => {\n cancelled = true;\n };\n }, [connectionSettings, kubernetesClusterId, overview, reconnectRequest, settingsTarget]);\n\n const allKafkas = mergeKafkaClusters(state.kafkas, manualKafkas);\n\n const addManualEndpoint = (): void => {\n const bootstrap = manualBootstrap.trim();\n const { host, port } = firstBrokerAddress(bootstrap);\n if (!host) {\n setManualError(\"Enter a Kafka bootstrap host or host:port.\");\n return;\n }\n const targetId = createKafkaTargetId(bootstrap);\n if (allKafkas.some((kafka) => kafka.targetId === targetId)) {\n setManualError(\"This endpoint is already listed.\");\n return;\n }\n\n const kafka: DiscoveredKafkaInfo = {\n targetId,\n source: \"manual\",\n name: host,\n namespace: \"\",\n bootstrap,\n tls: manualTls,\n port,\n listeners: [],\n brokerPods: [],\n provider: \"Manual\",\n external: true,\n securityHint: { tls: manualTls, auth: \"none\" },\n };\n setManualKafkas((current) => [...current, kafka]);\n resourceCache.invalidateDiscovery(kubernetesClusterId ?? \"active\");\n setManualBootstrap(\"\");\n setManualTls(false);\n setManualError(undefined);\n setManualOpen(false);\n };\n\n const removeManualEndpoint = (kafka: DiscoveredKafkaInfo): void => {\n const contextId = kubernetesClusterId ?? \"active\";\n resourceCache.invalidateDiscovery(contextId);\n resourceCache.invalidateTarget(contextId, kafka.targetId);\n persistentState.removeItem(aggregateHealthSnapshotKey(contextId, kafka.targetId));\n void invalidateHealth(kafka.targetId, { closeSessions: true, removePersisted: true });\n setManualKafkas((current) => current.filter((entry) => entry.targetId !== kafka.targetId));\n connectionSettings.removeTarget(contextId, kafka.targetId);\n if (kubernetesClusterId) {\n forgetKafkaClusterSelection(persistentState, kubernetesClusterId, kafka.targetId);\n }\n setSettingsTarget(null);\n };\n\n const applySecurity = (kafka: DiscoveredKafkaInfo, security?: KafkaSecurityOverride): void => {\n const key = kafka.targetId;\n resourceCache.invalidateTarget(kubernetesClusterId ?? \"active\", key);\n void invalidateHealth(key, { closeSessions: true });\n connectionSettings.set(kubernetesClusterId ?? \"active\", key, security);\n setReconnectRequest((current) => ({ revision: (current?.revision ?? 0) + 1, targetId: key }));\n };\n\n const normalizedQuery = query.trim().toLowerCase();\n const manualTargetIds = new Set(manualKafkas.map((kafka) => kafka.targetId));\n const missingTargetIds = new Set(\n savedCatalog.missing.filter((kafka) => !manualTargetIds.has(kafka.targetId)).map((kafka) => kafka.targetId),\n );\n const catalogStatus = savedCatalog.lastScanAt\n ? `Last scan ${new Date(savedCatalog.lastScanAt).toLocaleString()}`\n : \"Not scanned yet\";\n const filteredKafkas = allKafkas.filter((kafka) => {\n const pc = reach[kafka.bootstrap];\n if (reachabilityFilter === \"pc\" && pc !== true) return false;\n if (reachabilityFilter === \"pods\" && pc !== false) return false;\n if (!normalizedQuery) return true;\n return [kafka.name, kafka.namespace, kafka.bootstrap, sourceLabel(kafka), ...(kafka.referencedBy ?? [])]\n .join(\" \")\n .toLowerCase()\n .includes(normalizedQuery);\n });\n\n const reachableCount = allKafkas.filter((kafka) => reach[kafka.bootstrap] === true).length;\n const podOnlyCount = allKafkas.filter(\n (kafka) => kafka.source !== \"manual\" && reach[kafka.bootstrap] === false,\n ).length;\n\n return (\n <KafkaPageShell\n title=\"Kafka clusters\"\n subtitle={\n state.loading\n ? \"Discovering clusters\"\n : `${allKafkas.length} cluster${allKafkas.length === 1 ? \"\" : \"s\"} available`\n }\n actions={\n <>\n <Renderer.Component.Button outlined onClick={() => setManualOpen((open) => !open)}>\n <Renderer.Component.Icon material=\"add_link\" />\n Add endpoint\n </Renderer.Component.Button>\n <Renderer.Component.Button\n outlined\n className=\"KafkaRefreshButton\"\n waiting={state.loading}\n onClick={() => loadDiscovery(true)}\n title=\"Scan Kubernetes for Kafka clusters\"\n >\n <Renderer.Component.Icon material=\"search\" />\n Scan Kubernetes\n </Renderer.Component.Button>\n <div className=\"KafkaAutoScanControl\">\n <span>Auto-scan</span>\n <Renderer.Component.Switch\n checked={autoScanEnabled}\n onChange={(enabled) => {\n setAutoScanEnabled(enabled);\n catalogStore.setAutoScan(catalogContext, enabled);\n }}\n aria-label=\"Scan automatically when opening Kafka clusters\"\n />\n </div>\n <span className=\"KafkaCacheStatus\" data-testid=\"kafka-catalog-status\" title={catalogStatus}>\n {state.loading ? \"Scanning\" : catalogStatus}\n </span>\n </>\n }\n >\n {manualOpen && (\n <form\n className=\"KafkaManualEndpoint\"\n onSubmit={(event) => {\n event.preventDefault();\n addManualEndpoint();\n }}\n >\n <Renderer.Component.Input\n className=\"KafkaManualBootstrap\"\n value={manualBootstrap}\n onChange={(value) => {\n setManualBootstrap(value);\n setManualError(undefined);\n }}\n iconLeft=\"link\"\n placeholder=\"broker-1.example.com:9092,broker-2.example.com:9092\"\n aria-label=\"Kafka bootstrap servers\"\n autoFocus\n />\n <label className=\"KafkaTlsSwitch\">\n <span>TLS</span>\n <Renderer.Component.Switch checked={manualTls} onChange={setManualTls} />\n </label>\n <Renderer.Component.Button primary type=\"submit\" disabled={!manualBootstrap.trim()}>\n Add\n </Renderer.Component.Button>\n <Renderer.Component.Button plain onClick={() => setManualOpen(false)}>\n Cancel\n </Renderer.Component.Button>\n {manualError && <span className=\"KafkaManualError\">{manualError}</span>}\n </form>\n )}\n\n {state.loading && discoveryProgress && <OperationProgress progress={discoveryProgress} />}\n {state.error && discoveryProgress && (\n <div className=\"KafkaDiscoveryError\">\n <OperationProgress progress={discoveryProgress} error={state.error} />\n <Renderer.Component.Button outlined onClick={() => loadDiscovery(true)}>\n Retry\n </Renderer.Component.Button>\n </div>\n )}\n {!state.loading && !state.error && allKafkas.length === 0 && (\n <div className=\"KafkaPageState empty\" data-testid=\"kafka-clusters-onboarding\">\n <Renderer.Component.Icon material=\"hub\" />\n <div>\n <strong>Choose how to add Kafka clusters</strong>\n <span>Scan Kubernetes for discovered endpoints or add a Kafka bootstrap manually.</span>\n </div>\n <div className=\"KafkaOnboardingActions\">\n <Renderer.Component.Button primary onClick={() => loadDiscovery(true)}>\n <Renderer.Component.Icon material=\"search\" />\n Scan Kubernetes\n </Renderer.Component.Button>\n <Renderer.Component.Button outlined onClick={() => setManualOpen(true)}>\n <Renderer.Component.Icon material=\"add_link\" />\n Add manually\n </Renderer.Component.Button>\n </div>\n </div>\n )}\n\n {!state.loading && allKafkas.length > 0 && (\n <>\n <section className=\"KafkaToolbar\" aria-label=\"Kafka cluster filters\">\n <Renderer.Component.Input\n className=\"KafkaSearchInput\"\n value={query}\n onChange={setQuery}\n iconLeft=\"search\"\n placeholder=\"Filter by name, namespace, bootstrap or workload\"\n aria-label=\"Filter Kafka clusters\"\n />\n <div className=\"KafkaFilterGroup\" role=\"group\" aria-label=\"Reachability filter\">\n {(\n [\n [\"all\", `All ${allKafkas.length}`],\n [\"pc\", `From PC ${reachableCount}`],\n [\"pods\", `Pod only ${podOnlyCount}`],\n ] as const\n ).map(([value, label]) => (\n <Renderer.Component.Button\n key={value}\n plain\n active={reachabilityFilter === value}\n onClick={() => setReachabilityFilter(value)}\n >\n {label}\n </Renderer.Component.Button>\n ))}\n </div>\n </section>\n\n <main className=\"KafkaWorkspace\">\n <section className=\"KafkaListPane\" aria-label=\"Kafka clusters\">\n <Renderer.Component.Table<DiscoveredKafkaInfo>\n className=\"KafkaClusterTable\"\n tableId=\"kafka-clusters\"\n autoSize={false}\n selectable\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"name\", orderBy: \"asc\" }}\n sortable={{\n name: (kafka) => kafka.name.toLowerCase(),\n namespace: (kafka) => kafka.namespace.toLowerCase(),\n usage: (kafka) => kafkaUsageSummary(kafka).sortValue,\n source: (kafka) => sourceLabel(kafka).toLowerCase(),\n bootstrap: (kafka) => kafka.bootstrap.toLowerCase(),\n security: (kafka) =>\n securityLabel(kafka.securityHint ?? { tls: kafka.tls, auth: \"none\" }).toLowerCase(),\n pc: (kafka) => Number(reach[kafka.bootstrap] === true),\n }}\n noItems={\n <div className=\"KafkaNoMatches\">\n <Renderer.Component.Icon material=\"filter_alt_off\" />\n No clusters match the current filters.\n </div>\n }\n >\n <Renderer.Component.TableHead nowrap>\n <Renderer.Component.TableCell className=\"nameCell\" sortBy=\"name\">\n Cluster\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"usageCell\" sortBy=\"usage\">\n Kubernetes usage\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"sourceCell\" sortBy=\"source\">\n Source\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"bootstrapCell\" sortBy=\"bootstrap\">\n Bootstrap\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"securityCell\" sortBy=\"security\">\n Security\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"reachCell\" sortBy=\"pc\">\n From PC\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"podsCell\">From pods</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"actionCell\" />\n </Renderer.Component.TableHead>\n\n {filteredKafkas.map((kafka) => {\n const settingsOpen = settingsTarget?.targetId === kafka.targetId;\n const pc = reach[kafka.bootstrap];\n const strategy = pc === undefined ? undefined : chooseStrategy(kafka.source, pc);\n const inspectable =\n kafka.source === \"strimzi\" ||\n strategy === \"direct\" ||\n (pc === undefined && (kafka.source === \"manual\" || kafka.external === true));\n const inspectTitle =\n kafka.source === \"strimzi\"\n ? \"Connect via port-forward to the broker pods\"\n : pc === undefined\n ? \"Checking reachability…\"\n : strategy === \"direct\"\n ? \"Connect directly (reachable from this machine)\"\n : \"Reachable only from the cluster's pods — relay connect coming soon\";\n const rowInteraction: HTMLAttributes<HTMLDivElement> = inspectable\n ? {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open Overview for ${kafka.name}`,\n onClick: (event) => {\n event.stopPropagation();\n selectKafkaCluster(kafka);\n },\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n selectKafkaCluster(kafka);\n }\n },\n }\n : { \"aria-label\": inspectTitle, title: inspectTitle };\n return (\n <Renderer.Component.TableRow\n {...rowInteraction}\n key={kafka.targetId}\n sortItem={kafka}\n selected={settingsOpen}\n nowrap\n data-bootstrap={kafka.bootstrap}\n >\n <Renderer.Component.TableCell className=\"nameCell\" title={kafka.name}>\n <div className=\"KafkaClusterName\">\n <Renderer.Component.Icon material=\"hub\" />\n <span>{kafka.name}</span>\n {missingTargetIds.has(kafka.targetId) && (\n <Renderer.Component.Badge small label=\"Not found in latest scan\" />\n )}\n </div>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"usageCell\">\n <UsageCell kafka={kafka} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"sourceCell\">\n <SourceBadge kafka={kafka} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"bootstrapCell\" title={kafka.bootstrap}>\n <code className=\"KafkaEllipsis\">{kafka.bootstrap}</code>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"securityCell\">\n <SecurityBadge security={kafka.securityHint ?? { tls: kafka.tls, auth: \"none\" }} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"reachCell\">\n <ReachabilityBadge value={pc} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"podsCell\">\n <PodReachabilityBadge kafka={kafka} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"actionCell\">\n <Renderer.Component.Button\n plain\n round\n className=\"KafkaIconButton\"\n title={`Connection settings for ${kafka.name}`}\n aria-label={`Connection settings for ${kafka.name}`}\n onClick={(event) => {\n event.stopPropagation();\n openConnectionSettings(kafka);\n }}\n >\n <Renderer.Component.Icon material=\"tune\" />\n </Renderer.Component.Button>\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n </section>\n\n {settingsTarget && (\n <ConnectionSettingsDrawer\n key={settingsTarget.targetId}\n kafka={settingsTarget}\n pcReachable={reach[settingsTarget.bootstrap]}\n detail={{ ...detail, progress: detailProgress }}\n securityOverride={connectionSettings.get(kubernetesClusterId ?? \"active\", settingsTarget.targetId)}\n writeSettings={writeSettings}\n schemaRegistrySettings={schemaRegistrySettings}\n connectSettings={connectSettings}\n onApplySecurity={(security) => applySecurity(settingsTarget, security)}\n onClose={() => setSettingsTarget(null)}\n onRemove={settingsTarget.source === \"manual\" ? () => removeManualEndpoint(settingsTarget) : undefined}\n />\n )}\n </main>\n </>\n )}\n </KafkaPageShell>\n );\n}\n","export interface KafkaSnapshot<T> {\n data?: T;\n fresh: boolean;\n stale: boolean;\n loading: boolean;\n error?: string;\n updatedAt?: number;\n}\n\ninterface SnapshotEntry<T> {\n data?: T;\n error?: string;\n expiresAt?: number;\n generation: number;\n inFlight?: Promise<T>;\n lastAccessedAt: number;\n updatedAt?: number;\n}\n\nexport interface KafkaSnapshotCacheOptions {\n now?: () => number;\n ttlMs: number;\n maxEntries?: number;\n}\n\nexport class KafkaSnapshotCache<T> {\n private readonly entries = new Map<string, SnapshotEntry<T>>();\n private readonly now: () => number;\n private readonly ttlMs: number;\n private readonly maxEntries: number;\n private generation = 0;\n\n constructor(options: KafkaSnapshotCacheOptions) {\n this.now = options.now ?? Date.now;\n this.ttlMs = Math.max(1, options.ttlMs);\n this.maxEntries = Math.max(1, options.maxEntries ?? 100);\n }\n\n read(key: string): KafkaSnapshot<T> {\n const entry = this.entries.get(key);\n if (!entry) return { fresh: false, stale: false, loading: false };\n entry.lastAccessedAt = this.now();\n const fresh = entry.data !== undefined && entry.expiresAt !== undefined && entry.expiresAt > this.now();\n return {\n data: entry.data,\n fresh,\n stale: entry.data !== undefined && !fresh,\n loading: Boolean(entry.inFlight),\n error: entry.error,\n updatedAt: entry.updatedAt,\n };\n }\n\n load(key: string, loader: () => Promise<T>): Promise<T> {\n const existing = this.entries.get(key);\n if (existing) {\n existing.lastAccessedAt = this.now();\n if (existing.data !== undefined && existing.expiresAt !== undefined && existing.expiresAt > this.now()) {\n return Promise.resolve(existing.data);\n }\n if (existing.inFlight) return existing.inFlight;\n }\n\n const generation = ++this.generation;\n const inFlight = Promise.resolve()\n .then(loader)\n .then((data) => {\n const current = this.entries.get(key);\n if (current?.generation === generation) {\n const updatedAt = this.now();\n this.entries.set(key, {\n data,\n expiresAt: updatedAt + this.ttlMs,\n generation,\n lastAccessedAt: updatedAt,\n updatedAt,\n });\n this.evictIfNeeded();\n }\n return data;\n })\n .catch((error: unknown) => {\n const current = this.entries.get(key);\n if (current?.generation === generation) {\n this.entries.set(key, {\n ...current,\n error: error instanceof Error ? error.message : String(error),\n generation,\n inFlight: undefined,\n lastAccessedAt: this.now(),\n });\n }\n throw error;\n });\n\n this.entries.set(key, {\n data: existing?.data,\n error: undefined,\n expiresAt: existing?.expiresAt,\n generation,\n inFlight,\n lastAccessedAt: this.now(),\n updatedAt: existing?.updatedAt,\n });\n this.evictIfNeeded(key);\n return inFlight;\n }\n\n invalidate(key: string): void {\n const current = this.entries.get(key);\n if (!current) return;\n this.entries.set(key, {\n ...current,\n expiresAt: 0,\n generation: ++this.generation,\n inFlight: undefined,\n lastAccessedAt: this.now(),\n });\n }\n\n invalidatePrefix(prefix: string): void {\n for (const key of this.entries.keys()) {\n if (key.startsWith(prefix)) this.invalidate(key);\n }\n }\n\n delete(key: string): void {\n this.entries.delete(key);\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n size(): number {\n return this.entries.size;\n }\n\n private evictIfNeeded(protectedKey?: string): void {\n while (this.entries.size > this.maxEntries) {\n const candidate = [...this.entries.entries()]\n .filter(([key, entry]) => key !== protectedKey && !entry.inFlight)\n .sort(([, left], [, right]) => left.lastAccessedAt - right.lastAccessedAt)[0];\n if (!candidate) return;\n this.entries.delete(candidate[0]);\n }\n }\n}\n","import { KAFKA_CLUSTER_HEALTH_CACHE_TTL_MS, KAFKA_RESOURCE_CACHE_TTL_MS } from \"../common/constants\";\nimport { createKafkaTargetId } from \"../common/kafka-target\";\nimport { type KafkaSnapshot, KafkaSnapshotCache } from \"./kafka-snapshot-cache\";\n\nimport type {\n ClusterOverviewDto,\n ClusterOverviewHealthDto,\n ConsumerGroupsDto,\n DiscoveredKafkaInfo,\n TopicDetailDto,\n} from \"../common/ipc\";\n\ninterface CacheEntry<T> {\n data?: T;\n expiresAt?: number;\n generation: number;\n inFlight?: Promise<T>;\n operationId?: string;\n requestCount: number;\n updatedAt?: number;\n}\n\nexport interface KafkaCacheSnapshot<T> {\n data?: T;\n fresh: boolean;\n loading: boolean;\n operationId?: string;\n requestCount: number;\n updatedAt?: number;\n}\n\nexport interface KafkaResourceCacheStats {\n discoveryRequests: number;\n healthRequests: number;\n overviewRequests: number;\n reachabilityRequests: number;\n}\n\ninterface KafkaResourceCacheOptions {\n healthTtlMs?: number;\n now?: () => number;\n ttlMs?: number;\n}\n\nfunction emptySnapshot<T>(): KafkaCacheSnapshot<T> {\n return { fresh: false, loading: false, requestCount: 0 };\n}\n\nexport function formatKafkaCacheAge(updatedAt: number, now = Date.now()): string {\n const elapsed = Math.max(0, now - updatedAt);\n if (elapsed < 5_000) return \"just now\";\n if (elapsed < 60_000) return `${Math.floor(elapsed / 1_000)}s ago`;\n if (elapsed < 3_600_000) return `${Math.floor(elapsed / 60_000)}m ago`;\n return `${Math.floor(elapsed / 3_600_000)}h ago`;\n}\n\nexport class KafkaResourceCache {\n private activeKubernetesClusterId?: string;\n private readonly discovery = new Map<string, CacheEntry<DiscoveredKafkaInfo[]>>();\n private generation = 0;\n private readonly health = new Map<string, CacheEntry<ClusterOverviewHealthDto>>();\n private readonly healthTtlMs: number;\n private readonly now: () => number;\n private readonly overviews = new Map<string, CacheEntry<ClusterOverviewDto>>();\n private readonly reachability = new Map<string, CacheEntry<boolean>>();\n private readonly reachabilityRequestCounts = new Map<string, number>();\n private readonly topicDetails: KafkaSnapshotCache<TopicDetailDto>;\n private readonly groupLists: KafkaSnapshotCache<ConsumerGroupsDto>;\n private readonly ttlMs: number;\n\n constructor({\n healthTtlMs = KAFKA_CLUSTER_HEALTH_CACHE_TTL_MS,\n now = Date.now,\n ttlMs = KAFKA_RESOURCE_CACHE_TTL_MS,\n }: KafkaResourceCacheOptions = {}) {\n this.healthTtlMs = Math.max(1, healthTtlMs);\n this.now = now;\n this.ttlMs = ttlMs;\n this.topicDetails = new KafkaSnapshotCache({ now, ttlMs, maxEntries: 100 });\n this.groupLists = new KafkaSnapshotCache({ now, ttlMs, maxEntries: 10 });\n }\n\n activateKubernetesCluster(kubernetesClusterId: string): void {\n if (this.activeKubernetesClusterId === kubernetesClusterId) return;\n this.clear();\n this.activeKubernetesClusterId = kubernetesClusterId;\n }\n\n readDiscovery(kubernetesClusterId: string): KafkaCacheSnapshot<DiscoveredKafkaInfo[]> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.snapshot(this.discovery.get(kubernetesClusterId));\n }\n\n loadDiscovery(\n kubernetesClusterId: string,\n operationId: string,\n loader: () => Promise<DiscoveredKafkaInfo[]>,\n ): Promise<DiscoveredKafkaInfo[]> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.load(this.discovery, kubernetesClusterId, operationId, loader);\n }\n\n readOverview(kubernetesClusterId: string, targetId: string): KafkaCacheSnapshot<ClusterOverviewDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.snapshot(this.overviews.get(this.targetKey(kubernetesClusterId, targetId)));\n }\n\n loadOverview(\n kubernetesClusterId: string,\n targetId: string,\n operationId: string,\n loader: () => Promise<ClusterOverviewDto>,\n ): Promise<ClusterOverviewDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.load(this.overviews, this.targetKey(kubernetesClusterId, targetId), operationId, loader);\n }\n\n readHealth(kubernetesClusterId: string, targetId: string): KafkaCacheSnapshot<ClusterOverviewHealthDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.snapshot(this.health.get(this.targetKey(kubernetesClusterId, targetId)));\n }\n\n loadHealth(\n kubernetesClusterId: string,\n targetId: string,\n operationId: string,\n loader: () => Promise<ClusterOverviewHealthDto>,\n ): Promise<ClusterOverviewHealthDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.load(this.health, this.targetKey(kubernetesClusterId, targetId), operationId, loader, this.healthTtlMs);\n }\n\n readTopic(kubernetesClusterId: string, targetId: string, topic: string): KafkaSnapshot<TopicDetailDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.topicDetails.read(this.topicKey(kubernetesClusterId, targetId, topic));\n }\n\n loadTopic(\n kubernetesClusterId: string,\n targetId: string,\n topic: string,\n loader: () => Promise<TopicDetailDto>,\n ): Promise<TopicDetailDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.topicDetails.load(this.topicKey(kubernetesClusterId, targetId, topic), loader);\n }\n\n readGroups(kubernetesClusterId: string, targetId: string): KafkaSnapshot<ConsumerGroupsDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.groupLists.read(this.targetKey(kubernetesClusterId, targetId));\n }\n\n loadGroups(\n kubernetesClusterId: string,\n targetId: string,\n loader: () => Promise<ConsumerGroupsDto>,\n ): Promise<ConsumerGroupsDto> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.groupLists.load(this.targetKey(kubernetesClusterId, targetId), loader);\n }\n\n readReachability(kubernetesClusterId: string, targetId: string): KafkaCacheSnapshot<boolean> {\n this.activateKubernetesCluster(kubernetesClusterId);\n return this.snapshot(this.reachability.get(this.targetKey(kubernetesClusterId, targetId)));\n }\n\n async loadReachability(\n kubernetesClusterId: string,\n bootstraps: string[],\n loader: (missingBootstraps: string[]) => Promise<Record<string, boolean>>,\n ): Promise<Record<string, boolean>> {\n this.activateKubernetesCluster(kubernetesClusterId);\n const uniqueBootstraps = [...new Set(bootstraps)];\n const values = new Map<string, Promise<boolean>>();\n const missing: { bootstrap: string; key: string; generation: number }[] = [];\n\n for (const bootstrap of uniqueBootstraps) {\n const key = this.targetKey(kubernetesClusterId, createKafkaTargetId(bootstrap));\n const entry = this.reachability.get(key);\n if (entry?.data !== undefined && this.isFresh(entry)) {\n values.set(bootstrap, Promise.resolve(entry.data));\n } else if (entry?.inFlight) {\n values.set(bootstrap, entry.inFlight);\n } else {\n const generation = this.nextGeneration();\n missing.push({ bootstrap, key, generation });\n }\n }\n\n if (missing.length > 0) {\n this.reachabilityRequestCounts.set(\n kubernetesClusterId,\n (this.reachabilityRequestCounts.get(kubernetesClusterId) ?? 0) + 1,\n );\n const batch = this.callLoader(() => loader(missing.map(({ bootstrap }) => bootstrap)));\n\n for (const { bootstrap, key, generation } of missing) {\n const previous = this.reachability.get(key);\n const inFlight = batch\n .then((result) => {\n const data = result[bootstrap];\n if (data === undefined) throw new Error(`reachability result missing for ${bootstrap}`);\n const current = this.reachability.get(key);\n if (current?.generation === generation) {\n const updatedAt = this.now();\n this.reachability.set(key, {\n data,\n expiresAt: updatedAt + this.ttlMs,\n generation,\n requestCount: current.requestCount,\n updatedAt,\n });\n }\n return data;\n })\n .catch((error: unknown) => {\n const current = this.reachability.get(key);\n if (current?.generation === generation) {\n this.reachability.set(key, {\n data: previous?.data,\n expiresAt: previous?.expiresAt,\n generation,\n requestCount: current.requestCount,\n updatedAt: previous?.updatedAt,\n });\n }\n throw error;\n });\n\n this.reachability.set(key, {\n data: previous?.data,\n expiresAt: previous?.expiresAt,\n generation,\n inFlight,\n requestCount: (previous?.requestCount ?? 0) + 1,\n updatedAt: previous?.updatedAt,\n });\n values.set(bootstrap, inFlight);\n }\n }\n\n const resolved = await Promise.all(\n uniqueBootstraps.map(async (bootstrap) => [bootstrap, await values.get(bootstrap)] as const),\n );\n return Object.fromEntries(resolved) as Record<string, boolean>;\n }\n\n invalidateDiscovery(kubernetesClusterId: string): void {\n this.activateKubernetesCluster(kubernetesClusterId);\n this.invalidate(this.discovery, kubernetesClusterId);\n }\n\n invalidateTarget(kubernetesClusterId: string, targetId: string): void {\n this.activateKubernetesCluster(kubernetesClusterId);\n const key = this.targetKey(kubernetesClusterId, targetId);\n this.invalidate(this.health, key);\n this.invalidate(this.overviews, key);\n this.invalidate(this.reachability, key);\n this.topicDetails.invalidatePrefix(`${key}:`);\n this.groupLists.invalidate(key);\n }\n\n invalidateHealth(kubernetesClusterId: string, targetId: string): void {\n this.activateKubernetesCluster(kubernetesClusterId);\n this.invalidate(this.health, this.targetKey(kubernetesClusterId, targetId));\n }\n\n stats(kubernetesClusterId: string, targetId?: string): KafkaResourceCacheStats {\n this.activateKubernetesCluster(kubernetesClusterId);\n return {\n discoveryRequests: this.discovery.get(kubernetesClusterId)?.requestCount ?? 0,\n healthRequests: targetId\n ? (this.health.get(this.targetKey(kubernetesClusterId, targetId))?.requestCount ?? 0)\n : 0,\n overviewRequests: targetId\n ? (this.overviews.get(this.targetKey(kubernetesClusterId, targetId))?.requestCount ?? 0)\n : 0,\n reachabilityRequests: this.reachabilityRequestCounts.get(kubernetesClusterId) ?? 0,\n };\n }\n\n clear(): void {\n this.discovery.clear();\n this.health.clear();\n this.overviews.clear();\n this.reachability.clear();\n this.topicDetails.clear();\n this.groupLists.clear();\n this.reachabilityRequestCounts.clear();\n }\n\n private callLoader<T>(loader: () => Promise<T>): Promise<T> {\n try {\n return Promise.resolve(loader());\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n private invalidate<T>(entries: Map<string, CacheEntry<T>>, key: string): void {\n const current = entries.get(key);\n if (!current) return;\n entries.set(key, {\n ...current,\n expiresAt: 0,\n generation: this.nextGeneration(),\n inFlight: undefined,\n operationId: undefined,\n requestCount: current.requestCount,\n });\n }\n\n private isFresh<T>(entry: CacheEntry<T>): boolean {\n return entry.expiresAt !== undefined && entry.expiresAt > this.now();\n }\n\n private load<T>(\n entries: Map<string, CacheEntry<T>>,\n key: string,\n operationId: string,\n loader: () => Promise<T>,\n ttlMs = this.ttlMs,\n ): Promise<T> {\n const existing = entries.get(key);\n if (existing?.data !== undefined && this.isFresh(existing)) return Promise.resolve(existing.data);\n if (existing?.inFlight) return existing.inFlight;\n\n const generation = this.nextGeneration();\n const requestCount = (existing?.requestCount ?? 0) + 1;\n const inFlight = this.callLoader(loader)\n .then((data) => {\n const current = entries.get(key);\n if (current?.generation === generation) {\n const updatedAt = this.now();\n entries.set(key, {\n data,\n expiresAt: updatedAt + ttlMs,\n generation,\n requestCount: current.requestCount,\n updatedAt,\n });\n }\n return data;\n })\n .catch((error: unknown) => {\n const current = entries.get(key);\n if (current?.generation === generation) {\n entries.set(key, {\n data: existing?.data,\n expiresAt: existing?.expiresAt,\n generation,\n requestCount: current.requestCount,\n updatedAt: existing?.updatedAt,\n });\n }\n throw error;\n });\n\n entries.set(key, {\n data: existing?.data,\n expiresAt: existing?.expiresAt,\n generation,\n inFlight,\n operationId,\n requestCount,\n updatedAt: existing?.updatedAt,\n });\n return inFlight;\n }\n\n private snapshot<T>(entry?: CacheEntry<T>): KafkaCacheSnapshot<T> {\n if (!entry) return emptySnapshot();\n return {\n data: entry.data,\n fresh: entry.data !== undefined && this.isFresh(entry),\n loading: Boolean(entry.inFlight),\n operationId: entry.operationId,\n requestCount: entry.requestCount,\n updatedAt: entry.updatedAt,\n };\n }\n\n private nextGeneration(): number {\n this.generation += 1;\n return this.generation;\n }\n\n private targetKey(kubernetesClusterId: string, targetId: string): string {\n return `${kubernetesClusterId}:${targetId}`;\n }\n\n private topicKey(kubernetesClusterId: string, targetId: string, topic: string): string {\n return `${this.targetKey(kubernetesClusterId, targetId)}:${topic}`;\n }\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { aggregateHealthSnapshotKey, decodeAggregateHealthSnapshot } from \"../common/aggregate-health-snapshot\";\nimport { DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS, KAFKA_OVERVIEW_AUTO_REFRESH_OPTIONS } from \"../common/constants\";\nimport { kafkaPersistentStateStore } from \"../common/kafka-persistent-state-store\";\nimport { chooseStrategy } from \"../common/reachability\";\nimport { KafkaClusterCatalogStore } from \"./kafka-cluster-catalog\";\nimport { loadManualKafkaEndpoints, mergeKafkaClusters } from \"./kafka-manual-endpoints\";\nimport {\n rememberedKafkaTargetId,\n rememberKafkaClusterSelection,\n resolveKafkaClusterSelection,\n} from \"./kafka-navigation\";\nimport { HealthProgress, OperationProgress, ReachabilityBadge, SecurityBadge, SourceBadge } from \"./kafka-overview\";\nimport { KafkaClusterSelector, KafkaMetricStrip, KafkaPageShell } from \"./kafka-page-shell\";\nimport { formatKafkaCacheAge, type KafkaResourceCache } from \"./kafka-resource-cache\";\nimport {\n clusterHealthMetricValue,\n createOperationId,\n kafkaHealthCompletionMetadata,\n kafkaHealthCoverageLabel,\n kafkaHealthCoverageState,\n kafkaHealthNeedsCoverageNotice,\n kafkaUsageContext,\n} from \"./kafka-view-model\";\n\nimport type { CSSProperties, HTMLAttributes } from \"react\";\n\nimport type {\n BrokerConfigDto,\n BrokerConfigRequest,\n ClusterHealthRequest,\n ClusterOverviewDto,\n ClusterOverviewHealthDto,\n DiscoveredKafkaInfo,\n DiscoverRequest,\n KafkaConfigEntryDto,\n KafkaProgressEvent,\n OverviewRequest,\n} from \"../common/ipc\";\nimport type { KafkaConnectionSettingsStore } from \"./kafka-connection-settings\";\nimport type { KafkaOverviewSettingsStore } from \"./kafka-overview-settings\";\nimport type { KafkaWriteSettingsStore } from \"./kafka-write-settings\";\n\nexport interface KafkaResourcePageDependencies {\n connectionSettings: KafkaConnectionSettingsStore;\n writeSettings: KafkaWriteSettingsStore;\n kubernetesClusterId?: string;\n resourceCache: KafkaResourceCache;\n discover: (request?: DiscoverRequest) => Promise<DiscoveredKafkaInfo[]>;\n overview: (request: OverviewRequest) => Promise<ClusterOverviewDto>;\n reachability: (bootstraps: string[]) => Promise<Record<string, boolean>>;\n subscribeProgress: (listener: (progress: KafkaProgressEvent) => void) => () => void;\n}\n\nexport interface KafkaTargetPageProps extends KafkaResourcePageDependencies {\n health?: (request: ClusterHealthRequest) => Promise<ClusterOverviewHealthDto>;\n overviewSettings?: KafkaOverviewSettingsStore;\n params?: {\n target: Renderer.Navigation.PageParam<string>;\n };\n}\n\nexport interface KafkaBrokersPageProps extends KafkaResourcePageDependencies {\n params?: {\n target: Renderer.Navigation.PageParam<string>;\n broker: Renderer.Navigation.PageParam<string>;\n };\n brokerConfig: (request: BrokerConfigRequest) => Promise<BrokerConfigDto>;\n}\n\ninterface ClusterLoadState {\n cacheKey: string;\n loading: boolean;\n error?: string;\n clusters: DiscoveredKafkaInfo[];\n source?: \"cache\" | \"network\";\n updatedAt?: number;\n}\n\ninterface MetadataState {\n cacheKey?: string;\n loading: boolean;\n error?: string;\n data?: ClusterOverviewDto;\n source?: \"cache\" | \"network\";\n targetId?: string;\n updatedAt?: number;\n}\n\ninterface HealthState {\n cacheKey?: string;\n loading: boolean;\n error?: string;\n data?: ClusterOverviewHealthDto;\n source?: \"cache\" | \"network\" | \"persisted\";\n targetId?: string;\n updatedAt?: number;\n}\n\nexport function useKafkaPageParam(param?: Renderer.Navigation.PageParam<string>) {\n const routeValue = param?.get() ?? \"\";\n const [value, setValue] = useState(routeValue);\n\n useEffect(() => setValue(routeValue), [routeValue]);\n useEffect(() => {\n const syncFromHistory = () => setValue(param?.get() ?? \"\");\n window.addEventListener(\"popstate\", syncFromHistory);\n return () => window.removeEventListener(\"popstate\", syncFromHistory);\n }, [param]);\n\n const update = useCallback(\n (targetId: string, replaceHistory = false) => {\n setValue(targetId);\n param?.set(targetId, { replaceHistory });\n },\n [param],\n );\n\n return [value, update] as const;\n}\n\nexport function useKafkaResourcePage({\n connectionSettings,\n kubernetesClusterId,\n resourceCache,\n overview,\n health,\n reachability,\n subscribeProgress,\n params,\n}: KafkaTargetPageProps) {\n const cacheKey = kubernetesClusterId ?? \"active\";\n const persistentState = kafkaPersistentStateStore();\n const [requestedTargetId, setRequestedTargetId] = useKafkaPageParam(params?.target);\n const [healthRefreshVersion, setHealthRefreshVersion] = useState(0);\n const [refreshVersion, setRefreshVersion] = useState(0);\n const [clusterState, setClusterState] = useState<ClusterLoadState>(() => {\n const cached = resourceCache.readDiscovery(cacheKey);\n const catalog = new KafkaClusterCatalogStore(persistentState).targets(cacheKey);\n const clusters = cached.data ?? catalog;\n return {\n cacheKey,\n loading: false,\n clusters: mergeKafkaClusters(clusters, loadManualKafkaEndpoints(persistentState)),\n source: cached.data ? \"cache\" : undefined,\n updatedAt: cached.updatedAt,\n };\n });\n const [metadataState, setMetadataState] = useState<MetadataState>({ loading: false });\n const [healthState, setHealthState] = useState<HealthState>({ loading: false });\n const [discoveryProgress, setDiscoveryProgress] = useState<KafkaProgressEvent>();\n const [metadataProgress, setMetadataProgress] = useState<KafkaProgressEvent>();\n const [healthProgress, setHealthProgress] = useState<KafkaProgressEvent>();\n const [pcReachable, setPcReachable] = useState<boolean>();\n const discoveryOperationId = useRef<string>();\n const lastNetworkMetadata = useRef<{ targetId: string; updatedAt?: number }>();\n const metadataOperationId = useRef<string>();\n const healthOperationId = useRef<string>();\n const forcedHealthRefresh = useRef<{ targetId?: string; version: number }>({ version: 0 });\n\n useEffect(\n () =>\n subscribeProgress((progress) => {\n if (progress.operation === \"discovery\" && progress.operationId === discoveryOperationId.current) {\n setDiscoveryProgress(progress);\n } else if (progress.operation === \"overview\" && progress.operationId === metadataOperationId.current) {\n setMetadataProgress(progress);\n } else if (progress.operation === \"health\" && progress.operationId === healthOperationId.current) {\n setHealthProgress(progress);\n if (progress.healthSnapshot) {\n setHealthState((current) => ({\n ...current,\n data: { ...current.data, ...progress.healthSnapshot } as ClusterOverviewHealthDto,\n source: progress.healthSource ?? (progress.phase === \"cache\" ? (current.source ?? \"cache\") : \"network\"),\n updatedAt: progress.healthUpdatedAt ?? current.updatedAt,\n }));\n }\n }\n }),\n [subscribeProgress],\n );\n\n useEffect(() => {\n const cached = resourceCache.readDiscovery(cacheKey);\n const catalog = new KafkaClusterCatalogStore(persistentState).targets(cacheKey);\n const clusters = cached.data ?? catalog;\n discoveryOperationId.current = undefined;\n setDiscoveryProgress(undefined);\n setClusterState({\n cacheKey,\n loading: false,\n clusters: mergeKafkaClusters(clusters, loadManualKafkaEndpoints(persistentState)),\n source: cached.data ? \"cache\" : undefined,\n updatedAt: cached.updatedAt,\n });\n }, [cacheKey, refreshVersion, resourceCache]);\n\n const activeClusterState: ClusterLoadState =\n clusterState.cacheKey === cacheKey ? clusterState : { cacheKey, loading: true, clusters: [] };\n\n const rememberedTargetId = kubernetesClusterId\n ? rememberedKafkaTargetId(persistentState, kubernetesClusterId)\n : undefined;\n const selection = resolveKafkaClusterSelection(activeClusterState.clusters, requestedTargetId, rememberedTargetId);\n const selectedCluster = selection.state === \"selected\" ? selection.target : undefined;\n const selectedTargetId = selectedCluster?.targetId;\n const selectedNamespace = selectedCluster?.namespace;\n const selectedName = selectedCluster?.name;\n const selectedSource = selectedCluster?.source;\n const selectedBootstrap = selectedCluster?.bootstrap;\n const selectedTls = selectedCluster?.tls;\n const locatorNamespace = selectedCluster?.sourceLocator?.namespace;\n const locatorKind = selectedCluster?.sourceLocator?.kind;\n const locatorName = selectedCluster?.sourceLocator?.name;\n const locatorContainer = selectedCluster?.sourceLocator?.container;\n\n useEffect(() => {\n if (selectedCluster && selectedCluster.targetId !== requestedTargetId) {\n setRequestedTargetId(selectedCluster.targetId, true);\n }\n }, [requestedTargetId, selectedCluster, setRequestedTargetId]);\n\n useEffect(() => {\n if (!selectedCluster) {\n setMetadataState({ loading: false });\n setMetadataProgress(undefined);\n setPcReachable(undefined);\n return;\n }\n\n let cancelled = false;\n const cached = resourceCache.readOverview(cacheKey, selectedCluster.targetId);\n const cachedReachability = resourceCache.readReachability(cacheKey, selectedCluster.targetId);\n if (cachedReachability.fresh) setPcReachable(cachedReachability.data);\n\n if (cached.fresh) {\n const loadedByThisPage =\n lastNetworkMetadata.current?.targetId === selectedCluster.targetId &&\n lastNetworkMetadata.current.updatedAt === cached.updatedAt;\n metadataOperationId.current = undefined;\n setMetadataProgress(undefined);\n setMetadataState({\n cacheKey,\n loading: false,\n data: cached.data,\n source: loadedByThisPage ? \"network\" : \"cache\",\n targetId: selectedCluster.targetId,\n updatedAt: cached.updatedAt,\n });\n if (!cachedReachability.fresh) {\n reachability([selectedCluster.bootstrap])\n .then((result) => {\n if (!cancelled) setPcReachable(result[selectedCluster.bootstrap]);\n })\n .catch(() => undefined);\n }\n return () => {\n cancelled = true;\n };\n }\n\n const operationId = cached.operationId ?? createOperationId(\"overview\");\n metadataOperationId.current = operationId;\n setMetadataProgress({\n operationId,\n operation: \"overview\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing Kafka metadata\",\n detail: \"Selecting a safe read-only connection path.\",\n });\n setMetadataState({\n cacheKey,\n loading: true,\n data: cached.data,\n targetId: selectedCluster.targetId,\n updatedAt: cached.updatedAt,\n });\n if (!cachedReachability.fresh) setPcReachable(undefined);\n\n overview({\n operationId,\n targetId: selectedCluster.targetId,\n namespace: selectedCluster.namespace,\n clusterName: selectedCluster.name,\n source: selectedCluster.source,\n bootstrap: selectedCluster.bootstrap,\n tls: selectedCluster.tls,\n security: connectionSettings.get(cacheKey, selectedCluster.targetId),\n sourceLocator: selectedCluster.sourceLocator,\n })\n .then((data) => {\n if (!cancelled) {\n const snapshot = resourceCache.readOverview(cacheKey, selectedCluster.targetId);\n lastNetworkMetadata.current = { targetId: selectedCluster.targetId, updatedAt: snapshot.updatedAt };\n setMetadataState({\n cacheKey,\n loading: false,\n data,\n source: \"network\",\n targetId: selectedCluster.targetId,\n updatedAt: snapshot.updatedAt,\n });\n }\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setMetadataState({\n cacheKey,\n loading: false,\n error: error instanceof Error ? error.message : String(error),\n targetId: selectedCluster.targetId,\n });\n }\n });\n\n reachability([selectedCluster.bootstrap])\n .then((result) => {\n if (!cancelled) setPcReachable(result[selectedCluster.bootstrap]);\n })\n .catch(() => undefined);\n\n return () => {\n cancelled = true;\n };\n }, [cacheKey, connectionSettings, overview, reachability, refreshVersion, resourceCache, selectedCluster]);\n\n useEffect(() => {\n if (\n !health ||\n !selectedTargetId ||\n selectedNamespace === undefined ||\n !selectedName ||\n !selectedSource ||\n !selectedBootstrap ||\n selectedTls === undefined\n ) {\n healthOperationId.current = undefined;\n setHealthProgress(undefined);\n setHealthState({ loading: false });\n return;\n }\n\n let cancelled = false;\n let animationFrame: number | undefined;\n const cached = resourceCache.readHealth(cacheKey, selectedTargetId);\n if (cached.fresh) {\n healthOperationId.current = undefined;\n setHealthProgress(undefined);\n setHealthState({\n cacheKey,\n loading: false,\n data: cached.data,\n source: \"cache\",\n targetId: selectedTargetId,\n updatedAt: cached.updatedAt,\n });\n return;\n }\n\n const operationId = cached.operationId ?? createOperationId(\"health\");\n const forceRefresh =\n forcedHealthRefresh.current.targetId === selectedTargetId &&\n forcedHealthRefresh.current.version === healthRefreshVersion;\n if (forceRefresh) forcedHealthRefresh.current = { version: healthRefreshVersion };\n const persisted = decodeAggregateHealthSnapshot(\n persistentState.getItem(aggregateHealthSnapshotKey(cacheKey, selectedTargetId)),\n );\n const previousData = cached.data ?? persisted?.data;\n const previousSource: HealthState[\"source\"] = cached.data ? \"cache\" : persisted ? \"persisted\" : undefined;\n const previousUpdatedAt = cached.updatedAt ?? persisted?.updatedAt;\n healthOperationId.current = operationId;\n setHealthProgress({\n operationId,\n operation: \"health\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing cluster health\",\n detail: \"Broker and partition values will appear before the longer consumer lag calculation.\",\n });\n setHealthState({\n cacheKey,\n loading: true,\n data: previousData,\n source: previousSource,\n targetId: selectedTargetId,\n updatedAt: previousUpdatedAt,\n });\n const startHealth = () => {\n if (cancelled) return;\n health({\n operationId,\n targetId: selectedTargetId,\n namespace: selectedNamespace,\n clusterName: selectedName,\n source: selectedSource,\n bootstrap: selectedBootstrap,\n tls: selectedTls,\n security: connectionSettings.get(cacheKey, selectedTargetId),\n sourceLocator:\n locatorNamespace && locatorKind && locatorName\n ? { namespace: locatorNamespace, kind: locatorKind, name: locatorName, container: locatorContainer }\n : undefined,\n refresh: forceRefresh,\n })\n .then((data) => {\n if (!cancelled) {\n const completedUpdatedAt = resourceCache.readHealth(cacheKey, selectedTargetId).updatedAt;\n healthOperationId.current = undefined;\n setHealthProgress(undefined);\n setHealthState((current) => ({\n ...kafkaHealthCompletionMetadata(current, completedUpdatedAt),\n cacheKey,\n loading: false,\n data,\n targetId: selectedTargetId,\n }));\n }\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setHealthState((current) => ({\n cacheKey,\n loading: false,\n data: current.cacheKey === cacheKey && current.targetId === selectedTargetId ? current.data : undefined,\n error: error instanceof Error ? error.message : String(error),\n source:\n current.cacheKey === cacheKey && current.targetId === selectedTargetId ? current.source : undefined,\n targetId: selectedTargetId,\n updatedAt:\n current.cacheKey === cacheKey && current.targetId === selectedTargetId ? current.updatedAt : undefined,\n }));\n }\n });\n };\n if (previousData) animationFrame = window.requestAnimationFrame(startHealth);\n else startHealth();\n\n return () => {\n cancelled = true;\n if (animationFrame !== undefined) window.cancelAnimationFrame(animationFrame);\n };\n }, [\n cacheKey,\n connectionSettings,\n health,\n locatorContainer,\n locatorKind,\n locatorName,\n locatorNamespace,\n healthRefreshVersion,\n resourceCache,\n selectedBootstrap,\n selectedName,\n selectedNamespace,\n selectedSource,\n selectedTargetId,\n selectedTls,\n ]);\n\n const activeMetadataState: MetadataState =\n metadataState.cacheKey === cacheKey && metadataState.targetId === selectedCluster?.targetId\n ? metadataState\n : { cacheKey, loading: Boolean(selectedCluster), targetId: selectedCluster?.targetId };\n const cachedHealth = selectedCluster ? resourceCache.readHealth(cacheKey, selectedCluster.targetId) : undefined;\n const activeHealthState: HealthState =\n healthState.cacheKey === cacheKey && healthState.targetId === selectedCluster?.targetId\n ? healthState\n : {\n cacheKey,\n data: cachedHealth?.data,\n loading: cachedHealth?.loading ?? Boolean(health && selectedCluster && !cachedHealth?.fresh),\n source: cachedHealth?.data ? \"cache\" : undefined,\n targetId: selectedCluster?.targetId,\n updatedAt: cachedHealth?.updatedAt,\n };\n\n const selectCluster = useCallback(\n (targetId: string) => {\n const target = activeClusterState.clusters.find((cluster) => cluster.targetId === targetId);\n if (!target) return;\n if (targetId !== selectedCluster?.targetId) resourceCache.invalidateTarget(cacheKey, targetId);\n if (kubernetesClusterId) {\n rememberKafkaClusterSelection(persistentState, kubernetesClusterId, target);\n }\n setRequestedTargetId(targetId);\n },\n [\n activeClusterState.clusters,\n cacheKey,\n kubernetesClusterId,\n persistentState,\n resourceCache,\n selectedCluster?.targetId,\n setRequestedTargetId,\n ],\n );\n\n return {\n ...activeClusterState,\n selection,\n selectedCluster,\n metadataState: activeMetadataState,\n healthState: activeHealthState,\n healthProgress,\n discoveryProgress,\n metadataProgress,\n pcReachable,\n cacheStats: resourceCache.stats(cacheKey, selectedCluster?.targetId),\n selectCluster,\n refresh: () => {\n if (selectedCluster) {\n resourceCache.invalidateTarget(cacheKey, selectedCluster.targetId);\n setRefreshVersion((version) => {\n const next = version + 1;\n setHealthRefreshVersion((healthVersion) => {\n const nextHealth = healthVersion + 1;\n forcedHealthRefresh.current = { targetId: selectedCluster.targetId, version: nextHealth };\n return nextHealth;\n });\n return next;\n });\n }\n },\n refreshHealth: () => {\n if (!selectedCluster) return;\n resourceCache.invalidateHealth(cacheKey, selectedCluster.targetId);\n setHealthRefreshVersion((version) => {\n const next = version + 1;\n forcedHealthRefresh.current = { targetId: selectedCluster.targetId, version: next };\n return next;\n });\n },\n };\n}\n\nexport function KafkaResourceActions({\n state,\n onSelectCluster = state.selectCluster,\n}: {\n state: ReturnType<typeof useKafkaResourcePage>;\n onSelectCluster?: (targetId: string) => void;\n}) {\n const [now, setNow] = useState(Date.now());\n const updatedAt = state.metadataState.updatedAt ?? state.updatedAt;\n const loading = state.loading || state.metadataState.loading;\n const source = state.metadataState.data ? state.metadataState.source : state.source;\n const cacheState = loading ? (updatedAt ? \"refreshing\" : \"loading\") : source === \"cache\" ? \"cached\" : \"updated\";\n\n useEffect(() => {\n if (!updatedAt || loading) return;\n const interval = window.setInterval(() => setNow(Date.now()), 15_000);\n return () => window.clearInterval(interval);\n }, [loading, updatedAt]);\n\n const cacheLabel =\n cacheState === \"loading\"\n ? \"Loading\"\n : cacheState === \"refreshing\"\n ? \"Refreshing\"\n : `${cacheState === \"cached\" ? \"Cached\" : \"Updated\"} ${formatKafkaCacheAge(updatedAt ?? now, now)}`;\n\n return (\n <>\n <KafkaClusterSelector\n clusters={state.clusters}\n selectedTargetId={state.selectedCluster?.targetId}\n onChange={onSelectCluster}\n disabled={state.loading}\n />\n <span\n className={`KafkaCacheStatus ${cacheState}`}\n data-testid=\"kafka-cache-status\"\n data-cache-state={cacheState}\n data-cache-source={source ?? \"none\"}\n data-updated-at={updatedAt}\n data-discovery-requests={state.cacheStats.discoveryRequests}\n data-health-requests={state.cacheStats.healthRequests}\n data-overview-requests={state.cacheStats.overviewRequests}\n data-reachability-requests={state.cacheStats.reachabilityRequests}\n title={updatedAt ? `Last refreshed ${new Date(updatedAt).toLocaleString()}` : \"Loading Kafka resources\"}\n aria-live=\"polite\"\n >\n <Renderer.Component.Icon material={loading ? \"sync\" : cacheState === \"cached\" ? \"history\" : \"schedule\"} />\n <span className=\"KafkaCacheStatusLabel\">{cacheLabel}</span>\n </span>\n <Renderer.Component.Button\n outlined\n className=\"KafkaRefreshButton\"\n waiting={state.loading || state.metadataState.loading}\n onClick={state.refresh}\n title=\"Refresh Kafka metadata\"\n >\n <Renderer.Component.Icon material=\"refresh\" />\n Refresh\n </Renderer.Component.Button>\n </>\n );\n}\n\nexport function KafkaResourceState({ state }: { state: ReturnType<typeof useKafkaResourcePage> }) {\n if (state.loading && state.clusters.length === 0 && state.discoveryProgress) {\n return <OperationProgress progress={state.discoveryProgress} />;\n }\n if (state.error) {\n return (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Kafka discovery failed</strong>\n <span>{state.error}</span>\n </div>\n <Renderer.Component.Button outlined onClick={state.refresh}>\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n if (state.selection.state === \"empty\") {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"hub\" />\n <div>\n <strong>No Kafka clusters found</strong>\n <span>Open Clusters to discover or add a Kafka endpoint.</span>\n </div>\n </div>\n );\n }\n if (state.selection.state === \"required\") {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"rule\" />\n <div>\n <strong>Select a Kafka cluster</strong>\n <span>Choose one from the Kafka cluster selector to load read-only metadata.</span>\n </div>\n </div>\n );\n }\n if (state.metadataState.loading && !state.metadataState.data && state.metadataProgress) {\n return <OperationProgress progress={state.metadataProgress} />;\n }\n if (state.metadataState.error) {\n return (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Kafka metadata failed</strong>\n <span>{state.metadataState.error}</span>\n </div>\n <Renderer.Component.Button outlined onClick={state.refresh}>\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n return null;\n}\n\nfunction strategyLabel(cluster: DiscoveredKafkaInfo, pcReachable?: boolean): string {\n if (pcReachable === undefined && cluster.source !== \"strimzi\") return \"Checking reachability\";\n const strategy = chooseStrategy(cluster.source, pcReachable ?? false);\n if (strategy === \"portForward\") return \"Kubernetes port-forward\";\n if (strategy === \"direct\") return \"Direct\";\n return \"Pod-only · relay unavailable\";\n}\n\nfunction KafkaHealthCoverageNotice({ health }: { health: ClusterOverviewHealthDto | undefined }) {\n if (!kafkaHealthNeedsCoverageNotice(health) || !health) return null;\n const unavailableGroups = health.consumerGroupLagUnavailableGroups ?? 0;\n const unavailableTopics = health.consumerGroupLagUnavailableTopics ?? 0;\n const lowerBound = health.consumerGroupLag !== \"Unavailable\";\n const unavailableSummary =\n unavailableGroups > 0 || unavailableTopics > 0\n ? `${unavailableGroups} group(s) and ${unavailableTopics} topic(s) were unavailable. `\n : \"Consumer-group coverage is incomplete. \";\n\n return (\n <div className=\"KafkaHealthNotice\" role=\"status\" data-testid=\"kafka-health-notice\">\n <Renderer.Component.Icon material=\"info_outline\" />\n <div>\n <strong>{lowerBound ? \"Consumer lag is a minimum\" : \"Consumer lag unavailable\"}</strong>\n <span>\n {lowerBound ? unavailableSummary : \"Complete lag could not be calculated. \"}\n Broker and partition health is complete; the displayed lag never overstates the measured value.\n </span>\n </div>\n </div>\n );\n}\n\nfunction KafkaHealthProgressSlot({\n health,\n healthState,\n progress,\n}: {\n health: ClusterOverviewHealthDto | undefined;\n healthState: HealthState;\n progress: KafkaProgressEvent | undefined;\n}) {\n const active = Boolean((healthState.loading || healthState.error) && progress);\n return (\n <div className=\"KafkaHealthProgressSlot\" data-active={active}>\n {active && progress && (\n <HealthProgress progress={progress} error={healthState.error} hasSnapshot={Boolean(health)} />\n )}\n </div>\n );\n}\n\nfunction KafkaHealthFreshnessDetails({\n health,\n healthState,\n metadataLoading,\n metadataUpdatedAt,\n now,\n}: {\n health: ClusterOverviewHealthDto | undefined;\n healthState: HealthState;\n metadataLoading: boolean;\n metadataUpdatedAt: number | undefined;\n now: number;\n}) {\n const topologyUpdatedAt = health?.topologyMeasuredAt;\n const aggregateUpdatedAt = healthState.updatedAt;\n return (\n <>\n <div>\n <span>Metadata cache</span>\n <strong\n data-testid=\"kafka-metadata-freshness\"\n data-updated-at={metadataUpdatedAt}\n title={metadataUpdatedAt ? new Date(metadataUpdatedAt).toLocaleString() : undefined}\n >\n {metadataUpdatedAt\n ? formatKafkaCacheAge(metadataUpdatedAt, now)\n : metadataLoading\n ? \"Refreshing\"\n : \"Waiting for first result\"}\n </strong>\n </div>\n <div>\n <span>Topology health</span>\n <strong\n data-testid=\"kafka-topology-freshness\"\n data-updated-at={topologyUpdatedAt}\n title={topologyUpdatedAt ? new Date(topologyUpdatedAt).toLocaleString() : undefined}\n >\n {topologyUpdatedAt\n ? formatKafkaCacheAge(topologyUpdatedAt, now)\n : healthState.loading\n ? \"Refreshing\"\n : \"Waiting for first result\"}\n </strong>\n </div>\n <div>\n <span>Aggregate lag</span>\n <strong\n data-testid=\"kafka-aggregate-freshness\"\n data-updated-at={aggregateUpdatedAt}\n title={aggregateUpdatedAt ? new Date(aggregateUpdatedAt).toLocaleString() : undefined}\n >\n {aggregateUpdatedAt\n ? formatKafkaCacheAge(aggregateUpdatedAt, now)\n : healthState.loading\n ? \"Refreshing\"\n : \"Waiting for first result\"}\n </strong>\n </div>\n <div>\n <span>Coverage</span>\n <strong data-testid=\"kafka-health-coverage\" data-coverage={kafkaHealthCoverageState(health)}>\n {kafkaHealthCoverageLabel(health)}\n </strong>\n </div>\n </>\n );\n}\n\nexport function KafkaClusterOverviewPage(props: KafkaTargetPageProps) {\n const state = useKafkaResourcePage(props);\n const cluster = state.selectedCluster;\n const data = state.metadataState.data;\n const overviewSettings = props.overviewSettings;\n const health = state.healthState.data;\n const metadataUpdatedAt = state.metadataState.updatedAt;\n const [autoRefreshEnabled, setAutoRefreshEnabled] = useState(() =>\n cluster ? (overviewSettings?.get(cluster.targetId)?.enabled ?? false) : false,\n );\n const [autoRefreshInterval, setAutoRefreshInterval] = useState(() =>\n cluster\n ? (overviewSettings?.get(cluster.targetId)?.intervalMs ?? DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS)\n : DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS,\n );\n const [freshnessNow, setFreshnessNow] = useState(Date.now());\n\n useEffect(() => {\n if (!cluster || !overviewSettings) return;\n const settings = overviewSettings.get(cluster.targetId);\n setAutoRefreshEnabled(settings.enabled);\n setAutoRefreshInterval(settings.intervalMs);\n }, [cluster, overviewSettings]);\n\n useEffect(() => {\n if (!cluster || !overviewSettings) return;\n if (!autoRefreshEnabled) {\n overviewSettings.set(cluster.targetId, { enabled: false, intervalMs: autoRefreshInterval });\n return;\n }\n overviewSettings.set(cluster.targetId, { enabled: true, intervalMs: autoRefreshInterval });\n const timer = window.setInterval(() => {\n if (!state.healthState.loading) state.refreshHealth();\n }, autoRefreshInterval);\n return () => window.clearInterval(timer);\n }, [autoRefreshEnabled, autoRefreshInterval, cluster, overviewSettings, state]);\n\n useEffect(() => {\n setFreshnessNow(Date.now());\n if (!metadataUpdatedAt && !health?.topologyMeasuredAt && !state.healthState.updatedAt) return;\n const interval = window.setInterval(() => setFreshnessNow(Date.now()), 15_000);\n return () => window.clearInterval(interval);\n }, [health?.topologyMeasuredAt, metadataUpdatedAt, state.healthState.updatedAt]);\n\n const healthMetrics = (\n <KafkaMetricStrip\n ariaLabel=\"Kafka cluster health\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[\n {\n label: \"Online brokers\",\n value: clusterHealthMetricValue(state.healthState, health?.onlineBrokers, true),\n },\n {\n label: \"Unavailable partitions\",\n value: clusterHealthMetricValue(state.healthState, health?.unavailablePartitions, true),\n tone: health && health.unavailablePartitions > 0 ? \"error\" : undefined,\n },\n {\n label: \"Under-replicated\",\n value: clusterHealthMetricValue(state.healthState, health?.underReplicatedPartitions, true),\n tone: health && health.underReplicatedPartitions > 0 ? \"warning\" : undefined,\n },\n {\n label: \"Consumer lag\",\n value: clusterHealthMetricValue(state.healthState, health?.consumerGroupLag, true),\n tone:\n health?.consumerGroupLag === \"Unavailable\" ||\n health?.consumerGroupLagUnavailableTopics ||\n health?.consumerGroupLagUnavailableGroups\n ? \"warning\"\n : undefined,\n },\n ]}\n />\n );\n\n return (\n <KafkaPageShell\n title=\"Overview\"\n subtitle={cluster ? cluster.name : \"Health, identity and connection metadata\"}\n actions={<KafkaResourceActions state={state} />}\n >\n <KafkaResourceState state={state} />\n {cluster && health && !data && (\n <main\n className=\"KafkaResourcePage\"\n data-testid=\"kafka-overview-page\"\n data-health-state={state.healthState.loading ? \"updating\" : \"ready\"}\n data-health-error={state.healthState.error ?? undefined}\n data-health-source={state.healthState.source}\n data-health-updated-at={state.healthState.updatedAt}\n >\n {healthMetrics}\n <KafkaHealthProgressSlot health={health} healthState={state.healthState} progress={state.healthProgress} />\n {state.healthState.error && (\n <div className=\"KafkaHealthNotice\" role=\"status\" data-testid=\"kafka-health-notice\">\n <Renderer.Component.Icon material=\"info_outline\" />\n <div>\n <strong>Health refresh failed</strong>\n <span>{state.healthState.error} Previous measured values remain visible.</span>\n </div>\n </div>\n )}\n <KafkaHealthCoverageNotice health={health} />\n <section className=\"KafkaResourceDetails\" aria-label=\"Kafka health freshness\">\n <KafkaHealthFreshnessDetails\n health={health}\n healthState={state.healthState}\n metadataLoading={state.metadataState.loading}\n metadataUpdatedAt={metadataUpdatedAt}\n now={freshnessNow}\n />\n </section>\n </main>\n )}\n {cluster && data && (\n <main\n className=\"KafkaResourcePage\"\n data-testid=\"kafka-overview-page\"\n data-health-state={state.healthState.loading ? \"updating\" : state.healthState.error ? \"unavailable\" : \"ready\"}\n data-health-source={state.healthState.source}\n data-health-updated-at={state.healthState.updatedAt}\n >\n <KafkaMetricStrip\n ariaLabel=\"Kafka cluster summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[\n {\n label: \"Online brokers\",\n value: clusterHealthMetricValue(state.healthState, health?.onlineBrokers, true),\n },\n { label: \"Controller\", value: data.controller ?? \"—\" },\n { label: \"Topics\", value: data.topics.length },\n {\n label: \"Unavailable partitions\",\n value: clusterHealthMetricValue(state.healthState, health?.unavailablePartitions, true),\n tone: health && health.unavailablePartitions > 0 ? \"error\" : undefined,\n },\n {\n label: \"Under-replicated\",\n value: clusterHealthMetricValue(state.healthState, health?.underReplicatedPartitions, true),\n tone: health && health.underReplicatedPartitions > 0 ? \"warning\" : undefined,\n },\n {\n label: \"Consumer lag\",\n value: clusterHealthMetricValue(state.healthState, health?.consumerGroupLag, true),\n tone:\n health?.consumerGroupLag === \"Unavailable\" ||\n health?.consumerGroupLagUnavailableTopics ||\n health?.consumerGroupLagUnavailableGroups\n ? \"warning\"\n : undefined,\n },\n ]}\n />\n <KafkaHealthProgressSlot health={health} healthState={state.healthState} progress={state.healthProgress} />\n <KafkaHealthCoverageNotice health={health} />\n <section className=\"KafkaResourceDetails\" aria-label=\"Kafka connection summary\">\n <div>\n <span>Source</span>\n <SourceBadge kafka={cluster} />\n </div>\n <div>\n <span>Security</span>\n <SecurityBadge security={data.security ?? cluster.securityHint ?? { tls: cluster.tls, auth: \"none\" }} />\n </div>\n <div>\n <span>From PC</span>\n <ReachabilityBadge value={state.pcReachable} label />\n </div>\n <div>\n <span>Connection</span>\n <strong>{strategyLabel(cluster, state.pcReachable)}</strong>\n </div>\n <div>\n <span>Bootstrap</span>\n <code title={cluster.bootstrap}>{cluster.bootstrap}</code>\n </div>\n <div>\n <span>Kubernetes usage</span>\n <strong>{kafkaUsageContext(cluster)}</strong>\n </div>\n <KafkaHealthFreshnessDetails\n health={health}\n healthState={state.healthState}\n metadataLoading={state.metadataState.loading}\n metadataUpdatedAt={metadataUpdatedAt}\n now={freshnessNow}\n />\n <div>\n <span>Auto-refresh</span>\n <div className=\"KafkaAutoRefreshControl\">\n <Renderer.Component.Switch\n checked={autoRefreshEnabled}\n onChange={setAutoRefreshEnabled}\n aria-label=\"Enable auto-refresh\"\n />\n {autoRefreshEnabled && (\n <Renderer.Component.Select\n options={KAFKA_OVERVIEW_AUTO_REFRESH_OPTIONS}\n value={String(autoRefreshInterval)}\n onChange={(option) => {\n const next = Number(option?.value ?? \"30000\");\n setAutoRefreshInterval(next);\n }}\n aria-label=\"Refresh interval\"\n />\n )}\n </div>\n </div>\n </section>\n </main>\n )}\n </KafkaPageShell>\n );\n}\n\nconst BROKER_CONFIG_NAME_STYLE: CSSProperties = { flex: \"0 0 240px\", minWidth: 240, width: 240 };\nconst BROKER_CONFIG_VALUE_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst BROKER_CONFIG_SOURCE_STYLE: CSSProperties = { flex: \"0 0 230px\", minWidth: 230, width: 230 };\nconst BROKER_CONFIG_FLAGS_STYLE: CSSProperties = { flex: \"0 0 140px\", minWidth: 140, width: 140 };\n\ninterface BrokerConfigState {\n brokerId?: number;\n loading: boolean;\n data?: BrokerConfigDto;\n error?: string;\n progress?: KafkaProgressEvent;\n}\n\nfunction BrokerConfigView({ state, onRetry }: { state: BrokerConfigState; onRetry: () => void }) {\n if (state.loading && state.progress) return <OperationProgress progress={state.progress} />;\n if (state.loading) return <Renderer.Component.Spinner center />;\n if (state.error) {\n return (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Failed to load broker configuration</strong>\n <span>{state.error}</span>\n </div>\n <Renderer.Component.Button outlined onClick={onRetry}>\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n if (!state.data || state.data.entries.length === 0) {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"tune\" />\n <div>\n <strong>No configuration entries</strong>\n <span>Kafka returned no configuration entries for this broker.</span>\n </div>\n </div>\n );\n }\n\n return (\n <Renderer.Component.Table<KafkaConfigEntryDto>\n className=\"KafkaBrokerConfigTable\"\n tableId=\"kafka-broker-configuration\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"name\", orderBy: \"asc\" }}\n sortable={{ name: (entry) => entry.name.toLowerCase() }}\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell className=\"configNameCell\" sortBy=\"name\" style={BROKER_CONFIG_NAME_STYLE}>\n Name\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configValueCell\" style={BROKER_CONFIG_VALUE_STYLE}>\n Value\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configSourceCell\" style={BROKER_CONFIG_SOURCE_STYLE}>\n Source\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configFlagsCell\" style={BROKER_CONFIG_FLAGS_STYLE}>\n Flags\n </Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {state.data.entries.map((entry) => (\n <Renderer.Component.TableRow key={entry.name} sortItem={entry} nowrap>\n <Renderer.Component.TableCell className=\"configNameCell\" title={entry.name} style={BROKER_CONFIG_NAME_STYLE}>\n <span className=\"KafkaEllipsis\">{entry.name}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell\n className=\"configValueCell\"\n title={entry.value}\n style={BROKER_CONFIG_VALUE_STYLE}\n >\n <span className=\"KafkaEllipsis KafkaMono\">{entry.value || \"—\"}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configSourceCell\" style={BROKER_CONFIG_SOURCE_STYLE}>\n <span className=\"KafkaConfigSource\">{entry.source}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configFlagsCell\" style={BROKER_CONFIG_FLAGS_STYLE}>\n <div className=\"KafkaConfigFlags\">\n {entry.readOnly ? <Renderer.Component.Badge small label=\"Read-only\" /> : null}\n {entry.sensitive ? <Renderer.Component.Badge small label=\"Sensitive\" /> : null}\n {!entry.readOnly && !entry.sensitive ? <span>—</span> : null}\n </div>\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n ))}\n </Renderer.Component.Table>\n );\n}\n\nexport function KafkaBrokersPage(props: KafkaBrokersPageProps) {\n const state = useKafkaResourcePage(props);\n const [rawBrokerId, setRawBrokerId] = useKafkaPageParam(props.params?.broker);\n const cluster = state.selectedCluster;\n const data = state.metadataState.data;\n const parsedBrokerId = /^\\d+$/.test(rawBrokerId) ? Number(rawBrokerId) : undefined;\n const broker = data?.brokers.find((candidate) => candidate.nodeId === parsedBrokerId);\n const workspaceTargetId = useRef<string>();\n const operationId = useRef<string>();\n const [configState, setConfigState] = useState<BrokerConfigState>({ loading: false });\n\n useEffect(\n () =>\n props.subscribeProgress((progress) => {\n if (progress.operation === \"brokerConfig\" && progress.operationId === operationId.current) {\n setConfigState((current) => ({ ...current, progress }));\n }\n }),\n [props.subscribeProgress],\n );\n\n useEffect(() => {\n const selectedTargetId = cluster?.targetId;\n if (!selectedTargetId) return;\n if (!rawBrokerId) {\n workspaceTargetId.current = selectedTargetId;\n return;\n }\n const previous = workspaceTargetId.current;\n workspaceTargetId.current = selectedTargetId;\n if (previous && previous !== selectedTargetId) setRawBrokerId(\"\", true);\n }, [cluster?.targetId, rawBrokerId, setRawBrokerId]);\n\n const loadBrokerConfig = useCallback(() => {\n if (!cluster || !broker) {\n operationId.current = undefined;\n setConfigState({ loading: false });\n return;\n }\n const nextOperationId = createOperationId(\"brokerConfig\");\n operationId.current = nextOperationId;\n const progress: KafkaProgressEvent = {\n operationId: nextOperationId,\n operation: \"brokerConfig\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing broker configuration\",\n detail: \"Selecting the existing read-only connection path.\",\n };\n setConfigState({ brokerId: broker.nodeId, loading: true, progress });\n props\n .brokerConfig({\n operationId: nextOperationId,\n targetId: cluster.targetId,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: props.connectionSettings.get(props.kubernetesClusterId ?? \"active\", cluster.targetId),\n brokerId: broker.nodeId,\n })\n .then((result) => {\n if (operationId.current === nextOperationId) {\n setConfigState({ brokerId: broker.nodeId, loading: false, data: result });\n }\n })\n .catch((error: unknown) => {\n if (operationId.current !== nextOperationId) return;\n setConfigState({\n brokerId: broker.nodeId,\n loading: false,\n error: error instanceof Error ? error.message : String(error),\n progress,\n });\n });\n }, [broker, cluster, props.brokerConfig, props.connectionSettings, props.kubernetesClusterId]);\n\n useEffect(() => {\n if (!broker || configState.brokerId === broker.nodeId) return;\n loadBrokerConfig();\n }, [broker, configState.brokerId, loadBrokerConfig]);\n\n useEffect(\n () => () => {\n operationId.current = undefined;\n },\n [],\n );\n\n const selectWorkspaceCluster = (targetId: string): void => {\n state.selectCluster(targetId);\n setRawBrokerId(\"\", true);\n };\n\n if (rawBrokerId) {\n return (\n <KafkaPageShell\n title={broker ? `Broker ${broker.nodeId}` : \"Broker\"}\n subtitle={cluster ? `Brokers / ${cluster.name}` : \"Broker Workspace\"}\n actions={\n <>\n <Renderer.Component.Button outlined onClick={() => setRawBrokerId(\"\")}>\n <Renderer.Component.Icon material=\"arrow_back\" />\n Brokers\n </Renderer.Component.Button>\n <KafkaResourceActions state={state} onSelectCluster={selectWorkspaceCluster} />\n </>\n }\n >\n <KafkaResourceState state={state} />\n {cluster && data && !broker && (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Broker not found</strong>\n <span>Broker {rawBrokerId} was not returned by this Kafka cluster.</span>\n </div>\n </div>\n )}\n {cluster && data && broker && (\n <main className=\"KafkaResourcePage KafkaBrokerWorkspace\" data-testid=\"kafka-broker-workspace\">\n <KafkaMetricStrip\n ariaLabel=\"Kafka broker detail summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[\n { label: \"Broker\", value: broker.nodeId },\n { label: \"Role\", value: broker.nodeId === data.controller ? \"Controller\" : \"Broker\" },\n { label: \"Config entries\", value: configState.data?.entries.length ?? \"—\" },\n ]}\n />\n <section className=\"KafkaResourceDetails\" aria-label=\"Kafka broker identity\">\n <div>\n <span>Advertised host</span>\n <code title={broker.host}>{broker.host}</code>\n </div>\n <div>\n <span>Advertised port</span>\n <strong>{broker.port}</strong>\n </div>\n </section>\n <section className=\"KafkaBrokerConfigSection\" aria-label={`Configuration for broker ${broker.nodeId}`}>\n <h2>Configuration</h2>\n <BrokerConfigView state={configState} onRetry={loadBrokerConfig} />\n </section>\n </main>\n )}\n </KafkaPageShell>\n );\n }\n\n return (\n <KafkaPageShell\n title=\"Brokers\"\n subtitle={cluster ? cluster.name : \"Broker identities and advertised endpoints\"}\n actions={<KafkaResourceActions state={state} />}\n >\n <KafkaResourceState state={state} />\n {cluster && data && (\n <main className=\"KafkaResourcePage\" data-testid=\"kafka-brokers-page\">\n <KafkaMetricStrip\n ariaLabel=\"Kafka broker summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[\n { label: \"Brokers\", value: data.brokers.length },\n { label: \"Controller\", value: data.controller ?? \"—\" },\n { label: \"Advertised endpoints\", value: data.brokers.length },\n ]}\n />\n {data.brokers.length === 0 ? (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"dns\" />\n <div>\n <strong>No brokers reported</strong>\n <span>Kafka metadata returned no broker identities.</span>\n </div>\n </div>\n ) : (\n <Renderer.Component.Table autoSize={false} scrollable className=\"KafkaBrokerPageTable\">\n <Renderer.Component.TableHead nowrap>\n <Renderer.Component.TableCell className=\"brokerIdCell\">Broker</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerRoleCell\">Role</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerHostCell\">Advertised host</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerPortCell\">Port</Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {data.brokers.map((broker) => {\n const open = (event: { stopPropagation: () => void }): void => {\n event.stopPropagation();\n setRawBrokerId(String(broker.nodeId));\n };\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open broker ${broker.nodeId}`,\n onClick: open,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n open(event);\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={broker.nodeId}\n data-broker={broker.nodeId}\n nowrap\n >\n <Renderer.Component.TableCell className=\"brokerIdCell\">\n <strong>{broker.nodeId}</strong>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerRoleCell\">\n <Renderer.Component.Badge\n small\n className={broker.nodeId === data.controller ? \"KafkaControllerBadge\" : \"\"}\n label={broker.nodeId === data.controller ? \"Controller\" : \"Broker\"}\n />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerHostCell\" title={broker.host}>\n <code className=\"KafkaEllipsis\">{broker.host}</code>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"brokerPortCell\">\n {broker.port}\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n )}\n <div className=\"KafkaResourceFootnote\">\n Broker membership comes from cluster metadata; it is not an individual health probe.\n </div>\n </main>\n )}\n </KafkaPageShell>\n );\n}\n","export interface WriteActionConfirmationState {\n confirmationAccepted: boolean;\n requiredResourceName?: string;\n enteredResourceName?: string;\n}\n\nexport function canSubmitWriteAction({\n confirmationAccepted,\n requiredResourceName,\n enteredResourceName = \"\",\n}: WriteActionConfirmationState): boolean {\n if (!confirmationAccepted) return false;\n if (!requiredResourceName) return true;\n\n return enteredResourceName === requiredResourceName;\n}\n\nexport function getWriteConfirmationLabel({\n destructive,\n resourceName,\n}: {\n destructive: boolean;\n resourceName: string;\n}): string {\n if (destructive) return `Type ${resourceName} to confirm`;\n return \"Confirm once\";\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { KafkaPageShell } from \"./kafka-page-shell\";\nimport { KafkaResourceActions, type KafkaResourcePageDependencies, useKafkaResourcePage } from \"./kafka-resource-pages\";\nimport { canSubmitWriteAction } from \"./kafka-write-policy\";\n\nimport type { HTMLAttributes } from \"react\";\n\nimport type { AclWriteRequest, KafkaAclDto, KafkaAclResultDto, KafkaWorkloadSourceLocator } from \"../common/ipc\";\n\nconst RESOURCE_TYPES = [\"TOPIC\", \"GROUP\", \"CLUSTER\", \"TRANSACTIONAL_ID\"];\nconst PATTERN_TYPES = [\"LITERAL\", \"PREFIXED\"];\nconst OPERATIONS = [\"READ\", \"WRITE\", \"ALL\", \"CREATE\", \"DELETE\", \"ALTER\", \"DESCRIBE\"];\nconst PERMISSION_TYPES = [\"ALLOW\", \"DENY\"];\n\ninterface AclTargetRequest {\n namespace: string;\n clusterName: string;\n source: string;\n bootstrap: string;\n tls: boolean;\n targetId: string;\n sourceLocator?: KafkaWorkloadSourceLocator;\n}\n\nexport interface KafkaAclPageProps extends KafkaResourcePageDependencies {\n params?: { target: Renderer.Navigation.PageParam<string> };\n acls: (request: AclTargetRequest) => Promise<KafkaAclResultDto>;\n aclCreate: (request: AclWriteRequest) => Promise<void>;\n aclDelete: (request: AclWriteRequest) => Promise<void>;\n}\n\nfunction describeRule(acl: KafkaAclDto): string {\n return `${acl.permissionType} ${acl.principal} ${acl.operation} on ${acl.resourceType} ${acl.patternType} \"${acl.resourceName}\" from ${acl.host}`;\n}\n\nexport function KafkaAclPage({ params, acls, aclCreate, aclDelete, ...dependencies }: KafkaAclPageProps) {\n const state = useKafkaResourcePage({ ...dependencies, params });\n const cluster = state.selectedCluster;\n const request = useMemo<AclTargetRequest | undefined>(\n () =>\n cluster\n ? {\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n targetId: cluster.targetId,\n }\n : undefined,\n [cluster],\n );\n\n const [result, setResult] = useState<KafkaAclResultDto>();\n const [principalFilter, setPrincipalFilter] = useState(\"\");\n const [resourceTypeFilter, setResourceTypeFilter] = useState(\"ALL\");\n const [operationFilter, setOperationFilter] = useState(\"ALL\");\n\n const [resourceType, setResourceType] = useState(\"TOPIC\");\n const [resourceName, setResourceName] = useState(\"\");\n const [patternType, setPatternType] = useState(\"LITERAL\");\n const [principal, setPrincipal] = useState(\"\");\n const [host, setHost] = useState(\"*\");\n const [operation, setOperation] = useState(\"READ\");\n const [permissionType, setPermissionType] = useState(\"ALLOW\");\n\n const [createConfirmed, setCreateConfirmed] = useState(false);\n const [selected, setSelected] = useState<KafkaAclDto>();\n const [deleteConfirmed, setDeleteConfirmed] = useState(false);\n const [deleteText, setDeleteText] = useState(\"\");\n const [writeStatus, setWriteStatus] = useState<string>();\n const [writeError, setWriteError] = useState<string>();\n const [busy, setBusy] = useState(false);\n\n const reload = useCallback(async () => {\n if (!request) return;\n setResult(await acls(request));\n }, [acls, request]);\n\n useEffect(() => {\n reload().catch((error: unknown) =>\n setResult({\n available: false,\n acls: [],\n message: error instanceof Error ? error.message : String(error),\n }),\n );\n }, [reload]);\n\n useEffect(() => {\n setSelected(undefined);\n setWriteStatus(undefined);\n setWriteError(undefined);\n }, [cluster?.targetId]);\n\n const filtered = useMemo(\n () =>\n (result?.acls ?? []).filter(\n (acl) =>\n (resourceTypeFilter === \"ALL\" || acl.resourceType === resourceTypeFilter) &&\n (operationFilter === \"ALL\" || acl.operation === operationFilter) &&\n acl.principal.toLowerCase().includes(principalFilter.toLowerCase()),\n ),\n [operationFilter, principalFilter, resourceTypeFilter, result],\n );\n\n const canWrite = Boolean(cluster && dependencies.writeSettings.get(cluster.targetId));\n const draft: KafkaAclDto = { resourceType, resourceName, patternType, principal, host, operation, permissionType };\n const draftComplete = resourceName.trim().length > 0 && principal.trim().length > 0 && host.trim().length > 0;\n\n const runWrite = async (action: (write: AclWriteRequest) => Promise<void>, acl: KafkaAclDto, done: string) => {\n if (!request) return;\n setBusy(true);\n setWriteError(undefined);\n setWriteStatus(undefined);\n try {\n await action({ ...request, acl });\n await reload();\n setWriteStatus(done);\n } catch (error: unknown) {\n setWriteError(error instanceof Error ? error.message : String(error));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <KafkaPageShell\n title=\"ACLs\"\n subtitle={cluster?.name ?? \"Kafka security rules\"}\n actions={<KafkaResourceActions state={state} />}\n >\n <main className=\"KafkaResourcePage\" data-testid=\"kafka-acl-page\">\n <div className=\"KafkaToolbar\">\n <Renderer.Component.Input\n value={principalFilter}\n onChange={setPrincipalFilter}\n placeholder=\"Filter principal\"\n aria-label=\"Filter ACL principal\"\n />\n <select\n value={resourceTypeFilter}\n onChange={(event) => setResourceTypeFilter(event.target.value)}\n aria-label=\"Filter ACL resource type\"\n >\n {[\"ALL\", ...RESOURCE_TYPES].map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n <select\n value={operationFilter}\n onChange={(event) => setOperationFilter(event.target.value)}\n aria-label=\"Filter ACL operation\"\n >\n {[\"ALL\", ...OPERATIONS].map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n </div>\n\n {result && !result.available ? (\n <div className=\"KafkaPageState empty\" data-testid=\"kafka-acl-unavailable\">\n {result.message}\n </div>\n ) : (\n <>\n {result && filtered.length === 0 && <div className=\"KafkaPageState empty\">No ACL rules match.</div>}\n <Renderer.Component.Table className=\"KafkaAclTable\">\n <Renderer.Component.TableHead>\n <Renderer.Component.TableCell>Resource</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Pattern</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Principal</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Host</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Operation</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Permission</Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {filtered.map((acl) => {\n const selectAcl = (): void => {\n setSelected(acl);\n setDeleteText(\"\");\n setDeleteConfirmed(false);\n };\n const interaction: HTMLAttributes<HTMLDivElement> = {\n tabIndex: 0,\n onClick: selectAcl,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n selectAcl();\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n key={describeRule(acl)}\n data-resource-type={acl.resourceType}\n data-principal={acl.principal}\n >\n <Renderer.Component.TableCell>\n {acl.resourceType}:{acl.resourceName}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{acl.patternType}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{acl.principal}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{acl.host}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{acl.operation}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{acl.permissionType}</Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n </>\n )}\n\n {canWrite && result?.available && (\n <section className=\"KafkaWriteDrawer\" data-testid=\"kafka-acl-write-controls\" aria-label=\"ACL write actions\">\n <div className=\"KafkaWriteForm\" style={{ display: \"grid\", gap: 12 }}>\n <select\n value={resourceType}\n onChange={(event) => setResourceType(event.target.value)}\n aria-label=\"ACL resource type\"\n >\n {RESOURCE_TYPES.map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n <Renderer.Component.Input\n value={resourceName}\n onChange={setResourceName}\n placeholder=\"Resource name\"\n aria-label=\"ACL resource name\"\n />\n <select\n value={patternType}\n onChange={(event) => setPatternType(event.target.value)}\n aria-label=\"ACL pattern type\"\n >\n {PATTERN_TYPES.map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n <Renderer.Component.Input\n value={principal}\n onChange={setPrincipal}\n placeholder=\"User:name\"\n aria-label=\"ACL principal\"\n />\n <Renderer.Component.Input value={host} onChange={setHost} placeholder=\"*\" aria-label=\"ACL host\" />\n <select\n value={operation}\n onChange={(event) => setOperation(event.target.value)}\n aria-label=\"ACL operation\"\n >\n {OPERATIONS.map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n <select\n value={permissionType}\n onChange={(event) => setPermissionType(event.target.value)}\n aria-label=\"ACL permission type\"\n >\n {PERMISSION_TYPES.map((value) => (\n <option key={value}>{value}</option>\n ))}\n </select>\n </div>\n\n <div data-testid=\"kafka-acl-rule-preview\">{describeRule(draft)}</div>\n <Renderer.Component.Switch\n checked={createConfirmed}\n onChange={setCreateConfirmed}\n aria-label=\"Confirm ACL create\"\n />\n <Renderer.Component.Button\n disabled={busy || !draftComplete || !canSubmitWriteAction({ confirmationAccepted: createConfirmed })}\n onClick={() => void runWrite(aclCreate, draft, `Created ACL for ${draft.principal}`)}\n >\n Create ACL\n </Renderer.Component.Button>\n\n {selected && (\n <div data-testid=\"kafka-acl-delete-controls\">\n <div data-testid=\"kafka-acl-selected-rule\">{describeRule(selected)}</div>\n <Renderer.Component.Input\n value={deleteText}\n onChange={setDeleteText}\n placeholder={selected.resourceName}\n aria-label=\"Type ACL resource to confirm deletion\"\n />\n <Renderer.Component.Switch\n checked={deleteConfirmed}\n onChange={setDeleteConfirmed}\n aria-label=\"Confirm ACL deletion\"\n />\n <Renderer.Component.Button\n disabled={\n busy ||\n !canSubmitWriteAction({\n confirmationAccepted: deleteConfirmed,\n requiredResourceName: selected.resourceName,\n enteredResourceName: deleteText,\n })\n }\n onClick={() =>\n void runWrite(aclDelete, selected, `Deleted ACL for ${selected.principal}`).then(() =>\n setSelected(undefined),\n )\n }\n >\n Delete ACL\n </Renderer.Component.Button>\n </div>\n )}\n\n {writeStatus && (\n <div role=\"status\" data-testid=\"kafka-acl-write-status\">\n {writeStatus}\n </div>\n )}\n {writeError && (\n <div role=\"alert\" data-testid=\"kafka-acl-write-error\">\n {writeError}\n </div>\n )}\n </section>\n )}\n </main>\n </KafkaPageShell>\n );\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { KafkaPageShell } from \"./kafka-page-shell\";\nimport { type KafkaResourcePageDependencies, useKafkaPageParam, useKafkaResourcePage } from \"./kafka-resource-pages\";\nimport { canSubmitWriteAction } from \"./kafka-write-policy\";\n\nimport type { HTMLAttributes } from \"react\";\n\nimport type { ConnectorDetailDto, ConnectorSummaryDto, KafkaConnectCreateRequest } from \"../common/ipc\";\nimport type { KafkaConnectSettingsStore } from \"./kafka-connect-settings\";\n\nexport interface KafkaConnectPageProps extends KafkaResourcePageDependencies {\n params?: {\n target: Renderer.Navigation.PageParam<string>;\n query: Renderer.Navigation.PageParam<string>;\n connector: Renderer.Navigation.PageParam<string>;\n };\n connectSettings: KafkaConnectSettingsStore;\n connectNames: (request: { connectUrl: string; connectUsername?: string }) => Promise<string[]>;\n connectDetail: (request: {\n connectUrl: string;\n connectUsername?: string;\n connector: string;\n }) => Promise<ConnectorDetailDto>;\n connectPause: (request: { connectUrl: string; connectUsername?: string; connector: string }) => Promise<void>;\n connectResume: (request: { connectUrl: string; connectUsername?: string; connector: string }) => Promise<void>;\n connectDelete: (request: { connectUrl: string; connectUsername?: string; connector: string }) => Promise<void>;\n connectRestart: (request: { connectUrl: string; connectUsername?: string; connector: string }) => Promise<void>;\n connectUpdate: (request: KafkaConnectCreateRequest) => Promise<void>;\n connectCreate: (request: KafkaConnectCreateRequest) => Promise<{ name: string }>;\n}\n\nexport function KafkaConnectPage({\n params,\n connectSettings,\n connectNames,\n connectDetail,\n connectPause,\n connectResume,\n connectDelete,\n connectRestart,\n connectUpdate,\n connectCreate,\n ...dependencies\n}: KafkaConnectPageProps) {\n const state = useKafkaResourcePage({ ...dependencies, params });\n const [query, setQuery] = useKafkaPageParam(params?.query);\n const [connector, setConnector] = useKafkaPageParam(params?.connector);\n const selectedTargetId = state.selectedCluster?.targetId;\n const settings = useMemo(\n () => (selectedTargetId ? connectSettings.get(selectedTargetId) : undefined),\n [connectSettings, selectedTargetId],\n );\n const [items, setItems] = useState<ConnectorSummaryDto[]>([]);\n const [detail, setDetail] = useState<ConnectorDetailDto>();\n const [error, setError] = useState<string>();\n\n useEffect(() => {\n if (!settings) return void setItems([]);\n connectNames(settings)\n .then((names) => setItems(names.map((name) => ({ name, status: \"Details on open\", taskCount: 0 }))))\n .catch((reason: unknown) => setError(reason instanceof Error ? reason.message : String(reason)));\n }, [connectNames, settings]);\n useEffect(() => {\n if (!settings || !connector) return void setDetail(undefined);\n connectDetail({ ...settings, connector })\n .then(setDetail)\n .catch((reason: unknown) => setError(reason instanceof Error ? reason.message : String(reason)));\n }, [connectDetail, connector, settings]);\n\n const filtered = items.filter((item) => item.name.toLowerCase().includes(query.toLowerCase()));\n const canWrite = Boolean(state.selectedCluster && dependencies.writeSettings.get(state.selectedCluster.targetId));\n const [confirmed, setConfirmed] = useState(false);\n const [deleteText, setDeleteText] = useState(\"\");\n const [status, setStatus] = useState<string>();\n const [configText, setConfigText] = useState(\n '{\\n \"name\": \"new-connector\",\\n \"connector.class\": \"ExampleSource\"\\n}',\n );\n const [configError, setConfigError] = useState<string>();\n if (!settings)\n return (\n <KafkaPageShell title=\"Kafka Connect\" subtitle=\"No Connect endpoint configured\">\n <div className=\"KafkaPageState empty\" data-testid=\"kafka-connect-unconfigured\">\n Configure a Connect endpoint in Kafka settings.\n </div>\n </KafkaPageShell>\n );\n return (\n <KafkaPageShell title=\"Kafka Connect\" subtitle={settings.connectUrl}>\n <main className=\"KafkaWorkspace\" data-testid=\"kafka-connect-page\">\n <section className=\"KafkaListPane\">\n <Renderer.Component.Input\n value={query}\n onChange={(value) => setQuery(value, true)}\n placeholder=\"Filter connectors\"\n aria-label=\"Filter connectors\"\n />\n {error && <div role=\"alert\">{error}</div>}\n <Renderer.Component.Table className=\"KafkaConnectTable\">\n <Renderer.Component.TableHead>\n <Renderer.Component.TableCell>Name</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Type</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Status</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Tasks</Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {filtered.map((item) => {\n const interaction: HTMLAttributes<HTMLDivElement> = {\n tabIndex: 0,\n onClick: () => setConnector(item.name),\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setConnector(item.name);\n }\n },\n };\n return (\n <Renderer.Component.TableRow {...interaction} key={item.name} data-connector={item.name}>\n <Renderer.Component.TableCell>{item.name}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.type ?? \"unknown\"}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.status}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.taskCount}</Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n </section>\n {detail && (\n <aside className=\"KafkaDetailPane\" data-testid=\"kafka-connect-detail\">\n <h2>{detail.name}</h2>\n <p>{detail.connector.state}</p>\n {detail.tasks.map((task) => (\n <article key={task.id}>\n <strong>\n Task {task.id}: {task.state}\n </strong>\n {task.trace && <pre>{task.trace}</pre>}\n </article>\n ))}\n {canWrite && settings && (\n <section data-testid=\"kafka-connect-write-controls\">\n <Renderer.Component.Switch\n checked={confirmed}\n onChange={setConfirmed}\n aria-label=\"Confirm Connect action\"\n />\n <Renderer.Component.Button\n disabled={!canSubmitWriteAction({ confirmationAccepted: confirmed })}\n onClick={() =>\n void connectPause({ ...settings, connector }).then(() => setStatus(\"Paused connector\"))\n }\n >\n Pause\n </Renderer.Component.Button>\n <Renderer.Component.Button\n disabled={!canSubmitWriteAction({ confirmationAccepted: confirmed })}\n onClick={() =>\n void connectResume({ ...settings, connector }).then(() => setStatus(\"Resumed connector\"))\n }\n >\n Resume\n </Renderer.Component.Button>\n <Renderer.Component.Button\n disabled={!canSubmitWriteAction({ confirmationAccepted: confirmed })}\n onClick={() =>\n void connectRestart({ ...settings, connector }).then(() => setStatus(\"Restarted connector\"))\n }\n >\n Restart\n </Renderer.Component.Button>\n <Renderer.Component.Input\n value={deleteText}\n onChange={setDeleteText}\n aria-label=\"Type connector to confirm deletion\"\n />\n <Renderer.Component.Button\n disabled={\n !canSubmitWriteAction({\n confirmationAccepted: confirmed,\n requiredResourceName: connector,\n enteredResourceName: deleteText,\n })\n }\n onClick={() =>\n void connectDelete({ ...settings, connector }).then(() =>\n setStatus(`Deleted connector ${connector}`),\n )\n }\n >\n Delete\n </Renderer.Component.Button>\n <textarea\n value={configText}\n onChange={(event) => setConfigText(event.target.value)}\n aria-label=\"Connector JSON configuration\"\n />\n <Renderer.Component.Button\n disabled={!canSubmitWriteAction({ confirmationAccepted: confirmed })}\n onClick={() => {\n try {\n const config = JSON.parse(configText) as Record<string, string>;\n void connectUpdate({ ...settings, config }).then(() => setStatus(\"Updated connector\"));\n setConfigError(undefined);\n } catch {\n setConfigError(\"Invalid connector JSON\");\n }\n }}\n >\n Update connector\n </Renderer.Component.Button>\n {configError && <div role=\"alert\">{configError}</div>}\n {status && <div role=\"status\">{status}</div>}\n </section>\n )}\n </aside>\n )}\n {canWrite && settings && (\n <section data-testid=\"kafka-connect-create-controls\">\n <textarea\n value={configText}\n onChange={(event) => setConfigText(event.target.value)}\n aria-label=\"New connector JSON configuration\"\n />\n <Renderer.Component.Button\n disabled={!canSubmitWriteAction({ confirmationAccepted: confirmed })}\n onClick={() => {\n try {\n const config = JSON.parse(configText) as Record<string, string>;\n void connectCreate({ ...settings, config }).then((created) => {\n setConnector(created.name);\n setStatus(\"Created connector\");\n });\n setConfigError(undefined);\n } catch {\n setConfigError(\"Invalid connector JSON\");\n }\n }}\n >\n Create connector\n </Renderer.Component.Button>\n </section>\n )}\n </main>\n </KafkaPageShell>\n );\n}\n","import { observable } from \"mobx\";\n\nexport const KAFKA_CONNECT_SETTINGS_KEY = \"freelens-kafka.connect.v1\";\n\nexport interface KafkaConnectSettings {\n connectUrl: string;\n tls: boolean;\n username?: string;\n}\n\nexport class KafkaConnectSettingsStore {\n private readonly settings = new Map<string, KafkaConnectSettings>();\n private readonly configured = new Set<() => void>();\n private readonly configuredState = observable.box(false);\n\n constructor(private readonly storage: Storage = window.localStorage) {\n try {\n const parsed = JSON.parse(storage.getItem(KAFKA_CONNECT_SETTINGS_KEY) ?? \"{}\") as Record<\n string,\n KafkaConnectSettings\n >;\n for (const [targetId, value] of Object.entries(parsed)) {\n if (value?.connectUrl) this.settings.set(targetId, { ...value });\n }\n this.configuredState.set(this.settings.size > 0);\n } catch {\n this.settings.clear();\n }\n }\n\n get(targetId: string): KafkaConnectSettings | undefined {\n const value = this.settings.get(targetId);\n return value ? { ...value } : undefined;\n }\n\n hasAny(): boolean {\n return this.configuredState.get();\n }\n\n set(targetId: string, value?: KafkaConnectSettings): void {\n if (!value?.connectUrl.trim()) this.settings.delete(targetId);\n else this.settings.set(targetId, { ...value, connectUrl: value.connectUrl.trim() });\n this.persist();\n this.configuredState.set(this.settings.size > 0);\n for (const listener of this.configured) listener();\n }\n\n subscribe(listener: () => void): () => void {\n this.configured.add(listener);\n return () => this.configured.delete(listener);\n }\n\n private persist(): void {\n try {\n this.storage.setItem(KAFKA_CONNECT_SETTINGS_KEY, JSON.stringify(Object.fromEntries(this.settings)));\n } catch {\n // Keep current-session settings if storage is unavailable.\n }\n }\n}\n","import type { KafkaSecurityOverride } from \"../common/ipc\";\n\nexport class KafkaConnectionSettingsStore {\n private readonly overrides = new Map<string, KafkaSecurityOverride>();\n\n get(kubernetesClusterId: string, targetId: string): KafkaSecurityOverride | undefined {\n const override = this.overrides.get(this.key(kubernetesClusterId, targetId));\n return override ? { ...override } : undefined;\n }\n\n set(kubernetesClusterId: string, targetId: string, override?: KafkaSecurityOverride): void {\n const key = this.key(kubernetesClusterId, targetId);\n if (override) {\n this.overrides.set(key, { ...override });\n } else {\n this.overrides.delete(key);\n }\n }\n\n removeTarget(kubernetesClusterId: string, targetId: string): void {\n this.overrides.delete(this.key(kubernetesClusterId, targetId));\n }\n\n clear(): void {\n this.overrides.clear();\n }\n\n private key(kubernetesClusterId: string, targetId: string): string {\n return `${kubernetesClusterId}:${targetId}`;\n }\n}\n","export const KAFKA_LIST_PAGE_SIZE = 100;\n\nexport interface KafkaListWindow<T> {\n items: T[];\n page: number;\n pageCount: number;\n total: number;\n}\n\nexport function kafkaListWindow<T>(items: T[], page: number, pageSize = KAFKA_LIST_PAGE_SIZE): KafkaListWindow<T> {\n const safePageSize = Math.max(1, pageSize);\n const pageCount = Math.max(1, Math.ceil(items.length / safePageSize));\n const safePage = Math.min(Math.max(0, page), pageCount - 1);\n return {\n items: items.slice(safePage * safePageSize, (safePage + 1) * safePageSize),\n page: safePage,\n pageCount,\n total: items.length,\n };\n}\n","import { useEffect, useState } from \"react\";\n\nexport const KAFKA_WRITE_MODE_KEY = \"freelens-kafka.write-mode.v1\";\n\nexport interface KafkaWriteSettingsStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nfunction defaultStorage(): KafkaWriteSettingsStorage | undefined {\n try {\n return typeof window === \"undefined\" ? undefined : window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class KafkaWriteSettingsStore {\n private readonly writeMode = new Set<string>();\n private readonly listeners = new Set<() => void>();\n\n constructor(private readonly storage: KafkaWriteSettingsStorage | undefined = defaultStorage()) {\n this.syncFromStorage();\n }\n\n private syncFromStorage(): void {\n try {\n const stored = this.storage?.getItem(KAFKA_WRITE_MODE_KEY);\n if (!stored) return;\n const parsed = JSON.parse(stored) as unknown;\n if (Array.isArray(parsed)) {\n this.writeMode.clear();\n for (const targetId of parsed) {\n if (typeof targetId === \"string\") this.writeMode.add(targetId);\n }\n }\n } catch {\n this.writeMode.clear();\n }\n }\n\n get(targetId: string): boolean {\n this.syncFromStorage();\n return this.writeMode.has(targetId);\n }\n\n set(targetId: string, enabled: boolean): void {\n if (this.get(targetId) === enabled) return;\n if (enabled) {\n this.writeMode.add(targetId);\n } else {\n this.writeMode.delete(targetId);\n }\n this.persist();\n this.emit();\n }\n\n clear(): void {\n if (this.writeMode.size === 0) return;\n this.writeMode.clear();\n this.persist();\n this.emit();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private persist(): void {\n try {\n this.storage?.setItem(KAFKA_WRITE_MODE_KEY, JSON.stringify([...this.writeMode].sort()));\n } catch {\n // Write mode remains available for this renderer session when storage is unavailable.\n }\n }\n\n private emit(): void {\n for (const listener of this.listeners) listener();\n }\n}\n\nexport function useKafkaWriteMode(store: KafkaWriteSettingsStore, targetId?: string): boolean {\n const [enabled, setEnabled] = useState(() => Boolean(targetId && store.get(targetId)));\n\n useEffect(() => {\n const update = () => setEnabled(Boolean(targetId && store.get(targetId)));\n update();\n return store.subscribe(update);\n }, [store, targetId]);\n\n return enabled;\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { kafkaPersistentStateStore } from \"../common/kafka-persistent-state-store\";\nimport { kafkaListWindow } from \"./kafka-list-window\";\nimport { rememberKafkaClusterSelection } from \"./kafka-navigation\";\nimport { KafkaMetricStrip, KafkaPageShell } from \"./kafka-page-shell\";\nimport {\n KafkaResourceActions,\n type KafkaResourcePageDependencies,\n KafkaResourceState,\n useKafkaPageParam,\n useKafkaResourcePage,\n} from \"./kafka-resource-pages\";\nimport { createOperationId, kafkaDecimalSortKey } from \"./kafka-view-model\";\nimport { canSubmitWriteAction, getWriteConfirmationLabel } from \"./kafka-write-policy\";\nimport { useKafkaWriteMode } from \"./kafka-write-settings\";\n\nimport type { CSSProperties, HTMLAttributes } from \"react\";\n\nimport type {\n ConsumerGroupDetailDto,\n ConsumerGroupsDto,\n GroupDetailRequest,\n GroupsRequest,\n KafkaProgressEvent,\n ResetOffsetsRequest,\n ResetOffsetsResultDto,\n} from \"../common/ipc\";\n\nconst GROUP_NAME_COLUMN_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst GROUP_STATE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 136px\", minWidth: 136, width: 136 };\nconst GROUP_TYPE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 100px\", minWidth: 100, width: 100 };\nconst GROUP_MEMBERS_COLUMN_STYLE: CSSProperties = { flex: \"0 0 80px\", minWidth: 80, width: 80, textAlign: \"right\" };\nconst GROUP_ACTION_COLUMN_STYLE: CSSProperties = { flex: \"0 0 44px\", minWidth: 44, width: 44 };\n\ninterface KafkaGroupsPageParams {\n target: string;\n query: string;\n group: string;\n view: string;\n}\n\nexport type KafkaGroupView = \"offsets\" | \"members\" | \"topics\";\n\nexport interface KafkaGroupsPageProps extends KafkaResourcePageDependencies {\n params?: {\n target: Renderer.Navigation.PageParam<KafkaGroupsPageParams[\"target\"]>;\n query: Renderer.Navigation.PageParam<KafkaGroupsPageParams[\"query\"]>;\n group: Renderer.Navigation.PageParam<KafkaGroupsPageParams[\"group\"]>;\n view: Renderer.Navigation.PageParam<KafkaGroupsPageParams[\"view\"]>;\n };\n groups: (request: GroupsRequest) => Promise<ConsumerGroupsDto>;\n groupDetail: (request: GroupDetailRequest) => Promise<ConsumerGroupDetailDto>;\n onOpenTopic: (targetId: string, topic: string) => void;\n resetOffsets: (request: ResetOffsetsRequest) => Promise<ResetOffsetsResultDto>;\n}\n\nfunction implementedGroupView(view?: string): KafkaGroupView {\n return view === \"members\" || view === \"topics\" ? view : \"offsets\";\n}\n\nexport function KafkaGroupsPage({\n params,\n groups,\n groupDetail,\n onOpenTopic,\n resetOffsets,\n ...dependencies\n}: KafkaGroupsPageProps) {\n const state = useKafkaResourcePage({ ...dependencies, params });\n const canWrite = useKafkaWriteMode(dependencies.writeSettings, state.selectedCluster?.targetId);\n const [query, setQuery] = useKafkaPageParam(params?.query);\n const [groupId, setGroupId] = useKafkaPageParam(params?.group);\n const [rawView, setRawView] = useKafkaPageParam(params?.view);\n const view = groupId ? implementedGroupView(rawView) : \"offsets\";\n const workspaceTargetId = useRef<string>();\n\n const [groupsState, setGroupsState] = useState<{\n loading: boolean;\n data?: ConsumerGroupsDto;\n error?: string;\n progress?: KafkaProgressEvent;\n }>({ loading: false });\n const [resetOpen, setResetOpen] = useState(false);\n const [resetMode, setResetMode] = useState<\"earliest\" | \"latest\" | \"offset\" | \"timestamp\">(\"earliest\");\n const [resetOffset, setResetOffset] = useState(\"\");\n const [resetTimestamp, setResetTimestamp] = useState(\"\");\n const [resetConfirmed, setResetConfirmed] = useState(false);\n const [resetTypedName, setResetTypedName] = useState(\"\");\n const [resetResult, setResetResult] = useState<ResetOffsetsResultDto>();\n const [resetError, setResetError] = useState<string>();\n\n const [detailState, setDetailState] = useState<{\n loading: boolean;\n data?: ConsumerGroupDetailDto;\n error?: string;\n progress?: KafkaProgressEvent;\n }>({ loading: false });\n\n const groupsOperationId = useRef<string>();\n const detailOperationId = useRef<string>();\n const [groupPage, setGroupPage] = useState(0);\n\n useEffect(() => setGroupPage(0), [query]);\n\n // Normalize view when no group is selected.\n useEffect(() => {\n if (!groupId && rawView !== \"offsets\") setRawView(\"offsets\", true);\n }, [groupId, rawView, setRawView]);\n\n // Reset group + view on cluster switch from Group Workspace.\n useEffect(() => {\n const selectedTargetId = state.selectedCluster?.targetId;\n if (!selectedTargetId) return;\n if (!groupId) {\n workspaceTargetId.current = selectedTargetId;\n return;\n }\n const previous = workspaceTargetId.current;\n workspaceTargetId.current = selectedTargetId;\n if (previous && previous !== selectedTargetId) {\n params?.group?.clear?.();\n setGroupId(\"\", true);\n params?.query?.clear?.();\n setQuery(\"\", true);\n }\n }, [params?.group, params?.query, setGroupId, setQuery, state.selectedCluster?.targetId, groupId]);\n\n useEffect(\n () =>\n dependencies.subscribeProgress((progress) => {\n if (progress.operation === \"groups\" && progress.operationId === groupsOperationId.current) {\n setGroupsState((current) => ({ ...current, progress }));\n }\n if (progress.operation === \"groupDetail\" && progress.operationId === detailOperationId.current) {\n setDetailState((current) => ({ ...current, progress }));\n }\n }),\n [dependencies.subscribeProgress],\n );\n\n const loadGroups = useCallback(() => {\n const cluster = state.selectedCluster;\n if (!cluster) {\n groupsOperationId.current = undefined;\n setGroupsState({ loading: false });\n return;\n }\n const operationId = createOperationId(\"groups\");\n groupsOperationId.current = operationId;\n const cacheKey = dependencies.kubernetesClusterId ?? \"active\";\n const cached = dependencies.resourceCache.readGroups(cacheKey, cluster.targetId);\n setGroupsState({ loading: true, data: cached.data });\n dependencies.resourceCache\n .loadGroups(cacheKey, cluster.targetId, () =>\n groups({\n operationId,\n targetId: cluster.targetId,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: dependencies.connectionSettings.get(dependencies.kubernetesClusterId ?? \"active\", cluster.targetId),\n }),\n )\n .then((data) => {\n if (groupsOperationId.current !== operationId) return;\n setGroupsState({ loading: false, data });\n })\n .catch((error: unknown) => {\n if (groupsOperationId.current !== operationId) return;\n setGroupsState((current) => ({\n loading: false,\n data: current.data,\n error: error instanceof Error ? error.message : String(error),\n }));\n });\n }, [\n dependencies.connectionSettings,\n dependencies.kubernetesClusterId,\n dependencies.resourceCache,\n groups,\n state.selectedCluster,\n ]);\n\n useEffect(() => {\n loadGroups();\n return () => {\n groupsOperationId.current = undefined;\n };\n }, [loadGroups]);\n\n const loadDetail = useCallback(() => {\n const cluster = state.selectedCluster;\n if (!groupId || !cluster) {\n detailOperationId.current = undefined;\n setDetailState({ loading: false });\n return;\n }\n const operationId = createOperationId(\"groupDetail\");\n detailOperationId.current = operationId;\n setDetailState({ loading: true });\n groupDetail({\n operationId,\n targetId: cluster.targetId,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: dependencies.connectionSettings.get(dependencies.kubernetesClusterId ?? \"active\", cluster.targetId),\n groupId,\n })\n .then((data) => {\n if (detailOperationId.current !== operationId) return;\n setDetailState({ loading: false, data });\n })\n .catch((error: unknown) => {\n if (detailOperationId.current !== operationId) return;\n setDetailState({ loading: false, error: error instanceof Error ? error.message : String(error) });\n });\n }, [dependencies.connectionSettings, dependencies.kubernetesClusterId, groupDetail, groupId, state.selectedCluster]);\n\n useEffect(() => {\n loadDetail();\n return () => {\n detailOperationId.current = undefined;\n };\n }, [loadDetail]);\n\n const selectWorkspaceCluster = (targetId: string): void => {\n const cluster = state.clusters.find((c) => c.targetId === targetId);\n if (!cluster) return;\n if (dependencies.kubernetesClusterId) {\n rememberKafkaClusterSelection(kafkaPersistentStateStore(), dependencies.kubernetesClusterId, cluster);\n }\n params?.group?.clear?.();\n setGroupId(\"\", true);\n params?.query?.clear?.();\n setQuery(\"\", true);\n state.selectCluster(targetId);\n };\n\n if (groupId) {\n return (\n <KafkaPageShell\n title={groupId}\n subtitle={state.selectedCluster ? `Consumer Groups / ${state.selectedCluster.name}` : \"Group Workspace\"}\n actions={\n <>\n <Renderer.Component.Button\n outlined\n onClick={() => {\n setGroupId(\"\");\n setRawView(\"offsets\", true);\n }}\n >\n <Renderer.Component.Icon material=\"arrow_back\" />\n Consumer Groups\n </Renderer.Component.Button>\n {canWrite && groupId && (\n <Renderer.Component.Button\n outlined\n data-testid=\"kafka-reset-offsets-button\"\n onClick={() => {\n setResetConfirmed(false);\n setResetTypedName(\"\");\n setResetOffset(\"\");\n setResetTimestamp(\"\");\n setResetOpen(true);\n }}\n >\n <Renderer.Component.Icon material=\"restart_alt\" />\n Reset offsets\n </Renderer.Component.Button>\n )}\n <KafkaResourceActions state={state} onSelectCluster={selectWorkspaceCluster} />\n </>\n }\n >\n <KafkaResourceState state={state} />\n {state.selectedCluster && (\n <main className=\"KafkaResourcePage KafkaGroupWorkspace\" data-testid=\"kafka-group-workspace\">\n {resetOpen && groupId && (\n <section\n className=\"KafkaWriteDrawer\"\n data-testid=\"kafka-reset-offsets-drawer\"\n aria-label=\"Reset offsets confirmation\"\n >\n <div className=\"KafkaPageState warning\">\n <Renderer.Component.Icon material=\"restart_alt\" />\n <div>\n <strong>Reset offsets</strong>\n <span>Destructive or recovery-like changes require explicit confirmation before execution.</span>\n </div>\n </div>\n <div className=\"KafkaWriteForm\" style={{ display: \"grid\", gap: 12 }}>\n {resetResult && (\n <div role=\"status\">\n Reset partition {resetResult.partition} to offset {resetResult.offset}\n </div>\n )}\n {resetError && <div role=\"alert\">{resetError}</div>}\n <Renderer.Component.Select\n options={[\n { value: \"earliest\", label: \"Earliest\" },\n { value: \"latest\", label: \"Latest\" },\n { value: \"offset\", label: \"Specific offset\" },\n { value: \"timestamp\", label: \"Timestamp\" },\n ]}\n value={resetMode}\n onChange={(option) => setResetMode((option?.value as typeof resetMode) ?? \"earliest\")}\n aria-label=\"Offset reset mode\"\n />\n {resetMode === \"offset\" && (\n <Renderer.Component.Input\n value={resetOffset}\n onChange={setResetOffset}\n placeholder=\"Offset value\"\n aria-label=\"Offset number\"\n />\n )}\n {resetMode === \"timestamp\" && (\n <Renderer.Component.Input\n value={resetTimestamp}\n onChange={setResetTimestamp}\n placeholder=\"2026-08-17T00:00:00\"\n aria-label=\"Reset timestamp\"\n />\n )}\n <div className=\"KafkaWriteSummary\">\n <strong>Group</strong>\n <span>{groupId}</span>\n <strong>Cluster</strong>\n <span>{state.selectedCluster.name}</span>\n </div>\n <Renderer.Component.Input\n value={resetTypedName}\n onChange={setResetTypedName}\n placeholder={`Type ${groupId} to confirm`}\n aria-label=\"Type the exact resource name\"\n data-testid=\"kafka-reset-confirmation-text\"\n />\n <label style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <span>{getWriteConfirmationLabel({ destructive: true, resourceName: groupId })}</span>\n <Renderer.Component.Switch\n aria-label=\"Confirm reset offsets\"\n data-testid=\"kafka-reset-confirmation-switch\"\n checked={resetConfirmed}\n onChange={setResetConfirmed}\n />\n </label>\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\" }}>\n <Renderer.Component.Button outlined onClick={() => setResetOpen(false)}>\n Cancel\n </Renderer.Component.Button>\n <Renderer.Component.Button\n primary\n disabled={\n !canSubmitWriteAction({\n confirmationAccepted: resetConfirmed,\n requiredResourceName: groupId,\n enteredResourceName: resetTypedName,\n })\n }\n onClick={() => {\n if (\n !canSubmitWriteAction({\n confirmationAccepted: resetConfirmed,\n requiredResourceName: groupId,\n enteredResourceName: resetTypedName,\n })\n ) {\n return;\n }\n const firstTopic = detailState.data?.topicOffsets[0];\n const firstPartition = firstTopic?.partitions[0];\n if (!state.selectedCluster || !firstTopic || !firstPartition) return;\n setResetError(undefined);\n void resetOffsets({\n targetId: state.selectedCluster.targetId,\n source: state.selectedCluster.source,\n bootstrap: state.selectedCluster.bootstrap,\n tls: state.selectedCluster.tls,\n namespace: state.selectedCluster.namespace,\n clusterName: state.selectedCluster.name,\n groupId,\n topic: firstTopic.topic,\n partition: firstPartition.partition,\n mode: resetMode,\n offset: resetMode === \"offset\" ? resetOffset : undefined,\n timestamp: resetMode === \"timestamp\" ? Date.parse(resetTimestamp) : undefined,\n })\n .then((result) => setResetResult(result))\n .catch((error: unknown) =>\n setResetError(error instanceof Error ? error.message : String(error)),\n );\n }}\n >\n Reset offsets\n </Renderer.Component.Button>\n </div>\n </div>\n </section>\n )}\n <nav className=\"KafkaEntityTabs\" role=\"tablist\" aria-label=\"Group sections\">\n {([\"offsets\", \"members\", \"topics\"] as const).map((tab) => (\n <Renderer.Component.Button\n key={tab}\n plain\n role=\"tab\"\n active={view === tab}\n aria-selected={view === tab}\n onClick={() => setRawView(tab)}\n >\n {tab === \"offsets\" ? \"Offsets & Lag\" : tab === \"members\" ? \"Members\" : \"Topics\"}\n </Renderer.Component.Button>\n ))}\n </nav>\n {detailState.loading && (\n <div className=\"KafkaPageState loading\">\n <Renderer.Component.Spinner />\n <span>Loading group detail…</span>\n </div>\n )}\n {!detailState.loading && detailState.error && (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Failed to load group detail</strong>\n <span>{detailState.error}</span>\n </div>\n <Renderer.Component.Button outlined onClick={loadDetail}>\n Retry\n </Renderer.Component.Button>\n </div>\n )}\n {!detailState.loading && detailState.data && view === \"offsets\" && (\n <KafkaGroupOffsets detail={detailState.data} />\n )}\n {!detailState.loading && detailState.data && view === \"members\" && (\n <KafkaGroupMembers detail={detailState.data} />\n )}\n {!detailState.loading && detailState.data && view === \"topics\" && (\n <KafkaGroupTopics\n detail={detailState.data}\n onOpenTopic={(topic) => onOpenTopic(state.selectedCluster?.targetId ?? \"\", topic)}\n />\n )}\n </main>\n )}\n </KafkaPageShell>\n );\n }\n\n const allGroups = groupsState.data?.groups ?? [];\n const filteredGroups = allGroups.filter((g) =>\n query ? g.groupId.toLowerCase().includes(query.toLowerCase()) : true,\n );\n const groupWindow = kafkaListWindow(filteredGroups, groupPage);\n\n return (\n <KafkaPageShell\n title=\"Consumer Groups\"\n subtitle={state.selectedCluster ? state.selectedCluster.name : \"Browse consumer groups in a Kafka cluster\"}\n actions={<KafkaResourceActions state={state} />}\n >\n <KafkaResourceState state={state} />\n {state.selectedCluster && (\n <main className=\"KafkaResourcePage KafkaGroupsPage\" data-testid=\"kafka-groups-page\">\n {groupsState.loading && !groupsState.data && (\n <div className=\"KafkaPageState loading\">\n <Renderer.Component.Spinner />\n <span>Loading consumer groups…</span>\n </div>\n )}\n {!groupsState.loading && groupsState.error && (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Failed to load consumer groups</strong>\n <span>{groupsState.error}</span>\n </div>\n <Renderer.Component.Button outlined onClick={loadGroups}>\n Retry\n </Renderer.Component.Button>\n </div>\n )}\n {!groupsState.loading && groupsState.data && (\n <>\n <KafkaMetricStrip\n ariaLabel=\"Kafka consumer group summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[{ label: \"Groups\", value: allGroups.length }]}\n />\n {allGroups.length === 0 ? (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"group\" />\n <div>\n <strong>No consumer groups</strong>\n <span>Kafka returned no consumer groups for this cluster.</span>\n </div>\n </div>\n ) : (\n <>\n <Renderer.Component.Input\n className=\"KafkaTopicSearch\"\n value={query}\n onChange={(nextQuery) => setQuery(nextQuery, true)}\n iconLeft=\"search\"\n placeholder=\"Filter groups\"\n aria-label=\"Filter consumer groups\"\n />\n <Renderer.Component.Table<(typeof allGroups)[number]>\n className=\"KafkaGroupTable KafkaGroupPageTable\"\n tableId=\"kafka-groups-page\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"id\", orderBy: \"asc\" }}\n sortable={{ id: (g) => g.groupId.toLowerCase() }}\n noItems={\n <div className=\"KafkaTopicPrompt\">\n <Renderer.Component.Icon material=\"filter_alt_off\" />\n <span>No groups match the current filter.</span>\n </div>\n }\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell\n className=\"groupNameCell\"\n sortBy=\"id\"\n style={GROUP_NAME_COLUMN_STYLE}\n >\n Group ID\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupStateCell\" style={GROUP_STATE_COLUMN_STYLE}>\n State\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTypeCell\" style={GROUP_TYPE_COLUMN_STYLE}>\n Protocol\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupMembersCell\" style={GROUP_MEMBERS_COLUMN_STYLE}>\n Members\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupActionCell\" style={GROUP_ACTION_COLUMN_STYLE} />\n </Renderer.Component.TableHead>\n {groupWindow.items.map((group) => {\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open group ${group.groupId}`,\n onClick: (event) => {\n event.stopPropagation();\n setRawView(\"offsets\", true);\n setGroupId(group.groupId);\n },\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setRawView(\"offsets\", true);\n setGroupId(group.groupId);\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={group.groupId}\n sortItem={group}\n data-group={group.groupId}\n nowrap\n >\n <Renderer.Component.TableCell\n className=\"groupNameCell\"\n title={group.groupId}\n style={GROUP_NAME_COLUMN_STYLE}\n >\n <Renderer.Component.Icon material=\"group\" />\n <span className=\"KafkaEllipsis\">{group.groupId}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupStateCell\" style={GROUP_STATE_COLUMN_STYLE}>\n <GroupStateBadge state={group.state} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTypeCell\" style={GROUP_TYPE_COLUMN_STYLE}>\n <span className=\"KafkaGroupProtocol\">{group.protocolType || \"—\"}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupMembersCell\" style={GROUP_MEMBERS_COLUMN_STYLE}>\n {group.memberCount}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupActionCell\" style={GROUP_ACTION_COLUMN_STYLE}>\n <Renderer.Component.Icon material=\"chevron_right\" />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n {groupWindow.pageCount > 1 && (\n <div className=\"KafkaListPagination\" aria-label=\"Consumer group pages\">\n <Renderer.Component.Button\n outlined\n disabled={groupWindow.page === 0}\n onClick={() => setGroupPage((page) => Math.max(0, page - 1))}\n aria-label=\"Previous consumer group page\"\n >\n Previous\n </Renderer.Component.Button>\n <span>\n Page {groupWindow.page + 1} of {groupWindow.pageCount} ({groupWindow.total} groups)\n </span>\n <Renderer.Component.Button\n outlined\n disabled={groupWindow.page >= groupWindow.pageCount - 1}\n onClick={() => setGroupPage((page) => Math.min(groupWindow.pageCount - 1, page + 1))}\n aria-label=\"Next consumer group page\"\n >\n Next\n </Renderer.Component.Button>\n </div>\n )}\n </>\n )}\n </>\n )}\n </main>\n )}\n </KafkaPageShell>\n );\n}\n\nfunction GroupStateBadge({ state }: { state: string }) {\n const tone =\n state === \"Stable\"\n ? \"KafkaHealthyBadge\"\n : state === \"Dead\" || state === \"Unknown\"\n ? \"KafkaErrorBadge\"\n : \"KafkaWarningBadge\";\n return <Renderer.Component.Badge small className={tone} label={state || \"Unknown\"} />;\n}\n\nconst OFFSET_PARTITION_STYLE: CSSProperties = { flex: \"0 0 90px\", minWidth: 90, width: 90 };\nconst OFFSET_VALUE_STYLE: CSSProperties = { flex: \"0 0 140px\", minWidth: 140, width: 140, textAlign: \"right\" };\nconst OFFSET_LAG_STYLE: CSSProperties = { flex: \"0 0 100px\", minWidth: 100, width: 100, textAlign: \"right\" };\n\nfunction KafkaGroupOffsets({ detail }: { detail: ConsumerGroupDetailDto }) {\n if (detail.topicOffsets.length === 0) {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"rule\" />\n <div>\n <strong>No committed offsets</strong>\n <span>This group has no committed offsets for any topic.</span>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"KafkaGroupOffsetSection\" data-testid=\"kafka-group-offsets\">\n {detail.topicOffsets.map((topicData) => (\n <section key={topicData.topic} className=\"KafkaGroupTopicSection\">\n <header className=\"KafkaGroupTopicHeader\">\n <Renderer.Component.Icon material=\"topic\" />\n <span className=\"KafkaGroupTopicName\">{topicData.topic}</span>\n <span className=\"KafkaGroupTopicLag\">\n Total lag: <strong>{topicData.totalLag}</strong>\n </span>\n </header>\n <Renderer.Component.Table autoSize={false} scrollable className=\"KafkaOffsetTable\">\n <Renderer.Component.TableHead nowrap>\n <Renderer.Component.TableCell className=\"partitionCell\" style={OFFSET_PARTITION_STYLE}>\n Partition\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"committedCell\" style={OFFSET_VALUE_STYLE}>\n Committed offset\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"hwmCell\" style={OFFSET_VALUE_STYLE}>\n High watermark\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"lagCell\" style={OFFSET_LAG_STYLE}>\n Lag\n </Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {topicData.partitions.map((p) => (\n <Renderer.Component.TableRow key={p.partition} nowrap>\n <Renderer.Component.TableCell className=\"partitionCell\" style={OFFSET_PARTITION_STYLE}>\n <strong>{p.partition}</strong>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"committedCell\" style={OFFSET_VALUE_STYLE}>\n <code>{p.committedOffset === \"-1\" ? \"—\" : p.committedOffset}</code>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"hwmCell\" style={OFFSET_VALUE_STYLE}>\n <code>{p.highWatermark}</code>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"lagCell\" style={OFFSET_LAG_STYLE}>\n <LagValue lag={p.lag} />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n ))}\n </Renderer.Component.Table>\n </section>\n ))}\n </div>\n );\n}\n\nfunction LagValue({ lag }: { lag: string }) {\n if (lag === \"—\") return <span className=\"KafkaLagUnknown\">—</span>;\n const n = BigInt(lag);\n const tone = n === 0n ? \"KafkaLagZero\" : n < 1000n ? \"KafkaLagLow\" : \"KafkaLagHigh\";\n return <strong className={tone}>{lag}</strong>;\n}\n\nconst GROUP_TOPIC_NAME_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst GROUP_TOPIC_PARTITIONS_STYLE: CSSProperties = { flex: \"0 0 100px\", minWidth: 100, width: 100 };\nconst GROUP_TOPIC_LAG_STYLE: CSSProperties = { flex: \"0 0 120px\", minWidth: 120, width: 120 };\nconst GROUP_TOPIC_ACTION_STYLE: CSSProperties = { flex: \"0 0 44px\", minWidth: 44, width: 44 };\n\nfunction KafkaGroupTopics({\n detail,\n onOpenTopic,\n}: {\n detail: ConsumerGroupDetailDto;\n onOpenTopic: (topic: string) => void;\n}) {\n if (detail.topicOffsets.length === 0) {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"topic\" />\n <div>\n <strong>No consumed topics</strong>\n <span>This group has no committed offsets for any topic.</span>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"KafkaGroupTopicsSection\" data-testid=\"kafka-group-topics\">\n <KafkaMetricStrip\n ariaLabel=\"Group topic summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[{ label: \"Topics\", value: detail.topicOffsets.length }]}\n />\n <Renderer.Component.Table<(typeof detail.topicOffsets)[number]>\n autoSize={false}\n scrollable\n className=\"KafkaGroupTopicsTable\"\n tableId=\"kafka-group-topics\"\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"topic\", orderBy: \"asc\" }}\n sortable={{\n topic: (topic) => topic.topic.toLowerCase(),\n lag: (topic) => kafkaDecimalSortKey(topic.totalLag),\n }}\n >\n <Renderer.Component.TableHead nowrap>\n <Renderer.Component.TableCell className=\"groupTopicNameCell\" sortBy=\"topic\" style={GROUP_TOPIC_NAME_STYLE}>\n Topic\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicPartitionsCell\" style={GROUP_TOPIC_PARTITIONS_STYLE}>\n Partitions\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicLagCell\" sortBy=\"lag\" style={GROUP_TOPIC_LAG_STYLE}>\n Total lag\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicActionCell\" style={GROUP_TOPIC_ACTION_STYLE} />\n </Renderer.Component.TableHead>\n {detail.topicOffsets.map((topic) => {\n const open = (): void => onOpenTopic(topic.topic);\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open topic ${topic.topic}`,\n onClick: open,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n open();\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={topic.topic}\n sortItem={topic}\n data-topic={topic.topic}\n nowrap\n >\n <Renderer.Component.TableCell\n className=\"groupTopicNameCell\"\n title={topic.topic}\n style={GROUP_TOPIC_NAME_STYLE}\n >\n <Renderer.Component.Icon material=\"topic\" />\n <span className=\"KafkaEllipsis\">{topic.topic}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicPartitionsCell\" style={GROUP_TOPIC_PARTITIONS_STYLE}>\n {topic.partitions.length}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicLagCell\" style={GROUP_TOPIC_LAG_STYLE}>\n <LagValue lag={topic.totalLag} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"groupTopicActionCell\" style={GROUP_TOPIC_ACTION_STYLE}>\n <Renderer.Component.Icon material=\"chevron_right\" />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n </div>\n );\n}\n\nconst MEMBER_ID_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst MEMBER_CLIENT_STYLE: CSSProperties = { flex: \"0 0 200px\", minWidth: 200, width: 200 };\nconst MEMBER_HOST_STYLE: CSSProperties = { flex: \"0 0 180px\", minWidth: 180, width: 180 };\n\nfunction KafkaGroupMembers({ detail }: { detail: ConsumerGroupDetailDto }) {\n if (detail.members.length === 0) {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"person_off\" />\n <div>\n <strong>No active members</strong>\n <span>This consumer group has no active members.</span>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"KafkaGroupMemberSection\" data-testid=\"kafka-group-members\">\n <KafkaMetricStrip\n ariaLabel=\"Group member summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[{ label: \"Members\", value: detail.members.length }]}\n />\n <Renderer.Component.Table autoSize={false} scrollable className=\"KafkaMemberTable\">\n <Renderer.Component.TableHead nowrap>\n <Renderer.Component.TableCell className=\"memberIdCell\" style={MEMBER_ID_STYLE}>\n Member ID\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"clientIdCell\" style={MEMBER_CLIENT_STYLE}>\n Client ID\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"clientHostCell\" style={MEMBER_HOST_STYLE}>\n Client host\n </Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {detail.members.map((m) => (\n <Renderer.Component.TableRow key={m.memberId} nowrap>\n <Renderer.Component.TableCell className=\"memberIdCell\" title={m.memberId} style={MEMBER_ID_STYLE}>\n <code className=\"KafkaEllipsis\">{m.memberId}</code>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"clientIdCell\" title={m.clientId} style={MEMBER_CLIENT_STYLE}>\n <span className=\"KafkaEllipsis\">{m.clientId}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"clientHostCell\" title={m.clientHost} style={MEMBER_HOST_STYLE}>\n <code className=\"KafkaEllipsis\">{m.clientHost}</code>\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n ))}\n </Renderer.Component.Table>\n </div>\n );\n}\n","/** IPC contract shared between the Main (engine) and Renderer (UI) processes. */\nimport type { KafkaEtaStatus } from \"./kafka-phase-progress\";\n\nexport const KAFKA_IPC = {\n discover: \"kafka:discover\",\n overview: \"kafka:overview\",\n health: \"kafka:health\",\n healthInvalidate: \"kafka:health:invalidate\",\n topic: \"kafka:topic\",\n topicConfig: \"kafka:topic:config\",\n topicConsumers: \"kafka:topic:consumers\",\n brokerConfig: \"kafka:broker:config\",\n messagesBrowse: \"kafka:messages:browse\",\n groups: \"kafka:groups\",\n groupDetail: \"kafka:group:detail\",\n produce: \"kafka:produce\",\n resetOffsets: \"kafka:group:reset-offsets\",\n schemaSubjects: \"kafka:schema-registry:subjects\",\n schemaSubjectNames: \"kafka:schema-registry:subject-names\",\n schemaSubjectDetail: \"kafka:schema-registry:subject-detail\",\n schemaRegister: \"kafka:schema-registry:register\",\n schemaDeleteSubject: \"kafka:schema-registry:delete-subject\",\n connectList: \"kafka:connect:list\",\n connectNames: \"kafka:connect:names\",\n connectDetail: \"kafka:connect:detail\",\n connectPause: \"kafka:connect:pause\",\n connectResume: \"kafka:connect:resume\",\n connectDelete: \"kafka:connect:delete\",\n connectCreate: \"kafka:connect:create\",\n connectUpdate: \"kafka:connect:update\",\n connectRestart: \"kafka:connect:restart\",\n acls: \"kafka:acls\",\n aclCreate: \"kafka:acl:create\",\n aclDelete: \"kafka:acl:delete\",\n reachability: \"kafka:reachability\",\n progress: \"kafka:progress\",\n} as const;\n\nexport interface DiscoverRequest {\n operationId?: string;\n clusterId?: string;\n kubeConfigPath?: string;\n context?: string;\n namespace?: string;\n}\n\nexport interface OverviewRequest {\n operationId?: string;\n /** Stable non-secret renderer identity used to correlate shared metadata cache entries. */\n targetId?: string;\n clusterId?: string;\n kubeConfigPath?: string;\n context?: string;\n namespace: string;\n clusterName: string;\n user?: string;\n /** Discovery source of the target; when not `\"strimzi\"` the connection uses the Direct strategy. */\n source?: string;\n /** Bootstrap `host:port` (comma list) for the Direct strategy (non-Strimzi). */\n bootstrap?: string;\n /** Whether the target listener uses TLS (Direct strategy). */\n tls?: boolean;\n /** Optional per-connection override. Password is sent only over internal IPC and is never persisted. */\n security?: KafkaSecurityOverride;\n /** Non-secret source coordinates for targeted workload security resolution. */\n sourceLocator?: KafkaWorkloadSourceLocator;\n}\n\nexport interface TopicRequest extends OverviewRequest {\n topic: string;\n}\n\nexport interface ClusterHealthRequest extends OverviewRequest {\n /** Explicitly bypass Main and renderer health TTLs for this target. */\n refresh?: boolean;\n}\n\nexport interface AggregateHealthInvalidateRequest {\n clusterId?: string;\n context?: string;\n targetId: string;\n closeSessions?: boolean;\n removePersisted?: boolean;\n}\n\nexport interface TopicConfigRequest extends TopicRequest {}\n\nexport interface TopicConsumersRequest extends TopicRequest {}\n\nexport interface BrokerConfigRequest extends OverviewRequest {\n brokerId: number;\n}\n\nexport type KafkaMessageStartMode = \"earliest\" | \"latest\" | \"offset\" | \"timestamp\";\n\nexport interface MessageBrowseRequest extends TopicRequest {\n partition: number;\n startMode: KafkaMessageStartMode;\n offset?: string;\n timestamp?: number;\n limit: number;\n registryUrl?: string;\n registryUsername?: string;\n}\n\nexport type KafkaProgressOperation =\n | \"discovery\"\n | \"overview\"\n | \"health\"\n | \"topic\"\n | \"topicConfig\"\n | \"topicConsumers\"\n | \"brokerConfig\"\n | \"messagesBrowse\"\n | \"groups\"\n | \"groupDetail\";\n\nexport interface KafkaProgressEvent {\n operationId: string;\n operation: KafkaProgressOperation;\n /** Milliseconds since the operation progress reporter was created. */\n elapsedMs?: number;\n /** Milliseconds since the preceding progress update. */\n stageDurationMs?: number;\n /** Monotonic weighted phase completion in the inclusive range 0–100. */\n value: number;\n phase: string;\n /** Completion of the current phase only; never a weighted global percentage. */\n phasePercent?: number;\n /** Elapsed milliseconds since the current phase began. */\n phaseElapsedMs?: number;\n /** Smoothed remaining time, emitted only after confidence thresholds are met. */\n etaMs?: number;\n etaStatus?: KafkaEtaStatus;\n label: string;\n detail?: string;\n completed?: number;\n total?: number;\n /** Incremental non-secret health values measured before the full health operation completes. */\n healthSnapshot?: Partial<ClusterOverviewHealthDto>;\n /** Capture time of a restored or completed aggregate-health snapshot. */\n healthUpdatedAt?: number;\n /** Explicit origin of an aggregate-health snapshot. */\n healthSource?: \"cache\" | \"network\" | \"persisted\";\n /** Incremental read-only match emitted while building the Topic -> Consumer Groups index. */\n topicConsumerGroup?: TopicConsumerGroupDto;\n}\n\nexport type KafkaSaslMechanism = \"plain\" | \"scram-sha-256\" | \"scram-sha-512\";\nexport type KafkaTlsMode = \"auto\" | \"enabled\" | \"disabled\";\nexport type KafkaAuthMode = \"auto\" | \"none\" | KafkaSaslMechanism;\n\nexport interface KafkaSecurityOverride {\n tlsMode: KafkaTlsMode;\n authMode: KafkaAuthMode;\n username?: string;\n password?: string;\n}\n\nexport interface KafkaSecurityHint {\n tls: boolean;\n auth: \"none\" | \"mtls\" | KafkaSaslMechanism;\n}\n\nexport interface KafkaSecuritySummary extends KafkaSecurityHint {\n source: \"inferred\" | \"workload\" | \"strimzi\" | \"override\";\n}\n\n/** Non-secret workload coordinates used for targeted security refreshes. */\nexport interface KafkaWorkloadSourceLocator {\n namespace: string;\n kind: string;\n name: string;\n container?: string;\n}\n\n/** Bootstraps to TCP-probe for reachability from the machine running Freelens. */\nexport interface ReachabilityRequest {\n bootstraps: string[];\n}\n\nexport interface KafkaListenerInfo {\n name: string;\n port: number;\n tls: boolean;\n type?: string;\n}\n\n/** Serializable Kafka cluster info returned to the renderer by `discover`. */\nexport interface DiscoveredKafkaInfo {\n /** Stable, non-secret connection identity suitable for route parameters and renderer state. */\n targetId: string;\n source: string;\n name: string;\n namespace: string;\n bootstrap: string;\n tls: boolean;\n port: number;\n listeners: KafkaListenerInfo[];\n brokerPods: { brokerId: number; pod: string }[];\n /** Human-readable provider: `\"Strimzi\"` | `\"In-cluster\"` | `\"MSK\"` | `\"Confluent\"` | `\"Aiven\"` | … */\n provider?: string;\n /** Whether the bootstrap endpoint is external to the cluster (a managed/remote Kafka). */\n external?: boolean;\n /** For workload-sourced entries: the workloads that reference it (`ns/kind/name`). */\n referencedBy?: string[];\n /** Non-secret coordinates of one workload/container that references this bootstrap. */\n sourceLocator?: KafkaWorkloadSourceLocator;\n /** Non-secret security mode inferred from the workload configuration. */\n securityHint?: KafkaSecurityHint;\n}\n\nexport interface BrokerInfo {\n nodeId: number;\n host: string;\n port: number;\n}\n\nexport interface TopicPartitionDto {\n partitionId: number;\n leader: number;\n replicas: number[];\n isr: number[];\n offlineReplicas: number[];\n errorCode: number;\n underReplicated: boolean;\n unavailable: boolean;\n}\n\nexport interface TopicDetailDto {\n name: string;\n internal: boolean;\n partitions: TopicPartitionDto[];\n partitionCount: number;\n replicationFactor: number;\n underReplicatedPartitions: number;\n unavailablePartitions: number;\n}\n\nexport interface KafkaConfigEntryDto {\n name: string;\n value: string;\n source: string;\n readOnly: boolean;\n sensitive: boolean;\n}\n\nexport type TopicConfigEntryDto = KafkaConfigEntryDto;\n\nexport interface TopicConfigDto {\n topic: string;\n entries: TopicConfigEntryDto[];\n}\n\nexport interface BrokerConfigDto {\n brokerId: number;\n entries: KafkaConfigEntryDto[];\n}\n\nexport interface TopicConsumerGroupDto {\n groupId: string;\n state: string;\n memberCount: number;\n totalLag: string;\n}\n\nexport interface TopicConsumersDto {\n topic: string;\n groups: TopicConsumerGroupDto[];\n}\n\nexport type KafkaMessageBytesFormat = \"null\" | \"json\" | \"text\" | \"binary\";\n\nexport interface KafkaMessageBytesDto {\n format: KafkaMessageBytesFormat;\n byteLength: number;\n truncated: boolean;\n /** Exact bounded preview bytes. Omitted only for Kafka null. */\n base64?: string;\n /** Present only when the full source bytes are valid UTF-8. */\n text?: string;\n}\n\nexport interface KafkaMessageHeaderDto {\n name: string;\n value: KafkaMessageBytesDto;\n}\n\nexport interface KafkaRecordDto {\n topic: string;\n partition: number;\n offset: string;\n timestamp: string;\n key: KafkaMessageBytesDto;\n value: KafkaMessageBytesDto;\n headers: KafkaMessageHeaderDto[];\n decodedValue?: unknown;\n decodeWarning?: string;\n}\n\nexport interface MessageBrowseDto {\n topic: string;\n partition: number;\n startMode: KafkaMessageStartMode;\n requestedOffset?: string;\n startOffset: string;\n nextOffset: string;\n logStartOffset: string;\n highWatermark: string;\n returnedCount: number;\n hasMore: boolean;\n messages: KafkaRecordDto[];\n}\n\n/** Serializable cluster snapshot returned to the renderer by `overview`. */\nexport interface ClusterOverviewHealthDto {\n unavailablePartitions: number;\n underReplicatedPartitions: number;\n onlineBrokers: number;\n topologyMeasuredAt?: number;\n consumerGroupLag: string;\n consumerGroupLagUnavailableTopics?: number;\n consumerGroupLagUnavailableGroups?: number;\n consumerGroupLagCoverage?: {\n complete: boolean;\n completedAt?: number;\n resolvedGroups: number;\n startedAt?: number;\n totalGroups: number;\n unavailableGroups: number;\n };\n}\n\nexport interface ClusterOverviewDto {\n brokers: BrokerInfo[];\n controller: number | null;\n topics: string[];\n /** Whether this broker answered a DescribeAcls probe, gating the ACL page. */\n aclsAvailable?: boolean;\n /** Short cluster health summary for the Overview dashboard. */\n health?: ClusterOverviewHealthDto;\n /** Effective (non-secret) security profile used for this metadata read. */\n security?: KafkaSecuritySummary;\n}\n\n// ─── Consumer Groups ──────────────────────────────────────────────────────────\n\nexport interface GroupsRequest extends OverviewRequest {}\n\nexport interface GroupDetailRequest extends OverviewRequest {\n groupId: string;\n}\n\nexport interface ProduceRequest extends OverviewRequest {\n topic: string;\n key?: string;\n value: string;\n headers?: Record<string, string>;\n partition?: number;\n}\n\nexport interface ProduceResultDto {\n topic: string;\n partition: number;\n offset: string;\n}\n\nexport type OffsetResetMode = \"earliest\" | \"latest\" | \"offset\" | \"timestamp\";\n\nexport interface ResetOffsetsRequest extends OverviewRequest {\n groupId: string;\n topic: string;\n partition: number;\n mode: OffsetResetMode;\n offset?: string;\n timestamp?: number;\n}\n\nexport interface ResetOffsetsResultDto {\n groupId: string;\n topic: string;\n partition: number;\n offset: string;\n}\n\nexport interface SchemaRegistryRequest {\n registryUrl: string;\n registryUsername?: string;\n}\n\nexport interface SchemaSubjectsRequest extends SchemaRegistryRequest {}\nexport interface SchemaSubjectNamesRequest extends SchemaRegistryRequest {}\n\nexport interface SchemaSubjectDetailRequest extends SchemaRegistryRequest {\n subject: string;\n}\n\nexport interface SchemaRegisterRequest extends SchemaRegistryRequest {\n subject: string;\n schema: string;\n schemaType?: SchemaType;\n}\n\nexport interface SchemaDeleteSubjectRequest extends SchemaRegistryRequest {\n subject: string;\n}\n\nexport interface KafkaConnectRequest {\n connectUrl: string;\n connectUsername?: string;\n}\n\nexport interface KafkaConnectDetailRequest extends KafkaConnectRequest {\n connector: string;\n}\n\nexport interface KafkaConnectCreateRequest extends KafkaConnectRequest {\n config: Record<string, string>;\n}\n\nexport interface AclsRequest extends OverviewRequest {}\n\nexport interface KafkaAclDto {\n resourceType: string;\n resourceName: string;\n patternType: string;\n principal: string;\n host: string;\n operation: string;\n permissionType: string;\n}\n\nexport interface KafkaAclResultDto {\n available: boolean;\n acls: KafkaAclDto[];\n message?: string;\n}\n\nexport interface AclWriteRequest extends AclsRequest {\n acl: KafkaAclDto;\n}\n\nexport interface ConnectorSummaryDto {\n name: string;\n type?: string;\n status: string;\n taskCount: number;\n}\n\nexport interface ConnectorTaskDto {\n id: number;\n state: string;\n workerId?: string;\n trace?: string;\n}\n\nexport interface ConnectorDetailDto {\n name: string;\n config: Record<string, string>;\n connector: { state: string; workerId?: string; version?: string };\n tasks: ConnectorTaskDto[];\n}\n\nexport type SchemaType = \"AVRO\" | \"PROTOBUF\" | \"JSON\" | string;\n\nexport interface SchemaSubjectSummary {\n subject: string;\n latestVersion: number;\n schemaType: SchemaType;\n compatibility?: string;\n}\n\nexport interface SchemaVersion {\n id: number;\n version: number;\n subject: string;\n schema: string;\n schemaType: SchemaType;\n references?: Array<{ name: string; subject: string; version: number }>;\n}\n\nexport interface SchemaSubjectDetail {\n subject: string;\n compatibility?: string;\n versions: SchemaVersion[];\n}\n\nexport interface ConsumerGroupSummaryDto {\n groupId: string;\n state: string;\n protocolType: string;\n memberCount: number;\n}\n\nexport interface ConsumerGroupsDto {\n groups: ConsumerGroupSummaryDto[];\n}\n\nexport interface GroupMemberDto {\n memberId: string;\n clientId: string;\n clientHost: string;\n}\n\nexport interface GroupPartitionOffsetDto {\n partition: number;\n /** Decimal string; \"-1\" means the group has never committed an offset for this partition. */\n committedOffset: string;\n highWatermark: string;\n /** Decimal string lag, or \"—\" when committedOffset is -1. */\n lag: string;\n}\n\nexport interface GroupTopicOffsetDto {\n topic: string;\n partitions: GroupPartitionOffsetDto[];\n /** Sum of non-unknown partition lags, or \"—\" when all partitions are uncommitted. */\n totalLag: string;\n}\n\nexport interface ConsumerGroupDetailDto {\n groupId: string;\n state: string;\n protocol: string;\n protocolType: string;\n members: GroupMemberDto[];\n topicOffsets: GroupTopicOffsetDto[];\n}\n","export type IpcRequest = object | undefined;\n\nfunction requestWithoutOperationId(request: IpcRequest): IpcRequest {\n if (!request || Array.isArray(request)) return request;\n const { operationId: _operationId, ...parameters } = request as Record<string, unknown>;\n return parameters;\n}\n\nfunction stableRequestKey(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableRequestKey).join(\",\")}]`;\n if (value && typeof value === \"object\") {\n return `{${Object.entries(value)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, entry]) => `${JSON.stringify(key)}:${stableRequestKey(entry)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value);\n}\n\nexport function createIpcRequestDeduper() {\n const inFlight = new Map<string, Promise<unknown>>();\n\n return function dedupe<T>(channel: string, request: IpcRequest, invoke: () => Promise<T>): Promise<T> {\n const key = `${channel}:${stableRequestKey(requestWithoutOperationId(request))}`;\n const existing = inFlight.get(key);\n if (existing) return existing as Promise<T>;\n\n const promise = Promise.resolve()\n .then(invoke)\n .finally(() => inFlight.delete(key));\n inFlight.set(key, promise);\n return promise;\n };\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport {\n type AclsRequest,\n type AclWriteRequest,\n type AggregateHealthInvalidateRequest,\n type BrokerConfigDto,\n type BrokerConfigRequest,\n type ClusterHealthRequest,\n type ClusterOverviewDto,\n type ClusterOverviewHealthDto,\n type ConnectorDetailDto,\n type ConnectorSummaryDto,\n type ConsumerGroupDetailDto,\n type ConsumerGroupsDto,\n type DiscoveredKafkaInfo,\n type DiscoverRequest,\n type GroupDetailRequest,\n type GroupsRequest,\n KAFKA_IPC,\n type KafkaAclResultDto,\n type KafkaConnectCreateRequest,\n type KafkaConnectDetailRequest,\n type KafkaConnectRequest,\n type KafkaProgressEvent,\n type MessageBrowseDto,\n type MessageBrowseRequest,\n type OverviewRequest,\n type ProduceRequest,\n type ProduceResultDto,\n type ResetOffsetsRequest,\n type ResetOffsetsResultDto,\n type SchemaDeleteSubjectRequest,\n type SchemaRegisterRequest,\n type SchemaSubjectDetail,\n type SchemaSubjectDetailRequest,\n type SchemaSubjectNamesRequest,\n type SchemaSubjectSummary,\n type SchemaSubjectsRequest,\n type TopicConfigDto,\n type TopicConfigRequest,\n type TopicConsumersDto,\n type TopicConsumersRequest,\n type TopicDetailDto,\n type TopicRequest,\n} from \"../common/ipc\";\nimport { createIpcRequestDeduper, type IpcRequest } from \"./kafka-ipc-deduper\";\n\n/** Renderer-side client for the Kafka extension's Main IPC handlers. */\nexport class KafkaIpcRenderer extends Renderer.Ipc {\n private readonly dedupe = createIpcRequestDeduper();\n\n private read<T>(channel: string, request: IpcRequest): Promise<T> {\n return this.dedupe(channel, request, () => this.invoke(channel, request) as Promise<T>);\n }\n\n discover(request: DiscoverRequest = {}): Promise<DiscoveredKafkaInfo[]> {\n return this.read(KAFKA_IPC.discover, request);\n }\n\n overview(request: OverviewRequest): Promise<ClusterOverviewDto> {\n return this.read(KAFKA_IPC.overview, request);\n }\n\n health(request: ClusterHealthRequest): Promise<ClusterOverviewHealthDto> {\n return this.read(KAFKA_IPC.health, request);\n }\n\n invalidateHealth(request: AggregateHealthInvalidateRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.healthInvalidate, request) as Promise<void>;\n }\n\n topic(request: TopicRequest): Promise<TopicDetailDto> {\n return this.read(KAFKA_IPC.topic, request);\n }\n\n topicConfig(request: TopicConfigRequest): Promise<TopicConfigDto> {\n return this.read(KAFKA_IPC.topicConfig, request);\n }\n\n topicConsumers(request: TopicConsumersRequest): Promise<TopicConsumersDto> {\n return this.read(KAFKA_IPC.topicConsumers, request);\n }\n\n brokerConfig(request: BrokerConfigRequest): Promise<BrokerConfigDto> {\n return this.read(KAFKA_IPC.brokerConfig, request);\n }\n\n messagesBrowse(request: MessageBrowseRequest): Promise<MessageBrowseDto> {\n return this.read(KAFKA_IPC.messagesBrowse, request);\n }\n\n groups(request: GroupsRequest): Promise<ConsumerGroupsDto> {\n return this.read(KAFKA_IPC.groups, request);\n }\n\n groupDetail(request: GroupDetailRequest): Promise<ConsumerGroupDetailDto> {\n return this.read(KAFKA_IPC.groupDetail, request);\n }\n\n produce(request: ProduceRequest): Promise<ProduceResultDto> {\n return this.invoke(KAFKA_IPC.produce, request) as Promise<ProduceResultDto>;\n }\n\n resetOffsets(request: ResetOffsetsRequest): Promise<ResetOffsetsResultDto> {\n return this.invoke(KAFKA_IPC.resetOffsets, request) as Promise<ResetOffsetsResultDto>;\n }\n\n schemaSubjects(request: SchemaSubjectsRequest): Promise<SchemaSubjectSummary[]> {\n return this.read(KAFKA_IPC.schemaSubjects, request);\n }\n\n schemaSubjectNames(request: SchemaSubjectNamesRequest): Promise<string[]> {\n return this.read(KAFKA_IPC.schemaSubjectNames, request);\n }\n\n schemaSubjectDetail(request: SchemaSubjectDetailRequest): Promise<SchemaSubjectDetail> {\n return this.read(KAFKA_IPC.schemaSubjectDetail, request);\n }\n\n schemaRegister(request: SchemaRegisterRequest): Promise<{ id: number }> {\n return this.invoke(KAFKA_IPC.schemaRegister, request) as Promise<{ id: number }>;\n }\n\n schemaDeleteSubject(request: SchemaDeleteSubjectRequest): Promise<number[]> {\n return this.invoke(KAFKA_IPC.schemaDeleteSubject, request) as Promise<number[]>;\n }\n\n connectList(request: KafkaConnectRequest): Promise<ConnectorSummaryDto[]> {\n return this.read(KAFKA_IPC.connectList, request);\n }\n\n connectNames(request: KafkaConnectRequest): Promise<string[]> {\n return this.read(KAFKA_IPC.connectNames, request);\n }\n\n connectDetail(request: KafkaConnectDetailRequest): Promise<ConnectorDetailDto> {\n return this.read(KAFKA_IPC.connectDetail, request);\n }\n\n acls(request: AclsRequest): Promise<KafkaAclResultDto> {\n return this.read(KAFKA_IPC.acls, request);\n }\n\n aclCreate(request: AclWriteRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.aclCreate, request) as Promise<void>;\n }\n\n aclDelete(request: AclWriteRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.aclDelete, request) as Promise<void>;\n }\n\n connectPause(request: KafkaConnectDetailRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.connectPause, request) as Promise<void>;\n }\n connectResume(request: KafkaConnectDetailRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.connectResume, request) as Promise<void>;\n }\n connectDelete(request: KafkaConnectDetailRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.connectDelete, request) as Promise<void>;\n }\n connectRestart(request: KafkaConnectDetailRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.connectRestart, request) as Promise<void>;\n }\n connectUpdate(request: KafkaConnectCreateRequest): Promise<void> {\n return this.invoke(KAFKA_IPC.connectUpdate, request) as Promise<void>;\n }\n connectCreate(request: KafkaConnectCreateRequest): Promise<{ name: string }> {\n return this.invoke(KAFKA_IPC.connectCreate, request) as Promise<{ name: string }>;\n }\n\n reachability(bootstraps: string[]): Promise<Record<string, boolean>> {\n return this.read(KAFKA_IPC.reachability, { bootstraps });\n }\n\n onProgress(listener: (progress: KafkaProgressEvent) => void): () => void {\n return this.listen(KAFKA_IPC.progress, (_event, progress: KafkaProgressEvent) => listener(progress));\n }\n}\n","import {\n DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS,\n MIN_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS,\n} from \"../common/constants\";\n\nexport const KAFKA_OVERVIEW_SETTINGS_KEY = \"freelens-kafka.overview.v1\";\n\nexport interface KafkaOverviewSettings {\n enabled: boolean;\n intervalMs: number;\n}\n\ninterface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nfunction defaultStorage(): StorageLike | undefined {\n try {\n return typeof window === \"undefined\" ? undefined : window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class KafkaOverviewSettingsStore {\n private readonly settings = new Map<string, KafkaOverviewSettings>();\n private readonly storage: StorageLike | undefined;\n\n constructor(storage: StorageLike | undefined = defaultStorage()) {\n this.storage = storage;\n this.load();\n }\n\n get(targetId: string): KafkaOverviewSettings {\n const value = this.settings.get(targetId);\n if (value) return { ...value };\n return { enabled: false, intervalMs: DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS };\n }\n\n set(targetId: string, value: Partial<KafkaOverviewSettings> | undefined): void {\n const next = this.normalize(value);\n if (!next.enabled) {\n this.settings.delete(targetId);\n } else {\n this.settings.set(targetId, next);\n }\n this.persist();\n }\n\n clear(): void {\n this.settings.clear();\n this.persist();\n }\n\n private normalize(value?: Partial<KafkaOverviewSettings>): KafkaOverviewSettings {\n const enabled = Boolean(value?.enabled);\n const intervalMs = Math.max(\n MIN_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS,\n Number(value?.intervalMs ?? DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS) ||\n DEFAULT_KAFKA_OVERVIEW_REFRESH_INTERVAL_MS,\n );\n return { enabled, intervalMs };\n }\n\n private load(): void {\n try {\n const parsed = JSON.parse(this.storage?.getItem(KAFKA_OVERVIEW_SETTINGS_KEY) ?? \"{}\") as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return;\n for (const [targetId, raw] of Object.entries(parsed)) {\n if (!raw || typeof raw !== \"object\") continue;\n const candidate = raw as Partial<KafkaOverviewSettings>;\n const next = this.normalize(candidate);\n if (next.enabled) this.settings.set(targetId, next);\n }\n } catch {\n this.settings.clear();\n }\n }\n\n private persist(): void {\n try {\n const values = Object.fromEntries(this.settings.entries());\n this.storage?.setItem(KAFKA_OVERVIEW_SETTINGS_KEY, JSON.stringify(values));\n } catch {\n // Settings remain in-memory for the current session when storage is unavailable.\n }\n }\n}\n","import { KAFKA_PAGE_IDS } from \"./kafka-navigation\";\n\nexport const KAFKA_MENU_IDS = {\n root: \"kafka\",\n clusters: \"kafka-clusters\",\n overview: \"kafka-overview\",\n topics: \"kafka-topics\",\n groups: \"kafka-groups\",\n brokers: \"kafka-brokers\",\n schemas: \"kafka-schema-registry\",\n connect: \"kafka-connect\",\n acls: \"kafka-acls\",\n} as const;\n\nexport const KAFKA_ROUTE_OWNER_MENU_MANIFEST = [\n { id: \"kafka-overview-route-owner\", pageId: KAFKA_PAGE_IDS.overview },\n { id: \"kafka-topics-route-owner\", pageId: KAFKA_PAGE_IDS.topics },\n { id: \"kafka-groups-route-owner\", pageId: KAFKA_PAGE_IDS.groups },\n { id: \"kafka-brokers-route-owner\", pageId: KAFKA_PAGE_IDS.brokers },\n { id: \"kafka-schema-registry-route-owner\", pageId: KAFKA_PAGE_IDS.schemas },\n { id: \"kafka-connect-route-owner\", pageId: KAFKA_PAGE_IDS.connect },\n { id: \"kafka-acls-route-owner\", pageId: KAFKA_PAGE_IDS.acls },\n] as const;\n\nexport const KAFKA_CLUSTER_PAGE_MANIFEST = [\n {\n id: KAFKA_PAGE_IDS.clusters,\n params: { query: \"\" },\n },\n {\n id: KAFKA_PAGE_IDS.overview,\n params: { target: \"\" },\n },\n {\n id: KAFKA_PAGE_IDS.topics,\n params: {\n target: \"\",\n query: \"\",\n topic: \"\",\n view: \"overview\",\n keyFilter: \"\",\n valueFilter: \"\",\n headerKey: \"\",\n headerValue: \"\",\n timestamp: \"\",\n },\n },\n {\n id: KAFKA_PAGE_IDS.groups,\n params: { target: \"\", query: \"\", group: \"\", view: \"offsets\" },\n },\n {\n id: KAFKA_PAGE_IDS.brokers,\n params: { target: \"\", broker: \"\" },\n },\n {\n id: KAFKA_PAGE_IDS.schemas,\n params: { target: \"\", query: \"\", subject: \"\" },\n },\n {\n id: KAFKA_PAGE_IDS.connect,\n params: { target: \"\", query: \"\", connector: \"\" },\n },\n { id: KAFKA_PAGE_IDS.acls, params: { target: \"\" } },\n] as const;\n\nexport const KAFKA_CLUSTER_MENU_MANIFEST = [\n {\n id: KAFKA_MENU_IDS.root,\n title: \"Apache Kafka\",\n pageId: KAFKA_PAGE_IDS.clusters,\n },\n {\n id: KAFKA_MENU_IDS.clusters,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Clusters\",\n pageId: KAFKA_PAGE_IDS.clusters,\n },\n {\n id: KAFKA_MENU_IDS.overview,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Overview\",\n pageId: KAFKA_PAGE_IDS.overview,\n },\n {\n id: KAFKA_MENU_IDS.topics,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Topics\",\n pageId: KAFKA_PAGE_IDS.topics,\n },\n {\n id: KAFKA_MENU_IDS.groups,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Consumer Groups\",\n pageId: KAFKA_PAGE_IDS.groups,\n },\n {\n id: KAFKA_MENU_IDS.brokers,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Brokers\",\n pageId: KAFKA_PAGE_IDS.brokers,\n },\n {\n id: KAFKA_MENU_IDS.schemas,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Schema Registry\",\n pageId: KAFKA_PAGE_IDS.schemas,\n },\n {\n id: KAFKA_MENU_IDS.connect,\n parentId: KAFKA_MENU_IDS.root,\n title: \"Kafka Connect\",\n pageId: KAFKA_PAGE_IDS.connect,\n },\n { id: KAFKA_MENU_IDS.acls, parentId: KAFKA_MENU_IDS.root, title: \"ACLs\", pageId: KAFKA_PAGE_IDS.acls },\n] as const;\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect, useState } from \"react\";\nimport { updateKafkaClusterQuery } from \"./kafka-navigation\";\nimport { KafkaOverviewPage, type KafkaOverviewPageProps } from \"./kafka-overview\";\n\ninterface KafkaClustersPageParams {\n query: string;\n}\n\nexport interface KafkaClustersPageProps extends Omit<KafkaOverviewPageProps, \"query\" | \"onQueryChange\"> {\n params?: {\n query: Renderer.Navigation.PageParam<KafkaClustersPageParams[\"query\"]>;\n };\n}\n\nexport function KafkaClustersPage({ params, ...props }: KafkaClustersPageProps) {\n const routeQuery = params?.query.get() ?? \"\";\n const [query, setQuery] = useState(routeQuery);\n\n useEffect(() => setQuery(routeQuery), [routeQuery]);\n\n useEffect(() => {\n const syncFromHistory = () => setQuery(params?.query.get() ?? \"\");\n window.addEventListener(\"popstate\", syncFromHistory);\n return () => window.removeEventListener(\"popstate\", syncFromHistory);\n }, [params?.query]);\n\n return (\n <KafkaOverviewPage\n {...props}\n query={query}\n onQueryChange={(nextQuery) => {\n setQuery(nextQuery);\n updateKafkaClusterQuery(params?.query, nextQuery);\n }}\n />\n );\n}\n","import { useEffect } from \"react\";\nimport { clearKafkaReloadRoute, type KafkaReloadRoute, readKafkaReloadRoute } from \"./kafka-navigation\";\n\ninterface KafkaReloadRouteRestorerProps {\n onRestoreRoute: (route: KafkaReloadRoute) => void;\n}\n\nexport function KafkaReloadRouteRestorer({ onRestoreRoute }: KafkaReloadRouteRestorerProps) {\n useEffect(() => {\n const route = readKafkaReloadRoute();\n if (!route) return;\n\n let attempts = 0;\n let restoreTimer: number | undefined;\n const stop = () => {\n if (restoreTimer !== undefined) window.clearInterval(restoreTimer);\n };\n const restore = () => {\n if (window.location.pathname.endsWith(`/${route.pageId}`)) {\n clearKafkaReloadRoute();\n stop();\n return;\n }\n if (attempts >= 100) {\n stop();\n return;\n }\n attempts += 1;\n onRestoreRoute(route);\n };\n\n restore();\n restoreTimer = window.setInterval(restore, 100);\n return stop;\n }, [onRestoreRoute]);\n\n return null;\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { KafkaPageShell } from \"./kafka-page-shell\";\nimport { type KafkaResourcePageDependencies, useKafkaPageParam, useKafkaResourcePage } from \"./kafka-resource-pages\";\nimport { canSubmitWriteAction } from \"./kafka-write-policy\";\n\nimport type { HTMLAttributes } from \"react\";\n\nimport type { SchemaSubjectDetail, SchemaSubjectSummary } from \"../common/ipc\";\nimport type { KafkaSchemaRegistrySettingsStore } from \"./kafka-schema-registry-settings\";\n\nexport interface KafkaSchemaRegistryPageProps extends KafkaResourcePageDependencies {\n params?: {\n target: Renderer.Navigation.PageParam<string>;\n query: Renderer.Navigation.PageParam<string>;\n subject: Renderer.Navigation.PageParam<string>;\n };\n schemaRegistrySettings: KafkaSchemaRegistrySettingsStore;\n schemaSubjectNames: (request: { registryUrl: string; registryUsername?: string }) => Promise<string[]>;\n schemaSubjectDetail: (request: {\n registryUrl: string;\n registryUsername?: string;\n subject: string;\n }) => Promise<SchemaSubjectDetail>;\n schemaRegister: (request: {\n registryUrl: string;\n registryUsername?: string;\n subject: string;\n schema: string;\n schemaType?: string;\n }) => Promise<{ id: number }>;\n schemaDeleteSubject: (request: {\n registryUrl: string;\n registryUsername?: string;\n subject: string;\n }) => Promise<number[]>;\n}\n\nexport function KafkaSchemaRegistryPage({\n params,\n schemaRegistrySettings,\n schemaSubjectNames,\n schemaSubjectDetail,\n schemaRegister,\n schemaDeleteSubject,\n ...dependencies\n}: KafkaSchemaRegistryPageProps) {\n const state = useKafkaResourcePage({ ...dependencies, params });\n const [query, setQuery] = useKafkaPageParam(params?.query);\n const [subject, setSubject] = useKafkaPageParam(params?.subject);\n const selectedTargetId = state.selectedCluster?.targetId;\n const registry = useMemo(\n () => (selectedTargetId ? schemaRegistrySettings.get(selectedTargetId) : undefined),\n [schemaRegistrySettings, selectedTargetId],\n );\n const [subjects, setSubjects] = useState<SchemaSubjectSummary[]>([]);\n const [detail, setDetail] = useState<SchemaSubjectDetail>();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string>();\n const canWrite = Boolean(state.selectedCluster && dependencies.writeSettings.get(state.selectedCluster.targetId));\n const [newSchema, setNewSchema] = useState(\"\");\n const [registerConfirmed, setRegisterConfirmed] = useState(false);\n const [deleteText, setDeleteText] = useState(\"\");\n const [deleteConfirmed, setDeleteConfirmed] = useState(false);\n const [writeStatus, setWriteStatus] = useState<string>();\n const [writeError, setWriteError] = useState<string>();\n\n useEffect(() => {\n if (!registry) {\n setSubjects([]);\n setDetail(undefined);\n return;\n }\n let cancelled = false;\n setLoading(true);\n setError(undefined);\n schemaSubjectNames(registry)\n .then((names) => {\n if (!cancelled) {\n setSubjects(names.map((subject) => ({ subject, latestVersion: 0, schemaType: \"Details on open\" })));\n }\n })\n .catch((reason: unknown) => {\n if (!cancelled) setError(reason instanceof Error ? reason.message : String(reason));\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [registry, schemaSubjectNames]);\n\n useEffect(() => {\n if (!registry || !subject) {\n setDetail(undefined);\n return;\n }\n let cancelled = false;\n setLoading(true);\n schemaSubjectDetail({ ...registry, subject })\n .then((value) => {\n if (!cancelled) setDetail(value);\n })\n .catch((reason: unknown) => {\n if (!cancelled) setError(reason instanceof Error ? reason.message : String(reason));\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [registry, schemaSubjectDetail, subject]);\n\n const filtered = useMemo(\n () => subjects.filter((item) => item.subject.toLowerCase().includes(query.trim().toLowerCase())),\n [query, subjects],\n );\n\n if (!registry) {\n return (\n <KafkaPageShell title=\"Schema Registry\" subtitle=\"No Schema Registry configured\">\n <div className=\"KafkaPageState empty\" data-testid=\"kafka-schema-registry-unconfigured\">\n Configure a Registry endpoint in Kafka connection settings to browse subjects.\n </div>\n </KafkaPageShell>\n );\n }\n\n return (\n <KafkaPageShell title=\"Schema Registry\" subtitle={registry.registryUrl}>\n <main className=\"KafkaWorkspace\" data-testid=\"kafka-schema-registry-page\">\n <section className=\"KafkaListPane\">\n <div className=\"KafkaToolbar\">\n <Renderer.Component.Input\n value={query}\n onChange={(value) => setQuery(value, true)}\n placeholder=\"Filter subjects\"\n aria-label=\"Filter schema subjects\"\n />\n </div>\n {loading && <div className=\"KafkaPageState loading\">Loading schema subjects…</div>}\n {error && (\n <div className=\"KafkaPageState error\" role=\"alert\">\n {error}\n </div>\n )}\n {!loading && !error && filtered.length === 0 && (\n <div className=\"KafkaPageState empty\">No schema subjects match.</div>\n )}\n <Renderer.Component.Table className=\"KafkaSchemaSubjectTable\">\n <Renderer.Component.TableHead>\n <Renderer.Component.TableCell>Subject</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Latest version</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Type</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>Compatibility</Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {filtered.map((item) => {\n const interaction: HTMLAttributes<HTMLDivElement> = {\n tabIndex: 0,\n onClick: () => setSubject(item.subject),\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setSubject(item.subject);\n }\n },\n };\n return (\n <Renderer.Component.TableRow {...interaction} key={item.subject} data-subject={item.subject}>\n <Renderer.Component.TableCell>{item.subject}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.latestVersion}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.schemaType}</Renderer.Component.TableCell>\n <Renderer.Component.TableCell>{item.compatibility ?? \"Default\"}</Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n </section>\n {detail && (\n <aside className=\"KafkaDetailPane\" data-testid=\"kafka-schema-subject-detail\">\n <h2>{detail.subject}</h2>\n <span>Compatibility: {detail.compatibility ?? \"Default\"}</span>\n {detail.versions.map((version) => (\n <article key={version.version} className=\"KafkaSchemaVersion\">\n <h3>\n Version {version.version} · {version.schemaType}\n </h3>\n <pre>{version.schema}</pre>\n </article>\n ))}\n {canWrite && registry && (\n <section className=\"KafkaWriteDrawer\" data-testid=\"kafka-schema-write-controls\">\n <h3>Register schema version</h3>\n <Renderer.Component.Input value={newSchema} onChange={setNewSchema} aria-label=\"Schema definition\" />\n <Renderer.Component.Switch\n checked={registerConfirmed}\n onChange={setRegisterConfirmed}\n aria-label=\"Confirm schema registration\"\n />\n <Renderer.Component.Button\n primary\n disabled={!canSubmitWriteAction({ confirmationAccepted: registerConfirmed })}\n onClick={() => {\n setWriteError(undefined);\n void schemaRegister({ ...registry, subject, schema: newSchema })\n .then((result) => {\n setNewSchema(\"\");\n setWriteStatus(`Registered schema version with id ${result.id}`);\n })\n .catch((reason: unknown) =>\n setWriteError(reason instanceof Error ? reason.message : String(reason)),\n );\n }}\n >\n Register schema\n </Renderer.Component.Button>\n <h3>Delete subject</h3>\n <Renderer.Component.Input\n value={deleteText}\n onChange={setDeleteText}\n aria-label=\"Type subject to confirm deletion\"\n />\n <Renderer.Component.Switch\n checked={deleteConfirmed}\n onChange={setDeleteConfirmed}\n aria-label=\"Confirm subject deletion\"\n />\n <Renderer.Component.Button\n primary\n disabled={\n !canSubmitWriteAction({\n confirmationAccepted: deleteConfirmed,\n requiredResourceName: subject,\n enteredResourceName: deleteText,\n })\n }\n onClick={() => {\n setWriteError(undefined);\n void schemaDeleteSubject({ ...registry, subject })\n .then(() => {\n setWriteStatus(`Deleted subject ${subject}`);\n })\n .catch((reason: unknown) =>\n setWriteError(reason instanceof Error ? reason.message : String(reason)),\n );\n }}\n >\n Delete subject\n </Renderer.Component.Button>\n {writeStatus && (\n <div role=\"status\" data-testid=\"kafka-schema-write-status\">\n {writeStatus}\n </div>\n )}\n {writeError && (\n <div role=\"alert\" data-testid=\"kafka-schema-write-error\">\n {writeError}\n </div>\n )}\n </section>\n )}\n </aside>\n )}\n </main>\n </KafkaPageShell>\n );\n}\n","import { observable } from \"mobx\";\n\nexport const KAFKA_SCHEMA_REGISTRY_SETTINGS_KEY = \"freelens-kafka.schema-registry.v1\";\n\nexport interface SchemaRegistrySettings {\n registryUrl: string;\n tls: boolean;\n username?: string;\n}\n\ninterface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport class KafkaSchemaRegistrySettingsStore {\n private readonly settings = new Map<string, SchemaRegistrySettings>();\n private readonly listeners = new Set<() => void>();\n private readonly configured = observable.box(false);\n\n constructor(\n private readonly storage: StorageLike | undefined = typeof window === \"undefined\" ? undefined : window.localStorage,\n ) {\n this.load();\n }\n\n get(targetId: string): SchemaRegistrySettings | undefined {\n const value = this.settings.get(targetId);\n return value ? { ...value } : undefined;\n }\n\n hasAny(): boolean {\n return this.configured.get();\n }\n\n set(targetId: string, value?: SchemaRegistrySettings): void {\n if (!value?.registryUrl.trim()) this.settings.delete(targetId);\n else this.settings.set(targetId, { ...value, registryUrl: value.registryUrl.trim() });\n this.persist();\n this.configured.set(this.settings.size > 0);\n for (const listener of this.listeners) listener();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private load(): void {\n try {\n const parsed = JSON.parse(this.storage?.getItem(KAFKA_SCHEMA_REGISTRY_SETTINGS_KEY) ?? \"{}\") as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return;\n for (const [targetId, value] of Object.entries(parsed)) {\n if (!value || typeof value !== \"object\") continue;\n const candidate = value as Partial<SchemaRegistrySettings>;\n if (typeof candidate.registryUrl === \"string\" && candidate.registryUrl.trim()) {\n this.settings.set(targetId, {\n registryUrl: candidate.registryUrl,\n tls: Boolean(candidate.tls),\n ...(candidate.username ? { username: candidate.username } : {}),\n });\n }\n }\n this.configured.set(this.settings.size > 0);\n } catch {\n this.settings.clear();\n }\n }\n\n private persist(): void {\n try {\n const values = Object.fromEntries(this.settings.entries());\n this.storage?.setItem(KAFKA_SCHEMA_REGISTRY_SETTINGS_KEY, JSON.stringify(values));\n } catch {\n // Settings remain available for the current session when storage is unavailable.\n }\n }\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { OperationProgress } from \"./kafka-overview\";\nimport { createOperationId, matchesKafkaMessageFilters } from \"./kafka-view-model\";\n\nimport type { HTMLAttributes } from \"react\";\n\nimport type {\n DiscoveredKafkaInfo,\n KafkaMessageBytesDto,\n KafkaMessageStartMode,\n KafkaProgressEvent,\n KafkaRecordDto,\n KafkaSecurityOverride,\n MessageBrowseDto,\n MessageBrowseRequest,\n TopicPartitionDto,\n} from \"../common/ipc\";\n\nconst START_MODES: Array<{ value: KafkaMessageStartMode; label: string }> = [\n { value: \"latest\", label: \"Latest window\" },\n { value: \"earliest\", label: \"Earliest\" },\n { value: \"offset\", label: \"Offset\" },\n { value: \"timestamp\", label: \"Timestamp\" },\n];\n\nconst TAIL_POLL_INTERVAL_MS = 1500;\n\ninterface MessageBrowseState {\n loading: boolean;\n error?: string;\n data?: MessageBrowseDto;\n progress?: KafkaProgressEvent;\n}\n\ninterface TailState {\n active: boolean;\n bufferLimit: number;\n droppedCount: number;\n nextOffset?: string;\n}\n\ninterface KafkaMessagesBrowserProps {\n cluster: DiscoveredKafkaInfo;\n topic: string;\n partitions: TopicPartitionDto[];\n metadataLoading: boolean;\n metadataError?: string;\n metadataProgress?: KafkaProgressEvent;\n security?: KafkaSecurityOverride;\n browse: (request: MessageBrowseRequest) => Promise<MessageBrowseDto>;\n subscribeProgress: (listener: (progress: KafkaProgressEvent) => void) => () => void;\n onRetryMetadata: () => void;\n filters: KafkaMessageFilters;\n onFilterChange: (name: MessageFilterName, value: string) => void;\n timestamp: string;\n onTimestampChange: (value: string) => void;\n schemaRegistry?: { registryUrl: string; username?: string };\n}\n\ntype MessageFilterName = \"key\" | \"value\" | \"headerKey\" | \"headerValue\";\n\ninterface KafkaMessageFilters {\n key: string;\n value: string;\n headerKey: string;\n headerValue: string;\n}\n\nfunction formatTimestamp(timestamp: string): string {\n const value = Number(timestamp);\n return Number.isFinite(value) ? new Date(value).toLocaleString() : timestamp;\n}\n\nfunction bytesContent(bytes: KafkaMessageBytesDto): string {\n if (bytes.format === \"null\") return \"null\";\n if (bytes.format === \"json\" && !bytes.truncated && bytes.text !== undefined) {\n try {\n return JSON.stringify(JSON.parse(bytes.text), null, 2);\n } catch {\n return bytes.text;\n }\n }\n return bytes.text ?? bytes.base64 ?? \"\";\n}\n\nfunction FormatBadge({ bytes }: { bytes: KafkaMessageBytesDto }) {\n if (bytes.format === \"null\") {\n return <span className=\"KafkaMsgFormatBadge format-null\">null</span>;\n }\n const label = bytes.format === \"json\" ? \"JSON\" : bytes.format === \"text\" ? \"Text\" : \"Binary\";\n const suffix = bytes.truncated ? \" · truncated\" : \"\";\n return (\n <span className={`KafkaMsgFormatBadge format-${bytes.format}`}>\n {label} · {bytes.byteLength}\\u202fB{suffix}\n </span>\n );\n}\n\nfunction BytesSection({ label, bytes }: { label: string; bytes: KafkaMessageBytesDto }) {\n return (\n <>\n <Renderer.Component.DrawerTitle size=\"sub-title\">{label}</Renderer.Component.DrawerTitle>\n <div className=\"KafkaMsgBytesBody\">\n <FormatBadge bytes={bytes} />\n {bytes.format !== \"null\" && (\n <pre className=\"KafkaMsgCodeBlock\" data-format={bytes.format}>\n {bytesContent(bytes)}\n </pre>\n )}\n {(bytes.format === \"binary\" || bytes.truncated) && bytes.base64 !== undefined && (\n <details className=\"KafkaMsgBase64\">\n <summary>Raw base64</summary>\n <code>{bytes.base64}</code>\n </details>\n )}\n </div>\n </>\n );\n}\n\nfunction MessageInspector({ message }: { message: KafkaRecordDto }) {\n const hasHeaders = message.headers.length > 0;\n return (\n <div className=\"KafkaMessageInspector\" aria-label={`Message at offset ${message.offset}`}>\n <Renderer.Component.DrawerItem name=\"Partition\">{message.partition}</Renderer.Component.DrawerItem>\n <Renderer.Component.DrawerItem name=\"Offset\">\n <code className=\"KafkaMsgMono\">{message.offset}</code>\n </Renderer.Component.DrawerItem>\n <Renderer.Component.DrawerItem name=\"Timestamp\">\n <div className=\"KafkaMsgTimestamp\">\n <span>{formatTimestamp(message.timestamp)}</span>\n <small>{message.timestamp}</small>\n </div>\n </Renderer.Component.DrawerItem>\n\n <BytesSection label=\"Key\" bytes={message.key} />\n <BytesSection label=\"Value\" bytes={message.value} />\n {message.decodedValue !== undefined && (\n <>\n <Renderer.Component.DrawerTitle size=\"sub-title\">Decoded value</Renderer.Component.DrawerTitle>\n <pre className=\"KafkaMsgCodeBlock\" data-testid=\"kafka-decoded-value\">\n {JSON.stringify(message.decodedValue, null, 2)}\n </pre>\n </>\n )}\n {message.decodeWarning && (\n <div className=\"KafkaPageState warning\" role=\"status\" data-testid=\"kafka-decode-warning\">\n <Renderer.Component.Icon material=\"warning\" />\n {message.decodeWarning}\n </div>\n )}\n\n <Renderer.Component.DrawerTitle size=\"sub-title\">\n Headers{hasHeaders ? ` (${message.headers.length})` : \"\"}\n </Renderer.Component.DrawerTitle>\n {hasHeaders ? (\n <div className=\"KafkaMsgHeaderList\">\n {message.headers.map((header, index) => (\n <Renderer.Component.DrawerItem key={`${header.name}-${index}`} name={header.name}>\n {header.value.format === \"null\" ? (\n <FormatBadge bytes={header.value} />\n ) : (\n <div className=\"KafkaMsgHeaderValue\">\n <FormatBadge bytes={header.value} />\n <code className=\"KafkaMsgMono\">{bytesContent(header.value)}</code>\n </div>\n )}\n </Renderer.Component.DrawerItem>\n ))}\n </div>\n ) : (\n <div className=\"KafkaMsgEmpty\">\n <Renderer.Component.Icon material=\"label_off\" />\n No headers\n </div>\n )}\n </div>\n );\n}\n\nexport function KafkaMessagesBrowser({\n cluster,\n topic,\n partitions,\n metadataLoading,\n metadataError,\n metadataProgress,\n security,\n browse,\n subscribeProgress,\n onRetryMetadata,\n filters,\n onFilterChange,\n timestamp,\n onTimestampChange,\n schemaRegistry,\n}: KafkaMessagesBrowserProps) {\n const partitionOptions = partitions\n .map(({ partitionId }) => partitionId)\n .sort((left, right) => left - right)\n .map((partition) => ({ value: String(partition), label: `Partition ${partition}` }));\n const [partition, setPartition] = useState(partitionOptions[0]?.value ?? \"0\");\n const [startMode, setStartMode] = useState<KafkaMessageStartMode>(\"latest\");\n const [offset, setOffset] = useState(\"0\");\n const [limit, setLimit] = useState(\"50\");\n const [state, setState] = useState<MessageBrowseState>({ loading: false });\n const [selectedOffset, setSelectedOffset] = useState<string>();\n const [tailState, setTailState] = useState<TailState>({ active: false, bufferLimit: 0, droppedCount: 0 });\n const [browseRequests, setBrowseRequests] = useState(0);\n const operationId = useRef<string>();\n const tailSession = useRef(0);\n const tailTimer = useRef<number>();\n\n useEffect(\n () =>\n subscribeProgress((progress) => {\n if (progress.operation === \"messagesBrowse\" && progress.operationId === operationId.current) {\n setState((current) => ({ ...current, progress }));\n }\n }),\n [subscribeProgress],\n );\n\n useEffect(() => {\n operationId.current = undefined;\n setState({ loading: false });\n setSelectedOffset(undefined);\n tailSession.current += 1;\n if (tailTimer.current !== undefined) window.clearTimeout(tailTimer.current);\n setTailState({ active: false, bufferLimit: 0, droppedCount: 0 });\n setBrowseRequests(0);\n setPartition(partitionOptions[0]?.value ?? \"0\");\n }, [cluster.targetId, topic]);\n\n useEffect(\n () => () => {\n operationId.current = undefined;\n tailSession.current += 1;\n if (tailTimer.current !== undefined) window.clearTimeout(tailTimer.current);\n },\n [],\n );\n\n const stopTail = useCallback(() => {\n tailSession.current += 1;\n if (tailTimer.current !== undefined) {\n window.clearTimeout(tailTimer.current);\n tailTimer.current = undefined;\n }\n setTailState((current) => (current.active ? { ...current, active: false } : current));\n }, []);\n\n const parseBrowseControls = useCallback(\n (next?: { startMode?: KafkaMessageStartMode; offset?: string; timestamp?: string; limit?: string }) => {\n const parsedPartition = Number(partition);\n const parsedLimit = Number(next?.limit ?? limit);\n const requestedMode = next?.startMode ?? startMode;\n const requestedOffset = next?.offset ?? offset;\n const requestedTimestampText = next?.timestamp ?? timestamp;\n const requestedTimestamp = requestedTimestampText ? Date.parse(requestedTimestampText) : Number.NaN;\n\n if (!Number.isInteger(parsedPartition) || !partitions.some((item) => item.partitionId === parsedPartition)) {\n return { error: \"Select a valid partition.\" };\n }\n if (!Number.isInteger(parsedLimit) || parsedLimit < 1 || parsedLimit > 100) {\n return { error: \"Limit must be between 1 and 100.\" };\n }\n if (requestedMode === \"offset\" && !/^(0|[1-9]\\d*)$/.test(requestedOffset)) {\n return { error: \"Offset must be a non-negative decimal value.\" };\n }\n if (requestedMode === \"timestamp\" && !Number.isSafeInteger(requestedTimestamp)) {\n return { error: \"Select a valid timestamp.\" };\n }\n\n return {\n parsedPartition,\n parsedLimit,\n requestedMode,\n requestedOffset,\n requestedTimestamp,\n };\n },\n [limit, offset, partition, partitions, startMode, timestamp],\n );\n\n const runBrowse = useCallback(\n (next?: { startMode: KafkaMessageStartMode; offset?: string }) => {\n const resolved = parseBrowseControls(next);\n\n if (\"error\" in resolved) {\n setState({ loading: false, error: resolved.error });\n return;\n }\n\n const { parsedPartition, parsedLimit, requestedMode, requestedOffset, requestedTimestamp } = resolved;\n\n stopTail();\n const nextOperationId = createOperationId(\"messagesBrowse\");\n operationId.current = nextOperationId;\n const progress: KafkaProgressEvent = {\n operationId: nextOperationId,\n operation: \"messagesBrowse\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing message Browse\",\n detail: \"Selecting the existing read-only connection path.\",\n };\n setState((current) => ({ loading: true, data: current.data, progress }));\n setBrowseRequests((count) => count + 1);\n setSelectedOffset(undefined);\n if (next) {\n setStartMode(next.startMode);\n if (next.offset !== undefined) setOffset(next.offset);\n }\n\n browse({\n operationId: nextOperationId,\n targetId: cluster.targetId,\n topic,\n partition: parsedPartition,\n startMode: requestedMode,\n limit: parsedLimit,\n ...(requestedMode === \"offset\" ? { offset: requestedOffset } : {}),\n ...(requestedMode === \"timestamp\" ? { timestamp: requestedTimestamp } : {}),\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security,\n ...(schemaRegistry\n ? { registryUrl: schemaRegistry.registryUrl, registryUsername: schemaRegistry.username }\n : {}),\n ...(schemaRegistry\n ? { registryUrl: schemaRegistry.registryUrl, registryUsername: schemaRegistry.username }\n : {}),\n })\n .then((data) => {\n if (operationId.current !== nextOperationId) return;\n setState({ loading: false, data });\n })\n .catch((error: unknown) => {\n if (operationId.current !== nextOperationId) return;\n setState((current) => ({\n loading: false,\n data: current.data,\n error: error instanceof Error ? error.message : String(error),\n progress,\n }));\n });\n },\n [browse, cluster, parseBrowseControls, schemaRegistry, security, startMode, stopTail, topic],\n );\n\n const startTail = useCallback(() => {\n const resolved = parseBrowseControls({ startMode: \"latest\", limit });\n\n if (\"error\" in resolved) {\n setState({ loading: false, error: resolved.error });\n return;\n }\n\n stopTail();\n setSelectedOffset(undefined);\n\n const { parsedPartition, parsedLimit } = resolved;\n const sessionId = tailSession.current + 1;\n\n tailSession.current = sessionId;\n setTailState({ active: true, bufferLimit: parsedLimit, droppedCount: 0 });\n\n const poll = (cursor: string) => {\n const currentSession = sessionId;\n const nextOperationId = createOperationId(\"messagesBrowse\");\n\n operationId.current = nextOperationId;\n\n browse({\n operationId: nextOperationId,\n targetId: cluster.targetId,\n topic,\n partition: parsedPartition,\n startMode: \"offset\",\n offset: cursor,\n limit: parsedLimit,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n security,\n })\n .then((data) => {\n if (tailSession.current !== currentSession) return;\n\n setState((current) => {\n const existing = current.data?.messages ?? [];\n const seen = new Set(existing.map((message) => `${message.partition}:${message.offset}`));\n const appended = data.messages.filter((message) => !seen.has(`${message.partition}:${message.offset}`));\n const merged = [...existing, ...appended];\n const dropped = Math.max(0, merged.length - parsedLimit);\n const buffered = dropped > 0 ? merged.slice(dropped) : merged;\n\n setTailState((tail) => ({\n ...tail,\n active: true,\n bufferLimit: parsedLimit,\n droppedCount: tail.droppedCount + dropped,\n nextOffset: data.nextOffset,\n }));\n\n return {\n loading: false,\n data: {\n ...data,\n startMode: \"latest\",\n startOffset: buffered[0]?.offset ?? data.nextOffset,\n returnedCount: buffered.length,\n hasMore: false,\n messages: buffered,\n },\n };\n });\n\n tailTimer.current = window.setTimeout(() => poll(data.nextOffset), TAIL_POLL_INTERVAL_MS);\n })\n .catch((error: unknown) => {\n if (tailSession.current !== currentSession) return;\n stopTail();\n setState((current) => ({\n loading: false,\n data: current.data,\n error: error instanceof Error ? error.message : String(error),\n }));\n });\n };\n\n const nextOperationId = createOperationId(\"messagesBrowse\");\n\n operationId.current = nextOperationId;\n setState((current) => ({ loading: true, data: current.data }));\n setBrowseRequests((count) => count + 1);\n\n browse({\n operationId: nextOperationId,\n targetId: cluster.targetId,\n topic,\n partition: parsedPartition,\n startMode: \"latest\",\n limit: 1,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security,\n ...(schemaRegistry ? { registryUrl: schemaRegistry.registryUrl, registryUsername: schemaRegistry.username } : {}),\n })\n .then((data) => {\n if (tailSession.current !== sessionId) return;\n\n setState({\n loading: false,\n data: {\n ...data,\n startMode: \"latest\",\n startOffset: data.nextOffset,\n returnedCount: 0,\n hasMore: false,\n messages: [],\n },\n });\n setTailState({ active: true, bufferLimit: parsedLimit, droppedCount: 0, nextOffset: data.nextOffset });\n tailTimer.current = window.setTimeout(() => poll(data.nextOffset), TAIL_POLL_INTERVAL_MS);\n })\n .catch((error: unknown) => {\n if (tailSession.current !== sessionId) return;\n stopTail();\n setState((current) => ({\n loading: false,\n data: current.data,\n error: error instanceof Error ? error.message : String(error),\n }));\n });\n }, [browse, cluster, limit, parseBrowseControls, schemaRegistry, security, stopTail, topic]);\n\n if (metadataLoading && metadataProgress) return <OperationProgress progress={metadataProgress} />;\n if (metadataError) {\n return (\n <div className=\"KafkaPageState error\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <div>\n <strong>Topic metadata failed</strong>\n <span>{metadataError}</span>\n </div>\n <Renderer.Component.Button outlined onClick={onRetryMetadata}>\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n\n const allMessages = state.data?.messages ?? [];\n const filteredMessages = allMessages.filter((message) => matchesKafkaMessageFilters(message, filters));\n const filtersActive = Object.values(filters).some((value) => value.trim().length > 0);\n const selectedMessage = allMessages.find((message) => message.offset === selectedOffset);\n\n return (\n <section\n className=\"KafkaMessagesBrowser\"\n data-testid=\"kafka-messages-browser\"\n data-browse-state={state.loading ? \"loading\" : state.data ? \"complete\" : state.error ? \"error\" : \"idle\"}\n data-browse-requests={browseRequests}\n >\n <form\n className=\"KafkaMessageControls\"\n aria-label=\"Message Browse controls\"\n onSubmit={(event) => {\n event.preventDefault();\n runBrowse();\n }}\n >\n <label className=\"KafkaMessagePartitionField\">\n <span>Partition</span>\n <Renderer.Component.Select\n id=\"kafka-message-partition\"\n className=\"KafkaMessagePartitionSelect\"\n options={partitionOptions}\n value={partition}\n aria-label=\"Partition\"\n isSearchable={false}\n onChange={(option: Renderer.Component.SelectOption<string> | null) => {\n setPartition(option?.value ?? \"0\");\n setState({ loading: false });\n }}\n isDisabled={state.loading || partitionOptions.length === 0}\n themeName=\"lens\"\n menuPosition=\"fixed\"\n />\n </label>\n <fieldset className=\"KafkaMessageStartField\">\n <legend>Start position</legend>\n <div className=\"KafkaMessageStartModes\" role=\"group\" aria-label=\"Start position\">\n {START_MODES.map((mode) => (\n <Renderer.Component.Button\n key={mode.value}\n plain\n type=\"button\"\n aria-pressed={startMode === mode.value}\n disabled={state.loading}\n onClick={() => {\n setStartMode(mode.value);\n setState({ loading: false });\n }}\n >\n {mode.label}\n </Renderer.Component.Button>\n ))}\n </div>\n </fieldset>\n {startMode === \"offset\" && (\n <label>\n <span>Offset</span>\n <Renderer.Component.Input\n value={offset}\n onChange={setOffset}\n disabled={state.loading}\n aria-label=\"Starting offset\"\n />\n </label>\n )}\n {startMode === \"timestamp\" && (\n <label>\n <span>Timestamp</span>\n <Renderer.Component.Input\n type=\"datetime-local\"\n value={timestamp}\n onChange={onTimestampChange}\n disabled={state.loading}\n aria-label=\"Starting timestamp\"\n />\n </label>\n )}\n <label>\n <span>Limit</span>\n <Renderer.Component.Input\n type=\"number\"\n min={1}\n max={100}\n value={limit}\n onChange={setLimit}\n disabled={state.loading}\n aria-label=\"Record limit\"\n />\n </label>\n <Renderer.Component.Button\n primary\n type=\"button\"\n waiting={state.loading}\n disabled={partitionOptions.length === 0}\n aria-label=\"Browse messages\"\n onClick={() => runBrowse()}\n >\n <Renderer.Component.Icon material=\"search\" />\n Browse\n </Renderer.Component.Button>\n <Renderer.Component.Button\n primary={!tailState.active}\n outlined={tailState.active}\n type=\"button\"\n disabled={partitionOptions.length === 0 || state.loading}\n onClick={tailState.active ? stopTail : startTail}\n >\n <Renderer.Component.Icon material={tailState.active ? \"stop_circle\" : \"sync\"} />\n {tailState.active ? \"Stop tail\" : \"Start tail\"}\n </Renderer.Component.Button>\n </form>\n\n <fieldset className=\"KafkaMessageFilters\" aria-label=\"Message filters\">\n <legend>Filter loaded records</legend>\n <label>\n <span>Key</span>\n <Renderer.Component.Input\n value={filters.key}\n onChange={(value) => onFilterChange(\"key\", value)}\n placeholder=\"Substring or /regex/\"\n aria-label=\"Filter message key\"\n />\n </label>\n <label>\n <span>Value</span>\n <Renderer.Component.Input\n value={filters.value}\n onChange={(value) => onFilterChange(\"value\", value)}\n placeholder=\"Substring or /regex/\"\n aria-label=\"Filter message value\"\n />\n </label>\n <label>\n <span>Header key</span>\n <Renderer.Component.Input\n value={filters.headerKey}\n onChange={(value) => onFilterChange(\"headerKey\", value)}\n placeholder=\"x-trace-id\"\n aria-label=\"Filter message header key\"\n />\n </label>\n <label>\n <span>Header value</span>\n <Renderer.Component.Input\n value={filters.headerValue}\n onChange={(value) => onFilterChange(\"headerValue\", value)}\n placeholder=\"Substring or /regex/\"\n aria-label=\"Filter message header value\"\n />\n </label>\n </fieldset>\n\n {tailState.active && (\n <div className=\"KafkaMessageTailStatus\" role=\"status\" aria-live=\"polite\">\n <Renderer.Component.Icon material=\"sync\" />\n <div>\n <strong>Tailing partition {partition}</strong>\n <span>\n Buffer {state.data?.messages.length ?? 0}/{tailState.bufferLimit}\n {tailState.droppedCount > 0 ? ` · dropped ${tailState.droppedCount}` : \"\"}\n {tailState.nextOffset ? ` · next offset ${tailState.nextOffset}` : \"\"}\n </span>\n </div>\n </div>\n )}\n\n {state.error && (\n <div className=\"KafkaMessageError\" role=\"alert\">\n <Renderer.Component.Icon material=\"error_outline\" />\n <span>{state.error}</span>\n </div>\n )}\n {state.loading && state.progress && <OperationProgress progress={state.progress} />}\n\n {!state.loading && !state.data && !state.error && (\n <div className=\"KafkaMessageIdle\">\n <Renderer.Component.Icon material=\"pause_circle_outline\" />\n <div>\n <strong>No message window loaded</strong>\n <span>Browse is idle.</span>\n </div>\n </div>\n )}\n\n {state.data && (\n <>\n <header className=\"KafkaMessageRange\">\n <div>\n <strong>\n {tailState.active\n ? `${filteredMessages.length} buffered records`\n : filtersActive\n ? `${filteredMessages.length} of ${state.data.returnedCount} records`\n : `${state.data.returnedCount} records`}\n </strong>\n <span>\n {tailState.active\n ? `Tailing from offset ${state.data.startOffset} · high watermark ${state.data.highWatermark}`\n : `Offsets ${state.data.startOffset}–${state.data.nextOffset} · high watermark ${state.data.highWatermark}`}\n </span>\n </div>\n {!tailState.active && (\n <Renderer.Component.Button\n outlined\n disabled={!state.data.hasMore || state.loading}\n onClick={() => runBrowse({ startMode: \"offset\", offset: state.data?.nextOffset })}\n >\n Next window\n <Renderer.Component.Icon material=\"arrow_forward\" />\n </Renderer.Component.Button>\n )}\n </header>\n {filteredMessages.length === 0 ? (\n <div className=\"KafkaMessageIdle\">\n <Renderer.Component.Icon material=\"inbox\" />\n <div>\n <strong>\n {filtersActive ? \"No messages match the current filter\" : \"No committed records in this window\"}\n </strong>\n <span>\n {filtersActive\n ? \"Adjust the filter to inspect other loaded records.\"\n : `Next offset ${state.data.nextOffset}`}\n </span>\n </div>\n </div>\n ) : (\n <Renderer.Component.Table<KafkaRecordDto>\n className=\"KafkaMessageTable\"\n tableId=\"kafka-message-browser\"\n autoSize={false}\n scrollable\n selectable\n sortSyncWithUrl={false}\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell className=\"messageOffsetCell\">Offset</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageTimeCell\">Timestamp</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageKeyCell\">Key</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageValueCell\">Value</Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageActionCell\" />\n </Renderer.Component.TableHead>\n {filteredMessages.map((message) => {\n const select = (event: { stopPropagation: () => void }): void => {\n event.stopPropagation();\n setSelectedOffset(message.offset);\n };\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Inspect message at offset ${message.offset}`,\n \"aria-selected\": selectedOffset === message.offset,\n onClick: select,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n select(event);\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={`${message.partition}-${message.offset}`}\n sortItem={message}\n selected={selectedOffset === message.offset}\n data-offset={message.offset}\n nowrap\n >\n <Renderer.Component.TableCell className=\"messageOffsetCell\">\n {message.offset}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageTimeCell\" title={message.timestamp}>\n {formatTimestamp(message.timestamp)}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageKeyCell\" title={message.key.text}>\n <span className=\"KafkaEllipsis\">{bytesContent(message.key)}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageValueCell\" title={message.value.text}>\n <span className=\"KafkaEllipsis\">{bytesContent(message.value)}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"messageActionCell\">\n <Renderer.Component.Button\n plain\n round\n className=\"KafkaIconButton\"\n title={`View details for offset ${message.offset}`}\n aria-label={`View details for offset ${message.offset}`}\n onClick={select}\n >\n <Renderer.Component.Icon material=\"visibility\" />\n </Renderer.Component.Button>\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n )}\n </>\n )}\n\n {selectedMessage && (\n <Renderer.Component.Drawer\n className=\"KafkaMessageDetailDrawer\"\n contentClass=\"KafkaMessageDetailBody\"\n open\n usePortal\n size=\"min(760px, calc(100vw - 24px))\"\n title={`Message detail: offset ${selectedMessage.offset}`}\n data-testid=\"kafka-message-detail\"\n onClose={() => setSelectedOffset(undefined)}\n >\n <MessageInspector message={selectedMessage} />\n </Renderer.Component.Drawer>\n )}\n </section>\n );\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { kafkaPersistentStateStore } from \"../common/kafka-persistent-state-store\";\nimport { kafkaListWindow } from \"./kafka-list-window\";\nimport { KafkaMessagesBrowser } from \"./kafka-messages\";\nimport { implementedKafkaTopicView, rememberKafkaClusterSelection, saveKafkaReloadRoute } from \"./kafka-navigation\";\nimport { OperationProgress, TopicMetadata, type TopicState } from \"./kafka-overview\";\nimport { KafkaMetricStrip, KafkaPageShell } from \"./kafka-page-shell\";\nimport {\n KafkaResourceActions,\n type KafkaResourcePageDependencies,\n KafkaResourceState,\n useKafkaPageParam,\n useKafkaResourcePage,\n} from \"./kafka-resource-pages\";\nimport { createOperationId, filterTopicNames, kafkaDecimalSortKey } from \"./kafka-view-model\";\nimport { canSubmitWriteAction, getWriteConfirmationLabel } from \"./kafka-write-policy\";\nimport { useKafkaWriteMode } from \"./kafka-write-settings\";\n\nimport type { CSSProperties, HTMLAttributes } from \"react\";\n\nimport type {\n KafkaProgressEvent,\n MessageBrowseDto,\n MessageBrowseRequest,\n ProduceRequest,\n ProduceResultDto,\n TopicConfigDto,\n TopicConfigEntryDto,\n TopicConfigRequest,\n TopicConsumerGroupDto,\n TopicConsumersDto,\n TopicConsumersRequest,\n TopicDetailDto,\n TopicRequest,\n} from \"../common/ipc\";\nimport type { KafkaSchemaRegistrySettingsStore } from \"./kafka-schema-registry-settings\";\n\ninterface KafkaTopicsPageParams {\n target: string;\n query: string;\n topic: string;\n view: string;\n keyFilter: string;\n valueFilter: string;\n headerKey: string;\n headerValue: string;\n timestamp: string;\n}\n\nconst TOPIC_NAME_COLUMN_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst TOPIC_TYPE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 112px\", minWidth: 112, width: 112 };\nconst TOPIC_ACTION_COLUMN_STYLE: CSSProperties = { flex: \"0 0 44px\", minWidth: 44, width: 44 };\nconst TOPIC_CONFIG_NAME_COLUMN_STYLE: CSSProperties = { flex: \"0 0 220px\", minWidth: 220, width: 220 };\nconst TOPIC_CONFIG_VALUE_COLUMN_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst TOPIC_CONFIG_SOURCE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 230px\", minWidth: 230, width: 230 };\nconst TOPIC_CONFIG_FLAGS_COLUMN_STYLE: CSSProperties = { flex: \"0 0 140px\", minWidth: 140, width: 140 };\nconst TOPIC_CONSUMER_NAME_COLUMN_STYLE: CSSProperties = { flex: \"1 1 0\", minWidth: 0, width: 0 };\nconst TOPIC_CONSUMER_STATE_COLUMN_STYLE: CSSProperties = { flex: \"0 0 136px\", minWidth: 136, width: 136 };\nconst TOPIC_CONSUMER_MEMBERS_COLUMN_STYLE: CSSProperties = { flex: \"0 0 90px\", minWidth: 90, width: 90 };\nconst TOPIC_CONSUMER_LAG_COLUMN_STYLE: CSSProperties = { flex: \"0 0 120px\", minWidth: 120, width: 120 };\nconst TOPIC_CONSUMER_ACTION_COLUMN_STYLE: CSSProperties = { flex: \"0 0 44px\", minWidth: 44, width: 44 };\n\ninterface TopicConfigState {\n topic?: string;\n loading: boolean;\n data?: TopicConfigDto;\n error?: string;\n progress?: KafkaProgressEvent;\n}\n\ninterface TopicConsumersState {\n topic?: string;\n loading: boolean;\n data?: TopicConsumersDto;\n error?: string;\n progress?: KafkaProgressEvent;\n}\n\nfunction TopicConsumerStateBadge({ state }: { state: string }) {\n const tone =\n state === \"Stable\"\n ? \"KafkaHealthyBadge\"\n : state === \"Dead\" || state === \"Unknown\"\n ? \"KafkaErrorBadge\"\n : \"KafkaWarningBadge\";\n return <Renderer.Component.Badge small className={tone} label={state || \"Unknown\"} />;\n}\n\nfunction TopicConsumerLag({ lag }: { lag: string }) {\n if (lag === \"—\") return <span className=\"KafkaLagUnknown\">—</span>;\n const value = BigInt(lag);\n const tone = value === 0n ? \"KafkaLagZero\" : value < 1000n ? \"KafkaLagLow\" : \"KafkaLagHigh\";\n return <strong className={tone}>{lag}</strong>;\n}\n\nfunction TopicConsumers({\n state,\n onRetry,\n onOpenGroup,\n}: {\n state: TopicConsumersState;\n onRetry: () => void;\n onOpenGroup: (groupId: string) => void;\n}) {\n if (state.loading && state.progress && !state.data) {\n return <OperationProgress progress={state.progress} />;\n }\n if (state.loading && !state.data) {\n return <Renderer.Component.Spinner center />;\n }\n\n if (state.error) {\n return (\n <div className=\"KafkaTopicInlineError\" role=\"alert\">\n <span>{state.error}</span>\n <Renderer.Component.Button outlined onClick={onRetry}>\n <Renderer.Component.Icon material=\"refresh\" />\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n\n if (!state.data || state.data.groups.length === 0) {\n return (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"group_off\" />\n <div>\n <strong>No consumer groups</strong>\n <span>No consumer group has committed offsets on this topic.</span>\n </div>\n </div>\n );\n }\n\n return (\n <Renderer.Component.Table<TopicConsumerGroupDto>\n className=\"KafkaTopicConsumersTable\"\n tableId=\"kafka-topic-consumers\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"group\", orderBy: \"asc\" }}\n sortable={{\n group: (group) => group.groupId.toLowerCase(),\n lag: (group) => kafkaDecimalSortKey(group.totalLag),\n }}\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell\n className=\"consumerGroupCell\"\n sortBy=\"group\"\n style={TOPIC_CONSUMER_NAME_COLUMN_STYLE}\n >\n Consumer group\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerStateCell\" style={TOPIC_CONSUMER_STATE_COLUMN_STYLE}>\n State\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerMembersCell\" style={TOPIC_CONSUMER_MEMBERS_COLUMN_STYLE}>\n Members\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerLagCell\" sortBy=\"lag\" style={TOPIC_CONSUMER_LAG_COLUMN_STYLE}>\n Total lag\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerActionCell\" style={TOPIC_CONSUMER_ACTION_COLUMN_STYLE} />\n </Renderer.Component.TableHead>\n {state.data.groups.map((group) => {\n const open = (): void => onOpenGroup(group.groupId);\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open consumer group ${group.groupId}`,\n onClick: open,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n open();\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={group.groupId}\n sortItem={group}\n data-group={group.groupId}\n nowrap\n >\n <Renderer.Component.TableCell\n className=\"consumerGroupCell\"\n title={group.groupId}\n style={TOPIC_CONSUMER_NAME_COLUMN_STYLE}\n >\n <Renderer.Component.Icon material=\"group\" />\n <span className=\"KafkaEllipsis\">{group.groupId}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerStateCell\" style={TOPIC_CONSUMER_STATE_COLUMN_STYLE}>\n <TopicConsumerStateBadge state={group.state} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerMembersCell\" style={TOPIC_CONSUMER_MEMBERS_COLUMN_STYLE}>\n {group.memberCount}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerLagCell\" style={TOPIC_CONSUMER_LAG_COLUMN_STYLE}>\n <TopicConsumerLag lag={group.totalLag} />\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"consumerActionCell\" style={TOPIC_CONSUMER_ACTION_COLUMN_STYLE}>\n <Renderer.Component.Icon material=\"chevron_right\" />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n );\n}\n\nfunction TopicConfiguration({\n topic,\n state,\n onRetry,\n}: {\n topic: string;\n state: TopicConfigState;\n onRetry: () => void;\n}) {\n const hasEntries = (state.data?.entries.length ?? 0) > 0;\n\n if (state.loading && !state.data) {\n return <Renderer.Component.Spinner center />;\n }\n\n if (state.error) {\n return (\n <div className=\"KafkaTopicInlineError\" role=\"alert\">\n <span>{state.error}</span>\n <Renderer.Component.Button outlined onClick={onRetry}>\n <Renderer.Component.Icon material=\"refresh\" />\n Retry\n </Renderer.Component.Button>\n </div>\n );\n }\n\n if (!hasEntries) {\n return (\n <div className=\"KafkaTopicPrompt\">\n <Renderer.Component.Icon material=\"tune\" />\n <span>No configuration entries returned for {topic}.</span>\n </div>\n );\n }\n\n return (\n <Renderer.Component.Table<TopicConfigEntryDto>\n className=\"KafkaTopicConfigTable\"\n tableId=\"kafka-topic-configuration\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"name\", orderBy: \"asc\" }}\n sortable={{ name: (entry) => entry.name.toLowerCase() }}\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell className=\"configNameCell\" sortBy=\"name\" style={TOPIC_CONFIG_NAME_COLUMN_STYLE}>\n Name\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configValueCell\" style={TOPIC_CONFIG_VALUE_COLUMN_STYLE}>\n Value\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configSourceCell\" style={TOPIC_CONFIG_SOURCE_COLUMN_STYLE}>\n Source\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configFlagsCell\" style={TOPIC_CONFIG_FLAGS_COLUMN_STYLE}>\n Flags\n </Renderer.Component.TableCell>\n </Renderer.Component.TableHead>\n {state.data?.entries.map((entry) => (\n <Renderer.Component.TableRow key={entry.name} sortItem={entry} nowrap>\n <Renderer.Component.TableCell\n className=\"configNameCell\"\n title={entry.name}\n style={TOPIC_CONFIG_NAME_COLUMN_STYLE}\n >\n <span className=\"KafkaEllipsis\">{entry.name}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell\n className=\"configValueCell\"\n title={entry.value}\n style={TOPIC_CONFIG_VALUE_COLUMN_STYLE}\n >\n <span className=\"KafkaEllipsis KafkaMono\">{entry.value || \"—\"}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configSourceCell\" style={TOPIC_CONFIG_SOURCE_COLUMN_STYLE}>\n <span className=\"KafkaConfigSource\">{entry.source}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"configFlagsCell\" style={TOPIC_CONFIG_FLAGS_COLUMN_STYLE}>\n <div className=\"KafkaConfigFlags\">\n {entry.readOnly ? <Renderer.Component.Badge small label=\"Read-only\" /> : null}\n {entry.sensitive ? <Renderer.Component.Badge small label=\"Sensitive\" /> : null}\n {!entry.readOnly && !entry.sensitive ? <span>—</span> : null}\n </div>\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n ))}\n </Renderer.Component.Table>\n );\n}\n\nexport interface KafkaTopicsPageProps extends KafkaResourcePageDependencies {\n params?: {\n target: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"target\"]>;\n query: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"query\"]>;\n topic: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"topic\"]>;\n view: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"view\"]>;\n keyFilter: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"keyFilter\"]>;\n valueFilter: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"valueFilter\"]>;\n headerKey: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"headerKey\"]>;\n headerValue: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"headerValue\"]>;\n timestamp: Renderer.Navigation.PageParam<KafkaTopicsPageParams[\"timestamp\"]>;\n };\n topic: (request: TopicRequest) => Promise<TopicDetailDto>;\n topicConfig: (request: TopicConfigRequest) => Promise<TopicConfigDto>;\n topicConsumers: (request: TopicConsumersRequest) => Promise<TopicConsumersDto>;\n onOpenGroup: (targetId: string, groupId: string) => void;\n messagesBrowse: (request: MessageBrowseRequest) => Promise<MessageBrowseDto>;\n produce: (request: ProduceRequest) => Promise<ProduceResultDto>;\n schemaRegistrySettings: KafkaSchemaRegistrySettingsStore;\n}\n\nexport function KafkaTopicsPage({\n params,\n topic,\n topicConfig,\n topicConsumers,\n onOpenGroup,\n messagesBrowse,\n produce,\n schemaRegistrySettings,\n ...dependencies\n}: KafkaTopicsPageProps) {\n const state = useKafkaResourcePage({ ...dependencies, params });\n const canWrite = useKafkaWriteMode(dependencies.writeSettings, state.selectedCluster?.targetId);\n const [query, setQuery] = useKafkaPageParam(params?.query);\n const [topicName, setTopicName] = useKafkaPageParam(params?.topic);\n const [rawView, setRawView] = useKafkaPageParam(params?.view);\n const [keyFilter, setKeyFilter] = useKafkaPageParam(params?.keyFilter);\n const [valueFilter, setValueFilter] = useKafkaPageParam(params?.valueFilter);\n const [headerKey, setHeaderKey] = useKafkaPageParam(params?.headerKey);\n const [headerValue, setHeaderValue] = useKafkaPageParam(params?.headerValue);\n const [timestamp, setTimestamp] = useKafkaPageParam(params?.timestamp);\n // \"messages\"/\"partitions\" are only valid inside a topic workspace; fall back to overview otherwise.\n const view = topicName ? implementedKafkaTopicView(rawView) : \"overview\";\n const [topicState, setTopicState] = useState<TopicState>({ loading: false });\n const [topicConfigState, setTopicConfigState] = useState<TopicConfigState>({ loading: false });\n const [topicConsumersState, setTopicConsumersState] = useState<TopicConsumersState>({ loading: false });\n const [produceOpen, setProduceOpen] = useState(false);\n const [produceConfirmed, setProduceConfirmed] = useState(false);\n const [produceKey, setProduceKey] = useState(\"\");\n const [produceValue, setProduceValue] = useState(\"\");\n const [produceHeaders, setProduceHeaders] = useState(\"\");\n const [producePartition, setProducePartition] = useState(\"\");\n const [produceResult, setProduceResult] = useState<ProduceResultDto>();\n const [produceError, setProduceError] = useState<string>();\n const topicOperationId = useRef<string>();\n const topicConfigOperationId = useRef<string>();\n const topicConsumersOperationId = useRef<string>();\n const workspaceTargetId = useRef<string>();\n const [topicPage, setTopicPage] = useState(0);\n\n useEffect(() => setTopicPage(0), [query]);\n\n const clearPageParam = useCallback((param?: Renderer.Navigation.PageParam<string>) => {\n const candidate = param as Renderer.Navigation.PageParam<string> & { clear?: () => void };\n if (typeof candidate?.clear === \"function\") candidate.clear();\n else param?.set(\"\", { replaceHistory: true });\n }, []);\n\n useEffect(() => {\n if (rawView !== view) setRawView(view, true);\n }, [rawView, setRawView, view]);\n\n useEffect(() => {\n if (!topicName || !state.selectedCluster) return;\n const saveRoute = () => {\n saveKafkaReloadRoute({\n pageId: \"kafka-topics\",\n params: {\n target: state.selectedCluster?.targetId ?? \"\",\n topic: topicName,\n view,\n query,\n keyFilter,\n valueFilter,\n headerKey,\n headerValue,\n timestamp,\n },\n });\n };\n saveRoute();\n window.addEventListener(\"beforeunload\", saveRoute);\n window.addEventListener(\"pagehide\", saveRoute);\n return () => {\n window.removeEventListener(\"beforeunload\", saveRoute);\n window.removeEventListener(\"pagehide\", saveRoute);\n };\n }, [headerKey, headerValue, keyFilter, query, state.selectedCluster, timestamp, topicName, valueFilter, view]);\n\n // Switching Kafka cluster from Topic Workspace must clear topic-specific URL state.\n useEffect(() => {\n const selectedTargetId = state.selectedCluster?.targetId;\n\n if (!selectedTargetId) {\n // Keep the previous target during transient reload gaps so cluster-switch reset\n // still triggers when the new target becomes available.\n return;\n }\n\n if (!topicName) {\n workspaceTargetId.current = selectedTargetId;\n return;\n }\n\n const previousTargetId = workspaceTargetId.current;\n workspaceTargetId.current = selectedTargetId;\n\n if (previousTargetId && previousTargetId !== selectedTargetId) {\n clearPageParam(params?.topic);\n clearPageParam(params?.query);\n }\n }, [clearPageParam, params?.query, params?.topic, state.selectedCluster?.targetId, topicName]);\n\n useEffect(\n () =>\n dependencies.subscribeProgress((progress) => {\n if (progress.operation === \"topic\" && progress.operationId === topicOperationId.current) {\n setTopicState((current) => ({ ...current, progress }));\n }\n if (progress.operation === \"topicConfig\" && progress.operationId === topicConfigOperationId.current) {\n setTopicConfigState((current) => ({ ...current, progress }));\n }\n if (progress.operation === \"topicConsumers\" && progress.operationId === topicConsumersOperationId.current) {\n setTopicConsumersState((current) => {\n const partial = progress.topicConsumerGroup;\n if (!partial) return { ...current, progress };\n const groups = current.data?.groups ?? [];\n return {\n ...current,\n data: {\n topic: current.topic ?? topicName,\n groups: [...groups.filter((group) => group.groupId !== partial.groupId), partial].sort((left, right) =>\n left.groupId.localeCompare(right.groupId),\n ),\n },\n progress,\n };\n });\n }\n }),\n [dependencies.subscribeProgress, topicName],\n );\n\n const loadTopic = useCallback(() => {\n const cluster = state.selectedCluster;\n const topics = state.metadataState.data?.topics;\n if (!topicName || !cluster || !topics) {\n topicOperationId.current = undefined;\n setTopicState({ loading: false });\n return;\n }\n if (!topics.includes(topicName)) {\n topicOperationId.current = undefined;\n setTopicState({\n name: topicName,\n loading: false,\n error: `Topic ${topicName} was not found in this Kafka cluster.`,\n });\n return;\n }\n\n const operationId = createOperationId(\"topic\");\n topicOperationId.current = operationId;\n const progress: KafkaProgressEvent = {\n operationId,\n operation: \"topic\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing topic details\",\n detail: \"Selecting the existing read-only connection path.\",\n };\n const cacheKey = dependencies.kubernetesClusterId ?? \"active\";\n const cached = dependencies.resourceCache.readTopic(cacheKey, cluster.targetId, topicName);\n setTopicState({ name: topicName, loading: true, data: cached.data, progress });\n\n dependencies.resourceCache\n .loadTopic(cacheKey, cluster.targetId, topicName, () =>\n topic({\n operationId,\n targetId: cluster.targetId,\n topic: topicName,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: dependencies.connectionSettings.get(dependencies.kubernetesClusterId ?? \"active\", cluster.targetId),\n }),\n )\n .then((data) => {\n if (topicOperationId.current === operationId) {\n setTopicState({ name: topicName, loading: false, data });\n }\n })\n .catch((error: unknown) => {\n if (topicOperationId.current !== operationId) return;\n setTopicState((current) => ({\n name: topicName,\n loading: false,\n data: current.data,\n error: error instanceof Error ? error.message : String(error),\n progress,\n }));\n });\n }, [\n dependencies.connectionSettings,\n dependencies.kubernetesClusterId,\n dependencies.resourceCache,\n state.metadataState.data?.topics,\n state.selectedCluster,\n topic,\n topicName,\n ]);\n\n useEffect(() => {\n loadTopic();\n return () => {\n topicOperationId.current = undefined;\n };\n }, [loadTopic]);\n\n const loadTopicConfig = useCallback(() => {\n const cluster = state.selectedCluster;\n const topics = state.metadataState.data?.topics;\n if (!topicName || !cluster || !topics) {\n topicConfigOperationId.current = undefined;\n setTopicConfigState({ loading: false });\n return;\n }\n if (!topics.includes(topicName)) {\n topicConfigOperationId.current = undefined;\n setTopicConfigState({\n topic: topicName,\n loading: false,\n error: `Topic ${topicName} was not found in this Kafka cluster.`,\n });\n return;\n }\n\n const operationId = createOperationId(\"topicConfig\");\n topicConfigOperationId.current = operationId;\n const progress: KafkaProgressEvent = {\n operationId,\n operation: \"topicConfig\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing topic configuration\",\n detail: \"Selecting the existing read-only connection path.\",\n };\n\n setTopicConfigState({ topic: topicName, loading: true, progress });\n\n topicConfig({\n operationId,\n targetId: cluster.targetId,\n topic: topicName,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: dependencies.connectionSettings.get(dependencies.kubernetesClusterId ?? \"active\", cluster.targetId),\n })\n .then((data) => {\n if (topicConfigOperationId.current === operationId) {\n setTopicConfigState({ topic: topicName, loading: false, data });\n }\n })\n .catch((error: unknown) => {\n if (topicConfigOperationId.current !== operationId) return;\n setTopicConfigState({\n topic: topicName,\n loading: false,\n error: error instanceof Error ? error.message : String(error),\n progress,\n });\n });\n }, [\n dependencies.connectionSettings,\n dependencies.kubernetesClusterId,\n state.metadataState.data?.topics,\n state.selectedCluster,\n topicConfig,\n topicName,\n ]);\n\n useEffect(() => {\n if (view !== \"configuration\") return;\n if (topicConfigState.topic === topicName) return;\n loadTopicConfig();\n }, [loadTopicConfig, topicConfigState.topic, topicName, view]);\n\n const loadTopicConsumers = useCallback(() => {\n const cluster = state.selectedCluster;\n const topics = state.metadataState.data?.topics;\n if (!topicName || !cluster || !topics) {\n topicConsumersOperationId.current = undefined;\n setTopicConsumersState({ loading: false });\n return;\n }\n if (!topics.includes(topicName)) {\n topicConsumersOperationId.current = undefined;\n setTopicConsumersState({\n topic: topicName,\n loading: false,\n error: `Topic ${topicName} was not found in this Kafka cluster.`,\n });\n return;\n }\n\n const operationId = createOperationId(\"topicConsumers\");\n topicConsumersOperationId.current = operationId;\n const progress: KafkaProgressEvent = {\n operationId,\n operation: \"topicConsumers\",\n value: 1,\n phase: \"strategy\",\n label: \"Preparing topic consumers\",\n detail: \"Selecting the existing read-only connection path.\",\n };\n setTopicConsumersState({ topic: topicName, loading: true, progress });\n\n topicConsumers({\n operationId,\n targetId: cluster.targetId,\n topic: topicName,\n namespace: cluster.namespace,\n clusterName: cluster.name,\n source: cluster.source,\n bootstrap: cluster.bootstrap,\n tls: cluster.tls,\n sourceLocator: cluster.sourceLocator,\n security: dependencies.connectionSettings.get(dependencies.kubernetesClusterId ?? \"active\", cluster.targetId),\n })\n .then((data) => {\n if (topicConsumersOperationId.current === operationId) {\n setTopicConsumersState({ topic: topicName, loading: false, data });\n }\n })\n .catch((error: unknown) => {\n if (topicConsumersOperationId.current !== operationId) return;\n setTopicConsumersState({\n topic: topicName,\n loading: false,\n error: error instanceof Error ? error.message : String(error),\n progress,\n });\n });\n }, [\n dependencies.connectionSettings,\n dependencies.kubernetesClusterId,\n state.metadataState.data?.topics,\n state.selectedCluster,\n topicConsumers,\n topicName,\n ]);\n\n useEffect(() => {\n if (view !== \"consumers\") return;\n if (topicConsumersState.topic === topicName) return;\n loadTopicConsumers();\n }, [loadTopicConsumers, topicConsumersState.topic, topicName, view]);\n\n useEffect(\n () => () => {\n topicConfigOperationId.current = undefined;\n topicConsumersOperationId.current = undefined;\n },\n [],\n );\n\n const selectWorkspaceCluster = (targetId: string): void => {\n const cluster = state.clusters.find((candidate) => candidate.targetId === targetId);\n if (!cluster) return;\n if (dependencies.kubernetesClusterId) {\n rememberKafkaClusterSelection(kafkaPersistentStateStore(), dependencies.kubernetesClusterId, cluster);\n }\n clearPageParam(params?.topic);\n clearPageParam(params?.query);\n state.selectCluster(targetId);\n };\n\n const resetProduceDraft = useCallback(() => {\n setProduceConfirmed(false);\n setProduceKey(\"\");\n setProduceValue(\"\");\n setProduceHeaders(\"\");\n setProducePartition(\"\");\n setProduceResult(undefined);\n setProduceError(undefined);\n }, []);\n\n if (topicName) {\n return (\n <KafkaPageShell\n title={topicName}\n subtitle={state.selectedCluster ? `Topics / ${state.selectedCluster.name}` : \"Topic Workspace\"}\n actions={\n <>\n <Renderer.Component.Button\n outlined\n onClick={() => {\n setRawView(\"overview\", true);\n setTopicName(\"\");\n }}\n >\n <Renderer.Component.Icon material=\"arrow_back\" />\n Topics\n </Renderer.Component.Button>\n {canWrite && (\n <Renderer.Component.Button\n outlined\n data-testid=\"kafka-produce-message-button\"\n onClick={() => {\n resetProduceDraft();\n setProduceOpen(true);\n }}\n >\n <Renderer.Component.Icon material=\"edit\" />\n Produce message\n </Renderer.Component.Button>\n )}\n <KafkaResourceActions state={state} onSelectCluster={selectWorkspaceCluster} />\n </>\n }\n >\n <KafkaResourceState state={state} />\n {state.selectedCluster && state.metadataState.data && (\n <main className=\"KafkaResourcePage KafkaTopicWorkspace\" data-testid=\"kafka-topic-workspace\">\n {produceOpen && (\n <section\n className=\"KafkaWriteDrawer\"\n data-testid=\"kafka-produce-message-drawer\"\n aria-label=\"Produce message confirmation\"\n >\n <div className=\"KafkaPageState warning\">\n <Renderer.Component.Icon material=\"edit\" />\n <div>\n <strong>Produce message</strong>\n <span>Write operations must be confirmed before any Kafka call is made.</span>\n </div>\n {produceResult && (\n <div role=\"status\">\n Sent to partition {produceResult.partition} at offset {produceResult.offset}\n </div>\n )}\n {produceError && <div role=\"alert\">{produceError}</div>}\n </div>\n <div className=\"KafkaWriteForm\" style={{ display: \"grid\", gap: 12 }}>\n <Renderer.Component.Input\n value={produceKey}\n onChange={setProduceKey}\n placeholder=\"Key (optional)\"\n aria-label=\"Message key\"\n />\n <Renderer.Component.Input\n value={produceValue}\n onChange={setProduceValue}\n placeholder=\"Value\"\n aria-label=\"Message value\"\n />\n <Renderer.Component.Input\n value={produceHeaders}\n onChange={setProduceHeaders}\n placeholder=\"Headers (key=value, one per line)\"\n aria-label=\"Message headers\"\n />\n <Renderer.Component.Input\n value={producePartition}\n onChange={setProducePartition}\n placeholder=\"Partition (optional)\"\n aria-label=\"Message partition\"\n />\n <div className=\"KafkaWriteSummary\">\n <strong>Target</strong>\n <span>{state.selectedCluster.name}</span>\n <strong>Topic</strong>\n <span>{topicName}</span>\n </div>\n <label style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <span>{getWriteConfirmationLabel({ destructive: false, resourceName: topicName })}</span>\n <Renderer.Component.Switch\n aria-label=\"Confirm produce message\"\n data-testid=\"kafka-produce-confirmation-switch\"\n checked={produceConfirmed}\n onChange={setProduceConfirmed}\n />\n </label>\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\" }}>\n <Renderer.Component.Button outlined onClick={() => setProduceOpen(false)}>\n Cancel\n </Renderer.Component.Button>\n <Renderer.Component.Button\n primary\n disabled={\n !canSubmitWriteAction({\n confirmationAccepted: produceConfirmed,\n requiredResourceName: undefined,\n })\n }\n onClick={() => {\n if (\n !canSubmitWriteAction({\n confirmationAccepted: produceConfirmed,\n requiredResourceName: undefined,\n })\n ) {\n return;\n }\n if (!state.selectedCluster || !topicName) return;\n setProduceError(undefined);\n void produce({\n targetId: state.selectedCluster.targetId,\n source: state.selectedCluster.source,\n bootstrap: state.selectedCluster.bootstrap,\n tls: state.selectedCluster.tls,\n namespace: state.selectedCluster.namespace,\n clusterName: state.selectedCluster.name,\n topic: topicName,\n key: produceKey || undefined,\n value: produceValue,\n headers: Object.fromEntries(\n produceHeaders\n .split(\"\\n\")\n .map((line) => line.split(\"=\", 2))\n .filter(([key, value]) => key && value),\n ),\n partition: producePartition ? Number(producePartition) : undefined,\n })\n .then((result) => setProduceResult(result))\n .catch((error: unknown) =>\n setProduceError(error instanceof Error ? error.message : String(error)),\n );\n }}\n >\n Send message\n </Renderer.Component.Button>\n </div>\n </div>\n </section>\n )}\n <nav className=\"KafkaEntityTabs\" role=\"tablist\" aria-label=\"Topic sections\">\n {([\"overview\", \"messages\", \"partitions\", \"consumers\", \"configuration\"] as const).map((tab) => (\n <Renderer.Component.Button\n key={tab}\n plain\n role=\"tab\"\n active={view === tab}\n aria-selected={view === tab}\n onClick={() => setRawView(tab)}\n >\n {tab === \"overview\"\n ? \"Overview\"\n : tab === \"messages\"\n ? \"Messages\"\n : tab === \"partitions\"\n ? \"Partitions\"\n : tab === \"consumers\"\n ? \"Consumers\"\n : \"Configuration\"}\n </Renderer.Component.Button>\n ))}\n </nav>\n {view === \"messages\" ? (\n <KafkaMessagesBrowser\n cluster={state.selectedCluster}\n topic={topicName}\n partitions={topicState.data?.partitions ?? []}\n metadataLoading={topicState.loading}\n metadataError={topicState.error}\n metadataProgress={topicState.progress}\n security={dependencies.connectionSettings.get(\n dependencies.kubernetesClusterId ?? \"active\",\n state.selectedCluster.targetId,\n )}\n schemaRegistry={\n state.selectedCluster\n ? (() => {\n const configured = schemaRegistrySettings.get(state.selectedCluster.targetId);\n return configured\n ? { registryUrl: configured.registryUrl, username: configured.username }\n : undefined;\n })()\n : undefined\n }\n browse={messagesBrowse}\n subscribeProgress={dependencies.subscribeProgress}\n onRetryMetadata={loadTopic}\n filters={{ key: keyFilter, value: valueFilter, headerKey, headerValue }}\n timestamp={timestamp}\n onTimestampChange={(value) => setTimestamp(value, true)}\n onFilterChange={(name, value) => {\n const setters = {\n key: setKeyFilter,\n value: setValueFilter,\n headerKey: setHeaderKey,\n headerValue: setHeaderValue,\n };\n setters[name](value, true);\n }}\n />\n ) : view === \"configuration\" ? (\n <TopicConfiguration topic={topicName} state={topicConfigState} onRetry={loadTopicConfig} />\n ) : view === \"consumers\" ? (\n <TopicConsumers\n state={topicConsumersState}\n onRetry={loadTopicConsumers}\n onOpenGroup={(groupId) => onOpenGroup(state.selectedCluster?.targetId ?? \"\", groupId)}\n />\n ) : (\n <TopicMetadata\n state={topicState}\n onRetry={loadTopic}\n view={view === \"partitions\" ? \"partitions\" : \"overview\"}\n showHeader={false}\n />\n )}\n </main>\n )}\n </KafkaPageShell>\n );\n }\n\n const allTopics = state.metadataState.data?.topics ?? [];\n const filteredTopics = filterTopicNames(allTopics, query);\n const topicWindow = kafkaListWindow(filteredTopics, topicPage);\n const internalCount = allTopics.filter((name) => name.startsWith(\"__\")).length;\n\n return (\n <KafkaPageShell\n title=\"Topics\"\n subtitle={state.selectedCluster ? state.selectedCluster.name : \"Browse topics in a Kafka cluster\"}\n actions={<KafkaResourceActions state={state} />}\n >\n <KafkaResourceState state={state} />\n {state.selectedCluster && state.metadataState.data && (\n <main className=\"KafkaResourcePage KafkaTopicsPage\" data-testid=\"kafka-topics-page\">\n <KafkaMetricStrip\n ariaLabel=\"Kafka topic summary\"\n className=\"KafkaResourceMetricStrip\"\n metrics={[\n { label: \"Topics\", value: allTopics.length },\n { label: \"Application\", value: allTopics.length - internalCount },\n { label: \"Internal\", value: internalCount },\n ]}\n />\n {allTopics.length === 0 ? (\n <div className=\"KafkaPageState empty\">\n <Renderer.Component.Icon material=\"topic\" />\n <div>\n <strong>No topics returned</strong>\n <span>Kafka returned an empty topic list.</span>\n </div>\n </div>\n ) : (\n <>\n <Renderer.Component.Input\n className=\"KafkaTopicSearch\"\n value={query}\n onChange={(nextQuery) => setQuery(nextQuery, true)}\n iconLeft=\"search\"\n placeholder=\"Filter topics\"\n aria-label=\"Filter Kafka topics\"\n />\n <Renderer.Component.Table<string>\n className=\"KafkaTopicTable KafkaTopicPageTable\"\n tableId=\"kafka-topics-page\"\n autoSize={false}\n scrollable\n sortSyncWithUrl={false}\n sortByDefault={{ sortBy: \"name\", orderBy: \"asc\" }}\n sortable={{ name: (name) => name.toLowerCase() }}\n noItems={\n <div className=\"KafkaTopicPrompt\">\n <Renderer.Component.Icon material=\"filter_alt_off\" />\n <span>No topics match the current filter.</span>\n </div>\n }\n >\n <Renderer.Component.TableHead sticky={false} nowrap>\n <Renderer.Component.TableCell className=\"topicNameCell\" sortBy=\"name\" style={TOPIC_NAME_COLUMN_STYLE}>\n Topic\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"topicTypeCell\" style={TOPIC_TYPE_COLUMN_STYLE}>\n Type\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"topicActionCell\" style={TOPIC_ACTION_COLUMN_STYLE} />\n </Renderer.Component.TableHead>\n {topicWindow.items.map((name) => {\n const open = (event: { stopPropagation: () => void }): void => {\n event.stopPropagation();\n setRawView(\"overview\", true);\n setTopicName(name);\n };\n const interaction: HTMLAttributes<HTMLDivElement> = {\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": `Open topic ${name}`,\n onClick: open,\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n open(event);\n }\n },\n };\n return (\n <Renderer.Component.TableRow\n {...interaction}\n className=\"KafkaInteractiveRow\"\n key={name}\n sortItem={name}\n data-topic={name}\n nowrap\n >\n <Renderer.Component.TableCell\n className=\"topicNameCell\"\n title={name}\n style={TOPIC_NAME_COLUMN_STYLE}\n >\n <Renderer.Component.Icon material=\"topic\" />\n <span className=\"KafkaEllipsis\">{name}</span>\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"topicTypeCell\" style={TOPIC_TYPE_COLUMN_STYLE}>\n {name.startsWith(\"__\") ? (\n <Renderer.Component.Badge small className=\"KafkaInternalTopicBadge\" label=\"Internal\" />\n ) : (\n <span className=\"KafkaTopicType\">Application</span>\n )}\n </Renderer.Component.TableCell>\n <Renderer.Component.TableCell className=\"topicActionCell\" style={TOPIC_ACTION_COLUMN_STYLE}>\n <Renderer.Component.Icon material=\"chevron_right\" />\n </Renderer.Component.TableCell>\n </Renderer.Component.TableRow>\n );\n })}\n </Renderer.Component.Table>\n {topicWindow.pageCount > 1 && (\n <div className=\"KafkaListPagination\" aria-label=\"Topic pages\">\n <Renderer.Component.Button\n outlined\n disabled={topicWindow.page === 0}\n onClick={() => setTopicPage((page) => Math.max(0, page - 1))}\n aria-label=\"Previous topic page\"\n >\n Previous\n </Renderer.Component.Button>\n <span>\n Page {topicWindow.page + 1} of {topicWindow.pageCount} ({topicWindow.total} topics)\n </span>\n <Renderer.Component.Button\n outlined\n disabled={topicWindow.page >= topicWindow.pageCount - 1}\n onClick={() => setTopicPage((page) => Math.min(topicWindow.pageCount - 1, page + 1))}\n aria-label=\"Next topic page\"\n >\n Next\n </Renderer.Component.Button>\n </div>\n )}\n </>\n )}\n </main>\n )}\n </KafkaPageShell>\n );\n}\n","import { Renderer } from \"@freelensapp/extensions\";\nimport { computed } from \"mobx\";\nimport { kafkaPersistentStateStore } from \"../common/kafka-persistent-state-store\";\nimport { KafkaIcon } from \"./icon\";\nimport { KafkaAclAvailabilityStore } from \"./kafka-acl-availability\";\nimport { KafkaAclPage, type KafkaAclPageProps } from \"./kafka-acl-pages\";\nimport { KAFKA_CLUSTER_CATALOG_KEY } from \"./kafka-cluster-catalog\";\nimport { KafkaConnectPage, type KafkaConnectPageProps } from \"./kafka-connect-pages\";\nimport { KafkaConnectSettingsStore } from \"./kafka-connect-settings\";\nimport { KafkaConnectionSettingsStore } from \"./kafka-connection-settings\";\nimport { KafkaGroupsPage, type KafkaGroupsPageProps } from \"./kafka-group-pages\";\nimport { KafkaIpcRenderer } from \"./kafka-ipc\";\nimport { MANUAL_ENDPOINTS_KEY } from \"./kafka-manual-endpoints\";\nimport { KAFKA_PAGE_IDS, KAFKA_SELECTIONS_KEY, type KafkaReloadRoute } from \"./kafka-navigation\";\nimport { KafkaOverviewSettingsStore } from \"./kafka-overview-settings\";\nimport {\n KAFKA_CLUSTER_MENU_MANIFEST,\n KAFKA_CLUSTER_PAGE_MANIFEST,\n KAFKA_ROUTE_OWNER_MENU_MANIFEST,\n} from \"./kafka-page-manifest\";\nimport { KafkaClustersPage, type KafkaClustersPageProps } from \"./kafka-pages\";\nimport { KafkaReloadRouteRestorer } from \"./kafka-reload-route-restorer\";\nimport { KafkaResourceCache } from \"./kafka-resource-cache\";\nimport {\n KafkaBrokersPage,\n type KafkaBrokersPageProps,\n KafkaClusterOverviewPage,\n type KafkaTargetPageProps,\n} from \"./kafka-resource-pages\";\nimport { KafkaSchemaRegistryPage, type KafkaSchemaRegistryPageProps } from \"./kafka-schema-registry-pages\";\nimport { KafkaSchemaRegistrySettingsStore } from \"./kafka-schema-registry-settings\";\nimport { KafkaTopicsPage, type KafkaTopicsPageProps } from \"./kafka-topic-pages\";\nimport { createOperationId } from \"./kafka-view-model\";\nimport { KafkaWriteSettingsStore } from \"./kafka-write-settings\";\n\nimport type {\n AclsRequest,\n BrokerConfigRequest,\n ClusterHealthRequest,\n DiscoverRequest,\n GroupDetailRequest,\n GroupsRequest,\n KafkaConnectDetailRequest,\n KafkaConnectRequest,\n KafkaProgressEvent,\n MessageBrowseRequest,\n OverviewRequest,\n ProduceRequest,\n ResetOffsetsRequest,\n SchemaDeleteSubjectRequest,\n SchemaRegisterRequest,\n SchemaSubjectDetailRequest,\n SchemaSubjectNamesRequest,\n TopicConfigRequest,\n TopicConsumersRequest,\n TopicRequest,\n} from \"../common/ipc\";\n\nexport default class KafkaExtensionRenderer extends Renderer.LensExtension {\n private readonly connectionSettings = new KafkaConnectionSettingsStore();\n private readonly writeSettings = new KafkaWriteSettingsStore();\n private readonly schemaRegistrySettings = new KafkaSchemaRegistrySettingsStore();\n private readonly connectSettings = new KafkaConnectSettingsStore();\n private readonly overviewSettings = new KafkaOverviewSettingsStore();\n private readonly aclAvailability = new KafkaAclAvailabilityStore();\n private readonly hiddenMenu = computed(() => false);\n private readonly alwaysVisible = computed(() => true);\n private readonly schemaRegistryVisible = computed(() => this.schemaRegistrySettings.hasAny());\n private readonly connectVisible = computed(() => this.connectSettings.hasAny());\n private readonly aclsVisible = computed(() => this.aclAvailability.hasAny());\n private readonly resourceCache = new KafkaResourceCache();\n\n async onActivate(): Promise<void> {\n const stateStore = kafkaPersistentStateStore();\n stateStore.loadExtension(this);\n stateStore.migrateLegacy(window.localStorage, [\n KAFKA_CLUSTER_CATALOG_KEY,\n MANUAL_ENDPOINTS_KEY,\n KAFKA_SELECTIONS_KEY,\n ]);\n }\n\n private get client(): KafkaIpcRenderer {\n return KafkaIpcRenderer.createInstance(this);\n }\n\n /** Id of the cluster this frame is showing, so Main queries the right connected cluster. */\n private get clusterId(): string | undefined {\n return Renderer.Catalog.getActiveCluster()?.id;\n }\n\n private readonly discover = (request: DiscoverRequest = {}) => {\n const cachedRequest = { clusterId: this.clusterId, ...request };\n const kubernetesClusterId = cachedRequest.clusterId ?? \"active\";\n const operationId = cachedRequest.operationId ?? createOperationId(\"discovery\");\n return this.resourceCache.loadDiscovery(kubernetesClusterId, operationId, () =>\n this.client.discover({ ...cachedRequest, operationId }),\n );\n };\n private readonly overview = (request: OverviewRequest) => {\n const cachedRequest = { clusterId: this.clusterId, ...request };\n const kubernetesClusterId = cachedRequest.clusterId ?? \"active\";\n const targetId = cachedRequest.targetId ?? cachedRequest.bootstrap ?? cachedRequest.clusterName;\n const operationId = cachedRequest.operationId ?? createOperationId(\"overview\");\n return this.resourceCache\n .loadOverview(kubernetesClusterId, targetId, operationId, () =>\n this.client.overview({ ...cachedRequest, operationId, targetId }),\n )\n .then((data) => {\n if (targetId) this.aclAvailability.set(targetId, data.aclsAvailable === true);\n return data;\n });\n };\n private readonly health = (request: ClusterHealthRequest) => {\n const cachedRequest = { clusterId: this.clusterId, ...request };\n const kubernetesClusterId = cachedRequest.clusterId ?? \"active\";\n const targetId = cachedRequest.targetId ?? cachedRequest.bootstrap ?? cachedRequest.clusterName;\n const operationId = cachedRequest.operationId ?? createOperationId(\"health\");\n return this.resourceCache.loadHealth(kubernetesClusterId, targetId, operationId, () =>\n this.client.health({ ...cachedRequest, operationId, targetId }),\n );\n };\n private readonly invalidateHealth = (\n targetId: string,\n options: { closeSessions?: boolean; removePersisted?: boolean },\n ) => this.client.invalidateHealth({ clusterId: this.clusterId, targetId, ...options });\n private readonly topic = (request: TopicRequest) => this.client.topic({ clusterId: this.clusterId, ...request });\n private readonly topicConfig = (request: TopicConfigRequest) =>\n this.client.topicConfig({ clusterId: this.clusterId, ...request });\n private readonly topicConsumers = (request: TopicConsumersRequest) =>\n this.client.topicConsumers({ clusterId: this.clusterId, ...request });\n private readonly brokerConfig = (request: BrokerConfigRequest) =>\n this.client.brokerConfig({ clusterId: this.clusterId, ...request });\n private readonly messagesBrowse = (request: MessageBrowseRequest) =>\n this.client.messagesBrowse({ clusterId: this.clusterId, ...request });\n private readonly groups = (request: GroupsRequest) => this.client.groups({ clusterId: this.clusterId, ...request });\n private readonly groupDetail = (request: GroupDetailRequest) =>\n this.client.groupDetail({ clusterId: this.clusterId, ...request });\n private readonly produce = (request: ProduceRequest) =>\n this.client.produce({ clusterId: this.clusterId, ...request });\n private readonly resetOffsets = (request: ResetOffsetsRequest) =>\n this.client.resetOffsets({ clusterId: this.clusterId, ...request });\n private readonly schemaSubjectNames = (request: SchemaSubjectNamesRequest) => this.client.schemaSubjectNames(request);\n private readonly schemaSubjectDetail = (request: SchemaSubjectDetailRequest) =>\n this.client.schemaSubjectDetail(request);\n private readonly schemaRegister = (request: SchemaRegisterRequest) => this.client.schemaRegister(request);\n private readonly schemaDeleteSubject = (request: SchemaDeleteSubjectRequest) =>\n this.client.schemaDeleteSubject(request);\n private readonly connectNames = (request: KafkaConnectRequest) => this.client.connectNames(request);\n private readonly connectDetail = (request: KafkaConnectDetailRequest) => this.client.connectDetail(request);\n private readonly acls = (request: AclsRequest) => this.client.acls({ clusterId: this.clusterId, ...request });\n private readonly reachability = (bootstraps: string[]) =>\n this.resourceCache.loadReachability(this.clusterId ?? \"active\", bootstraps, (missingBootstraps) =>\n this.client.reachability(missingBootstraps),\n );\n private readonly subscribeProgress = (listener: (progress: KafkaProgressEvent) => void) =>\n this.client.onProgress(listener);\n private readonly restoreReloadRoute = (route: KafkaReloadRoute) => {\n void this.navigate(route.pageId, route.params);\n };\n\n clusterFrameComponents = [\n {\n id: \"kafka-reload-route-restorer\",\n Component: () => <KafkaReloadRouteRestorer onRestoreRoute={this.restoreReloadRoute} />,\n shouldRender: this.alwaysVisible,\n },\n ];\n\n clusterPages = [\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[0],\n components: {\n Page: ({ params }: Pick<KafkaClustersPageProps, \"params\">) => (\n <KafkaClustersPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n schemaRegistrySettings={this.schemaRegistrySettings}\n connectSettings={this.connectSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n onOpenCluster={(cluster) => {\n void this.navigate(KAFKA_PAGE_IDS.overview, { target: cluster.targetId });\n }}\n discover={this.discover}\n overview={this.overview}\n invalidateHealth={this.invalidateHealth}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[1],\n components: {\n Page: ({ params }: Pick<KafkaTargetPageProps, \"params\">) => (\n <KafkaClusterOverviewPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n overviewSettings={this.overviewSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n health={this.health}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[2],\n components: {\n Page: ({ params }: Pick<KafkaTopicsPageProps, \"params\">) => (\n <KafkaTopicsPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n topic={this.topic}\n topicConfig={this.topicConfig}\n topicConsumers={this.topicConsumers}\n onOpenGroup={(targetId, groupId) => {\n void this.navigate(KAFKA_PAGE_IDS.groups, { target: targetId, group: groupId, view: \"offsets\" });\n }}\n messagesBrowse={this.messagesBrowse}\n produce={this.produce}\n schemaRegistrySettings={this.schemaRegistrySettings}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[3],\n components: {\n Page: ({ params }: Pick<KafkaGroupsPageProps, \"params\">) => (\n <KafkaGroupsPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n groups={this.groups}\n groupDetail={this.groupDetail}\n resetOffsets={this.resetOffsets}\n onOpenTopic={(targetId, topic) => {\n void this.navigate(KAFKA_PAGE_IDS.topics, { target: targetId, topic, view: \"overview\" });\n }}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[4],\n components: {\n Page: ({ params }: Pick<KafkaBrokersPageProps, \"params\">) => (\n <KafkaBrokersPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n brokerConfig={this.brokerConfig}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[5],\n components: {\n Page: ({ params }: Pick<KafkaSchemaRegistryPageProps, \"params\">) => (\n <KafkaSchemaRegistryPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n schemaRegistrySettings={this.schemaRegistrySettings}\n schemaSubjectNames={this.schemaSubjectNames}\n schemaSubjectDetail={this.schemaSubjectDetail}\n schemaRegister={this.schemaRegister}\n schemaDeleteSubject={this.schemaDeleteSubject}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[6],\n components: {\n Page: ({ params }: Pick<KafkaConnectPageProps, \"params\">) => (\n <KafkaConnectPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n connectSettings={this.connectSettings}\n connectNames={this.connectNames}\n connectDetail={this.connectDetail}\n connectPause={(request) => this.client.connectPause(request)}\n connectResume={(request) => this.client.connectResume(request)}\n connectDelete={(request) => this.client.connectDelete(request)}\n connectRestart={(request) => this.client.connectRestart(request)}\n connectUpdate={(request) => this.client.connectUpdate(request)}\n connectCreate={(request) => this.client.connectCreate(request)}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n {\n ...KAFKA_CLUSTER_PAGE_MANIFEST[7],\n components: {\n Page: ({ params }: Pick<KafkaAclPageProps, \"params\">) => (\n <KafkaAclPage\n params={params}\n connectionSettings={this.connectionSettings}\n writeSettings={this.writeSettings}\n kubernetesClusterId={this.clusterId}\n resourceCache={this.resourceCache}\n discover={this.discover}\n overview={this.overview}\n acls={this.acls}\n aclCreate={(request) => this.client.aclCreate({ clusterId: this.clusterId, ...request })}\n aclDelete={(request) => this.client.aclDelete({ clusterId: this.clusterId, ...request })}\n reachability={this.reachability}\n subscribeProgress={this.subscribeProgress}\n />\n ),\n },\n },\n ];\n\n clusterPageMenus = [\n ...KAFKA_ROUTE_OWNER_MENU_MANIFEST.map(({ pageId, ...menu }) => ({\n ...menu,\n title: \"\",\n target: { pageId },\n components: {},\n visible: this.hiddenMenu,\n })),\n ...KAFKA_CLUSTER_MENU_MANIFEST.map(({ pageId, ...menu }, index) => ({\n ...menu,\n target: { pageId },\n components: index === 0 ? { Icon: KafkaIcon } : {},\n visible:\n pageId === KAFKA_PAGE_IDS.connect\n ? this.connectVisible\n : pageId === KAFKA_PAGE_IDS.schemas\n ? this.schemaRegistryVisible\n : pageId === KAFKA_PAGE_IDS.acls\n ? this.aclsVisible\n : undefined,\n })),\n ];\n\n openClusters = () => this.navigate(KAFKA_PAGE_IDS.clusters);\n}\n"],"mappings":"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"}