@skyhook-io/k8s-ui 1.17.0 → 1.18.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.
- package/README.md +41 -0
- package/package.json +6 -6
- package/src/components/charts/AreaChart.interaction.test.tsx +118 -0
- package/src/components/charts/AreaChart.test.tsx +25 -0
- package/src/components/charts/AreaChart.tsx +141 -12
- package/src/components/charts/index.ts +1 -0
- package/src/components/checks/ChecksView.tsx +18 -1
- package/src/components/cnpg/CNPGBackupSummary.tsx +57 -9
- package/src/components/cnpg/CNPGClusterHASection.test.tsx +90 -0
- package/src/components/cnpg/CNPGClusterHASection.tsx +331 -0
- package/src/components/cnpg/CNPGClusterSummary.test.tsx +275 -0
- package/src/components/cnpg/CNPGClusterSummary.tsx +310 -96
- package/src/components/cnpg/CNPGConnectSection.test.tsx +64 -0
- package/src/components/cnpg/CNPGConnectSection.tsx +178 -0
- package/src/components/cnpg/CNPGDeclarativeSummary.tsx +157 -26
- package/src/components/cnpg/CNPGImageCatalogSummary.tsx +7 -4
- package/src/components/cnpg/CNPGLogicalPath.test.tsx +22 -0
- package/src/components/cnpg/CNPGLogicalPath.tsx +150 -0
- package/src/components/cnpg/CNPGObjectStoreSummary.tsx +9 -6
- package/src/components/cnpg/CNPGObjectSummary.test.tsx +193 -2
- package/src/components/cnpg/CNPGPoolerScheduling.test.tsx +36 -0
- package/src/components/cnpg/CNPGPoolerSummary.tsx +241 -14
- package/src/components/cnpg/CNPGSharedSummary.tsx +15 -8
- package/src/components/cnpg/CNPGWALArchivingFact.test.tsx +39 -0
- package/src/components/cnpg/backupRuns.test.ts +17 -0
- package/src/components/cnpg/backupRuns.ts +19 -0
- package/src/components/cnpg/connect.test.ts +124 -0
- package/src/components/cnpg/connect.ts +155 -0
- package/src/components/cnpg/databaseRole.test.ts +38 -0
- package/src/components/cnpg/databaseRole.ts +80 -0
- package/src/components/cnpg/ha.test.ts +446 -0
- package/src/components/cnpg/ha.ts +621 -0
- package/src/components/cnpg/index.ts +18 -0
- package/src/components/cnpg/logicalReplication.test.ts +121 -0
- package/src/components/cnpg/logicalReplication.ts +252 -0
- package/src/components/cnpg/pooler.test.ts +84 -0
- package/src/components/cnpg/pooler.ts +225 -0
- package/src/components/cnpg/primitives.tsx +21 -117
- package/src/components/cnpg/problems.ts +12 -0
- package/src/components/cnpg/relations.test.ts +63 -13
- package/src/components/cnpg/relations.ts +61 -52
- package/src/components/cnpg/schedule.ts +35 -0
- package/src/components/cnpg/workspace-disk.test.ts +97 -0
- package/src/components/cnpg/workspace-fleet-metrics.test.ts +250 -0
- package/src/components/cnpg/workspace-problems.test.ts +175 -0
- package/src/components/cnpg/workspace.test.ts +380 -9
- package/src/components/cnpg/workspace.ts +1137 -136
- package/src/components/dock/DockContext.test.tsx +32 -0
- package/src/components/dock/DockContext.tsx +18 -4
- package/src/components/dock/LocalTerminalTab.test.tsx +40 -0
- package/src/components/dock/LocalTerminalTab.tsx +4 -3
- package/src/components/dock/TerminalTab.tsx +20 -8
- package/src/components/facts/certainty.tsx +36 -0
- package/src/components/facts/facts.test.tsx +24 -0
- package/src/components/facts/facts.tsx +62 -0
- package/src/components/facts/index.ts +6 -0
- package/src/components/facts/managed-by.test.tsx +17 -0
- package/src/components/facts/managed-by.tsx +36 -0
- package/src/components/facts/public-exports.test.tsx +35 -0
- package/src/components/gitops/GitOpsGraphFilterRail.tsx +7 -3
- package/src/components/gitops/GitOpsHealthSourceNotice.test.tsx +38 -0
- package/src/components/gitops/GitOpsHealthSourceNotice.tsx +13 -3
- package/src/components/gitops/insights/ArgoResourceDiff.test.tsx +142 -0
- package/src/components/gitops/insights/ArgoResourceDiff.tsx +22 -5
- package/src/components/gitops/insights/DriftPanel.tsx +62 -0
- package/src/components/gitops/insights/GitOpsInsightViews.tsx +40 -81
- package/src/components/gitops/insights/insights-helpers.test.ts +18 -0
- package/src/components/gitops/insights/insights-helpers.ts +7 -0
- package/src/components/gitops/tree/GitOpsTreeGraph.test.ts +91 -2
- package/src/components/gitops/tree/GitOpsTreeGraph.tsx +76 -76
- package/src/components/gitops/tree/layout.test.ts +111 -0
- package/src/components/gitops/tree/layout.ts +128 -0
- package/src/components/gitops/tree/tree-helpers.test.ts +23 -0
- package/src/components/gitops/tree/tree-helpers.ts +12 -2
- package/src/components/issues/ConditionalCleanup.test.tsx +82 -0
- package/src/components/issues/IssuesView.tsx +44 -6
- package/src/components/issues/ResourceIssuesSection.test.tsx +28 -0
- package/src/components/issues/ResourceIssuesSection.tsx +8 -2
- package/src/components/issues/diagnostic.ts +2 -0
- package/src/components/issues/index.ts +3 -1
- package/src/components/issues/issue-timing.ts +12 -1
- package/src/components/issues/issues.test.ts +75 -1
- package/src/components/issues/severity.ts +30 -2
- package/src/components/issues/types.ts +55 -4
- package/src/components/logs/LogCore.theme.test.tsx +206 -3
- package/src/components/logs/LogCore.tsx +180 -53
- package/src/components/logs/LogToolbarSelects.tsx +3 -1
- package/src/components/logs/LogsViewer.test.tsx +369 -0
- package/src/components/logs/LogsViewer.tsx +91 -13
- package/src/components/logs/StructuredLogLine.test.tsx +76 -0
- package/src/components/logs/StructuredLogLine.tsx +23 -31
- package/src/components/logs/WorkloadLogsViewer.test.tsx +65 -0
- package/src/components/logs/WorkloadLogsViewer.tsx +46 -11
- package/src/components/logs/useLogBuffer.reading.test.tsx +149 -0
- package/src/components/logs/useLogBuffer.test.ts +8 -0
- package/src/components/logs/useLogBuffer.ts +48 -18
- package/src/components/logs/useLogSearch.ts +3 -1
- package/src/components/logs/useLogStream.ts +17 -1
- package/src/components/problems/index.ts +1 -0
- package/src/components/problems/problems.test.tsx +63 -0
- package/src/components/problems/problems.tsx +165 -0
- package/src/components/resources/ActiveFilterBar.test.tsx +78 -0
- package/src/components/resources/ActiveFilterBar.tsx +86 -0
- package/src/components/resources/ColumnPickerList.test.tsx +46 -0
- package/src/components/resources/ColumnPickerList.tsx +174 -0
- package/src/components/resources/ResourcesSidebar.keyboard.test.tsx +42 -0
- package/src/components/resources/ResourcesSidebar.test.tsx +36 -2
- package/src/components/resources/ResourcesSidebar.tsx +92 -41
- package/src/components/resources/ResourcesView.kind-filter-memory.test.ts +52 -0
- package/src/components/resources/ResourcesView.kind-view.test.tsx +296 -0
- package/src/components/resources/ResourcesView.per-container.test.ts +56 -1
- package/src/components/resources/ResourcesView.tsx +392 -181
- package/src/components/resources/column-order.test.ts +104 -0
- package/src/components/resources/column-order.ts +64 -0
- package/src/components/resources/curated-column-ownership.test.ts +3 -3
- package/src/components/resources/renderers/ArgoApplicationRenderer.test.tsx +15 -0
- package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +4 -1
- package/src/components/resources/renderers/AutoscalingReferences.test.tsx +286 -0
- package/src/components/resources/renderers/CAPIClusterRenderer.tsx +3 -2
- package/src/components/resources/renderers/CAPIExactReferenceNavigation.test.tsx +27 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.test.tsx +23 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.tsx +8 -19
- package/src/components/resources/renderers/CNPGClusterRenderer.tsx +5 -7
- package/src/components/resources/renderers/CNPGDeclarativeRenderer.tsx +25 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.test.tsx +32 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +7 -15
- package/src/components/resources/renderers/CompositeRenderer.navigation.test.tsx +35 -0
- package/src/components/resources/renderers/CompositeRenderer.tsx +3 -3
- package/src/components/resources/renderers/CompositionRenderer.tsx +3 -3
- package/src/components/resources/renderers/ContourExactReferenceNavigation.test.tsx +34 -0
- package/src/components/resources/renderers/ContourHTTPProxyRenderer.tsx +11 -10
- package/src/components/resources/renderers/CronJobRenderer.test.tsx +31 -0
- package/src/components/resources/renderers/CronJobRenderer.tsx +28 -20
- package/src/components/resources/renderers/EndpointSliceRenderer.test.tsx +39 -1
- package/src/components/resources/renderers/EndpointSliceRenderer.tsx +14 -13
- package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +22 -9
- package/src/components/resources/renderers/HPARenderer.tsx +56 -16
- package/src/components/resources/renderers/IngressRenderer.defaultBackend.test.tsx +33 -0
- package/src/components/resources/renderers/IngressRenderer.tsx +30 -3
- package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +9 -9
- package/src/components/resources/renderers/IstioExactReferenceNavigation.test.tsx +34 -0
- package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +5 -8
- package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +13 -11
- package/src/components/resources/renderers/KnativeEventingRenderer.tsx +24 -31
- package/src/components/resources/renderers/KnativeExactReferenceNavigation.test.tsx +47 -0
- package/src/components/resources/renderers/KnativeFlowRenderer.tsx +6 -7
- package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +7 -9
- package/src/components/resources/renderers/KnativeReferenceLink.tsx +14 -0
- package/src/components/resources/renderers/KnativeReferenceLinks.test.tsx +60 -0
- package/src/components/resources/renderers/KnativeSourceRenderer.tsx +9 -11
- package/src/components/resources/renderers/ManagedResourceRenderer.tsx +2 -2
- package/src/components/resources/renderers/MetricsUnavailableNotice.tsx +3 -2
- package/src/components/resources/renderers/PodRenderer.sidecar-terminal.test.tsx +200 -0
- package/src/components/resources/renderers/PodRenderer.test.tsx +32 -0
- package/src/components/resources/renderers/PodRenderer.tsx +81 -40
- package/src/components/resources/renderers/SimpleRouteRenderer.tsx +1 -1
- package/src/components/resources/renderers/VPARenderer.tsx +17 -11
- package/src/components/resources/resource-utils-capi.ts +1 -1
- package/src/components/resources/resource-utils-cnpg.test.ts +35 -10
- package/src/components/resources/resource-utils-cnpg.ts +51 -20
- package/src/components/resources/resource-utils-contour.test.ts +44 -0
- package/src/components/resources/resource-utils-contour.ts +16 -0
- package/src/components/resources/resource-utils-istio.ts +12 -8
- package/src/components/resources/resource-utils-knative.ts +18 -0
- package/src/components/resources/resource-utils.ts +96 -7
- package/src/components/resources/rules-column-width.test.ts +1 -1
- package/src/components/resources/summarize-scheduler-message.test.ts +31 -0
- package/src/components/shared/ActionConfirmDialog.test.tsx +154 -0
- package/src/components/shared/ActionConfirmDialog.tsx +246 -0
- package/src/components/shared/CreateResourceDialog.test.tsx +330 -0
- package/src/components/shared/CreateResourceDialog.tsx +126 -80
- package/src/components/shared/DetailShell.test.tsx +80 -0
- package/src/components/shared/DetailShell.tsx +85 -10
- package/src/components/shared/DrainPlanDialog.test.tsx +7 -0
- package/src/components/shared/DrainPlanDialog.tsx +6 -2
- package/src/components/shared/EditableYamlView.test.tsx +7 -0
- package/src/components/shared/EditableYamlView.tsx +1 -1
- package/src/components/shared/ResourceActionsBar.tsx +14 -7
- package/src/components/shared/ResourceRendererDispatch.tsx +15 -10
- package/src/components/shared/index.ts +2 -0
- package/src/components/timeline/DiffViewer.test.tsx +69 -0
- package/src/components/timeline/DiffViewer.tsx +113 -4
- package/src/components/timeline/TimelineSwimlanes.tsx +1 -1
- package/src/components/timeline/shared.test.tsx +48 -0
- package/src/components/timeline/shared.tsx +14 -19
- package/src/components/timeline/timeline-filters.ts +1 -0
- package/src/components/topology/K8sResourceNode.test.ts +18 -1
- package/src/components/topology/K8sResourceNode.tsx +44 -2
- package/src/components/topology/TopologyFilterSidebar.tsx +1 -0
- package/src/components/topology/TopologyGraph.tsx +3 -71
- package/src/components/topology/TopologySearch.tsx +1 -0
- package/src/components/topology/internet-groups.test.ts +35 -0
- package/src/components/topology/internet-groups.ts +55 -0
- package/src/components/topology/layout.ts +1 -1
- package/src/components/ui/Badge.tsx +1 -0
- package/src/components/ui/FoldSection.tsx +68 -0
- package/src/components/ui/ForceDeleteConfirmDialog.test.tsx +62 -0
- package/src/components/ui/ForceDeleteConfirmDialog.tsx +24 -12
- package/src/components/ui/RefLink.tsx +20 -0
- package/src/components/ui/RowActionMenu.tsx +8 -3
- package/src/components/ui/Toast.tsx +15 -4
- package/src/components/ui/crd-definition-navigation.test.tsx +160 -0
- package/src/components/ui/drawer-components.test.tsx +110 -1
- package/src/components/ui/drawer-components.tsx +62 -9
- package/src/components/ui/index.ts +4 -2
- package/src/components/ui/monacoEditorFeatures.ts +77 -0
- package/src/components/ui/monacoRuntime.ts +14 -19
- package/src/components/ui/status-tone.test.ts +10 -1
- package/src/components/ui/status-tone.tsx +29 -0
- package/src/components/workload/WorkloadView.deleted.test.tsx +43 -0
- package/src/components/workload/WorkloadView.relationships.test.tsx +37 -0
- package/src/components/workload/WorkloadView.spec.test.tsx +149 -0
- package/src/components/workload/WorkloadView.tsx +193 -71
- package/src/index.ts +14 -1
- package/src/monaco-deep.d.ts +19 -12
- package/src/theme/components.css +13 -0
- package/src/types/capacity.ts +11 -2
- package/src/types/core.ts +53 -2
- package/src/types/gitops-flux-status.test.ts +32 -1
- package/src/types/gitops-insights.ts +20 -2
- package/src/types/gitops-tree.ts +12 -0
- package/src/types/gitops.ts +26 -6
- package/src/utils/api-resources.ts +7 -0
- package/src/utils/application-history.ts +1 -0
- package/src/utils/cnpg-backup.test.ts +26 -0
- package/src/utils/cnpg-backup.ts +70 -0
- package/src/utils/format.test.ts +9 -0
- package/src/utils/format.ts +4 -0
- package/src/utils/gitops-owner.ts +3 -2
- package/src/utils/grant.test.ts +19 -0
- package/src/utils/grant.ts +35 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/k8s-errors.ts +7 -7
- package/src/utils/log-format.test.ts +41 -0
- package/src/utils/log-format.ts +71 -15
- package/src/utils/log-level.ts +12 -8
- package/src/utils/navigation.test.ts +57 -0
- package/src/utils/navigation.ts +86 -8
- package/src/utils/object-reference-navigation.test.ts +43 -0
- package/src/utils/resource-hierarchy.test.ts +37 -0
- package/src/utils/resource-hierarchy.ts +15 -7
- package/src/utils/resource-icons.ts +2 -0
- package/src/utils/skeleton-yaml.test.ts +21 -0
- package/src/utils/skeleton-yaml.ts +16 -0
- package/src/utils/url-path.test.ts +35 -0
- package/src/utils/url-path.ts +21 -0
- package/src/utils/validators.test.ts +4 -13
- package/src/utils/validators.ts +5 -19
- package/src/utils/view-transition.test.ts +35 -1
- package/src/utils/view-transition.ts +16 -1
|
@@ -90,6 +90,8 @@ export interface WorkloadExtraTab {
|
|
|
90
90
|
icon?: ReactNode
|
|
91
91
|
after?: WorkloadTabType
|
|
92
92
|
replaces?: WorkloadTabType
|
|
93
|
+
/** Trailing adornment after the label, e.g. a status mark. */
|
|
94
|
+
badge?: ReactNode
|
|
93
95
|
render: () => ReactNode
|
|
94
96
|
}
|
|
95
97
|
|
|
@@ -145,6 +147,23 @@ interface WorkloadViewProps {
|
|
|
145
147
|
* the Escape shortcut.
|
|
146
148
|
*/
|
|
147
149
|
breadcrumb?: ReactNode
|
|
150
|
+
/** Where the object lives, shown on the title line before its name (e.g. "Workspace / View /"). */
|
|
151
|
+
titlePrefix?: ReactNode
|
|
152
|
+
/**
|
|
153
|
+
* Kind, status and namespace on the title line, wrapping below the name
|
|
154
|
+
* only when there is no room; other chips (image, owners) keep a second
|
|
155
|
+
* row. The header actions then wrap below the title as a group rather
|
|
156
|
+
* than squeezing it.
|
|
157
|
+
*/
|
|
158
|
+
inlineBadges?: boolean
|
|
159
|
+
/** A note right after the namespace, e.g. that it is outside the namespace filter. */
|
|
160
|
+
namespaceNote?: ReactNode
|
|
161
|
+
/** Replaces the derived status badge on the title line, e.g. with the controller's own reported phase. */
|
|
162
|
+
renderStatusBadge?: (resource: any) => ReactNode
|
|
163
|
+
/** A short status right after the controller status on the title line, e.g. a derived health verdict. */
|
|
164
|
+
statusNote?: ReactNode
|
|
165
|
+
/** Leave out the kind badge, for a host whose title prefix already names the kind. */
|
|
166
|
+
hideKindBadge?: boolean
|
|
148
167
|
/** Suppress the standalone back arrow — for embeddings where "back" has no
|
|
149
168
|
* meaningful target (a single-workload app has no app graph to return to). */
|
|
150
169
|
hideBackButton?: boolean
|
|
@@ -319,6 +338,14 @@ interface WorkloadViewProps {
|
|
|
319
338
|
}) => ReactNode
|
|
320
339
|
/** Extra tabs for the expanded view (e.g. a domain's own sections). */
|
|
321
340
|
extraTabs?: WorkloadExtraTab[]
|
|
341
|
+
/** Expanded view: a line under the title, above the tabs, shown on every tab. */
|
|
342
|
+
subheader?: ReactNode
|
|
343
|
+
/** Expanded view: tab ids in display order; tabs not listed follow in their usual order. */
|
|
344
|
+
tabOrder?: string[]
|
|
345
|
+
/** Expanded view: relabel, lead, or replace the whole "Spec & status" body. */
|
|
346
|
+
specTab?: { label?: string; icon?: ReactNode; lead?: ReactNode; render?: () => ReactNode }
|
|
347
|
+
/** Domain actions rendered in the header (drawer and expanded). */
|
|
348
|
+
renderHeaderActions?: (props: { resource: any; context: 'drawer' | 'expanded'; onNavigate?: NavigateToResource }) => ReactNode
|
|
322
349
|
/** Render a full replacement for the expanded Overview tab. */
|
|
323
350
|
renderExpandedOverview?: (props: {
|
|
324
351
|
kind: string
|
|
@@ -326,6 +353,8 @@ interface WorkloadViewProps {
|
|
|
326
353
|
namespace: string
|
|
327
354
|
name: string
|
|
328
355
|
resource: any
|
|
356
|
+
/** Place resource notices within the replacement layout's content area. */
|
|
357
|
+
leadContent?: ReactNode
|
|
329
358
|
}) => ReactNode
|
|
330
359
|
/** Render the metrics tab content */
|
|
331
360
|
renderMetricsTab?: (props: { kind: string; namespace: string; name: string }) => ReactNode
|
|
@@ -371,6 +400,8 @@ interface WorkloadViewProps {
|
|
|
371
400
|
* live issues for this resource). Avoids showing the same failure twice.
|
|
372
401
|
* Also gates the `renderOverviewLead` wrapper (see above). */
|
|
373
402
|
hasOperationalIssues?: boolean
|
|
403
|
+
/** Also show the lead for neutral context without suppressing renderer problems. */
|
|
404
|
+
hasOverviewLead?: boolean
|
|
374
405
|
/** True while the live-issues fetch is still pending. Renderers suppress their
|
|
375
406
|
* banners during this window too — a banner whose failure the pipeline covers
|
|
376
407
|
* would otherwise flash on first paint before the issues arrive and hide it. */
|
|
@@ -409,6 +440,12 @@ export function WorkloadView({
|
|
|
409
440
|
initialTab,
|
|
410
441
|
group,
|
|
411
442
|
breadcrumb,
|
|
443
|
+
titlePrefix,
|
|
444
|
+
inlineBadges = false,
|
|
445
|
+
namespaceNote,
|
|
446
|
+
renderStatusBadge,
|
|
447
|
+
statusNote,
|
|
448
|
+
hideKindBadge = false,
|
|
412
449
|
hideBackButton,
|
|
413
450
|
scopeControls,
|
|
414
451
|
compactHeader,
|
|
@@ -469,6 +506,10 @@ export function WorkloadView({
|
|
|
469
506
|
renderExpandedOverview,
|
|
470
507
|
renderSummary,
|
|
471
508
|
extraTabs,
|
|
509
|
+
tabOrder,
|
|
510
|
+
specTab,
|
|
511
|
+
subheader,
|
|
512
|
+
renderHeaderActions,
|
|
472
513
|
renderRelatedYaml,
|
|
473
514
|
renderMetricsTab,
|
|
474
515
|
renderCostTab,
|
|
@@ -481,6 +522,7 @@ export function WorkloadView({
|
|
|
481
522
|
renderOverviewIntro,
|
|
482
523
|
renderOverviewLead,
|
|
483
524
|
hasOperationalIssues,
|
|
525
|
+
hasOverviewLead,
|
|
484
526
|
operationalIssuesPending,
|
|
485
527
|
// Actions bar
|
|
486
528
|
actionsBarProps,
|
|
@@ -794,6 +836,9 @@ export function WorkloadView({
|
|
|
794
836
|
const renderOverviewLeadForState = resourceGone ? undefined : renderOverviewLead
|
|
795
837
|
const renderOverviewExtraForState = resourceGone ? undefined : renderOverviewExtra
|
|
796
838
|
const renderDiagnoseTabForState = resourceGone ? undefined : renderDiagnoseTab
|
|
839
|
+
// A host's summary, tabs and subheader can hold actions on the live object.
|
|
840
|
+
const renderSummaryForState = resourceGone ? undefined : renderSummary
|
|
841
|
+
const extraTabsForState = resourceGone ? undefined : extraTabs
|
|
797
842
|
// A remount closes any dialog the bar had open: once its actions are gone,
|
|
798
843
|
// a confirm button left on screen would do nothing.
|
|
799
844
|
const actionsBarKey = resourceGone ? 'gone' : 'live'
|
|
@@ -830,6 +875,7 @@ export function WorkloadView({
|
|
|
830
875
|
const renderDiagnose = actionsBarProps?.renderDiagnose as
|
|
831
876
|
| ((ctx: { kind: string; group?: string; namespace: string; name: string; health?: DiagnoseHealthHint }) => ReactNode)
|
|
832
877
|
| undefined
|
|
878
|
+
const headerActions = resource && !resourceGone && renderHeaderActions?.({ resource, context: expanded ? 'expanded' : 'drawer', onNavigate: onNavigateToResource })
|
|
833
879
|
const diagnoseAction = resourceGone ? null : renderDiagnose?.({
|
|
834
880
|
kind: resource?.kind ?? knownKindForPluralWithGroup(apiKind, group ?? '') ?? apiKind,
|
|
835
881
|
group,
|
|
@@ -849,11 +895,11 @@ export function WorkloadView({
|
|
|
849
895
|
const logsFallbackReady = !renderLogsTab || (!logsTabVisible && !podEvidenceLoading)
|
|
850
896
|
const requestedTab: TabType = activeTab
|
|
851
897
|
const summaryContext = { kind, apiKind, namespace, name, group, resource, onNavigate: onNavigateToResource }
|
|
852
|
-
const expandedSummary = expanded && resource ?
|
|
853
|
-
const drawerSummary = !expanded && resource ?
|
|
898
|
+
const expandedSummary = expanded && resource ? renderSummaryForState?.({ ...summaryContext, context: 'expanded' }) ?? null : null
|
|
899
|
+
const drawerSummary = !expanded && resource ? renderSummaryForState?.({ ...summaryContext, context: 'drawer' }) ?? null : null
|
|
854
900
|
const tabs: DetailShellTab<TabType>[] = [
|
|
855
901
|
{ id: 'overview', label: 'Overview', icon: <Layers className="w-4 h-4" /> },
|
|
856
|
-
{ id: 'spec', label: 'Spec & status', icon: <FileText className="w-4 h-4" />, hidden: !expandedSummary },
|
|
902
|
+
{ id: 'spec', label: specTab?.label ?? 'Spec & status', icon: specTab?.icon ?? <FileText className="w-4 h-4" />, hidden: !expandedSummary },
|
|
857
903
|
{ id: 'topology', label: 'Topology', icon: <Network className="w-4 h-4" />, hidden: topologyTabHidden },
|
|
858
904
|
{
|
|
859
905
|
id: 'timeline',
|
|
@@ -872,10 +918,10 @@ export function WorkloadView({
|
|
|
872
918
|
{ id: 'cost', label: 'Cost', icon: <Coins className="w-4 h-4" />, hidden: !costTabVisible },
|
|
873
919
|
{ id: 'yaml', label: 'YAML', icon: <FileText className="w-4 h-4" /> },
|
|
874
920
|
]
|
|
875
|
-
const allTabs = mergeExtraTabs(tabs, expanded ?
|
|
921
|
+
const allTabs = orderTabs(mergeExtraTabs(tabs, expanded ? extraTabsForState : undefined), expanded ? tabOrder : undefined)
|
|
876
922
|
const requestedTabAvailable = allTabs.some((tab) => tab.id === requestedTab && !tab.hidden)
|
|
877
923
|
const effectiveTab: TabType = requestedTabAvailable ? requestedTab : 'overview'
|
|
878
|
-
const activeExtraTab = expanded ?
|
|
924
|
+
const activeExtraTab = expanded ? extraTabsForState?.find((x) => x.id === effectiveTab) : undefined
|
|
879
925
|
const shouldCommitFallback =
|
|
880
926
|
requestedTab !== 'overview' &&
|
|
881
927
|
!requestedTabAvailable &&
|
|
@@ -889,7 +935,12 @@ export function WorkloadView({
|
|
|
889
935
|
useEffect(() => {
|
|
890
936
|
if (shouldCommitFallback && activeTab !== 'overview') onTabChange?.('overview', { replace: true })
|
|
891
937
|
}, [activeTab, onTabChange, shouldCommitFallback])
|
|
892
|
-
const expandedOverview = expanded ? renderExpandedOverview?.({
|
|
938
|
+
const expandedOverview = expanded ? renderExpandedOverview?.({
|
|
939
|
+
kind, apiKind, namespace, name, resource,
|
|
940
|
+
leadContent: (hasOverviewLead ?? hasOperationalIssues) && renderOverviewLeadForState
|
|
941
|
+
? renderOverviewLeadForState({ kind, namespace, name })
|
|
942
|
+
: undefined,
|
|
943
|
+
}) : null
|
|
893
944
|
const overviewIntro = renderOverviewIntro?.({ kind, namespace, name })
|
|
894
945
|
|
|
895
946
|
// ── Collapsed (drawer) mode ──────────────────────────────────────────────
|
|
@@ -904,13 +955,13 @@ export function WorkloadView({
|
|
|
904
955
|
<span className={clsx('badge', getKindColorOutline(apiKind))}>
|
|
905
956
|
{displayKindName(apiKind, resource?.kind)}
|
|
906
957
|
</span>
|
|
907
|
-
{status && (
|
|
958
|
+
{renderStatusBadge && resource && !resourceGone ? renderStatusBadge(resource) : status && (
|
|
908
959
|
<span className={clsx('badge', status.color)}>
|
|
909
960
|
{status.text}
|
|
910
961
|
</span>
|
|
911
962
|
)}
|
|
912
963
|
</div>
|
|
913
|
-
<div className="flex items-center gap-1.5">
|
|
964
|
+
<div className="flex shrink-0 flex-nowrap items-center justify-end gap-1.5">
|
|
914
965
|
{diagnoseAction}
|
|
915
966
|
{onExpand && (
|
|
916
967
|
<Tooltip content="Open full view" delay={150} position="bottom">
|
|
@@ -982,7 +1033,7 @@ export function WorkloadView({
|
|
|
982
1033
|
</div>
|
|
983
1034
|
|
|
984
1035
|
{/* Actions bar */}
|
|
985
|
-
<ResourceActionsBar key={actionsBarKey} resource={selectedResource} data={resource} onClose={onClose} showYaml={showYaml} onToggleYaml={() => switchView(!showYaml)} {...actionsBarPropsForState} />
|
|
1036
|
+
<ResourceActionsBar key={actionsBarKey} resource={selectedResource} data={resource} onClose={onClose} showYaml={showYaml} onToggleYaml={() => switchView(!showYaml)} {...actionsBarPropsForState} leadingActions={headerActions} />
|
|
986
1037
|
</div>
|
|
987
1038
|
|
|
988
1039
|
{/* Success animation overlay */}
|
|
@@ -1049,11 +1100,12 @@ export function WorkloadView({
|
|
|
1049
1100
|
drawerSummary
|
|
1050
1101
|
) : (
|
|
1051
1102
|
<>
|
|
1052
|
-
{renderOverviewLeadForState && hasOperationalIssues && (
|
|
1103
|
+
{renderOverviewLeadForState && (hasOverviewLead ?? hasOperationalIssues) && (
|
|
1053
1104
|
<div className="px-4 pt-4">
|
|
1054
1105
|
{renderOverviewLeadForState({ kind, namespace, name })}
|
|
1055
1106
|
</div>
|
|
1056
1107
|
)}
|
|
1108
|
+
{overviewIntro && <div className="px-4 pt-4">{overviewIntro}</div>}
|
|
1057
1109
|
<ResourceRendererDispatch
|
|
1058
1110
|
resource={selectedResource}
|
|
1059
1111
|
data={resource}
|
|
@@ -1091,6 +1143,8 @@ export function WorkloadView({
|
|
|
1091
1143
|
<OperationalIssuesShownContext.Provider value={!!hasOperationalIssues || !!operationalIssuesPending}>
|
|
1092
1144
|
<DetailShell
|
|
1093
1145
|
breadcrumb={breadcrumb}
|
|
1146
|
+
wrapHeader={inlineBadges}
|
|
1147
|
+
subheader={resourceGone ? undefined : subheader}
|
|
1094
1148
|
nav={
|
|
1095
1149
|
breadcrumb || hideBackButton ? undefined : (
|
|
1096
1150
|
<Tooltip content="Go back (Esc)" delay={150} position="bottom">
|
|
@@ -1104,68 +1158,111 @@ export function WorkloadView({
|
|
|
1104
1158
|
</Tooltip>
|
|
1105
1159
|
)
|
|
1106
1160
|
}
|
|
1107
|
-
identity={
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
<
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
)}
|
|
1132
|
-
<div className="flex items-center gap-3 text-sm text-theme-text-secondary">
|
|
1133
|
-
<span className={clsx('badge', getKindColorOutline(apiKind))}>
|
|
1134
|
-
{displayKindName(apiKind, resource?.kind)}
|
|
1135
|
-
</span>
|
|
1136
|
-
{status && (
|
|
1137
|
-
<span className={clsx('badge', status.color)}>
|
|
1161
|
+
identity={(() => {
|
|
1162
|
+
const nameAndCopy = (
|
|
1163
|
+
<>
|
|
1164
|
+
<h1 className="text-lg font-semibold text-theme-text-primary truncate">{name}</h1>
|
|
1165
|
+
<Tooltip content="Copy name" delay={150}>
|
|
1166
|
+
<button
|
|
1167
|
+
onClick={() => copyToClipboard(name, 'name')}
|
|
1168
|
+
className="p-1 text-theme-text-secondary hover:text-theme-text-primary hover:bg-theme-elevated rounded shrink-0"
|
|
1169
|
+
aria-label="Copy name"
|
|
1170
|
+
>
|
|
1171
|
+
{copied === 'name' ? <Check className="w-3.5 h-3.5 text-green-400" /> : <Copy className="w-3.5 h-3.5" />}
|
|
1172
|
+
</button>
|
|
1173
|
+
</Tooltip>
|
|
1174
|
+
</>
|
|
1175
|
+
)
|
|
1176
|
+
const kindAndStatus = (
|
|
1177
|
+
<>
|
|
1178
|
+
{!hideKindBadge && (
|
|
1179
|
+
<span className={clsx('badge whitespace-nowrap', getKindColorOutline(apiKind))}>
|
|
1180
|
+
{displayKindName(apiKind, resource?.kind)}
|
|
1181
|
+
</span>
|
|
1182
|
+
)}
|
|
1183
|
+
{renderStatusBadge && resource && !resourceGone ? renderStatusBadge(resource) : status && (
|
|
1184
|
+
<span className={clsx('badge whitespace-nowrap', status.color)}>
|
|
1138
1185
|
{status.text}
|
|
1139
1186
|
</span>
|
|
1140
1187
|
)}
|
|
1188
|
+
{!resourceGone && statusNote}
|
|
1189
|
+
</>
|
|
1190
|
+
)
|
|
1191
|
+
const coreBadges = (
|
|
1192
|
+
<>
|
|
1193
|
+
{/* On the title line the kind and status wrap together, never apart. */}
|
|
1194
|
+
{inlineBadges ? <span className="inline-flex items-center gap-x-3">{kindAndStatus}</span> : kindAndStatus}
|
|
1141
1195
|
{namespace && namespace !== '_' && (
|
|
1142
|
-
<span>Namespace: <span className="text-theme-text-primary">{namespace}</span></span>
|
|
1143
|
-
)}
|
|
1144
|
-
{headerImage && (
|
|
1145
|
-
<Tooltip content={headerImage} delay={300} wrapperClassName="min-w-0 max-w-md">
|
|
1146
|
-
<span className="truncate font-mono text-xs">
|
|
1147
|
-
{midTruncate(headerImage, 72)}
|
|
1148
|
-
</span>
|
|
1149
|
-
</Tooltip>
|
|
1150
|
-
)}
|
|
1151
|
-
{gitopsOwner && (
|
|
1152
|
-
<ManagedByChip owner={gitopsOwner} status={gitOpsOwnerStatus} verified={gitOpsOwnerVerified} pending={gitOpsOwnerPending} source={gitOpsOwnerSource} onOpen={onOpenGitOpsResource} variant="block" />
|
|
1153
|
-
)}
|
|
1154
|
-
{helmOwner && (
|
|
1155
|
-
<HelmManagedByChip owner={helmOwner} source={helmOwnerSource} onOpen={onOpenHelmRelease} variant="block" />
|
|
1196
|
+
<span className="whitespace-nowrap">Namespace: <span className="text-theme-text-primary">{namespace}</span></span>
|
|
1156
1197
|
)}
|
|
1157
|
-
{
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1198
|
+
{namespace && namespace !== '_' && namespaceNote}
|
|
1199
|
+
</>
|
|
1200
|
+
)
|
|
1201
|
+
const extraChips = [
|
|
1202
|
+
headerImage && (
|
|
1203
|
+
<Tooltip key="image" content={headerImage} delay={300} wrapperClassName="min-w-0 max-w-md">
|
|
1204
|
+
<span className="truncate font-mono text-xs">
|
|
1205
|
+
{midTruncate(headerImage, 72)}
|
|
1206
|
+
</span>
|
|
1207
|
+
</Tooltip>
|
|
1208
|
+
),
|
|
1209
|
+
gitopsOwner && (
|
|
1210
|
+
<ManagedByChip key="gitops" owner={gitopsOwner} status={gitOpsOwnerStatus} verified={gitOpsOwnerVerified} pending={gitOpsOwnerPending} source={gitOpsOwnerSource} onOpen={onOpenGitOpsResource} variant="block" />
|
|
1211
|
+
),
|
|
1212
|
+
helmOwner && (
|
|
1213
|
+
<HelmManagedByChip key="helm" owner={helmOwner} source={helmOwnerSource} onOpen={onOpenHelmRelease} variant="block" />
|
|
1214
|
+
),
|
|
1215
|
+
gitOpsResourcePath && onNavigateGitOpsPath && (
|
|
1216
|
+
<OpenInGitOpsChip key="open-gitops" onClick={() => onNavigateGitOpsPath(gitOpsResourcePath)} />
|
|
1217
|
+
),
|
|
1218
|
+
onOpenLiveTraffic && <LiveTrafficChip key="live-traffic" onClick={onOpenLiveTraffic} />,
|
|
1219
|
+
relationships?.owner && !showOwnershipHeading && (
|
|
1220
|
+
<span key="owner">Owner: <button onClick={() => onNavigateToResource?.(refToSelectedResource(relationships.owner!))} className="text-blue-500 hover:underline">{relationships.owner.name}</button></span>
|
|
1221
|
+
),
|
|
1222
|
+
].filter(Boolean)
|
|
1223
|
+
if (inlineBadges && !(showOwnershipHeading && ownershipContext)) {
|
|
1224
|
+
// The name and its copy button stay together and truncate only when
|
|
1225
|
+
// the line holds nothing else; the badges wrap below before that.
|
|
1226
|
+
return (
|
|
1227
|
+
<>
|
|
1228
|
+
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-theme-text-secondary">
|
|
1229
|
+
{titlePrefix}
|
|
1230
|
+
<div className="flex min-w-0 max-w-full items-center gap-2">{nameAndCopy}</div>
|
|
1231
|
+
{coreBadges}
|
|
1232
|
+
</div>
|
|
1233
|
+
{extraChips.length > 0 && (
|
|
1234
|
+
<div className="mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-theme-text-secondary">{extraChips}</div>
|
|
1235
|
+
)}
|
|
1236
|
+
</>
|
|
1237
|
+
)
|
|
1238
|
+
}
|
|
1239
|
+
return (
|
|
1240
|
+
<>
|
|
1241
|
+
{showOwnershipHeading && ownershipContext ? (
|
|
1242
|
+
<OwnershipHeading
|
|
1243
|
+
podName={name}
|
|
1244
|
+
context={ownershipContext}
|
|
1245
|
+
copied={copied === 'name'}
|
|
1246
|
+
onCopy={() => copyToClipboard(name, 'name')}
|
|
1247
|
+
onNavigateToResource={onNavigateToResource}
|
|
1248
|
+
onOpenApplication={onOpenApplication}
|
|
1249
|
+
/>
|
|
1250
|
+
) : (
|
|
1251
|
+
<div className="flex items-center gap-3 mb-1">
|
|
1252
|
+
{titlePrefix}
|
|
1253
|
+
{nameAndCopy}
|
|
1254
|
+
</div>
|
|
1163
1255
|
)}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1256
|
+
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-theme-text-secondary">
|
|
1257
|
+
{coreBadges}
|
|
1258
|
+
{extraChips}
|
|
1259
|
+
</div>
|
|
1260
|
+
</>
|
|
1261
|
+
)
|
|
1262
|
+
})()}
|
|
1167
1263
|
headerActions={
|
|
1168
1264
|
<>
|
|
1265
|
+
{headerActions}
|
|
1169
1266
|
{diagnoseAction}
|
|
1170
1267
|
<Tooltip content="Refresh" delay={150} position="bottom">
|
|
1171
1268
|
<button
|
|
@@ -1217,13 +1314,10 @@ export function WorkloadView({
|
|
|
1217
1314
|
<div className="h-full min-h-0 overflow-y-auto">{expandedSummary}</div>
|
|
1218
1315
|
) : effectiveTab === 'overview' && expandedOverview ? (
|
|
1219
1316
|
<div className="h-full min-h-0">
|
|
1220
|
-
{hasOperationalIssues && renderOverviewLeadForState && (
|
|
1221
|
-
<div className="px-4 pt-4">
|
|
1222
|
-
{renderOverviewLeadForState({ kind, namespace, name })}
|
|
1223
|
-
</div>
|
|
1224
|
-
)}
|
|
1225
1317
|
{expandedOverview}
|
|
1226
1318
|
</div>
|
|
1319
|
+
) : effectiveTab === 'spec' && specTab?.render && !resourceGone ? (
|
|
1320
|
+
<div className="h-full min-h-0 overflow-y-auto">{specTab.render()}</div>
|
|
1227
1321
|
) : (effectiveTab === 'overview' || effectiveTab === 'spec') && (
|
|
1228
1322
|
<InfoTab
|
|
1229
1323
|
resource={resource}
|
|
@@ -1258,7 +1352,14 @@ export function WorkloadView({
|
|
|
1258
1352
|
updatesError={resourceFocusedUpdatesError}
|
|
1259
1353
|
extraContent={renderOverviewExtraForState && renderOverviewExtraForState({ kind, namespace, name, group, context: 'expanded' })}
|
|
1260
1354
|
introContent={overviewIntro}
|
|
1261
|
-
leadContent={
|
|
1355
|
+
leadContent={
|
|
1356
|
+
// A host's spec lead replaces the operational issues there: its Overview already leads with them.
|
|
1357
|
+
effectiveTab === 'spec' && specTab?.lead
|
|
1358
|
+
? specTab.lead
|
|
1359
|
+
: (hasOverviewLead ?? hasOperationalIssues) && renderOverviewLeadForState
|
|
1360
|
+
? renderOverviewLeadForState({ kind, namespace, name })
|
|
1361
|
+
: undefined
|
|
1362
|
+
}
|
|
1262
1363
|
onEvaluateCapacity={onEvaluateCapacity}
|
|
1263
1364
|
recentImageSave={recentImageSave}
|
|
1264
1365
|
/>
|
|
@@ -2110,6 +2211,7 @@ function WorkloadOverviewTab({
|
|
|
2110
2211
|
const relationshipGroups = buildRelationshipGroups(relationships)
|
|
2111
2212
|
const servingRelationshipGroups = buildServingRelationshipGroups(relationships)
|
|
2112
2213
|
const dependencyRelationshipGroups = buildDependencyRelationshipGroups(relationships)
|
|
2214
|
+
const observationGroups = dependencyRelationshipGroups.filter((group) => group.label === 'Monitored By' || group.label === 'Staged Policies')
|
|
2113
2215
|
const showServingPath = servingRelationshipGroups.length > 0 && overviewShape !== 'job' && overviewShape !== 'cronjob'
|
|
2114
2216
|
const secondaryRelationshipGroups = showServingPath ? dependencyRelationshipGroups : relationshipGroups
|
|
2115
2217
|
const relationshipCardTitle =
|
|
@@ -2188,6 +2290,14 @@ function WorkloadOverviewTab({
|
|
|
2188
2290
|
onNavigate={onNavigate}
|
|
2189
2291
|
onSwitchToTopology={onSwitchToTopology}
|
|
2190
2292
|
/>
|
|
2293
|
+
{observationGroups.length > 0 && (
|
|
2294
|
+
<ServingDependenciesCard
|
|
2295
|
+
title="Related resources"
|
|
2296
|
+
groups={observationGroups}
|
|
2297
|
+
onNavigate={onNavigate}
|
|
2298
|
+
onSwitchToTopology={onSwitchToTopology}
|
|
2299
|
+
/>
|
|
2300
|
+
)}
|
|
2191
2301
|
{extraContent}
|
|
2192
2302
|
</div>
|
|
2193
2303
|
</div>
|
|
@@ -3877,6 +3987,7 @@ function buildServingRelationshipGroups(relationships: Relationships | undefined
|
|
|
3877
3987
|
...(relationships.ingresses ?? []),
|
|
3878
3988
|
...(relationships.gateways ?? []),
|
|
3879
3989
|
...(relationships.routes ?? []),
|
|
3990
|
+
...(relationships.routedFrom ?? []),
|
|
3880
3991
|
])
|
|
3881
3992
|
return [
|
|
3882
3993
|
{ label: 'Services', refs: dedupeResourceRefs(relationships.services ?? []) },
|
|
@@ -3891,6 +4002,8 @@ function buildDependencyRelationshipGroups(relationships: Relationships | undefi
|
|
|
3891
4002
|
{ label: 'Autoscalers', refs: dedupeResourceRefs(relationships.scalers ?? []) },
|
|
3892
4003
|
{ label: 'Disruption budgets', refs: dedupeResourceRefs(relationships.pdbs ?? []) },
|
|
3893
4004
|
{ label: 'Network policies', refs: dedupeResourceRefs(relationships.networkPolicies ?? []) },
|
|
4005
|
+
{ label: 'Staged Policies', refs: dedupeResourceRefs(relationships.stagedPolicies ?? []) },
|
|
4006
|
+
{ label: 'Monitored By', refs: dedupeResourceRefs(relationships.monitors ?? []) },
|
|
3894
4007
|
{ label: 'Storage claims', refs: dedupeResourceRefs(relationships.resourceClaims ?? []) },
|
|
3895
4008
|
].filter((group) => group.refs.length > 0)
|
|
3896
4009
|
}
|
|
@@ -3990,12 +4103,21 @@ function mergeAndRankEvents(events: TimelineEvent[], updates: TimelineEvent[]):
|
|
|
3990
4103
|
})
|
|
3991
4104
|
}
|
|
3992
4105
|
|
|
4106
|
+
function orderTabs(tabs: DetailShellTab<TabType>[], order: string[] | undefined): DetailShellTab<TabType>[] {
|
|
4107
|
+
if (!order || order.length === 0) return tabs
|
|
4108
|
+
const rank = (id: string) => {
|
|
4109
|
+
const i = order.indexOf(id)
|
|
4110
|
+
return i < 0 ? order.length : i
|
|
4111
|
+
}
|
|
4112
|
+
return tabs.map((t, i) => ({ t, i })).sort((a, b) => rank(a.t.id) - rank(b.t.id) || a.i - b.i).map((x) => x.t)
|
|
4113
|
+
}
|
|
4114
|
+
|
|
3993
4115
|
function mergeExtraTabs(tabs: DetailShellTab<TabType>[], extra: WorkloadExtraTab[] | undefined): DetailShellTab<TabType>[] {
|
|
3994
4116
|
if (!extra || extra.length === 0) return tabs
|
|
3995
4117
|
const replaced = new Set(extra.map((x) => x.replaces).filter(Boolean))
|
|
3996
4118
|
const out = tabs.map((t) => (replaced.has(t.id) ? { ...t, hidden: true } : t))
|
|
3997
4119
|
for (const x of extra) {
|
|
3998
|
-
const tab: DetailShellTab<TabType> = { id: x.id as TabType, label: x.label, icon: x.icon }
|
|
4120
|
+
const tab: DetailShellTab<TabType> = { id: x.id as TabType, label: x.label, icon: x.icon, badge: x.badge }
|
|
3999
4121
|
const anchor = x.after ?? x.replaces
|
|
4000
4122
|
const idx = anchor ? out.findIndex((t) => t.id === anchor) : -1
|
|
4001
4123
|
if (idx >= 0) out.splice(idx + 1, 0, tab)
|
package/src/index.ts
CHANGED
|
@@ -55,7 +55,7 @@ export * from './components/checks'
|
|
|
55
55
|
// queue)
|
|
56
56
|
export * from './components/issues'
|
|
57
57
|
|
|
58
|
-
// CloudNativePG workspace model (fleet derivation over /api/cnpg/workspace)
|
|
58
|
+
// CloudNativePG workspace model (fleet derivation over /api/cnpg/workspace) and summaries
|
|
59
59
|
export * from './components/cnpg'
|
|
60
60
|
|
|
61
61
|
// Cluster switcher (shared trigger+dropdown for OSS Radar and Radar Hub)
|
|
@@ -82,3 +82,16 @@ export * from './components/compare'
|
|
|
82
82
|
|
|
83
83
|
// Perf instrumentation (ELK + structureKey timers, surfaced in diagnostics overlay)
|
|
84
84
|
export * from './perf'
|
|
85
|
+
|
|
86
|
+
export { CertaintyGlyph, certaintyGlyph, certaintyValueLabel, type Certainty } from './components/facts/certainty'
|
|
87
|
+
|
|
88
|
+
export * from './components/facts'
|
|
89
|
+
export {
|
|
90
|
+
WorkspaceProblemCallout,
|
|
91
|
+
ProblemList,
|
|
92
|
+
ProblemMeta,
|
|
93
|
+
OpenIssueContext,
|
|
94
|
+
problemOriginLabel,
|
|
95
|
+
type WorkspaceProblem,
|
|
96
|
+
type ProblemOrigin,
|
|
97
|
+
} from './components/problems'
|
package/src/monaco-deep.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
// @monaco-editor/react and @monaco-editor/loader type monaco through this path,
|
|
2
|
+
// which monaco-editor's exports map does not serve.
|
|
1
3
|
declare module 'monaco-editor/esm/vs/editor/editor.api' {
|
|
2
|
-
export * from 'monaco-editor'
|
|
4
|
+
export * from 'monaco-editor/editor/editor.api'
|
|
3
5
|
}
|
|
4
6
|
|
|
5
|
-
declare module 'monaco-editor/
|
|
6
|
-
declare module 'monaco-editor/
|
|
7
|
-
declare module 'monaco-editor/
|
|
8
|
-
declare module 'monaco-editor/
|
|
9
|
-
declare module 'monaco-editor/
|
|
10
|
-
declare module 'monaco-editor/
|
|
11
|
-
declare module 'monaco-editor/
|
|
12
|
-
declare module 'monaco-editor/
|
|
13
|
-
declare module 'monaco-editor/
|
|
14
|
-
declare module 'monaco-editor/
|
|
15
|
-
declare module 'monaco-editor/
|
|
7
|
+
declare module 'monaco-editor/languages/definitions/yaml/register'
|
|
8
|
+
declare module 'monaco-editor/languages/definitions/xml/register'
|
|
9
|
+
declare module 'monaco-editor/languages/definitions/html/register'
|
|
10
|
+
declare module 'monaco-editor/languages/definitions/css/register'
|
|
11
|
+
declare module 'monaco-editor/languages/definitions/javascript/register'
|
|
12
|
+
declare module 'monaco-editor/languages/definitions/typescript/register'
|
|
13
|
+
declare module 'monaco-editor/languages/definitions/python/register'
|
|
14
|
+
declare module 'monaco-editor/languages/definitions/shell/register'
|
|
15
|
+
declare module 'monaco-editor/languages/definitions/markdown/register'
|
|
16
|
+
declare module 'monaco-editor/languages/definitions/ini/register'
|
|
17
|
+
declare module 'monaco-editor/languages/definitions/dockerfile/register'
|
|
18
|
+
declare module 'monaco-editor/editor/contrib/*'
|
|
19
|
+
declare module 'monaco-editor/editor/standalone/*'
|
|
20
|
+
declare module 'monaco-editor/editor/browser/*'
|
|
21
|
+
declare module 'monaco-editor/editor/common/*'
|
|
22
|
+
declare module 'monaco-editor/features/*'
|
package/src/theme/components.css
CHANGED
|
@@ -35,6 +35,19 @@
|
|
|
35
35
|
opacity: 0.5;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
.btn-secondary {
|
|
39
|
+
border: 1px solid var(--border-default);
|
|
40
|
+
background-color: var(--bg-surface);
|
|
41
|
+
color: var(--text-primary);
|
|
42
|
+
border-radius: 0.625rem;
|
|
43
|
+
}
|
|
44
|
+
.btn-secondary:hover {
|
|
45
|
+
background-color: var(--bg-hover);
|
|
46
|
+
}
|
|
47
|
+
.btn-secondary:disabled {
|
|
48
|
+
opacity: 0.5;
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
.btn-brand-toggle {
|
|
39
52
|
background-color: color-mix(in srgb, var(--color-brand) 50%, transparent);
|
|
40
53
|
color: var(--text-primary);
|
package/src/types/capacity.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Issue } from "../components/issues/types";
|
|
2
|
+
import type { Certainty } from "../components/facts/certainty";
|
|
2
3
|
import type { NodeLifecycleObservation } from "../utils/node-lifecycle";
|
|
3
4
|
|
|
4
5
|
export const CAPACITY_SCHEMA_VERSION = "v1alpha1" as const;
|
|
@@ -16,8 +17,7 @@ export interface CapacityResourceIdentity {
|
|
|
16
17
|
uid?: string;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export type CapacityCertainty =
|
|
20
|
-
"exact" | "lower_bound" | "upper_bound" | "unknown";
|
|
20
|
+
export type CapacityCertainty = Certainty;
|
|
21
21
|
export type CapacityGranularity =
|
|
22
22
|
"aggregate" | "aggregate_not_binpacked" | "per_node";
|
|
23
23
|
export type CapacityResourceVector = Record<string, string>;
|
|
@@ -418,6 +418,14 @@ export interface CapacityScalingFact {
|
|
|
418
418
|
summary: string;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
+
/** Published scale-down observations; candidates do not imply a removal ETA. */
|
|
422
|
+
export interface CapacityAutoscalerScaleDown {
|
|
423
|
+
status?: string;
|
|
424
|
+
candidates?: number;
|
|
425
|
+
lastTransitionTime?: string;
|
|
426
|
+
asOf?: string;
|
|
427
|
+
}
|
|
428
|
+
|
|
421
429
|
export interface CapacityAutoscalerBackoff {
|
|
422
430
|
errorClass?: string;
|
|
423
431
|
errorCode?: string;
|
|
@@ -440,6 +448,7 @@ export interface CapacityAutoscalerChildObservation {
|
|
|
440
448
|
readyNodes?: number;
|
|
441
449
|
totalNodes?: number;
|
|
442
450
|
backoff?: CapacityAutoscalerBackoff;
|
|
451
|
+
scaleDown?: CapacityAutoscalerScaleDown;
|
|
443
452
|
asOf?: string;
|
|
444
453
|
}
|
|
445
454
|
|