unictive-angular 1.0.36 → 1.0.38
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/utils/createStructure.js +4 -0
- package/bin/utils/resource/.postcssrc.json +1 -2
- package/bin/utils/resource/src/app/API/auth/auth.service.ts +160 -0
- package/bin/utils/resource/src/app/PAGES/authentication/login/login.component.spec.ts +28 -0
- package/bin/utils/resource/src/app/{MODULES → PAGES}/authentication/login/login.component.ts +9 -3
- package/bin/utils/resource/src/app/PAGES/authentication/page404/page404.component.spec.ts +28 -0
- package/bin/utils/resource/src/app/{MODULES → PAGES}/authentication/page404/page404.component.ts +1 -2
- package/bin/utils/resource/src/app/PAGES/home/home.component.html +5 -0
- package/bin/utils/resource/src/app/PAGES/home/home.component.spec.ts +28 -0
- package/bin/utils/resource/src/app/{MODULES → PAGES}/home/home.component.ts +3 -3
- package/bin/utils/resource/src/app/app.config.ts +30 -0
- package/bin/utils/resource/src/app/app.routes.ts +4 -7
- package/bin/utils/resource/src/app/app.ts +6 -5
- package/bin/utils/resource/src/app/core/config/entity-store.ts +44 -15
- package/bin/utils/resource/src/app/core/config/single-store.ts +2 -0
- package/bin/utils/resource/src/app/core/guards/auth.guard.ts +43 -0
- package/bin/utils/resource/src/app/core/guards/login.guard.ts +37 -0
- package/bin/utils/resource/src/app/core/models/entities/user.entity.ts +36 -7
- package/bin/utils/resource/src/app/core/services/helper.service.ts +41 -28
- package/bin/utils/resource/src/app/core/services/listener.service.ts +25 -0
- package/bin/utils/resource/src/app/shared/ui/button/button.component.ts +96 -0
- package/bin/utils/resource/tsconfig.json +2 -2
- package/bin/utils/updatePackageJson.js +78 -54
- package/index.js +3 -2
- package/package.json +2 -2
- package/bin/utils/resource/src/app/MODULES/auth/README.md +0 -10
- package/bin/utils/resource/src/app/MODULES/authentication/login/login.module.ts +0 -19
- package/bin/utils/resource/src/app/MODULES/authentication/page404/page404.module.ts +0 -17
- package/bin/utils/resource/src/app/MODULES/authentication/register/register.component.html +0 -3
- package/bin/utils/resource/src/app/MODULES/authentication/register/register.component.ts +0 -16
- package/bin/utils/resource/src/app/MODULES/authentication/register/register.module.ts +0 -18
- package/bin/utils/resource/src/app/MODULES/dashboard/README.md +0 -10
- package/bin/utils/resource/src/app/MODULES/home/README.md +0 -10
- package/bin/utils/resource/src/app/MODULES/home/home.component.html +0 -4
- package/bin/utils/resource/src/app/MODULES/home/home.module.ts +0 -19
- package/bin/utils/resource/src/app/core/models/entities/screen.entity.spec.ts +0 -41
- package/bin/utils/resource/src/app/core/models/entities/screen.entity.ts +0 -16
- package/bin/utils/resource/src/app/core/respositories/screen_repo/screen.repo.ts +0 -19
- package/bin/utils/resource/src/app/core/respository/screen_repo/screen.repo.ts +0 -27
- package/bin/utils/resource/src/app/core/respository/user/user_repo.ts +0 -26
- package/bin/utils/resource/src/styles.scss +0 -2
- /package/bin/utils/resource/src/app/{MODULES/authentication/login/login.component.scss → PAGES/authentication/login/login.component.css} +0 -0
- /package/bin/utils/resource/src/app/{MODULES → PAGES}/authentication/login/login.component.html +0 -0
- /package/bin/utils/resource/src/app/{MODULES/authentication/page404/page404.component.scss → PAGES/authentication/page404/page404.component.css} +0 -0
- /package/bin/utils/resource/src/app/{MODULES → PAGES}/authentication/page404/page404.component.html +0 -0
- /package/bin/utils/resource/src/app/{MODULES/authentication/register/register.component.scss → PAGES/home/home.component.css} +0 -0
- /package/bin/utils/resource/src/{app/MODULES/home/home.component.scss → styles.css} +0 -0
|
@@ -1,15 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
import { singleStoreFactory } from "@core/config/single-store";
|
|
3
3
|
|
|
4
|
+
export interface User_m {
|
|
5
|
+
nip: string;
|
|
6
|
+
peopleId?: any;
|
|
7
|
+
peopleName?: string;
|
|
8
|
+
roleName?: string;
|
|
9
|
+
position?: string;
|
|
10
|
+
imageProfile?: string;
|
|
11
|
+
isCulture?: boolean;
|
|
12
|
+
isInovation?: boolean
|
|
13
|
+
branch?: string;
|
|
14
|
+
role?: Role_m[];
|
|
15
|
+
roleId?: number;
|
|
16
|
+
groupId?: number;
|
|
17
|
+
roleCode?: string;
|
|
18
|
+
apps: apps[];
|
|
19
|
+
}
|
|
4
20
|
|
|
21
|
+
export interface apps {
|
|
22
|
+
appId?: string;
|
|
23
|
+
show?: boolean;
|
|
24
|
+
active?: boolean;
|
|
25
|
+
count_notif?: number;
|
|
26
|
+
}
|
|
5
27
|
|
|
6
|
-
export interface
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
28
|
+
export interface Role_m {
|
|
29
|
+
id?: number;
|
|
30
|
+
people_id?: number;
|
|
31
|
+
branch?: string;
|
|
32
|
+
primary_role_id?: string;
|
|
33
|
+
position_name?: string;
|
|
34
|
+
role_atasan?: string;
|
|
35
|
+
group_id?: number;
|
|
36
|
+
is_active?: string;
|
|
37
|
+
start_date?: string;
|
|
38
|
+
end_date?: string;
|
|
39
|
+
parent_id?: number;
|
|
12
40
|
}
|
|
13
41
|
|
|
14
42
|
|
|
43
|
+
|
|
15
44
|
export const Entity_User = singleStoreFactory<User_m>();
|
|
@@ -185,51 +185,64 @@ export class HelperService {
|
|
|
185
185
|
Swal.close();
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
async confirmationAlert(data: Popup_m): Promise<boolean> {
|
|
189
|
-
switch (data.type) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
188
|
+
async confirmationAlert(data: Popup_m, strict = true): Promise<boolean> {
|
|
189
|
+
// switch (data.type) {
|
|
190
|
+
// case 'delete':
|
|
191
|
+
// data.icon = 'icon-delete.svg';
|
|
192
|
+
// break;
|
|
193
|
+
// case 'success':
|
|
194
|
+
// data.icon = 'icon-success.svg';
|
|
195
|
+
// break;
|
|
196
|
+
// case 'confirm':
|
|
197
|
+
// data.icon = 'icon-confirm.svg';
|
|
198
|
+
// break;
|
|
199
|
+
// case 'suspend':
|
|
200
|
+
// data.icon = 'icon-suspend.svg';
|
|
201
|
+
// break;
|
|
202
|
+
// case 'change':
|
|
203
|
+
// data.icon = 'icon-edit.svg';
|
|
204
|
+
// break;
|
|
205
|
+
// case 'send':
|
|
206
|
+
// data.icon = 'icon-send.png';
|
|
207
|
+
// break;
|
|
208
|
+
// case 'restore':
|
|
209
|
+
// data.icon = 'icon-restore.png';
|
|
210
|
+
// break;
|
|
211
|
+
// default:
|
|
212
|
+
// break;
|
|
213
|
+
// }
|
|
214
214
|
|
|
215
215
|
return Swal.fire({
|
|
216
216
|
html: `
|
|
217
|
-
<
|
|
218
|
-
<div class="
|
|
217
|
+
<h5 class="text-[18px] lg:text-[24px] font-semibold mb-2 text-[#272727]">${data.title}</h5>
|
|
218
|
+
<div class="text-[#272727]! text-[16px] leading-[1.2]">${data.message}</div>
|
|
219
219
|
`,
|
|
220
220
|
|
|
221
|
+
icon: data.icon ? 'info' : undefined,
|
|
221
222
|
showCancelButton: data?.showCancel ?? true,
|
|
222
223
|
confirmButtonText: data.button,
|
|
223
224
|
cancelButtonText: data?.button_cancel ? data.button_cancel : 'Batal',
|
|
224
225
|
reverseButtons: true,
|
|
226
|
+
|
|
225
227
|
confirmButtonColor: data.type == 'delete' ? '#D12114' : '#0072B9',
|
|
226
228
|
customClass: {
|
|
227
229
|
cancelButton: 'custom-cancel-button',
|
|
230
|
+
|
|
231
|
+
|
|
228
232
|
},
|
|
233
|
+
|
|
234
|
+
allowOutsideClick: strict, // klik luar modal
|
|
235
|
+
allowEscapeKey: strict, // tombol ESC
|
|
236
|
+
allowEnterKey: strict, // enter (opsional)
|
|
237
|
+
showCloseButton: strict,
|
|
229
238
|
}).then((result) => result.isConfirmed);
|
|
230
239
|
}
|
|
231
240
|
|
|
232
241
|
|
|
242
|
+
currentUrl() {
|
|
243
|
+
return this.router.url;
|
|
244
|
+
}
|
|
245
|
+
|
|
233
246
|
|
|
234
247
|
|
|
235
248
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Injectable, signal } from '@angular/core';
|
|
2
2
|
|
|
3
|
+
export type ForceLogoutReason =
|
|
4
|
+
| 'SESSION_TAKEN'
|
|
5
|
+
| 'TOKEN_EXPIRED'
|
|
6
|
+
| 'BANNED';
|
|
7
|
+
|
|
3
8
|
@Injectable({
|
|
4
9
|
providedIn: 'root'
|
|
5
10
|
})
|
|
@@ -10,6 +15,26 @@ export class ListenerService {
|
|
|
10
15
|
message: null,
|
|
11
16
|
});
|
|
12
17
|
|
|
18
|
+
|
|
19
|
+
forceLogout = signal<{
|
|
20
|
+
reason: ForceLogoutReason;
|
|
21
|
+
payload?: any;
|
|
22
|
+
at: number;
|
|
23
|
+
} | null>(null);
|
|
24
|
+
|
|
13
25
|
constructor() { }
|
|
14
26
|
|
|
27
|
+
|
|
28
|
+
emitForceLogout(reason: ForceLogoutReason, payload?: any) {
|
|
29
|
+
this.forceLogout.set({
|
|
30
|
+
reason,
|
|
31
|
+
payload,
|
|
32
|
+
at: Date.now()
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
clear() {
|
|
37
|
+
this.forceLogout.set(null);
|
|
38
|
+
}
|
|
39
|
+
|
|
15
40
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { NgClass } from '@angular/common';
|
|
2
|
+
import { Component, computed, EventEmitter, Input, input, OnInit, Output, signal } from '@angular/core';
|
|
3
|
+
import { ButtonModule } from 'primeng/button';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// import { ButtonModule } from 'primeng/button';
|
|
7
|
+
|
|
8
|
+
@Component({
|
|
9
|
+
selector: 'app-button',
|
|
10
|
+
template: `
|
|
11
|
+
<button
|
|
12
|
+
pButton
|
|
13
|
+
[type]="type"
|
|
14
|
+
[disabled]="isDisabled()"
|
|
15
|
+
[ngClass]="[class, variantClass]"
|
|
16
|
+
style="background:none;"
|
|
17
|
+
class="rounded-xl! flex items-center text-sm!"
|
|
18
|
+
(click)="handleClick()"
|
|
19
|
+
>
|
|
20
|
+
@if (loadings() && loading) {
|
|
21
|
+
<i class="pi pi-spinner animate-spin text-white"></i>
|
|
22
|
+
}
|
|
23
|
+
<ng-content>
|
|
24
|
+
Label
|
|
25
|
+
</ng-content>
|
|
26
|
+
</button>
|
|
27
|
+
`,
|
|
28
|
+
imports: [ButtonModule, NgClass],
|
|
29
|
+
})
|
|
30
|
+
export class ButtonComponent implements OnInit {
|
|
31
|
+
|
|
32
|
+
disabled: any = input(false);
|
|
33
|
+
internalDisabled = signal(false);
|
|
34
|
+
isDisabled = computed(() => this.internalDisabled() || this.disabled());
|
|
35
|
+
@Input() variant: 'primary' | 'outline-primary' | 'success' | 'warning' | 'secondary' | 'danger' | 'outline' | 'softblue' | 'gray' | 'white' | 'ghost' = 'primary';
|
|
36
|
+
@Input() type: 'button' | 'submit' = 'button';
|
|
37
|
+
@Input() class = '';
|
|
38
|
+
@Input() loading = false;
|
|
39
|
+
|
|
40
|
+
@Input() debounceTime = 2000; // waktu tunggu (2 detik)
|
|
41
|
+
private debounceTimer: any = null;
|
|
42
|
+
|
|
43
|
+
loadings = signal(false);
|
|
44
|
+
|
|
45
|
+
@Output() onClick = new EventEmitter<void>();
|
|
46
|
+
|
|
47
|
+
constructor() { }
|
|
48
|
+
|
|
49
|
+
ngOnInit() { }
|
|
50
|
+
|
|
51
|
+
handleClick() {
|
|
52
|
+
// logika anti spam klik berulang
|
|
53
|
+
if (!this.debounceTimer) {
|
|
54
|
+
this.onClick.emit();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.loadings.set(true);
|
|
58
|
+
|
|
59
|
+
clearTimeout(this.debounceTimer);
|
|
60
|
+
// set timer baru
|
|
61
|
+
this.debounceTimer = setTimeout(() => {
|
|
62
|
+
this.debounceTimer = null;
|
|
63
|
+
this.loadings.set(false);
|
|
64
|
+
}, this.debounceTime);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get variantClass() {
|
|
68
|
+
switch (this.variant) {
|
|
69
|
+
case 'primary':
|
|
70
|
+
return '!bg-[#206EE1] !border-[#206EE1] text-white hover:!bg-[#206EE1]/90';
|
|
71
|
+
case 'success':
|
|
72
|
+
return '!bg-[#15A244] !border-[#15A244] text-white hover:!bg-[#13b248]';
|
|
73
|
+
case 'warning':
|
|
74
|
+
return '!bg-[#CC8E12] !border-[#CC8E12] text-white hover:!bg-[#e09d17]';
|
|
75
|
+
case 'secondary':
|
|
76
|
+
return '!bg-[#EFF2F5] !border-[#EFF2F5] !text-[#050505] hover:!bg-[#E5E5E5]';
|
|
77
|
+
case 'danger':
|
|
78
|
+
return '!bg-[#D12D39] !border-[#D12D39] text-white hover:!bg-[#fd313f]';
|
|
79
|
+
case 'outline':
|
|
80
|
+
return '!bg-[#FFFFFF] !border-[#EFF2F5] !text-[#050505] hover:!bg-[#F8F9FA]';
|
|
81
|
+
case 'ghost':
|
|
82
|
+
return '!bg-transparent !border-none !text-[#585858]';
|
|
83
|
+
case 'softblue':
|
|
84
|
+
return '!text-primary !bg-[#e5f0fb] !border-[#e5f0fb] hover:!bg-[#d5e7f8]';
|
|
85
|
+
case 'gray':
|
|
86
|
+
return '!bg-[#EFF2F5] !border-[#EFF2F5] hover:!bg-[#E5E5E5] !text-[#6A6C6D]';
|
|
87
|
+
case 'outline-primary':
|
|
88
|
+
return '!bg-transparent !border-primary !text-primary';
|
|
89
|
+
case 'white':
|
|
90
|
+
return '!bg-[#FFFFFF70] !border-none !text-black hover:!bg-[#FFFFFF95]';
|
|
91
|
+
default:
|
|
92
|
+
return '!bg-primary !border-primary text-white hover:!bg-primary/90';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"@api/*": ["src/app/API/*"],
|
|
21
21
|
"@core": ["src/app/core"],
|
|
22
22
|
"@core/*": ["src/app/core/*"],
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
23
|
+
"@PAGES": ["src/app/PAGES"],
|
|
24
|
+
"@PAGES/*": ["src/app/PAGES/*"],
|
|
25
25
|
"@shared": ["src/app/shared"],
|
|
26
26
|
"@shared/*": ["src/app/shared/*"],
|
|
27
27
|
},
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { show_status } = require('./showStatus');
|
|
3
|
+
const { execSync} = require("child_process");
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const listPackagesToInstall = [
|
|
7
|
+
"npm i tailwindcss @tailwindcss/postcss postcss --force",
|
|
8
|
+
"npm i @ngx-pwa/local-storage --legacy-peer-deps",
|
|
9
|
+
"npm i primeng --legacy-peer-deps",
|
|
10
|
+
"npm i primeicons @primeuix/themes quill --legacy-peer-deps",
|
|
11
|
+
"npm i sweetalert2 --legacy-peer-deps"
|
|
12
|
+
];
|
|
3
13
|
|
|
4
14
|
|
|
5
15
|
// ===================== Update package.json =====================
|
|
6
|
-
function update_package_json() {
|
|
16
|
+
async function update_package_json() {
|
|
7
17
|
show_status("Memperbarui package.json...", "info");
|
|
8
18
|
|
|
9
19
|
const pkgPath = "package.json";
|
|
@@ -29,60 +39,74 @@ function update_package_json() {
|
|
|
29
39
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
30
40
|
show_status("package.json berhasil diperbarui dengan script build multi-env!", "success");
|
|
31
41
|
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
listPackagesToInstall.forEach(command => {
|
|
45
|
+
console.log(`Menjalankan: ${command}`);
|
|
46
|
+
try {
|
|
47
|
+
execSync(command, { stdio: 'inherit' });
|
|
48
|
+
show_status(`Berhasil menjalankan: ${command}`, "success");
|
|
49
|
+
} catch (error) {
|
|
50
|
+
show_status(`Gagal menjalankan: ${command}`, "error");
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
32
56
|
// ------------------- Angular file replacements -------------------
|
|
33
|
-
if (!fs.existsSync(angularJsonPath)) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, "utf8"));
|
|
39
|
-
|
|
40
|
-
// Pilih project
|
|
41
|
-
const projectNames = Object.keys(angularJson.projects);
|
|
42
|
-
const projectName = angularJson.defaultProject || projectNames[0];
|
|
43
|
-
|
|
44
|
-
const project = angularJson.projects[projectName];
|
|
45
|
-
const buildTarget = project.architect?.build || project.targets?.build;
|
|
46
|
-
|
|
47
|
-
if (!buildTarget) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const buildConfig = buildTarget.configurations || {};
|
|
53
|
-
|
|
54
|
-
// ------------------- Tambahkan environment config -------------------
|
|
55
|
-
buildConfig["dev"] = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
buildConfig["staging"] = {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
buildConfig["production"] = {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
buildTarget.configurations = buildConfig;
|
|
83
|
-
|
|
84
|
-
fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2));
|
|
85
|
-
show_status("angular.json berhasil diperbarui dengan file replacement multi-env!", "success");
|
|
57
|
+
// if (!fs.existsSync(angularJsonPath)) {
|
|
58
|
+
// show_status("⚠ angular.json tidak ditemukan! Lewati file replacement.", "warning");
|
|
59
|
+
// return;
|
|
60
|
+
// }
|
|
61
|
+
|
|
62
|
+
// const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, "utf8"));
|
|
63
|
+
|
|
64
|
+
// // Pilih project
|
|
65
|
+
// const projectNames = Object.keys(angularJson.projects);
|
|
66
|
+
// const projectName = angularJson.defaultProject || projectNames[0];
|
|
67
|
+
|
|
68
|
+
// const project = angularJson.projects[projectName];
|
|
69
|
+
// const buildTarget = project.architect?.build || project.targets?.build;
|
|
70
|
+
|
|
71
|
+
// if (!buildTarget) {
|
|
72
|
+
// show_status("⚠ Build target tidak ditemukan di angular.json!", "error");
|
|
73
|
+
// return;
|
|
74
|
+
// }
|
|
75
|
+
|
|
76
|
+
// const buildConfig = buildTarget.configurations || {};
|
|
77
|
+
|
|
78
|
+
// // ------------------- Tambahkan environment config -------------------
|
|
79
|
+
// buildConfig["dev"] = {
|
|
80
|
+
// fileReplacements: [
|
|
81
|
+
// {
|
|
82
|
+
// replace: "src/environments/environment.ts",
|
|
83
|
+
// with: "src/environments/environment.dev.ts"
|
|
84
|
+
// }
|
|
85
|
+
// ]
|
|
86
|
+
// };
|
|
87
|
+
|
|
88
|
+
// buildConfig["staging"] = {
|
|
89
|
+
// fileReplacements: [
|
|
90
|
+
// {
|
|
91
|
+
// replace: "src/environments/environment.ts",
|
|
92
|
+
// with: "src/environments/environment.staging.ts"
|
|
93
|
+
// }
|
|
94
|
+
// ]
|
|
95
|
+
// };
|
|
96
|
+
|
|
97
|
+
// buildConfig["production"] = {
|
|
98
|
+
// fileReplacements: [
|
|
99
|
+
// {
|
|
100
|
+
// replace: "src/environments/environment.ts",
|
|
101
|
+
// with: "src/environments/environment.prod.ts"
|
|
102
|
+
// }
|
|
103
|
+
// ]
|
|
104
|
+
// };
|
|
105
|
+
|
|
106
|
+
// buildTarget.configurations = buildConfig;
|
|
107
|
+
|
|
108
|
+
// fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2));
|
|
109
|
+
// show_status("angular.json berhasil diperbarui dengan file replacement multi-env!", "success");
|
|
86
110
|
}
|
|
87
111
|
|
|
88
112
|
module.exports = {update_package_json };
|
package/index.js
CHANGED
|
@@ -25,6 +25,7 @@ const chalk = require('chalk');
|
|
|
25
25
|
require('@dotenvx/dotenvx').config({ path: path.resolve(__dirname, ".env"), silent: true });
|
|
26
26
|
|
|
27
27
|
const { login, logout } = require("./bin/utils/auth");
|
|
28
|
+
const { update_package_json } = require("./bin/utils/updatePackageJson");
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
// Baca versi dari package.json
|
|
@@ -192,8 +193,8 @@ async function main() {
|
|
|
192
193
|
await sleep(1000);
|
|
193
194
|
refactorAngularJson();
|
|
194
195
|
await sleep(1000);
|
|
195
|
-
|
|
196
|
-
await run_with_spinner("npm install", "Menginstall dependencies...", "Dependencies berhasil diinstall!", "Gagal install dependencies");
|
|
196
|
+
await update_package_json();
|
|
197
|
+
// await run_with_spinner("npm install", "Menginstall dependencies...", "Dependencies berhasil diinstall!", "Gagal install dependencies");
|
|
197
198
|
await sleep(1000);
|
|
198
199
|
show_completion(projectName, OS);
|
|
199
200
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unictive-angular",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.38",
|
|
4
4
|
"description": "CLI untuk membuat project Angular dengan struktur kustom (Modules, Core, API, Shared).",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "npm version patch && npm publish"
|
|
6
|
+
"build": "npm version patch && npm publish --access public"
|
|
7
7
|
},
|
|
8
8
|
"bin": {
|
|
9
9
|
"unictive-angular": "./index.js"
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# AUTH
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **auth**.
|
|
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,19 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { LoginComponent } from './login.component';
|
|
4
|
-
import { RouterModule, Routes } from '@angular/router';
|
|
5
|
-
import { LibraryModule } from '@shared/libs/library.module';
|
|
6
|
-
|
|
7
|
-
const routes: Routes = [
|
|
8
|
-
{ path: '', component: LoginComponent }
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
@NgModule({
|
|
12
|
-
imports: [
|
|
13
|
-
CommonModule,
|
|
14
|
-
LibraryModule,
|
|
15
|
-
RouterModule.forChild(routes)
|
|
16
|
-
],
|
|
17
|
-
declarations: [LoginComponent]
|
|
18
|
-
})
|
|
19
|
-
export class LoginModule { }
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { Page404Component } from './page404.component';
|
|
4
|
-
import { RouterModule, Routes } from '@angular/router';
|
|
5
|
-
|
|
6
|
-
const routes: Routes = [
|
|
7
|
-
{ path: '', component: Page404Component }
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
@NgModule({
|
|
11
|
-
imports: [
|
|
12
|
-
CommonModule,
|
|
13
|
-
RouterModule.forChild(routes)
|
|
14
|
-
],
|
|
15
|
-
declarations: [Page404Component]
|
|
16
|
-
})
|
|
17
|
-
export class Page404Module { }
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Component, OnInit } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
@Component({
|
|
4
|
-
selector: 'app-register',
|
|
5
|
-
templateUrl: './register.component.html',
|
|
6
|
-
styleUrls: ['./register.component.scss'],
|
|
7
|
-
standalone: false
|
|
8
|
-
})
|
|
9
|
-
export class RegisterComponent implements OnInit {
|
|
10
|
-
|
|
11
|
-
constructor() { }
|
|
12
|
-
|
|
13
|
-
ngOnInit() {
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { RegisterComponent } from './register.component';
|
|
4
|
-
import { RouterModule, Routes } from '@angular/router';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const routes: Routes = [
|
|
8
|
-
{ path: '', component: RegisterComponent }
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
@NgModule({
|
|
12
|
-
imports: [
|
|
13
|
-
CommonModule,
|
|
14
|
-
RouterModule.forChild(routes)
|
|
15
|
-
],
|
|
16
|
-
declarations: [RegisterComponent]
|
|
17
|
-
})
|
|
18
|
-
export class RegisterModule { }
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# DASHBOARD
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **dashboard**.
|
|
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
|
-
# HOME
|
|
2
|
-
|
|
3
|
-
Folder ini untuk layer **home**.
|
|
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,19 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { HomeComponent } from './home.component';
|
|
4
|
-
import { RouterModule, Routes } from '@angular/router';
|
|
5
|
-
import { Widget_gameModule } from '@shared/widgets/widget_game/widget_game.module';
|
|
6
|
-
|
|
7
|
-
const routes: Routes = [
|
|
8
|
-
{ path: '', component: HomeComponent }
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
@NgModule({
|
|
12
|
-
imports: [
|
|
13
|
-
CommonModule,
|
|
14
|
-
Widget_gameModule,
|
|
15
|
-
RouterModule.forChild(routes)
|
|
16
|
-
],
|
|
17
|
-
declarations: [HomeComponent]
|
|
18
|
-
})
|
|
19
|
-
export class HomeModule { }
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { RepoScreen } from '@core/respository/screen_repo/screen.repo';
|
|
2
|
-
import { ScreenEntity, Screen_m } from './screen.entity';
|
|
3
|
-
import { provideZonelessChangeDetection } from '@angular/core';
|
|
4
|
-
import { TestBed } from '@angular/core/testing';
|
|
5
|
-
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
describe('ScreenEntity', () => {
|
|
9
|
-
let repo: RepoScreen;
|
|
10
|
-
|
|
11
|
-
const mockScreen: Screen_m = {
|
|
12
|
-
timestamp: Date.now(),
|
|
13
|
-
type: 'test',
|
|
14
|
-
id: 123,
|
|
15
|
-
name: 'Mock Screen',
|
|
16
|
-
mode: 'demo',
|
|
17
|
-
time: 60000
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
beforeEach(async () => {
|
|
22
|
-
await TestBed.configureTestingModule({
|
|
23
|
-
imports: [HttpClientTestingModule],
|
|
24
|
-
providers: [provideZonelessChangeDetection()]
|
|
25
|
-
}).compileComponents();
|
|
26
|
-
|
|
27
|
-
repo = TestBed.inject(RepoScreen);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should set and get screen', () => {
|
|
31
|
-
repo.setData(mockScreen);
|
|
32
|
-
expect(repo.getData.value).toEqual(mockScreen);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should update state when entity is set again', () => {
|
|
36
|
-
const newMock: Screen_m = { ...mockScreen, id: 456, name: 'New Mock' };
|
|
37
|
-
repo.setData(newMock);
|
|
38
|
-
expect(repo.getData.value?.id).toBe(456);
|
|
39
|
-
expect(repo.getData.value?.name).toBe('New Mock');
|
|
40
|
-
});
|
|
41
|
-
});
|