@kortix/ui 0.14.8 → 0.14.10
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/README.md +2 -2
- package/dist/_vendor/kortix-shared.js +116 -3
- package/dist/_vendor/shared/app-config.d.ts +175 -0
- package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
- package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
- package/dist/_vendor/shared/channel-message.d.ts +45 -5
- package/dist/_vendor/shared/index.d.ts +2 -0
- package/dist/_vendor/shared/space-slug.d.ts +37 -0
- package/dist/access/access/access-detail-shell.js +1 -1
- package/dist/access/access/principal-picker.d.ts +11 -0
- package/dist/access/access/principal-picker.js +3 -2
- package/dist/apps/app-preview-pool.d.ts +7 -2
- package/dist/apps/app-preview-pool.js +30 -7
- package/dist/apps/app-shared.d.ts +22 -15
- package/dist/apps/app-shared.js +37 -19
- package/dist/apps/index.d.ts +2 -2
- package/dist/apps/index.js +2 -2
- package/dist/artifacts/artifact-frame.d.ts +16 -0
- package/dist/artifacts/artifact-frame.js +55 -0
- package/dist/artifacts/artifact-session.d.ts +18 -0
- package/dist/artifacts/artifact-session.js +101 -0
- package/dist/artifacts/frame-policy.d.ts +30 -0
- package/dist/artifacts/frame-policy.js +61 -0
- package/dist/artifacts/index.d.ts +3 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +2 -2
- package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
- package/dist/customize/agents/agent-grant-pages.js +30 -4
- package/dist/customize/agents/agent-page.js +3 -1
- package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
- package/dist/customize/agents/agent-policy-sets.js +72 -0
- package/dist/customize/agents/agent-triggers-section.js +2 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
- package/dist/customize/connectors/agent-access.d.ts +35 -0
- package/dist/customize/connectors/agent-access.js +77 -0
- package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
- package/dist/customize/connectors/catalog/browse-sections.js +7 -74
- package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
- package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
- package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
- package/dist/customize/connectors/catalog/connector-browse.js +19 -50
- package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
- package/dist/customize/connectors/catalog/use-catalog.js +48 -175
- package/dist/customize/connectors/connector-identity.d.ts +9 -11
- package/dist/customize/connectors/connector-identity.js +13 -42
- package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
- package/dist/customize/connectors/connector-moves-banner.js +4 -6
- package/dist/customize/connectors/connector-routes.d.ts +21 -9
- package/dist/customize/connectors/connector-routes.js +29 -20
- package/dist/customize/connectors/connectors-page.js +53 -82
- package/dist/customize/connectors/detail/app-page.js +226 -98
- package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
- package/dist/customize/connectors/detail/computer-app-page.js +39 -0
- package/dist/customize/connectors/detail/connector-accounts.js +3 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
- package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
- package/dist/customize/connectors/detail/connector-agents.js +69 -0
- package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
- package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
- package/dist/customize/connectors/detail/connector-move-row.js +23 -14
- package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-page.js +14 -10
- package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
- package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
- package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-settings.js +7 -3
- package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
- package/dist/customize/connectors/detail/connector-status.js +34 -10
- package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-tabs.js +8 -2
- package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
- package/dist/customize/connectors/detail/connector-tools.js +105 -48
- package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
- package/dist/customize/connectors/detail/email-inboxes.js +184 -0
- package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
- package/dist/customize/connectors/detail/provider-info.js +2 -2
- package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
- package/dist/customize/connectors/detail/status-badge.js +4 -5
- package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
- package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
- package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
- package/dist/customize/connectors/install/install-dialog.js +40 -0
- package/dist/customize/connectors/install/install.d.ts +13 -2
- package/dist/customize/connectors/install/install.js +9 -4
- package/dist/customize/connectors/install/use-install.d.ts +19 -2
- package/dist/customize/connectors/install/use-install.js +65 -37
- package/dist/customize/connectors/install/way-kind.d.ts +5 -0
- package/dist/customize/connectors/install/way-kind.js +16 -0
- package/dist/customize/connectors/provider-label.d.ts +2 -1
- package/dist/customize/connectors/provider-label.js +13 -3
- package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
- package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
- package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
- package/dist/customize/connectors/tools/policy-sets.js +41 -0
- package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
- package/dist/customize/connectors/tools/tool-groups.js +78 -16
- package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
- package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
- package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
- package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
- package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
- package/dist/customize/connectors/tools/tool-policy.js +74 -8
- package/dist/customize/connectors/use-agent-access.d.ts +85 -0
- package/dist/customize/connectors/use-agent-access.js +72 -0
- package/dist/customize/migrate-to-v2/index.d.ts +1 -2
- package/dist/customize/migrate-to-v2/index.js +1 -2
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
- package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
- package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
- package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
- package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
- package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
- package/dist/customize/providers/provider-accordion.js +17 -2
- package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
- package/dist/customize/sections/component/channel-access-panel.js +146 -0
- package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
- package/dist/customize/sections/component/channel-connect-hero.js +3 -2
- package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
- package/dist/customize/sections/component/channel-hero-frame.js +40 -0
- package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
- package/dist/customize/sections/component/channel-mocks.js +46 -0
- package/dist/customize/sections/component/channel-row.d.ts +13 -3
- package/dist/customize/sections/component/channel-row.js +10 -4
- package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
- package/dist/customize/sections/component/email-connect-form.js +183 -0
- package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/slack-connect-card.js +2 -3
- package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/teams-connect-card.js +2 -3
- package/dist/customize/sections/component/telegram-channel-row.js +21 -28
- package/dist/customize/sections/connectors-view.d.ts +1 -15
- package/dist/customize/sections/connectors-view.js +81 -314
- package/dist/customize/sections/view/agent-editor-catalog.js +10 -0
- package/dist/customize/sections/view/channels-view.d.ts +6 -1
- package/dist/customize/sections/view/channels-view.js +72 -81
- package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
- package/dist/customize/settings/rail.js +9 -0
- package/dist/customize/settings/settings-tabs.d.ts +1 -1
- package/dist/customize/settings/settings-tabs.js +1 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
- package/dist/customize/settings/tabs/experimental-tab.js +35 -16
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +4 -15
- package/dist/customize/shared/catalog/catalog-empty-state.js +9 -7
- package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
- package/dist/customize/shared/channels-switch-dialog.js +30 -0
- package/dist/customize/shared/feature-gate-screen.js +27 -9
- package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
- package/dist/customize/shared/use-customize-prefetch.js +9 -27
- package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
- package/dist/customize/triggers/schedule/post-to-field.js +49 -0
- package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
- package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
- package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
- package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
- package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
- package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
- package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
- package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
- package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
- package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
- package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
- package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
- package/dist/customize/triggers/schedule-view.js +5 -2
- package/dist/files/index.d.ts +1 -0
- package/dist/files/index.js +1 -0
- package/dist/files/project/change-request-recovery.d.ts +1 -26
- package/dist/files/project/change-request-recovery.js +1 -59
- package/dist/files/project/components/change-request-detail-dialog.js +13 -3
- package/dist/files/project/components/drive-explorer.js +15 -15
- package/dist/files/project/components/drive-toolbar.d.ts +16 -2
- package/dist/files/project/components/drive-toolbar.js +14 -5
- package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
- package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
- package/dist/files/project/hooks/use-change-requests.js +11 -2
- package/dist/files/renderers/image-frame.d.ts +48 -0
- package/dist/files/renderers/image-frame.js +59 -0
- package/dist/files/renderers/image-renderer.d.ts +11 -1
- package/dist/files/renderers/image-renderer.js +13 -3
- package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
- package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
- package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
- package/dist/files/renderers/show-content-renderer.d.ts +9 -1
- package/dist/files/renderers/show-content-renderer.js +56 -14
- package/dist/files/runtime/file-source.js +2 -0
- package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
- package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
- package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
- package/dist/files/runtime/hooks/use-shared-image.js +177 -0
- package/dist/files/viewer/file-content-renderer.d.ts +22 -1
- package/dist/files/viewer/file-content-renderer.js +50 -7
- package/dist/files/viewer/file-header.d.ts +7 -3
- package/dist/files/viewer/file-header.js +20 -11
- package/dist/files/viewer/file-preview-modal.d.ts +1 -1
- package/dist/files/viewer/file-preview-modal.js +10 -22
- package/dist/files/viewer/file-source.d.ts +13 -0
- package/dist/files/viewer/use-file-content-state.d.ts +2 -0
- package/dist/files/viewer/use-file-content-state.js +28 -10
- package/dist/files/viewer/viewer-actions.d.ts +3 -1
- package/dist/files/viewer/viewer-actions.js +2 -2
- package/dist/hooks/use-media-query.d.ts +1 -0
- package/dist/hooks/use-mobile.d.ts +5 -0
- package/dist/hooks/use-mobile.js +8 -0
- package/dist/i18n/en.d.ts +1062 -85
- package/dist/i18n/en.js +1078 -101
- package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
- package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
- package/dist/internal/account-hub/hub-sheet.js +21 -5
- package/dist/internal/account-hub/sections.d.ts +1 -1
- package/dist/internal/account-hub/sections.js +2 -1
- package/dist/internal/apps-and-extensions/apps-modal.d.ts +9 -0
- package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
- package/dist/internal/auth/auth-card-shell.js +3 -3
- package/dist/internal/chrome/browser-icon.d.ts +24 -0
- package/dist/internal/chrome/browser-icon.js +58 -0
- package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
- package/dist/internal/chrome/chrome-card-state.js +9 -0
- package/dist/internal/chrome/chrome-connect.d.ts +69 -0
- package/dist/internal/chrome/chrome-connect.js +178 -0
- package/dist/internal/chrome/chrome-mock.d.ts +4 -0
- package/dist/internal/chrome/chrome-mock.js +15 -0
- package/dist/internal/chrome/chrome-names.d.ts +15 -0
- package/dist/internal/chrome/chrome-names.js +35 -0
- package/dist/internal/chrome/extension.d.ts +47 -0
- package/dist/internal/chrome/extension.js +91 -0
- package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
- package/dist/internal/chrome/use-chrome-offered.js +22 -0
- package/dist/internal/components/agent-mark.js +5 -2
- package/dist/internal/connector-logo/connector-logo-source.d.ts +64 -0
- package/dist/internal/connector-logo/connector-logo-source.js +49 -0
- package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
- package/dist/internal/connector-logo/connector-logo.js +56 -0
- package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
- package/dist/internal/connector-logo/connector-mark-files.js +35 -0
- package/dist/internal/files/file-read-retry.d.ts +13 -0
- package/dist/internal/files/file-read-retry.js +23 -3
- package/dist/internal/files/session-drive-files.d.ts +5 -1
- package/dist/internal/files/session-drive-files.js +7 -2
- package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
- package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
- package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
- package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
- package/dist/internal/hooks/connectors/use-add-account.js +1 -1
- package/dist/internal/hooks/index.d.ts +1 -1
- package/dist/internal/hooks/index.js +1 -1
- package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
- package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
- package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
- package/dist/internal/hooks/use-auto-scroll.js +4 -4
- package/dist/internal/icons/edge.d.ts +5 -0
- package/dist/internal/icons/edge.js +10 -0
- package/dist/internal/icons/telegram.d.ts +5 -0
- package/dist/internal/icons/telegram.js +6 -1
- package/dist/internal/layout/nav-hover-card.d.ts +35 -0
- package/dist/internal/layout/nav-hover-card.js +84 -0
- package/dist/internal/layout/project-nav-row.d.ts +3 -1
- package/dist/internal/layout/project-nav-row.js +3 -2
- package/dist/internal/layout/project-page-header.d.ts +4 -2
- package/dist/internal/layout/project-page-header.js +4 -3
- package/dist/internal/layout/project-settings-nav.js +59 -2
- package/dist/internal/lib/browser-error-noise.d.ts +1 -1
- package/dist/internal/lib/browser-error-noise.js +1 -1
- package/dist/internal/lib/browser-noise/rules/extensions.js +17 -3
- package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
- package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
- package/dist/internal/lib/detect-os.d.ts +43 -0
- package/dist/internal/lib/detect-os.js +70 -0
- package/dist/internal/lib/manifest-version.d.ts +1 -1
- package/dist/internal/lib/manifest-version.js +2 -2
- package/dist/internal/lib/memory-href.d.ts +16 -0
- package/dist/internal/lib/memory-href.js +46 -0
- package/dist/internal/lib/use-project-feature-flags.js +13 -9
- package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
- package/dist/internal/lib/utils/heic-convert.js +3 -4
- package/dist/internal/lib/web-notifications.d.ts +20 -0
- package/dist/internal/lib/web-notifications.js +48 -4
- package/dist/internal/notifications/notification-bell.d.ts +4 -1
- package/dist/internal/notifications/notification-bell.js +2 -2
- package/dist/internal/selection/selection-bar.d.ts +2 -1
- package/dist/internal/selection/selection-bar.js +1 -1
- package/dist/internal/stores/apps-modal-store.d.ts +8 -0
- package/dist/internal/stores/apps-modal-store.js +6 -0
- package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
- package/dist/internal/stores/file-preview-store.d.ts +29 -2
- package/dist/internal/stores/file-preview-store.js +19 -1
- package/dist/internal/stores/kortix-computer-store.js +3 -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 +13 -1
- package/dist/lib/routes.js +13 -0
- package/dist/markdown/index.d.ts +2 -1
- package/dist/markdown/index.js +2 -1
- package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
- package/dist/markdown/setup-links/approval-decision.js +9 -3
- package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
- package/dist/markdown/setup-links/connector-handshake.js +12 -10
- package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
- package/dist/markdown/setup-links/secret-intake-form.js +1 -1
- package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
- package/dist/markdown/setup-links/show-connect-hero.js +91 -0
- package/dist/markdown/unified-markdown.js +5 -5
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.js +2 -0
- package/dist/primitives/disclosure.js +14 -2
- package/dist/primitives/empty-art.d.ts +12 -0
- package/dist/primitives/empty-art.js +11 -0
- package/dist/primitives/empty-state.d.ts +2 -2
- package/dist/primitives/empty-state.js +6 -5
- package/dist/primitives/mermaid-renderer.d.ts +2 -0
- package/dist/primitives/mermaid-renderer.js +21 -15
- package/dist/primitives/resizable.js +6 -1
- package/dist/primitives/resize-seam.d.ts +11 -0
- package/dist/primitives/resize-seam.js +12 -0
- package/dist/primitives/sidebar-panel.js +4 -7
- package/dist/primitives/tabs.d.ts +14 -1
- package/dist/primitives/tabs.js +1 -1
- package/dist/providers/ui-provider.d.ts +9 -0
- package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
- package/dist/session/composer/ComposerAboveCard.js +2 -2
- package/dist/session/composer/ComposerCard.d.ts +1 -1
- package/dist/session/composer/ComposerCard.js +3 -3
- package/dist/session/composer/agent-selector.d.ts +13 -1
- package/dist/session/composer/agent-selector.js +25 -5
- package/dist/session/composer/composer-agent-access.d.ts +15 -0
- package/dist/session/composer/composer-agent-access.js +27 -0
- package/dist/session/composer/composer-chat-input.d.ts +8 -2
- package/dist/session/composer/composer-chat-input.js +8 -6
- package/dist/session/composer/composer-logic.d.ts +16 -0
- package/dist/session/composer/composer-logic.js +12 -0
- package/dist/session/composer/composer-underbar.d.ts +3 -1
- package/dist/session/composer/composer-underbar.js +4 -3
- package/dist/session/composer/composer.d.ts +15 -1
- package/dist/session/composer/composer.js +19 -1
- package/dist/session/composer/draft/composer-draft.d.ts +6 -2
- package/dist/session/composer/draft/composer-draft.js +5 -1
- package/dist/session/composer/reasoning-effort-selector.js +1 -1
- package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
- package/dist/session/models/chatgpt-connection-button.js +54 -0
- package/dist/session/models/model-selector.js +5 -2
- package/dist/session/models/use-model-connection-gate.d.ts +5 -5
- package/dist/session/models/use-model-connection-gate.js +5 -5
- package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
- package/dist/session/outcomes/jump-to-outcome.js +11 -0
- package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
- package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
- package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
- package/dist/session/outcomes/session-outcomes-provider.js +33 -3
- package/dist/session/panel/easy/app-preview.d.ts +10 -0
- package/dist/session/panel/easy/app-preview.js +31 -12
- package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
- package/dist/session/panel/easy/change-requests-card.js +17 -0
- package/dist/session/panel/easy/easy-panel-logic.js +7 -1
- package/dist/session/panel/easy/easy-panel.js +5 -2
- package/dist/session/panel/easy/file-preview.js +1 -1
- package/dist/session/panel/easy/outputs-card.d.ts +2 -1
- package/dist/session/panel/easy/outputs-card.js +3 -2
- package/dist/session/panel/mobile-tool-drawer.js +7 -1
- package/dist/session/panel/session-audit-panel.js +9 -2
- package/dist/session/panel/session-audit-shared.js +3 -1
- package/dist/session/panel/session-detail-panel.js +9 -3
- package/dist/session/panel/session-files-explorer.d.ts +9 -0
- package/dist/session/panel/session-files-explorer.js +12 -3
- package/dist/session/panel/session-panel-provider.d.ts +15 -1
- package/dist/session/panel/session-panel-provider.js +32 -7
- package/dist/session/panel/shared/derive-panels.d.ts +8 -1
- package/dist/session/panel/shared/derive-panels.js +12 -2
- package/dist/session/panel/shared/output-priority.js +2 -0
- package/dist/session/participants/session-participants.d.ts +8 -2
- package/dist/session/participants/session-participants.js +11 -4
- package/dist/session/prompts/approval-request.d.ts +5 -0
- package/dist/session/prompts/approval-request.js +9 -1
- package/dist/session/prompts/session-approval-review.d.ts +9 -0
- package/dist/session/prompts/session-approval-review.js +18 -0
- package/dist/session/status/session-error-banner.js +2 -49
- package/dist/session/status/session-starting-loader.d.ts +14 -2
- package/dist/session/status/session-starting-loader.js +16 -4
- package/dist/session/thread/after-first-prompt.d.ts +7 -0
- package/dist/session/thread/after-first-prompt.js +8 -0
- package/dist/session/thread/detect-command.d.ts +12 -0
- package/dist/session/thread/detect-command.js +20 -0
- package/dist/session/thread/session-chat.d.ts +3 -1
- package/dist/session/thread/session-chat.js +377 -252
- package/dist/session/thread/session-thread.d.ts +15 -1
- package/dist/session/thread/session-thread.js +20 -3
- package/dist/session/thread/session-transcript-class.d.ts +5 -1
- package/dist/session/thread/session-transcript-class.js +5 -1
- package/dist/session/thread/thread-boot-rows.d.ts +36 -0
- package/dist/session/thread/thread-boot-rows.js +89 -0
- package/dist/session/thread/transcript-rows.d.ts +31 -0
- package/dist/session/thread/transcript-rows.js +3 -0
- package/dist/session/thread/transcript.d.ts +0 -9
- package/dist/session/thread/transcript.js +104 -19
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
- package/dist/session/tool/tool-part-renderer.d.ts +5 -4
- package/dist/session/tool/tool-part-renderer.js +8 -3
- package/dist/session/tool/tools/bash-tool.js +7 -6
- package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
- package/dist/session/tool/tools/channel-send.d.ts +2 -1
- package/dist/session/tool/tools/codemode-tool.js +1 -1
- package/dist/session/tool/tools/connector-tools.js +1 -1
- package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
- package/dist/session/tool/tools/image-gen-tool.js +241 -53
- package/dist/session/tool/tools/show-tool.js +19 -8
- package/dist/session/turn/channel-brand.d.ts +8 -3
- package/dist/session/turn/channel-brand.js +20 -4
- package/dist/session/turn/message-author.d.ts +8 -0
- package/dist/session/turn/message-author.js +24 -0
- package/dist/session/turn/message-row.d.ts +52 -0
- package/dist/session/turn/message-row.js +44 -0
- package/dist/session/turn/plan-anchor.d.ts +1 -1
- package/dist/session/turn/plan-anchor.js +1 -1
- package/dist/session/turn/user-message.d.ts +14 -6
- package/dist/session/turn/user-message.js +35 -15
- package/dist/styles.css +1 -1
- package/dist/workspace/home/access-requests-bell.d.ts +9 -2
- package/dist/workspace/home/access-requests-bell.js +20 -6
- package/dist/workspace/home/first-chat.d.ts +8 -21
- package/dist/workspace/home/first-chat.js +22 -72
- package/dist/workspace/index.d.ts +6 -0
- package/dist/workspace/index.js +6 -0
- package/dist/workspace/layout/project-home.d.ts +14 -2
- package/dist/workspace/layout/project-home.js +60 -21
- package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
- package/dist/workspace/layout/use-project-home-send.js +82 -3
- package/dist/workspace/memory/body-doc.d.ts +17 -0
- package/dist/workspace/memory/body-doc.js +208 -0
- package/dist/workspace/memory/body-extensions.d.ts +38 -0
- package/dist/workspace/memory/body-extensions.js +103 -0
- package/dist/workspace/memory/company-memory-page.d.ts +8 -0
- package/dist/workspace/memory/company-memory-page.js +16 -0
- package/dist/workspace/memory/memory-all.d.ts +20 -0
- package/dist/workspace/memory/memory-all.js +27 -0
- package/dist/workspace/memory/memory-body.d.ts +19 -0
- package/dist/workspace/memory/memory-body.js +139 -0
- package/dist/workspace/memory/memory-empty.d.ts +13 -0
- package/dist/workspace/memory/memory-empty.js +28 -0
- package/dist/workspace/memory/memory-history.d.ts +27 -0
- package/dist/workspace/memory/memory-history.js +108 -0
- package/dist/workspace/memory/memory-labels.d.ts +16 -0
- package/dist/workspace/memory/memory-labels.js +47 -0
- package/dist/workspace/memory/memory-page-list.d.ts +34 -0
- package/dist/workspace/memory/memory-page-list.js +156 -0
- package/dist/workspace/memory/memory-reader.d.ts +58 -0
- package/dist/workspace/memory/memory-reader.js +123 -0
- package/dist/workspace/memory/memory-view.d.ts +21 -0
- package/dist/workspace/memory/memory-view.js +124 -0
- package/dist/workspace/memory/remember-popover.d.ts +19 -0
- package/dist/workspace/memory/remember-popover.js +61 -0
- package/dist/workspace/memory/remember-this.d.ts +12 -0
- package/dist/workspace/memory/remember-this.js +89 -0
- package/dist/workspace/memory/source-mark.d.ts +18 -0
- package/dist/workspace/memory/source-mark.js +79 -0
- package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
- package/dist/workspace/memory/used-memory-chip.js +61 -0
- package/dist/workspace/new/advanced-fields.d.ts +2 -1
- package/dist/workspace/new/advanced-fields.js +2 -2
- package/dist/workspace/new/source-param.d.ts +1 -1
- package/dist/workspace/new/source-param.js +3 -1
- package/dist/workspace/new/use-create-workspace.d.ts +8 -10
- package/dist/workspace/new/use-create-workspace.js +3 -3
- package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
- package/dist/workspace/projects/onboarding/app-logo.js +6 -13
- package/dist/workspace/projects/policies-panel.js +5 -3
- package/dist/workspace/review/review-actions.d.ts +4 -2
- package/dist/workspace/review/review-actions.js +8 -2
- package/dist/workspace/review/review-center.js +11 -7
- package/dist/workspace/review/review-detail.d.ts +10 -0
- package/dist/workspace/review/review-detail.js +101 -13
- package/dist/workspace/saved-session-skeleton.d.ts +2 -2
- package/dist/workspace/saved-session-skeleton.js +3 -3
- package/dist/workspace/session-workspace.js +15 -13
- package/dist/workspace/sessions/project-sessions-view.js +3 -2
- package/dist/workspace/sessions/session-label-badges.js +2 -1
- package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
- package/dist/workspace/sessions/sessions-toolbar.js +2 -2
- package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
- package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
- package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
- package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.d.ts +10 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -0
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
- package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
- package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
- 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 +68 -56
- package/dist/workspace/sidebar/project-sidebar.js +13 -2
- package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
- package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
- package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
- package/dist/workspace/sidebar/session-group-order.js +25 -0
- package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
- package/dist/workspace/sidebar/session-group-sections.js +267 -0
- package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
- package/dist/workspace/sidebar/session-list-chrome.js +50 -0
- package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
- package/dist/workspace/spaces/channel-glyph.js +6 -0
- package/dist/workspace/spaces/channel-setup.d.ts +16 -0
- package/dist/workspace/spaces/channel-setup.js +105 -0
- package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
- package/dist/workspace/spaces/channels-onboarding.js +37 -0
- package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
- package/dist/workspace/spaces/create-channel-dialog.js +158 -0
- package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
- package/dist/workspace/spaces/private-channels-not-in.js +69 -0
- package/dist/workspace/spaces/space-agents.d.ts +10 -0
- package/dist/workspace/spaces/space-agents.js +10 -0
- package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
- package/dist/workspace/spaces/space-details-dialog.js +176 -0
- package/dist/workspace/spaces/space-link-label.d.ts +49 -0
- package/dist/workspace/spaces/space-link-label.js +73 -0
- package/dist/workspace/spaces/space-links.d.ts +19 -0
- package/dist/workspace/spaces/space-links.js +230 -0
- package/dist/workspace/spaces/space-members.d.ts +46 -0
- package/dist/workspace/spaces/space-members.js +182 -0
- package/dist/workspace/spaces/space-roster.d.ts +15 -0
- package/dist/workspace/spaces/space-roster.js +44 -0
- package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
- package/dist/workspace/spaces/space-threads-tab.js +156 -0
- package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
- package/dist/workspace/spaces/space-timeline-view.js +235 -0
- package/dist/workspace/spaces/space-timeline.d.ts +106 -0
- package/dist/workspace/spaces/space-timeline.js +183 -0
- package/dist/workspace/spaces/space-triggers.d.ts +13 -0
- package/dist/workspace/spaces/space-triggers.js +78 -0
- package/dist/workspace/spaces/space-view.d.ts +37 -0
- package/dist/workspace/spaces/space-view.js +436 -0
- package/package.json +67 -36
- package/skills/kortix-ui/SKILL.md +3 -3
- package/skills/kortix-ui/references/custom-dashboard.md +3 -3
- package/skills/kortix-ui/references/modules.md +29 -5
- package/skills/kortix-ui/references/theming.md +1 -1
- package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
- package/dist/customize/connectors/catalog/merge-search.js +0 -26
- package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
- package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
- package/dist/customize/sections/connector-connection-header.d.ts +0 -36
- package/dist/customize/sections/connector-connection-header.js +0 -33
- package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
- package/dist/customize/sections/connector-connection-modal.js +0 -72
- package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
- package/dist/customize/sections/discover-catalogue-card.js +0 -26
- package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
- package/dist/customize/sections/discover-catalogue-detail.js +0 -24
- package/dist/customize/sections/discover-catalogue.d.ts +0 -17
- package/dist/customize/sections/discover-catalogue.js +0 -132
- package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
- package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
- package/dist/files/project/components/drive-empty-art.d.ts +0 -2
- package/dist/files/project/components/drive-empty-art.js +0 -5
- package/dist/internal/hooks/use-media-query.d.ts +0 -2
- package/dist/internal/share/public-share-link-button.d.ts +0 -14
- package/dist/internal/share/public-share-link-button.js +0 -17
- package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
- package/dist/markdown/setup-links/app-credentials-form.js +0 -115
- /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
|
@@ -8,7 +8,7 @@ import { SessionSharedIcon } from '../projects/session-shared-icon.js';
|
|
|
8
8
|
import { Button } from '../../primitives/button.js';
|
|
9
9
|
import { CountBadge } from '../../primitives/count-badge.js';
|
|
10
10
|
import { Disclosure, DisclosureContent, DisclosureTrigger } from '../../primitives/disclosure.js';
|
|
11
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../primitives/dropdown-menu.js';
|
|
11
|
+
import { DropdownMenu, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../primitives/dropdown-menu.js';
|
|
12
12
|
import { FadedScrollArea } from '../../primitives/faded-scroll-area.js';
|
|
13
13
|
import Hint from '../../primitives/hint.js';
|
|
14
14
|
import { KortixLogo } from '../../primitives/kortix-logo.js';
|
|
@@ -28,6 +28,8 @@ import { ShareSessionModal } from './modal/share-session-modal.js';
|
|
|
28
28
|
import { getSessionDisplayTitle, groupChangeRequestsBySession, projectSessionsRefetchInterval, resolveSessionListViewState, shortRelative, starterSectionOf, } from '../../session/actions/project-session-list-helpers.js';
|
|
29
29
|
import { MobileSessionCreatedTime, SessionBriefDescription, SessionBriefCardHost, SessionBriefHoverCard, SubagentHoverCard, } from './session-brief-hover-card.js';
|
|
30
30
|
import { SessionFilterMenu } from './session-filter-menu.js';
|
|
31
|
+
import { SESSION_MENU_TRIGGER_CLASS, SESSION_ROW_HEIGHT_CLASS, SIDEBAR_PAGE_SIZE, ShowMoreButton, } from './session-list-chrome.js';
|
|
32
|
+
import { SessionGroupNameModal, SessionGroupSections, UngroupDropArea, startSessionDrag, useSessionGroupActions, } from './session-group-sections.js';
|
|
31
33
|
import { groupSessions, } from './session-grouping.js';
|
|
32
34
|
import { useSessionOpenIntent } from './session-open-intent.js';
|
|
33
35
|
import { isReviewOverdue, SessionStatusMark } from './session-status-mark.js';
|
|
@@ -39,8 +41,8 @@ import { selectExpandedIds, useSessionExpandedStore } from '../../internal/store
|
|
|
39
41
|
import { selectCollapsedSections, selectGroupMode, selectHiddenSections, selectLabelFilters, selectOrderMode, selectSourceFilters, selectStatusFilters, useSessionFilterStore, } from '../../internal/stores/session-filter-store.js';
|
|
40
42
|
import { shouldBeginSessionSwitch, useSessionSwitchStore } from '../../internal/stores/session-switch-store.js';
|
|
41
43
|
import { directSubsessions, createProjectSession, listChangeRequests, restartProjectSession, sessionParentId, stopProjectSession, } from '@kortix/sdk';
|
|
42
|
-
import { qk, useProjectSession, useProjectSessions, useRuntimeSupports, useSessionChildren, useFeatureFlag, useSessionGoal, } from '@kortix/sdk/react';
|
|
43
|
-
import { ArchiveIcon, ArrowsSplitIcon, CaretRightIcon, DotsThreeIcon, PushPinIcon, PushPinSlashIcon, RobotIcon, GitForkIcon, PencilSimpleIcon, ArrowCounterClockwiseIcon as RotateCcw, ShareIcon as Share, SparkleIcon, TargetIcon, SquareIcon as Square, TagIcon, TrashIcon, TreeViewIcon, } from '@phosphor-icons/react';
|
|
44
|
+
import { qk, useProjectSession, useProjectSessions, useRuntimeSupports, useSessionChildren, useFeatureFlag, useProjectSessionGroups, useSessionGoal, } from '@kortix/sdk/react';
|
|
45
|
+
import { ArchiveIcon, ArrowsSplitIcon, CaretRightIcon, CheckIcon, DotsThreeIcon, FolderSimpleIcon, FolderSimpleMinusIcon, FolderSimplePlusIcon, PushPinIcon, PushPinSlashIcon, RobotIcon, GitForkIcon, PencilSimpleIcon, ArrowCounterClockwiseIcon as RotateCcw, ShareIcon as Share, SparkleIcon, TargetIcon, SquareIcon as Square, TagIcon, TrashIcon, TreeViewIcon, } from '@phosphor-icons/react';
|
|
44
46
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
45
47
|
import { formatDistanceToNowStrict } from 'date-fns';
|
|
46
48
|
import { useUiPathname, useUiRouter, useUiSearchParams, useUiViewerId } from '../../providers/ui-provider.js';
|
|
@@ -48,38 +50,6 @@ import { useEffect, useId, useMemo, useState } from 'react';
|
|
|
48
50
|
import { useSessionListActions } from '../../session/actions/use-session-list-actions.js';
|
|
49
51
|
import { Separator } from '../../primitives/separator.js';
|
|
50
52
|
const SESSION_RELATIVE_TIME_CLASS = 'text-muted-foreground block w-10 min-w-10 max-w-10 shrink-0 truncate text-right text-xs tabular-nums';
|
|
51
|
-
/** The one `⋯` box. All three menus in this file — the `Sessions` header, every
|
|
52
|
-
* section header, and every session row — render `Button variant="ghost"
|
|
53
|
-
* size="icon-xs"` with THIS class, so the glyph sits on a single vertical
|
|
54
|
-
* axis at every level of the tree.
|
|
55
|
-
*
|
|
56
|
-
* The geometry, given every row is `px-2` inside the same column: the trigger
|
|
57
|
-
* is flush to the right edge of that padded box, so its 24px square spans
|
|
58
|
-
* `[W-32, W-8]` and the 16px glyph inside spans `[W-28, W-12]` — identical for
|
|
59
|
-
* all three, at any sidebar width.
|
|
60
|
-
*
|
|
61
|
-
* Do NOT rebuild this from `SidebarMenuButton`. That primitive's base carries
|
|
62
|
-
* `p-2 w-full h-8 gap-2 overflow-hidden`; `size-6` only beats `w-full`/`h-8`
|
|
63
|
-
* through tailwind-merge, and `p-2` survives outright — leaving a 16px icon
|
|
64
|
-
* overflowing an 8px content box, centered by coincidence rather than by
|
|
65
|
-
* layout, with a different hover fill than the other two. */
|
|
66
|
-
const SESSION_MENU_TRIGGER_CLASS = cn('text-muted-foreground shrink-0 transition-none',
|
|
67
|
-
// An OPAQUE hover fill, and the reason it has to be opaque:
|
|
68
|
-
//
|
|
69
|
-
// `variant="ghost"` hovers to `bg-foreground/10`. `background-color` is one
|
|
70
|
-
// property, so on the row trigger that 10% tint did not sit on top of the
|
|
71
|
-
// `bg-(--session-row-surface)` mask — it REPLACED it. The mask exists to hide
|
|
72
|
-
// the truncated session title running underneath the glyph, so hovering
|
|
73
|
-
// punched a translucent hole in it and the title bled through: the washed-out
|
|
74
|
-
// grey square in the bug report, with a muted `⋯` floating in it.
|
|
75
|
-
//
|
|
76
|
-
// `sidebar-row-control` is one opaque step above the row's own fill
|
|
77
|
-
// (`--sidebar-row`) on hover, in both themes. The square reads as lifted, stays a solid
|
|
78
|
-
// mask, and needs no pseudo-element to stack a tint above a fill.
|
|
79
|
-
'hover:bg-sidebar-row-control data-[state=open]:bg-sidebar-row-control',
|
|
80
|
-
// Full contrast once the pointer is on it — the glyph is a control now, not a
|
|
81
|
-
// marker.
|
|
82
|
-
'hover:text-foreground data-[state=open]:text-foreground');
|
|
83
53
|
/** The same trigger on a touch device.
|
|
84
54
|
*
|
|
85
55
|
* It cannot stay hover-revealed and absolutely positioned — there is no hover,
|
|
@@ -104,12 +74,6 @@ const SESSION_MENU_TRIGGER_CLASS = cn('text-muted-foreground shrink-0 transition
|
|
|
104
74
|
* (`min-width: 768px` AND `hover: hover` AND `pointer: fine`), which is why the
|
|
105
75
|
* same block is written narrow-viewport, no-hover, and coarse-pointer. */
|
|
106
76
|
const SESSION_MENU_TRIGGER_TOUCH_CLASS = cn("max-md:pointer-events-auto max-md:relative max-md:size-8 max-md:translate-y-0 max-md:opacity-100 max-md:after:absolute max-md:after:-inset-2 max-md:after:content-['']", "[@media(hover:none)]:pointer-events-auto [@media(hover:none)]:relative [@media(hover:none)]:size-8 [@media(hover:none)]:translate-y-0 [@media(hover:none)]:opacity-100 [@media(hover:none)]:after:absolute [@media(hover:none)]:after:-inset-2 [@media(hover:none)]:after:content-['']", "pointer-coarse:pointer-events-auto pointer-coarse:relative pointer-coarse:size-8 pointer-coarse:translate-y-0 pointer-coarse:opacity-100 pointer-coarse:after:absolute pointer-coarse:after:-inset-2 pointer-coarse:after:content-['']");
|
|
107
|
-
/** Every row that can carry a `⋯` is this tall, so the trigger's 24px square is
|
|
108
|
-
* centered in an identical 32px line at all three levels. */
|
|
109
|
-
const SESSION_ROW_HEIGHT_CLASS = 'h-8';
|
|
110
|
-
/** Rows per page of an expanded parent, and per page of the Shared and
|
|
111
|
-
* Automated sections. */
|
|
112
|
-
const SIDEBAR_PAGE_SIZE = 20;
|
|
113
77
|
/** The Pinned section's id in the collapsed-sections store: open unless closed. */
|
|
114
78
|
const PINNED_SECTION_ID = 'section:pinned';
|
|
115
79
|
/** The newest change requests the session briefs read: one server page. */
|
|
@@ -145,6 +109,23 @@ export function ProjectSessionList({ projectId }) {
|
|
|
145
109
|
// carry every selected label, so a match on an unloaded page still shows.
|
|
146
110
|
const labelFilters = useSessionFilterStore(selectLabelFilters(projectId));
|
|
147
111
|
const labels = labelFilters.length > 0 ? labelFilters : undefined;
|
|
112
|
+
// Session groups (`session_groups`): every group is its own section above
|
|
113
|
+
// the rest, so the lists below hold only the sessions in no group. While the
|
|
114
|
+
// flag is unknown the lists wait: a list keyed without `group` would load,
|
|
115
|
+
// then load again with it.
|
|
116
|
+
const sessionGroupsFlag = useFeatureFlag(projectId, 'session_groups');
|
|
117
|
+
const groupsQuery = useProjectSessionGroups(projectId, { enabled: sessionGroupsFlag.enabled });
|
|
118
|
+
// Groups render once their list loaded. Until then the lists below wait; if
|
|
119
|
+
// the list cannot load, they list every session (as with the flag off), so
|
|
120
|
+
// a grouped session never disappears behind a failed read.
|
|
121
|
+
const groupsEnabled = sessionGroupsFlag.enabled && groupsQuery.isSuccess;
|
|
122
|
+
const listsReady = !sessionGroupsFlag.isLoading && !(sessionGroupsFlag.enabled && groupsQuery.isPending);
|
|
123
|
+
const groupFilter = groupsEnabled ? 'none' : undefined;
|
|
124
|
+
const groups = useMemo(() => (groupsEnabled ? (groupsQuery.data ?? []) : []), [groupsEnabled, groupsQuery.data]);
|
|
125
|
+
const groupActions = useSessionGroupActions(projectId, groups);
|
|
126
|
+
const [groupToRename, setGroupToRename] = useState(null);
|
|
127
|
+
// `fileSessionId`: the row whose "New group…" opened the dialog goes into the new group.
|
|
128
|
+
const [groupCreate, setGroupCreate] = useState(null);
|
|
148
129
|
// Paged, not the whole inventory. This list is the always-mounted poller: it
|
|
149
130
|
// re-fetches every 5s while any loaded row is still provisioning, so its cost
|
|
150
131
|
// per tick is the cost of the whole surface. Unbounded, a 12,617-session
|
|
@@ -158,6 +139,8 @@ export function ProjectSessionList({ projectId }) {
|
|
|
158
139
|
parent: 'root',
|
|
159
140
|
startedBy: 'me',
|
|
160
141
|
labels,
|
|
142
|
+
group: groupFilter,
|
|
143
|
+
enabled: listsReady,
|
|
161
144
|
refetchInterval: (loaded) => projectSessionsRefetchInterval({
|
|
162
145
|
sessions: loaded,
|
|
163
146
|
hasOpenSession: Boolean(activeSessionId),
|
|
@@ -175,6 +158,8 @@ export function ProjectSessionList({ projectId }) {
|
|
|
175
158
|
parent: 'root',
|
|
176
159
|
startedBy: 'others',
|
|
177
160
|
labels,
|
|
161
|
+
group: groupFilter,
|
|
162
|
+
enabled: listsReady,
|
|
178
163
|
limit: SIDEBAR_PAGE_SIZE,
|
|
179
164
|
refetchOnWindowFocus: true,
|
|
180
165
|
});
|
|
@@ -182,6 +167,8 @@ export function ProjectSessionList({ projectId }) {
|
|
|
182
167
|
parent: 'root',
|
|
183
168
|
startedBy: 'automated',
|
|
184
169
|
labels,
|
|
170
|
+
group: groupFilter,
|
|
171
|
+
enabled: listsReady,
|
|
185
172
|
limit: SIDEBAR_PAGE_SIZE,
|
|
186
173
|
refetchOnWindowFocus: true,
|
|
187
174
|
});
|
|
@@ -278,13 +265,14 @@ export function ProjectSessionList({ projectId }) {
|
|
|
278
265
|
const passesFacets = (session) => matchesStatusFilters(session, statusFilters) &&
|
|
279
266
|
matchesSourceFilters(session, sourceFilters, tI18nComplete);
|
|
280
267
|
const visiblePinned = pinnedQuery.sessions.filter(passesFacets);
|
|
281
|
-
|
|
268
|
+
// A row filed into a group a moment ago leaves these lists before their refetch lands.
|
|
269
|
+
const unpinned = (session) => !session.pinned_at && !(groupsEnabled && session.group_id) && passesFacets(session);
|
|
282
270
|
const visibleSessions = sessions.filter(unpinned);
|
|
283
271
|
const visibleShared = sharedQuery.sessions.filter(unpinned);
|
|
284
272
|
const visibleAutomated = automatedQuery.sessions.filter(unpinned);
|
|
285
273
|
const otherCount = sharedQuery.sessions.length + automatedQuery.sessions.length + pinnedQuery.sessions.length;
|
|
286
274
|
const visibleOtherCount = visibleShared.length + visibleAutomated.length + visiblePinned.length;
|
|
287
|
-
const
|
|
275
|
+
const resolvedViewState = resolveSessionListViewState({
|
|
288
276
|
hasData: data !== undefined,
|
|
289
277
|
isError,
|
|
290
278
|
totalCount: sessions.length + otherCount,
|
|
@@ -293,6 +281,11 @@ export function ProjectSessionList({ projectId }) {
|
|
|
293
281
|
scanning: isScanning || sharedQuery.isScanning || automatedQuery.isScanning || pinnedQuery.isScanning,
|
|
294
282
|
hasMore: hasNextPage || sharedQuery.hasNextPage || automatedQuery.hasNextPage || pinnedQuery.hasNextPage,
|
|
295
283
|
});
|
|
284
|
+
// The groups are content too: a project whose every session sits in a group
|
|
285
|
+
// is not empty, and a filter that matches nothing below still shows them.
|
|
286
|
+
const viewState = groups.length > 0 && (resolvedViewState === 'empty' || resolvedViewState === 'no-matches')
|
|
287
|
+
? 'content'
|
|
288
|
+
: resolvedViewState;
|
|
296
289
|
// One session row, its opencode sub-sessions, and (top-level rows only) the
|
|
297
290
|
// sessions it spawned, loaded when the row opens. `nested` marks a spawned
|
|
298
291
|
// row: the connector already carries the link, and it has no children of its
|
|
@@ -318,7 +311,12 @@ export function ProjectSessionList({ projectId }) {
|
|
|
318
311
|
if (shouldBeginSessionSwitch(event, session.session_id, activeSessionId)) {
|
|
319
312
|
beginSessionSwitch(session.session_id);
|
|
320
313
|
}
|
|
321
|
-
}, displayTitle: getSessionDisplayTitle(session), inSharedGroup: inSharedGroup, spawned: nested, subagentCount: children.length, spawnedCount: spawnedCount, childRunsOpen: childRunsOpen, onToggleChildRuns: () => toggleExpanded(projectId, session.session_id), reviewCount: needsYouBySession[session.session_id] ?? 0, awaitingAnswer: awaitingAnswer.has(session.session_id), changeRequests: changeRequestsBySession.get(session.session_id) ?? [], canShowHoverCard: canShowSessionHoverCard, onDelete: (id, label) => setSessionToDelete({ id, label }), onPin: (id, pinned) => void listActions.setPinned(id, pinned), onArchive: (id, archived) => void listActions.setArchived(id, archived), onShare: (s) => setSessionToShare(s), onRename: (id, name) => setSessionToRename({ id, name }), onEditLabels: setSessionToLabel,
|
|
314
|
+
}, displayTitle: getSessionDisplayTitle(session), inSharedGroup: inSharedGroup, spawned: nested, subagentCount: children.length, spawnedCount: spawnedCount, childRunsOpen: childRunsOpen, onToggleChildRuns: () => toggleExpanded(projectId, session.session_id), reviewCount: needsYouBySession[session.session_id] ?? 0, awaitingAnswer: awaitingAnswer.has(session.session_id), changeRequests: changeRequestsBySession.get(session.session_id) ?? [], canShowHoverCard: canShowSessionHoverCard, onDelete: (id, label) => setSessionToDelete({ id, label }), onPin: (id, pinned) => void listActions.setPinned(id, pinned), onArchive: (id, archived) => void listActions.setArchived(id, archived), onShare: (s) => setSessionToShare(s), onRename: (id, name) => setSessionToRename({ id, name }), onEditLabels: setSessionToLabel,
|
|
315
|
+
// Top-level sessions only: a spawned session stays with its parent,
|
|
316
|
+
// also where it shows on its own (Pinned).
|
|
317
|
+
groups: groupsEnabled && !nested && sessionParentId(session) === null ? groups : undefined, onMoveToGroup: (id, groupId) => void groupActions.move(id, groupId, { toast: true }), onNewGroupFor: (id) => setGroupCreate({ fileSessionId: id }), onDragStart: groupsEnabled && !nested && sessionParentId(session) === null
|
|
318
|
+
? (event) => startSessionDrag(event, session.session_id)
|
|
319
|
+
: undefined, onRestart: (id, label) => restartMutation.mutate({ sessionId: id, label }), isRestarting: restartMutation.isPending && restartMutation.variables?.sessionId === session.session_id, onStop: (id, label) => stopMutation.mutate({ sessionId: id, label }), isStopping: stopMutation.isPending && stopMutation.variables?.sessionId === session.session_id, canFork: runtimeForks &&
|
|
322
320
|
session.session_id === activeSessionId &&
|
|
323
321
|
!!(session.runtime_session_id ?? session.opencode_session_id), isForking: forkSession.isPending &&
|
|
324
322
|
forkSession.variables?.sessionId ===
|
|
@@ -364,15 +362,28 @@ export function ProjectSessionList({ projectId }) {
|
|
|
364
362
|
// that case here instead of letting `FadedScrollArea` render nothing with
|
|
365
363
|
// no explanation.
|
|
366
364
|
// `more`: no row yet, but a list has a next page. Its Load more renders below.
|
|
367
|
-
if (viewState !== 'more' && grouped.sections.length === 0 && visibleOtherCount === 0) {
|
|
365
|
+
if (viewState !== 'more' && grouped.sections.length === 0 && visibleOtherCount === 0 && groups.length === 0) {
|
|
368
366
|
return (_jsx("div", { className: "text-muted-foreground px-2 pt-1 pb-2 text-xs", children: t('allSectionsHidden') }));
|
|
369
367
|
}
|
|
370
|
-
return (_jsxs(FadedScrollArea, { fadeColor: "from-background", className: "h-full min-h-0 space-y-px", children: [_jsx(StarterSection, { title: tPinArchive('section'), query: pinnedQuery, sessions: visiblePinned, open: !collapsedSectionIds.has(PINNED_SECTION_ID), onToggle: () => toggleSectionCollapsed(projectId, PINNED_SECTION_ID), renderNode: (session) => renderSessionNode(session, false), caretOnHover: true }),
|
|
368
|
+
return (_jsxs(FadedScrollArea, { fadeColor: "from-background", className: "h-full min-h-0 space-y-px", children: [_jsx(StarterSection, { title: tPinArchive('section'), query: pinnedQuery, sessions: visiblePinned, open: !collapsedSectionIds.has(PINNED_SECTION_ID), onToggle: () => toggleSectionCollapsed(projectId, PINNED_SECTION_ID), renderNode: (session) => renderSessionNode(session, false), caretOnHover: true }), groups.length > 0 && (_jsx(SessionGroupSections, { projectId: projectId, groups: groups, labels: labels, collapsedSectionIds: collapsedSectionIds, onToggleSection: (sectionId) => toggleSectionCollapsed(projectId, sectionId), passesFacets: passesFacets, renderNode: (session) => renderSessionNode(session, false), actions: groupActions, onRename: setGroupToRename })), (visiblePinned.length > 0 || groups.length > 0) && !grouped.showHeaders && (_jsx("div", { className: "px-2 py-1", children: _jsx(Separator, {}) })), groupsEnabled ? (_jsx(UngroupDropArea, { onDropSession: (sessionId) => void groupActions.move(sessionId, null), children: renderUngrouped(grouped) })) : (renderUngrouped(grouped))] }));
|
|
369
|
+
}
|
|
370
|
+
/** The sessions in no group: the grouped sections, Load more, Shared, Automated and the first chat. */
|
|
371
|
+
function renderUngrouped(grouped) {
|
|
372
|
+
return (_jsxs(_Fragment, { children: [grouped.sections.map((section) => (_jsx(SessionListSection, { section: section, projectId: projectId, sessions: sessions, reviewCountBySession: needsYouBySession, showHeader: grouped.showHeaders, open: !collapsedSectionIds.has(section.id), onOpenChange: () => toggleSectionCollapsed(projectId, section.id), children: section.sessions.map((session) => renderSessionNode(session, false)) }, section.id))), hasNextPage && (_jsx(ShowMoreButton, { loading: isFetchingNextPage, failed: isFetchNextPageError, label: t('loadMore'), onClick: () => fetchNextPage() })), _jsx(StarterSection, { title: t('startedBy.others'), query: sharedQuery, sessions: visibleShared, open: expandedIdSet.has('section:shared'), onToggle: () => toggleExpanded(projectId, 'section:shared'), renderNode: (session) => renderSessionNode(session, false, true) }), _jsx(StarterSection, { title: t('startedBy.automated'), query: automatedQuery, sessions: visibleAutomated, open: expandedIdSet.has('section:automated'), onToggle: () => toggleExpanded(projectId, 'section:automated'), renderNode: (session) => renderSessionNode(session, false), caretOnHover: true }), firstChatPending &&
|
|
371
373
|
!hasNextPage &&
|
|
372
374
|
!sharedQuery.hasNextPage &&
|
|
373
375
|
!automatedQuery.hasNextPage && (_jsx(FirstChatRow, { projectId: projectId, isActive: pathname === uiRoutes().project(projectId) && isFirstChatRequested(searchParams) }))] }));
|
|
374
376
|
}
|
|
375
|
-
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-px", children: [_jsx(SessionListHeader, { projectId: projectId, sessions: sessions, reviewCountBySession: needsYouBySession, onMenuOpenChange: holdPeek }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: renderBody() }), _jsx(ShareSessionModal, { projectId: projectId, session: sessionToShare, open: !!sessionToShare, onOpenChange: (open) => !open && setSessionToShare(null), onSaved: () => queryClient.invalidateQueries({ queryKey: qk.project.sessionsScope(projectId) }) }), _jsx(SessionLabelsModal, { projectId: projectId, session: sessionToLabel, open: !!sessionToLabel, onOpenChange: (open) => !open && setSessionToLabel(null) }), _jsx(RenameSessionModal, { projectId: projectId, sessionId: sessionToRename?.id ?? null, currentName: sessionToRename?.name, open: !!sessionToRename, onOpenChange: (open) => !open && setSessionToRename(null) }), _jsx(
|
|
377
|
+
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-px", children: [_jsx(SessionListHeader, { projectId: projectId, sessions: sessions, reviewCountBySession: needsYouBySession, onMenuOpenChange: holdPeek, onNewGroup: groupsEnabled ? () => setGroupCreate({ fileSessionId: null }) : undefined }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: renderBody() }), _jsx(ShareSessionModal, { projectId: projectId, session: sessionToShare, open: !!sessionToShare, onOpenChange: (open) => !open && setSessionToShare(null), onSaved: () => queryClient.invalidateQueries({ queryKey: qk.project.sessionsScope(projectId) }) }), _jsx(SessionLabelsModal, { projectId: projectId, session: sessionToLabel, open: !!sessionToLabel, onOpenChange: (open) => !open && setSessionToLabel(null) }), _jsx(RenameSessionModal, { projectId: projectId, sessionId: sessionToRename?.id ?? null, currentName: sessionToRename?.name, open: !!sessionToRename, onOpenChange: (open) => !open && setSessionToRename(null) }), groupsEnabled && (_jsx(SessionGroupNameModal, { projectId: projectId, group: groupToRename, open: !!groupToRename || !!groupCreate, onOpenChange: (open) => {
|
|
378
|
+
if (open)
|
|
379
|
+
return;
|
|
380
|
+
setGroupToRename(null);
|
|
381
|
+
setGroupCreate(null);
|
|
382
|
+
}, onCreated: (group) => {
|
|
383
|
+
// The row whose menu opened it goes in; the group appearing with it is the result.
|
|
384
|
+
if (groupCreate?.fileSessionId)
|
|
385
|
+
void groupActions.move(groupCreate.fileSessionId, group.group_id);
|
|
386
|
+
} })), _jsx(SessionDeleteModal, { projectId: projectId, sessionId: sessionToDelete?.id ?? null, sessionLabel: sessionToDelete?.label, open: !!sessionToDelete, onOpenChange: (open) => !open && setSessionToDelete(null) }), canShowSessionHoverCard && _jsx(SessionBriefCardHost, {})] }));
|
|
376
387
|
}
|
|
377
388
|
/** The `Sessions` row above the list. Lives here — not in `project-sidebar.tsx`
|
|
378
389
|
* — because everything it needs (the session list, the review summary, the
|
|
@@ -381,10 +392,11 @@ export function ProjectSessionList({ projectId }) {
|
|
|
381
392
|
* same horizontal padding. The label opens the full sessions page; the `⋯`
|
|
382
393
|
* opens the nested Grouping/Ordering/Show/Filters menu (`SessionFilterMenu`)
|
|
383
394
|
* and appears whenever there is at least one session. */
|
|
384
|
-
function SessionListHeader({ projectId, sessions, reviewCountBySession, onMenuOpenChange, }) {
|
|
395
|
+
function SessionListHeader({ projectId, sessions, reviewCountBySession, onMenuOpenChange, onNewGroup, }) {
|
|
385
396
|
const t = useTranslations('sidebar');
|
|
397
|
+
const tGroups = useTranslations('sidebar.sessionGroups');
|
|
386
398
|
const sessionsHref = uiRoutes().sessions(projectId);
|
|
387
|
-
return (_jsxs("div", { className: cn('flex w-full shrink-0 flex-row items-center gap-1 px-2', SESSION_ROW_HEIGHT_CLASS), children: [sessionsHref ? (_jsx(HoverPrefetchLink, { href: sessionsHref, className: "text-muted-foreground hover:text-sidebar-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })) : (_jsx("span", { className: "text-muted-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })), sessions.length > 0 && (_jsxs(DropdownMenu, { onOpenChange: onMenuOpenChange, children: [_jsx(SessionFilterMenu, { projectId: projectId, sessions: sessions, reviewCountBySession: reviewCountBySession, align: "start" }), _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": t('sessionViewOptions'), className: SESSION_MENU_TRIGGER_CLASS, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) })] }))] }));
|
|
399
|
+
return (_jsxs("div", { className: cn('flex w-full shrink-0 flex-row items-center gap-1 px-2', SESSION_ROW_HEIGHT_CLASS), children: [sessionsHref ? (_jsx(HoverPrefetchLink, { href: sessionsHref, className: "text-muted-foreground hover:text-sidebar-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })) : (_jsx("span", { className: "text-muted-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })), onNewGroup && (_jsx(Hint, { side: "top", label: tGroups('newGroup'), children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": tGroups('newGroup'), className: SESSION_MENU_TRIGGER_CLASS, onClick: onNewGroup, children: _jsx(FolderSimplePlusIcon, { className: "size-4" }) }) })), sessions.length > 0 && (_jsxs(DropdownMenu, { onOpenChange: onMenuOpenChange, children: [_jsx(SessionFilterMenu, { projectId: projectId, sessions: sessions, reviewCountBySession: reviewCountBySession, align: "start" }), _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": t('sessionViewOptions'), className: SESSION_MENU_TRIGGER_CLASS, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) })] }))] }));
|
|
388
400
|
}
|
|
389
401
|
/** Non-sticky by design: FadedScrollArea masks its own edges, and a sticky
|
|
390
402
|
* header fights that mask.
|
|
@@ -479,10 +491,6 @@ function StarterSection({ title, query, sessions, open, onToggle, renderNode, ca
|
|
|
479
491
|
return (_jsxs(Disclosure, { open: open, onOpenChange: onToggle, className: "group/section space-y-1", transition: { duration: 0.15, ease: 'easeOut' }, children: [_jsx(DisclosureTrigger, { children: _jsxs("div", { className: cn('group/section-header text-muted-foreground flex items-center gap-1 px-2 text-sm font-medium', SESSION_ROW_HEIGHT_CLASS), children: [_jsx("span", { className: "truncate", children: title }), _jsx(CaretRightIcon, { "aria-hidden": true, className: cn('duration-normal size-3 shrink-0 transition-[transform,opacity] ease-out group-data-[state=open]/section:rotate-90', caretOnHover &&
|
|
480
492
|
'opacity-0 group-hover/section-header:opacity-100 group-focus-visible/section-header:opacity-100') })] }) }), _jsxs(DisclosureContent, { contentClassName: "space-y-px", children: [sessions.map(renderNode), query.hasNextPage && (_jsx(ShowMoreButton, { loading: query.isFetchingNextPage, failed: query.isFetchNextPageError, label: t('loadMore'), onClick: () => query.fetchNextPage() }))] })] }));
|
|
481
493
|
}
|
|
482
|
-
function ShowMoreButton({ loading, failed, label, onClick, }) {
|
|
483
|
-
const t = useTranslations('sidebar');
|
|
484
|
-
return (_jsx(Button, { variant: "ghost", size: "sm", className: "text-muted-foreground hover:text-foreground h-8 w-full justify-start px-2 text-xs", disabled: loading, onClick: onClick, children: loading ? t('loadingMore') : failed ? t('retry') : label }));
|
|
485
|
-
}
|
|
486
494
|
/**
|
|
487
495
|
* Everything one session started, on ONE trunk: its sub-agents first, then the
|
|
488
496
|
* sessions it spawned (fetched when the row opens, 20 at a time). `ml-4` puts
|
|
@@ -512,10 +520,11 @@ function SpawnedSessions({ projectId, parentId, renderNode, }) {
|
|
|
512
520
|
const rows = children.sessions;
|
|
513
521
|
return (_jsxs(_Fragment, { children: [rows.map((child, index) => (_jsx(ChildRunBranch, { continues: index < rows.length - 1 || children.hasNextPage, children: renderNode(child) }, child.session_id))), children.hasNextPage && (_jsx(ChildRunBranch, { continues: false, children: _jsx(ShowMoreButton, { loading: children.isFetchingNextPage, failed: children.isFetchNextPageError, label: t('sessionList.showMore'), onClick: () => children.fetchNextPage() }) }))] }));
|
|
514
522
|
}
|
|
515
|
-
function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, displayTitle, onDelete, onPin, onArchive, onShare, onRename, onEditLabels, onRestart, isRestarting, onStop, isStopping, canFork = false, isForking = false, onFork, spawned = false, subagentCount = 0, spawnedCount = 0, childRunsOpen = false, onToggleChildRuns, reviewCount = 0, awaitingAnswer = false, changeRequests, canShowHoverCard, inSharedGroup = false, }) {
|
|
523
|
+
function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, displayTitle, onDelete, onPin, onArchive, onShare, onRename, onEditLabels, groups, onMoveToGroup, onNewGroupFor, onDragStart, onRestart, isRestarting, onStop, isStopping, canFork = false, isForking = false, onFork, spawned = false, subagentCount = 0, spawnedCount = 0, childRunsOpen = false, onToggleChildRuns, reviewCount = 0, awaitingAnswer = false, changeRequests, canShowHoverCard, inSharedGroup = false, }) {
|
|
516
524
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
517
525
|
const t = useTranslations('sidebar');
|
|
518
526
|
const tPinArchive = useTranslations('sidebar.pinArchive');
|
|
527
|
+
const tGroups = useTranslations('sidebar.sessionGroups');
|
|
519
528
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
520
529
|
const descriptionId = useId();
|
|
521
530
|
// Start the session's open read (snapshot + row) on intent, so the click
|
|
@@ -550,7 +559,7 @@ function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, d
|
|
|
550
559
|
const displayStatus = sessionDisplayStatus(session, reviewCount);
|
|
551
560
|
const waitingOn = awaitingAnswer ? 'answer' : 'review';
|
|
552
561
|
const sessionLink = (_jsxs(HoverPrefetchLink, { href: href, prefetch: true, onClick: onNavigate, ...openIntent, "aria-busy": isSwitching || undefined, "aria-current": isActive ? 'page' : undefined, "aria-describedby": descriptionId, className: "focus-visible:ring-kortix-base flex min-w-0 flex-1 items-center gap-2 self-stretch rounded-md py-1 focus-visible:ring-[0.6px] focus-visible:outline-none", children: [_jsx("div", { className: "size-4 shrink-0", children: spawned ? (_jsx(ArrowsSplitIcon, { "aria-hidden": true, className: "text-muted-foreground size-4" })) : (_jsx(SessionStatusDot, { session: session, reviewCount: reviewCount, waitingOn: waitingOn, changeRequests: changeRequests })) }), _jsx(SessionGoalMark, { projectId: session.project_id, sessionId: session.session_id }), isMeta && (_jsx(Hint, { side: "top", label: t('metaCoordinator'), children: _jsx("span", { className: "text-muted-foreground flex size-4 shrink-0 items-center justify-center", children: _jsx(SparkleIcon, { className: "size-3.5", weight: "fill" }) }) })), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx(SessionTitle, { title: displayTitle, className: cn('min-w-0', isActive && 'font-medium') }), _jsx("span", { className: "hidden max-md:block pointer-coarse:block [@media(hover:none)]:block", "aria-hidden": true, "data-session-mobile-created-at": "true", children: _jsx(MobileSessionCreatedTime, { createdAt: session.created_at }) })] }), subagentCount + spawnedCount > 0 && onToggleChildRuns && (_jsx(ChildRunsToggle, { count: subagentCount + spawnedCount, open: childRunsOpen, onToggle: onToggleChildRuns, clearOfMenu: !hasIndicators })), hasIndicators && (_jsxs("div", { className: cn('flex shrink-0 items-center gap-0 transition-none', 'max-md:hidden pointer-coarse:hidden [@media(hover:none)]:hidden', 'group-hover/session-list:pointer-events-none group-hover/session-list:opacity-0', 'group-has-data-[state=open]/session-list:pointer-events-none group-has-data-[state=open]/session-list:opacity-0'), "data-session-indicators": "true", children: [showStarter && (_jsx("span", { className: "flex size-5 shrink-0 items-center justify-center", "data-session-source": "true", "data-session-starter": starter.type, children: _jsx(Hint, { side: "top", label: t('startedByLabel', { name: starter.label }), children: _jsx("span", { className: "text-muted-foreground flex size-5 items-center justify-center", children: _jsx(SessionStarterMark, { session: session, starter: starter, iconClassName: "size-3", avatarClassName: "size-5" }) }) }) })), !inSharedGroup && _jsx(SessionSharedIcon, { session: session })] }))] }));
|
|
553
|
-
return (_jsx("div", { className: "group/session-list block", children: _jsxs("div", { className: cn(
|
|
562
|
+
return (_jsx("div", { className: "group/session-list block", onDragStart: onDragStart, children: _jsxs("div", { className: cn(
|
|
554
563
|
// --session-row-surface paints the row AND the title fade in the same
|
|
555
564
|
// style pass. Do not transition background — transition-colors made the
|
|
556
565
|
// fill ease for 150ms while the fade snapped, which read as a flicker.
|
|
@@ -561,7 +570,10 @@ function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, d
|
|
|
561
570
|
: 'text-muted-foreground hover:text-sidebar-foreground bg-(--session-row-surface) [--session-row-surface:var(--background)] hover:[--session-row-surface:var(--sidebar-row)]'), children: [canShowHoverCard ? (_jsx(SessionBriefHoverCard, { sessionId: session.session_id, title: displayTitle, status: displayStatus, createdAt: session.created_at, source: source, changeRequests: changeRequests, waitingOn: waitingOn, spawned: spawned, subagentCount: subagentCount, spawnedCount: spawnedCount, labels: session.labels, projectId: session.project_id, children: sessionLink })) : (sessionLink), _jsx(SessionBriefDescription, { id: descriptionId, status: displayStatus, createdAt: session.created_at, source: source, changeRequests: changeRequests, waitingOn: waitingOn }), _jsxs(DropdownMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", type: "button", "aria-label": t('sessionList.actionsFor', { title: displayTitle }), className: cn(SESSION_MENU_TRIGGER_CLASS, 'absolute top-1/2 right-1 z-10 -translate-y-1/2', 'bg-(--session-row-surface)', 'pointer-events-none opacity-0', 'group-hover/session-list:pointer-events-auto group-hover/session-list:opacity-100', 'focus-visible:pointer-events-auto focus-visible:opacity-100', 'data-[state=open]:pointer-events-auto data-[state=open]:opacity-100', SESSION_MENU_TRIGGER_TOUCH_CLASS), onClick: (e) => {
|
|
562
571
|
e.preventDefault();
|
|
563
572
|
e.stopPropagation();
|
|
564
|
-
}, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { align: "start", side: "right", className: "w-44", children: [_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onRename(session.session_id, displayTitle)), children: [_jsx(PencilSimpleIcon, {}), tI18nComplete.raw('text3064d79a295c')] }), _jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onEditLabels(session)), children: [_jsx(TagIcon, {}), t('labels.menu')] }), _jsxs(
|
|
573
|
+
}, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { align: "start", side: "right", className: "w-44", children: [_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onRename(session.session_id, displayTitle)), children: [_jsx(PencilSimpleIcon, {}), tI18nComplete.raw('text3064d79a295c')] }), _jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onEditLabels(session)), children: [_jsx(TagIcon, {}), t('labels.menu')] }), groups && onMoveToGroup && (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { className: "cursor-pointer", children: [_jsx(FolderSimpleIcon, {}), tGroups('moveTo')] }), _jsxs(DropdownMenuSubContent, { className: "w-48", children: [groups.map((group) => {
|
|
574
|
+
const current = session.group_id === group.group_id;
|
|
575
|
+
return (_jsxs(DropdownMenuItem, { className: "cursor-pointer", disabled: current, onSelect: () => deferAfterClose(() => onMoveToGroup(session.session_id, group.group_id)), children: [current ? _jsx(CheckIcon, {}) : _jsx(FolderSimpleIcon, {}), _jsx("span", { className: "truncate", children: group.name })] }, group.group_id));
|
|
576
|
+
}), groups.length > 0 && _jsx(DropdownMenuSeparator, {}), onNewGroupFor && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onNewGroupFor(session.session_id)), children: [_jsx(FolderSimplePlusIcon, {}), tGroups('newGroupFromMenu')] })), session.group_id && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onMoveToGroup(session.session_id, null)), children: [_jsx(FolderSimpleMinusIcon, {}), tGroups('removeFromGroup')] }))] })] })), _jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onShare(session)), children: [_jsx(Share, {}), session.can_manage_sharing !== false
|
|
565
577
|
? 'Share'
|
|
566
578
|
: tI18nComplete.raw('textadc01d813da0')] }), session.pinned_at !== undefined && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onPin(session.session_id, !session.pinned_at)), children: [session.pinned_at ? _jsx(PushPinSlashIcon, {}) : _jsx(PushPinIcon, {}), tPinArchive(session.pinned_at ? 'unpin' : 'pin')] }), _jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onArchive(session.session_id, !session.archived_at)), children: [_jsx(ArchiveIcon, {}), tPinArchive(session.archived_at ? 'unarchive' : 'archive')] })] })), session.can_manage_lifecycle !== false && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", disabled: isRestarting, onSelect: () => deferAfterClose(() => onRestart(session.session_id, displayTitle)), children: [isRestarting ? _jsx(Loading, { className: "size-4 shrink-0" }) : _jsx(RotateCcw, {}), tI18nComplete.raw('text6b983a81e5e8')] })), sessionCanBeStopped(session) && session.can_manage_lifecycle !== false && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", disabled: isStopping, onSelect: () => deferAfterClose(() => onStop(session.session_id, displayTitle)), children: [isStopping ? _jsx(Loading, { className: "size-4 shrink-0" }) : _jsx(Square, {}), tI18nComplete.raw('textcae7d57bc067')] })), canFork && runtimeRootId && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", disabled: isForking, onSelect: () => deferAfterClose(() => onFork(runtimeRootId, href)), children: [isForking ? _jsx(Loading, { className: "size-4 shrink-0" }) : _jsx(GitForkIcon, {}), tI18nComplete.raw('text0e5f7f6732e0')] })), session.can_manage_lifecycle !== false && (_jsxs(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => deferAfterClose(() => onDelete(session.session_id, displayTitle)), children: [_jsx(TrashIcon, {}), tI18nComplete.raw('texte2d0a54968ea')] }))] })] })] }) }));
|
|
567
579
|
}
|
|
@@ -14,14 +14,20 @@ import { ProjectManifestUpgradeAlert } from './footer/project-manifest-upgrade-a
|
|
|
14
14
|
import { ProjectSandboxAlert } from './footer/project-sandbox-alert.js';
|
|
15
15
|
import { ProjectRepositoryDisconnectedAlert } from '../repository-disconnected.js';
|
|
16
16
|
import { CustomizeSidebarModal } from './customize-sidebar-modal.js';
|
|
17
|
+
import { ProjectMemoryNavItem } from './footer/project-memory-nav.js';
|
|
17
18
|
import { ProjectNavItems } from './project-nav-items.js';
|
|
18
19
|
import { ProjectSessionList } from './project-session-list.js';
|
|
20
|
+
import { ProjectSpacesNav } from './project-spaces-nav.js';
|
|
19
21
|
import { useIsCreatingProjectSession } from '../../internal/hooks/projects/new-session-guard.js';
|
|
20
22
|
import { useNewProjectSession } from '../../internal/hooks/projects/use-new-project-session.js';
|
|
21
23
|
import { useIsMobile } from '../../internal/hooks/index.js';
|
|
22
24
|
import { useTranslations } from '../../i18n/index.js';
|
|
23
25
|
import { cn } from '../../internal/lib/utils.js';
|
|
24
26
|
import { useBillingAccountId } from '../../internal/stores/billing-account-context.js';
|
|
27
|
+
import { useFeatureFlag } from '@kortix/sdk/react';
|
|
28
|
+
import { AppsModal } from '../../internal/apps-and-extensions/apps-modal.js';
|
|
29
|
+
import { useAppsModalStore } from '../../internal/stores/apps-modal-store.js';
|
|
30
|
+
import { ProjectChromeNavItem } from './footer/project-chrome-nav.js';
|
|
25
31
|
import { MagnifyingGlassIcon, NavigationArrowIcon, } from '@phosphor-icons/react';
|
|
26
32
|
import { UiLink as Link } from '../../providers/ui-provider.js';
|
|
27
33
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
@@ -43,6 +49,9 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
43
49
|
const [computerConnectOpen, setComputerConnectOpen] = useState(false);
|
|
44
50
|
const [connectMcpOpen, setConnectMcpOpen] = useState(false);
|
|
45
51
|
const accountId = useBillingAccountId();
|
|
52
|
+
// Channels replace New session and the session list (fail-closed: off until the project answers).
|
|
53
|
+
const channels = useFeatureFlag(projectId, 'project_channels').enabled;
|
|
54
|
+
const chrome = useFeatureFlag(projectId, 'chrome').enabled;
|
|
46
55
|
// Open the project composer without creating a durable session.
|
|
47
56
|
const newSession = useNewProjectSession(projectId);
|
|
48
57
|
const creatingSession = useIsCreatingProjectSession(projectId);
|
|
@@ -72,6 +81,8 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
72
81
|
onOpenSearch?.();
|
|
73
82
|
}, [isMobile, setOpenMobile, onOpenSearch]);
|
|
74
83
|
useEffect(() => {
|
|
84
|
+
if (channels)
|
|
85
|
+
return;
|
|
75
86
|
const handler = (event) => {
|
|
76
87
|
if ((event.metaKey || event.ctrlKey) &&
|
|
77
88
|
!event.shiftKey &&
|
|
@@ -83,7 +94,7 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
83
94
|
};
|
|
84
95
|
window.addEventListener('keydown', handler);
|
|
85
96
|
return () => window.removeEventListener('keydown', handler);
|
|
86
|
-
}, [handleNewSession]);
|
|
97
|
+
}, [channels, handleNewSession]);
|
|
87
98
|
return (_jsxs(_Fragment, { children: [_jsxs(Sidebar, { collapsible: "offcanvas", variant: "inset",
|
|
88
99
|
// No background here. This className lands on the sidebar CONTAINER —
|
|
89
100
|
// the square positioning box — while the visible card is the rounded
|
|
@@ -97,5 +108,5 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
97
108
|
// box clears the 44px floor with the vertical-only extension —
|
|
98
109
|
// vertical-only because this titlebar row packs several
|
|
99
110
|
// controls side by side (KRTX-2004).
|
|
100
|
-
className: "shrink-0 hit-area-y-3", children: _jsx(MagnifyingGlassIcon, { className: "size-4" }) }) })), isMobile && (_jsx(Button, { type: "button", "aria-label": tCommon('close'), variant: "ghost", size: "icon", onClick: () => setOpenMobile(false), className: "shrink-0 hit-area-y-3", children: _jsx(Close, {}) })), !isMobile && !peek && (_jsx(Hint, { side: "bottom", label: _jsxs("span", { className: "flex items-center gap-1.5", children: [isExpanded ? t('collapse') : t('pin'), _jsxs(KbdGroup, { children: [_jsx(Kbd, { className: "font-mono", children: modSymbol }), _jsx(Kbd, { className: "font-mono", children: "B" })] })] }), children: _jsx(Button, { type: "button", "aria-label": isExpanded ? t('collapse') : t('pin'), variant: "ghost", size: "icon", onClick: toggleSidebar, className: "shrink-0", children: _jsx(PanelLeft, { className: "cn-rtl-flip" }) }) }))] })] }) }), _jsx(SidebarContent, { className: "relative min-h-0 flex-1 [scrollbar-width:'none'] overflow-hidden [-ms-overflow-style:'none'] [&::-webkit-scrollbar]:hidden [&_[data-sidebar=menu-button]]:pl-2", children: _jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-2", children: [_jsx(SidebarGroup, { className: "py-0", children: _jsxs(SidebarMenu, { children: [_jsx(SidebarMenuItem, { children: creatingSession ? (_jsx(SidebarMenuButton, { disabled: true, "aria-busy": true, className: "group/menu-button text-sidebar-foreground relative", children: newSessionRowBody })) : (_jsx(SidebarMenuButton, { asChild: true, className: "group/menu-button text-sidebar-foreground relative", children: _jsx(Link, { href: uiRoutes().project(projectId), prefetch: true, onClick: handleNewSessionClick, children: newSessionRowBody }) })) }), _jsx(ProjectNavItems, { projectId: projectId })] }) }), _jsx(SidebarGroup, { className: "min-h-0 flex-1 flex-col py-0", ref: sessionsGroupRef, children: _jsx(ProjectSessionList, { projectId: projectId }) }), _jsx(SidebarGroup, { className: "mt-auto", children: _jsxs(SidebarMenu, { className: "gap-1", children: [_jsx(ProjectRepositoryDisconnectedAlert, { projectId: projectId }), _jsx(ProjectSandboxAlert, { projectId: projectId }), _jsx(ProjectManifestUpgradeAlert, { projectId: projectId }), _jsx(SidebarBalanceWarning, { accountId: accountId }), _jsx("li", { className: "not-has-[li]:hidden", children: _jsxs(SidebarMenu, { className: "gap-px [&>li:not(:first-child)>[data-sidebar=menu-button]]:rounded-t-sm [&>li:not(:last-child)>[data-sidebar=menu-button]]:rounded-b-sm", children: [_jsx(ProjectMcpNavItem, { onOpenConnect: () => setConnectMcpOpen(true) }), _jsx(ProjectComputerNavItem, { projectId: projectId, onOpenConnect: () => setComputerConnectOpen(true) })] }) }), _jsx(SidebarUpgradeButton, { accountId: accountId })] }) })] }) }), _jsx(SidebarRail, { "aria-label": t('resize'), title: t('resizeHelp') })] }), _jsx(ComputerConnectModal, { projectId: projectId, open: computerConnectOpen, onOpenChange: setComputerConnectOpen }), _jsx(ConnectMcpModal, { open: connectMcpOpen, onOpenChange: setConnectMcpOpen }), _jsx(CustomizeSidebarModal, { projectId: projectId })] }));
|
|
111
|
+
className: "shrink-0 hit-area-y-3", children: _jsx(MagnifyingGlassIcon, { className: "size-4" }) }) })), isMobile && (_jsx(Button, { type: "button", "aria-label": tCommon('close'), variant: "ghost", size: "icon", onClick: () => setOpenMobile(false), className: "shrink-0 hit-area-y-3", children: _jsx(Close, {}) })), !isMobile && !peek && (_jsx(Hint, { side: "bottom", label: _jsxs("span", { className: "flex items-center gap-1.5", children: [isExpanded ? t('collapse') : t('pin'), _jsxs(KbdGroup, { children: [_jsx(Kbd, { className: "font-mono", children: modSymbol }), _jsx(Kbd, { className: "font-mono", children: "B" })] })] }), children: _jsx(Button, { type: "button", "aria-label": isExpanded ? t('collapse') : t('pin'), variant: "ghost", size: "icon", onClick: toggleSidebar, className: "shrink-0", children: _jsx(PanelLeft, { className: "cn-rtl-flip" }) }) }))] })] }) }), _jsx(SidebarContent, { className: "relative min-h-0 flex-1 [scrollbar-width:'none'] overflow-hidden [-ms-overflow-style:'none'] [&::-webkit-scrollbar]:hidden [&_[data-sidebar=menu-button]]:pl-2", children: _jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-2", children: [_jsx(SidebarGroup, { className: "py-0", children: _jsxs(SidebarMenu, { children: [channels ? null : (_jsx(SidebarMenuItem, { children: creatingSession ? (_jsx(SidebarMenuButton, { disabled: true, "aria-busy": true, className: "group/menu-button text-sidebar-foreground relative", children: newSessionRowBody })) : (_jsx(SidebarMenuButton, { asChild: true, className: "group/menu-button text-sidebar-foreground relative", children: _jsx(Link, { href: uiRoutes().project(projectId), prefetch: true, onClick: handleNewSessionClick, children: newSessionRowBody }) })) })), channels ? _jsx(ProjectMemoryNavItem, { projectId: projectId }) : null, _jsx(ProjectNavItems, { projectId: projectId })] }) }), _jsx(SidebarGroup, { className: "min-h-0 flex-1 flex-col py-0", ref: sessionsGroupRef, children: channels ? (_jsx(ProjectSpacesNav, { projectId: projectId })) : (_jsx(ProjectSessionList, { projectId: projectId })) }), _jsx(SidebarGroup, { className: "mt-auto", children: _jsxs(SidebarMenu, { className: "gap-1", children: [_jsx(ProjectRepositoryDisconnectedAlert, { projectId: projectId }), _jsx(ProjectSandboxAlert, { projectId: projectId }), _jsx(ProjectManifestUpgradeAlert, { projectId: projectId }), _jsx(SidebarBalanceWarning, { accountId: accountId }), _jsx("li", { className: "not-has-[li]:hidden", children: _jsxs(SidebarMenu, { className: "gap-px [&>li:not(:first-child)>[data-sidebar=menu-button]]:rounded-t-sm [&>li:not(:last-child)>[data-sidebar=menu-button]]:rounded-b-sm", children: [_jsx(ProjectMcpNavItem, { onOpenConnect: () => setConnectMcpOpen(true) }), _jsx(ProjectComputerNavItem, { projectId: projectId, onOpenConnect: () => setComputerConnectOpen(true) }), chrome ? (_jsx(ProjectChromeNavItem, { onOpenConnect: () => useAppsModalStore.getState().setOpen(true) })) : null] }) }), _jsx(SidebarUpgradeButton, { accountId: accountId })] }) })] }) }), _jsx(SidebarRail, { "aria-label": t('resize'), title: t('resizeHelp') })] }), _jsx(ComputerConnectModal, { projectId: projectId, open: computerConnectOpen, onOpenChange: setComputerConnectOpen }), _jsx(AppsModal, { chrome: chrome, onOpenComputer: () => setComputerConnectOpen(true), onOpenMcp: () => setConnectMcpOpen(true) }), _jsx(ConnectMcpModal, { open: connectMcpOpen, onOpenChange: setConnectMcpOpen }), _jsx(CustomizeSidebarModal, { projectId: projectId })] }));
|
|
101
112
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sidebar under the `project_channels` flag: Channels, then Direct
|
|
3
|
+
* messages, in the slot the session list holds with the flag off. A section
|
|
4
|
+
* renders once its data arrives: no skeleton rows for navigation.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ProjectSpacesNav({ projectId }: {
|
|
7
|
+
projectId: string;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useProjectSpaces, useVisibleAgents } from '@kortix/sdk/react';
|
|
4
|
+
import { CaretRightIcon, PlusIcon } from '@phosphor-icons/react';
|
|
5
|
+
import { useMemo, useState } from 'react';
|
|
6
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
7
|
+
import { AgentMark } from '../../internal/components/agent-mark.js';
|
|
8
|
+
import { ProjectNavRow } from '../../internal/layout/project-nav-row.js';
|
|
9
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
10
|
+
import { selectCollapsedSections, useSessionFilterStore, } from '../../internal/stores/session-filter-store.js';
|
|
11
|
+
import { customizePath, uiRoutes } from '../../lib/routes.js';
|
|
12
|
+
import { Button } from '../../primitives/button.js';
|
|
13
|
+
import { Disclosure, DisclosureContent, DisclosureTrigger } from '../../primitives/disclosure.js';
|
|
14
|
+
import { FadedScrollArea } from '../../primitives/faded-scroll-area.js';
|
|
15
|
+
import Hint from '../../primitives/hint.js';
|
|
16
|
+
import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '../../primitives/sidebar.js';
|
|
17
|
+
import { useUiPathname, useUiRouter } from '../../providers/ui-provider.js';
|
|
18
|
+
import { CreateChannelDialog } from '../spaces/create-channel-dialog.js';
|
|
19
|
+
import { PrivateChannelsNotInRow } from '../spaces/private-channels-not-in.js';
|
|
20
|
+
import { agentLabel } from '../spaces/space-timeline.js';
|
|
21
|
+
import { ChannelGlyph } from '../spaces/channel-glyph.js';
|
|
22
|
+
/** Collapse state lives in the persisted session-filter store, beside the session sections. */
|
|
23
|
+
const CHANNELS_SECTION_ID = 'section:channels';
|
|
24
|
+
const DMS_SECTION_ID = 'section:dms';
|
|
25
|
+
/** `href`, or a page under it. */
|
|
26
|
+
function isAt(pathname, href) {
|
|
27
|
+
return !!pathname && (pathname === href || pathname.startsWith(`${href}/`));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The sidebar under the `project_channels` flag: Channels, then Direct
|
|
31
|
+
* messages, in the slot the session list holds with the flag off. A section
|
|
32
|
+
* renders once its data arrives: no skeleton rows for navigation.
|
|
33
|
+
*/
|
|
34
|
+
export function ProjectSpacesNav({ projectId }) {
|
|
35
|
+
const t = useTranslations('sidebar');
|
|
36
|
+
const pathname = useUiPathname();
|
|
37
|
+
const router = useUiRouter();
|
|
38
|
+
const spaces = useProjectSpaces(projectId);
|
|
39
|
+
const agents = useVisibleAgents({ projectId });
|
|
40
|
+
const [createOpen, setCreateOpen] = useState(false);
|
|
41
|
+
const collapsedSections = useSessionFilterStore(selectCollapsedSections(projectId));
|
|
42
|
+
const collapsed = useMemo(() => new Set(collapsedSections), [collapsedSections]);
|
|
43
|
+
const toggleSectionCollapsed = useSessionFilterStore((s) => s.toggleSectionCollapsed);
|
|
44
|
+
const channels = spaces.data?.filter((space) => space.kind === 'channel' && !space.archived_at);
|
|
45
|
+
return (_jsxs(FadedScrollArea, { fadeColor: "from-background", className: "h-full min-h-0 space-y-2", children: [spaces.isError && !spaces.data ? (_jsxs("div", { className: "space-y-1.5 px-2 py-2", children: [_jsx("p", { className: "text-destructive/80 text-xs", children: t('spaces.loadError') }), _jsx(Button, { variant: "outline", size: "xs", onClick: () => spaces.refetch(), children: t('retry') })] })) : null, channels ? (_jsxs(SpacesSection, { title: t('spaces.channels'), open: !collapsed.has(CHANNELS_SECTION_ID), onToggle: () => toggleSectionCollapsed(projectId, CHANNELS_SECTION_ID), action: { label: t('spaces.addChannel'), onClick: () => setCreateOpen(true) }, children: [channels.map((channel) => {
|
|
46
|
+
const href = uiRoutes().channel(projectId, channel.slug ?? '');
|
|
47
|
+
return (_jsxs(ProjectNavRow, { href: href, active: isAt(pathname, href), label: `#${channel.slug}`, children: [_jsx(ChannelGlyph, { visibility: channel.visibility }), _jsx("span", { children: channel.slug })] }, channel.space_id));
|
|
48
|
+
}), _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { onClick: () => setCreateOpen(true), className: "text-muted-foreground hover:text-sidebar-foreground", children: [_jsx(PlusIcon, {}), _jsx("span", { children: t('spaces.addChannel') })] }) }), _jsx(PrivateChannelsNotInRow, { projectId: projectId })] })) : null, spaces.data && agents.length > 0 ? (_jsx(SpacesSection, { title: t('spaces.directMessages'), open: !collapsed.has(DMS_SECTION_ID), onToggle: () => toggleSectionCollapsed(projectId, DMS_SECTION_ID),
|
|
49
|
+
// Every visible agent already has a DM row: the `+` makes a new agent.
|
|
50
|
+
action: { label: t('spaces.newAgent'), onClick: () => router.push(customizePath(projectId, 'agents')) }, children: agents.map((agent) => {
|
|
51
|
+
const name = agentLabel(agent.name);
|
|
52
|
+
const href = uiRoutes().dm(projectId, agent.name);
|
|
53
|
+
return (_jsxs(ProjectNavRow, { href: href, active: isAt(pathname, href), label: name,
|
|
54
|
+
// The row forces every svg to size-4: the pixel mark keeps its 14px glyph.
|
|
55
|
+
className: "[&_[data-slot=agent-mark]>svg]:size-[14px]!", children: [_jsx(AgentMark, { slug: agent.name, size: 14 }), _jsx("span", { children: name })] }, agent.name));
|
|
56
|
+
}) })) : null, _jsx(CreateChannelDialog, { projectId: projectId, open: createOpen, onOpenChange: setCreateOpen })] }));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A collapsible section: the muted label, then the caret, then a `+` at the
|
|
60
|
+
* trailing edge. The caret and the `+` stay hidden until the header is hovered
|
|
61
|
+
* or focused, so the list reads as names, not chrome. A collapsed section keeps
|
|
62
|
+
* its caret, so a closed section still says it holds more.
|
|
63
|
+
*
|
|
64
|
+
* The `+` is a sibling of the trigger, not inside it: a button nested in a
|
|
65
|
+
* `role="button"` is invalid, and its click would also toggle the section.
|
|
66
|
+
*/
|
|
67
|
+
function SpacesSection({ title, open, onToggle, action, children, }) {
|
|
68
|
+
return (_jsxs(Disclosure, { open: open, onOpenChange: onToggle, className: "group/section", transition: { duration: 0.15, ease: 'easeOut' }, children: [_jsxs("div", { className: "group/section-header flex h-8 items-center gap-1 pr-1", children: [_jsx(DisclosureTrigger, { children: _jsxs("div", { className: cn('text-muted-foreground hover:text-sidebar-foreground flex h-full min-w-0 flex-1 cursor-pointer items-center gap-1 rounded-md px-2 text-sm font-medium', 'focus-visible:ring-kortix-base focus-visible:ring-[0.6px] focus-visible:outline-none'), children: [_jsx("span", { className: "truncate", children: title }), _jsx(CaretRightIcon, { "aria-hidden": true, className: cn('duration-normal size-3 shrink-0 transition-[rotate,opacity] ease-out', 'opacity-0 group-focus-within/section-header:opacity-100 group-hover/section-header:opacity-100', 'group-data-[state=closed]/section:opacity-100 group-data-[state=open]/section:rotate-90') })] }) }), _jsx(Hint, { label: action.label, side: "right", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": action.label, onClick: action.onClick, className: "text-muted-foreground hover:text-sidebar-foreground shrink-0 opacity-0 group-focus-within/section-header:opacity-100 group-hover/section-header:opacity-100 focus-visible:opacity-100", children: _jsx(PlusIcon, { className: "size-3.5" }) }) })] }), _jsx(DisclosureContent, { contentClassName: "pt-px", children: _jsx(SidebarMenu, { className: "gap-px", children: children }) })] }));
|
|
69
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's session groups in a new order, for `PUT /session-groups/order`
|
|
3
|
+
* (every id, once). Null when nothing would move, so a caller sends no request
|
|
4
|
+
* and a menu item can render disabled.
|
|
5
|
+
*/
|
|
6
|
+
/** `ids` with `id` moved to `index`, clamped to the ends: a group dropped on another takes its place. */
|
|
7
|
+
export declare function moveGroupTo(ids: readonly string[], id: string, index: number): string[] | null;
|
|
8
|
+
/** `ids` with `id` moved one place up (`-1`) or down (`1`). Null at that end. */
|
|
9
|
+
export declare function moveGroupBy(ids: readonly string[], id: string, delta: -1 | 1): string[] | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's session groups in a new order, for `PUT /session-groups/order`
|
|
3
|
+
* (every id, once). Null when nothing would move, so a caller sends no request
|
|
4
|
+
* and a menu item can render disabled.
|
|
5
|
+
*/
|
|
6
|
+
/** `ids` with `id` moved to `index`, clamped to the ends: a group dropped on another takes its place. */
|
|
7
|
+
export function moveGroupTo(ids, id, index) {
|
|
8
|
+
const from = ids.indexOf(id);
|
|
9
|
+
if (from === -1)
|
|
10
|
+
return null;
|
|
11
|
+
const to = Math.max(0, Math.min(ids.length - 1, index));
|
|
12
|
+
if (to === from)
|
|
13
|
+
return null;
|
|
14
|
+
const next = ids.filter((other) => other !== id);
|
|
15
|
+
next.splice(to, 0, id);
|
|
16
|
+
return next;
|
|
17
|
+
}
|
|
18
|
+
/** `ids` with `id` moved one place up (`-1`) or down (`1`). Null at that end. */
|
|
19
|
+
export function moveGroupBy(ids, id, delta) {
|
|
20
|
+
const from = ids.indexOf(id);
|
|
21
|
+
const to = from + delta;
|
|
22
|
+
if (from === -1 || to < 0 || to >= ids.length)
|
|
23
|
+
return null;
|
|
24
|
+
return moveGroupTo(ids, id, to);
|
|
25
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session groups in the sidebar (`session_groups` flag): the project's shared,
|
|
3
|
+
* named folders of sessions, between Pinned and the rest of the list.
|
|
4
|
+
*
|
|
5
|
+
* Each group is a section. Its rows load when it is open (one paged list per
|
|
6
|
+
* group, any starter, any depth), and its open state is the viewer's own,
|
|
7
|
+
* beside the other sections in the session-filter store. A session moves into
|
|
8
|
+
* a group from its `⋯` menu or by dragging its row onto the group; a group
|
|
9
|
+
* moves by dragging its header onto another group, or with Move up / Move
|
|
10
|
+
* down. Dragging a row onto the rest of the list takes it out of its group.
|
|
11
|
+
*/
|
|
12
|
+
import { type ProjectSession, type ProjectSessionGroup } from '@kortix/sdk';
|
|
13
|
+
import { type DragEvent, type ReactNode } from 'react';
|
|
14
|
+
/** The collapsed-sections id of one group. */
|
|
15
|
+
export declare function sessionGroupSectionId(groupId: string): string;
|
|
16
|
+
/** `onDragStart` of a session row: the row's link drag also carries the session id. */
|
|
17
|
+
export declare function startSessionDrag(event: DragEvent, sessionId: string): void;
|
|
18
|
+
/** Filing and reordering, with their result toasts. One instance per list. */
|
|
19
|
+
export declare function useSessionGroupActions(projectId: string, groups: readonly ProjectSessionGroup[]): {
|
|
20
|
+
/** `toast`: a menu move reports where the row went; a drop shows it in place. */
|
|
21
|
+
move: (sessionId: string, groupId: string | null, options?: {
|
|
22
|
+
toast?: boolean;
|
|
23
|
+
}) => Promise<void>;
|
|
24
|
+
reorder: (groupIds: string[] | null) => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Create a group (`group` null) or rename one. A taken name and the group
|
|
28
|
+
* limit show in the dialog; the dialog closes with a toast once the list holds
|
|
29
|
+
* the change. `onCreated` receives the new group (a row's "New group…" files
|
|
30
|
+
* its session into it).
|
|
31
|
+
*/
|
|
32
|
+
export declare function SessionGroupNameModal({ projectId, group, open, onOpenChange, onCreated, }: {
|
|
33
|
+
projectId: string;
|
|
34
|
+
group: ProjectSessionGroup | null;
|
|
35
|
+
open: boolean;
|
|
36
|
+
onOpenChange: (open: boolean) => void;
|
|
37
|
+
onCreated?: (group: ProjectSessionGroup) => void;
|
|
38
|
+
}): import("react").JSX.Element;
|
|
39
|
+
interface SessionGroupSectionsProps {
|
|
40
|
+
projectId: string;
|
|
41
|
+
groups: readonly ProjectSessionGroup[];
|
|
42
|
+
/** The Labels facet, sent to every group's list like the main list's. */
|
|
43
|
+
labels: string[] | undefined;
|
|
44
|
+
collapsedSectionIds: ReadonlySet<string>;
|
|
45
|
+
onToggleSection: (sectionId: string) => void;
|
|
46
|
+
/** The status and source facets, applied to each group's rows. */
|
|
47
|
+
passesFacets: (session: ProjectSession) => boolean;
|
|
48
|
+
renderNode: (session: ProjectSession) => ReactNode;
|
|
49
|
+
actions: ReturnType<typeof useSessionGroupActions>;
|
|
50
|
+
onRename: (group: ProjectSessionGroup) => void;
|
|
51
|
+
}
|
|
52
|
+
/** Every group of the project, in order. */
|
|
53
|
+
export declare function SessionGroupSections({ groups, ...rest }: SessionGroupSectionsProps): import("react").JSX.Element;
|
|
54
|
+
/**
|
|
55
|
+
* The rest of the list as a drop target: a session row dropped here leaves
|
|
56
|
+
* its group. Highlights only while a row is over it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function UngroupDropArea({ onDropSession, children, }: {
|
|
59
|
+
onDropSession: (sessionId: string) => void;
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
}): import("react").JSX.Element;
|
|
62
|
+
export {};
|