@kortix/ui 0.14.5 → 0.14.7
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/_vendor/kortix-shared.js +489 -381
- package/dist/access/access/access-dialog.js +8 -5
- package/dist/access/access/copy-row.js +2 -2
- package/dist/access/sharing-picker.js +2 -1
- package/dist/browser/app-in-browser.js +5 -3
- package/dist/browser/browser-panel.js +6 -6
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +4 -3
- package/dist/customize/agents/agent-access.d.ts +20 -0
- package/dist/customize/agents/agent-access.js +17 -0
- package/dist/customize/agents/agent-authority-card.js +1 -2
- package/dist/customize/agents/agent-detail-aside.js +15 -14
- package/dist/customize/agents/agent-drives-section.js +5 -6
- package/dist/customize/agents/agent-grant-pages.js +73 -76
- package/dist/customize/agents/agent-nav.prototype.d.ts +35 -0
- package/dist/customize/agents/agent-nav.prototype.js +95 -0
- package/dist/customize/agents/agent-page.js +59 -23
- package/dist/customize/agents/agent-people-section.js +18 -17
- package/dist/customize/agents/agent-triggers-section.js +6 -5
- package/dist/customize/agents/agents-page.js +18 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server.js +4 -2
- package/dist/customize/connectors/catalog/catalog-entry.d.ts +14 -0
- package/dist/customize/connectors/catalog/catalog-entry.js +18 -1
- package/dist/customize/connectors/catalog/connector-browse.d.ts +28 -0
- package/dist/customize/connectors/catalog/connector-browse.js +18 -5
- package/dist/customize/connectors/connector-routes.d.ts +3 -1
- package/dist/customize/connectors/connector-routes.js +18 -0
- package/dist/customize/connectors/connectors-page.js +23 -4
- package/dist/customize/connectors/detail/app-page.js +19 -5
- package/dist/customize/connectors/detail/connector-advanced-tools.js +4 -6
- package/dist/customize/connectors/detail/connector-modal.d.ts +10 -13
- package/dist/customize/connectors/detail/connector-modal.js +18 -101
- package/dist/customize/connectors/detail/connector-notice.js +6 -2
- package/dist/customize/connectors/detail/connector-page.d.ts +30 -0
- package/dist/customize/connectors/detail/connector-page.js +26 -13
- package/dist/customize/providers/provider-accordion.js +2 -1
- package/dist/customize/providers/provider-connect.js +2 -1
- package/dist/customize/sections/component/telegram-channel-row.js +1 -1
- package/dist/customize/sections/connector-connection-modal.js +11 -9
- package/dist/customize/sections/connectors-view.js +11 -13
- package/dist/customize/sections/llm-provider/custom-provider-form.js +24 -7
- package/dist/customize/sections/llm-provider/custom-provider-panel.js +44 -8
- package/dist/customize/sections/llm-provider/types.d.ts +3 -0
- package/dist/customize/sections/llm-provider/utils.js +2 -2
- package/dist/customize/sections/view/agent-editor-access-fields.d.ts +9 -16
- package/dist/customize/sections/view/agent-editor-access-fields.js +30 -30
- package/dist/customize/sections/view/agent-editor-basics-fields.js +3 -10
- package/dist/customize/sections/view/agent-editor-primitives.d.ts +28 -10
- package/dist/customize/sections/view/agent-editor-primitives.js +32 -19
- package/dist/customize/sections/view/agent-editor.js +3 -3
- package/dist/customize/sections/view/gateway/gateway-routing.js +18 -21
- package/dist/customize/sections/view/grant-mode-field.d.ts +2 -5
- package/dist/customize/sections/view/grant-mode-field.js +10 -18
- package/dist/customize/sections/view/permission-editor.js +11 -8
- package/dist/customize/sections/view/secrets-view.js +2 -1
- package/dist/customize/settings/rail-copy-context.js +5 -3
- package/dist/customize/settings/tabs/general-tab.d.ts +9 -2
- package/dist/customize/settings/tabs/general-tab.js +33 -11
- package/dist/customize/settings/tabs/sandbox-template-form.js +9 -12
- package/dist/customize/settings/tabs/transfer-workspace-dialog.d.ts +4 -0
- package/dist/customize/settings/tabs/transfer-workspace-dialog.js +82 -0
- package/dist/customize/shared/capability-tabs.js +2 -1
- package/dist/customize/skills/skills-page.js +3 -5
- package/dist/customize/triggers/schedule/event-trigger-copy.js +3 -2
- package/dist/customize/triggers/schedule/schedule-builder.js +7 -4
- package/dist/customize/triggers/schedule/trigger-composer.js +5 -2
- package/dist/customize/triggers/schedule/when-event.js +1 -1
- package/dist/diff/diff-view.js +9 -10
- package/dist/files/editor/code-editor.js +2 -3
- package/dist/files/project/api/runtime-files.js +3 -2
- package/dist/files/project/components/change-request-detail-dialog.d.ts +3 -1
- package/dist/files/project/components/change-request-detail-dialog.js +3 -5
- package/dist/files/project/components/change-request-status-badge.d.ts +12 -0
- package/dist/files/project/components/change-request-status-badge.js +27 -0
- package/dist/files/project/components/change-requests-panel.js +1 -1
- package/dist/files/project/components/drive-explorer.js +2 -1
- package/dist/files/project/components/drive-grid-view.js +11 -7
- package/dist/files/project/components/drive-list-view.js +4 -4
- package/dist/files/project/components/file-breadcrumbs.js +1 -1
- package/dist/files/project/components/file-explorer-page.js +1 -1
- package/dist/files/project/components/file-history-popover.js +1 -6
- package/dist/files/project/components/file-search.js +6 -1
- package/dist/files/project/components/open-change-request-dialog.js +2 -1
- package/dist/files/project/components/version-selector-logic.d.ts +11 -0
- package/dist/files/project/components/version-selector-logic.js +26 -0
- package/dist/files/project/components/version-selector.js +11 -20
- package/dist/files/project/file-source.js +18 -1
- package/dist/files/project/hooks/use-file-content.js +2 -0
- package/dist/files/project/hooks/use-server-health.js +17 -15
- package/dist/files/renderers/docx/docx-viewer.js +0 -5
- package/dist/files/renderers/image-renderer.js +6 -24
- package/dist/files/renderers/pdf/pdf-viewer.js +1 -1
- package/dist/files/renderers/presentation/FullScreenPresentationViewer.js +2 -11
- package/dist/files/renderers/show-content-renderer.js +1 -1
- package/dist/files/renderers/sqlite-renderer.js +8 -3
- package/dist/files/renderers/xlsx/xlsx-viewer.js +15 -16
- package/dist/files/tree/components/file-tree-item.js +1 -1
- package/dist/files/viewer/file-header.js +1 -1
- package/dist/files/viewer/file-preview-modal.d.ts +1 -1
- package/dist/files/viewer/file-preview-modal.js +13 -3
- package/dist/files/viewer/file-source.d.ts +3 -1
- package/dist/files/viewer/use-file-content-state.js +27 -8
- package/dist/files/viewer/viewer-actions.js +2 -2
- package/dist/i18n/en.d.ts +355 -12
- package/dist/i18n/en.js +360 -17
- package/dist/internal/desktop/desktop-back-button.js +5 -3
- package/dist/internal/files/types.d.ts +2 -0
- package/dist/internal/goals/goal-meta.d.ts +30 -0
- package/dist/internal/goals/goal-meta.js +55 -0
- package/dist/internal/hooks/use-auto-scroll.js +5 -3
- package/dist/internal/lib/query-client-singleton.d.ts +9 -3
- package/dist/internal/lib/query-client-singleton.js +18 -12
- package/dist/internal/notifications/notification-rows.js +2 -1
- package/dist/internal/outcomes/outcome-types.d.ts +5 -0
- package/dist/internal/share/session-shares-modal.js +3 -7
- package/dist/internal/stores/kortix-computer-store.js +14 -2
- package/dist/internal/stores/session-hover-store.d.ts +32 -0
- package/dist/internal/stores/session-hover-store.js +38 -0
- package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
- package/dist/internal/stores/sidebar-nav-store.js +3 -1
- package/dist/lib/routes.d.ts +2 -0
- package/dist/lib/routes.js +1 -0
- package/dist/markdown/code/inline-code.js +8 -0
- package/dist/markdown/code/output-paths-context.d.ts +18 -0
- package/dist/markdown/code/output-paths-context.js +35 -0
- package/dist/markdown/genui/components/charts.js +6 -5
- package/dist/primitives/map.js +2 -1
- package/dist/primitives/preview-image.js +4 -2
- package/dist/primitives/settings-section-header.d.ts +1 -1
- package/dist/primitives/textarea.js +1 -1
- package/dist/primitives/typed-title.js +12 -14
- package/dist/primitives/typing-animation.js +4 -2
- package/dist/session/composer/agent-selector.js +6 -1
- package/dist/session/composer/attachment-tile.d.ts +0 -2
- package/dist/session/composer/attachment-tile.js +0 -8
- package/dist/session/composer/clipboard-files.d.ts +2 -1
- package/dist/session/composer/composer-chat-input.js +5 -3
- package/dist/session/composer/composer-draft-recovery.d.ts +1 -2
- package/dist/session/composer/composer-draft-recovery.js +0 -13
- package/dist/session/composer/composer-logic.js +8 -7
- package/dist/session/composer/context-ring.d.ts +1 -1
- package/dist/session/composer/context-ring.js +2 -2
- package/dist/session/composer/context-usage.d.ts +3 -6
- package/dist/session/composer/context-usage.js +3 -6
- package/dist/session/composer/draft/composer-draft.js +4 -4
- package/dist/session/composer/inbox-row-claims.d.ts +2 -2
- package/dist/session/composer/inbox-row-claims.js +1 -1
- package/dist/session/composer/pasted-text.js +3 -2
- package/dist/session/composer/queue-projection.d.ts +3 -2
- package/dist/session/composer/queued-prompt-edit.d.ts +1 -1
- package/dist/session/composer/reasoning-effort-selector.d.ts +2 -1
- package/dist/session/composer/session-composer-readiness.d.ts +7 -22
- package/dist/session/composer/session-composer-readiness.js +12 -40
- package/dist/session/composer/stores/queued-draft-store.js +3 -2
- package/dist/session/composer/token-progress.d.ts +1 -1
- package/dist/session/composer/token-progress.js +2 -2
- package/dist/session/header/reminder-parts.d.ts +11 -2
- package/dist/session/header/reminder-parts.js +9 -4
- package/dist/session/header/session-goal-indicator.d.ts +1 -0
- package/dist/session/header/session-goal-indicator.js +41 -0
- package/dist/session/header/session-site-header.js +2 -1
- package/dist/session/media/sandbox-url-detector.js +0 -7
- package/dist/session/outcomes/change-request-outcomes.js +24 -3
- package/dist/session/overrides/provider-secret-pool-editor.js +2 -1
- package/dist/session/panel/advanced/advanced-panel.js +3 -7
- package/dist/session/panel/easy/app-preview.js +12 -2
- package/dist/session/panel/easy/easy-panel-logic.d.ts +1 -1
- package/dist/session/panel/easy/easy-panel-logic.js +1 -1
- package/dist/session/panel/easy/outputs-card.js +2 -1
- package/dist/session/panel/easy/panel-card.js +5 -3
- package/dist/session/panel/easy/preview-load.d.ts +14 -0
- package/dist/session/panel/easy/preview-load.js +15 -0
- package/dist/session/panel/easy/step-detail-body.js +2 -7
- package/dist/session/panel/session-action-panel-column.js +11 -1
- package/dist/session/panel/session-audit-shared.d.ts +0 -4
- package/dist/session/panel/session-audit-shared.js +1 -1
- package/dist/session/panel/session-changes-shared.d.ts +2 -1
- package/dist/session/panel/session-panel-provider.js +6 -2
- package/dist/session/panel/shared/use-panel-derivations.js +6 -4
- package/dist/session/panel/use-session-panel-layout.js +7 -5
- package/dist/session/print/session-print-header.js +9 -8
- package/dist/session/prompts/session-permission-prompt.js +6 -3
- package/dist/session/status/provisioning-failure.d.ts +2 -1
- package/dist/session/status/session-error-banner.js +8 -6
- package/dist/session/status/session-starting-loader.d.ts +24 -31
- package/dist/session/status/session-starting-loader.js +32 -81
- package/dist/session/thread/chat-minimap-items.d.ts +4 -4
- package/dist/session/thread/first-prompt-handover.d.ts +3 -2
- package/dist/session/thread/message-parsing.d.ts +3 -3
- package/dist/session/thread/session-chat.js +15 -19
- package/dist/session/thread/session-history-scroll.d.ts +2 -1
- package/dist/session/thread/session-history.js +3 -1
- package/dist/session/thread/session-thread.js +1 -1
- package/dist/session/thread/transcript.js +13 -7
- package/dist/session/tool/shared/file-list.js +19 -2
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +7 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +7 -0
- package/dist/session/tool/shared/infrastructure-output.js +9 -5
- package/dist/session/tool/shared/infrastructure-row-header.js +9 -1
- package/dist/session/tool/shared/infrastructure-rows.js +7 -5
- package/dist/session/tool/tools/bash-tool.js +10 -6
- package/dist/session/tool/tools/web-search-tool.js +25 -3
- package/dist/session/turn/recovered-failures.d.ts +8 -0
- package/dist/session/turn/recovered-failures.js +32 -0
- package/dist/session/turn/streaming-cadence.js +5 -8
- package/dist/styles.css +1 -1
- package/dist/terminal/pty-connection.d.ts +5 -4
- package/dist/terminal/session-terminal-panel.js +3 -5
- package/dist/theme/theme.js +2 -1
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/index.js +1 -0
- package/dist/workspace/projects/modal/github-import-pickers.js +7 -6
- package/dist/workspace/review/review-center.js +13 -10
- package/dist/workspace/saved-session-skeleton-shape.d.ts +4 -3
- package/dist/workspace/saved-session-skeleton.d.ts +5 -1
- package/dist/workspace/saved-session-skeleton.js +5 -4
- package/dist/workspace/session-workspace.js +9 -14
- package/dist/workspace/sessions/deleted-session-row.js +5 -2
- package/dist/workspace/sidebar/footer/project-computer-nav.js +6 -4
- package/dist/workspace/sidebar/footer/project-goals-nav.d.ts +6 -0
- package/dist/workspace/sidebar/footer/project-goals-nav.js +26 -0
- package/dist/workspace/sidebar/footer/project-mcp-nav.js +6 -2
- package/dist/workspace/sidebar/modal/rename-session-modal.js +8 -3
- package/dist/workspace/sidebar/modal/session-embed-section.d.ts +25 -0
- package/dist/workspace/sidebar/modal/session-embed-section.js +71 -0
- package/dist/workspace/sidebar/modal/share-session-modal.js +2 -2
- package/dist/workspace/sidebar/nav-row-meta.js +14 -2
- package/dist/workspace/sidebar/project-nav-items.js +3 -0
- package/dist/workspace/sidebar/project-session-list.js +12 -3
- package/dist/workspace/sidebar/session-brief-hover-card.js +5 -8
- package/package.json +4 -4
- package/skills/kortix-ui/references/modules.md +2 -0
- package/dist/session/status/use-readiness-settling.d.ts +0 -18
- package/dist/session/status/use-readiness-settling.js +0 -43
- package/dist/workspace/sidebar/modal/session-public-link-section.d.ts +0 -13
- package/dist/workspace/sidebar/modal/session-public-link-section.js +0 -66
|
@@ -84,7 +84,7 @@ function ListRow({ node, onClick, onDoubleClick, onDownload, onRename, onDelete,
|
|
|
84
84
|
(isCut || isCopied || selected) && 'ring-ring bg-ring/15 ring-1 ring-inset', isDragging && 'opacity-30', isDragOver && 'bg-primary/8'), children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [selectMode ? _jsx(SelectionCheck, { selected: selected, className: "shrink-0" }) : null, isDir ? (_jsx(Folder, { className: "text-muted-foreground size-4 shrink-0" })) : (getFileIcon(node.name, {
|
|
85
85
|
className: 'size-4 shrink-0 text-muted-foreground',
|
|
86
86
|
variant: 'monochrome',
|
|
87
|
-
})), isRenaming ? (_jsx("input", { ref: renameInputRef, type: "text", value: renameName, onChange: (e) => setRenameName(e.target.value), onKeyDown: (e) => {
|
|
87
|
+
})), isRenaming ? (_jsx("input", { ref: renameInputRef, type: "text", "aria-label": tHardcodedUi.raw('i18nComplete.text3064d79a295c'), value: renameName, onChange: (e) => setRenameName(e.target.value), onKeyDown: (e) => {
|
|
88
88
|
if (e.key === 'Enter') {
|
|
89
89
|
if (e.nativeEvent.isComposing)
|
|
90
90
|
return;
|
|
@@ -92,7 +92,7 @@ function ListRow({ node, onClick, onDoubleClick, onDownload, onRename, onDelete,
|
|
|
92
92
|
}
|
|
93
93
|
if (e.key === 'Escape')
|
|
94
94
|
setIsRenaming(false);
|
|
95
|
-
}, onBlur: confirmRename, onClick: (e) => e.stopPropagation(), className: "border-border min-w-0 flex-1 border-b bg-transparent py-0.5 text-sm outline-none" })) : (_jsx("span", { className: cn('truncate text-sm font-medium', node.ignored && 'opacity-50', node.name.startsWith('.') && 'text-muted-foreground'), children: node.name })), uploading ? (_jsx("span", { role: "status", "aria-label": tDrives('uploadingFile', { name: node.name }), className: "shrink-0", children: _jsx(Loading, { variant: "spokes", className: "size-3.5" }) })) : null] }) }), _jsx(TableCell, { children: isDir ? (_jsx(ChalkBadge, { label: tHardcodedUi.raw('i18nComplete.text74ccd4330384') })) : ext ? (_jsx(ChalkBadge, { label: ext })) : (_jsx("span", { className: "text-muted-foreground text-sm", children: "\u2014" })) }), _jsx(TableCell, { children: !isRenaming && (_jsx("div", { className: "flex justify-end", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { onClick: (e) => e.stopPropagation(), variant: "ghost", size: "icon-xs", className: "shrink-0 opacity-0 group-hover:opacity-100", children: _jsx(MoreVertical, { className: "text-muted-foreground size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", className: "w-48", children: isDir ? (_jsx(FolderDriveMenuItems, { Item: DropdownMenuItem, Separator: DropdownMenuSeparator, ...folderMenuProps })) : (_jsx(FileDriveMenuItems, { Item: DropdownMenuItem, Separator: DropdownMenuSeparator, ...fileMenuProps })) })] }) })) })] }) }), _jsx(ContextMenuContent, { className: "w-48", children: selection?.selectionMenu(node, ContextMenuItem, ContextMenuSeparator) ?? (_jsxs(_Fragment, { children: [_jsx(SelectMenuItem, { selection: selection, node: node, Item: ContextMenuItem, Separator: ContextMenuSeparator }), isDir ? (_jsx(FolderDriveMenuItems, { Item: ContextMenuItem, Separator: ContextMenuSeparator, ...folderMenuProps })) : (_jsx(FileDriveMenuItems, { Item: ContextMenuItem, Separator: ContextMenuSeparator, ...fileMenuProps }))] })) })] }));
|
|
95
|
+
}, onBlur: confirmRename, onClick: (e) => e.stopPropagation(), className: "border-border min-w-0 flex-1 border-b bg-transparent py-0.5 text-sm outline-none" })) : (_jsx("span", { className: cn('truncate text-sm font-medium', node.ignored && 'opacity-50', node.name.startsWith('.') && 'text-muted-foreground'), children: node.name })), uploading ? (_jsx("span", { role: "status", "aria-label": tDrives('uploadingFile', { name: node.name }), className: "shrink-0", children: _jsx(Loading, { variant: "spokes", className: "size-3.5" }) })) : null] }) }), _jsx(TableCell, { children: isDir ? (_jsx(ChalkBadge, { label: tHardcodedUi.raw('i18nComplete.text74ccd4330384') })) : ext ? (_jsx(ChalkBadge, { label: ext })) : (_jsx("span", { className: "text-muted-foreground text-sm", children: "\u2014" })) }), _jsx(TableCell, { children: !isRenaming && (_jsx("div", { className: "flex justify-end", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { onClick: (e) => e.stopPropagation(), "aria-label": tHardcodedUi.raw('i18nComplete.textf8d46c2570e7'), variant: "ghost", size: "icon-xs", className: "shrink-0 opacity-0 group-hover:opacity-100", children: _jsx(MoreVertical, { className: "text-muted-foreground size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", className: "w-48", children: isDir ? (_jsx(FolderDriveMenuItems, { Item: DropdownMenuItem, Separator: DropdownMenuSeparator, ...folderMenuProps })) : (_jsx(FileDriveMenuItems, { Item: DropdownMenuItem, Separator: DropdownMenuSeparator, ...fileMenuProps })) })] }) })) })] }) }), _jsx(ContextMenuContent, { className: "w-48", children: selection?.selectionMenu(node, ContextMenuItem, ContextMenuSeparator) ?? (_jsxs(_Fragment, { children: [_jsx(SelectMenuItem, { selection: selection, node: node, Item: ContextMenuItem, Separator: ContextMenuSeparator }), isDir ? (_jsx(FolderDriveMenuItems, { Item: ContextMenuItem, Separator: ContextMenuSeparator, ...folderMenuProps })) : (_jsx(FileDriveMenuItems, { Item: ContextMenuItem, Separator: ContextMenuSeparator, ...fileMenuProps }))] })) })] }));
|
|
96
96
|
}
|
|
97
97
|
function ElevatedDirRow({ node, onNavigate }) {
|
|
98
98
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
@@ -119,10 +119,10 @@ export function DriveListView({ elevatedDirs, dirs, files, onNavigateToDir, onOp
|
|
|
119
119
|
setSortBy(field);
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
|
-
const
|
|
122
|
+
const renderSortIcon = (field) => {
|
|
123
123
|
if (sortDisabled || sortBy !== field)
|
|
124
124
|
return null;
|
|
125
125
|
return sortOrder === 'asc' ? (_jsx(ArrowUp, { className: "ml-1 size-3" })) : (_jsx(ArrowDown, { className: "ml-1 size-3" }));
|
|
126
126
|
};
|
|
127
|
-
return (_jsx("div", { className: "space-y-7 p-5", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { children: _jsxs(Button, { onClick: () => handleHeaderClick('name'), disabled: sortDisabled, variant: "transparent", className: "text-muted-foreground hover:text-foreground m-0 h-fit w-fit p-0 font-normal has-[>svg]:p-0", children: [tI18nComplete.raw('textdcd1d5223f73'),
|
|
127
|
+
return (_jsx("div", { className: "space-y-7 p-5", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { children: _jsxs(Button, { onClick: () => handleHeaderClick('name'), disabled: sortDisabled, variant: "transparent", className: "text-muted-foreground hover:text-foreground m-0 h-fit w-fit p-0 font-normal has-[>svg]:p-0", children: [tI18nComplete.raw('textdcd1d5223f73'), renderSortIcon('name')] }) }), _jsx(TableHead, { children: _jsxs(Button, { onClick: () => handleHeaderClick('type'), disabled: sortDisabled, variant: "transparent", className: "text-muted-foreground hover:text-foreground m-0 h-fit w-fit p-0 font-normal has-[>svg]:p-0", children: [tI18nComplete.raw('textbaaddf70fb5d'), renderSortIcon('type')] }) }), _jsx(TableHead, { className: "w-[52px]", children: _jsx("span", { className: "sr-only", children: tI18nComplete.raw('textff8059dc6752') }) })] }) }), _jsxs(TableBody, { children: [elevatedDirs.map((node) => (_jsx(ElevatedDirRow, { node: node, onNavigate: () => onNavigateToDir(node) }, node.path))), dirs.map((node) => (_jsx(ListRow, { node: node, onClick: () => onNavigateToDir(node), onDownload: onDownloadDir, isDownloadingItem: isDirDownloading(node.path), onRename: isFixed?.(node.path) ? undefined : onRename, onDelete: isFixed?.(node.path) ? undefined : onDelete, onCopy: onCopy, onCut: isFixed?.(node.path) ? undefined : onCut, onDropMove: onDropMove, onDropUpload: onDropUpload, isCut: clipboardOperation === 'cut' && clipboardPath === node.path, isCopied: clipboardOperation === 'copy' && clipboardPath === node.path }, node.path))), files.map((node) => (_jsx(ListRow, { node: node, onClick: () => onPreviewFile(node), onDoubleClick: () => onOpenFile(node), onDownload: onDownload, onRename: onRename, onDelete: onDelete, onHistory: onHistory, onCopy: onCopy, onCut: onCut, gitStatus: gitStatusMap.get(node.path), isCut: clipboardOperation === 'cut' && clipboardPath === node.path, isCopied: clipboardOperation === 'copy' && clipboardPath === node.path, uploading: uploadingPaths?.has(node.path) }, node.path)))] })] }) }));
|
|
128
128
|
}
|
|
@@ -12,7 +12,7 @@ function BreadcrumbSegments({ segments, onSegmentClick, onHomeClick, fileMode, f
|
|
|
12
12
|
// When rootPath is set, only show segments at or below it
|
|
13
13
|
const rootSegmentCount = useMemo(() => (rootPath ? rootPath.split('/').filter(Boolean).length : 0), [rootPath]);
|
|
14
14
|
const visibleSegments = useMemo(() => (rootPath ? segments.slice(rootSegmentCount) : segments), [rootPath, segments, rootSegmentCount]);
|
|
15
|
-
return (_jsxs("nav", { className: "flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto", onDoubleClick: onDoubleClick, title: onDoubleClick ? tI18nComplete.raw('text5efd0bed7735') : undefined, children: [_jsx("button", { onClick: onHomeClick, className: cn('flex shrink-0 cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-colors', 'hover:bg-muted', visibleSegments.length === 0
|
|
15
|
+
return (_jsxs("nav", { className: "flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto", onDoubleClick: onDoubleClick, title: onDoubleClick ? tI18nComplete.raw('text5efd0bed7735') : undefined, children: [_jsx("button", { onClick: onHomeClick, "aria-label": tI18nComplete.raw('text3a78695388b3'), className: cn('flex shrink-0 cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-colors', 'hover:bg-muted', visibleSegments.length === 0
|
|
16
16
|
? 'text-foreground bg-muted/50 font-medium'
|
|
17
17
|
: 'text-muted-foreground'), children: _jsx(FolderRoot, { className: "h-3.5 w-3.5" }) }), visibleSegments.map((segment, visibleIndex) => {
|
|
18
18
|
// Skip 'workspace' when not sandboxed (rootPath null)
|
|
@@ -357,7 +357,7 @@ export function FileExplorerPage({ embedded = false } = {}) {
|
|
|
357
357
|
gridTemplateColumns: "repeat(auto-fill, minmax(150px, 1fr))",
|
|
358
358
|
}, children: Array.from({ length: 8 }).map((_, i) => (_jsx(Skeleton, { className: "h-[138px] rounded-lg" }, `fi${i}`))) })] })] })) : (_jsx("div", { className: "space-y-1", children: Array.from({ length: 10 }).map((_, i) => (_jsx(Skeleton, { className: "h-10 w-full rounded" }, i))) })) })), !!error && !isLoading && (_jsx(ErrorState, { title: tHardcodedUi.raw('featuresProjectFilesComponentsFileExplorerPage.line658JsxTextFailedToLoadFiles'), description: error instanceof Error
|
|
359
359
|
? error.message
|
|
360
|
-
: tHardcodedUi.raw('i18nComplete.text27c2ccd962c2'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => refetchFiles(), children: tHardcodedUi.raw('i18nComplete.text942087cc2d41') }) })), isEmpty && (_jsx(EmptyState, { icon: FolderOpen, title: tHardcodedUi.raw('featuresProjectFilesComponentsDriveListView.line396JsxTextThisFolderIsEmpty'), description: tHardcodedUi.raw('featuresProjectFilesComponentsDriveListView.line398JsxTextNoFilesOrSubfoldersAtThisPathIn') })), !isLoading && !error && files && !isEmpty && (_jsxs(_Fragment, { children: [viewMode === 'grid' ? (_jsx(DriveGridView, { elevatedDirs: elevatedDirs, dirs: dirs, files: fileItems, onNavigateToDir: handleNavigateToDir, onOpenFile: handleOpenFile, onPreviewFile: handlePreviewFile, onDownload: handleDownload, onDownloadDir: handleDownloadDir, onRename: handleRename, onDelete: handleDelete, onHistory: handleHistory, onCopy: handleCopy, onCut: handleCut, onDropMove: handleDropMove, gitStatusMap: gitStatusMap, clipboardPath: clipboard?.path, clipboardOperation: clipboard?.operation, isDirDownloading: isDirDownloading, readOnly: true })) : (_jsx(DriveListView, { elevatedDirs: elevatedDirs, dirs: dirs, files: fileItems, sortDisabled: partial, onNavigateToDir: handleNavigateToDir, onOpenFile: handleOpenFile, onPreviewFile: handlePreviewFile, onDownload: handleDownload, onDownloadDir: handleDownloadDir, onRename: handleRename, onDelete: handleDelete, onHistory: handleHistory, onCopy: handleCopy, onCut: handleCut, onDropMove: handleDropMove, gitStatusMap: gitStatusMap, clipboardPath: clipboard?.path, clipboardOperation: clipboard?.operation, isDirDownloading: isDirDownloading, readOnly: true })), _jsx(LoadMoreRow, { listing: listing })] }))] }), _jsx(CheckpointsPanel, { open: rightPanel === 'history', onClose: () => setRightPanel(null) }), _jsx(ChangeRequestsPanel, { open: rightPanel === 'proposed-changes', onClose: () => setRightPanel(null) })] }), _jsx(ChangeRequestDetailDialog, { crId: createdCrId, onClose: () => setCreatedCrId(null) }), _jsx(ExplorerFilePreview, {}), searchEnabled && isSearchOpen && _jsx(FileSearch, {}), historyPopoverPath && (_jsx("div", { className: "bg-popover border-border animate-in slide-in-from-bottom-4 fade-in-0 fixed right-4 bottom-4 z-50 overflow-hidden rounded-md border shadow-2xl duration-200", children: _jsx(FileHistoryPopoverContent, { filePath: historyPopoverPath, onClose: () => setHistoryPopoverPath(null) }) })), _jsx(AlertDialog, { open: !!deleteTarget, onOpenChange: () => setDeleteTarget(null), children: _jsxs(AlertDialogContent, { className: "sm:max-w-md", onOpenAutoFocus: (e) => {
|
|
360
|
+
: tHardcodedUi.raw('i18nComplete.text27c2ccd962c2'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => refetchFiles(), children: tHardcodedUi.raw('i18nComplete.text942087cc2d41') }) })), isEmpty && (_jsx(EmptyState, { icon: FolderOpen, title: tHardcodedUi.raw('featuresProjectFilesComponentsDriveListView.line396JsxTextThisFolderIsEmpty'), description: tHardcodedUi.raw('featuresProjectFilesComponentsDriveListView.line398JsxTextNoFilesOrSubfoldersAtThisPathIn') })), !isLoading && !error && files && !isEmpty && (_jsxs(_Fragment, { children: [viewMode === 'grid' ? (_jsx(DriveGridView, { elevatedDirs: elevatedDirs, dirs: dirs, files: fileItems, onNavigateToDir: handleNavigateToDir, onOpenFile: handleOpenFile, onPreviewFile: handlePreviewFile, onDownload: handleDownload, onDownloadDir: handleDownloadDir, onRename: handleRename, onDelete: handleDelete, onHistory: handleHistory, onCopy: handleCopy, onCut: handleCut, onDropMove: handleDropMove, gitStatusMap: gitStatusMap, clipboardPath: clipboard?.path, clipboardOperation: clipboard?.operation, isDirDownloading: isDirDownloading, readOnly: true })) : (_jsx(DriveListView, { elevatedDirs: elevatedDirs, dirs: dirs, files: fileItems, sortDisabled: partial, onNavigateToDir: handleNavigateToDir, onOpenFile: handleOpenFile, onPreviewFile: handlePreviewFile, onDownload: handleDownload, onDownloadDir: handleDownloadDir, onRename: handleRename, onDelete: handleDelete, onHistory: handleHistory, onCopy: handleCopy, onCut: handleCut, onDropMove: handleDropMove, gitStatusMap: gitStatusMap, clipboardPath: clipboard?.path, clipboardOperation: clipboard?.operation, isDirDownloading: isDirDownloading, readOnly: true })), _jsx(LoadMoreRow, { listing: listing })] }))] }), _jsx(CheckpointsPanel, { open: rightPanel === 'history', onClose: () => setRightPanel(null) }), _jsx(ChangeRequestsPanel, { open: rightPanel === 'proposed-changes', onClose: () => setRightPanel(null) })] }), _jsx(ChangeRequestDetailDialog, { crId: createdCrId, onClose: () => setCreatedCrId(null), onOpenChangeRequest: setCreatedCrId }), _jsx(ExplorerFilePreview, {}), searchEnabled && isSearchOpen && _jsx(FileSearch, {}), historyPopoverPath && (_jsx("div", { className: "bg-popover border-border animate-in slide-in-from-bottom-4 fade-in-0 fixed right-4 bottom-4 z-50 overflow-hidden rounded-md border shadow-2xl duration-200", children: _jsx(FileHistoryPopoverContent, { filePath: historyPopoverPath, onClose: () => setHistoryPopoverPath(null) }) })), _jsx(AlertDialog, { open: !!deleteTarget, onOpenChange: () => setDeleteTarget(null), children: _jsxs(AlertDialogContent, { className: "sm:max-w-md", onOpenAutoFocus: (e) => {
|
|
361
361
|
e.preventDefault();
|
|
362
362
|
deleteButtonRef.current?.focus();
|
|
363
363
|
}, children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { children: [tHardcodedUi.raw('i18nComplete.texte2d0a54968ea'), ' ', deleteTarget?.type === 'directory' ? 'folder' : 'file'] }), _jsxs(AlertDialogDescription, { children: [tHardcodedUi.raw('featuresProjectFilesComponentsFileExplorerPage.line806JsxTextAreYouSureYouWantToDelete'), ' ', _jsxs("span", { className: "text-foreground font-semibold", children: [tHardcodedUi.raw('featuresProjectFilesComponentsFileExplorerPage.line807JsxTextQuot'), deleteTarget?.name, tHardcodedUi.raw('featuresProjectFilesComponentsFileExplorerPage.line807JsxTextQuot32c14d98')] }), tHardcodedUi.raw('featuresProjectFilesComponentsFileExplorerPage.line807JsxTextThisActionCannotBeUndone')] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: deleteMutation.isPending, children: tHardcodedUi.raw('i18nComplete.text19766ed6ccb2') }), _jsx(AlertDialogAction, { ref: deleteButtonRef, onClick: (e) => {
|
|
@@ -83,12 +83,7 @@ function CompactCommitRow({ commit, filePath }) {
|
|
|
83
83
|
setTimeout(() => setCopied(false), 2000);
|
|
84
84
|
}, [commit.hash]);
|
|
85
85
|
const toggle = () => setExpanded((v) => !v);
|
|
86
|
-
return (_jsxs("li", { className: cn('relative rounded-md', expanded && 'bg-muted'), children: [_jsxs("div", {
|
|
87
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
88
|
-
e.preventDefault();
|
|
89
|
-
toggle();
|
|
90
|
-
}
|
|
91
|
-
}, className: cn('group/row focus-visible:ring-ring flex w-full cursor-pointer items-start gap-3 rounded-md px-2 py-2 text-left outline-none focus-visible:ring-1', !expanded && 'hover:bg-muted'), children: [_jsx("span", { className: "border-muted-foreground bg-background relative z-10 mt-[5px] size-2.5 shrink-0 rounded-full border" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-foreground truncate text-sm font-medium", children: commit.subject }), _jsxs(InlineMeta, { className: "mt-0.5", children: [commit.author, _jsx("time", { title: formatFullDate(commit.timestamp), children: formatRelativeDate(commit.timestamp) })] })] }), _jsxs("button", { type: "button", onClick: handleCopyHash, className: "text-muted-foreground hover:text-foreground flex shrink-0 items-center gap-1 rounded-sm px-1 font-mono text-xs leading-5", title: tHardcodedUi.raw('featuresProjectFilesComponentsFileHistoryPopover.line160JsxAttrTitleCopyCheckpointId'), children: [copied ? (_jsx(SolidCheckIcon, { className: "text-kortix-green size-3" })) : (_jsx(Copy, { className: "size-3 opacity-0 group-hover/row:opacity-100" })), commit.shortHash] })] }), expanded && _jsx(CompactCommitDiff, { filePath: filePath, commitHash: commit.hash })] }));
|
|
86
|
+
return (_jsxs("li", { className: cn('relative rounded-md', expanded && 'bg-muted'), children: [_jsxs("div", { className: cn('group/row has-[button[aria-expanded]:focus-visible]:ring-ring flex w-full items-start gap-3 rounded-md has-[button[aria-expanded]:focus-visible]:ring-1', !expanded && 'hover:bg-muted'), children: [_jsxs("button", { type: "button", "aria-expanded": expanded, onClick: toggle, className: "flex min-w-0 flex-1 cursor-pointer items-start gap-3 py-2 pl-2 text-left outline-none", children: [_jsx("span", { className: "border-muted-foreground bg-background relative z-10 mt-[5px] size-2.5 shrink-0 rounded-full border" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-foreground truncate text-sm font-medium", children: commit.subject }), _jsxs(InlineMeta, { className: "mt-0.5", children: [commit.author, _jsx("time", { title: formatFullDate(commit.timestamp), children: formatRelativeDate(commit.timestamp) })] })] })] }), _jsxs("button", { type: "button", onClick: handleCopyHash, className: "text-muted-foreground hover:text-foreground my-2 mr-2 flex shrink-0 items-center gap-1 rounded-sm px-1 font-mono text-xs leading-5", title: tHardcodedUi.raw('featuresProjectFilesComponentsFileHistoryPopover.line160JsxAttrTitleCopyCheckpointId'), children: [copied ? (_jsx(SolidCheckIcon, { className: "text-kortix-green size-3" })) : (_jsx(Copy, { className: "size-3 opacity-0 group-hover/row:opacity-100" })), commit.shortHash] })] }), expanded && _jsx(CompactCommitDiff, { filePath: filePath, commitHash: commit.hash })] }));
|
|
92
87
|
}
|
|
93
88
|
export function FileHistoryPopoverContent({ filePath, onClose }) {
|
|
94
89
|
const tHardcodedUi = useTranslations('hardcodedUi');
|
|
@@ -112,7 +112,12 @@ export function FileSearch() {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
}, [closeSearch, results, selectedIndex, handleSelect, scrollItemIntoView]);
|
|
115
|
-
return (_jsx("div", { className: "absolute inset-0 z-50 bg-black/60 backdrop-blur-sm", onClick:
|
|
115
|
+
return (_jsx("div", { role: "presentation", className: "absolute inset-0 z-50 bg-black/60 backdrop-blur-sm", onClick: (e) => {
|
|
116
|
+
if (e.target === e.currentTarget)
|
|
117
|
+
closeSearch();
|
|
118
|
+
else
|
|
119
|
+
e.stopPropagation();
|
|
120
|
+
}, children: _jsx("div", { className: "mx-auto mt-4 max-w-lg px-4", children: _jsxs("div", { className: "border-border bg-card overflow-hidden rounded-2xl border shadow-2xl", children: [_jsxs("div", { className: "flex items-center gap-2 border-b px-3", children: [_jsx(Search, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx(Input, { type: "text", ref: inputRef, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: handleInputKeyDown, placeholder: tHardcodedUi.raw(searchContents
|
|
116
121
|
? 'featuresProjectFilesComponentsFileSearch.searchContentsPlaceholder'
|
|
117
122
|
: 'featuresProjectFilesComponentsFileSearch.line109JsxAttrPlaceholderSearchFiles'), className: "h-10 border-0 px-0 shadow-none focus-visible:ring-0" }), _jsx("button", { onClick: closeSearch, "aria-label": tI18nHardcoded.raw('autoFeaturesProjectFilesComponentsFileSearchJsxAttrAriaLabel732c1816'), className: "hover:bg-muted rounded p-1", children: _jsx(X, { className: "text-muted-foreground h-4 w-4" }) })] }), canSearchContents && (_jsx("div", { className: "flex items-center border-b", children: _jsx(Switch, { label: tHardcodedUi.raw('featuresProjectFilesComponentsFileSearch.searchContents'), "aria-label": tHardcodedUi.raw('featuresProjectFilesComponentsFileSearch.searchContents'), checked: contentMode, onCheckedChange: (checked) => {
|
|
118
123
|
setContentMode(checked);
|
|
@@ -30,6 +30,7 @@ function BranchRow({ branch }) {
|
|
|
30
30
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
31
31
|
return (_jsxs("div", { className: "flex items-center justify-start gap-2 py-0.5", children: [_jsx(Layers, { className: "text-muted-foreground size-4 shrink-0" }), _jsxs("div", { className: "flex flex-col items-start gap-0", children: [branch.subject && (_jsx("span", { className: "text-muted-foreground/80 truncate text-xs", children: branch.subject })), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate font-mono text-xs", children: displayBranchName(branch.name) }), branch.is_default && (_jsx(Badge, { variant: "kortix", size: "xs", className: "shrink-0 text-[11px]", children: tI18nComplete.raw('text37a8eec1ce19') }))] })] })] }));
|
|
32
32
|
}
|
|
33
|
+
const NO_BRANCHES = [];
|
|
33
34
|
const PICKER_TRIGGER_CLASS = 'py-2 flex-1 min-w-0 rounded-sm border-0 bg-transparent px-2 hover:bg-muted/40 focus:ring-0';
|
|
34
35
|
export function OpenChangeRequestDialog({ open, onOpenChange, projectId, defaultBranch, session = null, initialHeadRef, onCreated, }) {
|
|
35
36
|
const tHardcodedUi = useTranslations('hardcodedUi');
|
|
@@ -41,7 +42,7 @@ export function OpenChangeRequestDialog({ open, onOpenChange, projectId, default
|
|
|
41
42
|
const activeSession = session ?? lastSessionRef.current;
|
|
42
43
|
const sessionMode = activeSession !== null;
|
|
43
44
|
const branchesQuery = useBranches({ enabled: open && !sessionMode, projectId });
|
|
44
|
-
const branches = branchesQuery.data?.branches ??
|
|
45
|
+
const branches = branchesQuery.data?.branches ?? NO_BRANCHES;
|
|
45
46
|
const branchMap = useMemo(() => {
|
|
46
47
|
const m = new Map();
|
|
47
48
|
for (const b of branches)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProjectBranch } from '@kortix/sdk';
|
|
2
|
+
/** A session branch is named by its session id. A person knows it by the session's title (KRTX-3020). */
|
|
3
|
+
export declare function versionTitle(branch: ProjectBranch): string;
|
|
4
|
+
/** Search reads the title, the agent, the branch name and the last commit. */
|
|
5
|
+
export declare function versionMatches(branch: ProjectBranch, query: string): boolean;
|
|
6
|
+
/** The default branch, live work, then what the person archived or deleted, each in served order. */
|
|
7
|
+
export declare function groupVersions(branches: ProjectBranch[]): {
|
|
8
|
+
primary: ProjectBranch[];
|
|
9
|
+
others: ProjectBranch[];
|
|
10
|
+
archived: ProjectBranch[];
|
|
11
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** A session branch is named by its session id. A person knows it by the session's title (KRTX-3020). */
|
|
2
|
+
export function versionTitle(branch) {
|
|
3
|
+
return branch.session?.title?.trim() || branch.name;
|
|
4
|
+
}
|
|
5
|
+
/** Search reads the title, the agent, the branch name and the last commit. */
|
|
6
|
+
export function versionMatches(branch, query) {
|
|
7
|
+
const q = query.trim().toLowerCase();
|
|
8
|
+
if (!q)
|
|
9
|
+
return true;
|
|
10
|
+
return [branch.session?.title, branch.session?.agent_name, branch.name, branch.subject].some((value) => value?.toLowerCase().includes(q));
|
|
11
|
+
}
|
|
12
|
+
/** The default branch, live work, then what the person archived or deleted, each in served order. */
|
|
13
|
+
export function groupVersions(branches) {
|
|
14
|
+
const primary = [];
|
|
15
|
+
const others = [];
|
|
16
|
+
const archived = [];
|
|
17
|
+
for (const b of branches) {
|
|
18
|
+
if (b.is_default)
|
|
19
|
+
primary.push(b);
|
|
20
|
+
else if (b.session?.archived || b.session?.deleted)
|
|
21
|
+
archived.push(b);
|
|
22
|
+
else
|
|
23
|
+
others.push(b);
|
|
24
|
+
}
|
|
25
|
+
return { primary, others, archived };
|
|
26
|
+
}
|
|
@@ -13,6 +13,7 @@ import { useMemo, useState } from 'react';
|
|
|
13
13
|
import { useProjectContext } from '../context.js';
|
|
14
14
|
import { useBranches } from '../hooks/use-branches.js';
|
|
15
15
|
import { useVersionStore } from '../store/version-store.js';
|
|
16
|
+
import { groupVersions, versionMatches, versionTitle } from './version-selector-logic.js';
|
|
16
17
|
/** Shared formatter, hoisted so each row render does not rebuild the Intl
|
|
17
18
|
* machinery. Same options as the old `toLocaleDateString` call — identical output. */
|
|
18
19
|
const commitDateFormatter = new Intl.DateTimeFormat(undefined, {
|
|
@@ -30,24 +31,10 @@ export function VersionSelector() {
|
|
|
30
31
|
const { data, isLoading, error } = useBranches({ enabled: open || activeRef !== '' });
|
|
31
32
|
const defaultBranch = data?.default_branch ?? activeRef;
|
|
32
33
|
const isOnMain = activeRef === defaultBranch;
|
|
33
|
-
const filtered = useMemo(() =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return branches;
|
|
38
|
-
return branches.filter((b) => b.name.toLowerCase().includes(trimmed) || b.subject.toLowerCase().includes(trimmed));
|
|
39
|
-
}, [data?.branches, query]);
|
|
40
|
-
const { primary, others } = useMemo(() => {
|
|
41
|
-
const primary = [];
|
|
42
|
-
const others = [];
|
|
43
|
-
for (const b of filtered) {
|
|
44
|
-
if (b.is_default)
|
|
45
|
-
primary.push(b);
|
|
46
|
-
else
|
|
47
|
-
others.push(b);
|
|
48
|
-
}
|
|
49
|
-
return { primary, others };
|
|
50
|
-
}, [filtered]);
|
|
34
|
+
const filtered = useMemo(() => (data?.branches ?? []).filter((b) => versionMatches(b, query)), [data?.branches, query]);
|
|
35
|
+
const { primary, others, archived } = useMemo(() => groupVersions(filtered), [filtered]);
|
|
36
|
+
const activeBranch = data?.branches.find((b) => b.name === activeRef);
|
|
37
|
+
const activeLabel = activeBranch ? versionTitle(activeBranch) : activeRef;
|
|
51
38
|
const handleSelect = (branchName) => {
|
|
52
39
|
setVersion(projectId, branchName === defaultBranch ? null : branchName);
|
|
53
40
|
setOpen(false);
|
|
@@ -57,10 +44,14 @@ export function VersionSelector() {
|
|
|
57
44
|
setOpen(v);
|
|
58
45
|
if (!v)
|
|
59
46
|
setQuery('');
|
|
60
|
-
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline-ghost", type: "button", size: "sm", className:
|
|
47
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline-ghost", type: "button", size: "sm", className: "max-w-48 min-w-30 shrink-0 justify-between", title: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line88JsxAttrTitleSwitchVersion'), children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Layers, { className: "text-muted-foreground size-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: activeLabel || 'Version' })] }), _jsx(ChevronsUpDown, { className: "text-muted-foreground size-3 shrink-0" })] }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 6, className: "flex w-[340px] flex-col overflow-hidden p-0", children: [_jsxs("div", { className: "border-border flex shrink-0 items-center gap-1.5 border-b px-3 py-2", children: [_jsx(Search, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("input", { type: "text", value: query, onChange: (e) => setQuery(e.target.value), placeholder: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line112JsxAttrPlaceholderFindAVersion'), className: "text-foreground placeholder:text-muted-foreground h-7 min-w-0 flex-1 border-0 bg-transparent px-0 text-sm outline-none" })] }), _jsx("div", { className: "h-[520px] max-h-[calc(100vh-8rem)] min-h-0 shrink", children: _jsxs(FadedScrollArea, { fadeColor: "from-popover", className: "h-full overscroll-contain", children: [isLoading && (_jsxs("div", { className: "text-muted-foreground flex items-center justify-center gap-2 py-8 text-xs", children: [_jsx(Loading, { className: "size-3.5" }), tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line122JsxTextLoadingVersions')] })), error && !isLoading && (_jsx("div", { className: "text-muted-foreground px-4 py-8 text-center text-xs", children: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line128JsxTextFailedToLoadVersions') })), !isLoading && !error && filtered.length === 0 && (_jsxs("div", { className: "text-muted-foreground px-4 py-8 text-center text-xs", children: [tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line134JsxTextNoVersionsMatch'), ' ', query ? `“${query}”` : ''] })), primary.length > 0 && (_jsxs("div", { className: cn('space-y-3 p-3', others.length + archived.length > 0 ? 'pb-0' : 'pb-3'), children: [_jsx(Label, { children: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line140JsxTextMainVersion') }), primary.map((b) => (_jsx(VersionRow, { branch: b, isActive: activeRef === b.name, onClick: () => handleSelect(b.name) }, b.name)))] })), others.length > 0 && (_jsxs("div", { className: cn('space-y-3 p-3', archived.length > 0 ? 'pb-0' : 'pb-3'), children: [_jsx(Label, { children: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line154JsxTextOtherVersions') }), others.map((b) => (_jsx(VersionRow, { branch: b, isActive: activeRef === b.name, onClick: () => handleSelect(b.name) }, b.name)))] })), archived.length > 0 && (_jsxs("div", { className: "space-y-3 p-3 pb-3", children: [_jsx(Label, { children: tHardcodedUi.raw('i18nComplete.textbdb86505f806') }), archived.map((b) => (_jsx(VersionRow, { branch: b, isActive: activeRef === b.name, onClick: () => handleSelect(b.name) }, b.name)))] }))] }) })] })] }));
|
|
61
48
|
}
|
|
62
49
|
function VersionRow({ branch, isActive, onClick, }) {
|
|
63
50
|
const tHardcodedUi = useTranslations('hardcodedUi');
|
|
64
51
|
const date = branch.committed_at ? commitDateFormatter.format(new Date(branch.committed_at)) : '';
|
|
65
|
-
|
|
52
|
+
const title = versionTitle(branch);
|
|
53
|
+
const agent = branch.session?.agent_name;
|
|
54
|
+
return (_jsxs("button", { type: "button", onClick: onClick,
|
|
55
|
+
// The id stays one hover away, and search still finds it.
|
|
56
|
+
title: title === branch.name ? undefined : branch.name, className: cn('border-border bg-popover hover:bg-foreground/4 flex w-full cursor-pointer items-start gap-2.5 rounded-md px-3 py-2 text-left', isActive && 'bg-primary/5'), children: [_jsx("div", { className: "mt-0.5 flex size-4 shrink-0 items-center justify-center", children: isActive ? (_jsx(Check, { className: "text-primary size-3.5" })) : (_jsx(Layers, { className: "text-muted-foreground size-3.5" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: title }), branch.is_default && (_jsx(Badge, { variant: "kortix", size: "xs", children: tHardcodedUi.raw('i18nComplete.texteb814be3ca3b') })), branch.session?.deleted && (_jsx(Badge, { variant: "outline", size: "xs", children: tHardcodedUi.raw('i18nComplete.textb48ff39c2e0f') }))] }), _jsxs("div", { className: "text-muted-foreground mt-0.5 flex items-center gap-1.5 text-xs", children: [agent && _jsx("span", { className: "truncate", children: agent }), agent && date && _jsx("span", { className: "text-muted-foreground", children: "\u00B7" }), date && (_jsxs("span", { children: [tHardcodedUi.raw('i18nComplete.text3a5ecca188c0'), " ", date] })), !branch.is_default && branch.ahead != null && branch.behind != null && (_jsxs(_Fragment, { children: [date && _jsx("span", { className: "text-muted-foreground", children: "\u00B7" }), _jsxs("span", { className: "inline-flex items-center gap-1 tabular-nums", title: tHardcodedUi.raw('featuresProjectFilesComponentsVersionSelector.line234JsxAttrTitleAheadBehindMainVersion'), children: [_jsxs("span", { className: "text-kortix-green inline-flex items-center gap-0.5", children: [_jsx(ArrowUpRight, { className: "h-2.5 w-2.5" }), branch.ahead] }), _jsxs("span", { className: "text-kortix-red inline-flex items-center gap-0.5", children: [_jsx(ArrowDownLeft, { className: "h-2.5 w-2.5" }), branch.behind] })] })] }))] }), branch.subject && (_jsx("div", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: branch.subject }))] })] }));
|
|
66
57
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { writeProjectFile } from '@kortix/sdk';
|
|
4
|
+
import { fileContentKeys } from './hooks/use-file-content.js';
|
|
5
|
+
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
6
|
+
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
2
7
|
import { useMemo } from 'react';
|
|
3
8
|
import { downloadFile, uploadFile } from './api/runtime-files.js';
|
|
4
9
|
import { FilePathBreadcrumbs } from './components/file-breadcrumbs.js';
|
|
@@ -16,6 +21,8 @@ import { useBinaryBlob } from './hooks/use-binary-blob.js';
|
|
|
16
21
|
*/
|
|
17
22
|
export function useProjectFileSource() {
|
|
18
23
|
const ctx = useProjectContext();
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
const canWrite = useProjectCan(ctx?.projectId ?? '', PROJECT_ACTIONS.PROJECT_FILE_WRITE).allowed === true;
|
|
19
26
|
return useMemo(() => ({
|
|
20
27
|
id: 'project-ref',
|
|
21
28
|
useFileContent,
|
|
@@ -25,6 +32,16 @@ export function useProjectFileSource() {
|
|
|
25
32
|
? downloadFile(ctx.projectId, ctx.ref, filePath, fileName)
|
|
26
33
|
: Promise.reject(new Error('No project context for download')),
|
|
27
34
|
upload: uploadFile,
|
|
35
|
+
editablePreview: canWrite,
|
|
36
|
+
save: ctx && canWrite ? async (filePath, file, revision) => {
|
|
37
|
+
if (!revision)
|
|
38
|
+
throw new Error('Reload the file before saving.');
|
|
39
|
+
await writeProjectFile(ctx.projectId, {
|
|
40
|
+
path: filePath.replace(/^\/workspace\//, '').replace(/^\//, ''), ref: ctx.ref,
|
|
41
|
+
content: await file.text(), expected_revision: revision,
|
|
42
|
+
});
|
|
43
|
+
await queryClient.invalidateQueries({ queryKey: fileContentKeys.all });
|
|
44
|
+
} : undefined,
|
|
28
45
|
Breadcrumbs: FilePathBreadcrumbs,
|
|
29
|
-
}), [ctx]);
|
|
46
|
+
}), [ctx, canWrite, queryClient]);
|
|
30
47
|
}
|
|
@@ -20,6 +20,8 @@ export function useFileContent(filePath, options) {
|
|
|
20
20
|
staleTime: options?.staleTime ?? 10_000,
|
|
21
21
|
gcTime: 5 * 60_000,
|
|
22
22
|
refetchOnWindowFocus: false,
|
|
23
|
+
// A revision used for edits must remain paired with the displayed text.
|
|
24
|
+
refetchOnMount: false,
|
|
23
25
|
retry: (failureCount, error) => {
|
|
24
26
|
const msg = error.message.toLowerCase();
|
|
25
27
|
if (msg.includes('404') ||
|
|
@@ -18,19 +18,21 @@ export function useServerHealth(_options) {
|
|
|
18
18
|
* git-status gate (`project?.vcs === 'git'`) continues to behave correctly.
|
|
19
19
|
*/
|
|
20
20
|
export function useCurrentProject(_options) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
return useMemo(() => {
|
|
22
|
+
const data = {
|
|
23
|
+
id: 'project-files',
|
|
24
|
+
worktree: '/workspace',
|
|
25
|
+
vcs: 'git',
|
|
26
|
+
name: 'project',
|
|
27
|
+
time: { created: Date.now(), updated: Date.now() },
|
|
28
|
+
sandboxes: [],
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
data,
|
|
32
|
+
isLoading: false,
|
|
33
|
+
isError: false,
|
|
34
|
+
error: null,
|
|
35
|
+
refetch: async () => ({ data }),
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
36
38
|
}
|
|
@@ -196,11 +196,6 @@ function DocxPageNumberControl({ activePageStore, controlsDisabled, onPageChange
|
|
|
196
196
|
const displayPage = pageCount ? activePage : 1;
|
|
197
197
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
198
198
|
const [draftPage, setDraftPage] = React.useState(() => String(displayPage));
|
|
199
|
-
React.useEffect(() => {
|
|
200
|
-
if (!isEditing) {
|
|
201
|
-
setDraftPage(String(displayPage));
|
|
202
|
-
}
|
|
203
|
-
}, [displayPage, isEditing]);
|
|
204
199
|
React.useEffect(() => {
|
|
205
200
|
if (!isEditing)
|
|
206
201
|
return;
|
|
@@ -55,11 +55,10 @@ export function ImageRenderer({ url, className, fileName, controls = 'hover', ba
|
|
|
55
55
|
const [rotation, setRotation] = useState(0);
|
|
56
56
|
const [isPanning, setIsPanning] = useState(false);
|
|
57
57
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
58
|
-
const
|
|
58
|
+
const startPanPositionRef = useRef({ x: 0, y: 0 });
|
|
59
59
|
const [backdrop, setBackdrop] = useState('transparent');
|
|
60
60
|
const [imgLoaded, setImgLoaded] = useState(false);
|
|
61
61
|
const [imgError, setImgError] = useState(false);
|
|
62
|
-
const [imgInfo, setImgInfo] = useState(null);
|
|
63
62
|
// ── Retry state ──────────────────────────────────────────────────────
|
|
64
63
|
const [retryCount, setRetryCount] = useState(0);
|
|
65
64
|
const [imgSrc, setImgSrc] = useState(url);
|
|
@@ -71,18 +70,6 @@ export function ImageRenderer({ url, className, fileName, controls = 'hover', ba
|
|
|
71
70
|
const isSvg = fileName?.toLowerCase().endsWith('.svg') ||
|
|
72
71
|
url?.toLowerCase().endsWith('.svg') ||
|
|
73
72
|
url?.includes('image/svg');
|
|
74
|
-
// Derive the display file type for the info panel
|
|
75
|
-
const displayFileType = (() => {
|
|
76
|
-
if (isSvg)
|
|
77
|
-
return 'SVG';
|
|
78
|
-
if (fileName) {
|
|
79
|
-
const ext = fileName.split('.').pop()?.toUpperCase();
|
|
80
|
-
if (ext)
|
|
81
|
-
return ext;
|
|
82
|
-
}
|
|
83
|
-
const ext = url.split('.').pop()?.toUpperCase();
|
|
84
|
-
return ext || 'Image';
|
|
85
|
-
})();
|
|
86
73
|
// When the parent passes a new URL, reset everything. The reset runs during
|
|
87
74
|
// render, not in an effect: an effect also ran on mount, after a cached
|
|
88
75
|
// image had already fired `load`, and set `imgLoaded` back to false. The
|
|
@@ -123,17 +110,12 @@ export function ImageRenderer({ url, className, fileName, controls = 'hover', ba
|
|
|
123
110
|
setImgError(false);
|
|
124
111
|
setRetryCount(0); // reset on success
|
|
125
112
|
if (imageRef.current) {
|
|
126
|
-
setImgInfo({
|
|
127
|
-
width: imageRef.current.naturalWidth,
|
|
128
|
-
height: imageRef.current.naturalHeight,
|
|
129
|
-
type: displayFileType,
|
|
130
|
-
});
|
|
131
113
|
previewFit?.report({
|
|
132
114
|
width: imageRef.current.naturalWidth,
|
|
133
115
|
height: imageRef.current.naturalHeight,
|
|
134
116
|
});
|
|
135
117
|
}
|
|
136
|
-
}, [
|
|
118
|
+
}, [previewFit]);
|
|
137
119
|
// Retries exhausted: these bytes are never going to decode, so there will be
|
|
138
120
|
// no `report` for this image. Say "never" rather than staying silent — a
|
|
139
121
|
// consumer reads silence as "still loading" and keeps whatever width it last
|
|
@@ -213,17 +195,17 @@ export function ImageRenderer({ url, className, fileName, controls = 'hover', ba
|
|
|
213
195
|
const handleMouseDown = (e) => {
|
|
214
196
|
if (canPan) {
|
|
215
197
|
setIsPanning(true);
|
|
216
|
-
|
|
198
|
+
startPanPositionRef.current = {
|
|
217
199
|
x: e.clientX - position.x,
|
|
218
200
|
y: e.clientY - position.y,
|
|
219
|
-
}
|
|
201
|
+
};
|
|
220
202
|
}
|
|
221
203
|
};
|
|
222
204
|
const handleMouseMove = (e) => {
|
|
223
205
|
if (isPanning && canPan) {
|
|
224
206
|
setPosition({
|
|
225
|
-
x: e.clientX -
|
|
226
|
-
y: e.clientY -
|
|
207
|
+
x: e.clientX - startPanPositionRef.current.x,
|
|
208
|
+
y: e.clientY - startPanPositionRef.current.y,
|
|
227
209
|
});
|
|
228
210
|
}
|
|
229
211
|
};
|
|
@@ -240,7 +240,7 @@ function PDFViewerFileActionsMenu({ onUploadFile, showUpload = false, }) {
|
|
|
240
240
|
const inputRef = React.useRef(null);
|
|
241
241
|
if (!showUpload || !onUploadFile)
|
|
242
242
|
return null;
|
|
243
|
-
return (_jsxs(_Fragment, { children: [_jsx("input", { ref: inputRef, type: "file", accept: "application/pdf,.pdf", className: "sr-only", tabIndex: -1, onChange: (event) => {
|
|
243
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { ref: inputRef, type: "file", accept: "application/pdf,.pdf", "aria-label": tI18nComplete.raw('text865e89de78d9'), className: "sr-only", tabIndex: -1, onChange: (event) => {
|
|
244
244
|
const nextFile = event.target.files?.[0];
|
|
245
245
|
if (nextFile) {
|
|
246
246
|
onUploadFile(nextFile);
|
|
@@ -19,11 +19,9 @@ export function FullScreenPresentationViewer({ isOpen, onClose, presentationName
|
|
|
19
19
|
const [metadata, setMetadata] = useState(null);
|
|
20
20
|
const [currentSlide, setCurrentSlide] = useState(initialSlide);
|
|
21
21
|
const [isLoading, setIsLoading] = useState(false);
|
|
22
|
-
const [error, setError] = useState(null);
|
|
23
22
|
const [retryAttempt, setRetryAttempt] = useState(0);
|
|
24
23
|
const retryTimeoutRef = useRef(null);
|
|
25
24
|
const hasLoadedRef = useRef(false);
|
|
26
|
-
const [showControls, setShowControls] = useState(true);
|
|
27
25
|
const [showEditor, setShowEditor] = useState(false);
|
|
28
26
|
const [isDownloadingPDF, setIsDownloadingPDF] = useState(false);
|
|
29
27
|
const [isDownloadingPPTX, setIsDownloadingPPTX] = useState(false);
|
|
@@ -57,7 +55,6 @@ export function FullScreenPresentationViewer({ isOpen, onClose, presentationName
|
|
|
57
55
|
return;
|
|
58
56
|
}
|
|
59
57
|
setIsLoading(true);
|
|
60
|
-
setError(null);
|
|
61
58
|
setRetryAttempt(retryCount);
|
|
62
59
|
try {
|
|
63
60
|
// Sanitize the presentation name to match backend directory creation
|
|
@@ -218,12 +215,6 @@ export function FullScreenPresentationViewer({ isOpen, onClose, presentationName
|
|
|
218
215
|
document.addEventListener('keydown', handleKeyDown, true);
|
|
219
216
|
return () => document.removeEventListener('keydown', handleKeyDown, true);
|
|
220
217
|
}, [isOpen, goToNextSlide, goToPreviousSlide, totalSlides, onClose, showEditor]);
|
|
221
|
-
// Always show controls
|
|
222
|
-
useEffect(() => {
|
|
223
|
-
if (isOpen) {
|
|
224
|
-
setShowControls(true);
|
|
225
|
-
}
|
|
226
|
-
}, [isOpen]);
|
|
227
218
|
// Download handlers
|
|
228
219
|
const handleDownload = async (format) => {
|
|
229
220
|
if (isDownloadRestricted) {
|
|
@@ -322,7 +313,7 @@ export function FullScreenPresentationViewer({ isOpen, onClose, presentationName
|
|
|
322
313
|
});
|
|
323
314
|
SlideIframeComponent.displayName = 'SlideIframeComponent';
|
|
324
315
|
return SlideIframeComponent;
|
|
325
|
-
}, [sandboxUrl, refreshTimestamp, showEditor, subdomainOpts, tHardcodedUi]);
|
|
316
|
+
}, [sandboxUrl, refreshTimestamp, showEditor, subdomainOpts, tHardcodedUi, tI18nComplete]);
|
|
326
317
|
if (!isOpen)
|
|
327
318
|
return null;
|
|
328
319
|
// Render slide iframe with proper scaling
|
|
@@ -331,7 +322,7 @@ export function FullScreenPresentationViewer({ isOpen, onClose, presentationName
|
|
|
331
322
|
? tHardcodedUi.raw('i18nComplete.textbd0b7be215ce')
|
|
332
323
|
: tHardcodedUi.raw('i18nComplete.text8268dd9ea939'), onClick: () => setShowEditor(!showEditor), children: showEditor ? (_jsx(Presentation, { className: "h-3.5 w-3.5" })) : (_jsx(Edit, { className: "h-3.5 w-3.5" })) }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "sm", className: "w-8 p-0", title: tHardcodedUi.raw('componentsThreadToolViewsPresentationToolsFullscreenpresentationviewer.line485JsxAttrTitleExportPresentation'), disabled: isDownloadingPDF || isDownloadingPPTX, children: isDownloadingPDF || isDownloadingPPTX ? (_jsx(KortixLoader, { customSize: 14 })) : (_jsx(Download, { className: "h-3.5 w-3.5" })) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-32", children: [_jsxs(DropdownMenuItem, { className: "cursor-pointer", onClick: () => handleDownload(DownloadFormat.PDF), disabled: isDownloadingPDF, children: [_jsx(FileText, { className: "mr-2 h-4 w-4" }), "PDF"] }), _jsxs(DropdownMenuItem, { className: "cursor-pointer", onClick: () => handleDownload(DownloadFormat.PPTX), disabled: isDownloadingPPTX, children: [_jsx(Presentation, { className: "mr-2 h-4 w-4" }), "PPTX"] })] })] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, className: "h-8 w-8 p-0", title: tHardcodedUi.raw('componentsThreadToolViewsPresentationToolsFullscreenpresentationviewer.line529JsxAttrTitleCloseFullScreen'), children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })] }) }), _jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center bg-zinc-100 p-2 dark:bg-zinc-900", children: isLoading || !currentSlideData ? (_jsxs("div", { className: "text-center", children: [_jsx(KortixLoader, { size: "large", className: "mx-auto mb-4" }), _jsx("p", { className: "text-zinc-700 dark:text-zinc-300", children: retryAttempt > 0
|
|
333
324
|
? tI18nComplete('text3df439a7a73b', { value0: retryAttempt + 1 })
|
|
334
|
-
: tHardcodedUi.raw('i18nComplete.text1ac9fe8126fa') })] })) : currentSlideData ? (_jsxs("div", { className: "flex h-full w-full flex-col", children: [_jsx("div", { className: "flex-1 overflow-hidden rounded-xl bg-transparent", style: { aspectRatio: '16 / 9' }, children: renderSlide }), _jsxs("div", { className: "mt-3 flex items-center justify-between px-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setCurrentSlide(1), disabled: currentSlide <= 1, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(SkipBack, { className: "h-3.5 w-3.5" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: goToPreviousSlide, disabled: currentSlide <= 1, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(ChevronLeft, { className: "h-4 w-4" }) })] }), _jsx("div", { className: "flex items-center", children: _jsx("div", { className: "flex gap-2", children: slides.map((slide) => (_jsx("button", { onClick: () => setCurrentSlide(slide.number), className: cn('h-2.5 w-2.5 rounded-full transition-colors duration-200', slide.number === currentSlide
|
|
325
|
+
: tHardcodedUi.raw('i18nComplete.text1ac9fe8126fa') })] })) : currentSlideData ? (_jsxs("div", { className: "flex h-full w-full flex-col", children: [_jsx("div", { className: "flex-1 overflow-hidden rounded-xl bg-transparent", style: { aspectRatio: '16 / 9' }, children: renderSlide }), _jsxs("div", { className: "mt-3 flex items-center justify-between px-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setCurrentSlide(1), disabled: currentSlide <= 1, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(SkipBack, { className: "h-3.5 w-3.5" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: goToPreviousSlide, disabled: currentSlide <= 1, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(ChevronLeft, { className: "h-4 w-4" }) })] }), _jsx("div", { className: "flex items-center", children: _jsx("div", { className: "flex gap-2", children: slides.map((slide) => (_jsx("button", { "aria-label": `${tHardcodedUi.raw('i18nComplete.text6bb4c1177681')} ${slide.number}`, onClick: () => setCurrentSlide(slide.number), className: cn('h-2.5 w-2.5 rounded-full transition-colors duration-200', slide.number === currentSlide
|
|
335
326
|
? 'bg-black dark:bg-white'
|
|
336
327
|
: 'bg-zinc-300 hover:bg-zinc-400 dark:bg-zinc-600 dark:hover:bg-zinc-500') }, slide.number))) }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: goToNextSlide, disabled: currentSlide >= totalSlides, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(ChevronRight, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setCurrentSlide(totalSlides), disabled: currentSlide >= totalSlides, className: "h-8 w-8 p-0 disabled:opacity-50", children: _jsx(SkipForward, { className: "h-3.5 w-3.5" }) })] })] })] })) : (_jsx("div", { className: "text-center", children: _jsx("p", { className: "text-zinc-700 dark:text-zinc-300", children: tHardcodedUi.raw('componentsThreadToolViewsPresentationToolsFullscreenpresentationviewer.line621JsxTextNoSlideFound') }) })) })] }));
|
|
337
328
|
}
|
|
@@ -692,7 +692,7 @@ export function ShowCarousel({ items, LocalhostPreview, onIndexChange, fill = fa
|
|
|
692
692
|
const currentItem = items[currentIndex];
|
|
693
693
|
if (!currentItem)
|
|
694
694
|
return null;
|
|
695
|
-
return (_jsxs("div", { className: cn('outline-none', fill && 'flex h-full flex-col'),
|
|
695
|
+
return (_jsxs("div", { role: "group", className: cn('outline-none', fill && 'flex h-full flex-col'),
|
|
696
696
|
// -1: a click on the content focuses the card, so ←/→ page it next,
|
|
697
697
|
// without adding a Tab stop. Tab still reaches the chevrons inside.
|
|
698
698
|
tabIndex: fill || count < 2 ? undefined : -1, onKeyDown: fill || count < 2 ? undefined : (e) => handleArrowKey(e), children: [_jsx("div", { className: cn(fill ? 'min-h-0 flex-1 overflow-hidden' : 'min-h-[420px]'), children: currentItem.status === 'pending' ? (_jsxs("div", { className: cn('flex items-center justify-center gap-3', fill ? 'h-full' : 'min-h-[420px]'), children: [_jsx(Loading, { className: "text-muted-foreground size-4" }), _jsx(TextShimmer, { duration: 1, spread: 2, className: "text-sm", children: tHardcodedUi.raw('componentsSessionToolRenderers.line4935JsxTextPreparingOutput') })] })) : (_jsx(ShowContentRenderer, { type: currentItem.type, title: currentItem.title, description: currentItem.description, path: currentItem.path, url: currentItem.url, content: currentItem.content, language: currentItem.language, aspectRatio: currentItem.aspect_ratio, attachment: currentItem.attachment, LocalhostPreview: LocalhostPreview, toolbarActions: toolbarActions, fill: fill })) }), count > 1 && !hideNav && (_jsxs("div", { className: "border-border flex shrink-0 items-center gap-2 border-t px-2 py-1.5 pr-3.5", children: [_jsxs("div", { className: "flex shrink-0 items-center", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: prev, className: "hit-area-2 hit-area-r-0 transition-transform active:scale-[0.96]", disabled: currentIndex === 0, "aria-label": tI18nComplete.raw('text81b35f1b4332'), children: _jsx(ChevronLeft, { className: "size-4" }) }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: next, className: "hit-area-2 hit-area-l-0 transition-transform active:scale-[0.96]", disabled: currentIndex >= count - 1, "aria-label": tI18nComplete.raw('text1e47d4f7a1a3'), children: _jsx(ChevronRight, { className: "size-4" }) })] }), _jsx(FadedScrollArea, { ref: stripRef, orientation: "horizontal", fadeColor: "from-secondary", className: "min-w-0 flex-1 overscroll-x-contain", children: _jsx("div", { className: "flex w-max min-w-0 items-center gap-1", children: items.map((item, i) => {
|