@scalar/api-client 3.5.1 → 3.6.1
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/CHANGELOG.md +24 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/style.css +3933 -4768
- package/dist/styles/tailwind.config.css +20 -0
- package/dist/styles/utilities.css +45 -0
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.d.ts.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.js.map +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js +1 -1
- package/dist/v2/blocks/operation-code-sample/components/OperationCodeSample.vue.script.js.map +1 -1
- package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
- package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts +1 -1
- package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
- package/dist/v2/constants.js +1 -1
- package/dist/v2/features/app/App.vue.d.ts +15 -31
- package/dist/v2/features/app/App.vue.d.ts.map +1 -1
- package/dist/v2/features/app/App.vue.js.map +1 -1
- package/dist/v2/features/app/App.vue.script.js +131 -50
- package/dist/v2/features/app/App.vue.script.js.map +1 -1
- package/dist/v2/features/app/app-state.d.ts +10 -14
- package/dist/v2/features/app/app-state.d.ts.map +1 -1
- package/dist/v2/features/app/app-state.js +53 -21
- package/dist/v2/features/app/app-state.js.map +1 -1
- package/dist/v2/features/app/components/AppHeader.vue.d.ts.map +1 -1
- package/dist/v2/features/app/components/AppHeader.vue.js.map +1 -1
- package/dist/v2/features/app/components/AppHeader.vue.script.js +4 -3
- package/dist/v2/features/app/components/AppHeader.vue.script.js.map +1 -1
- package/dist/v2/features/app/components/AppHeaderActions.vue.d.ts +32 -0
- package/dist/v2/features/app/components/AppHeaderActions.vue.d.ts.map +1 -0
- package/dist/v2/features/app/components/AppHeaderActions.vue.js +7 -0
- package/dist/v2/features/app/components/AppHeaderActions.vue.js.map +1 -0
- package/dist/v2/features/app/components/AppHeaderActions.vue.script.js +172 -0
- package/dist/v2/features/app/components/AppHeaderActions.vue.script.js.map +1 -0
- package/dist/v2/features/app/components/AppSidebar.vue.d.ts +2 -5
- package/dist/v2/features/app/components/AppSidebar.vue.d.ts.map +1 -1
- package/dist/v2/features/app/components/AppSidebar.vue.js +1 -1
- package/dist/v2/features/app/components/AppSidebar.vue.js.map +1 -1
- package/dist/v2/features/app/components/AppSidebar.vue.script.js +4 -9
- package/dist/v2/features/app/components/AppSidebar.vue.script.js.map +1 -1
- package/dist/v2/features/app/components/DesktopTabs.vue.d.ts.map +1 -1
- package/dist/v2/features/app/components/DesktopTabs.vue.js.map +1 -1
- package/dist/v2/features/app/components/DesktopTabs.vue.script.js +2 -2
- package/dist/v2/features/app/components/DesktopTabs.vue.script.js.map +1 -1
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.d.ts +1 -2
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.d.ts.map +1 -1
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.js +1 -1
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.js.map +1 -1
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.script.js +4 -35
- package/dist/v2/features/app/components/DocumentBreadcrumb.vue.script.js.map +1 -1
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.d.ts +1 -1
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.d.ts.map +1 -1
- package/dist/v2/features/app/components/PublishDocumentModal.vue.d.ts +77 -0
- package/dist/v2/features/app/components/PublishDocumentModal.vue.d.ts.map +1 -0
- package/dist/v2/features/app/components/PublishDocumentModal.vue.js +7 -0
- package/dist/v2/features/app/components/PublishDocumentModal.vue.js.map +1 -0
- package/dist/v2/features/app/components/PublishDocumentModal.vue.script.js +209 -0
- package/dist/v2/features/app/components/PublishDocumentModal.vue.script.js.map +1 -0
- package/dist/v2/features/app/components/SyncConflictResolutionEditor.vue.d.ts.map +1 -0
- package/dist/v2/features/{collection → app}/components/SyncConflictResolutionEditor.vue.js +2 -2
- package/dist/v2/features/app/components/SyncConflictResolutionEditor.vue.js.map +1 -0
- package/dist/v2/features/{collection → app}/components/SyncConflictResolutionEditor.vue.script.js +1 -1
- package/dist/v2/features/{collection/components/SyncConflictResolutionEditor.vue.js.map → app/components/SyncConflictResolutionEditor.vue.script.js.map} +1 -1
- package/dist/v2/features/app/helpers/check-version-conflict.d.ts +8 -5
- package/dist/v2/features/app/helpers/check-version-conflict.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/check-version-conflict.js +10 -7
- package/dist/v2/features/app/helpers/check-version-conflict.js.map +1 -1
- package/dist/v2/features/app/helpers/create-api-client-app.d.ts +8 -5
- package/dist/v2/features/app/helpers/create-api-client-app.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/create-api-client-app.js +2 -2
- package/dist/v2/features/app/helpers/create-api-client-app.js.map +1 -1
- package/dist/v2/features/app/helpers/load-registry-document.d.ts +1 -10
- package/dist/v2/features/app/helpers/load-registry-document.d.ts.map +1 -1
- package/dist/v2/features/app/helpers/load-registry-document.js +6 -5
- package/dist/v2/features/app/helpers/load-registry-document.js.map +1 -1
- package/dist/v2/features/app/helpers/registry-error-messages.d.ts +23 -0
- package/dist/v2/features/app/helpers/registry-error-messages.d.ts.map +1 -0
- package/dist/v2/features/app/helpers/registry-error-messages.js +63 -0
- package/dist/v2/features/app/helpers/registry-error-messages.js.map +1 -0
- package/dist/v2/features/app/hooks/use-active-document-version.d.ts +2 -1
- package/dist/v2/features/app/hooks/use-active-document-version.d.ts.map +1 -1
- package/dist/v2/features/app/hooks/use-active-document-version.js.map +1 -1
- package/dist/v2/features/app/hooks/use-document-sync.d.ts +126 -0
- package/dist/v2/features/app/hooks/use-document-sync.d.ts.map +1 -0
- package/dist/v2/features/app/hooks/use-document-sync.js +448 -0
- package/dist/v2/features/app/hooks/use-document-sync.js.map +1 -0
- package/dist/v2/features/app/hooks/use-network-status.d.ts +29 -0
- package/dist/v2/features/app/hooks/use-network-status.d.ts.map +1 -0
- package/dist/v2/features/app/hooks/use-network-status.js +58 -0
- package/dist/v2/features/app/hooks/use-network-status.js.map +1 -0
- package/dist/v2/features/app/hooks/use-sidebar-documents.d.ts +1 -25
- package/dist/v2/features/app/hooks/use-sidebar-documents.d.ts.map +1 -1
- package/dist/v2/features/app/hooks/use-sidebar-documents.js.map +1 -1
- package/dist/v2/features/app/index.d.ts +1 -1
- package/dist/v2/features/app/index.d.ts.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.d.ts.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.js.map +1 -1
- package/dist/v2/features/collection/DocumentCollection.vue.script.js +43 -277
- package/dist/v2/features/collection/DocumentCollection.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteExample.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteExample.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteExample.vue.script.js +35 -17
- package/dist/v2/features/command-palette/components/CommandPaletteExample.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.script.js +15 -13
- package/dist/v2/features/command-palette/components/CommandPaletteImport.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportCurl.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportCurl.vue.js +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportCurl.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteImportCurl.vue.script.js +51 -39
- package/dist/v2/features/command-palette/components/CommandPaletteImportCurl.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteOpenApiDocument.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteOpenApiDocument.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteOpenApiDocument.vue.script.js +30 -14
- package/dist/v2/features/command-palette/components/CommandPaletteOpenApiDocument.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteRequest.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteRequest.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteRequest.vue.script.js +44 -42
- package/dist/v2/features/command-palette/components/CommandPaletteRequest.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteTag.vue.d.ts.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteTag.vue.js.map +1 -1
- package/dist/v2/features/command-palette/components/CommandPaletteTag.vue.script.js +33 -17
- package/dist/v2/features/command-palette/components/CommandPaletteTag.vue.script.js.map +1 -1
- package/dist/v2/features/command-palette/helpers/load-document-from-source.d.ts.map +1 -1
- package/dist/v2/features/command-palette/helpers/load-document-from-source.js +3 -2
- package/dist/v2/features/command-palette/helpers/load-document-from-source.js.map +1 -1
- package/dist/v2/features/editor/hooks/use-three-way-merge-editor.d.ts.map +1 -1
- package/dist/v2/features/editor/hooks/use-three-way-merge-editor.js +5 -5
- package/dist/v2/features/editor/hooks/use-three-way-merge-editor.js.map +1 -1
- package/dist/v2/helpers/is-url.d.ts.map +1 -1
- package/dist/v2/helpers/is-url.js +2 -1
- package/dist/v2/helpers/is-url.js.map +1 -1
- package/dist/v2/types/configuration.d.ts +273 -7
- package/dist/v2/types/configuration.d.ts.map +1 -1
- package/dist/vue-styles.css +1389 -0
- package/package.json +20 -14
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.js +0 -7
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.js.map +0 -1
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.script.js +0 -51
- package/dist/v2/features/app/components/DocumentSyncIndicator.vue.script.js.map +0 -1
- package/dist/v2/features/collection/components/SyncConflictResolutionEditor.vue.d.ts.map +0 -1
- package/dist/v2/features/collection/components/SyncConflictResolutionEditor.vue.script.js.map +0 -1
- /package/dist/v2/features/{collection → app}/components/SyncConflictResolutionEditor.vue.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/app/App.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"App.vue.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/app/App.vue"],"names":[],"mappings":"AA+bA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAkB7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+DAA+D,CAAA;AAKxG,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C;;;;GAIG;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AAGzC,QAAA,MAAM,YAAY;YAER,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC;cAC5B,YAAY,EAAE;iBACX,MAAM,QAAQ;4BACH,MAAM,mBAAmB;IACjD;;;;;;;OAOG;eACQ,eAAe;;;;YAZlB,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC;cAC5B,YAAY,EAAE;iBACX,MAAM,QAAQ;4BACH,MAAM,mBAAmB;IACjD;;;;;;;OAOG;eACQ,eAAe;;IAsB1B;;;;;;;;;OASG;oBACa,CAAC,OAAO,EAAE;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO;IAClE;;;;;OAKG;0BACmB,MAAM,OAAO;IACnC;;;OAGG;mBACY,MAAM,OAAO;EAslB1B,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.vue.js","names":[],"sources":["../../../../src/v2/features/app/App.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Main entry point for the API client for electron and web.\n *\n * This component handles all events and store business logic for the application.\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport {\n ScalarTeleportRoot,\n useModal,\n type ModalState,\n} from '@scalar/components'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport { extensions } from '@scalar/workspace-store/schemas/extensions'\nimport { computed, onBeforeUnmount, toValue, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport { SidebarToggle } from '@/v2/components/sidebar'\nimport AppHeader from '@/v2/features/app/components/AppHeader.vue'\nimport AppSidebar from '@/v2/features/app/components/AppSidebar.vue'\nimport CreateWorkspaceModal from '@/v2/features/app/components/CreateWorkspaceModal.vue'\nimport DocumentBreadcrumb from '@/v2/features/app/components/DocumentBreadcrumb.vue'\nimport DocumentSyncIndicator from '@/v2/features/app/components/DocumentSyncIndicator.vue'\nimport SplashScreen from '@/v2/features/app/components/SplashScreen.vue'\nimport type { RouteProps } from '@/v2/features/app/helpers/routes'\nimport { useDocumentWatcher } from '@/v2/features/app/hooks/use-document-watcher'\nimport type { RegistryDocumentsState } from '@/v2/features/app/hooks/use-sidebar-documents'\nimport type { CommandPaletteState } from '@/v2/features/command-palette/hooks/use-command-palette-state'\nimport TheCommandPalette from '@/v2/features/command-palette/TheCommandPalette.vue'\nimport { useMonacoEditorConfiguration } from '@/v2/features/editor'\nimport { useColorMode } from '@/v2/hooks/use-color-mode'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport type { ImportDocumentFromRegistry } from '@/v2/types/configuration'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport type { AppState } from './app-state'\nimport DesktopTabs from './components/DesktopTabs.vue'\n\nconst {\n layout,\n plugins = [],\n getAppState,\n getCommandPaletteState,\n fetchRegistryDocument,\n registryDocuments = { status: 'success', documents: [] },\n} = defineProps<{\n layout: Exclude<ClientLayout, 'modal'>\n plugins?: ClientPlugin[]\n getAppState: () => AppState\n getCommandPaletteState: () => CommandPaletteState\n /** Fetches the full document from registry by meta. Passed through to route props for sync. */\n fetchRegistryDocument?: ImportDocumentFromRegistry\n /**\n * The list of all available registry documents, with a loading status so the\n * sidebar can render skeleton placeholders until the real list is ready.\n */\n registryDocuments?: RegistryDocumentsState\n}>()\n\ndefineSlots<{\n /**\n * Slot for customizing the create workspace modal.\n * This slot is used to render custom actions or components within the create workspace modal.\n */\n 'create-workspace'?: (payload: { state: ModalState }) => unknown\n /**\n * Replaces the Scalar logo inside the header menu button. Typically used by\n * team-aware consumers (e.g. Scalar Cloud) to render a team avatar so the\n * left-most chrome reads as \"this team's workspace\" rather than the\n * generic Scalar wordmark.\n *\n * Receives `isTeamWorkspace` so consumers can opt into rendering a team\n * image only when the active workspace actually belongs to a team, while\n * keeping the default Scalar logo for local workspaces.\n */\n 'header-logo'?: (payload: { isTeamWorkspace: boolean }) => unknown\n /**\n * Slot for customizing the menu items section of the app header.\n * Defaults to a workspace picker bound to the current app state. Overriding this slot\n * replaces the default picker entirely, so the consumer is responsible for rendering\n * any workspace switcher (or other menu content) they need.\n */\n 'header-menu-items'?: () => unknown\n /**\n * Slot rendered at the trailing edge of the header, immediately before the\n * `header-end` slot. Use this for context-specific action buttons (for\n * example a \"Save\" button) so they sit next to the document chrome rather\n * than getting mixed in with the user / account controls in `header-end`.\n *\n * When both this slot and `header-end` are provided, a vertical divider is\n * inserted between them so the two groups read as visually distinct\n * clusters.\n */\n 'header-actions'?: () => unknown\n /**\n * Slot for customizing the end section of the app header.\n * Typically used for user menus, action buttons, or other trailing controls.\n */\n 'header-end'?: () => unknown\n}>()\n\ndefineExpose({\n openCreateWorkspace: () => createWorkspaceModalState.show(),\n})\n\nconst app = getAppState()\nconst paletteState = getCommandPaletteState()\n\n/** Expose workspace store to window for debugging purposes. */\nif (typeof window !== 'undefined') {\n window.dataDumpWorkspace = () => app.store.value\n window.dumpAppState = () => app\n}\n\n/** Call lifecycle hooks on plugins and subscribe to event bus events */\nconst pluginUnsubscribes: (() => void)[] = []\n\nfor (const plugin of plugins) {\n plugin.lifecycle?.onInit?.({ config: { telemetry: app.telemetry.value } })\n\n if (plugin.on) {\n for (const [event, handler] of Object.entries(plugin.on)) {\n pluginUnsubscribes.push(app.eventBus.on(event as any, handler as any))\n }\n }\n}\n\n/** Notify plugins when telemetry config changes */\nwatch(app.telemetry, () => {\n for (const plugin of plugins) {\n plugin.lifecycle?.onConfigChange?.({\n config: { telemetry: app.telemetry.value },\n })\n }\n})\n\nonBeforeUnmount(() => {\n for (const unsub of pluginUnsubscribes) {\n unsub()\n }\n for (const plugin of plugins) {\n plugin.lifecycle?.onDestroy?.()\n }\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(app.eventBus, layout)\n\nconst DEFAULT_DOCUMENT_WATCH_TIMEOUT = 5000\n\n/** Watch the active document for changes and rebase it with its remote source */\nuseDocumentWatcher({\n documentName: () =>\n app.store.value?.workspace[extensions.workspace.activeDocument],\n store: app.store,\n initialTimeout: DEFAULT_DOCUMENT_WATCH_TIMEOUT,\n})\n\n/** Color mode */\nuseColorMode({ workspaceStore: app.store })\n\nconst currentTheme = computed(() => app.theme.styles.value.themeStyles)\nconst isDarkMode = computed(() => app.isDarkMode.value)\n\n/** Setup monaco editor configuration */\nuseMonacoEditorConfiguration({\n theme: currentTheme,\n darkMode: isDarkMode,\n})\n\nconst createWorkspaceModalState = useModal()\n\n/** Props to pass to the RouterView component. */\nconst routerViewProps = computed<RouteProps>(() => {\n return {\n documentSlug: app.activeEntities.documentSlug.value ?? '',\n document: app.store.value?.workspace.activeDocument ?? null,\n environment: app.environment.value,\n eventBus: app.eventBus,\n exampleName: app.activeEntities.exampleName.value,\n fetchRegistryDocument,\n layout,\n method: app.activeEntities.method.value,\n path: app.activeEntities.path.value,\n workspaceStore: app.store.value!,\n activeWorkspace: app.workspace.activeWorkspace.value!,\n isTeamWorkspace: app.workspace.isTeamWorkspace.value,\n plugins,\n isDarkMode: app.isDarkMode.value,\n currentTheme: app.theme.styles.value.themeStyles,\n customThemes: toValue(app.theme.customThemes),\n telemetry: app.telemetry.value,\n onUpdateTelemetry: (value: boolean) => {\n app.telemetry.value = value\n },\n options: app.options,\n }\n})\n</script>\n\n<template>\n <ScalarTeleportRoot>\n <!-- Theme style tag -->\n <div v-html=\"app.theme.themeStyleTag.value\" />\n\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- Main content -->\n <main\n v-if=\"\n app.store.value !== null &&\n app.workspace.activeWorkspace.value !== null &&\n !app.loading.value\n \">\n <div class=\"relative flex h-dvh w-dvw flex-col\">\n <SidebarToggle\n v-model=\"app.sidebar.isOpen.value\"\n class=\"absolute z-60 md:hidden\"\n :class=\"layout === 'desktop' ? 'top-14 left-4' : 'top-4 left-4'\" />\n <AppHeader\n :menuTitle=\"app.workspace.isTeamWorkspace.value ? 'Team' : 'Local'\"\n @navigate:to:settings=\"\n app.eventBus.emit('ui:navigate', {\n page: 'workspace',\n path: 'settings',\n })\n \">\n <!--\n Only forward the consumer-provided logo (typically a team\n avatar from Scalar Cloud) while the user is actually inside a\n team workspace. Outside of a team context the avatar would be\n misleading, so we omit the `#logo` template entirely and let\n `ScalarMenuButton` fall back to its default Scalar wordmark.\n -->\n <template\n v-if=\"$slots['header-logo'] && app.workspace.isTeamWorkspace.value\"\n #logo>\n <slot\n :isTeamWorkspace=\"app.workspace.isTeamWorkspace.value\"\n name=\"header-logo\" />\n </template>\n <template #menuItems>\n <!--\n The workspace picker used to live here as a submenu. It is now\n surfaced inline in the breadcrumb so the user reaches it in a\n single click. Consumers that want extra menu rows can still\n inject them through the `header-menu-items` slot.\n -->\n <slot name=\"header-menu-items\" />\n </template>\n <template #breadcrumb>\n <DocumentBreadcrumb\n :app=\"app\"\n :fetchRegistryDocument=\"fetchRegistryDocument\"\n :registryDocuments=\"registryDocuments\"\n @createWorkspace=\"createWorkspaceModalState.show()\" />\n </template>\n <template #end>\n <div class=\"flex items-center gap-2\">\n <!--\n Sync status mirrors the icon in the version picker so the\n user can see at a glance whether the active registry-backed\n document is synced / pending push / pending pull / in\n conflict, even when the picker dropdown is closed. We only\n mount it while a document is actually active on the route -\n on workspace-level pages (settings, get-started, etc.)\n there is nothing to sync, and an indicator there would just\n be noise.\n -->\n <DocumentSyncIndicator\n v-if=\"app.activeEntities.documentSlug.value\"\n :app=\"app\"\n :registryDocuments=\"registryDocuments\" />\n <slot\n v-if=\"$slots['header-actions']\"\n name=\"header-actions\" />\n <!--\n Vertical divider between the two trailing slot clusters.\n Only rendered when both `header-actions` and `header-end`\n are provided, so consumers using just one of the slots do\n not get an orphaned separator.\n -->\n <span\n v-if=\"$slots['header-actions'] && $slots['header-end']\"\n aria-hidden=\"true\"\n class=\"bg-border h-4 w-px shrink-0\" />\n <slot\n v-if=\"$slots['header-end']\"\n name=\"header-end\" />\n </div>\n </template>\n </AppHeader>\n <div class=\"flex min-h-0 flex-1 flex-row\">\n <!-- App sidebar -->\n <AppSidebar\n :app=\"app\"\n :fetchRegistryDocument=\"fetchRegistryDocument\"\n :registryDocuments=\"registryDocuments\"\n :sidebarWidth=\"app.sidebar.width.value\"\n @update:sidebarWidth=\"app.sidebar.handleSidebarWidthUpdate\" />\n\n <div class=\"flex min-h-0 flex-1 flex-col\">\n <!-- App Tabs -->\n <DesktopTabs\n v-if=\"layout === 'desktop'\"\n :activeTabIndex=\"app.tabs.activeTabIndex.value\"\n :eventBus=\"app.eventBus\"\n :tabs=\"app.tabs.state.value\" />\n\n <!-- Router view min-h-0 is required for scrolling, do not remove it -->\n <div class=\"bg-b-1 relative min-h-0 flex-1\">\n <RouterView v-bind=\"routerViewProps\" />\n </div>\n </div>\n </div>\n </div>\n\n <slot\n name=\"create-workspace\"\n :state=\"createWorkspaceModalState\">\n <!-- Create workspace modal -->\n <CreateWorkspaceModal\n :state=\"createWorkspaceModalState\"\n @create:workspace=\"(payload) => app.workspace.create(payload)\" />\n </slot>\n <!-- Popup command palette to add resources from anywhere -->\n <TheCommandPalette\n :eventBus=\"app.eventBus\"\n :paletteState=\"paletteState\"\n :workspaceStore=\"app.store.value!\" />\n </main>\n <!-- Splash screen -->\n <main v-else>\n <SplashScreen />\n </main>\n </ScalarTeleportRoot>\n</template>\n\n<style>\n#scalar-client {\n position: relative;\n background-color: var(--scalar-background-2);\n}\n.dark-mode #scalar-client {\n background-color: color-mix(in srgb, var(--scalar-background-1) 65%, black);\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"App.vue.js","names":[],"sources":["../../../../src/v2/features/app/App.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Main entry point for the API client for electron and web.\n *\n * This component handles all events and store business logic for the application.\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarModal, ScalarTeleportRoot, useModal } from '@scalar/components'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport { extensions } from '@scalar/workspace-store/schemas/extensions'\nimport { computed, onBeforeUnmount, toValue, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport { SidebarToggle } from '@/v2/components/sidebar'\nimport AppHeader from '@/v2/features/app/components/AppHeader.vue'\nimport AppHeaderActions from '@/v2/features/app/components/AppHeaderActions.vue'\nimport AppSidebar from '@/v2/features/app/components/AppSidebar.vue'\nimport CreateWorkspaceModal from '@/v2/features/app/components/CreateWorkspaceModal.vue'\nimport DocumentBreadcrumb from '@/v2/features/app/components/DocumentBreadcrumb.vue'\nimport PublishDocumentModal from '@/v2/features/app/components/PublishDocumentModal.vue'\nimport SplashScreen from '@/v2/features/app/components/SplashScreen.vue'\nimport SyncConflictResolutionEditor from '@/v2/features/app/components/SyncConflictResolutionEditor.vue'\nimport type { RouteProps } from '@/v2/features/app/helpers/routes'\nimport { useDocumentSync } from '@/v2/features/app/hooks/use-document-sync'\nimport { useDocumentWatcher } from '@/v2/features/app/hooks/use-document-watcher'\nimport type { CommandPaletteState } from '@/v2/features/command-palette/hooks/use-command-palette-state'\nimport TheCommandPalette from '@/v2/features/command-palette/TheCommandPalette.vue'\nimport { useMonacoEditorConfiguration } from '@/v2/features/editor'\nimport { useColorMode } from '@/v2/hooks/use-color-mode'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport type {\n RegistryAdapter,\n RegistryDocumentsState,\n} from '@/v2/types/configuration'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport type { AppState } from './app-state'\nimport DesktopTabs from './components/DesktopTabs.vue'\n\nconst {\n layout,\n plugins = [],\n getAppState,\n getCommandPaletteState,\n registry,\n} = defineProps<{\n layout: Exclude<ClientLayout, 'modal'>\n plugins?: ClientPlugin[]\n getAppState: () => AppState\n getCommandPaletteState: () => CommandPaletteState\n /**\n * Adapter wiring the API client up to an external registry (Scalar\n * Cloud or a custom self-hosted setup). The adapter itself is optional\n * - omit it to opt out of registry features entirely - but every\n * field on it (`documents`, `namespaces`, `fetchDocument`,\n * `publishDocument`, `publishVersion`) is required when provided so\n * the client can rely on the full surface.\n */\n registry?: RegistryAdapter\n}>()\n\n/**\n * Reactive view of the registry documents list with a sane default for\n * setups that did not wire an adapter up. The sidebar and breadcrumb\n * read this getter so they keep rendering skeletons / empty states even\n * when the host application has not provided a `registry` prop.\n */\nconst registryDocuments = computed<RegistryDocumentsState>(\n () => registry?.documents ?? { status: 'success', documents: [] },\n)\n\ndefineSlots<{\n /**\n * Replaces the Scalar logo inside the header menu button. Typically used by\n * team-aware consumers (e.g. Scalar Cloud) to render a team avatar so the\n * left-most chrome reads as \"this team's workspace\" rather than the\n * generic Scalar wordmark.\n *\n * Receives `isTeamWorkspace` so consumers can opt into rendering a team\n * image only when the active workspace actually belongs to a team, while\n * keeping the default Scalar logo for local workspaces.\n */\n 'header-logo'?: (payload: { isTeamWorkspace: boolean }) => unknown\n /**\n * Slot for customizing the menu items section of the app header.\n * Defaults to a workspace picker bound to the current app state. Overriding this slot\n * replaces the default picker entirely, so the consumer is responsible for rendering\n * any workspace switcher (or other menu content) they need.\n */\n 'header-menu-items'?: () => unknown\n /**\n * Slot for customizing the end section of the app header.\n * Typically used for user menus, action buttons, or other trailing controls.\n */\n 'header-end'?: () => unknown\n}>()\n\ndefineExpose({\n openCreateWorkspace: () => createWorkspaceModalState.show(),\n})\n\nconst app = getAppState()\nconst paletteState = getCommandPaletteState()\n\n/** Expose workspace store to window for debugging purposes. */\nif (typeof window !== 'undefined') {\n window.dataDumpWorkspace = () => app.store.value\n window.dumpAppState = () => app\n}\n\n/** Call lifecycle hooks on plugins and subscribe to event bus events */\nconst pluginUnsubscribes: (() => void)[] = []\n\nfor (const plugin of plugins) {\n plugin.lifecycle?.onInit?.({ config: { telemetry: app.telemetry.value } })\n\n if (plugin.on) {\n for (const [event, handler] of Object.entries(plugin.on)) {\n pluginUnsubscribes.push(app.eventBus.on(event as any, handler as any))\n }\n }\n}\n\n/** Notify plugins when telemetry config changes */\nwatch(app.telemetry, () => {\n for (const plugin of plugins) {\n plugin.lifecycle?.onConfigChange?.({\n config: { telemetry: app.telemetry.value },\n })\n }\n})\n\nonBeforeUnmount(() => {\n for (const unsub of pluginUnsubscribes) {\n unsub()\n }\n for (const plugin of plugins) {\n plugin.lifecycle?.onDestroy?.()\n }\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(app.eventBus, layout)\n\nconst DEFAULT_DOCUMENT_WATCH_TIMEOUT = 5000\n\n/** Watch the active document for changes and rebase it with its remote source */\nuseDocumentWatcher({\n documentName: () =>\n app.store.value?.workspace[extensions.workspace.activeDocument],\n store: app.store,\n initialTimeout: DEFAULT_DOCUMENT_WATCH_TIMEOUT,\n})\n\n/** Color mode */\nuseColorMode({ workspaceStore: app.store })\n\nconst currentTheme = computed(() => app.theme.styles.value.themeStyles)\nconst isDarkMode = computed(() => app.isDarkMode.value)\n\n/** Setup monaco editor configuration */\nuseMonacoEditorConfiguration({\n theme: currentTheme,\n darkMode: isDarkMode,\n})\n\nconst createWorkspaceModalState = useModal()\n\n/**\n * Owns the document-level Save / Revert / Pull / Push / Publish flow.\n * Keeping it in a dedicated hook leaves this component focused on\n * routing, layout, and slot composition.\n */\nconst {\n showLocalSaveActions,\n showTeamSyncActions,\n showTeamPublishAction,\n hasHeaderActionCluster,\n isActiveDocumentDirty,\n isOffline,\n canPullActiveDocument,\n canPushActiveDocument,\n publishDocumentModalState,\n syncConflictModalState,\n pendingPullState,\n publishDefaultSlug,\n publishDefaultVersion,\n registryNamespaces,\n handleSaveDocument,\n handleRevertDocument,\n handlePullDocument,\n handlePushDocument,\n handlePublishDocument,\n handlePublishDocumentSubmit,\n handleSyncConflictApplyChanges,\n handleSyncConflictModalClose,\n} = useDocumentSync({\n app,\n registry,\n registryDocuments: () => registryDocuments.value,\n})\n\n/** Props to pass to the RouterView component. */\nconst routerViewProps = computed<RouteProps>(() => {\n return {\n documentSlug: app.activeEntities.documentSlug.value ?? '',\n document: app.store.value?.workspace.activeDocument ?? null,\n environment: app.environment.value,\n eventBus: app.eventBus,\n exampleName: app.activeEntities.exampleName.value,\n fetchRegistryDocument: registry?.fetchDocument,\n layout,\n method: app.activeEntities.method.value,\n path: app.activeEntities.path.value,\n workspaceStore: app.store.value!,\n activeWorkspace: app.workspace.activeWorkspace.value!,\n isTeamWorkspace: app.workspace.isTeamWorkspace.value,\n plugins,\n isDarkMode: app.isDarkMode.value,\n currentTheme: app.theme.styles.value.themeStyles,\n customThemes: toValue(app.theme.customThemes),\n telemetry: app.telemetry.value,\n onUpdateTelemetry: (value: boolean) => {\n app.telemetry.value = value\n },\n options: app.options,\n }\n})\n</script>\n\n<template>\n <ScalarTeleportRoot>\n <!-- Theme style tag -->\n <div v-html=\"app.theme.themeStyleTag.value\" />\n\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- Main content -->\n <main\n v-if=\"\n app.store.value !== null &&\n app.workspace.activeWorkspace.value !== null &&\n !app.loading.value\n \">\n <div\n class=\"relative flex h-dvh w-dvw flex-col\"\n :style=\"{\n '--app-desktop-tabs-height': layout === 'desktop' ? '2.5rem' : '0px',\n }\">\n <!--\n Sits in the same visual slot as the operation Header gutter (size-8).\n Offset = desktop tab strip (layout desktop only) + ScalarHeader (min-h-header)\n + OperationBlock outer p-2 + Header pt-2 (1rem total) so we clear app chrome.\n `--app-desktop-tabs-height` is set on this shell so the mobile sidebar inset\n matches (see AppSidebar).\n -->\n <SidebarToggle\n v-model=\"app.sidebar.isOpen.value\"\n class=\"app-no-drag-region absolute top-[calc(var(--app-desktop-tabs-height)+var(--spacing-header,48px)+1rem)] left-4 z-60 md:hidden\" />\n <!-- App Tabs -->\n <DesktopTabs\n v-if=\"layout === 'desktop'\"\n :activeTabIndex=\"app.tabs.activeTabIndex.value\"\n :eventBus=\"app.eventBus\"\n :tabs=\"app.tabs.state.value\" />\n <AppHeader\n :menuTitle=\"app.workspace.isTeamWorkspace.value ? 'Team' : 'Local'\"\n @navigate:to:settings=\"\n app.eventBus.emit('ui:navigate', {\n page: 'workspace',\n path: 'settings',\n })\n \">\n <!--\n Only forward the consumer-provided logo (typically a team\n avatar from Scalar Cloud) while the user is actually inside a\n team workspace. Outside of a team context the avatar would be\n misleading, so we omit the `#logo` template entirely and let\n `ScalarMenuButton` fall back to its default Scalar wordmark.\n -->\n <template\n v-if=\"$slots['header-logo'] && app.workspace.isTeamWorkspace.value\"\n #logo>\n <slot\n :isTeamWorkspace=\"app.workspace.isTeamWorkspace.value\"\n name=\"header-logo\" />\n </template>\n <template #menuItems>\n <!--\n The workspace picker used to live here as a submenu. It is now\n surfaced inline in the breadcrumb so the user reaches it in a\n single click. Consumers that want extra menu rows can still\n inject them through the `header-menu-items` slot.\n -->\n <slot name=\"header-menu-items\" />\n </template>\n <template #breadcrumb>\n <DocumentBreadcrumb\n :app=\"app\"\n :fetchRegistryDocument=\"registry?.fetchDocument\"\n :registryDocuments=\"registryDocuments\"\n @createWorkspace=\"createWorkspaceModalState.show()\" />\n </template>\n <!--\n Only forward the trailing `#end` cluster when it has actual\n content. The action clusters and the consumer slots all gate\n independently, so we mirror those conditions on the wrapper to\n avoid mounting an empty cluster that would otherwise leak a\n stray divider.\n -->\n <template\n v-if=\"\n hasHeaderActionCluster ||\n $slots['header-actions'] ||\n $slots['header-end']\n \"\n #end>\n <div class=\"flex items-center gap-2\">\n <AppHeaderActions\n :canPullActiveDocument=\"canPullActiveDocument\"\n :canPushActiveDocument=\"canPushActiveDocument\"\n :isActiveDocumentDirty=\"isActiveDocumentDirty\"\n :isOffline=\"isOffline\"\n :showLocalSaveActions=\"showLocalSaveActions\"\n :showTeamPublishAction=\"showTeamPublishAction\"\n :showTeamSyncActions=\"showTeamSyncActions\"\n @publish=\"handlePublishDocument\"\n @pull=\"handlePullDocument\"\n @push=\"handlePushDocument\"\n @revert=\"handleRevertDocument\"\n @save=\"handleSaveDocument\" />\n <!--\n Vertical divider\n -->\n <span\n v-if=\"$slots['header-end']\"\n aria-hidden=\"true\"\n class=\"bg-border h-4 w-px shrink-0\" />\n <slot\n v-if=\"$slots['header-end']\"\n name=\"header-end\" />\n </div>\n </template>\n </AppHeader>\n <div class=\"flex min-h-0 flex-1 flex-row\">\n <!-- App sidebar -->\n <AppSidebar\n :app=\"app\"\n :fetchRegistryDocument=\"registry?.fetchDocument\"\n :registryDocuments=\"registryDocuments\"\n :sidebarWidth=\"app.sidebar.width.value\"\n @update:sidebarWidth=\"app.sidebar.handleSidebarWidthUpdate\" />\n\n <!-- Router view min-h-0 is required for scrolling, do not remove it -->\n <div class=\"bg-b-1 relative min-h-0 flex-1\">\n <RouterView v-bind=\"routerViewProps\" />\n </div>\n </div>\n </div>\n <!-- Create workspace modal -->\n <CreateWorkspaceModal\n :state=\"createWorkspaceModalState\"\n @create:workspace=\"(payload) => app.workspace.create(payload)\" />\n\n <!--\n First-time publish modal. Only mounted when a registry adapter\n is wired up - without one there is nothing meaningful to send,\n and the modal would never be opened anyway.\n -->\n <PublishDocumentModal\n v-if=\"registry\"\n :defaultSlug=\"publishDefaultSlug\"\n :defaultVersion=\"publishDefaultVersion\"\n :namespaces=\"registryNamespaces\"\n :state=\"publishDocumentModalState\"\n @submit=\"handlePublishDocumentSubmit\" />\n <!--\n Three-way merge editor for the Pull flow. We mount it lazily on\n `pendingPullState` so the heavy Monaco editors only spin up when\n a pull actually has conflicts to walk through. The full-size\n layout mirrors `DocumentCollection.vue`'s sync modal so the\n editor has enough room to render the local / remote / result\n panes side-by-side.\n -->\n <ScalarModal\n v-if=\"pendingPullState\"\n bodyClass=\"sync-conflict-modal-root flex h-dvh flex-col p-4\"\n maxWidth=\"calc(100dvw - 32px)\"\n size=\"full\"\n :state=\"syncConflictModalState\"\n @close=\"handleSyncConflictModalClose\">\n <div class=\"flex h-full w-full flex-col gap-4 overflow-hidden\">\n <SyncConflictResolutionEditor\n :baseDocument=\"pendingPullState.rebaseResult.originalDocument\"\n :conflicts=\"pendingPullState.rebaseResult.conflicts\"\n :resolvedDocument=\"pendingPullState.rebaseResult.resolvedDocument\"\n @applyChanges=\"handleSyncConflictApplyChanges\" />\n </div>\n </ScalarModal>\n <!-- Popup command palette to add resources from anywhere -->\n <TheCommandPalette\n :eventBus=\"app.eventBus\"\n :paletteState=\"paletteState\"\n :workspaceStore=\"app.store.value!\" />\n </main>\n <!-- Splash screen -->\n <main v-else>\n <SplashScreen />\n </main>\n </ScalarTeleportRoot>\n</template>\n\n<style>\n#scalar-client {\n position: relative;\n background-color: var(--scalar-background-2);\n}\n.dark-mode #scalar-client {\n background-color: color-mix(in srgb, var(--scalar-background-1) 65%, black);\n}\n\n/*\n * The three-way merge editor needs the full viewport to fit its three\n * Monaco panes. `DocumentCollection.vue` ships the same override for\n * its in-page Sync modal, but the pull flow can run without that view\n * being mounted, so we duplicate the rule here to keep the modal\n * full-bleed.\n */\n.full-size-styles:has(.sync-conflict-modal-root) {\n width: 100dvw !important;\n max-width: 100dvw !important;\n border-right: none !important;\n}\n\n.full-size-styles:has(.sync-conflict-modal-root)::after {\n display: none;\n}\n</style>\n"],"mappings":""}
|
|
@@ -2,34 +2,36 @@ import TheCommandPalette_default from "../command-palette/TheCommandPalette.vue.
|
|
|
2
2
|
import SidebarToggle_default from "../../components/sidebar/SidebarToggle.vue.js";
|
|
3
3
|
import CreateWorkspaceModal_default from "./components/CreateWorkspaceModal.vue.js";
|
|
4
4
|
import AppHeader_default from "./components/AppHeader.vue.js";
|
|
5
|
+
import AppHeaderActions_default from "./components/AppHeaderActions.vue.js";
|
|
5
6
|
import AppSidebar_default from "./components/AppSidebar.vue.js";
|
|
6
7
|
import DocumentBreadcrumb_default from "./components/DocumentBreadcrumb.vue.js";
|
|
7
|
-
import
|
|
8
|
+
import PublishDocumentModal_default from "./components/PublishDocumentModal.vue.js";
|
|
8
9
|
import SplashScreen_default from "./components/SplashScreen.vue.js";
|
|
9
|
-
import { useDocumentWatcher } from "./hooks/use-document-watcher.js";
|
|
10
10
|
import { useMonacoEditorConfiguration } from "../editor/config.js";
|
|
11
|
+
import SyncConflictResolutionEditor_default from "./components/SyncConflictResolutionEditor.vue.js";
|
|
12
|
+
import { useDocumentSync } from "./hooks/use-document-sync.js";
|
|
13
|
+
import { useDocumentWatcher } from "./hooks/use-document-watcher.js";
|
|
11
14
|
import { useColorMode } from "../../hooks/use-color-mode.js";
|
|
12
15
|
import { useGlobalHotKeys } from "../../hooks/use-global-hot-keys.js";
|
|
13
16
|
import DesktopTabs_default from "./components/DesktopTabs.vue.js";
|
|
14
|
-
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, guardReactiveProps,
|
|
15
|
-
import { ScalarTeleportRoot, useModal } from "@scalar/components";
|
|
17
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, guardReactiveProps, normalizeProps, normalizeStyle, onBeforeUnmount, openBlock, renderSlot, toValue, unref, watch, withCtx } from "vue";
|
|
18
|
+
import { ScalarModal, ScalarTeleportRoot, useModal } from "@scalar/components";
|
|
16
19
|
import { ScalarToasts } from "@scalar/use-toasts";
|
|
17
20
|
import { RouterView } from "vue-router";
|
|
18
21
|
import { extensions } from "@scalar/workspace-store/schemas/extensions";
|
|
19
22
|
//#region src/v2/features/app/App.vue?vue&type=script&setup=true&lang.ts
|
|
20
23
|
var _hoisted_1 = ["innerHTML"];
|
|
21
24
|
var _hoisted_2 = { key: 0 };
|
|
22
|
-
var _hoisted_3 = { class: "
|
|
23
|
-
var _hoisted_4 = {
|
|
24
|
-
|
|
25
|
-
key: 2,
|
|
25
|
+
var _hoisted_3 = { class: "flex items-center gap-2" };
|
|
26
|
+
var _hoisted_4 = {
|
|
27
|
+
key: 0,
|
|
26
28
|
"aria-hidden": "true",
|
|
27
29
|
class: "bg-border h-4 w-px shrink-0"
|
|
28
30
|
};
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
31
|
+
var _hoisted_5 = { class: "flex min-h-0 flex-1 flex-row" };
|
|
32
|
+
var _hoisted_6 = { class: "bg-b-1 relative min-h-0 flex-1" };
|
|
33
|
+
var _hoisted_7 = { class: "flex h-full w-full flex-col gap-4 overflow-hidden" };
|
|
34
|
+
var _hoisted_8 = { key: 1 };
|
|
33
35
|
var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
34
36
|
__name: "App",
|
|
35
37
|
props: {
|
|
@@ -37,13 +39,19 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
37
39
|
plugins: { default: () => [] },
|
|
38
40
|
getAppState: { type: Function },
|
|
39
41
|
getCommandPaletteState: { type: Function },
|
|
40
|
-
|
|
41
|
-
registryDocuments: { default: () => ({
|
|
42
|
-
status: "success",
|
|
43
|
-
documents: []
|
|
44
|
-
}) }
|
|
42
|
+
registry: {}
|
|
45
43
|
},
|
|
46
44
|
setup(__props, { expose: __expose }) {
|
|
45
|
+
/**
|
|
46
|
+
* Reactive view of the registry documents list with a sane default for
|
|
47
|
+
* setups that did not wire an adapter up. The sidebar and breadcrumb
|
|
48
|
+
* read this getter so they keep rendering skeletons / empty states even
|
|
49
|
+
* when the host application has not provided a `registry` prop.
|
|
50
|
+
*/
|
|
51
|
+
const registryDocuments = computed(() => __props.registry?.documents ?? {
|
|
52
|
+
status: "success",
|
|
53
|
+
documents: []
|
|
54
|
+
});
|
|
47
55
|
__expose({ openCreateWorkspace: () => createWorkspaceModalState.show() });
|
|
48
56
|
const app = __props.getAppState();
|
|
49
57
|
const paletteState = __props.getCommandPaletteState();
|
|
@@ -82,6 +90,16 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
82
90
|
darkMode: computed(() => app.isDarkMode.value)
|
|
83
91
|
});
|
|
84
92
|
const createWorkspaceModalState = useModal();
|
|
93
|
+
/**
|
|
94
|
+
* Owns the document-level Save / Revert / Pull / Push / Publish flow.
|
|
95
|
+
* Keeping it in a dedicated hook leaves this component focused on
|
|
96
|
+
* routing, layout, and slot composition.
|
|
97
|
+
*/
|
|
98
|
+
const { showLocalSaveActions, showTeamSyncActions, showTeamPublishAction, hasHeaderActionCluster, isActiveDocumentDirty, isOffline, canPullActiveDocument, canPushActiveDocument, publishDocumentModalState, syncConflictModalState, pendingPullState, publishDefaultSlug, publishDefaultVersion, registryNamespaces, handleSaveDocument, handleRevertDocument, handlePullDocument, handlePushDocument, handlePublishDocument, handlePublishDocumentSubmit, handleSyncConflictApplyChanges, handleSyncConflictModalClose } = useDocumentSync({
|
|
99
|
+
app,
|
|
100
|
+
registry: __props.registry,
|
|
101
|
+
registryDocuments: () => registryDocuments.value
|
|
102
|
+
});
|
|
85
103
|
/** Props to pass to the RouterView component. */
|
|
86
104
|
const routerViewProps = computed(() => {
|
|
87
105
|
return {
|
|
@@ -90,7 +108,7 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
90
108
|
environment: app.environment.value,
|
|
91
109
|
eventBus: app.eventBus,
|
|
92
110
|
exampleName: app.activeEntities.exampleName.value,
|
|
93
|
-
fetchRegistryDocument: __props.
|
|
111
|
+
fetchRegistryDocument: __props.registry?.fetchDocument,
|
|
94
112
|
layout: __props.layout,
|
|
95
113
|
method: app.activeEntities.method.value,
|
|
96
114
|
path: app.activeEntities.path.value,
|
|
@@ -114,12 +132,25 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
114
132
|
createElementVNode("div", { innerHTML: unref(app).theme.themeStyleTag.value }, null, 8, _hoisted_1),
|
|
115
133
|
createVNode(unref(ScalarToasts)),
|
|
116
134
|
unref(app).store.value !== null && unref(app).workspace.activeWorkspace.value !== null && !unref(app).loading.value ? (openBlock(), createElementBlock("main", _hoisted_2, [
|
|
117
|
-
createElementVNode("div",
|
|
135
|
+
createElementVNode("div", {
|
|
136
|
+
class: "relative flex h-dvh w-dvw flex-col",
|
|
137
|
+
style: normalizeStyle({ "--app-desktop-tabs-height": __props.layout === "desktop" ? "2.5rem" : "0px" })
|
|
138
|
+
}, [
|
|
118
139
|
createVNode(unref(SidebarToggle_default), {
|
|
119
140
|
modelValue: unref(app).sidebar.isOpen.value,
|
|
120
141
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(app).sidebar.isOpen.value = $event),
|
|
121
|
-
class:
|
|
122
|
-
}, null, 8, ["modelValue"
|
|
142
|
+
class: "app-no-drag-region absolute top-[calc(var(--app-desktop-tabs-height)+var(--spacing-header,48px)+1rem)] left-4 z-60 md:hidden"
|
|
143
|
+
}, null, 8, ["modelValue"]),
|
|
144
|
+
__props.layout === "desktop" ? (openBlock(), createBlock(DesktopTabs_default, {
|
|
145
|
+
key: 0,
|
|
146
|
+
activeTabIndex: unref(app).tabs.activeTabIndex.value,
|
|
147
|
+
eventBus: unref(app).eventBus,
|
|
148
|
+
tabs: unref(app).tabs.state.value
|
|
149
|
+
}, null, 8, [
|
|
150
|
+
"activeTabIndex",
|
|
151
|
+
"eventBus",
|
|
152
|
+
"tabs"
|
|
153
|
+
])) : createCommentVNode("", true),
|
|
123
154
|
createVNode(AppHeader_default, {
|
|
124
155
|
menuTitle: unref(app).workspace.isTeamWorkspace.value ? "Team" : "Local",
|
|
125
156
|
"onNavigate:to:settings": _cache[2] || (_cache[2] = ($event) => unref(app).eventBus.emit("ui:navigate", {
|
|
@@ -130,34 +161,58 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
130
161
|
menuItems: withCtx(() => [renderSlot(_ctx.$slots, "header-menu-items")]),
|
|
131
162
|
breadcrumb: withCtx(() => [createVNode(DocumentBreadcrumb_default, {
|
|
132
163
|
app: unref(app),
|
|
133
|
-
fetchRegistryDocument: __props.
|
|
134
|
-
registryDocuments:
|
|
164
|
+
fetchRegistryDocument: __props.registry?.fetchDocument,
|
|
165
|
+
registryDocuments: registryDocuments.value,
|
|
135
166
|
onCreateWorkspace: _cache[1] || (_cache[1] = ($event) => unref(createWorkspaceModalState).show())
|
|
136
167
|
}, null, 8, [
|
|
137
168
|
"app",
|
|
138
169
|
"fetchRegistryDocument",
|
|
139
170
|
"registryDocuments"
|
|
140
171
|
])]),
|
|
141
|
-
end: withCtx(() => [createElementVNode("div", _hoisted_4, [
|
|
142
|
-
unref(app).activeEntities.documentSlug.value ? (openBlock(), createBlock(DocumentSyncIndicator_default, {
|
|
143
|
-
key: 0,
|
|
144
|
-
app: unref(app),
|
|
145
|
-
registryDocuments: __props.registryDocuments
|
|
146
|
-
}, null, 8, ["app", "registryDocuments"])) : createCommentVNode("", true),
|
|
147
|
-
_ctx.$slots["header-actions"] ? renderSlot(_ctx.$slots, "header-actions", { key: 1 }) : createCommentVNode("", true),
|
|
148
|
-
_ctx.$slots["header-actions"] && _ctx.$slots["header-end"] ? (openBlock(), createElementBlock("span", _hoisted_5)) : createCommentVNode("", true),
|
|
149
|
-
_ctx.$slots["header-end"] ? renderSlot(_ctx.$slots, "header-end", { key: 3 }) : createCommentVNode("", true)
|
|
150
|
-
])]),
|
|
151
172
|
_: 2
|
|
152
173
|
}, [_ctx.$slots["header-logo"] && unref(app).workspace.isTeamWorkspace.value ? {
|
|
153
174
|
name: "logo",
|
|
154
175
|
fn: withCtx(() => [renderSlot(_ctx.$slots, "header-logo", { isTeamWorkspace: unref(app).workspace.isTeamWorkspace.value })]),
|
|
155
176
|
key: "0"
|
|
177
|
+
} : void 0, unref(hasHeaderActionCluster) || _ctx.$slots["header-actions"] || _ctx.$slots["header-end"] ? {
|
|
178
|
+
name: "end",
|
|
179
|
+
fn: withCtx(() => [createElementVNode("div", _hoisted_3, [
|
|
180
|
+
createVNode(AppHeaderActions_default, {
|
|
181
|
+
canPullActiveDocument: unref(canPullActiveDocument),
|
|
182
|
+
canPushActiveDocument: unref(canPushActiveDocument),
|
|
183
|
+
isActiveDocumentDirty: unref(isActiveDocumentDirty),
|
|
184
|
+
isOffline: unref(isOffline),
|
|
185
|
+
showLocalSaveActions: unref(showLocalSaveActions),
|
|
186
|
+
showTeamPublishAction: unref(showTeamPublishAction),
|
|
187
|
+
showTeamSyncActions: unref(showTeamSyncActions),
|
|
188
|
+
onPublish: unref(handlePublishDocument),
|
|
189
|
+
onPull: unref(handlePullDocument),
|
|
190
|
+
onPush: unref(handlePushDocument),
|
|
191
|
+
onRevert: unref(handleRevertDocument),
|
|
192
|
+
onSave: unref(handleSaveDocument)
|
|
193
|
+
}, null, 8, [
|
|
194
|
+
"canPullActiveDocument",
|
|
195
|
+
"canPushActiveDocument",
|
|
196
|
+
"isActiveDocumentDirty",
|
|
197
|
+
"isOffline",
|
|
198
|
+
"showLocalSaveActions",
|
|
199
|
+
"showTeamPublishAction",
|
|
200
|
+
"showTeamSyncActions",
|
|
201
|
+
"onPublish",
|
|
202
|
+
"onPull",
|
|
203
|
+
"onPush",
|
|
204
|
+
"onRevert",
|
|
205
|
+
"onSave"
|
|
206
|
+
]),
|
|
207
|
+
_ctx.$slots["header-end"] ? (openBlock(), createElementBlock("span", _hoisted_4)) : createCommentVNode("", true),
|
|
208
|
+
_ctx.$slots["header-end"] ? renderSlot(_ctx.$slots, "header-end", { key: 1 }) : createCommentVNode("", true)
|
|
209
|
+
])]),
|
|
210
|
+
key: "1"
|
|
156
211
|
} : void 0]), 1032, ["menuTitle"]),
|
|
157
|
-
createElementVNode("div",
|
|
212
|
+
createElementVNode("div", _hoisted_5, [createVNode(AppSidebar_default, {
|
|
158
213
|
app: unref(app),
|
|
159
|
-
fetchRegistryDocument: __props.
|
|
160
|
-
registryDocuments:
|
|
214
|
+
fetchRegistryDocument: __props.registry?.fetchDocument,
|
|
215
|
+
registryDocuments: registryDocuments.value,
|
|
161
216
|
sidebarWidth: unref(app).sidebar.width.value,
|
|
162
217
|
"onUpdate:sidebarWidth": unref(app).sidebar.handleSidebarWidthUpdate
|
|
163
218
|
}, null, 8, [
|
|
@@ -166,21 +221,47 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
166
221
|
"registryDocuments",
|
|
167
222
|
"sidebarWidth",
|
|
168
223
|
"onUpdate:sidebarWidth"
|
|
169
|
-
]), createElementVNode("div",
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
eventBus: unref(app).eventBus,
|
|
173
|
-
tabs: unref(app).tabs.state.value
|
|
174
|
-
}, null, 8, [
|
|
175
|
-
"activeTabIndex",
|
|
176
|
-
"eventBus",
|
|
177
|
-
"tabs"
|
|
178
|
-
])) : createCommentVNode("", true), createElementVNode("div", _hoisted_8, [createVNode(unref(RouterView), normalizeProps(guardReactiveProps(routerViewProps.value)), null, 16)])])])
|
|
179
|
-
]),
|
|
180
|
-
renderSlot(_ctx.$slots, "create-workspace", { state: unref(createWorkspaceModalState) }, () => [createVNode(CreateWorkspaceModal_default, {
|
|
224
|
+
]), createElementVNode("div", _hoisted_6, [createVNode(unref(RouterView), normalizeProps(guardReactiveProps(routerViewProps.value)), null, 16)])])
|
|
225
|
+
], 4),
|
|
226
|
+
createVNode(CreateWorkspaceModal_default, {
|
|
181
227
|
state: unref(createWorkspaceModalState),
|
|
182
228
|
"onCreate:workspace": _cache[3] || (_cache[3] = (payload) => unref(app).workspace.create(payload))
|
|
183
|
-
}, null, 8, ["state"])
|
|
229
|
+
}, null, 8, ["state"]),
|
|
230
|
+
__props.registry ? (openBlock(), createBlock(PublishDocumentModal_default, {
|
|
231
|
+
key: 0,
|
|
232
|
+
defaultSlug: unref(publishDefaultSlug),
|
|
233
|
+
defaultVersion: unref(publishDefaultVersion),
|
|
234
|
+
namespaces: unref(registryNamespaces),
|
|
235
|
+
state: unref(publishDocumentModalState),
|
|
236
|
+
onSubmit: unref(handlePublishDocumentSubmit)
|
|
237
|
+
}, null, 8, [
|
|
238
|
+
"defaultSlug",
|
|
239
|
+
"defaultVersion",
|
|
240
|
+
"namespaces",
|
|
241
|
+
"state",
|
|
242
|
+
"onSubmit"
|
|
243
|
+
])) : createCommentVNode("", true),
|
|
244
|
+
unref(pendingPullState) ? (openBlock(), createBlock(unref(ScalarModal), {
|
|
245
|
+
key: 1,
|
|
246
|
+
bodyClass: "sync-conflict-modal-root flex h-dvh flex-col p-4",
|
|
247
|
+
maxWidth: "calc(100dvw - 32px)",
|
|
248
|
+
size: "full",
|
|
249
|
+
state: unref(syncConflictModalState),
|
|
250
|
+
onClose: unref(handleSyncConflictModalClose)
|
|
251
|
+
}, {
|
|
252
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_7, [createVNode(SyncConflictResolutionEditor_default, {
|
|
253
|
+
baseDocument: unref(pendingPullState).rebaseResult.originalDocument,
|
|
254
|
+
conflicts: unref(pendingPullState).rebaseResult.conflicts,
|
|
255
|
+
resolvedDocument: unref(pendingPullState).rebaseResult.resolvedDocument,
|
|
256
|
+
onApplyChanges: unref(handleSyncConflictApplyChanges)
|
|
257
|
+
}, null, 8, [
|
|
258
|
+
"baseDocument",
|
|
259
|
+
"conflicts",
|
|
260
|
+
"resolvedDocument",
|
|
261
|
+
"onApplyChanges"
|
|
262
|
+
])])]),
|
|
263
|
+
_: 1
|
|
264
|
+
}, 8, ["state", "onClose"])) : createCommentVNode("", true),
|
|
184
265
|
createVNode(TheCommandPalette_default, {
|
|
185
266
|
eventBus: unref(app).eventBus,
|
|
186
267
|
paletteState: unref(paletteState),
|
|
@@ -190,7 +271,7 @@ var App_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
190
271
|
"paletteState",
|
|
191
272
|
"workspaceStore"
|
|
192
273
|
])
|
|
193
|
-
])) : (openBlock(), createElementBlock("main",
|
|
274
|
+
])) : (openBlock(), createElementBlock("main", _hoisted_8, [createVNode(SplashScreen_default)]))
|
|
194
275
|
]),
|
|
195
276
|
_: 3
|
|
196
277
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.vue.script.js","names":["$slots"],"sources":["../../../../src/v2/features/app/App.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Main entry point for the API client for electron and web.\n *\n * This component handles all events and store business logic for the application.\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport {\n ScalarTeleportRoot,\n useModal,\n type ModalState,\n} from '@scalar/components'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport { extensions } from '@scalar/workspace-store/schemas/extensions'\nimport { computed, onBeforeUnmount, toValue, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport { SidebarToggle } from '@/v2/components/sidebar'\nimport AppHeader from '@/v2/features/app/components/AppHeader.vue'\nimport AppSidebar from '@/v2/features/app/components/AppSidebar.vue'\nimport CreateWorkspaceModal from '@/v2/features/app/components/CreateWorkspaceModal.vue'\nimport DocumentBreadcrumb from '@/v2/features/app/components/DocumentBreadcrumb.vue'\nimport DocumentSyncIndicator from '@/v2/features/app/components/DocumentSyncIndicator.vue'\nimport SplashScreen from '@/v2/features/app/components/SplashScreen.vue'\nimport type { RouteProps } from '@/v2/features/app/helpers/routes'\nimport { useDocumentWatcher } from '@/v2/features/app/hooks/use-document-watcher'\nimport type { RegistryDocumentsState } from '@/v2/features/app/hooks/use-sidebar-documents'\nimport type { CommandPaletteState } from '@/v2/features/command-palette/hooks/use-command-palette-state'\nimport TheCommandPalette from '@/v2/features/command-palette/TheCommandPalette.vue'\nimport { useMonacoEditorConfiguration } from '@/v2/features/editor'\nimport { useColorMode } from '@/v2/hooks/use-color-mode'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport type { ImportDocumentFromRegistry } from '@/v2/types/configuration'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport type { AppState } from './app-state'\nimport DesktopTabs from './components/DesktopTabs.vue'\n\nconst {\n layout,\n plugins = [],\n getAppState,\n getCommandPaletteState,\n fetchRegistryDocument,\n registryDocuments = { status: 'success', documents: [] },\n} = defineProps<{\n layout: Exclude<ClientLayout, 'modal'>\n plugins?: ClientPlugin[]\n getAppState: () => AppState\n getCommandPaletteState: () => CommandPaletteState\n /** Fetches the full document from registry by meta. Passed through to route props for sync. */\n fetchRegistryDocument?: ImportDocumentFromRegistry\n /**\n * The list of all available registry documents, with a loading status so the\n * sidebar can render skeleton placeholders until the real list is ready.\n */\n registryDocuments?: RegistryDocumentsState\n}>()\n\ndefineSlots<{\n /**\n * Slot for customizing the create workspace modal.\n * This slot is used to render custom actions or components within the create workspace modal.\n */\n 'create-workspace'?: (payload: { state: ModalState }) => unknown\n /**\n * Replaces the Scalar logo inside the header menu button. Typically used by\n * team-aware consumers (e.g. Scalar Cloud) to render a team avatar so the\n * left-most chrome reads as \"this team's workspace\" rather than the\n * generic Scalar wordmark.\n *\n * Receives `isTeamWorkspace` so consumers can opt into rendering a team\n * image only when the active workspace actually belongs to a team, while\n * keeping the default Scalar logo for local workspaces.\n */\n 'header-logo'?: (payload: { isTeamWorkspace: boolean }) => unknown\n /**\n * Slot for customizing the menu items section of the app header.\n * Defaults to a workspace picker bound to the current app state. Overriding this slot\n * replaces the default picker entirely, so the consumer is responsible for rendering\n * any workspace switcher (or other menu content) they need.\n */\n 'header-menu-items'?: () => unknown\n /**\n * Slot rendered at the trailing edge of the header, immediately before the\n * `header-end` slot. Use this for context-specific action buttons (for\n * example a \"Save\" button) so they sit next to the document chrome rather\n * than getting mixed in with the user / account controls in `header-end`.\n *\n * When both this slot and `header-end` are provided, a vertical divider is\n * inserted between them so the two groups read as visually distinct\n * clusters.\n */\n 'header-actions'?: () => unknown\n /**\n * Slot for customizing the end section of the app header.\n * Typically used for user menus, action buttons, or other trailing controls.\n */\n 'header-end'?: () => unknown\n}>()\n\ndefineExpose({\n openCreateWorkspace: () => createWorkspaceModalState.show(),\n})\n\nconst app = getAppState()\nconst paletteState = getCommandPaletteState()\n\n/** Expose workspace store to window for debugging purposes. */\nif (typeof window !== 'undefined') {\n window.dataDumpWorkspace = () => app.store.value\n window.dumpAppState = () => app\n}\n\n/** Call lifecycle hooks on plugins and subscribe to event bus events */\nconst pluginUnsubscribes: (() => void)[] = []\n\nfor (const plugin of plugins) {\n plugin.lifecycle?.onInit?.({ config: { telemetry: app.telemetry.value } })\n\n if (plugin.on) {\n for (const [event, handler] of Object.entries(plugin.on)) {\n pluginUnsubscribes.push(app.eventBus.on(event as any, handler as any))\n }\n }\n}\n\n/** Notify plugins when telemetry config changes */\nwatch(app.telemetry, () => {\n for (const plugin of plugins) {\n plugin.lifecycle?.onConfigChange?.({\n config: { telemetry: app.telemetry.value },\n })\n }\n})\n\nonBeforeUnmount(() => {\n for (const unsub of pluginUnsubscribes) {\n unsub()\n }\n for (const plugin of plugins) {\n plugin.lifecycle?.onDestroy?.()\n }\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(app.eventBus, layout)\n\nconst DEFAULT_DOCUMENT_WATCH_TIMEOUT = 5000\n\n/** Watch the active document for changes and rebase it with its remote source */\nuseDocumentWatcher({\n documentName: () =>\n app.store.value?.workspace[extensions.workspace.activeDocument],\n store: app.store,\n initialTimeout: DEFAULT_DOCUMENT_WATCH_TIMEOUT,\n})\n\n/** Color mode */\nuseColorMode({ workspaceStore: app.store })\n\nconst currentTheme = computed(() => app.theme.styles.value.themeStyles)\nconst isDarkMode = computed(() => app.isDarkMode.value)\n\n/** Setup monaco editor configuration */\nuseMonacoEditorConfiguration({\n theme: currentTheme,\n darkMode: isDarkMode,\n})\n\nconst createWorkspaceModalState = useModal()\n\n/** Props to pass to the RouterView component. */\nconst routerViewProps = computed<RouteProps>(() => {\n return {\n documentSlug: app.activeEntities.documentSlug.value ?? '',\n document: app.store.value?.workspace.activeDocument ?? null,\n environment: app.environment.value,\n eventBus: app.eventBus,\n exampleName: app.activeEntities.exampleName.value,\n fetchRegistryDocument,\n layout,\n method: app.activeEntities.method.value,\n path: app.activeEntities.path.value,\n workspaceStore: app.store.value!,\n activeWorkspace: app.workspace.activeWorkspace.value!,\n isTeamWorkspace: app.workspace.isTeamWorkspace.value,\n plugins,\n isDarkMode: app.isDarkMode.value,\n currentTheme: app.theme.styles.value.themeStyles,\n customThemes: toValue(app.theme.customThemes),\n telemetry: app.telemetry.value,\n onUpdateTelemetry: (value: boolean) => {\n app.telemetry.value = value\n },\n options: app.options,\n }\n})\n</script>\n\n<template>\n <ScalarTeleportRoot>\n <!-- Theme style tag -->\n <div v-html=\"app.theme.themeStyleTag.value\" />\n\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- Main content -->\n <main\n v-if=\"\n app.store.value !== null &&\n app.workspace.activeWorkspace.value !== null &&\n !app.loading.value\n \">\n <div class=\"relative flex h-dvh w-dvw flex-col\">\n <SidebarToggle\n v-model=\"app.sidebar.isOpen.value\"\n class=\"absolute z-60 md:hidden\"\n :class=\"layout === 'desktop' ? 'top-14 left-4' : 'top-4 left-4'\" />\n <AppHeader\n :menuTitle=\"app.workspace.isTeamWorkspace.value ? 'Team' : 'Local'\"\n @navigate:to:settings=\"\n app.eventBus.emit('ui:navigate', {\n page: 'workspace',\n path: 'settings',\n })\n \">\n <!--\n Only forward the consumer-provided logo (typically a team\n avatar from Scalar Cloud) while the user is actually inside a\n team workspace. Outside of a team context the avatar would be\n misleading, so we omit the `#logo` template entirely and let\n `ScalarMenuButton` fall back to its default Scalar wordmark.\n -->\n <template\n v-if=\"$slots['header-logo'] && app.workspace.isTeamWorkspace.value\"\n #logo>\n <slot\n :isTeamWorkspace=\"app.workspace.isTeamWorkspace.value\"\n name=\"header-logo\" />\n </template>\n <template #menuItems>\n <!--\n The workspace picker used to live here as a submenu. It is now\n surfaced inline in the breadcrumb so the user reaches it in a\n single click. Consumers that want extra menu rows can still\n inject them through the `header-menu-items` slot.\n -->\n <slot name=\"header-menu-items\" />\n </template>\n <template #breadcrumb>\n <DocumentBreadcrumb\n :app=\"app\"\n :fetchRegistryDocument=\"fetchRegistryDocument\"\n :registryDocuments=\"registryDocuments\"\n @createWorkspace=\"createWorkspaceModalState.show()\" />\n </template>\n <template #end>\n <div class=\"flex items-center gap-2\">\n <!--\n Sync status mirrors the icon in the version picker so the\n user can see at a glance whether the active registry-backed\n document is synced / pending push / pending pull / in\n conflict, even when the picker dropdown is closed. We only\n mount it while a document is actually active on the route -\n on workspace-level pages (settings, get-started, etc.)\n there is nothing to sync, and an indicator there would just\n be noise.\n -->\n <DocumentSyncIndicator\n v-if=\"app.activeEntities.documentSlug.value\"\n :app=\"app\"\n :registryDocuments=\"registryDocuments\" />\n <slot\n v-if=\"$slots['header-actions']\"\n name=\"header-actions\" />\n <!--\n Vertical divider between the two trailing slot clusters.\n Only rendered when both `header-actions` and `header-end`\n are provided, so consumers using just one of the slots do\n not get an orphaned separator.\n -->\n <span\n v-if=\"$slots['header-actions'] && $slots['header-end']\"\n aria-hidden=\"true\"\n class=\"bg-border h-4 w-px shrink-0\" />\n <slot\n v-if=\"$slots['header-end']\"\n name=\"header-end\" />\n </div>\n </template>\n </AppHeader>\n <div class=\"flex min-h-0 flex-1 flex-row\">\n <!-- App sidebar -->\n <AppSidebar\n :app=\"app\"\n :fetchRegistryDocument=\"fetchRegistryDocument\"\n :registryDocuments=\"registryDocuments\"\n :sidebarWidth=\"app.sidebar.width.value\"\n @update:sidebarWidth=\"app.sidebar.handleSidebarWidthUpdate\" />\n\n <div class=\"flex min-h-0 flex-1 flex-col\">\n <!-- App Tabs -->\n <DesktopTabs\n v-if=\"layout === 'desktop'\"\n :activeTabIndex=\"app.tabs.activeTabIndex.value\"\n :eventBus=\"app.eventBus\"\n :tabs=\"app.tabs.state.value\" />\n\n <!-- Router view min-h-0 is required for scrolling, do not remove it -->\n <div class=\"bg-b-1 relative min-h-0 flex-1\">\n <RouterView v-bind=\"routerViewProps\" />\n </div>\n </div>\n </div>\n </div>\n\n <slot\n name=\"create-workspace\"\n :state=\"createWorkspaceModalState\">\n <!-- Create workspace modal -->\n <CreateWorkspaceModal\n :state=\"createWorkspaceModalState\"\n @create:workspace=\"(payload) => app.workspace.create(payload)\" />\n </slot>\n <!-- Popup command palette to add resources from anywhere -->\n <TheCommandPalette\n :eventBus=\"app.eventBus\"\n :paletteState=\"paletteState\"\n :workspaceStore=\"app.store.value!\" />\n </main>\n <!-- Splash screen -->\n <main v-else>\n <SplashScreen />\n </main>\n </ScalarTeleportRoot>\n</template>\n\n<style>\n#scalar-client {\n position: relative;\n background-color: var(--scalar-background-2);\n}\n.dark-mode #scalar-client {\n background-color: color-mix(in srgb, var(--scalar-background-1) 65%, black);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"App.vue.script.js","names":["$slots"],"sources":["../../../../src/v2/features/app/App.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Main entry point for the API client for electron and web.\n *\n * This component handles all events and store business logic for the application.\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport { ScalarModal, ScalarTeleportRoot, useModal } from '@scalar/components'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport { extensions } from '@scalar/workspace-store/schemas/extensions'\nimport { computed, onBeforeUnmount, toValue, watch } from 'vue'\nimport { RouterView } from 'vue-router'\n\nimport { SidebarToggle } from '@/v2/components/sidebar'\nimport AppHeader from '@/v2/features/app/components/AppHeader.vue'\nimport AppHeaderActions from '@/v2/features/app/components/AppHeaderActions.vue'\nimport AppSidebar from '@/v2/features/app/components/AppSidebar.vue'\nimport CreateWorkspaceModal from '@/v2/features/app/components/CreateWorkspaceModal.vue'\nimport DocumentBreadcrumb from '@/v2/features/app/components/DocumentBreadcrumb.vue'\nimport PublishDocumentModal from '@/v2/features/app/components/PublishDocumentModal.vue'\nimport SplashScreen from '@/v2/features/app/components/SplashScreen.vue'\nimport SyncConflictResolutionEditor from '@/v2/features/app/components/SyncConflictResolutionEditor.vue'\nimport type { RouteProps } from '@/v2/features/app/helpers/routes'\nimport { useDocumentSync } from '@/v2/features/app/hooks/use-document-sync'\nimport { useDocumentWatcher } from '@/v2/features/app/hooks/use-document-watcher'\nimport type { CommandPaletteState } from '@/v2/features/command-palette/hooks/use-command-palette-state'\nimport TheCommandPalette from '@/v2/features/command-palette/TheCommandPalette.vue'\nimport { useMonacoEditorConfiguration } from '@/v2/features/editor'\nimport { useColorMode } from '@/v2/hooks/use-color-mode'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport type {\n RegistryAdapter,\n RegistryDocumentsState,\n} from '@/v2/types/configuration'\nimport type { ClientLayout } from '@/v2/types/layout'\n\nimport type { AppState } from './app-state'\nimport DesktopTabs from './components/DesktopTabs.vue'\n\nconst {\n layout,\n plugins = [],\n getAppState,\n getCommandPaletteState,\n registry,\n} = defineProps<{\n layout: Exclude<ClientLayout, 'modal'>\n plugins?: ClientPlugin[]\n getAppState: () => AppState\n getCommandPaletteState: () => CommandPaletteState\n /**\n * Adapter wiring the API client up to an external registry (Scalar\n * Cloud or a custom self-hosted setup). The adapter itself is optional\n * - omit it to opt out of registry features entirely - but every\n * field on it (`documents`, `namespaces`, `fetchDocument`,\n * `publishDocument`, `publishVersion`) is required when provided so\n * the client can rely on the full surface.\n */\n registry?: RegistryAdapter\n}>()\n\n/**\n * Reactive view of the registry documents list with a sane default for\n * setups that did not wire an adapter up. The sidebar and breadcrumb\n * read this getter so they keep rendering skeletons / empty states even\n * when the host application has not provided a `registry` prop.\n */\nconst registryDocuments = computed<RegistryDocumentsState>(\n () => registry?.documents ?? { status: 'success', documents: [] },\n)\n\ndefineSlots<{\n /**\n * Replaces the Scalar logo inside the header menu button. Typically used by\n * team-aware consumers (e.g. Scalar Cloud) to render a team avatar so the\n * left-most chrome reads as \"this team's workspace\" rather than the\n * generic Scalar wordmark.\n *\n * Receives `isTeamWorkspace` so consumers can opt into rendering a team\n * image only when the active workspace actually belongs to a team, while\n * keeping the default Scalar logo for local workspaces.\n */\n 'header-logo'?: (payload: { isTeamWorkspace: boolean }) => unknown\n /**\n * Slot for customizing the menu items section of the app header.\n * Defaults to a workspace picker bound to the current app state. Overriding this slot\n * replaces the default picker entirely, so the consumer is responsible for rendering\n * any workspace switcher (or other menu content) they need.\n */\n 'header-menu-items'?: () => unknown\n /**\n * Slot for customizing the end section of the app header.\n * Typically used for user menus, action buttons, or other trailing controls.\n */\n 'header-end'?: () => unknown\n}>()\n\ndefineExpose({\n openCreateWorkspace: () => createWorkspaceModalState.show(),\n})\n\nconst app = getAppState()\nconst paletteState = getCommandPaletteState()\n\n/** Expose workspace store to window for debugging purposes. */\nif (typeof window !== 'undefined') {\n window.dataDumpWorkspace = () => app.store.value\n window.dumpAppState = () => app\n}\n\n/** Call lifecycle hooks on plugins and subscribe to event bus events */\nconst pluginUnsubscribes: (() => void)[] = []\n\nfor (const plugin of plugins) {\n plugin.lifecycle?.onInit?.({ config: { telemetry: app.telemetry.value } })\n\n if (plugin.on) {\n for (const [event, handler] of Object.entries(plugin.on)) {\n pluginUnsubscribes.push(app.eventBus.on(event as any, handler as any))\n }\n }\n}\n\n/** Notify plugins when telemetry config changes */\nwatch(app.telemetry, () => {\n for (const plugin of plugins) {\n plugin.lifecycle?.onConfigChange?.({\n config: { telemetry: app.telemetry.value },\n })\n }\n})\n\nonBeforeUnmount(() => {\n for (const unsub of pluginUnsubscribes) {\n unsub()\n }\n for (const plugin of plugins) {\n plugin.lifecycle?.onDestroy?.()\n }\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(app.eventBus, layout)\n\nconst DEFAULT_DOCUMENT_WATCH_TIMEOUT = 5000\n\n/** Watch the active document for changes and rebase it with its remote source */\nuseDocumentWatcher({\n documentName: () =>\n app.store.value?.workspace[extensions.workspace.activeDocument],\n store: app.store,\n initialTimeout: DEFAULT_DOCUMENT_WATCH_TIMEOUT,\n})\n\n/** Color mode */\nuseColorMode({ workspaceStore: app.store })\n\nconst currentTheme = computed(() => app.theme.styles.value.themeStyles)\nconst isDarkMode = computed(() => app.isDarkMode.value)\n\n/** Setup monaco editor configuration */\nuseMonacoEditorConfiguration({\n theme: currentTheme,\n darkMode: isDarkMode,\n})\n\nconst createWorkspaceModalState = useModal()\n\n/**\n * Owns the document-level Save / Revert / Pull / Push / Publish flow.\n * Keeping it in a dedicated hook leaves this component focused on\n * routing, layout, and slot composition.\n */\nconst {\n showLocalSaveActions,\n showTeamSyncActions,\n showTeamPublishAction,\n hasHeaderActionCluster,\n isActiveDocumentDirty,\n isOffline,\n canPullActiveDocument,\n canPushActiveDocument,\n publishDocumentModalState,\n syncConflictModalState,\n pendingPullState,\n publishDefaultSlug,\n publishDefaultVersion,\n registryNamespaces,\n handleSaveDocument,\n handleRevertDocument,\n handlePullDocument,\n handlePushDocument,\n handlePublishDocument,\n handlePublishDocumentSubmit,\n handleSyncConflictApplyChanges,\n handleSyncConflictModalClose,\n} = useDocumentSync({\n app,\n registry,\n registryDocuments: () => registryDocuments.value,\n})\n\n/** Props to pass to the RouterView component. */\nconst routerViewProps = computed<RouteProps>(() => {\n return {\n documentSlug: app.activeEntities.documentSlug.value ?? '',\n document: app.store.value?.workspace.activeDocument ?? null,\n environment: app.environment.value,\n eventBus: app.eventBus,\n exampleName: app.activeEntities.exampleName.value,\n fetchRegistryDocument: registry?.fetchDocument,\n layout,\n method: app.activeEntities.method.value,\n path: app.activeEntities.path.value,\n workspaceStore: app.store.value!,\n activeWorkspace: app.workspace.activeWorkspace.value!,\n isTeamWorkspace: app.workspace.isTeamWorkspace.value,\n plugins,\n isDarkMode: app.isDarkMode.value,\n currentTheme: app.theme.styles.value.themeStyles,\n customThemes: toValue(app.theme.customThemes),\n telemetry: app.telemetry.value,\n onUpdateTelemetry: (value: boolean) => {\n app.telemetry.value = value\n },\n options: app.options,\n }\n})\n</script>\n\n<template>\n <ScalarTeleportRoot>\n <!-- Theme style tag -->\n <div v-html=\"app.theme.themeStyleTag.value\" />\n\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- Main content -->\n <main\n v-if=\"\n app.store.value !== null &&\n app.workspace.activeWorkspace.value !== null &&\n !app.loading.value\n \">\n <div\n class=\"relative flex h-dvh w-dvw flex-col\"\n :style=\"{\n '--app-desktop-tabs-height': layout === 'desktop' ? '2.5rem' : '0px',\n }\">\n <!--\n Sits in the same visual slot as the operation Header gutter (size-8).\n Offset = desktop tab strip (layout desktop only) + ScalarHeader (min-h-header)\n + OperationBlock outer p-2 + Header pt-2 (1rem total) so we clear app chrome.\n `--app-desktop-tabs-height` is set on this shell so the mobile sidebar inset\n matches (see AppSidebar).\n -->\n <SidebarToggle\n v-model=\"app.sidebar.isOpen.value\"\n class=\"app-no-drag-region absolute top-[calc(var(--app-desktop-tabs-height)+var(--spacing-header,48px)+1rem)] left-4 z-60 md:hidden\" />\n <!-- App Tabs -->\n <DesktopTabs\n v-if=\"layout === 'desktop'\"\n :activeTabIndex=\"app.tabs.activeTabIndex.value\"\n :eventBus=\"app.eventBus\"\n :tabs=\"app.tabs.state.value\" />\n <AppHeader\n :menuTitle=\"app.workspace.isTeamWorkspace.value ? 'Team' : 'Local'\"\n @navigate:to:settings=\"\n app.eventBus.emit('ui:navigate', {\n page: 'workspace',\n path: 'settings',\n })\n \">\n <!--\n Only forward the consumer-provided logo (typically a team\n avatar from Scalar Cloud) while the user is actually inside a\n team workspace. Outside of a team context the avatar would be\n misleading, so we omit the `#logo` template entirely and let\n `ScalarMenuButton` fall back to its default Scalar wordmark.\n -->\n <template\n v-if=\"$slots['header-logo'] && app.workspace.isTeamWorkspace.value\"\n #logo>\n <slot\n :isTeamWorkspace=\"app.workspace.isTeamWorkspace.value\"\n name=\"header-logo\" />\n </template>\n <template #menuItems>\n <!--\n The workspace picker used to live here as a submenu. It is now\n surfaced inline in the breadcrumb so the user reaches it in a\n single click. Consumers that want extra menu rows can still\n inject them through the `header-menu-items` slot.\n -->\n <slot name=\"header-menu-items\" />\n </template>\n <template #breadcrumb>\n <DocumentBreadcrumb\n :app=\"app\"\n :fetchRegistryDocument=\"registry?.fetchDocument\"\n :registryDocuments=\"registryDocuments\"\n @createWorkspace=\"createWorkspaceModalState.show()\" />\n </template>\n <!--\n Only forward the trailing `#end` cluster when it has actual\n content. The action clusters and the consumer slots all gate\n independently, so we mirror those conditions on the wrapper to\n avoid mounting an empty cluster that would otherwise leak a\n stray divider.\n -->\n <template\n v-if=\"\n hasHeaderActionCluster ||\n $slots['header-actions'] ||\n $slots['header-end']\n \"\n #end>\n <div class=\"flex items-center gap-2\">\n <AppHeaderActions\n :canPullActiveDocument=\"canPullActiveDocument\"\n :canPushActiveDocument=\"canPushActiveDocument\"\n :isActiveDocumentDirty=\"isActiveDocumentDirty\"\n :isOffline=\"isOffline\"\n :showLocalSaveActions=\"showLocalSaveActions\"\n :showTeamPublishAction=\"showTeamPublishAction\"\n :showTeamSyncActions=\"showTeamSyncActions\"\n @publish=\"handlePublishDocument\"\n @pull=\"handlePullDocument\"\n @push=\"handlePushDocument\"\n @revert=\"handleRevertDocument\"\n @save=\"handleSaveDocument\" />\n <!--\n Vertical divider\n -->\n <span\n v-if=\"$slots['header-end']\"\n aria-hidden=\"true\"\n class=\"bg-border h-4 w-px shrink-0\" />\n <slot\n v-if=\"$slots['header-end']\"\n name=\"header-end\" />\n </div>\n </template>\n </AppHeader>\n <div class=\"flex min-h-0 flex-1 flex-row\">\n <!-- App sidebar -->\n <AppSidebar\n :app=\"app\"\n :fetchRegistryDocument=\"registry?.fetchDocument\"\n :registryDocuments=\"registryDocuments\"\n :sidebarWidth=\"app.sidebar.width.value\"\n @update:sidebarWidth=\"app.sidebar.handleSidebarWidthUpdate\" />\n\n <!-- Router view min-h-0 is required for scrolling, do not remove it -->\n <div class=\"bg-b-1 relative min-h-0 flex-1\">\n <RouterView v-bind=\"routerViewProps\" />\n </div>\n </div>\n </div>\n <!-- Create workspace modal -->\n <CreateWorkspaceModal\n :state=\"createWorkspaceModalState\"\n @create:workspace=\"(payload) => app.workspace.create(payload)\" />\n\n <!--\n First-time publish modal. Only mounted when a registry adapter\n is wired up - without one there is nothing meaningful to send,\n and the modal would never be opened anyway.\n -->\n <PublishDocumentModal\n v-if=\"registry\"\n :defaultSlug=\"publishDefaultSlug\"\n :defaultVersion=\"publishDefaultVersion\"\n :namespaces=\"registryNamespaces\"\n :state=\"publishDocumentModalState\"\n @submit=\"handlePublishDocumentSubmit\" />\n <!--\n Three-way merge editor for the Pull flow. We mount it lazily on\n `pendingPullState` so the heavy Monaco editors only spin up when\n a pull actually has conflicts to walk through. The full-size\n layout mirrors `DocumentCollection.vue`'s sync modal so the\n editor has enough room to render the local / remote / result\n panes side-by-side.\n -->\n <ScalarModal\n v-if=\"pendingPullState\"\n bodyClass=\"sync-conflict-modal-root flex h-dvh flex-col p-4\"\n maxWidth=\"calc(100dvw - 32px)\"\n size=\"full\"\n :state=\"syncConflictModalState\"\n @close=\"handleSyncConflictModalClose\">\n <div class=\"flex h-full w-full flex-col gap-4 overflow-hidden\">\n <SyncConflictResolutionEditor\n :baseDocument=\"pendingPullState.rebaseResult.originalDocument\"\n :conflicts=\"pendingPullState.rebaseResult.conflicts\"\n :resolvedDocument=\"pendingPullState.rebaseResult.resolvedDocument\"\n @applyChanges=\"handleSyncConflictApplyChanges\" />\n </div>\n </ScalarModal>\n <!-- Popup command palette to add resources from anywhere -->\n <TheCommandPalette\n :eventBus=\"app.eventBus\"\n :paletteState=\"paletteState\"\n :workspaceStore=\"app.store.value!\" />\n </main>\n <!-- Splash screen -->\n <main v-else>\n <SplashScreen />\n </main>\n </ScalarTeleportRoot>\n</template>\n\n<style>\n#scalar-client {\n position: relative;\n background-color: var(--scalar-background-2);\n}\n.dark-mode #scalar-client {\n background-color: color-mix(in srgb, var(--scalar-background-1) 65%, black);\n}\n\n/*\n * The three-way merge editor needs the full viewport to fit its three\n * Monaco panes. `DocumentCollection.vue` ships the same override for\n * its in-page Sync modal, but the pull flow can run without that view\n * being mounted, so we duplicate the rule here to keep the modal\n * full-bleed.\n */\n.full-size-styles:has(.sync-conflict-modal-root) {\n width: 100dvw !important;\n max-width: 100dvw !important;\n border-right: none !important;\n}\n\n.full-size-styles:has(.sync-conflict-modal-root)::after {\n display: none;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ScalarListboxOption, WorkspaceGroup } from '@scalar/components';
|
|
2
2
|
import type { HttpMethod } from '@scalar/helpers/http/http-methods';
|
|
3
3
|
import type { LoaderPlugin } from '@scalar/json-magic/bundle';
|
|
4
|
+
import type { Team } from '@scalar/sdk/models/components';
|
|
4
5
|
import { createSidebarState } from '@scalar/sidebar';
|
|
5
6
|
import type { Theme } from '@scalar/themes';
|
|
6
7
|
import { type WorkspaceStore } from '@scalar/workspace-store/client';
|
|
@@ -80,6 +81,12 @@ export type AppState = {
|
|
|
80
81
|
} | null>;
|
|
81
82
|
/** Navigates to the specified workspace */
|
|
82
83
|
navigateToWorkspace: (teamSlug?: string, slug?: string) => Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Routes to the get-started page of a workspace identified by id.
|
|
86
|
+
* Mirrors the picker affordances in the breadcrumb and header menu
|
|
87
|
+
* so both surfaces stay in sync when the user switches workspaces.
|
|
88
|
+
*/
|
|
89
|
+
navigateToWorkspaceGetStarted: (workspaceId: string) => void;
|
|
83
90
|
/** Whether the workspace page is open */
|
|
84
91
|
isOpen: ComputedRef<boolean>;
|
|
85
92
|
/**
|
|
@@ -113,8 +120,6 @@ export type AppState = {
|
|
|
113
120
|
exampleName: Ref<string | undefined>;
|
|
114
121
|
/** The slug of the selected team context (read-only; use setTeamSlug to change) */
|
|
115
122
|
teamSlug: Readonly<Ref<string>>;
|
|
116
|
-
/** Sets the current team context by team slug */
|
|
117
|
-
setTeamSlug: (value: string) => void;
|
|
118
123
|
};
|
|
119
124
|
/** The currently active environment */
|
|
120
125
|
environment: ComputedRef<XScalarEnvironment>;
|
|
@@ -136,20 +141,11 @@ export type AppState = {
|
|
|
136
141
|
};
|
|
137
142
|
telemetry: Ref<boolean>;
|
|
138
143
|
};
|
|
139
|
-
|
|
140
|
-
export declare const DEFAULT_TEAM_WORKSPACE_SLUG = "default";
|
|
141
|
-
/**
|
|
142
|
-
* Temporary kill switch for team workspace functionality.
|
|
143
|
-
*
|
|
144
|
-
* While the team workspace experience is still being polished we hide the
|
|
145
|
-
* "Team Workspaces" group from the picker and refuse to create new team
|
|
146
|
-
* workspaces. Existing team workspaces remain in storage and can be restored
|
|
147
|
-
* by flipping this flag back to `true`.
|
|
148
|
-
*/
|
|
149
|
-
export declare const TEAM_WORKSPACES_ENABLED = false;
|
|
150
|
-
export declare const createAppState: ({ router, fileLoader, fallbackThemeSlug, customThemes, telemetryDefault, options, }: {
|
|
144
|
+
export declare const createAppState: ({ router, fileLoader, currentTeam, fallbackThemeSlug, customThemes, telemetryDefault, options, }: {
|
|
151
145
|
router: Router;
|
|
152
146
|
fileLoader?: LoaderPlugin;
|
|
147
|
+
/** The currently active team */
|
|
148
|
+
currentTeam?: MaybeRefOrGetter<Team | undefined>;
|
|
153
149
|
customThemes?: MaybeRefOrGetter<Theme[]>;
|
|
154
150
|
fallbackThemeSlug?: MaybeRefOrGetter<string>;
|
|
155
151
|
telemetryDefault?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-state.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/app/app-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,EAAE,kBAAkB,EAAwB,MAAM,iBAAiB,CAAA;AAC1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,gCAAgC,CAAA;AAC1F,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,gCAAgC,CAAA;AAMvC,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAEnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oEAAoE,CAAA;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,GAAG,EACR,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"app-state.d.ts","sourceRoot":"","sources":["../../../../src/v2/features/app/app-state.ts"],"names":[],"mappings":"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"}
|