@memberjunction/ng-shared 5.51.0 → 6.1.0-edge.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/LICENSE +7 -0
- package/dist/lib/base-dashboard.d.ts +16 -0
- package/dist/lib/base-dashboard.d.ts.map +1 -1
- package/dist/lib/base-dashboard.js +36 -5
- package/dist/lib/base-dashboard.js.map +1 -1
- package/dist/lib/base-resource-component.d.ts +33 -3
- package/dist/lib/base-resource-component.d.ts.map +1 -1
- package/dist/lib/base-resource-component.js +65 -11
- package/dist/lib/base-resource-component.js.map +1 -1
- package/dist/lib/explorer-breakpoint.service.d.ts +39 -0
- package/dist/lib/explorer-breakpoint.service.d.ts.map +1 -0
- package/dist/lib/explorer-breakpoint.service.js +57 -0
- package/dist/lib/explorer-breakpoint.service.js.map +1 -0
- package/dist/lib/home-pin.service.d.ts.map +1 -1
- package/dist/lib/home-pin.service.js +0 -2
- package/dist/lib/home-pin.service.js.map +1 -1
- package/dist/lib/navigation.interfaces.d.ts +13 -0
- package/dist/lib/navigation.interfaces.d.ts.map +1 -1
- package/dist/lib/navigation.interfaces.js.map +1 -1
- package/dist/lib/navigation.service.d.ts +70 -8
- package/dist/lib/navigation.service.d.ts.map +1 -1
- package/dist/lib/navigation.service.js +356 -50
- package/dist/lib/navigation.service.js.map +1 -1
- package/dist/lib/record-open-style.d.ts +88 -0
- package/dist/lib/record-open-style.d.ts.map +1 -0
- package/dist/lib/record-open-style.js +124 -0
- package/dist/lib/record-open-style.js.map +1 -0
- package/dist/lib/record-tab-icon.d.ts +10 -0
- package/dist/lib/record-tab-icon.d.ts.map +1 -0
- package/dist/lib/record-tab-icon.js +15 -0
- package/dist/lib/record-tab-icon.js.map +1 -0
- package/dist/lib/safe-detect-changes.d.ts +18 -0
- package/dist/lib/safe-detect-changes.d.ts.map +1 -0
- package/dist/lib/safe-detect-changes.js +29 -0
- package/dist/lib/safe-detect-changes.js.map +1 -0
- package/dist/lib/shared.service.d.ts +5 -1
- package/dist/lib/shared.service.d.ts.map +1 -1
- package/dist/lib/shared.service.js +16 -14
- package/dist/lib/shared.service.js.map +1 -1
- package/dist/public-api.d.ts +4 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +4 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +22 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home-pin.service.js","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { toJpeg } from 'html-to-image';\nimport { HomeAppPinnedItem, HomeAppPinInput, HomeAppPinUpdate } from './home-pin.types';\n\n/** UserSettings key for persisting pins */\nconst PINS_SETTING_KEY = 'HomeApp.PinnedItems';\n\n/**\n * Service for managing pinned items on the Home dashboard.\n *\n * All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.\n * Uses debounced saving to avoid excessive DB writes during edit mode operations.\n */\n@Injectable({ providedIn: 'root' })\nexport class HomeAppPinService {\n /** Max time to wait for a thumbnail capture before giving up and pinning without a preview. */\n private static readonly THUMBNAIL_CAPTURE_TIMEOUT_MS = 4000;\n\n /**\n * Max DOM node count we'll attempt to rasterize. Above this, html-to-image's synchronous\n * clone/inline step blocks the main thread long enough to freeze the UI, so we skip the\n * (decorative) preview instead. Tuned to comfortably allow typical dashboards/forms while\n * excluding heavy grid/map views like the Data Explorer.\n */\n private static readonly THUMBNAIL_MAX_NODES = 3000;\n\n /** Observable of current pins (for reactive UI) */\n public readonly Pins$ = new BehaviorSubject<HomeAppPinnedItem[]>([]);\n\n private loaded = false;\n\n // =============================================\n // LOADING\n // =============================================\n\n /**\n * Load pins from UserSettings. Safe to call multiple times (loads only once).\n */\n async LoadPins(): Promise<void> {\n if (this.loaded) return;\n\n const raw = UserInfoEngine.Instance.GetSetting(PINS_SETTING_KEY);\n if (raw) {\n try {\n const pins = JSON.parse(raw) as HomeAppPinnedItem[];\n this.Pins$.next(this.sortPins(pins));\n } catch (err) {\n console.warn('HomeAppPinService: Failed to parse saved pins, starting fresh', err);\n this.Pins$.next([]);\n }\n }\n this.loaded = true;\n }\n\n /**\n * Force reload from UserSettings (e.g. after external changes)\n */\n async ReloadPins(): Promise<void> {\n this.loaded = false;\n await this.LoadPins();\n }\n\n // =============================================\n // CRUD OPERATIONS\n // =============================================\n\n /**\n * Add a new pin. Returns false if a duplicate already exists.\n */\n AddPin(input: HomeAppPinInput): boolean {\n if (this.IsPinned(input.ResourceType, input.Configuration)) {\n return false;\n }\n\n const pins = [...this.Pins$.value];\n const newPin: HomeAppPinnedItem = {\n ...input,\n Id: this.generateId(),\n Sequence: pins.length,\n PinnedAt: new Date().toISOString()\n };\n\n pins.push(newPin);\n this.updateAndSave(pins);\n return true;\n }\n\n /**\n * Remove a pin by ID\n */\n RemovePin(pinId: string): void {\n const pins = this.Pins$.value.filter(p => p.Id !== pinId);\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n /**\n * Update pin properties (name, description, icon, group, thumbnail)\n */\n UpdatePin(pinId: string, updates: HomeAppPinUpdate): void {\n const pins = this.Pins$.value.map(p => {\n if (p.Id !== pinId) return p;\n return { ...p, ...updates };\n });\n this.updateAndSave(pins);\n }\n\n /**\n * Reorder pins. Accepts full reordered array with updated Sequence values.\n */\n ReorderPins(pins: HomeAppPinnedItem[]): void {\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n // =============================================\n // DUPLICATE DETECTION\n // =============================================\n\n /**\n * Check if a resource is already pinned\n */\n IsPinned(resourceType: string, config: Record<string, unknown>): boolean {\n return this.Pins$.value.some(pin => this.matchesResource(pin, resourceType, config));\n }\n\n /**\n * Find the pin for a given resource, if it exists\n */\n FindPin(resourceType: string, config: Record<string, unknown>): HomeAppPinnedItem | undefined {\n return this.Pins$.value.find(pin => this.matchesResource(pin, resourceType, config));\n }\n\n // =============================================\n // HELPERS\n // =============================================\n\n /**\n * Get ungrouped pins (Group is null/undefined/empty)\n */\n GetUngroupedPins(): HomeAppPinnedItem[] {\n return this.Pins$.value.filter(p => !p.Group);\n }\n\n /**\n * Get unique group names in display order (ordered by lowest Sequence in group)\n */\n GetGroups(): string[] {\n const groupMinSeq = new Map<string, number>();\n for (const pin of this.Pins$.value) {\n if (!pin.Group) continue;\n const current = groupMinSeq.get(pin.Group);\n if (current === undefined || pin.Sequence < current) {\n groupMinSeq.set(pin.Group, pin.Sequence);\n }\n }\n return [...groupMinSeq.entries()]\n .sort((a, b) => a[1] - b[1])\n .map(([name]) => name);\n }\n\n /**\n * Get pins in a specific group\n */\n GetPinsInGroup(groupName: string): HomeAppPinnedItem[] {\n return this.Pins$.value\n .filter(p => p.Group === groupName)\n .sort((a, b) => a.Sequence - b.Sequence);\n }\n\n // =============================================\n // THUMBNAIL CAPTURE\n // =============================================\n\n /**\n * Capture a thumbnail of a DOM element using html-to-image.\n * Uses SVG foreignObject so the browser's own CSS engine handles\n * modern features like color-mix() that html2canvas can't parse.\n * Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.\n */\n async CaptureThumbnail(element: HTMLElement): Promise<string | undefined> {\n try {\n if (element.clientWidth === 0 || element.clientHeight === 0) {\n return undefined;\n }\n // Bail on very large DOM trees. html-to-image clones and inlines the ENTIRE subtree\n // SYNCHRONOUSLY before it ever yields, so a heavy view (e.g. the Data Explorer's grid\n // + map) blocks the main thread for seconds — long enough to freeze the UI, and the\n // timeout below (setTimeout-based) can't even fire while the thread is blocked. A\n // thumbnail is best-effort decoration, so skip rather than jank the app.\n const nodeCount = element.getElementsByTagName('*').length;\n if (nodeCount > HomeAppPinService.THUMBNAIL_MAX_NODES) {\n return undefined;\n }\n // Race against a timeout as a secondary guard for the async portion: toJpeg() can also\n // hang on content with cross-origin resources it must re-fetch (e.g. Leaflet map tiles),\n // where the inlining/canvas step never resolves. Don't cacheBust — re-fetching every\n // image is what tends to stall, and a slightly cached preview is fine.\n const capture = toJpeg(element, {\n quality: 0.6,\n pixelRatio: 0.2,\n });\n return await this.withTimeout(capture, HomeAppPinService.THUMBNAIL_CAPTURE_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve to `undefined` if the given promise hasn't settled within `ms`.\n * Note: this does not cancel the underlying work (toJpeg is not cancelable),\n * it just stops the pin flow from waiting on it.\n */\n private withTimeout(promise: Promise<string>, ms: number): Promise<string | undefined> {\n return new Promise<string | undefined>((resolve) => {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(undefined);\n }\n }, ms);\n promise.then(\n (value) => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(value);\n }\n },\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(undefined);\n }\n }\n );\n });\n }\n\n // =============================================\n // PRIVATE\n // =============================================\n\n private matchesResource(pin: HomeAppPinnedItem, resourceType: string, config: Record<string, unknown>): boolean {\n if (pin.ResourceType !== resourceType) return false;\n switch (resourceType) {\n case 'Dashboards':\n return pin.Configuration['dashboardId'] === config['dashboardId'];\n case 'User Views':\n return pin.Configuration['viewId'] === config['viewId'];\n case 'Queries':\n return pin.Configuration['queryId'] === config['queryId'];\n case 'Reports':\n return pin.Configuration['reportId'] === config['reportId'];\n case 'Records':\n return pin.Configuration['Entity'] === config['Entity']\n && pin.Configuration['recordId'] === config['recordId'];\n case 'Custom': {\n // Match by app name + nav item name + route — never use appId or driverClass\n // Include route to differentiate same nav item with different URL paths\n const sameApp = pin.Configuration['appName'] === config['appName'];\n const sameNav = pin.Configuration['navItemName'] === config['navItemName'];\n const pinRoute = pin.Configuration['route'] as string || '';\n const configRoute = config['route'] as string || '';\n const sameRoute = pinRoute === configRoute;\n // Also compare queryParams if present\n const pinQP = JSON.stringify(pin.Configuration['queryParams'] || {});\n const configQP = JSON.stringify(config['queryParams'] || {});\n const sameQP = pinQP === configQP;\n return sameApp && sameNav && sameRoute && sameQP;\n }\n case 'Actions': {\n // A pinned Action is unique per (actionId + preset-params + runtime-params + title).\n // Two pins targeting the same action with different preset configs are allowed —\n // e.g. \"Weekly Report — Sales\" vs. \"Weekly Report — Ops\" both pin \"Run Report\".\n if (pin.Configuration['actionId'] !== config['actionId']) return false;\n const pinPreset = JSON.stringify(pin.Configuration['presetParams'] ?? {});\n const configPreset = JSON.stringify(config['presetParams'] ?? {});\n const pinRuntime = JSON.stringify(pin.Configuration['runtimeParamNames'] ?? []);\n const configRuntime = JSON.stringify(config['runtimeParamNames'] ?? []);\n const samePreset = pinPreset === configPreset;\n const sameRuntime = pinRuntime === configRuntime;\n const sameTitle = pin.DisplayName === (config['displayName'] ?? pin.DisplayName);\n return samePreset && sameRuntime && sameTitle;\n }\n default:\n return false;\n }\n }\n\n private updateAndSave(pins: HomeAppPinnedItem[]): void {\n const sorted = this.sortPins(pins);\n this.Pins$.next(sorted);\n UserInfoEngine.Instance.SetSettingDebounced(\n PINS_SETTING_KEY,\n JSON.stringify(sorted)\n );\n }\n\n private sortPins(pins: HomeAppPinnedItem[]): HomeAppPinnedItem[] {\n return [...pins].sort((a, b) => a.Sequence - b.Sequence);\n }\n\n private resequence(pins: HomeAppPinnedItem[]): void {\n pins.forEach((pin, i) => { pin.Sequence = i; });\n }\n\n private generateId(): string {\n // Crypto.randomUUID is available in modern browsers\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"home-pin.service.js","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { toJpeg } from 'html-to-image';\nimport { HomeAppPinnedItem, HomeAppPinInput, HomeAppPinUpdate } from './home-pin.types';\n\n/** UserSettings key for persisting pins */\nconst PINS_SETTING_KEY = 'HomeApp.PinnedItems';\n\n/**\n * Service for managing pinned items on the Home dashboard.\n *\n * All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.\n * Uses debounced saving to avoid excessive DB writes during edit mode operations.\n */\n@Injectable({ providedIn: 'root' })\nexport class HomeAppPinService {\n /** Max time to wait for a thumbnail capture before giving up and pinning without a preview. */\n private static readonly THUMBNAIL_CAPTURE_TIMEOUT_MS = 4000;\n\n /**\n * Max DOM node count we'll attempt to rasterize. Above this, html-to-image's synchronous\n * clone/inline step blocks the main thread long enough to freeze the UI, so we skip the\n * (decorative) preview instead. Tuned to comfortably allow typical dashboards/forms while\n * excluding heavy grid/map views like the Data Explorer.\n */\n private static readonly THUMBNAIL_MAX_NODES = 3000;\n\n /** Observable of current pins (for reactive UI) */\n public readonly Pins$ = new BehaviorSubject<HomeAppPinnedItem[]>([]);\n\n private loaded = false;\n\n // =============================================\n // LOADING\n // =============================================\n\n /**\n * Load pins from UserSettings. Safe to call multiple times (loads only once).\n */\n async LoadPins(): Promise<void> {\n if (this.loaded) return;\n\n const raw = UserInfoEngine.Instance.GetSetting(PINS_SETTING_KEY);\n if (raw) {\n try {\n const pins = JSON.parse(raw) as HomeAppPinnedItem[];\n this.Pins$.next(this.sortPins(pins));\n } catch (err) {\n console.warn('HomeAppPinService: Failed to parse saved pins, starting fresh', err);\n this.Pins$.next([]);\n }\n }\n this.loaded = true;\n }\n\n /**\n * Force reload from UserSettings (e.g. after external changes)\n */\n async ReloadPins(): Promise<void> {\n this.loaded = false;\n await this.LoadPins();\n }\n\n // =============================================\n // CRUD OPERATIONS\n // =============================================\n\n /**\n * Add a new pin. Returns false if a duplicate already exists.\n */\n AddPin(input: HomeAppPinInput): boolean {\n if (this.IsPinned(input.ResourceType, input.Configuration)) {\n return false;\n }\n\n const pins = [...this.Pins$.value];\n const newPin: HomeAppPinnedItem = {\n ...input,\n Id: this.generateId(),\n Sequence: pins.length,\n PinnedAt: new Date().toISOString()\n };\n\n pins.push(newPin);\n this.updateAndSave(pins);\n return true;\n }\n\n /**\n * Remove a pin by ID\n */\n RemovePin(pinId: string): void {\n const pins = this.Pins$.value.filter(p => p.Id !== pinId);\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n /**\n * Update pin properties (name, description, icon, group, thumbnail)\n */\n UpdatePin(pinId: string, updates: HomeAppPinUpdate): void {\n const pins = this.Pins$.value.map(p => {\n if (p.Id !== pinId) return p;\n return { ...p, ...updates };\n });\n this.updateAndSave(pins);\n }\n\n /**\n * Reorder pins. Accepts full reordered array with updated Sequence values.\n */\n ReorderPins(pins: HomeAppPinnedItem[]): void {\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n // =============================================\n // DUPLICATE DETECTION\n // =============================================\n\n /**\n * Check if a resource is already pinned\n */\n IsPinned(resourceType: string, config: Record<string, unknown>): boolean {\n return this.Pins$.value.some(pin => this.matchesResource(pin, resourceType, config));\n }\n\n /**\n * Find the pin for a given resource, if it exists\n */\n FindPin(resourceType: string, config: Record<string, unknown>): HomeAppPinnedItem | undefined {\n return this.Pins$.value.find(pin => this.matchesResource(pin, resourceType, config));\n }\n\n // =============================================\n // HELPERS\n // =============================================\n\n /**\n * Get ungrouped pins (Group is null/undefined/empty)\n */\n GetUngroupedPins(): HomeAppPinnedItem[] {\n return this.Pins$.value.filter(p => !p.Group);\n }\n\n /**\n * Get unique group names in display order (ordered by lowest Sequence in group)\n */\n GetGroups(): string[] {\n const groupMinSeq = new Map<string, number>();\n for (const pin of this.Pins$.value) {\n if (!pin.Group) continue;\n const current = groupMinSeq.get(pin.Group);\n if (current === undefined || pin.Sequence < current) {\n groupMinSeq.set(pin.Group, pin.Sequence);\n }\n }\n return [...groupMinSeq.entries()]\n .sort((a, b) => a[1] - b[1])\n .map(([name]) => name);\n }\n\n /**\n * Get pins in a specific group\n */\n GetPinsInGroup(groupName: string): HomeAppPinnedItem[] {\n return this.Pins$.value\n .filter(p => p.Group === groupName)\n .sort((a, b) => a.Sequence - b.Sequence);\n }\n\n // =============================================\n // THUMBNAIL CAPTURE\n // =============================================\n\n /**\n * Capture a thumbnail of a DOM element using html-to-image.\n * Uses SVG foreignObject so the browser's own CSS engine handles\n * modern features like color-mix() that html2canvas can't parse.\n * Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.\n */\n async CaptureThumbnail(element: HTMLElement): Promise<string | undefined> {\n try {\n if (element.clientWidth === 0 || element.clientHeight === 0) {\n return undefined;\n }\n // Bail on very large DOM trees. html-to-image clones and inlines the ENTIRE subtree\n // SYNCHRONOUSLY before it ever yields, so a heavy view (e.g. the Data Explorer's grid\n // + map) blocks the main thread for seconds — long enough to freeze the UI, and the\n // timeout below (setTimeout-based) can't even fire while the thread is blocked. A\n // thumbnail is best-effort decoration, so skip rather than jank the app.\n const nodeCount = element.getElementsByTagName('*').length;\n if (nodeCount > HomeAppPinService.THUMBNAIL_MAX_NODES) {\n return undefined;\n }\n // Race against a timeout as a secondary guard for the async portion: toJpeg() can also\n // hang on content with cross-origin resources it must re-fetch (e.g. Leaflet map tiles),\n // where the inlining/canvas step never resolves. Don't cacheBust — re-fetching every\n // image is what tends to stall, and a slightly cached preview is fine.\n const capture = toJpeg(element, {\n quality: 0.6,\n pixelRatio: 0.2,\n });\n return await this.withTimeout(capture, HomeAppPinService.THUMBNAIL_CAPTURE_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve to `undefined` if the given promise hasn't settled within `ms`.\n * Note: this does not cancel the underlying work (toJpeg is not cancelable),\n * it just stops the pin flow from waiting on it.\n */\n private withTimeout(promise: Promise<string>, ms: number): Promise<string | undefined> {\n return new Promise<string | undefined>((resolve) => {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(undefined);\n }\n }, ms);\n promise.then(\n (value) => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(value);\n }\n },\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(undefined);\n }\n }\n );\n });\n }\n\n // =============================================\n // PRIVATE\n // =============================================\n\n private matchesResource(pin: HomeAppPinnedItem, resourceType: string, config: Record<string, unknown>): boolean {\n if (pin.ResourceType !== resourceType) return false;\n switch (resourceType) {\n case 'Dashboards':\n return pin.Configuration['dashboardId'] === config['dashboardId'];\n case 'User Views':\n return pin.Configuration['viewId'] === config['viewId'];\n case 'Queries':\n return pin.Configuration['queryId'] === config['queryId'];\n case 'Records':\n return pin.Configuration['Entity'] === config['Entity']\n && pin.Configuration['recordId'] === config['recordId'];\n case 'Custom': {\n // Match by app name + nav item name + route — never use appId or driverClass\n // Include route to differentiate same nav item with different URL paths\n const sameApp = pin.Configuration['appName'] === config['appName'];\n const sameNav = pin.Configuration['navItemName'] === config['navItemName'];\n const pinRoute = pin.Configuration['route'] as string || '';\n const configRoute = config['route'] as string || '';\n const sameRoute = pinRoute === configRoute;\n // Also compare queryParams if present\n const pinQP = JSON.stringify(pin.Configuration['queryParams'] || {});\n const configQP = JSON.stringify(config['queryParams'] || {});\n const sameQP = pinQP === configQP;\n return sameApp && sameNav && sameRoute && sameQP;\n }\n case 'Actions': {\n // A pinned Action is unique per (actionId + preset-params + runtime-params + title).\n // Two pins targeting the same action with different preset configs are allowed —\n // e.g. \"Weekly Report — Sales\" vs. \"Weekly Report — Ops\" both pin \"Run Report\".\n if (pin.Configuration['actionId'] !== config['actionId']) return false;\n const pinPreset = JSON.stringify(pin.Configuration['presetParams'] ?? {});\n const configPreset = JSON.stringify(config['presetParams'] ?? {});\n const pinRuntime = JSON.stringify(pin.Configuration['runtimeParamNames'] ?? []);\n const configRuntime = JSON.stringify(config['runtimeParamNames'] ?? []);\n const samePreset = pinPreset === configPreset;\n const sameRuntime = pinRuntime === configRuntime;\n const sameTitle = pin.DisplayName === (config['displayName'] ?? pin.DisplayName);\n return samePreset && sameRuntime && sameTitle;\n }\n default:\n return false;\n }\n }\n\n private updateAndSave(pins: HomeAppPinnedItem[]): void {\n const sorted = this.sortPins(pins);\n this.Pins$.next(sorted);\n UserInfoEngine.Instance.SetSettingDebounced(\n PINS_SETTING_KEY,\n JSON.stringify(sorted)\n );\n }\n\n private sortPins(pins: HomeAppPinnedItem[]): HomeAppPinnedItem[] {\n return [...pins].sort((a, b) => a.Sequence - b.Sequence);\n }\n\n private resequence(pins: HomeAppPinnedItem[]): void {\n pins.forEach((pin, i) => { pin.Sequence = i; });\n }\n\n private generateId(): string {\n // Crypto.randomUUID is available in modern browsers\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n"]}
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
import { RecordSourceContext } from './record-open-style';
|
|
1
2
|
/**
|
|
2
3
|
* Options for controlling navigation behavior
|
|
3
4
|
*/
|
|
4
5
|
export interface NavigationOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Origin override for record opens (records-style origin crumb).
|
|
8
|
+
* - omitted: NavigationService snapshots the active app/tab — correct for
|
|
9
|
+
* in-tab surfaces, WRONG for overlays/dialogs (it blames the page behind
|
|
10
|
+
* them).
|
|
11
|
+
* - a RecordSourceContext: used verbatim. Overlay surfaces set at least
|
|
12
|
+
* `sourceLabel` ('Conversation', 'Search', ...), plus app/nav-label when
|
|
13
|
+
* there is a real place to return to.
|
|
14
|
+
* - 'none': the open has no meaningful origin (e.g. recreating a closed
|
|
15
|
+
* tab from browser history) — no crumb is rendered.
|
|
16
|
+
*/
|
|
17
|
+
recordSource?: RecordSourceContext | 'none';
|
|
5
18
|
/**
|
|
6
19
|
* Force creation of a new tab instead of replacing temporary tabs
|
|
7
20
|
* If not specified, the NavigationService will use global shift-key detection
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.interfaces.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.interfaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7C"}
|
|
1
|
+
{"version":3,"file":"navigation.interfaces.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;IAE5C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.interfaces.js","sourceRoot":"","sources":["../../src/lib/navigation.interfaces.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Options for controlling navigation behavior\n */\nexport interface NavigationOptions {\n /**\n * Force creation of a new tab instead of replacing temporary tabs\n * If not specified, the NavigationService will use global shift-key detection\n */\n forceNewTab?: boolean;\n\n /**\n * Create the tab as a pinned (permanent) tab\n */\n pinTab?: boolean;\n\n /**\n * Focus the tab after creation (default: true)\n */\n focusTab?: boolean;\n\n /**\n * Replace the currently active tab instead of creating a new one\n */\n replaceActive?: boolean;\n\n /**\n * Initial values to populate when creating a new record.\n * Should be a plain object with field names as keys.\n */\n newRecordValues?: Record<string, unknown>;\n\n /**\n * URL query parameters to set on the tab after navigation.\n * Use null values to remove a query param.\n */\n queryParams?: Record<string, string | null>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"navigation.interfaces.js","sourceRoot":"","sources":["../../src/lib/navigation.interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import { RecordSourceContext } from './record-open-style';\n\n/**\n * Options for controlling navigation behavior\n */\nexport interface NavigationOptions {\n /**\n * Origin override for record opens (records-style origin crumb).\n * - omitted: NavigationService snapshots the active app/tab — correct for\n * in-tab surfaces, WRONG for overlays/dialogs (it blames the page behind\n * them).\n * - a RecordSourceContext: used verbatim. Overlay surfaces set at least\n * `sourceLabel` ('Conversation', 'Search', ...), plus app/nav-label when\n * there is a real place to return to.\n * - 'none': the open has no meaningful origin (e.g. recreating a closed\n * tab from browser history) — no crumb is rendered.\n */\n recordSource?: RecordSourceContext | 'none';\n\n /**\n * Force creation of a new tab instead of replacing temporary tabs\n * If not specified, the NavigationService will use global shift-key detection\n */\n forceNewTab?: boolean;\n\n /**\n * Create the tab as a pinned (permanent) tab\n */\n pinTab?: boolean;\n\n /**\n * Focus the tab after creation (default: true)\n */\n focusTab?: boolean;\n\n /**\n * Replace the currently active tab instead of creating a new one\n */\n replaceActive?: boolean;\n\n /**\n * Initial values to populate when creating a new record.\n * Should be a plain object with field names as keys.\n */\n newRecordValues?: Record<string, unknown>;\n\n /**\n * URL query parameters to set on the tab after navigation.\n * Use null values to remove a query param.\n */\n queryParams?: Record<string, string | null>;\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OnDestroy } from '@angular/core';
|
|
2
2
|
import { WorkspaceStateManager, NavItem, ApplicationManager } from '@memberjunction/ng-base-application';
|
|
3
3
|
import { NavigationOptions } from './navigation.interfaces';
|
|
4
|
+
import { RecordSourceContext } from './record-open-style';
|
|
4
5
|
import { CompositeKey } from '@memberjunction/core';
|
|
5
6
|
import { BehaviorSubject, Subject, Observable } from 'rxjs';
|
|
6
7
|
import type { AppContextSnapshot } from '@memberjunction/ai-core-plus';
|
|
@@ -14,6 +15,13 @@ import * as i0 from "@angular/core";
|
|
|
14
15
|
export interface QueryParamChangeEvent {
|
|
15
16
|
TabId: string;
|
|
16
17
|
Params: Record<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Bypass the receiving component's duplicate-delivery guard. Set by
|
|
20
|
+
* explicit restore navigations (e.g. the origin crumb): the component's
|
|
21
|
+
* state may have DRIFTED from the last-delivered params, in which case a
|
|
22
|
+
* restore to those same params would otherwise be dropped as a duplicate.
|
|
23
|
+
*/
|
|
24
|
+
Force?: boolean;
|
|
17
25
|
}
|
|
18
26
|
/**
|
|
19
27
|
* Event emitted when a resource component reports its agent context or tools.
|
|
@@ -226,10 +234,69 @@ export declare class NavigationService implements OnDestroy {
|
|
|
226
234
|
*/
|
|
227
235
|
OpenNavItem(appId: string, navItem: NavItem, appColor: string, options?: NavigationOptions): string;
|
|
228
236
|
/**
|
|
229
|
-
* Open an entity record view
|
|
230
|
-
*
|
|
237
|
+
* Open an entity record view. Behavior forks on the deployment's
|
|
238
|
+
* record-open style (see record-open-style.ts):
|
|
239
|
+
* - 'records' (default): the record ALWAYS opens as its own tab, assigned
|
|
240
|
+
* to the app the user is standing in (no Home reassignment, no nav flip).
|
|
241
|
+
* Re-opening a record that's already open focuses its existing tab,
|
|
242
|
+
* browser-style. The shell's Records pill + strip are the visible UI.
|
|
243
|
+
* - 'classic': the original Home-first assignment and tab semantics.
|
|
244
|
+
* Both styles capture the source-app trail into the tab configuration for
|
|
245
|
+
* context UI and diagnostics.
|
|
231
246
|
*/
|
|
232
247
|
OpenEntityRecord(entityName: string, recordPkey: CompositeKey, options?: NavigationOptions): string;
|
|
248
|
+
/**
|
|
249
|
+
* Opening a record means the record WINS the activation race — assert it
|
|
250
|
+
* after the synchronous open flow settles. Surfaces that both emit a
|
|
251
|
+
* record-open AND run their own internal navigation in the same click
|
|
252
|
+
* (e.g. a grid row's select handler updating query params from a config
|
|
253
|
+
* snapshot captured before the open) can otherwise stomp the activation
|
|
254
|
+
* with stale state, leaving the tab open but never shown. Skipped when the
|
|
255
|
+
* tab was closed in the meantime.
|
|
256
|
+
*/
|
|
257
|
+
private assertRecordActivation;
|
|
258
|
+
/** Find an already-open tab showing this exact record (records-style dedup) */
|
|
259
|
+
private findOpenRecordTab;
|
|
260
|
+
/**
|
|
261
|
+
* Overwrite a record tab's origin with a freshly-resolved one (the dedup
|
|
262
|
+
* re-open path). All source keys are explicitly cleared first — a shallow
|
|
263
|
+
* config merge would otherwise let fields from the OLD origin shape leak
|
|
264
|
+
* through (e.g. a parent-record origin's sourceRecordEntity surviving a
|
|
265
|
+
* re-open from a nav page, or pre-schema captures keeping stale labels).
|
|
266
|
+
*/
|
|
267
|
+
private refreshSourceContext;
|
|
268
|
+
/**
|
|
269
|
+
* Resolve the source context to stamp into a record tab's configuration.
|
|
270
|
+
* Callers that are workspace tabs omit options.recordSource and get the
|
|
271
|
+
* active app/tab snapshot; overlay surfaces pass their own context;
|
|
272
|
+
* 'none' means no origin (no crumb).
|
|
273
|
+
*/
|
|
274
|
+
private resolveSourceContext;
|
|
275
|
+
/**
|
|
276
|
+
* Snapshot of where the user was when the record was
|
|
277
|
+
* opened — the source app and (when the active tab belongs to that app and
|
|
278
|
+
* isn't itself a record) the nav page they were on. Rendered by the
|
|
279
|
+
* breadcrumb strip as "App › Page › Record".
|
|
280
|
+
*/
|
|
281
|
+
private captureSourceContext;
|
|
282
|
+
/**
|
|
283
|
+
* Switch to an app's LANDING page — its default nav item in its BASE
|
|
284
|
+
* state (drifted section params cleared, reset force-delivered so the
|
|
285
|
+
* dashboard actually returns to its landing even if its state diverged).
|
|
286
|
+
* The origin crumb's APP segment uses this: classic breadcrumb semantics,
|
|
287
|
+
* each level goes to that level's home.
|
|
288
|
+
*/
|
|
289
|
+
SwitchToAppHome(appId: string): Promise<void>;
|
|
290
|
+
/**
|
|
291
|
+
* Take the user back to where they were when a record was opened (the
|
|
292
|
+
* origin crumb's click path). Fidelity ladder:
|
|
293
|
+
* 1. The exact source tab, if it's still open — reactivate it with all its
|
|
294
|
+
* state (query params, scroll, cached component) intact.
|
|
295
|
+
* 2. Otherwise re-resolve by app + nav label via SwitchToApp, which reuses
|
|
296
|
+
* a matching open tab or opens the nav item fresh.
|
|
297
|
+
* No-ops when the context has no sourceAppId (capture was best-effort).
|
|
298
|
+
*/
|
|
299
|
+
ReturnToRecordSource(origin: RecordSourceContext): Promise<void>;
|
|
233
300
|
/**
|
|
234
301
|
* Open a view
|
|
235
302
|
* Uses Home app if available, otherwise falls back to active app or system app
|
|
@@ -240,11 +307,6 @@ export declare class NavigationService implements OnDestroy {
|
|
|
240
307
|
* Uses Home app if available, otherwise falls back to active app or system app
|
|
241
308
|
*/
|
|
242
309
|
OpenDashboard(dashboardId: string, dashboardName: string, options?: NavigationOptions): string;
|
|
243
|
-
/**
|
|
244
|
-
* Open a report
|
|
245
|
-
* Uses Home app if available, otherwise falls back to active app or system app
|
|
246
|
-
*/
|
|
247
|
-
OpenReport(reportId: string, reportName: string, options?: NavigationOptions): string;
|
|
248
310
|
/**
|
|
249
311
|
* Open an artifact
|
|
250
312
|
* Artifacts are versioned content containers (reports, dashboards, UI components, etc.)
|
|
@@ -337,7 +399,7 @@ export declare class NavigationService implements OnDestroy {
|
|
|
337
399
|
* Called by the shell when back/forward navigation changes query params on the active tab.
|
|
338
400
|
* The notification includes the tab ID so only the component in that tab reacts.
|
|
339
401
|
*/
|
|
340
|
-
NotifyQueryParamsChanged(tabId: string, params: Record<string, string
|
|
402
|
+
NotifyQueryParamsChanged(tabId: string, params: Record<string, string>, force?: boolean): void;
|
|
341
403
|
/**
|
|
342
404
|
* Reactively observe the query params for a specific tab.
|
|
343
405
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.service.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAA8B,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAa,eAAe,EAAE,OAAO,EAAgB,UAAU,EAAE,MAAM,MAAM,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;
|
|
1
|
+
{"version":3,"file":"navigation.service.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"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"}
|