@sneat/space-components 0.27.5 → 0.27.6
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/index.js +1 -0
- package/esm2022/lib/index.js.map +1 -1
- package/esm2022/lib/space-base-component.directive.js +31 -9
- package/esm2022/lib/space-base-component.directive.js.map +1 -1
- package/esm2022/lib/space-extension-links/index.js +3 -0
- package/esm2022/lib/space-extension-links/index.js.map +1 -0
- package/esm2022/lib/space-extension-links/space-extension-links.component.js +52 -0
- package/esm2022/lib/space-extension-links/space-extension-links.component.js.map +1 -0
- package/esm2022/lib/space-extension-links/space-extension-nav-item.js +6 -0
- package/esm2022/lib/space-extension-links/space-extension-nav-item.js.map +1 -0
- package/esm2022/lib/space-menu/space-menu.component.js +7 -6
- package/esm2022/lib/space-menu/space-menu.component.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/space-base-component.directive.d.ts +3 -1
- package/lib/space-extension-links/index.d.ts +2 -0
- package/lib/space-extension-links/space-extension-links.component.d.ts +20 -0
- package/lib/space-extension-links/space-extension-nav-item.d.ts +20 -0
- package/package.json +1 -1
- package/tsconfig.lib.prod.tsbuildinfo +1 -1
package/esm2022/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './avatar/avatar.component';
|
|
2
2
|
export * from './space-menu';
|
|
3
|
+
export * from './space-extension-links';
|
|
3
4
|
export * from './spaces-menu';
|
|
4
5
|
export * from './space-page-title/space-page-title.component';
|
|
5
6
|
export * from './space-page-base-component.service';
|
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,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 './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,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-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,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
2
|
+
import { computed, Directive, effect, inject, PLATFORM_ID, signal, } from '@angular/core';
|
|
2
3
|
import { ActivatedRoute } from '@angular/router';
|
|
3
4
|
import { NavController } from '@ionic/angular';
|
|
4
5
|
import { equalSpaceRefs, writeCurrentSpace, } from '@sneat/core';
|
|
@@ -34,6 +35,10 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
34
35
|
...(ngDevMode ? [{ debugName: "$spaceBrief" }] : /* istanbul ignore next */ []));
|
|
35
36
|
this.$spaceDbo = signal(undefined, /* @ts-ignore */
|
|
36
37
|
...(ngDevMode ? [{ debugName: "$spaceDbo" }] : /* istanbul ignore next */ []));
|
|
38
|
+
this.$spaceAccessDenied = signal(false, /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "$spaceAccessDenied" }] : /* istanbul ignore next */ []));
|
|
40
|
+
this.$spaceNotFound = computed(() => this.$spaceDbo() === null || this.$spaceAccessDenied(), /* @ts-ignore */
|
|
41
|
+
...(ngDevMode ? [{ debugName: "$spaceNotFound" }] : /* istanbul ignore next */ []));
|
|
37
42
|
// private readonly $_spaceID = signal<string | undefined>(undefined);
|
|
38
43
|
// protected readonly $spaceID = this.$_spaceID.asReadonly();
|
|
39
44
|
this.$spaceID = computed(() => this.$spaceRef()?.id, /* @ts-ignore */
|
|
@@ -52,7 +57,6 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
52
57
|
...(ngDevMode ? [{ debugName: "$space" }] : /* istanbul ignore next */ []));
|
|
53
58
|
this.spaceIDChanged = new Subject();
|
|
54
59
|
this.spaceTypeChanged = new Subject();
|
|
55
|
-
this.noPermissions = false;
|
|
56
60
|
this.spaceBriefChanged = new Subject();
|
|
57
61
|
this.spaceDboChanged = new Subject();
|
|
58
62
|
// protected spaceContext?: ISpaceContext;
|
|
@@ -89,6 +93,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
89
93
|
...(ngDevMode ? [{ debugName: "$defaultBackUrl" }] : /* istanbul ignore next */ []));
|
|
90
94
|
this.route = inject(ActivatedRoute);
|
|
91
95
|
this.spaceParams = inject(SpaceComponentBaseParams);
|
|
96
|
+
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
92
97
|
this.onSpaceIdChangedInUrl = (space) => {
|
|
93
98
|
const prevSpace = this.$space();
|
|
94
99
|
this.log(`${this.className}:SpaceBaseComponent.onSpaceIdChangedInUrl(): prevSpace.id: ${prevSpace?.id} => ${space?.id}`);
|
|
@@ -102,6 +107,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
102
107
|
this.setSpaceContext(space);
|
|
103
108
|
};
|
|
104
109
|
this.onSpaceContextChanged = (space) => {
|
|
110
|
+
this.$spaceAccessDenied.set(false);
|
|
105
111
|
const isDboChanged = space.dbo !== this.$space()?.dbo;
|
|
106
112
|
// this.log(
|
|
107
113
|
// `${this.className}:SpaceBaseComponent.onSpaceContextChanged() => dtoChanged=${dtoChanged}, space:`,
|
|
@@ -114,6 +120,9 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
114
120
|
if (space.brief?.type) {
|
|
115
121
|
space = { ...space, type: space.brief.type };
|
|
116
122
|
}
|
|
123
|
+
else if (this.$spaceType()) {
|
|
124
|
+
space = { ...space, type: this.$spaceType() };
|
|
125
|
+
}
|
|
117
126
|
}
|
|
118
127
|
this.setSpaceContext(space);
|
|
119
128
|
if (isDboChanged) {
|
|
@@ -142,7 +151,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
142
151
|
this.unsubscribe('$spaceID() changed');
|
|
143
152
|
this.$spaceBrief.set(undefined);
|
|
144
153
|
this.$spaceDbo.set(undefined);
|
|
145
|
-
if (spaceID) {
|
|
154
|
+
if (spaceID && this.isBrowser) {
|
|
146
155
|
setTimeout(() => this.subscribeForSpaceChanges(spaceID), 1);
|
|
147
156
|
}
|
|
148
157
|
});
|
|
@@ -180,7 +189,7 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
180
189
|
onUserIdChanged() {
|
|
181
190
|
if (!this.currentUserId) {
|
|
182
191
|
this.subs.unsubscribe();
|
|
183
|
-
if (this.space
|
|
192
|
+
if (this.space.brief || this.space.dbo) {
|
|
184
193
|
this.setSpaceContext({
|
|
185
194
|
...this.space,
|
|
186
195
|
brief: undefined,
|
|
@@ -234,14 +243,20 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
234
243
|
this.spaceService
|
|
235
244
|
.watchSpace(spaceID)
|
|
236
245
|
.pipe(this.takeUntilDestroyed(), takeUntil(this.spaceIDChanged$), map((space) => {
|
|
237
|
-
return {
|
|
246
|
+
return {
|
|
247
|
+
...space,
|
|
248
|
+
type: space.dbo?.type || space.type || this.$spaceType(),
|
|
249
|
+
};
|
|
238
250
|
}))
|
|
239
251
|
.subscribe({
|
|
240
252
|
next: this.onSpaceContextChanged,
|
|
241
253
|
error: (err) => {
|
|
242
254
|
if (err.code === 'permission-denied') {
|
|
243
255
|
this.log('subscribeForSpaceChanges() => permission denied to read space record');
|
|
244
|
-
|
|
256
|
+
// Firestore intentionally does not reveal whether a protected
|
|
257
|
+
// document exists. For navigation purposes this is a terminal
|
|
258
|
+
// unavailable-space state, just like a missing snapshot.
|
|
259
|
+
this.$spaceAccessDenied.set(true);
|
|
245
260
|
return;
|
|
246
261
|
}
|
|
247
262
|
this.errorLogger.logError('failed to get team record');
|
|
@@ -249,7 +264,9 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
249
264
|
});
|
|
250
265
|
}
|
|
251
266
|
getSpaceContextFromRouteState() {
|
|
252
|
-
const space =
|
|
267
|
+
const space = this.isBrowser
|
|
268
|
+
? history.state?.team
|
|
269
|
+
: undefined;
|
|
253
270
|
this.log(`${this.className}:SpaceBaseComponent.getSpaceContextFromRouteState()`, space);
|
|
254
271
|
if (!space?.id) {
|
|
255
272
|
return;
|
|
@@ -263,8 +280,10 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
263
280
|
next: (uid) => {
|
|
264
281
|
if (!uid) {
|
|
265
282
|
this.unsubscribe('user signed out');
|
|
266
|
-
this.setSpaceContext(undefined);
|
|
267
283
|
}
|
|
284
|
+
// A space's id and type come from the public URL and remain useful
|
|
285
|
+
// before authentication and after sign-out. Only loaded protected
|
|
286
|
+
// data is cleared by onUserIdChanged().
|
|
268
287
|
this.onUserIdChanged();
|
|
269
288
|
},
|
|
270
289
|
error: (e) => this.logError(e, 'Failed to get user record'),
|
|
@@ -324,8 +343,11 @@ export class SpaceBaseComponent extends SneatBaseComponent {
|
|
|
324
343
|
return;
|
|
325
344
|
}
|
|
326
345
|
const idChanged = prevSpace?.id != spaceContext?.id;
|
|
346
|
+
if (idChanged) {
|
|
347
|
+
this.$spaceAccessDenied.set(false);
|
|
348
|
+
}
|
|
327
349
|
const briefChanged = !equalSpaceBriefs(prevSpace?.brief, spaceContext?.brief);
|
|
328
|
-
const dboChanged = prevSpace?.dbo
|
|
350
|
+
const dboChanged = prevSpace?.dbo !== spaceContext?.dbo;
|
|
329
351
|
this.log(`${this.className}:SpaceBaseComponent.setSpaceContext(id=${spaceContext?.id}) => idChanged=${idChanged}, briefChanged=${briefChanged}, dtoChanged=${dboChanged}`);
|
|
330
352
|
if (briefChanged) {
|
|
331
353
|
this.$spaceBrief.set(spaceContext?.brief);
|
|
@@ -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 {\n computed,\n Directive,\n effect,\n inject,\n OnInit,\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\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 noPermissions = false;\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\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) {\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 && 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 { ...space, type: space.dbo?.type };\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 this.noPermissions = true;\n return;\n }\n this.errorLogger.logError('failed to get team record');\n },\n });\n }\n\n private getSpaceContextFromRouteState(): void {\n const space = history.state?.team as ISpaceContext;\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 this.setSpaceContext(undefined);\n }\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 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 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 }\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 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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/space-extension-links/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC","sourcesContent":["export * from './space-extension-links.component';\nexport * from './space-extension-nav-item';\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, inject, input, output, } from '@angular/core';
|
|
2
|
+
import { RouterLink } from '@angular/router';
|
|
3
|
+
import { IonButton, IonButtons, IonIcon, IonItem, IonLabel, } from '@ionic/angular';
|
|
4
|
+
import { spacePageUrl } from '../space-base-component.directive';
|
|
5
|
+
import { SPACE_EXTENSION_NAV_ITEMS, } from './space-extension-nav-item';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export class SpaceExtensionLinksComponent {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.configuredItems = inject(SPACE_EXTENSION_NAV_ITEMS, { optional: true }) ?? [];
|
|
10
|
+
this.$space = input.required(/* @ts-ignore */
|
|
11
|
+
...(ngDevMode ? [{ debugName: "$space" }] : /* istanbul ignore next */ []));
|
|
12
|
+
this.$items = input(this.configuredItems, /* @ts-ignore */
|
|
13
|
+
...(ngDevMode ? [{ debugName: "$items" }] : /* istanbul ignore next */ []));
|
|
14
|
+
this.$presentation = input('menu', /* @ts-ignore */
|
|
15
|
+
...(ngDevMode ? [{ debugName: "$presentation" }] : /* istanbul ignore next */ []));
|
|
16
|
+
this.$currentPage = input('', /* @ts-ignore */
|
|
17
|
+
...(ngDevMode ? [{ debugName: "$currentPage" }] : /* istanbul ignore next */ []));
|
|
18
|
+
this.$disabled = input(false, /* @ts-ignore */
|
|
19
|
+
...(ngDevMode ? [{ debugName: "$disabled" }] : /* istanbul ignore next */ []));
|
|
20
|
+
this.linkSelected = output();
|
|
21
|
+
this.$visibleItems = computed(() => {
|
|
22
|
+
const spaceType = this.$space().type;
|
|
23
|
+
return this.$items().filter((item) => !item.spaceTypes || item.spaceTypes.includes(spaceType || ''));
|
|
24
|
+
}, /* @ts-ignore */
|
|
25
|
+
...(ngDevMode ? [{ debugName: "$visibleItems" }] : /* istanbul ignore next */ []));
|
|
26
|
+
}
|
|
27
|
+
itemUrl(path) {
|
|
28
|
+
return spacePageUrl(this.$space(), path) || '';
|
|
29
|
+
}
|
|
30
|
+
isCurrent(item) {
|
|
31
|
+
const currentPage = this.$currentPage();
|
|
32
|
+
return currentPage === item.id || currentPage === item.path;
|
|
33
|
+
}
|
|
34
|
+
visibleActions(item) {
|
|
35
|
+
const presentation = this.$presentation();
|
|
36
|
+
return (item.actions || []).filter((action) => !action.presentations || action.presentations.includes(presentation));
|
|
37
|
+
}
|
|
38
|
+
onLinkSelected() {
|
|
39
|
+
this.linkSelected.emit();
|
|
40
|
+
}
|
|
41
|
+
onActionSelected(event) {
|
|
42
|
+
event.stopPropagation();
|
|
43
|
+
this.linkSelected.emit();
|
|
44
|
+
}
|
|
45
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceExtensionLinksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
46
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: SpaceExtensionLinksComponent, isStandalone: true, selector: "sneat-space-extension-links", inputs: { $space: { classPropertyName: "$space", publicName: "$space", isSignal: true, isRequired: true, transformFunction: null }, $items: { classPropertyName: "$items", publicName: "$items", isSignal: true, isRequired: false, transformFunction: null }, $presentation: { classPropertyName: "$presentation", publicName: "$presentation", isSignal: true, isRequired: false, transformFunction: null }, $currentPage: { classPropertyName: "$currentPage", publicName: "$currentPage", isSignal: true, isRequired: false, transformFunction: null }, $disabled: { classPropertyName: "$disabled", publicName: "$disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { linkSelected: "linkSelected" }, ngImport: i0, template: "@for (item of $visibleItems(); track item.id; let last = $last) {\n <ion-item\n tappable\n [attr.data-extension-id]=\"item.id\"\n [routerLink]=\"itemUrl(item.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n [detail]=\"$presentation() === 'card'\"\n [disabled]=\"$disabled()\"\n [lines]=\"last ? 'none' : undefined\"\n [class.last-extension-item]=\"last\"\n [class.currentPage]=\"isCurrent(item)\"\n (click)=\"onLinkSelected()\"\n >\n <ion-icon [icon]=\"item.icon\" slot=\"start\" />\n <ion-label class=\"extension-title\">{{ item.title }}</ion-label>\n @if (visibleActions(item).length) {\n <ion-buttons slot=\"end\">\n @for (action of visibleActions(item); track action.id) {\n <ion-button\n [attr.title]=\"action.title\"\n [routerLink]=\"itemUrl(action.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n (click)=\"onActionSelected($event)\"\n >\n <ion-label style=\"text-transform: none\">\n @if (action.emoji) {\n <span>{{ action.emoji }}</span>\n }\n @if ($presentation() === 'card' || !action.emoji) {\n <span\n class=\"sneat-hide-if-width-less-320\"\n [style.margin-left]=\"action.emoji ? '0.5em' : undefined\"\n >{{ action.title }}</span\n >\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n }\n </ion-item>\n}\n", styles: [":host{display:block}ion-item.currentPage ion-label.extension-title{font-weight:700}ion-item.last-extension-item{--border-width: 0;--inner-border-width: 0}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { 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: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
47
|
+
}
|
|
48
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceExtensionLinksComponent, decorators: [{
|
|
49
|
+
type: Component,
|
|
50
|
+
args: [{ selector: 'sneat-space-extension-links', imports: [RouterLink, IonItem, IonIcon, IonLabel, IonButtons, IonButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "@for (item of $visibleItems(); track item.id; let last = $last) {\n <ion-item\n tappable\n [attr.data-extension-id]=\"item.id\"\n [routerLink]=\"itemUrl(item.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n [detail]=\"$presentation() === 'card'\"\n [disabled]=\"$disabled()\"\n [lines]=\"last ? 'none' : undefined\"\n [class.last-extension-item]=\"last\"\n [class.currentPage]=\"isCurrent(item)\"\n (click)=\"onLinkSelected()\"\n >\n <ion-icon [icon]=\"item.icon\" slot=\"start\" />\n <ion-label class=\"extension-title\">{{ item.title }}</ion-label>\n @if (visibleActions(item).length) {\n <ion-buttons slot=\"end\">\n @for (action of visibleActions(item); track action.id) {\n <ion-button\n [attr.title]=\"action.title\"\n [routerLink]=\"itemUrl(action.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n (click)=\"onActionSelected($event)\"\n >\n <ion-label style=\"text-transform: none\">\n @if (action.emoji) {\n <span>{{ action.emoji }}</span>\n }\n @if ($presentation() === 'card' || !action.emoji) {\n <span\n class=\"sneat-hide-if-width-less-320\"\n [style.margin-left]=\"action.emoji ? '0.5em' : undefined\"\n >{{ action.title }}</span\n >\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n }\n </ion-item>\n}\n", styles: [":host{display:block}ion-item.currentPage ion-label.extension-title{font-weight:700}ion-item.last-extension-item{--border-width: 0;--inner-border-width: 0}\n"] }]
|
|
51
|
+
}], propDecorators: { $space: [{ type: i0.Input, args: [{ isSignal: true, alias: "$space", required: true }] }], $items: [{ type: i0.Input, args: [{ isSignal: true, alias: "$items", required: false }] }], $presentation: [{ type: i0.Input, args: [{ isSignal: true, alias: "$presentation", required: false }] }], $currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "$currentPage", required: false }] }], $disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "$disabled", required: false }] }], linkSelected: [{ type: i0.Output, args: ["linkSelected"] }] } });
|
|
52
|
+
//# sourceMappingURL=space-extension-links.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-extension-links.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/space-extension-links/space-extension-links.component.ts","../../../../../../../libs/space/components/src/lib/space-extension-links/space-extension-links.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,KAAK,EACL,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,OAAO,EACP,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EACL,yBAAyB,GAI1B,MAAM,4BAA4B,CAAC;;AAsBpC,MAAM,OAAO,4BAA4B;IApBzC;QAqBmB,oBAAe,GAC9B,MAAM,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAE9C,WAAM,GAAG,KAAK,CAAC,QAAQ;mFAAiB,CAAC;QACzC,WAAM,GAAG,KAAK,CAC5B,IAAI,CAAC,eAAe;mFACrB,CAAC;QACc,kBAAa,GAC3B,KAAK,CAAkC,MAAM;0FAAC,CAAC;QACjC,iBAAY,GAAG,KAAK,CAAC,EAAE;yFAAC,CAAC;QACzB,cAAS,GAAG,KAAK,CAAC,KAAK;sFAAC,CAAC;QAEzB,iBAAY,GAAG,MAAM,EAAQ,CAAC;QAE3B,kBAAa,GAAG,QAAQ,CAAC,GAAG,EAAE;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;YACrC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CACzB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CACxE,CAAC;QACJ,CAAC;0FAAC,CAAC;KA6BJ;IA3BW,OAAO,CAAC,IAAY;QAC5B,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IAES,SAAS,CAAC,IAA2B;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACxC,OAAO,WAAW,KAAK,IAAI,CAAC,EAAE,IAAI,WAAW,KAAK,IAAI,CAAC,IAAI,CAAC;IAC9D,CAAC;IAES,cAAc,CACtB,IAA2B;QAE3B,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAChC,CAAC,MAAM,EAAE,EAAE,CACT,CAAC,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CACvE,CAAC;IACJ,CAAC;IAES,cAAc;QACtB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAES,gBAAgB,CAAC,KAAY;QACrC,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;8GAhDU,4BAA4B;kGAA5B,4BAA4B,oyBC7CzC,mkDA0CA,sNDAY,UAAU,kPAAE,OAAO,0NAAE,OAAO,2JAAE,QAAQ,6FAAE,UAAU,8EAAE,SAAS;;2FAG5D,4BAA4B;kBApBxC,SAAS;+BACE,6BAA6B,WAgB9B,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,mBACvD,uBAAuB,CAAC,MAAM","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport {\n IonButton,\n IonButtons,\n IonIcon,\n IonItem,\n IonLabel,\n} from '@ionic/angular';\nimport { ISpaceContext } from '@sneat/space-models';\nimport { spacePageUrl } from '../space-base-component.directive';\nimport {\n SPACE_EXTENSION_NAV_ITEMS,\n SpaceExtensionLinksPresentation,\n SpaceExtensionNavAction,\n SpaceExtensionNavItem,\n} from './space-extension-nav-item';\n\n@Component({\n selector: 'sneat-space-extension-links',\n templateUrl: './space-extension-links.component.html',\n styles: `\n :host {\n display: block;\n }\n\n ion-item.currentPage ion-label.extension-title {\n font-weight: bold;\n }\n\n ion-item.last-extension-item {\n --border-width: 0;\n --inner-border-width: 0;\n }\n `,\n imports: [RouterLink, IonItem, IonIcon, IonLabel, IonButtons, IonButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpaceExtensionLinksComponent {\n private readonly configuredItems =\n inject(SPACE_EXTENSION_NAV_ITEMS, { optional: true }) ?? [];\n\n public readonly $space = input.required<ISpaceContext>();\n public readonly $items = input<readonly SpaceExtensionNavItem[]>(\n this.configuredItems,\n );\n public readonly $presentation =\n input<SpaceExtensionLinksPresentation>('menu');\n public readonly $currentPage = input('');\n public readonly $disabled = input(false);\n\n public readonly linkSelected = output<void>();\n\n protected readonly $visibleItems = computed(() => {\n const spaceType = this.$space().type;\n return this.$items().filter(\n (item) => !item.spaceTypes || item.spaceTypes.includes(spaceType || ''),\n );\n });\n\n protected itemUrl(path: string): string {\n return spacePageUrl(this.$space(), path) || '';\n }\n\n protected isCurrent(item: SpaceExtensionNavItem): boolean {\n const currentPage = this.$currentPage();\n return currentPage === item.id || currentPage === item.path;\n }\n\n protected visibleActions(\n item: SpaceExtensionNavItem,\n ): readonly SpaceExtensionNavAction[] {\n const presentation = this.$presentation();\n return (item.actions || []).filter(\n (action) =>\n !action.presentations || action.presentations.includes(presentation),\n );\n }\n\n protected onLinkSelected(): void {\n this.linkSelected.emit();\n }\n\n protected onActionSelected(event: Event): void {\n event.stopPropagation();\n this.linkSelected.emit();\n }\n}\n","@for (item of $visibleItems(); track item.id; let last = $last) {\n <ion-item\n tappable\n [attr.data-extension-id]=\"item.id\"\n [routerLink]=\"itemUrl(item.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n [detail]=\"$presentation() === 'card'\"\n [disabled]=\"$disabled()\"\n [lines]=\"last ? 'none' : undefined\"\n [class.last-extension-item]=\"last\"\n [class.currentPage]=\"isCurrent(item)\"\n (click)=\"onLinkSelected()\"\n >\n <ion-icon [icon]=\"item.icon\" slot=\"start\" />\n <ion-label class=\"extension-title\">{{ item.title }}</ion-label>\n @if (visibleActions(item).length) {\n <ion-buttons slot=\"end\">\n @for (action of visibleActions(item); track action.id) {\n <ion-button\n [attr.title]=\"action.title\"\n [routerLink]=\"itemUrl(action.path)\"\n [routerDirection]=\"$presentation() === 'menu' ? 'root' : undefined\"\n (click)=\"onActionSelected($event)\"\n >\n <ion-label style=\"text-transform: none\">\n @if (action.emoji) {\n <span>{{ action.emoji }}</span>\n }\n @if ($presentation() === 'card' || !action.emoji) {\n <span\n class=\"sneat-hide-if-width-less-320\"\n [style.margin-left]=\"action.emoji ? '0.5em' : undefined\"\n >{{ action.title }}</span\n >\n }\n </ion-label>\n </ion-button>\n }\n </ion-buttons>\n }\n </ion-item>\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
export const SPACE_EXTENSION_NAV_ITEMS = new InjectionToken('space-extension-nav-items');
|
|
3
|
+
export function provideSpaceExtensionNavItems(items) {
|
|
4
|
+
return { provide: SPACE_EXTENSION_NAV_ITEMS, useValue: items };
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=space-extension-nav-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-extension-nav-item.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/space-extension-links/space-extension-nav-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAY,MAAM,eAAe,CAAC;AAsBzD,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,cAAc,CAEzD,2BAA2B,CAAC,CAAC;AAE/B,MAAM,UAAU,6BAA6B,CAC3C,KAAuC;IAEvC,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACjE,CAAC","sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\n\nexport type SpaceExtensionLinksPresentation = 'menu' | 'card';\n\nexport interface SpaceExtensionNavAction {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n readonly emoji?: string;\n readonly presentations?: readonly SpaceExtensionLinksPresentation[];\n}\n\nexport interface SpaceExtensionNavItem {\n readonly id: string;\n readonly title: string;\n readonly path: string;\n /** An imported Ionicon SVG definition, passed directly to ion-icon. */\n readonly icon: string;\n readonly spaceTypes?: readonly string[];\n readonly actions?: readonly SpaceExtensionNavAction[];\n}\n\nexport const SPACE_EXTENSION_NAV_ITEMS = new InjectionToken<\n readonly SpaceExtensionNavItem[]\n>('space-extension-nav-items');\n\nexport function provideSpaceExtensionNavItems(\n items: readonly SpaceExtensionNavItem[],\n): Provider {\n return { provide: SPACE_EXTENSION_NAV_ITEMS, useValue: items };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TitleCasePipe } from '@angular/common';
|
|
2
2
|
import { ChangeDetectionStrategy, Component, computed, inject, signal, } from '@angular/core';
|
|
3
3
|
import { ActivatedRoute, NavigationEnd, Router, RouterLink, } from '@angular/router';
|
|
4
|
-
import {
|
|
4
|
+
import { IonIcon, IonItem, IonItemDivider, IonLabel, IonList, IonSelect, IonSelectOption, MenuController, } from '@ionic/angular';
|
|
5
5
|
import { AuthMenuItemComponent } from '@sneat/auth-ui';
|
|
6
6
|
import { zipMapBriefsWithIDs } from '@sneat/space-models';
|
|
7
7
|
import { SpaceServiceModule } from '@sneat/space-services';
|
|
@@ -10,6 +10,7 @@ import { takeUntil } from 'rxjs/operators';
|
|
|
10
10
|
import { SpaceBaseComponent } from '../space-base-component.directive';
|
|
11
11
|
import { SpaceComponentBaseParams } from '../space-component-base-params.service';
|
|
12
12
|
import { ClassName } from '@sneat/ui';
|
|
13
|
+
import { SpaceExtensionLinksComponent } from '../space-extension-links';
|
|
13
14
|
import * as i0 from "@angular/core";
|
|
14
15
|
export class SpaceMenuComponent extends SpaceBaseComponent {
|
|
15
16
|
constructor() {
|
|
@@ -17,7 +18,7 @@ export class SpaceMenuComponent extends SpaceBaseComponent {
|
|
|
17
18
|
super();
|
|
18
19
|
this.$spaces = signal(undefined, /* @ts-ignore */
|
|
19
20
|
...(ngDevMode ? [{ debugName: "$spaces" }] : /* istanbul ignore next */ []));
|
|
20
|
-
this.$disabled = computed(() => !this.$spaceID(), /* @ts-ignore */
|
|
21
|
+
this.$disabled = computed(() => !this.$spaceID() || this.$spaceNotFound(), /* @ts-ignore */
|
|
21
22
|
...(ngDevMode ? [{ debugName: "$disabled" }] : /* istanbul ignore next */ []));
|
|
22
23
|
this.$currentPage = signal('', /* @ts-ignore */
|
|
23
24
|
...(ngDevMode ? [{ debugName: "$currentPage" }] : /* istanbul ignore next */ []));
|
|
@@ -92,7 +93,7 @@ export class SpaceMenuComponent extends SpaceBaseComponent {
|
|
|
92
93
|
useValue: 'SpaceMenuComponent',
|
|
93
94
|
},
|
|
94
95
|
SpaceComponentBaseParams,
|
|
95
|
-
], usesInheritance: true, ngImport: i0, template: "<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('
|
|
96
|
+
], usesInheritance: true, ngImport: i0, template: "<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('members')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'members'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"people-circle-outline\" slot=\"start\" />\n <ion-label>Members</ion-label>\n </ion-item>\n <ion-item\n tappable\n lines=\"none\"\n class=\"sneat-no-bottom-border\"\n [routerLink]=\"spacePageUrl('calendar')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'calendar'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"calendar-outline\" slot=\"start\" />\n <ion-label>Calendar</ion-label>\n </ion-item>\n <ion-item-divider color=\"header\">\n <ion-label color=\"medium\">Extensions</ion-label>\n </ion-item-divider>\n <sneat-space-extension-links\n [$space]=\"$space()\"\n [$presentation]=\"'menu'\"\n [$currentPage]=\"$currentPage()\"\n [$disabled]=\"$disabled()\"\n (linkSelected)=\"closeMenu()\"\n />\n <sneat-auth-menu-item />\n</ion-list>\n", styles: [".currentPage ion-label{font-weight:700}\n"], dependencies: [{ kind: "component", type: AuthMenuItemComponent, selector: "sneat-auth-menu-item" }, { kind: "ngmodule", type: SpaceServiceModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "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: IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["description", "disabled", "justify", "labelPlacement", "mode", "value"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: SpaceExtensionLinksComponent, selector: "sneat-space-extension-links", inputs: ["$space", "$items", "$presentation", "$currentPage", "$disabled"], outputs: ["linkSelected"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
96
97
|
}
|
|
97
98
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceMenuComponent, decorators: [{
|
|
98
99
|
type: Component,
|
|
@@ -103,18 +104,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
103
104
|
RouterLink,
|
|
104
105
|
IonList,
|
|
105
106
|
IonItem,
|
|
107
|
+
IonItemDivider,
|
|
106
108
|
IonSelect,
|
|
107
109
|
IonSelectOption,
|
|
108
110
|
IonIcon,
|
|
109
111
|
IonLabel,
|
|
110
|
-
|
|
111
|
-
IonButton,
|
|
112
|
+
SpaceExtensionLinksComponent,
|
|
112
113
|
], providers: [
|
|
113
114
|
{
|
|
114
115
|
provide: ClassName,
|
|
115
116
|
useValue: 'SpaceMenuComponent',
|
|
116
117
|
},
|
|
117
118
|
SpaceComponentBaseParams,
|
|
118
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('
|
|
119
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('members')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'members'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"people-circle-outline\" slot=\"start\" />\n <ion-label>Members</ion-label>\n </ion-item>\n <ion-item\n tappable\n lines=\"none\"\n class=\"sneat-no-bottom-border\"\n [routerLink]=\"spacePageUrl('calendar')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'calendar'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"calendar-outline\" slot=\"start\" />\n <ion-label>Calendar</ion-label>\n </ion-item>\n <ion-item-divider color=\"header\">\n <ion-label color=\"medium\">Extensions</ion-label>\n </ion-item-divider>\n <sneat-space-extension-links\n [$space]=\"$space()\"\n [$presentation]=\"'menu'\"\n [$currentPage]=\"$currentPage()\"\n [$disabled]=\"$disabled()\"\n (linkSelected)=\"closeMenu()\"\n />\n <sneat-auth-menu-item />\n</ion-list>\n", styles: [".currentPage ion-label{font-weight:700}\n"] }]
|
|
119
120
|
}], ctorParameters: () => [] });
|
|
120
121
|
//# sourceMappingURL=space-menu.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"space-menu.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/space-menu/space-menu.component.ts","../../../../../../../libs/space/components/src/lib/space-menu/space-menu.component.html"],"names":[],"mappings":"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","sourcesContent":["import { TitleCasePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n NavigationEnd,\n Router,\n RouterLink,\n} from '@angular/router';\nimport {\n IonButton,\n IonButtons,\n IonIcon,\n IonItem,\n IonLabel,\n IonList,\n IonSelect,\n IonSelectOption,\n MenuController,\n} from '@ionic/angular';\nimport { ISneatUserState } from '@sneat/auth-core';\nimport { IUserSpaceBrief } from '@sneat/auth-models';\nimport { AuthMenuItemComponent } from '@sneat/auth-ui';\nimport { IIdAndBrief } from '@sneat/core';\nimport { zipMapBriefsWithIDs } from '@sneat/space-models';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { filter } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SpaceBaseComponent } from '../space-base-component.directive';\nimport { SpaceComponentBaseParams } from '../space-component-base-params.service';\nimport { ClassName } from '@sneat/ui';\n\n@Component({\n selector: 'sneat-space-menu',\n templateUrl: './space-menu.component.html',\n styles: '.currentPage ion-label {font-weight: bold}',\n imports: [\n AuthMenuItemComponent,\n SpaceServiceModule,\n TitleCasePipe,\n RouterLink,\n IonList,\n IonItem,\n IonSelect,\n IonSelectOption,\n IonIcon,\n IonLabel,\n IonButtons,\n IonButton,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'SpaceMenuComponent',\n },\n SpaceComponentBaseParams,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpaceMenuComponent extends SpaceBaseComponent {\n protected readonly $spaces = signal<\n readonly IIdAndBrief<IUserSpaceBrief>[] | undefined\n >(undefined);\n\n protected readonly $disabled = computed(() => !this.$spaceID());\n\n protected readonly $currentPage = signal<string>('');\n\n private readonly activatedRoute = inject(ActivatedRoute);\n private readonly menuCtrl = inject(MenuController);\n\n constructor() {\n const router = inject(Router);\n\n super();\n this.spaceParams.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe({\n next: this.onUserStateChanged,\n error: this.errorLogger.logErrorHandler('failed to get user stage'),\n });\n router.events\n .pipe(\n this.takeUntilDestroyed(),\n filter((event) => event instanceof NavigationEnd),\n )\n .subscribe((event: NavigationEnd) => {\n let route = this.activatedRoute.firstChild;\n while (route?.firstChild) {\n route = route.firstChild;\n }\n const url = event.urlAfterRedirects.split('/');\n this.$currentPage.set(url.length > 4 ? url[4] : '');\n });\n }\n\n // TODO: Should we use goSpacePage('') instead?\n protected goOverview(): boolean {\n const space = this.$space();\n if (!space) {\n this.errorLogger.logError('no space context');\n return false;\n }\n this.spaceParams.spaceNavService.navigateToSpace(space).then((v) => {\n if (v) {\n this.closeMenu();\n }\n });\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected goSpacePage(event: Event, _p: string): boolean {\n // At the moment we use routerLink for navigation\n event.stopPropagation();\n // event.preventDefault();\n this.closeMenu();\n return false;\n }\n\n protected closeMenu(): void {\n this.menuCtrl.close().catch(this.errorLogger.logError);\n }\n\n protected onSpaceSelected(event: Event): void {\n const spaceID = (event as CustomEvent).detail.value as string;\n if (spaceID === this.space?.id) {\n return;\n }\n const space = this.$spaces()?.find((t) => t.id === spaceID);\n if (space) {\n this.setSpaceRef(space);\n this.spaceNav\n .navigateToSpace(space)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate to teams page on current team changed from team menu dropdown',\n ),\n );\n }\n this.menuCtrl.close().catch(console.error);\n return;\n }\n\n private readonly onUserStateChanged = (userState: ISneatUserState): void => {\n this.$spaces.set(\n userState?.record\n ? zipMapBriefsWithIDs(userState.record.spaces) || []\n : undefined,\n );\n };\n}\n","<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('assets')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'assets'\"\n (click)=\"goSpacePage($event, 'assets')\"\n >\n <ion-icon name=\"car-sport-outline\" slot=\"start\" />\n <ion-label>Assets</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('budget')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'budget'\"\n (click)=\"goSpacePage($event, 'budget')\"\n >\n <ion-icon name=\"cash-outline\" slot=\"start\" />\n <ion-label>Budget</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('calendar')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'calendar'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"calendar-outline\" slot=\"start\" />\n <ion-label>Calendar</ion-label>\n <!--\t\t<ion-buttons slot=\"end\">-->\n <!--\t\t\t<ion-button color=\"primary\" style=\"text-transform: none; font-size: x-small\">Today</ion-button>-->\n <!--\t\t\t<ion-button color=\"primary\" style=\"text-transform: none; font-size: x-small\">Tomorrow</ion-button>-->\n <!--\t\t</ion-buttons>-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('eventus')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'eventus'\"\n (click)=\"goSpacePage($event, 'eventus')\"\n >\n <ion-icon name=\"balloon-outline\" slot=\"start\" />\n <ion-label>Eventus</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('contacts')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'contacts'\"\n (click)=\"goSpacePage($event, 'contacts')\"\n >\n <ion-icon name=\"people-outline\" slot=\"start\" />\n <ion-label>Contacts</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('debts')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'debts'\"\n (click)=\"goSpacePage($event, 'debts')\"\n >\n <ion-icon name=\"cash-outline\" slot=\"start\" />\n <ion-label>Debts</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('documents')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'documents'\"\n (click)=\"goSpacePage($event, 'documents')\"\n >\n <ion-icon name=\"documents-outline\" slot=\"start\" />\n <ion-label>Documents</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('lists')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'lists'\"\n (click)=\"goSpacePage($event, 'lists')\"\n >\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label>Lists</ion-label>\n <ion-buttons slot=\"end\">\n <ion-button\n routerDirection=\"root\"\n [routerLink]=\"spacePageUrl('list/buy/groceries')\"\n (click)=\"goSpacePage($event, 'list/buy/groceries')\"\n >\n <ion-label>🛒</ion-label>\n </ion-button>\n <!--\t\t\t<ion-button routerLink=\"./list/towatch\">🍿</ion-button>-->\n </ion-buttons>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('members')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'members'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"people-circle-outline\" slot=\"start\" />\n <ion-label>Members</ion-label>\n </ion-item>\n <!-- Sizes — the sizeus extension (extension id: sizeus). The `sizes` space\n route (space matrix + contact Sizes aspect) is registered by the\n consuming app; frontend libs live in github.com/sneat-co/sizeus. -->\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('sizes')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'sizes'\"\n (click)=\"goSpacePage($event, 'sizes')\"\n >\n <ion-icon name=\"shirt-outline\" slot=\"start\" />\n <ion-label>Sizes</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('trackers')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'trackers'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"bar-chart-outline\" slot=\"start\" />\n <ion-label>Trackers</ion-label>\n </ion-item>\n <sneat-auth-menu-item />\n</ion-list>\n"]}
|
|
1
|
+
{"version":3,"file":"space-menu.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/space-menu/space-menu.component.ts","../../../../../../../libs/space/components/src/lib/space-menu/space-menu.component.html"],"names":[],"mappings":"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","sourcesContent":["import { TitleCasePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n NavigationEnd,\n Router,\n RouterLink,\n} from '@angular/router';\nimport {\n IonIcon,\n IonItem,\n IonItemDivider,\n IonLabel,\n IonList,\n IonSelect,\n IonSelectOption,\n MenuController,\n} from '@ionic/angular';\nimport { ISneatUserState } from '@sneat/auth-core';\nimport { IUserSpaceBrief } from '@sneat/auth-models';\nimport { AuthMenuItemComponent } from '@sneat/auth-ui';\nimport { IIdAndBrief } from '@sneat/core';\nimport { zipMapBriefsWithIDs } from '@sneat/space-models';\nimport { SpaceServiceModule } from '@sneat/space-services';\nimport { filter } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SpaceBaseComponent } from '../space-base-component.directive';\nimport { SpaceComponentBaseParams } from '../space-component-base-params.service';\nimport { ClassName } from '@sneat/ui';\nimport { SpaceExtensionLinksComponent } from '../space-extension-links';\n\n@Component({\n selector: 'sneat-space-menu',\n templateUrl: './space-menu.component.html',\n styles: '.currentPage ion-label {font-weight: bold}',\n imports: [\n AuthMenuItemComponent,\n SpaceServiceModule,\n TitleCasePipe,\n RouterLink,\n IonList,\n IonItem,\n IonItemDivider,\n IonSelect,\n IonSelectOption,\n IonIcon,\n IonLabel,\n SpaceExtensionLinksComponent,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'SpaceMenuComponent',\n },\n SpaceComponentBaseParams,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpaceMenuComponent extends SpaceBaseComponent {\n protected readonly $spaces = signal<\n readonly IIdAndBrief<IUserSpaceBrief>[] | undefined\n >(undefined);\n\n protected readonly $disabled = computed(\n () => !this.$spaceID() || this.$spaceNotFound(),\n );\n\n protected readonly $currentPage = signal<string>('');\n\n private readonly activatedRoute = inject(ActivatedRoute);\n private readonly menuCtrl = inject(MenuController);\n\n constructor() {\n const router = inject(Router);\n\n super();\n this.spaceParams.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe({\n next: this.onUserStateChanged,\n error: this.errorLogger.logErrorHandler('failed to get user stage'),\n });\n router.events\n .pipe(\n this.takeUntilDestroyed(),\n filter((event) => event instanceof NavigationEnd),\n )\n .subscribe((event: NavigationEnd) => {\n let route = this.activatedRoute.firstChild;\n while (route?.firstChild) {\n route = route.firstChild;\n }\n const url = event.urlAfterRedirects.split('/');\n this.$currentPage.set(url.length > 4 ? url[4] : '');\n });\n }\n\n // TODO: Should we use goSpacePage('') instead?\n protected goOverview(): boolean {\n const space = this.$space();\n if (!space) {\n this.errorLogger.logError('no space context');\n return false;\n }\n this.spaceParams.spaceNavService.navigateToSpace(space).then((v) => {\n if (v) {\n this.closeMenu();\n }\n });\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected goSpacePage(event: Event, _p: string): boolean {\n // At the moment we use routerLink for navigation\n event.stopPropagation();\n // event.preventDefault();\n this.closeMenu();\n return false;\n }\n\n protected closeMenu(): void {\n this.menuCtrl.close().catch(this.errorLogger.logError);\n }\n\n protected onSpaceSelected(event: Event): void {\n const spaceID = (event as CustomEvent).detail.value as string;\n if (spaceID === this.space?.id) {\n return;\n }\n const space = this.$spaces()?.find((t) => t.id === spaceID);\n if (space) {\n this.setSpaceRef(space);\n this.spaceNav\n .navigateToSpace(space)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate to teams page on current team changed from team menu dropdown',\n ),\n );\n }\n this.menuCtrl.close().catch(console.error);\n return;\n }\n\n private readonly onUserStateChanged = (userState: ISneatUserState): void => {\n this.$spaces.set(\n userState?.record\n ? zipMapBriefsWithIDs(userState.record.spaces) || []\n : undefined,\n );\n };\n}\n","<ion-list>\n <ion-item>\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <ion-select\n label=\"Space\"\n [value]=\"$space().id\"\n interface=\"popover\"\n (ionChange)=\"onSpaceSelected($event)\"\n style=\"font-weight: bold\"\n >\n @for (userSpace of $spaces(); track userSpace.id) {\n <ion-select-option [value]=\"userSpace.id\"\n >{{\n userSpace.brief.title ||\n (userSpace.brief.type | titlecase) ||\n space.id\n }}\n </ion-select-option>\n } @empty {\n @let space = $space();\n <ion-select-option [value]=\"$safeNavigationMigration(space?.id)\">\n @if (!space || (!space?.id && !space?.type)) {\n Loading...\n } @else {\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n }\n </ion-select-option>\n }\n </ion-select>\n <!--\t\t@if (!spaces) {-->\n <!--\t\t\t<ion-spinner name=\"lines\" slot=\"end\"></ion-spinner>-->\n <!--\t\t}-->\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('overview')\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === ''\"\n (click)=\"goOverview()\"\n >\n <ion-icon name=\"home-outline\" slot=\"start\" />\n <ion-label>Overview</ion-label>\n </ion-item>\n <ion-item\n tappable\n [routerLink]=\"spacePageUrl('members')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'members'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"people-circle-outline\" slot=\"start\" />\n <ion-label>Members</ion-label>\n </ion-item>\n <ion-item\n tappable\n lines=\"none\"\n class=\"sneat-no-bottom-border\"\n [routerLink]=\"spacePageUrl('calendar')\"\n routerDirection=\"root\"\n [disabled]=\"$disabled()\"\n [class.currentPage]=\"$currentPage() === 'calendar'\"\n (click)=\"closeMenu()\"\n >\n <ion-icon name=\"calendar-outline\" slot=\"start\" />\n <ion-label>Calendar</ion-label>\n </ion-item>\n <ion-item-divider color=\"header\">\n <ion-label color=\"medium\">Extensions</ion-label>\n </ion-item-divider>\n <sneat-space-extension-links\n [$space]=\"$space()\"\n [$presentation]=\"'menu'\"\n [$currentPage]=\"$currentPage()\"\n [$disabled]=\"$disabled()\"\n (linkSelected)=\"closeMenu()\"\n />\n <sneat-auth-menu-item />\n</ion-list>\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './avatar/avatar.component';
|
|
2
2
|
export * from './space-menu';
|
|
3
|
+
export * from './space-extension-links';
|
|
3
4
|
export * from './spaces-menu';
|
|
4
5
|
export * from './space-page-title/space-page-title.component';
|
|
5
6
|
export * from './space-page-base-component.service';
|