@sneat/space-components 0.27.5 → 0.27.7

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.
Files changed (30) hide show
  1. package/esm2022/lib/index.js +2 -0
  2. package/esm2022/lib/index.js.map +1 -1
  3. package/esm2022/lib/space-base-component.directive.js +31 -9
  4. package/esm2022/lib/space-base-component.directive.js.map +1 -1
  5. package/esm2022/lib/space-extension-links/index.js +3 -0
  6. package/esm2022/lib/space-extension-links/index.js.map +1 -0
  7. package/esm2022/lib/space-extension-links/space-extension-links.component.js +52 -0
  8. package/esm2022/lib/space-extension-links/space-extension-links.component.js.map +1 -0
  9. package/esm2022/lib/space-extension-links/space-extension-nav-item.js +6 -0
  10. package/esm2022/lib/space-extension-links/space-extension-nav-item.js.map +1 -0
  11. package/esm2022/lib/space-menu/space-menu.component.js +10 -41
  12. package/esm2022/lib/space-menu/space-menu.component.js.map +1 -1
  13. package/esm2022/lib/space-selector/index.js +2 -0
  14. package/esm2022/lib/space-selector/index.js.map +1 -0
  15. package/esm2022/lib/space-selector/space-selector.component.js +133 -0
  16. package/esm2022/lib/space-selector/space-selector.component.js.map +1 -0
  17. package/esm2022/lib/spaces-card/spaces-card.component.js +2 -2
  18. package/esm2022/lib/spaces-card/spaces-card.component.js.map +1 -1
  19. package/esm2022/lib/spaces-list/spaces-list.component.js +2 -2
  20. package/esm2022/lib/spaces-list/spaces-list.component.js.map +1 -1
  21. package/lib/index.d.ts +2 -0
  22. package/lib/space-base-component.directive.d.ts +3 -1
  23. package/lib/space-extension-links/index.d.ts +2 -0
  24. package/lib/space-extension-links/space-extension-links.component.d.ts +20 -0
  25. package/lib/space-extension-links/space-extension-nav-item.d.ts +20 -0
  26. package/lib/space-menu/space-menu.component.d.ts +0 -5
  27. package/lib/space-selector/index.d.ts +1 -0
  28. package/lib/space-selector/space-selector.component.d.ts +28 -0
  29. package/package.json +1 -1
  30. package/tsconfig.lib.prod.tsbuildinfo +1 -1
@@ -1,5 +1,7 @@
1
1
  export * from './avatar/avatar.component';
2
2
  export * from './space-menu';
3
+ export * from './space-selector';
4
+ export * from './space-extension-links';
3
5
  export * from './spaces-menu';
4
6
  export * from './space-page-title/space-page-title.component';
5
7
  export * from './space-page-base-component.service';
@@ -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,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC","sourcesContent":["export * from './avatar/avatar.component';\nexport * from './space-menu';\nexport * from './space-selector';\nexport * from './space-extension-links';\nexport * from './spaces-menu';\nexport * from './space-page-title/space-page-title.component';\nexport * from './space-page-base-component.service';\nexport * from './space-component-base-params.service';\nexport * from './space-item-page-base.component';\nexport * from './space-items-base.component';\nexport * from './spaces-list';\nexport * from './spaces-card';\nexport * from './space-module-base.component';\nexport * from './space-base-component.directive';\n"]}
@@ -1,4 +1,5 @@
1
- import { computed, Directive, effect, inject, signal, } from '@angular/core';
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 && this.space.dbo) {
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 { ...space, type: space.dbo?.type };
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
- this.noPermissions = true;
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 = history.state?.team;
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 != spaceContext?.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,3 @@
1
+ export * from './space-extension-links.component';
2
+ export * from './space-extension-nav-item';
3
+ //# sourceMappingURL=index.js.map
@@ -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,39 +1,25 @@
1
- import { TitleCasePipe } from '@angular/common';
2
1
  import { ChangeDetectionStrategy, Component, computed, inject, signal, } from '@angular/core';
3
2
  import { ActivatedRoute, NavigationEnd, Router, RouterLink, } from '@angular/router';
4
- import { IonButton, IonButtons, IonIcon, IonItem, IonLabel, IonList, IonSelect, IonSelectOption, MenuController, } from '@ionic/angular';
3
+ import { IonIcon, IonItem, IonItemDivider, IonLabel, IonList, MenuController, } from '@ionic/angular';
5
4
  import { AuthMenuItemComponent } from '@sneat/auth-ui';
6
- import { zipMapBriefsWithIDs } from '@sneat/space-models';
7
5
  import { SpaceServiceModule } from '@sneat/space-services';
8
6
  import { filter } from 'rxjs';
9
- import { takeUntil } from 'rxjs/operators';
10
7
  import { SpaceBaseComponent } from '../space-base-component.directive';
11
8
  import { SpaceComponentBaseParams } from '../space-component-base-params.service';
12
9
  import { ClassName } from '@sneat/ui';
10
+ import { SpaceExtensionLinksComponent } from '../space-extension-links';
11
+ import { SpaceSelectorComponent } from '../space-selector';
13
12
  import * as i0 from "@angular/core";
14
13
  export class SpaceMenuComponent extends SpaceBaseComponent {
15
14
  constructor() {
16
15
  const router = inject(Router);
17
16
  super();
18
- this.$spaces = signal(undefined, /* @ts-ignore */
19
- ...(ngDevMode ? [{ debugName: "$spaces" }] : /* istanbul ignore next */ []));
20
- this.$disabled = computed(() => !this.$spaceID(), /* @ts-ignore */
17
+ this.$disabled = computed(() => !this.$spaceID() || this.$spaceNotFound(), /* @ts-ignore */
21
18
  ...(ngDevMode ? [{ debugName: "$disabled" }] : /* istanbul ignore next */ []));
22
19
  this.$currentPage = signal('', /* @ts-ignore */
23
20
  ...(ngDevMode ? [{ debugName: "$currentPage" }] : /* istanbul ignore next */ []));
24
21
  this.activatedRoute = inject(ActivatedRoute);
25
22
  this.menuCtrl = inject(MenuController);
26
- this.onUserStateChanged = (userState) => {
27
- this.$spaces.set(userState?.record
28
- ? zipMapBriefsWithIDs(userState.record.spaces) || []
29
- : undefined);
30
- };
31
- this.spaceParams.userService.userState
32
- .pipe(takeUntil(this.destroyed$))
33
- .subscribe({
34
- next: this.onUserStateChanged,
35
- error: this.errorLogger.logErrorHandler('failed to get user stage'),
36
- });
37
23
  router.events
38
24
  .pipe(this.takeUntilDestroyed(), filter((event) => event instanceof NavigationEnd))
39
25
  .subscribe((event) => {
@@ -70,51 +56,34 @@ export class SpaceMenuComponent extends SpaceBaseComponent {
70
56
  closeMenu() {
71
57
  this.menuCtrl.close().catch(this.errorLogger.logError);
72
58
  }
73
- onSpaceSelected(event) {
74
- const spaceID = event.detail.value;
75
- if (spaceID === this.space?.id) {
76
- return;
77
- }
78
- const space = this.$spaces()?.find((t) => t.id === spaceID);
79
- if (space) {
80
- this.setSpaceRef(space);
81
- this.spaceNav
82
- .navigateToSpace(space)
83
- .catch(this.errorLogger.logErrorHandler('Failed to navigate to teams page on current team changed from team menu dropdown'));
84
- }
85
- this.menuCtrl.close().catch(console.error);
86
- return;
87
- }
88
59
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
89
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: SpaceMenuComponent, isStandalone: true, selector: "sneat-space-menu", providers: [
60
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.3", type: SpaceMenuComponent, isStandalone: true, selector: "sneat-space-menu", providers: [
90
61
  {
91
62
  provide: ClassName,
92
63
  useValue: 'SpaceMenuComponent',
93
64
  },
94
65
  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('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>\uD83D\uDED2</ion-label>\n </ion-button>\n <!--\t\t\t<ion-button routerLink=\"./list/towatch\">\uD83C\uDF7F</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 \u2014 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", 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: 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: 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"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
66
+ ], usesInheritance: true, ngImport: i0, template: "<ion-list>\n <ion-item class=\"sneat-pane-header\">\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <sneat-space-selector\n [closeMenuOnSelection]=\"true\"\n justify=\"space-between\"\n />\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: 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: "component", type: SpaceSelectorComponent, selector: "sneat-space-selector", inputs: ["closeMenuOnSelection", "justify", "navigateOnSelection"], outputs: ["spaceSelected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
96
67
  }
97
68
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceMenuComponent, decorators: [{
98
69
  type: Component,
99
70
  args: [{ selector: 'sneat-space-menu', imports: [
100
71
  AuthMenuItemComponent,
101
72
  SpaceServiceModule,
102
- TitleCasePipe,
103
73
  RouterLink,
104
74
  IonList,
105
75
  IonItem,
106
- IonSelect,
107
- IonSelectOption,
76
+ IonItemDivider,
108
77
  IonIcon,
109
78
  IonLabel,
110
- IonButtons,
111
- IonButton,
79
+ SpaceExtensionLinksComponent,
80
+ SpaceSelectorComponent,
112
81
  ], providers: [
113
82
  {
114
83
  provide: ClassName,
115
84
  useValue: 'SpaceMenuComponent',
116
85
  },
117
86
  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('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>\uD83D\uDED2</ion-label>\n </ion-button>\n <!--\t\t\t<ion-button routerLink=\"./list/towatch\">\uD83C\uDF7F</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 \u2014 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", styles: [".currentPage ion-label{font-weight:700}\n"] }]
87
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-list>\n <ion-item class=\"sneat-pane-header\">\n <!--\t\t<ion-icon [name]=\"space.type === 'family' ? 'people-outline' : space.type === 'private' ? 'person-circle-outline' : 'people-outline' \" slot=\"end\" />-->\n <sneat-space-selector\n [closeMenuOnSelection]=\"true\"\n justify=\"space-between\"\n />\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
88
  }], ctorParameters: () => [] });
120
89
  //# sourceMappingURL=space-menu.component.js.map