cyc-base 0.0.2 → 1.0.1
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/.editorconfig +17 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/tasks.json +42 -0
- package/README.md +4 -0
- package/angular.json +36 -0
- package/package.json +44 -16
- package/projects/cyc-base/README.md +26 -0
- package/projects/cyc-base/ng-package.json +7 -0
- package/projects/cyc-base/package.json +12 -0
- package/projects/cyc-base/src/classes/BasePage.ts +82 -0
- package/projects/cyc-base/src/classes/CommonPage.ts +211 -0
- package/projects/cyc-base/src/classes/ExtendedCommonPage.ts +125 -0
- package/projects/cyc-base/src/classes/FirebasePage.ts +66 -0
- package/projects/cyc-base/src/classes/SecurePage.ts +229 -0
- package/projects/cyc-base/src/components/mat-nav-bar/mat-nav-bar.component.html +21 -0
- package/projects/cyc-base/src/components/mat-nav-bar/mat-nav-bar.component.scss +5 -0
- package/projects/cyc-base/src/components/mat-nav-bar/mat-nav-bar.component.spec.ts +22 -0
- package/projects/cyc-base/src/components/mat-nav-bar/mat-nav-bar.component.ts +47 -0
- package/projects/cyc-base/src/lib/cyc-base.spec.ts +23 -0
- package/projects/cyc-base/src/lib/cyc-base.ts +15 -0
- package/projects/cyc-base/src/lib/shared-db.spec.ts +16 -0
- package/projects/cyc-base/src/lib/shared-db.ts +182 -0
- package/projects/cyc-base/src/public-api.ts +18 -0
- package/projects/cyc-base/tsconfig.lib.json +18 -0
- package/projects/cyc-base/tsconfig.lib.prod.json +11 -0
- package/projects/cyc-base/tsconfig.spec.json +15 -0
- package/tsconfig.json +39 -0
- package/fesm2022/cyc-base.mjs +0 -730
- package/fesm2022/cyc-base.mjs.map +0 -1
- package/index.d.ts +0 -333
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Auth, getAuth } from 'firebase/auth';
|
|
2
|
+
import { Database, getDatabase, ref } from 'firebase/database';
|
|
3
|
+
import { ExtendedCommonPage } from './ExtendedCommonPage';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @extends CommonPage
|
|
7
|
+
* @extends ExtendedCommonPage
|
|
8
|
+
*/
|
|
9
|
+
export class FirebasePage extends ExtendedCommonPage {
|
|
10
|
+
db!: Database;
|
|
11
|
+
auth!: Auth;
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
|
|
15
|
+
this.auth = getAuth();
|
|
16
|
+
this.db = getDatabase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get userRef() {
|
|
20
|
+
return ref(this.db, 'move_follow_up_2023/users');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get clusterRef() {
|
|
24
|
+
return ref(this.db, 'move_follow_up_2023/clusters');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get stRef() {
|
|
28
|
+
return ref(this.db, 'move_follow_up_2023/small_teams');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get cgRef() {
|
|
32
|
+
return ref(this.db, 'move_follow_up_2023/CGs');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get sheepRef() {
|
|
36
|
+
return ref(this.db, 'move_follow_up_2023/sheeps');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get sheepLogRef() {
|
|
40
|
+
return ref(this.db, 'move_follow_up_2023/sheeps_log');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get msjClassTypeRef() {
|
|
44
|
+
return ref(this.db, 'move_follow_up_2023/msj/msj_class_type');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get msjClassBatchRef() {
|
|
48
|
+
return ref(this.db, 'move_follow_up_2023/msj/msj_class_batch');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get msjClassTimeRef() {
|
|
52
|
+
return ref(this.db, 'move_follow_up_2023/msj/msj_class_time');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get msjStudBatchRef() {
|
|
56
|
+
return ref(this.db, 'move_follow_up_2023/msj/msj_student_batch_record');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get attRef() {
|
|
60
|
+
return ref(this.db, 'move_follow_up_2023/attendance/atts');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get titleRef() {
|
|
64
|
+
return ref(this.db, 'move_follow_up_2023/attendance/titles');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { Router } from '@angular/router';
|
|
2
|
+
import {
|
|
3
|
+
PERMISSION,
|
|
4
|
+
AppUser,
|
|
5
|
+
ClickAction,
|
|
6
|
+
Click,
|
|
7
|
+
MsjClassBatch,
|
|
8
|
+
} from 'cyc-type-def';
|
|
9
|
+
import { FirebasePage } from './FirebasePage';
|
|
10
|
+
import {
|
|
11
|
+
ref,
|
|
12
|
+
onValue,
|
|
13
|
+
push,
|
|
14
|
+
get,
|
|
15
|
+
equalTo,
|
|
16
|
+
orderByChild,
|
|
17
|
+
query,
|
|
18
|
+
} from 'firebase/database';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* using observable to read user
|
|
22
|
+
* replace BasePage
|
|
23
|
+
*
|
|
24
|
+
* ---
|
|
25
|
+
* @extends CommonPage
|
|
26
|
+
* @extends ExtendedCommonPage
|
|
27
|
+
* @extends FirebasePage
|
|
28
|
+
*/
|
|
29
|
+
export class SecurePage extends FirebasePage {
|
|
30
|
+
protected isSecure: boolean;
|
|
31
|
+
protected router: Router;
|
|
32
|
+
|
|
33
|
+
constructor(router: Router, isSecure: boolean) {
|
|
34
|
+
super();
|
|
35
|
+
|
|
36
|
+
this.isSecure = isSecure;
|
|
37
|
+
this.router = router;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override checkAccessAndLoadData() {
|
|
41
|
+
if (this.firebaseUser) {
|
|
42
|
+
if (this.user) {
|
|
43
|
+
if (this.user.permission == PERMISSION.NOT_VERIFIED && this.isSecure) {
|
|
44
|
+
// not verified user
|
|
45
|
+
// redirect to home page
|
|
46
|
+
this.navigateHome();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// if (this.user.permissions) {
|
|
50
|
+
// this.isSuperUser = this.user.permissions.includes(
|
|
51
|
+
// PERMISSION.SUPER_USER
|
|
52
|
+
// );
|
|
53
|
+
// }
|
|
54
|
+
|
|
55
|
+
this.checkPermission(this.user);
|
|
56
|
+
this.readData();
|
|
57
|
+
} else {
|
|
58
|
+
// user logged in but no data
|
|
59
|
+
// redirect to home page (how he came to here?)
|
|
60
|
+
if (this.isSecure) this.navigateHome();
|
|
61
|
+
// this.readData(); // navigated home, no need read data
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
// user not logged in
|
|
65
|
+
// redirect to home page
|
|
66
|
+
if (this.isSecure) this.navigateHome();
|
|
67
|
+
// this.readData(); // navigated home, no need read data
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
navigateHome(): void {
|
|
72
|
+
this.router.navigate(['']);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
loadTitle() {
|
|
76
|
+
const titleRef = ref(this.db, 'move_follow_up_2023/attendance/titles');
|
|
77
|
+
onValue(titleRef, (v) => {
|
|
78
|
+
if (v.exists()) {
|
|
79
|
+
this.arrTitle = Object.values(v.val());
|
|
80
|
+
this.arrTitleForRef = v.val();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
loadSheep() {
|
|
86
|
+
const sheepRef = ref(this.db, 'move_follow_up_2023/sheeps');
|
|
87
|
+
onValue(sheepRef, (v) => {
|
|
88
|
+
if (v.exists()) {
|
|
89
|
+
this.arrSheep = Object.values(v.val());
|
|
90
|
+
this.arrSheepForRef = v.val();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
loadAttendance() {}
|
|
96
|
+
loadUsers() {}
|
|
97
|
+
loadUsersAsync() {
|
|
98
|
+
const userRef = ref(this.db, 'move_follow_up_2023/users');
|
|
99
|
+
return get(userRef);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
handleTitleSelected() {}
|
|
103
|
+
handleClusterSelected() {}
|
|
104
|
+
handleSmallTeamSelected() {}
|
|
105
|
+
handleCGSelected() {}
|
|
106
|
+
|
|
107
|
+
loadMsjClassType() {
|
|
108
|
+
const msjClassTypeRef = ref(
|
|
109
|
+
this.db,
|
|
110
|
+
'move_follow_up_2023/msj/msj_class_type'
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
return get(msjClassTypeRef);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
loadMsjClassBatch() {
|
|
117
|
+
const msjClassBatchRef = ref(
|
|
118
|
+
this.db,
|
|
119
|
+
'move_follow_up_2023/msj/msj_class_batch'
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return get(msjClassBatchRef);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
loadMsjClassTime(msjClassBatch?: MsjClassBatch) {
|
|
126
|
+
const msjClassTimeRef = ref(
|
|
127
|
+
this.db,
|
|
128
|
+
'move_follow_up_2023/msj/msj_class_time'
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
let q = query(msjClassTimeRef);
|
|
132
|
+
if (msjClassBatch)
|
|
133
|
+
q = query(
|
|
134
|
+
msjClassTimeRef,
|
|
135
|
+
orderByChild('idMsjClassBatch'),
|
|
136
|
+
equalTo(msjClassBatch.id)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
return get(q);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
recordClick(action: ClickAction) {
|
|
143
|
+
const testAccId = '5FUtbbtMe4RNPys6QSUzri5UXFN2';
|
|
144
|
+
const testAcc2Id = 'q1GEMXkzbWOOEg2wreNuPsTgCw52';
|
|
145
|
+
const testAcc3Id = 'XZUlKaa5aUhwJ2KlEa5oJfImwZA3';
|
|
146
|
+
const testAcc4Id = '9O3bSHbL2pfWBC9BOJiwMbkHQdr2';
|
|
147
|
+
const developerAccId = 'ZqdQyuc1uuTbAfmhkjw5HgLFnc82';
|
|
148
|
+
|
|
149
|
+
let userId = this.user?.id;
|
|
150
|
+
if (
|
|
151
|
+
userId == testAccId ||
|
|
152
|
+
userId == testAcc2Id ||
|
|
153
|
+
userId == testAcc3Id ||
|
|
154
|
+
userId == testAcc4Id ||
|
|
155
|
+
userId == developerAccId
|
|
156
|
+
) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const obj: Click = { action, timeStamp: new Date().getTime() };
|
|
161
|
+
if (userId) {
|
|
162
|
+
obj['userId'] = userId;
|
|
163
|
+
}
|
|
164
|
+
push(ref(this.db, 'move_follow_up_2023/attendance/clicks'), obj);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// FUNCTIONS INTERFACE
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Execute after reading user data from database
|
|
171
|
+
*
|
|
172
|
+
* @Override
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
this.firebaseUser = user;
|
|
176
|
+
if (user) {
|
|
177
|
+
const userRef = ref(this.db, 'move_follow_up_2023/users/' + user.uid);
|
|
178
|
+
onValue(userRef, (v) => {
|
|
179
|
+
if (v.exists()) {
|
|
180
|
+
this.user = v.val();
|
|
181
|
+
|
|
182
|
+
if (this.user.permission == PERMISSION.NOT_VERIFIED) {
|
|
183
|
+
// not verified user
|
|
184
|
+
// redirect to home page
|
|
185
|
+
router.navigate(['']);
|
|
186
|
+
// this.router.navigate(['']);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
this.checkPermission(this.user);
|
|
190
|
+
this.loadDataClone();
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
*
|
|
196
|
+
* @param user
|
|
197
|
+
*/
|
|
198
|
+
checkPermission(user: AppUser): void {
|
|
199
|
+
// console.log('checkPermission');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Execute after reading user data from database
|
|
204
|
+
*
|
|
205
|
+
* @Override
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
this.firebaseUser = user;
|
|
209
|
+
if (user) {
|
|
210
|
+
const userRef = ref(this.db, 'move_follow_up_2023/users/' + user.uid);
|
|
211
|
+
onValue(userRef, (v) => {
|
|
212
|
+
if (v.exists()) {
|
|
213
|
+
this.user = v.val();
|
|
214
|
+
|
|
215
|
+
if (this.user.permission == PERMISSION.NOT_VERIFIED) {
|
|
216
|
+
// not verified user
|
|
217
|
+
// redirect to home page
|
|
218
|
+
router.navigate(['']);
|
|
219
|
+
// this.router.navigate(['']);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.checkPermission(this.user);
|
|
223
|
+
this.loadDataClone();
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
*/
|
|
228
|
+
readData(): void {}
|
|
229
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<mat-toolbar style="padding-left: 8px; padding-right: 8px">
|
|
2
|
+
<button mat-icon-button (click)="toggleSideNav()">
|
|
3
|
+
<mat-icon>menu</mat-icon>
|
|
4
|
+
</button>
|
|
5
|
+
<span style="font-size: large"> {{ title() }} </span>
|
|
6
|
+
<span class="space"></span>
|
|
7
|
+
@if (user()) {
|
|
8
|
+
<mat-label style="font-size: x-small; text-wrap: wrap; line-height: 10px">{{
|
|
9
|
+
user().name ? user().name : user().phoneNum
|
|
10
|
+
}}</mat-label>
|
|
11
|
+
<button mat-icon-button (click)="logout()">
|
|
12
|
+
<mat-icon>exit_to_app</mat-icon>
|
|
13
|
+
</button>
|
|
14
|
+
} @else {
|
|
15
|
+
@if (!user()) {
|
|
16
|
+
<button mat-stroked-button routerLink="/login-email">
|
|
17
|
+
Login
|
|
18
|
+
</button>
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</mat-toolbar>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { MatNavBarComponent } from './mat-nav-bar.component';
|
|
4
|
+
|
|
5
|
+
describe('MatNavBarComponent', () => {
|
|
6
|
+
let component: MatNavBarComponent;
|
|
7
|
+
let fixture: ComponentFixture<MatNavBarComponent>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
imports: [MatNavBarComponent],
|
|
12
|
+
}).compileComponents();
|
|
13
|
+
|
|
14
|
+
fixture = TestBed.createComponent(MatNavBarComponent);
|
|
15
|
+
component = fixture.componentInstance;
|
|
16
|
+
fixture.detectChanges();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should create', () => {
|
|
20
|
+
expect(component).toBeTruthy();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Component, input, OnInit } from '@angular/core';
|
|
2
|
+
import { MatButtonModule, MatIconButton } from '@angular/material/button';
|
|
3
|
+
import { MatLabel } from '@angular/material/form-field';
|
|
4
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
5
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
6
|
+
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
7
|
+
import { RouterModule } from '@angular/router';
|
|
8
|
+
import { Auth, signOut } from 'firebase/auth';
|
|
9
|
+
import { AppUser } from 'cyc-type-def';
|
|
10
|
+
|
|
11
|
+
@Component({
|
|
12
|
+
selector: 'app-mat-nav-bar',
|
|
13
|
+
templateUrl: './mat-nav-bar.component.html',
|
|
14
|
+
styleUrls: ['./mat-nav-bar.component.scss'],
|
|
15
|
+
standalone: true,
|
|
16
|
+
imports: [
|
|
17
|
+
RouterModule,
|
|
18
|
+
MatLabel,
|
|
19
|
+
MatIconModule,
|
|
20
|
+
MatToolbarModule,
|
|
21
|
+
MatButtonModule,
|
|
22
|
+
MatMenuModule,
|
|
23
|
+
MatIconButton,
|
|
24
|
+
],
|
|
25
|
+
})
|
|
26
|
+
export class MatNavBarComponent implements OnInit {
|
|
27
|
+
user = input.required<AppUser>();
|
|
28
|
+
title = input.required<string>();
|
|
29
|
+
auth = input.required<Auth>();
|
|
30
|
+
|
|
31
|
+
constructor() {}
|
|
32
|
+
|
|
33
|
+
ngOnInit() {}
|
|
34
|
+
|
|
35
|
+
logout() {
|
|
36
|
+
signOut(this.auth())
|
|
37
|
+
.then(() => {
|
|
38
|
+
console.log('Signed out.');
|
|
39
|
+
window.location.reload();
|
|
40
|
+
})
|
|
41
|
+
.catch((err) => {});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
toggleSideNav() {
|
|
45
|
+
// this.helper.toggleSideNav();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { CycBase } from './cyc-base';
|
|
4
|
+
|
|
5
|
+
describe('CycBase', () => {
|
|
6
|
+
let component: CycBase;
|
|
7
|
+
let fixture: ComponentFixture<CycBase>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
imports: [CycBase]
|
|
12
|
+
})
|
|
13
|
+
.compileComponents();
|
|
14
|
+
|
|
15
|
+
fixture = TestBed.createComponent(CycBase);
|
|
16
|
+
component = fixture.componentInstance;
|
|
17
|
+
fixture.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
expect(component).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { SharedDb } from './shared-db';
|
|
4
|
+
|
|
5
|
+
describe('SharedDb', () => {
|
|
6
|
+
let service: SharedDb;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
TestBed.configureTestingModule({});
|
|
10
|
+
service = TestBed.inject(SharedDb);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should be created', () => {
|
|
14
|
+
expect(service).toBeTruthy();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { AppUser, CG, Cluster, SmallTeam } from 'cyc-type-def';
|
|
3
|
+
import { Auth, getAuth, onAuthStateChanged, User } from 'firebase/auth';
|
|
4
|
+
import { Database, getDatabase, onValue, ref } from 'firebase/database';
|
|
5
|
+
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
export interface AppData {
|
|
8
|
+
arrCluster?: Cluster[];
|
|
9
|
+
arrClusterForRef?: { [key: string]: Cluster };
|
|
10
|
+
|
|
11
|
+
arrSt?: SmallTeam[];
|
|
12
|
+
arrStForRef?: { [key: string]: SmallTeam };
|
|
13
|
+
|
|
14
|
+
arrCg?: CG[];
|
|
15
|
+
arrCgForRef?: { [key: string]: CG };
|
|
16
|
+
|
|
17
|
+
firebaseUser?: User | null;
|
|
18
|
+
user?: AppUser;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Injectable({
|
|
22
|
+
providedIn: 'root',
|
|
23
|
+
})
|
|
24
|
+
export class SharedDb {
|
|
25
|
+
private _db: Database;
|
|
26
|
+
private firebaseAuth: Auth;
|
|
27
|
+
|
|
28
|
+
private dataSubject = new BehaviorSubject<AppData>({});
|
|
29
|
+
private listeners: { [key: string]: any } = {};
|
|
30
|
+
private isInitialized = false;
|
|
31
|
+
|
|
32
|
+
// Public observable for components to subscribe to
|
|
33
|
+
public data$ = this.dataSubject.asObservable();
|
|
34
|
+
|
|
35
|
+
public auth$ = new ReplaySubject<{ user: AppUser; firebaseUser: User } | undefined>(1);
|
|
36
|
+
|
|
37
|
+
constructor() {
|
|
38
|
+
this._db = getDatabase();
|
|
39
|
+
this.firebaseAuth = getAuth();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async initializeData(): Promise<void> {
|
|
43
|
+
if (this.isInitialized) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this.isInitialized = true;
|
|
48
|
+
|
|
49
|
+
this.listenToCluster();
|
|
50
|
+
this.listenToSmallTeam();
|
|
51
|
+
this.listenToCG();
|
|
52
|
+
this.listenToUser();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private listenToCluster(): void {
|
|
56
|
+
const dataRef = ref(this.db, 'move_follow_up_2023/clusters');
|
|
57
|
+
|
|
58
|
+
this.listeners['clusters'] = onValue(dataRef, (snapshot) => {
|
|
59
|
+
// console.log('listenToCluster');
|
|
60
|
+
|
|
61
|
+
const obj: { [key: string]: Cluster } = snapshot.val();
|
|
62
|
+
this.updateData({ arrClusterForRef: obj });
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private listenToSmallTeam(): void {
|
|
67
|
+
const dataRef = ref(this.db, 'move_follow_up_2023/small_teams');
|
|
68
|
+
|
|
69
|
+
this.listeners['small_teams'] = onValue(dataRef, (snapshot) => {
|
|
70
|
+
// console.log('listenToSmallTeam');
|
|
71
|
+
|
|
72
|
+
const obj: { [key: string]: SmallTeam } = snapshot.val();
|
|
73
|
+
this.updateData({ arrStForRef: obj });
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private listenToCG(): void {
|
|
78
|
+
const dataRef = ref(this.db, 'move_follow_up_2023/CGs');
|
|
79
|
+
|
|
80
|
+
this.listeners['CGs'] = onValue(dataRef, (snapshot) => {
|
|
81
|
+
// console.log('listenToCG');
|
|
82
|
+
|
|
83
|
+
const obj: { [key: string]: CG } = snapshot.val();
|
|
84
|
+
this.updateData({ arrCgForRef: obj });
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private listenToUser(): void {
|
|
89
|
+
this.listeners['firebaseUser'] = onAuthStateChanged(this.firebaseAuth, (user) => {
|
|
90
|
+
console.log('auth change');
|
|
91
|
+
|
|
92
|
+
this.fetchUser(user);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private fetchUser(user: User | null) {
|
|
97
|
+
if (!user) {
|
|
98
|
+
this.auth$.next(undefined);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const dataRef = ref(this.db, 'move_follow_up_2023/users/' + user.uid);
|
|
103
|
+
onValue(dataRef, (snapshot) => {
|
|
104
|
+
console.log('userRef onValue');
|
|
105
|
+
|
|
106
|
+
if (snapshot.exists()) {
|
|
107
|
+
let _user: AppUser = snapshot.val();
|
|
108
|
+
this.auth$.next({ user: _user, firebaseUser: user });
|
|
109
|
+
} else {
|
|
110
|
+
this.auth$.next(undefined);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private updateData(newData: Partial<AppData>): void {
|
|
116
|
+
const currentData = this.dataSubject.value;
|
|
117
|
+
const updatedData = { ...currentData, ...newData };
|
|
118
|
+
this.dataSubject.next(updatedData);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get auth(): Observable<{ user: AppUser; firebaseUser: User } | undefined> {
|
|
122
|
+
return new Observable((observer) => {
|
|
123
|
+
this.auth$.subscribe((data) => {
|
|
124
|
+
// console.log(data);
|
|
125
|
+
console.log('auth$');
|
|
126
|
+
|
|
127
|
+
if (!data) {
|
|
128
|
+
observer.next(undefined);
|
|
129
|
+
} else {
|
|
130
|
+
observer.next({
|
|
131
|
+
firebaseUser: data.firebaseUser,
|
|
132
|
+
user: data.user,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
get pastoralTeam(): Observable<AppData> {
|
|
140
|
+
return new Observable((observer) => {
|
|
141
|
+
this.data$.subscribe((data) => {
|
|
142
|
+
// console.log(data);
|
|
143
|
+
|
|
144
|
+
observer.next({
|
|
145
|
+
arrClusterForRef: data.arrClusterForRef,
|
|
146
|
+
arrStForRef: data.arrStForRef,
|
|
147
|
+
arrCgForRef: data.arrCgForRef,
|
|
148
|
+
// firebaseUser: data.firebaseUser,
|
|
149
|
+
// user: data.user,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
get cluster(): Observable<{ [key: string]: Cluster }> {
|
|
156
|
+
return new Observable((observer) => {
|
|
157
|
+
this.data$.subscribe((data) => {
|
|
158
|
+
observer.next(data.arrClusterForRef || {});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
get smallTeam(): Observable<{ [key: string]: SmallTeam }> {
|
|
164
|
+
return new Observable((observer) => {
|
|
165
|
+
this.data$.subscribe((data) => {
|
|
166
|
+
observer.next(data.arrStForRef || {});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
get CG(): Observable<{ [key: string]: CG }> {
|
|
172
|
+
return new Observable((observer) => {
|
|
173
|
+
this.data$.subscribe((data) => {
|
|
174
|
+
observer.next(data.arrCgForRef || {});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
get db() {
|
|
180
|
+
return this._db;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of cyc-base
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export * from './lib/cyc-base';
|
|
6
|
+
|
|
7
|
+
// service
|
|
8
|
+
export * from './lib/shared-db';
|
|
9
|
+
|
|
10
|
+
// base class
|
|
11
|
+
export * from './classes/CommonPage';
|
|
12
|
+
export * from './classes/ExtendedCommonPage';
|
|
13
|
+
export * from './classes/FirebasePage';
|
|
14
|
+
export * from './classes/SecurePage';
|
|
15
|
+
export * from './classes/BasePage';
|
|
16
|
+
|
|
17
|
+
// components
|
|
18
|
+
export * from './components/mat-nav-bar/mat-nav-bar.component';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
+
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
+
{
|
|
4
|
+
"extends": "../../tsconfig.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"outDir": "../../out-tsc/lib",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"declarationMap": true,
|
|
9
|
+
"inlineSources": true,
|
|
10
|
+
"types": []
|
|
11
|
+
},
|
|
12
|
+
"include": [
|
|
13
|
+
"src/**/*.ts"
|
|
14
|
+
],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"**/*.spec.ts"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
+
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
+
{
|
|
4
|
+
"extends": "./tsconfig.lib.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"declarationMap": false
|
|
7
|
+
},
|
|
8
|
+
"angularCompilerOptions": {
|
|
9
|
+
"compilationMode": "partial"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
+
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
+
{
|
|
4
|
+
"extends": "../../tsconfig.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"outDir": "../../out-tsc/spec",
|
|
7
|
+
"types": [
|
|
8
|
+
"jasmine"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"src/**/*.d.ts",
|
|
13
|
+
"src/**/*.spec.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|