@k2b/cloud 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +22 -11
- package/scripts/README.md +10 -0
- package/scripts/browser-performance.ts +14 -0
- package/scripts/build-pdf-renderer.ts +39 -0
- package/scripts/build.ts +20 -35
- package/scripts/preload.ts +16 -12
- package/scripts/sync-recovery-smoke.ts +22 -6
- package/src/_internal/app-presentation.ts +14 -2
- package/src/_internal/build-metadata.ts +8 -1
- package/src/_internal/capabilities.ts +131 -7
- package/src/_internal/capability-streams.ts +81 -0
- package/src/_internal/define-app.ts +80 -37
- package/src/_internal/heartbeat.ts +4 -0
- package/src/_internal/help-catalog.ts +27 -172
- package/src/_internal/help.ts +13 -76
- package/src/_internal/page-responses.ts +2 -0
- package/src/_internal/postgres-application-name.ts +30 -0
- package/src/_internal/process-identity.ts +15 -0
- package/src/_internal/process-sync.ts +1 -1
- package/src/_internal/readiness.ts +4 -1
- package/src/_internal/registry-validation.ts +29 -25
- package/src/_internal/registry.ts +2 -53
- package/src/_internal/runtime-context.ts +5 -16
- package/src/_internal/server-timing.ts +13 -0
- package/src/_internal/status-preserving-ssr.ts +18 -6
- package/src/_internal/web-vitals-asset.ts +10 -0
- package/src/access/PermissionEditor.tsx +18 -151
- package/src/access/PrincipalPicker.tsx +110 -0
- package/src/access/ResourceApiKeys.tsx +1 -1
- package/src/access/ui.ts +1 -0
- package/src/ai/admin.ts +14 -13
- package/src/ai/assistant-models.ts +12 -1
- package/src/ai/audio-format.ts +34 -0
- package/src/ai/audio-tool.ts +90 -0
- package/src/ai/browser-code-contracts.ts +201 -0
- package/src/ai/browser.ts +4 -0
- package/src/ai/capabilities.ts +55 -36
- package/src/ai/capability-execution.ts +47 -12
- package/src/ai/chat/blocks.tsx +229 -90
- package/src/ai/chat/builtin-tools.tsx +2 -4
- package/src/ai/chat/capability-result.ts +15 -0
- package/src/ai/chat/capability-table.tsx +2 -10
- package/src/ai/chat/composer-adapter.ts +83 -3
- package/src/ai/chat/message-actions.tsx +8 -7
- package/src/ai/chat/message-utils.ts +25 -1
- package/src/ai/chat/messages.ts +2 -0
- package/src/ai/chat/presentation.tsx +31 -47
- package/src/ai/chat/primitives.tsx +43 -1
- package/src/ai/chat/tool-disclosure.tsx +21 -2
- package/src/ai/chat/tool-groups.ts +58 -0
- package/src/ai/chat-quotas.ts +25 -0
- package/src/ai/chat-task-contracts.ts +14 -10
- package/src/ai/chat-tasks.ts +297 -43
- package/src/ai/client/controller.ts +165 -39
- package/src/ai/client/file-source.ts +12 -6
- package/src/ai/client/live-connection.ts +1 -0
- package/src/ai/client/projection.ts +29 -11
- package/src/ai/client/transport.ts +6 -0
- package/src/ai/code-capability-routes.ts +105 -0
- package/src/ai/code-capability-transport.ts +39 -0
- package/src/ai/code-execution.ts +53 -0
- package/src/ai/code-mode-skill.ts +118 -0
- package/src/ai/code-runtime-tools.ts +179 -0
- package/src/ai/code-source-contracts.ts +270 -0
- package/src/ai/code-source-tools.ts +188 -0
- package/src/ai/compaction.ts +27 -6
- package/src/ai/data-analysis-skill.ts +10 -0
- package/src/ai/default-tools.ts +99 -3
- package/src/ai/dictation-runtime.ts +171 -0
- package/src/ai/dictations.ts +188 -0
- package/src/ai/draft-content.ts +49 -0
- package/src/ai/enrich.ts +6 -0
- package/src/ai/executor.ts +189 -33
- package/src/ai/fetch-file-tool.ts +2 -2
- package/src/ai/file-content-version.ts +27 -0
- package/src/ai/file-context.ts +2 -1
- package/src/ai/file-media-type.ts +12 -0
- package/src/ai/file-reference-contracts.ts +15 -0
- package/src/ai/file-tools.ts +8 -1
- package/src/ai/files-store.ts +212 -71
- package/src/ai/fixtures/vision-encrypted.pdf +0 -0
- package/src/ai/grids-skill.ts +42 -10
- package/src/ai/http.ts +26 -8
- package/src/ai/index.ts +26 -3
- package/src/ai/inference-calls.ts +197 -0
- package/src/ai/live-events.ts +5 -1
- package/src/ai/live.ts +1 -1
- package/src/ai/markdown-pdf-tool.ts +2 -2
- package/src/ai/memories.ts +30 -27
- package/src/ai/memory-learning-runs.ts +1 -1
- package/src/ai/memory-learning.ts +64 -32
- package/src/ai/memory-tool.ts +1 -5
- package/src/ai/memory-workflow-evidence.ts +9 -4
- package/src/ai/message-queue.ts +178 -0
- package/src/ai/migrate.ts +189 -11
- package/src/ai/model-pricing.ts +43 -0
- package/src/ai/pdf-render-worker.ts +75 -0
- package/src/ai/pdf-render.fixture.ts +28 -0
- package/src/ai/pdf-render.ts +77 -0
- package/src/ai/projects-routes.ts +18 -43
- package/src/ai/projects.ts +33 -14
- package/src/ai/protocol.ts +3 -0
- package/src/ai/provider.ts +1 -8
- package/src/ai/quota-provider.ts +192 -0
- package/src/ai/quota-report.ts +152 -0
- package/src/ai/quotas-migrate.ts +45 -0
- package/src/ai/quotas.ts +168 -0
- package/src/ai/routes.ts +241 -11
- package/src/ai/run-timeout.ts +12 -0
- package/src/ai/runtime-tools.ts +7 -5
- package/src/ai/runtime.ts +74 -17
- package/src/ai/settings.ts +36 -8
- package/src/ai/short-id.ts +4 -5
- package/src/ai/skill-catalog.ts +0 -10
- package/src/ai/skill-search.ts +58 -0
- package/src/ai/skill-seeds.ts +114 -20
- package/src/ai/skill-tool.ts +21 -5
- package/src/ai/skills-routes.ts +49 -4
- package/src/ai/skills.ts +358 -163
- package/src/ai/store.ts +416 -201
- package/src/ai/stream.ts +5 -0
- package/src/ai/structured-runs.ts +4 -3
- package/src/ai/structured.ts +12 -1
- package/src/ai/system-prompt.ts +14 -2
- package/src/ai/task-contracts.ts +84 -0
- package/src/ai/task-execution.ts +92 -0
- package/src/ai/timeline.ts +2 -5
- package/src/ai/todo-contracts.ts +32 -0
- package/src/ai/todo-tool.ts +19 -0
- package/src/ai/tool-audit.ts +30 -40
- package/src/ai/tools.ts +6 -0
- package/src/ai/transcription.ts +202 -0
- package/src/ai/turn-timing.ts +114 -0
- package/src/ai/types.ts +58 -10
- package/src/ai/ui.tsx +3 -0
- package/src/ai/usage.ts +118 -118
- package/src/ai/vision-tool.ts +60 -10
- package/src/api/admin-ai-projects.ts +2 -2
- package/src/api/admin-ai-quotas.ts +80 -0
- package/src/api/admin-ai-skills.ts +48 -5
- package/src/api/admin-ai-usage.ts +2 -2
- package/src/api/admin-core-settings.ts +25 -0
- package/src/api/admin-identity.ts +91 -51
- package/src/api/admin-linux-identities.ts +10 -4
- package/src/api/admin-rail.ts +58 -0
- package/src/api/announcements.ts +14 -0
- package/src/api/app-approval.ts +2 -2
- package/src/api/auth.ts +1 -1
- package/src/api/capabilities.ts +324 -43
- package/src/api/capability-streams.ts +262 -0
- package/src/api/help.ts +8 -44
- package/src/api/index.ts +8 -2
- package/src/api/mcp.ts +45 -34
- package/src/api/me-web-vitals.ts +35 -0
- package/src/api/me.ts +2 -0
- package/src/api/search/schemas.ts +26 -15
- package/src/api/search.bench.ts +1 -1
- package/src/api/search.ts +54 -17
- package/src/browser/CloudResourceSearch.tsx +640 -702
- package/src/browser/app-approval-vault.ts +19 -7
- package/src/browser/command-bridge.ts +109 -0
- package/src/browser/command-shortcuts.ts +76 -0
- package/src/browser/commands.ts +67 -0
- package/src/browser/navigation-search.ts +48 -0
- package/src/browser/notifications.ts +1 -1
- package/src/browser/resource-picker.tsx +5 -18
- package/src/browser/resource-search-dialog.ts +9 -0
- package/src/browser/resource-search-input.ts +46 -0
- package/src/browser/resource-search-messages.ts +76 -40
- package/src/browser/resource-search.ts +7 -0
- package/src/browser/search-bridge.ts +102 -0
- package/src/browser/search-commands.ts +59 -0
- package/src/browser/search.ts +13 -0
- package/src/browser/spotlight-position.ts +208 -0
- package/src/browser/testing.ts +6 -0
- package/src/browser/web-vitals.ts +25 -0
- package/src/capabilities/claims.ts +179 -0
- package/src/capabilities/client.ts +34 -0
- package/src/capabilities/command-link.ts +16 -0
- package/src/capabilities/executions.ts +298 -0
- package/src/capabilities/migrate.ts +81 -0
- package/src/capabilities/server.ts +116 -35
- package/src/capabilities/stream-body.ts +16 -0
- package/src/capabilities/streams.ts +28 -0
- package/src/cli/admin/ai-quotas.ts +161 -0
- package/src/cli/admin/ai-skills.ts +64 -0
- package/src/cli/admin/ai-usage.ts +53 -30
- package/src/cli/admin/app-credentials.ts +77 -0
- package/src/cli/admin/data.ts +17 -0
- package/src/cli/admin/index.ts +10 -1
- package/src/cli/admin/instance.ts +2 -2
- package/src/cli/admin/linux.ts +4 -2
- package/src/cli/admin/sync.ts +1 -1
- package/src/cli/capabilities.ts +42 -0
- package/src/cli/capability-streams.ts +25 -0
- package/src/cli/index.ts +3 -2
- package/src/config/define-env.ts +97 -0
- package/src/config/env.ts +147 -51
- package/src/config/index.ts +3 -1
- package/src/contracts/app.ts +23 -3
- package/src/contracts/capabilities.ts +75 -5
- package/src/contracts/capability-streams.ts +46 -0
- package/src/contracts/commands.ts +49 -0
- package/src/contracts/index.ts +5 -2
- package/src/contracts/rail-admin.ts +38 -0
- package/src/contracts/rail-preferences.ts +16 -0
- package/src/contracts/registry.ts +5 -27
- package/src/contracts/settings-types.ts +1 -1
- package/src/contracts/shared.ts +18 -5
- package/src/contracts/web-vitals.ts +27 -0
- package/src/desktop/index.ts +1 -0
- package/src/desktop/solid.tsx +1 -1
- package/src/index.ts +8 -6
- package/src/server/index.ts +3 -0
- package/src/server/middleware/auth.ts +3 -2
- package/src/server/middleware/route-template.ts +9 -3
- package/src/server/middleware/runtime.ts +2 -1
- package/src/server/middleware/settings.ts +17 -11
- package/src/server/ratelimit.ts +1 -1
- package/src/server/services/access-revision.ts +10 -0
- package/src/server/services/access.ts +3 -1
- package/src/server/services/index.ts +1 -0
- package/src/services/account-category-policy.ts +9 -0
- package/src/services/account-lifecycle/audit.ts +1 -1
- package/src/services/accounts/app.ts +12 -2
- package/src/services/accounts/email-write.ts +23 -0
- package/src/services/accounts/groups.ts +15 -4
- package/src/services/accounts/identities.ts +249 -0
- package/src/services/accounts/identity-reconciliation.ts +87 -0
- package/src/services/accounts/ipa-data.ts +2 -2
- package/src/services/accounts/local-groups.ts +2 -2
- package/src/services/accounts/notification-sender.ts +12 -2
- package/src/services/accounts/posix.ts +45 -29
- package/src/services/accounts/users.ts +2 -2
- package/src/services/announcements/index.ts +69 -8
- package/src/services/app-approval.ts +11 -10
- package/src/services/audit/index.ts +1 -1
- package/src/services/cache-fill.ts +35 -0
- package/src/services/help/index.ts +109 -0
- package/src/services/help/maintenance.ts +25 -0
- package/src/services/help/store.ts +180 -0
- package/src/services/help/types.ts +46 -0
- package/src/services/identity/invocation-actor.ts +2 -2
- package/src/services/identity/key-config.ts +8 -5
- package/src/services/identity/key-ring.ts +1 -1
- package/src/services/identity/runtime-config.ts +6 -5
- package/src/services/index.ts +15 -0
- package/src/services/ipa/posix.ts +1 -1
- package/src/services/ipa/sync.ts +1 -1
- package/src/services/ipa/users.ts +268 -221
- package/src/services/legal-consent.ts +1 -1
- package/src/services/logging/index.ts +15 -13
- package/src/services/logging/trace.ts +2 -1
- package/src/services/logging/web-vitals.ts +81 -0
- package/src/services/mandates/index.ts +21 -4
- package/src/services/mandates/policy.ts +165 -2
- package/src/services/notifications/batches.ts +125 -57
- package/src/services/notifications/browser.ts +12 -0
- package/src/services/notifications/index.ts +0 -2
- package/src/services/notifications/platform.ts +0 -4
- package/src/services/oauth-tokens.ts +3 -3
- package/src/services/pdf/gotenberg.ts +131 -72
- package/src/services/pdf/index.ts +11 -8
- package/src/services/providers/local/users.ts +25 -16
- package/src/services/public-http.ts +101 -0
- package/src/services/rail-shortcuts.ts +95 -0
- package/src/services/rail-snapshot.ts +53 -0
- package/src/services/request-cache-redis.ts +29 -0
- package/src/services/session/index.ts +15 -2
- package/src/services/session/user.ts +62 -37
- package/src/services/settings/app.ts +5 -1
- package/src/services/settings/core-settings.ts +26 -35
- package/src/services/settings/defaults.ts +5 -0
- package/src/services/settings/index.ts +3 -3
- package/src/services/settings/store.ts +58 -84
- package/src/services/webauthn.ts +1 -1
- package/src/shared/ai-costs.ts +42 -0
- package/src/shared/ai-platform-prompt.ts +1 -1
- package/src/shared/ai-quotas.ts +136 -0
- package/src/shared/ai-usage.ts +6 -16
- package/src/shared/app-presentation.ts +21 -15
- package/src/shared/capability-messages.ts +14 -0
- package/src/shared/help.ts +6 -42
- package/src/shared/index.ts +3 -0
- package/src/shared/markdown/extensions/info-blocks.ts +1 -1
- package/src/ssr/AdminLayout.tsx +7 -5
- package/src/ssr/AdminSidebar.tsx +30 -16
- package/src/ssr/AppLaunchpad.island.tsx +33 -136
- package/src/ssr/AppLaunchpadPanel.tsx +181 -0
- package/src/ssr/BrowserPushRegistration.island.tsx +12 -0
- package/src/ssr/GlobalSearchDialog.tsx +167 -20
- package/src/ssr/GlobalSearchTrigger.island.tsx +33 -22
- package/src/ssr/Layout.tsx +17 -6
- package/src/ssr/LayoutBreadcrumbs.island.tsx +3 -5
- package/src/ssr/LayoutFooter.tsx +1 -1
- package/src/ssr/LayoutHeader.tsx +46 -14
- package/src/ssr/LayoutHelp.tsx +22 -23
- package/src/ssr/{HotkeysHelpRail.island.tsx → LayoutHelpTrigger.island.tsx} +18 -12
- package/src/ssr/LayoutRail.tsx +17 -9
- package/src/ssr/MinimalLayout.tsx +1 -1
- package/src/ssr/MobileNavigation.tsx +71 -0
- package/src/ssr/MobileProfileActions.tsx +49 -0
- package/src/ssr/ProfilePreferences.island.tsx +3 -36
- package/src/ssr/RailApps.island.tsx +2 -2
- package/src/ssr/RailEditor.tsx +17 -2
- package/src/ssr/WorkspaceNavigation.island.tsx +7 -0
- package/src/ssr/WorkspaceNavigationProvider.tsx +16 -0
- package/src/ssr/admin-navigation.ts +11 -1
- package/src/ssr/help.ts +29 -0
- package/src/ssr/islands/SearchBar.tsx +67 -0
- package/src/ssr/islands/index.ts +3 -1
- package/src/ssr/layout-context.ts +2 -2
- package/src/ssr/layout-help-search.ts +15 -0
- package/src/ssr/mobile-menu-history.ts +70 -0
- package/src/ssr/platform-messages.ts +16 -8
- package/src/ssr/profile-actions.ts +42 -0
- package/src/ssr/rail-context.ts +8 -4
- package/src/ssr/rail-messages.ts +2 -0
- package/src/ssr/rail-navigation.ts +3 -3
- package/src/ssr/workspace-navigation.ts +75 -0
- package/src/styles/effects.css +6 -6
- package/src/styles/global.css +54 -0
- package/src/styles/input.css +43 -41
- package/src/styles/resource-search.css +505 -0
- package/src/styles/utilities-feedback.css +13 -0
- package/src/styles/utilities-layout.css +1 -5
- package/src/styles/utilities-navigation.css +3 -39
- package/src/types/ambient.d.ts +5 -0
- package/src/workflows/ai/index.ts +2 -2
- package/src/workflows/ai/runtime.ts +19 -90
- package/src/workflows/ai/store.ts +2 -0
- package/src/workflows/ai/types.ts +6 -82
- package/src/workflows/ai-actions.ts +16 -13
- package/src/workflows/definition.ts +10 -5
- package/src/workflows/store/actions.ts +44 -20
- package/src/workflows/store/index.ts +4 -2
- package/src/workflows/store/runs.ts +36 -0
- package/src/workflows/store/worker-pool.ts +55 -0
- package/src/workflows/store/worker-runtime.ts +90 -0
- package/src/ai/kit-skill.ts +0 -22
- package/src/ai/usage-migrate.ts +0 -81
- package/src/browser/notification-target.ts +0 -27
- package/src/contracts/notification-live.ts +0 -66
- package/src/server/services/freeipa/test-certificates.ts +0 -44
- package/src/services/notifications/live.ts +0 -50
- package/src/services/session/test-fixture.ts +0 -18
- package/src/ssr/BrowserNotifications.island.tsx +0 -135
- package/src/ssr/islands/SearchBar.island.tsx +0 -80
|
@@ -9,21 +9,22 @@ const mergedTranslation = (catalog: AppPresentationCatalog, requestedLocale: str
|
|
|
9
9
|
return canonical ? [[canonical, translation] as const] : [];
|
|
10
10
|
}),
|
|
11
11
|
);
|
|
12
|
-
const overlays = localeFallbackChain(requestedLocale, baseLocale)
|
|
13
|
-
|
|
14
|
-
(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
const overlays = localeFallbackChain(requestedLocale, baseLocale)
|
|
13
|
+
.filter((locale) => locale !== baseLocale)
|
|
14
|
+
.reverse();
|
|
15
|
+
return overlays.reduce<AppPresentationTranslation>((current, locale) => {
|
|
16
|
+
const next = byLocale.get(locale);
|
|
17
|
+
if (!next) return current;
|
|
18
|
+
return {
|
|
19
|
+
...current,
|
|
20
|
+
...next,
|
|
21
|
+
adminGroups: { ...current.adminGroups, ...next.adminGroups },
|
|
22
|
+
adminLinks: { ...current.adminLinks, ...next.adminLinks },
|
|
23
|
+
legalLinks: { ...current.legalLinks, ...next.legalLinks },
|
|
24
|
+
searchLinks: { ...current.searchLinks, ...next.searchLinks },
|
|
25
|
+
searchLinkDescriptions: { ...current.searchLinkDescriptions, ...next.searchLinkDescriptions },
|
|
26
|
+
};
|
|
27
|
+
}, {});
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
/** Resolve only human presentation; stable app identity, routes, icons, and authorization stay untouched. */
|
|
@@ -40,6 +41,11 @@ export const resolveAppPresentation = <T extends AppMeta>(app: T, requestedLocal
|
|
|
40
41
|
label: (group.id && translation.adminGroups?.[group.id]) || group.label,
|
|
41
42
|
links: group.links.map((link) => ({ ...link, label: translation.adminLinks?.[link.href] ?? link.label })),
|
|
42
43
|
})),
|
|
44
|
+
searchLinks: app.searchLinks?.map((link) => ({
|
|
45
|
+
...link,
|
|
46
|
+
label: translation.searchLinks?.[link.href] ?? link.label,
|
|
47
|
+
description: translation.searchLinkDescriptions?.[link.href] ?? link.description,
|
|
48
|
+
})),
|
|
43
49
|
legalLinks: app.legalLinks?.map((link) => ({ ...link, label: translation.legalLinks?.[link.href] ?? link.label })),
|
|
44
50
|
};
|
|
45
51
|
};
|
|
@@ -11,10 +11,17 @@ const catalog = i18n.define({
|
|
|
11
11
|
catalogLimit: ({ max }: { max: number }) => `Capability catalog limit must be between 1 and ${max}`,
|
|
12
12
|
cloudUnavailable: "Cloud is unavailable",
|
|
13
13
|
deadlineExceeded: "The capability deadline was exceeded",
|
|
14
|
+
idempotencyConflict: "This Idempotency-Key was already used with different input",
|
|
15
|
+
idempotencyInProgress:
|
|
16
|
+
"An identical call with this Idempotency-Key is still running; verify the outcome with a Query before retrying",
|
|
14
17
|
idempotencyInvalid: "Idempotency-Key is invalid",
|
|
15
18
|
idempotencyNotAllowed: "This Action does not support idempotent retries; omit Idempotency-Key",
|
|
16
19
|
idempotencyOnlyActions: "Idempotency-Key is only valid for Actions that require it",
|
|
17
20
|
idempotencyRequired: "This Action requires an Idempotency-Key",
|
|
21
|
+
idempotencyResultNotRetained:
|
|
22
|
+
"This Action already succeeded, but its result was too large to retain; read the current state with a Query",
|
|
23
|
+
idempotencyUncertain:
|
|
24
|
+
"An earlier call with this Idempotency-Key ended with an unknown outcome; verify the current state with a Query",
|
|
18
25
|
inputNotSerializable: "Capability input must be JSON-serializable",
|
|
19
26
|
inputSchemaMismatch: "Capability input did not match the registered schema",
|
|
20
27
|
invalidCapabilityError: ({ appId }: { appId: string }) => `App ${appId} returned an invalid capability error`,
|
|
@@ -39,10 +46,17 @@ const catalog = i18n.define({
|
|
|
39
46
|
catalogLimit: ({ max }) => `Das Limit des Capability-Katalogs muss zwischen 1 und ${max} liegen`,
|
|
40
47
|
cloudUnavailable: "Cloud ist nicht verfügbar",
|
|
41
48
|
deadlineExceeded: "Das Zeitlimit der Capability wurde überschritten",
|
|
49
|
+
idempotencyConflict: "Dieser Idempotency-Key wurde bereits mit anderen Eingaben verwendet",
|
|
50
|
+
idempotencyInProgress:
|
|
51
|
+
"Ein identischer Aufruf mit diesem Idempotency-Key läuft noch; prüfe das Ergebnis mit einer Query, bevor du erneut aufrufst",
|
|
42
52
|
idempotencyInvalid: "Der Idempotency-Key ist ungültig",
|
|
43
53
|
idempotencyNotAllowed: "Diese Action unterstützt keine idempotenten Wiederholungen; Idempotency-Key weglassen",
|
|
44
54
|
idempotencyOnlyActions: "Ein Idempotency-Key ist nur für Actions gültig, die ihn voraussetzen",
|
|
45
55
|
idempotencyRequired: "Diese Action benötigt einen Idempotency-Key",
|
|
56
|
+
idempotencyResultNotRetained:
|
|
57
|
+
"Diese Action war bereits erfolgreich, ihr Ergebnis war jedoch zu groß zum Aufbewahren; lies den aktuellen Stand mit einer Query",
|
|
58
|
+
idempotencyUncertain:
|
|
59
|
+
"Ein früherer Aufruf mit diesem Idempotency-Key endete mit unbekanntem Ergebnis; prüfe den aktuellen Stand mit einer Query",
|
|
46
60
|
inputNotSerializable: "Die Capability-Eingabe muss als JSON serialisierbar sein",
|
|
47
61
|
inputSchemaMismatch: "Die Capability-Eingabe entspricht nicht dem registrierten Schema",
|
|
48
62
|
invalidCapabilityError: ({ appId }) => `App ${appId} hat einen ungültigen Capability-Fehler zurückgegeben`,
|
package/src/shared/help.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { localeFallbackChain } from "./locale";
|
|
2
2
|
|
|
3
3
|
export type HelpDocumentManifest = {
|
|
4
|
-
/** Resolved content locale
|
|
4
|
+
/** Resolved content locale on central Help manifests. */
|
|
5
5
|
locale?: string;
|
|
6
6
|
id: string;
|
|
7
7
|
title: string;
|
|
@@ -13,56 +13,20 @@ export type HelpDocumentManifest = {
|
|
|
13
13
|
url: string;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export type HelpManifest = {
|
|
17
|
-
manifestHash: string;
|
|
18
|
-
pageBase: string;
|
|
19
|
-
/** Base language that owns the complete logical article set. Absent on legacy registrations. */
|
|
20
|
-
baseLocale?: string;
|
|
21
|
-
/** Localized metadata variants keyed by canonical BCP 47 locale. */
|
|
22
|
-
documentsByLocale?: Readonly<Record<string, readonly HelpDocumentManifest[]>>;
|
|
23
|
-
documents: readonly HelpDocumentManifest[];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
16
|
export type HelpSearchPayload = {
|
|
27
|
-
/** Resolved request locale.
|
|
28
|
-
locale
|
|
17
|
+
/** Resolved request locale. */
|
|
18
|
+
locale: string;
|
|
29
19
|
ids: string[];
|
|
30
20
|
};
|
|
31
21
|
|
|
32
22
|
export type HelpDocumentPayload = {
|
|
33
|
-
/** Resolved request locale.
|
|
34
|
-
locale
|
|
23
|
+
/** Resolved request locale. */
|
|
24
|
+
locale: string;
|
|
35
25
|
id: string;
|
|
36
26
|
title: string;
|
|
37
27
|
markdown: string;
|
|
38
28
|
html: string;
|
|
39
29
|
};
|
|
40
30
|
|
|
41
|
-
export type ResolvedHelpManifest = Omit<HelpManifest, "documentsByLocale" | "documents"> & {
|
|
42
|
-
locale: string;
|
|
43
|
-
documents: readonly HelpDocumentManifest[];
|
|
44
|
-
};
|
|
45
|
-
|
|
46
31
|
/** Exact locale, then BCP 47 ancestors, then the corpus base locale. */
|
|
47
32
|
export const helpLocaleChain = localeFallbackChain;
|
|
48
|
-
|
|
49
|
-
/** Resolve localized Help metadata per article while preserving the base article set and order. */
|
|
50
|
-
export const resolveHelpManifest = (manifest: HelpManifest, requestedLocale: string): ResolvedHelpManifest => {
|
|
51
|
-
const baseLocale = canonicalLocale(manifest.baseLocale ?? "en") ?? "en";
|
|
52
|
-
const variants = manifest.documentsByLocale ?? {};
|
|
53
|
-
const chain = helpLocaleChain(requestedLocale, baseLocale);
|
|
54
|
-
const selectedLocale = chain.find((locale) => locale === baseLocale || variants[locale] !== undefined) ?? baseLocale;
|
|
55
|
-
const overlays = [...chain.slice(0, chain.indexOf(baseLocale)), baseLocale].reverse();
|
|
56
|
-
const byId = new Map(manifest.documents.map((document) => [document.id, document]));
|
|
57
|
-
for (const locale of overlays) {
|
|
58
|
-
if (locale === baseLocale) continue;
|
|
59
|
-
for (const document of variants[locale] ?? []) byId.set(document.id, { ...byId.get(document.id), ...document });
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
manifestHash: manifest.manifestHash,
|
|
63
|
-
pageBase: manifest.pageBase,
|
|
64
|
-
baseLocale,
|
|
65
|
-
locale: selectedLocale,
|
|
66
|
-
documents: manifest.documents.map((document) => ({ ...(byId.get(document.id) ?? document), locale: selectedLocale })),
|
|
67
|
-
};
|
|
68
|
-
};
|
package/src/shared/index.ts
CHANGED
|
@@ -11,8 +11,11 @@ export {
|
|
|
11
11
|
} from "./account-action-notice";
|
|
12
12
|
export * from "./account-display";
|
|
13
13
|
export * from "./account-session";
|
|
14
|
+
export * from "./ai-costs";
|
|
14
15
|
export type { AiPromptContextInput, AiToolPromptHint } from "./ai-platform-prompt";
|
|
15
16
|
export { AI_PLATFORM_PROMPT_TEMPLATE, aiPromptContext, renderAiPlatformPrompt } from "./ai-platform-prompt";
|
|
17
|
+
export type { AiChatQuotaSnapshot } from "./ai-quotas";
|
|
18
|
+
export * from "./ai-quotas";
|
|
16
19
|
export {
|
|
17
20
|
AI_USAGE_RANGES,
|
|
18
21
|
AI_USAGE_REASONS,
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* Supported types: note, info, success, warning, danger
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import type { MarkedExtension, Tokens } from "marked";
|
|
17
16
|
import { NOTICE_CARD_CLASSES, NOTICE_CARD_ICONS, type NoticeTone } from "@k2b/ui";
|
|
17
|
+
import type { MarkedExtension, Tokens } from "marked";
|
|
18
18
|
import { escapeHtml } from "../shared";
|
|
19
19
|
|
|
20
20
|
type BlockType = "note" | "info" | "success" | "warning" | "danger";
|
package/src/ssr/AdminLayout.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AppWorkspace } from "@k2b/ui";
|
|
2
2
|
import type { JSX } from "solid-js/jsx-runtime";
|
|
3
|
-
import type {
|
|
3
|
+
import type { RailSnapshot } from "../contracts/rail-preferences";
|
|
4
4
|
import { getLocale } from "../server/locale";
|
|
5
5
|
import type { LayoutAnnouncementsState } from "../server/middleware/settings";
|
|
6
6
|
import AdminSidebar from "./AdminSidebar";
|
|
@@ -10,7 +10,7 @@ import { getLocalizedRuntimeContext, type RuntimeContext } from "./runtime";
|
|
|
10
10
|
|
|
11
11
|
type Breadcrumb = { title: string; href?: string };
|
|
12
12
|
type AdminLayoutContext = {
|
|
13
|
-
get(key: "railPreferences"):
|
|
13
|
+
get(key: "railPreferences"): RailSnapshot | undefined;
|
|
14
14
|
get(key: "user"): any;
|
|
15
15
|
get(key: "page"): any;
|
|
16
16
|
get(key: "runtime"): RuntimeContext;
|
|
@@ -25,7 +25,9 @@ type Props = {
|
|
|
25
25
|
/** Disable when a bounded child such as SettingsPage owns scrolling. */
|
|
26
26
|
scroll?: boolean;
|
|
27
27
|
};
|
|
28
|
-
export default function AdminLayout(
|
|
28
|
+
export default function AdminLayout(props: Props) {
|
|
29
|
+
// Keep children lazy so Layout installs the request locale before rendering them.
|
|
30
|
+
const { c, title, scroll = true } = props;
|
|
29
31
|
const locale = getLocale(c);
|
|
30
32
|
const t = platformMessages.resolve([locale]).t;
|
|
31
33
|
const url = new URL(c.req.raw.url);
|
|
@@ -40,11 +42,11 @@ export default function AdminLayout({ children, c, title, scroll = true }: Props
|
|
|
40
42
|
}
|
|
41
43
|
return (
|
|
42
44
|
<Layout c={c} fullWidth fullPage title={breadcrumbs}>
|
|
43
|
-
<AppWorkspace class="min-h-0 flex-1" resizable={false}>
|
|
45
|
+
<AppWorkspace mobileSurface="flush" class="min-h-0 flex-1" resizable={false}>
|
|
44
46
|
<AdminSidebar currentPath={currentPath} apps={runtime.apps} />
|
|
45
47
|
<AppWorkspace.Content>
|
|
46
48
|
<AppWorkspace.Main scroll={scroll} class={scroll ? "p-[var(--ui-space-shell)]" : undefined}>
|
|
47
|
-
{children}
|
|
49
|
+
{props.children}
|
|
48
50
|
</AppWorkspace.Main>
|
|
49
51
|
</AppWorkspace.Content>
|
|
50
52
|
</AppWorkspace>
|
package/src/ssr/AdminSidebar.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AppWorkspace, useLocale } from "@k2b/ui";
|
|
2
2
|
import { activeAdminHref } from "./admin-active-link";
|
|
3
3
|
import { type AdminLink, buildAdminGroups } from "./admin-navigation";
|
|
4
|
-
import type { RuntimeContext } from "./runtime";
|
|
5
4
|
import { platformMessages } from "./platform-messages";
|
|
5
|
+
import type { RuntimeContext } from "./runtime";
|
|
6
|
+
import WorkspaceNavigation from "./WorkspaceNavigation.island";
|
|
6
7
|
|
|
7
8
|
const AdminNavigation = (props: { currentPath: string; groups: ReturnType<typeof buildAdminGroups> }) => {
|
|
8
9
|
const activeHref = activeAdminHref(
|
|
@@ -31,20 +32,33 @@ export default function AdminSidebar({ currentPath, apps }: { currentPath: strin
|
|
|
31
32
|
const groups = () => buildAdminGroups(apps, locale());
|
|
32
33
|
|
|
33
34
|
return (
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
<>
|
|
36
|
+
<WorkspaceNavigation
|
|
37
|
+
label={t().admin}
|
|
38
|
+
items={groups().map((group) => ({
|
|
39
|
+
id: group.label,
|
|
40
|
+
label: group.label,
|
|
41
|
+
children: group.links.map((link) => ({
|
|
42
|
+
id: link.href,
|
|
43
|
+
label: link.label,
|
|
44
|
+
href: link.href,
|
|
45
|
+
icon: `ti ${link.icon}`,
|
|
46
|
+
active:
|
|
47
|
+
link.href ===
|
|
48
|
+
activeAdminHref(
|
|
49
|
+
currentPath,
|
|
50
|
+
groups().flatMap((entry) => entry.links.map((entry) => entry.href)),
|
|
51
|
+
),
|
|
52
|
+
})),
|
|
53
|
+
}))}
|
|
54
|
+
/>
|
|
55
|
+
<AppWorkspace.Sidebar resizable={false}>
|
|
56
|
+
<AppWorkspace.SidebarDesktop>
|
|
57
|
+
<AppWorkspace.SidebarBody scrollPreserveKey="admin-sidebar">
|
|
58
|
+
<AdminNavigation currentPath={currentPath} groups={groups()} />
|
|
59
|
+
</AppWorkspace.SidebarBody>
|
|
60
|
+
</AppWorkspace.SidebarDesktop>
|
|
61
|
+
</AppWorkspace.Sidebar>
|
|
62
|
+
</>
|
|
49
63
|
);
|
|
50
64
|
}
|
|
@@ -1,42 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { platformMessages } from "./platform-messages";
|
|
4
|
-
import { openRailEditor } from "./RailEditor";
|
|
5
|
-
import { readRailContext } from "./rail-context";
|
|
6
|
-
import { railMessages } from "./rail-messages";
|
|
7
|
-
import { projectRailNavigation } from "./rail-navigation";
|
|
8
|
-
|
|
9
|
-
export type AppLaunchpadApp = {
|
|
10
|
-
id: string;
|
|
11
|
-
iconClass: string;
|
|
12
|
-
label: string;
|
|
13
|
-
href: string;
|
|
14
|
-
description?: string;
|
|
15
|
-
accent?: string;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export type AppLaunchpadLegalLink = {
|
|
19
|
-
label: string;
|
|
20
|
-
href: string;
|
|
21
|
-
icon?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type AppLaunchpadContext = {
|
|
25
|
-
apps: AppLaunchpadApp[];
|
|
26
|
-
legalLinks: AppLaunchpadLegalLink[];
|
|
27
|
-
};
|
|
1
|
+
import { type AppLaunchpadApp, type AppLaunchpadContext, type AppLaunchpadLegalLink, AppLaunchpadPanel } from "./AppLaunchpadPanel";
|
|
2
|
+
import { openCloudMobileMenu } from "./MobileNavigation";
|
|
28
3
|
|
|
29
|
-
type
|
|
4
|
+
export type { AppLaunchpadApp, AppLaunchpadLegalLink } from "./AppLaunchpadPanel";
|
|
30
5
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{ from: "#7c3aed" },
|
|
35
|
-
{ from: "#d97706" },
|
|
36
|
-
{ from: "#e11d48" },
|
|
37
|
-
{ from: "#0891b2" },
|
|
38
|
-
{ from: "#52525b" },
|
|
39
|
-
];
|
|
6
|
+
import { dialogCore, IconButton, Tooltip, useLocale } from "@k2b/ui";
|
|
7
|
+
import { createEffect } from "solid-js";
|
|
8
|
+
import { platformMessages } from "./platform-messages";
|
|
40
9
|
|
|
41
10
|
declare global {
|
|
42
11
|
interface Window {
|
|
@@ -47,17 +16,6 @@ declare global {
|
|
|
47
16
|
}
|
|
48
17
|
}
|
|
49
18
|
|
|
50
|
-
const paletteForId = (id: string) => {
|
|
51
|
-
let hash = 0;
|
|
52
|
-
for (let i = 0; i < id.length; i++) hash = (hash + id.charCodeAt(i)) % appIconPalette.length;
|
|
53
|
-
return appIconPalette[hash] ?? appIconPalette[0];
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const appIconStyle = (app: AppLaunchpadApp) => {
|
|
57
|
-
const tone = /^#[0-9a-f]{6}$/i.test(app.accent ?? "") ? app.accent! : paletteForId(app.id).from;
|
|
58
|
-
return `--app-icon-color:${tone}`;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
19
|
const readEmbeddedContext = (): AppLaunchpadContext | undefined => {
|
|
62
20
|
if (typeof document === "undefined") return undefined;
|
|
63
21
|
const element = document.getElementById("cloud-app-launchpad-data");
|
|
@@ -69,6 +27,7 @@ const readEmbeddedContext = (): AppLaunchpadContext | undefined => {
|
|
|
69
27
|
if (!Array.isArray(parsed.apps)) return undefined;
|
|
70
28
|
return {
|
|
71
29
|
apps: parsed.apps,
|
|
30
|
+
profile: parsed.profile?.name && (parsed.profile.theme === "dark" || parsed.profile.theme === "light") ? parsed.profile : undefined,
|
|
72
31
|
legalLinks: Array.isArray(parsed.legalLinks) ? parsed.legalLinks : [],
|
|
73
32
|
};
|
|
74
33
|
} catch {
|
|
@@ -76,99 +35,28 @@ const readEmbeddedContext = (): AppLaunchpadContext | undefined => {
|
|
|
76
35
|
}
|
|
77
36
|
};
|
|
78
37
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<ScrollArea class="launchpad-panel mx-auto max-h-[min(86vh,var(--ui-dialog-available-height))] w-[var(--ui-dialog-available-width)] max-w-[var(--ui-dialog-available-width)] overscroll-contain p-4 text-primary sm:w-fit sm:p-6 md:p-7 dark:text-white">
|
|
86
|
-
<Show when={rail}>
|
|
87
|
-
<div class="mb-2 flex justify-end">
|
|
88
|
-
<IconButton
|
|
89
|
-
variant="ghost"
|
|
90
|
-
size="sm"
|
|
91
|
-
label={t().customize}
|
|
92
|
-
tooltip={t().customize}
|
|
93
|
-
tooltipDelay={0}
|
|
94
|
-
onClick={() => {
|
|
95
|
-
props.close();
|
|
96
|
-
openRailEditor(locale());
|
|
97
|
-
}}
|
|
98
|
-
>
|
|
99
|
-
<i class="ti ti-adjustments-horizontal" aria-hidden="true" />
|
|
100
|
-
</IconButton>
|
|
101
|
-
</div>
|
|
102
|
-
</Show>
|
|
103
|
-
<Show when={shortcuts().length > 0}>
|
|
104
|
-
<section class="mb-5 flex flex-col gap-3" aria-label={t().shortcuts}>
|
|
105
|
-
<h3 class="text-center text-sm font-medium">{t().shortcuts}</h3>
|
|
106
|
-
<div class="flex flex-wrap justify-center gap-2">
|
|
107
|
-
<For each={shortcuts()}>
|
|
108
|
-
{(shortcut) => (
|
|
109
|
-
<a
|
|
110
|
-
href={shortcut.href}
|
|
111
|
-
class="inline-flex items-center gap-2 rounded-lg border border-[var(--ui-border)] px-3 py-2 text-sm"
|
|
112
|
-
>
|
|
113
|
-
<i class={shortcut.iconClass} aria-hidden="true" />
|
|
114
|
-
{shortcut.label}
|
|
115
|
-
</a>
|
|
116
|
-
)}
|
|
117
|
-
</For>
|
|
118
|
-
</div>
|
|
119
|
-
</section>
|
|
120
|
-
</Show>
|
|
121
|
-
<div class="flex flex-wrap justify-center gap-x-4 gap-y-4 sm:gap-x-7 sm:gap-y-6">
|
|
122
|
-
<For each={props.apps}>
|
|
123
|
-
{(app) => (
|
|
124
|
-
<a
|
|
125
|
-
href={app.href}
|
|
126
|
-
class="group flex w-[4.75rem] min-w-0 flex-col items-center gap-1.5 rounded-2xl p-1 text-center outline-none focus-visible:ring-2 focus-visible:ring-white/60 sm:w-[6.25rem] sm:gap-2 sm:p-2"
|
|
127
|
-
>
|
|
128
|
-
<span
|
|
129
|
-
class="app-icon grid h-12 w-12 place-items-center rounded-[0.95rem] text-[1.25rem] sm:h-16 sm:w-16 sm:rounded-[1.25rem] sm:text-[1.7rem]"
|
|
130
|
-
style={appIconStyle(app)}
|
|
131
|
-
>
|
|
132
|
-
<i class={app.iconClass} />
|
|
133
|
-
</span>
|
|
134
|
-
<span class="max-w-full truncate text-[11px] font-medium text-primary sm:text-xs dark:text-white">{app.label}</span>
|
|
135
|
-
</a>
|
|
136
|
-
)}
|
|
137
|
-
</For>
|
|
138
|
-
</div>
|
|
139
|
-
<Show when={props.legalLinks.length > 0}>
|
|
140
|
-
<div class="mt-7 flex flex-wrap justify-center text-[11px] text-dimmed dark:text-white/56">
|
|
141
|
-
<For each={props.legalLinks}>
|
|
142
|
-
{(link) => (
|
|
143
|
-
<a
|
|
144
|
-
href={link.href}
|
|
145
|
-
class="inline-flex items-center gap-1.5 rounded-md px-2 py-1 transition-colors hover:text-primary dark:hover:text-white"
|
|
146
|
-
>
|
|
147
|
-
<i class={link.icon ?? "ti ti-file-text"} />
|
|
148
|
-
{link.label}
|
|
149
|
-
</a>
|
|
150
|
-
)}
|
|
151
|
-
</For>
|
|
152
|
-
</div>
|
|
153
|
-
</Show>
|
|
154
|
-
</ScrollArea>
|
|
155
|
-
);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export function setAppLaunchpadContext(apps: AppLaunchpadApp[], legalLinks: AppLaunchpadLegalLink[] = []) {
|
|
38
|
+
export function setAppLaunchpadContext(
|
|
39
|
+
apps: AppLaunchpadApp[],
|
|
40
|
+
legalLinks: AppLaunchpadLegalLink[] = [],
|
|
41
|
+
profile?: AppLaunchpadContext["profile"],
|
|
42
|
+
) {
|
|
159
43
|
if (typeof window === "undefined") return;
|
|
160
|
-
window.__cloudAppLaunchpad = { apps, legalLinks };
|
|
44
|
+
window.__cloudAppLaunchpad = { apps, legalLinks, profile };
|
|
161
45
|
window.cloud ??= {};
|
|
162
46
|
window.cloud.openAppLaunchpad = () => {
|
|
163
47
|
openAppLaunchpad();
|
|
164
48
|
};
|
|
165
49
|
}
|
|
166
50
|
|
|
167
|
-
export function openAppLaunchpad(apps?: AppLaunchpadApp[], legalLinks?: AppLaunchpadLegalLink[]) {
|
|
51
|
+
export function openAppLaunchpad(apps?: AppLaunchpadApp[], legalLinks?: AppLaunchpadLegalLink[], profile?: AppLaunchpadContext["profile"]) {
|
|
168
52
|
if (typeof window === "undefined") return;
|
|
169
|
-
const context = apps ? { apps, legalLinks: legalLinks ?? [] } : (window.__cloudAppLaunchpad ?? readEmbeddedContext());
|
|
170
|
-
if (!context
|
|
53
|
+
const context = apps ? { apps, legalLinks: legalLinks ?? [], profile } : (window.__cloudAppLaunchpad ?? readEmbeddedContext());
|
|
54
|
+
if (!context) return;
|
|
171
55
|
window.__cloudAppLaunchpad = context;
|
|
56
|
+
if (window.matchMedia("(max-width: 1023px)").matches) {
|
|
57
|
+
void openCloudMobileMenu(context);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
172
60
|
void dialogCore.open<void>((close) => <AppLaunchpadPanel apps={context.apps} legalLinks={context.legalLinks} close={close} />, {
|
|
173
61
|
panelClassName: "k2b-dialog k2b-dialog--large is-bare",
|
|
174
62
|
contentClassName: "k2b-dialog__viewport is-bare",
|
|
@@ -178,7 +66,7 @@ export function openAppLaunchpad(apps?: AppLaunchpadApp[], legalLinks?: AppLaunc
|
|
|
178
66
|
|
|
179
67
|
export function AppLaunchpadProvider(props: AppLaunchpadContext) {
|
|
180
68
|
createEffect(() => {
|
|
181
|
-
setAppLaunchpadContext(props.apps, props.legalLinks);
|
|
69
|
+
setAppLaunchpadContext(props.apps, props.legalLinks, props.profile);
|
|
182
70
|
});
|
|
183
71
|
|
|
184
72
|
return <span class="hidden" data-cloud-app-launchpad-provider />;
|
|
@@ -187,13 +75,14 @@ export function AppLaunchpadProvider(props: AppLaunchpadContext) {
|
|
|
187
75
|
export function AppLaunchpadButton(props: AppLaunchpadContext & { variant: "rail" | "header" | "menu"; label?: string }) {
|
|
188
76
|
const locale = useLocale();
|
|
189
77
|
const t = () => platformMessages.resolve([locale()]).t;
|
|
190
|
-
const open = () => openAppLaunchpad(props.apps, props.legalLinks);
|
|
78
|
+
const open = () => openAppLaunchpad(props.apps, props.legalLinks, props.profile);
|
|
191
79
|
|
|
192
80
|
if (props.variant === "rail") {
|
|
193
81
|
return (
|
|
194
82
|
<Tooltip.Trigger
|
|
195
83
|
type="button"
|
|
196
84
|
class="rail-item shrink-0"
|
|
85
|
+
data-cloud-launchpad
|
|
197
86
|
content={props.label ?? t().apps}
|
|
198
87
|
placement="right"
|
|
199
88
|
delay={0}
|
|
@@ -227,10 +116,18 @@ export function AppLaunchpadButton(props: AppLaunchpadContext & { variant: "rail
|
|
|
227
116
|
|
|
228
117
|
export function AppLaunchpad(props: AppLaunchpadContext & { variant?: "provider" | "rail" | "header" | "menu"; label?: string }) {
|
|
229
118
|
if (!props.variant || props.variant === "provider") {
|
|
230
|
-
return <AppLaunchpadProvider apps={props.apps} legalLinks={props.legalLinks} />;
|
|
119
|
+
return <AppLaunchpadProvider apps={props.apps} legalLinks={props.legalLinks} profile={props.profile} />;
|
|
231
120
|
}
|
|
232
121
|
|
|
233
|
-
return
|
|
122
|
+
return (
|
|
123
|
+
<AppLaunchpadButton
|
|
124
|
+
apps={props.apps}
|
|
125
|
+
legalLinks={props.legalLinks}
|
|
126
|
+
profile={props.profile}
|
|
127
|
+
variant={props.variant}
|
|
128
|
+
label={props.label}
|
|
129
|
+
/>
|
|
130
|
+
);
|
|
234
131
|
}
|
|
235
132
|
|
|
236
133
|
export default AppLaunchpad;
|