unictive-angular 1.0.15 → 1.0.16
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/bin/index.js +4 -1
- package/package.json +1 -1
- package/coba/.editorconfig +0 -17
- package/coba/.postcssrc.json +0 -12
- package/coba/.vscode/extensions.json +0 -4
- package/coba/.vscode/launch.json +0 -20
- package/coba/.vscode/tasks.json +0 -42
- package/coba/README.md +0 -59
- package/coba/angular.json +0 -102
- package/coba/package-lock.json +0 -10696
- package/coba/package.json +0 -48
- package/coba/public/favicon.ico +0 -0
- package/coba/src/app/MODULES/auth/README.md +0 -10
- package/coba/src/app/MODULES/dashboard/README.md +0 -10
- package/coba/src/app/MODULES/home/README.md +0 -10
- package/coba/src/app/app.config.ts +0 -20
- package/coba/src/app/app.html +0 -263
- package/coba/src/app/app.routes.ts +0 -3
- package/coba/src/app/app.scss +0 -6
- package/coba/src/app/app.spec.ts +0 -25
- package/coba/src/app/app.ts +0 -32
- package/coba/src/app/core/README.md +0 -10
- package/coba/src/app/core/config/README.md +0 -10
- package/coba/src/app/core/guards/README.md +0 -10
- package/coba/src/app/core/interceptors/README.md +0 -10
- package/coba/src/app/core/interceptors/error.interceptor.ts +0 -47
- package/coba/src/app/core/interceptors/jsonrpc.ts +0 -440
- package/coba/src/app/core/interceptors/jwt.interceptor.ts +0 -36
- package/coba/src/app/core/models/README.md +0 -10
- package/coba/src/app/core/services/README.md +0 -10
- package/coba/src/app/shared/README.md +0 -10
- package/coba/src/app/shared/directives/README.md +0 -10
- package/coba/src/app/shared/pipes/README.md +0 -10
- package/coba/src/app/shared/ui/README.md +0 -10
- package/coba/src/app/shared/utils/README.md +0 -10
- package/coba/src/app/shared/utils/logger.ts +0 -40
- package/coba/src/app/shared/widgets/test/test.component.css +0 -0
- package/coba/src/app/shared/widgets/test/test.component.html +0 -20
- package/coba/src/app/shared/widgets/test/test.component.ts +0 -56
- package/coba/src/app/shared/widgets/test/test.module.ts +0 -10
- package/coba/src/environments/environment.prod.ts +0 -6
- package/coba/src/environments/environment.staging.ts +0 -6
- package/coba/src/environments/environment.ts +0 -6
- package/coba/src/index.html +0 -16
- package/coba/src/main.ts +0 -6
- package/coba/src/styles.scss +0 -2
- package/coba/src/tailwind.css +0 -11
- package/coba/tailwind.config.js +0 -19
- package/coba/tsconfig.app.json +0 -15
- package/coba/tsconfig.json +0 -46
- package/coba/tsconfig.spec.json +0 -14
- package/test/node_modules/@tailwindcss/oxide-win32-x64-msvc/tailwindcss-oxide.win32-x64-msvc.node +0 -0
|
@@ -1,440 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HttpClient,
|
|
3
|
-
HttpEvent,
|
|
4
|
-
HttpEventType,
|
|
5
|
-
HttpHeaders,
|
|
6
|
-
HttpParams,
|
|
7
|
-
HttpRequest,
|
|
8
|
-
} from '@angular/common/http';
|
|
9
|
-
import { logger } from '@shared/utils/logger';
|
|
10
|
-
import { delay, lastValueFrom, Observable } from 'rxjs';
|
|
11
|
-
import { environment } from 'src/environments/environment';
|
|
12
|
-
|
|
13
|
-
export abstract class AbstractApiService<T> {
|
|
14
|
-
constructor(protected http: HttpClient, protected path: string) {}
|
|
15
|
-
|
|
16
|
-
protected createCustomHeaders(headers: {
|
|
17
|
-
[key: string]: string;
|
|
18
|
-
}): HttpHeaders {
|
|
19
|
-
let customHeaders = new HttpHeaders();
|
|
20
|
-
for (const key in headers) {
|
|
21
|
-
if (headers.hasOwnProperty(key)) {
|
|
22
|
-
customHeaders = customHeaders.set(key, headers[key]);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return customHeaders;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async export2(endpointURL?: string): Promise<any> {
|
|
29
|
-
return lastValueFrom(
|
|
30
|
-
this.http.get<any>(
|
|
31
|
-
`${environment.apiUrl}` + (endpointURL ? endpointURL : this.path),
|
|
32
|
-
{ responseType: 'blob' as 'json' }
|
|
33
|
-
)
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async exportPost(data: any, endpointURL?: string, param?: any): Promise<any> {
|
|
38
|
-
return lastValueFrom(
|
|
39
|
-
this.http.post<any>(
|
|
40
|
-
`${environment.apiUrl}` +
|
|
41
|
-
(endpointURL ? endpointURL : this.path) +
|
|
42
|
-
(param ? '?' + new HttpParams({ fromObject: param }).toString() : ''),
|
|
43
|
-
data,
|
|
44
|
-
{ responseType: 'blob' as 'json' }
|
|
45
|
-
)
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
//MARK:GET
|
|
50
|
-
async getAll(params?: any, endpointURL?: string): Promise<any> {
|
|
51
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
52
|
-
return lastValueFrom(
|
|
53
|
-
this.http.get<any>(
|
|
54
|
-
`${environment.apiUrl}` +
|
|
55
|
-
(endpointURL ? endpointURL : this.path) +
|
|
56
|
-
(param ? '?' + param : '')
|
|
57
|
-
)
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getById(id?: any, endpointURL?: string): Promise<any> {
|
|
62
|
-
return lastValueFrom(
|
|
63
|
-
this.http.get<any>(
|
|
64
|
-
`${environment.apiUrl}` +
|
|
65
|
-
(endpointURL ? endpointURL : this.path) +
|
|
66
|
-
'/' +
|
|
67
|
-
id
|
|
68
|
-
)
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async get(endpointURL?: string): Promise<any> {
|
|
73
|
-
return lastValueFrom(
|
|
74
|
-
this.http.get<any>(
|
|
75
|
-
`${environment.apiUrl}` + (endpointURL ? endpointURL : this.path)
|
|
76
|
-
)
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async getURL(url: string): Promise<any> {
|
|
81
|
-
return lastValueFrom(this.http.get<any>(url));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
//MARK:POST
|
|
85
|
-
|
|
86
|
-
async post(data: any, endpointURL?: string, param?: any): Promise<any> {
|
|
87
|
-
let params;
|
|
88
|
-
if (param) {
|
|
89
|
-
params = new HttpParams({ fromObject: param }).toString();
|
|
90
|
-
}
|
|
91
|
-
return lastValueFrom(
|
|
92
|
-
this.http.post<any>(
|
|
93
|
-
`${environment.apiUrl}` +
|
|
94
|
-
(endpointURL ? endpointURL : this.path) +
|
|
95
|
-
(params ? '?' + params : ''),
|
|
96
|
-
data
|
|
97
|
-
)
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
//POST with form data
|
|
102
|
-
|
|
103
|
-
async post_formdata_edited_array(
|
|
104
|
-
data: any,
|
|
105
|
-
endpointURL?: string,
|
|
106
|
-
params?: any
|
|
107
|
-
): Promise<any> {
|
|
108
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
109
|
-
let body = new FormData();
|
|
110
|
-
|
|
111
|
-
for (var key in data) {
|
|
112
|
-
// body.append(key, data[key]);
|
|
113
|
-
|
|
114
|
-
if (data[key] == null) {
|
|
115
|
-
body.append(key, '');
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (Array.isArray(data[key])) {
|
|
120
|
-
data[key].forEach((item: any) => {
|
|
121
|
-
body.append(`${key}[]`, item);
|
|
122
|
-
});
|
|
123
|
-
} else {
|
|
124
|
-
body.append(key, data[key]);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return lastValueFrom(
|
|
129
|
-
this.http.post<any>(
|
|
130
|
-
`${environment.apiUrl}` +
|
|
131
|
-
(endpointURL ? endpointURL : this.path) +
|
|
132
|
-
(param ? '?' + param : ''),
|
|
133
|
-
body,
|
|
134
|
-
{
|
|
135
|
-
headers: this.createCustomHeaders({
|
|
136
|
-
Accept: 'application/json',
|
|
137
|
-
// Add any other headers you need here
|
|
138
|
-
}),
|
|
139
|
-
}
|
|
140
|
-
)
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async acces_custom(endpointURL?: string, token?: any) {
|
|
145
|
-
return lastValueFrom(
|
|
146
|
-
this.http.get<any>(
|
|
147
|
-
`${environment.apiUrl}` + (endpointURL ? endpointURL : this.path),
|
|
148
|
-
{
|
|
149
|
-
headers: this.createCustomHeaders({
|
|
150
|
-
// Accept: 'application/json',
|
|
151
|
-
Authorization: `Bearer ${token}`, // Assuming token is a string
|
|
152
|
-
'Content-Type': 'application/json', // Set content type if needed
|
|
153
|
-
// Add any other headers you need here
|
|
154
|
-
}),
|
|
155
|
-
}
|
|
156
|
-
)
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async post_formdata(
|
|
161
|
-
data: any,
|
|
162
|
-
endpointURL?: string,
|
|
163
|
-
params?: any
|
|
164
|
-
): Promise<any> {
|
|
165
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
166
|
-
let body = new FormData();
|
|
167
|
-
|
|
168
|
-
for (var key in data) {
|
|
169
|
-
// body.append(key, data[key]);
|
|
170
|
-
|
|
171
|
-
if (Array.isArray(data[key])) {
|
|
172
|
-
data[key].forEach((item: any) => {
|
|
173
|
-
body.append(key, item == null ? '' : item);
|
|
174
|
-
});
|
|
175
|
-
} else {
|
|
176
|
-
body.append(key, data[key] == null ? '' : data[key]);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return lastValueFrom(
|
|
181
|
-
this.http.post<any>(
|
|
182
|
-
`${environment.apiUrl}` +
|
|
183
|
-
(endpointURL ? endpointURL : this.path) +
|
|
184
|
-
(param ? '?' + param : ''),
|
|
185
|
-
body,
|
|
186
|
-
{
|
|
187
|
-
headers: this.createCustomHeaders({
|
|
188
|
-
Accept: 'application/json',
|
|
189
|
-
// Add any other headers you need here
|
|
190
|
-
}),
|
|
191
|
-
}
|
|
192
|
-
)
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
//MARK:PUT
|
|
197
|
-
async putId(id: number | string, data: T, endpointURL?: string): Promise<T> {
|
|
198
|
-
return lastValueFrom(
|
|
199
|
-
this.http.put<T>(
|
|
200
|
-
`${environment.apiUrl}` +
|
|
201
|
-
(endpointURL ? endpointURL : this.path) +
|
|
202
|
-
'/' +
|
|
203
|
-
id,
|
|
204
|
-
data
|
|
205
|
-
)
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async put_custom(data: any, endpointURL?: string, params?: any): Promise<T> {
|
|
210
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
211
|
-
return lastValueFrom(
|
|
212
|
-
this.http.put<T>(
|
|
213
|
-
`${environment.apiUrl}` +
|
|
214
|
-
(endpointURL ? endpointURL : this.path) +
|
|
215
|
-
(param ? '?' + param : ''),
|
|
216
|
-
data
|
|
217
|
-
)
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
//put with form data
|
|
222
|
-
async put_formdata(
|
|
223
|
-
data: any,
|
|
224
|
-
endpointURL?: string,
|
|
225
|
-
params?: any
|
|
226
|
-
): Promise<Response> {
|
|
227
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
228
|
-
let body = new FormData();
|
|
229
|
-
for (var key in data) {
|
|
230
|
-
body.append(key, data[key]);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return lastValueFrom(
|
|
234
|
-
this.http.put<Response>(
|
|
235
|
-
`${environment.apiUrl}` +
|
|
236
|
-
(endpointURL ? endpointURL : this.path) +
|
|
237
|
-
(param ? '?' + param : ''),
|
|
238
|
-
body,
|
|
239
|
-
{
|
|
240
|
-
headers: this.createCustomHeaders({
|
|
241
|
-
Accept: 'application/json',
|
|
242
|
-
// Add any other headers you need here
|
|
243
|
-
}),
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
//MARK:DELETE
|
|
250
|
-
async delete(id: number | string, endpointURL?: string): Promise<Response> {
|
|
251
|
-
return lastValueFrom(
|
|
252
|
-
this.http.delete<Response>(
|
|
253
|
-
`${environment.apiUrl}` +
|
|
254
|
-
(endpointURL ? endpointURL : this.path) +
|
|
255
|
-
'/' +
|
|
256
|
-
id
|
|
257
|
-
)
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
async delete_param(params?: any, endpointURL?: string): Promise<any> {
|
|
261
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
262
|
-
return lastValueFrom(
|
|
263
|
-
this.http.delete<any>(
|
|
264
|
-
`${environment.apiUrl}` +
|
|
265
|
-
(endpointURL ? endpointURL : this.path) +
|
|
266
|
-
(param ? '?' + param : '')
|
|
267
|
-
)
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
//MARK:PATCH
|
|
272
|
-
async patch(
|
|
273
|
-
id: number | string,
|
|
274
|
-
partialdata: Partial<T>,
|
|
275
|
-
endpointURL?: string
|
|
276
|
-
): Promise<T> {
|
|
277
|
-
return lastValueFrom(
|
|
278
|
-
this.http.patch<T>(
|
|
279
|
-
`${environment.apiUrl}` +
|
|
280
|
-
(endpointURL ? endpointURL : this.path) +
|
|
281
|
-
'/' +
|
|
282
|
-
id,
|
|
283
|
-
partialdata
|
|
284
|
-
)
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
async post_formdata_custom(
|
|
289
|
-
data: any,
|
|
290
|
-
endpointURL?: string,
|
|
291
|
-
params?: any
|
|
292
|
-
): Promise<any> {
|
|
293
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
294
|
-
let body = this.jsonToFormData(data);
|
|
295
|
-
|
|
296
|
-
return lastValueFrom(
|
|
297
|
-
this.http.post<any>(
|
|
298
|
-
`${environment.apiUrl}` +
|
|
299
|
-
(endpointURL ? endpointURL : this.path) +
|
|
300
|
-
(param ? '?' + param : ''),
|
|
301
|
-
body,
|
|
302
|
-
{
|
|
303
|
-
headers: this.createCustomHeaders({
|
|
304
|
-
Accept: 'application/json',
|
|
305
|
-
// Add any other headers you need here
|
|
306
|
-
}),
|
|
307
|
-
}
|
|
308
|
-
)
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
async put_formdata_custom(
|
|
313
|
-
data: any,
|
|
314
|
-
endpointURL?: string,
|
|
315
|
-
params?: any
|
|
316
|
-
): Promise<any> {
|
|
317
|
-
let param = new HttpParams({ fromObject: params }).toString();
|
|
318
|
-
let body = this.jsonToFormData(data);
|
|
319
|
-
|
|
320
|
-
return lastValueFrom(
|
|
321
|
-
this.http.post<any>(
|
|
322
|
-
`${environment.apiUrl}` +
|
|
323
|
-
(endpointURL ? endpointURL : this.path) +
|
|
324
|
-
(param ? '?' + param : ''),
|
|
325
|
-
body,
|
|
326
|
-
{
|
|
327
|
-
headers: this.createCustomHeaders({
|
|
328
|
-
Accept: 'application/json',
|
|
329
|
-
// Add any other headers you need here
|
|
330
|
-
}),
|
|
331
|
-
}
|
|
332
|
-
)
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
uploadFile(file: File): Observable<HttpEvent<any>> {
|
|
337
|
-
const formData: FormData = new FormData();
|
|
338
|
-
formData.append('file', file);
|
|
339
|
-
|
|
340
|
-
const req = this.http.post('/api/upload', formData, {
|
|
341
|
-
reportProgress: true,
|
|
342
|
-
observe: 'events',
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
return req;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
consoleFormData(payload: any) {
|
|
349
|
-
const form = this.jsonToFormData(payload);
|
|
350
|
-
for (const [key, value] of form.entries()) {
|
|
351
|
-
console.log(`${key}: ${value}`);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
logger.log('Form Data:', form);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
jsonToFormData(
|
|
358
|
-
json: any,
|
|
359
|
-
formData: FormData = new FormData(),
|
|
360
|
-
parentKey: string = ''
|
|
361
|
-
): FormData {
|
|
362
|
-
for (const key in json) {
|
|
363
|
-
if (json.hasOwnProperty(key)) {
|
|
364
|
-
const value = json[key];
|
|
365
|
-
|
|
366
|
-
//console.log(value);
|
|
367
|
-
const newKey = parentKey ? `${parentKey}[${key}]` : key;
|
|
368
|
-
|
|
369
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
370
|
-
// Rekursif untuk nested object
|
|
371
|
-
if (value instanceof File) {
|
|
372
|
-
formData.append(newKey, value);
|
|
373
|
-
} else {
|
|
374
|
-
this.jsonToFormData(value, formData, newKey);
|
|
375
|
-
}
|
|
376
|
-
} else if (Array.isArray(value)) {
|
|
377
|
-
// Tangani array
|
|
378
|
-
value.forEach((item, index) => {
|
|
379
|
-
if (item && typeof item === 'object' && item.id !== undefined) {
|
|
380
|
-
// Array berisi objek dengan id
|
|
381
|
-
|
|
382
|
-
if (item?.isObject) {
|
|
383
|
-
for (const subKey in item) {
|
|
384
|
-
if (item.hasOwnProperty(subKey) && subKey != 'isObject') {
|
|
385
|
-
const subValue = item[subKey];
|
|
386
|
-
const newSubKey = `${newKey}[${item.id}][${subKey}]`;
|
|
387
|
-
if (subValue && typeof subValue === 'object') {
|
|
388
|
-
// this.jsonToFormData(subValue, formData, newSubKey);
|
|
389
|
-
formData.append(newSubKey, !subValue ? '' : subValue);
|
|
390
|
-
} else {
|
|
391
|
-
formData.append(newSubKey, !subValue ? '' : subValue);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
} else {
|
|
396
|
-
formData.append(
|
|
397
|
-
`${newKey}[${item.id}]`,
|
|
398
|
-
item?.value ? item.value : ''
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
} else {
|
|
402
|
-
// Array berisi objek sederhana
|
|
403
|
-
if (item?.isObject) {
|
|
404
|
-
for (const subKey in item) {
|
|
405
|
-
if (item.hasOwnProperty(subKey) && subKey != 'isObject') {
|
|
406
|
-
const subValue = item[subKey];
|
|
407
|
-
const newSubKey = `${newKey}[${index}][${subKey}]`;
|
|
408
|
-
if (subValue && typeof subValue === 'object') {
|
|
409
|
-
// this.jsonToFormData(subValue, formData, newSubKey);
|
|
410
|
-
formData.append(newSubKey, !subValue ? '' : subValue);
|
|
411
|
-
} else {
|
|
412
|
-
formData.append(newSubKey, !subValue ? '' : subValue);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
// Array berisi nilai sederhana
|
|
418
|
-
formData.append(
|
|
419
|
-
`${newKey}[${index}]`,
|
|
420
|
-
item === null || item === undefined ? '' : item
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
if (value.length === 0) {
|
|
427
|
-
formData.append(`${newKey}[]`, '');
|
|
428
|
-
}
|
|
429
|
-
} else {
|
|
430
|
-
// Nilai sederhana langsung append ke FormData
|
|
431
|
-
formData.append(
|
|
432
|
-
newKey,
|
|
433
|
-
value === null || value === undefined ? '' : value
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return formData;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { inject, Injectable } from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
HttpRequest,
|
|
4
|
-
HttpHandler,
|
|
5
|
-
HttpEvent,
|
|
6
|
-
HttpInterceptor,
|
|
7
|
-
HttpInterceptorFn,
|
|
8
|
-
} from '@angular/common/http';
|
|
9
|
-
import { Observable, finalize, from, switchMap } from 'rxjs';
|
|
10
|
-
|
|
11
|
-
import { StorageMap } from '@ngx-pwa/local-storage';
|
|
12
|
-
import { environment } from 'src/environments/environment';
|
|
13
|
-
|
|
14
|
-
export const jwtInterceptor: HttpInterceptorFn = (request, next) => {
|
|
15
|
-
// Assume you have access to StorageMap and environment
|
|
16
|
-
// You may need to inject StorageMap via a provider in your app module
|
|
17
|
-
const storage = inject(StorageMap);
|
|
18
|
-
|
|
19
|
-
return from(storage.get(environment.tokenName)).pipe(
|
|
20
|
-
switchMap((token: any) => {
|
|
21
|
-
if (token) {
|
|
22
|
-
request = request.clone({
|
|
23
|
-
setHeaders: {
|
|
24
|
-
Authorization: `Bearer ${token.token}`,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return next(request).pipe(
|
|
30
|
-
finalize(() => {
|
|
31
|
-
// end loading
|
|
32
|
-
})
|
|
33
|
-
);
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# MODELS
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **models**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# SERVICES
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **services**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# SHARED
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **shared**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# DIRECTIVES
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **directives**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# PIPES
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **pipes**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# UI
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **ui**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# UTILS
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **utils**.
|
|
4
|
-
|
|
5
|
-
- **domain** → berisi entity, interface, dan aturan bisnis murni
|
|
6
|
-
- **application** → berisi use case, service koordinasi domain
|
|
7
|
-
- **infrastructure** → berisi API call, repository, integrasi eksternal
|
|
8
|
-
- **presentation** → berisi komponen Angular, routing, dan UI
|
|
9
|
-
|
|
10
|
-
> Bagian ini adalah bagian dari arsitektur **Clean Architecture** untuk fitur ini.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { environment } from 'src/environments/environment';
|
|
2
|
-
|
|
3
|
-
export const logger = {
|
|
4
|
-
/**
|
|
5
|
-
* Log information when not in production
|
|
6
|
-
* @param label - Label for the information
|
|
7
|
-
* @param data - Data to log
|
|
8
|
-
*/
|
|
9
|
-
log(labelOrData: string | unknown, data?: unknown): void {
|
|
10
|
-
if (environment.envName != 'prod') {
|
|
11
|
-
if (typeof labelOrData === 'string' && data !== undefined) {
|
|
12
|
-
console.log(`🔥 [${labelOrData}]`, data);
|
|
13
|
-
} else {
|
|
14
|
-
console.log('🔥', labelOrData);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Log error when not in production
|
|
21
|
-
* @param label - Label for the error
|
|
22
|
-
* @param error - Error to log
|
|
23
|
-
*/
|
|
24
|
-
error(label: string, error: unknown): void {
|
|
25
|
-
if (environment.envName != 'prod') {
|
|
26
|
-
console.error(`❌ [${label}]`, error);
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Log warning when not in production
|
|
32
|
-
* @param label - Label for the warning
|
|
33
|
-
* @param data - Data to log
|
|
34
|
-
*/
|
|
35
|
-
warn(label: string, data: unknown): void {
|
|
36
|
-
if (environment.envName != 'prod') {
|
|
37
|
-
console.warn(`⚠️ [${label}]`, data);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
};
|
|
File without changes
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<div class="fixed inset-0 bgs z-50 flex items-center justify-center">
|
|
2
|
-
<div class="absolute transition-all duration-100 ease-in-out transform hover:scale-110"
|
|
3
|
-
style="padding: 50px; box-sizing: content-box;"
|
|
4
|
-
[ngStyle]="{ top: boxPosition.top, left: boxPosition.left, position: 'absolute' }" (mouseenter)="onMouseEnterBox()">
|
|
5
|
-
|
|
6
|
-
<div (click)="onLogout()"
|
|
7
|
-
class=" w-40 h-20 bg-black text-white flex items-center text-center justify-center cursor-pointer rounded-xl shadow-lg">
|
|
8
|
-
Tangkap
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
<div class="absolute top-5 right-5 text-white text-xl space-y-2 text-right bg-amber-900 p-2 rounded-2xl">
|
|
13
|
-
<div>Waktu: {{ timer }} detik</div>
|
|
14
|
-
<div>Skor: {{ score }}</div>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<div *ngIf="gameEnded" class="absolute bottom-10 text-white text-2xl font-bold">
|
|
18
|
-
Permainan Selesai! Skor akhir: {{ score }}
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Component, OnInit } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
@Component({
|
|
4
|
-
selector: 'app-test-box',
|
|
5
|
-
templateUrl: './test.component.html',
|
|
6
|
-
styleUrls: ['./test.component.css'],
|
|
7
|
-
standalone: false,
|
|
8
|
-
})
|
|
9
|
-
export class TestComponent implements OnInit {
|
|
10
|
-
boxPosition = { top: '50%', left: '50%' };
|
|
11
|
-
gameStarted = false;
|
|
12
|
-
gameEnded = false;
|
|
13
|
-
timer = 60;
|
|
14
|
-
score = 0;
|
|
15
|
-
intervalId: any;
|
|
16
|
-
constructor() { }
|
|
17
|
-
|
|
18
|
-
ngOnInit() {
|
|
19
|
-
this.startGame();
|
|
20
|
-
}
|
|
21
|
-
startGame() {
|
|
22
|
-
this.gameStarted = true;
|
|
23
|
-
this.timer = 60;
|
|
24
|
-
this.score = 0;
|
|
25
|
-
this.gameEnded = false;
|
|
26
|
-
this.moveBoxRandomly();
|
|
27
|
-
|
|
28
|
-
this.intervalId = setInterval(() => {
|
|
29
|
-
this.timer--;
|
|
30
|
-
if (this.timer <= 0) {
|
|
31
|
-
clearInterval(this.intervalId);
|
|
32
|
-
this.gameEnded = true;
|
|
33
|
-
}
|
|
34
|
-
}, 1000);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
onMouseEnterBox() {
|
|
38
|
-
if (!this.gameEnded) {
|
|
39
|
-
this.score++;
|
|
40
|
-
this.moveBoxRandomly();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
moveBoxRandomly() {
|
|
45
|
-
const top = Math.random() * 90;
|
|
46
|
-
const left = Math.random() * 90;
|
|
47
|
-
this.boxPosition = {
|
|
48
|
-
top: `${top}%`,
|
|
49
|
-
left: `${left}%`,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
onLogout() {
|
|
54
|
-
// this.auth.onLogout();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { TestComponent } from './test.component';
|
|
4
|
-
|
|
5
|
-
@NgModule({
|
|
6
|
-
imports: [CommonModule],
|
|
7
|
-
declarations: [TestComponent],
|
|
8
|
-
exports: [TestComponent],
|
|
9
|
-
})
|
|
10
|
-
export class TestBoxModule {}
|