@kortix/ui 0.14.8 → 0.14.9
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 +63 -3
- package/dist/_vendor/shared/app-config.d.ts +175 -0
- package/dist/_vendor/shared/channel-message.d.ts +34 -5
- package/dist/_vendor/shared/index.d.ts +1 -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 +11 -5
- 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 +51 -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 +16 -25
- 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 +5 -0
- package/dist/customize/sections/view/channels-view.d.ts +5 -1
- package/dist/customize/sections/view/channels-view.js +61 -75
- package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
- package/dist/customize/settings/tabs/experimental-tab.js +35 -16
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +1 -12
- package/dist/customize/shared/catalog/catalog-empty-state.js +3 -3
- 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 +46 -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 +873 -85
- package/dist/i18n/en.js +888 -100
- 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/auth/auth-card-shell.js +3 -3
- package/dist/internal/components/agent-mark.js +5 -2
- package/dist/internal/connector-logo/connector-logo-source.d.ts +63 -0
- package/dist/internal/connector-logo/connector-logo-source.js +48 -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/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/injected-scripts.d.ts +7 -0
- package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -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 +9 -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/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 +6 -2
- 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/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-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 +5 -1
- package/dist/session/participants/session-participants.js +9 -2
- package/dist/session/prompts/approval-request.d.ts +5 -0
- package/dist/session/prompts/approval-request.js +7 -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 +3 -1
- package/dist/session/thread/session-thread.js +9 -2
- 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 +240 -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 +7 -1
- package/dist/session/turn/user-message.js +21 -7
- 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/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-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 +9 -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 +27 -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 +28 -4
- 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
|
@@ -231,4 +231,9 @@ export const KORTIX_PERMISSIONS_CATALOG = [
|
|
|
231
231
|
actions: ['project.room.read', 'project.room.write'],
|
|
232
232
|
featureFlag: 'agent_rooms',
|
|
233
233
|
},
|
|
234
|
+
{
|
|
235
|
+
group: 'Artifacts',
|
|
236
|
+
actions: ['project.artifact.read', 'project.artifact.write', 'project.artifact.manage', 'project.artifact.public'],
|
|
237
|
+
featureFlag: 'artifacts',
|
|
238
|
+
},
|
|
234
239
|
];
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/** Reserved slug for the built-in Email channel (see api connectors.ts). */
|
|
2
|
+
/** A Kortix channel's own page (`platform`), or every channel (the Channels page). */
|
|
3
|
+
export type ChannelPlatform = 'slack' | 'teams' | 'email' | 'telegram';
|
|
4
|
+
export declare function ChannelsSection({ projectId, platform }: {
|
|
2
5
|
projectId: string;
|
|
6
|
+
platform?: ChannelPlatform;
|
|
3
7
|
}): import("react").JSX.Element;
|
|
@@ -75,64 +75,42 @@ import { Button } from '../../../primitives/button.js';
|
|
|
75
75
|
import { Field, FieldDescription, FieldGroup, FieldTitle } from '../../../primitives/field.js';
|
|
76
76
|
import { InfoBanner } from '../../../primitives/info-banner.js';
|
|
77
77
|
import { InputGroupSearch, InputGroupSearchClear, InputGroupSearchIcon, InputGroupSearchInput, } from '../../../primitives/input-group.js';
|
|
78
|
-
import { Label } from '../../../primitives/label.js';
|
|
79
78
|
import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, } from '../../../primitives/modal.js';
|
|
80
79
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../../primitives/select.js';
|
|
81
80
|
import { Skeleton } from '../../../primitives/skeleton.js';
|
|
82
81
|
import { Tabs, TabsListCompact, TabsTriggerCompact } from '../../../primitives/tabs.js';
|
|
83
82
|
import Loading from '../../../primitives/loading.js';
|
|
84
83
|
import { errorToast, infoToast, successToast, warningToast } from '../../../primitives/toast.js';
|
|
85
|
-
import { MicrosoftTeams } from '../../../internal/icons/microsoft-teams.js';
|
|
86
|
-
import { Slack } from '../../../internal/icons/slack.js';
|
|
87
84
|
import { ModelSelector } from '../../../session/models/model-selector.js';
|
|
88
85
|
import { AgentSelector } from '../../../session/composer/session-chat-input.js';
|
|
89
86
|
import { ChannelDisconnectButton, ChannelRow, } from '../component/channel-row.js';
|
|
90
|
-
import { TeamsConnectCard } from '../component/teams-connect-card.js';
|
|
87
|
+
import { TeamsChannelMock, TeamsConnectCard } from '../component/teams-connect-card.js';
|
|
91
88
|
import { TelegramChannelRow } from '../component/telegram-channel-row.js';
|
|
92
|
-
import { SlackConnectCard } from '../component/slack-connect-card.js';
|
|
93
|
-
import {
|
|
89
|
+
import { SlackChannelMock, SlackConnectCard } from '../component/slack-connect-card.js';
|
|
90
|
+
import { ChannelHeroLayoutProvider } from '../component/channel-hero-frame.js';
|
|
91
|
+
import { EmailHero } from '../../connectors/detail/email-inboxes.js';
|
|
94
92
|
import { ChannelBrandMark } from '../../../session/turn/channel-brand.js';
|
|
95
93
|
import { channelSettingsPatch, } from './channel-settings-patch.js';
|
|
96
94
|
import { slackConversationName } from '../../../session/turn/channel-message.js';
|
|
97
95
|
import { bindingTabs } from './channel-binding-tabs.js';
|
|
98
|
-
import { projectSettingsSectionHref } from '../../project-settings/project-settings-sections.js';
|
|
99
96
|
import { AccessRow } from '../../../access/access/access-row.js';
|
|
100
97
|
import { useChannelBindings, useUpdateChannelBinding, } from '../../../internal/hooks/use-channel-bindings.js';
|
|
101
|
-
import {
|
|
98
|
+
import { useDisconnectSlack, useSlackInstall, useSlackMode, } from '../../../internal/hooks/channels/use-channels-installations.js';
|
|
102
99
|
import { useDisconnectTeams, useTeamsInstall, useTeamsMode, } from '@kortix/sdk/react';
|
|
103
100
|
import { modelRefToKey } from '@kortix/sdk';
|
|
104
101
|
import { PROJECT_ACTIONS } from '../../../internal/lib/project-actions.js';
|
|
105
102
|
import { useProjectCan } from '../../../internal/lib/use-project-can.js';
|
|
106
103
|
import { cn } from '../../../internal/lib/utils.js';
|
|
107
104
|
import { flattenModels, modelProviderMode, useFeatureFlag, useRuntimeProviders, useVisibleAgents, } from '@kortix/sdk/react';
|
|
108
|
-
import { AtIcon, CaretLeftIcon, CaretRightIcon,
|
|
105
|
+
import { AtIcon, CaretLeftIcon, CaretRightIcon, MagnifyingGlassIcon, WarningCircleIcon, } from '@phosphor-icons/react';
|
|
109
106
|
import { UiLink as Link, useUiPathname, useUiRouter, useUiSearchParams } from '../../../providers/ui-provider.js';
|
|
110
107
|
import { useEffect, useMemo, useState } from 'react';
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
* short rows. Matching the shape is the point — a placeholder that settles
|
|
116
|
-
* into a different geometry reads as a layout jump, not as loading.
|
|
117
|
-
*/
|
|
118
|
-
const CHANNEL_LOADING_ROWS = ['channel-loading-1', 'channel-loading-2'];
|
|
119
|
-
export function ChannelsSection({ projectId }) {
|
|
108
|
+
import { useTunnelConnections } from '@kortix/sdk/react';
|
|
109
|
+
import { ComputerHero } from '../../connectors/detail/computer-app-page.js';
|
|
110
|
+
import { FeatureGateScreen } from '../../shared/feature-gate-screen.js';
|
|
111
|
+
export function ChannelsSection({ projectId, platform }) {
|
|
120
112
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
121
113
|
useTeamsInstallReturnToast();
|
|
122
|
-
// This view used to read the flags off the project SUMMARY query
|
|
123
|
-
// (`qk.project.summary` / `getProject`, whose payload nests them one level
|
|
124
|
-
// shallower). It now reads the one gating primitive, which is backed by
|
|
125
|
-
// `qk.project.detail` — the entry the Customize panel that hosts this view
|
|
126
|
-
// already holds, so the switch removes a fetch rather than adding one.
|
|
127
|
-
//
|
|
128
|
-
// The LOADING semantics are preserved deliberately: unlike its siblings, this
|
|
129
|
-
// surface WAITS on the flag before painting (`emailFlag.isLoading` feeds
|
|
130
|
-
// `loading` below), so the header action cannot flash the wrong state, and
|
|
131
|
-
// `useEmailInstall` stays unfired until the flag resolves.
|
|
132
|
-
const emailFlag = useFeatureFlag(projectId, 'agentmail_email');
|
|
133
|
-
const emailChannelEnabled = emailFlag.enabled;
|
|
134
|
-
// Telegram is a channel connector behind connectors_v2; off, it is not listed.
|
|
135
|
-
const telegramEnabled = useFeatureFlag(projectId, 'connectors_v2').enabled;
|
|
136
114
|
const { data: install, isLoading: loadingInstall } = useSlackInstall(projectId);
|
|
137
115
|
const { data: mode, isLoading: loadingMode } = useSlackMode(projectId);
|
|
138
116
|
// Teams is on for every project (its feature flag graduated on 2026-10-01).
|
|
@@ -140,11 +118,12 @@ export function ChannelsSection({ projectId }) {
|
|
|
140
118
|
const { data: teamsMode } = useTeamsMode(projectId);
|
|
141
119
|
// Not connected, Teams gets the same hero as Slack; connected, it is a row.
|
|
142
120
|
const teamsHero = !teamsInstall && Boolean(teamsMode?.enabled);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
121
|
+
// Email (Resend Inboxes) is experimental behind `email_channel`. Off, it is on
|
|
122
|
+
// no surface, and its inboxes are never read (EmailHero is not mounted).
|
|
123
|
+
const emailFlag = useFeatureFlag(projectId, 'email_channel');
|
|
124
|
+
const emailEnabled = emailFlag.enabled;
|
|
125
|
+
const loading = loadingInstall || loadingMode || emailFlag.isLoading;
|
|
126
|
+
const tPages = useTranslations('connectorPages');
|
|
148
127
|
const oauthInstallUrl = mode?.oauth_available ? mode.install_url : null;
|
|
149
128
|
const canWrite = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_CONNECTOR_WRITE).allowed === true;
|
|
150
129
|
// Each platform's row shows how many conversations it has bound and opens
|
|
@@ -154,29 +133,50 @@ export function ChannelsSection({ projectId }) {
|
|
|
154
133
|
const channelCounts = new Map(bindingTabs(bindingsQuery.data?.bindings ?? []).map((tab) => [tab.platform, tab.count]));
|
|
155
134
|
const [channelsDialog, setChannelsDialog] = useState({ open: false, platform: 'slack', session: 0 });
|
|
156
135
|
const openChannels = (platform) => setChannelsDialog((dialog) => ({ open: true, platform, session: dialog.session + 1 }));
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
136
|
+
// Every channel draws as a hero, connected or not: its own page shows one
|
|
137
|
+
// platform, the Channels tab every platform, one under the other.
|
|
138
|
+
const platforms = platform
|
|
139
|
+
? [platform]
|
|
140
|
+
: ['slack', 'teams', ...(emailEnabled ? ['email'] : []), 'telegram'];
|
|
141
|
+
// The Kortix tab also holds the computer, where this deployment can pair one
|
|
142
|
+
// (the machine list answers 503 where computers are off).
|
|
143
|
+
const computersEnabled = useTunnelConnections({ refetchInterval: false }).isSuccess;
|
|
144
|
+
const showComputer = !platform && computersEnabled;
|
|
145
|
+
const hero = (pf) => {
|
|
146
|
+
switch (pf) {
|
|
147
|
+
case 'slack':
|
|
148
|
+
return install ? (_jsxs(_Fragment, { children: [_jsx(SlackChannelRow, { projectId: projectId, installation: install, canWrite: canWrite, channelCount: channelCounts.get('slack') ?? 0, onOpenChannels: () => openChannels('slack') }), _jsx(SlackFollowUp, { projectId: projectId })] })) : (_jsx(SlackConnectCard, { projectId: projectId, oauthInstallUrl: oauthInstallUrl, canWrite: canWrite }));
|
|
149
|
+
case 'teams':
|
|
150
|
+
return teamsHero && teamsMode ? (_jsx(TeamsConnectCard, { projectId: projectId, mode: teamsMode, canWrite: canWrite })) : (_jsxs(_Fragment, { children: [_jsx(TeamsChannelRow, { projectId: projectId, canWrite: canWrite, channelCount: channelCounts.get('teams') ?? 0, onOpenChannels: () => openChannels('teams') }), teamsInstall?.appUpdateAvailable ? (_jsx(TeamsAppUpdateNotice, { install: teamsInstall, tI18nComplete: tI18nComplete })) : null] }));
|
|
151
|
+
case 'email':
|
|
152
|
+
// Each inbox is an account on `kortix_email`: the hero counts them, Manage lists them.
|
|
153
|
+
return _jsx(EmailHero, { projectId: projectId, canWrite: canWrite });
|
|
154
|
+
case 'telegram':
|
|
155
|
+
return _jsx(TelegramChannelRow, { projectId: projectId, canWrite: canWrite });
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
// The Email page with the flag off: the standard flag-off screen, with its enable action.
|
|
159
|
+
if (platform === 'email' && !emailFlag.isLoading && !emailEnabled) {
|
|
160
|
+
return (_jsx(FeatureGateScreen, { featureKey: "email_channel", featureName: tPages('emailGateName'), description: tPages('emailGateDescription') }));
|
|
161
|
+
}
|
|
164
162
|
return (
|
|
165
|
-
/* Full width of the Connectors shell
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
`CapabilityPageShell` in `connectors-page.tsx`; a second of either would
|
|
172
|
-
print a second `<h1>` and scroll the wrong box. */
|
|
173
|
-
_jsx("div", { className: "w-full space-y-6", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-64 rounded-md" }), _jsx("div", { className: "space-y-2", children: CHANNEL_LOADING_ROWS.map((key) => (_jsx(Skeleton, { className: "h-14 rounded-md" }, key))) })] })) : (_jsxs(_Fragment, { children: [install ? null : (_jsx(SlackConnectCard, { projectId: projectId, oauthInstallUrl: oauthInstallUrl, canWrite: canWrite })), teamsHero && teamsMode ? (_jsx(TeamsConnectCard, { projectId: projectId, mode: teamsMode, canWrite: canWrite })) : null, _jsxs("section", { className: "space-y-2", children: [showMoreLabel ? _jsx(Label, { children: tI18nComplete.raw('text28647129955c') }) : null, _jsxs("ul", { className: "space-y-2", children: [install ? (_jsx(SlackChannelRow, { projectId: projectId, installation: install, canWrite: canWrite, channelCount: channelCounts.get('slack') ?? 0, onOpenChannels: () => openChannels('slack') })) : null, _jsx(EmailChannelRow, { projectId: projectId, enabled: emailChannelEnabled, installation: emailInstall ?? null, canWrite: canWrite }), telegramEnabled ? _jsx(TelegramChannelRow, { projectId: projectId, canWrite: canWrite }) : null, teamsHero ? null : (_jsx(TeamsChannelRow, { projectId: projectId, canWrite: canWrite, channelCount: channelCounts.get('teams') ?? 0, onOpenChannels: () => openChannels('teams') }))] }), teamsInstall?.appUpdateAvailable ? (_jsx(TeamsAppUpdateNotice, { install: teamsInstall, tI18nComplete: tI18nComplete })) : null] }), install ? _jsx(SlackFollowUp, { projectId: projectId }) : null, _jsx(ChannelBindingsDialog, { projectId: projectId, canWrite: canWrite, platform: channelsDialog.platform, open: channelsDialog.open, onOpenChange: (open) => setChannelsDialog((dialog) => ({ ...dialog, open })) }, channelsDialog.session)] })) }));
|
|
163
|
+
/* Full width of the Connectors shell: the heroes are split cards whose
|
|
164
|
+
chat preview needs the room. No heading and no scroll container here;
|
|
165
|
+
both belong to the `CapabilityPageShell` in `connectors-page.tsx`. */
|
|
166
|
+
_jsx(ChannelHeroLayoutProvider, { children: _jsxs("div", { className: "w-full space-y-6", children: [loading
|
|
167
|
+
? platforms.map((pf) => _jsx(Skeleton, { className: "h-72 w-full rounded-lg" }, pf))
|
|
168
|
+
: platforms.map((pf) => (_jsx("div", { className: "space-y-4", children: hero(pf) }, pf))), showComputer && !loading ? _jsx(ComputerHero, { projectId: projectId }) : null, _jsx(ChannelBindingsDialog, { projectId: projectId, canWrite: canWrite, platform: channelsDialog.platform, open: channelsDialog.open, onOpenChange: (open) => setChannelsDialog((dialog) => ({ ...dialog, open })) }, channelsDialog.session)] }) }));
|
|
174
169
|
}
|
|
175
170
|
/** Slack as a peer row, once it is connected. */
|
|
176
171
|
function SlackChannelRow({ projectId, installation, canWrite, channelCount, onOpenChannels, }) {
|
|
177
172
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
173
|
+
const tPages = useTranslations('connectorPages');
|
|
178
174
|
const disconnect = useDisconnectSlack();
|
|
179
|
-
return (_jsx(ChannelRow, {
|
|
175
|
+
return (_jsx(ChannelRow, { app: "slack", name: "Slack", connected: true, detail: installation.workspaceName ?? installation.workspaceId, pitch: tI18nComplete.raw('text9bd1c37ed121'), hero: {
|
|
176
|
+
title: tI18nComplete.raw('text89e9e20668f3'),
|
|
177
|
+
connectedTitle: tPages('channelConnectedTitle', { name: 'Slack' }),
|
|
178
|
+
preview: _jsx(SlackChannelMock, {}),
|
|
179
|
+
}, actions: _jsxs(_Fragment, { children: [channelCount > 0 ? _jsx(ChannelsButton, { count: channelCount, onOpen: onOpenChannels }) : null, canWrite ? (_jsx(ChannelDisconnectButton, { pending: disconnect.isPending, onConfirm: (done) => disconnect.mutate(projectId, {
|
|
180
180
|
onSuccess: () => {
|
|
181
181
|
done();
|
|
182
182
|
successToast(tI18nComplete.raw('textd948c285986a'));
|
|
@@ -556,6 +556,7 @@ function TeamsAppUpdateNotice({ install, tI18nComplete, }) {
|
|
|
556
556
|
}
|
|
557
557
|
function TeamsChannelRow({ projectId, canWrite, channelCount, onOpenChannels, }) {
|
|
558
558
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
559
|
+
const tPages = useTranslations('connectorPages');
|
|
559
560
|
const { data: install } = useTeamsInstall(projectId);
|
|
560
561
|
const { data: mode } = useTeamsMode(projectId);
|
|
561
562
|
const disconnect = useDisconnectTeams();
|
|
@@ -579,29 +580,14 @@ function TeamsChannelRow({ projectId, canWrite, channelCount, onOpenChannels, })
|
|
|
579
580
|
const detail = install?.publishState === 'failed' && install.publishError
|
|
580
581
|
? `${install.teamName ?? install.tenantId} · ${install.publishError}`
|
|
581
582
|
: (install?.teamName ?? install?.tenantId ?? null);
|
|
582
|
-
return (_jsx(ChannelRow, {
|
|
583
|
+
return (_jsx(ChannelRow, { app: "teams", name: "Microsoft Teams", connected: connected, detail: detail, pitch: tI18nComplete.raw('text9225e456b795'), hero: {
|
|
584
|
+
title: tI18nComplete.raw('textc1bd5ca19f5f'),
|
|
585
|
+
connectedTitle: tPages('channelConnectedTitle', { name: 'Microsoft Teams' }),
|
|
586
|
+
preview: _jsx(TeamsChannelMock, {}),
|
|
587
|
+
}, badge: install ? _jsx(TeamsPublishBadge, { install: install, tI18nComplete: tI18nComplete }) : null, actions: _jsxs(_Fragment, { children: [connected && channelCount > 0 ? (_jsx(ChannelsButton, { count: channelCount, onOpen: onOpenChannels })) : null, !canWrite ? null : connected ? (_jsxs(_Fragment, { children: [deepLinkUrl ? (_jsx(Button, { size: "sm", variant: "secondary", asChild: true, children: _jsx(Link, { href: deepLinkUrl, target: "_blank", rel: "noopener noreferrer", children: tI18nComplete.raw('text1fece1858ee9') }) })) : null, retryUrl ? (_jsx(Button, { size: "sm", variant: "secondary", asChild: true, children: _jsx(Link, { href: retryUrl, target: "_blank", rel: "noopener noreferrer", children: retryLabel }) })) : null, _jsx(ChannelDisconnectButton, { pending: disconnect.isPending, onConfirm: (done) => disconnect.mutate(projectId, {
|
|
583
588
|
onSuccess: () => {
|
|
584
589
|
done();
|
|
585
590
|
successToast(tI18nComplete.raw('textf2e69a5e24ba'));
|
|
586
591
|
},
|
|
587
|
-
}) })] })) : installUrl ? (_jsx(Button, {
|
|
588
|
-
}
|
|
589
|
-
function EmailChannelRow({ projectId, enabled, installation, canWrite, }) {
|
|
590
|
-
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
591
|
-
const disconnect = useDisconnectEmail();
|
|
592
|
-
const [connectOpen, setConnectOpen] = useState(false);
|
|
593
|
-
const connected = Boolean(installation);
|
|
594
|
-
return (_jsxs(_Fragment, { children: [_jsx(ChannelRow, { icon: _jsx(EnvelopeIcon, { className: "text-muted-foreground size-5 shrink-0" }), name: "Email", connected: connected, detail: installation?.email ?? null, pitch: enabled
|
|
595
|
-
? tI18nComplete.raw('text27ba4ec98716')
|
|
596
|
-
: // `FeatureGateScreen`'s exact words for a flag that is off, with
|
|
597
|
-
// the name the Feature flags section lists the flag under.
|
|
598
|
-
`AgentMail Email ${tI18nComplete.raw('text26965989cce5')}`, actions: !enabled ? (_jsx(Button, { size: "sm", variant: "secondary", asChild: true, children: _jsx(Link, { href: projectSettingsSectionHref(projectId, 'feature-flags'), children: tI18nComplete.raw('text20a2e59ba129') }) })) : !canWrite ? null : connected ? (_jsx(ChannelDisconnectButton, { pending: disconnect.isPending, onConfirm: (done) => disconnect.mutate({ projectId, connectorSlug: EMAIL_CONNECTOR_SLUG }, {
|
|
599
|
-
onSuccess: () => {
|
|
600
|
-
done();
|
|
601
|
-
successToast(tI18nComplete.raw('text958c8e06d3e7'));
|
|
602
|
-
},
|
|
603
|
-
}) })) : (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => setConnectOpen(true), children: tI18nComplete.raw('text1a2303ede074') })) }), _jsx(Modal, { open: connectOpen, onOpenChange: setConnectOpen, children: _jsxs(ModalContent, { className: "lg:max-w-2xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text3de5e2a29bbc') }), _jsx(ModalDescription, { children: tI18nComplete.raw('texte13e04973080') })] }), _jsx(ModalBody, { className: "max-h-[75vh] overflow-y-auto", children: _jsx(EmailConnectForm, { projectId: projectId, connectorSlug: EMAIL_CONNECTOR_SLUG, onConnected: () => {
|
|
604
|
-
setConnectOpen(false);
|
|
605
|
-
successToast(tI18nComplete.raw('text62c381e56f37'));
|
|
606
|
-
} }) })] }) })] }));
|
|
592
|
+
}) })] })) : installUrl ? (_jsx(Button, { className: "transition-transform active:scale-96", asChild: true, children: _jsx(Link, { href: installUrl, target: "_blank", rel: "noopener noreferrer", children: tI18nComplete.raw('text1a2303ede074') }) })) : null] }) }));
|
|
607
593
|
}
|
|
@@ -11,6 +11,8 @@ import { cn } from '../../../../internal/lib/utils.js';
|
|
|
11
11
|
import { CostPanel, CostSection, MetricTab, RangeSelector, ShareBar, UsageChart, fmtCompact, fmtCredits, fmtMs, weightedP50, } from './_metrics.js';
|
|
12
12
|
import { displayModel } from './_shared.js';
|
|
13
13
|
import { GatewayBudgetSection } from './gateway-budgets.js';
|
|
14
|
+
/** An LLM usage estimate in US dollars, to 4 decimals. */
|
|
15
|
+
const usd4 = (value) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4, maximumFractionDigits: 4 }).format(value);
|
|
14
16
|
const METRICS = [
|
|
15
17
|
// Spend reads in credits; the tooltip appends the unit in the component.
|
|
16
18
|
{ key: 'cost', label: 'Spend', keys: ['cost'], fmt: (v) => fmtCredits(v) },
|
|
@@ -144,11 +146,17 @@ export function GatewayOverview({ projectId, canWrite = false, }) {
|
|
|
144
146
|
// No scroller and no padding of its own: this is a tab of
|
|
145
147
|
// `/projects/[id]/models`, and `CapabilityPageShell` owns the page's one
|
|
146
148
|
// scroll container and its column.
|
|
147
|
-
_jsx("div", { className: "flex flex-col", children: _jsxs("div", { className: "w-full space-y-12", children: [_jsxs("section", { className: "border-border bg-surface overflow-hidden rounded-xl border", children: [_jsxs("div", { className: "border-border flex flex-col border-b sm:flex-row", children: [_jsx("div", { role: "tablist", "aria-label": tI18nComplete.raw('text9e217716c4e0'), className: "flex min-w-0 flex-1", children: tabs.map((m) => (_jsx(MetricTab, { label: tab(m.key), value: m.value, unit: m.unit, selected: metric === m.key, onSelect: () => setMetric(m.key) }, m.key))) }), _jsx("div", { className: "border-border flex items-center border-t px-4 py-3 sm:border-t-0 sm:border-l sm:py-0", children: _jsx(RangeSelector, { days: days, setDays: setDays }) })] }), _jsxs("div", { className: "space-y-2 px-5 pt-6 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-xs tabular-nums", children: tabs.find((m) => m.key === metric)?.sub }),
|
|
149
|
+
_jsx("div", { className: "flex flex-col", children: _jsxs("div", { className: "w-full space-y-12", children: [_jsxs("section", { className: "border-border bg-surface overflow-hidden rounded-xl border", children: [_jsxs("div", { className: "border-border flex flex-col border-b sm:flex-row", children: [_jsx("div", { role: "tablist", "aria-label": tI18nComplete.raw('text9e217716c4e0'), className: "flex min-w-0 flex-1", children: tabs.map((m) => (_jsx(MetricTab, { label: tab(m.key), value: m.value, unit: m.unit, selected: metric === m.key, onSelect: () => setMetric(m.key) }, m.key))) }), _jsx("div", { className: "border-border flex items-center border-t px-4 py-3 sm:border-t-0 sm:border-l sm:py-0", children: _jsx(RangeSelector, { days: days, setDays: setDays }) })] }), _jsxs("div", { className: "space-y-2 px-5 pt-6 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-xs tabular-nums", children: tabs.find((m) => m.key === metric)?.sub }), _jsxs("p", { className: "text-muted-foreground text-xs tabular-nums", children: [t('estimatedUsageValueLabel'), ' ', overview?.estimated_usage_value == null
|
|
150
|
+
? t('unknownValue')
|
|
151
|
+
: usd4(overview.estimated_usage_value), ' · ', t('pricedRequests', { count: overview?.priced_requests ?? 0 }), ' · ', t('unpricedRequests', { count: overview?.unpriced_requests ?? 0 })] }), _jsxs("p", { className: "text-muted-foreground text-xs", children: [overview?.valuation?.coverage ?? t('estimateCoverageUnavailable'), " ", t('estimatesSeparate'), ' ', overview?.valuation?.rate_version] }), _jsx(UsageChart, { data: series, keys: activeMetric.keys, yFormatter: activeMetric.key === 'cost'
|
|
148
152
|
? (v) => `${credits(v)} ${creditsUnit}`
|
|
149
153
|
: activeMetric.fmt })] })] }), _jsx(GatewayBudgetSection, { projectId: projectId, canWrite: canWrite }), _jsxs("div", { className: "flex flex-col gap-4 lg:flex-row", children: [_jsx(CostSection, { title: t('mostSpend'), description: t('mostSpendHint'), children: _jsx(CostPanel, { children: spend.named.length === 0 ? (_jsx("p", { className: "text-muted-foreground flex h-10 items-center text-xs", children: tI18nComplete.raw('textea923f45a415') })) : (_jsxs(_Fragment, { children: [spend.named.map(({ model, share }) => (_jsx(SpendRow, { label: displayModel(model.model) || 'unknown', value: `${credits(model.cost)} ${creditsUnit} · ${share}%` }, `${model.provider}/${model.model}`))), spend.rest ? (_jsx(SpendRow, { label: t('everythingElse'), value: `${credits(spend.rest.cost)} ${creditsUnit} · ${spend.rest.share}%` })) : null] })) }) }), _jsx(CostSection, { title: tI18nComplete.raw('textfec78985c8f3'), description: t('sessionsHint'), children: _jsx(CostPanel, { children: sessions.length === 0 ? (_jsx("p", { className: "text-muted-foreground flex h-10 items-center text-xs", children: tI18nComplete.raw('text0e25da739ad6') })) : (sessions.map((s) => {
|
|
150
154
|
const name = sessionNames.get(s.session_id);
|
|
151
|
-
return (_jsxs("div", { className: "border-border flex min-h-13 items-center gap-4 border-b py-2 last:border-b-0", "data-session-row": "", children: [_jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsx("span", { className: cn('text-foreground truncate text-xs', !name && 'font-mono'), children: name ?? s.session_id.slice(0, 8) }), _jsxs("span", { className: "text-muted-foreground truncate text-xs tabular-nums", children: [name ? _jsxs("span", { className: "font-mono", children: [s.session_id.slice(0, 8), " \u00B7 "] }) : null, t('sessionModel', { cost: credits(s.llm_cost) }), " \u00B7", ' ', t('sessionSandbox', {
|
|
155
|
+
return (_jsxs("div", { className: "border-border flex min-h-13 items-center gap-4 border-b py-2 last:border-b-0", "data-session-row": "", children: [_jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsx("span", { className: cn('text-foreground truncate text-xs', !name && 'font-mono'), children: name ?? s.session_id.slice(0, 8) }), _jsxs("span", { className: "text-muted-foreground truncate text-xs tabular-nums", children: [name ? (_jsxs("span", { className: "font-mono", children: [s.session_id.slice(0, 8), " \u00B7 "] })) : null, t('sessionModel', { cost: credits(s.llm_cost) }), " \u00B7", ' ', t('sessionSandbox', {
|
|
156
|
+
cost: credits(s.compute_cost),
|
|
157
|
+
}), ' ', "\u00B7 ", s.requests.toLocaleString(), " ", tI18nComplete.raw('textc3f7bdf537c4'), ' · ', t('llmEstimateLabel'), ' ', s.estimated_usage_value == null
|
|
158
|
+
? t('unknownValue')
|
|
159
|
+
: usd4(s.estimated_usage_value)] })] }), _jsx(ShareBar, { className: "w-24", segments: [
|
|
152
160
|
{ pct: (s.llm_cost / maxSessionCost) * 100, color: 'var(--kortix-blue)' },
|
|
153
161
|
{
|
|
154
162
|
pct: (s.compute_cost / maxSessionCost) * 100,
|
|
@@ -53,7 +53,7 @@ import { useTranslations as useI18nTranslations } from '../../../i18n/index.js';
|
|
|
53
53
|
* hook only runs once this tab is actually mounted, which `SettingsTabPane`
|
|
54
54
|
* in `settings-panel.tsx` guarantees happens only while this tab is active.
|
|
55
55
|
*/
|
|
56
|
-
import {
|
|
56
|
+
import { useRef, useState } from 'react';
|
|
57
57
|
import { Button } from '../../../primitives/button.js';
|
|
58
58
|
import { InputGroupSearch, InputGroupSearchClear, InputGroupSearchIcon, InputGroupSearchInput, } from '../../../primitives/input-group.js';
|
|
59
59
|
import Loading from '../../../primitives/loading.js';
|
|
@@ -70,6 +70,7 @@ import { getProject, updateFeatureFlag, } from '@kortix/sdk';
|
|
|
70
70
|
import { contract, invalidateProject, qk } from '@kortix/sdk/react';
|
|
71
71
|
import { FlagIcon, MagnifyingGlassIcon as Search } from '@phosphor-icons/react';
|
|
72
72
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
73
|
+
import { ChannelsSwitchDialog } from '../../shared/channels-switch-dialog.js';
|
|
73
74
|
import { SettingsTabHeader } from '../settings-tab-header.js';
|
|
74
75
|
export const DEFAULT_EXPERIMENTAL_COPY = {
|
|
75
76
|
overridden: 'Overridden for this project',
|
|
@@ -256,22 +257,40 @@ export function ExperimentalTab({ projectId }) {
|
|
|
256
257
|
...f,
|
|
257
258
|
enabled: pendingValues[f.key] ?? f.enabled,
|
|
258
259
|
}));
|
|
259
|
-
|
|
260
|
-
|
|
260
|
+
// the Channels switch changes the sidebar for everyone, so only a
|
|
261
|
+
// viewer who may flip it sees it (hidden while that answer loads).
|
|
262
|
+
const visible = canEdit ? withPending : withPending.filter((f) => f.key !== 'project_channels');
|
|
263
|
+
const features = filterFeatures(visible, query);
|
|
264
|
+
const apply = (key, next) => {
|
|
261
265
|
setPendingValues((prev) => ({ ...prev, [key]: next }));
|
|
262
266
|
toggleMutation.mutate({ key: key, next });
|
|
263
267
|
};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
268
|
+
// Channels asks first: the dialog says what changes for everyone.
|
|
269
|
+
const [channelsTarget, setChannelsTarget] = useState(null);
|
|
270
|
+
const handleToggle = (key, next) => {
|
|
271
|
+
if (key === 'project_channels')
|
|
272
|
+
setChannelsTarget(next);
|
|
273
|
+
else
|
|
274
|
+
apply(key, next);
|
|
275
|
+
};
|
|
276
|
+
const drive = rawFeatures.find((f) => f.key === 'drives');
|
|
277
|
+
return (_jsxs(_Fragment, { children: [_jsx(ChannelsSwitchDialog, { open: channelsTarget !== null, onOpenChange: (open) => !open && setChannelsTarget(null), turningOn: channelsTarget === true, projectName: project?.name ?? '', driveOff: !!drive && !drive.enabled && drive.operator_only !== true, onConfirm: (alsoDrive) => {
|
|
278
|
+
const target = channelsTarget === true;
|
|
279
|
+
setChannelsTarget(null);
|
|
280
|
+
apply('project_channels', target);
|
|
281
|
+
if (alsoDrive)
|
|
282
|
+
apply('drives', true);
|
|
283
|
+
} }), _jsx(ExperimentalTabView, { isLoading: projectQuery.isLoading, isError: projectQuery.isError, errorMessage: projectQuery.error?.message ?? '', onRetry: () => projectQuery.refetch(), features: features, pendingKeys: Object.keys(pendingValues), canManage: canEdit, canManageOperatorOnly: isOperator, onToggle: handleToggle, showPermissionNotice: !canEdit && !writeCap.isLoading, query: query, onQueryChange: setQuery, copy: {
|
|
284
|
+
overridden: t('origin.overridden'),
|
|
285
|
+
managedByKortix: tI18nComplete.raw('texte9ec6c0ad396'),
|
|
286
|
+
defaultOn: t('origin.defaultOn'),
|
|
287
|
+
defaultOff: t('origin.defaultOff'),
|
|
288
|
+
search: t('search'),
|
|
289
|
+
loadFailed: t('loadFailed'),
|
|
290
|
+
retry: t('retry'),
|
|
291
|
+
noMatches: (value) => t('noMatches', { query: value }),
|
|
292
|
+
emptyTitle: t('emptyTitle'),
|
|
293
|
+
emptyDescription: t('emptyDescription'),
|
|
294
|
+
permission: t('permission'),
|
|
295
|
+
} })] }));
|
|
277
296
|
}
|
|
@@ -15,17 +15,6 @@ export declare function CatalogEmptyNote({ children }: {
|
|
|
15
15
|
* spaces inside a monospace span, which reads as a rendering bug rather than as
|
|
16
16
|
* a report of what was searched for.
|
|
17
17
|
*/
|
|
18
|
-
export declare function CatalogNoMatch({ query
|
|
18
|
+
export declare function CatalogNoMatch({ query }: {
|
|
19
19
|
query: string;
|
|
20
|
-
/**
|
|
21
|
-
* Apps that matched but expose no actions, so the catalogue does not offer
|
|
22
|
-
* them.
|
|
23
|
-
*
|
|
24
|
-
* Without this the page reports a flat "No matches for SAP" — which is wrong
|
|
25
|
-
* twice, because `sap_s_4hana_cloud` and `sap_s_4hana_cloud_sandbox` both
|
|
26
|
-
* exist upstream and the reason they are absent is one we can state.
|
|
27
|
-
* Reporting a bare zero is what made the catalogue look broken rather than
|
|
28
|
-
* selective.
|
|
29
|
-
*/
|
|
30
|
-
excludedNoActions?: number;
|
|
31
20
|
}): import("react").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useTranslations } from '../../../i18n/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* The "nothing here" line every catalog uses, so five hand-typed copies of one
|
|
@@ -16,7 +16,7 @@ export function CatalogEmptyNote({ children }) {
|
|
|
16
16
|
* spaces inside a monospace span, which reads as a rendering bug rather than as
|
|
17
17
|
* a report of what was searched for.
|
|
18
18
|
*/
|
|
19
|
-
export function CatalogNoMatch({ query
|
|
19
|
+
export function CatalogNoMatch({ query }) {
|
|
20
20
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
21
|
-
return (_jsxs(CatalogEmptyNote, { children: [tI18nComplete.raw('texta8897de42124'), ' ', _jsx("span", { className: "text-foreground font-mono", children: query.trim() }), "."
|
|
21
|
+
return (_jsxs(CatalogEmptyNote, { children: [tI18nComplete.raw('texta8897de42124'), ' ', _jsx("span", { className: "text-foreground font-mono", children: query.trim() }), "."] }));
|
|
22
22
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The confirm step of the project's Channels switch (`project_channels`):
|
|
3
|
+
* what turning it on or off changes for everyone in the project. Turning it
|
|
4
|
+
* on while Drive is off offers to turn Drive on too (channels get Files).
|
|
5
|
+
* Every surface that flips the flag asks through this dialog.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ChannelsSwitchDialog({ open, onOpenChange, turningOn, projectName, driveOff, pending, onConfirm, }: {
|
|
8
|
+
open: boolean;
|
|
9
|
+
onOpenChange: (open: boolean) => void;
|
|
10
|
+
/** The switch's target: on, or off. */
|
|
11
|
+
turningOn: boolean;
|
|
12
|
+
projectName: string;
|
|
13
|
+
/** Drive is off and the viewer could turn it on: offer it beside Channels. */
|
|
14
|
+
driveOff: boolean;
|
|
15
|
+
pending?: boolean;
|
|
16
|
+
/** `alsoDrive`: turn Drive on too. */
|
|
17
|
+
onConfirm: (alsoDrive: boolean) => void;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useState } from 'react';
|
|
4
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
5
|
+
import { Button } from '../../primitives/button.js';
|
|
6
|
+
import { Checkbox } from '../../primitives/checkbox.js';
|
|
7
|
+
import Loading from '../../primitives/loading.js';
|
|
8
|
+
import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from '../../primitives/modal.js';
|
|
9
|
+
/**
|
|
10
|
+
* The confirm step of the project's Channels switch (`project_channels`):
|
|
11
|
+
* what turning it on or off changes for everyone in the project. Turning it
|
|
12
|
+
* on while Drive is off offers to turn Drive on too (channels get Files).
|
|
13
|
+
* Every surface that flips the flag asks through this dialog.
|
|
14
|
+
*/
|
|
15
|
+
export function ChannelsSwitchDialog({ open, onOpenChange, turningOn, projectName, driveOff, pending = false, onConfirm, }) {
|
|
16
|
+
const t = useTranslations('settings.featureFlags.channelsSwitch');
|
|
17
|
+
const id = useId();
|
|
18
|
+
const [alsoDrive, setAlsoDrive] = useState(false);
|
|
19
|
+
const offerDrive = turningOn && driveOff;
|
|
20
|
+
return (_jsx(Modal, { open: open, onOpenChange: (next) => {
|
|
21
|
+
if (pending)
|
|
22
|
+
return;
|
|
23
|
+
if (!next)
|
|
24
|
+
setAlsoDrive(false);
|
|
25
|
+
onOpenChange(next);
|
|
26
|
+
}, children: _jsxs(ModalContent, { className: "lg:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: turningOn ? t('onTitle', { project: projectName }) : t('offTitle') }), _jsx(ModalDescription, { children: turningOn ? t('onBody') : t('offBody') })] }), offerDrive ? (_jsx(ModalBody, { children: _jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx(Checkbox, { id: `${id}-drive`, checked: alsoDrive, onCheckedChange: (value) => setAlsoDrive(value === true) }), _jsx("label", { htmlFor: `${id}-drive`, className: "text-sm", children: t('drive') })] }) })) : null, _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", disabled: pending, onClick: () => onOpenChange(false), children: t('cancel') }), _jsxs(Button, { type: "button", disabled: pending, "aria-busy": pending || undefined, onClick: () => {
|
|
27
|
+
onConfirm(offerDrive && alsoDrive);
|
|
28
|
+
setAlsoDrive(false);
|
|
29
|
+
}, children: [pending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, turningOn ? t('turnOn') : t('turnOff')] })] })] }) }));
|
|
30
|
+
}
|
|
@@ -4,12 +4,13 @@ import { useTranslations } from '../../i18n/index.js';
|
|
|
4
4
|
import { UiLink, useUiParams } from '../../providers/ui-provider.js';
|
|
5
5
|
import { Button } from '../../primitives/button.js';
|
|
6
6
|
import { projectSettingsSectionHref } from '../project-settings/project-settings-sections.js';
|
|
7
|
+
import { ChannelsSwitchDialog } from './channels-switch-dialog.js';
|
|
7
8
|
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
8
9
|
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
9
|
-
import { updateFeatureFlag } from '@kortix/sdk';
|
|
10
|
-
import { invalidateProject, qk } from '@kortix/sdk/react';
|
|
10
|
+
import { getProject, updateFeatureFlag } from '@kortix/sdk';
|
|
11
|
+
import { contract, invalidateProject, qk } from '@kortix/sdk/react';
|
|
11
12
|
import { FlagIcon } from '@phosphor-icons/react';
|
|
12
|
-
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
13
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
13
14
|
import { useState } from 'react';
|
|
14
15
|
/** A disabled surface keeps its enable action and settings link in place. */
|
|
15
16
|
export function FeatureGateScreen({ featureKey, featureName, description, internalOnly = false, }) {
|
|
@@ -21,11 +22,12 @@ export function FeatureGateScreen({ featureKey, featureName, description, intern
|
|
|
21
22
|
const permission = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_SETTINGS_WRITE);
|
|
22
23
|
const [error, setError] = useState('');
|
|
23
24
|
const enable = useMutation({
|
|
24
|
-
mutationFn: () => {
|
|
25
|
+
mutationFn: async (alsoDrive = false) => {
|
|
25
26
|
if (!projectId || internalOnly || permission.isLoading || permission.allowed !== true) {
|
|
26
27
|
throw new Error('Feature activation is not permitted');
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
const updated = await updateFeatureFlag(projectId, featureKey, true);
|
|
30
|
+
return alsoDrive ? updateFeatureFlag(projectId, 'drives', true) : updated;
|
|
29
31
|
},
|
|
30
32
|
onSuccess: (updated) => {
|
|
31
33
|
if (!projectId)
|
|
@@ -37,8 +39,24 @@ export function FeatureGateScreen({ featureKey, featureName, description, intern
|
|
|
37
39
|
},
|
|
38
40
|
onError: (cause) => setError(cause.message),
|
|
39
41
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const channels = featureKey === 'project_channels';
|
|
43
|
+
const [confirming, setConfirming] = useState(false);
|
|
44
|
+
const project = useQuery({
|
|
45
|
+
queryKey: qk.project.summary(projectId ?? ''),
|
|
46
|
+
queryFn: () => getProject(projectId),
|
|
47
|
+
enabled: channels && !!projectId,
|
|
48
|
+
...contract('config'),
|
|
49
|
+
});
|
|
50
|
+
const drive = project.data?.experimental_features?.find((f) => f.key === 'drives' && f.available);
|
|
51
|
+
return (_jsxs("div", { className: "bg-popover rounded-md border px-4 py-5", children: [channels ? (_jsx(ChannelsSwitchDialog, { open: confirming, onOpenChange: setConfirming, turningOn: true, projectName: project.data?.name ?? '', driveOff: !!drive && !drive.enabled && drive.operator_only !== true, onConfirm: (alsoDrive) => {
|
|
52
|
+
setConfirming(false);
|
|
53
|
+
enable.mutate(alsoDrive);
|
|
54
|
+
} })) : null, _jsxs("div", { className: "flex flex-col gap-5 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [_jsx("span", { className: "bg-muted/50 flex size-9 shrink-0 items-center justify-center rounded-sm", children: _jsx(FlagIcon, { className: "text-muted-foreground size-5" }) }), _jsxs("div", { className: "min-w-0 space-y-1", children: [_jsxs("p", { className: "text-foreground text-sm font-medium", children: [featureName, " ", tI18nComplete.raw('text26965989cce5')] }), _jsx("p", { className: "text-muted-foreground max-w-xl text-xs text-pretty", children: description }), internalOnly ? (_jsx("p", { className: "text-muted-foreground max-w-xl text-xs text-pretty", children: tI18nComplete.raw('text1c41abcc2fff') })) : null] })] }), error ? (_jsx("p", { role: "alert", className: "text-destructive text-xs", children: error })) : null, projectId && !internalOnly ? (_jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx(Button, { size: "sm", disabled: permission.isLoading || permission.allowed !== true || enable.isPending, onClick: () => {
|
|
55
|
+
setError('');
|
|
56
|
+
// Channels changes the sidebar for everyone: it asks first.
|
|
57
|
+
if (channels)
|
|
58
|
+
setConfirming(true);
|
|
59
|
+
else
|
|
60
|
+
enable.mutate(false);
|
|
61
|
+
}, children: enable.isPending ? t('enabling') : t('enable', { name: featureName }) }), _jsx(Button, { asChild: true, size: "sm", variant: "secondary", className: "shrink-0", children: _jsx(UiLink, { href: projectSettingsSectionHref(projectId, 'feature-flags'), children: tI18nComplete.raw('text20a2e59ba129') }) })] })) : null] })] }));
|
|
44
62
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* - A longer `gcTime` keeps the entries through a long session on another
|
|
19
19
|
* route; the default five minutes would drop them before Customize opens.
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
21
|
+
import { getModelDefaults, getProject, getProjectModelPicker, listConnectors, listProjectBranches, listProjectResourceGrants, listProjectSandboxTemplates, listProjectSecrets, listProjectSnapshots, listProjectTriggers, listReviewItems } from '@kortix/sdk';
|
|
22
22
|
import { type QueryClient } from '@tanstack/react-query';
|
|
23
23
|
/** Keep prefetched Customize data for half an hour without an observer. */
|
|
24
24
|
export declare const CUSTOMIZE_PREFETCH_GC_MS: number;
|
|
@@ -35,11 +35,10 @@ export interface CustomizePrefetchGates {
|
|
|
35
35
|
reviewRead: boolean;
|
|
36
36
|
membersManage: boolean;
|
|
37
37
|
}
|
|
38
|
-
type CatalogQueries = Pick<typeof import('../connectors/catalog/use-catalog.js'), 'catalogSectionsQuery'
|
|
38
|
+
type CatalogQueries = Pick<typeof import('../connectors/catalog/use-catalog.js'), 'catalogSectionsQuery'>;
|
|
39
39
|
/** The reads the prefetch issues. Injected in tests; the SDK in production. */
|
|
40
40
|
export interface CustomizePrefetchApi {
|
|
41
41
|
getProject: typeof getProject;
|
|
42
|
-
getConnectStatus: typeof getConnectStatus;
|
|
43
42
|
getModelDefaults: typeof getModelDefaults;
|
|
44
43
|
getProjectModelPicker: typeof getProjectModelPicker;
|
|
45
44
|
listConnectors: typeof listConnectors;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* - A longer `gcTime` keeps the entries through a long session on another
|
|
20
20
|
* route; the default five minutes would drop them before Customize opens.
|
|
21
21
|
*/
|
|
22
|
-
import {
|
|
22
|
+
import { getModelDefaults, getProject, getProjectDetail, getProjectModelPicker, listConnectors, listProjectBranches, listProjectResourceGrants, listProjectSandboxTemplates, listProjectSecrets, listProjectSnapshots, listProjectTriggers, listReviewItems, } from '@kortix/sdk';
|
|
23
23
|
import { contract, FRESHNESS, qk } from '@kortix/sdk/react';
|
|
24
24
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
25
25
|
import { useEffect, useMemo } from 'react';
|
|
@@ -31,7 +31,6 @@ export const CUSTOMIZE_PREFETCH_GC_MS = 30 * 60_000;
|
|
|
31
31
|
const IDLE_TIMEOUT_MS = 1_000;
|
|
32
32
|
const sdkApi = {
|
|
33
33
|
getProject,
|
|
34
|
-
getConnectStatus,
|
|
35
34
|
getModelDefaults,
|
|
36
35
|
getProjectModelPicker,
|
|
37
36
|
listConnectors,
|
|
@@ -137,35 +136,18 @@ export async function prefetchCustomize(queryClient, projectId, gates, api = sdk
|
|
|
137
136
|
}
|
|
138
137
|
await Promise.all(work);
|
|
139
138
|
}
|
|
140
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* Connectors → the catalogue's landing sections, as the page opens it: One-click
|
|
141
|
+
* only on, no type filter (`ConnectorsPage`). Same key as `useCatalog`.
|
|
142
|
+
*/
|
|
141
143
|
async function prefetchCatalogLanding(queryClient, projectId, api) {
|
|
142
144
|
const catalog = await api.loadCatalogQueries().catch(() => null);
|
|
143
145
|
if (!catalog)
|
|
144
146
|
return;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const status = await queryClient
|
|
150
|
-
.fetchQuery({
|
|
151
|
-
queryKey: connectStatusQuery.queryKey,
|
|
152
|
-
queryFn: api.getConnectStatus,
|
|
153
|
-
staleTime: 30_000,
|
|
154
|
-
retry: false,
|
|
155
|
-
})
|
|
156
|
-
.catch(() => null);
|
|
157
|
-
if (!status?.configured)
|
|
158
|
-
return;
|
|
159
|
-
const providers = status.providers ?? (status.provider ? [status.provider] : []);
|
|
160
|
-
// Same provider choice as `useConnectProviderStatus`: Composio first.
|
|
161
|
-
const provider = providers.includes('composio')
|
|
162
|
-
? 'composio'
|
|
163
|
-
: providers.includes('pipedream')
|
|
164
|
-
? 'pipedream'
|
|
165
|
-
: null;
|
|
166
|
-
if (!provider)
|
|
167
|
-
return;
|
|
168
|
-
await queryClient.prefetchQuery({ ...catalogSectionsQuery(projectId, provider), ...gc });
|
|
147
|
+
await queryClient.prefetchQuery({
|
|
148
|
+
...catalog.catalogSectionsQuery(projectId, true),
|
|
149
|
+
gcTime: CUSTOMIZE_PREFETCH_GC_MS,
|
|
150
|
+
});
|
|
169
151
|
}
|
|
170
152
|
function whenIdle(run) {
|
|
171
153
|
if (typeof window === 'undefined')
|