Skip to content

Commit db08317

Browse files
authored
Clarify private investigations and simplify sharing confirmation (#1650)
## Summary Make investigation privacy visible even when sharing controls are unavailable, and keep the sharing confirmation focused on its actual audience and capabilities rather than a redundant generic warning. ## Changes - Private hosted investigations without sharing controls retain a Private badge. Its tooltip says: “Only you can view this investigation. Other organization members don’t have access.” It does not guess why sharing is unavailable. - The sharing confirmation retains the disclosure that organization members can read the entire investigation and continue or stop it, along with its confirm/cancel actions. - Add an optional `showWarning` prop to the shared ConfirmDialog, defaulting to true. Only the investigation-sharing dialog opts out; existing warning and destructive-dialog defaults remain unchanged. ## OSS vs hosted These investigation affordances apply to hosted runs with visibility metadata, including SaaS and self-hosted Hub. Standalone OSS gains no sharing controls or permissions. Existing callers of the shared dialog retain their current behavior. ## Testing - Frontend typecheck and full `make build` (frontend, embed, Go binary). - 24 targeted tests: DiagnoseSurface plus three dialog-rendering tests covering disclosure/action preservation, opt-out, and unchanged warning/destructive defaults. - Visual-test: skipped for this small copy/affordance change; no new screenshots or live E2E claims. ## Release notes Companion settings-copy PR: skyhook-dev/radar-hub-web#283 (independent; no runtime dependency). Before publishing `radar-app`, publish the `k8s-ui` version containing `showWarning`, then raise radar-app's `@skyhook-io/k8s-ui` peer minimum (and matching lock metadata) to that actual release. Merely updating Cloud's installed package is not sufficient: the package contract must exclude incompatible older peers. Adopt the matching packages in Cloud. The version is intentionally not guessed before the release is selected. No backend API, authorization, retention, or investigation-execution changes. Package publication and deployment are not part of this PR.
1 parent 102bb47 commit db08317

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { type ReactNode } from 'react'
2+
import { renderToStaticMarkup } from 'react-dom/server'
3+
import { describe, expect, it, vi } from 'vitest'
4+
import { ConfirmDialog } from './ConfirmDialog'
5+
6+
vi.mock('./DialogPortal', () => ({
7+
DialogPortal: ({ children }: { children: ReactNode }) => <>{children}</>,
8+
}))
9+
10+
const props = {
11+
open: true,
12+
onClose: () => {},
13+
onConfirm: () => {},
14+
title: 'Share this investigation?',
15+
message: 'Organization members can read and continue this investigation.',
16+
confirmLabel: 'Share with organization',
17+
}
18+
19+
describe('ConfirmDialog warning disclosure', () => {
20+
it('can omit redundant boilerplate without removing the actual disclosure or actions', () => {
21+
const html = renderToStaticMarkup(<ConfirmDialog {...props} variant="warning" showWarning={false} />)
22+
expect(html).toContain(props.message)
23+
expect(html).toContain(props.confirmLabel)
24+
expect(html).toContain('Cancel')
25+
expect(html).not.toContain('Please confirm you want to proceed')
26+
})
27+
28+
it('preserves warning boilerplate by default for existing callers', () => {
29+
expect(renderToStaticMarkup(<ConfirmDialog {...props} variant="warning" />))
30+
.toContain('Please confirm you want to proceed with this action.')
31+
})
32+
33+
it('preserves the irreversible-action warning for destructive callers', () => {
34+
expect(renderToStaticMarkup(<ConfirmDialog {...props} />))
35+
.toContain('This action cannot be undone.')
36+
})
37+
})

‎packages/k8s-ui/src/components/ui/ConfirmDialog.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface ConfirmDialogProps {
1818
isLoading?: boolean
1919
isClosable?: boolean // Allow closing even when isLoading (e.g., for long-running ops the user can dismiss)
2020
confirmDisabled?: boolean // Block the confirm action while custom content is invalid (e.g., bad YAML)
21+
showWarning?: boolean
2122
className?: string
2223
children?: ReactNode // Optional custom content (e.g., checkboxes)
2324
}
@@ -35,6 +36,7 @@ export function ConfirmDialog({
3536
isLoading = false,
3637
isClosable = false,
3738
confirmDisabled = false,
39+
showWarning = true,
3840
className,
3941
children,
4042
}: ConfirmDialogProps) {
@@ -84,7 +86,7 @@ export function ConfirmDialog({
8486
)}
8587

8688
{/* Warning message — hidden once the action is in progress */}
87-
{!isLoading && !children && (
89+
{showWarning && !isLoading && !children && (
8890
<div className="p-4">
8991
<div
9092
className={clsx(

‎web/src/components/diagnose/DiagnoseSurface.tsx‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ function VisibilityControl({
224224
Organization
225225
</Badge>
226226
</Tooltip>
227+
) : run.visibility === "private" ? (
228+
<Tooltip content="Only you can view this investigation. Other organization members don’t have access." position="bottom">
229+
<Badge severity="neutral" size="sm" className="shrink-0">
230+
<Lock className="h-3 w-3" />
231+
Private
232+
</Badge>
233+
</Tooltip>
227234
) : null;
228235
}
229236
const shared = run.visibility === "organization";
@@ -277,6 +284,7 @@ function VisibilityControl({
277284
title="Share this investigation?"
278285
message="Everyone in your organization can read this entire investigation—including your questions and the logs and manifests Radar read—and can continue or stop it."
279286
confirmLabel="Share with organization"
287+
showWarning={false}
280288
variant="warning"
281289
isLoading={busy}
282290
/>

0 commit comments

Comments
 (0)