@meshmakers/shared-ui 3.4.1480 → 3.5.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.
Files changed (56) hide show
  1. package/README.md +48 -0
  2. package/assets/octobot/lg/octo_blink.webp +0 -0
  3. package/assets/octobot/lg/octo_blink_still.png +0 -0
  4. package/assets/octobot/lg/octo_idle.webp +0 -0
  5. package/assets/octobot/lg/octo_idle_still.png +0 -0
  6. package/assets/octobot/lg/octo_look.webp +0 -0
  7. package/assets/octobot/lg/octo_look_still.png +0 -0
  8. package/assets/octobot/lg/octo_swim.webp +0 -0
  9. package/assets/octobot/lg/octo_swim_still.png +0 -0
  10. package/assets/octobot/lg/octo_thinking.webp +0 -0
  11. package/assets/octobot/lg/octo_thinking_still.png +0 -0
  12. package/assets/octobot/lg/octo_wave.webp +0 -0
  13. package/assets/octobot/lg/octo_wave_still.png +0 -0
  14. package/assets/octobot/md/octo_blink.webp +0 -0
  15. package/assets/octobot/md/octo_blink_still.png +0 -0
  16. package/assets/octobot/md/octo_idle.webp +0 -0
  17. package/assets/octobot/md/octo_idle_still.png +0 -0
  18. package/assets/octobot/md/octo_look.webp +0 -0
  19. package/assets/octobot/md/octo_look_still.png +0 -0
  20. package/assets/octobot/md/octo_swim.webp +0 -0
  21. package/assets/octobot/md/octo_swim_still.png +0 -0
  22. package/assets/octobot/md/octo_thinking.webp +0 -0
  23. package/assets/octobot/md/octo_thinking_still.png +0 -0
  24. package/assets/octobot/md/octo_wave.webp +0 -0
  25. package/assets/octobot/md/octo_wave_still.png +0 -0
  26. package/assets/octobot/sm/octo_blink.webp +0 -0
  27. package/assets/octobot/sm/octo_blink_still.png +0 -0
  28. package/assets/octobot/sm/octo_idle.webp +0 -0
  29. package/assets/octobot/sm/octo_idle_still.png +0 -0
  30. package/assets/octobot/sm/octo_look.webp +0 -0
  31. package/assets/octobot/sm/octo_look_still.png +0 -0
  32. package/assets/octobot/sm/octo_swim.webp +0 -0
  33. package/assets/octobot/sm/octo_swim_still.png +0 -0
  34. package/assets/octobot/sm/octo_thinking.webp +0 -0
  35. package/assets/octobot/sm/octo_thinking_still.png +0 -0
  36. package/assets/octobot/sm/octo_wave.webp +0 -0
  37. package/assets/octobot/sm/octo_wave_still.png +0 -0
  38. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs +940 -0
  39. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs.map +1 -0
  40. package/fesm2022/meshmakers-shared-ui-assistant.mjs +819 -0
  41. package/fesm2022/meshmakers-shared-ui-assistant.mjs.map +1 -0
  42. package/fesm2022/meshmakers-shared-ui-command-palette.mjs +817 -0
  43. package/fesm2022/meshmakers-shared-ui-command-palette.mjs.map +1 -0
  44. package/fesm2022/meshmakers-shared-ui-shell.mjs +1738 -0
  45. package/fesm2022/meshmakers-shared-ui-shell.mjs.map +1 -0
  46. package/fesm2022/meshmakers-shared-ui-testing.mjs +92 -0
  47. package/fesm2022/meshmakers-shared-ui-testing.mjs.map +1 -0
  48. package/fesm2022/meshmakers-shared-ui.mjs +1550 -203
  49. package/fesm2022/meshmakers-shared-ui.mjs.map +1 -1
  50. package/package.json +28 -2
  51. package/types/meshmakers-shared-ui-assistant-core.d.ts +732 -0
  52. package/types/meshmakers-shared-ui-assistant.d.ts +258 -0
  53. package/types/meshmakers-shared-ui-command-palette.d.ts +398 -0
  54. package/types/meshmakers-shared-ui-shell.d.ts +939 -0
  55. package/types/meshmakers-shared-ui-testing.d.ts +41 -0
  56. package/types/meshmakers-shared-ui.d.ts +1004 -154
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meshmakers-shared-ui-command-palette.mjs","sources":["../../../../projects/meshmakers/shared-ui/command-palette/src/command-palette.models.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/command-palette.messages.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/command-palette.service.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/palette-navigation.service.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/palette-query.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/palette-search.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/palette-ranking.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/command-palette.component.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/command-palette.component.html","../../../../projects/meshmakers/shared-ui/command-palette/src/public-api.ts","../../../../projects/meshmakers/shared-ui/command-palette/src/meshmakers-shared-ui-command-palette.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { SVGIcon } from '@progress/kendo-svg-icons';\nimport { Observable } from 'rxjs';\n\n/**\n * Result groups of the command palette, in the vocabulary of\n * `docs/concepts/ui-concept-ai-os.md` §4.1. The group decides the section\n * header a result is listed under and which typed prefix scopes to it.\n */\nexport type PaletteGroup = 'recent' | 'page' | 'action' | 'entity' | 'board' | 'tenant' | 'ai';\n\n/** How a result is opened: Enter opens in place, Cmd/Ctrl+Enter in a new browser tab. */\nexport type PaletteRunMode = 'open' | 'newTab';\n\n/**\n * What the palette does after a result or action ran. By default it closes;\n * an outcome with `query` keeps it open and replaces the query (e.g. \"Switch\n * tenant…\" re-scopes the palette to `/`).\n */\nexport interface PaletteRunOutcome {\n query: string;\n}\n\nexport type PaletteRunResult = PaletteRunOutcome | void;\n\n/** One entry of a result's actions sub-menu (opened with Tab). */\nexport interface PaletteAction {\n id: string;\n label: string;\n /** Keyboard hint shown on the right, e.g. '↵'. */\n hint?: string;\n run(): Promise<PaletteRunResult>;\n}\n\n/** One row of the palette. Providers create them; the ranking orders them. */\nexport interface PaletteResult {\n /** Unique and stable across searches (prefix it with the provider id). */\n id: string;\n group: PaletteGroup;\n label: string;\n /** Secondary text on the right, e.g. \"Adapter · Online\". */\n description?: string;\n /** Where the result lives, e.g. ['Integration'] — rendered \"Integration ›\". */\n path?: string[];\n /** Technical id rendered in mono type, e.g. an rtId or ckTypeId. */\n typeHint?: string;\n icon?: SVGIcon;\n /** One-character text icon used when there is no SVG icon. */\n glyph?: string;\n /** Extra search terms (matched one tier below the label). */\n keywords?: string[];\n /** Key into the recents store; results with a key get the frecency boost. */\n recentKey?: string;\n /** Set by entity providers when the query was this result's exact id: ranks first. */\n exactMatch?: boolean;\n /**\n * Extra ranking weight 0…1 on top of the frecency, e.g. 1 for a pinned board, so pinned\n * and recently used rows lead their group (only orders within a match tier).\n */\n rankBoost?: number;\n /** Keep this row after ranking even without a text match (e.g. the assistant fallback). */\n alwaysShow?: boolean;\n run(mode: PaletteRunMode): Promise<PaletteRunResult>;\n /** Sub-menu opened with Tab. */\n actions?: PaletteAction[];\n}\n\n/** A parsed palette query: an optional scope from a typed prefix plus the search text. */\nexport interface PaletteQuery {\n /** The input exactly as typed. */\n raw: string;\n /** The prefix character when one was typed ('>', '@', '#', '/', '?'). */\n prefix: string | null;\n /** The group the prefix scopes to, or null for an unscoped search. */\n scope: PaletteGroup | null;\n /** The search text without the prefix, trimmed. */\n text: string;\n}\n\n/**\n * One async result source. The palette calls `search` for every query\n * change; a new query unsubscribes the previous search (cancellation), and a\n * provider with `debounceMs` is only asked once typing paused that long.\n * A provider error drops that provider's rows only.\n */\nexport interface PaletteProvider {\n /** Stable id, used to prefix result ids. */\n readonly id: string;\n /** Groups this provider produces; a scoped query skips providers without that group. */\n readonly groups: readonly PaletteGroup[];\n /** Remote providers debounce (§4.2: 150 ms); local ones answer immediately. */\n readonly debounceMs?: number;\n search(query: PaletteQuery): Observable<PaletteResult[]>;\n /** Called whenever the palette opens: drop per-session caches (visibility gates, pages). */\n reset?(): void;\n}\n\n/** Multi-provider token for the palette sources: `{ provide: PALETTE_PROVIDERS, useClass: MyProvider, multi: true }`. */\nexport const PALETTE_PROVIDERS = new InjectionToken<PaletteProvider[]>('PALETTE_PROVIDERS');\n\n/**\n * Where the palette reads the frecency of recently used results (the boost for rows with a\n * `recentKey`). Optional: without a source every frecency is 0. Read once per palette session.\n *\n * ```ts\n * { provide: PALETTE_RECENT_ITEMS_SOURCE, useFactory: () => {\n * const recents = inject(RecentItemsService);\n * return { frecencies: now => new Map(recents.items(now).map(i => [i.key, normalizedFrecency(i, now)])) };\n * } }\n * ```\n */\nexport interface PaletteRecentItemsSource {\n /** Normalised frecency 0…1 per `recentKey` at `now` (ms since epoch). */\n frecencies(now: number): ReadonlyMap<string, number>;\n}\n\nexport const PALETTE_RECENT_ITEMS_SOURCE = new InjectionToken<PaletteRecentItemsSource>('PALETTE_RECENT_ITEMS_SOURCE');\n","import { computed, inject, InjectionToken, Signal } from '@angular/core';\nimport { PaletteGroup } from './command-palette.models';\n\n/**\n * UI strings of the command palette (`mm-command-palette`) and of\n * {@link PaletteNavigationService}'s clipboard notifications.\n *\n * Provide translations app wide with {@link COMMAND_PALETTE_MESSAGES} or per instance with the\n * component's `messages` input (wins over the token). Missing, `undefined` or `null` members keep\n * the English default of {@link DEFAULT_COMMAND_PALETTE_MESSAGES}; `{name}` placeholders are\n * filled with {@link formatCommandPaletteMessage}.\n */\nexport interface CommandPaletteMessages {\n /** `aria-label` of the dialog. */\n dialogLabel: string;\n /** `aria-label` of the search input. */\n inputLabel: string;\n placeholder: string;\n /** Close button on phones. */\n cancel: string;\n /** `aria-label` of the result list. */\n results: string;\n /** `aria-label` of the actions sub-menu; `{label}` = result label. */\n actionsFor: string;\n /** Header of the actions sub-menu; `{label}` = result label. */\n actionsHeader: string;\n /** Tooltip of the Tab hint on rows with actions. */\n tabForActions: string;\n /** Live status with one result. */\n oneResult: string;\n /** Live status; `{count}` = number of results. */\n manyResults: string;\n /** Empty list with a search text; `{text}` = search text. */\n noResultsFor: string;\n /** Empty list without a search text. */\n typeToSearch: string;\n // --- Footer ---\n footerMove: string;\n footerOpen: string;\n footerNewTab: string;\n footerActions: string;\n prefixActions: string;\n prefixEntities: string;\n prefixBoards: string;\n prefixTenants: string;\n // --- Group headers ---\n groupRecent: string;\n groupPage: string;\n groupAction: string;\n groupEntity: string;\n groupBoard: string;\n groupTenant: string;\n groupAi: string;\n // --- Clipboard (PaletteNavigationService.copy) ---\n /** `{label}` = what was copied, e.g. \"RtId\". */\n copied: string;\n copyFailed: string;\n}\n\nexport const DEFAULT_COMMAND_PALETTE_MESSAGES: CommandPaletteMessages = {\n dialogLabel: 'Command palette',\n inputLabel: 'Search pages, entities, boards, tenants and commands',\n placeholder: 'Search pages, entities, boards…',\n cancel: 'Cancel',\n results: 'Results',\n actionsFor: 'Actions for {label}',\n actionsHeader: '{label} · Actions',\n tabForActions: 'Tab: actions',\n oneResult: '1 result',\n manyResults: '{count} results',\n noResultsFor: 'No results for “{text}”',\n typeToSearch: 'Type to search',\n footerMove: 'move',\n footerOpen: 'open',\n footerNewTab: 'new tab',\n footerActions: 'actions',\n prefixActions: 'actions',\n prefixEntities: 'entities',\n prefixBoards: 'boards',\n prefixTenants: 'tenants',\n groupRecent: 'Recent',\n groupPage: 'Pages',\n groupAction: 'Actions',\n groupEntity: 'Entities',\n groupBoard: 'Boards',\n groupTenant: 'Tenants',\n groupAi: 'Assistant',\n copied: '{label} copied',\n copyFailed: 'Failed to copy to clipboard',\n};\n\n/** App-wide translations of the command palette (partial). */\nexport const COMMAND_PALETTE_MESSAGES = new InjectionToken<Partial<CommandPaletteMessages>>('COMMAND_PALETTE_MESSAGES');\n\n/** Merges overrides over {@link DEFAULT_COMMAND_PALETTE_MESSAGES}, later sources winning; null/undefined members are ignored. */\nexport function resolveCommandPaletteMessages(\n ...overrides: (Partial<CommandPaletteMessages> | null | undefined)[]\n): CommandPaletteMessages {\n const resolved: CommandPaletteMessages = { ...DEFAULT_COMMAND_PALETTE_MESSAGES };\n for (const messages of overrides) {\n if (!messages) {\n continue;\n }\n for (const key of Object.keys(messages) as (keyof CommandPaletteMessages)[]) {\n const value = messages[key];\n if (value !== undefined && value !== null) {\n resolved[key] = value;\n }\n }\n }\n return resolved;\n}\n\n/** Replaces `{name}` placeholders; unknown placeholders stay as they are. */\nexport function formatCommandPaletteMessage(message: string, values: Record<string, string | number>): string {\n return message.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match);\n}\n\n/** The group header of a result group. */\nexport function paletteGroupLabel(group: PaletteGroup, messages: CommandPaletteMessages): string {\n switch (group) {\n case 'recent': return messages.groupRecent;\n case 'page': return messages.groupPage;\n case 'action': return messages.groupAction;\n case 'entity': return messages.groupEntity;\n case 'board': return messages.groupBoard;\n case 'tenant': return messages.groupTenant;\n case 'ai': return messages.groupAi;\n }\n}\n\n/**\n * {@link COMMAND_PALETTE_MESSAGES} merged with a component input (the input wins).\n * Call it in an injection context.\n * @internal\n */\nexport function commandPaletteMessages(\n input: Signal<Partial<CommandPaletteMessages> | null | undefined>\n): Signal<CommandPaletteMessages> {\n const injected = inject(COMMAND_PALETTE_MESSAGES, { optional: true });\n return computed(() => resolveCommandPaletteMessages(injected, input()));\n}\n","import { Injectable, signal } from '@angular/core';\n\n/** A request to show the palette with a query; a new object per call so effects re-run. */\nexport interface PaletteOpenRequest {\n query: string;\n}\n\n/**\n * Opens and closes the command palette (Cmd/Ctrl+K). The host (AppComponent) renders\n * the overlay and binds the global hotkey; anything else — the top bar's\n * \"Search ⌘K\" trigger, a Home tile, an empty state — calls {@link open}.\n *\n * Focus returns to the element that had it when the palette opened.\n */\n@Injectable({ providedIn: 'root' })\nexport class CommandPaletteService {\n private readonly _isOpen = signal(false);\n private readonly _request = signal<PaletteOpenRequest>({ query: '' });\n private returnFocusTo: HTMLElement | null = null;\n\n /** Whether the palette is shown. */\n readonly isOpen = this._isOpen.asReadonly();\n /** The latest open request; the palette adopts its query (also while already open). */\n readonly request = this._request.asReadonly();\n\n /**\n * Shows the palette. `initialQuery` pre-fills the input, e.g. `'>'` for\n * actions or `'/'` for the tenant list. Calling it while open replaces the query.\n */\n open(initialQuery = ''): void {\n if (!this._isOpen()) {\n const active = document.activeElement;\n this.returnFocusTo = active instanceof HTMLElement && active !== document.body ? active : null;\n }\n this._request.set({ query: initialQuery });\n this._isOpen.set(true);\n }\n\n /** Hides the palette and gives focus back to where it was. */\n close(): void {\n if (!this._isOpen()) {\n return;\n }\n this._isOpen.set(false);\n const target = this.returnFocusTo;\n this.returnFocusTo = null;\n if (target?.isConnected) {\n target.focus();\n }\n }\n\n /** Opens when closed, closes when open. */\n toggle(initialQuery = ''): void {\n if (this._isOpen()) {\n this.close();\n } else {\n this.open(initialQuery);\n }\n }\n}\n\n/** What a global keydown should do to the palette. */\nexport type PaletteHotkeyAction = 'toggle' | 'open';\n\n/**\n * Maps a document keydown to a palette action (ui-concept §4.3):\n *\n * - Cmd+K (macOS) / Ctrl+K toggles — except inside a Monaco code editor,\n * whose own Cmd+K chords (comment, format …) must keep working;\n * - `/` opens when no text field, text role, grid or Kendo widget is focused;\n * - everything else, and events another handler already consumed, is ignored.\n */\nexport function paletteHotkeyAction(event: KeyboardEvent, isOpen: boolean): PaletteHotkeyAction | null {\n if (event.defaultPrevented || event.isComposing) {\n return null;\n }\n const key = event.key?.toLowerCase();\n const target = event.target instanceof Element ? event.target : null;\n if (key === 'k' && (event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey) {\n return target?.closest('.monaco-editor') ? null : 'toggle';\n }\n if (event.key === '/' && !isOpen && !event.metaKey && !event.ctrlKey && !event.altKey && !isEditable(target)) {\n return 'open';\n }\n return null;\n}\n\n/**\n * Targets where `/` is typed or means something else: text fields, ARIA text\n * roles, grids (Kendo grid keyboard navigation) and Kendo widgets.\n */\nconst TEXT_ENTRY_SELECTOR = [\n 'input', 'textarea', 'select', '[contenteditable=\"\"]', '[contenteditable=\"true\"]',\n '[role=\"combobox\"]', '[role=\"textbox\"]', '[role=\"searchbox\"]', '[role=\"spinbutton\"]',\n '[role=\"grid\"]', '[role=\"gridcell\"]', '[role=\"treegrid\"]',\n '.k-grid', 'kendo-grid', '.k-input', '.k-widget', '.monaco-editor'\n].join(', ');\n\nfunction isEditable(element: Element | null): boolean {\n if (!element) {\n return false;\n }\n if (element instanceof HTMLElement && element.isContentEditable) {\n return true;\n }\n return element.closest(TEXT_ENTRY_SELECTOR) !== null;\n}\n","import { Injectable, inject } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { NotificationDisplayService } from '@meshmakers/shared-ui';\nimport { PaletteRunMode } from './command-palette.models';\nimport { COMMAND_PALETTE_MESSAGES, formatCommandPaletteMessage, resolveCommandPaletteMessages } from './command-palette.messages';\n\n/**\n * Navigation and clipboard helpers shared by the palette providers. All\n * palette targets are absolute router URLs (`/<tenant>/…`), so a result\n * behaves the same whichever page the palette was opened on.\n */\n@Injectable({ providedIn: 'root' })\nexport class PaletteNavigationService {\n private readonly router = inject(Router);\n private readonly notifications = inject(NotificationDisplayService);\n private readonly messages = resolveCommandPaletteMessages(inject(COMMAND_PALETTE_MESSAGES, { optional: true }));\n\n /** The tenant of the current URL (first path segment), or null outside a tenant. */\n currentTenantId(): string | null {\n const path = (this.router.url ?? '').split('#')[0].split('?')[0];\n const first = path.split('/').find(segment => segment.length > 0);\n return first ? decodeURIComponent(first.split(';')[0]) : null;\n }\n\n /**\n * Turns a command link into an absolute URL: links starting with `/` are\n * absolute already, all others are relative to the tenant (as the drawer\n * resolves them via `navigateRelativeToRoute`).\n */\n tenantUrl(link: string): string {\n if (link.startsWith('/')) {\n return link;\n }\n const tenantId = this.currentTenantId();\n const relative = link.replace(/^\\.?\\/?/, '');\n return tenantId ? `/${encodeURIComponent(tenantId)}${relative ? '/' + relative : ''}` : `/${relative}`;\n }\n\n /** Opens an absolute router URL in place or in a new browser tab. */\n async open(url: string, mode: PaletteRunMode = 'open'): Promise<void> {\n if (mode === 'newTab') {\n window.open(this.toHref(url), '_blank', 'noopener');\n return;\n }\n await this.router.navigateByUrl(url);\n }\n\n /** Opens an external link (href) in a new tab, as the drawer does. */\n openExternal(href: string, target = '_blank'): void {\n window.open(href, target, 'noopener,noreferrer');\n }\n\n /** Copies a value and confirms it with a short notification. */\n async copy(value: string, label: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(value);\n this.notifications.showSuccess(formatCommandPaletteMessage(this.messages.copied, { label }), 2000);\n } catch (error) {\n console.error('Failed to copy to clipboard:', error);\n this.notifications.showError(this.messages.copyFailed);\n }\n }\n\n private toHref(url: string): string {\n try {\n return new URL(`.${url}`, document.baseURI).href;\n } catch {\n return url;\n }\n }\n}\n","import { PaletteGroup, PaletteQuery } from './command-palette.models';\n\n/** Typed prefixes that force a group (ui-concept §4.2 rule 4). */\nexport const PALETTE_PREFIXES: Readonly<Record<string, PaletteGroup>> = {\n '>': 'action',\n '@': 'entity',\n '#': 'board',\n '/': 'tenant',\n '?': 'ai'\n};\n\n/**\n * Splits the raw input into an optional scope and the search text:\n * `\"> theme\"` → scope `action`, text `theme`; `\"edge\"` → no scope.\n * Only the first non-blank character counts as a prefix.\n */\nexport function parsePaletteQuery(raw: string): PaletteQuery {\n const trimmed = (raw ?? '').trim();\n const first = trimmed.charAt(0);\n const scope = PALETTE_PREFIXES[first] ?? null;\n if (scope) {\n return { raw, prefix: first, scope, text: trimmed.slice(1).trim() };\n }\n return { raw, prefix: null, scope: null, text: trimmed };\n}\n\n/** A runtime id: 24 hex characters (MongoDB ObjectId). */\nexport function isRtId(text: string): boolean {\n return /^[0-9a-f]{24}$/i.test(text);\n}\n","import { combineLatest, defer, Observable, of, timer } from 'rxjs';\nimport { catchError, map, startWith, switchMap } from 'rxjs/operators';\nimport { PaletteProvider, PaletteQuery, PaletteResult } from './command-palette.models';\n\n/**\n * Runs every provider for every query and merges their rows.\n *\n * - A provider whose groups do not include the query's scope is skipped (its rows clear at once).\n * - A new query cancels the provider's running search (`switchMap` unsubscribes).\n * - Providers with `debounceMs` start only after the query stood still that long; until\n * then their previous rows stay, so remote results do not flicker away while typing\n * (the ranking drops rows that no longer match).\n * - An error drops only that provider's rows.\n *\n * The output emits on every provider answer, so local rows show immediately\n * and remote rows stream in.\n */\nexport function searchProviders(\n providers: readonly PaletteProvider[],\n query$: Observable<PaletteQuery>\n): Observable<PaletteResult[]> {\n if (providers.length === 0) {\n return query$.pipe(map(() => []));\n }\n const streams = providers.map(provider => query$.pipe(\n switchMap(query => {\n if (query.scope && !provider.groups.includes(query.scope)) {\n return of<PaletteResult[]>([]);\n }\n const search$ = defer(() => provider.search(query)).pipe(\n catchError(error => {\n console.warn(`Command palette provider '${provider.id}' failed:`, error);\n return of<PaletteResult[]>([]);\n })\n );\n return provider.debounceMs ? timer(provider.debounceMs).pipe(switchMap(() => search$)) : search$;\n }),\n startWith<PaletteResult[]>([])\n ));\n return combineLatest(streams).pipe(map(lists => lists.flat()));\n}\n","import { PaletteGroup, PaletteQuery, PaletteResult } from './command-palette.models';\n\n/** Match tiers: prefix > word-start > subsequence (ui-concept §4.2 rule 2). */\nexport enum MatchTier {\n None = 0,\n Fuzzy = 1,\n WordStart = 2,\n Prefix = 3\n}\n\nconst TIER_WEIGHT = 100;\n/** A keyword/path/id match counts like a label match of the same tier minus this. */\nconst SECONDARY_PENALTY = 40;\n/** Frecency adds at most this — less than the gap between tiers, so it only orders within a tier. */\nconst FRECENCY_WEIGHT = 30;\n/** `rankBoost` (pinned boards) adds at most this: more than any frecency, so pinned rows lead; both together stay below the tier gap. */\nconst RANK_BOOST_WEIGHT = 35;\nconst EXACT_MATCH_SCORE = 10_000;\n\n/** Short queries (≤ 3 chars) list pages and actions first, longer ones entities (§4.2 rule 3). */\nconst SHORT_QUERY_ORDER: readonly PaletteGroup[] = ['recent', 'page', 'action', 'entity', 'board', 'tenant', 'ai'];\nconst LONG_QUERY_ORDER: readonly PaletteGroup[] = ['entity', 'page', 'board', 'action', 'tenant', 'recent', 'ai'];\n\n/** Rows per group: a few for an empty query, more for a search, many when scoped by a prefix. */\nconst LIMIT_EMPTY = 6;\nconst LIMIT_SEARCH = 8;\nconst LIMIT_SCOPED = 50;\n\n/** How well `text` matches `query` (both compared case-insensitively). */\nexport function matchTier(text: string | null | undefined, query: string): MatchTier {\n if (!text || !query) {\n return MatchTier.None;\n }\n const haystack = text.toLowerCase();\n const needle = query.toLowerCase();\n if (haystack.startsWith(needle)) {\n return MatchTier.Prefix;\n }\n if (haystack.split(/[\\s/.\\-_:›,()]+/).some(word => word.startsWith(needle))) {\n return MatchTier.WordStart;\n }\n let index = 0;\n for (const char of haystack) {\n if (char === needle[index]) {\n index++;\n if (index === needle.length) {\n return MatchTier.Fuzzy;\n }\n }\n }\n return MatchTier.None;\n}\n\n/**\n * Score of one result for a query: 0 means \"does not match\". `frecency` is\n * the normalised (0…1) frecency of the result's recent key.\n */\nexport function scoreResult(result: PaletteResult, text: string, frecency = 0): number {\n const boost = Math.max(0, Math.min(1, frecency)) * FRECENCY_WEIGHT\n + Math.max(0, Math.min(1, result.rankBoost ?? 0)) * RANK_BOOST_WEIGHT;\n if (result.exactMatch) {\n return EXACT_MATCH_SCORE + boost;\n }\n if (!text) {\n return 1 + boost;\n }\n const labelTier = matchTier(result.label, text);\n const secondary = [...(result.keywords ?? []), ...(result.path ?? []), result.typeHint]\n .reduce<MatchTier>((best, candidate) => Math.max(best, matchTier(candidate, text)) as MatchTier, MatchTier.None);\n const labelScore = labelTier * TIER_WEIGHT;\n const secondaryScore = secondary > MatchTier.None ? secondary * TIER_WEIGHT - SECONDARY_PENALTY : 0;\n const base = Math.max(labelScore, secondaryScore);\n if (base === 0) {\n return result.alwaysShow ? 1 : 0;\n }\n return base + boost;\n}\n\n/** A section of the ranked palette list. */\nexport interface RankedGroup {\n group: PaletteGroup;\n results: PaletteResult[];\n}\n\n/**\n * Orders the rows of all providers into sections. Pure: the same input gives\n * the same output, so the palette can re-rank whenever a provider streams in\n * without the list jumping around for unchanged rows.\n *\n * - non-matching rows are dropped (except `alwaysShow`),\n * - rows sort by score within their group, ties by label,\n * - groups follow the short/long query order; a group holding an exact id match goes first,\n * - the assistant row (group `ai`) always stays last.\n */\nexport function rankResults(\n results: readonly PaletteResult[],\n query: PaletteQuery,\n frecencyOf: (key: string) => number = () => 0\n): RankedGroup[] {\n const text = query.text;\n const scored = new Map<PaletteGroup, { result: PaletteResult; score: number }[]>();\n const seen = new Set<string>();\n for (const result of results) {\n if (seen.has(result.id)) {\n continue;\n }\n seen.add(result.id);\n const frecency = result.recentKey ? frecencyOf(result.recentKey) : 0;\n const score = scoreResult(result, text, frecency);\n if (score <= 0) {\n continue;\n }\n const bucket = scored.get(result.group) ?? [];\n bucket.push({ result, score });\n scored.set(result.group, bucket);\n }\n\n const limit = query.scope ? LIMIT_SCOPED : text ? LIMIT_SEARCH : LIMIT_EMPTY;\n const order = text.length <= 3 ? SHORT_QUERY_ORDER : LONG_QUERY_ORDER;\n const groups: (RankedGroup & { exact: boolean })[] = [];\n for (const [group, bucket] of scored) {\n bucket.sort((a, b) => b.score - a.score || a.result.label.localeCompare(b.result.label));\n groups.push({\n group,\n exact: bucket.some(entry => entry.result.exactMatch === true),\n results: bucket.slice(0, limit).map(entry => entry.result)\n });\n }\n groups.sort((a, b) => {\n if (a.group === 'ai' || b.group === 'ai') {\n return a.group === 'ai' ? 1 : -1;\n }\n if (a.exact !== b.exact) {\n return a.exact ? -1 : 1;\n }\n return order.indexOf(a.group) - order.indexOf(b.group);\n });\n return groups.map(({ group, results: rows }) => ({ group, results: rows }));\n}\n\n/** Splits a label into plain and highlighted parts for the first case-insensitive occurrence of `text`. */\nexport function highlightSegments(label: string, text: string): { text: string; match: boolean }[] {\n if (!text) {\n return [{ text: label, match: false }];\n }\n const index = label.toLowerCase().indexOf(text.toLowerCase());\n if (index < 0) {\n return [{ text: label, match: false }];\n }\n return [\n { text: label.slice(0, index), match: false },\n { text: label.slice(index, index + text.length), match: true },\n { text: label.slice(index + text.length), match: false }\n ].filter(segment => segment.text.length > 0);\n}\n\n/**\n * Keeps what the user already sees in place while results stream in for the\n * SAME query (ui-concept §4.2 rule 5): groups already shown keep their\n * position and new groups are appended below them (the assistant row stays\n * last); inside a group, rows already shown keep their order and late rows\n * are appended. Rows a provider no longer returns disappear. For a new query\n * the fresh ranking is used as is.\n */\nexport function stabilizeRanking(previous: readonly RankedGroup[], next: readonly RankedGroup[]): RankedGroup[] {\n if (previous.length === 0) {\n return [...next];\n }\n const nextByGroup = new Map(next.map(section => [section.group, section]));\n const ordered: RankedGroup[] = [];\n for (const old of previous) {\n const fresh = nextByGroup.get(old.group);\n if (!fresh || old.group === 'ai') {\n continue;\n }\n const freshIds = new Set(fresh.results.map(result => result.id));\n const freshById = new Map(fresh.results.map(result => [result.id, result]));\n const kept = old.results.filter(result => freshIds.has(result.id)).map(result => freshById.get(result.id) as PaletteResult);\n const keptIds = new Set(kept.map(result => result.id));\n ordered.push({ group: old.group, results: [...kept, ...fresh.results.filter(result => !keptIds.has(result.id))] });\n nextByGroup.delete(old.group);\n }\n for (const section of next) {\n if (nextByGroup.has(section.group) && section.group !== 'ai') {\n ordered.push(section);\n }\n }\n const ai = nextByGroup.get('ai') ?? next.find(section => section.group === 'ai');\n if (ai) {\n ordered.push(ai);\n }\n return ordered;\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n OnInit,\n signal,\n untracked,\n viewChild\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { SVGIconComponent } from '@progress/kendo-angular-icons';\nimport { BehaviorSubject } from 'rxjs';\nimport { distinctUntilChanged, map } from 'rxjs/operators';\nimport {\n PALETTE_PROVIDERS,\n PALETTE_RECENT_ITEMS_SOURCE,\n PaletteAction,\n PaletteGroup,\n PaletteQuery,\n PaletteResult,\n PaletteRunMode,\n PaletteRunResult\n} from './command-palette.models';\nimport { CommandPaletteMessages, commandPaletteMessages, formatCommandPaletteMessage, paletteGroupLabel } from './command-palette.messages';\nimport { CommandPaletteService } from './command-palette.service';\nimport { parsePaletteQuery } from './palette-query';\nimport { highlightSegments, rankResults, RankedGroup, stabilizeRanking } from './palette-ranking';\nimport { searchProviders } from './palette-search';\n\ninterface PaletteRow {\n index: number;\n result: PaletteResult;\n segments: { text: string; match: boolean }[];\n side: string;\n}\n\ninterface PaletteSection {\n group: PaletteGroup;\n label: string;\n rows: PaletteRow[];\n}\n\n/**\n * The command palette overlay (Cmd/Ctrl+K, ui-concept §4). Render it only while\n * {@link CommandPaletteService.isOpen} — one component instance is one palette session:\n *\n * ```html\n * @if (commandPalette.isOpen()) { <mm-command-palette /> }\n * ```\n *\n * Results come from the {@link PALETTE_PROVIDERS}; the frecency boost from the optional\n * {@link PALETTE_RECENT_ITEMS_SOURCE}.\n *\n * Accessibility: modal dialog; the input is a combobox driving a listbox via\n * `aria-activedescendant`, so focus never leaves the input (Tab is taken for\n * the actions sub-menu, which keeps keyboard focus trapped in the dialog);\n * focus goes back to the invoking element on close (the service does that).\n */\n@Component({\n selector: 'mm-command-palette',\n imports: [SVGIconComponent],\n templateUrl: './command-palette.component.html',\n styleUrl: './command-palette.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class CommandPaletteComponent implements OnInit {\n private readonly palette = inject(CommandPaletteService);\n private readonly providers = inject(PALETTE_PROVIDERS, { optional: true }) ?? [];\n private readonly recents = inject(PALETTE_RECENT_ITEMS_SOURCE, { optional: true });\n\n /** Translations; members left out fall back to {@link COMMAND_PALETTE_MESSAGES}, then English. */\n readonly messages = input<Partial<CommandPaletteMessages> | null>(null);\n protected readonly m = commandPaletteMessages(this.messages);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly input = viewChild.required<ElementRef<HTMLInputElement>>('input');\n\n protected readonly query = signal('');\n private readonly query$ = new BehaviorSubject<string>('');\n private readonly ranked = signal<RankedGroup[]>([]);\n private readonly parsed = computed<PaletteQuery>(() => parsePaletteQuery(this.query()));\n\n private readonly results = computed(() => this.ranked().flatMap(section => section.results));\n /** Id of the highlighted row; null means \"the first row\" (reset whenever the user types). */\n private readonly activeId = signal<string | null>(null);\n protected readonly activeIndex = computed(() => {\n const results = this.results();\n const id = this.activeId();\n const index = id === null ? -1 : results.findIndex(result => result.id === id);\n return index >= 0 ? index : results.length > 0 ? 0 : -1;\n });\n\n /** The result whose actions sub-menu is open (Tab), or null. */\n protected readonly actionsFor = signal<PaletteResult | null>(null);\n protected readonly activeActionIndex = signal(0);\n\n protected readonly sections = computed<PaletteSection[]>(() => {\n const text = this.parsed().text;\n let index = 0;\n return this.ranked().map(section => ({\n group: section.group,\n label: paletteGroupLabel(section.group, this.m()),\n rows: section.results.map(result => ({\n index: index++,\n result,\n segments: result.group === 'ai' ? [{ text: result.label, match: false }] : highlightSegments(result.label, text),\n side: [result.path?.length ? `${result.path.join(' › ')} ›` : '', result.description ?? ''].filter(Boolean).join(' ')\n }))\n }));\n });\n\n protected readonly activeDescendant = computed(() => {\n if (this.actionsFor()) {\n return `cp-action-${this.activeActionIndex()}`;\n }\n const index = this.activeIndex();\n return index >= 0 ? `cp-option-${index}` : null;\n });\n\n /** Whether a listbox with options is shown (bound to the combobox's aria-expanded). */\n protected readonly expanded = computed(() =>\n this.actionsFor() ? (this.actionsFor()?.actions?.length ?? 0) > 0 : this.results().length > 0);\n\n protected readonly statusText = computed(() => {\n const count = this.results().length;\n return count === 1 ? this.m().oneResult : formatCommandPaletteMessage(this.m().manyResults, { count });\n });\n\n protected readonly emptyText = computed(() =>\n this.parsed().text ? formatCommandPaletteMessage(this.m().noResultsFor, { text: this.parsed().text }) : this.m().typeToSearch);\n\n protected get modifierLabel(): string {\n return /Mac|iPhone|iPad/i.test(navigator.platform || navigator.userAgent) ? '⌘' : 'Ctrl';\n }\n\n constructor() {\n // open('…') while already open replaces the query (e.g. the top bar's trigger).\n effect(() => {\n const request = this.palette.request();\n untracked(() => this.setQuery(request.query));\n });\n afterNextRender(() => this.focusInput());\n }\n\n ngOnInit(): void {\n for (const provider of this.providers) {\n provider.reset?.();\n }\n this.setQuery(this.palette.request().query);\n\n // Frecency is read once per session; a palette session is short.\n const now = Date.now();\n const frecency = this.recents?.frecencies(now) ?? new Map<string, number>();\n const frecencyOf = (key: string): number => frecency.get(key) ?? 0;\n\n const parsed$ = this.query$.pipe(distinctUntilChanged(), map(raw => parsePaletteQuery(raw)));\n // Late answers for the same query only fill in below what is shown (§4.2 rule 5).\n let rankedFor: string | null = null;\n searchProviders(this.providers, parsed$).pipe(\n map(results => {\n const raw = this.query$.value;\n const fresh = rankResults(results, parsePaletteQuery(raw), frecencyOf);\n const ranked = raw === rankedFor ? stabilizeRanking(this.ranked(), fresh) : fresh;\n rankedFor = raw;\n return ranked;\n }),\n takeUntilDestroyed(this.destroyRef)\n ).subscribe(ranked => this.ranked.set(ranked));\n }\n\n protected groupLabel(group: PaletteGroup): string {\n return paletteGroupLabel(group, this.m());\n }\n\n protected format(message: string, values: Record<string, string>): string {\n return formatCommandPaletteMessage(message, values);\n }\n\n protected onInput(event: Event): void {\n this.setQuery((event.target as HTMLInputElement).value);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.move(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.move(-1);\n break;\n case 'Home':\n event.preventDefault();\n this.moveTo(0);\n break;\n case 'End':\n event.preventDefault();\n this.moveTo(Number.MAX_SAFE_INTEGER);\n break;\n case 'Enter': {\n event.preventDefault();\n const target = this.actionsFor();\n if (target) {\n const action = target.actions?.[this.activeActionIndex()];\n if (action) {\n void this.runAction(action);\n }\n } else {\n const result = this.results()[this.activeIndex()];\n if (result) {\n void this.execute(result, event.metaKey || event.ctrlKey ? 'newTab' : 'open');\n }\n }\n break;\n }\n case 'Tab':\n // Keeps focus in the dialog (trap) and toggles the actions sub-menu.\n event.preventDefault();\n if (event.shiftKey || this.actionsFor()) {\n this.actionsFor.set(null);\n } else {\n this.openActions();\n }\n break;\n case 'Escape':\n event.preventDefault();\n event.stopPropagation();\n if (this.actionsFor()) {\n this.actionsFor.set(null);\n } else {\n this.palette.close();\n }\n break;\n }\n }\n\n /** Clicks on the dialog's chrome (header, footer, group headers) must not take focus from the input. */\n protected onDialogMouseDown(event: MouseEvent): void {\n if (event.target !== this.input().nativeElement) {\n event.preventDefault();\n }\n }\n\n protected close(): void {\n this.palette.close();\n }\n\n protected onScrimMouseDown(event: MouseEvent): void {\n if (event.target === event.currentTarget) {\n this.palette.close();\n }\n }\n\n protected onOptionHover(result: PaletteResult): void {\n if (this.activeId() !== result.id) {\n this.activeId.set(result.id);\n }\n }\n\n protected onOptionClick(result: PaletteResult, event: MouseEvent): void {\n void this.execute(result, event.metaKey || event.ctrlKey ? 'newTab' : 'open');\n }\n\n /** Runs a result. The palette closes first; an outcome with a query reopens it with that query. */\n protected async execute(result: PaletteResult, mode: PaletteRunMode): Promise<void> {\n await this.finish(() => result.run(mode));\n }\n\n protected async runAction(action: PaletteAction): Promise<void> {\n await this.finish(() => action.run());\n }\n\n private async finish(run: () => Promise<PaletteRunResult>): Promise<void> {\n this.palette.close();\n try {\n const outcome = await run();\n if (outcome && typeof outcome.query === 'string') {\n this.palette.open(outcome.query);\n }\n } catch (error) {\n console.error('Command palette: running the result failed', error);\n }\n }\n\n private openActions(): void {\n const result = this.results()[this.activeIndex()];\n if (result?.actions?.length) {\n this.actionsFor.set(result);\n this.activeActionIndex.set(0);\n }\n }\n\n private move(delta: number): void {\n const count = this.actionsFor() ? this.actionsFor()?.actions?.length ?? 0 : this.results().length;\n if (count === 0) {\n return;\n }\n const current = this.actionsFor() ? this.activeActionIndex() : Math.max(0, this.activeIndex());\n this.moveTo((current + delta + count) % count);\n }\n\n private moveTo(index: number): void {\n const target = this.actionsFor();\n if (target) {\n const count = target.actions?.length ?? 0;\n if (count > 0) {\n this.activeActionIndex.set(Math.min(index, count - 1));\n }\n } else {\n const results = this.results();\n if (results.length === 0) {\n return;\n }\n this.activeId.set(results[Math.min(index, results.length - 1)].id);\n }\n this.scrollActiveIntoView();\n }\n\n private setQuery(value: string): void {\n if (value === this.query() && value === this.query$.value) {\n return;\n }\n this.query.set(value);\n this.activeId.set(null);\n this.actionsFor.set(null);\n this.query$.next(value);\n }\n\n private focusInput(): void {\n const element = this.input().nativeElement;\n element.focus();\n const end = element.value.length;\n element.setSelectionRange(end, end);\n }\n\n private scrollActiveIntoView(): void {\n const id = this.activeDescendant();\n const element = id ? document.getElementById(id) : null;\n if (element && typeof element.scrollIntoView === 'function') {\n element.scrollIntoView({ block: 'nearest' });\n }\n }\n}\n","<div class=\"cp-scrim\" (mousedown)=\"onScrimMouseDown($event)\">\n <div class=\"cp-dialog\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"m().dialogLabel\" (keydown)=\"onKeydown($event)\" (mousedown)=\"onDialogMouseDown($event)\">\n <div class=\"cp-input-row\">\n <svg class=\"cp-search-icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m20 20-3.5-3.5\"/></svg>\n <input\n #input\n class=\"cp-input\"\n type=\"text\"\n role=\"combobox\"\n [attr.aria-label]=\"m().inputLabel\"\n [attr.aria-expanded]=\"expanded()\"\n aria-autocomplete=\"list\"\n [attr.aria-controls]=\"actionsFor() ? 'cp-actions' : 'cp-listbox'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"m().placeholder\"\n [value]=\"query()\"\n (input)=\"onInput($event)\" />\n <kbd class=\"cp-esc\" aria-hidden=\"true\">esc</kbd>\n <!-- Phones: full-screen palette without scrim and Esc key — an explicit way out. -->\n <button type=\"button\" class=\"cp-close\" (click)=\"close()\">{{ m().cancel }}</button>\n </div>\n\n @if (actionsFor(); as target) {\n <div class=\"cp-list\" id=\"cp-actions\" role=\"listbox\" [attr.aria-label]=\"format(m().actionsFor, { label: target.label })\">\n <div class=\"cp-group-header\" role=\"presentation\">{{ format(m().actionsHeader, { label: target.label }) }}</div>\n @for (action of target.actions ?? []; track action.id; let i = $index) {\n <div\n class=\"cp-option\"\n role=\"option\"\n [id]=\"'cp-action-' + i\"\n [attr.aria-selected]=\"i === activeActionIndex()\"\n (mousedown)=\"$event.preventDefault()\"\n (mousemove)=\"activeActionIndex.set(i)\"\n (click)=\"runAction(action)\">\n <span class=\"cp-icon\" aria-hidden=\"true\">▸</span>\n <span class=\"cp-label\">{{ action.label }}</span>\n <span class=\"cp-side\"></span>\n <span class=\"cp-tab-col\">\n @if (action.hint) {\n <kbd aria-hidden=\"true\">{{ action.hint }}</kbd>\n }\n </span>\n </div>\n }\n </div>\n } @else {\n <div class=\"cp-list\" id=\"cp-listbox\" role=\"listbox\" [attr.aria-label]=\"m().results\">\n @for (section of sections(); track section.group) {\n <div class=\"cp-section\" [class.cp-section-ai]=\"section.group === 'ai'\" role=\"group\" [attr.aria-labelledby]=\"'cp-group-' + section.group\">\n <div class=\"cp-group-header\" role=\"presentation\" [id]=\"'cp-group-' + section.group\">{{ section.label }}</div>\n @for (row of section.rows; track row.result.id) {\n <div\n class=\"cp-option\"\n role=\"option\"\n [class.cp-ai]=\"row.result.group === 'ai'\"\n [id]=\"'cp-option-' + row.index\"\n [attr.aria-selected]=\"row.index === activeIndex()\"\n (mousedown)=\"$event.preventDefault()\"\n (mousemove)=\"onOptionHover(row.result)\"\n (click)=\"onOptionClick(row.result, $event)\">\n <span class=\"cp-icon\" aria-hidden=\"true\">\n @if (row.result.icon) {\n <kendo-svgicon [icon]=\"row.result.icon\" size=\"small\"></kendo-svgicon>\n } @else {\n {{ row.result.glyph ?? '·' }}\n }\n </span>\n <!-- One line on purpose: whitespace between the segments would show as gaps in the label. -->\n <span class=\"cp-label\">@for (segment of row.segments; track $index) {@if (segment.match) {<mark>{{ segment.text }}</mark>}@else{<span>{{ segment.text }}</span>}}</span>\n <span class=\"cp-side\">\n @if (row.side) {\n <span class=\"cp-description\" [title]=\"row.side\">{{ row.side }}</span>\n }\n @if (row.result.typeHint) {\n <code class=\"cp-hint\">{{ row.result.typeHint }}</code>\n }\n </span>\n <!-- Own grid column, so the Tab key lines up on every row. -->\n <span class=\"cp-tab-col\" aria-hidden=\"true\">\n @if (row.result.actions?.length) {\n <kbd class=\"cp-tab-hint\" [title]=\"m().tabForActions\">⇥</kbd>\n }\n </span>\n </div>\n }\n </div>\n } @empty {\n <div class=\"cp-empty\" role=\"presentation\">{{ emptyText() }}</div>\n }\n </div>\n }\n\n <div class=\"cp-footer\" aria-hidden=\"true\">\n <span><kbd>↑</kbd><kbd>↓</kbd> {{ m().footerMove }}</span>\n <span><kbd>↵</kbd> {{ m().footerOpen }}</span>\n <span><kbd>{{ modifierLabel }}↵</kbd> {{ m().footerNewTab }}</span>\n <span><kbd>⇥</kbd> {{ m().footerActions }}</span>\n <span class=\"cp-prefixes\">\n <span class=\"cp-prefix\"><kbd>&gt;</kbd> {{ m().prefixActions }}</span>\n <span class=\"cp-prefix\"><kbd>&#64;</kbd> {{ m().prefixEntities }}</span>\n <span class=\"cp-prefix\"><kbd>#</kbd> {{ m().prefixBoards }}</span>\n <span class=\"cp-prefix\"><kbd>/</kbd> {{ m().prefixTenants }}</span>\n </span>\n </div>\n <div class=\"cp-status\" role=\"status\" aria-live=\"polite\">{{ statusText() }}</div>\n </div>\n</div>\n","/*\n * Public API Surface of @meshmakers/shared-ui/command-palette (AB#5621)\n */\n\n/**\n * The command palette (Cmd/Ctrl+K) of the OctoMesh Refinery Studio as an app-agnostic building\n * block: the overlay component, the open/close service with the hotkey mapping, query parsing,\n * multi-provider search and ranking. It knows no data source of its own — every row comes from a\n * {@link PALETTE_PROVIDERS} entry the host registers (pages, actions, entities, tenants …).\n *\n * Usage:\n *\n * ```ts\n * import { CommandPaletteComponent, CommandPaletteService, PALETTE_PROVIDERS, PaletteProvider,\n * paletteHotkeyAction } from '@meshmakers/shared-ui/command-palette';\n *\n * // app.config.ts\n * providers: [\n * { provide: PALETTE_PROVIDERS, useClass: PagesPaletteProvider, multi: true },\n * { provide: PALETTE_PROVIDERS, useClass: TenantsPaletteProvider, multi: true },\n * ]\n *\n * // AppComponent: host the overlay and bind the hotkeys\n * template: `@if (palette.isOpen()) { <mm-command-palette /> }`\n * @HostListener('document:keydown', ['$event'])\n * onKeydown(event: KeyboardEvent): void {\n * const action = paletteHotkeyAction(event, this.palette.isOpen());\n * if (action) { event.preventDefault(); action === 'toggle' ? this.palette.toggle() : this.palette.open(); }\n * }\n * ```\n *\n * A provider implements {@link PaletteProvider}: `search(query)` returns an Observable of\n * {@link PaletteResult}s (a new query cancels the previous search; `debounceMs` for remote\n * sources; an error drops only that provider's rows), `reset()` runs whenever the palette opens.\n * {@link PaletteNavigationService} offers tenant-relative navigation and clipboard helpers.\n *\n * Optional providers:\n * - `PALETTE_RECENT_ITEMS_SOURCE` — frecency per `recentKey` (boosts recently used rows);\n * - `COMMAND_PALETTE_MESSAGES` — translations (`Partial<CommandPaletteMessages>`, English defaults;\n * the component's `messages` input wins over the token).\n */\n\n// --- Contract ---\nexport { PALETTE_PROVIDERS, PALETTE_RECENT_ITEMS_SOURCE } from './command-palette.models';\nexport type {\n PaletteGroup,\n PaletteRunMode,\n PaletteRunOutcome,\n PaletteRunResult,\n PaletteAction,\n PaletteResult,\n PaletteQuery,\n PaletteProvider,\n PaletteRecentItemsSource,\n} from './command-palette.models';\n\n// --- Messages / i18n ---\nexport {\n DEFAULT_COMMAND_PALETTE_MESSAGES,\n COMMAND_PALETTE_MESSAGES,\n resolveCommandPaletteMessages,\n formatCommandPaletteMessage,\n paletteGroupLabel,\n} from './command-palette.messages';\nexport type { CommandPaletteMessages } from './command-palette.messages';\n\n// --- Services ---\nexport { CommandPaletteService, paletteHotkeyAction } from './command-palette.service';\nexport type { PaletteOpenRequest, PaletteHotkeyAction } from './command-palette.service';\nexport { PaletteNavigationService } from './palette-navigation.service';\n\n// --- Pure functions ---\nexport { PALETTE_PREFIXES, parsePaletteQuery, isRtId } from './palette-query';\nexport { searchProviders } from './palette-search';\nexport { MatchTier, matchTier, scoreResult, rankResults, highlightSegments, stabilizeRanking } from './palette-ranking';\nexport type { RankedGroup } from './palette-ranking';\n\n// --- Component ---\nexport { CommandPaletteComponent } from './command-palette.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}