@skyhook-io/radar-app 1.12.3 → 1.13.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/package.json +5 -5
- package/src/App.tsx +1 -0
- package/src/api/client.ts +38 -6
- package/src/components/cost/ApplicationCostTab.test.ts +45 -0
- package/src/components/cost/ApplicationCostTab.tsx +115 -64
- package/src/components/cost/CostTrendChart.test.ts +65 -0
- package/src/components/cost/CostTrendChart.tsx +107 -17
- package/src/components/cost/CostView.test.ts +36 -1
- package/src/components/cost/CostView.tsx +133 -51
- package/src/components/cost/CurrentAllocationUse.tsx +8 -4
- package/src/components/cost/WorkloadCostTab.test.ts +50 -0
- package/src/components/cost/WorkloadCostTab.tsx +109 -61
- package/src/components/cost/source.test.ts +33 -0
- package/src/components/cost/source.ts +100 -0
- package/src/components/diagnose/parts.test.tsx +12 -4
- package/src/components/diagnose/parts.tsx +19 -15
- package/src/components/home/CostCard.tsx +3 -2
- package/src/components/rightsizing/RightsizingScanView.tsx +36 -12
- package/src/components/rightsizing/copy.test.ts +19 -0
- package/src/components/settings/SettingsDialog.tsx +666 -103
- package/src/components/settings/settings-state.test.ts +42 -0
- package/src/components/settings/settings-state.ts +39 -0
- package/src/index.css +11 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
costSourceApplyLabel,
|
|
4
|
+
shouldOfferCostReview,
|
|
5
|
+
shouldShowSettingsFooter,
|
|
6
|
+
} from "./settings-state";
|
|
7
|
+
|
|
8
|
+
describe("Cost settings state", () => {
|
|
9
|
+
it("keeps source drafts inline while the Cost section is open", () => {
|
|
10
|
+
expect(shouldOfferCostReview(true, "cost")).toBe(false);
|
|
11
|
+
expect(
|
|
12
|
+
shouldShowSettingsFooter({
|
|
13
|
+
canEditConfig: true,
|
|
14
|
+
confirmingClose: false,
|
|
15
|
+
configDirty: false,
|
|
16
|
+
costIntegrationDirty: true,
|
|
17
|
+
section: "cost",
|
|
18
|
+
hasSaveMessage: false,
|
|
19
|
+
}),
|
|
20
|
+
).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("offers review from other sections and retains the close guard", () => {
|
|
24
|
+
expect(shouldOfferCostReview(true, "overview")).toBe(true);
|
|
25
|
+
expect(
|
|
26
|
+
shouldShowSettingsFooter({
|
|
27
|
+
canEditConfig: true,
|
|
28
|
+
confirmingClose: true,
|
|
29
|
+
configDirty: false,
|
|
30
|
+
costIntegrationDirty: true,
|
|
31
|
+
section: "cost",
|
|
32
|
+
hasSaveMessage: false,
|
|
33
|
+
}),
|
|
34
|
+
).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("only claims to test sources that the backend probes", () => {
|
|
38
|
+
expect(costSourceApplyLabel("auto")).toBe("Test & apply source");
|
|
39
|
+
expect(costSourceApplyLabel("kubecost")).toBe("Test & apply source");
|
|
40
|
+
expect(costSourceApplyLabel("prometheus")).toBe("Apply source");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type SettingsSectionId =
|
|
2
|
+
| 'overview'
|
|
3
|
+
| 'perms'
|
|
4
|
+
| 'connection'
|
|
5
|
+
| 'prometheus'
|
|
6
|
+
| 'cost'
|
|
7
|
+
| 'argocd'
|
|
8
|
+
| 'ai'
|
|
9
|
+
| 'advanced'
|
|
10
|
+
|
|
11
|
+
export function shouldOfferCostReview(
|
|
12
|
+
costIntegrationDirty: boolean,
|
|
13
|
+
section: SettingsSectionId,
|
|
14
|
+
): boolean {
|
|
15
|
+
return costIntegrationDirty && section !== 'cost'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function shouldShowSettingsFooter(input: {
|
|
19
|
+
canEditConfig: boolean
|
|
20
|
+
confirmingClose: boolean
|
|
21
|
+
configDirty: boolean
|
|
22
|
+
costIntegrationDirty: boolean
|
|
23
|
+
section: SettingsSectionId
|
|
24
|
+
hasSaveMessage: boolean
|
|
25
|
+
}): boolean {
|
|
26
|
+
return (
|
|
27
|
+
input.canEditConfig &&
|
|
28
|
+
(input.confirmingClose ||
|
|
29
|
+
input.configDirty ||
|
|
30
|
+
shouldOfferCostReview(input.costIntegrationDirty, input.section) ||
|
|
31
|
+
input.hasSaveMessage)
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function costSourceApplyLabel(
|
|
36
|
+
source: 'auto' | 'prometheus' | 'kubecost',
|
|
37
|
+
): string {
|
|
38
|
+
return source === 'prometheus' ? 'Apply source' : 'Test & apply source'
|
|
39
|
+
}
|
package/src/index.css
CHANGED
|
@@ -269,8 +269,18 @@ body {
|
|
|
269
269
|
.animate-transcript-enter {
|
|
270
270
|
animation: transcript-enter 180ms ease-out both;
|
|
271
271
|
}
|
|
272
|
+
|
|
273
|
+
@keyframes status-enter {
|
|
274
|
+
from { opacity: 0; }
|
|
275
|
+
to { opacity: 1; }
|
|
276
|
+
}
|
|
277
|
+
.animate-status-enter {
|
|
278
|
+
animation: status-enter 140ms ease-out both;
|
|
279
|
+
}
|
|
280
|
+
|
|
272
281
|
@media (prefers-reduced-motion: reduce) {
|
|
273
|
-
.animate-transcript-enter
|
|
282
|
+
.animate-transcript-enter,
|
|
283
|
+
.animate-status-enter {
|
|
274
284
|
animation: none;
|
|
275
285
|
}
|
|
276
286
|
}
|