mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
Render light-mode banner and callout text at full strength (#2485)
Light-mode text on tinted callouts, banners and selection cards drew at 25% alpha: CalloutCard titles and bodies in every tone (the Security overview's "Recommended hardening steps"), the Alerts thresholds help, the update-channel card titles, Patrol and Action banners. The Tailwind v3 config redefined each colour's 900 and 950 shades as 25% alpha so dark-mode backgrounds could tint, which also faded every light-mode text-*-900. The Tailwind 4 migration kept that parity by rewriting the usages to -900/25. Every light-mode text-*-900/25 and text-*-950/25, hover included, now uses the solid shade. Dark variants, backgrounds, borders and rings keep their tint, so dark mode is unchanged. Contract-Neutral: restores light-mode text colour tokens only; no behaviour, data, route or contract change
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"version": 1,
|
||||
"base_sha": "f909577fbf0cad505cb159d3c991333a615f0df9",
|
||||
"verified_at": "2026-10-05T02:03:21Z",
|
||||
"result": "passed",
|
||||
"changed_paths": [
|
||||
"frontend-modern/src/components/AI/AICostDashboard.tsx",
|
||||
"frontend-modern/src/components/AI/Chat/ApprovalCard.tsx",
|
||||
"frontend-modern/src/components/AI/Chat/MessageItem.tsx",
|
||||
"frontend-modern/src/components/AI/Chat/index.tsx",
|
||||
"frontend-modern/src/components/Alerts/EmailProviderSelect.tsx",
|
||||
"frontend-modern/src/components/Alerts/ThresholdsTable.tsx",
|
||||
"frontend-modern/src/components/Alerts/WebhookConfigForm.tsx",
|
||||
"frontend-modern/src/components/Discovery/AvailabilityProposalCard.tsx",
|
||||
"frontend-modern/src/components/Infrastructure/ResourceActionHistory.tsx",
|
||||
"frontend-modern/src/components/Infrastructure/ResourceOperatorStateSection.tsx",
|
||||
"frontend-modern/src/components/Settings/APITokenManager.tsx",
|
||||
"frontend-modern/src/components/Settings/APITokenManagerDialogs.tsx",
|
||||
"frontend-modern/src/components/Settings/AuditWebhookPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/DataHandlingPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx",
|
||||
"frontend-modern/src/components/Settings/InfrastructureSourcePicker.tsx",
|
||||
"frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx",
|
||||
"frontend-modern/src/components/Settings/SecurityOverviewPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/SettingsPageShell.tsx",
|
||||
"frontend-modern/src/components/Settings/UpdateInstallGuide.tsx",
|
||||
"frontend-modern/src/components/Settings/UpdatesSettingsPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/UserAssignmentsPanel.tsx",
|
||||
"frontend-modern/src/components/Settings/useProLicensePanelState.ts",
|
||||
"frontend-modern/src/components/SetupWizard/steps/WelcomeStep.tsx",
|
||||
"frontend-modern/src/components/UpdateBanner.tsx",
|
||||
"frontend-modern/src/components/patrol/ApprovalBanner.tsx",
|
||||
"frontend-modern/src/components/patrol/ApprovalSection.tsx",
|
||||
"frontend-modern/src/components/patrol/InvestigationMessages.tsx",
|
||||
"frontend-modern/src/components/shared/CalloutCard.tsx",
|
||||
"frontend-modern/src/components/shared/TlsVerificationWarningBanner.tsx",
|
||||
"frontend-modern/src/components/shared/buttonModel.ts",
|
||||
"frontend-modern/src/components/shared/selectionCardGroupModel.ts",
|
||||
"frontend-modern/src/features/actions/ActionDecisionPacket.tsx",
|
||||
"frontend-modern/src/features/actions/ActionReviewDialog.tsx",
|
||||
"frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolAttentionWorkbench.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolAutopilotAcknowledgementDialog.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceBanners.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceHeader.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx",
|
||||
"frontend-modern/src/features/patrol/PatrolObjectivesPanel.tsx",
|
||||
"frontend-modern/src/features/storageBackups/diskPresentation.ts",
|
||||
"frontend-modern/src/features/vmware/VmwarePageSurface.tsx",
|
||||
"frontend-modern/src/utils/licensePresentation.ts"
|
||||
],
|
||||
"content_sha256": {
|
||||
"frontend-modern/src/components/AI/AICostDashboard.tsx": "a62ca94c90bc91e17fd2612d36d7167e0abd2947436f310be48f7bdab9dc9078",
|
||||
"frontend-modern/src/components/AI/Chat/ApprovalCard.tsx": "e1b77b05da2a29166390ee17dd7aa2ed0d5d4a951e07961e944faeb7611c2638",
|
||||
"frontend-modern/src/components/AI/Chat/MessageItem.tsx": "67704b8321a20531bbc85403a36a6757fa4c5e9ec119017275d3f19481793853",
|
||||
"frontend-modern/src/components/AI/Chat/index.tsx": "c7f3b5629eafc661f4a2799acbcbcf069b4a9e82d9b41cb55d366a49dbeed3cf",
|
||||
"frontend-modern/src/components/Alerts/EmailProviderSelect.tsx": "574120ba54426bff04de0c27c5be9a9e43ae5e63d486556269c74f9aaf2bc8c6",
|
||||
"frontend-modern/src/components/Alerts/ThresholdsTable.tsx": "f26c74d485ce6150d346b765c5afac608c5965ee9ebf7f1c02a4f1a17fae3413",
|
||||
"frontend-modern/src/components/Alerts/WebhookConfigForm.tsx": "e88e1ca899d06edac6f817e0c4bd5dadddfba9e47ebfec95fa8cf8a649d7014b",
|
||||
"frontend-modern/src/components/Discovery/AvailabilityProposalCard.tsx": "3e802a5c3366f8395f728d684db60988cc30c035460354cd269c76719334f93c",
|
||||
"frontend-modern/src/components/Infrastructure/ResourceActionHistory.tsx": "85cff86139a44f7fa1e105384446544eaf0a573435f4fe116c5417fcec960616",
|
||||
"frontend-modern/src/components/Infrastructure/ResourceOperatorStateSection.tsx": "7676174aa82f275341d33a62cd0a3ce250107f3a4aa38d8743269cdeedc10d8c",
|
||||
"frontend-modern/src/components/Settings/APITokenManager.tsx": "e0635436c22cd345d2cb7a3e1db8f99c7c78eb8d6d6f790b0dc197774219d338",
|
||||
"frontend-modern/src/components/Settings/APITokenManagerDialogs.tsx": "6e47421f8b3beb59d1e01def1b6408ffb90d5a8eac4e92ba8b20bb3417612760",
|
||||
"frontend-modern/src/components/Settings/AuditWebhookPanel.tsx": "5477ea4a1e83b4075784f77105d84916c817d20026107feb67ff9c71575ea853",
|
||||
"frontend-modern/src/components/Settings/DataHandlingPanel.tsx": "a822bd5bdc4af59772fec2533d2fd31bfb02f807f23dd12b31f985e6821ec05c",
|
||||
"frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx": "9f5a2d35b1d1053dadeeb1dac9a969a8ecb3d1839fc5400619afcd7e162116f6",
|
||||
"frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx": "2e0ed1f0e5868723e13d6f8b55c520285f04a0193d3defd51a24a09ef347d94f",
|
||||
"frontend-modern/src/components/Settings/InfrastructureSourcePicker.tsx": "65d3b8936db63ac70f99bf4e40242e7547a0f3f4522c174e99d5a3d4c2b0fc77",
|
||||
"frontend-modern/src/components/Settings/NodeModalSetupGuideSection.tsx": "f49d30fda691d6b7329f519c0e644f4f55a090b40ad857cf3573b1398a7c36f1",
|
||||
"frontend-modern/src/components/Settings/SecurityOverviewPanel.tsx": "1301357c6095a957d37cbd9828938de4fd09d82a46355824f457b9ffc7653662",
|
||||
"frontend-modern/src/components/Settings/SettingsPageShell.tsx": "1cd0d27ce3ee4e157340942b997bf59359797173cadb6b050db496f821bee0f0",
|
||||
"frontend-modern/src/components/Settings/UpdateInstallGuide.tsx": "8baaf508f256ce88607efd3998f364a93ec130c265eaae3bf544f34cd305b94c",
|
||||
"frontend-modern/src/components/Settings/UpdatesSettingsPanel.tsx": "ae2ddb9a136739331e444aff73e948654c9077ba1756116f517f12a5b3c080d9",
|
||||
"frontend-modern/src/components/Settings/UserAssignmentsPanel.tsx": "68f7f454c886465cfeeecff540ce8f31af5df3bd30570102208f14bc52aa2c5c",
|
||||
"frontend-modern/src/components/Settings/useProLicensePanelState.ts": "014fd9de556af74ff2551b15d46df74a9c1b96710723b86895390d3ebba4aa1c",
|
||||
"frontend-modern/src/components/SetupWizard/steps/WelcomeStep.tsx": "916216841d26a06113e648b76af6e7548eeb5653e8f668f207f924f1502af30c",
|
||||
"frontend-modern/src/components/UpdateBanner.tsx": "d845bb4b8f096686e383ef0c9645f4741b13ca26e200437f144086b2318805af",
|
||||
"frontend-modern/src/components/patrol/ApprovalBanner.tsx": "d60a47251ec2e31a6294e71472f8e1f387b341e4071a85501240c9a2a51259d8",
|
||||
"frontend-modern/src/components/patrol/ApprovalSection.tsx": "e10509a60d988cfa99a430dbaa60821941e46675bd7e40d7e4a650b2ac4a1b88",
|
||||
"frontend-modern/src/components/patrol/InvestigationMessages.tsx": "1ffd77e185821ac31850a8cb8a9f0ae95d4645daa9e676d57a7bd9cdf191af6f",
|
||||
"frontend-modern/src/components/shared/CalloutCard.tsx": "cc8a9c0f3f6afff5ab908b2b366b5bf35654830589cee96249e9855210e222a4",
|
||||
"frontend-modern/src/components/shared/TlsVerificationWarningBanner.tsx": "83f60a1e536ddca211e4acceb08aa6a928672cc86936f8333cd4be27edcf9110",
|
||||
"frontend-modern/src/components/shared/buttonModel.ts": "d3d9341bd669e1823ae4566cb6c473c81269cd404ee0ddec79e0e60aeb028748",
|
||||
"frontend-modern/src/components/shared/selectionCardGroupModel.ts": "a289e079e949556d91e9c7629447ddba504f7b024c269c6e17068d01e9562413",
|
||||
"frontend-modern/src/features/actions/ActionDecisionPacket.tsx": "1bd8c7b8cc929ace1cf9f1d505c1ba30928d681f314a3e63ab89e36b66600ee1",
|
||||
"frontend-modern/src/features/actions/ActionReviewDialog.tsx": "9e37a0d32b8f9a0bb051ca2239624b963641b2a2d47e8f776ca3f4571be56ca9",
|
||||
"frontend-modern/src/features/alerts/AlertDeadManDestinationSection.tsx": "98ac0feefcb93200019401037954fe11b603a4a8e708e219edc11138d36e4f17",
|
||||
"frontend-modern/src/features/patrol/PatrolAttentionWorkbench.tsx": "a37adba09e97accc240823bfa0e7e2c3b5182af8254b51524b893a5d70e868ba",
|
||||
"frontend-modern/src/features/patrol/PatrolAutopilotAcknowledgementDialog.tsx": "cccaf1577b2e87dde34e6e86dc2fae211a1b5bc994f5d8bc6b9aef9e7ef5a836",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceBanners.tsx": "637245636f965fcfb9552d83c74d87578b261b9fcee5ba5f9ffc293282060341",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceHeader.tsx": "f70c38f961118d7f01ea9a2967a285fe5a7ee3690f84fcbc0d3ac329daf4d6ee",
|
||||
"frontend-modern/src/features/patrol/PatrolIntelligenceWorkspace.tsx": "bb130227a29b4639613abf965113ab6a8c1d260ab35072d2d598791361c7360d",
|
||||
"frontend-modern/src/features/patrol/PatrolObjectivesPanel.tsx": "64f6c34b4c5d2e284f1d312fc1a80c763245a11d22628a41fc92ffbadbddc8da",
|
||||
"frontend-modern/src/features/storageBackups/diskPresentation.ts": "acede3bda0c8e85233370e956da9a81a432e5c1637ef04f4e27d642361e7bcd4",
|
||||
"frontend-modern/src/features/vmware/VmwarePageSurface.tsx": "c1ef786960f15e4bd3090da6656b79df32d461f3631c01ada68bfc867307c236",
|
||||
"frontend-modern/src/utils/licensePresentation.ts": "e0bb3dc230b3bb74cd98f9d1c6e6f4a033a59c42f56a4606436e4b4fe0d7c66e"
|
||||
},
|
||||
"routes": [
|
||||
"/alerts/thresholds/proxmox",
|
||||
"/settings/security-overview",
|
||||
"/settings/system-updates",
|
||||
"/patrol",
|
||||
"/actions"
|
||||
],
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900
|
||||
},
|
||||
{
|
||||
"width": 390,
|
||||
"height": 844
|
||||
}
|
||||
],
|
||||
"states": [
|
||||
"Light mode before: computed text colour alpha 0.25 on the thresholds help banner (4 lines), the Security overview callout title, and the Stable update-channel card title",
|
||||
"Light mode after: zero elements with text alpha below 0.5 on all five routes; titles and bodies render in solid 900 shades",
|
||||
"Dark mode after: callout, help banner and channel card unchanged (dark: variants untouched)",
|
||||
"Phone 390: thresholds help banner and security callout readable"
|
||||
],
|
||||
"interactions": [
|
||||
"Probed every visible text element computed colour alpha per route before and after",
|
||||
"Captured element screenshots in light and dark colour schemes"
|
||||
]
|
||||
}
|
||||
@@ -549,7 +549,7 @@
|
||||
"path": "src/components/Settings/DiscoverySettingsForm.tsx",
|
||||
"patterns": [
|
||||
"rounded-md border border-amber-200 bg-amber-50/80",
|
||||
"text-amber-900/25 dark:text-amber-100"
|
||||
"text-amber-900 dark:text-amber-100"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -644,14 +644,14 @@
|
||||
"path": "src/features/platformPage/PlatformOutdatedAgentNotice.tsx",
|
||||
"patterns": [
|
||||
"rounded-lg border border-amber-300 bg-amber-50",
|
||||
"text-amber-900/25 underline-offset-2"
|
||||
"text-amber-900 underline-offset-2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "src/features/platformPage/PlatformOutdatedSensorSetupNotice.tsx",
|
||||
"patterns": [
|
||||
"rounded-lg border border-amber-300 bg-amber-50",
|
||||
"text-amber-900/25 underline-offset-2"
|
||||
"text-amber-900 underline-offset-2"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1283,9 +1283,9 @@
|
||||
"path": "src/components/Settings/InfrastructureInstallerSection.tsx",
|
||||
"patterns": [
|
||||
"inline-flex items-center justify-center rounded-md bg-emerald-600 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-emerald-700",
|
||||
"inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 transition-colors hover:bg-emerald-100",
|
||||
"inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100",
|
||||
"inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100"
|
||||
"inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 transition-colors hover:bg-emerald-100",
|
||||
"inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100",
|
||||
"inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1432,12 +1432,12 @@
|
||||
"patterns": [
|
||||
"flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-surface disabled:hover:text-muted",
|
||||
"shrink-0 p-2 hover:text-base-content rounded-md hover:bg-surface-hover transition-colors",
|
||||
"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60",
|
||||
"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60",
|
||||
"rounded-sm p-1 text-muted opacity-0 transition-opacity hover:bg-blue-100 hover:text-blue-600 focus:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-blue-900/25 dark:hover:text-blue-300",
|
||||
"order-2 flex h-9 w-9 shrink-0 items-center justify-center rounded-md hover:text-base-content hover:bg-surface-hover transition-colors sm:order-0",
|
||||
"flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25",
|
||||
"flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:text-amber-200 dark:hover:bg-amber-900/25",
|
||||
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 dark:text-blue-200 dark:hover:bg-blue-900/60",
|
||||
"flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25",
|
||||
"flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/25",
|
||||
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 dark:text-blue-200 dark:hover:bg-blue-900/60",
|
||||
"flex h-9 w-9 items-center justify-center rounded-md bg-blue-600 text-white shadow-xs transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-45",
|
||||
"flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content focus:outline-hidden focus:ring-2 focus:ring-blue-500/30"
|
||||
]
|
||||
@@ -1445,7 +1445,7 @@
|
||||
{
|
||||
"path": "src/components/AI/Chat/MessageItem.tsx",
|
||||
"patterns": [
|
||||
"inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30"
|
||||
"inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -3408,7 +3408,7 @@
|
||||
"scopes": ["src/components/AI/Chat/MessageItem.tsx"],
|
||||
"extensions": [".tsx"],
|
||||
"allPatterns": [
|
||||
"inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30"
|
||||
"inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30"
|
||||
],
|
||||
"legacyReason": "Retired migration debt. AI Chat queued message icon actions belong to ActionIconButton.",
|
||||
"allowedPaths": [],
|
||||
@@ -3457,7 +3457,7 @@
|
||||
"scopes": ["src/components/AI/Chat"],
|
||||
"extensions": [".tsx"],
|
||||
"allPatterns": [
|
||||
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25"
|
||||
"inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950"
|
||||
],
|
||||
"legacyReason": "Retired migration debt. AI Chat accent icon actions belong to ActionIconButton.",
|
||||
"allowedPaths": [],
|
||||
@@ -6103,7 +6103,7 @@
|
||||
"scopes": ["src/components/Settings", "src/features", "src/pages"],
|
||||
"extensions": [".tsx"],
|
||||
"allPatterns": [
|
||||
"rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25"
|
||||
"rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900"
|
||||
],
|
||||
"legacyReason": "Retired migration debt. Positive outlined settings actions belong to the shared Button primitive family.",
|
||||
"allowedPaths": [],
|
||||
@@ -6124,7 +6124,7 @@
|
||||
},
|
||||
"scopes": ["src/components/Settings", "src/features", "src/pages"],
|
||||
"extensions": [".tsx"],
|
||||
"allPatterns": ["rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25"],
|
||||
"allPatterns": ["rounded-md px-3 py-2 text-sm font-medium text-emerald-900"],
|
||||
"legacyReason": "Retired migration debt. Positive ghost settings actions belong to the shared Button primitive family.",
|
||||
"allowedPaths": [],
|
||||
"ignoredPaths": ["src/components/shared/Button.test.tsx"],
|
||||
|
||||
@@ -340,14 +340,14 @@ export const AICostDashboard: Component = () => {
|
||||
</Show>
|
||||
|
||||
<Show when={summary()?.truncated}>
|
||||
<div class="text-xs px-3 py-2 rounded-sm border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/25 text-blue-900/25 dark:text-blue-100">
|
||||
<div class="text-xs px-3 py-2 rounded-sm border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/25 text-blue-900 dark:text-blue-100">
|
||||
Showing the last {summary()?.effective_days} days due to a {summary()?.retention_days}
|
||||
-day retention window.
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={isOverBudget()}>
|
||||
<div class="text-xs px-3 py-2 rounded-sm border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/25 text-red-900/25 dark:text-red-100">
|
||||
<div class="text-xs px-3 py-2 rounded-sm border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/25 text-red-900 dark:text-red-100">
|
||||
Estimated spend ({formatUSD(estimatedTotalUSD() ?? 0)}) is above your budget (
|
||||
{formatUSD(budgetForRange() ?? 0)}).
|
||||
</div>
|
||||
@@ -357,7 +357,7 @@ export const AICostDashboard: Component = () => {
|
||||
<div
|
||||
role="alert"
|
||||
aria-live="polite"
|
||||
class="flex items-center justify-between gap-3 text-xs px-3 py-2 rounded-sm border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100"
|
||||
class="flex items-center justify-between gap-3 text-xs px-3 py-2 rounded-sm border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100"
|
||||
>
|
||||
<div class="truncate">Couldn’t refresh. Showing last loaded data. {loadError()}</div>
|
||||
<button
|
||||
|
||||
@@ -76,7 +76,7 @@ export const ApprovalCard: Component<ApprovalCardProps> = (props) => {
|
||||
{/* Command */}
|
||||
<div class="px-3 py-3 bg-amber-50 dark:bg-amber-900/25">
|
||||
<Show when={props.approval.description}>
|
||||
<p class="mb-3 text-xs leading-relaxed text-amber-900/25 dark:text-amber-100">
|
||||
<p class="mb-3 text-xs leading-relaxed text-amber-900 dark:text-amber-100">
|
||||
{props.approval.description}
|
||||
</p>
|
||||
</Show>
|
||||
|
||||
@@ -566,7 +566,7 @@ export const MessageItem: Component<MessageItemProps> = (props) => {
|
||||
<div
|
||||
class={`min-w-0 px-4 py-2.5 rounded-md rounded-br-sm shadow-xs ${
|
||||
isQueuedUserMessage()
|
||||
? 'border border-blue-200 bg-blue-50 text-blue-950/25 dark:border-blue-900/60 dark:bg-blue-950/30 dark:text-blue-100'
|
||||
? 'border border-blue-200 bg-blue-50 text-blue-950 dark:border-blue-900/60 dark:bg-blue-950/30 dark:text-blue-100'
|
||||
: 'bg-blue-600 text-white'
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -667,12 +667,12 @@ describe('AIChat', () => {
|
||||
for (const retiredActionIconShell of [
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-surface disabled:hover:text-muted',
|
||||
'shrink-0 p-2 hover:text-base-content rounded-md hover:bg-surface-hover transition-colors',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'rounded-sm p-1 text-muted opacity-0 transition-opacity hover:bg-blue-100 hover:text-blue-600 focus:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-blue-900/25 dark:hover:text-blue-300',
|
||||
'order-2 flex h-9 w-9 shrink-0 items-center justify-center rounded-md hover:text-base-content hover:bg-surface-hover transition-colors sm:order-0',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-9 w-9 items-center justify-center rounded-md bg-blue-600 text-white shadow-xs transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-45',
|
||||
'flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
'disabled:opacity-45',
|
||||
|
||||
@@ -137,7 +137,7 @@ describe('MessageItem', () => {
|
||||
'mt-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border-subtle bg-surface text-muted opacity-0 shadow-xs transition-opacity hover:text-base-content',
|
||||
);
|
||||
expect(messageItemSource).not.toContain(
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2758,7 +2758,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||
const currentStatusKind = createMemo(() => currentStatus()?.type);
|
||||
const currentStatusRowClass = createMemo(() => {
|
||||
if (currentStatusKind() === 'retrying') {
|
||||
return 'bg-amber-50/80 text-amber-900/25 dark:bg-amber-950/25 dark:text-amber-100';
|
||||
return 'bg-amber-50/80 text-amber-900 dark:bg-amber-950/25 dark:text-amber-100';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
@@ -4787,7 +4787,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||
<Show when={transcriptCopyFallback()}>
|
||||
{(fallback) => (
|
||||
<section
|
||||
class="border-b border-amber-200 bg-amber-50 px-4 py-3 text-amber-950/25 dark:border-amber-900/25 dark:bg-amber-950/30 dark:text-amber-100"
|
||||
class="border-b border-amber-200 bg-amber-50 px-4 py-3 text-amber-950 dark:border-amber-900/25 dark:bg-amber-950/30 dark:text-amber-100"
|
||||
aria-label={AI_CHAT_TRANSCRIPT_FALLBACK_TITLE}
|
||||
>
|
||||
<div class="mb-2 flex items-center justify-between gap-2">
|
||||
@@ -5130,7 +5130,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => updateControlLevel('controlled')}
|
||||
class="inline-flex shrink-0 items-center rounded-md border border-red-200 bg-surface px-2 py-1 text-[10px] font-medium text-red-700 transition-colors hover:bg-red-50 hover:text-red-900/25 dark:border-red-800 dark:bg-surface dark:text-red-200 dark:hover:bg-red-950/40"
|
||||
class="inline-flex shrink-0 items-center rounded-md border border-red-200 bg-surface px-2 py-1 text-[10px] font-medium text-red-700 transition-colors hover:bg-red-50 hover:text-red-900 dark:border-red-800 dark:bg-surface dark:text-red-200 dark:hover:bg-red-950/40"
|
||||
aria-label={AI_CHAT_SWITCH_TO_APPROVAL_LABEL}
|
||||
>
|
||||
Switch to Ask first
|
||||
@@ -5194,7 +5194,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||
};
|
||||
return (
|
||||
<div
|
||||
class="flex min-h-7 items-center gap-2 rounded-md bg-white/70 px-2 py-1 text-xs text-blue-900/25 outline-hidden transition-colors focus:bg-white focus:ring-2 focus:ring-blue-500/40 dark:bg-blue-900/30 dark:text-blue-100 dark:focus:bg-blue-900/50"
|
||||
class="flex min-h-7 items-center gap-2 rounded-md bg-white/70 px-2 py-1 text-xs text-blue-900 outline-hidden transition-colors focus:bg-white focus:ring-2 focus:ring-blue-500/40 dark:bg-blue-900/30 dark:text-blue-100 dark:focus:bg-blue-900/50"
|
||||
classList={{
|
||||
'bg-blue-50 ring-2 ring-blue-500/60 dark:bg-blue-800/50':
|
||||
queuedFollowUpCommandTargetId() === queued.id,
|
||||
|
||||
@@ -65,7 +65,7 @@ export function EmailProviderSelect(props: EmailProviderSelectProps) {
|
||||
minimumSeverity: `${fieldIdPrefix}-minimum-severity`,
|
||||
};
|
||||
const instructionBoxClass =
|
||||
'mt-2 rounded-sm border border-blue-200 bg-blue-50 px-3 py-2 text-xs leading-relaxed text-blue-900/25 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-200';
|
||||
'mt-2 rounded-sm border border-blue-200 bg-blue-50 px-3 py-2 text-xs leading-relaxed text-blue-900 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-200';
|
||||
|
||||
return (
|
||||
<div class="space-y-4 text-sm overflow-hidden">
|
||||
|
||||
@@ -120,7 +120,7 @@ export function ThresholdsTable(props: ThresholdsTableProps) {
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<div class="text-sm text-blue-900/25 dark:text-blue-100">
|
||||
<div class="text-sm text-blue-900 dark:text-blue-100">
|
||||
<p class="font-medium">{state.getAlertThresholdsHelpBanner().title}</p>
|
||||
<p class="mt-1">{state.getAlertThresholdsHelpBanner().toggleGuidance}</p>
|
||||
<p>{state.getAlertThresholdsHelpBanner().inheritanceGuidance}</p>
|
||||
|
||||
@@ -114,7 +114,7 @@ export function WebhookConfigForm(props: WebhookConfigFormProps) {
|
||||
|
||||
<Show when={props.currentTemplate()?.instructions}>
|
||||
<div class="mb-3 border-l-2 border-blue-300 pl-3 text-xs leading-relaxed text-blue-800 dark:border-blue-700 dark:text-blue-200">
|
||||
<h4 class="text-sm font-medium text-blue-900/25 dark:text-blue-100 mb-2">
|
||||
<h4 class="text-sm font-medium text-blue-900 dark:text-blue-100 mb-2">
|
||||
{getAlertWebhookSetupInstructionsTitle()}
|
||||
</h4>
|
||||
{props.currentTemplate()!.instructions}
|
||||
|
||||
@@ -228,7 +228,7 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<h3 class="text-sm font-semibold text-blue-950/25 dark:text-blue-100">
|
||||
<h3 class="text-sm font-semibold text-blue-950 dark:text-blue-100">
|
||||
Suggested service verification
|
||||
</h3>
|
||||
<span class="rounded-full border border-blue-300 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-blue-700 dark:border-blue-700 dark:text-blue-300">
|
||||
@@ -344,7 +344,7 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
<Show when={duplicate()}>
|
||||
{(match) => (
|
||||
<div
|
||||
class="mt-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-200"
|
||||
class="mt-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-200"
|
||||
role="status"
|
||||
>
|
||||
{match().kind === 'endpoint'
|
||||
@@ -359,7 +359,7 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={targets.error}>
|
||||
<div class="mt-3 rounded-md border border-red-300 bg-red-50 px-3 py-2 text-xs text-red-900/25 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200">
|
||||
<div class="mt-3 rounded-md border border-red-300 bg-red-50 px-3 py-2 text-xs text-red-900 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200">
|
||||
<p role="alert">
|
||||
Pulse could not check for existing active checks. Creating a check is unavailable
|
||||
until that safety check succeeds.
|
||||
@@ -380,8 +380,8 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
<div
|
||||
class={`mt-3 rounded-md border px-3 py-2 text-xs ${
|
||||
result().success
|
||||
? 'border-emerald-300 bg-emerald-50 text-emerald-900/25 dark:border-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-200'
|
||||
: 'border-red-300 bg-red-50 text-red-900/25 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200'
|
||||
? 'border-emerald-300 bg-emerald-50 text-emerald-900 dark:border-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-200'
|
||||
: 'border-red-300 bg-red-50 text-red-900 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200'
|
||||
}`}
|
||||
role={result().success ? 'status' : 'alert'}
|
||||
>
|
||||
@@ -392,7 +392,7 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
<Show when={createdTarget()}>
|
||||
{(created) => (
|
||||
<div
|
||||
class="mt-3 flex items-center gap-2 rounded-md border border-emerald-300 bg-emerald-50 px-3 py-2 text-xs text-emerald-900/25 dark:border-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-200"
|
||||
class="mt-3 flex items-center gap-2 rounded-md border border-emerald-300 bg-emerald-50 px-3 py-2 text-xs text-emerald-900 dark:border-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-200"
|
||||
role="status"
|
||||
>
|
||||
<CheckCircleIcon class="h-4 w-4" aria-hidden="true" />
|
||||
@@ -478,7 +478,7 @@ export const AvailabilityProposalCard: Component<AvailabilityProposalCardProps>
|
||||
</Show>
|
||||
<Show when={machineDiscoveries.error}>
|
||||
<p
|
||||
class="rounded-md border border-red-300 bg-red-50 p-4 text-sm text-red-900/25 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200"
|
||||
class="rounded-md border border-red-300 bg-red-50 p-4 text-sm text-red-900 dark:border-red-800 dark:bg-red-950/30 dark:text-red-200"
|
||||
role="alert"
|
||||
>
|
||||
Pulse could not load this machine’s assurance suggestions. Close this review and
|
||||
|
||||
@@ -162,7 +162,7 @@ const ActionHistoryRow: Component<{ audit: ActionAuditRecord }> = (props) => {
|
||||
{(presentation) => (
|
||||
<div
|
||||
data-testid="resource-apt-action-next-step"
|
||||
class="rounded-sm border border-blue-200 bg-blue-50 px-2 py-1 text-[10px] text-blue-900/25 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-200"
|
||||
class="rounded-sm border border-blue-200 bg-blue-50 px-2 py-1 text-[10px] text-blue-900 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-200"
|
||||
>
|
||||
<span class="font-medium">Next: </span>
|
||||
{presentation().nextStep}
|
||||
|
||||
@@ -1041,7 +1041,7 @@ export const ResourceOperatorStateSection: Component<ResourceOperatorStateSectio
|
||||
</div>
|
||||
|
||||
<Show when={confirmingLock()}>
|
||||
<div class="rounded-sm border border-red-300 bg-red-50 px-3 py-2.5 text-xs text-red-900/25 dark:border-red-800 dark:bg-red-950/25 dark:text-red-100">
|
||||
<div class="rounded-sm border border-red-300 bg-red-50 px-3 py-2.5 text-xs text-red-900 dark:border-red-800 dark:bg-red-950/25 dark:text-red-100">
|
||||
<p class="font-semibold">Lock this resource against all automated remediation?</p>
|
||||
<p class="mt-1 leading-relaxed">
|
||||
Pulse will refuse every dispatch targeting this resource, including approved actions
|
||||
@@ -1051,7 +1051,7 @@ export const ResourceOperatorStateSection: Component<ResourceOperatorStateSectio
|
||||
<button
|
||||
type="button"
|
||||
onClick={confirmLockToggle}
|
||||
class="rounded-sm border border-red-400 bg-white px-2 py-1 text-xs font-medium text-red-900/25 hover:bg-red-100 dark:border-red-700 dark:bg-red-900/25 dark:text-red-100 dark:hover:bg-red-800"
|
||||
class="rounded-sm border border-red-400 bg-white px-2 py-1 text-xs font-medium text-red-900 hover:bg-red-100 dark:border-red-700 dark:bg-red-900/25 dark:text-red-100 dark:hover:bg-red-800"
|
||||
>
|
||||
Lock this resource
|
||||
</button>
|
||||
|
||||
@@ -384,7 +384,7 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
|
||||
<p class="mt-1 text-xs text-muted">Limited access tokens with defined scopes</p>
|
||||
</div>
|
||||
<div
|
||||
class={`rounded-md border p-4 text-sm shadow-xs ${hasWildcardTokens() ? 'border-amber-300 bg-amber-50 text-amber-900/25 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100' : 'border-border bg-surface text-base-content'}`}
|
||||
class={`rounded-md border p-4 text-sm shadow-xs ${hasWildcardTokens() ? 'border-amber-300 bg-amber-50 text-amber-900 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100' : 'border-border bg-surface text-base-content'}`}
|
||||
>
|
||||
<div
|
||||
class={`text-[0.7rem] font-semibold uppercase tracking-wide ${
|
||||
@@ -440,7 +440,7 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
|
||||
<button
|
||||
onClick={reopenTokenDialog}
|
||||
disabled={!canManage()}
|
||||
class="font-medium underline decoration-green-500 underline-offset-2 hover:text-green-900/25 dark:hover:text-green-100"
|
||||
class="font-medium underline decoration-green-500 underline-offset-2 hover:text-green-900 dark:hover:text-green-100"
|
||||
>
|
||||
Show
|
||||
</button>
|
||||
@@ -448,7 +448,7 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
|
||||
onClick={() => {
|
||||
dismissNewToken();
|
||||
}}
|
||||
class="font-medium underline decoration-green-500 underline-offset-2 hover:text-green-900/25 dark:hover:text-green-100"
|
||||
class="font-medium underline decoration-green-500 underline-offset-2 hover:text-green-900 dark:hover:text-green-100"
|
||||
>
|
||||
Dismiss
|
||||
</button>
|
||||
@@ -461,7 +461,7 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
|
||||
newTokenRecord()?.scopes?.[0] === MONITORING_READ_SCOPE
|
||||
}
|
||||
>
|
||||
<div class="rounded-md border border-blue-200 bg-blue-50 p-4 text-sm text-blue-900/25 shadow-xs dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100">
|
||||
<div class="rounded-md border border-blue-200 bg-blue-50 p-4 text-sm text-blue-900 shadow-xs dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100">
|
||||
<div class="mb-2 font-semibold">Magic Kiosk Link</div>
|
||||
<p class="mb-3 text-xs text-blue-700 dark:text-blue-300">
|
||||
Use this link to open Pulse directly in Kiosk mode without logging in. Perfect for
|
||||
|
||||
@@ -53,7 +53,7 @@ export const APITokenManagerDialogs: Component<APITokenManagerDialogsProps> = (p
|
||||
class="mt-0.5 h-4 w-4 rounded-sm border-border text-amber-600 focus:ring-amber-500"
|
||||
/>
|
||||
<span>
|
||||
<span class="block font-semibold text-amber-900/25 dark:text-amber-100">
|
||||
<span class="block font-semibold text-amber-900 dark:text-amber-100">
|
||||
Full access
|
||||
</span>
|
||||
<span class="text-amber-800 dark:text-amber-200">
|
||||
|
||||
@@ -151,7 +151,7 @@ export const AuditWebhookPanel: Component<AuditWebhookPanelProps> = (props) => {
|
||||
<Shield size={22} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-base font-semibold text-amber-900/25 dark:text-amber-100 mb-1.5">
|
||||
<h3 class="text-base font-semibold text-amber-900 dark:text-amber-100 mb-1.5">
|
||||
{AUDIT_WEBHOOK_SECURITY_NOTE_TITLE}
|
||||
</h3>
|
||||
<p class="text-sm text-amber-800 dark:text-amber-200 leading-relaxed">
|
||||
|
||||
@@ -176,7 +176,7 @@ export const DataHandlingPanel: Component = () => {
|
||||
<div
|
||||
role="alert"
|
||||
aria-live="polite"
|
||||
class="rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900/25 dark:border-amber-800 dark:bg-amber-900/25 dark:text-amber-100"
|
||||
class="rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-900/25 dark:text-amber-100"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<AlertTriangle class="mt-0.5 h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
|
||||
@@ -555,9 +555,7 @@ export const DiagnosticsResultsPanel: Component<DiagnosticsResultsPanelProps> =
|
||||
>
|
||||
<div class="mb-3 flex items-center gap-3">
|
||||
<XCircle class="h-5 w-5 text-red-600 dark:text-red-400" />
|
||||
<h4 class="text-sm font-semibold text-red-900/25 dark:text-red-100">
|
||||
Errors Detected
|
||||
</h4>
|
||||
<h4 class="text-sm font-semibold text-red-900 dark:text-red-100">Errors Detected</h4>
|
||||
</div>
|
||||
<ul class="space-y-2 text-xs text-red-700 dark:text-red-300">
|
||||
<For each={props.diagnosticsData?.errors || []}>
|
||||
|
||||
@@ -155,7 +155,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
>
|
||||
<Show when={state.setupHandoff()}>
|
||||
{(handoff) => (
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-4 text-sm text-emerald-950/25 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50">
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-4 text-sm text-emerald-950 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50">
|
||||
<div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
||||
<div class="space-y-2">
|
||||
<p class="font-semibold">
|
||||
@@ -241,7 +241,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
</Show>
|
||||
|
||||
<div class="space-y-5">
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-950/25 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50">
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-950 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50">
|
||||
<p class="font-semibold">{presentation().recommendationTitle}</p>
|
||||
<p class="mt-1 text-xs text-emerald-800 dark:text-emerald-200">
|
||||
{presentation().recommendationDetail}
|
||||
@@ -251,7 +251,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
<Show when={focus() === 'agent'}>
|
||||
<div
|
||||
data-testid="proxmox-api-first-guidance"
|
||||
class="rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950/25 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-50"
|
||||
class="rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-50"
|
||||
>
|
||||
<p class="font-semibold">Adding Proxmox? Start with the API connection.</p>
|
||||
<p class="mt-1 text-xs text-blue-800 dark:text-blue-200">
|
||||
@@ -263,19 +263,19 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
<div class="mt-2 flex flex-wrap gap-x-4 gap-y-2 text-xs font-medium">
|
||||
<a
|
||||
href={buildInfrastructureOnboardingPath('pve')}
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900/25 dark:text-blue-200 dark:hover:text-white"
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900 dark:text-blue-200 dark:hover:text-white"
|
||||
>
|
||||
Connect Proxmox VE through the API
|
||||
</a>
|
||||
<a
|
||||
href={buildInfrastructureOnboardingPath('pbs')}
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900/25 dark:text-blue-200 dark:hover:text-white"
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900 dark:text-blue-200 dark:hover:text-white"
|
||||
>
|
||||
Connect PBS through the API
|
||||
</a>
|
||||
<a
|
||||
href="/docs/PRODUCTION_SECURITY"
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900/25 dark:text-blue-200 dark:hover:text-white"
|
||||
class="text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-900 dark:text-blue-200 dark:hover:text-white"
|
||||
>
|
||||
Review the production security model
|
||||
</a>
|
||||
@@ -284,7 +284,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
</Show>
|
||||
|
||||
<Show when={focus() === 'docker'}>
|
||||
<div class="rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950/25 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-50">
|
||||
<div class="rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-950 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-50">
|
||||
<p class="font-semibold">Docker inside Proxmox LXCs</p>
|
||||
<p class="mt-1 text-xs text-blue-800 dark:text-blue-200">
|
||||
Install the agent on the Proxmox node, not inside every LXC. In advanced options,
|
||||
@@ -633,7 +633,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-2 text-sm text-emerald-900/25 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-100">
|
||||
<div class="rounded-md border border-emerald-200 bg-emerald-50 px-4 py-2 text-sm text-emerald-900 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-100">
|
||||
<span class="font-medium">Config signing (optional)</span> — Require signed
|
||||
remote config payloads with{' '}
|
||||
<code>PULSE_AGENT_CONFIG_SIGNATURE_REQUIRED=true</code>. Provide keys via{' '}
|
||||
@@ -732,7 +732,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
</For>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3 rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-900/25 dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100">
|
||||
<div class="space-y-3 rounded-md border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-900 dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<h5 class="text-sm font-semibold">Check installation status</h5>
|
||||
<button
|
||||
@@ -764,7 +764,7 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
}
|
||||
}}
|
||||
placeholder="Hostname or agent ID"
|
||||
class="flex-1 rounded-md border border-blue-200 bg-surface px-3 py-2 text-sm text-blue-900/25 shadow-xs focus:border-blue-500 focus:outline-hidden focus:ring-2 focus:ring-blue-200 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-100 dark:focus:border-blue-300 dark:focus:ring-blue-800"
|
||||
class="flex-1 rounded-md border border-blue-200 bg-surface px-3 py-2 text-sm text-blue-900 shadow-xs focus:border-blue-500 focus:outline-hidden focus:ring-2 focus:ring-blue-200 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-100 dark:focus:border-blue-300 dark:focus:ring-blue-800"
|
||||
/>
|
||||
</div>
|
||||
<Show when={state.lookupError()}>
|
||||
@@ -783,8 +783,8 @@ export const InfrastructureInstallerSection: Component<InfrastructureInstallerSe
|
||||
<div
|
||||
class={`space-y-3 rounded-md border px-3 py-3 text-xs ${
|
||||
isConnected()
|
||||
? 'border-emerald-200 bg-emerald-50 text-emerald-950/25 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50'
|
||||
: 'border-blue-200 bg-surface text-blue-900/25 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-100'
|
||||
? 'border-emerald-200 bg-emerald-50 text-emerald-950 dark:border-emerald-700 dark:bg-emerald-900/25 dark:text-emerald-50'
|
||||
: 'border-blue-200 bg-surface text-blue-900 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-100'
|
||||
}`}
|
||||
>
|
||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
|
||||
|
||||
@@ -214,7 +214,7 @@ export const InfrastructureSourcePicker: Component<InfrastructureSourcePickerPro
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowAllSources(true)}
|
||||
class="mt-1 inline-flex items-center text-xs font-medium text-blue-700 hover:text-blue-900/25 hover:underline dark:text-blue-300 dark:hover:text-blue-100"
|
||||
class="mt-1 inline-flex items-center text-xs font-medium text-blue-700 hover:text-blue-900 hover:underline dark:text-blue-300 dark:hover:text-blue-100"
|
||||
>
|
||||
Show {hiddenCount()} more source{hiddenCount() === 1 ? '' : 's'}
|
||||
</button>
|
||||
|
||||
@@ -100,7 +100,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
<Show when={modalProps.nodeType === 'pve'}>
|
||||
<div class="space-y-3 text-xs">
|
||||
<div class="bg-blue-50 dark:bg-blue-900/25 border border-blue-200 dark:border-blue-800 rounded-md p-4">
|
||||
<h5 class="text-sm font-medium text-blue-900/25 dark:text-blue-100 mb-3 flex items-center gap-2">
|
||||
<h5 class="text-sm font-medium text-blue-900 dark:text-blue-100 mb-3 flex items-center gap-2">
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
@@ -329,7 +329,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
<Show when={state.quickSetupTokenHint().length > 0}>
|
||||
<div class="mt-2 text-xs text-blue-800 dark:text-blue-200">
|
||||
<span class="font-semibold">Setup token hint:</span>
|
||||
<code class="ml-1 font-mono break-all text-blue-900/25 dark:text-blue-100">
|
||||
<code class="ml-1 font-mono break-all text-blue-900 dark:text-blue-100">
|
||||
{state.quickSetupTokenHint()}
|
||||
</code>
|
||||
<Show when={state.quickSetupExpiry()}>
|
||||
@@ -584,7 +584,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
</div>
|
||||
|
||||
<div class="bg-green-50 dark:bg-green-900/25 border border-green-200 dark:border-green-800 rounded-md p-2">
|
||||
<p class="text-sm font-medium text-green-900/25 dark:text-green-100 mb-1">
|
||||
<p class="text-sm font-medium text-green-900 dark:text-green-100 mb-1">
|
||||
4. Add to Pulse with:
|
||||
</p>
|
||||
<ul class="text-xs text-green-800 dark:text-green-200 ml-4 list-disc">
|
||||
@@ -611,7 +611,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
<Show when={modalProps.nodeType === 'pbs'}>
|
||||
<div class="space-y-3 text-xs">
|
||||
<div class="bg-blue-50 dark:bg-blue-900/25 border border-blue-200 dark:border-blue-800 rounded-md p-4">
|
||||
<h5 class="text-sm font-medium text-blue-900/25 dark:text-blue-100 mb-3 flex items-center gap-2">
|
||||
<h5 class="text-sm font-medium text-blue-900 dark:text-blue-100 mb-3 flex items-center gap-2">
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
@@ -802,7 +802,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
<Show when={state.quickSetupTokenHint().length > 0}>
|
||||
<div class="mt-2 text-xs text-blue-800 dark:text-blue-200">
|
||||
<span class="font-semibold">Setup token hint:</span>
|
||||
<code class="ml-1 font-mono break-all text-blue-900/25 dark:text-blue-100">
|
||||
<code class="ml-1 font-mono break-all text-blue-900 dark:text-blue-100">
|
||||
{state.quickSetupTokenHint()}
|
||||
</code>
|
||||
<Show when={state.quickSetupExpiry()}>
|
||||
@@ -1053,7 +1053,7 @@ export const NodeModalSetupGuideSection: Component<NodeModalSetupGuideSectionPro
|
||||
</div>
|
||||
|
||||
<div class="bg-green-50 dark:bg-green-900/25 border border-green-200 dark:border-green-800 rounded-md p-2">
|
||||
<p class="text-sm font-medium text-green-900/25 dark:text-green-100 mb-1">
|
||||
<p class="text-sm font-medium text-green-900 dark:text-green-100 mb-1">
|
||||
4. Add to Pulse with:
|
||||
</p>
|
||||
<ul class="text-xs text-green-800 dark:text-green-200 ml-4 list-disc">
|
||||
|
||||
@@ -225,7 +225,7 @@ export const SecurityOverviewPanel: Component<SecurityOverviewPanelProps> = (pro
|
||||
<Shield class="w-5 h-5 text-blue-600 dark:text-blue-300" strokeWidth={2} />
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm font-semibold text-blue-900/25 dark:text-blue-100">
|
||||
<p class="text-sm font-semibold text-blue-900 dark:text-blue-100">
|
||||
Proxy Authentication Active
|
||||
</p>
|
||||
<p class="text-sm text-blue-700 dark:text-blue-300">
|
||||
|
||||
@@ -64,7 +64,7 @@ export const SettingsPageShell: Component<SettingsPageShellProps> = (props) => {
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="font-semibold text-amber-900/25 dark:text-amber-100">
|
||||
<p class="font-semibold text-amber-900 dark:text-amber-100">
|
||||
{unsavedChangesBanner().title}
|
||||
</p>
|
||||
<p class="text-sm text-amber-700 dark:text-amber-200 mt-0.5">
|
||||
|
||||
@@ -71,11 +71,11 @@ function InstallStep(props: { step: UpdateInstallStep; index: number }) {
|
||||
function readinessTone(status: UpdateReadiness['status']) {
|
||||
switch (status) {
|
||||
case 'blocked':
|
||||
return 'border-red-200 bg-red-50 text-red-900/25 dark:border-red-800 dark:bg-red-950/40 dark:text-red-100';
|
||||
return 'border-red-200 bg-red-50 text-red-900 dark:border-red-800 dark:bg-red-950/40 dark:text-red-100';
|
||||
case 'attention':
|
||||
return 'border-amber-200 bg-amber-50 text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100';
|
||||
return 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100';
|
||||
default:
|
||||
return 'border-green-200 bg-green-50 text-green-900/25 dark:border-green-800 dark:bg-green-950/40 dark:text-green-100';
|
||||
return 'border-green-200 bg-green-50 text-green-900 dark:border-green-800 dark:bg-green-950/40 dark:text-green-100';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ export const UpdateInstallGuide: Component<UpdateInstallGuideProps> = (props) =>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-base font-semibold text-green-900/25 dark:text-green-100">
|
||||
<h4 class="text-base font-semibold text-green-900 dark:text-green-100">
|
||||
{guide()!.headerTitle}
|
||||
</h4>
|
||||
<p class="text-xs text-green-700 dark:text-green-300">{guide()!.headerSummary}</p>
|
||||
|
||||
@@ -312,7 +312,7 @@ export const UpdatesSettingsPanel: Component<UpdatesSettingsPanelProps> = (props
|
||||
/>
|
||||
|
||||
<Show when={isPreviewChannel()}>
|
||||
<div class="rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100">
|
||||
<div class="rounded-md border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100">
|
||||
<p class="font-medium">{UPDATES_PANEL_COPY.previewChannelTitle}</p>
|
||||
<p class="mt-1 text-xs text-amber-800 dark:text-amber-200">
|
||||
{UPDATES_PANEL_COPY.previewChannelDescription}
|
||||
|
||||
@@ -226,7 +226,7 @@ export const UserAssignmentsPanel: Component = () => {
|
||||
revokes their active Pulse sessions.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/25 dark:text-amber-100">
|
||||
<div class="rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/25 dark:text-amber-100">
|
||||
This does not disable the account at the identity provider. A later authorized SSO
|
||||
login will create the user record again.
|
||||
</div>
|
||||
|
||||
@@ -630,10 +630,10 @@ describe('settings architecture guardrails', () => {
|
||||
'inline-flex items-center justify-center rounded-md bg-emerald-600 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-emerald-700',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain(
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 transition-colors hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 transition-colors hover:bg-emerald-100',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain(
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100',
|
||||
);
|
||||
|
||||
expect(ssoProvidersPanelSource).toContain(
|
||||
|
||||
@@ -201,7 +201,7 @@ export function useProLicensePanelState() {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
tone: 'border-sky-200 dark:border-sky-900/25 bg-sky-50 dark:bg-sky-950/25 text-sky-900/25 dark:text-sky-100',
|
||||
tone: 'border-sky-200 dark:border-sky-900/25 bg-sky-50 dark:bg-sky-950/25 text-sky-900 dark:text-sky-100',
|
||||
title: SELF_HOSTED_PRO_BILLING_PRESENTATION.planSelectionPromptTitle,
|
||||
body: SELF_HOSTED_PRO_BILLING_PRESENTATION.planSelectionPromptBody,
|
||||
actionLabel: SELF_HOSTED_PRO_BILLING_PRESENTATION.planSelectionPromptActionLabel,
|
||||
|
||||
@@ -220,7 +220,7 @@ export const WelcomeStep: Component<WelcomeStepProps> = (props) => {
|
||||
|
||||
<p class="text-xs text-muted">{t('setup.welcome.tokenHelp.afterVerify')}</p>
|
||||
<Show when={looksLikeBootstrapTokenSnapshot(props.bootstrapToken)}>
|
||||
<p class="rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100">
|
||||
<p class="rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100">
|
||||
{snapshotPasteHelp()}
|
||||
</p>
|
||||
</Show>
|
||||
|
||||
@@ -365,7 +365,7 @@ export function UpdateBanner() {
|
||||
href={PRO_RELEASE_ACCESS_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-block mt-2 underline hover:text-blue-900/25 dark:hover:text-blue-100"
|
||||
class="inline-block mt-2 underline hover:text-blue-900 dark:hover:text-blue-100"
|
||||
>
|
||||
Open Private Release Access →
|
||||
</a>
|
||||
|
||||
@@ -60,7 +60,7 @@ export const ApprovalBanner: Component = () => {
|
||||
<div>
|
||||
<Show when={pending().length === 1 && firstApproval()}>
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<span class="text-sm font-medium text-amber-900/25 dark:text-amber-100">
|
||||
<span class="text-sm font-medium text-amber-900 dark:text-amber-100">
|
||||
Action awaiting approval
|
||||
</span>
|
||||
<MetadataBadge
|
||||
@@ -81,7 +81,7 @@ export const ApprovalBanner: Component = () => {
|
||||
</p>
|
||||
</Show>
|
||||
<Show when={pending().length > 1}>
|
||||
<span class="text-sm font-medium text-amber-900/25 dark:text-amber-100">
|
||||
<span class="text-sm font-medium text-amber-900 dark:text-amber-100">
|
||||
{pending().length} actions awaiting your approval
|
||||
</span>
|
||||
</Show>
|
||||
|
||||
@@ -259,7 +259,7 @@ export const ApprovalSection: Component<ApprovalSectionProps> = (props) => {
|
||||
<Show when={!reviewedPlanHash()}>
|
||||
<div
|
||||
role="alert"
|
||||
class="rounded-sm border border-amber-300 bg-amber-50 p-2 text-sm text-amber-900/25 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
class="rounded-sm border border-amber-300 bg-amber-50 p-2 text-sm text-amber-900 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
>
|
||||
This action has no reviewed plan identity. Create a new plan before approving
|
||||
or running it.
|
||||
|
||||
@@ -70,7 +70,7 @@ export const InvestigationMessages: Component<InvestigationMessagesProps> = (pro
|
||||
<div
|
||||
class={`max-w-[85%] rounded-md px-3 py-2 ${
|
||||
msg.role === 'user'
|
||||
? 'bg-blue-100 dark:bg-blue-900/25 text-blue-900/25 dark:text-blue-100'
|
||||
? 'bg-blue-100 dark:bg-blue-900/25 text-blue-900 dark:text-blue-100'
|
||||
: msg.role === 'system'
|
||||
? 'bg-surface-alt text-muted text-xs'
|
||||
: 'bg-surface text-base-content'
|
||||
|
||||
@@ -151,11 +151,11 @@ describe('Button', () => {
|
||||
|
||||
const openInventoryButton = screen.getByRole('button', { name: 'Open inventory' });
|
||||
expect(openInventoryButton).toHaveClass('border-emerald-300');
|
||||
expect(openInventoryButton).toHaveClass('text-emerald-900/25');
|
||||
expect(openInventoryButton).toHaveClass('text-emerald-900');
|
||||
|
||||
const dismissButton = screen.getByRole('button', { name: 'Dismiss' });
|
||||
expect(dismissButton).toHaveClass('border-transparent');
|
||||
expect(dismissButton).toHaveClass('text-emerald-900/25');
|
||||
expect(dismissButton).toHaveClass('text-emerald-900');
|
||||
|
||||
const removeMemberButton = screen.getByRole('button', { name: 'Remove member' });
|
||||
expect(removeMemberButton).toHaveClass('border-transparent');
|
||||
|
||||
@@ -15,12 +15,12 @@ interface CalloutCardProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'tit
|
||||
|
||||
const toneClassByTone: Record<CalloutTone, string> = {
|
||||
danger:
|
||||
'border border-red-200 bg-red-50 text-red-900/25 dark:border-red-800 dark:bg-red-900/25 dark:text-red-100',
|
||||
info: 'border border-blue-200 bg-blue-50 text-blue-900/25 dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100',
|
||||
'border border-red-200 bg-red-50 text-red-900 dark:border-red-800 dark:bg-red-900/25 dark:text-red-100',
|
||||
info: 'border border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-800 dark:bg-blue-900/25 dark:text-blue-100',
|
||||
success:
|
||||
'border border-emerald-200 bg-emerald-50 text-emerald-900/25 dark:border-emerald-800 dark:bg-emerald-900/25 dark:text-emerald-100',
|
||||
'border border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-800 dark:bg-emerald-900/25 dark:text-emerald-100',
|
||||
warning:
|
||||
'border border-amber-200 bg-amber-50 text-amber-900/25 dark:border-amber-800 dark:bg-amber-900/25 dark:text-amber-100',
|
||||
'border border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-800 dark:bg-amber-900/25 dark:text-amber-100',
|
||||
};
|
||||
|
||||
const iconClassByTone: Record<CalloutTone, string> = {
|
||||
@@ -31,10 +31,10 @@ const iconClassByTone: Record<CalloutTone, string> = {
|
||||
};
|
||||
|
||||
const titleClassByTone: Record<CalloutTone, string> = {
|
||||
danger: 'text-lg font-semibold text-red-900/25 dark:text-red-100',
|
||||
info: 'text-lg font-semibold text-blue-900/25 dark:text-blue-100',
|
||||
success: 'text-lg font-semibold text-emerald-900/25 dark:text-emerald-100',
|
||||
warning: 'text-lg font-semibold text-amber-900/25 dark:text-amber-100',
|
||||
danger: 'text-lg font-semibold text-red-900 dark:text-red-100',
|
||||
info: 'text-lg font-semibold text-blue-900 dark:text-blue-100',
|
||||
success: 'text-lg font-semibold text-emerald-900 dark:text-emerald-100',
|
||||
warning: 'text-lg font-semibold text-amber-900 dark:text-amber-100',
|
||||
};
|
||||
|
||||
const descriptionClassByTone: Record<CalloutTone, string> = {
|
||||
@@ -62,10 +62,10 @@ const contentClassByScale: Record<CalloutScale, string> = {
|
||||
const titleClassByScaleAndTone: Record<CalloutScale, Record<CalloutTone, string>> = {
|
||||
default: titleClassByTone,
|
||||
compact: {
|
||||
danger: 'text-sm font-semibold text-red-900/25 dark:text-red-100',
|
||||
info: 'text-sm font-semibold text-blue-900/25 dark:text-blue-100',
|
||||
success: 'text-sm font-semibold text-emerald-900/25 dark:text-emerald-100',
|
||||
warning: 'text-sm font-semibold text-amber-900/25 dark:text-amber-100',
|
||||
danger: 'text-sm font-semibold text-red-900 dark:text-red-100',
|
||||
info: 'text-sm font-semibold text-blue-900 dark:text-blue-100',
|
||||
success: 'text-sm font-semibold text-emerald-900 dark:text-emerald-100',
|
||||
warning: 'text-sm font-semibold text-amber-900 dark:text-amber-100',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -3526,9 +3526,9 @@ describe('shared primitive guardrails', () => {
|
||||
path: 'src/components/Settings/InfrastructureInstallerSection.tsx',
|
||||
patterns: expect.arrayContaining([
|
||||
'inline-flex items-center justify-center rounded-md bg-emerald-600 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-emerald-700',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 transition-colors hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 transition-colors hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100',
|
||||
]),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
@@ -3784,7 +3784,7 @@ describe('shared primitive guardrails', () => {
|
||||
);
|
||||
expect(settingsSuccessOutlineActionGuard?.canonical?.export).toBe('getButtonClass');
|
||||
expect(settingsSuccessOutlineActionGuard?.allPatterns).toEqual([
|
||||
'rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25',
|
||||
'rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900',
|
||||
]);
|
||||
expect(settingsSuccessOutlineActionGuard?.scopes).toEqual([
|
||||
'src/components/Settings',
|
||||
@@ -3800,7 +3800,7 @@ describe('shared primitive guardrails', () => {
|
||||
);
|
||||
expect(settingsSuccessGhostActionGuard?.canonical?.export).toBe('getButtonClass');
|
||||
expect(settingsSuccessGhostActionGuard?.allPatterns).toEqual([
|
||||
'rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25',
|
||||
'rounded-md px-3 py-2 text-sm font-medium text-emerald-900',
|
||||
]);
|
||||
expect(settingsSuccessGhostActionGuard?.scopes).toEqual([
|
||||
'src/components/Settings',
|
||||
@@ -4088,12 +4088,12 @@ describe('shared primitive guardrails', () => {
|
||||
patterns: expect.arrayContaining([
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-surface disabled:hover:text-muted',
|
||||
'shrink-0 p-2 hover:text-base-content rounded-md hover:bg-surface-hover transition-colors',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'rounded-sm p-1 text-muted opacity-0 transition-opacity hover:bg-blue-100 hover:text-blue-600 focus:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-blue-900/25 dark:hover:text-blue-300',
|
||||
'order-2 flex h-9 w-9 shrink-0 items-center justify-center rounded-md hover:text-base-content hover:bg-surface-hover transition-colors sm:order-0',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-9 w-9 items-center justify-center rounded-md bg-blue-600 text-white shadow-xs transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-45',
|
||||
'flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
]),
|
||||
@@ -4101,7 +4101,7 @@ describe('shared primitive guardrails', () => {
|
||||
expect.objectContaining({
|
||||
path: 'src/components/AI/Chat/MessageItem.tsx',
|
||||
patterns: expect.arrayContaining([
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
]),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
@@ -4156,7 +4156,7 @@ describe('shared primitive guardrails', () => {
|
||||
);
|
||||
expect(aiChatMessageQueuedActionGuard?.canonical?.export).toBe('ActionIconButton');
|
||||
expect(aiChatMessageQueuedActionGuard?.allPatterns).toEqual([
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
]);
|
||||
expect(aiChatMessageQueuedActionGuard?.scopes).toEqual([
|
||||
'src/components/AI/Chat/MessageItem.tsx',
|
||||
@@ -4185,7 +4185,7 @@ describe('shared primitive guardrails', () => {
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content',
|
||||
]);
|
||||
expect(aiChatActionIconAccentGuard?.allPatterns).toEqual([
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950',
|
||||
]);
|
||||
expect(aiChatActionIconPrimarySendGuard?.allPatterns).toEqual([
|
||||
'flex h-9 w-9 items-center justify-center rounded-md bg-blue-600 text-white shadow-xs transition-colors hover:bg-blue-700',
|
||||
@@ -4373,12 +4373,12 @@ describe('shared primitive guardrails', () => {
|
||||
for (const retiredActionIconShell of [
|
||||
'flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-surface disabled:hover:text-muted',
|
||||
'shrink-0 p-2 hover:text-base-content rounded-md hover:bg-surface-hover transition-colors',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 disabled:cursor-wait disabled:opacity-70 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'rounded-sm p-1 text-muted opacity-0 transition-opacity hover:bg-blue-100 hover:text-blue-600 focus:opacity-100 group-hover:opacity-100 group-focus-within:opacity-100 dark:hover:bg-blue-900/25 dark:hover:text-blue-300',
|
||||
'order-2 flex h-9 w-9 shrink-0 items-center justify-center rounded-md hover:text-base-content hover:bg-surface-hover transition-colors sm:order-0',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900/25 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md border border-amber-200 bg-surface text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'flex h-7 w-7 items-center justify-center rounded-md text-amber-700 transition-colors hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'flex h-9 w-9 items-center justify-center rounded-md bg-blue-600 text-white shadow-xs transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-45',
|
||||
'flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border bg-surface text-muted transition-colors hover:border-border hover:bg-surface-hover hover:text-base-content focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
]) {
|
||||
@@ -4401,7 +4401,7 @@ describe('shared primitive guardrails', () => {
|
||||
'ml-auto inline-flex h-7 w-7 items-center justify-center rounded-md border border-border-subtle bg-surface text-muted opacity-0 shadow-xs transition-opacity hover:text-base-content',
|
||||
);
|
||||
expect(messageItemSource).not.toContain(
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950/25 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
'inline-flex h-5 w-5 items-center justify-center rounded-sm text-blue-700 transition-colors hover:bg-blue-100 hover:text-blue-950 focus:bg-blue-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500/30',
|
||||
);
|
||||
expect(toolExecutionBlockSource).toContain('@/components/shared/Button');
|
||||
expect(toolExecutionBlockSource).toContain('CopyValueButton');
|
||||
@@ -4510,13 +4510,13 @@ describe('shared primitive guardrails', () => {
|
||||
'inline-flex items-center justify-center rounded-md bg-emerald-600 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-emerald-700',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain(
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 transition-colors hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 transition-colors hover:bg-emerald-100',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain(
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md border border-emerald-300 bg-white px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain(
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900/25 hover:bg-emerald-100',
|
||||
'inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-emerald-900 hover:bg-emerald-100',
|
||||
);
|
||||
expect(infrastructureInstallerSectionSource).not.toContain('absolute right-2 top-2');
|
||||
expect(infrastructureInstallerSectionSource).not.toContain('bg-surface-hover p-2');
|
||||
@@ -5055,7 +5055,7 @@ describe('shared primitive guardrails', () => {
|
||||
]) {
|
||||
expect(source).toContain('InlineNotice');
|
||||
expect(source).not.toContain('rounded-lg border border-amber-300 bg-amber-50');
|
||||
expect(source).not.toContain('text-amber-900/25 underline-offset-2');
|
||||
expect(source).not.toContain('text-amber-900 underline-offset-2');
|
||||
}
|
||||
expect(platformOutdatedAgentNoticeSource).toContain(
|
||||
"import { presentationPolicyIsReadOnly } from '@/stores/sessionPresentationPolicy';",
|
||||
|
||||
@@ -6,7 +6,7 @@ interface TlsVerificationWarningBannerProps extends JSX.HTMLAttributes<HTMLDivEl
|
||||
}
|
||||
|
||||
const bannerClass =
|
||||
'rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900/25 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-200';
|
||||
'rounded-md border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 dark:border-amber-700 dark:bg-amber-950/40 dark:text-amber-200';
|
||||
|
||||
export function TlsVerificationWarningBanner(props: TlsVerificationWarningBannerProps) {
|
||||
const [local, rest] = splitProps(props, ['subject', 'remediation', 'class']);
|
||||
|
||||
+4
-4
@@ -188,13 +188,13 @@ describe('selectionCardGroupModel.branchcov0720pm', () => {
|
||||
|
||||
it("returns the green title class for variant='detail', active=true, tone='success' (tone === 'success' arm)", () => {
|
||||
expect(getSelectionCardTitleClass('detail', 'success', true)).toBe(
|
||||
'text-sm font-semibold text-green-900/25 dark:text-green-100',
|
||||
'text-sm font-semibold text-green-900 dark:text-green-100',
|
||||
);
|
||||
});
|
||||
|
||||
it("returns the blue title class for variant='detail', active=true, tone='accent' (else arm)", () => {
|
||||
expect(getSelectionCardTitleClass('detail', 'accent', true)).toBe(
|
||||
'text-sm font-semibold text-blue-900/25 dark:text-blue-100',
|
||||
'text-sm font-semibold text-blue-900 dark:text-blue-100',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -257,8 +257,8 @@ describe('selectionCardGroupModel.branchcov0720pm', () => {
|
||||
const result = getSelectionCardTitleClass('detail', tone, true);
|
||||
const titleToken =
|
||||
tone === 'success'
|
||||
? 'text-green-900/25 dark:text-green-100'
|
||||
: 'text-blue-900/25 dark:text-blue-100';
|
||||
? 'text-green-900 dark:text-green-100'
|
||||
: 'text-blue-900 dark:text-blue-100';
|
||||
expect(result).toContain(titleToken);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -37,9 +37,9 @@ export const BUTTON_VARIANT_CLASSES: Record<ButtonVariant, string> = {
|
||||
info: 'border border-blue-200 bg-blue-50 text-blue-700 hover:bg-blue-100 dark:border-blue-700 dark:bg-blue-900/25 dark:text-blue-200',
|
||||
success: 'border border-transparent bg-emerald-600 text-white shadow-xs hover:bg-emerald-700',
|
||||
successOutline:
|
||||
'border border-emerald-300 bg-white text-emerald-900/25 hover:bg-emerald-100 dark:border-emerald-700 dark:bg-emerald-950/25 dark:text-emerald-100 dark:hover:bg-emerald-800',
|
||||
'border border-emerald-300 bg-white text-emerald-900 hover:bg-emerald-100 dark:border-emerald-700 dark:bg-emerald-950/25 dark:text-emerald-100 dark:hover:bg-emerald-800',
|
||||
successGhost:
|
||||
'border border-transparent bg-transparent text-emerald-900/25 hover:bg-emerald-100 dark:text-emerald-100 dark:hover:bg-emerald-800',
|
||||
'border border-transparent bg-transparent text-emerald-900 hover:bg-emerald-100 dark:text-emerald-100 dark:hover:bg-emerald-800',
|
||||
secondary: 'border border-border bg-surface text-base-content shadow-xs hover:bg-surface-hover',
|
||||
danger: 'border border-transparent bg-rose-600 text-white shadow-xs hover:bg-rose-700',
|
||||
dangerOutline:
|
||||
@@ -144,13 +144,13 @@ export const ACTION_ICON_BUTTON_TONE_CLASSES: Record<ActionIconButtonTone, strin
|
||||
accent:
|
||||
'bg-blue-50 text-blue-600 hover:bg-blue-100 hover:text-blue-700 dark:bg-blue-900/25 dark:text-blue-400 dark:hover:bg-blue-950/25 dark:hover:text-blue-300',
|
||||
accentGhost:
|
||||
'text-blue-700 hover:bg-blue-100 hover:text-blue-950/25 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
'text-blue-700 hover:bg-blue-100 hover:text-blue-950 dark:text-blue-200 dark:hover:bg-blue-900/60',
|
||||
success:
|
||||
'bg-green-50 text-green-600 hover:bg-green-100 hover:text-green-700 dark:bg-green-900/25 dark:text-green-400 dark:hover:bg-green-950/25 dark:hover:text-green-300',
|
||||
warningGhost:
|
||||
'text-amber-700 hover:bg-amber-100 hover:text-amber-900/25 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'text-amber-700 hover:bg-amber-100 hover:text-amber-900 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
warningOutline:
|
||||
'border border-amber-200 bg-surface text-amber-700 hover:bg-amber-100 hover:text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
'border border-amber-200 bg-surface text-amber-700 hover:bg-amber-100 hover:text-amber-900 dark:border-amber-800 dark:bg-amber-950/60 dark:text-amber-200 dark:hover:bg-amber-900/25',
|
||||
infoGhost: 'text-cyan-500 hover:bg-cyan-100 dark:text-cyan-400 dark:hover:bg-cyan-800',
|
||||
danger:
|
||||
'text-red-600 hover:bg-red-50 hover:text-red-700 dark:text-red-400 dark:hover:bg-red-950/25 dark:hover:text-red-300',
|
||||
|
||||
@@ -96,8 +96,8 @@ export function getSelectionCardTitleClass(
|
||||
return 'text-sm font-semibold text-base-content';
|
||||
}
|
||||
return tone === 'success'
|
||||
? 'text-sm font-semibold text-green-900/25 dark:text-green-100'
|
||||
: 'text-sm font-semibold text-blue-900/25 dark:text-blue-100';
|
||||
? 'text-sm font-semibold text-green-900 dark:text-green-100'
|
||||
: 'text-sm font-semibold text-blue-900 dark:text-blue-100';
|
||||
}
|
||||
|
||||
export function getSelectionCardDescriptionClass(variant: SelectionCardGroupVariant): string {
|
||||
|
||||
@@ -333,7 +333,7 @@ export const ActionDecisionPacket: Component<{
|
||||
{(presentation) => (
|
||||
<div
|
||||
data-testid="apt-action-next-step"
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-4 text-sm text-blue-900/25 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-200"
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-4 text-sm text-blue-900 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-200"
|
||||
>
|
||||
<div class="font-semibold">What to do next</div>
|
||||
<p class="mt-1">{presentation().nextStep}</p>
|
||||
|
||||
@@ -533,7 +533,7 @@ export const ActionReviewDialog: Component<{
|
||||
<div
|
||||
role="alert"
|
||||
data-testid="action-review-invalid"
|
||||
class="mt-4 rounded-sm border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900/25 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
class="mt-4 rounded-sm border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
>
|
||||
{invalidActionMessage()}
|
||||
</div>
|
||||
|
||||
@@ -26,19 +26,19 @@ const statusPresentation: Record<DeadManStatus['state'], { label: string; class:
|
||||
},
|
||||
delivery_failed: {
|
||||
label: 'Delivery failing',
|
||||
class: 'bg-amber-100 text-amber-900/25 dark:bg-amber-900/25 dark:text-amber-100',
|
||||
class: 'bg-amber-100 text-amber-900 dark:bg-amber-900/25 dark:text-amber-100',
|
||||
},
|
||||
monitor_stalled: {
|
||||
label: 'Monitoring stalled',
|
||||
class: 'bg-red-100 text-red-900/25 dark:bg-red-900/25 dark:text-red-100',
|
||||
class: 'bg-red-100 text-red-900 dark:bg-red-900/25 dark:text-red-100',
|
||||
},
|
||||
misconfigured: {
|
||||
label: 'Configuration invalid',
|
||||
class: 'bg-red-100 text-red-900/25 dark:bg-red-900/25 dark:text-red-100',
|
||||
class: 'bg-red-100 text-red-900 dark:bg-red-900/25 dark:text-red-100',
|
||||
},
|
||||
configuration_unavailable: {
|
||||
label: 'Configuration unavailable',
|
||||
class: 'bg-red-100 text-red-900/25 dark:bg-red-900/25 dark:text-red-100',
|
||||
class: 'bg-red-100 text-red-900 dark:bg-red-900/25 dark:text-red-100',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -187,7 +187,7 @@ export function AlertDeadManDestinationSection(props: AlertDeadManDestinationSec
|
||||
</Show>
|
||||
|
||||
<Show when={status()?.lastError}>
|
||||
<p class="rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900/25 dark:border-amber-700 dark:bg-amber-950/25 dark:text-amber-100">
|
||||
<p class="rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-700 dark:bg-amber-950/25 dark:text-amber-100">
|
||||
{status()!.lastError}
|
||||
</p>
|
||||
</Show>
|
||||
|
||||
@@ -986,7 +986,7 @@ function AttentionDetail(props: {
|
||||
</p>
|
||||
<Show when={getAttentionFlappingPresentation(loaded().item.flapping)}>
|
||||
{(flapping) => (
|
||||
<p class="mt-2 flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50/70 px-3 py-2 text-xs leading-5 text-amber-900/25 dark:border-amber-900/25 dark:bg-amber-950/30 dark:text-amber-200">
|
||||
<p class="mt-2 flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50/70 px-3 py-2 text-xs leading-5 text-amber-900 dark:border-amber-900/25 dark:bg-amber-950/30 dark:text-amber-200">
|
||||
<RepeatIcon class="mt-0.5 h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
<span>{flapping().detail}</span>
|
||||
</p>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const PatrolAutopilotAcknowledgementDialog: Component<{ state: PatrolInte
|
||||
</Button>
|
||||
</header>
|
||||
<div class="overflow-y-auto px-5 py-4">
|
||||
<div class="rounded-lg border border-amber-300 bg-amber-50 p-4 text-sm text-amber-950/25 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100">
|
||||
<div class="rounded-lg border border-amber-300 bg-amber-50 p-4 text-sm text-amber-950 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100">
|
||||
<p class="font-semibold">
|
||||
Autopilot may execute eligible infrastructure actions without asking each time.
|
||||
</p>
|
||||
|
||||
@@ -78,7 +78,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<div class="shrink-0 border-b border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-800 dark:bg-amber-900/25">
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-amber-900/25 dark:text-amber-100">
|
||||
<p class="text-sm font-semibold text-amber-900 dark:text-amber-100">
|
||||
Patrol could not refresh
|
||||
</p>
|
||||
<p class="text-xs text-amber-700 dark:text-amber-300">
|
||||
@@ -89,7 +89,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
type="button"
|
||||
onClick={() => void state.handleRefreshPatrol()}
|
||||
disabled={state.isManualRefreshRunning()}
|
||||
class="inline-flex items-center justify-center gap-2 rounded-md border border-amber-200 bg-amber-100 px-3 py-1.5 text-xs font-semibold text-amber-900/25 transition-colors hover:bg-amber-200 disabled:cursor-wait disabled:opacity-60 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100 dark:hover:bg-amber-900/25"
|
||||
class="inline-flex items-center justify-center gap-2 rounded-md border border-amber-200 bg-amber-100 px-3 py-1.5 text-xs font-semibold text-amber-900 transition-colors hover:bg-amber-200 disabled:cursor-wait disabled:opacity-60 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100 dark:hover:bg-amber-900/25"
|
||||
>
|
||||
<RefreshCwIcon
|
||||
class={`h-3.5 w-3.5 ${state.isManualRefreshRunning() ? 'animate-spin' : ''}`}
|
||||
@@ -112,7 +112,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<div class="shrink-0 bg-blue-50 dark:bg-blue-900/25 border-b border-blue-200 dark:border-blue-800 px-3 py-2">
|
||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||
<p class="text-xs text-blue-700 dark:text-blue-300">
|
||||
<span class="font-semibold text-blue-900/25 dark:text-blue-100">
|
||||
<span class="font-semibold text-blue-900 dark:text-blue-100">
|
||||
{autonomyAvailability().title}.
|
||||
</span>{' '}
|
||||
{autonomyAvailability().body}
|
||||
@@ -167,8 +167,8 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<p
|
||||
class={`text-sm font-semibold ${
|
||||
state.patrolReadiness()?.status === 'not_ready'
|
||||
? 'text-red-900/25 dark:text-red-100'
|
||||
: 'text-amber-900/25 dark:text-amber-100'
|
||||
? 'text-red-900 dark:text-red-100'
|
||||
: 'text-amber-900 dark:text-amber-100'
|
||||
}`}
|
||||
>
|
||||
{state.patrolReadiness()?.status === 'not_ready'
|
||||
@@ -238,7 +238,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<Show when={shouldShowReadinessAction()}>
|
||||
<a
|
||||
href={setupAction().href}
|
||||
class="inline-flex items-center justify-center gap-2 px-3 py-1.5 text-xs font-semibold rounded-md border border-amber-200 bg-amber-100 text-amber-900/25 transition-colors hover:bg-amber-200 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100 dark:hover:bg-amber-900/25"
|
||||
class="inline-flex items-center justify-center gap-2 px-3 py-1.5 text-xs font-semibold rounded-md border border-amber-200 bg-amber-100 text-amber-900 transition-colors hover:bg-amber-200 dark:border-amber-700 dark:bg-amber-900/25 dark:text-amber-100 dark:hover:bg-amber-900/25"
|
||||
>
|
||||
<SettingsIcon class="w-3.5 h-3.5" />
|
||||
{setupAction().label}
|
||||
@@ -256,7 +256,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<ShieldAlertIcon class="w-4 h-4 text-amber-600 dark:text-amber-400" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-amber-900/25 dark:text-amber-100">
|
||||
<p class="text-sm font-semibold text-amber-900 dark:text-amber-100">
|
||||
Patrol paused
|
||||
</p>
|
||||
<p class="text-xs text-amber-700 dark:text-amber-300">{state.blockedReason()}</p>
|
||||
@@ -270,7 +270,7 @@ export function PatrolIntelligenceBanners(props: { state: PatrolIntelligenceStat
|
||||
<div class="flex items-center gap-2">
|
||||
<a
|
||||
href={setupAction().href}
|
||||
class="inline-flex items-center justify-center gap-2 px-3 py-1.5 text-xs font-semibold text-amber-900/25 dark:text-amber-100 bg-amber-100 dark:bg-amber-900/25 border border-amber-200 dark:border-amber-700 rounded-md hover:bg-amber-200 dark:hover:bg-amber-900/25 transition-colors"
|
||||
class="inline-flex items-center justify-center gap-2 px-3 py-1.5 text-xs font-semibold text-amber-900 dark:text-amber-100 bg-amber-100 dark:bg-amber-900/25 border border-amber-200 dark:border-amber-700 rounded-md hover:bg-amber-200 dark:hover:bg-amber-900/25 transition-colors"
|
||||
>
|
||||
<SettingsIcon class="w-3.5 h-3.5" />
|
||||
{setupAction().label}
|
||||
|
||||
@@ -230,7 +230,7 @@ export function PatrolIntelligenceHeader(props: { state: PatrolIntelligenceState
|
||||
<Show when={showAutonomyAvailabilityPrompt()}>
|
||||
<div class="mt-3 flex flex-col gap-3 rounded-md border border-blue-200 bg-blue-50 px-3 py-3 dark:border-blue-800 dark:bg-blue-950/40 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="min-w-0">
|
||||
<p class="text-sm font-semibold text-blue-950/25 dark:text-blue-100">
|
||||
<p class="text-sm font-semibold text-blue-950 dark:text-blue-100">
|
||||
{autonomyAvailability().title}
|
||||
</p>
|
||||
<p class="mt-1 text-xs leading-5 text-blue-800 dark:text-blue-200">
|
||||
@@ -258,7 +258,7 @@ export function PatrolIntelligenceHeader(props: { state: PatrolIntelligenceState
|
||||
<Show when={state.requestedAutonomyLevel() !== state.autonomyLevel()}>
|
||||
<div
|
||||
role="status"
|
||||
class="mt-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900/25 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
class="mt-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-200"
|
||||
>
|
||||
Requested {PATROL_AUTONOMY_POLICY_PRESENTATION[state.requestedAutonomyLevel()].label}.
|
||||
Effective mode is {selectedAutonomyPolicy().label}. Server status:{' '}
|
||||
|
||||
@@ -206,7 +206,7 @@ export function PatrolIntelligenceWorkspace(props: {
|
||||
<div class="flex flex-col gap-3 rounded-md border border-blue-200 bg-blue-50 px-3 py-3 text-blue-800 dark:border-blue-800 dark:bg-blue-950/40 dark:text-blue-200 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div class="min-w-0 space-y-1">
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs">
|
||||
<span class="font-semibold text-blue-950/25 dark:text-blue-100">
|
||||
<span class="font-semibold text-blue-950 dark:text-blue-100">
|
||||
Patrol run {formatRelativeTime(run().started_at, { compact: true })}
|
||||
</span>
|
||||
<span>{formatTriggerReason(run().trigger_reason)}</span>
|
||||
|
||||
@@ -229,7 +229,7 @@ export const PatrolObjectivesPanel: Component = () => {
|
||||
<Show
|
||||
when={!loadError()}
|
||||
fallback={
|
||||
<div class="rounded-lg border border-red-300 bg-red-50 p-4 text-sm text-red-900/25 dark:border-red-900/25 dark:bg-red-950/30 dark:text-red-100">
|
||||
<div class="rounded-lg border border-red-300 bg-red-50 p-4 text-sm text-red-900 dark:border-red-900/25 dark:bg-red-950/30 dark:text-red-100">
|
||||
<p>Patrol objectives could not be loaded.</p>
|
||||
<Button class="mt-3" size="sm" onClick={() => void loadObjectives()}>
|
||||
Try again
|
||||
|
||||
@@ -90,7 +90,7 @@ export const PHYSICAL_DISK_EMPTY_FALLBACK_TEXT_CLASS = 'text-sm text-muted';
|
||||
export const PHYSICAL_DISK_EMPTY_REQUIREMENTS_CLASS =
|
||||
'mt-4 rounded-md border border-blue-200 bg-blue-50 p-4 text-left dark:border-blue-800 dark:bg-blue-900/25';
|
||||
export const PHYSICAL_DISK_EMPTY_REQUIREMENTS_TITLE_CLASS =
|
||||
'mb-2 text-sm font-medium text-blue-900/25 dark:text-blue-100';
|
||||
'mb-2 text-sm font-medium text-blue-900 dark:text-blue-100';
|
||||
export const PHYSICAL_DISK_EMPTY_REQUIREMENTS_LIST_CLASS =
|
||||
'ml-4 list-decimal space-y-1.5 text-xs text-blue-800 dark:text-blue-200';
|
||||
export const PHYSICAL_DISK_EMPTY_REQUIREMENTS_NOTE_CLASS =
|
||||
|
||||
@@ -121,7 +121,7 @@ function VmwareInventoryCompletenessNotice(props: {
|
||||
return (
|
||||
<Show when={props.error || degradedSources().length > 0}>
|
||||
<div
|
||||
class="rounded-xs border border-amber-300 bg-amber-50/70 px-3 py-2.5 text-sm text-amber-950/25 dark:border-amber-900/70 dark:bg-amber-950/20 dark:text-amber-100"
|
||||
class="rounded-xs border border-amber-300 bg-amber-50/70 px-3 py-2.5 text-sm text-amber-950 dark:border-amber-900/70 dark:bg-amber-950/20 dark:text-amber-100"
|
||||
data-testid="vmware-inventory-completeness-notice"
|
||||
>
|
||||
<div class="flex items-start gap-2">
|
||||
|
||||
@@ -1222,7 +1222,7 @@ describe('licensePresentation', () => {
|
||||
source: 'purchase',
|
||||
}),
|
||||
).toEqual({
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900/25 dark:text-green-100',
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900 dark:text-green-100',
|
||||
title: 'Pulse Pro is now active',
|
||||
body: 'Checkout completed and Pulse Pro is active. Choose Patrol mode.',
|
||||
highlightsLabel: 'Available now on this instance',
|
||||
@@ -1258,7 +1258,7 @@ describe('licensePresentation', () => {
|
||||
source: 'manual',
|
||||
}),
|
||||
).toEqual({
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900/25 dark:text-green-100',
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900 dark:text-green-100',
|
||||
title: 'Relay is now active',
|
||||
body: 'The license key was accepted and this instance is now running Relay.',
|
||||
highlightsLabel: 'Available now on this instance',
|
||||
|
||||
@@ -476,7 +476,7 @@ export const getGrandfatheredPriceContinuityNotice = (
|
||||
}
|
||||
|
||||
return {
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900/25 dark:text-green-100',
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900 dark:text-green-100',
|
||||
title: 'Grandfathered v5 pricing',
|
||||
body: 'This migrated v5 Pro subscription keeps its existing recurring price until you cancel. Self-hosted monitoring and child-resource volume are not metered in current v6 self-hosted packaging. If you cancel and return later, current v6 pricing applies for paid features.',
|
||||
};
|
||||
@@ -988,8 +988,8 @@ export const getSelfHostedActivationSuccessPresentation = ({
|
||||
|
||||
return {
|
||||
tone: runtimeMismatch
|
||||
? 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100'
|
||||
: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900/25 dark:text-green-100',
|
||||
? 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100'
|
||||
: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900 dark:text-green-100',
|
||||
title: runtimeMismatch ? `${planLabel} license is active` : `${planLabel} is now active`,
|
||||
body:
|
||||
source === 'purchase'
|
||||
@@ -1075,7 +1075,7 @@ export const getCommercialMigrationNotice = (
|
||||
}
|
||||
|
||||
return {
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100',
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100',
|
||||
title: 'v5 license migration pending',
|
||||
body: `${body} ${actionText}`,
|
||||
};
|
||||
@@ -1116,7 +1116,7 @@ export const getCommercialMigrationNotice = (
|
||||
}
|
||||
|
||||
return {
|
||||
tone: 'border-red-200 dark:border-red-900/25 bg-red-50 dark:bg-red-900/25 text-red-900/25 dark:text-red-100',
|
||||
tone: 'border-red-200 dark:border-red-900/25 bg-red-50 dark:bg-red-900/25 text-red-900 dark:text-red-100',
|
||||
title: 'v5 license migration needs attention',
|
||||
body: `${body} ${actionText}`,
|
||||
};
|
||||
@@ -1126,31 +1126,31 @@ export const getPurchaseActivationNotice = (result?: string | null): LicenseInli
|
||||
switch ((result || '').trim().toLowerCase()) {
|
||||
case 'activated':
|
||||
return {
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900/25 dark:text-green-100',
|
||||
tone: 'border-green-200 dark:border-green-900/25 bg-green-50 dark:bg-green-900/25 text-green-900 dark:text-green-100',
|
||||
title: 'Plan activated',
|
||||
body: 'Pulse finished checkout and activated this instance automatically. The plan state below is live.',
|
||||
};
|
||||
case 'cancelled':
|
||||
return {
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100',
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100',
|
||||
title: 'Checkout cancelled',
|
||||
body: 'Checkout was cancelled before completion. The current plan state below is unchanged until you start the upgrade again.',
|
||||
};
|
||||
case 'expired':
|
||||
return {
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100',
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100',
|
||||
title: 'Upgrade return expired',
|
||||
body: 'That secure checkout return link expired or was already used. Start the upgrade again from this instance if you still need it.',
|
||||
};
|
||||
case 'failed':
|
||||
return {
|
||||
tone: 'border-red-200 dark:border-red-900/25 bg-red-50 dark:bg-red-900/25 text-red-900/25 dark:text-red-100',
|
||||
tone: 'border-red-200 dark:border-red-900/25 bg-red-50 dark:bg-red-900/25 text-red-900 dark:text-red-100',
|
||||
title: 'Plan needs attention',
|
||||
body: 'Checkout completed, but this instance could not apply the plan automatically. Review the current plan below, then open recovery if you already have a key from this purchase.',
|
||||
};
|
||||
case 'unavailable':
|
||||
return {
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900/25 dark:text-amber-100',
|
||||
tone: 'border-amber-200 dark:border-amber-900/25 bg-amber-50 dark:bg-amber-900/25 text-amber-900 dark:text-amber-100',
|
||||
title: 'Pulse Account unavailable',
|
||||
body: 'Pulse could not open the Pulse Account upgrade flow right now. The current plan state below is unchanged. Retry from this instance in a moment, or use recovery below if you already have a key.',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user