@sneat/extension-contactus 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,272 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Component, signal, computed, effect, ChangeDetectionStrategy } from '@angular/core';
3
+ import { IonHeader, IonToolbar, IonButtons, IonBackButton, IonTitle, IonButton, IonIcon, IonMenuButton, IonContent, IonNav } from '@ionic/angular/standalone';
4
+ import { ContactDetailsComponent, PersonTitle, NewContactFormComponent, LocationFormComponent } from '@sneat/extension-contactus-ui';
5
+ import { SneatNavService, emptySpaceRef } from '@sneat/core';
6
+ import { C as ContactService, a as ContactusServicesModule } from './sneat-extension-contactus-sneat-extension-contactus-BkVEPHoJ.mjs';
7
+ import { SpaceServiceModule } from '@sneat/space-services';
8
+ import { ClassName } from '@sneat/ui';
9
+ import { C as ContactBasePage } from './sneat-extension-contactus-contact-base-page-D6vHs5em.mjs';
10
+ export { ContactsPageComponent } from './sneat-extension-contactus-contacts-page.component-BzTRhfPJ.mjs';
11
+ import { FormsModule } from '@angular/forms';
12
+ import { BehaviorSubject } from 'rxjs';
13
+ import { SpaceBaseComponent, SpaceComponentBaseParams } from '@sneat/space-components';
14
+
15
+ class ContactPageComponent extends ContactBasePage {
16
+ contactsService = inject(ContactService);
17
+ sneatNavService = inject(SneatNavService);
18
+ segment = 'contact';
19
+ constructor() {
20
+ super(inject(ContactService));
21
+ this.defaultBackPage = 'contacts';
22
+ }
23
+ // TODO: use or remove
24
+ watchChildContacts() {
25
+ const contactID = this.$contactID();
26
+ if (!contactID) {
27
+ return;
28
+ }
29
+ const space = this.space;
30
+ if (!space) {
31
+ return;
32
+ }
33
+ this.contactsService
34
+ .watchChildContacts(space, contactID)
35
+ .pipe(this.takeUntilDestroyed())
36
+ .subscribe({
37
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
38
+ next: (_children) => {
39
+ // Handle children if needed
40
+ },
41
+ error: this.errorLogger.logErrorHandler('failed to get child contacts'),
42
+ });
43
+ }
44
+ // TODO: use or remove
45
+ saveAddress(save) {
46
+ const spaceID = this.space?.id, contactID = this.$contactID(), address = save.object;
47
+ if (!spaceID || !contactID || !address) {
48
+ save.error('Can not save address without team and contact context');
49
+ return;
50
+ }
51
+ const request = {
52
+ spaceID,
53
+ contactID,
54
+ address,
55
+ };
56
+ this.contactService.updateContact(request).subscribe({
57
+ next: () => save.success(),
58
+ error: save.error,
59
+ });
60
+ }
61
+ deleteContact() {
62
+ const contact = this.$contact();
63
+ if (!contact) {
64
+ return;
65
+ }
66
+ if (!confirm(`Are you sure you want to delete contact "${contact.brief?.title}"?`)) {
67
+ return;
68
+ }
69
+ const request = {
70
+ spaceID: this.space.id,
71
+ contactID: contact.id,
72
+ };
73
+ this.contactsService.deleteContact(request).subscribe({
74
+ next: () => {
75
+ this.sneatNavService.goBack(`/space/${this.space?.id}/contacts`);
76
+ },
77
+ error: this.errorLogger.logErrorHandler('failed to delete contact'),
78
+ });
79
+ }
80
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContactPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
81
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ContactPageComponent, isStandalone: true, selector: "sneat-contact-page", providers: [{ provide: ClassName, useValue: 'ContactPageComponent' }], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if ($contact(); as contact) {\n {{ contact | personTitle }}\n } @else {\n Contact\n }\n </ion-title>\n <ion-buttons slot=\"end\">\n <ion-button\n title=\"Delete contact\"\n color=\"medium\"\n (click)=\"deleteContact()\"\n >\n <ion-icon name=\"trash\" slot=\"start\" />\n </ion-button>\n <ion-menu-button />\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-contact-details [$contact]=\"$contact()\" [$space]=\"$space()\" />\n</ion-content>\n", dependencies: [{ kind: "component", type: ContactDetailsComponent, selector: "sneat-contact-details", inputs: ["$contact"], outputs: ["contactChange"] }, { kind: "ngmodule", type: ContactusServicesModule }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { 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"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonMenuButton, selector: "ion-menu-button", inputs: ["autoHide", "color", "disabled", "menu", "mode", "type"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "pipe", type: PersonTitle, name: "personTitle" }] });
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ContactPageComponent, decorators: [{
84
+ type: Component,
85
+ args: [{ selector: 'sneat-contact-page', imports: [
86
+ ContactDetailsComponent,
87
+ ContactusServicesModule,
88
+ SpaceServiceModule,
89
+ PersonTitle,
90
+ IonHeader,
91
+ IonToolbar,
92
+ IonButtons,
93
+ IonBackButton,
94
+ IonTitle,
95
+ IonButton,
96
+ IonIcon,
97
+ IonMenuButton,
98
+ IonContent,
99
+ ], providers: [{ provide: ClassName, useValue: 'ContactPageComponent' }], template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if ($contact(); as contact) {\n {{ contact | personTitle }}\n } @else {\n Contact\n }\n </ion-title>\n <ion-buttons slot=\"end\">\n <ion-button\n title=\"Delete contact\"\n color=\"medium\"\n (click)=\"deleteContact()\"\n >\n <ion-icon name=\"trash\" slot=\"start\" />\n </ion-button>\n <ion-menu-button />\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-contact-details [$contact]=\"$contact()\" [$space]=\"$space()\" />\n</ion-content>\n" }]
100
+ }], ctorParameters: () => [] });
101
+
102
+ class NewContactPageComponent extends SpaceBaseComponent {
103
+ // @ViewChild('nameInput', { static: true }) nameInput?: IonInput;
104
+ // TODO: relationship is not implemented yet
105
+ $relation = signal(undefined, ...(ngDevMode ? [{ debugName: "$relation" }] : /* istanbul ignore next */ []));
106
+ $contact = signal({
107
+ space: emptySpaceRef,
108
+ dbo: {
109
+ type: 'person',
110
+ gender: 'unknown', // Undefined would indicate "loading" and gender form would be disabled.
111
+ },
112
+ }, ...(ngDevMode ? [{ debugName: "$contact" }] : /* istanbul ignore next */ []));
113
+ $contactGroupID = signal('', ...(ngDevMode ? [{ debugName: "$contactGroupID" }] : /* istanbul ignore next */ []));
114
+ $contactRoleID = signal(undefined, ...(ngDevMode ? [{ debugName: "$contactRoleID" }] : /* istanbul ignore next */ []));
115
+ // Feeds the preselected group/role (from URL query params) into the contact
116
+ // form so the wizard can skip the group/role steps the user already chose.
117
+ // BehaviorSubject replays the latest value to the form when it subscribes.
118
+ selectGroupAndRole$ = new BehaviorSubject(undefined);
119
+ $assetID = signal('', ...(ngDevMode ? [{ debugName: "$assetID" }] : /* istanbul ignore next */ []));
120
+ $contactRole = signal(undefined, ...(ngDevMode ? [{ debugName: "$contactRole" }] : /* istanbul ignore next */ []));
121
+ $contactGroup = signal(undefined, ...(ngDevMode ? [{ debugName: "$contactGroup" }] : /* istanbul ignore next */ []));
122
+ $parentContactID = signal('', ...(ngDevMode ? [{ debugName: "$parentContactID" }] : /* istanbul ignore next */ []));
123
+ $title = computed(() => {
124
+ const contactRoleBrief = this.$contactRole()?.brief;
125
+ return contactRoleBrief
126
+ ? `${contactRoleBrief.emoji} New ${contactRoleBrief.title.toLowerCase()}`
127
+ : 'New contact';
128
+ }, ...(ngDevMode ? [{ debugName: "$title" }] : /* istanbul ignore next */ []));
129
+ $asset = signal(undefined, ...(ngDevMode ? [{ debugName: "$asset" }] : /* istanbul ignore next */ []));
130
+ constructor() {
131
+ super();
132
+ this.defaultBackPage = 'contacts';
133
+ this.$asset.set(window.history.state?.asset);
134
+ // The contact's space drives the create request's spaceID. $contact starts
135
+ // with emptySpaceRef, so fill it once the route's space is loaded; otherwise
136
+ // createContact fails backend validation ("missing required field spaceID").
137
+ effect(() => {
138
+ const space = this.$space();
139
+ if (space?.id) {
140
+ this.$contact.update((c) => c.space?.id === space.id ? c : { ...c, space });
141
+ }
142
+ });
143
+ }
144
+ // onContactTypeChanged(v: ContactRole): void {
145
+ //
146
+ // }
147
+ ngOnInit() {
148
+ super.ngOnInit();
149
+ this.route.queryParamMap
150
+ .pipe(this.takeUntilDestroyed())
151
+ .subscribe(this.onUrlParamsChanged);
152
+ }
153
+ onUrlParamsChanged = (params) => {
154
+ const relation = params.get('relation');
155
+ if (relation) {
156
+ this.$relation.set(relation);
157
+ }
158
+ const contactGroupID = params.get('group');
159
+ if (contactGroupID && contactGroupID !== this.$contactGroupID()) {
160
+ this.$contactGroupID.set(contactGroupID);
161
+ }
162
+ const contactRole = params.get('role');
163
+ if (contactRole && !this.$contactRole()) {
164
+ this.$contactRoleID.set(contactRole);
165
+ }
166
+ const space = this.space;
167
+ if (!space) {
168
+ throw new Error('Space is not defined');
169
+ }
170
+ const assetId = params.get('asset');
171
+ if (assetId && assetId !== this.$assetID()) {
172
+ this.$assetID.set(assetId);
173
+ }
174
+ const parentContactID = params.get('contact');
175
+ if (parentContactID && this.$parentContactID() !== parentContactID) {
176
+ this.$parentContactID.set(parentContactID);
177
+ }
178
+ // Preselect group/role in the form. The form's handler only reads `.id`
179
+ // (it self-loads the brief by ID), so a minimal id-only object is enough;
180
+ // the cast satisfies the brief-required event-args type. `event` is unused
181
+ // by the handler but required by the type.
182
+ if (contactGroupID || contactRole) {
183
+ this.selectGroupAndRole$.next({
184
+ event: new Event('preselect'),
185
+ group: contactGroupID
186
+ ? { id: contactGroupID }
187
+ : undefined,
188
+ role: contactRole
189
+ ? { id: contactRole }
190
+ : undefined,
191
+ });
192
+ }
193
+ };
194
+ onContactChanged(contact) {
195
+ // console.log('onContactChanged', contact);
196
+ this.$contact.set(contact);
197
+ }
198
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewContactPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
199
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: NewContactPageComponent, isStandalone: true, selector: "sneat-new-contact-page", providers: [
200
+ SpaceComponentBaseParams,
201
+ { provide: ClassName, useValue: 'NewContactPageComponent' },
202
+ ], usesInheritance: true, ngImport: i0, template: "<ion-nav />\n\n<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $title() }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-new-contact-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n [selectGroupAndRole$]=\"selectGroupAndRole$\"\n (contactChange)=\"onContactChanged($event)\"\n />\n <!--\t<sneat-new-person-form-->\n <!--\t\t[$fixedGroupID]=\"$contactGroupID()\"-->\n <!--\t\t[$fixedRoleID]=\"$contactRoleID()\"-->\n <!--\t\t[$parentContactID]=\"$parentContactID()\"-->\n <!--\t\t(contactRoleChange)=\"$contactRole.set($event)\"-->\n <!--\t\t(contactGroupChange)=\"$contactGroup.set($event)\"-->\n <!--\t\t(contactChange)=\"$contact.set($event)\"-->\n <!--\t/>-->\n</ion-content>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "ngmodule", type: ContactusServicesModule }, { kind: "component", type: IonNav, selector: "ion-nav" }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: NewContactFormComponent, selector: "sneat-new-contact-form", inputs: ["command", "selectGroupAndRole$", "isInModal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
203
+ }
204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewContactPageComponent, decorators: [{
205
+ type: Component,
206
+ args: [{ imports: [
207
+ FormsModule,
208
+ SpaceServiceModule,
209
+ ContactusServicesModule,
210
+ IonNav,
211
+ IonHeader,
212
+ IonToolbar,
213
+ IonButtons,
214
+ IonBackButton,
215
+ IonTitle,
216
+ IonContent,
217
+ NewContactFormComponent,
218
+ ], providers: [
219
+ SpaceComponentBaseParams,
220
+ { provide: ClassName, useValue: 'NewContactPageComponent' },
221
+ ], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-new-contact-page', template: "<ion-nav />\n\n<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $title() }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-new-contact-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n [selectGroupAndRole$]=\"selectGroupAndRole$\"\n (contactChange)=\"onContactChanged($event)\"\n />\n <!--\t<sneat-new-person-form-->\n <!--\t\t[$fixedGroupID]=\"$contactGroupID()\"-->\n <!--\t\t[$fixedRoleID]=\"$contactRoleID()\"-->\n <!--\t\t[$parentContactID]=\"$parentContactID()\"-->\n <!--\t\t(contactRoleChange)=\"$contactRole.set($event)\"-->\n <!--\t\t(contactGroupChange)=\"$contactGroup.set($event)\"-->\n <!--\t\t(contactChange)=\"$contact.set($event)\"-->\n <!--\t/>-->\n</ion-content>\n" }]
222
+ }], ctorParameters: () => [] });
223
+
224
+ class NewLocationPageComponent extends ContactBasePage {
225
+ newLocation = {
226
+ id: '',
227
+ brief: { type: 'location' },
228
+ // space: this.space,
229
+ };
230
+ constructor() {
231
+ super(inject(ContactService));
232
+ }
233
+ onSpaceDboChanged() {
234
+ super.onSpaceDboChanged();
235
+ // if (this.team?.dto?.countryID && !this.newLocationDto.countryID) {
236
+ // this.newLocationDto = { ...this.newLocationDto, countryID: this.team.dto.countryID };
237
+ // }
238
+ }
239
+ onLocationChanged(contact) {
240
+ this.newLocation = contact;
241
+ }
242
+ onContactCreated(contact) {
243
+ this.newLocation = contact;
244
+ const space = this.space;
245
+ if (!space) {
246
+ throw new Error('Space is not defined');
247
+ }
248
+ const url = this.spacePageUrl(`contact/${this.$contactID()}`);
249
+ if (url) {
250
+ this.navController
251
+ .navigateBack(url)
252
+ .catch(this.errorLogger.logErrorHandler('failed navigate to parent contact'));
253
+ }
254
+ }
255
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewLocationPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
256
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: NewLocationPageComponent, isStandalone: true, selector: "sneat-new-location-page", providers: [{ provide: ClassName, useValue: 'NewLocationPageComponent' }], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-back-button\n slot=\"start\"\n [defaultHref]=\"spacePageUrl('contact/{{contact?.id}}')\"\n />\n <ion-title>\n @if ($contact(); as contact) {\n New location &#64; {{ contact | personTitle }}\n } @else {\n New location\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-location-form\n [$space]=\"$space()\"\n [parentContact]=\"$contact()\"\n [location]=\"newLocation\"\n (locationChange)=\"onLocationChanged($event)\"\n (locationCreated)=\"onContactCreated($event)\"\n />\n</ion-content>\n", dependencies: [{ kind: "component", type: LocationFormComponent, selector: "sneat-location-form", inputs: ["$space", "contactRole", "countryID", "location", "parentContact", "hideSubmitButton", "label", "contactType"], outputs: ["locationChange", "locationCreated"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "pipe", type: PersonTitle, name: "personTitle" }] });
257
+ }
258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: NewLocationPageComponent, decorators: [{
259
+ type: Component,
260
+ args: [{ selector: 'sneat-new-location-page', imports: [
261
+ LocationFormComponent,
262
+ PersonTitle,
263
+ IonHeader,
264
+ IonToolbar,
265
+ IonBackButton,
266
+ IonTitle,
267
+ IonContent,
268
+ ], providers: [{ provide: ClassName, useValue: 'NewLocationPageComponent' }], template: "<ion-header>\n <ion-toolbar color=\"light\">\n <ion-back-button\n slot=\"start\"\n [defaultHref]=\"spacePageUrl('contact/{{contact?.id}}')\"\n />\n <ion-title>\n @if ($contact(); as contact) {\n New location &#64; {{ contact | personTitle }}\n } @else {\n New location\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-location-form\n [$space]=\"$space()\"\n [parentContact]=\"$contact()\"\n [location]=\"newLocation\"\n (locationChange)=\"onLocationChanged($event)\"\n (locationCreated)=\"onContactCreated($event)\"\n />\n</ion-content>\n" }]
269
+ }], ctorParameters: () => [] });
270
+
271
+ export { ContactPageComponent, NewContactPageComponent, NewLocationPageComponent };
272
+ //# sourceMappingURL=sneat-extension-contactus-index-weKgp-3B.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sneat-extension-contactus-index-weKgp-3B.mjs","sources":["../../../../../../libs/extensions/contactus/runtime/src/lib/pages/contact/contact-page.component.ts","../../../../../../libs/extensions/contactus/runtime/src/lib/pages/contact/contact-page.component.html","../../../../../../libs/extensions/contactus/runtime/src/lib/pages/new-contact/new-contact-page.component.ts","../../../../../../libs/extensions/contactus/runtime/src/lib/pages/new-contact/new-contact-page.component.html","../../../../../../libs/extensions/contactus/runtime/src/lib/pages/new-location/new-location-page.component.ts","../../../../../../libs/extensions/contactus/runtime/src/lib/pages/new-location/new-location-page.component.html"],"sourcesContent":["import { Component, inject } from '@angular/core';\nimport {\n IonBackButton,\n IonButton,\n IonButtons,\n IonContent,\n IonHeader,\n IonIcon,\n IonMenuButton,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport { ISaveEvent } from '@sneat/components';\nimport { ContactDetailsComponent, PersonTitle } from '@sneat/extension-contactus-ui';\nimport { SneatNavService } from '@sneat/core';\nimport {\n IAddress,\n IContactRequest,\n IUpdateContactRequest,\n} from '@sneat/extension-contactus-contract';\nimport {\n ContactService,\n ContactusServicesModule,\n} from '../../services';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { ClassName } from '@sneat/ui';\nimport { ContactBasePage } from '../contact-base-page';\n\n@Component({\n selector: 'sneat-contact-page',\n templateUrl: './contact-page.component.html',\n imports: [\n ContactDetailsComponent,\n ContactusServicesModule,\n SpaceServiceModule,\n PersonTitle,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonButton,\n IonIcon,\n IonMenuButton,\n IonContent,\n ],\n providers: [{ provide: ClassName, useValue: 'ContactPageComponent' }],\n})\nexport class ContactPageComponent extends ContactBasePage {\n private readonly contactsService = inject(ContactService);\n private readonly sneatNavService = inject(SneatNavService);\n\n protected segment: 'contact' | 'members' | 'assets' = 'contact';\n\n constructor() {\n super(inject(ContactService));\n this.defaultBackPage = 'contacts';\n }\n\n // TODO: use or remove\n private watchChildContacts(): void {\n const contactID = this.$contactID();\n if (!contactID) {\n return;\n }\n const space = this.space;\n if (!space) {\n return;\n }\n this.contactsService\n .watchChildContacts(space, contactID)\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n next: (_children) => {\n // Handle children if needed\n },\n error: this.errorLogger.logErrorHandler('failed to get child contacts'),\n });\n }\n\n // TODO: use or remove\n protected saveAddress(save: ISaveEvent<IAddress>): void {\n const spaceID = this.space?.id,\n contactID = this.$contactID(),\n address = save.object;\n\n if (!spaceID || !contactID || !address) {\n save.error('Can not save address without team and contact context');\n return;\n }\n\n const request: IUpdateContactRequest = {\n spaceID,\n contactID,\n address,\n };\n\n this.contactService.updateContact(request).subscribe({\n next: () => save.success(),\n error: save.error,\n });\n }\n\n protected deleteContact(): void {\n const contact = this.$contact();\n if (!contact) {\n return;\n }\n if (\n !confirm(\n `Are you sure you want to delete contact \"${contact.brief?.title}\"?`,\n )\n ) {\n return;\n }\n const request: IContactRequest = {\n spaceID: this.space.id,\n contactID: contact.id,\n };\n\n this.contactsService.deleteContact(request).subscribe({\n next: () => {\n this.sneatNavService.goBack(`/space/${this.space?.id}/contacts`);\n },\n error: this.errorLogger.logErrorHandler('failed to delete contact'),\n });\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>\n @if ($contact(); as contact) {\n {{ contact | personTitle }}\n } @else {\n Contact\n }\n </ion-title>\n <ion-buttons slot=\"end\">\n <ion-button\n title=\"Delete contact\"\n color=\"medium\"\n (click)=\"deleteContact()\"\n >\n <ion-icon name=\"trash\" slot=\"start\" />\n </ion-button>\n <ion-menu-button />\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-contact-details [$contact]=\"$contact()\" [$space]=\"$space()\" />\n</ion-content>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n OnInit,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ParamMap } from '@angular/router';\nimport {\n IonBackButton,\n IonButtons,\n IonContent,\n IonHeader,\n IonNav,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport { ContactusServicesModule } from '../../services';\nimport {\n IContactAddEventArgs,\n OptionalContactGroupIdAndBrief,\n OptionalContactRoleIdAndBrief,\n NewContactFormComponent,\n} from '@sneat/extension-contactus-ui';\nimport {\n ContactGroupWithIdAndBrief,\n ContactIdAndDboWithSpaceRef,\n ContactRole,\n ContactToContactRelation,\n IContactRoleWithIdAndBrief,\n NewContactBaseDboAndSpaceRef,\n} from '@sneat/extension-contactus-contract';\nimport { BehaviorSubject } from 'rxjs';\nimport { emptySpaceRef } from '@sneat/core';\nimport {\n SpaceBaseComponent,\n SpaceComponentBaseParams,\n} from '@sneat/space-components';\nimport type { IAssetContext } from '@sneat/extension-assetus-contract';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { ClassName } from '@sneat/ui';\n\n@Component({\n imports: [\n FormsModule,\n SpaceServiceModule,\n ContactusServicesModule,\n IonNav,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n NewContactFormComponent,\n ],\n providers: [\n SpaceComponentBaseParams,\n { provide: ClassName, useValue: 'NewContactPageComponent' },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-new-contact-page',\n templateUrl: './new-contact-page.component.html',\n})\nexport class NewContactPageComponent\n extends SpaceBaseComponent\n implements OnInit\n{\n // @ViewChild('nameInput', { static: true }) nameInput?: IonInput;\n\n // TODO: relationship is not implemented yet\n protected $relation = signal<ContactToContactRelation | undefined>(undefined);\n\n public readonly $contact = signal<NewContactBaseDboAndSpaceRef>({\n space: emptySpaceRef,\n dbo: {\n type: 'person',\n gender: 'unknown', // Undefined would indicate \"loading\" and gender form would be disabled.\n },\n } as ContactIdAndDboWithSpaceRef);\n\n protected readonly $contactGroupID = signal<string>('');\n protected readonly $contactRoleID = signal<ContactRole | undefined>(\n undefined,\n );\n\n // Feeds the preselected group/role (from URL query params) into the contact\n // form so the wizard can skip the group/role steps the user already chose.\n // BehaviorSubject replays the latest value to the form when it subscribes.\n protected readonly selectGroupAndRole$ = new BehaviorSubject<\n IContactAddEventArgs | undefined\n >(undefined);\n protected readonly $assetID = signal<string>('');\n\n protected readonly $contactRole =\n signal<OptionalContactRoleIdAndBrief>(undefined);\n protected readonly $contactGroup =\n signal<OptionalContactGroupIdAndBrief>(undefined);\n\n protected readonly $parentContactID = signal<string>('');\n\n protected readonly $title = computed(() => {\n const contactRoleBrief = this.$contactRole()?.brief;\n return contactRoleBrief\n ? `${contactRoleBrief.emoji} New ${contactRoleBrief.title.toLowerCase()}`\n : 'New contact';\n });\n\n protected readonly $asset = signal<IAssetContext | undefined>(undefined);\n\n constructor() {\n super();\n this.defaultBackPage = 'contacts';\n this.$asset.set(window.history.state?.asset as IAssetContext);\n\n // The contact's space drives the create request's spaceID. $contact starts\n // with emptySpaceRef, so fill it once the route's space is loaded; otherwise\n // createContact fails backend validation (\"missing required field spaceID\").\n effect(() => {\n const space = this.$space();\n if (space?.id) {\n this.$contact.update((c) =>\n c.space?.id === space.id ? c : { ...c, space },\n );\n }\n });\n }\n\n // onContactTypeChanged(v: ContactRole): void {\n //\n // }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.route.queryParamMap\n .pipe(this.takeUntilDestroyed())\n .subscribe(this.onUrlParamsChanged);\n }\n\n private readonly onUrlParamsChanged = (params: ParamMap): void => {\n const relation = params.get('relation');\n if (relation) {\n this.$relation.set(relation as ContactToContactRelation);\n }\n const contactGroupID = params.get('group');\n if (contactGroupID && contactGroupID !== this.$contactGroupID()) {\n this.$contactGroupID.set(contactGroupID);\n }\n const contactRole = params.get('role');\n\n if (contactRole && !this.$contactRole()) {\n this.$contactRoleID.set(contactRole as ContactRole);\n }\n\n const space = this.space;\n if (!space) {\n throw new Error('Space is not defined');\n }\n\n const assetId = params.get('asset');\n if (assetId && assetId !== this.$assetID()) {\n this.$assetID.set(assetId);\n }\n const parentContactID = params.get('contact');\n if (parentContactID && this.$parentContactID() !== parentContactID) {\n this.$parentContactID.set(parentContactID);\n }\n\n // Preselect group/role in the form. The form's handler only reads `.id`\n // (it self-loads the brief by ID), so a minimal id-only object is enough;\n // the cast satisfies the brief-required event-args type. `event` is unused\n // by the handler but required by the type.\n if (contactGroupID || contactRole) {\n this.selectGroupAndRole$.next({\n event: new Event('preselect'),\n group: contactGroupID\n ? ({ id: contactGroupID } as ContactGroupWithIdAndBrief)\n : undefined,\n role: contactRole\n ? ({ id: contactRole } as IContactRoleWithIdAndBrief)\n : undefined,\n });\n }\n };\n\n protected onContactChanged(contact: NewContactBaseDboAndSpaceRef): void {\n // console.log('onContactChanged', contact);\n this.$contact.set(contact);\n }\n}\n","<ion-nav />\n\n<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <ion-title>{{ $title() }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-new-contact-form\n [$space]=\"$space()\"\n [$contact]=\"$contact()\"\n [selectGroupAndRole$]=\"selectGroupAndRole$\"\n (contactChange)=\"onContactChanged($event)\"\n />\n <!--\t<sneat-new-person-form-->\n <!--\t\t[$fixedGroupID]=\"$contactGroupID()\"-->\n <!--\t\t[$fixedRoleID]=\"$contactRoleID()\"-->\n <!--\t\t[$parentContactID]=\"$parentContactID()\"-->\n <!--\t\t(contactRoleChange)=\"$contactRole.set($event)\"-->\n <!--\t\t(contactGroupChange)=\"$contactGroup.set($event)\"-->\n <!--\t\t(contactChange)=\"$contact.set($event)\"-->\n <!--\t/>-->\n</ion-content>\n","import { Component, inject } from '@angular/core';\nimport {\n IonBackButton,\n IonContent,\n IonHeader,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport { PersonTitle } from '@sneat/extension-contactus-ui';\nimport { ContactService } from '../../services';\nimport { LocationFormComponent } from '@sneat/extension-contactus-ui';\nimport { IContactWithOptionalDbo } from '@sneat/extension-contactus-contract';\nimport { ClassName } from '@sneat/ui';\nimport { ContactBasePage } from '../contact-base-page';\n\n@Component({\n selector: 'sneat-new-location-page',\n templateUrl: './new-location-page.component.html',\n imports: [\n LocationFormComponent,\n PersonTitle,\n IonHeader,\n IonToolbar,\n IonBackButton,\n IonTitle,\n IonContent,\n ],\n providers: [{ provide: ClassName, useValue: 'NewLocationPageComponent' }],\n})\nexport class NewLocationPageComponent extends ContactBasePage {\n newLocation: IContactWithOptionalDbo = {\n id: '',\n brief: { type: 'location' },\n // space: this.space,\n };\n\n public constructor() {\n super(inject(ContactService));\n }\n\n protected override onSpaceDboChanged() {\n super.onSpaceDboChanged();\n // if (this.team?.dto?.countryID && !this.newLocationDto.countryID) {\n // \tthis.newLocationDto = { ...this.newLocationDto, countryID: this.team.dto.countryID };\n // }\n }\n\n onLocationChanged(contact: IContactWithOptionalDbo): void {\n this.newLocation = contact;\n }\n\n onContactCreated(contact: IContactWithOptionalDbo): void {\n this.newLocation = contact;\n const space = this.space;\n if (!space) {\n throw new Error('Space is not defined');\n }\n const url = this.spacePageUrl(`contact/${this.$contactID()}`);\n if (url) {\n this.navController\n .navigateBack(url)\n .catch(\n this.errorLogger.logErrorHandler('failed navigate to parent contact'),\n );\n }\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-back-button\n slot=\"start\"\n [defaultHref]=\"spacePageUrl('contact/{{contact?.id}}')\"\n />\n <ion-title>\n @if ($contact(); as contact) {\n New location &#64; {{ contact | personTitle }}\n } @else {\n New location\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n <sneat-location-form\n [$space]=\"$space()\"\n [parentContact]=\"$contact()\"\n [location]=\"newLocation\"\n (locationChange)=\"onLocationChanged($event)\"\n (locationCreated)=\"onContactCreated($event)\"\n />\n</ion-content>\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import * as i1 from '@angular/forms';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { IonHeader, IonToolbar, IonButtons, IonBackButton, IonMenuButton, IonContent, IonSegment, IonSegmentButton, IonLabel, IonCard, IonItemGroup, IonItemDivider, IonIcon, IonBadge, IonItem, IonFooter, IonButton } from '@ionic/angular/standalone';
5
+ import { b as ContactusSpaceService, a as ContactusServicesModule } from './sneat-extension-contactus-sneat-extension-contactus-BkVEPHoJ.mjs';
6
+ import { ContactusModuleBaseComponent, FamilyMembersComponent } from '@sneat/extension-contactus-ui';
7
+ import { isSpaceSupportsMemberGroups } from '@sneat/dto';
8
+ import { SpacePageTitleComponent, SpaceComponentBaseParams } from '@sneat/space-components';
9
+ import { SpaceServiceModule } from '@sneat/space-services';
10
+ import { ClassName } from '@sneat/ui';
11
+ import * as i0 from '@angular/core';
12
+ import { inject, Component } from '@angular/core';
13
+
14
+ class MembersBasePage extends ContactusModuleBaseComponent {
15
+ members;
16
+ // protected setCurrentUser(dto: IDtoUser) {
17
+ // this.currentUserDto = dto;
18
+ // }
19
+ constructor(contactusTeamService) {
20
+ super(contactusTeamService);
21
+ // this.userService.currentUserLoaded.subscribe(user => this.setCurrentUser(user));
22
+ }
23
+ goNewMember = () => {
24
+ // TODO: use it?
25
+ this.navigateForwardToSpacePage('new-member').catch(this.logErrorHandler('failed to navigate to new member page'));
26
+ };
27
+ // goMember = (member: IMemberContext, page?: MemberPages) => {
28
+ // this.navigateForwardToSpacePage(
29
+ // (page || 'member') + '/' + member.id,
30
+ // ).catch(this.logErrorHandler('failed to navigate to team member page'));
31
+ // };
32
+ //
33
+ // goContact = (id: string, event: Event) => {
34
+ // event.stopPropagation();
35
+ // this.navigateForwardToSpacePage(`contact/${id}`)
36
+ // .catch(this.logErrorHandler('failed to navigate to contact page'));
37
+ // };
38
+ get supportsMemberGroups() {
39
+ return (!!this.space?.brief && isSpaceSupportsMemberGroups(this.space.brief.type));
40
+ }
41
+ }
42
+
43
+ class MembersPageComponent extends MembersBasePage {
44
+ // private readonly memberGroupService = inject(MemberGroupService);
45
+ memberGroups;
46
+ // public loadingStubs?: number[];
47
+ segment = 'all';
48
+ // public listMode: 'list' | 'cards' = 'list';
49
+ // public membersByGroupId: { [id: string]: IMemberContext[] } = {};
50
+ memberType = 'member';
51
+ constructor() {
52
+ const contactusTeamService = inject(ContactusSpaceService);
53
+ super(contactusTeamService);
54
+ }
55
+ goGroup(memberGroup) {
56
+ this.navigateForwardToSpacePage(`group/${memberGroup.id}`, {
57
+ state: { memberGroup },
58
+ }).catch(this.logErrorHandler('failed to navigate to members group page'));
59
+ }
60
+ goNewMemberPage(group) {
61
+ const queryParams = group
62
+ ? { group: group.id }
63
+ : undefined;
64
+ this.navigateForwardToSpacePage('new-member', {
65
+ queryParams,
66
+ state: { group },
67
+ }).catch(this.logErrorHandler('failed to navigate to new member page with age parameter'));
68
+ }
69
+ goNew() {
70
+ switch (this.segment) {
71
+ case 'all':
72
+ this.goNewMemberPage();
73
+ break;
74
+ case 'groups':
75
+ this.navigateForwardToSpacePage('new-group').catch(this.logErrorHandler('failed to navigate to new group page'));
76
+ break;
77
+ default:
78
+ alert(`Unknown segment: ${this.segment}`);
79
+ return;
80
+ }
81
+ }
82
+ onSpaceDboChanged() {
83
+ super.onSpaceDboChanged();
84
+ if (!this.space) {
85
+ throw new Error('!this.commune');
86
+ }
87
+ // console.log(`MembersPageComponent.onSpaceDboChanged()`);
88
+ // if (this.team?.dto?.numberOf?.members) {
89
+ // this.loadingStubs = Array(this.team?.dto?.numberOf?.members).fill(1);
90
+ // }
91
+ // if (!isNaN(this.prevMembersCount) && this.prevMembersCount != this.commune.numberOf.members) {
92
+ // this.loadData();
93
+ // }
94
+ this.loadData('onSpaceDboChanged');
95
+ // this.prevMembersCount = this.team?.dto?.numberOf?.members || 0;
96
+ }
97
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
98
+ loadData(_source) {
99
+ // console.log(`MembersPageComponent.loadData(source=${source})`);
100
+ // this.unsubscribe();
101
+ const space = this.space;
102
+ if (!space) {
103
+ throw new Error('!this.team');
104
+ }
105
+ // this.noGroupMembers = this.team?.brief && isTeamSupportsMemberGroups(this.team.brief.type) ? [] : undefined;
106
+ // const contactusTeam = this.teamModuleDto;
107
+ //
108
+ // if (contactusTeam?.dto?.contacts) {
109
+ // this.processContactusSpaceDbo(contactusTeam.dto);
110
+ // } else {
111
+ // this.contactService
112
+ // .watchContactsWithRole(space, 'space_member') // TODO: use constant
113
+ // .pipe(takeUntil(this.spaceIDChanged$))
114
+ // .subscribe({
115
+ // next: (members) => {
116
+ // console.log(
117
+ // `MembersPageComponent.loadData(source=${source}), members =>`,
118
+ // members,
119
+ // );
120
+ // if (members?.length) {
121
+ // // TODO: deep equal
122
+ // members.forEach((m) => {
123
+ // if (m.id) {
124
+ // if (m.dto?.related) {
125
+ // // this.contactsByMember[m.id] = zipMapBriefsWithIDs(
126
+ // // m.dto.relatedContacts,
127
+ // // );
128
+ // } else if (this.contactsByMember[m.id]) {
129
+ // delete this.contactsByMember[m.id];
130
+ // }
131
+ // }
132
+ // });
133
+ // this.members = members;
134
+ // this.processMembers();
135
+ // }
136
+ // },
137
+ // });
138
+ // }
139
+ if (space.type && isSpaceSupportsMemberGroups(space.type)) {
140
+ throw new Error('not implemented yet due to refactoring');
141
+ // this.contactService.watchContactsByRole(team)
142
+ // .subscribe(memberGroups => {
143
+ // if (memberGroups && (!this.memberGroups || memberGroups.length !== this.memberGroups.length)) { // TODO: deep equal
144
+ // this.memberGroups = memberGroups;
145
+ // }
146
+ // });
147
+ }
148
+ }
149
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MembersPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MembersPageComponent, isStandalone: true, selector: "sneat-members-page", providers: [
151
+ { provide: ClassName, useValue: 'MembersPageComponent' },
152
+ SpaceComponentBaseParams,
153
+ ], usesInheritance: true, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button with-end-buttons\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <sneat-space-page-title\n [space]=\"space\"\n generalTitle=\"Members\"\n icon=\"\uD83D\uDC6A\"\n [titlesBySpaceType]=\"{\n family: 'Family members',\n }\"\n />\n <ion-buttons slot=\"end\">\n <ion-menu-button menu=\"mainMenu\" />\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n @if (supportsMemberGroups) {\n <div class=\"segment\">\n <ion-segment [(ngModel)]=\"segment\">\n <ion-segment-button value=\"all\">\n <ion-label>All</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"groups\">\n <ion-label>\n @if (space.type === \"cohabit\") {\n By room\n } @else {\n By group\n }\n </ion-label>\n </ion-segment-button>\n </ion-segment>\n </div>\n }\n\n <!--\t<div class=\"segment\" *ngIf=\"spaceType === 'family'\">-->\n <!--\t\t<ion-segment [(ngModel)]=\"listMode\">-->\n <!--\t\t\t<ion-segment-button value=\"list\">List</ion-segment-button>-->\n <!--\t\t\t<ion-segment-button value=\"cards\">Cards</ion-segment-button>-->\n <!--\t\t</ion-segment>-->\n <!--\t</div>-->\n\n <!--\t<ion-list *ngIf=\"segment === 'all' && teamType === 'family'\">-->\n <!--\t\t<sneat-members-list *ngIf=\"adults\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[team]=\"team\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[allMembers]=\"members\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[contactsByMember]=\"contactsByMember\"-->\n <!--\t\t></sneat-members-list>-->\n <!--\t</ion-list>-->\n\n @if (segment === \"all\" && $spaceType() === \"family\") {\n <ion-card>\n <sneat-family-members\n [$space]=\"$space()\"\n [contactusSpaceDbo]=\"spaceModuleDbo$ | async\"\n (addMember)=\"goNewMemberPage($event)\"\n />\n </ion-card>\n }\n\n @if (segment === \"groups\") {\n @if ($spaceType() === \"cohabit\") {\n @if (memberGroups) {\n @for (group of memberGroups; track group.id) {\n <ion-item-group>\n <ion-item-divider>\n <ion-icon name=\"people\" style=\"margin-right: 0.5em\" />\n <ion-label>\n {{ group.brief?.title }}\n </ion-label>\n @if (group.dbo?.numberOf?.members) {\n <ion-badge color=\"light\">\n {{ group.dbo?.numberOf?.members }} members\n </ion-badge>\n }\n </ion-item-divider>\n <!--\t\t\t\t\t<ng-container *ngIf=\"membersByGroupId[group.id]\">-->\n <!--\t\t\t\t\t\t<sneat-members-list [members]=\"this.membersByGroupId[group.id]\"-->\n <!--\t\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t\t</ng-container>-->\n </ion-item-group>\n }\n\n <!--\t\t\t\t<ng-container *ngIf=\"noGroupMembers && noGroupMembers.length\">-->\n <!--\t\t\t\t\t<ion-item-divider>-->\n <!--\t\t\t\t\t\t<ion-label>No group members</ion-label>-->\n <!--\t\t\t\t\t</ion-item-divider>-->\n <!--\t\t\t\t\t<sneat-members-list [members]=\"noGroupMembers\"-->\n <!--\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t</ng-container>-->\n }\n } @else if (memberGroups) {\n @for (group of memberGroups; track group.id) {\n <ion-item-group>\n <ion-item button=\"button\" (click)=\"goGroup(group)\">\n <ion-icon name=\"people\" style=\"margin-right: 0.5em\" />\n <ion-label>\n {{ group.brief?.title }}\n </ion-label>\n @if (group.dbo?.numberOf?.members) {\n <ion-badge color=\"light\">\n {{ group?.dbo?.numberOf?.members }} members\n </ion-badge>\n }\n </ion-item>\n </ion-item-group>\n }\n <!--\t\t\t\t<ng-container *ngIf=\"noGroupMembers && noGroupMembers.length\">-->\n <!--\t\t\t\t\t<ion-item-divider>-->\n <!--\t\t\t\t\t\t<ion-label>No group members</ion-label>-->\n <!--\t\t\t\t\t\t<ion-badge color=\"light\" slot=\"end\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t style=\"margin-right: 1em\">{{noGroupMembers.length}}</ion-badge>-->\n <!--\t\t\t\t\t</ion-item-divider>-->\n <!--\t\t\t\t\t<sneat-members-list-->\n <!--\t\t\t\t\t\t[members]=\"noGroupMembers\"-->\n <!--\t\t\t\t\t\t[contactsByMember]=\"contactsByMember\"-->\n <!--\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t</ng-container>-->\n }\n }\n</ion-content>\n\n<ion-footer>\n <ion-toolbar color=\"light\">\n @if (space.dbo) {\n @switch (segment) {\n @case (\"all\") {\n <ion-label>\n <b>Total</b>:\n <!--\t\t\t{{ team.dto.numberOf?.members ?? 0 }}-->\n <!--\t\t\t{{ team.dto.numberOf?.members === 1 ? \"member\" : \"members\" }}-->\n </ion-label>\n }\n @case (\"groups\") {\n <ion-label>\n <b>Total</b>:\n <!--\t\t\t{{ team.dto.numberOf?.memberGroups || 0 }}-->\n <!--\t\t\t{{ team.dto.numberOf?.memberGroups === 1 ? \"group\" : \"groups\" }}-->\n </ion-label>\n }\n }\n } @else {\n <ion-label>Loading...</ion-label>\n }\n\n <ion-buttons slot=\"end\">\n <ion-button\n size=\"small\"\n color=\"primary\"\n [disabled]=\"!space.brief\"\n (click)=\"goNew()\"\n [title]=\"segment === 'groups' ? 'Add new group' : 'Add new member'\"\n >\n <ion-icon name=\"add\" />\n <ion-label>Add</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-footer>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SpacePageTitleComponent, selector: "sneat-space-page-title", inputs: ["icon", "generalTitle", "space", "titlesBySpaceType"] }, { kind: "ngmodule", type: ContactusServicesModule }, { kind: "component", type: FamilyMembersComponent, selector: "sneat-family-members", inputs: ["contactusSpaceDbo"], outputs: ["addMember"] }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonBackButton, selector: "ion-back-button" }, { kind: "component", type: IonMenuButton, selector: "ion-menu-button", inputs: ["autoHide", "color", "disabled", "menu", "mode", "type"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonSegment, selector: "ion-segment", inputs: ["color", "disabled", "mode", "scrollable", "selectOnFocus", "swipeGesture", "value"] }, { kind: "component", type: IonSegmentButton, selector: "ion-segment-button", inputs: ["contentId", "disabled", "layout", "mode", "type", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItemGroup, selector: "ion-item-group" }, { kind: "component", type: IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { 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: IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { 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"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
154
+ }
155
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MembersPageComponent, decorators: [{
156
+ type: Component,
157
+ args: [{ imports: [
158
+ FormsModule,
159
+ SpacePageTitleComponent,
160
+ ContactusServicesModule,
161
+ FamilyMembersComponent,
162
+ SpaceServiceModule,
163
+ IonHeader,
164
+ IonToolbar,
165
+ IonButtons,
166
+ IonBackButton,
167
+ IonMenuButton,
168
+ IonContent,
169
+ IonSegment,
170
+ IonSegmentButton,
171
+ IonLabel,
172
+ IonCard,
173
+ AsyncPipe,
174
+ IonItemGroup,
175
+ IonItemDivider,
176
+ IonIcon,
177
+ IonBadge,
178
+ IonItem,
179
+ IonFooter,
180
+ IonButton,
181
+ ], providers: [
182
+ { provide: ClassName, useValue: 'MembersPageComponent' },
183
+ SpaceComponentBaseParams,
184
+ ], selector: 'sneat-members-page', template: "<ion-header>\n <ion-toolbar color=\"light\" class=\"with-back-button with-end-buttons\">\n <ion-buttons slot=\"start\">\n <ion-back-button [defaultHref]=\"$defaultBackUrl()\" />\n </ion-buttons>\n <sneat-space-page-title\n [space]=\"space\"\n generalTitle=\"Members\"\n icon=\"\uD83D\uDC6A\"\n [titlesBySpaceType]=\"{\n family: 'Family members',\n }\"\n />\n <ion-buttons slot=\"end\">\n <ion-menu-button menu=\"mainMenu\" />\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"cardy\">\n @if (supportsMemberGroups) {\n <div class=\"segment\">\n <ion-segment [(ngModel)]=\"segment\">\n <ion-segment-button value=\"all\">\n <ion-label>All</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"groups\">\n <ion-label>\n @if (space.type === \"cohabit\") {\n By room\n } @else {\n By group\n }\n </ion-label>\n </ion-segment-button>\n </ion-segment>\n </div>\n }\n\n <!--\t<div class=\"segment\" *ngIf=\"spaceType === 'family'\">-->\n <!--\t\t<ion-segment [(ngModel)]=\"listMode\">-->\n <!--\t\t\t<ion-segment-button value=\"list\">List</ion-segment-button>-->\n <!--\t\t\t<ion-segment-button value=\"cards\">Cards</ion-segment-button>-->\n <!--\t\t</ion-segment>-->\n <!--\t</div>-->\n\n <!--\t<ion-list *ngIf=\"segment === 'all' && teamType === 'family'\">-->\n <!--\t\t<sneat-members-list *ngIf=\"adults\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[team]=\"team\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[allMembers]=\"members\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t\t[contactsByMember]=\"contactsByMember\"-->\n <!--\t\t></sneat-members-list>-->\n <!--\t</ion-list>-->\n\n @if (segment === \"all\" && $spaceType() === \"family\") {\n <ion-card>\n <sneat-family-members\n [$space]=\"$space()\"\n [contactusSpaceDbo]=\"spaceModuleDbo$ | async\"\n (addMember)=\"goNewMemberPage($event)\"\n />\n </ion-card>\n }\n\n @if (segment === \"groups\") {\n @if ($spaceType() === \"cohabit\") {\n @if (memberGroups) {\n @for (group of memberGroups; track group.id) {\n <ion-item-group>\n <ion-item-divider>\n <ion-icon name=\"people\" style=\"margin-right: 0.5em\" />\n <ion-label>\n {{ group.brief?.title }}\n </ion-label>\n @if (group.dbo?.numberOf?.members) {\n <ion-badge color=\"light\">\n {{ group.dbo?.numberOf?.members }} members\n </ion-badge>\n }\n </ion-item-divider>\n <!--\t\t\t\t\t<ng-container *ngIf=\"membersByGroupId[group.id]\">-->\n <!--\t\t\t\t\t\t<sneat-members-list [members]=\"this.membersByGroupId[group.id]\"-->\n <!--\t\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t\t</ng-container>-->\n </ion-item-group>\n }\n\n <!--\t\t\t\t<ng-container *ngIf=\"noGroupMembers && noGroupMembers.length\">-->\n <!--\t\t\t\t\t<ion-item-divider>-->\n <!--\t\t\t\t\t\t<ion-label>No group members</ion-label>-->\n <!--\t\t\t\t\t</ion-item-divider>-->\n <!--\t\t\t\t\t<sneat-members-list [members]=\"noGroupMembers\"-->\n <!--\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t</ng-container>-->\n }\n } @else if (memberGroups) {\n @for (group of memberGroups; track group.id) {\n <ion-item-group>\n <ion-item button=\"button\" (click)=\"goGroup(group)\">\n <ion-icon name=\"people\" style=\"margin-right: 0.5em\" />\n <ion-label>\n {{ group.brief?.title }}\n </ion-label>\n @if (group.dbo?.numberOf?.members) {\n <ion-badge color=\"light\">\n {{ group?.dbo?.numberOf?.members }} members\n </ion-badge>\n }\n </ion-item>\n </ion-item-group>\n }\n <!--\t\t\t\t<ng-container *ngIf=\"noGroupMembers && noGroupMembers.length\">-->\n <!--\t\t\t\t\t<ion-item-divider>-->\n <!--\t\t\t\t\t\t<ion-label>No group members</ion-label>-->\n <!--\t\t\t\t\t\t<ion-badge color=\"light\" slot=\"end\"-->\n <!--\t\t\t\t\t\t\t\t\t\t\t style=\"margin-right: 1em\">{{noGroupMembers.length}}</ion-badge>-->\n <!--\t\t\t\t\t</ion-item-divider>-->\n <!--\t\t\t\t\t<sneat-members-list-->\n <!--\t\t\t\t\t\t[members]=\"noGroupMembers\"-->\n <!--\t\t\t\t\t\t[contactsByMember]=\"contactsByMember\"-->\n <!--\t\t\t\t\t></sneat-members-list>-->\n <!--\t\t\t\t</ng-container>-->\n }\n }\n</ion-content>\n\n<ion-footer>\n <ion-toolbar color=\"light\">\n @if (space.dbo) {\n @switch (segment) {\n @case (\"all\") {\n <ion-label>\n <b>Total</b>:\n <!--\t\t\t{{ team.dto.numberOf?.members ?? 0 }}-->\n <!--\t\t\t{{ team.dto.numberOf?.members === 1 ? \"member\" : \"members\" }}-->\n </ion-label>\n }\n @case (\"groups\") {\n <ion-label>\n <b>Total</b>:\n <!--\t\t\t{{ team.dto.numberOf?.memberGroups || 0 }}-->\n <!--\t\t\t{{ team.dto.numberOf?.memberGroups === 1 ? \"group\" : \"groups\" }}-->\n </ion-label>\n }\n }\n } @else {\n <ion-label>Loading...</ion-label>\n }\n\n <ion-buttons slot=\"end\">\n <ion-button\n size=\"small\"\n color=\"primary\"\n [disabled]=\"!space.brief\"\n (click)=\"goNew()\"\n [title]=\"segment === 'groups' ? 'Add new group' : 'Add new member'\"\n >\n <ion-icon name=\"add\" />\n <ion-label>Add</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-footer>\n" }]
185
+ }], ctorParameters: () => [] });
186
+
187
+ export { MembersPageComponent };
188
+ //# sourceMappingURL=sneat-extension-contactus-members-page.component-DPXZ6eSl.mjs.map