@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.
@@ -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
  }