@sneat/space-services 0.1.3 → 0.1.4
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/index.js +8 -0
- package/esm2022/index.js.map +1 -0
- package/esm2022/lib/components/with-space-input.directive.js +37 -0
- package/esm2022/lib/components/with-space-input.directive.js.map +1 -0
- package/esm2022/lib/services/space-context.service.js +26 -0
- package/esm2022/lib/services/space-context.service.js.map +1 -0
- package/esm2022/lib/services/space-item.service.js +132 -0
- package/esm2022/lib/services/space-item.service.js.map +1 -0
- package/esm2022/lib/services/space-module.service.js +35 -0
- package/esm2022/lib/services/space-module.service.js.map +1 -0
- package/esm2022/lib/services/space-nav.service.js +97 -0
- package/esm2022/lib/services/space-nav.service.js.map +1 -0
- package/esm2022/lib/services/space-service.module.js +15 -0
- package/esm2022/lib/services/space-service.module.js.map +1 -0
- package/esm2022/lib/services/space.service.js +209 -0
- package/esm2022/lib/services/space.service.js.map +1 -0
- package/esm2022/sneat-space-services.js +5 -0
- package/esm2022/sneat-space-services.js.map +1 -0
- package/{src/index.ts → index.d.ts} +0 -1
- package/lib/components/with-space-input.directive.d.ts +20 -0
- package/lib/services/space-context.service.d.ts +9 -0
- package/lib/services/space-item.service.d.ts +43 -0
- package/lib/services/space-module.service.d.ts +10 -0
- package/lib/services/space-nav.service.d.ts +32 -0
- package/lib/services/space-service.module.d.ts +6 -0
- package/lib/services/space.service.d.ts +33 -0
- package/package.json +14 -2
- package/sneat-space-services.d.ts +5 -0
- package/eslint.config.js +0 -7
- package/ng-package.json +0 -7
- package/project.json +0 -38
- package/src/lib/components/with-space-input.directive.spec.ts +0 -41
- package/src/lib/components/with-space-input.directive.ts +0 -40
- package/src/lib/services/space-context.service.spec.ts +0 -16
- package/src/lib/services/space-context.service.ts +0 -45
- package/src/lib/services/space-item.service.spec.ts +0 -179
- package/src/lib/services/space-item.service.ts +0 -308
- package/src/lib/services/space-module.service.spec.ts +0 -48
- package/src/lib/services/space-module.service.ts +0 -69
- package/src/lib/services/space-nav-service.service.spec.ts +0 -32
- package/src/lib/services/space-nav.service.ts +0 -175
- package/src/lib/services/space-service.module.spec.ts +0 -46
- package/src/lib/services/space-service.module.ts +0 -7
- package/src/lib/services/space.service.spec.ts +0 -44
- package/src/lib/services/space.service.ts +0 -291
- package/src/test-setup.ts +0 -3
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -19
- package/tsconfig.lib.prod.json +0 -7
- package/tsconfig.spec.json +0 -31
- package/vite.config.mts +0 -10
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { HttpParams } from '@angular/common/http';
|
|
2
|
+
import { Injectable, Injector, inject, runInInjectionContext, } from '@angular/core';
|
|
3
|
+
import { Firestore as AngularFirestore, collection, } from '@angular/fire/firestore';
|
|
4
|
+
import { SneatApiService, SneatFirestoreService } from '@sneat/api';
|
|
5
|
+
import { AuthStatuses, SneatAuthStateService, } from '@sneat/auth-core';
|
|
6
|
+
import { ErrorLogger } from '@sneat/core';
|
|
7
|
+
import { zipMapBriefsWithIDs, } from '@sneat/space-models';
|
|
8
|
+
import { SneatUserService } from '@sneat/auth-core';
|
|
9
|
+
import { BehaviorSubject, throwError, } from 'rxjs';
|
|
10
|
+
import { filter, first, map, tap } from 'rxjs/operators';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
const spaceBriefFromUserSpaceInfo = (v) => ({
|
|
13
|
+
...v,
|
|
14
|
+
type: v.type,
|
|
15
|
+
});
|
|
16
|
+
// export class CachedDataService<Brief, Dbo extends Brief> {
|
|
17
|
+
// constructor(
|
|
18
|
+
// private readonly db: AngularFirestore,
|
|
19
|
+
// ) {
|
|
20
|
+
// }
|
|
21
|
+
//
|
|
22
|
+
// // watchRecord()
|
|
23
|
+
// }
|
|
24
|
+
export class SpaceService {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.sneatAuthStateService = inject(SneatAuthStateService);
|
|
27
|
+
this.errorLogger = inject(ErrorLogger);
|
|
28
|
+
this.afs = inject(AngularFirestore);
|
|
29
|
+
this.userService = inject(SneatUserService);
|
|
30
|
+
this.sneatApiService = inject(SneatApiService);
|
|
31
|
+
this.spaces$ = {};
|
|
32
|
+
this.subscriptions = [];
|
|
33
|
+
this.injector = inject(Injector);
|
|
34
|
+
this.processUserRecordInSpaceService = (userState) => {
|
|
35
|
+
const user = userState?.record;
|
|
36
|
+
if (!user) {
|
|
37
|
+
// this.userID = undefined;
|
|
38
|
+
if (userState.status === AuthStatuses.notAuthenticated &&
|
|
39
|
+
this.subscriptions?.length) {
|
|
40
|
+
this.unsubscribe('user is not authenticated and active team subscriptions');
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (userState.user?.uid !== this.userID) {
|
|
45
|
+
if (this.userID) {
|
|
46
|
+
this.unsubscribe('user id changed');
|
|
47
|
+
}
|
|
48
|
+
this.userID = userState.user?.uid;
|
|
49
|
+
}
|
|
50
|
+
this.currentUserSpaces = user?.spaces;
|
|
51
|
+
zipMapBriefsWithIDs(user.spaces).forEach(this.subscribeForUserSpaceChanges);
|
|
52
|
+
};
|
|
53
|
+
this.subscribeForUserSpaceChanges = (userSpaceBrief) => {
|
|
54
|
+
let subj = this.spaces$[userSpaceBrief.id];
|
|
55
|
+
if (subj) {
|
|
56
|
+
let space = subj.value;
|
|
57
|
+
if (space && !space?.type) {
|
|
58
|
+
space = {
|
|
59
|
+
...space,
|
|
60
|
+
type: userSpaceBrief.brief?.type,
|
|
61
|
+
brief: spaceBriefFromUserSpaceInfo(userSpaceBrief.brief),
|
|
62
|
+
};
|
|
63
|
+
subj.next(space);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const space = {
|
|
68
|
+
id: userSpaceBrief.id,
|
|
69
|
+
type: userSpaceBrief.brief.type,
|
|
70
|
+
brief: spaceBriefFromUserSpaceInfo(userSpaceBrief.brief),
|
|
71
|
+
};
|
|
72
|
+
this.spaces$[space.id] = subj = new BehaviorSubject(space);
|
|
73
|
+
this.subscribeForSpaceChanges(space.id, subj);
|
|
74
|
+
};
|
|
75
|
+
const sneatAuthStateService = this.sneatAuthStateService;
|
|
76
|
+
// console.log('SpaceService.constructor()');
|
|
77
|
+
this.sfs = new SneatFirestoreService(this.injector, (id, dto) => ({
|
|
78
|
+
id,
|
|
79
|
+
...dto,
|
|
80
|
+
}));
|
|
81
|
+
const onAuthStatusChanged = (status) => {
|
|
82
|
+
if (status === 'notAuthenticated') {
|
|
83
|
+
this.unsubscribe('signed out');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
sneatAuthStateService.authStatus.subscribe(onAuthStatusChanged);
|
|
87
|
+
// We are intentionally not un-subscribing from user record updates. TODO: why?
|
|
88
|
+
this.userService.userState.subscribe({
|
|
89
|
+
next: this.processUserRecordInSpaceService,
|
|
90
|
+
error: this.errorLogger.logErrorHandler('failed to load user record'),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
createSpace(request) {
|
|
94
|
+
return this.sneatApiService
|
|
95
|
+
.post('spaces/create_space', request)
|
|
96
|
+
.pipe(map((response) => response.space));
|
|
97
|
+
}
|
|
98
|
+
// public getSpace(ref: ISpaceRef): Observable<ISpaceContext> {
|
|
99
|
+
// return this.watchSpace(ref).pipe(first());
|
|
100
|
+
// }
|
|
101
|
+
watchSpace(id) {
|
|
102
|
+
if (!id) {
|
|
103
|
+
throw new Error('space id is a required parameter');
|
|
104
|
+
}
|
|
105
|
+
if (id === 'contacts') {
|
|
106
|
+
throw new Error('watchSpace({i}d===contacts})');
|
|
107
|
+
}
|
|
108
|
+
let subj = this.spaces$[id];
|
|
109
|
+
if (subj) {
|
|
110
|
+
return subj.asObservable().pipe(filter((s) => !!s));
|
|
111
|
+
}
|
|
112
|
+
let spaceContext = undefined;
|
|
113
|
+
if (this.currentUserSpaces) {
|
|
114
|
+
const userSpaceInfo = this.currentUserSpaces[id];
|
|
115
|
+
if (userSpaceInfo) {
|
|
116
|
+
spaceContext = {
|
|
117
|
+
id,
|
|
118
|
+
type: userSpaceInfo.type,
|
|
119
|
+
brief: spaceBriefFromUserSpaceInfo(userSpaceInfo),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
subj = new BehaviorSubject(spaceContext);
|
|
124
|
+
this.spaces$[id] = subj;
|
|
125
|
+
if (this.userService.currentUserID) {
|
|
126
|
+
this.subscribeForSpaceChanges(id, subj);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.userService.userState
|
|
130
|
+
.pipe(filter((v) => v.status === AuthStatuses.authenticated), first())
|
|
131
|
+
.subscribe({
|
|
132
|
+
next: () => this.subscribeForSpaceChanges(id, subj),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return subj.asObservable().pipe(filter((s) => !!s));
|
|
136
|
+
}
|
|
137
|
+
onSpaceUpdated(space) {
|
|
138
|
+
let team$ = this.spaces$[space.id];
|
|
139
|
+
if (team$) {
|
|
140
|
+
const prevTeam = team$.value;
|
|
141
|
+
space = { ...prevTeam, ...space };
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.spaces$[space.id] = team$ = new BehaviorSubject(space);
|
|
145
|
+
}
|
|
146
|
+
team$.next(space);
|
|
147
|
+
}
|
|
148
|
+
leaveSpace(request) {
|
|
149
|
+
return this.sneatApiService.post('space/leave_space', request);
|
|
150
|
+
}
|
|
151
|
+
updateRelated(request) {
|
|
152
|
+
return this.sneatApiService.post('space/update_related', request);
|
|
153
|
+
}
|
|
154
|
+
// TODO: move to separate module
|
|
155
|
+
deleteMetrics(space, metrics) {
|
|
156
|
+
return this.sneatApiService.post('space/remove_metrics', {
|
|
157
|
+
space,
|
|
158
|
+
metrics,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// TODO: move to separate module
|
|
162
|
+
addMetric(space, metric) {
|
|
163
|
+
if (!space) {
|
|
164
|
+
return throwError(() => 'space parameter is required');
|
|
165
|
+
}
|
|
166
|
+
const params = new HttpParams({ fromObject: { id: space } });
|
|
167
|
+
return this.sneatApiService.post('space/add_metric?' + params.toString(), {
|
|
168
|
+
metric,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
subscribeForSpaceChanges(id, subj) {
|
|
172
|
+
if (id === 'contacts') {
|
|
173
|
+
throw new Error('subscribeForSpaceChanges(id===contacts)');
|
|
174
|
+
}
|
|
175
|
+
const spacesCollection = runInInjectionContext(this.injector, () => collection(this.afs, 'spaces'));
|
|
176
|
+
const o = this.sfs
|
|
177
|
+
.watchByID(spacesCollection, id)
|
|
178
|
+
.pipe(map((team) => {
|
|
179
|
+
// const _prevTeam = this.spaces$[id].value;
|
|
180
|
+
// if (prevTeam.assets) {
|
|
181
|
+
// team = { ...team, assets: prevTeam.assets};
|
|
182
|
+
// console.log('Reusing assets from prev context');
|
|
183
|
+
// }
|
|
184
|
+
return team;
|
|
185
|
+
}), tap(() => {
|
|
186
|
+
// subj.next(team);
|
|
187
|
+
}));
|
|
188
|
+
this.subscriptions.push(o.subscribe({
|
|
189
|
+
next: (v) => subj.next(v), // Do not use as "next: subj.next" because it will be called with wrong "this" context
|
|
190
|
+
error: (err) => subj.error(err),
|
|
191
|
+
}));
|
|
192
|
+
}
|
|
193
|
+
unsubscribe(_reason) {
|
|
194
|
+
try {
|
|
195
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
196
|
+
this.subscriptions = [];
|
|
197
|
+
this.spaces$ = {};
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
this.errorLogger.logError(e, 'SpaceService failed to unsubscribe');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SpaceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
204
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SpaceService }); }
|
|
205
|
+
}
|
|
206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SpaceService, decorators: [{
|
|
207
|
+
type: Injectable
|
|
208
|
+
}], ctorParameters: () => [] });
|
|
209
|
+
//# sourceMappingURL=space.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space.service.js","sourceRoot":"","sources":["../../../../../../../libs/space/services/src/lib/services/space.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpParams } from '@angular/common/http';\nimport {\n Injectable,\n Injector,\n inject,\n runInInjectionContext,\n} from '@angular/core';\nimport {\n Firestore as AngularFirestore,\n CollectionReference,\n collection,\n} from '@angular/fire/firestore';\nimport { SneatApiService, SneatFirestoreService } from '@sneat/api';\nimport {\n AuthStatus,\n AuthStatuses,\n SneatAuthStateService,\n} from '@sneat/auth-core';\nimport { IUserSpaceBrief } from '@sneat/auth-models';\nimport { IIdAndBrief } from '@sneat/core';\nimport { IRecord } from '@sneat/data';\nimport { ISpaceBrief, ISpaceDbo, ISpaceMetric } from '@sneat/dto';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport {\n ICreateSpaceRequest,\n ICreateSpaceResponse,\n ILeaveSpaceRequest,\n ISpaceContext,\n IUpdateRelatedRequest,\n zipMapBriefsWithIDs,\n} from '@sneat/space-models';\nimport { ISneatUserState, SneatUserService } from '@sneat/auth-core';\nimport {\n BehaviorSubject,\n Observable,\n Subject,\n Subscription,\n throwError,\n} from 'rxjs';\nimport { filter, first, map, tap } from 'rxjs/operators';\n\nconst spaceBriefFromUserSpaceInfo = (v: IUserSpaceBrief): ISpaceBrief => ({\n ...v,\n type: v.type,\n});\n\n// export class CachedDataService<Brief, Dbo extends Brief> {\n// \tconstructor(\n// \t\tprivate readonly db: AngularFirestore,\n// \t) {\n// \t}\n//\n// \t// watchRecord()\n// }\n\n@Injectable()\nexport class SpaceService {\n readonly sneatAuthStateService = inject(SneatAuthStateService);\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly afs = inject(AngularFirestore);\n private readonly userService = inject(SneatUserService);\n private readonly sneatApiService = inject(SneatApiService);\n\n private userID?: string;\n\n private currentUserSpaces?: Record<string, IUserSpaceBrief>;\n\n private spaces$: Record<string, BehaviorSubject<ISpaceContext | undefined>> =\n {};\n private subscriptions: Subscription[] = [];\n\n private readonly sfs: SneatFirestoreService<ISpaceBrief, ISpaceDbo>;\n\n private readonly injector = inject(Injector);\n\n constructor() {\n const sneatAuthStateService = this.sneatAuthStateService;\n\n // console.log('SpaceService.constructor()');\n this.sfs = new SneatFirestoreService<ISpaceBrief, ISpaceDbo>(\n this.injector,\n (id: string, dto: ISpaceDbo) => ({\n id,\n ...dto,\n }),\n );\n const onAuthStatusChanged = (status: AuthStatus): void => {\n if (status === 'notAuthenticated') {\n this.unsubscribe('signed out');\n }\n };\n sneatAuthStateService.authStatus.subscribe(onAuthStatusChanged);\n\n // We are intentionally not un-subscribing from user record updates. TODO: why?\n this.userService.userState.subscribe({\n next: this.processUserRecordInSpaceService,\n error: this.errorLogger.logErrorHandler('failed to load user record'),\n });\n }\n\n private readonly processUserRecordInSpaceService = (\n userState: ISneatUserState,\n ): void => {\n const user = userState?.record;\n if (!user) {\n // this.userID = undefined;\n if (\n userState.status === AuthStatuses.notAuthenticated &&\n this.subscriptions?.length\n ) {\n this.unsubscribe(\n 'user is not authenticated and active team subscriptions',\n );\n }\n return;\n }\n if (userState.user?.uid !== this.userID) {\n if (this.userID) {\n this.unsubscribe('user id changed');\n }\n this.userID = userState.user?.uid;\n }\n this.currentUserSpaces = user?.spaces;\n\n zipMapBriefsWithIDs(user.spaces).forEach(this.subscribeForUserSpaceChanges);\n };\n\n public createSpace(\n request: ICreateSpaceRequest,\n ): Observable<IRecord<ISpaceDbo>> {\n return this.sneatApiService\n .post<ICreateSpaceResponse>('spaces/create_space', request)\n .pipe(map((response: ICreateSpaceResponse) => response.space));\n }\n\n // public getSpace(ref: ISpaceRef): Observable<ISpaceContext> {\n // \treturn this.watchSpace(ref).pipe(first());\n // }\n\n public watchSpace(id: string): Observable<ISpaceContext> {\n if (!id) {\n throw new Error('space id is a required parameter');\n }\n if (id === 'contacts') {\n throw new Error('watchSpace({i}d===contacts})');\n }\n let subj = this.spaces$[id];\n if (subj) {\n return subj.asObservable().pipe(filter((s) => !!s));\n }\n let spaceContext: ISpaceContext | undefined = undefined;\n if (this.currentUserSpaces) {\n const userSpaceInfo = this.currentUserSpaces[id];\n if (userSpaceInfo) {\n spaceContext = {\n id,\n type: userSpaceInfo.type,\n brief: spaceBriefFromUserSpaceInfo(userSpaceInfo),\n };\n }\n }\n subj = new BehaviorSubject<ISpaceContext | undefined>(spaceContext);\n this.spaces$[id] = subj;\n if (this.userService.currentUserID) {\n this.subscribeForSpaceChanges(id, subj);\n } else {\n this.userService.userState\n .pipe(\n filter((v) => v.status === AuthStatuses.authenticated),\n first(),\n )\n .subscribe({\n next: () => this.subscribeForSpaceChanges(id, subj),\n });\n }\n return subj.asObservable().pipe(filter((s) => !!s));\n }\n\n public onSpaceUpdated(space: ISpaceContext): void {\n let team$ = this.spaces$[space.id];\n if (team$) {\n const prevTeam = team$.value;\n space = { ...prevTeam, ...space };\n } else {\n this.spaces$[space.id] = team$ = new BehaviorSubject<\n ISpaceContext | undefined\n >(space);\n }\n team$.next(space);\n }\n\n public leaveSpace(request: ILeaveSpaceRequest): Observable<void> {\n return this.sneatApiService.post('space/leave_space', request);\n }\n\n public updateRelated(request: IUpdateRelatedRequest): Observable<void> {\n return this.sneatApiService.post('space/update_related', request);\n }\n\n // TODO: move to separate module\n public deleteMetrics(space: string, metrics: string[]): Observable<void> {\n return this.sneatApiService.post('space/remove_metrics', {\n space,\n metrics,\n });\n }\n\n // TODO: move to separate module\n public addMetric(space: string, metric: ISpaceMetric): Observable<void> {\n if (!space) {\n return throwError(() => 'space parameter is required');\n }\n const params = new HttpParams({ fromObject: { id: space } });\n return this.sneatApiService.post('space/add_metric?' + params.toString(), {\n metric,\n });\n }\n\n private readonly subscribeForUserSpaceChanges = (\n userSpaceBrief: IIdAndBrief<IUserSpaceBrief>,\n ): void => {\n let subj = this.spaces$[userSpaceBrief.id];\n if (subj) {\n let space = subj.value;\n if (space && !space?.type) {\n space = {\n ...space,\n type: userSpaceBrief.brief?.type,\n brief: spaceBriefFromUserSpaceInfo(userSpaceBrief.brief),\n };\n subj.next(space);\n }\n return;\n }\n\n const space: ISpaceContext = {\n id: userSpaceBrief.id,\n type: userSpaceBrief.brief.type,\n brief: spaceBriefFromUserSpaceInfo(userSpaceBrief.brief),\n };\n this.spaces$[space.id] = subj = new BehaviorSubject<\n ISpaceContext | undefined\n >(space);\n this.subscribeForSpaceChanges(space.id, subj);\n };\n\n private subscribeForSpaceChanges(\n id: string,\n subj: Subject<ISpaceContext | undefined>,\n ): void {\n if (id === 'contacts') {\n throw new Error('subscribeForSpaceChanges(id===contacts)');\n }\n const spacesCollection = runInInjectionContext(\n this.injector,\n () => collection(this.afs, 'spaces') as CollectionReference<ISpaceDbo>,\n );\n const o: Observable<ISpaceContext> = this.sfs\n .watchByID(spacesCollection, id)\n .pipe(\n map((team) => {\n // const _prevTeam = this.spaces$[id].value;\n // if (prevTeam.assets) {\n // \tteam = { ...team, assets: prevTeam.assets};\n // \tconsole.log('Reusing assets from prev context');\n // }\n return team;\n }),\n tap(() => {\n // subj.next(team);\n }),\n );\n\n this.subscriptions.push(\n o.subscribe({\n next: (v) => subj.next(v), // Do not use as \"next: subj.next\" because it will be called with wrong \"this\" context\n error: (err) => subj.error(err),\n }),\n );\n }\n\n private unsubscribe(_reason?: string): void {\n try {\n this.subscriptions.forEach((s) => s.unsubscribe());\n this.subscriptions = [];\n this.spaces$ = {};\n } catch (e) {\n this.errorLogger.logError(e, 'SpaceService failed to unsubscribe');\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sneat-space-services.js","sourceRoot":"","sources":["../../../../../libs/space/services/src/sneat-space-services.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC","sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"]}
|
|
@@ -4,5 +4,4 @@ export * from './lib/services/space.service';
|
|
|
4
4
|
export * from './lib/services/space-item.service';
|
|
5
5
|
export * from './lib/services/space-context.service';
|
|
6
6
|
export * from './lib/services/space-module.service';
|
|
7
|
-
|
|
8
7
|
export * from './lib/components/with-space-input.directive';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ISpaceContext } from '@sneat/space-models';
|
|
2
|
+
import { SneatBaseComponent } from '@sneat/ui';
|
|
3
|
+
import { SpaceNavService } from '../services/space-nav.service';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare abstract class WithSpaceInput extends SneatBaseComponent {
|
|
6
|
+
protected readonly spaceNavService: SpaceNavService;
|
|
7
|
+
readonly $space: import("@angular/core").InputSignal<ISpaceContext>;
|
|
8
|
+
protected readonly $spaceID: import("@angular/core").Signal<string>;
|
|
9
|
+
private readonly spaceIDChanged;
|
|
10
|
+
protected spaceID$: import("rxjs").Observable<string | undefined>;
|
|
11
|
+
protected readonly $spaceType: import("@angular/core").Signal<import("@sneat/core").SpaceType | undefined>;
|
|
12
|
+
protected readonly $spaceRef: import("@angular/core").Signal<{
|
|
13
|
+
id: string;
|
|
14
|
+
type: import("@sneat/core").SpaceType | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
constructor();
|
|
17
|
+
protected onSpaceIdChanged(spaceID: string): void;
|
|
18
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<WithSpaceInput, never>;
|
|
19
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<WithSpaceInput, never, never, { "$space": { "alias": "$space"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ParamMap } from '@angular/router';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ISpaceContext } from '@sneat/space-models';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class SpaceContextService {
|
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaceContextService, never>;
|
|
7
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SpaceContextService>;
|
|
8
|
+
}
|
|
9
|
+
export declare function trackSpaceIdAndTypeFromRouteParameter(paramMap$: Observable<ParamMap>): Observable<ISpaceContext | undefined>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Injector } from '@angular/core';
|
|
2
|
+
import { Firestore as AngularFirestore, CollectionReference } from '@angular/fire/firestore';
|
|
3
|
+
import { QuerySnapshot } from '@firebase/firestore-types';
|
|
4
|
+
import { IQueryArgs, SneatApiService, SneatFirestoreService } from '@sneat/api';
|
|
5
|
+
import { IIdAndBriefAndDbo, IIdAndOptionalBriefAndOptionalDbo, ISpaceItemWithBriefAndDbo, ISpaceRef } from '@sneat/core';
|
|
6
|
+
import { ISpaceDbo } from '@sneat/dto';
|
|
7
|
+
import { ISpaceItemNavContext, ISpaceRequest } from '@sneat/space-models';
|
|
8
|
+
import { Observable } from 'rxjs';
|
|
9
|
+
declare abstract class SpaceItemBaseService<Brief, Dbo extends Brief> {
|
|
10
|
+
protected readonly injector: Injector;
|
|
11
|
+
readonly collectionName: string;
|
|
12
|
+
readonly afs: AngularFirestore;
|
|
13
|
+
readonly sneatApiService: SneatApiService;
|
|
14
|
+
protected readonly sfs: SneatFirestoreService<Brief, Dbo>;
|
|
15
|
+
protected constructor(injector: Injector, collectionName: string, afs: AngularFirestore, sneatApiService: SneatApiService);
|
|
16
|
+
private _collectionRef?;
|
|
17
|
+
protected abstract collectionRef<Dbo2 extends Dbo>(spaceID: string): CollectionReference<Dbo2>;
|
|
18
|
+
watchSpaceItemByIdWithSpaceRef<Dbo2 extends Dbo>(space: ISpaceRef, itemID: string): Observable<ISpaceItemNavContext<Brief, Dbo2>>;
|
|
19
|
+
protected queryItems<Dbo2 extends Dbo>(collectionRef: CollectionReference<Dbo2>, queryArgs?: IQueryArgs): Observable<IIdAndBriefAndDbo<Brief, Dbo2>[]>;
|
|
20
|
+
protected mapQueryItem<Dbo2 extends Dbo>(querySnapshot: QuerySnapshot<Dbo2>): IIdAndBriefAndDbo<Brief, Dbo2>[];
|
|
21
|
+
deleteSpaceItem<Response>(endpoint: string, request: ISpaceRequest): Observable<Response>;
|
|
22
|
+
createSpaceItem<Brief, Dbo extends Brief>(endpoint: string, spaceRef: ISpaceRef, request: ISpaceRequest): Observable<ISpaceItemWithBriefAndDbo<Brief, Dbo>>;
|
|
23
|
+
}
|
|
24
|
+
export declare class GlobalSpaceItemService<Brief, Dbo extends Brief> extends SpaceItemBaseService<Brief, Dbo> {
|
|
25
|
+
protected collectionRef<Dbo2 extends Dbo>(): CollectionReference<Dbo2>;
|
|
26
|
+
watchGlobalItems<Dbo2 extends Dbo>(queryArgs: IQueryArgs): Observable<IIdAndBriefAndDbo<Brief, Dbo2>[]>;
|
|
27
|
+
watchGlobalSpaceItemsWithSpaceRef<Dbo2 extends Dbo>(space: ISpaceRef, queryArgs: IQueryArgs): Observable<ISpaceItemWithBriefAndDbo<Brief, Dbo2>[]>;
|
|
28
|
+
watchGlobalSpaceItems<Dbo2 extends Dbo>(spaceID: string, queryArgs: IQueryArgs): Observable<IIdAndBriefAndDbo<Brief, Dbo2>[]>;
|
|
29
|
+
}
|
|
30
|
+
export declare class ModuleSpaceItemService<Brief, Dbo extends Brief> extends SpaceItemBaseService<Brief, Dbo> {
|
|
31
|
+
readonly moduleID: string;
|
|
32
|
+
protected readonly spacesCollection: CollectionReference<ISpaceDbo>;
|
|
33
|
+
constructor(injector: Injector, moduleID: string, collectionName: string, afs: AngularFirestore, sneatApiService: SneatApiService);
|
|
34
|
+
protected readonly dto2brief: (id: string, dto: Dbo) => {
|
|
35
|
+
id: string;
|
|
36
|
+
} & Dbo;
|
|
37
|
+
protected collectionRef<Dbo2 extends Dbo>(spaceID: string): CollectionReference<Dbo2>;
|
|
38
|
+
private readonly spaceRef;
|
|
39
|
+
watchModuleSpaceItem<Dbo2 extends Dbo>(space: ISpaceRef, itemID: string): Observable<IIdAndOptionalBriefAndOptionalDbo<Brief, Dbo2>>;
|
|
40
|
+
watchModuleSpaceItemsWithSpaceRef<Dbo2 extends Dbo>(space: ISpaceRef, queryArgs?: IQueryArgs): Observable<ISpaceItemWithBriefAndDbo<Brief, Dbo2>[]>;
|
|
41
|
+
watchModuleSpaceItems<Dbo2 extends Dbo>(spaceID: string, queryArgs?: IQueryArgs): Observable<IIdAndBriefAndDbo<Brief, Dbo2>[]>;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Injector } from '@angular/core';
|
|
2
|
+
import { Firestore as AngularFirestore } from '@angular/fire/firestore';
|
|
3
|
+
import { IIdAndBrief, IIdAndOptionalDbo } from '@sneat/core';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
import { ModuleSpaceItemService } from './space-item.service';
|
|
6
|
+
export declare abstract class SpaceModuleService<Dbo> extends ModuleSpaceItemService<Dbo, Dbo> {
|
|
7
|
+
protected constructor(injector: Injector, moduleID: string, afs: AngularFirestore);
|
|
8
|
+
watchSpaceModuleRecord(spaceID: string): Observable<IIdAndOptionalDbo<Dbo>>;
|
|
9
|
+
watchBriefs<ItemBrief>(spaceID: string, getBriefs: (dto?: Dbo) => Readonly<Record<string, ItemBrief>>): Observable<IIdAndBrief<ItemBrief>[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Params } from '@angular/router';
|
|
2
|
+
import { NavController } from '@ionic/angular';
|
|
3
|
+
import { IIdAndBrief } from '@sneat/core';
|
|
4
|
+
import { IMemberBrief } from '@sneat/contactus-core';
|
|
5
|
+
import { IRecord } from '@sneat/data';
|
|
6
|
+
import { ISpaceDbo } from '@sneat/dto';
|
|
7
|
+
import { ISpaceContext } from '@sneat/space-models';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
type NavigationOptions = NonNullable<Parameters<NavController['navigateRoot']>[1]>;
|
|
10
|
+
export type ScrumPageTab = 'team' | 'my' | 'risks' | 'qna';
|
|
11
|
+
export declare class SpaceNavService {
|
|
12
|
+
private readonly errorLogger;
|
|
13
|
+
private readonly navController;
|
|
14
|
+
private readonly analyticsService;
|
|
15
|
+
navigateToSpaces(animationDirection?: 'forward' | 'back'): void;
|
|
16
|
+
navigateToLogin(options?: {
|
|
17
|
+
returnTo?: string;
|
|
18
|
+
queryParams?: Params;
|
|
19
|
+
}): void;
|
|
20
|
+
navigateToUserProfile(): void;
|
|
21
|
+
navigateToSpace(space: ISpaceContext, animationDirection?: 'forward' | 'back'): Promise<boolean>;
|
|
22
|
+
navigateToMember(space: ISpaceContext, memberInfo: IIdAndBrief<IMemberBrief>): void;
|
|
23
|
+
navigateToAddMetric: (navController: NavController, team: IRecord<ISpaceDbo>) => void;
|
|
24
|
+
navigateBackToSpacePage(space: ISpaceContext, page: string, navOptions?: NavigationOptions): Promise<boolean>;
|
|
25
|
+
navigateForwardToSpacePage(space: ISpaceContext, page: string, navOptions?: NavigationOptions): Promise<boolean>;
|
|
26
|
+
private navigateToSpacePage;
|
|
27
|
+
private navForward;
|
|
28
|
+
private navToSpacePage;
|
|
29
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaceNavService, never>;
|
|
30
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SpaceNavService>;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class SpaceServiceModule {
|
|
3
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaceServiceModule, never>;
|
|
4
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<SpaceServiceModule, never, never, never>;
|
|
5
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<SpaceServiceModule>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SneatAuthStateService } from '@sneat/auth-core';
|
|
2
|
+
import { IRecord } from '@sneat/data';
|
|
3
|
+
import { ISpaceDbo, ISpaceMetric } from '@sneat/dto';
|
|
4
|
+
import { ICreateSpaceRequest, ILeaveSpaceRequest, ISpaceContext, IUpdateRelatedRequest } from '@sneat/space-models';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export declare class SpaceService {
|
|
8
|
+
readonly sneatAuthStateService: SneatAuthStateService;
|
|
9
|
+
private readonly errorLogger;
|
|
10
|
+
private readonly afs;
|
|
11
|
+
private readonly userService;
|
|
12
|
+
private readonly sneatApiService;
|
|
13
|
+
private userID?;
|
|
14
|
+
private currentUserSpaces?;
|
|
15
|
+
private spaces$;
|
|
16
|
+
private subscriptions;
|
|
17
|
+
private readonly sfs;
|
|
18
|
+
private readonly injector;
|
|
19
|
+
constructor();
|
|
20
|
+
private readonly processUserRecordInSpaceService;
|
|
21
|
+
createSpace(request: ICreateSpaceRequest): Observable<IRecord<ISpaceDbo>>;
|
|
22
|
+
watchSpace(id: string): Observable<ISpaceContext>;
|
|
23
|
+
onSpaceUpdated(space: ISpaceContext): void;
|
|
24
|
+
leaveSpace(request: ILeaveSpaceRequest): Observable<void>;
|
|
25
|
+
updateRelated(request: IUpdateRelatedRequest): Observable<void>;
|
|
26
|
+
deleteMetrics(space: string, metrics: string[]): Observable<void>;
|
|
27
|
+
addMetric(space: string, metric: ISpaceMetric): Observable<void>;
|
|
28
|
+
private readonly subscribeForUserSpaceChanges;
|
|
29
|
+
private subscribeForSpaceChanges;
|
|
30
|
+
private unsubscribe;
|
|
31
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaceService, never>;
|
|
32
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SpaceService>;
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sneat/space-services",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -13,5 +13,17 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"tslib": "2.8.1"
|
|
16
|
-
}
|
|
16
|
+
},
|
|
17
|
+
"module": "esm2022/sneat-space-services.js",
|
|
18
|
+
"typings": "sneat-space-services.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
"./package.json": {
|
|
21
|
+
"default": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./sneat-space-services.d.ts",
|
|
25
|
+
"default": "./esm2022/sneat-space-services.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false
|
|
17
29
|
}
|
package/eslint.config.js
DELETED
package/ng-package.json
DELETED
package/project.json
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "space-services",
|
|
3
|
-
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"projectType": "library",
|
|
5
|
-
"sourceRoot": "libs/space/services/src",
|
|
6
|
-
"prefix": "sneat",
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/angular:ng-packagr-lite",
|
|
10
|
-
"outputs": [
|
|
11
|
-
"{workspaceRoot}/dist/libs/space/services"
|
|
12
|
-
],
|
|
13
|
-
"options": {
|
|
14
|
-
"project": "libs/space/services/ng-package.json",
|
|
15
|
-
"tsConfig": "libs/space/services/tsconfig.lib.json"
|
|
16
|
-
},
|
|
17
|
-
"configurations": {
|
|
18
|
-
"production": {
|
|
19
|
-
"tsConfig": "libs/space/services/tsconfig.lib.prod.json"
|
|
20
|
-
},
|
|
21
|
-
"development": {}
|
|
22
|
-
},
|
|
23
|
-
"defaultConfiguration": "production"
|
|
24
|
-
},
|
|
25
|
-
"test": {
|
|
26
|
-
"executor": "@nx/vitest:test",
|
|
27
|
-
"outputs": [
|
|
28
|
-
"{workspaceRoot}/coverage/libs/space/services"
|
|
29
|
-
],
|
|
30
|
-
"options": {
|
|
31
|
-
"tsConfig": "libs/space/services/tsconfig.spec.json"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"lint": {
|
|
35
|
-
"executor": "@nx/eslint:lint"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
import { NavController } from '@ionic/angular';
|
|
3
|
-
import { AnalyticsService, ErrorLogger } from '@sneat/core';
|
|
4
|
-
import { SpaceNavService } from '../services/space-nav.service';
|
|
5
|
-
|
|
6
|
-
// Simplified test - complex component testing skipped for now
|
|
7
|
-
describe('WithSpaceInput', () => {
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
TestBed.configureTestingModule({
|
|
10
|
-
providers: [
|
|
11
|
-
{
|
|
12
|
-
provide: SpaceNavService,
|
|
13
|
-
useValue: {
|
|
14
|
-
navigateToSpace: vi.fn(),
|
|
15
|
-
navigateToSpaces: vi.fn(),
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
provide: NavController,
|
|
20
|
-
useValue: {
|
|
21
|
-
navigateRoot: vi.fn().mockResolvedValue(true),
|
|
22
|
-
navigateForward: vi.fn().mockResolvedValue(true),
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
provide: AnalyticsService,
|
|
27
|
-
useValue: { logEvent: vi.fn() },
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
provide: ErrorLogger,
|
|
31
|
-
useValue: { logError: vi.fn(), logErrorHandler: () => vi.fn() },
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should have SpaceNavService available', () => {
|
|
38
|
-
const service = TestBed.inject(SpaceNavService);
|
|
39
|
-
expect(service).toBeTruthy();
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { computed, Directive, effect, inject, input } from '@angular/core';
|
|
2
|
-
import { ISpaceContext } from '@sneat/space-models';
|
|
3
|
-
import { SneatBaseComponent } from '@sneat/ui';
|
|
4
|
-
import { BehaviorSubject, distinctUntilChanged } from 'rxjs';
|
|
5
|
-
import { SpaceNavService } from '../services/space-nav.service';
|
|
6
|
-
|
|
7
|
-
@Directive()
|
|
8
|
-
export abstract class WithSpaceInput extends SneatBaseComponent {
|
|
9
|
-
protected readonly spaceNavService = inject(SpaceNavService);
|
|
10
|
-
|
|
11
|
-
public readonly $space = input.required<ISpaceContext>();
|
|
12
|
-
|
|
13
|
-
protected readonly $spaceID = computed(() => this.$space().id);
|
|
14
|
-
private readonly spaceIDChanged = new BehaviorSubject<string | undefined>(
|
|
15
|
-
undefined,
|
|
16
|
-
);
|
|
17
|
-
protected spaceID$ = this.spaceIDChanged
|
|
18
|
-
.asObservable()
|
|
19
|
-
.pipe(this.takeUntilDestroyed(), distinctUntilChanged());
|
|
20
|
-
|
|
21
|
-
protected readonly $spaceType = computed(() => this.$space().type);
|
|
22
|
-
protected readonly $spaceRef = computed(() => ({
|
|
23
|
-
id: this.$spaceID(),
|
|
24
|
-
type: this.$spaceType(),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
constructor() {
|
|
28
|
-
super();
|
|
29
|
-
effect(() => {
|
|
30
|
-
const spaceID = this.$spaceID();
|
|
31
|
-
if (spaceID !== this.spaceIDChanged.value) {
|
|
32
|
-
this.onSpaceIdChanged(spaceID);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
protected onSpaceIdChanged(spaceID: string): void {
|
|
38
|
-
this.spaceIDChanged.next(spaceID);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { SpaceContextService } from './space-context.service';
|
|
4
|
-
|
|
5
|
-
describe('SpaceContextService', () => {
|
|
6
|
-
let service: SpaceContextService;
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
TestBed.configureTestingModule({});
|
|
10
|
-
service = TestBed.inject(SpaceContextService);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should be created', () => {
|
|
14
|
-
expect(service).toBeTruthy();
|
|
15
|
-
});
|
|
16
|
-
});
|