@memberjunction/ng-explorer-core 6.2.0-edge.1 → 6.2.0-edge.3
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/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +22 -2
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +7 -3
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +10 -5
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +13 -2
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +35 -6
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts +46 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js +62 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js.map +1 -0
- package/dist/lib/resource-wrappers/human-handoff-console-resource.component.d.ts +32 -0
- package/dist/lib/resource-wrappers/human-handoff-console-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/human-handoff-console-resource.component.js +114 -0
- package/dist/lib/resource-wrappers/human-handoff-console-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +13 -0
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js +210 -132
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/meetings-resource.component.d.ts +42 -0
- package/dist/lib/resource-wrappers/meetings-resource.component.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/meetings-resource.component.js +225 -0
- package/dist/lib/resource-wrappers/meetings-resource.component.js.map +1 -0
- package/dist/lib/resource-wrappers/record-resource.component.d.ts +27 -2
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +58 -6
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +6 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +37 -7
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/server-connectivity.service.d.ts +9 -4
- package/dist/lib/services/server-connectivity.service.d.ts.map +1 -1
- package/dist/lib/services/server-connectivity.service.js +56 -12
- package/dist/lib/services/server-connectivity.service.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +31 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +57 -2
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +2 -0
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +19 -9
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +29 -3
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +44 -4
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +13 -0
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +67 -0
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/module.d.ts +36 -33
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -4
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +53 -52
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Component } from '@angular/core';
|
|
8
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { GraphQLDataProvider, GraphQLMeetingClient, } from '@memberjunction/graphql-dataprovider';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
import * as i1 from "@memberjunction/ng-mj-livekit-room";
|
|
13
|
+
function MeetingsResource_Case_0_Template(rf, ctx) { if (rf & 1) {
|
|
14
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
15
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "mj-livekit-agent-room", 2);
|
|
16
|
+
i0.ɵɵlistener("Disconnected", function MeetingsResource_Case_0_Template_mj_livekit_agent_room_Disconnected_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLiveRoomLeft()); });
|
|
17
|
+
i0.ɵɵelementEnd()();
|
|
18
|
+
} if (rf & 2) {
|
|
19
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
20
|
+
i0.ɵɵadvance();
|
|
21
|
+
i0.ɵɵproperty("RoomName", ctx_r1.LiveRoomName)("Provider", ctx_r1.ProviderToUse)("StartWithMicrophone", ctx_r1.StartWithMic)("StartWithCamera", ctx_r1.StartWithCam)("ShowAgentState", true)("EnableLayoutSwitcher", true)("EnableLeaveControl", true);
|
|
22
|
+
} }
|
|
23
|
+
function MeetingsResource_Case_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
25
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "button", 3);
|
|
26
|
+
i0.ɵɵlistener("click", function MeetingsResource_Case_1_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnLobbyCancelled()); });
|
|
27
|
+
i0.ɵɵelement(2, "i", 4);
|
|
28
|
+
i0.ɵɵtext(3, " Back to Meetings ");
|
|
29
|
+
i0.ɵɵelementEnd();
|
|
30
|
+
i0.ɵɵelementStart(4, "mj-meeting-lobby", 5);
|
|
31
|
+
i0.ɵɵlistener("JoinConfirmed", function MeetingsResource_Case_1_Conditional_0_Template_mj_meeting_lobby_JoinConfirmed_4_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnJoinConfirmed($event)); })("Cancelled", function MeetingsResource_Case_1_Conditional_0_Template_mj_meeting_lobby_Cancelled_4_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnLobbyCancelled()); });
|
|
32
|
+
i0.ɵɵelementEnd()();
|
|
33
|
+
} if (rf & 2) {
|
|
34
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
35
|
+
i0.ɵɵadvance(4);
|
|
36
|
+
i0.ɵɵproperty("Meeting", ctx_r1.ActiveMeeting)("Provider", ctx_r1.ProviderToUse);
|
|
37
|
+
} }
|
|
38
|
+
function MeetingsResource_Case_1_Template(rf, ctx) { if (rf & 1) {
|
|
39
|
+
i0.ɵɵconditionalCreate(0, MeetingsResource_Case_1_Conditional_0_Template, 5, 2, "div", 1);
|
|
40
|
+
} if (rf & 2) {
|
|
41
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
42
|
+
i0.ɵɵconditional(ctx_r1.ActiveMeeting ? 0 : -1);
|
|
43
|
+
} }
|
|
44
|
+
function MeetingsResource_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
45
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
46
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "button", 3);
|
|
47
|
+
i0.ɵɵlistener("click", function MeetingsResource_Case_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScheduleCancelled()); });
|
|
48
|
+
i0.ɵɵelement(2, "i", 4);
|
|
49
|
+
i0.ɵɵtext(3, " Back to Meetings ");
|
|
50
|
+
i0.ɵɵelementEnd();
|
|
51
|
+
i0.ɵɵelementStart(4, "mj-meeting-schedule-form", 6);
|
|
52
|
+
i0.ɵɵlistener("MeetingSaved", function MeetingsResource_Case_2_Template_mj_meeting_schedule_form_MeetingSaved_4_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnMeetingSaved($event)); })("Cancelled", function MeetingsResource_Case_2_Template_mj_meeting_schedule_form_Cancelled_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScheduleCancelled()); });
|
|
53
|
+
i0.ɵɵelementEnd()();
|
|
54
|
+
} if (rf & 2) {
|
|
55
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
56
|
+
i0.ɵɵadvance(4);
|
|
57
|
+
i0.ɵɵproperty("Provider", ctx_r1.ProviderToUse)("Meeting", ctx_r1.EditingMeeting || undefined);
|
|
58
|
+
} }
|
|
59
|
+
function MeetingsResource_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
61
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "mj-meeting-list", 7);
|
|
62
|
+
i0.ɵɵlistener("JoinMeeting", function MeetingsResource_Case_3_Template_mj_meeting_list_JoinMeeting_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnJoinMeetingFromList($event)); })("ScheduleRequested", function MeetingsResource_Case_3_Template_mj_meeting_list_ScheduleRequested_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnScheduleRequested()); })("EditMeetingRequested", function MeetingsResource_Case_3_Template_mj_meeting_list_EditMeetingRequested_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnEditMeetingRequested($event)); });
|
|
63
|
+
i0.ɵɵelementEnd()();
|
|
64
|
+
} if (rf & 2) {
|
|
65
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
66
|
+
i0.ɵɵadvance();
|
|
67
|
+
i0.ɵɵproperty("Provider", ctx_r1.ProviderToUse);
|
|
68
|
+
} }
|
|
69
|
+
/**
|
|
70
|
+
* Meetings Resource — multi-party scheduled and ad-hoc meeting hub in Explorer (the Meet app's "Meetings").
|
|
71
|
+
*
|
|
72
|
+
* Coordinates:
|
|
73
|
+
* - Meeting list view (`mj-meeting-list`)
|
|
74
|
+
* - Scheduling / editing form (`mj-meeting-schedule-form`)
|
|
75
|
+
* - Pre-join lobby with AV checks & dial-in info (`mj-meeting-lobby`)
|
|
76
|
+
* - Active multi-party call (`mj-livekit-agent-room` in join mode)
|
|
77
|
+
*
|
|
78
|
+
* Registered via `@RegisterClass(BaseResourceComponent, 'MeetingsResource')`.
|
|
79
|
+
*/
|
|
80
|
+
let MeetingsResource = class MeetingsResource extends BaseResourceComponent {
|
|
81
|
+
Phase = 'list';
|
|
82
|
+
ActiveMeeting = null;
|
|
83
|
+
EditingMeeting = null;
|
|
84
|
+
LiveRoomName = '';
|
|
85
|
+
StartWithMic = true;
|
|
86
|
+
StartWithCam = false;
|
|
87
|
+
ngOnInit() {
|
|
88
|
+
super.ngOnInit();
|
|
89
|
+
void this.initialize();
|
|
90
|
+
}
|
|
91
|
+
async initialize() {
|
|
92
|
+
const config = this.Data?.Configuration;
|
|
93
|
+
const initialMeetingId = config?.MeetingID || this.Data?.ResourceRecordID;
|
|
94
|
+
if (initialMeetingId) {
|
|
95
|
+
try {
|
|
96
|
+
const client = new GraphQLMeetingClient(this.ProviderToUse || GraphQLDataProvider.Instance);
|
|
97
|
+
const meeting = await client.GetMeeting(initialMeetingId);
|
|
98
|
+
if (meeting) {
|
|
99
|
+
this.ActiveMeeting = meeting;
|
|
100
|
+
this.Phase = 'lobby';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.warn('MeetingsResource: unable to resolve initial meeting deep-link', err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.NotifyLoadComplete();
|
|
108
|
+
}
|
|
109
|
+
OnScheduleRequested() {
|
|
110
|
+
this.EditingMeeting = null;
|
|
111
|
+
this.Phase = 'schedule';
|
|
112
|
+
}
|
|
113
|
+
OnEditMeetingRequested(meeting) {
|
|
114
|
+
this.EditingMeeting = meeting;
|
|
115
|
+
this.Phase = 'schedule';
|
|
116
|
+
}
|
|
117
|
+
OnMeetingSaved(meeting) {
|
|
118
|
+
this.ActiveMeeting = meeting;
|
|
119
|
+
this.EditingMeeting = null;
|
|
120
|
+
this.Phase = 'lobby';
|
|
121
|
+
}
|
|
122
|
+
OnScheduleCancelled() {
|
|
123
|
+
this.EditingMeeting = null;
|
|
124
|
+
this.Phase = 'list';
|
|
125
|
+
}
|
|
126
|
+
OnJoinMeetingFromList(meeting) {
|
|
127
|
+
this.ActiveMeeting = meeting;
|
|
128
|
+
this.Phase = 'lobby';
|
|
129
|
+
}
|
|
130
|
+
OnJoinConfirmed(prefs) {
|
|
131
|
+
this.StartWithMic = prefs.startWithAudio;
|
|
132
|
+
this.StartWithCam = prefs.startWithVideo;
|
|
133
|
+
this.LiveRoomName = this.ActiveMeeting?.RoomName || '';
|
|
134
|
+
this.Phase = 'live';
|
|
135
|
+
}
|
|
136
|
+
OnLobbyCancelled() {
|
|
137
|
+
this.ActiveMeeting = null;
|
|
138
|
+
this.Phase = 'list';
|
|
139
|
+
}
|
|
140
|
+
OnLiveRoomLeft() {
|
|
141
|
+
this.LiveRoomName = '';
|
|
142
|
+
this.ActiveMeeting = null;
|
|
143
|
+
this.Phase = 'list';
|
|
144
|
+
}
|
|
145
|
+
async GetResourceDisplayName(_data) {
|
|
146
|
+
return this.ActiveMeeting?.Title || 'Meetings';
|
|
147
|
+
}
|
|
148
|
+
async GetResourceIconClass(_data) {
|
|
149
|
+
return 'fa-solid fa-calendar-users';
|
|
150
|
+
}
|
|
151
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵMeetingsResource_BaseFactory; return function MeetingsResource_Factory(__ngFactoryType__) { return (ɵMeetingsResource_BaseFactory || (ɵMeetingsResource_BaseFactory = i0.ɵɵgetInheritedFactory(MeetingsResource)))(__ngFactoryType__ || MeetingsResource); }; })();
|
|
152
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MeetingsResource, selectors: [["mj-meetings-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 1, consts: [[1, "mj-mtg-live-container"], [1, "mj-mtg-resource-wrapper"], ["Mode", "join", 1, "mj-mtg-room", 3, "Disconnected", "RoomName", "Provider", "StartWithMicrophone", "StartWithCamera", "ShowAgentState", "EnableLayoutSwitcher", "EnableLeaveControl"], ["type", "button", 1, "mj-mtg-back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [3, "JoinConfirmed", "Cancelled", "Meeting", "Provider"], [3, "MeetingSaved", "Cancelled", "Provider", "Meeting"], [3, "JoinMeeting", "ScheduleRequested", "EditMeetingRequested", "Provider"]], template: function MeetingsResource_Template(rf, ctx) { if (rf & 1) {
|
|
153
|
+
i0.ɵɵconditionalCreate(0, MeetingsResource_Case_0_Template, 2, 7, "div", 0)(1, MeetingsResource_Case_1_Template, 1, 1)(2, MeetingsResource_Case_2_Template, 5, 2, "div", 1)(3, MeetingsResource_Case_3_Template, 2, 1, "div", 1);
|
|
154
|
+
} if (rf & 2) {
|
|
155
|
+
let tmp_0_0;
|
|
156
|
+
i0.ɵɵconditional((tmp_0_0 = ctx.Phase) === "live" ? 0 : tmp_0_0 === "lobby" ? 1 : tmp_0_0 === "schedule" ? 2 : 3);
|
|
157
|
+
} }, dependencies: [i1.MJLiveKitRoomComponent, i1.MJMeetingListComponent, i1.MJMeetingScheduleFormComponent, i1.MJMeetingLobbyComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n overflow-y: auto;\n background: var(--mj-bg-page, #f8fafc);\n }\n .mj-mtg-resource-wrapper[_ngcontent-%COMP%] {\n padding: var(--mj-space-4, 16px);\n }\n .mj-mtg-live-container[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .mj-mtg-room[_ngcontent-%COMP%] {\n display: block;\n height: 100%;\n }\n .mj-mtg-back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: none;\n background: none;\n color: var(--mj-brand-primary, #0076b6);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n padding: 8px 12px;\n margin-bottom: 12px;\n border-radius: 6px;\n }\n .mj-mtg-back-btn[_ngcontent-%COMP%]:hover {\n background: rgba(0, 118, 182, 0.08);\n }"] });
|
|
158
|
+
};
|
|
159
|
+
MeetingsResource = __decorate([
|
|
160
|
+
RegisterClass(BaseResourceComponent, 'MeetingsResource')
|
|
161
|
+
], MeetingsResource);
|
|
162
|
+
export { MeetingsResource };
|
|
163
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MeetingsResource, [{
|
|
164
|
+
type: Component,
|
|
165
|
+
args: [{ standalone: false, selector: 'mj-meetings-resource', template: `
|
|
166
|
+
@switch (Phase) {
|
|
167
|
+
@case ('live') {
|
|
168
|
+
<div class="mj-mtg-live-container">
|
|
169
|
+
<mj-livekit-agent-room
|
|
170
|
+
class="mj-mtg-room"
|
|
171
|
+
Mode="join"
|
|
172
|
+
[RoomName]="LiveRoomName"
|
|
173
|
+
[Provider]="ProviderToUse"
|
|
174
|
+
[StartWithMicrophone]="StartWithMic"
|
|
175
|
+
[StartWithCamera]="StartWithCam"
|
|
176
|
+
[ShowAgentState]="true"
|
|
177
|
+
[EnableLayoutSwitcher]="true"
|
|
178
|
+
[EnableLeaveControl]="true"
|
|
179
|
+
(Disconnected)="OnLiveRoomLeft()"
|
|
180
|
+
></mj-livekit-agent-room>
|
|
181
|
+
</div>
|
|
182
|
+
}
|
|
183
|
+
@case ('lobby') {
|
|
184
|
+
@if (ActiveMeeting) {
|
|
185
|
+
<div class="mj-mtg-resource-wrapper">
|
|
186
|
+
<button type="button" class="mj-mtg-back-btn" (click)="OnLobbyCancelled()">
|
|
187
|
+
<i class="fa-solid fa-arrow-left"></i> Back to Meetings
|
|
188
|
+
</button>
|
|
189
|
+
<mj-meeting-lobby
|
|
190
|
+
[Meeting]="ActiveMeeting"
|
|
191
|
+
[Provider]="ProviderToUse"
|
|
192
|
+
(JoinConfirmed)="OnJoinConfirmed($event)"
|
|
193
|
+
(Cancelled)="OnLobbyCancelled()"
|
|
194
|
+
></mj-meeting-lobby>
|
|
195
|
+
</div>
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
@case ('schedule') {
|
|
199
|
+
<div class="mj-mtg-resource-wrapper">
|
|
200
|
+
<button type="button" class="mj-mtg-back-btn" (click)="OnScheduleCancelled()">
|
|
201
|
+
<i class="fa-solid fa-arrow-left"></i> Back to Meetings
|
|
202
|
+
</button>
|
|
203
|
+
<mj-meeting-schedule-form
|
|
204
|
+
[Provider]="ProviderToUse"
|
|
205
|
+
[Meeting]="EditingMeeting || undefined"
|
|
206
|
+
(MeetingSaved)="OnMeetingSaved($event)"
|
|
207
|
+
(Cancelled)="OnScheduleCancelled()"
|
|
208
|
+
></mj-meeting-schedule-form>
|
|
209
|
+
</div>
|
|
210
|
+
}
|
|
211
|
+
@default {
|
|
212
|
+
<div class="mj-mtg-resource-wrapper">
|
|
213
|
+
<mj-meeting-list
|
|
214
|
+
[Provider]="ProviderToUse"
|
|
215
|
+
(JoinMeeting)="OnJoinMeetingFromList($event)"
|
|
216
|
+
(ScheduleRequested)="OnScheduleRequested()"
|
|
217
|
+
(EditMeetingRequested)="OnEditMeetingRequested($event)"
|
|
218
|
+
></mj-meeting-list>
|
|
219
|
+
</div>
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
`, styles: ["\n :host {\n display: block;\n height: 100%;\n overflow-y: auto;\n background: var(--mj-bg-page, #f8fafc);\n }\n .mj-mtg-resource-wrapper {\n padding: var(--mj-space-4, 16px);\n }\n .mj-mtg-live-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .mj-mtg-room {\n display: block;\n height: 100%;\n }\n .mj-mtg-back-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: none;\n background: none;\n color: var(--mj-brand-primary, #0076b6);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n padding: 8px 12px;\n margin-bottom: 12px;\n border-radius: 6px;\n }\n .mj-mtg-back-btn:hover {\n background: rgba(0, 118, 182, 0.08);\n }\n "] }]
|
|
223
|
+
}], null, null); })();
|
|
224
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MeetingsResource, { className: "MeetingsResource", filePath: "src/lib/resource-wrappers/meetings-resource.component.ts", lineNumber: 124 }); })();
|
|
225
|
+
//# sourceMappingURL=meetings-resource.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meetings-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/meetings-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport {\n GraphQLDataProvider,\n GraphQLMeetingClient,\n type MeetingInfo,\n} from '@memberjunction/graphql-dataprovider';\n\n/**\n * Meetings Resource — multi-party scheduled and ad-hoc meeting hub in Explorer (the Meet app's \"Meetings\").\n *\n * Coordinates:\n * - Meeting list view (`mj-meeting-list`)\n * - Scheduling / editing form (`mj-meeting-schedule-form`)\n * - Pre-join lobby with AV checks & dial-in info (`mj-meeting-lobby`)\n * - Active multi-party call (`mj-livekit-agent-room` in join mode)\n *\n * Registered via `@RegisterClass(BaseResourceComponent, 'MeetingsResource')`.\n */\n@RegisterClass(BaseResourceComponent, 'MeetingsResource')\n@Component({\n standalone: false,\n selector: 'mj-meetings-resource',\n template: `\n @switch (Phase) {\n @case ('live') {\n <div class=\"mj-mtg-live-container\">\n <mj-livekit-agent-room\n class=\"mj-mtg-room\"\n Mode=\"join\"\n [RoomName]=\"LiveRoomName\"\n [Provider]=\"ProviderToUse\"\n [StartWithMicrophone]=\"StartWithMic\"\n [StartWithCamera]=\"StartWithCam\"\n [ShowAgentState]=\"true\"\n [EnableLayoutSwitcher]=\"true\"\n [EnableLeaveControl]=\"true\"\n (Disconnected)=\"OnLiveRoomLeft()\"\n ></mj-livekit-agent-room>\n </div>\n }\n @case ('lobby') {\n @if (ActiveMeeting) {\n <div class=\"mj-mtg-resource-wrapper\">\n <button type=\"button\" class=\"mj-mtg-back-btn\" (click)=\"OnLobbyCancelled()\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back to Meetings\n </button>\n <mj-meeting-lobby\n [Meeting]=\"ActiveMeeting\"\n [Provider]=\"ProviderToUse\"\n (JoinConfirmed)=\"OnJoinConfirmed($event)\"\n (Cancelled)=\"OnLobbyCancelled()\"\n ></mj-meeting-lobby>\n </div>\n }\n }\n @case ('schedule') {\n <div class=\"mj-mtg-resource-wrapper\">\n <button type=\"button\" class=\"mj-mtg-back-btn\" (click)=\"OnScheduleCancelled()\">\n <i class=\"fa-solid fa-arrow-left\"></i> Back to Meetings\n </button>\n <mj-meeting-schedule-form\n [Provider]=\"ProviderToUse\"\n [Meeting]=\"EditingMeeting || undefined\"\n (MeetingSaved)=\"OnMeetingSaved($event)\"\n (Cancelled)=\"OnScheduleCancelled()\"\n ></mj-meeting-schedule-form>\n </div>\n }\n @default {\n <div class=\"mj-mtg-resource-wrapper\">\n <mj-meeting-list\n [Provider]=\"ProviderToUse\"\n (JoinMeeting)=\"OnJoinMeetingFromList($event)\"\n (ScheduleRequested)=\"OnScheduleRequested()\"\n (EditMeetingRequested)=\"OnEditMeetingRequested($event)\"\n ></mj-meeting-list>\n </div>\n }\n }\n `,\n styles: [\n `\n :host {\n display: block;\n height: 100%;\n overflow-y: auto;\n background: var(--mj-bg-page, #f8fafc);\n }\n .mj-mtg-resource-wrapper {\n padding: var(--mj-space-4, 16px);\n }\n .mj-mtg-live-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n .mj-mtg-room {\n display: block;\n height: 100%;\n }\n .mj-mtg-back-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: none;\n background: none;\n color: var(--mj-brand-primary, #0076b6);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n padding: 8px 12px;\n margin-bottom: 12px;\n border-radius: 6px;\n }\n .mj-mtg-back-btn:hover {\n background: rgba(0, 118, 182, 0.08);\n }\n `,\n ],\n})\nexport class MeetingsResource extends BaseResourceComponent implements OnInit {\n public Phase: 'list' | 'schedule' | 'lobby' | 'live' = 'list';\n public ActiveMeeting: MeetingInfo | null = null;\n public EditingMeeting: MeetingInfo | null = null;\n public LiveRoomName: string = '';\n public StartWithMic: boolean = true;\n public StartWithCam: boolean = false;\n\n override ngOnInit(): void {\n super.ngOnInit();\n void this.initialize();\n }\n\n private async initialize(): Promise<void> {\n const config = this.Data?.Configuration as { MeetingID?: string } | undefined;\n const initialMeetingId = config?.MeetingID || this.Data?.ResourceRecordID;\n if (initialMeetingId) {\n try {\n const client = new GraphQLMeetingClient(this.ProviderToUse || GraphQLDataProvider.Instance);\n const meeting = await client.GetMeeting(initialMeetingId);\n if (meeting) {\n this.ActiveMeeting = meeting;\n this.Phase = 'lobby';\n }\n } catch (err) {\n console.warn('MeetingsResource: unable to resolve initial meeting deep-link', err);\n }\n }\n this.NotifyLoadComplete();\n }\n\n public OnScheduleRequested(): void {\n this.EditingMeeting = null;\n this.Phase = 'schedule';\n }\n\n public OnEditMeetingRequested(meeting: MeetingInfo): void {\n this.EditingMeeting = meeting;\n this.Phase = 'schedule';\n }\n\n public OnMeetingSaved(meeting: MeetingInfo): void {\n this.ActiveMeeting = meeting;\n this.EditingMeeting = null;\n this.Phase = 'lobby';\n }\n\n public OnScheduleCancelled(): void {\n this.EditingMeeting = null;\n this.Phase = 'list';\n }\n\n public OnJoinMeetingFromList(meeting: MeetingInfo): void {\n this.ActiveMeeting = meeting;\n this.Phase = 'lobby';\n }\n\n public OnJoinConfirmed(prefs: { startWithAudio: boolean; startWithVideo: boolean }): void {\n this.StartWithMic = prefs.startWithAudio;\n this.StartWithCam = prefs.startWithVideo;\n this.LiveRoomName = this.ActiveMeeting?.RoomName || '';\n this.Phase = 'live';\n }\n\n public OnLobbyCancelled(): void {\n this.ActiveMeeting = null;\n this.Phase = 'list';\n }\n\n public OnLiveRoomLeft(): void {\n this.LiveRoomName = '';\n this.ActiveMeeting = null;\n this.Phase = 'list';\n }\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return this.ActiveMeeting?.Title || 'Meetings';\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-calendar-users';\n }\n}\n"]}
|
|
@@ -1,11 +1,36 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
1
2
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
2
3
|
import { ResourceData } from '@memberjunction/core-entities';
|
|
3
4
|
import { CompositeKey, IMetadataProvider } from '@memberjunction/core';
|
|
5
|
+
import { type FormCompositionSnapshot } from '@memberjunction/ng-base-forms';
|
|
4
6
|
import * as i0 from "@angular/core";
|
|
5
|
-
export declare class EntityRecordResource extends BaseResourceComponent {
|
|
7
|
+
export declare class EntityRecordResource extends BaseResourceComponent implements OnInit {
|
|
6
8
|
private singleRecord?;
|
|
7
|
-
|
|
9
|
+
private readonly workspace;
|
|
10
|
+
/** The form context this tab last reported, kept so it can be published again. */
|
|
11
|
+
private agentContext;
|
|
12
|
+
/** Fallback read for the pool predicate; promotion via ResourceEditModeChanged is the primary guard. */
|
|
8
13
|
IsEditing(): boolean;
|
|
14
|
+
/** The hosted form entered or left edit mode; the shell promotes the tab on `true`. */
|
|
15
|
+
ResourceEditModeChanged(editing: boolean): void;
|
|
16
|
+
ngOnInit(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Report the form to the agent context, so an agent asked to build a panel for this record
|
|
19
|
+
* knows what the form shows. The agent gets the compact form ({@link BuildFormAgentContext}):
|
|
20
|
+
* entity, record, which form, and the sections. The full snapshot stays in the browser, in
|
|
21
|
+
* the `FormCompositionRegistry` the apply flow reads.
|
|
22
|
+
*
|
|
23
|
+
* The shell folds this into `AppContextSnapshot.AdditionalContext` and assigns that wholesale,
|
|
24
|
+
* so the last publisher wins app-wide, and it rebuilds the app context without it on every tab
|
|
25
|
+
* switch. So the context is kept here and published only while this tab is the one on screen
|
|
26
|
+
* (attached and the active tab): a background tab's late resolve cannot replace the context of
|
|
27
|
+
* the surface the user sees, and returning to this tab publishes it again.
|
|
28
|
+
*/
|
|
29
|
+
OnCompositionChanged(snapshot: FormCompositionSnapshot): void;
|
|
30
|
+
/** Publishes the kept context while this tab is on screen and the shell's context lacks it. */
|
|
31
|
+
private publishAgentContext;
|
|
32
|
+
/** True while the cache has this tab attached and it is the workspace's active tab. */
|
|
33
|
+
private isOnScreen;
|
|
9
34
|
get PrimaryKey(): CompositeKey;
|
|
10
35
|
static GetPrimaryKey(data: ResourceData, provider?: IMetadataProvider): CompositeKey;
|
|
11
36
|
GetResourceDisplayName(data: ResourceData): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"record-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAqB,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAY,YAAY,EAAc,iBAAiB,EAA0B,MAAM,sBAAsB,CAAC;AAErH,OAAO,EAAgD,KAAK,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;;AAC3H,qBAOa,oBAAqB,SAAQ,qBAAsB,YAAW,MAAM;IAC3C,OAAO,CAAC,YAAY,CAAC,CAAwB;IAE/E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D,kFAAkF;IAClF,OAAO,CAAC,YAAY,CAA2C;IAE/D,wGAAwG;IACxF,SAAS,IAAI,OAAO;IAIpC,uFAAuF;IAChF,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAItC,QAAQ,IAAI,IAAI;IAahC;;;;;;;;;;;OAWG;IACI,oBAAoB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,IAAI;IAKpE,+FAA+F;IAC/F,OAAO,CAAC,mBAAmB;IAO3B,uFAAuF;IACvF,OAAO,CAAC,UAAU;IAMlB,IAAW,UAAU,IAAI,YAAY,CAEpC;WAEa,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,YAAY;IA4BrF,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA2B3D,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;yCA1HtD,oBAAoB;2CAApB,oBAAoB;CAuIhC"}
|
|
@@ -5,20 +5,72 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var EntityRecordResource_1;
|
|
8
|
-
import { Component, ViewChild } from '@angular/core';
|
|
8
|
+
import { Component, ViewChild, inject } from '@angular/core';
|
|
9
|
+
import { asapScheduler, merge } from 'rxjs';
|
|
10
|
+
import { filter, observeOn, takeUntil } from 'rxjs/operators';
|
|
9
11
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
12
|
+
import { WorkspaceStateManager } from '@memberjunction/ng-base-application';
|
|
10
13
|
import { RegisterClass } from '@memberjunction/global';
|
|
11
14
|
import { Metadata, CompositeKey, IsNewEntityRecordUrlId } from '@memberjunction/core';
|
|
12
15
|
import { SingleRecordComponent } from '../single-record/single-record.component';
|
|
16
|
+
import { BuildFormAgentContext } from '@memberjunction/ng-base-forms';
|
|
13
17
|
import * as i0 from "@angular/core";
|
|
14
18
|
import * as i1 from "../single-record/single-record.component";
|
|
15
19
|
let EntityRecordResource = class EntityRecordResource extends BaseResourceComponent {
|
|
16
20
|
static { EntityRecordResource_1 = this; }
|
|
17
21
|
singleRecord;
|
|
18
|
-
|
|
22
|
+
workspace = inject(WorkspaceStateManager);
|
|
23
|
+
/** The form context this tab last reported, kept so it can be published again. */
|
|
24
|
+
agentContext = null;
|
|
25
|
+
/** Fallback read for the pool predicate; promotion via ResourceEditModeChanged is the primary guard. */
|
|
19
26
|
IsEditing() {
|
|
20
27
|
return this.singleRecord?.IsEditing() === true;
|
|
21
28
|
}
|
|
29
|
+
/** The hosted form entered or left edit mode; the shell promotes the tab on `true`. */
|
|
30
|
+
ResourceEditModeChanged(editing) {
|
|
31
|
+
this.NotifyEditModeChanged(editing);
|
|
32
|
+
}
|
|
33
|
+
ngOnInit() {
|
|
34
|
+
super.ngOnInit();
|
|
35
|
+
// Publish the kept context again when the shell's app context lacks it, or when the cache
|
|
36
|
+
// reattaches this tab. Deferred, so a publish never runs inside another subscriber's
|
|
37
|
+
// AppContextSnapshot$ delivery.
|
|
38
|
+
merge(this.navigationService.AppContextSnapshot$, this.navigationService.ResourceReattached$.pipe(filter((resource) => resource === this)))
|
|
39
|
+
.pipe(observeOn(asapScheduler), takeUntil(this.destroy$))
|
|
40
|
+
.subscribe(() => this.publishAgentContext());
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Report the form to the agent context, so an agent asked to build a panel for this record
|
|
44
|
+
* knows what the form shows. The agent gets the compact form ({@link BuildFormAgentContext}):
|
|
45
|
+
* entity, record, which form, and the sections. The full snapshot stays in the browser, in
|
|
46
|
+
* the `FormCompositionRegistry` the apply flow reads.
|
|
47
|
+
*
|
|
48
|
+
* The shell folds this into `AppContextSnapshot.AdditionalContext` and assigns that wholesale,
|
|
49
|
+
* so the last publisher wins app-wide, and it rebuilds the app context without it on every tab
|
|
50
|
+
* switch. So the context is kept here and published only while this tab is the one on screen
|
|
51
|
+
* (attached and the active tab): a background tab's late resolve cannot replace the context of
|
|
52
|
+
* the surface the user sees, and returning to this tab publishes it again.
|
|
53
|
+
*/
|
|
54
|
+
OnCompositionChanged(snapshot) {
|
|
55
|
+
this.agentContext = { Form: BuildFormAgentContext(snapshot) };
|
|
56
|
+
this.publishAgentContext();
|
|
57
|
+
}
|
|
58
|
+
/** Publishes the kept context while this tab is on screen and the shell's context lacks it. */
|
|
59
|
+
publishAgentContext() {
|
|
60
|
+
const context = this.agentContext;
|
|
61
|
+
if (!context || !this.isOnScreen())
|
|
62
|
+
return;
|
|
63
|
+
if (this.navigationService.AppContextSnapshot$.value?.AdditionalContext === context)
|
|
64
|
+
return;
|
|
65
|
+
this.navigationService.SetAgentContext(this, context);
|
|
66
|
+
}
|
|
67
|
+
/** True while the cache has this tab attached and it is the workspace's active tab. */
|
|
68
|
+
isOnScreen() {
|
|
69
|
+
if (this.navigationService.IsResourceDetached(this))
|
|
70
|
+
return false;
|
|
71
|
+
const tabId = this.getTabId();
|
|
72
|
+
return !!tabId && this.workspace.GetActiveTabId() === tabId;
|
|
73
|
+
}
|
|
22
74
|
get PrimaryKey() {
|
|
23
75
|
return EntityRecordResource_1.GetPrimaryKey(this.Data, this.ProviderToUse);
|
|
24
76
|
}
|
|
@@ -89,9 +141,9 @@ let EntityRecordResource = class EntityRecordResource extends BaseResourceCompon
|
|
|
89
141
|
} if (rf & 2) {
|
|
90
142
|
let _t;
|
|
91
143
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.singleRecord = _t.first);
|
|
92
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 3, consts: [[3, "loadComplete", "recordSaved", "recordDismissed", "PrimaryKey", "entityName", "newRecordValues"]], template: function EntityRecordResource_Template(rf, ctx) { if (rf & 1) {
|
|
144
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 3, consts: [[3, "loadComplete", "recordSaved", "recordDismissed", "EditModeChanged", "CompositionChanged", "PrimaryKey", "entityName", "newRecordValues"]], template: function EntityRecordResource_Template(rf, ctx) { if (rf & 1) {
|
|
93
145
|
i0.ɵɵelementStart(0, "mj-single-record", 0);
|
|
94
|
-
i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); })("recordSaved", function EntityRecordResource_Template_mj_single_record_recordSaved_0_listener($event) { return ctx.ResourceRecordSaved($event); })("recordDismissed", function EntityRecordResource_Template_mj_single_record_recordDismissed_0_listener() { return ctx.NotifyCloseRequested(); });
|
|
146
|
+
i0.ɵɵlistener("loadComplete", function EntityRecordResource_Template_mj_single_record_loadComplete_0_listener() { return ctx.NotifyLoadComplete(); })("recordSaved", function EntityRecordResource_Template_mj_single_record_recordSaved_0_listener($event) { return ctx.ResourceRecordSaved($event); })("recordDismissed", function EntityRecordResource_Template_mj_single_record_recordDismissed_0_listener() { return ctx.NotifyCloseRequested(); })("EditModeChanged", function EntityRecordResource_Template_mj_single_record_EditModeChanged_0_listener($event) { return ctx.ResourceEditModeChanged($event); })("CompositionChanged", function EntityRecordResource_Template_mj_single_record_CompositionChanged_0_listener($event) { return ctx.OnCompositionChanged($event); });
|
|
95
147
|
i0.ɵɵelementEnd();
|
|
96
148
|
} if (rf & 2) {
|
|
97
149
|
i0.ɵɵproperty("PrimaryKey", ctx.PrimaryKey)("entityName", ctx.Data.Configuration.Entity)("newRecordValues", ctx.Data.Configuration.NewRecordValues);
|
|
@@ -103,10 +155,10 @@ EntityRecordResource = EntityRecordResource_1 = __decorate([
|
|
|
103
155
|
export { EntityRecordResource };
|
|
104
156
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityRecordResource, [{
|
|
105
157
|
type: Component,
|
|
106
|
-
args: [{ standalone: false, selector: 'mj-record-resource', template: `<mj-single-record [PrimaryKey]="this.PrimaryKey" [entityName]="Data.Configuration.Entity" [newRecordValues]="Data.Configuration.NewRecordValues" (loadComplete)="NotifyLoadComplete()" (recordSaved)="ResourceRecordSaved($event)" (recordDismissed)="NotifyCloseRequested()"></mj-single-record>`, styles: [":host { display: block; height: 100%; width: 100%; }"] }]
|
|
158
|
+
args: [{ standalone: false, selector: 'mj-record-resource', template: `<mj-single-record [PrimaryKey]="this.PrimaryKey" [entityName]="Data.Configuration.Entity" [newRecordValues]="Data.Configuration.NewRecordValues" (loadComplete)="NotifyLoadComplete()" (recordSaved)="ResourceRecordSaved($event)" (recordDismissed)="NotifyCloseRequested()" (EditModeChanged)="ResourceEditModeChanged($event)" (CompositionChanged)="OnCompositionChanged($event)"></mj-single-record>`, styles: [":host { display: block; height: 100%; width: 100%; }"] }]
|
|
107
159
|
}], null, { singleRecord: [{
|
|
108
160
|
type: ViewChild,
|
|
109
161
|
args: [SingleRecordComponent]
|
|
110
162
|
}] }); })();
|
|
111
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityRecordResource, { className: "EntityRecordResource", filePath: "src/lib/resource-wrappers/record-resource.component.ts", lineNumber:
|
|
163
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityRecordResource, { className: "EntityRecordResource", filePath: "src/lib/resource-wrappers/record-resource.component.ts", lineNumber: 18 }); })();
|
|
112
164
|
//# sourceMappingURL=record-resource.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Metadata, CompositeKey, EntityInfo, IMetadataProvider, IsNewEntityRecordUrlId } from '@memberjunction/core';\nimport { SingleRecordComponent } from '../single-record/single-record.component';\n@RegisterClass(BaseResourceComponent, 'RecordResource')\n@Component({\n standalone: false,\n selector: 'mj-record-resource',\n styles: [`:host { display: block; height: 100%; width: 100%; }`],\n template: `<mj-single-record [PrimaryKey]=\"this.PrimaryKey\" [entityName]=\"Data.Configuration.Entity\" [newRecordValues]=\"Data.Configuration.NewRecordValues\" (loadComplete)=\"NotifyLoadComplete()\" (recordSaved)=\"ResourceRecordSaved($event)\" (recordDismissed)=\"NotifyCloseRequested()\"></mj-single-record>`\n})\nexport class EntityRecordResource extends BaseResourceComponent {\n @ViewChild(SingleRecordComponent) private singleRecord?: SingleRecordComponent;\n\n /** A record being edited must never be consumed as the region's temp tab. */\n public override IsEditing(): boolean {\n return this.singleRecord?.IsEditing() === true;\n }\n\n public get PrimaryKey(): CompositeKey {\n return EntityRecordResource.GetPrimaryKey(this.Data, this.ProviderToUse);\n }\n\n public static GetPrimaryKey(data: ResourceData, provider?: IMetadataProvider): CompositeKey {\n // global-provider-ok: static helper has no component instance scope; falls back to default provider\n const md = (provider ?? Metadata.Provider) as IMetadataProvider;\n const requested = (data.Configuration.Entity ?? '').trim();\n // Prefer EntityByName (project rule: never use Entities.find for\n // single-entity lookups — case/whitespace tolerant + O(1) map). Fall\n // back to DisplayName match for callers (AI agents, hand-typed URLs,\n // external CTAs) that pass the human-readable display name instead\n // of the canonical Name (e.g. \"Users\" for \"MJ: Users\").\n let e: EntityInfo | undefined = md.EntityByName(requested);\n if (!e) {\n const lowered = requested.toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e){\n throw new Error(`Entity ${data.Configuration.Entity} not found in metadata (tried Name and DisplayName)`);\n }\n\n if (IsNewEntityRecordUrlId(data.ResourceRecordID)) {\n return new CompositeKey();\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromURLSegment(e, data.ResourceRecordID);\n return compositeKey;\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity) {\n return '';\n }\n\n const md = this.ProviderToUse;\n let e = md.EntityByName(data.Configuration.Entity);\n if (!e) {\n // Same DisplayName fallback as GetPrimaryKey — keeps the\n // breadcrumb/title in sync when a CTA used the display name.\n const lowered = (data.Configuration.Entity ?? '').trim().toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e) {\n return '';\n }\n\n const pk: CompositeKey = EntityRecordResource.GetPrimaryKey(data, this.ProviderToUse);\n if (pk.HasValue) {\n const name = await md.GetEntityRecordName(data.Configuration.Entity, pk);\n return name ? name : e.DisplayNameOrName;\n } else {\n return `New ${e.DisplayNameOrName} Record`;\n }\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity){\n return ''\n }\n else {\n const md = this.ProviderToUse;\n const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (e)\n return e?.Icon;\n else\n return '';\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"record-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/record-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ViewChild, inject } from '@angular/core';\nimport { asapScheduler, merge } from 'rxjs';\nimport { filter, observeOn, takeUntil } from 'rxjs/operators';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { WorkspaceStateManager } from '@memberjunction/ng-base-application';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Metadata, CompositeKey, EntityInfo, IMetadataProvider, IsNewEntityRecordUrlId } from '@memberjunction/core';\nimport { SingleRecordComponent } from '../single-record/single-record.component';\nimport { BuildFormAgentContext, type FormAgentContext, type FormCompositionSnapshot } from '@memberjunction/ng-base-forms';\n@RegisterClass(BaseResourceComponent, 'RecordResource')\n@Component({\n standalone: false,\n selector: 'mj-record-resource',\n styles: [`:host { display: block; height: 100%; width: 100%; }`],\n template: `<mj-single-record [PrimaryKey]=\"this.PrimaryKey\" [entityName]=\"Data.Configuration.Entity\" [newRecordValues]=\"Data.Configuration.NewRecordValues\" (loadComplete)=\"NotifyLoadComplete()\" (recordSaved)=\"ResourceRecordSaved($event)\" (recordDismissed)=\"NotifyCloseRequested()\" (EditModeChanged)=\"ResourceEditModeChanged($event)\" (CompositionChanged)=\"OnCompositionChanged($event)\"></mj-single-record>`\n})\nexport class EntityRecordResource extends BaseResourceComponent implements OnInit {\n @ViewChild(SingleRecordComponent) private singleRecord?: SingleRecordComponent;\n\n private readonly workspace = inject(WorkspaceStateManager);\n\n /** The form context this tab last reported, kept so it can be published again. */\n private agentContext: { Form: FormAgentContext } | null = null;\n\n /** Fallback read for the pool predicate; promotion via ResourceEditModeChanged is the primary guard. */\n public override IsEditing(): boolean {\n return this.singleRecord?.IsEditing() === true;\n }\n\n /** The hosted form entered or left edit mode; the shell promotes the tab on `true`. */\n public ResourceEditModeChanged(editing: boolean): void {\n this.NotifyEditModeChanged(editing);\n }\n\n public override ngOnInit(): void {\n super.ngOnInit();\n // Publish the kept context again when the shell's app context lacks it, or when the cache\n // reattaches this tab. Deferred, so a publish never runs inside another subscriber's\n // AppContextSnapshot$ delivery.\n merge(\n this.navigationService.AppContextSnapshot$,\n this.navigationService.ResourceReattached$.pipe(filter((resource) => resource === this)),\n )\n .pipe(observeOn(asapScheduler), takeUntil(this.destroy$))\n .subscribe(() => this.publishAgentContext());\n }\n\n /**\n * Report the form to the agent context, so an agent asked to build a panel for this record\n * knows what the form shows. The agent gets the compact form ({@link BuildFormAgentContext}):\n * entity, record, which form, and the sections. The full snapshot stays in the browser, in\n * the `FormCompositionRegistry` the apply flow reads.\n *\n * The shell folds this into `AppContextSnapshot.AdditionalContext` and assigns that wholesale,\n * so the last publisher wins app-wide, and it rebuilds the app context without it on every tab\n * switch. So the context is kept here and published only while this tab is the one on screen\n * (attached and the active tab): a background tab's late resolve cannot replace the context of\n * the surface the user sees, and returning to this tab publishes it again.\n */\n public OnCompositionChanged(snapshot: FormCompositionSnapshot): void {\n this.agentContext = { Form: BuildFormAgentContext(snapshot) };\n this.publishAgentContext();\n }\n\n /** Publishes the kept context while this tab is on screen and the shell's context lacks it. */\n private publishAgentContext(): void {\n const context = this.agentContext;\n if (!context || !this.isOnScreen()) return;\n if (this.navigationService.AppContextSnapshot$.value?.AdditionalContext === context) return;\n this.navigationService.SetAgentContext(this, context);\n }\n\n /** True while the cache has this tab attached and it is the workspace's active tab. */\n private isOnScreen(): boolean {\n if (this.navigationService.IsResourceDetached(this)) return false;\n const tabId = this.getTabId();\n return !!tabId && this.workspace.GetActiveTabId() === tabId;\n }\n\n public get PrimaryKey(): CompositeKey {\n return EntityRecordResource.GetPrimaryKey(this.Data, this.ProviderToUse);\n }\n\n public static GetPrimaryKey(data: ResourceData, provider?: IMetadataProvider): CompositeKey {\n // global-provider-ok: static helper has no component instance scope; falls back to default provider\n const md = (provider ?? Metadata.Provider) as IMetadataProvider;\n const requested = (data.Configuration.Entity ?? '').trim();\n // Prefer EntityByName (project rule: never use Entities.find for\n // single-entity lookups — case/whitespace tolerant + O(1) map). Fall\n // back to DisplayName match for callers (AI agents, hand-typed URLs,\n // external CTAs) that pass the human-readable display name instead\n // of the canonical Name (e.g. \"Users\" for \"MJ: Users\").\n let e: EntityInfo | undefined = md.EntityByName(requested);\n if (!e) {\n const lowered = requested.toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e){\n throw new Error(`Entity ${data.Configuration.Entity} not found in metadata (tried Name and DisplayName)`);\n }\n\n if (IsNewEntityRecordUrlId(data.ResourceRecordID)) {\n return new CompositeKey();\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromURLSegment(e, data.ResourceRecordID);\n return compositeKey;\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity) {\n return '';\n }\n\n const md = this.ProviderToUse;\n let e = md.EntityByName(data.Configuration.Entity);\n if (!e) {\n // Same DisplayName fallback as GetPrimaryKey — keeps the\n // breadcrumb/title in sync when a CTA used the display name.\n const lowered = (data.Configuration.Entity ?? '').trim().toLowerCase();\n e = md.Entities.find((x: EntityInfo) =>\n (x.DisplayName ?? '').trim().toLowerCase() === lowered);\n }\n if (!e) {\n return '';\n }\n\n const pk: CompositeKey = EntityRecordResource.GetPrimaryKey(data, this.ProviderToUse);\n if (pk.HasValue) {\n const name = await md.GetEntityRecordName(data.Configuration.Entity, pk);\n return name ? name : e.DisplayNameOrName;\n } else {\n return `New ${e.DisplayNameOrName} Record`;\n }\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n if (!data.Configuration.Entity){\n return ''\n }\n else {\n const md = this.ProviderToUse;\n const e = md.Entities.find(e => e.Name.trim().toLowerCase() === data.Configuration.Entity.trim().toLowerCase());\n if (e)\n return e?.Icon;\n else\n return '';\n }\n }\n}\n"]}
|
|
@@ -76,6 +76,7 @@ export declare class UserViewResource extends BaseResourceComponent {
|
|
|
76
76
|
private dataLoaded;
|
|
77
77
|
private get metadata();
|
|
78
78
|
constructor(cdr: ChangeDetectorRef, exportService: ExportService);
|
|
79
|
+
ngOnInit(): void;
|
|
79
80
|
set Data(value: ResourceData);
|
|
80
81
|
get Data(): ResourceData;
|
|
81
82
|
/**
|
|
@@ -128,7 +129,11 @@ export declare class UserViewResource extends BaseResourceComponent {
|
|
|
128
129
|
OnExport(): Promise<void>;
|
|
129
130
|
/** @deprecated Use {@link OnExport}. */
|
|
130
131
|
onExport(): Promise<void>;
|
|
131
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* Columns to export — from grid state, else the view's columns, else the entity's real fields. Each
|
|
134
|
+
* column carries its field's export type, as the grid's export does, so a date-only field writes
|
|
135
|
+
* a date cell on its stored day rather than a timestamp.
|
|
136
|
+
*/
|
|
132
137
|
private buildExportColumns;
|
|
133
138
|
private buildExportFileName;
|
|
134
139
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"view-resource.component.d.ts","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/view-resource.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,8 +8,10 @@ import { Component, ViewChild } from '@angular/core';
|
|
|
8
8
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
9
9
|
import { ViewInfo } from '@memberjunction/core-entities';
|
|
10
10
|
import { RegisterClass, MJGlobal, MJEventType, UUIDsEqual } from '@memberjunction/global';
|
|
11
|
-
import { CompositeKey } from '@memberjunction/core';
|
|
11
|
+
import { CompositeKey, BaseEntity } from '@memberjunction/core';
|
|
12
|
+
import { ExportColumnTypeForSQLType } from '@memberjunction/ng-entity-viewer';
|
|
12
13
|
import { GraphQLListsClient } from '@memberjunction/graphql-dataprovider';
|
|
14
|
+
import { debounceTime, filter, takeUntil } from 'rxjs/operators';
|
|
13
15
|
import * as i0 from "@angular/core";
|
|
14
16
|
import * as i1 from "@memberjunction/ng-export-service";
|
|
15
17
|
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
@@ -244,6 +246,25 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
244
246
|
this.cdr = cdr;
|
|
245
247
|
this.exportService = exportService;
|
|
246
248
|
}
|
|
249
|
+
ngOnInit() {
|
|
250
|
+
super.ngOnInit();
|
|
251
|
+
// Refresh when rows of this view's entity change: a local save/delete, or a server-side
|
|
252
|
+
// write announced as remote-invalidate (a clone, or another server). Debounced, so a burst
|
|
253
|
+
// of writes (a clone creating many rows) reloads the view once.
|
|
254
|
+
MJGlobal.Instance.GetEventListener()
|
|
255
|
+
.pipe(filter((event) => {
|
|
256
|
+
if (event.event !== MJEventType.ComponentEvent || event.eventCode !== BaseEntity.BaseEventCode)
|
|
257
|
+
return false;
|
|
258
|
+
const entityEvent = event.args;
|
|
259
|
+
const type = entityEvent?.type;
|
|
260
|
+
if (type !== 'save' && type !== 'delete' && type !== 'remote-invalidate')
|
|
261
|
+
return false;
|
|
262
|
+
const affectedName = (entityEvent.baseEntity?.EntityInfo?.Name ?? entityEvent.entityName)?.trim().toLowerCase();
|
|
263
|
+
return !!affectedName && affectedName === this.entityInfo?.Name?.trim().toLowerCase();
|
|
264
|
+
}), debounceTime(300), takeUntil(this.destroy$))
|
|
265
|
+
// In place: a change made elsewhere shouldn't move the user off their page or sort.
|
|
266
|
+
.subscribe(() => this.entityViewerRef?.RefreshInPlace());
|
|
267
|
+
}
|
|
247
268
|
set Data(value) {
|
|
248
269
|
const previousRecordId = super.Data?.ResourceRecordID;
|
|
249
270
|
const previousEntity = super.Data?.Configuration?.Entity;
|
|
@@ -469,23 +490,32 @@ let UserViewResource = class UserViewResource extends BaseResourceComponent {
|
|
|
469
490
|
async onExport() {
|
|
470
491
|
return this.OnExport();
|
|
471
492
|
}
|
|
472
|
-
/**
|
|
493
|
+
/**
|
|
494
|
+
* Columns to export — from grid state, else the view's columns, else the entity's real fields. Each
|
|
495
|
+
* column carries its field's export type, as the grid's export does, so a date-only field writes
|
|
496
|
+
* a date cell on its stored day rather than a timestamp.
|
|
497
|
+
*/
|
|
473
498
|
buildExportColumns() {
|
|
474
499
|
if (!this.EntityInfo)
|
|
475
500
|
return [];
|
|
501
|
+
const entity = this.EntityInfo;
|
|
502
|
+
const typed = (name, displayName) => {
|
|
503
|
+
const field = entity.Fields.find(f => f.Name.toLowerCase() === name.toLowerCase());
|
|
504
|
+
return { name, displayName, dataType: ExportColumnTypeForSQLType(field?.Type) };
|
|
505
|
+
};
|
|
476
506
|
if (this.GridState?.columnSettings && this.GridState.columnSettings.length > 0) {
|
|
477
507
|
return this.GridState.columnSettings
|
|
478
508
|
.filter(col => col.hidden !== true)
|
|
479
|
-
.map(col => (
|
|
509
|
+
.map(col => typed(col.Name, col.DisplayName || col.Name));
|
|
480
510
|
}
|
|
481
511
|
if (this.ViewEntity?.Columns) {
|
|
482
512
|
return this.ViewEntity.Columns
|
|
483
513
|
.filter(col => !col.hidden)
|
|
484
|
-
.map(col => (
|
|
514
|
+
.map(col => typed(col.Name, col.DisplayName || col.Name));
|
|
485
515
|
}
|
|
486
|
-
return
|
|
516
|
+
return entity.Fields
|
|
487
517
|
.filter(f => !f.IsVirtual)
|
|
488
|
-
.map(f => (
|
|
518
|
+
.map(f => typed(f.Name, f.DisplayNameOrName));
|
|
489
519
|
}
|
|
490
520
|
buildExportFileName() {
|
|
491
521
|
const viewName = this.ViewEntity?.Name || 'Data';
|
|
@@ -639,5 +669,5 @@ export { UserViewResource };
|
|
|
639
669
|
type: ViewChild,
|
|
640
670
|
args: ['entityViewer']
|
|
641
671
|
}] }); })();
|
|
642
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserViewResource, { className: "UserViewResource", filePath: "src/lib/resource-wrappers/view-resource.component.ts", lineNumber:
|
|
672
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserViewResource, { className: "UserViewResource", filePath: "src/lib/resource-wrappers/view-resource.component.ts", lineNumber: 139 }); })();
|
|
643
673
|
//# sourceMappingURL=view-resource.component.js.map
|