@memberjunction/ng-shared 5.21.0 → 5.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/base-resource-component.d.ts +8 -0
- package/dist/lib/base-resource-component.d.ts.map +1 -1
- package/dist/lib/base-resource-component.js +16 -0
- package/dist/lib/base-resource-component.js.map +1 -1
- package/dist/lib/home-pin.service.d.ts +73 -0
- package/dist/lib/home-pin.service.d.ts.map +1 -0
- package/dist/lib/home-pin.service.js +233 -0
- package/dist/lib/home-pin.service.js.map +1 -0
- package/dist/lib/home-pin.types.d.ts +41 -0
- package/dist/lib/home-pin.types.d.ts.map +1 -0
- package/dist/lib/home-pin.types.js +2 -0
- package/dist/lib/home-pin.types.js.map +1 -0
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +12 -11
|
@@ -18,8 +18,16 @@ export declare abstract class BaseResourceComponent extends BaseNavigationCompon
|
|
|
18
18
|
private _resourceRecordSavedEvent;
|
|
19
19
|
get ResourceRecordSavedEvent(): any;
|
|
20
20
|
set ResourceRecordSavedEvent(value: any);
|
|
21
|
+
private _displayNameChangedEvent;
|
|
22
|
+
get DisplayNameChangedEvent(): ((newName: string) => void) | null;
|
|
23
|
+
set DisplayNameChangedEvent(value: ((newName: string) => void) | null);
|
|
21
24
|
protected NotifyLoadComplete(): void;
|
|
22
25
|
protected NotifyLoadStarted(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Call this to notify the tab system that the resource's display name has changed.
|
|
28
|
+
* The tab container will update the tab title and browser title accordingly.
|
|
29
|
+
*/
|
|
30
|
+
protected NotifyDisplayNameChanged(newName: string): void;
|
|
23
31
|
protected ResourceRecordSaved(resourceRecordEntity: BaseEntity): void;
|
|
24
32
|
abstract GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
25
33
|
abstract GetResourceIconClass(data: ResourceData): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-resource-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-resource-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,8BAAsB,qBAAsB,SAAQ,uBAAuB;IACvE,OAAO,CAAC,KAAK,CAAoC;IAEjD,IAAW,IAAI,IAAI,YAAY,CAE9B;IACD,IAAW,IAAI,CAAC,KAAK,EAAE,YAAY,EAElC;IAED,OAAO,CAAC,aAAa,CAAkB;IACvC,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED,OAAO,CAAC,YAAY,CAAkB;IACtC,IAAW,WAAW,IAAI,OAAO,CAEhC;IAGD,OAAO,CAAC,kBAAkB,CAAa;IACvC,IAAW,iBAAiB,IAAI,GAAG,CAElC;IACD,IAAW,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAEtC;IAED,OAAO,CAAC,iBAAiB,CAAa;IACtC,IAAW,gBAAgB,IAAI,GAAG,CAEjC;IACD,IAAW,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAErC;IAED,OAAO,CAAC,yBAAyB,CAAa;IAC9C,IAAW,wBAAwB,IAAI,GAAG,CAEzC;IACD,IAAW,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAE7C;IAED,SAAS,CAAC,kBAAkB;IAO5B,SAAS,CAAC,iBAAiB;IAS3B,SAAS,CAAC,mBAAmB,CAAC,oBAAoB,EAAE,UAAU;IAO9D,QAAQ,CAAC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAEpE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;CACrE"}
|
|
1
|
+
{"version":3,"file":"base-resource-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-resource-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,8BAAsB,qBAAsB,SAAQ,uBAAuB;IACvE,OAAO,CAAC,KAAK,CAAoC;IAEjD,IAAW,IAAI,IAAI,YAAY,CAE9B;IACD,IAAW,IAAI,CAAC,KAAK,EAAE,YAAY,EAElC;IAED,OAAO,CAAC,aAAa,CAAkB;IACvC,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED,OAAO,CAAC,YAAY,CAAkB;IACtC,IAAW,WAAW,IAAI,OAAO,CAEhC;IAGD,OAAO,CAAC,kBAAkB,CAAa;IACvC,IAAW,iBAAiB,IAAI,GAAG,CAElC;IACD,IAAW,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAEtC;IAED,OAAO,CAAC,iBAAiB,CAAa;IACtC,IAAW,gBAAgB,IAAI,GAAG,CAEjC;IACD,IAAW,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAErC;IAED,OAAO,CAAC,yBAAyB,CAAa;IAC9C,IAAW,wBAAwB,IAAI,GAAG,CAEzC;IACD,IAAW,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAE7C;IAED,OAAO,CAAC,wBAAwB,CAA4C;IAC5E,IAAW,uBAAuB,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAEvE;IACD,IAAW,uBAAuB,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,EAE3E;IAED,SAAS,CAAC,kBAAkB;IAO5B,SAAS,CAAC,iBAAiB;IAS3B;;;OAGG;IACH,SAAS,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMzD,SAAS,CAAC,mBAAmB,CAAC,oBAAoB,EAAE,UAAU;IAO9D,QAAQ,CAAC,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAEpE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;CACrE"}
|
|
@@ -37,6 +37,13 @@ export class BaseResourceComponent extends BaseNavigationComponent {
|
|
|
37
37
|
set ResourceRecordSavedEvent(value) {
|
|
38
38
|
this._resourceRecordSavedEvent = value;
|
|
39
39
|
}
|
|
40
|
+
_displayNameChangedEvent = null;
|
|
41
|
+
get DisplayNameChangedEvent() {
|
|
42
|
+
return this._displayNameChangedEvent;
|
|
43
|
+
}
|
|
44
|
+
set DisplayNameChangedEvent(value) {
|
|
45
|
+
this._displayNameChangedEvent = value;
|
|
46
|
+
}
|
|
40
47
|
NotifyLoadComplete() {
|
|
41
48
|
this._loadComplete = true;
|
|
42
49
|
if (this._loadCompleteEvent) {
|
|
@@ -49,6 +56,15 @@ export class BaseResourceComponent extends BaseNavigationComponent {
|
|
|
49
56
|
this._loadStartedEvent();
|
|
50
57
|
}
|
|
51
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Call this to notify the tab system that the resource's display name has changed.
|
|
61
|
+
* The tab container will update the tab title and browser title accordingly.
|
|
62
|
+
*/
|
|
63
|
+
NotifyDisplayNameChanged(newName) {
|
|
64
|
+
if (this._displayNameChangedEvent) {
|
|
65
|
+
this._displayNameChangedEvent(newName);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
52
68
|
ResourceRecordSaved(resourceRecordEntity) {
|
|
53
69
|
this.Data.ResourceRecordID = resourceRecordEntity.PrimaryKey.ToString();
|
|
54
70
|
if (this._resourceRecordSavedEvent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-resource-component.js","sourceRoot":"","sources":["../../src/lib/base-resource-component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,OAAgB,qBAAsB,SAAQ,uBAAuB;IAC/D,KAAK,GAAiB,IAAI,YAAY,EAAE,CAAC;IAEjD,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IACD,IAAW,IAAI,CAAC,KAAmB;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAEO,aAAa,GAAY,KAAK,CAAC;IACvC,IAAW,YAAY;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEO,YAAY,GAAY,KAAK,CAAC;IACtC,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAGO,kBAAkB,GAAQ,IAAI,CAAC;IACvC,IAAW,iBAAiB;QACxB,OAAO,IAAI,CAAC,kBAAkB,CAAA;IAClC,CAAC;IACD,IAAW,iBAAiB,CAAC,KAAU;QACnC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IACpC,CAAC;IAEO,iBAAiB,GAAQ,IAAI,CAAC;IACtC,IAAW,gBAAgB;QACvB,OAAO,IAAI,CAAC,iBAAiB,CAAA;IACjC,CAAC;IACD,IAAW,gBAAgB,CAAC,KAAU;QAClC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IACnC,CAAC;IAEO,yBAAyB,GAAQ,IAAI,CAAC;IAC9C,IAAW,wBAAwB;QAC/B,OAAO,IAAI,CAAC,yBAAyB,CAAA;IACzC,CAAC;IACD,IAAW,wBAAwB,CAAC,KAAU;QAC1C,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC;IAC3C,CAAC;IAES,kBAAkB;QACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAES,iBAAiB;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;
|
|
1
|
+
{"version":3,"file":"base-resource-component.js","sourceRoot":"","sources":["../../src/lib/base-resource-component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,OAAgB,qBAAsB,SAAQ,uBAAuB;IAC/D,KAAK,GAAiB,IAAI,YAAY,EAAE,CAAC;IAEjD,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IACD,IAAW,IAAI,CAAC,KAAmB;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAEO,aAAa,GAAY,KAAK,CAAC;IACvC,IAAW,YAAY;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAEO,YAAY,GAAY,KAAK,CAAC;IACtC,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAGO,kBAAkB,GAAQ,IAAI,CAAC;IACvC,IAAW,iBAAiB;QACxB,OAAO,IAAI,CAAC,kBAAkB,CAAA;IAClC,CAAC;IACD,IAAW,iBAAiB,CAAC,KAAU;QACnC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IACpC,CAAC;IAEO,iBAAiB,GAAQ,IAAI,CAAC;IACtC,IAAW,gBAAgB;QACvB,OAAO,IAAI,CAAC,iBAAiB,CAAA;IACjC,CAAC;IACD,IAAW,gBAAgB,CAAC,KAAU;QAClC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IACnC,CAAC;IAEO,yBAAyB,GAAQ,IAAI,CAAC;IAC9C,IAAW,wBAAwB;QAC/B,OAAO,IAAI,CAAC,yBAAyB,CAAA;IACzC,CAAC;IACD,IAAW,wBAAwB,CAAC,KAAU;QAC1C,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC;IAC3C,CAAC;IAEO,wBAAwB,GAAuC,IAAI,CAAC;IAC5E,IAAW,uBAAuB;QAC9B,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACzC,CAAC;IACD,IAAW,uBAAuB,CAAC,KAAyC;QACxE,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;IAC1C,CAAC;IAES,kBAAkB;QACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAES,iBAAiB;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAID;;;OAGG;IACO,wBAAwB,CAAC,OAAe;QAC9C,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC;IAES,mBAAmB,CAAC,oBAAgC;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,oBAAoB,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACxE,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACjC,IAAI,CAAC,yBAAyB,CAAC,oBAAoB,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;CAKJ","sourcesContent":["import { BaseEntity } from \"@memberjunction/core\";\nimport { SharedService } from \"./shared.service\";\nimport { BaseNavigationComponent } from \"./base-navigation-component\";\nimport { ResourceData } from \"@memberjunction/core-entities\";\n\nexport abstract class BaseResourceComponent extends BaseNavigationComponent {\n private _data: ResourceData = new ResourceData();\n\n public get Data(): ResourceData {\n return this._data;\n }\n public set Data(value: ResourceData) {\n this._data = value;\n }\n\n private _loadComplete: boolean = false;\n public get LoadComplete(): boolean {\n return this._loadComplete;\n }\n\n private _loadStarted: boolean = false;\n public get LoadStarted(): boolean {\n return this._loadStarted;\n }\n\n \n private _loadCompleteEvent: any = null;\n public get LoadCompleteEvent(): any {\n return this._loadCompleteEvent\n }\n public set LoadCompleteEvent(value: any) {\n this._loadCompleteEvent = value;\n }\n\n private _loadStartedEvent: any = null;\n public get LoadStartedEvent(): any {\n return this._loadStartedEvent\n }\n public set LoadStartedEvent(value: any) {\n this._loadStartedEvent = value;\n }\n\n private _resourceRecordSavedEvent: any = null;\n public get ResourceRecordSavedEvent(): any {\n return this._resourceRecordSavedEvent\n }\n public set ResourceRecordSavedEvent(value: any) {\n this._resourceRecordSavedEvent = value;\n }\n\n private _displayNameChangedEvent: ((newName: string) => void) | null = null;\n public get DisplayNameChangedEvent(): ((newName: string) => void) | null {\n return this._displayNameChangedEvent;\n }\n public set DisplayNameChangedEvent(value: ((newName: string) => void) | null) {\n this._displayNameChangedEvent = value;\n }\n\n protected NotifyLoadComplete() {\n this._loadComplete = true;\n if (this._loadCompleteEvent) {\n this._loadCompleteEvent();\n }\n }\n\n protected NotifyLoadStarted() {\n this._loadStarted = true;\n if (this._loadStartedEvent) {\n this._loadStartedEvent();\n }\n }\n \n \n\n /**\n * Call this to notify the tab system that the resource's display name has changed.\n * The tab container will update the tab title and browser title accordingly.\n */\n protected NotifyDisplayNameChanged(newName: string): void {\n if (this._displayNameChangedEvent) {\n this._displayNameChangedEvent(newName);\n }\n }\n\n protected ResourceRecordSaved(resourceRecordEntity: BaseEntity) {\n this.Data.ResourceRecordID = resourceRecordEntity.PrimaryKey.ToString();\n if (this._resourceRecordSavedEvent) {\n this._resourceRecordSavedEvent(resourceRecordEntity);\n }\n }\n\n abstract GetResourceDisplayName(data: ResourceData): Promise<string>\n\n abstract GetResourceIconClass(data: ResourceData): Promise<string>\n}\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2
|
+
import { HomeAppPinnedItem, HomeAppPinInput, HomeAppPinUpdate } from './home-pin.types';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Service for managing pinned items on the Home dashboard.
|
|
6
|
+
*
|
|
7
|
+
* All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.
|
|
8
|
+
* Uses debounced saving to avoid excessive DB writes during edit mode operations.
|
|
9
|
+
*/
|
|
10
|
+
export declare class HomeAppPinService {
|
|
11
|
+
/** Observable of current pins (for reactive UI) */
|
|
12
|
+
readonly Pins$: BehaviorSubject<HomeAppPinnedItem[]>;
|
|
13
|
+
private loaded;
|
|
14
|
+
/**
|
|
15
|
+
* Load pins from UserSettings. Safe to call multiple times (loads only once).
|
|
16
|
+
*/
|
|
17
|
+
LoadPins(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Force reload from UserSettings (e.g. after external changes)
|
|
20
|
+
*/
|
|
21
|
+
ReloadPins(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Add a new pin. Returns false if a duplicate already exists.
|
|
24
|
+
*/
|
|
25
|
+
AddPin(input: HomeAppPinInput): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Remove a pin by ID
|
|
28
|
+
*/
|
|
29
|
+
RemovePin(pinId: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Update pin properties (name, description, icon, group, thumbnail)
|
|
32
|
+
*/
|
|
33
|
+
UpdatePin(pinId: string, updates: HomeAppPinUpdate): void;
|
|
34
|
+
/**
|
|
35
|
+
* Reorder pins. Accepts full reordered array with updated Sequence values.
|
|
36
|
+
*/
|
|
37
|
+
ReorderPins(pins: HomeAppPinnedItem[]): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a resource is already pinned
|
|
40
|
+
*/
|
|
41
|
+
IsPinned(resourceType: string, config: Record<string, unknown>): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Find the pin for a given resource, if it exists
|
|
44
|
+
*/
|
|
45
|
+
FindPin(resourceType: string, config: Record<string, unknown>): HomeAppPinnedItem | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Get ungrouped pins (Group is null/undefined/empty)
|
|
48
|
+
*/
|
|
49
|
+
GetUngroupedPins(): HomeAppPinnedItem[];
|
|
50
|
+
/**
|
|
51
|
+
* Get unique group names in display order (ordered by lowest Sequence in group)
|
|
52
|
+
*/
|
|
53
|
+
GetGroups(): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Get pins in a specific group
|
|
56
|
+
*/
|
|
57
|
+
GetPinsInGroup(groupName: string): HomeAppPinnedItem[];
|
|
58
|
+
/**
|
|
59
|
+
* Capture a thumbnail of a DOM element using html-to-image.
|
|
60
|
+
* Uses SVG foreignObject so the browser's own CSS engine handles
|
|
61
|
+
* modern features like color-mix() that html2canvas can't parse.
|
|
62
|
+
* Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.
|
|
63
|
+
*/
|
|
64
|
+
CaptureThumbnail(element: HTMLElement): Promise<string | undefined>;
|
|
65
|
+
private matchesResource;
|
|
66
|
+
private updateAndSave;
|
|
67
|
+
private sortPins;
|
|
68
|
+
private resequence;
|
|
69
|
+
private generateId;
|
|
70
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<HomeAppPinService, never>;
|
|
71
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<HomeAppPinService>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=home-pin.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home-pin.service.d.ts","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;;AAKxF;;;;;GAKG;AACH,qBACa,iBAAiB;IAC5B,mDAAmD;IACnD,SAAgB,KAAK,uCAAgD;IAErE,OAAO,CAAC,MAAM,CAAS;IAMvB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAkBvC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAQzD;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAS5C;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAIxE;;OAEG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,GAAG,SAAS;IAQ7F;;OAEG;IACH,gBAAgB,IAAI,iBAAiB,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAcrB;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAUtD;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAmBzE,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;yCAhOP,iBAAiB;6CAAjB,iBAAiB;CA4O7B"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
4
|
+
import { toJpeg } from 'html-to-image';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/** UserSettings key for persisting pins */
|
|
7
|
+
const PINS_SETTING_KEY = 'HomeApp.PinnedItems';
|
|
8
|
+
/**
|
|
9
|
+
* Service for managing pinned items on the Home dashboard.
|
|
10
|
+
*
|
|
11
|
+
* All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.
|
|
12
|
+
* Uses debounced saving to avoid excessive DB writes during edit mode operations.
|
|
13
|
+
*/
|
|
14
|
+
export class HomeAppPinService {
|
|
15
|
+
/** Observable of current pins (for reactive UI) */
|
|
16
|
+
Pins$ = new BehaviorSubject([]);
|
|
17
|
+
loaded = false;
|
|
18
|
+
// =============================================
|
|
19
|
+
// LOADING
|
|
20
|
+
// =============================================
|
|
21
|
+
/**
|
|
22
|
+
* Load pins from UserSettings. Safe to call multiple times (loads only once).
|
|
23
|
+
*/
|
|
24
|
+
async LoadPins() {
|
|
25
|
+
if (this.loaded)
|
|
26
|
+
return;
|
|
27
|
+
const raw = UserInfoEngine.Instance.GetSetting(PINS_SETTING_KEY);
|
|
28
|
+
if (raw) {
|
|
29
|
+
try {
|
|
30
|
+
const pins = JSON.parse(raw);
|
|
31
|
+
this.Pins$.next(this.sortPins(pins));
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.warn('HomeAppPinService: Failed to parse saved pins, starting fresh', err);
|
|
35
|
+
this.Pins$.next([]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
this.loaded = true;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Force reload from UserSettings (e.g. after external changes)
|
|
42
|
+
*/
|
|
43
|
+
async ReloadPins() {
|
|
44
|
+
this.loaded = false;
|
|
45
|
+
await this.LoadPins();
|
|
46
|
+
}
|
|
47
|
+
// =============================================
|
|
48
|
+
// CRUD OPERATIONS
|
|
49
|
+
// =============================================
|
|
50
|
+
/**
|
|
51
|
+
* Add a new pin. Returns false if a duplicate already exists.
|
|
52
|
+
*/
|
|
53
|
+
AddPin(input) {
|
|
54
|
+
if (this.IsPinned(input.ResourceType, input.Configuration)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const pins = [...this.Pins$.value];
|
|
58
|
+
const newPin = {
|
|
59
|
+
...input,
|
|
60
|
+
Id: this.generateId(),
|
|
61
|
+
Sequence: pins.length,
|
|
62
|
+
PinnedAt: new Date().toISOString()
|
|
63
|
+
};
|
|
64
|
+
pins.push(newPin);
|
|
65
|
+
this.updateAndSave(pins);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Remove a pin by ID
|
|
70
|
+
*/
|
|
71
|
+
RemovePin(pinId) {
|
|
72
|
+
const pins = this.Pins$.value.filter(p => p.Id !== pinId);
|
|
73
|
+
this.resequence(pins);
|
|
74
|
+
this.updateAndSave(pins);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Update pin properties (name, description, icon, group, thumbnail)
|
|
78
|
+
*/
|
|
79
|
+
UpdatePin(pinId, updates) {
|
|
80
|
+
const pins = this.Pins$.value.map(p => {
|
|
81
|
+
if (p.Id !== pinId)
|
|
82
|
+
return p;
|
|
83
|
+
return { ...p, ...updates };
|
|
84
|
+
});
|
|
85
|
+
this.updateAndSave(pins);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Reorder pins. Accepts full reordered array with updated Sequence values.
|
|
89
|
+
*/
|
|
90
|
+
ReorderPins(pins) {
|
|
91
|
+
this.resequence(pins);
|
|
92
|
+
this.updateAndSave(pins);
|
|
93
|
+
}
|
|
94
|
+
// =============================================
|
|
95
|
+
// DUPLICATE DETECTION
|
|
96
|
+
// =============================================
|
|
97
|
+
/**
|
|
98
|
+
* Check if a resource is already pinned
|
|
99
|
+
*/
|
|
100
|
+
IsPinned(resourceType, config) {
|
|
101
|
+
return this.Pins$.value.some(pin => this.matchesResource(pin, resourceType, config));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Find the pin for a given resource, if it exists
|
|
105
|
+
*/
|
|
106
|
+
FindPin(resourceType, config) {
|
|
107
|
+
return this.Pins$.value.find(pin => this.matchesResource(pin, resourceType, config));
|
|
108
|
+
}
|
|
109
|
+
// =============================================
|
|
110
|
+
// HELPERS
|
|
111
|
+
// =============================================
|
|
112
|
+
/**
|
|
113
|
+
* Get ungrouped pins (Group is null/undefined/empty)
|
|
114
|
+
*/
|
|
115
|
+
GetUngroupedPins() {
|
|
116
|
+
return this.Pins$.value.filter(p => !p.Group);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get unique group names in display order (ordered by lowest Sequence in group)
|
|
120
|
+
*/
|
|
121
|
+
GetGroups() {
|
|
122
|
+
const groupMinSeq = new Map();
|
|
123
|
+
for (const pin of this.Pins$.value) {
|
|
124
|
+
if (!pin.Group)
|
|
125
|
+
continue;
|
|
126
|
+
const current = groupMinSeq.get(pin.Group);
|
|
127
|
+
if (current === undefined || pin.Sequence < current) {
|
|
128
|
+
groupMinSeq.set(pin.Group, pin.Sequence);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return [...groupMinSeq.entries()]
|
|
132
|
+
.sort((a, b) => a[1] - b[1])
|
|
133
|
+
.map(([name]) => name);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get pins in a specific group
|
|
137
|
+
*/
|
|
138
|
+
GetPinsInGroup(groupName) {
|
|
139
|
+
return this.Pins$.value
|
|
140
|
+
.filter(p => p.Group === groupName)
|
|
141
|
+
.sort((a, b) => a.Sequence - b.Sequence);
|
|
142
|
+
}
|
|
143
|
+
// =============================================
|
|
144
|
+
// THUMBNAIL CAPTURE
|
|
145
|
+
// =============================================
|
|
146
|
+
/**
|
|
147
|
+
* Capture a thumbnail of a DOM element using html-to-image.
|
|
148
|
+
* Uses SVG foreignObject so the browser's own CSS engine handles
|
|
149
|
+
* modern features like color-mix() that html2canvas can't parse.
|
|
150
|
+
* Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.
|
|
151
|
+
*/
|
|
152
|
+
async CaptureThumbnail(element) {
|
|
153
|
+
try {
|
|
154
|
+
if (element.clientWidth === 0 || element.clientHeight === 0) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
return await toJpeg(element, {
|
|
158
|
+
quality: 0.6,
|
|
159
|
+
pixelRatio: 0.2,
|
|
160
|
+
cacheBust: true,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// =============================================
|
|
168
|
+
// PRIVATE
|
|
169
|
+
// =============================================
|
|
170
|
+
matchesResource(pin, resourceType, config) {
|
|
171
|
+
if (pin.ResourceType !== resourceType)
|
|
172
|
+
return false;
|
|
173
|
+
switch (resourceType) {
|
|
174
|
+
case 'Dashboards':
|
|
175
|
+
return pin.Configuration['dashboardId'] === config['dashboardId'];
|
|
176
|
+
case 'User Views':
|
|
177
|
+
return pin.Configuration['viewId'] === config['viewId'];
|
|
178
|
+
case 'Queries':
|
|
179
|
+
return pin.Configuration['queryId'] === config['queryId'];
|
|
180
|
+
case 'Reports':
|
|
181
|
+
return pin.Configuration['reportId'] === config['reportId'];
|
|
182
|
+
case 'Records':
|
|
183
|
+
return pin.Configuration['Entity'] === config['Entity']
|
|
184
|
+
&& pin.Configuration['recordId'] === config['recordId'];
|
|
185
|
+
case 'Custom': {
|
|
186
|
+
// Match by app name + nav item name + route — never use appId or driverClass
|
|
187
|
+
// Include route to differentiate same nav item with different URL paths
|
|
188
|
+
const sameApp = pin.Configuration['appName'] === config['appName'];
|
|
189
|
+
const sameNav = pin.Configuration['navItemName'] === config['navItemName'];
|
|
190
|
+
const pinRoute = pin.Configuration['route'] || '';
|
|
191
|
+
const configRoute = config['route'] || '';
|
|
192
|
+
const sameRoute = pinRoute === configRoute;
|
|
193
|
+
// Also compare queryParams if present
|
|
194
|
+
const pinQP = JSON.stringify(pin.Configuration['queryParams'] || {});
|
|
195
|
+
const configQP = JSON.stringify(config['queryParams'] || {});
|
|
196
|
+
const sameQP = pinQP === configQP;
|
|
197
|
+
return sameApp && sameNav && sameRoute && sameQP;
|
|
198
|
+
}
|
|
199
|
+
default:
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
updateAndSave(pins) {
|
|
204
|
+
const sorted = this.sortPins(pins);
|
|
205
|
+
this.Pins$.next(sorted);
|
|
206
|
+
UserInfoEngine.Instance.SetSettingDebounced(PINS_SETTING_KEY, JSON.stringify(sorted));
|
|
207
|
+
}
|
|
208
|
+
sortPins(pins) {
|
|
209
|
+
return [...pins].sort((a, b) => a.Sequence - b.Sequence);
|
|
210
|
+
}
|
|
211
|
+
resequence(pins) {
|
|
212
|
+
pins.forEach((pin, i) => { pin.Sequence = i; });
|
|
213
|
+
}
|
|
214
|
+
generateId() {
|
|
215
|
+
// Crypto.randomUUID is available in modern browsers
|
|
216
|
+
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
217
|
+
return crypto.randomUUID();
|
|
218
|
+
}
|
|
219
|
+
// Fallback for older browsers
|
|
220
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
221
|
+
const r = (Math.random() * 16) | 0;
|
|
222
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
223
|
+
return v.toString(16);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
static ɵfac = function HomeAppPinService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HomeAppPinService)(); };
|
|
227
|
+
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HomeAppPinService, factory: HomeAppPinService.ɵfac, providedIn: 'root' });
|
|
228
|
+
}
|
|
229
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeAppPinService, [{
|
|
230
|
+
type: Injectable,
|
|
231
|
+
args: [{ providedIn: 'root' }]
|
|
232
|
+
}], null, null); })();
|
|
233
|
+
//# sourceMappingURL=home-pin.service.js.map
|
|
@@ -0,0 +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 /** 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 return await toJpeg(element, {\n quality: 0.6,\n pixelRatio: 0.2,\n cacheBust: true,\n });\n } catch {\n return undefined;\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 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"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A pinned item on the Home dashboard.
|
|
3
|
+
* Stored as JSON array in UserSettings key 'HomeApp.PinnedItems'.
|
|
4
|
+
*/
|
|
5
|
+
export interface HomeAppPinnedItem {
|
|
6
|
+
/** Client-generated UUID */
|
|
7
|
+
Id: string;
|
|
8
|
+
/** User-editable display name (defaults to tab title at pin time) */
|
|
9
|
+
DisplayName: string;
|
|
10
|
+
/** Optional user-editable subtitle */
|
|
11
|
+
Description?: string;
|
|
12
|
+
/** FA icon class override. Null = auto-resolve from entity/app metadata */
|
|
13
|
+
Icon?: string;
|
|
14
|
+
/** Hex color override. Null = derive from source app's Color */
|
|
15
|
+
Color?: string;
|
|
16
|
+
/** MJ resource type: "Dashboards", "User Views", "Reports", "Queries", "Records", "Custom" */
|
|
17
|
+
ResourceType: string;
|
|
18
|
+
/** Source app ID (null = orphan / Home context) */
|
|
19
|
+
ApplicationID?: string;
|
|
20
|
+
/** Source app name for display badge ("AI", "CRM", etc.) */
|
|
21
|
+
ApplicationName?: string;
|
|
22
|
+
/** Full TabConfiguration blob - everything needed to re-open the resource */
|
|
23
|
+
Configuration: Record<string, unknown>;
|
|
24
|
+
/** Base64 JPEG thumbnail screenshot (~5-15KB at 0.2x scale). Null = use icon fallback */
|
|
25
|
+
Thumbnail?: string;
|
|
26
|
+
/** Display order within group (0-based) */
|
|
27
|
+
Sequence: number;
|
|
28
|
+
/** Optional group name for organizing pins. Null = ungrouped (shown first) */
|
|
29
|
+
Group?: string;
|
|
30
|
+
/** ISO timestamp of when this was pinned */
|
|
31
|
+
PinnedAt: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Input for creating a new pin (ID, Sequence, and PinnedAt are auto-generated)
|
|
35
|
+
*/
|
|
36
|
+
export type HomeAppPinInput = Omit<HomeAppPinnedItem, 'Id' | 'Sequence' | 'PinnedAt'>;
|
|
37
|
+
/**
|
|
38
|
+
* Fields that can be updated on an existing pin
|
|
39
|
+
*/
|
|
40
|
+
export type HomeAppPinUpdate = Partial<Pick<HomeAppPinnedItem, 'DisplayName' | 'Description' | 'Icon' | 'Color' | 'Group' | 'Thumbnail'>>;
|
|
41
|
+
//# sourceMappingURL=home-pin.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home-pin.types.d.ts","sourceRoot":"","sources":["../../src/lib/home-pin.types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IAEX,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IAEpB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IAErB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvC,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IAEjB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home-pin.types.js","sourceRoot":"","sources":["../../src/lib/home-pin.types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A pinned item on the Home dashboard.\n * Stored as JSON array in UserSettings key 'HomeApp.PinnedItems'.\n */\nexport interface HomeAppPinnedItem {\n /** Client-generated UUID */\n Id: string;\n\n /** User-editable display name (defaults to tab title at pin time) */\n DisplayName: string;\n\n /** Optional user-editable subtitle */\n Description?: string;\n\n /** FA icon class override. Null = auto-resolve from entity/app metadata */\n Icon?: string;\n\n /** Hex color override. Null = derive from source app's Color */\n Color?: string;\n\n /** MJ resource type: \"Dashboards\", \"User Views\", \"Reports\", \"Queries\", \"Records\", \"Custom\" */\n ResourceType: string;\n\n /** Source app ID (null = orphan / Home context) */\n ApplicationID?: string;\n\n /** Source app name for display badge (\"AI\", \"CRM\", etc.) */\n ApplicationName?: string;\n\n /** Full TabConfiguration blob - everything needed to re-open the resource */\n Configuration: Record<string, unknown>;\n\n /** Base64 JPEG thumbnail screenshot (~5-15KB at 0.2x scale). Null = use icon fallback */\n Thumbnail?: string;\n\n /** Display order within group (0-based) */\n Sequence: number;\n\n /** Optional group name for organizing pins. Null = ungrouped (shown first) */\n Group?: string;\n\n /** ISO timestamp of when this was pinned */\n PinnedAt: string;\n}\n\n/**\n * Input for creating a new pin (ID, Sequence, and PinnedAt are auto-generated)\n */\nexport type HomeAppPinInput = Omit<HomeAppPinnedItem, 'Id' | 'Sequence' | 'PinnedAt'>;\n\n/**\n * Fields that can be updated on an existing pin\n */\nexport type HomeAppPinUpdate = Partial<Pick<HomeAppPinnedItem, 'DisplayName' | 'Description' | 'Icon' | 'Color' | 'Group' | 'Thumbnail'>>;\n"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from './lib/navigation.service';
|
|
|
8
8
|
export * from './lib/navigation.interfaces';
|
|
9
9
|
export * from './lib/title.service';
|
|
10
10
|
export * from './lib/developer-mode.service';
|
|
11
|
+
export * from './lib/home-pin.types';
|
|
12
|
+
export * from './lib/home-pin.service';
|
|
11
13
|
export { SYSTEM_APP_ID } from './lib/navigation.service';
|
|
12
14
|
export * from '@memberjunction/ng-shared-generic';
|
|
13
15
|
export * from './module';
|
package/dist/public-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,cAAc,mCAAmC,CAAC;AAClD,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,cAAc,mCAAmC,CAAC;AAClD,cAAc,UAAU,CAAC"}
|
package/dist/public-api.js
CHANGED
|
@@ -11,6 +11,8 @@ export * from './lib/navigation.service';
|
|
|
11
11
|
export * from './lib/navigation.interfaces';
|
|
12
12
|
export * from './lib/title.service';
|
|
13
13
|
export * from './lib/developer-mode.service';
|
|
14
|
+
export * from './lib/home-pin.types';
|
|
15
|
+
export * from './lib/home-pin.service';
|
|
14
16
|
export { SYSTEM_APP_ID } from './lib/navigation.service';
|
|
15
17
|
// Re-export from ng-shared-generic for backwards compatibility
|
|
16
18
|
export * from '@memberjunction/ng-shared-generic';
|
package/dist/public-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,+DAA+D;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,UAAU,CAAC","sourcesContent":["/*\n * Public API Surface\n */\n\nexport * from './lib/urlPipe';\nexport * from './lib/base-dashboard';\nexport * from './lib/simpleTextFormat';\nexport * from './lib/shared.service';\nexport * from './lib/base-resource-component'\nexport * from './lib/base-navigation-component';\nexport * from './lib/navigation.service';\nexport * from './lib/navigation.interfaces';\nexport * from './lib/title.service';\nexport * from './lib/developer-mode.service';\nexport { SYSTEM_APP_ID } from './lib/navigation.service';\n// Re-export from ng-shared-generic for backwards compatibility\nexport * from '@memberjunction/ng-shared-generic';\nexport * from './module';"]}
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,+DAA+D;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,UAAU,CAAC","sourcesContent":["/*\n * Public API Surface\n */\n\nexport * from './lib/urlPipe';\nexport * from './lib/base-dashboard';\nexport * from './lib/simpleTextFormat';\nexport * from './lib/shared.service';\nexport * from './lib/base-resource-component'\nexport * from './lib/base-navigation-component';\nexport * from './lib/navigation.service';\nexport * from './lib/navigation.interfaces';\nexport * from './lib/title.service';\nexport * from './lib/developer-mode.service';\nexport * from './lib/home-pin.types';\nexport * from './lib/home-pin.service';\nexport { SYSTEM_APP_ID } from './lib/navigation.service';\n// Re-export from ng-shared-generic for backwards compatibility\nexport * from '@memberjunction/ng-shared-generic';\nexport * from './module';"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-shared",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.22.0",
|
|
4
4
|
"description": "MemberJunction: MJ Explorer Angular Shared Package - utility functions and other reusable elements used across other MJ Angular packages within the MJ Explorer App - do not use outside of MJ Explorer.",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -29,17 +29,18 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@angular/platform-browser": "21.1.3",
|
|
32
|
-
"@memberjunction/ai-engine-base": "5.
|
|
33
|
-
"@memberjunction/core": "5.
|
|
34
|
-
"@memberjunction/core-entities": "5.
|
|
35
|
-
"@memberjunction/global": "5.
|
|
36
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
37
|
-
"@memberjunction/entity-communications-base": "5.
|
|
38
|
-
"@memberjunction/ng-base-application": "5.
|
|
39
|
-
"@memberjunction/ng-base-types": "5.
|
|
40
|
-
"@memberjunction/ng-notifications": "5.
|
|
41
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
32
|
+
"@memberjunction/ai-engine-base": "5.22.0",
|
|
33
|
+
"@memberjunction/core": "5.22.0",
|
|
34
|
+
"@memberjunction/core-entities": "5.22.0",
|
|
35
|
+
"@memberjunction/global": "5.22.0",
|
|
36
|
+
"@memberjunction/graphql-dataprovider": "5.22.0",
|
|
37
|
+
"@memberjunction/entity-communications-base": "5.22.0",
|
|
38
|
+
"@memberjunction/ng-base-application": "5.22.0",
|
|
39
|
+
"@memberjunction/ng-base-types": "5.22.0",
|
|
40
|
+
"@memberjunction/ng-notifications": "5.22.0",
|
|
41
|
+
"@memberjunction/ng-shared-generic": "5.22.0",
|
|
42
42
|
"@progress/kendo-angular-notification": "22.0.1",
|
|
43
|
+
"html-to-image": "^1.11.11",
|
|
43
44
|
"tslib": "^2.8.1"
|
|
44
45
|
},
|
|
45
46
|
"sideEffects": false,
|