@gntik-ai/blocks 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +34 -7
- package/dist/index.js +283 -109
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/builders/LogViewer/LogViewer.test.tsx +11 -0
- package/src/builders/LogViewer/LogViewer.tsx +28 -22
- package/src/forms/CredentialDisclosureDialog/CredentialDisclosureDialog.additional.test.tsx +467 -0
- package/src/forms/CredentialDisclosureDialog/CredentialDisclosureDialog.tsx +175 -106
- package/src/forms/CredentialDisclosureDialog/IssueOnClick.test.tsx +56 -0
- package/src/forms/CredentialDisclosureDialog/SecretCopy.tsx +83 -0
- package/src/forms/CredentialDisclosureDialog/block.meta.ts +1 -1
- package/src/forms/CredentialDisclosureDialog/examples/Inline.tsx +19 -0
- package/src/forms/CredentialDisclosureDialog/examples/IssueOnClick.tsx +87 -0
- package/src/forms/CredentialDisclosureDialog/examples/MultiSecret.tsx +29 -0
- package/src/forms/CredentialDisclosureDialog/focus.ts +18 -0
- package/src/forms/CredentialDisclosureDialog/types.ts +5 -0
- package/src/page-chrome/PageHeader/PageHeader.test.tsx +18 -0
- package/src/page-chrome/PageHeader/PageHeader.tsx +3 -1
- package/src/page-chrome/PageHeader/block.meta.ts +1 -1
- package/src/page-chrome/PageHeader/examples/Spanish.tsx +11 -0
- package/src/tables/DataTable/DataTable.labels.test.tsx +2 -0
- package/src/tables/DataTable/DataTable.locale.test.tsx +153 -0
- package/src/tables/DataTable/DataTable.server-pagination.test.tsx +1 -1
- package/src/tables/DataTable/DataTable.test.tsx +16 -0
- package/src/tables/DataTable/block.meta.ts +2 -0
- package/src/tables/DataTable/data-table-row.tsx +18 -2
- package/src/tables/DataTable/data-table-utils.ts +18 -4
- package/src/tables/DataTable/labels.ts +2 -0
- package/src/test/CredentialDisclosureDialog.compatibility.tsx +30 -0
package/dist/index.d.ts
CHANGED
|
@@ -1815,6 +1815,13 @@ export declare function CreateApiKeyDialog({ scopes, expiries, defaultExpiry, on
|
|
|
1815
1815
|
//#region src/forms/CreateApiKeyDialog/block.meta.d.ts
|
|
1816
1816
|
declare const meta$13: BlockMeta;
|
|
1817
1817
|
//#endregion
|
|
1818
|
+
//#region src/forms/CredentialDisclosureDialog/types.d.ts
|
|
1819
|
+
interface CredentialSecret {
|
|
1820
|
+
id: string;
|
|
1821
|
+
label: string;
|
|
1822
|
+
value: string;
|
|
1823
|
+
}
|
|
1824
|
+
//#endregion
|
|
1818
1825
|
//#region src/forms/CredentialDisclosureDialog/CredentialDisclosureDialog.d.ts
|
|
1819
1826
|
export interface CredentialDisclosure {
|
|
1820
1827
|
variant: 'stored' | 'fresh';
|
|
@@ -1824,9 +1831,21 @@ export interface CredentialDisclosure {
|
|
|
1824
1831
|
secret: string;
|
|
1825
1832
|
}
|
|
1826
1833
|
export interface CredentialDisclosureDialogProps {
|
|
1834
|
+
/** Additional masked values; ids must be unique, non-empty and not "secret". */
|
|
1835
|
+
additionalSecrets?: readonly CredentialSecret[];
|
|
1836
|
+
/** Mask a fresh primary secret; read at the start of each session. */
|
|
1837
|
+
maskFresh?: boolean;
|
|
1838
|
+
/** Redacted content below the secrets; clear secret-bearing content on close. */
|
|
1839
|
+
revealContent?: ReactNode;
|
|
1840
|
+
/** Presentation fixed for each non-null opening. Defaults to a modal dialog. */
|
|
1841
|
+
presentation?: 'dialog' | 'inline';
|
|
1842
|
+
/** Called after copying with the secret id (primary: "secret"), never its value. */
|
|
1843
|
+
onCopy?: (id: string) => void;
|
|
1844
|
+
/** Label-only success announcement override, used only in multi-secret mode. */
|
|
1845
|
+
copiedAnnouncementFor?: (label: string) => string;
|
|
1827
1846
|
/** Set only after a successful response. Leave null while pending or on failure. */
|
|
1828
1847
|
disclosure: CredentialDisclosure | null;
|
|
1829
|
-
/** Clear disclosure
|
|
1848
|
+
/** Clear disclosure, additionalSecrets and secret-bearing revealContent on dismissal. */
|
|
1830
1849
|
onClose: () => void;
|
|
1831
1850
|
/** Resolve the current row action at close time, including after list reloads. */
|
|
1832
1851
|
resolveReturnFocus?: () => HTMLElement | null;
|
|
@@ -1848,9 +1867,10 @@ export interface CredentialDisclosureDialogProps {
|
|
|
1848
1867
|
closeLabel?: string;
|
|
1849
1868
|
}
|
|
1850
1869
|
/**
|
|
1851
|
-
*
|
|
1852
|
-
*
|
|
1853
|
-
*
|
|
1870
|
+
* Render only successful responses. Keep disclosure null while pending or on failure.
|
|
1871
|
+
* On close, clear disclosure, additionalSecrets and any secret-bearing revealContent.
|
|
1872
|
+
* No pending/error state or internal secret retention. Retained dismissed sessions stay closed;
|
|
1873
|
+
* a changed credential/value or a null-to-value opening starts a new session.
|
|
1854
1874
|
*/
|
|
1855
1875
|
export declare function CredentialDisclosureDialog(props: CredentialDisclosureDialogProps): import("react").JSX.Element | null;
|
|
1856
1876
|
//#endregion
|
|
@@ -2904,8 +2924,13 @@ export declare function selectionState(visibleIds: readonly string[], selected:
|
|
|
2904
2924
|
/** Selects all of `ids` when not all are selected; otherwise clears them. Other selections are kept. */
|
|
2905
2925
|
export declare function toggleAll(ids: readonly string[], selected: ReadonlySet<string>): Set<string>;
|
|
2906
2926
|
export declare function toggleOne(id: string, selected: ReadonlySet<string>): Set<string>;
|
|
2907
|
-
/**
|
|
2908
|
-
export
|
|
2927
|
+
/** Optional locale and boolean text for default cells. */
|
|
2928
|
+
export interface DataTableCellFormatOptions {
|
|
2929
|
+
locale?: string;
|
|
2930
|
+
booleanLabels?: [trueLabel: string, falseLabel: string];
|
|
2931
|
+
}
|
|
2932
|
+
/** Default cell text for a raw value. Omitting options preserves the legacy output. */
|
|
2933
|
+
export declare function formatCell(value: CellValue, options?: DataTableCellFormatOptions): ReactNode;
|
|
2909
2934
|
/** Groups rows by a field key or by a function returning the group key. */
|
|
2910
2935
|
export type DataTableGroupBy<T> = Extract<keyof T, string> | ((row: T) => string | number | null | undefined);
|
|
2911
2936
|
/** One group of rows, in display order. */
|
|
@@ -2978,6 +3003,8 @@ export declare function PaginationFooter({ total, page: pageProp, defaultPage, o
|
|
|
2978
3003
|
//#region src/tables/DataTable/labels.d.ts
|
|
2979
3004
|
/** Per-instance table chrome, including the composed PaginationFooter. Caller data stays caller-owned. */
|
|
2980
3005
|
interface DataTableLabels extends PaginationFooterLabels {
|
|
3006
|
+
booleanTrue: string;
|
|
3007
|
+
booleanFalse: string;
|
|
2981
3008
|
/** Non-virtual table overflow region; virtualized regions keep the caller caption. */
|
|
2982
3009
|
scrollRegion: string;
|
|
2983
3010
|
selectionCount: (count: number) => string;
|
|
@@ -3730,5 +3757,5 @@ export declare function SessionsDevices({ sessions, onRevoke, onRevokeOthers, ti
|
|
|
3730
3757
|
//#region src/team/SessionsDevices/block.meta.d.ts
|
|
3731
3758
|
declare const meta$60: BlockMeta;
|
|
3732
3759
|
//#endregion
|
|
3733
|
-
export { type ApiKeyExpiry, type ApiKeyScope, type Assistant, type AssistantStatus, type AuthFormAccessibilityProps, type AuthHeaderProps, type AuthIdentifierConfig, type AuthSignUpField, type AuthSignUpValidationMessages, type AuthUnavailableState, type AuthValidationMessages, type BlockMeta, type CodeFile, type CodePanelMarker, type CodeProblem, type ColumnResizeHandleProps, type ColumnVisibilityMenuProps, type ColumnWidths, type ConfirmDestructiveDialogProps, type ConsoleEntry, type CostPoint, type DangerZoneAction, type DataTableCellEdit, type DataTableCellEditHandler, type DataTableCellEditResult, type DataTableLabels, type DataTableProps, type DataTableView, type DataTableViewState, ViewSwitcher as DataTableViewSwitcher, type ViewSwitcherProps as DataTableViewSwitcherProps, type DensityToggleProps, type DeploymentRow, type DeviceKind, type DeviceSession, type EditableMember, type EvalMetric, type EvalRow, type EventKind, type EventTone, type FeedbackAction, type FlowConnection, type FlowConnectionRejection, type FlowEdge, type FlowHandle, type FlowNode, type FlowNodeData, type FlowNodeKind, type FlowNodeRenderProps, type FlowNodeRenderer, type FlowTone, type FlowValidationIssue, type Invitation, type LogLevel, type LogLine, type MarketingAction, type Member, type ModelKey, type ModelKeyStatus, type MonacoReady, type NodeInspectorProps, type NodePaletteProps, type NotificationChannel, type NotificationEvent, type NotificationMatrixValue, type PageChromeAction, type PaletteItem, type PanelHeading, type PinSide, type PinnedColumns, type PlanSummaryProps, type ProblemSeverity, type Profile, type ProfileMetaItem, type RoleOption, type RunConsoleProps, type ScheduleEvent, type SpanDetailsProps, type SpanKind, type SsoProvider, type SummaryPlan, type TokenUsagePeriod, type TraceSpan, type TrafficRow, type UploadItem, type UploadStatus, type ValidationIssue, meta$1 as activityFeedMeta, meta$2 as agendaListMeta, meta$3 as appSidebarMeta, meta$4 as appTopbarMeta, meta$5 as assistantCardGridMeta, meta$6 as bulkActionBarMeta, meta$7 as chartCardMeta, meta$8 as codePanelMeta, meta$9 as commentThreadMeta, meta$10 as comparisonTableMeta, meta$11 as confirmDestructiveMeta, meta$12 as costBreakdownMeta, meta$13 as createApiKeyDialogMeta, meta$14 as credentialDisclosureDialogMeta, meta$15 as cursorPagerFooterMeta, meta$16 as dangerZoneMeta, meta$17 as dataTableMeta, meta$18 as dateRangeFilterMeta, meta$19 as descriptionListCardMeta, meta$20 as dialogWizardMeta, meta$21 as emptyStatesMeta, meta$22 as environmentBadgeMeta, meta$23 as errorPanelMeta, meta$24 as evaluationScorecardMeta, meta$25 as faqMeta, meta$26 as featureGridMeta, meta$27 as fileUploadPanelMeta, meta$28 as filterBarMeta, meta$29 as flowBuilderMeta, meta$30 as forgotPasswordFormMeta, meta$31 as formSectionMeta, meta$32 as globalSearchMeta, meta$33 as heroMeta, meta$34 as inlineCalloutMeta, meta$35 as inlineEditRowMeta, meta$36 as inviteMembersDialogMeta, meta$37 as invoiceTableMeta, meta$38 as kpiRowMeta, meta$39 as loadMoreFooterMeta, meta$40 as logViewerMeta, meta$41 as membersTableMeta, meta$42 as mfaChallengeMeta, meta$43 as modelKeysListMeta, meta$44 as monthCalendarMeta, meta$45 as notificationMatrixMeta, meta$46 as pageHeaderMeta, meta$47 as pageToolbarMeta, meta$48 as paginationFooterMeta, meta$49 as paymentMethodCardMeta, meta$50 as pendingInvitationsMeta, meta$51 as planCardMeta, meta$52 as planDefinitionCardMeta, meta$53 as pricingTableMeta, meta$54 as profileHeaderMeta, meta$55 as promptEditorMeta, meta$56 as quotaMetersMeta, meta$57 as resetPasswordFormMeta, meta$58 as resourceCardGridMeta, deviceSessions as sampleDeviceSessions, invitations$1 as sampleInvitations, members$1 as sampleMembers, profile$1 as sampleProfile, sampleEvents as sampleScheduleEvents, sampleToday as sampleScheduleToday, meta$59 as sectionHeaderMeta, meta$60 as sessionsDevicesMeta, meta$61 as settingsRowMeta, meta$62 as signInFormMeta, meta$63 as signUpFormMeta, meta$64 as skeletonsMeta, meta$65 as spendVsBudgetMeta, meta$66 as ssoButtonsMeta, meta$67 as statCardMeta, meta$68 as statusTimelineMeta, meta$69 as stickyActionBarMeta, meta$70 as subordinateListMeta, meta$71 as systemBannerMeta, meta$72 as timeSlotPickerMeta, meta$73 as tokenCostCardMeta, meta$74 as traceWaterfallMeta, meta$75 as truncatedCollectionFooterMeta, validationIssues$1 as validationIssues, meta$76 as validationSummaryMeta, meta$77 as weekCalendarMeta };
|
|
3760
|
+
export { type ApiKeyExpiry, type ApiKeyScope, type Assistant, type AssistantStatus, type AuthFormAccessibilityProps, type AuthHeaderProps, type AuthIdentifierConfig, type AuthSignUpField, type AuthSignUpValidationMessages, type AuthUnavailableState, type AuthValidationMessages, type BlockMeta, type CodeFile, type CodePanelMarker, type CodeProblem, type ColumnResizeHandleProps, type ColumnVisibilityMenuProps, type ColumnWidths, type ConfirmDestructiveDialogProps, type ConsoleEntry, type CostPoint, type CredentialSecret, type DangerZoneAction, type DataTableCellEdit, type DataTableCellEditHandler, type DataTableCellEditResult, type DataTableLabels, type DataTableProps, type DataTableView, type DataTableViewState, ViewSwitcher as DataTableViewSwitcher, type ViewSwitcherProps as DataTableViewSwitcherProps, type DensityToggleProps, type DeploymentRow, type DeviceKind, type DeviceSession, type EditableMember, type EvalMetric, type EvalRow, type EventKind, type EventTone, type FeedbackAction, type FlowConnection, type FlowConnectionRejection, type FlowEdge, type FlowHandle, type FlowNode, type FlowNodeData, type FlowNodeKind, type FlowNodeRenderProps, type FlowNodeRenderer, type FlowTone, type FlowValidationIssue, type Invitation, type LogLevel, type LogLine, type MarketingAction, type Member, type ModelKey, type ModelKeyStatus, type MonacoReady, type NodeInspectorProps, type NodePaletteProps, type NotificationChannel, type NotificationEvent, type NotificationMatrixValue, type PageChromeAction, type PaletteItem, type PanelHeading, type PinSide, type PinnedColumns, type PlanSummaryProps, type ProblemSeverity, type Profile, type ProfileMetaItem, type RoleOption, type RunConsoleProps, type ScheduleEvent, type SpanDetailsProps, type SpanKind, type SsoProvider, type SummaryPlan, type TokenUsagePeriod, type TraceSpan, type TrafficRow, type UploadItem, type UploadStatus, type ValidationIssue, meta$1 as activityFeedMeta, meta$2 as agendaListMeta, meta$3 as appSidebarMeta, meta$4 as appTopbarMeta, meta$5 as assistantCardGridMeta, meta$6 as bulkActionBarMeta, meta$7 as chartCardMeta, meta$8 as codePanelMeta, meta$9 as commentThreadMeta, meta$10 as comparisonTableMeta, meta$11 as confirmDestructiveMeta, meta$12 as costBreakdownMeta, meta$13 as createApiKeyDialogMeta, meta$14 as credentialDisclosureDialogMeta, meta$15 as cursorPagerFooterMeta, meta$16 as dangerZoneMeta, meta$17 as dataTableMeta, meta$18 as dateRangeFilterMeta, meta$19 as descriptionListCardMeta, meta$20 as dialogWizardMeta, meta$21 as emptyStatesMeta, meta$22 as environmentBadgeMeta, meta$23 as errorPanelMeta, meta$24 as evaluationScorecardMeta, meta$25 as faqMeta, meta$26 as featureGridMeta, meta$27 as fileUploadPanelMeta, meta$28 as filterBarMeta, meta$29 as flowBuilderMeta, meta$30 as forgotPasswordFormMeta, meta$31 as formSectionMeta, meta$32 as globalSearchMeta, meta$33 as heroMeta, meta$34 as inlineCalloutMeta, meta$35 as inlineEditRowMeta, meta$36 as inviteMembersDialogMeta, meta$37 as invoiceTableMeta, meta$38 as kpiRowMeta, meta$39 as loadMoreFooterMeta, meta$40 as logViewerMeta, meta$41 as membersTableMeta, meta$42 as mfaChallengeMeta, meta$43 as modelKeysListMeta, meta$44 as monthCalendarMeta, meta$45 as notificationMatrixMeta, meta$46 as pageHeaderMeta, meta$47 as pageToolbarMeta, meta$48 as paginationFooterMeta, meta$49 as paymentMethodCardMeta, meta$50 as pendingInvitationsMeta, meta$51 as planCardMeta, meta$52 as planDefinitionCardMeta, meta$53 as pricingTableMeta, meta$54 as profileHeaderMeta, meta$55 as promptEditorMeta, meta$56 as quotaMetersMeta, meta$57 as resetPasswordFormMeta, meta$58 as resourceCardGridMeta, deviceSessions as sampleDeviceSessions, invitations$1 as sampleInvitations, members$1 as sampleMembers, profile$1 as sampleProfile, sampleEvents as sampleScheduleEvents, sampleToday as sampleScheduleToday, meta$59 as sectionHeaderMeta, meta$60 as sessionsDevicesMeta, meta$61 as settingsRowMeta, meta$62 as signInFormMeta, meta$63 as signUpFormMeta, meta$64 as skeletonsMeta, meta$65 as spendVsBudgetMeta, meta$66 as ssoButtonsMeta, meta$67 as statCardMeta, meta$68 as statusTimelineMeta, meta$69 as stickyActionBarMeta, meta$70 as subordinateListMeta, meta$71 as systemBannerMeta, meta$72 as timeSlotPickerMeta, meta$73 as tokenCostCardMeta, meta$74 as traceWaterfallMeta, meta$75 as truncatedCollectionFooterMeta, validationIssues$1 as validationIssues, meta$76 as validationSummaryMeta, meta$77 as weekCalendarMeta };
|
|
3734
3761
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { Fragment, createElement, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
+
import { Fragment, createElement, useCallback, useEffect, useEffectEvent, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
3
3
|
import { Activity, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, BarChart3, Bookmark, Bot, Boxes, Braces, Building2, CalendarCheck, CalendarDays, Camera, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, CircleAlert, CircleCheck, CircleHelp, CircleX, Clock, Cog, Columns3, Copy, CreditCard, Database, Download, ExternalLink, Eye, FileCode, FileText, FolderKanban, FolderPlus, Gauge, GitBranch, Globe, HardDrive, Home, Inbox, Info, KeyRound, Layers, LayoutGrid, List, ListFilter, Lock, LogOut, Mail, MailCheck, MapPin, Minus, Monitor, MousePointerClick, Pencil, Play, PlugZap, Plus, RefreshCw, Rocket, RotateCcw, RotateCw, Rows2, Rows3, Search, SearchX, Server, ServerCrash, Settings, ShieldCheck, SlidersHorizontal, Smartphone, Sparkles, Table2, Tablet, Trash2, TriangleAlert, Upload, User, UserMinus, UserPlus, Users, Workflow, Wrench, X, Zap } from "@gntik-ai/icons";
|
|
4
|
-
import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Avatar, Badge, Breadcrumbs, Button, Card, CardAction, CardBody, CardDescription, CardHeader, CardTitle, Checkbox, CheckboxGroup, ClickableCard, CodeBlock, Collapsible, CollapsiblePanel, CollapsibleTrigger, CommandPalette, CommandPaletteTrigger, CopyButton, CursorPagination, DEFAULT_DATE_RANGE_PRESETS, DateRangePicker, DensityProvider, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, EmptyState, Field, FieldDescription, FieldError, FieldLabel, Fieldset, FieldsetLegend, IconButton, Input, Link, LiveAnnouncer, Logo, Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger, Meter, MoreMenu, NavList, NotificationsPopover, OtpInput, Pagination, PasswordInput, Progress, Radio, RadioGroup, ResizablePanel, ResizablePanelGroup, ResizeHandle, SecretField, Select, SelectContent, SelectItem, SelectTrigger, SimpleSelect, Skeleton, Slider, Sparkline, Spinner, StatusDot, StatusTag, Switch, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsList, TabsPanel, TabsTab, Textarea, ThemeCycleButton, ThemeSwitcher, Timestamp, Toggle, ToggleGroup, Token, TokenInput, Toolbar, ToolbarButton, ToolbarEnd, ToolbarInput, ToolbarSeparator, ToolbarStart, UserMenu, WizardLayout, WorkspaceSwitcher, buttonVariants, cn, nextSortDirection, tableVariants, toDate, useAnnounce, useDensity, useHasLiveAnnouncer, useI18n } from "@gntik-ai/ui";
|
|
4
|
+
import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Avatar, Badge, Breadcrumbs, Button, Card, CardAction, CardBody, CardDescription, CardHeader, CardTitle, Checkbox, CheckboxGroup, ClickableCard, CodeBlock, Collapsible, CollapsiblePanel, CollapsibleTrigger, CommandPalette, CommandPaletteTrigger, CopyButton, CursorPagination, DEFAULT_DATE_RANGE_PRESETS, DateRangePicker, DensityProvider, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, EmptyState, Field, FieldDescription, FieldError, FieldLabel, Fieldset, FieldsetLegend, IconButton, Input, Link, LiveAnnouncer, Logo, Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger, Meter, MoreMenu, NavList, NotificationsPopover, OtpInput, Pagination, PasswordInput, Progress, Radio, RadioGroup, ResizablePanel, ResizablePanelGroup, ResizeHandle, SecretField, Select, SelectContent, SelectItem, SelectTrigger, SimpleSelect, Skeleton, Slider, Sparkline, Spinner, StatusDot, StatusTag, Switch, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsList, TabsPanel, TabsTab, Textarea, ThemeCycleButton, ThemeSwitcher, Timestamp, Toggle, ToggleGroup, Token, TokenInput, Toolbar, ToolbarButton, ToolbarEnd, ToolbarInput, ToolbarSeparator, ToolbarStart, UserMenu, WizardLayout, WorkspaceSwitcher, buttonVariants, cn, foldText, matchRanges, nextSortDirection, tableVariants, toDate, useAnnounce, useDensity, useHasLiveAnnouncer, useI18n, useOptionalI18n } from "@gntik-ai/ui";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { AreaChart, BarChart, CHART_COLORS, DonutChart, Heatmap, LineChart, chartFmt } from "@gntik-ai/charts";
|
|
7
7
|
import { FLOW_TONES, FlowCanvas, KIND_CHIP, KindGlyph, useFlowState } from "@gntik-ai/flow";
|
|
@@ -5130,23 +5130,18 @@ const LEVEL_STYLE = {
|
|
|
5130
5130
|
}
|
|
5131
5131
|
};
|
|
5132
5132
|
/** Wraps case-insensitive matches of `query` in <mark>. */
|
|
5133
|
-
function highlight(text, query) {
|
|
5134
|
-
if (!query) return text;
|
|
5135
|
-
const lower = text.toLowerCase();
|
|
5136
|
-
const q = query.toLowerCase();
|
|
5133
|
+
function highlight(text, query, locale) {
|
|
5137
5134
|
const parts = [];
|
|
5138
5135
|
let from = 0;
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
if (at > from) parts.push(text.slice(from, at));
|
|
5136
|
+
for (const [start, end] of matchRanges(text, query, { locale })) {
|
|
5137
|
+
parts.push(text.slice(from, start));
|
|
5142
5138
|
parts.push(/* @__PURE__ */ jsx("mark", {
|
|
5143
5139
|
className: "rounded-sm bg-warning/30 text-foreground",
|
|
5144
|
-
children: text.slice(
|
|
5145
|
-
},
|
|
5146
|
-
from =
|
|
5147
|
-
at = lower.indexOf(q, from);
|
|
5140
|
+
children: text.slice(start, end)
|
|
5141
|
+
}, start));
|
|
5142
|
+
from = end;
|
|
5148
5143
|
}
|
|
5149
|
-
|
|
5144
|
+
parts.push(text.slice(from));
|
|
5150
5145
|
return parts;
|
|
5151
5146
|
}
|
|
5152
5147
|
function lineText(line) {
|
|
@@ -5158,6 +5153,7 @@ function lineText(line) {
|
|
|
5158
5153
|
* follow-tail and per-line copy.
|
|
5159
5154
|
*/
|
|
5160
5155
|
function LogViewer({ lines = logLines, title = "Logs", height = 360, rowHeight = 24, overscan = 8, defaultLevels = LOG_LEVELS, defaultFollow = true, onCopyLine, onSelectLine, selectedLineId, announceLines = true, titleAs: TitleTag = "h3", className }) {
|
|
5156
|
+
const { locale } = useI18n();
|
|
5161
5157
|
const titleId = useId();
|
|
5162
5158
|
const viewport = useRef(null);
|
|
5163
5159
|
const copyTimer = useRef(void 0);
|
|
@@ -5176,13 +5172,19 @@ function LogViewer({ lines = logLines, title = "Logs", height = 360, rowHeight =
|
|
|
5176
5172
|
for (const l of lines) c[l.level] += 1;
|
|
5177
5173
|
return c;
|
|
5178
5174
|
}, [lines]);
|
|
5175
|
+
const foldedLines = useMemo(() => lines.map((line) => ({
|
|
5176
|
+
line,
|
|
5177
|
+
message: foldText(line.message, locale),
|
|
5178
|
+
source: foldText(line.source ?? "", locale)
|
|
5179
|
+
})), [lines, locale]);
|
|
5179
5180
|
const visible = useMemo(() => {
|
|
5180
|
-
const q = query.trim()
|
|
5181
|
-
return
|
|
5181
|
+
const q = foldText(query.trim(), locale);
|
|
5182
|
+
return foldedLines.filter(({ line, message, source }) => levels.includes(line.level) && (!q || message.indexOf(q) !== -1 || source.indexOf(q) !== -1)).map(({ line }) => line);
|
|
5182
5183
|
}, [
|
|
5183
|
-
|
|
5184
|
+
foldedLines,
|
|
5184
5185
|
levels,
|
|
5185
|
-
query
|
|
5186
|
+
query,
|
|
5187
|
+
locale
|
|
5186
5188
|
]);
|
|
5187
5189
|
const total = visible.length * rowHeight;
|
|
5188
5190
|
const maxScroll = Math.max(0, total - height);
|
|
@@ -5298,13 +5300,13 @@ function LogViewer({ lines = logLines, title = "Logs", height = 360, rowHeight =
|
|
|
5298
5300
|
className: "hidden shrink-0 text-muted-foreground sm:inline",
|
|
5299
5301
|
children: [
|
|
5300
5302
|
"[",
|
|
5301
|
-
highlight(line.source, query
|
|
5303
|
+
highlight(line.source, query, locale),
|
|
5302
5304
|
"]"
|
|
5303
5305
|
]
|
|
5304
5306
|
}),
|
|
5305
5307
|
/* @__PURE__ */ jsx("span", {
|
|
5306
5308
|
className: "min-w-0 flex-1 truncate text-foreground",
|
|
5307
|
-
children: highlight(line.message, query
|
|
5309
|
+
children: highlight(line.message, query, locale)
|
|
5308
5310
|
}),
|
|
5309
5311
|
onSelectLine && /* @__PURE__ */ jsx(IconButton, {
|
|
5310
5312
|
size: "sm",
|
|
@@ -8056,11 +8058,78 @@ const meta$12 = {
|
|
|
8056
8058
|
]
|
|
8057
8059
|
};
|
|
8058
8060
|
//#endregion
|
|
8061
|
+
//#region src/forms/CredentialDisclosureDialog/SecretCopy.tsx
|
|
8062
|
+
/** Each secret owns feedback so simultaneous settlements cannot overwrite each other. */
|
|
8063
|
+
function SecretCopy({ secret, options, grouped = false, masked = true, warning }) {
|
|
8064
|
+
const { t } = useI18n();
|
|
8065
|
+
const [pending, setPending] = useState(false);
|
|
8066
|
+
const copied = options.copiedLabel ?? t("credentialDisclosure.copied");
|
|
8067
|
+
const content = /* @__PURE__ */ jsxs(LiveAnnouncer, { children: [
|
|
8068
|
+
warning,
|
|
8069
|
+
/* @__PURE__ */ jsx("div", {
|
|
8070
|
+
"data-kit-redact": true,
|
|
8071
|
+
children: masked ? /* @__PURE__ */ jsx(SecretField, {
|
|
8072
|
+
value: secret.value,
|
|
8073
|
+
copyable: false,
|
|
8074
|
+
"aria-label": secret.label,
|
|
8075
|
+
showLabel: options.showLabel ?? t("credentialDisclosure.show"),
|
|
8076
|
+
hideLabel: options.hideLabel ?? t("credentialDisclosure.hide")
|
|
8077
|
+
}) : /* @__PURE__ */ jsx(CodeBlock, {
|
|
8078
|
+
code: secret.value,
|
|
8079
|
+
copyable: false,
|
|
8080
|
+
label: secret.label,
|
|
8081
|
+
wrapToggle: false,
|
|
8082
|
+
defaultWrap: true
|
|
8083
|
+
})
|
|
8084
|
+
}),
|
|
8085
|
+
/* @__PURE__ */ jsx(CopyButton, {
|
|
8086
|
+
value: () => {
|
|
8087
|
+
if (grouped) setPending(true);
|
|
8088
|
+
return secret.value;
|
|
8089
|
+
},
|
|
8090
|
+
loading: grouped && pending,
|
|
8091
|
+
display: "label",
|
|
8092
|
+
label: options.copyLabel ?? t("credentialDisclosure.copy"),
|
|
8093
|
+
copiedLabel: copied,
|
|
8094
|
+
announcement: grouped ? options.copiedAnnouncementFor?.(secret.label) ?? `${secret.label}: ${copied}` : options.successAnnouncement ?? t("credentialDisclosure.success"),
|
|
8095
|
+
failureLabel: options.failureAnnouncement ?? t("credentialDisclosure.failure"),
|
|
8096
|
+
failureAnnouncement: options.failureAnnouncement ?? t("credentialDisclosure.failure"),
|
|
8097
|
+
failurePoliteness: "polite",
|
|
8098
|
+
onCopy: () => {
|
|
8099
|
+
if (grouped) setPending(false);
|
|
8100
|
+
options.onCopy?.(secret.id);
|
|
8101
|
+
},
|
|
8102
|
+
onCopyError: () => {
|
|
8103
|
+
if (grouped) setPending(false);
|
|
8104
|
+
}
|
|
8105
|
+
})
|
|
8106
|
+
] });
|
|
8107
|
+
return grouped ? /* @__PURE__ */ jsx("div", {
|
|
8108
|
+
role: "group",
|
|
8109
|
+
"aria-label": secret.label,
|
|
8110
|
+
children: content
|
|
8111
|
+
}) : content;
|
|
8112
|
+
}
|
|
8113
|
+
//#endregion
|
|
8114
|
+
//#region src/forms/CredentialDisclosureDialog/focus.ts
|
|
8115
|
+
/** Programmatic focus permits negative tabIndex, but never hidden, inert or disabled targets. */
|
|
8116
|
+
function usableFocusTarget(element) {
|
|
8117
|
+
if (!(element instanceof HTMLElement) || !element.isConnected || element === document.body) return false;
|
|
8118
|
+
if (element.matches(":disabled, [disabled], [aria-disabled=\"true\"], input[type=\"hidden\"]")) return false;
|
|
8119
|
+
for (let ancestor = element; ancestor; ancestor = ancestor.parentElement) {
|
|
8120
|
+
if (ancestor.hidden || ancestor.hasAttribute("inert") || ancestor.getAttribute("aria-disabled") === "true") return false;
|
|
8121
|
+
const style = getComputedStyle(ancestor);
|
|
8122
|
+
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse" || style.contentVisibility === "hidden") return false;
|
|
8123
|
+
}
|
|
8124
|
+
return element.tabIndex >= 0 || element.hasAttribute("tabindex") || element.isContentEditable;
|
|
8125
|
+
}
|
|
8126
|
+
//#endregion
|
|
8059
8127
|
//#region src/forms/CredentialDisclosureDialog/CredentialDisclosureDialog.tsx
|
|
8060
8128
|
/**
|
|
8061
|
-
*
|
|
8062
|
-
*
|
|
8063
|
-
*
|
|
8129
|
+
* Render only successful responses. Keep disclosure null while pending or on failure.
|
|
8130
|
+
* On close, clear disclosure, additionalSecrets and any secret-bearing revealContent.
|
|
8131
|
+
* No pending/error state or internal secret retention. Retained dismissed sessions stay closed;
|
|
8132
|
+
* a changed credential/value or a null-to-value opening starts a new session.
|
|
8064
8133
|
*/
|
|
8065
8134
|
function CredentialDisclosureDialog(props) {
|
|
8066
8135
|
if (!props.disclosure) return null;
|
|
@@ -8071,93 +8140,182 @@ function CredentialDisclosureDialog(props) {
|
|
|
8071
8140
|
}
|
|
8072
8141
|
function DisclosureOpening(props) {
|
|
8073
8142
|
const [opener] = useState(() => typeof document === "undefined" ? null : document.activeElement);
|
|
8143
|
+
const [presentation] = useState(props.presentation ?? "dialog");
|
|
8144
|
+
const root = useRef(null);
|
|
8145
|
+
const target = useRef(null);
|
|
8146
|
+
const active = useRef(opener);
|
|
8147
|
+
const started = useRef(false);
|
|
8148
|
+
const activeWasInside = useRef(false);
|
|
8149
|
+
const returnFocus = () => {
|
|
8150
|
+
const current = props.resolveReturnFocus?.();
|
|
8151
|
+
if (usableFocusTarget(current)) return current;
|
|
8152
|
+
const fallback = props.fallbackFocus?.();
|
|
8153
|
+
if (usableFocusTarget(fallback)) return fallback;
|
|
8154
|
+
return usableFocusTarget(opener) ? opener : false;
|
|
8155
|
+
};
|
|
8156
|
+
const restore = useEffectEvent(() => {
|
|
8157
|
+
if (root.current?.contains(document.activeElement)) {
|
|
8158
|
+
const element = returnFocus();
|
|
8159
|
+
if (element) element.focus();
|
|
8160
|
+
}
|
|
8161
|
+
});
|
|
8162
|
+
useLayoutEffect(() => {
|
|
8163
|
+
const track = () => {
|
|
8164
|
+
if (document.activeElement !== document.body) {
|
|
8165
|
+
active.current = document.activeElement;
|
|
8166
|
+
activeWasInside.current = root.current?.contains(document.activeElement) ?? false;
|
|
8167
|
+
}
|
|
8168
|
+
};
|
|
8169
|
+
document.addEventListener("focusin", track);
|
|
8170
|
+
return () => {
|
|
8171
|
+
document.removeEventListener("focusin", track);
|
|
8172
|
+
restore();
|
|
8173
|
+
};
|
|
8174
|
+
}, [presentation]);
|
|
8175
|
+
useLayoutEffect(() => {
|
|
8176
|
+
if (activeWasInside.current && active.current && !active.current.isConnected) target.current?.focus();
|
|
8177
|
+
});
|
|
8178
|
+
const seen = /* @__PURE__ */ new Set(["secret", ""]);
|
|
8179
|
+
const additionalSecrets = (props.additionalSecrets ?? []).filter(({ id }) => {
|
|
8180
|
+
if (seen.has(id)) return false;
|
|
8181
|
+
seen.add(id);
|
|
8182
|
+
return true;
|
|
8183
|
+
});
|
|
8074
8184
|
const { variant, credentialId, secret } = props.disclosure;
|
|
8075
8185
|
return /* @__PURE__ */ jsx(DisclosureSession, {
|
|
8076
8186
|
...props,
|
|
8077
|
-
|
|
8187
|
+
presentation,
|
|
8188
|
+
additionalSecrets,
|
|
8189
|
+
onRootRef: (node) => {
|
|
8190
|
+
root.current = node;
|
|
8191
|
+
},
|
|
8192
|
+
onTargetRef: (node) => {
|
|
8193
|
+
target.current = node;
|
|
8194
|
+
},
|
|
8195
|
+
onPopupRef: (node) => {
|
|
8196
|
+
root.current = node;
|
|
8197
|
+
target.current = node;
|
|
8198
|
+
},
|
|
8199
|
+
containsFocus: () => root.current?.contains(document.activeElement) ?? false,
|
|
8200
|
+
initialFocus: () => {
|
|
8201
|
+
const shouldFocus = !started.current || activeWasInside.current && !active.current?.isConnected;
|
|
8202
|
+
started.current = true;
|
|
8203
|
+
return shouldFocus ? root.current : false;
|
|
8204
|
+
},
|
|
8205
|
+
returnFocus
|
|
8078
8206
|
}, JSON.stringify([
|
|
8079
8207
|
variant,
|
|
8080
8208
|
credentialId,
|
|
8081
|
-
secret
|
|
8209
|
+
secret,
|
|
8210
|
+
...additionalSecrets.map(({ id, value }) => [id, value])
|
|
8082
8211
|
]));
|
|
8083
8212
|
}
|
|
8084
|
-
function DisclosureSession(
|
|
8213
|
+
function DisclosureSession(props) {
|
|
8085
8214
|
const { t } = useI18n();
|
|
8215
|
+
const { disclosure, onRootRef, onTargetRef, onPopupRef, initialFocus, containsFocus, presentation, additionalSecrets = [] } = props;
|
|
8086
8216
|
const [open, setOpen] = useState(true);
|
|
8087
|
-
const
|
|
8217
|
+
const [maskFresh] = useState(props.maskFresh ?? false);
|
|
8088
8218
|
const dismissed = useRef(false);
|
|
8089
|
-
const
|
|
8090
|
-
|
|
8091
|
-
if (
|
|
8092
|
-
|
|
8093
|
-
if (
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8219
|
+
const headingId = useId();
|
|
8220
|
+
const close = () => {
|
|
8221
|
+
if (dismissed.current) return;
|
|
8222
|
+
dismissed.current = true;
|
|
8223
|
+
if (presentation === "inline" && containsFocus()) {
|
|
8224
|
+
const element = props.returnFocus();
|
|
8225
|
+
if (element) element.focus();
|
|
8226
|
+
}
|
|
8227
|
+
setOpen(false);
|
|
8228
|
+
props.onClose();
|
|
8229
|
+
};
|
|
8230
|
+
const closeLabel = props.closeLabel ?? t("credentialDisclosure.close");
|
|
8231
|
+
const title = props.title ?? t("credentialDisclosure.title");
|
|
8232
|
+
const description = props.description ?? t("credentialDisclosure.description");
|
|
8233
|
+
const secretLabel = props.secretLabel ?? t("credentialDisclosure.secret");
|
|
8234
|
+
const warning = disclosure.variant === "fresh" ? /* @__PURE__ */ jsx(Alert, {
|
|
8235
|
+
role: presentation === "inline" ? "note" : "alert",
|
|
8236
|
+
tone: "warning",
|
|
8237
|
+
title: props.warningTitle ?? t("credentialDisclosure.warningTitle"),
|
|
8238
|
+
description: props.warningText ?? t("credentialDisclosure.warningText")
|
|
8239
|
+
}) : null;
|
|
8240
|
+
const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
8241
|
+
/* @__PURE__ */ jsxs("dl", {
|
|
8242
|
+
className: "grid grid-cols-2 gap-2 text-sm",
|
|
8243
|
+
children: [
|
|
8244
|
+
/* @__PURE__ */ jsx("dt", {
|
|
8245
|
+
className: "text-muted-foreground",
|
|
8246
|
+
children: props.credentialIdLabel ?? t("credentialDisclosure.credentialId")
|
|
8247
|
+
}),
|
|
8248
|
+
/* @__PURE__ */ jsx("dd", {
|
|
8249
|
+
className: "break-all font-mono",
|
|
8250
|
+
children: disclosure.credentialId
|
|
8251
|
+
}),
|
|
8252
|
+
/* @__PURE__ */ jsx("dt", {
|
|
8253
|
+
className: "text-muted-foreground",
|
|
8254
|
+
children: props.expiryLabel ?? t("credentialDisclosure.expiry")
|
|
8255
|
+
}),
|
|
8256
|
+
/* @__PURE__ */ jsx("dd", { children: disclosure.expiresAt })
|
|
8257
|
+
]
|
|
8258
|
+
}),
|
|
8259
|
+
/* @__PURE__ */ jsx(SecretCopy, {
|
|
8260
|
+
secret: {
|
|
8261
|
+
id: "secret",
|
|
8262
|
+
label: secretLabel,
|
|
8263
|
+
value: disclosure.secret
|
|
8264
|
+
},
|
|
8265
|
+
options: props,
|
|
8266
|
+
grouped: additionalSecrets.length > 0,
|
|
8267
|
+
masked: disclosure.variant === "stored" || maskFresh,
|
|
8268
|
+
warning
|
|
8269
|
+
}),
|
|
8270
|
+
additionalSecrets.map((secret) => /* @__PURE__ */ jsx(SecretCopy, {
|
|
8271
|
+
secret,
|
|
8272
|
+
options: props,
|
|
8273
|
+
grouped: true
|
|
8274
|
+
}, secret.id)),
|
|
8275
|
+
props.revealContent != null && /* @__PURE__ */ jsx("div", {
|
|
8276
|
+
"data-kit-redact": true,
|
|
8277
|
+
children: props.revealContent
|
|
8278
|
+
})
|
|
8279
|
+
] });
|
|
8280
|
+
if (presentation === "inline") {
|
|
8281
|
+
if (!open) return null;
|
|
8282
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
8283
|
+
ref: onRootRef,
|
|
8284
|
+
"aria-labelledby": headingId,
|
|
8285
|
+
className: "grid gap-4",
|
|
8286
|
+
children: [
|
|
8287
|
+
/* @__PURE__ */ jsx("h2", {
|
|
8288
|
+
id: headingId,
|
|
8289
|
+
tabIndex: -1,
|
|
8290
|
+
ref: onTargetRef,
|
|
8291
|
+
children: title
|
|
8292
|
+
}),
|
|
8293
|
+
/* @__PURE__ */ jsx("p", { children: description }),
|
|
8294
|
+
body,
|
|
8295
|
+
/* @__PURE__ */ jsx(Button, {
|
|
8296
|
+
variant: "secondary",
|
|
8297
|
+
onClick: close,
|
|
8298
|
+
children: closeLabel
|
|
8299
|
+
})
|
|
8300
|
+
]
|
|
8301
|
+
});
|
|
8302
|
+
}
|
|
8098
8303
|
return /* @__PURE__ */ jsx(Dialog, {
|
|
8099
8304
|
open,
|
|
8100
8305
|
onOpenChange: (next) => {
|
|
8101
|
-
if (!next
|
|
8102
|
-
dismissed.current = true;
|
|
8103
|
-
setOpen(false);
|
|
8104
|
-
onClose();
|
|
8105
|
-
}
|
|
8306
|
+
if (!next) close();
|
|
8106
8307
|
},
|
|
8107
8308
|
children: /* @__PURE__ */ jsx(DialogContent, {
|
|
8108
|
-
ref:
|
|
8109
|
-
initialFocus
|
|
8110
|
-
finalFocus: returnFocus,
|
|
8309
|
+
ref: onPopupRef,
|
|
8310
|
+
initialFocus,
|
|
8311
|
+
finalFocus: () => dismissed.current ? props.returnFocus() : false,
|
|
8111
8312
|
showClose: false,
|
|
8112
8313
|
closeLabel,
|
|
8113
8314
|
children: open && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
8114
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children:
|
|
8115
|
-
/* @__PURE__ */
|
|
8315
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })] }),
|
|
8316
|
+
/* @__PURE__ */ jsx(DialogBody, {
|
|
8116
8317
|
className: "grid gap-4",
|
|
8117
|
-
children:
|
|
8118
|
-
className: "grid grid-cols-2 gap-2 text-sm",
|
|
8119
|
-
children: [
|
|
8120
|
-
/* @__PURE__ */ jsx("dt", {
|
|
8121
|
-
className: "text-muted-foreground",
|
|
8122
|
-
children: labels.credentialIdLabel ?? t("credentialDisclosure.credentialId")
|
|
8123
|
-
}),
|
|
8124
|
-
/* @__PURE__ */ jsx("dd", {
|
|
8125
|
-
className: "break-all font-mono",
|
|
8126
|
-
children: disclosure.credentialId
|
|
8127
|
-
}),
|
|
8128
|
-
/* @__PURE__ */ jsx("dt", {
|
|
8129
|
-
className: "text-muted-foreground",
|
|
8130
|
-
children: labels.expiryLabel ?? t("credentialDisclosure.expiry")
|
|
8131
|
-
}),
|
|
8132
|
-
/* @__PURE__ */ jsx("dd", { children: disclosure.expiresAt })
|
|
8133
|
-
]
|
|
8134
|
-
}), /* @__PURE__ */ jsxs(LiveAnnouncer, { children: [disclosure.variant === "stored" ? /* @__PURE__ */ jsx(SecretField, {
|
|
8135
|
-
value: disclosure.secret,
|
|
8136
|
-
copyable: false,
|
|
8137
|
-
"aria-label": secretLabel,
|
|
8138
|
-
showLabel: labels.showLabel ?? t("credentialDisclosure.show"),
|
|
8139
|
-
hideLabel: labels.hideLabel ?? t("credentialDisclosure.hide")
|
|
8140
|
-
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Alert, {
|
|
8141
|
-
role: "alert",
|
|
8142
|
-
tone: "warning",
|
|
8143
|
-
title: labels.warningTitle ?? t("credentialDisclosure.warningTitle"),
|
|
8144
|
-
description: labels.warningText ?? t("credentialDisclosure.warningText")
|
|
8145
|
-
}), /* @__PURE__ */ jsx(CodeBlock, {
|
|
8146
|
-
code: disclosure.secret,
|
|
8147
|
-
copyable: false,
|
|
8148
|
-
label: secretLabel,
|
|
8149
|
-
wrapToggle: false,
|
|
8150
|
-
defaultWrap: true
|
|
8151
|
-
})] }), /* @__PURE__ */ jsx(CopyButton, {
|
|
8152
|
-
value: () => disclosure.secret,
|
|
8153
|
-
display: "label",
|
|
8154
|
-
label: labels.copyLabel ?? t("credentialDisclosure.copy"),
|
|
8155
|
-
copiedLabel: labels.copiedLabel ?? t("credentialDisclosure.copied"),
|
|
8156
|
-
announcement: labels.successAnnouncement ?? t("credentialDisclosure.success"),
|
|
8157
|
-
failureLabel: labels.failureAnnouncement ?? t("credentialDisclosure.failure"),
|
|
8158
|
-
failureAnnouncement: labels.failureAnnouncement ?? t("credentialDisclosure.failure"),
|
|
8159
|
-
failurePoliteness: "polite"
|
|
8160
|
-
})] })]
|
|
8318
|
+
children: body
|
|
8161
8319
|
}),
|
|
8162
8320
|
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(DialogClose, {
|
|
8163
8321
|
render: /* @__PURE__ */ jsx(Button, { variant: "secondary" }),
|
|
@@ -8167,24 +8325,13 @@ function DisclosureSession({ disclosure, onClose, resolveReturnFocus, fallbackFo
|
|
|
8167
8325
|
})
|
|
8168
8326
|
});
|
|
8169
8327
|
}
|
|
8170
|
-
/** Programmatic focus permits negative tabIndex, but never hidden, inert or disabled targets. */
|
|
8171
|
-
function usableFocusTarget(element) {
|
|
8172
|
-
if (!(element instanceof HTMLElement) || !element.isConnected || element === document.body) return false;
|
|
8173
|
-
if (element.matches(":disabled, [disabled], [aria-disabled=\"true\"], input[type=\"hidden\"]")) return false;
|
|
8174
|
-
for (let ancestor = element; ancestor; ancestor = ancestor.parentElement) {
|
|
8175
|
-
if (ancestor.hidden || ancestor.hasAttribute("inert") || ancestor.getAttribute("aria-disabled") === "true") return false;
|
|
8176
|
-
const style = getComputedStyle(ancestor);
|
|
8177
|
-
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse" || style.contentVisibility === "hidden") return false;
|
|
8178
|
-
}
|
|
8179
|
-
return element.tabIndex >= 0 || element.hasAttribute("tabindex") || element.isContentEditable;
|
|
8180
|
-
}
|
|
8181
8328
|
//#endregion
|
|
8182
8329
|
//#region src/forms/CredentialDisclosureDialog/block.meta.ts
|
|
8183
8330
|
const meta$13 = {
|
|
8184
8331
|
name: "Credential disclosure dialog",
|
|
8185
8332
|
family: "forms",
|
|
8186
8333
|
status: "beta",
|
|
8187
|
-
description: "Controlled disclosure for an existing credential. Set disclosure ({variant: stored | fresh, credentialId, expiresAt: caller-formatted ReactNode, secret}) only after a successful response; null renders nothing while pending or on failure. Clear disclosure
|
|
8334
|
+
description: "Controlled disclosure for an existing credential. Set disclosure ({variant: stored | fresh, credentialId, expiresAt: caller-formatted ReactNode, secret}) only after a successful response; null renders nothing while pending or on failure. Clear disclosure, additionalSecrets and secret-bearing revealContent in onClose to drop every secret; a fresh secret requires a new successful response before showing it again. No pending/error state or internal secret retention. Stored values start masked; each null-to-value opening or changed credentialId/secret resets masking and copy feedback. Fresh values use a non-copyable CodeBlock with a kit CopyButton and a replacement warning, or a masked SecretField when maskFresh is set at session start. Optional additionalSecrets ({id, label, value}) are always masked and use independent toggles and serialized copy actions; ids must be non-empty, unique and not secret, with the first duplicate winning. Multi-secret groups announce label plus copiedLabel, or copiedAnnouncementFor(label); onCopy(id) never receives a value. Every secret and the optional revealContent slot have data-kit-redact. The session key includes additional ids and values. presentation is dialog by default or inline, fixed until the next opening: inline is a named section, never traps focus or handles Escape, and its warning is a non-live note. Surviving focus stays; removing the focused slot or session control focuses the popup or inline heading. Focused inline unmounts return focus through the same resolvers. Dismissed retained props stay hidden; clear and re-set or change a session value to reopen. Optional English defaults through en/es i18n for title, description, credentialIdLabel, expiryLabel, secretLabel, showLabel, hideLabel, copyLabel, copiedLabel, successAnnouncement, failureAnnouncement, warningTitle, warningText and closeLabel. Copy results are announced politely, including manual-selection fallback. Popup initial focus and focus trapping use Base UI; at close, resolveReturnFocus() is validated for connection, visibility, enabled state and focusability, then fallbackFocus(), then the original opener. Synthetic fixtures only; the default Stored preview is masked and the Fresh preview starts closed.",
|
|
8188
8335
|
uses: [
|
|
8189
8336
|
"Dialog",
|
|
8190
8337
|
"SecretField",
|
|
@@ -9927,6 +10074,7 @@ const pageHeaderTabs = [
|
|
|
9927
10074
|
//#region src/page-chrome/PageHeader/PageHeader.tsx
|
|
9928
10075
|
/** Screen header: breadcrumb, title + status, description, meta row, actions and optional tabs. */
|
|
9929
10076
|
function PageHeader({ as: Root = "header", breadcrumbs = pageHeaderBreadcrumbs, title = "Deployments", titleRef, description = "Every build and release of this project across its environments.", status = "active", statuses, meta = pageHeaderMeta, actions = pageHeaderActions, tabs = pageHeaderTabs, tab, defaultTab, onTabChange, className }) {
|
|
10077
|
+
const { t } = useI18n();
|
|
9930
10078
|
const explicitPrimary = actions.findIndex((a) => a.variant === "primary");
|
|
9931
10079
|
const primaryIndex = explicitPrimary >= 0 ? explicitPrimary : actions.length - 1;
|
|
9932
10080
|
const primary = actions[primaryIndex];
|
|
@@ -10005,7 +10153,7 @@ function PageHeader({ as: Root = "header", breadcrumbs = pageHeaderBreadcrumbs,
|
|
|
10005
10153
|
onValueChange: (value) => onTabChange?.(String(value)),
|
|
10006
10154
|
className: "mt-5",
|
|
10007
10155
|
children: /* @__PURE__ */ jsx(TabsList, {
|
|
10008
|
-
"aria-label": "
|
|
10156
|
+
"aria-label": t("pageHeader.sections"),
|
|
10009
10157
|
className: "overflow-x-auto",
|
|
10010
10158
|
children: tabs.map((t) => /* @__PURE__ */ jsx(TabsTab, {
|
|
10011
10159
|
value: t.value,
|
|
@@ -10023,7 +10171,7 @@ const meta$45 = {
|
|
|
10023
10171
|
name: "Page header",
|
|
10024
10172
|
family: "page-chrome",
|
|
10025
10173
|
status: "beta",
|
|
10026
|
-
description: "Screen header with breadcrumb, title and status, description, meta row, actions that fold into a MoreMenu on small screens, and optional navigation tabs. titleRef targets the h1 for titleRef.current.focus(), adding tabIndex=-1 only when supplied so the title stays outside the Tab order. In a StatusLayout heading slot use as=\"div\" and disable breadcrumb, meta, tabs, actions, status and description fixtures; the slot supplies the page’s only h1.",
|
|
10174
|
+
description: "Screen header with breadcrumb, title and status, description, meta row, actions that fold into a MoreMenu on small screens, and optional navigation tabs. titleRef targets the h1 for titleRef.current.focus(), adding tabIndex=-1 only when supplied so the title stays outside the Tab order. In a StatusLayout heading slot use as=\"div\" and disable breadcrumb, meta, tabs, actions, status and description fixtures; the slot supplies the page’s only h1. The tablist name follows I18nProvider (en/es); the Spanish preview keeps caller content unchanged.",
|
|
10027
10175
|
uses: [
|
|
10028
10176
|
"Breadcrumbs",
|
|
10029
10177
|
"Button",
|
|
@@ -12275,11 +12423,23 @@ function toggleOne(id, selected) {
|
|
|
12275
12423
|
else next.add(id);
|
|
12276
12424
|
return next;
|
|
12277
12425
|
}
|
|
12278
|
-
/** Default cell text for a raw value. */
|
|
12279
|
-
function formatCell(value) {
|
|
12426
|
+
/** Default cell text for a raw value. Omitting options preserves the legacy output. */
|
|
12427
|
+
function formatCell(value, options) {
|
|
12280
12428
|
if (value == null) return "—";
|
|
12281
|
-
if (value instanceof Date)
|
|
12282
|
-
|
|
12429
|
+
if (value instanceof Date) {
|
|
12430
|
+
if (!options) return value.toLocaleDateString();
|
|
12431
|
+
if (Number.isNaN(value.getTime())) return "—";
|
|
12432
|
+
return new Intl.DateTimeFormat(options.locale, {
|
|
12433
|
+
year: "numeric",
|
|
12434
|
+
month: "numeric",
|
|
12435
|
+
day: "numeric"
|
|
12436
|
+
}).format(value);
|
|
12437
|
+
}
|
|
12438
|
+
if (typeof value === "boolean") return (options?.booleanLabels ?? ["Yes", "No"])[value ? 0 : 1];
|
|
12439
|
+
if (typeof value === "number" && Number.isFinite(value) && options?.locale !== void 0) {
|
|
12440
|
+
const decimal = new Intl.NumberFormat(options.locale).formatToParts(1.1).find((part) => part.type === "decimal");
|
|
12441
|
+
return String(value).replace(".", decimal?.value ?? ".");
|
|
12442
|
+
}
|
|
12283
12443
|
return value;
|
|
12284
12444
|
}
|
|
12285
12445
|
/** Group key of a row (`''` when the value is null or undefined). */
|
|
@@ -12522,6 +12682,7 @@ function isCellEditable(column, row) {
|
|
|
12522
12682
|
//#region src/tables/DataTable/data-table-row.tsx
|
|
12523
12683
|
function DataTableRow({ labels, row, columns, getRowId, getRowLabel, selectable, selected, singleSelection, onToggleRow, rowActions, layout, onCellEdit, editHintId, ariaRowIndex, style }) {
|
|
12524
12684
|
const { t } = useI18n();
|
|
12685
|
+
const locale = useOptionalI18n()?.locale;
|
|
12525
12686
|
const id = getRowId(row);
|
|
12526
12687
|
const selectionColumn = selectable || singleSelection != null;
|
|
12527
12688
|
const isSelected = singleSelection ? singleSelection.selectedId === id : selected.has(id);
|
|
@@ -12551,7 +12712,10 @@ function DataTableRow({ labels, row, columns, getRowId, getRowLabel, selectable,
|
|
|
12551
12712
|
}),
|
|
12552
12713
|
columns.map((c) => {
|
|
12553
12714
|
const cl = layout?.columns.get(c.id);
|
|
12554
|
-
const content = c.cell ? c.cell(row) : formatCell(c.accessor?.(row)
|
|
12715
|
+
const content = c.cell ? c.cell(row) : formatCell(c.accessor?.(row), {
|
|
12716
|
+
locale,
|
|
12717
|
+
booleanLabels: [labels?.booleanTrue ?? t("common.yes"), labels?.booleanFalse ?? t("common.no")]
|
|
12718
|
+
});
|
|
12555
12719
|
const editable = onCellEdit && editHintId && isCellEditable(c, row);
|
|
12556
12720
|
return /* @__PURE__ */ jsx(TableCell, {
|
|
12557
12721
|
align: columnAlign(c),
|
|
@@ -13777,6 +13941,16 @@ const meta$16 = {
|
|
|
13777
13941
|
status: "beta",
|
|
13778
13942
|
description: "Generic typed table: sortable headers with aria-sort, row selection with select-all and indeterminate by default (selectionMode=\"multiple\"), selectionMode=\"none\" to hide selection, column visibility menu, density toggle, row actions, loading and empty states, client-side sort and pagination, optional row groups (groupBy) with rowgroup header rows, counts, keyboard-accessible collapse buttons and group selection; column resize (pointer drag or a focusable role=\"separator\" handle with arrow keys, min/max widths, controlled columnWidths), column pinning to either edge with sticky cells (column menu or pinnedColumns), row virtualization for large datasets (aria-rowcount/aria-rowindex, works with selection and grouping), inline cell editing (text, number and select editors; Enter/F2 to edit, Enter/Tab to commit, Escape to cancel, onCellEdit can reject with an inline error) and saved views (filters, sort, visible columns, widths, pinning and grouping) with a view switcher to save as, rename, delete and reset. Opt-in selectionMode=\"single\" uses native radios in a labelled fieldset (never paginated or virtualized; paginated defaults to false and paginated=true is a type error). Single mode uses selectedId/onSelectedIdChange or defaultSelectedId; isRowDisabled skips unavailable rows and preserves a checked disabled choice without callbacks. Supply legend, aria-label or aria-labelledby for the group and getRowLabel for each radio (otherwise the first column labels it). selectionName is used verbatim and must be unique per page; omitted names use an instance-unique useId name, and duplicate supplied names or missing group labels warn in development. Tab enters once on the checked enabled row or first enabled row; arrows wrap and skip disabled rows, Space selects, Shift+Tab exits, and all-disabled groups have no tab stop. No select-all, group checkboxes, bulk actions or selection summary appear in single mode. Examples in examples/single-selection.tsx: an uncontrolled non-paginated list with legend=\"Available items\" and a controlled versions table with legend=\"Available versions\", selectedId=\"v2\" and a checked disabled version. Opt-in paginationMode=\"server\" accepts a controlled 1-based page, pageSize and required rowCount (known total), with onPageChange/onPageSizeChange requests. Supplied rows render in order without client sorting or slicing, and headers have no sort affordance. Single selection cannot use server mode. The footer stays visible for empty results, clamps stale pages for display without callbacks, and hides during loading. Page-size changes may also request a page to keep the first visible row on screen. The consumer owns fetching and reconciles stale pages. See examples/server-pagination.tsx for an items/total/page/pageSize envelope consumer that handles both callbacks.",
|
|
13779
13943
|
labels: [
|
|
13944
|
+
{
|
|
13945
|
+
key: "booleanTrue",
|
|
13946
|
+
type: "string",
|
|
13947
|
+
state: "Default cell text for a true boolean value"
|
|
13948
|
+
},
|
|
13949
|
+
{
|
|
13950
|
+
key: "booleanFalse",
|
|
13951
|
+
type: "string",
|
|
13952
|
+
state: "Default cell text for a false boolean value"
|
|
13953
|
+
},
|
|
13780
13954
|
{
|
|
13781
13955
|
key: "scrollRegion",
|
|
13782
13956
|
type: "string",
|