@sneat/space-components 0.27.27 → 0.27.29
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/esm2022/lib/contact-role-assignment/contact-role-assignment.component.js +265 -0
- package/esm2022/lib/contact-role-assignment/contact-role-assignment.component.js.map +1 -0
- package/esm2022/lib/index.js +1 -0
- package/esm2022/lib/index.js.map +1 -1
- package/esm2022/lib/space-base-component.directive.js +8 -3
- package/esm2022/lib/space-base-component.directive.js.map +1 -1
- package/lib/contact-role-assignment/contact-role-assignment.component.d.ts +39 -0
- package/lib/index.d.ts +1 -0
- package/lib/space-base-component.directive.d.ts +1 -1
- package/package.json +1 -1
- package/tsconfig.lib.prod.tsbuildinfo +1 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, DestroyRef, effect, inject, input, output, signal, untracked, } from '@angular/core';
|
|
2
|
+
import { IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonSpinner, } from '@ionic/angular';
|
|
3
|
+
import { CONTACT_ROLE_ASSIGNMENT_PICKER, } from '@sneat/space-models';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
const refKey = (ref) => JSON.stringify([
|
|
6
|
+
ref.spaceID,
|
|
7
|
+
ref.module,
|
|
8
|
+
ref.collection,
|
|
9
|
+
ref.itemID,
|
|
10
|
+
ref.subPath || '',
|
|
11
|
+
]);
|
|
12
|
+
const validContact = (ref, spaceID) => ref.spaceID === spaceID &&
|
|
13
|
+
ref.module === 'contactus' &&
|
|
14
|
+
ref.collection === 'contacts' &&
|
|
15
|
+
!!ref.itemID &&
|
|
16
|
+
!/[@/]/.test(ref.itemID) &&
|
|
17
|
+
!ref.subPath;
|
|
18
|
+
const copyAssignments = (rows) => rows.map((row) => ({
|
|
19
|
+
...row,
|
|
20
|
+
contact: { ...row.contact },
|
|
21
|
+
roleIDs: [...row.roleIDs],
|
|
22
|
+
}));
|
|
23
|
+
/** No role or commercial policy lives here. Missing product configuration is readonly. */
|
|
24
|
+
export class ContactRoleAssignmentComponent {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.target = input(/* @ts-ignore */
|
|
27
|
+
...(ngDevMode ? [undefined, { debugName: "target" }] : /* istanbul ignore next */ []));
|
|
28
|
+
this.space = input(/* @ts-ignore */
|
|
29
|
+
...(ngDevMode ? [undefined, { debugName: "space" }] : /* istanbul ignore next */ []));
|
|
30
|
+
this.assignments = input([], /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "assignments" }] : /* istanbul ignore next */ []));
|
|
32
|
+
this.roles = input([], /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "roles" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.roleDirection = input(/* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [undefined, { debugName: "roleDirection" }] : /* istanbul ignore next */ []));
|
|
36
|
+
this.readonly = input(true, /* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
38
|
+
this.busy = input(false, /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
|
|
40
|
+
this.savePort = input(/* @ts-ignore */
|
|
41
|
+
...(ngDevMode ? [undefined, { debugName: "savePort" }] : /* istanbul ignore next */ []));
|
|
42
|
+
this.picker = input(/* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [undefined, { debugName: "picker" }] : /* istanbul ignore next */ []));
|
|
44
|
+
this.saved = output();
|
|
45
|
+
this.injectedPicker = inject(CONTACT_ROLE_ASSIGNMENT_PICKER, {
|
|
46
|
+
optional: true,
|
|
47
|
+
});
|
|
48
|
+
this.baseline = [];
|
|
49
|
+
this.epoch = 0;
|
|
50
|
+
this.draft = signal([], /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
|
|
52
|
+
this.pending = signal(false, /* @ts-ignore */
|
|
53
|
+
...(ngDevMode ? [{ debugName: "pending" }] : /* istanbul ignore next */ []));
|
|
54
|
+
this.error = signal('', /* @ts-ignore */
|
|
55
|
+
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
56
|
+
this.locked = computed(() => this.busy() || this.pending(), /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "locked" }] : /* istanbul ignore next */ []));
|
|
58
|
+
this.configured = computed(() => {
|
|
59
|
+
const target = this.target();
|
|
60
|
+
const options = this.roles();
|
|
61
|
+
return (!!target?.spaceID &&
|
|
62
|
+
!!target.module &&
|
|
63
|
+
!!target.collection &&
|
|
64
|
+
!!target.itemID &&
|
|
65
|
+
!target.subPath &&
|
|
66
|
+
target.spaceID === this.space()?.id &&
|
|
67
|
+
!!this.roleDirection() &&
|
|
68
|
+
!!this.savePort() &&
|
|
69
|
+
!!(this.picker() || this.injectedPicker) &&
|
|
70
|
+
options.length > 0 &&
|
|
71
|
+
options.every((role) => !!role.id.trim() && !!role.label.trim()) &&
|
|
72
|
+
new Set(options.map((role) => role.id)).size === options.length &&
|
|
73
|
+
this.assignments().every((row) => validContact(row.contact, target.spaceID || '') &&
|
|
74
|
+
new Set(row.roleIDs).size === row.roleIDs.length) &&
|
|
75
|
+
new Set(this.assignments().map((row) => refKey(row.contact))).size ===
|
|
76
|
+
this.assignments().length);
|
|
77
|
+
}, /* @ts-ignore */
|
|
78
|
+
...(ngDevMode ? [{ debugName: "configured" }] : /* istanbul ignore next */ []));
|
|
79
|
+
this.canEdit = computed(() => this.configured() && !this.readonly() && !this.locked(), /* @ts-ignore */
|
|
80
|
+
...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
|
|
81
|
+
this.changed = computed(() => this.changes().length > 0 ||
|
|
82
|
+
this.draft().some((row) => !this.baseline.some((before) => this.key(before) === this.key(row))), /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "changed" }] : /* istanbul ignore next */ []));
|
|
84
|
+
inject(DestroyRef).onDestroy(() => this.epoch++);
|
|
85
|
+
effect(() => {
|
|
86
|
+
const rows = this.assignments();
|
|
87
|
+
// Changes of authorization/configuration invalidate every outstanding async operation.
|
|
88
|
+
this.target();
|
|
89
|
+
this.space();
|
|
90
|
+
this.roles();
|
|
91
|
+
this.readonly();
|
|
92
|
+
this.savePort();
|
|
93
|
+
this.picker();
|
|
94
|
+
this.roleDirection();
|
|
95
|
+
untracked(() => {
|
|
96
|
+
this.epoch++;
|
|
97
|
+
this.baseline = copyAssignments(rows);
|
|
98
|
+
this.draft.set(copyAssignments(rows));
|
|
99
|
+
this.pending.set(false);
|
|
100
|
+
this.error.set('');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
contextSignature() {
|
|
105
|
+
return JSON.stringify([
|
|
106
|
+
this.target(),
|
|
107
|
+
this.space()?.id,
|
|
108
|
+
this.roles(),
|
|
109
|
+
this.assignments(),
|
|
110
|
+
this.readonly(),
|
|
111
|
+
this.roleDirection(),
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
captureContext() {
|
|
115
|
+
const epoch = this.epoch;
|
|
116
|
+
const signature = this.contextSignature();
|
|
117
|
+
const port = this.savePort();
|
|
118
|
+
const picker = this.picker();
|
|
119
|
+
// Compare immediately too: an Angular effect can run after a Promise continuation.
|
|
120
|
+
return () => epoch === this.epoch &&
|
|
121
|
+
signature === this.contextSignature() &&
|
|
122
|
+
port === this.savePort() &&
|
|
123
|
+
picker === this.picker();
|
|
124
|
+
}
|
|
125
|
+
key(row) {
|
|
126
|
+
return refKey(row.contact);
|
|
127
|
+
}
|
|
128
|
+
hasUnknownRole(row) {
|
|
129
|
+
return row.roleIDs.some((role) => !this.roles().some((option) => option.id === role));
|
|
130
|
+
}
|
|
131
|
+
setRole(row, role, enabled) {
|
|
132
|
+
if (!this.canEdit() ||
|
|
133
|
+
this.hasUnknownRole(row) ||
|
|
134
|
+
!this.roles().some((r) => r.id === role))
|
|
135
|
+
return;
|
|
136
|
+
this.draft.update((rows) => rows.map((current) => this.key(current) === this.key(row)
|
|
137
|
+
? {
|
|
138
|
+
...current,
|
|
139
|
+
roleIDs: enabled
|
|
140
|
+
? [...new Set([...current.roleIDs, role])]
|
|
141
|
+
: current.roleIDs.filter((r) => r !== role),
|
|
142
|
+
}
|
|
143
|
+
: current));
|
|
144
|
+
}
|
|
145
|
+
remove(row) {
|
|
146
|
+
if (!this.canEdit() || this.hasUnknownRole(row))
|
|
147
|
+
return;
|
|
148
|
+
this.draft.update((rows) => rows.filter((current) => this.key(current) !== this.key(row)));
|
|
149
|
+
}
|
|
150
|
+
cancel() {
|
|
151
|
+
if (this.locked())
|
|
152
|
+
return;
|
|
153
|
+
this.draft.set(copyAssignments(this.baseline));
|
|
154
|
+
this.error.set('');
|
|
155
|
+
}
|
|
156
|
+
async addContact() {
|
|
157
|
+
const picker = this.picker() || this.injectedPicker;
|
|
158
|
+
const space = this.space();
|
|
159
|
+
if (!this.canEdit() || !picker || !space)
|
|
160
|
+
return;
|
|
161
|
+
const current = this.captureContext();
|
|
162
|
+
this.pending.set(true);
|
|
163
|
+
this.error.set('');
|
|
164
|
+
try {
|
|
165
|
+
const row = await picker.selectContact({
|
|
166
|
+
space: { ...space },
|
|
167
|
+
exclude: this.draft().map((r) => ({ ...r.contact })),
|
|
168
|
+
});
|
|
169
|
+
if (!current() || !row)
|
|
170
|
+
return;
|
|
171
|
+
if (!validContact(row.contact, space.id))
|
|
172
|
+
throw new Error('The selected contact does not belong to this Space.');
|
|
173
|
+
if (!this.draft().some((current) => this.key(current) === refKey(row.contact)))
|
|
174
|
+
this.draft.update((rows) => [
|
|
175
|
+
...rows,
|
|
176
|
+
{ ...row, contact: { ...row.contact }, roleIDs: [] },
|
|
177
|
+
]);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
if (current())
|
|
181
|
+
this.error.set('Could not select a contact. Please try again.');
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
if (current())
|
|
185
|
+
this.pending.set(false);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
changes() {
|
|
189
|
+
const current = new Map(this.draft().map((row) => [this.key(row), row]));
|
|
190
|
+
const previous = new Map(this.baseline.map((row) => [this.key(row), row]));
|
|
191
|
+
const direction = this.roleDirection();
|
|
192
|
+
if (!direction)
|
|
193
|
+
return [];
|
|
194
|
+
return [...new Set([...previous.keys(), ...current.keys()])].flatMap((key) => {
|
|
195
|
+
const before = previous.get(key);
|
|
196
|
+
const after = current.get(key);
|
|
197
|
+
const row = after || before;
|
|
198
|
+
if (!row)
|
|
199
|
+
return [];
|
|
200
|
+
const add = (after?.roleIDs || []).filter((role) => !before?.roleIDs.includes(role));
|
|
201
|
+
const remove = (before?.roleIDs || []).filter((role) => !after?.roleIDs.includes(role));
|
|
202
|
+
return add.length || remove.length
|
|
203
|
+
? [
|
|
204
|
+
{
|
|
205
|
+
itemRef: { ...row.contact },
|
|
206
|
+
...(add.length ? { add: { [direction]: add } } : {}),
|
|
207
|
+
...(remove.length ? { remove: { [direction]: remove } } : {}),
|
|
208
|
+
},
|
|
209
|
+
]
|
|
210
|
+
: [];
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async save() {
|
|
214
|
+
const port = this.savePort();
|
|
215
|
+
const target = this.target();
|
|
216
|
+
const changes = this.changes();
|
|
217
|
+
if (!this.canEdit() || !port || !target)
|
|
218
|
+
return;
|
|
219
|
+
if (this.draft().some((row) => !row.roleIDs.length)) {
|
|
220
|
+
this.error.set('Choose at least one role for each contact.');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (!changes.length)
|
|
224
|
+
return;
|
|
225
|
+
const current = this.captureContext();
|
|
226
|
+
this.pending.set(true);
|
|
227
|
+
this.error.set('');
|
|
228
|
+
try {
|
|
229
|
+
const rows = await port.save({ target: { ...target }, changes });
|
|
230
|
+
if (!current())
|
|
231
|
+
return;
|
|
232
|
+
if (new Set(rows.map((row) => refKey(row.contact))).size !== rows.length ||
|
|
233
|
+
rows.some((row) => !validContact(row.contact, target.spaceID || '') ||
|
|
234
|
+
!row.roleIDs.length ||
|
|
235
|
+
new Set(row.roleIDs).size !== row.roleIDs.length))
|
|
236
|
+
throw new Error('Invalid assignments response');
|
|
237
|
+
this.baseline = copyAssignments(rows);
|
|
238
|
+
this.draft.set(copyAssignments(rows));
|
|
239
|
+
this.saved.emit(copyAssignments(rows));
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
if (current()) {
|
|
243
|
+
let message;
|
|
244
|
+
try {
|
|
245
|
+
message = port.errorMessage?.(error);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
/* Keep the safe fallback. */
|
|
249
|
+
}
|
|
250
|
+
this.error.set(message || 'Assignments were not saved. Your changes are retained.');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
if (current())
|
|
255
|
+
this.pending.set(false);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ContactRoleAssignmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
259
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: ContactRoleAssignmentComponent, isStandalone: true, selector: "sneat-contact-role-assignment", inputs: { target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, space: { classPropertyName: "space", publicName: "space", isSignal: true, isRequired: false, transformFunction: null }, assignments: { classPropertyName: "assignments", publicName: "assignments", isSignal: true, isRequired: false, transformFunction: null }, roles: { classPropertyName: "roles", publicName: "roles", isSignal: true, isRequired: false, transformFunction: null }, roleDirection: { classPropertyName: "roleDirection", publicName: "roleDirection", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, savePort: { classPropertyName: "savePort", publicName: "savePort", isSignal: true, isRequired: false, transformFunction: null }, picker: { classPropertyName: "picker", publicName: "picker", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved" }, ngImport: i0, template: "<ion-list aria-label=\"Contact role assignments\">\n @for (row of draft(); track key(row)) {\n <ion-item>\n <ion-label>{{ row.title || row.contact.itemID }}</ion-label>\n @if (hasUnknownRole(row)) {\n <ion-label\n >Existing roles: {{ row.roleIDs.join(', ') }} (read-only)</ion-label\n >\n } @else {\n @for (role of roles(); track role.id) {\n <ion-checkbox\n [checked]=\"row.roleIDs.includes(role.id)\"\n [disabled]=\"!canEdit()\"\n (ionChange)=\"setRole(row, role.id, $event.detail.checked)\"\n >{{ role.label }}</ion-checkbox\n >\n }\n <ion-button [disabled]=\"!canEdit()\" (click)=\"remove(row)\"\n >Remove</ion-button\n >\n }\n </ion-item>\n } @empty {\n <ion-item><ion-label>No contacts assigned.</ion-label></ion-item>\n }\n</ion-list>\n@if (!configured()) {\n <p>Contact assignment is unavailable for this item.</p>\n} @else if (readonly()) {\n <p>Contact assignments are read-only.</p>\n}\n@if (error()) {\n <p role=\"alert\">{{ error() }}</p>\n}\n@if (pending()) {\n <ion-spinner aria-label=\"Updating contact assignments\" />\n}\n<ion-button [disabled]=\"!canEdit()\" (click)=\"addContact()\"\n >Add contact</ion-button\n>\n<ion-button [disabled]=\"!canEdit() || !changed()\" (click)=\"save()\"\n >Save</ion-button\n>\n<ion-button [disabled]=\"locked() || !changed()\" (click)=\"cancel()\"\n >Cancel</ion-button\n>\n", dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
260
|
+
}
|
|
261
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ContactRoleAssignmentComponent, decorators: [{
|
|
262
|
+
type: Component,
|
|
263
|
+
args: [{ selector: 'sneat-contact-role-assignment', changeDetection: ChangeDetectionStrategy.OnPush, imports: [IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonSpinner], template: "<ion-list aria-label=\"Contact role assignments\">\n @for (row of draft(); track key(row)) {\n <ion-item>\n <ion-label>{{ row.title || row.contact.itemID }}</ion-label>\n @if (hasUnknownRole(row)) {\n <ion-label\n >Existing roles: {{ row.roleIDs.join(', ') }} (read-only)</ion-label\n >\n } @else {\n @for (role of roles(); track role.id) {\n <ion-checkbox\n [checked]=\"row.roleIDs.includes(role.id)\"\n [disabled]=\"!canEdit()\"\n (ionChange)=\"setRole(row, role.id, $event.detail.checked)\"\n >{{ role.label }}</ion-checkbox\n >\n }\n <ion-button [disabled]=\"!canEdit()\" (click)=\"remove(row)\"\n >Remove</ion-button\n >\n }\n </ion-item>\n } @empty {\n <ion-item><ion-label>No contacts assigned.</ion-label></ion-item>\n }\n</ion-list>\n@if (!configured()) {\n <p>Contact assignment is unavailable for this item.</p>\n} @else if (readonly()) {\n <p>Contact assignments are read-only.</p>\n}\n@if (error()) {\n <p role=\"alert\">{{ error() }}</p>\n}\n@if (pending()) {\n <ion-spinner aria-label=\"Updating contact assignments\" />\n}\n<ion-button [disabled]=\"!canEdit()\" (click)=\"addContact()\"\n >Add contact</ion-button\n>\n<ion-button [disabled]=\"!canEdit() || !changed()\" (click)=\"save()\"\n >Save</ion-button\n>\n<ion-button [disabled]=\"locked() || !changed()\" (click)=\"cancel()\"\n >Cancel</ion-button\n>\n" }]
|
|
264
|
+
}], ctorParameters: () => [], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], space: [{ type: i0.Input, args: [{ isSignal: true, alias: "space", required: false }] }], assignments: [{ type: i0.Input, args: [{ isSignal: true, alias: "assignments", required: false }] }], roles: [{ type: i0.Input, args: [{ isSignal: true, alias: "roles", required: false }] }], roleDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "roleDirection", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], savePort: [{ type: i0.Input, args: [{ isSignal: true, alias: "savePort", required: false }] }], picker: [{ type: i0.Input, args: [{ isSignal: true, alias: "picker", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }] } });
|
|
265
|
+
//# sourceMappingURL=contact-role-assignment.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact-role-assignment.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/contact-role-assignment/contact-role-assignment.component.ts","../../../../../../../libs/space/components/src/lib/contact-role-assignment/contact-role-assignment.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n input,\n output,\n signal,\n untracked,\n} from '@angular/core';\nimport {\n IonButton,\n IonCheckbox,\n IonItem,\n IonLabel,\n IonList,\n IonSpinner,\n} from '@ionic/angular';\nimport { ISpaceModuleItemRef } from '@sneat/dto';\nimport {\n CONTACT_ROLE_ASSIGNMENT_PICKER,\n IContactAssignmentRoleOption,\n IContactRoleAssignment,\n IContactRoleAssignmentPicker,\n IContactRoleAssignmentSavePort,\n IRelatedItemChange,\n ISpaceContext,\n} from '@sneat/space-models';\n\nconst refKey = (ref: ISpaceModuleItemRef) =>\n JSON.stringify([\n ref.spaceID,\n ref.module,\n ref.collection,\n ref.itemID,\n ref.subPath || '',\n ]);\nconst validContact = (ref: ISpaceModuleItemRef, spaceID: string) =>\n ref.spaceID === spaceID &&\n ref.module === 'contactus' &&\n ref.collection === 'contacts' &&\n !!ref.itemID &&\n !/[@/]/.test(ref.itemID) &&\n !ref.subPath;\nconst copyAssignments = (rows: readonly IContactRoleAssignment[]) =>\n rows.map((row) => ({\n ...row,\n contact: { ...row.contact },\n roleIDs: [...row.roleIDs],\n }));\n\n/** No role or commercial policy lives here. Missing product configuration is readonly. */\n@Component({\n selector: 'sneat-contact-role-assignment',\n templateUrl: './contact-role-assignment.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [IonButton, IonCheckbox, IonItem, IonLabel, IonList, IonSpinner],\n})\nexport class ContactRoleAssignmentComponent {\n readonly target = input<ISpaceModuleItemRef>();\n readonly space = input<ISpaceContext>();\n readonly assignments = input<readonly IContactRoleAssignment[]>([]);\n readonly roles = input<readonly IContactAssignmentRoleOption[]>([]);\n readonly roleDirection = input<'rolesOfItem' | 'rolesToItem'>();\n readonly readonly = input(true);\n readonly busy = input(false);\n readonly savePort = input<IContactRoleAssignmentSavePort>();\n readonly picker = input<IContactRoleAssignmentPicker>();\n readonly saved = output<readonly IContactRoleAssignment[]>();\n private readonly injectedPicker = inject(CONTACT_ROLE_ASSIGNMENT_PICKER, {\n optional: true,\n });\n private baseline: readonly IContactRoleAssignment[] = [];\n private epoch = 0;\n readonly draft = signal<readonly IContactRoleAssignment[]>([]);\n readonly pending = signal(false);\n readonly error = signal('');\n readonly locked = computed(() => this.busy() || this.pending());\n readonly configured = computed(() => {\n const target = this.target();\n const options = this.roles();\n return (\n !!target?.spaceID &&\n !!target.module &&\n !!target.collection &&\n !!target.itemID &&\n !target.subPath &&\n target.spaceID === this.space()?.id &&\n !!this.roleDirection() &&\n !!this.savePort() &&\n !!(this.picker() || this.injectedPicker) &&\n options.length > 0 &&\n options.every((role) => !!role.id.trim() && !!role.label.trim()) &&\n new Set(options.map((role) => role.id)).size === options.length &&\n this.assignments().every(\n (row) =>\n validContact(row.contact, target.spaceID || '') &&\n new Set(row.roleIDs).size === row.roleIDs.length,\n ) &&\n new Set(this.assignments().map((row) => refKey(row.contact))).size ===\n this.assignments().length\n );\n });\n readonly canEdit = computed(\n () => this.configured() && !this.readonly() && !this.locked(),\n );\n readonly changed = computed(\n () =>\n this.changes().length > 0 ||\n this.draft().some(\n (row) =>\n !this.baseline.some((before) => this.key(before) === this.key(row)),\n ),\n );\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.epoch++);\n effect(() => {\n const rows = this.assignments();\n // Changes of authorization/configuration invalidate every outstanding async operation.\n this.target();\n this.space();\n this.roles();\n this.readonly();\n this.savePort();\n this.picker();\n this.roleDirection();\n untracked(() => {\n this.epoch++;\n this.baseline = copyAssignments(rows);\n this.draft.set(copyAssignments(rows));\n this.pending.set(false);\n this.error.set('');\n });\n });\n }\n\n private contextSignature(): string {\n return JSON.stringify([\n this.target(),\n this.space()?.id,\n this.roles(),\n this.assignments(),\n this.readonly(),\n this.roleDirection(),\n ]);\n }\n private captureContext(): () => boolean {\n const epoch = this.epoch;\n const signature = this.contextSignature();\n const port = this.savePort();\n const picker = this.picker();\n // Compare immediately too: an Angular effect can run after a Promise continuation.\n return () =>\n epoch === this.epoch &&\n signature === this.contextSignature() &&\n port === this.savePort() &&\n picker === this.picker();\n }\n\n key(row: IContactRoleAssignment): string {\n return refKey(row.contact);\n }\n hasUnknownRole(row: IContactRoleAssignment): boolean {\n return row.roleIDs.some(\n (role) => !this.roles().some((option) => option.id === role),\n );\n }\n setRole(row: IContactRoleAssignment, role: string, enabled: boolean): void {\n if (\n !this.canEdit() ||\n this.hasUnknownRole(row) ||\n !this.roles().some((r) => r.id === role)\n )\n return;\n this.draft.update((rows) =>\n rows.map((current) =>\n this.key(current) === this.key(row)\n ? {\n ...current,\n roleIDs: enabled\n ? [...new Set([...current.roleIDs, role])]\n : current.roleIDs.filter((r) => r !== role),\n }\n : current,\n ),\n );\n }\n remove(row: IContactRoleAssignment): void {\n if (!this.canEdit() || this.hasUnknownRole(row)) return;\n this.draft.update((rows) =>\n rows.filter((current) => this.key(current) !== this.key(row)),\n );\n }\n cancel(): void {\n if (this.locked()) return;\n this.draft.set(copyAssignments(this.baseline));\n this.error.set('');\n }\n async addContact(): Promise<void> {\n const picker = this.picker() || this.injectedPicker;\n const space = this.space();\n if (!this.canEdit() || !picker || !space) return;\n const current = this.captureContext();\n this.pending.set(true);\n this.error.set('');\n try {\n const row = await picker.selectContact({\n space: { ...space },\n exclude: this.draft().map((r) => ({ ...r.contact })),\n });\n if (!current() || !row) return;\n if (!validContact(row.contact, space.id))\n throw new Error('The selected contact does not belong to this Space.');\n if (\n !this.draft().some(\n (current) => this.key(current) === refKey(row.contact),\n )\n )\n this.draft.update((rows) => [\n ...rows,\n { ...row, contact: { ...row.contact }, roleIDs: [] },\n ]);\n } catch {\n if (current())\n this.error.set('Could not select a contact. Please try again.');\n } finally {\n if (current()) this.pending.set(false);\n }\n }\n private changes(): readonly IRelatedItemChange[] {\n const current = new Map(this.draft().map((row) => [this.key(row), row]));\n const previous = new Map(this.baseline.map((row) => [this.key(row), row]));\n const direction = this.roleDirection();\n if (!direction) return [];\n return [...new Set([...previous.keys(), ...current.keys()])].flatMap(\n (key) => {\n const before = previous.get(key);\n const after = current.get(key);\n const row = after || before;\n if (!row) return [];\n const add = (after?.roleIDs || []).filter(\n (role) => !before?.roleIDs.includes(role),\n );\n const remove = (before?.roleIDs || []).filter(\n (role) => !after?.roleIDs.includes(role),\n );\n return add.length || remove.length\n ? [\n {\n itemRef: { ...row.contact },\n ...(add.length ? { add: { [direction]: add } } : {}),\n ...(remove.length ? { remove: { [direction]: remove } } : {}),\n },\n ]\n : [];\n },\n );\n }\n async save(): Promise<void> {\n const port = this.savePort();\n const target = this.target();\n const changes = this.changes();\n if (!this.canEdit() || !port || !target) return;\n if (this.draft().some((row) => !row.roleIDs.length)) {\n this.error.set('Choose at least one role for each contact.');\n return;\n }\n if (!changes.length) return;\n const current = this.captureContext();\n this.pending.set(true);\n this.error.set('');\n try {\n const rows = await port.save({ target: { ...target }, changes });\n if (!current()) return;\n if (\n new Set(rows.map((row) => refKey(row.contact))).size !== rows.length ||\n rows.some(\n (row) =>\n !validContact(row.contact, target.spaceID || '') ||\n !row.roleIDs.length ||\n new Set(row.roleIDs).size !== row.roleIDs.length,\n )\n )\n throw new Error('Invalid assignments response');\n this.baseline = copyAssignments(rows);\n this.draft.set(copyAssignments(rows));\n this.saved.emit(copyAssignments(rows));\n } catch (error) {\n if (current()) {\n let message: string | undefined;\n try {\n message = port.errorMessage?.(error);\n } catch {\n /* Keep the safe fallback. */\n }\n this.error.set(\n message || 'Assignments were not saved. Your changes are retained.',\n );\n }\n } finally {\n if (current()) this.pending.set(false);\n }\n }\n}\n","<ion-list aria-label=\"Contact role assignments\">\n @for (row of draft(); track key(row)) {\n <ion-item>\n <ion-label>{{ row.title || row.contact.itemID }}</ion-label>\n @if (hasUnknownRole(row)) {\n <ion-label\n >Existing roles: {{ row.roleIDs.join(', ') }} (read-only)</ion-label\n >\n } @else {\n @for (role of roles(); track role.id) {\n <ion-checkbox\n [checked]=\"row.roleIDs.includes(role.id)\"\n [disabled]=\"!canEdit()\"\n (ionChange)=\"setRole(row, role.id, $event.detail.checked)\"\n >{{ role.label }}</ion-checkbox\n >\n }\n <ion-button [disabled]=\"!canEdit()\" (click)=\"remove(row)\"\n >Remove</ion-button\n >\n }\n </ion-item>\n } @empty {\n <ion-item><ion-label>No contacts assigned.</ion-label></ion-item>\n }\n</ion-list>\n@if (!configured()) {\n <p>Contact assignment is unavailable for this item.</p>\n} @else if (readonly()) {\n <p>Contact assignments are read-only.</p>\n}\n@if (error()) {\n <p role=\"alert\">{{ error() }}</p>\n}\n@if (pending()) {\n <ion-spinner aria-label=\"Updating contact assignments\" />\n}\n<ion-button [disabled]=\"!canEdit()\" (click)=\"addContact()\"\n >Add contact</ion-button\n>\n<ion-button [disabled]=\"!canEdit() || !changed()\" (click)=\"save()\"\n >Save</ion-button\n>\n<ion-button [disabled]=\"locked() || !changed()\" (click)=\"cancel()\"\n >Cancel</ion-button\n>\n"]}
|
package/esm2022/lib/index.js
CHANGED
|
@@ -12,4 +12,5 @@ export * from './spaces-list';
|
|
|
12
12
|
export * from './spaces-card';
|
|
13
13
|
export * from './space-module-base.component';
|
|
14
14
|
export * from './space-base-component.directive';
|
|
15
|
+
export * from './contact-role-assignment/contact-role-assignment.component';
|
|
15
16
|
//# sourceMappingURL=index.js.map
|
package/esm2022/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/space/components/src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC","sourcesContent":["export * from './avatar/avatar.component';\nexport * from './space-menu';\nexport * from './space-selector';\nexport * from './space-extension-links';\nexport * from './spaces-menu';\nexport * from './space-page-title/space-page-title.component';\nexport * from './space-page-base-component.service';\nexport * from './space-component-base-params.service';\nexport * from './space-item-page-base.component';\nexport * from './space-items-base.component';\nexport * from './spaces-list';\nexport * from './spaces-card';\nexport * from './space-module-base.component';\nexport * from './space-base-component.directive';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/space/components/src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6DAA6D,CAAC","sourcesContent":["export * from './avatar/avatar.component';\nexport * from './space-menu';\nexport * from './space-selector';\nexport * from './space-extension-links';\nexport * from './spaces-menu';\nexport * from './space-page-title/space-page-title.component';\nexport * from './space-page-base-component.service';\nexport * from './space-component-base-params.service';\nexport * from './space-item-page-base.component';\nexport * from './space-items-base.component';\nexport * from './spaces-list';\nexport * from './spaces-card';\nexport * from './space-module-base.component';\nexport * from './space-base-component.directive';\nexport * from './contact-role-assignment/contact-role-assignment.component';\n"]}
|
|
@@ -2,7 +2,7 @@ import { isPlatformBrowser } from '@angular/common';
|
|
|
2
2
|
import { computed, Directive, effect, inject, PLATFORM_ID, signal, } from '@angular/core';
|
|
3
3
|
import { ActivatedRoute } from '@angular/router';
|
|
4
4
|
import { NavController } from '@ionic/angular';
|
|
5
|
-
import { equalSpaceRefs, writeCurrentSpace, } from '@sneat/core';
|
|
5
|
+
import { clearCurrentSpace, equalSpaceRefs, readCurrentSpace, writeCurrentSpace, } from '@sneat/core';
|
|
6
6
|
import { equalSpaceBriefs } from '@sneat/dto';
|
|
7
7
|
import { SpaceService, trackSpaceIdAndTypeFromRouteParameter, } from '@sneat/space-services';
|
|
8
8
|
import { SneatBaseComponent } from '@sneat/ui';
|
|
@@ -67,7 +67,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
67
67
|
this.navController = inject(NavController);
|
|
68
68
|
// protected readonly communeService: ICommuneService;
|
|
69
69
|
this.spaceService = inject(SpaceService);
|
|
70
|
-
this.spaceIDChanged$ = this.spaceIDChanged.asObservable().pipe(this.takeUntilDestroyed(), distinctUntilChanged());
|
|
70
|
+
this.spaceIDChanged$ = this.spaceIDChanged.asObservable().pipe(this.takeUntilDestroyed(), distinctUntilChanged(), shareReplay(1));
|
|
71
71
|
this.spaceTypeChanged$ = this.spaceTypeChanged.pipe(this.takeUntilDestroyed(), distinctUntilChanged(),
|
|
72
72
|
// tap(v => console.log('spaceTypeChanged$ before replay =>', v)),
|
|
73
73
|
shareReplay(1));
|
|
@@ -76,7 +76,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
76
76
|
.pipe(this.takeUntilDestroyed(), distinctUntilChanged(equalSpaceBriefs));
|
|
77
77
|
this.spaceDboChanged$ = this.spaceDboChanged
|
|
78
78
|
.asObservable()
|
|
79
|
-
.pipe(this.takeUntilDestroyed(), distinctUntilChanged());
|
|
79
|
+
.pipe(this.takeUntilDestroyed(), distinctUntilChanged(), shareReplay(1));
|
|
80
80
|
this.$defaultBackUrlSpacePath = signal('', /* @ts-ignore */
|
|
81
81
|
...(ngDevMode ? [{ debugName: "$defaultBackUrlSpacePath" }] : /* istanbul ignore next */ []));
|
|
82
82
|
// Intentionally not readonly, but might reconsider
|
|
@@ -151,6 +151,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
151
151
|
this.unsubscribe('$spaceID() changed');
|
|
152
152
|
this.$spaceBrief.set(undefined);
|
|
153
153
|
this.$spaceDbo.set(undefined);
|
|
154
|
+
this.spaceDboChanged.next(undefined);
|
|
154
155
|
if (spaceID && this.isBrowser) {
|
|
155
156
|
setTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);
|
|
156
157
|
}
|
|
@@ -257,6 +258,10 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
257
258
|
// document exists. For navigation purposes this is a terminal
|
|
258
259
|
// unavailable-space state, just like a missing snapshot.
|
|
259
260
|
this.$spaceAccessDenied.set(true);
|
|
261
|
+
const current = readCurrentSpace();
|
|
262
|
+
if (current?.id === spaceID) {
|
|
263
|
+
clearCurrentSpace();
|
|
264
|
+
}
|
|
260
265
|
return;
|
|
261
266
|
}
|
|
262
267
|
this.errorLogger.logError('failed to get team record');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"space-base-component.directive.js","sourceRoot":"","sources":["../../../../../../libs/space/components/src/lib/space-base-component.directive.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n computed,\n Directive,\n effect,\n inject,\n OnInit,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { ActivatedRoute, ParamMap } from '@angular/router';\nimport { NavController } from '@ionic/angular';\nimport {\n equalSpaceRefs,\n ILogger,\n ISpaceRef,\n SpaceType,\n writeCurrentSpace,\n} from '@sneat/core';\n\ntype NavigationOptions = NonNullable<\n Parameters<NavController['navigateRoot']>[1]\n>;\nimport { equalSpaceBriefs, ISpaceBrief, ISpaceDbo } from '@sneat/dto';\nimport { ISpaceContext } from '@sneat/space-models';\nimport {\n SpaceService,\n trackSpaceIdAndTypeFromRouteParameter,\n} from '@sneat/space-services';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { SneatBaseComponent } from '@sneat/ui';\nimport {\n distinctUntilChanged,\n map,\n MonoTypeOperatorFunction,\n Observable,\n shareReplay,\n Subject,\n} from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SpaceComponentBaseParams } from './space-component-base-params.service';\n\n@Directive() // The @Directive is required by Angular as we are implementing OnInit\nexport abstract class SpaceBaseComponent\n extends SneatBaseComponent\n implements OnInit\n{\n protected readonly $spaceRef = signal<ISpaceRef | undefined | null>(\n undefined,\n );\n private readonly $spaceBrief = signal<ISpaceBrief | undefined | null>(\n undefined,\n );\n private readonly $spaceDbo = signal<ISpaceDbo | undefined | null>(undefined);\n private readonly $spaceAccessDenied = signal(false);\n\n protected readonly $spaceNotFound = computed(\n () => this.$spaceDbo() === null || this.$spaceAccessDenied(),\n );\n\n // private readonly $_spaceID = signal<string | undefined>(undefined);\n // protected readonly $spaceID = this.$_spaceID.asReadonly();\n protected readonly $spaceID = computed(() => this.$spaceRef()?.id);\n\n // private readonly $_spaceType = signal<SpaceType | undefined>(undefined);\n // protected readonly $spaceType = this.$_spaceType.asReadonly();\n protected readonly $spaceType = computed(() => this.$spaceRef()?.type);\n\n protected readonly $space = computed<ISpaceContext>(() => {\n return {\n ...(this.$spaceRef() || { id: '' }),\n brief: this.$spaceBrief(),\n dbo: this.$spaceDbo(),\n };\n });\n\n private readonly spaceIDChanged = new Subject<string | undefined>();\n private readonly spaceTypeChanged = new Subject<SpaceType | undefined>();\n\n protected takeUntilSpaceIdChanged<T>(): MonoTypeOperatorFunction<T> {\n return takeUntil(this.spaceIDChanged$);\n }\n\n protected readonly spaceBriefChanged = new Subject<\n ISpaceBrief | undefined | null\n >();\n protected readonly spaceDboChanged = new Subject<\n ISpaceDbo | undefined | null\n >();\n\n // protected spaceContext?: ISpaceContext;\n\n private readonly spaceChanged = new Subject<ISpaceContext>();\n protected readonly spaceChanged$ = this.spaceChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed());\n\n protected readonly navController = inject(NavController);\n // protected readonly activeCommuneService: IActiveCommuneService;\n protected readonly userService: SneatUserService;\n // protected readonly communeService: ICommuneService;\n protected readonly spaceService = inject(SpaceService);\n // protected readonly authStateService: IAuthStateService;\n protected readonly logger: ILogger;\n // protected readonly willLeave = new Subject<void>();\n protected defaultBackPage?: string;\n\n protected readonly spaceIDChanged$ = this.spaceIDChanged.asObservable().pipe(\n this.takeUntilDestroyed(),\n distinctUntilChanged(),\n // tap((id) => console.log(this.className + '=> spaceIDChanged$: ' + id)),\n );\n\n protected readonly spaceTypeChanged$: Observable<SpaceType | undefined> =\n this.spaceTypeChanged.pipe(\n this.takeUntilDestroyed(),\n distinctUntilChanged(),\n // tap(v => console.log('spaceTypeChanged$ before replay =>', v)),\n shareReplay(1),\n // tap(v => console.log('spaceTypeChanged$ after replay =>', v)),\n );\n\n protected readonly spaceBriefChanged$ = this.spaceBriefChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed(), distinctUntilChanged(equalSpaceBriefs));\n\n public readonly spaceDboChanged$ = this.spaceDboChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed(), distinctUntilChanged());\n\n protected get space(): ISpaceContext {\n // TODO: Document why we do not allow undefined\n return this.$space() || ({ id: '' } as ISpaceContext);\n }\n\n protected get preloader() {\n return this.spaceParams.preloader;\n }\n\n protected get spaceNav() {\n return this.spaceParams.spaceNavService;\n }\n\n protected get currentUserId() {\n return this.userService.currentUserID;\n }\n\n protected readonly $defaultBackUrlSpacePath = signal('');\n\n // Intentionally not readonly, but might reconsider\n protected $defaultBackUrl = computed<string>(() => {\n const space = this.$space();\n const path = this.$defaultBackUrlSpacePath();\n let url = space ? `/space/${space.type}/${space.id}` : '';\n url = url && this.defaultBackPage ? url + '/' + this.defaultBackPage : url;\n if (path) {\n url = url + '/' + path;\n }\n return url;\n });\n\n protected readonly route = inject(ActivatedRoute);\n protected readonly spaceParams = inject(SpaceComponentBaseParams);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n public constructor() {\n super();\n\n let prevSpaceID: string | undefined;\n\n effect(() => {\n const spaceID = this.$spaceID();\n\n if (spaceID === prevSpaceID) {\n // This seems to be a bag or a strange feature in Angular signals?\n // this happens if we call this.spaceIDChanged.next(spaceID);\n // Giving up for now so not logging as a warning\n return;\n }\n prevSpaceID = spaceID;\n this.spaceIDChanged.next(spaceID); // This should be BEFORE onSpaceIdChanged()!\n this.onSpaceIdChanged(); // This should be AFTER spaceIDChanged.next()!\n this.unsubscribe('$spaceID() changed');\n this.$spaceBrief.set(undefined);\n this.$spaceDbo.set(undefined);\n if (spaceID && this.isBrowser) {\n setTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);\n }\n });\n\n // this.spaceIDChanged$\n // \t.pipe(this.takeUntilDestroyed(), distinctUntilChanged())\n // \t.subscribe((spaceID) => {\n // \t\tif (spaceID) {\n // \t\t\t// !!! Be careful to migrate this to signal effect - can cause dead cycles!\n // \t\t\tsetTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);\n // \t\t}\n // \t});\n\n effect(() => {\n this.spaceTypeChanged.next(this.$spaceType());\n });\n\n try {\n // this.navController = spaceParams.navController;\n this.userService = this.spaceParams.userService;\n this.logger = this.spaceParams.loggerFactory.getLogger(this.className);\n this.getSpaceContextFromRouteState();\n this.cleanupOnUserLogout();\n } catch (e) {\n this.errorLogger.logError(\n e,\n `Failed in ${this.className}:SpaceBaseComponent.constructor()`,\n );\n throw e;\n }\n }\n\n public ngOnInit(): void {\n // We can't call this in constructor as some members of the child class may not be initialized yet\n this.trackRouteParamMap(\n this.route.paramMap.pipe(this.takeUntilDestroyed()),\n );\n }\n\n // public ionViewWillLeave(): void {\n // \t// console.log(`${this.className}:SpaceBaseComponent.ionViewWillLeave()`);\n // \tthis.willLeave.next();\n // }\n\n protected onUserIdChanged(): void {\n if (!this.currentUserId) {\n this.subs.unsubscribe();\n if (this.space.brief || this.space.dbo) {\n this.setSpaceContext({\n ...this.space,\n brief: undefined,\n dbo: undefined,\n });\n }\n }\n }\n\n protected navigateForwardToSpacePage(\n page: string,\n navOptions?: NavigationOptions,\n ) {\n if (!this.space) {\n return Promise.reject('no space context');\n }\n return this.spaceParams.spaceNavService.navigateForwardToSpacePage(\n this.space,\n page,\n navOptions,\n );\n }\n\n // TODO: Consider removing this method as it is fragile.\n // It is easy go get it wrong and server similar purpose as spaceIDChanged$.\n protected onSpaceIdChanged(): void {\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceIdChanged() spaceID=${this.space?.id}`,\n // );\n }\n\n protected onSpaceDboChanged(): void {\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceDboChanged(): ` +\n // \t\tJSON.stringify(this.space.dbo),\n // );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function\n protected onRouteParamsChanged(params: ParamMap): void {}\n\n protected trackRouteParamMap(paramMap$: Observable<ParamMap>): void {\n this.trackSpaceIdFromRouteParams(paramMap$);\n paramMap$.subscribe({\n next: (paramMap) => this.onRouteParamsChanged(paramMap),\n });\n }\n\n private trackSpaceIdFromRouteParams(paramMap$: Observable<ParamMap>): void {\n trackSpaceIdAndTypeFromRouteParameter(paramMap$)\n // .pipe(\n // \ttap((v) => this.log('trackSpaceIdFromRouteParams 1', v)),\n // \tdistinctUntilChanged(\n // \t\t(previous, current) => previous?.id === current?.id,\n // \t),\n // \ttap((v) => this.log('trackSpaceIdFromRouteParams 3', v)),\n // )\n .subscribe({\n next: this.onSpaceIdChangedInUrl,\n error: this.logErrorHandler,\n });\n }\n\n private readonly onSpaceIdChangedInUrl = (space?: ISpaceContext): void => {\n const prevSpace = this.$space();\n this.log(\n `${this.className}:SpaceBaseComponent.onSpaceIdChangedInUrl(): prevSpace.id: ${prevSpace?.id} => ${space?.id}`,\n );\n if (\n space === prevSpace ||\n (space?.id === prevSpace?.id && space?.type === prevSpace?.type)\n ) {\n return;\n }\n if (space && prevSpace?.id === space?.id) {\n space = { ...prevSpace, ...space };\n }\n this.setSpaceContext(space);\n };\n\n private subscribeForSpaceChanges(spaceID: string): void {\n this.spaceService\n .watchSpace(spaceID)\n .pipe(\n this.takeUntilDestroyed(),\n takeUntil(this.spaceIDChanged$),\n map((space) => {\n return {\n ...space,\n type: space.dbo?.type || space.type || this.$spaceType(),\n };\n }),\n )\n .subscribe({\n next: this.onSpaceContextChanged,\n error: (err) => {\n if (err.code === 'permission-denied') {\n this.log(\n 'subscribeForSpaceChanges() => permission denied to read space record',\n );\n // Firestore intentionally does not reveal whether a protected\n // document exists. For navigation purposes this is a terminal\n // unavailable-space state, just like a missing snapshot.\n this.$spaceAccessDenied.set(true);\n return;\n }\n this.errorLogger.logError('failed to get team record');\n },\n });\n }\n\n private getSpaceContextFromRouteState(): void {\n const space = this.isBrowser\n ? (history.state?.team as ISpaceContext)\n : undefined;\n this.log(\n `${this.className}:SpaceBaseComponent.getSpaceContextFromRouteState()`,\n space,\n );\n if (!space?.id) {\n return;\n }\n // TODO: document why not to set team context immediately\n setTimeout(() => this.setSpaceContext(space), 1);\n }\n\n private cleanupOnUserLogout(): void {\n try {\n this.userService.userChanged.pipe(this.takeUntilDestroyed()).subscribe({\n next: (uid) => {\n if (!uid) {\n this.unsubscribe('user signed out');\n }\n // A space's id and type come from the public URL and remain useful\n // before authentication and after sign-out. Only loaded protected\n // data is cleared by onUserIdChanged().\n this.onUserIdChanged();\n },\n error: (e) => this.logError(e, 'Failed to get user record'),\n });\n } catch (e) {\n this.logError(\n e,\n 'Failed to subscribe a hook on page cleanup on user logout',\n );\n }\n }\n\n // private updateExistingSpaceContext(spaceContext: ISpaceContext): void {\n // \tconst dtoChanged = this.spaceContext?.dto != spaceContext.dto;\n // \tthis.spaceContext = spaceContext;\n // \tif (dtoChanged) {\n // \t\tthis.onSpaceDtoChanged();\n // \t}\n // }\n\n protected setSpaceRef(spaceRef?: ISpaceRef): void {\n let idChanged = false;\n let typeChanged = false;\n this.$spaceRef.update((prev) => {\n if (prev === spaceRef) {\n return prev;\n }\n idChanged = prev?.id !== spaceRef?.id;\n typeChanged = prev?.type !== spaceRef?.type;\n if (!idChanged && !typeChanged) {\n return prev;\n }\n if (!spaceRef) {\n return undefined;\n }\n if (equalSpaceRefs(spaceRef, prev)) {\n return prev;\n }\n const keys = Object.keys(spaceRef || {});\n return (keys.length === 1 && keys[0] === 'id') ||\n (keys.length === 2 && keys.includes('id') && keys.includes('type'))\n ? spaceRef\n : spaceRef.type || (prev?.type && prev.id !== spaceRef.id)\n ? { id: spaceRef.id, type: spaceRef.type || prev?.type }\n : { id: spaceRef.id };\n });\n const currentSpaceRef = this.$spaceRef();\n if (currentSpaceRef) {\n // Persist so the login page can restore it after sign-in. No-op unless id+type are known.\n writeCurrentSpace(currentSpaceRef);\n }\n }\n\n private setSpaceContext(spaceContext?: ISpaceContext): void {\n const prevSpace = this.$space();\n this.log(\n `${this.className}:SpaceBaseComponent.setSpaceContext(id=${spaceContext?.id}), previous id=${prevSpace.id}`,\n spaceContext,\n );\n if (!equalSpaceRefs(spaceContext, this.$spaceRef())) {\n this.setSpaceRef(spaceContext);\n }\n if (prevSpace == spaceContext) {\n this.console.warn(\n 'Duplicate call to SpaceBaseComponent.setSpaceContext() with same spaceContext:',\n spaceContext,\n );\n return;\n }\n const idChanged = prevSpace?.id != spaceContext?.id;\n if (idChanged) {\n this.$spaceAccessDenied.set(false);\n }\n const briefChanged = !equalSpaceBriefs(\n prevSpace?.brief,\n spaceContext?.brief,\n );\n const dboChanged = prevSpace?.dbo !== spaceContext?.dbo;\n this.log(\n `${this.className}:SpaceBaseComponent.setSpaceContext(id=${spaceContext?.id}) => idChanged=${idChanged}, briefChanged=${briefChanged}, dtoChanged=${dboChanged}`,\n );\n if (briefChanged) {\n this.$spaceBrief.set(spaceContext?.brief);\n this.spaceBriefChanged.next(spaceContext?.brief);\n }\n if (dboChanged) {\n this.$spaceDbo.set(spaceContext?.dbo);\n this.spaceDboChanged.next(spaceContext?.dbo);\n }\n if (spaceContext) {\n this.spaceChanged.next(spaceContext);\n }\n }\n\n private readonly onSpaceContextChanged = (space: ISpaceContext): void => {\n this.$spaceAccessDenied.set(false);\n const isDboChanged = space.dbo !== this.$space()?.dbo;\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceContextChanged() => dtoChanged=${dtoChanged}, space:`,\n // \tspace,\n // );\n if (!space.brief && space.dbo) {\n space = { ...space, brief: space.dbo };\n }\n if (!space.type) {\n if (space.brief?.type) {\n space = { ...space, type: space.brief.type };\n } else if (this.$spaceType()) {\n space = { ...space, type: this.$spaceType() };\n }\n }\n this.setSpaceContext(space);\n if (isDboChanged) {\n this.onSpaceDboChanged();\n }\n // this.log(`${this.className} => loaded team record:`, newTeam);\n // if (newSpace.id === this.spaceContext?.id) {\n // \tthis.setNewSpaceContext({ ...this.spaceContext, ...newSpace });\n // \t// this.spaceContext = ;\n // } else { // Whe should never end up here as should unsubscribe on leaving page or ID change\n // \tthis.errorLogger.logError(`got team record after space context changed: received id=${newSpace.id}, current id=${this.spaceContext?.id}`);\n // }\n };\n\n protected saveNotes(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n // alert('Saving noes is not implemented yet');\n }\n\n protected spacePageUrl(page: string): string {\n return spacePageUrl(this.$space(), page) || '';\n }\n}\n\nexport const spacePageUrl = (\n team?: ISpaceContext,\n page?: string,\n): string | undefined => {\n return team?.id\n ? page\n ? `/space/${team.type}/${team.id}/${page}`\n : `/space/${team.type}/${team.id}`\n : undefined;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"space-base-component.directive.js","sourceRoot":"","sources":["../../../../../../libs/space/components/src/lib/space-base-component.directive.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n computed,\n Directive,\n effect,\n inject,\n OnInit,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { ActivatedRoute, ParamMap } from '@angular/router';\nimport { NavController } from '@ionic/angular';\nimport {\n clearCurrentSpace,\n equalSpaceRefs,\n ILogger,\n ISpaceRef,\n readCurrentSpace,\n SpaceType,\n writeCurrentSpace,\n} from '@sneat/core';\n\ntype NavigationOptions = NonNullable<\n Parameters<NavController['navigateRoot']>[1]\n>;\nimport { equalSpaceBriefs, ISpaceBrief, ISpaceDbo } from '@sneat/dto';\nimport { ISpaceContext } from '@sneat/space-models';\nimport {\n SpaceService,\n trackSpaceIdAndTypeFromRouteParameter,\n} from '@sneat/space-services';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { SneatBaseComponent } from '@sneat/ui';\nimport {\n distinctUntilChanged,\n map,\n MonoTypeOperatorFunction,\n Observable,\n shareReplay,\n Subject,\n} from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SpaceComponentBaseParams } from './space-component-base-params.service';\n\n@Directive() // The @Directive is required by Angular as we are implementing OnInit\nexport abstract class SpaceBaseComponent\n extends SneatBaseComponent\n implements OnInit\n{\n protected readonly $spaceRef = signal<ISpaceRef | undefined | null>(\n undefined,\n );\n private readonly $spaceBrief = signal<ISpaceBrief | undefined | null>(\n undefined,\n );\n private readonly $spaceDbo = signal<ISpaceDbo | undefined | null>(undefined);\n protected readonly $spaceAccessDenied = signal(false);\n\n protected readonly $spaceNotFound = computed(\n () => this.$spaceDbo() === null || this.$spaceAccessDenied(),\n );\n\n // private readonly $_spaceID = signal<string | undefined>(undefined);\n // protected readonly $spaceID = this.$_spaceID.asReadonly();\n protected readonly $spaceID = computed(() => this.$spaceRef()?.id);\n\n // private readonly $_spaceType = signal<SpaceType | undefined>(undefined);\n // protected readonly $spaceType = this.$_spaceType.asReadonly();\n protected readonly $spaceType = computed(() => this.$spaceRef()?.type);\n\n protected readonly $space = computed<ISpaceContext>(() => {\n return {\n ...(this.$spaceRef() || { id: '' }),\n brief: this.$spaceBrief(),\n dbo: this.$spaceDbo(),\n };\n });\n\n private readonly spaceIDChanged = new Subject<string | undefined>();\n private readonly spaceTypeChanged = new Subject<SpaceType | undefined>();\n\n protected takeUntilSpaceIdChanged<T>(): MonoTypeOperatorFunction<T> {\n return takeUntil(this.spaceIDChanged$);\n }\n\n protected readonly spaceBriefChanged = new Subject<\n ISpaceBrief | undefined | null\n >();\n protected readonly spaceDboChanged = new Subject<\n ISpaceDbo | undefined | null\n >();\n\n // protected spaceContext?: ISpaceContext;\n\n private readonly spaceChanged = new Subject<ISpaceContext>();\n protected readonly spaceChanged$ = this.spaceChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed());\n\n protected readonly navController = inject(NavController);\n // protected readonly activeCommuneService: IActiveCommuneService;\n protected readonly userService: SneatUserService;\n // protected readonly communeService: ICommuneService;\n protected readonly spaceService = inject(SpaceService);\n // protected readonly authStateService: IAuthStateService;\n protected readonly logger: ILogger;\n // protected readonly willLeave = new Subject<void>();\n protected defaultBackPage?: string;\n\n protected readonly spaceIDChanged$ = this.spaceIDChanged.asObservable().pipe(\n this.takeUntilDestroyed(),\n distinctUntilChanged(),\n shareReplay(1),\n // tap((id) => console.log(this.className + '=> spaceIDChanged$: ' + id)),\n );\n\n protected readonly spaceTypeChanged$: Observable<SpaceType | undefined> =\n this.spaceTypeChanged.pipe(\n this.takeUntilDestroyed(),\n distinctUntilChanged(),\n // tap(v => console.log('spaceTypeChanged$ before replay =>', v)),\n shareReplay(1),\n // tap(v => console.log('spaceTypeChanged$ after replay =>', v)),\n );\n\n protected readonly spaceBriefChanged$ = this.spaceBriefChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed(), distinctUntilChanged(equalSpaceBriefs));\n\n public readonly spaceDboChanged$ = this.spaceDboChanged\n .asObservable()\n .pipe(this.takeUntilDestroyed(), distinctUntilChanged(), shareReplay(1));\n\n protected get space(): ISpaceContext {\n // TODO: Document why we do not allow undefined\n return this.$space() || ({ id: '' } as ISpaceContext);\n }\n\n protected get preloader() {\n return this.spaceParams.preloader;\n }\n\n protected get spaceNav() {\n return this.spaceParams.spaceNavService;\n }\n\n protected get currentUserId() {\n return this.userService.currentUserID;\n }\n\n protected readonly $defaultBackUrlSpacePath = signal('');\n\n // Intentionally not readonly, but might reconsider\n protected $defaultBackUrl = computed<string>(() => {\n const space = this.$space();\n const path = this.$defaultBackUrlSpacePath();\n let url = space ? `/space/${space.type}/${space.id}` : '';\n url = url && this.defaultBackPage ? url + '/' + this.defaultBackPage : url;\n if (path) {\n url = url + '/' + path;\n }\n return url;\n });\n\n protected readonly route = inject(ActivatedRoute);\n protected readonly spaceParams = inject(SpaceComponentBaseParams);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n public constructor() {\n super();\n\n let prevSpaceID: string | undefined;\n\n effect(() => {\n const spaceID = this.$spaceID();\n\n if (spaceID === prevSpaceID) {\n // This seems to be a bag or a strange feature in Angular signals?\n // this happens if we call this.spaceIDChanged.next(spaceID);\n // Giving up for now so not logging as a warning\n return;\n }\n prevSpaceID = spaceID;\n this.spaceIDChanged.next(spaceID); // This should be BEFORE onSpaceIdChanged()!\n this.onSpaceIdChanged(); // This should be AFTER spaceIDChanged.next()!\n this.unsubscribe('$spaceID() changed');\n this.$spaceBrief.set(undefined);\n this.$spaceDbo.set(undefined);\n this.spaceDboChanged.next(undefined);\n if (spaceID && this.isBrowser) {\n setTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);\n }\n });\n\n // this.spaceIDChanged$\n // \t.pipe(this.takeUntilDestroyed(), distinctUntilChanged())\n // \t.subscribe((spaceID) => {\n // \t\tif (spaceID) {\n // \t\t\t// !!! Be careful to migrate this to signal effect - can cause dead cycles!\n // \t\t\tsetTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);\n // \t\t}\n // \t});\n\n effect(() => {\n this.spaceTypeChanged.next(this.$spaceType());\n });\n\n try {\n // this.navController = spaceParams.navController;\n this.userService = this.spaceParams.userService;\n this.logger = this.spaceParams.loggerFactory.getLogger(this.className);\n this.getSpaceContextFromRouteState();\n this.cleanupOnUserLogout();\n } catch (e) {\n this.errorLogger.logError(\n e,\n `Failed in ${this.className}:SpaceBaseComponent.constructor()`,\n );\n throw e;\n }\n }\n\n public ngOnInit(): void {\n // We can't call this in constructor as some members of the child class may not be initialized yet\n this.trackRouteParamMap(\n this.route.paramMap.pipe(this.takeUntilDestroyed()),\n );\n }\n\n // public ionViewWillLeave(): void {\n // \t// console.log(`${this.className}:SpaceBaseComponent.ionViewWillLeave()`);\n // \tthis.willLeave.next();\n // }\n\n protected onUserIdChanged(): void {\n if (!this.currentUserId) {\n this.subs.unsubscribe();\n if (this.space.brief || this.space.dbo) {\n this.setSpaceContext({\n ...this.space,\n brief: undefined,\n dbo: undefined,\n });\n }\n }\n }\n\n protected navigateForwardToSpacePage(\n page: string,\n navOptions?: NavigationOptions,\n ) {\n if (!this.space) {\n return Promise.reject('no space context');\n }\n return this.spaceParams.spaceNavService.navigateForwardToSpacePage(\n this.space,\n page,\n navOptions,\n );\n }\n\n // TODO: Consider removing this method as it is fragile.\n // It is easy go get it wrong and server similar purpose as spaceIDChanged$.\n protected onSpaceIdChanged(): void {\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceIdChanged() spaceID=${this.space?.id}`,\n // );\n }\n\n protected onSpaceDboChanged(): void {\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceDboChanged(): ` +\n // \t\tJSON.stringify(this.space.dbo),\n // );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function\n protected onRouteParamsChanged(params: ParamMap): void {}\n\n protected trackRouteParamMap(paramMap$: Observable<ParamMap>): void {\n this.trackSpaceIdFromRouteParams(paramMap$);\n paramMap$.subscribe({\n next: (paramMap) => this.onRouteParamsChanged(paramMap),\n });\n }\n\n private trackSpaceIdFromRouteParams(paramMap$: Observable<ParamMap>): void {\n trackSpaceIdAndTypeFromRouteParameter(paramMap$)\n // .pipe(\n // \ttap((v) => this.log('trackSpaceIdFromRouteParams 1', v)),\n // \tdistinctUntilChanged(\n // \t\t(previous, current) => previous?.id === current?.id,\n // \t),\n // \ttap((v) => this.log('trackSpaceIdFromRouteParams 3', v)),\n // )\n .subscribe({\n next: this.onSpaceIdChangedInUrl,\n error: this.logErrorHandler,\n });\n }\n\n private readonly onSpaceIdChangedInUrl = (space?: ISpaceContext): void => {\n const prevSpace = this.$space();\n this.log(\n `${this.className}:SpaceBaseComponent.onSpaceIdChangedInUrl(): prevSpace.id: ${prevSpace?.id} => ${space?.id}`,\n );\n if (\n space === prevSpace ||\n (space?.id === prevSpace?.id && space?.type === prevSpace?.type)\n ) {\n return;\n }\n if (space && prevSpace?.id === space?.id) {\n space = { ...prevSpace, ...space };\n }\n this.setSpaceContext(space);\n };\n\n private subscribeForSpaceChanges(spaceID: string): void {\n this.spaceService\n .watchSpace(spaceID)\n .pipe(\n this.takeUntilDestroyed(),\n takeUntil(this.spaceIDChanged$),\n map((space) => {\n return {\n ...space,\n type: space.dbo?.type || space.type || this.$spaceType(),\n };\n }),\n )\n .subscribe({\n next: this.onSpaceContextChanged,\n error: (err) => {\n if (err.code === 'permission-denied') {\n this.log(\n 'subscribeForSpaceChanges() => permission denied to read space record',\n );\n // Firestore intentionally does not reveal whether a protected\n // document exists. For navigation purposes this is a terminal\n // unavailable-space state, just like a missing snapshot.\n this.$spaceAccessDenied.set(true);\n const current = readCurrentSpace();\n if (current?.id === spaceID) {\n clearCurrentSpace();\n }\n return;\n }\n this.errorLogger.logError('failed to get team record');\n },\n });\n }\n\n private getSpaceContextFromRouteState(): void {\n const space = this.isBrowser\n ? (history.state?.team as ISpaceContext)\n : undefined;\n this.log(\n `${this.className}:SpaceBaseComponent.getSpaceContextFromRouteState()`,\n space,\n );\n if (!space?.id) {\n return;\n }\n // TODO: document why not to set team context immediately\n setTimeout(() => this.setSpaceContext(space), 1);\n }\n\n private cleanupOnUserLogout(): void {\n try {\n this.userService.userChanged.pipe(this.takeUntilDestroyed()).subscribe({\n next: (uid) => {\n if (!uid) {\n this.unsubscribe('user signed out');\n }\n // A space's id and type come from the public URL and remain useful\n // before authentication and after sign-out. Only loaded protected\n // data is cleared by onUserIdChanged().\n this.onUserIdChanged();\n },\n error: (e) => this.logError(e, 'Failed to get user record'),\n });\n } catch (e) {\n this.logError(\n e,\n 'Failed to subscribe a hook on page cleanup on user logout',\n );\n }\n }\n\n // private updateExistingSpaceContext(spaceContext: ISpaceContext): void {\n // \tconst dtoChanged = this.spaceContext?.dto != spaceContext.dto;\n // \tthis.spaceContext = spaceContext;\n // \tif (dtoChanged) {\n // \t\tthis.onSpaceDtoChanged();\n // \t}\n // }\n\n protected setSpaceRef(spaceRef?: ISpaceRef): void {\n let idChanged = false;\n let typeChanged = false;\n this.$spaceRef.update((prev) => {\n if (prev === spaceRef) {\n return prev;\n }\n idChanged = prev?.id !== spaceRef?.id;\n typeChanged = prev?.type !== spaceRef?.type;\n if (!idChanged && !typeChanged) {\n return prev;\n }\n if (!spaceRef) {\n return undefined;\n }\n if (equalSpaceRefs(spaceRef, prev)) {\n return prev;\n }\n const keys = Object.keys(spaceRef || {});\n return (keys.length === 1 && keys[0] === 'id') ||\n (keys.length === 2 && keys.includes('id') && keys.includes('type'))\n ? spaceRef\n : spaceRef.type || (prev?.type && prev.id !== spaceRef.id)\n ? { id: spaceRef.id, type: spaceRef.type || prev?.type }\n : { id: spaceRef.id };\n });\n const currentSpaceRef = this.$spaceRef();\n if (currentSpaceRef) {\n // Persist so the login page can restore it after sign-in. No-op unless id+type are known.\n writeCurrentSpace(currentSpaceRef);\n }\n }\n\n private setSpaceContext(spaceContext?: ISpaceContext): void {\n const prevSpace = this.$space();\n this.log(\n `${this.className}:SpaceBaseComponent.setSpaceContext(id=${spaceContext?.id}), previous id=${prevSpace.id}`,\n spaceContext,\n );\n if (!equalSpaceRefs(spaceContext, this.$spaceRef())) {\n this.setSpaceRef(spaceContext);\n }\n if (prevSpace == spaceContext) {\n this.console.warn(\n 'Duplicate call to SpaceBaseComponent.setSpaceContext() with same spaceContext:',\n spaceContext,\n );\n return;\n }\n const idChanged = prevSpace?.id != spaceContext?.id;\n if (idChanged) {\n this.$spaceAccessDenied.set(false);\n }\n const briefChanged = !equalSpaceBriefs(\n prevSpace?.brief,\n spaceContext?.brief,\n );\n const dboChanged = prevSpace?.dbo !== spaceContext?.dbo;\n this.log(\n `${this.className}:SpaceBaseComponent.setSpaceContext(id=${spaceContext?.id}) => idChanged=${idChanged}, briefChanged=${briefChanged}, dtoChanged=${dboChanged}`,\n );\n if (briefChanged) {\n this.$spaceBrief.set(spaceContext?.brief);\n this.spaceBriefChanged.next(spaceContext?.brief);\n }\n if (dboChanged) {\n this.$spaceDbo.set(spaceContext?.dbo);\n this.spaceDboChanged.next(spaceContext?.dbo);\n }\n if (spaceContext) {\n this.spaceChanged.next(spaceContext);\n }\n }\n\n private readonly onSpaceContextChanged = (space: ISpaceContext): void => {\n this.$spaceAccessDenied.set(false);\n const isDboChanged = space.dbo !== this.$space()?.dbo;\n // this.log(\n // \t`${this.className}:SpaceBaseComponent.onSpaceContextChanged() => dtoChanged=${dtoChanged}, space:`,\n // \tspace,\n // );\n if (!space.brief && space.dbo) {\n space = { ...space, brief: space.dbo };\n }\n if (!space.type) {\n if (space.brief?.type) {\n space = { ...space, type: space.brief.type };\n } else if (this.$spaceType()) {\n space = { ...space, type: this.$spaceType() };\n }\n }\n this.setSpaceContext(space);\n if (isDboChanged) {\n this.onSpaceDboChanged();\n }\n // this.log(`${this.className} => loaded team record:`, newTeam);\n // if (newSpace.id === this.spaceContext?.id) {\n // \tthis.setNewSpaceContext({ ...this.spaceContext, ...newSpace });\n // \t// this.spaceContext = ;\n // } else { // Whe should never end up here as should unsubscribe on leaving page or ID change\n // \tthis.errorLogger.logError(`got team record after space context changed: received id=${newSpace.id}, current id=${this.spaceContext?.id}`);\n // }\n };\n\n protected saveNotes(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n // alert('Saving noes is not implemented yet');\n }\n\n protected spacePageUrl(page: string): string {\n return spacePageUrl(this.$space(), page) || '';\n }\n}\n\nexport const spacePageUrl = (\n team?: ISpaceContext,\n page?: string,\n): string | undefined => {\n return team?.id\n ? page\n ? `/space/${team.type}/${team.id}/${page}`\n : `/space/${team.type}/${team.id}`\n : undefined;\n};\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ISpaceModuleItemRef } from '@sneat/dto';
|
|
2
|
+
import { IContactAssignmentRoleOption, IContactRoleAssignment, IContactRoleAssignmentPicker, IContactRoleAssignmentSavePort, ISpaceContext } from '@sneat/space-models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/** No role or commercial policy lives here. Missing product configuration is readonly. */
|
|
5
|
+
export declare class ContactRoleAssignmentComponent {
|
|
6
|
+
readonly target: import("@angular/core").InputSignal<ISpaceModuleItemRef | undefined>;
|
|
7
|
+
readonly space: import("@angular/core").InputSignal<ISpaceContext | undefined>;
|
|
8
|
+
readonly assignments: import("@angular/core").InputSignal<readonly IContactRoleAssignment[]>;
|
|
9
|
+
readonly roles: import("@angular/core").InputSignal<readonly IContactAssignmentRoleOption[]>;
|
|
10
|
+
readonly roleDirection: import("@angular/core").InputSignal<"rolesOfItem" | "rolesToItem" | undefined>;
|
|
11
|
+
readonly readonly: import("@angular/core").InputSignal<boolean>;
|
|
12
|
+
readonly busy: import("@angular/core").InputSignal<boolean>;
|
|
13
|
+
readonly savePort: import("@angular/core").InputSignal<IContactRoleAssignmentSavePort | undefined>;
|
|
14
|
+
readonly picker: import("@angular/core").InputSignal<IContactRoleAssignmentPicker | undefined>;
|
|
15
|
+
readonly saved: import("@angular/core").OutputEmitterRef<readonly IContactRoleAssignment[]>;
|
|
16
|
+
private readonly injectedPicker;
|
|
17
|
+
private baseline;
|
|
18
|
+
private epoch;
|
|
19
|
+
readonly draft: import("@angular/core").WritableSignal<readonly IContactRoleAssignment[]>;
|
|
20
|
+
readonly pending: import("@angular/core").WritableSignal<boolean>;
|
|
21
|
+
readonly error: import("@angular/core").WritableSignal<string>;
|
|
22
|
+
readonly locked: import("@angular/core").Signal<boolean>;
|
|
23
|
+
readonly configured: import("@angular/core").Signal<boolean>;
|
|
24
|
+
readonly canEdit: import("@angular/core").Signal<boolean>;
|
|
25
|
+
readonly changed: import("@angular/core").Signal<boolean>;
|
|
26
|
+
constructor();
|
|
27
|
+
private contextSignature;
|
|
28
|
+
private captureContext;
|
|
29
|
+
key(row: IContactRoleAssignment): string;
|
|
30
|
+
hasUnknownRole(row: IContactRoleAssignment): boolean;
|
|
31
|
+
setRole(row: IContactRoleAssignment, role: string, enabled: boolean): void;
|
|
32
|
+
remove(row: IContactRoleAssignment): void;
|
|
33
|
+
cancel(): void;
|
|
34
|
+
addContact(): Promise<void>;
|
|
35
|
+
private changes;
|
|
36
|
+
save(): Promise<void>;
|
|
37
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ContactRoleAssignmentComponent, never>;
|
|
38
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ContactRoleAssignmentComponent, "sneat-contact-role-assignment", never, { "target": { "alias": "target"; "required": false; "isSignal": true; }; "space": { "alias": "space"; "required": false; "isSignal": true; }; "assignments": { "alias": "assignments"; "required": false; "isSignal": true; }; "roles": { "alias": "roles"; "required": false; "isSignal": true; }; "roleDirection": { "alias": "roleDirection"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "savePort": { "alias": "savePort"; "required": false; "isSignal": true; }; "picker": { "alias": "picker"; "required": false; "isSignal": true; }; }, { "saved": "saved"; }, never, never, true, never>;
|
|
39
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare abstract class SpaceBaseComponent extends SneatBaseComponent impl
|
|
|
15
15
|
protected readonly $spaceRef: import("@angular/core").WritableSignal<ISpaceRef | null | undefined>;
|
|
16
16
|
private readonly $spaceBrief;
|
|
17
17
|
private readonly $spaceDbo;
|
|
18
|
-
|
|
18
|
+
protected readonly $spaceAccessDenied: import("@angular/core").WritableSignal<boolean>;
|
|
19
19
|
protected readonly $spaceNotFound: import("@angular/core").Signal<boolean>;
|
|
20
20
|
protected readonly $spaceID: import("@angular/core").Signal<string | undefined>;
|
|
21
21
|
protected readonly $spaceType: import("@angular/core").Signal<SpaceType | undefined>;
|