Commit 264a7c6c by Ooh-Ao

portal

parent ba8399fd
......@@ -15,9 +15,6 @@ import { DashboardViewerComponent } from './portal-manage/dashboard-viewer/dashb
import { UnauthorizedComponent } from './core/components/unauthorized.component';
export const App_Route: Route[] = [
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' },
{ path: '', component: ContentLayoutComponent, children: content},
{
path: 'auth/login',
component: LoginComponent
......@@ -42,12 +39,14 @@ export const App_Route: Route[] = [
}
]
},
{
path: 'home',
component: HomeComponent
{
path: 'home',
component: HomeComponent,
canActivate: [authGuard]
},
{
path: 'unauthorized',
component: UnauthorizedComponent
},
]
\ No newline at end of file
{ path: '', component: ContentLayoutComponent, children: content},
]
......@@ -11,5 +11,5 @@ export const authGuard: CanActivateFn = (route, state) => {
}
// Redirect to the login page
return router.parseUrl('/auth/login');
return router.parseUrl('/auth/simple-login');
};
......@@ -11,15 +11,21 @@ export class AuthService {
// In a real app, you would check for a token in localStorage
constructor() {
const token = localStorage.getItem('authToken');
if (token) {
this.checkAuthStatus();
}
private checkAuthStatus(): void {
const authToken = localStorage.getItem('authToken');
const jwtToken = localStorage.getItem('jwtToken');
if (authToken || jwtToken) {
this._isLoggedIn = true;
// You might decode the token to get roles
this._userRoles = ['ADMIN', 'MYHR_PLUS_USER'];
}
}
get isLoggedIn(): boolean {
this.checkAuthStatus(); // Check every time
return this._isLoggedIn;
}
......@@ -43,5 +49,6 @@ export class AuthService {
this._isLoggedIn = false;
this._userRoles = [];
localStorage.removeItem('authToken');
localStorage.removeItem('jwtToken');
}
}
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { TokenService } from '../../shared/services/token.service';
import { CompanyService } from '../services/company.service';
import { Component } from '@angular/core';
@Component({
selector: 'app-company-management',
templateUrl: './company-management.component.html',
styleUrls: ['./company-management.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Company Management</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบจัดการบริษัท</p>
<p>ระบบจัดการข้อมูลบริษัทและพนักงาน</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class InstallManagementComponent implements OnInit {
companyId = ""
constructor(private router: Router, private route: ActivatedRoute, private comService: CompanyService, private tokenService: TokenService) {
}
ngOnInit() {
this.companyId = this.route.snapshot.paramMap.get('companyId')!;
this.comService.getById(this.companyId).subscribe(result => {
this.tokenService.saveSelectCompany(result);
// this.router.navigate(["/company",""]);
})
}
export class CompanyManagementComponent {
constructor() { }
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { InstallManagementComponent } from './company-management.component';
import { RouterModule, Routes } from '@angular/router';
import { SharedModule } from '../../shared/shared.module';
export const companyRoutes: Routes = [
{
path: 'company/home/:companyId',
loadComponent: () =>
import('./home-installer/home-installer.component').then((m) => m.HomeInstallerComponent),
},
{
path: 'company/company-info',
loadComponent: () =>
import('./company-info/company-info.component').then((m) => m.CompanyInfoComponent),
},
{
path: 'company/company-location',
loadComponent: () =>
import('./company-location/company-location.component').then((m) => m.CompanyLocationComponent),
},
{
path: 'company/company-emp',
loadComponent: () =>
import('./company-emp/company-emp.component').then((m) => m.CompanyEmpComponent),
},
{
path: 'company/timestamp-log',
loadComponent: () =>
import('./timestamp-log/timestamp-log.component').then((m) => m.TimestampLogComponent),
},
{
path: 'company/timestamp-log/:company_employeeId',
loadComponent: () =>
import('./timestamp-log/timestamp-log.component').then((m) => m.TimestampLogComponent),
},
{
path: 'company/timestamp-face',
loadComponent: () =>
import('./enroll-face/enroll-face.component').then((m) => m.EnrollFaceComponent),
},
{
path: 'company/warning-timestamp-log',
loadComponent: () =>
import('./warning-timetamp/warning-timetamp.component').then((m) => m.WarningTimetampComponent),
},
import { CompanyManagementComponent } from './company-management.component';
export const routes: Routes = [
{
path: '',
component: CompanyManagementComponent
}
];
@NgModule({
declarations: [
CompanyManagementComponent
],
imports: [
CommonModule,
RouterModule.forChild(companyRoutes)
RouterModule.forChild(routes)
],
exports: [RouterModule],
declarations: [InstallManagementComponent]
exports: [
CompanyManagementComponent
]
})
export class CompanyManagementModule {
static routes = companyRoutes;
static routes = routes;
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { DashboardManagementComponent } from './dashboard-management.component';
import { DatasetPickerComponent } from './dataset-picker.component';
import { WidgetConfigComponent } from './widget-config/widget-config.component';
export const routes: Routes = [
{
path: '',
component: DashboardManagementComponent
}
];
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild(routes),
DashboardManagementComponent,
DatasetPickerComponent,
WidgetConfigComponent
],
exports: []
})
export class DashboardManagementModule {
static routes = routes;
}
......@@ -114,7 +114,7 @@
<mat-card>
<mat-card-header>
<mat-card-title>ช่วงเวลาที่ว่าง</mat-card-title>
<mat-card-subtitle *ngIf="selectedRoom">ห้อง: {{ (rooms$ | async)?.find(r => r.id === selectedRoom)?.name }}</mat-card-subtitle>
<mat-card-subtitle *ngIf="selectedRoom">ห้อง: {{ getRoomName(selectedRoom) }}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngIf="isLoading" class="text-center">
......@@ -154,7 +154,7 @@
</mat-card-header>
<mat-card-content>
<div class="table-responsive">
<table mat-table [dataSource]="bookings$ | async" class="w-100">
<table mat-table [dataSource]="(bookings$ | async) || []" class="w-100">
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef>หัวข้อ</th>
<td mat-cell *matCellDef="let booking">{{ booking.title }}</td>
......
......@@ -67,6 +67,8 @@ export class MeetingBookingComponent implements OnInit {
displayedColumns: string[] = ['title', 'room', 'startTime', 'endTime', 'organizer', 'status', 'actions'];
separatorKeysCodes: number[] = [13, 188]; // ENTER and COMMA key codes
constructor(
private meetingBookingService: MeetingBookingService,
private fb: FormBuilder,
......@@ -220,4 +222,15 @@ export class MeetingBookingComponent implements OnInit {
default: return 'ไม่ทราบสถานะ';
}
}
getRoomName(roomId: string): string {
let roomName = 'ไม่ระบุ';
this.rooms$.subscribe(rooms => {
const room = rooms.find(r => r.id === roomId);
if (room) {
roomName = room.name;
}
});
return roomName;
}
}
......@@ -41,7 +41,7 @@
<mat-card>
<mat-card-header>
<mat-card-title>สิทธิ์การเข้าถึงเมนู</mat-card-title>
<mat-card-subtitle>กำหนดสิทธิ์สำหรับบทบาท: {{ roles.find(r => r.id === selectedRoleId)?.name }}</mat-card-subtitle>
<mat-card-subtitle>กำหนดสิทธิ์สำหรับบทบาท: {{ getRoleName(selectedRoleId) }}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="permission-tree">
......@@ -118,7 +118,7 @@
<mat-label>เลือกผู้ใช้</mat-label>
<mat-select [(ngModel)]="selectedUserId">
<mat-option *ngFor="let user of users" [value]="user.id">
{{ user.name }} ({{ roles.find(r => r.id === user.roleId)?.name }})
{{ user.name }} ({{ getRoleName(user.roleId) }})
</mat-option>
</mat-select>
</mat-form-field>
......@@ -143,7 +143,7 @@
<mat-card>
<mat-card-header>
<mat-card-title>สิทธิ์การเข้าถึงเมนู</mat-card-title>
<mat-card-subtitle>กำหนดสิทธิ์สำหรับผู้ใช้: {{ users.find(u => u.id === selectedUserId)?.name }}</mat-card-subtitle>
<mat-card-subtitle>กำหนดสิทธิ์สำหรับผู้ใช้: {{ getUserName(selectedUserId) }}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<p class="text-info">
......
......@@ -55,8 +55,8 @@ interface MenuNode extends MenuHierarchy {
styleUrls: ['./menu-permission-management.component.scss']
})
export class MenuPermissionManagementComponent implements OnInit {
treeControl = new NestedTreeControl<MenuNode>(node => node.children);
dataSource = new MatTreeNestedDataSource<MenuNode>();
treeControl = new NestedTreeControl<any>(node => node.children);
dataSource = new MatTreeNestedDataSource<any>();
selectedRoleId: string = '';
selectedUserId: string = '';
......@@ -176,8 +176,8 @@ export class MenuPermissionManagementComponent implements OnInit {
permissions: node.permissions
});
if (node.children) {
permissions.push(...this.extractMenuPermissions(node.children));
if (node.children && Array.isArray(node.children)) {
permissions.push(...this.extractMenuPermissions(node.children as any[]));
}
});
......@@ -187,4 +187,14 @@ export class MenuPermissionManagementComponent implements OnInit {
resetPermissions(): void {
this.loadMenuHierarchy();
}
getRoleName(roleId: string): string {
const role = this.roles.find(r => r.id === roleId);
return role ? role.name : 'ไม่ระบุ';
}
getUserName(userId: string): string {
const user = this.users.find(u => u.id === userId);
return user ? user.name : 'ไม่ระบุ';
}
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myface-attendance',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">ระบบลงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบลงเวลาด้วยใบหน้าสำหรับ MyFace</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
ลงเวลาด้วยใบหน้า
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyfaceAttendanceComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-myface-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myFace Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ myFace</p>
<p>ระบบจัดการใบหน้าและความปลอดภัย</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyfaceDashboardComponent {
constructor() { }
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myface-face-management',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการข้อมูลใบหน้า</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการข้อมูลใบหน้าสำหรับ MyFace</p>
<div class="mt-4">
<button class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded mr-2">
เพิ่มใบหน้า
</button>
<button class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded">
ลบใบหน้า
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyfaceFaceManagementComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myface-face-recognition',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">ระบบจดจำใบหน้า</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจดจำใบหน้าสำหรับ MyFace</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
เริ่มจดจำใบหน้า
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyfaceFaceRecognitionComponent { }
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-myface',
templateUrl: './myface.component.html',
styleUrls: ['./myface.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myFace</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyfaceComponent implements OnInit {
export class MyfaceComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyfaceComponent } from './myface.component';
import { RouterModule, Routes } from '@angular/router';
export const myface: Routes = [
import { MyfaceComponent } from './myface.component';
import { MyfaceDashboardComponent } from './dashboard/myface-dashboard.component';
export const routes: Routes = [
{
path: "myface", children:[
path: '',
component: MyfaceComponent,
children: [
{
path: 'dashboard',
loadComponent: () =>
import('./dashboard/dashboard.component').then((m) => m.DashboardComponent),
component: MyfaceDashboardComponent
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
]
];
@NgModule({
declarations: [
MyfaceComponent,
MyfaceDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(myface),
RouterModule.forChild(routes)
],
declarations: [MyfaceComponent]
exports: [
MyfaceComponent
]
})
export class MyfaceModule {
static routes = myface;
}
static routes = routes;
}
import { Routes } from '@angular/router';
import { MyfaceComponent } from './myface.component';
import { MyfaceDashboardComponent } from './dashboard/myface-dashboard.component';
export const MYFACE_ROUTES: Routes = [
{
path: '',
component: MyfaceComponent,
children: [
{
path: 'dashboard',
component: MyfaceDashboardComponent
},
{
path: 'face-recognition',
loadComponent: () => import('./face-recognition/myface-face-recognition.component').then(m => m.MyfaceFaceRecognitionComponent)
},
{
path: 'face-management',
loadComponent: () => import('./face-management/myface-face-management.component').then(m => m.MyfaceFaceManagementComponent)
},
{
path: 'attendance',
loadComponent: () => import('./attendance/myface-attendance.component').then(m => m.MyfaceAttendanceComponent)
},
{
path: 'attendance-report',
loadComponent: () => import('./reports/myface-attendance-report.component').then(m => m.MyfaceAttendanceReportComponent)
},
{
path: 'face-report',
loadComponent: () => import('./reports/myface-face-report.component').then(m => m.MyfaceFaceReportComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myface-attendance-report',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงานการลงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>รายงานการลงเวลาด้วยใบหน้าสำหรับ MyFace</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
ส่งออกรายงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyfaceAttendanceReportComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myface-face-report',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงานการจดจำใบหน้า</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>รายงานการจดจำใบหน้าสำหรับ MyFace</p>
<div class="mt-4">
<button class="bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded">
ส่งออกรายงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyfaceFaceReportComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-myhr-lite-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myHR-Lite Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ myHR-Lite</p>
<p>ระบบจัดการทรัพยากรบุคคลพื้นฐาน</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyhrLiteDashboardComponent {
constructor() { }
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-lite-employee',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการพนักงาน</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการข้อมูลพนักงานสำหรับ MyHR-Lite</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
เพิ่มพนักงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class MyhrLiteEmployeeComponent { }
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-myhr-lite',
templateUrl: './myhr-lite.component.html',
styleUrls: ['./myhr-lite.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myHR-Lite</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyhrLiteComponent implements OnInit {
export class MyhrLiteComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyhrLiteComponent } from './myhr-lite.component';
import { RouterModule, Routes } from '@angular/router';
export const myhrlite: Routes = [
import { MyhrLiteComponent } from './myhr-lite.component';
import { MyhrLiteDashboardComponent } from './dashboard/myhr-lite-dashboard.component';
export const routes: Routes = [
{
path: "myhr-lite", children:[
path: '',
component: MyhrLiteComponent,
children: [
{
path: 'dashboard',
loadComponent: () =>
import('./dashboard/dashboard.component').then((m) => m.DashboardComponent),
component: MyhrLiteDashboardComponent
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
]
];
@NgModule({
declarations: [
MyhrLiteComponent,
MyhrLiteDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(myhrlite),
RouterModule.forChild(routes)
],
declarations: [MyhrLiteComponent],
exports: [RouterModule],
exports: [
MyhrLiteComponent
]
})
export class MyhrLiteModule {
static routes = myhrlite;
}
static routes = routes;
}
import { Routes } from '@angular/router';
import { MyhrLiteComponent } from './myhr-lite.component';
import { MyhrLiteDashboardComponent } from './dashboard/myhr-lite-dashboard.component';
export const MYHR_LITE_ROUTES: Routes = [
{
path: '',
component: MyhrLiteComponent,
children: [
{
path: 'dashboard',
component: MyhrLiteDashboardComponent
},
{
path: 'employee',
loadComponent: () => import('./employee/myhr-lite-employee.component').then(m => m.MyhrLiteEmployeeComponent)
},
{
path: 'reports',
loadComponent: () => import('./reports/myhr-lite-reports.component').then(m => m.MyhrLiteReportsComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-lite-reports',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงาน</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบรายงานสำหรับ MyHR-Lite</p>
<div class="mt-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="font-semibold text-blue-800">รายงานพนักงาน</h3>
<p class="text-sm text-blue-600">ข้อมูลพนักงานทั้งหมด</p>
</div>
<div class="bg-green-50 p-4 rounded-lg">
<h3 class="font-semibold text-green-800">รายงานการลา</h3>
<p class="text-sm text-green-600">สถิติการลาของพนักงาน</p>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<h3 class="font-semibold text-purple-800">รายงานเงินเดือน</h3>
<p class="text-sm text-purple-600">ข้อมูลเงินเดือนพนักงาน</p>
</div>
</div>
</div>
</div>
`,
styles: []
})
export class MyhrLiteReportsComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-attendance',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">ระบบลงเวลา</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบลงเวลาสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusAttendanceComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-department',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการแผนก</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการแผนกสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusDepartmentComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-employee',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการข้อมูลพนักงาน</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการข้อมูลพนักงานสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusEmployeeComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-leave',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการการลา</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการการลาสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusLeaveComponent { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyhrPlusComponent } from './myhr-plus.component';
import { RouterModule, Routes } from '@angular/router';
const portalRoutes: Routes = [
{
path: 'category-list',
loadComponent: () =>
import('../my-portal/category-list/category-list.component').then((m) => m.CategorylistComponent),
},
{
path: 'view-list-excel',
loadComponent: () =>
import('../my-portal/category-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc',
loadComponent: () =>
import('../my-portal/category-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course',
loadComponent: () =>
import('../my-portal/category-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'create-category',
loadComponent: () =>
import('../my-portal/create-category/create-category.component').then((m) => m.CreateCategoryComponent),
},
{
path: 'list-excel',
loadComponent: () =>
import('../my-portal/create-category/list-excel/list-excel.component').then((m) => m.ListExcelComponent),
},
{
path: 'list-doc',
loadComponent: () =>
import('../my-portal/create-category/list-doc/list-doc.component').then((m) => m.ListDocComponent),
},
{
path: 'list-course',
loadComponent: () =>
import('../my-portal/create-category/list-course/list-course.component').then((m) => m.ListCourseComponent),
},
{
path: 'category-list-approve',
loadComponent: () =>
import('../my-portal/category-list-approve/category-list-approve.component').then((m) => m.CategoryListApproveComponent),
},
{
path: 'approve-excel',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-excel/approve-excel.component').then((m) => m.ApproveExcelComponent),
},
{
path: 'approve-doc',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-doc/approve-doc.component').then((m) => m.ApproveDocComponent),
},
{
path: 'approve-course',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-course/approve-course.component').then((m) => m.ApproveCourseComponent),
},
{
path: 'approved-list',
loadComponent: () =>
import('../my-portal/approved-list/approved-list.component').then((m) => m.ApprovedListComponent),
},
{
path: 'view-list-excel/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'excel-list',
loadComponent: () =>
import('../my-portal/excel-list/excel-list.component').then((m) => m.ExcelListComponent),
},
{
path: 'excel-report-toggle',
loadComponent: () =>
import('../my-portal/excel-report-toggle/excel-report-toggle.component').then((m) => m.ExcelReportToggleComponent),
},
{
path: 'datasource-table',
loadComponent: () =>
import('../my-portal/datasource-table/datasource-table.component').then((m) => m.DatasourceTableComponent),
},
{
path: 'excel-report',
loadComponent: () =>
import('../my-portal/excel-report/excel-report.component').then((m) => m.ExcelReportComponent),
}
]
export const myhrplus: Routes = [
{
path: "myhr-plus", children: [
{
path: 'dashboard',
loadComponent: () =>
import('./dashboard/dashboard.component').then((m) => m.DashboardComponent),
},
...portalRoutes
]
}
]
import { RouterModule } from '@angular/router';
import { MYHR_PLUS_ROUTES } from './myhr-plus.routes';
import { HrDashboardComponent } from './hr-dashboard.component';
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild(myhrplus),
RouterModule.forChild(MYHR_PLUS_ROUTES),
HrDashboardComponent
],
declarations: [MyhrPlusComponent]
exports: []
})
export class MyhrPlusModule {
static routes = myhrplus;
static routes = MYHR_PLUS_ROUTES;
}
......@@ -14,6 +14,34 @@ export const MYHR_PLUS_ROUTES: Routes = [
component: HrDashboardComponent
},
{
path: 'employee-management',
loadComponent: () => import('./employee/myhr-plus-employee.component').then(m => m.MyhrPlusEmployeeComponent)
},
{
path: 'attendance',
loadComponent: () => import('./attendance/myhr-plus-attendance.component').then(m => m.MyhrPlusAttendanceComponent)
},
{
path: 'leave-management',
loadComponent: () => import('./leave/myhr-plus-leave.component').then(m => m.MyhrPlusLeaveComponent)
},
{
path: 'payroll',
loadComponent: () => import('./payroll/myhr-plus-payroll.component').then(m => m.MyhrPlusPayrollComponent)
},
{
path: 'department',
loadComponent: () => import('./department/myhr-plus-department.component').then(m => m.MyhrPlusDepartmentComponent)
},
{
path: 'position',
loadComponent: () => import('./position/myhr-plus-position.component').then(m => m.MyhrPlusPositionComponent)
},
{
path: 'org-chart',
loadComponent: () => import('./org-chart/myhr-plus-org-chart.component').then(m => m.MyhrPlusOrgChartComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
......
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-org-chart',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">แผนภูมิองค์กร</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบแผนภูมิองค์กรสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusOrgChartComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-payroll',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">ระบบเงินเดือน</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบเงินเดือนสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusPayrollComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myhr-plus-position',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการตำแหน่ง</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการตำแหน่งสำหรับ MyHR-Plus</p></div></div>`,
styles: []
})
export class MyhrPlusPositionComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-articles',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการบทความ</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการบทความสำหรับ MyJob</p>
</div>
</div>
`,
styles: []
})
export class MyjobArticlesComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-career-cluster',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการกลุ่มอาชีพ</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการกลุ่มอาชีพสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobCareerClusterComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-category-company',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการประเภทธุรกิจ</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการประเภทธุรกิจสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobCategoryCompanyComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-company',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการบริษัท</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการบริษัทสำหรับ MyJob</p>
</div>
</div>
`,
styles: []
})
export class MyjobCompanyComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-country',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการประเทศ</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการประเทศสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobCountryComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-myjob-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myJob Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ myJob</p>
<p>ระบบจัดการงานและโครงการ</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyjobDashboardComponent {
constructor() { }
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-degree',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการระดับการศึกษา</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการระดับการศึกษาสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobDegreeComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-department',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการแผนกบริษัท</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการแผนกบริษัทสำหรับ MyJob</p>
</div>
</div>
`,
styles: []
})
export class MyjobDepartmentComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-faculty',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการคณะ</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการคณะสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobFacultyComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-institution',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการสถาบันการศึกษา</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการสถาบันการศึกษาสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobInstitutionComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-job-types',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการประเภทงาน</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการประเภทงานสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobJobTypesComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-major',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการสาขาวิชา</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการสาขาวิชาสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobMajorComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-member',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการผู้สมัครงาน</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการผู้สมัครงานสำหรับ MyJob</p>
</div>
</div>
`,
styles: []
})
export class MyjobMemberComponent { }
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-myjob',
templateUrl: './myjob.component.html',
styleUrls: ['./myjob.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myJob</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyjobComponent implements OnInit {
export class MyjobComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyjobComponent } from './myjob.component';
import { RouterModule, Routes } from '@angular/router';
import { QuillModule } from 'ngx-quill';
const portalRoutes: Routes = [
{
path: 'category-list',
loadComponent: () =>
import('../my-portal/category-list/category-list.component').then((m) => m.CategorylistComponent),
},
{
path: 'view-list-excel',
loadComponent: () =>
import('../my-portal/category-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc',
loadComponent: () =>
import('../my-portal/category-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course',
loadComponent: () =>
import('../my-portal/category-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'create-category',
loadComponent: () =>
import('../my-portal/create-category/create-category.component').then((m) => m.CreateCategoryComponent),
},
{
path: 'list-excel',
loadComponent: () =>
import('../my-portal/create-category/list-excel/list-excel.component').then((m) => m.ListExcelComponent),
},
{
path: 'list-doc',
loadComponent: () =>
import('../my-portal/create-category/list-doc/list-doc.component').then((m) => m.ListDocComponent),
},
{
path: 'list-course',
loadComponent: () =>
import('../my-portal/create-category/list-course/list-course.component').then((m) => m.ListCourseComponent),
},
{
path: 'category-list-approve',
loadComponent: () =>
import('../my-portal/category-list-approve/category-list-approve.component').then((m) => m.CategoryListApproveComponent),
},
{
path: 'approve-excel',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-excel/approve-excel.component').then((m) => m.ApproveExcelComponent),
},
{
path: 'approve-doc',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-doc/approve-doc.component').then((m) => m.ApproveDocComponent),
},
{
path: 'approve-course',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-course/approve-course.component').then((m) => m.ApproveCourseComponent),
},
{
path: 'approved-list',
loadComponent: () =>
import('../my-portal/approved-list/approved-list.component').then((m) => m.ApprovedListComponent),
},
{
path: 'view-list-excel/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'excel-list',
loadComponent: () =>
import('../my-portal/excel-list/excel-list.component').then((m) => m.ExcelListComponent),
},
{
path: 'excel-report-toggle',
loadComponent: () =>
import('../my-portal/excel-report-toggle/excel-report-toggle.component').then((m) => m.ExcelReportToggleComponent),
},
{
path: 'datasource-table',
loadComponent: () =>
import('../my-portal/datasource-table/datasource-table.component').then((m) => m.DatasourceTableComponent),
},
{
path: 'excel-report',
loadComponent: () =>
import('../my-portal/excel-report/excel-report.component').then((m) => m.ExcelReportComponent),
}
]
export const myjob: Routes = [
import { MyjobComponent } from './myjob.component';
import { MyjobDashboardComponent } from './dashboard/myjob-dashboard.component';
export const routes: Routes = [
{
path: "myjob", children: [
{
//////////////MyJob/////////////////
path: 'home',
loadComponent: () =>
import('./home-common/home-common.component').then((m) => m.HomeCommonComponent),
},
{
path: 'member-manage',
loadComponent: () =>
import('./user-management/user-setting/user-setting.component').then((m) => m.UserSettingComponent),
},
{
path: 'manage-companys',
loadComponent: () =>
import('./company-manage/company-manage.component').then((m) => m.CompanyManageComponent),
},
{
path: 'manage-articles',
loadComponent: () =>
import('./article-manage/article-manage.component').then((m) => m.ArticleManageComponent),
},
{
path: 'admin-manage',
loadComponent: () =>
import('./admin-manage/admin-manage.component').then((m) => m.AdminManageComponent),
},
{
path: 'pdpa-manage',
loadComponent: () =>
import('./pdpa-manage/pdpa-manage.component').then((m) => m.PdpaManageComponent),
},
{
path: 'company-departments',
loadComponent: () =>
import('./company-department/company-department.component').then((m) => m.CompanyDepartmentComponent),
},
{
path: 'country-registration',
loadComponent: () =>
import('./company-department/country-registration/country-registration.component').then((m) => m.CountryRegistrationComponent),
},
{
path: 'category-company',
loadComponent: () =>
import('./company-department/category-company/category-company.component').then((m) => m.CategoryCompanyComponent),
},
{
path: 'degree-manage',
loadComponent: () =>
import('./company-department/degree-manage/degree-manage.component').then((m) => m.DegreeManageComponent),
},
path: '',
component: MyjobComponent,
children: [
{
path: 'job-types',
loadComponent: () =>
import('./company-department/job-type/job-type.component').then((m) => m.JobTypeComponent),
path: 'dashboard',
component: MyjobDashboardComponent
},
{
path: 'provinces',
loadComponent: () =>
import('./company-department/province/province.component').then((m) => m.ProvinceComponent),
},
{
path: 'admin-manage',
loadComponent: () =>
import('./admin-manage/admin-manage.component').then((m) => m.AdminManageComponent),
},
{
path: 'position',
loadComponent: () =>
import('./company-department/company-position/company-position.component').then((m) => m.CompanyPositionComponent),
},
{
path: 'career-cluster',
loadComponent: () =>
import('./company-department/career-cluster/career-cluster.component').then((m) => m.CareerClusterComponent),
},
{
path: 'institution',
loadComponent: () =>
import('./company-department/institution/institution.component').then((m) => m.InstitutionComponent),
},
{
path: 'faculty',
loadComponent: () =>
import('./company-department/faculty/faculty.component').then((m) => m.FacultyComponent),
},
{
path: 'major',
loadComponent: () =>
import('./company-department/major/major.component').then((m) => m.MajorComponent),
},
...portalRoutes
],
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
]
];
@NgModule({
declarations: [
MyjobComponent,
MyjobDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(myjob),
QuillModule.forRoot(),
RouterModule.forChild(routes)
],
declarations: [MyjobComponent],
exports: [RouterModule],
exports: [
MyjobComponent
]
})
export class MyjobModule {
static routes = myjob;
static routes = routes;
}
import { Routes } from '@angular/router';
import { MyjobComponent } from './myjob.component';
import { MyjobDashboardComponent } from './dashboard/myjob-dashboard.component';
export const MYJOB_ROUTES: Routes = [
{
path: '',
component: MyjobComponent,
children: [
{
path: 'dashboard',
component: MyjobDashboardComponent
},
{
path: 'pdpa-manage',
loadComponent: () => import('./pdpa/myjob-pdpa-manage.component').then(m => m.MyjobPdpaManageComponent)
},
{
path: 'manage-articles',
loadComponent: () => import('./articles/myjob-articles.component').then(m => m.MyjobArticlesComponent)
},
{
path: 'manage-companys',
loadComponent: () => import('./company/myjob-company.component').then(m => m.MyjobCompanyComponent)
},
{
path: 'member-manage',
loadComponent: () => import('./member/myjob-member.component').then(m => m.MyjobMemberComponent)
},
{
path: 'company-departments',
loadComponent: () => import('./department/myjob-department.component').then(m => m.MyjobDepartmentComponent)
},
{
path: 'career-cluster',
loadComponent: () => import('./career/myjob-career-cluster.component').then(m => m.MyjobCareerClusterComponent)
},
{
path: 'position',
loadComponent: () => import('./position/myjob-position.component').then(m => m.MyjobPositionComponent)
},
{
path: 'job-types',
loadComponent: () => import('./job-type/myjob-job-types.component').then(m => m.MyjobJobTypesComponent)
},
{
path: 'category-company',
loadComponent: () => import('./category/myjob-category-company.component').then(m => m.MyjobCategoryCompanyComponent)
},
{
path: 'degree-manage',
loadComponent: () => import('./degree/myjob-degree.component').then(m => m.MyjobDegreeComponent)
},
{
path: 'country-registration',
loadComponent: () => import('./country/myjob-country.component').then(m => m.MyjobCountryComponent)
},
{
path: 'provinces',
loadComponent: () => import('./province/myjob-province.component').then(m => m.MyjobProvinceComponent)
},
{
path: 'institution',
loadComponent: () => import('./institution/myjob-institution.component').then(m => m.MyjobInstitutionComponent)
},
{
path: 'faculty',
loadComponent: () => import('./faculty/myjob-faculty.component').then(m => m.MyjobFacultyComponent)
},
{
path: 'major',
loadComponent: () => import('./major/myjob-major.component').then(m => m.MyjobMajorComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-pdpa-manage',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการ PDPA</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการ PDPA สำหรับ MyJob</p>
</div>
</div>
`,
styles: []
})
export class MyjobPdpaManageComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-position',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการตำแหน่ง</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการตำแหน่งสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobPositionComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-myjob-province',
standalone: true,
imports: [CommonModule],
template: `<div class="p-4"><h1 class="text-2xl font-bold mb-4">จัดการจังหวัด</h1><div class="bg-white rounded-lg shadow p-6"><p>ระบบจัดการจังหวัดสำหรับ MyJob</p></div></div>`,
styles: []
})
export class MyjobProvinceComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-company',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการบริษัท</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการบริษัทสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnCompanyComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-company-course',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการคอร์สบริษัท</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการคอร์สบริษัทสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnCompanyCourseComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-course-transfer',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">โอนย้ายคอร์ส</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบโอนย้ายคอร์สสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnCourseTransferComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-mylearn-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myLearn Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ myLearn</p>
<p>ระบบจัดการการเรียนรู้และฝึกอบรม</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MylearnDashboardComponent {
constructor() { }
}
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-mylearn',
templateUrl: './mylearn.component.html',
styleUrls: ['./mylearn.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">myLearn</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MylearnComponent implements OnInit {
export class MylearnComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MylearnComponent } from './mylearn.component';
import { RouterModule, Routes } from '@angular/router';
const portalRoutes: Routes = [
{
path: 'category-list',
loadComponent: () =>
import('../my-portal/category-list/category-list.component').then((m) => m.CategorylistComponent),
},
{
path: 'view-list-excel',
loadComponent: () =>
import('../my-portal/category-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc',
loadComponent: () =>
import('../my-portal/category-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course',
loadComponent: () =>
import('../my-portal/category-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'create-category',
loadComponent: () =>
import('../my-portal/create-category/create-category.component').then((m) => m.CreateCategoryComponent),
},
{
path: 'list-excel',
loadComponent: () =>
import('../my-portal/create-category/list-excel/list-excel.component').then((m) => m.ListExcelComponent),
},
{
path: 'list-doc',
loadComponent: () =>
import('../my-portal/create-category/list-doc/list-doc.component').then((m) => m.ListDocComponent),
},
{
path: 'list-course',
loadComponent: () =>
import('../my-portal/create-category/list-course/list-course.component').then((m) => m.ListCourseComponent),
},
{
path: 'category-list-approve',
loadComponent: () =>
import('../my-portal/category-list-approve/category-list-approve.component').then((m) => m.CategoryListApproveComponent),
},
{
path: 'approve-excel',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-excel/approve-excel.component').then((m) => m.ApproveExcelComponent),
},
{
path: 'approve-doc',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-doc/approve-doc.component').then((m) => m.ApproveDocComponent),
},
{
path: 'approve-course',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-course/approve-course.component').then((m) => m.ApproveCourseComponent),
},
{
path: 'approved-list',
loadComponent: () =>
import('../my-portal/approved-list/approved-list.component').then((m) => m.ApprovedListComponent),
},
{
path: 'view-list-excel/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'excel-list',
loadComponent: () =>
import('../my-portal/excel-list/excel-list.component').then((m) => m.ExcelListComponent),
},
{
path: 'excel-report-toggle',
loadComponent: () =>
import('../my-portal/excel-report-toggle/excel-report-toggle.component').then((m) => m.ExcelReportToggleComponent),
},
{
path: 'datasource-table',
loadComponent: () =>
import('../my-portal/datasource-table/datasource-table.component').then((m) => m.DatasourceTableComponent),
},
{
path: 'excel-report',
loadComponent: () =>
import('../my-portal/excel-report/excel-report.component').then((m) => m.ExcelReportComponent),
}
]
export const mylearn: Routes = [
import { MylearnComponent } from './mylearn.component';
import { MylearnDashboardComponent } from './dashboard/mylearn-dashboard.component';
export const routes: Routes = [
{
path: "mylearn", children: [
path: '',
component: MylearnComponent,
children: [
{
path: 'dashboard',
loadComponent: () =>
import('./dashboard/dashboard.component').then((m) => m.DashboardComponent),
},
{
path: 'mylearn-pdpa-manage',
loadComponent: () =>
import('./pdpa-manage/pdpa-manage.component').then((m) => m.PdpaManageComponent),
},
{
path: 'user-company',
loadComponent: () =>
import('./user-company/user-company.component').then((m) => m.UserCompanyComponent),
},
{
path: 'myhrcompany',
children: [
{
path: 'manage-course/:id',
loadComponent: () =>
import('./myhrcompany/manage-course/manage-course.component')
.then(m => m.ManageCourseComponent),
},
{
path: '',
loadComponent: () =>
import('./myhrcompany/myhrcompany.component')
.then(m => m.MyhrcompanyComponent),
},
]
},
{
path: 'course-transfer',
loadComponent: () =>
import('./course-transfer/course-transfer.component').then((m) => m.CourseTransferComponent),
component: MylearnDashboardComponent
},
{
path: 'timeout-screen-manage',
loadComponent: () =>
import('./timeout-screen-manage/timeout-screen-manage.component').then((m) => m.TimeoutScreenManageComponent),
},
{
path: 'management-user',
children: [
{
path: 'user-role/:id',
loadComponent: () =>
import('./management-user/user-role/user-role.component')
.then(m => m.UserRoleComponent),
},
{
path: 'user-authorization/:id',
loadComponent: () =>
import('./management-user/user-authorization/user-authorization.component')
.then(m => m.UserAuthorizationComponent),
},
{
path: '',
loadComponent: () =>
import('./management-user/management-user.component')
.then(m => m.ManagementUserComponent),
},
]
},
...portalRoutes
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
]
];
@NgModule({
declarations: [
MylearnComponent,
MylearnDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(mylearn),
RouterModule.forChild(routes)
],
declarations: [MylearnComponent],
exports: [RouterModule],
exports: [
MylearnComponent
]
})
export class MylearnModule {
static routes = mylearn;
static routes = routes;
}
import { Routes } from '@angular/router';
import { MylearnComponent } from './mylearn.component';
import { MylearnDashboardComponent } from './dashboard/mylearn-dashboard.component';
export const MYLEARN_ROUTES: Routes = [
{
path: '',
component: MylearnComponent,
children: [
{
path: 'dashboard',
component: MylearnDashboardComponent
},
{
path: 'mylearn-pdpa-manage',
loadComponent: () => import('./pdpa/mylearn-pdpa-manage.component').then(m => m.MylearnPdpaManageComponent)
},
{
path: 'myhrcompany',
loadComponent: () => import('./company/mylearn-company.component').then(m => m.MylearnCompanyComponent)
},
{
path: 'management-user',
loadComponent: () => import('./user/mylearn-user-management.component').then(m => m.MylearnUserManagementComponent)
},
{
path: 'course-transfer',
loadComponent: () => import('./course/mylearn-course-transfer.component').then(m => m.MylearnCourseTransferComponent)
},
{
path: 'timeout-screen-manage',
loadComponent: () => import('./timeout/mylearn-timeout-manage.component').then(m => m.MylearnTimeoutManageComponent)
},
{
path: 'company-manage-course',
loadComponent: () => import('./course/mylearn-company-course.component').then(m => m.MylearnCompanyCourseComponent)
},
{
path: 'user-company',
loadComponent: () => import('./user/mylearn-user-company.component').then(m => m.MylearnUserCompanyComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-pdpa-manage',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการ PDPA</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการ PDPA สำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnPdpaManageComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-timeout-manage',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการเวลาหน้าจอ</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการเวลาหน้าจอสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnTimeoutManageComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-user-company',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">จัดการผู้ใช้บริษัท</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการผู้ใช้บริษัทสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnUserCompanyComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-mylearn-user-management',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">การจัดการผู้ใช้งาน</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการผู้ใช้งานสำหรับ MyLearn</p>
</div>
</div>
`,
styles: []
})
export class MylearnUserManagementComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-myskill-x-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">mySkill-X Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ mySkill-X</p>
<p>ระบบจัดการทักษะและความสามารถ</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyskillXDashboardComponent {
constructor() { }
}
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-myskill-x',
templateUrl: './myskill-x.component.html',
styleUrls: ['./myskill-x.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">mySkill-X</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class MyskillXComponent implements OnInit {
export class MyskillXComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyskillXComponent } from './myskill-x.component';
import { RouterModule, Routes } from '@angular/router';
import { SharedModule } from '../../shared/shared.module';
import { QuillModule } from 'ngx-quill';
import { MyskillXComponent } from './myskill-x.component';
import { MyskillXDashboardComponent } from './dashboard/myskill-x-dashboard.component';
const portalRoutes: Routes = [
{
path: 'category-list',
loadComponent: () =>
import('../my-portal/category-list/category-list.component').then((m) => m.CategorylistComponent),
},
{
path: 'view-list-excel',
loadComponent: () =>
import('../my-portal/category-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc',
loadComponent: () =>
import('../my-portal/category-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course',
loadComponent: () =>
import('../my-portal/category-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'create-category',
loadComponent: () =>
import('../my-portal/create-category/create-category.component').then((m) => m.CreateCategoryComponent),
},
{
path: 'list-excel',
loadComponent: () =>
import('../my-portal/create-category/list-excel/list-excel.component').then((m) => m.ListExcelComponent),
},
{
path: 'list-doc',
loadComponent: () =>
import('../my-portal/create-category/list-doc/list-doc.component').then((m) => m.ListDocComponent),
},
{
path: 'list-course',
loadComponent: () =>
import('../my-portal/create-category/list-course/list-course.component').then((m) => m.ListCourseComponent),
},
{
path: 'category-list-approve',
loadComponent: () =>
import('../my-portal/category-list-approve/category-list-approve.component').then((m) => m.CategoryListApproveComponent),
},
{
path: 'approve-excel',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-excel/approve-excel.component').then((m) => m.ApproveExcelComponent),
},
{
path: 'approve-doc',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-doc/approve-doc.component').then((m) => m.ApproveDocComponent),
},
{
path: 'approve-course',
loadComponent: () =>
import('../my-portal/category-list-approve/approve-course/approve-course.component').then((m) => m.ApproveCourseComponent),
},
{
path: 'approved-list',
loadComponent: () =>
import('../my-portal/approved-list/approved-list.component').then((m) => m.ApprovedListComponent),
},
{
path: 'view-list-excel/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-excel/view-list-excel.component').then((m) => m.ViewListExcelComponent),
},
{
path: 'view-list-doc/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-doc/view-list-doc.component').then((m) => m.ViewListDocComponent),
},
{
path: 'view-list-course/:type',
loadComponent: () =>
import('../my-portal/approved-list/view-list-course/view-list-course.component').then((m) => m.ViewListCourseComponent),
},
{
path: 'excel-list',
loadComponent: () =>
import('../my-portal/excel-list/excel-list.component').then((m) => m.ExcelListComponent),
},
{
path: 'excel-report-toggle',
loadComponent: () =>
import('../my-portal/excel-report-toggle/excel-report-toggle.component').then((m) => m.ExcelReportToggleComponent),
},
{
path: 'datasource-table',
loadComponent: () =>
import('../my-portal/datasource-table/datasource-table.component').then((m) => m.DatasourceTableComponent),
},
{
path: 'excel-report',
loadComponent: () =>
import('../my-portal/excel-report/excel-report.component').then((m) => m.ExcelReportComponent),
}
]
export const myportal: Routes = [
{
path: 'myskill-x', children: [
//////////////MyPortal/////////////////
...portalRoutes
export const routes: Routes = [
{
path: '',
component: MyskillXComponent,
children: [
{
path: 'dashboard',
component: MyskillXDashboardComponent
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
@NgModule({
declarations: [
MyskillXComponent,
MyskillXDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(myportal),
QuillModule.forRoot(),
RouterModule.forChild(routes)
],
exports: [RouterModule],
declarations: [MyskillXComponent]
exports: [
MyskillXComponent
]
})
export class MyskillXModule {
static routes = myportal;
static routes = routes;
}
import { Routes } from '@angular/router';
import { MyskillXComponent } from './myskill-x.component';
import { MyskillXDashboardComponent } from './dashboard/myskill-x-dashboard.component';
export const MYSKILL_X_ROUTES: Routes = [
{
path: '',
component: MyskillXComponent,
children: [
{
path: 'dashboard',
component: MyskillXDashboardComponent
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
......@@ -5,22 +5,128 @@ import { WidgetListComponent } from './widget-management/widget-list.component';
import { WidgetFormComponent } from './widget-management/widget-form.component';
import { moduleAccessGuard } from '../core/guards/module-access.guard';
import { DatasetWidgetLinkerComponent } from './widget-management/dataset-widget-linker.component';
import { HomeComponent } from './home/home.component';
import { MeetingBookingComponent } from './meeting-booking/meeting-booking.component';
import { MenuPermissionManagementComponent } from './menu-permission-management/menu-permission-management.component';
// import { CompanyManagementComponent } from './company-management/company-management.component';
export const portalManageRoutes: Routes = [
// Route for the specific MyHR+ module, which has its own services and routing.
// This must come BEFORE the generic ':appName' routes.
// Home/Dashboard Route
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'home',
component: HomeComponent
},
// === แอปพลิเคชันที่เข้าถึงได้ ===
// myHR-Plus Module
{
path: 'myhr-plus',
canActivate: [moduleAccessGuard], // Use the same guard to check if user can access 'myhr-plus'
canActivate: [moduleAccessGuard],
loadChildren: () => import('./myhr-plus/myhr-plus.routes').then(m => m.MYHR_PLUS_ROUTES)
},
// myHR-Lite Module
{
path: 'myhr-lite',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./myhr-lite/myhr-lite.routes').then(m => m.MYHR_LITE_ROUTES)
},
// Zeeme Plus Module
{
path: 'zeeme',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./zeeme/zeeme.routes').then(m => m.ZEEME_ROUTES)
},
// myFace Module
{
path: 'myface',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./myface/myface.routes').then(m => m.MYFACE_ROUTES)
},
// myLearn Module
{
path: 'mylearn',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./mylearn/mylearn.routes').then(m => m.MYLEARN_ROUTES)
},
// myJob Module
{
path: 'myjob',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./myjob/myjob.routes').then(m => m.MYJOB_ROUTES)
},
// mySkill-X Module
{
path: 'myskill-x',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./myskill-x/myskill-x.routes').then(m => m.MYSKILL_X_ROUTES)
},
// === การบริการ ===
// Dashboard
{
path: 'dashboard',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./dashboard-management/dashboard-management.module').then(m => m.DashboardManagementModule)
},
// Meeting Booking
{
path: 'meeting-booking',
component: MeetingBookingComponent,
canActivate: [moduleAccessGuard]
},
// === การตั้งค่าระบบ ===
// Permission Management
{
path: 'permission-management',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./permission-management/permission-management.routes').then(m => m.PERMISSION_ROUTES)
},
// --- Generic App Routes ---
// Menu Permission Management
{
path: 'menu-permission-management',
component: MenuPermissionManagementComponent,
canActivate: [moduleAccessGuard]
},
// Company Management
{
path: 'company-management',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./company-management/company-management.module').then(m => m.CompanyManagementModule)
},
// Widget Management
{
path: 'widget-management',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./widget-management/widget-management.module').then(m => m.WidgetManagementModule)
},
// Dashboard Management
{
path: 'dashboard-management',
component: DashboardManagementComponent,
canActivate: [moduleAccessGuard]
},
// === Generic App Routes ===
// These routes are for simple apps that don't need special module-level services.
// Dynamic route for dashboard management per application
......@@ -29,6 +135,7 @@ export const portalManageRoutes: Routes = [
component: DashboardManagementComponent,
canActivate: [moduleAccessGuard]
},
// Dynamic routes for widget warehouse per application
{
path: ':appName/widget-warehouse',
......@@ -45,15 +152,17 @@ export const portalManageRoutes: Routes = [
component: DatasetWidgetLinkerComponent,
canActivate: [moduleAccessGuard]
},
// Route for viewing a specific dashboard, remains unchanged
// Route for viewing a specific dashboard
{
path: 'dashboard-viewer/:dashboardId',
component: DashboardViewerComponent
},
// Redirect for unknown routes
{
path: '**',
redirectTo: '',
pathMatch: 'full'
}
// Optional: A redirect for the base portal-manage path
// {
// path: '',
// redirectTo: 'myhr-plus/dashboard-management', // Default to one app
// pathMatch: 'full'
// }
];
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">จัดการผู้ใช้และบทบาท</h4>
<p class="card-subtitle">จัดการข้อมูลผู้ใช้ บทบาท และสิทธิ์การเข้าถึง</p>
</div>
<div class="card-body">
<mat-tab-group>
<!-- User Management Tab -->
<mat-tab label="จัดการผู้ใช้">
<div class="row mt-3">
<!-- User Filter -->
<div class="col-12">
<mat-card>
<mat-card-header>
<mat-card-title>ค้นหาและกรอง</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-md-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ค้นหา</mat-label>
<input matInput [(ngModel)]="userFilter.search"
(ngModelChange)="onUserFilterChange()"
placeholder="ชื่อ, อีเมล, หรือชื่อผู้ใช้">
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label>แผนก</mat-label>
<mat-select [(ngModel)]="userFilter.department"
(selectionChange)="onUserFilterChange()">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option *ngFor="let dept of departments$ | async" [value]="dept.id">
{{ dept.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ตำแหน่ง</mat-label>
<mat-select [(ngModel)]="userFilter.position"
(selectionChange)="onUserFilterChange()">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option *ngFor="let pos of positions$ | async" [value]="pos.id">
{{ pos.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label>สถานะ</mat-label>
<mat-select [(ngModel)]="userFilter.isActive"
(selectionChange)="onUserFilterChange()">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option [value]="true">ใช้งาน</mat-option>
<mat-option [value]="false">ไม่ใช้งาน</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
<!-- User Form -->
<div class="col-md-4">
<mat-card>
<mat-card-header>
<mat-card-title>เพิ่มผู้ใช้ใหม่</mat-card-title>
</mat-card-header>
<mat-card-content>
<form [formGroup]="userForm" (ngSubmit)="createUser()">
<div class="row">
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ชื่อผู้ใช้</mat-label>
<input matInput formControlName="username" placeholder="username">
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>อีเมล</mat-label>
<input matInput formControlName="email" type="email" placeholder="email@company.com">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ชื่อ</mat-label>
<input matInput formControlName="firstName" placeholder="ชื่อ">
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>นามสกุล</mat-label>
<input matInput formControlName="lastName" placeholder="นามสกุล">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>เบอร์โทร</mat-label>
<input matInput formControlName="phone" placeholder="081-234-5678">
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>แผนก</mat-label>
<mat-select formControlName="department">
<mat-option *ngFor="let dept of departments$ | async" [value]="dept.id">
{{ dept.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ตำแหน่ง</mat-label>
<mat-select formControlName="position">
<mat-option *ngFor="let pos of positions$ | async" [value]="pos.id">
{{ pos.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-slide-toggle formControlName="isActive" class="mt-3">
ใช้งาน
</mat-slide-toggle>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<button mat-raised-button color="primary" type="submit"
[disabled]="!userForm.valid">
<mat-icon>person_add</mat-icon>
เพิ่มผู้ใช้
</button>
<button mat-button type="button" (click)="userForm.reset()">
<mat-icon>refresh</mat-icon>
รีเซ็ต
</button>
</div>
</div>
</form>
</mat-card-content>
</mat-card>
</div>
<!-- User List -->
<div class="col-md-8">
<mat-card>
<mat-card-header>
<mat-card-title>รายการผู้ใช้</mat-card-title>
<mat-card-subtitle>ผู้ใช้ทั้งหมดในระบบ</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngIf="isLoading" class="text-center">
<mat-spinner diameter="30"></mat-spinner>
<p>กำลังโหลด...</p>
</div>
<div *ngIf="!isLoading" class="table-responsive">
<table mat-table [dataSource]="users$ | async" class="w-100">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="masterUserSelectionChange($event.checked)"
[checked]="isAllUsersSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let user">
<mat-checkbox (change)="userSelectionChange(user, $event.checked)"
[checked]="isUserSelected(user)">
</mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="fullName">
<th mat-header-cell *matHeaderCellDef>ชื่อ-นามสกุล</th>
<td mat-cell *matCellDef="let user">
<div class="user-info">
<div class="user-name">{{ user.fullName }}</div>
<div class="user-email text-muted">{{ user.email }}</div>
</div>
</td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef>อีเมล</th>
<td mat-cell *matCellDef="let user">{{ user.email }}</td>
</ng-container>
<ng-container matColumnDef="department">
<th mat-header-cell *matHeaderCellDef>แผนก</th>
<td mat-cell *matCellDef="let user">{{ user.department || '-' }}</td>
</ng-container>
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>ตำแหน่ง</th>
<td mat-cell *matCellDef="let user">{{ user.position || '-' }}</td>
</ng-container>
<ng-container matColumnDef="isActive">
<th mat-header-cell *matHeaderCellDef>สถานะ</th>
<td mat-cell *matCellDef="let user">
<span class="badge badge-{{ getStatusColor(user.isActive) }}">
{{ getStatusText(user.isActive) }}
</span>
</td>
</ng-container>
<ng-container matColumnDef="lastLogin">
<th mat-header-cell *matHeaderCellDef>เข้าสู่ระบบล่าสุด</th>
<td mat-cell *matCellDef="let user">{{ formatDate(user.lastLogin) }}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>การดำเนินการ</th>
<td mat-cell *matCellDef="let user">
<button mat-icon-button matTooltip="แก้ไข">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button matTooltip="ลบ" (click)="deleteUser(user)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="userDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: userDisplayedColumns;"></tr>
</table>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-tab>
<!-- Role Management Tab -->
<mat-tab label="จัดการบทบาท">
<div class="row mt-3">
<!-- Role Filter -->
<div class="col-12">
<mat-card>
<mat-card-header>
<mat-card-title>ค้นหาและกรอง</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-md-4">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ค้นหา</mat-label>
<input matInput [(ngModel)]="roleFilter.search"
(ngModelChange)="onRoleFilterChange()"
placeholder="ชื่อบทบาทหรือคำอธิบาย">
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ประเภท</mat-label>
<mat-select [(ngModel)]="roleFilter.isSystem"
(selectionChange)="onRoleFilterChange()">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option [value]="true">ระบบ</mat-option>
<mat-option [value]="false">ผู้ใช้สร้าง</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field appearance="outline" class="w-100">
<mat-label>สถานะ</mat-label>
<mat-select [(ngModel)]="roleFilter.isActive"
(selectionChange)="onRoleFilterChange()">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option [value]="true">ใช้งาน</mat-option>
<mat-option [value]="false">ไม่ใช้งาน</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
<!-- Role Form -->
<div class="col-md-4">
<mat-card>
<mat-card-header>
<mat-card-title>เพิ่มบทบาทใหม่</mat-card-title>
</mat-card-header>
<mat-card-content>
<form [formGroup]="roleForm" (ngSubmit)="createRole()">
<div class="row">
<div class="col-12">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ชื่อบทบาท</mat-label>
<input matInput formControlName="name" placeholder="role_name">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-12">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ชื่อแสดง</mat-label>
<input matInput formControlName="displayName" placeholder="ชื่อบทบาท">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-12">
<mat-form-field appearance="outline" class="w-100">
<mat-label>คำอธิบาย</mat-label>
<textarea matInput formControlName="description"
placeholder="คำอธิบายบทบาท" rows="3"></textarea>
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-slide-toggle formControlName="isSystem" class="mt-3">
บทบาทระบบ
</mat-slide-toggle>
</div>
<div class="col-md-6">
<mat-slide-toggle formControlName="isActive" class="mt-3">
ใช้งาน
</mat-slide-toggle>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<button mat-raised-button color="primary" type="submit"
[disabled]="!roleForm.valid">
<mat-icon>add</mat-icon>
เพิ่มบทบาท
</button>
<button mat-button type="button" (click)="roleForm.reset()">
<mat-icon>refresh</mat-icon>
รีเซ็ต
</button>
</div>
</div>
</form>
</mat-card-content>
</mat-card>
</div>
<!-- Role List -->
<div class="col-md-8">
<mat-card>
<mat-card-header>
<mat-card-title>รายการบทบาท</mat-card-title>
<mat-card-subtitle>บทบาททั้งหมดในระบบ</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div class="table-responsive">
<table mat-table [dataSource]="roles$ | async" class="w-100">
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="masterRoleSelectionChange($event.checked)"
[checked]="isAllRolesSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let role">
<mat-checkbox (change)="roleSelectionChange(role, $event.checked)"
[checked]="isRoleSelected(role)">
</mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>ชื่อบทบาท</th>
<td mat-cell *matCellDef="let role">{{ role.name }}</td>
</ng-container>
<ng-container matColumnDef="displayName">
<th mat-header-cell *matHeaderCellDef>ชื่อแสดง</th>
<td mat-cell *matCellDef="let role">{{ role.displayName }}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>คำอธิบาย</th>
<td mat-cell *matCellDef="let role">{{ role.description || '-' }}</td>
</ng-container>
<ng-container matColumnDef="isSystem">
<th mat-header-cell *matHeaderCellDef>ระบบ</th>
<td mat-cell *matCellDef="let role">
<span class="badge" [class.badge-primary]="role.isSystem"
[class.badge-secondary]="!role.isSystem">
{{ role.isSystem ? 'ใช่' : 'ไม่' }}
</span>
</td>
</ng-container>
<ng-container matColumnDef="isActive">
<th mat-header-cell *matHeaderCellDef>สถานะ</th>
<td mat-cell *matCellDef="let role">
<span class="badge badge-{{ getStatusColor(role.isActive) }}">
{{ getStatusText(role.isActive) }}
</span>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>การดำเนินการ</th>
<td mat-cell *matCellDef="let role">
<button mat-icon-button matTooltip="แก้ไข">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button matTooltip="ลบ" (click)="deleteRole(role)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="roleDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: roleDisplayedColumns;"></tr>
</table>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-tab>
<!-- Permission Management Tab -->
<mat-tab label="จัดการสิทธิ์">
<div class="row mt-3">
<div class="col-12">
<mat-card>
<mat-card-header>
<mat-card-title>จัดการสิทธิ์การเข้าถึง</mat-card-title>
<mat-card-subtitle>กำหนดสิทธิ์สำหรับบทบาทและผู้ใช้</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngIf="permissions$ | async as permissions">
<div *ngFor="let category of getPermissionCategories(permissions)" class="permission-category">
<h5>{{ category }}</h5>
<div class="permission-grid">
<div *ngFor="let permission of getPermissionsByCategory(permissions, category)"
class="permission-item">
<mat-checkbox [checked]="false">
{{ permission.displayName }}
</mat-checkbox>
<small class="text-muted">{{ permission.description }}</small>
</div>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-tab>
<!-- Statistics Tab -->
<mat-tab label="สถิติ">
<div class="row mt-3">
<div class="col-12">
<mat-card>
<mat-card-header>
<mat-card-title>สถิติผู้ใช้และบทบาท</mat-card-title>
<mat-card-subtitle>ข้อมูลสถิติการใช้งานระบบ</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngIf="statistics$ | async as stats" class="row">
<div class="col-md-3">
<div class="stat-card">
<div class="stat-number">{{ stats.totalUsers }}</div>
<div class="stat-label">ผู้ใช้ทั้งหมด</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-number">{{ stats.activeUsers }}</div>
<div class="stat-label">ผู้ใช้ที่ใช้งาน</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-number">{{ stats.inactiveUsers }}</div>
<div class="stat-label">ผู้ใช้ที่ไม่ใช้งาน</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-number">{{ (roles$ | async)?.length || 0 }}</div>
<div class="stat-label">บทบาททั้งหมด</div>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>
</div>
</div>
.user-info {
.user-name {
font-weight: 500;
margin-bottom: 2px;
}
.user-email {
font-size: 0.875rem;
}
}
.badge {
padding: 4px 8px;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 500;
&.badge-success {
background-color: #4caf50;
color: white;
}
&.badge-danger {
background-color: #f44336;
color: white;
}
&.badge-primary {
background-color: #2196f3;
color: white;
}
&.badge-secondary {
background-color: #6c757d;
color: white;
}
}
.stat-card {
text-align: center;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 8px;
margin-bottom: 16px;
.stat-number {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 8px;
}
.stat-label {
font-size: 0.9rem;
opacity: 0.9;
}
}
.permission-category {
margin-bottom: 24px;
h5 {
color: #333;
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 2px solid #e0e0e0;
}
.permission-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 12px;
.permission-item {
padding: 12px;
border: 1px solid #e0e0e0;
border-radius: 4px;
background-color: #fafafa;
mat-checkbox {
margin-bottom: 4px;
}
small {
display: block;
margin-top: 4px;
}
}
}
}
.table-responsive {
overflow-x: auto;
}
mat-card {
margin-bottom: 16px;
}
mat-card-header {
margin-bottom: 16px;
}
mat-form-field {
margin-bottom: 16px;
}
// Form styling
form {
.row {
margin-bottom: 16px;
}
}
// Button styling
button[mat-raised-button] {
margin-right: 8px;
}
// Loading spinner
mat-spinner {
margin: 0 auto;
}
// Empty state
.text-center {
text-align: center;
}
.text-muted {
color: #6c757d;
}
// Card hover effects
mat-card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
transition: box-shadow 0.2s ease;
}
// Responsive design
@media (max-width: 768px) {
.permission-grid {
grid-template-columns: 1fr;
}
.stat-card {
margin-bottom: 12px;
.stat-number {
font-size: 2rem;
}
}
.table-responsive {
font-size: 0.875rem;
}
}
// Material table styling
.mat-mdc-table {
width: 100%;
}
.mat-mdc-header-cell {
font-weight: 600;
color: #333;
}
.mat-mdc-cell {
padding: 8px 12px;
}
// Checkbox styling
mat-checkbox {
margin-right: 8px;
}
// Slide toggle styling
mat-slide-toggle {
margin: 8px 0;
}
// Form field styling
mat-form-field {
.mat-mdc-form-field-subscript-wrapper {
display: none;
}
}
// Tab styling
mat-tab-group {
margin-top: 16px;
}
// Card content spacing
mat-card-content {
padding: 16px;
}
// Row spacing
.row {
margin-bottom: 16px;
}
// Utility classes
.w-100 {
width: 100%;
}
.mt-3 {
margin-top: 16px;
}
.mb-3 {
margin-bottom: 16px;
}
.me-2 {
margin-right: 8px;
}
.ms-2 {
margin-left: 8px;
}
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatCardModule } from '@angular/material/card';
import { FormsModule } from '@angular/forms';
import { MatTableModule } from '@angular/material/table';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule, MatDialog } from '@angular/material/dialog';
import { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
import { MatSnackBarModule, MatSnackBar } from '@angular/material/snack-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatChipInputEvent } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { UserRoleService } from '../services/user-role.service';
import { User, Role, Permission, Department, Position, UserFilter, RoleFilter } from '../models/user-role.model';
interface User {
id: string;
name: string;
email: string;
roleId: string;
departmentId: string;
positionId: string;
status: string;
}
interface Role {
id: string;
name: string;
description: string;
permissions: string[];
}
interface Department {
id: string;
name: string;
}
interface Position {
id: string;
name: string;
}
interface UserFilter {
search: string;
roleId: string;
departmentId: string;
positionId: string;
status: string;
}
@Component({
selector: 'app-user-role-management',
......@@ -30,322 +54,297 @@ import { User, Role, Permission, Department, Position, UserFilter, RoleFilter }
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
MatCardModule,
MatTableModule,
MatButtonModule,
MatIconModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatTableModule,
MatPaginatorModule,
MatSortModule,
MatCheckboxModule,
MatChipsModule,
MatDialogModule,
MatCardModule,
MatTabsModule,
MatDialogModule,
MatSnackBarModule,
MatProgressSpinnerModule,
MatSlideToggleModule,
TranslateModule
],
templateUrl: './user-role-management.component.html',
styleUrls: ['./user-role-management.component.scss']
})
export class UserRoleManagementComponent implements OnInit {
users$: Observable<User[]>;
roles$: Observable<Role[]>;
permissions$: Observable<Permission[]>;
departments$: Observable<Department[]>;
positions$: Observable<Position[]>;
statistics$: Observable<any>;
// User management
userForm: FormGroup;
userFilter: UserFilter = {};
selectedUsers: User[] = [];
userDisplayedColumns: string[] = ['select', 'fullName', 'email', 'department', 'position', 'isActive', 'lastLogin', 'actions'];
// Role management
roleForm: FormGroup;
roleFilter: RoleFilter = {};
selectedRoles: Role[] = [];
roleDisplayedColumns: string[] = ['select', 'name', 'displayName', 'description', 'isSystem', 'isActive', 'actions'];
// Permission management
selectedRolePermissions: { [roleId: string]: string[] } = {};
selectedUserPermissions: { [userId: string]: string[] } = {};
isLoading = false;
constructor(
private userRoleService: UserRoleService,
private fb: FormBuilder,
private dialog: MatDialog,
private snackBar: MatSnackBar
) {
this.users$ = this.userRoleService.users$;
this.roles$ = this.userRoleService.roles$;
this.permissions$ = this.userRoleService.permissions$;
this.departments$ = this.userRoleService.departments$;
this.positions$ = this.userRoleService.positions$;
this.statistics$ = this.userRoleService.getUserStatistics();
this.userForm = this.fb.group({
username: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
phone: [''],
department: [''],
position: [''],
isActive: [true]
});
this.roleForm = this.fb.group({
name: ['', Validators.required],
displayName: ['', Validators.required],
description: [''],
isSystem: [false],
isActive: [true],
permissions: [[]]
});
}
ngOnInit(): void {
this.loadData();
}
loadData(): void {
this.isLoading = true;
this.userRoleService.getUsers(this.userFilter).subscribe({
next: () => this.isLoading = false,
error: () => this.isLoading = false
});
}
// User management methods
onUserFilterChange(): void {
this.loadData();
}
createUser(): void {
if (this.userForm.valid) {
const formValue = this.userForm.value;
const user = {
username: formValue.username,
email: formValue.email,
firstName: formValue.firstName,
lastName: formValue.lastName,
fullName: `${formValue.firstName} ${formValue.lastName}`,
phone: formValue.phone,
department: formValue.department,
position: formValue.position,
isActive: formValue.isActive
};
this.userRoleService.createUser(user).subscribe({
next: () => {
this.snackBar.open('สร้างผู้ใช้สำเร็จ', 'ปิด', { duration: 3000 });
this.userForm.reset();
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">จัดการผู้ใช้และบทบาท</h4>
</div>
<div class="card-body">
<mat-tab-group>
<!-- Users Tab -->
<mat-tab label="ผู้ใช้">
<div class="mt-3">
<!-- Filter Section -->
<div class="row mb-3">
<div class="col-md-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ค้นหา</mat-label>
<input matInput [(ngModel)]="userFilter.search" placeholder="ชื่อ, อีเมล">
</mat-form-field>
</div>
<div class="col-md-2">
<mat-form-field appearance="outline" class="w-100">
<mat-label>บทบาท</mat-label>
<mat-select [(ngModel)]="userFilter.roleId">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option *ngFor="let role of roles" [value]="role.id">{{ role.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<mat-form-field appearance="outline" class="w-100">
<mat-label>แผนก</mat-label>
<mat-select [(ngModel)]="userFilter.departmentId">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option *ngFor="let dept of departments" [value]="dept.id">{{ dept.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<mat-form-field appearance="outline" class="w-100">
<mat-label>ตำแหน่ง</mat-label>
<mat-select [(ngModel)]="userFilter.positionId">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option *ngFor="let pos of positions" [value]="pos.id">{{ pos.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<mat-form-field appearance="outline" class="w-100">
<mat-label>สถานะ</mat-label>
<mat-select [(ngModel)]="userFilter.status">
<mat-option value="">ทั้งหมด</mat-option>
<mat-option value="active">ใช้งาน</mat-option>
<mat-option value="inactive">ไม่ใช้งาน</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-1">
<button mat-raised-button color="primary" (click)="filterUsers()" class="w-100">
<mat-icon>search</mat-icon>
</button>
</div>
</div>
<!-- Users Table -->
<div class="table-responsive">
<table mat-table [dataSource]="filteredUsers" class="w-100">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>ชื่อ</th>
<td mat-cell *matCellDef="let user">{{ user.name }}</td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef>อีเมล</th>
<td mat-cell *matCellDef="let user">{{ user.email }}</td>
</ng-container>
<ng-container matColumnDef="role">
<th mat-header-cell *matHeaderCellDef>บทบาท</th>
<td mat-cell *matCellDef="let user">{{ getRoleName(user.roleId) }}</td>
</ng-container>
<ng-container matColumnDef="department">
<th mat-header-cell *matHeaderCellDef>แผนก</th>
<td mat-cell *matCellDef="let user">{{ getDepartmentName(user.departmentId) }}</td>
</ng-container>
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>ตำแหน่ง</th>
<td mat-cell *matCellDef="let user">{{ getPositionName(user.positionId) }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef>สถานะ</th>
<td mat-cell *matCellDef="let user">
<span [class]="user.status === 'active' ? 'badge badge-success' : 'badge badge-danger'">
{{ user.status === 'active' ? 'ใช้งาน' : 'ไม่ใช้งาน' }}
</span>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>การดำเนินการ</th>
<td mat-cell *matCellDef="let user">
<button mat-icon-button color="primary" (click)="editUser(user)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteUser(user)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="userColumns"></tr>
<tr mat-row *matRowDef="let row; columns: userColumns;"></tr>
</table>
</div>
</div>
</mat-tab>
<!-- Roles Tab -->
<mat-tab label="บทบาท">
<div class="mt-3">
<!-- Roles Table -->
<div class="table-responsive">
<table mat-table [dataSource]="roles" class="w-100">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>ชื่อบทบาท</th>
<td mat-cell *matCellDef="let role">{{ role.name }}</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>คำอธิบาย</th>
<td mat-cell *matCellDef="let role">{{ role.description }}</td>
</ng-container>
<ng-container matColumnDef="permissions">
<th mat-header-cell *matHeaderCellDef>สิทธิ์</th>
<td mat-cell *matCellDef="let role">
<span *ngFor="let permission of role.permissions" class="badge badge-info mr-1">
{{ permission }}
</span>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>การดำเนินการ</th>
<td mat-cell *matCellDef="let role">
<button mat-icon-button color="primary" (click)="editRole(role)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteRole(role)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="roleColumns"></tr>
<tr mat-row *matRowDef="let row; columns: roleColumns;"></tr>
</table>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
}
updateUser(user: User): void {
this.userRoleService.updateUser(user.id, user).subscribe({
next: () => {
this.snackBar.open('อัปเดตผู้ใช้สำเร็จ', 'ปิด', { duration: 3000 });
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
}
deleteUser(user: User): void {
if (confirm(`คุณต้องการลบผู้ใช้ ${user.fullName} หรือไม่?`)) {
this.userRoleService.deleteUser(user.id).subscribe({
next: () => {
this.snackBar.open('ลบผู้ใช้สำเร็จ', 'ปิด', { duration: 3000 });
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
}
// Role management methods
onRoleFilterChange(): void {
this.userRoleService.getRoles(this.roleFilter).subscribe();
}
createRole(): void {
if (this.roleForm.valid) {
const formValue = this.roleForm.value;
const role = {
name: formValue.name,
displayName: formValue.displayName,
description: formValue.description,
isSystem: formValue.isSystem,
isActive: formValue.isActive,
permissions: formValue.permissions || []
};
this.userRoleService.createRole(role).subscribe({
next: () => {
this.snackBar.open('สร้างบทบาทสำเร็จ', 'ปิด', { duration: 3000 });
this.roleForm.reset();
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
}
}
updateRole(role: Role): void {
this.userRoleService.updateRole(role.id, role).subscribe({
next: () => {
this.snackBar.open('อัปเดตบทบาทสำเร็จ', 'ปิด', { duration: 3000 });
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
}
deleteRole(role: Role): void {
if (confirm(`คุณต้องการลบบทบาท ${role.displayName} หรือไม่?`)) {
this.userRoleService.deleteRole(role.id).subscribe({
next: () => {
this.snackBar.open('ลบบทบาทสำเร็จ', 'ปิด', { duration: 3000 });
this.loadData();
},
error: (error) => {
this.snackBar.open('เกิดข้อผิดพลาด: ' + error.message, 'ปิด', { duration: 5000 });
}
});
}
}
// Permission management methods
onRolePermissionChange(roleId: string, permissionId: string, isChecked: boolean): void {
if (!this.selectedRolePermissions[roleId]) {
this.selectedRolePermissions[roleId] = [];
.badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
}
if (isChecked) {
if (!this.selectedRolePermissions[roleId].includes(permissionId)) {
this.selectedRolePermissions[roleId].push(permissionId);
}
} else {
this.selectedRolePermissions[roleId] = this.selectedRolePermissions[roleId].filter(p => p !== permissionId);
.badge-success {
background-color: #28a745;
color: white;
}
}
onUserPermissionChange(userId: string, permissionId: string, isChecked: boolean): void {
if (!this.selectedUserPermissions[userId]) {
this.selectedUserPermissions[userId] = [];
.badge-danger {
background-color: #dc3545;
color: white;
}
if (isChecked) {
if (!this.selectedUserPermissions[userId].includes(permissionId)) {
this.selectedUserPermissions[userId].push(permissionId);
}
} else {
this.selectedUserPermissions[userId] = this.selectedUserPermissions[userId].filter(p => p !== permissionId);
.badge-info {
background-color: #17a2b8;
color: white;
}
}
`]
})
export class UserRoleManagementComponent implements OnInit {
users: User[] = [];
filteredUsers: User[] = [];
roles: Role[] = [];
departments: Department[] = [];
positions: Position[] = [];
saveRolePermissions(roleId: string): void {
const permissions = this.selectedRolePermissions[roleId] || [];
// Implementation would save role permissions
this.snackBar.open('บันทึกสิทธิ์บทบาทสำเร็จ', 'ปิด', { duration: 3000 });
}
userFilter: UserFilter = {
search: '',
roleId: '',
departmentId: '',
positionId: '',
status: ''
};
saveUserPermissions(userId: string): void {
const permissions = this.selectedUserPermissions[userId] || [];
// Implementation would save user permissions
this.snackBar.open('บันทึกสิทธิ์ผู้ใช้สำเร็จ', 'ปิด', { duration: 3000 });
}
userColumns: string[] = ['name', 'email', 'role', 'department', 'position', 'status', 'actions'];
roleColumns: string[] = ['name', 'description', 'permissions', 'actions'];
// Selection methods
isAllUsersSelected(): boolean {
// Implementation for checking if all users are selected
return false;
}
constructor() { }
isAllRolesSelected(): boolean {
// Implementation for checking if all roles are selected
return false;
ngOnInit(): void {
this.loadData();
}
masterUserSelectionChange(isChecked: boolean): void {
// Implementation for master user selection
loadData(): void {
// Mock data
this.users = [
{ id: '1', name: 'John Doe', email: 'john@example.com', roleId: '1', departmentId: '1', positionId: '1', status: 'active' },
{ id: '2', name: 'Jane Smith', email: 'jane@example.com', roleId: '2', departmentId: '2', positionId: '2', status: 'active' }
];
this.roles = [
{ id: '1', name: 'Admin', description: 'ผู้ดูแลระบบ', permissions: ['read', 'write', 'delete'] },
{ id: '2', name: 'User', description: 'ผู้ใช้ทั่วไป', permissions: ['read'] }
];
this.departments = [
{ id: '1', name: 'IT' },
{ id: '2', name: 'HR' }
];
this.positions = [
{ id: '1', name: 'Manager' },
{ id: '2', name: 'Developer' }
];
this.filteredUsers = [...this.users];
}
masterRoleSelectionChange(isChecked: boolean): void {
// Implementation for master role selection
}
filterUsers(): void {
this.filteredUsers = this.users.filter(user => {
const matchesSearch = !this.userFilter.search ||
user.name.toLowerCase().includes(this.userFilter.search.toLowerCase()) ||
user.email.toLowerCase().includes(this.userFilter.search.toLowerCase());
isUserSelected(user: User): boolean {
return this.selectedUsers.includes(user);
}
const matchesRole = !this.userFilter.roleId || user.roleId === this.userFilter.roleId;
const matchesDepartment = !this.userFilter.departmentId || user.departmentId === this.userFilter.departmentId;
const matchesPosition = !this.userFilter.positionId || user.positionId === this.userFilter.positionId;
const matchesStatus = !this.userFilter.status || user.status === this.userFilter.status;
isRoleSelected(role: Role): boolean {
return this.selectedRoles.includes(role);
return matchesSearch && matchesRole && matchesDepartment && matchesPosition && matchesStatus;
});
}
userSelectionChange(user: User, isChecked: boolean): void {
if (isChecked) {
if (!this.selectedUsers.includes(user)) {
this.selectedUsers.push(user);
}
} else {
this.selectedUsers = this.selectedUsers.filter(u => u.id !== user.id);
}
getRoleName(roleId: string): string {
const role = this.roles.find(r => r.id === roleId);
return role ? role.name : 'ไม่ระบุ';
}
roleSelectionChange(role: Role, isChecked: boolean): void {
if (isChecked) {
if (!this.selectedRoles.includes(role)) {
this.selectedRoles.push(role);
}
} else {
this.selectedRoles = this.selectedRoles.filter(r => r.id !== role.id);
}
getDepartmentName(departmentId: string): string {
const dept = this.departments.find(d => d.id === departmentId);
return dept ? dept.name : 'ไม่ระบุ';
}
// Utility methods
getStatusColor(isActive: boolean): string {
return isActive ? 'success' : 'danger';
getPositionName(positionId: string): string {
const pos = this.positions.find(p => p.id === positionId);
return pos ? pos.name : 'ไม่ระบุ';
}
getStatusText(isActive: boolean): string {
return isActive ? 'ใช้งาน' : 'ไม่ใช้งาน';
editUser(user: User): void {
console.log('Edit user:', user);
}
formatDate(date: Date | string | undefined): string {
if (!date) return '-';
return new Date(date).toLocaleDateString('th-TH');
deleteUser(user: User): void {
console.log('Delete user:', user);
}
getPermissionCategories(permissions: Permission[]): string[] {
return [...new Set(permissions.map(p => p.category))];
editRole(role: Role): void {
console.log('Edit role:', role);
}
getPermissionsByCategory(permissions: Permission[], category: string): Permission[] {
return permissions.filter(p => p.category === category);
deleteRole(role: Role): void {
console.log('Delete role:', role);
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { WidgetListComponent } from './widget-list.component';
import { WidgetFormComponent } from './widget-form.component';
export const routes: Routes = [
{
path: '',
component: WidgetListComponent
},
{
path: 'edit/:widgetId',
component: WidgetFormComponent
}
];
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild(routes),
WidgetListComponent,
WidgetFormComponent
],
exports: []
})
export class WidgetManagementModule {
static routes = routes;
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-attendance',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">ระบบลงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบลงเวลาทำงานสำหรับ Zeeme</p>
<div class="mt-4 grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-green-50 p-4 rounded-lg">
<h3 class="font-semibold text-green-800">เข้างาน</h3>
<p class="text-sm text-green-600">เวลา: 08:00</p>
</div>
<div class="bg-red-50 p-4 rounded-lg">
<h3 class="font-semibold text-red-800">ออกงาน</h3>
<p class="text-sm text-red-600">เวลา: 17:00</p>
</div>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeAttendanceComponent { }
import { Component } from '@angular/core';
@Component({
selector: 'app-zeeme-dashboard',
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Zeeme Plus Dashboard</h4>
</div>
<div class="card-body">
<p>ยินดีต้อนรับสู่ระบบ Zeeme Plus</p>
<p>ระบบจัดการเวลาและลงเวลา</p>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class ZeemeDashboardComponent {
constructor() { }
}
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-overtime',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">การทำงานล่วงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบจัดการการทำงานล่วงเวลาสำหรับ Zeeme</p>
<div class="mt-4">
<button class="bg-orange-500 hover:bg-orange-600 text-white px-4 py-2 rounded">
ขอทำงานล่วงเวลา
</button>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeOvertimeComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-attendance-report',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงานการลงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>รายงานการลงเวลาทำงานสำหรับ Zeeme</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
ส่งออกรายงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeAttendanceReportComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-overtime-report',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงานการทำงานล่วงเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>รายงานการทำงานล่วงเวลาสำหรับ Zeeme</p>
<div class="mt-4">
<button class="bg-orange-500 hover:bg-orange-600 text-white px-4 py-2 rounded">
ส่งออกรายงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeOvertimeReportComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-summary-report',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">รายงานสรุป</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>รายงานสรุปข้อมูลการทำงานสำหรับ Zeeme</p>
<div class="mt-4">
<button class="bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded">
ส่งออกรายงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeSummaryReportComponent { }
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-zeeme-time-tracking',
standalone: true,
imports: [CommonModule],
template: `
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">ติดตามเวลา</h1>
<div class="bg-white rounded-lg shadow p-6">
<p>ระบบติดตามเวลาทำงานสำหรับ Zeeme</p>
<div class="mt-4">
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded mr-2">
เริ่มงาน
</button>
<button class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded">
หยุดงาน
</button>
</div>
</div>
</div>
`,
styles: []
})
export class ZeemeTimeTrackingComponent { }
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'app-zeeme',
templateUrl: './zeeme.component.html',
styleUrls: ['./zeeme.component.css']
template: `
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Zeeme Plus</h4>
</div>
<div class="card-body">
<router-outlet></router-outlet>
</div>
</div>
</div>
</div>
</div>
`,
styles: [`
.card {
margin: 20px 0;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
`]
})
export class ZeemeComponent implements OnInit {
export class ZeemeComponent {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ZeemeComponent } from './zeeme.component';
import { RouterModule, Routes } from '@angular/router';
export const zeeme: Routes = [
import { ZeemeComponent } from './zeeme.component';
import { ZeemeDashboardComponent } from './dashboard/zeeme-dashboard.component';
export const routes: Routes = [
{
path: "zeeme", children:[
path: '',
component: ZeemeComponent,
children: [
{
path: 'dashboard',
loadComponent: () =>
import('./dashboard/dashboard.component').then((m) => m.DashboardComponent),
component: ZeemeDashboardComponent
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
]
];
@NgModule({
declarations: [
ZeemeComponent,
ZeemeDashboardComponent
],
imports: [
CommonModule,
RouterModule.forChild(zeeme),
RouterModule.forChild(routes)
],
declarations: [ZeemeComponent]
exports: [
ZeemeComponent
]
})
export class ZeemeModule {
static routes = zeeme;
}
static routes = routes;
}
import { Routes } from '@angular/router';
import { ZeemeComponent } from './zeeme.component';
import { ZeemeDashboardComponent } from './dashboard/zeeme-dashboard.component';
export const ZEEME_ROUTES: Routes = [
{
path: '',
component: ZeemeComponent,
children: [
{
path: 'dashboard',
component: ZeemeDashboardComponent
},
{
path: 'time-tracking',
loadComponent: () => import('./time-tracking/zeeme-time-tracking.component').then(m => m.ZeemeTimeTrackingComponent)
},
{
path: 'attendance',
loadComponent: () => import('./attendance/zeeme-attendance.component').then(m => m.ZeemeAttendanceComponent)
},
{
path: 'overtime',
loadComponent: () => import('./overtime/zeeme-overtime.component').then(m => m.ZeemeOvertimeComponent)
},
{
path: 'attendance-report',
loadComponent: () => import('./reports/zeeme-attendance-report.component').then(m => m.ZeemeAttendanceReportComponent)
},
{
path: 'overtime-report',
loadComponent: () => import('./reports/zeeme-overtime-report.component').then(m => m.ZeemeOvertimeReportComponent)
},
{
path: 'summary-report',
loadComponent: () => import('./reports/zeeme-summary-report.component').then(m => m.ZeemeSummaryReportComponent)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
}
];
......@@ -64,7 +64,7 @@ export class SidebarComponent {
options = { autoHide: false, scrollbarMinSize: 100 };
icon!: SafeHtml;
public menuItems!: Menu[];
public menuItems: Menu[] = [];
public menuitemsSubscribe$!: Subscription;
companyModel: CompanyModel = new CompanyModel()
isCommonRoute: boolean = false;
......@@ -167,7 +167,7 @@ export class SidebarComponent {
console.log('myface routes',this.isMyFaceRoute);
console.log('zeeme routes',this.isZeemeRoute);
console.log('myhrplus routes',this.isMyhrPlusRoute);
}
checkUrlChanges(): void {
......@@ -188,7 +188,7 @@ export class SidebarComponent {
(this.previousUrl.includes('/myprotal')&& this.currentUrl.includes('/myprotal')) ||
(this.previousUrl.includes('/mylearn')&& this.currentUrl.includes('/mylearn')) ||
(this.previousUrl.includes('/myjob')&& this.currentUrl.includes('/myjob')) ||
(this.previousUrl.includes('/myhr-lite')&& this.currentUrl.includes('/myhr-lite'))
(this.previousUrl.includes('/myhr-lite')&& this.currentUrl.includes('/myhr-lite'))
) {
console.log('URL changed between /installer and /admin.');
// Implement any logic needed when changing between /installer and /admin
......@@ -279,6 +279,9 @@ export class SidebarComponent {
//Active Nav State
setNavActive(item: any) {
if (!this.menuItems || !Array.isArray(this.menuItems)) {
return;
}
this.menuItems?.filter((menuItem) => {
if (menuItem !== item) {
menuItem.active = false;
......@@ -330,6 +333,9 @@ export class SidebarComponent {
if (!item.active) {
if (!this.menuItems || !Array.isArray(this.menuItems)) {
return;
}
this.menuItems?.forEach((a: any) => {
if (this.menuItems.includes(item)) {
a.active = false;
......@@ -352,6 +358,9 @@ export class SidebarComponent {
}
// Close Nav menu
closeNavActive() {
if (!this.menuItems || !Array.isArray(this.menuItems)) {
return;
}
this.menuItems?.forEach((a: any) => {
if (this.menuItems) {
a.active = false;
......@@ -365,6 +374,9 @@ export class SidebarComponent {
}
ParentActive() {
if (!this.menuItems || !Array.isArray(this.menuItems)) {
return;
}
this.menuItems.map((element: any) => {
if (element.children) {
element.active = false;
......
......@@ -170,7 +170,6 @@ export class NavService implements OnDestroy {
// Dashboard
{ headTitle: 'จัดการบริษัท' },
this.createDashboardMenu('company'),
// { headTitle: 'User Management' },
{
title: 'จัดการข้อมูลบริษัท',
icon: 'buildings',
......@@ -179,11 +178,10 @@ export class NavService implements OnDestroy {
badgeText: 'warning',
active: false,
children: [
{ path: '/company/company-info', title: 'ข้อมูลบริษัท', type: 'link' },
{ path: '/company/company-department', title: 'จัดการแผนก', type: 'link' },
{ path: '/company/company-position', title: 'จัดการตำแหน่ง', type: 'link' },
// { path: '/company/company-hr', title: 'จัดการผู้ดูแลบริษัท', type: 'link' },
{ path: '/company/company-emp', title: 'พนักงาน', type: 'link' },
{ path: '/portal-manage/company-management/company-info', title: 'ข้อมูลบริษัท', type: 'link' },
{ path: '/portal-manage/company-management/company-department', title: 'จัดการแผนก', type: 'link' },
{ path: '/portal-manage/company-management/company-position', title: 'จัดการตำแหน่ง', type: 'link' },
{ path: '/portal-manage/company-management/company-emp', title: 'พนักงาน', type: 'link' },
],
},
{
......@@ -194,9 +192,19 @@ export class NavService implements OnDestroy {
badgeText: 'warning',
active: false,
children: [
{ path: '/company/company-location', title: 'สถานที่การลงเวลา', type: 'link' },
{ path: '/company/timestamp-log', title: 'ข้อมูลการลงเวลา', type: 'link' },
// { path: '/company/warning-timestamp-log', title: 'อนุมัติการลงเวลา', type: 'link' },
{ path: '/portal-manage/company-management/company-location', title: 'สถานที่การลงเวลา', type: 'link' },
{ path: '/portal-manage/company-management/timestamp-log', title: 'ข้อมูลการลงเวลา', type: 'link' },
{ path: '/portal-manage/company-management/warning-timetamp', title: 'อนุมัติการลงเวลา', type: 'link' },
],
},
{
title: 'จัดการใบหน้า',
icon: 'user-check',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/company-management/enroll-face', title: 'ลงทะเบียนใบหน้า', type: 'link' },
{ path: '/portal-manage/company-management/home-installer', title: 'ติดตั้งระบบ', type: 'link' },
],
}
];
......@@ -204,58 +212,50 @@ export class NavService implements OnDestroy {
getMyportalMenu() {
return [
// Myportal
// MyPortal
{ headTitle: 'MyPortal' },
this.createDashboardMenu('myskill-x'),
...this.createPortalMenu('myskill-x'),
{}
{
title: 'จัดการระบบ',
icon: 'settings',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myskill-x/admin-manage', title: 'จัดการผู้ดูแลระบบ', type: 'link' },
{ path: '/portal-manage/myskill-x/user-management', title: 'จัดการผู้ใช้', type: 'link' },
],
}
];
}
getMylearnMenu() {
return [
// Myportal
{ headTitle: 'Mylearn' },
// MyLearn
{ headTitle: 'MyLearn' },
this.createDashboardMenu('mylearn'),
{
// icon: 'receipt',
// path: '/mylearn/dashboard',
// title: 'dashboard',
// type: 'link',
icon: 'news bx-flip-horizontal',
path: '/mylearn/mylearn-pdpa-manage',
title: 'จัดการ PDPA',
type: 'link',
},
// {
// icon: 'receipt',
// path: '/mylearn/user-company',
// title: 'จัดการบริษัท',
// type: 'link',
// },
{
icon: 'briefcase',
path: '/mylearn/myhrcompany',
title: 'จัดการบริษัท',
type: 'link',
},
{
icon: 'user',
path: '/mylearn/management-user',
title: 'การจัดการผู้ใช้งาน',
type: 'link',
},
{
icon: 'repeat',
path: '/mylearn/course-transfer',
title: 'โอนย้ายคอร์ส',
type: 'link',
title: 'จัดการระบบ',
icon: 'settings',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/mylearn/mylearn-pdpa-manage', title: 'จัดการ PDPA', type: 'link' },
{ path: '/portal-manage/mylearn/myhrcompany', title: 'จัดการบริษัท', type: 'link' },
{ path: '/portal-manage/mylearn/management-user', title: 'การจัดการผู้ใช้งาน', type: 'link' },
{ path: '/portal-manage/mylearn/course-transfer', title: 'โอนย้ายคอร์ส', type: 'link' },
{ path: '/portal-manage/mylearn/timeout-screen-manage', title: 'จัดการเวลาหน้าจอ', type: 'link' },
],
},
{
icon: 'time',
path: '/mylearn/timeout-screen-manage',
title: 'จัดการเวลาหน้าจอ',
type: 'link',
title: 'จัดการคอร์ส',
icon: 'book-open',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/mylearn/company-manage-course', title: 'จัดการคอร์สบริษัท', type: 'link' },
{ path: '/portal-manage/mylearn/user-company', title: 'จัดการผู้ใช้บริษัท', type: 'link' },
],
},
...this.createPortalMenu('mylearn')
];
......@@ -263,47 +263,54 @@ export class NavService implements OnDestroy {
getMyJobMenu() {
return [
// Dashboard
// MyJob
{ headTitle: 'MyJob' },
this.createDashboardMenu('myjob'),
{
icon: 'news bx-flip-horizontal',
path: '/myjob/pdpa-manage',
title: 'จัดการ PDPA',
type: 'link',
},
{
icon: 'receipt',
path: '/myjob/manage-articles',
title: 'จัดการบทความ',
type: 'link',
title: 'จัดการระบบ',
icon: 'settings',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myjob/pdpa-manage', title: 'จัดการ PDPA', type: 'link' },
{ path: '/portal-manage/myjob/manage-articles', title: 'จัดการบทความ', type: 'link' },
],
},
{
icon: 'user',
path: '/myjob/company-departments',
title: 'จัดการผู้ใช้',
icon: 'user',
type: 'sub',
active: false,
children: [
{ path: '/myjob/manage-companys', title: 'จัดการบริษัท', type: 'link' },
{ path: '/myjob/member-manage', title: 'จัดการผู้สมัครงาน', type: 'link' }
{ path: '/portal-manage/myjob/manage-companys', title: 'จัดการบริษัท', type: 'link' },
{ path: '/portal-manage/myjob/member-manage', title: 'จัดการผู้สมัครงาน', type: 'link' },
{ path: '/portal-manage/myjob/company-departments', title: 'จัดการแผนกบริษัท', type: 'link' },
],
},
{
icon: 'buildings',
path: '/myjob/company-departments',
title: 'ทะเบียนบริษัท',
icon: 'buildings',
type: 'sub',
active: false,
children: [
{ path: '/myjob/career-cluster', title: 'จัดการกลุ่มอาชีพ', type: 'link' },
{ path: '/myjob/position', title: 'จัดการตำแหน่ง', type: 'link' },
{ path: '/myjob/job-types', title: 'จัดการประเภทงาน', type: 'link' },
{ path: '/myjob/category-company', title: 'จัดการประเภทธุรกิจ', type: 'link' },
{ path: '/myjob/degree-manage', title: 'จัดการระดับการศึกษา', type: 'link' },
{ path: '/myjob/country-registration', title: 'จัดการประเทศ', type: 'link' },
{ path: '/myjob/provinces', title: 'จัดการจังหวัด', type: 'link' },
{ path: '/myjob/institution', title: 'จัดการสถาบันการศึกษา', type: 'link' },
{ path: '/myjob/faculty', title: 'จัดการคณะ', type: 'link' },
{ path: '/myjob/major', title: 'จัดการสาขาวิชา', type: 'link' },
{ path: '/portal-manage/myjob/career-cluster', title: 'จัดการกลุ่มอาชีพ', type: 'link' },
{ path: '/portal-manage/myjob/position', title: 'จัดการตำแหน่ง', type: 'link' },
{ path: '/portal-manage/myjob/job-types', title: 'จัดการประเภทงาน', type: 'link' },
{ path: '/portal-manage/myjob/category-company', title: 'จัดการประเภทธุรกิจ', type: 'link' },
],
},
{
title: 'จัดการข้อมูลพื้นฐาน',
icon: 'database',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myjob/degree-manage', title: 'จัดการระดับการศึกษา', type: 'link' },
{ path: '/portal-manage/myjob/country-registration', title: 'จัดการประเทศ', type: 'link' },
{ path: '/portal-manage/myjob/provinces', title: 'จัดการจังหวัด', type: 'link' },
{ path: '/portal-manage/myjob/institution', title: 'จัดการสถาบันการศึกษา', type: 'link' },
{ path: '/portal-manage/myjob/faculty', title: 'จัดการคณะ', type: 'link' },
{ path: '/portal-manage/myjob/major', title: 'จัดการสาขาวิชา', type: 'link' },
],
},
...this.createPortalMenu('myjob')
......@@ -313,59 +320,271 @@ export class NavService implements OnDestroy {
getMyhrLiteMenu() {
return [
// myHR-Lite
{ headTitle: 'Myhr-lite' },
{ headTitle: 'myHR-Lite' },
this.createDashboardMenu('myhr-lite'),
{
icon: 'receipt',
path: '/myhr-lite/dashboard',
title: 'dashboard',
title: 'แดชบอร์ด',
icon: 'dashboard',
path: '/portal-manage/myhr-lite/dashboard',
type: 'link',
},
{
title: 'จัดการระบบ',
icon: 'settings',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myhr-lite/employee', title: 'จัดการพนักงาน', type: 'link' },
{ path: '/portal-manage/myhr-lite/reports', title: 'รายงาน', type: 'link' },
],
}
];
}
getMyFaceMenu() {
return [
// myHR-Lite
{ headTitle: 'Myface' },
// myFace
{ headTitle: 'myFace' },
this.createDashboardMenu('myface'),
{
icon: 'receipt',
path: '/myface/dashboard',
title: 'dashboard',
title: 'แดชบอร์ด',
icon: 'dashboard',
path: '/portal-manage/myface/dashboard',
type: 'link',
},
{
title: 'จัดการใบหน้า',
icon: 'user-check',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myface/face-recognition', title: 'ระบบจดจำใบหน้า', type: 'link' },
{ path: '/portal-manage/myface/face-management', title: 'จัดการข้อมูลใบหน้า', type: 'link' },
{ path: '/portal-manage/myface/attendance', title: 'ระบบลงเวลา', type: 'link' },
],
},
{
title: 'รายงาน',
icon: 'chart-bar',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myface/attendance-report', title: 'รายงานการลงเวลา', type: 'link' },
{ path: '/portal-manage/myface/face-report', title: 'รายงานการจดจำใบหน้า', type: 'link' },
],
}
];
}
getZeemeMenu() {
return [
// myHR-Lite
{ headTitle: 'Zeemeplus' },
// Zeeme Plus
{ headTitle: 'Zeeme Plus' },
this.createDashboardMenu('zeeme'),
{
icon: 'receipt',
path: '/zeeme/dashboard',
title: 'dashboard',
title: 'แดชบอร์ด',
icon: 'dashboard',
path: '/portal-manage/zeeme/dashboard',
type: 'link',
},
{
title: 'จัดการเวลา',
icon: 'time',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/zeeme/time-tracking', title: 'ติดตามเวลา', type: 'link' },
{ path: '/portal-manage/zeeme/attendance', title: 'ระบบลงเวลา', type: 'link' },
{ path: '/portal-manage/zeeme/overtime', title: 'การทำงานล่วงเวลา', type: 'link' },
],
},
{
title: 'รายงาน',
icon: 'chart-bar',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/zeeme/attendance-report', title: 'รายงานการลงเวลา', type: 'link' },
{ path: '/portal-manage/zeeme/overtime-report', title: 'รายงานการทำงานล่วงเวลา', type: 'link' },
{ path: '/portal-manage/zeeme/summary-report', title: 'รายงานสรุป', type: 'link' },
],
}
];
}
getMyhrPlusMenu() {
return [
// myHR-Lite
{ headTitle: 'Myhr-plus' },
// myHR-Plus
{ headTitle: 'myHR-Plus' },
this.createDashboardMenu('myhr-plus'),
{
icon: 'receipt',
path: '/myhr-plus/dashboard',
title: 'dashboard',
title: 'แดชบอร์ด',
icon: 'dashboard',
path: '/portal-manage/myhr-plus/dashboard',
type: 'link',
},
{
title: 'จัดการพนักงาน',
icon: 'users',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myhr-plus/employee-management', title: 'จัดการข้อมูลพนักงาน', type: 'link' },
{ path: '/portal-manage/myhr-plus/attendance', title: 'ระบบลงเวลา', type: 'link' },
{ path: '/portal-manage/myhr-plus/leave-management', title: 'จัดการการลา', type: 'link' },
{ path: '/portal-manage/myhr-plus/payroll', title: 'ระบบเงินเดือน', type: 'link' },
],
},
{
title: 'จัดการองค์กร',
icon: 'building',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myhr-plus/department', title: 'จัดการแผนก', type: 'link' },
{ path: '/portal-manage/myhr-plus/position', title: 'จัดการตำแหน่ง', type: 'link' },
{ path: '/portal-manage/myhr-plus/org-chart', title: 'แผนภูมิองค์กร', type: 'link' },
],
},
{
title: 'รายงาน',
icon: 'chart-bar',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/myhr-plus/hr-reports', title: 'รายงาน HR', type: 'link' },
{ path: '/portal-manage/myhr-plus/attendance-reports', title: 'รายงานการลงเวลา', type: 'link' },
{ path: '/portal-manage/myhr-plus/payroll-reports', title: 'รายงานเงินเดือน', type: 'link' },
],
},
...this.createPortalMenu('myhr-plus')
];
}
// เมนูสำหรับการตั้งค่าระบบ
getSystemManagementMenu() {
return [
{ headTitle: 'การตั้งค่าระบบ' },
{
title: 'จัดการสิทธิ์',
icon: 'shield',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/permission-management', title: 'จัดการสิทธิ์และบทบาท', type: 'link' },
{ path: '/portal-manage/menu-permission-management', title: 'จัดการสิทธิ์เมนู', type: 'link' },
{ path: '/portal-manage/user-role-management', title: 'จัดการผู้ใช้และบทบาท', type: 'link' },
],
},
{
title: 'จัดการวิดเจ็ต',
icon: 'widget',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/widget-management', title: 'จัดการวิดเจ็ต', type: 'link' },
{ path: '/portal-manage/widget-stock', title: 'คลังวิดเจ็ต', type: 'link' },
],
},
{
title: 'จัดการแดชบอร์ด',
icon: 'dashboard',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/dashboard-management', title: 'จัดการแดชบอร์ด', type: 'link' },
{ path: '/portal-manage/dashboard-viewer', title: 'ดูแดชบอร์ด', type: 'link' },
],
},
{
title: 'การบริการ',
icon: 'service',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/meeting-booking', title: 'จองห้องประชุม', type: 'link' },
],
}
];
}
// เมนูสำหรับ Dashboard
getDashboardMenu() {
return [
{ headTitle: 'แดชบอร์ด' },
{
title: 'แดชบอร์ดหลัก',
icon: 'dashboard',
path: '/portal-manage/dashboard',
type: 'link',
},
{
title: 'การจัดการ',
icon: 'settings',
type: 'sub',
active: false,
children: [
{ path: '/portal-manage/dashboard-management', title: 'จัดการแดชบอร์ด', type: 'link' },
{ path: '/portal-manage/dashboard-viewer', title: 'ดูแดชบอร์ด', type: 'link' },
],
}
];
}
// Method สำหรับดึงเมนูตาม app ID
getMenuByAppId(appId: string): Menu[] {
switch (appId) {
case 'myhr-plus':
return this.getMyhrPlusMenu();
case 'myhr-lite':
return this.getMyhrLiteMenu();
case 'zeeme':
return this.getZeemeMenu();
case 'myface':
return this.getMyFaceMenu();
case 'mylearn':
return this.getMylearnMenu();
case 'myjob':
return this.getMyJobMenu();
case 'myskill-x':
return this.getMyportalMenu();
case 'company-management':
return this.getCompanyMenu();
case 'dashboard':
return this.getDashboardMenu();
case 'meeting-booking':
return this.getSystemManagementMenu();
case 'permission-management':
case 'menu-permission-management':
case 'user-role-management':
case 'widget-management':
case 'dashboard-management':
return this.getSystemManagementMenu();
default:
return [];
}
}
// Method สำหรับดึงเมนูทั้งหมด
getAllMenus(): { [key: string]: Menu[] } {
return {
'myhr-plus': this.getMyhrPlusMenu(),
'myhr-lite': this.getMyhrLiteMenu(),
'zeeme': this.getZeemeMenu(),
'myface': this.getMyFaceMenu(),
'mylearn': this.getMylearnMenu(),
'myjob': this.getMyJobMenu(),
'myskill-x': this.getMyportalMenu(),
'company-management': this.getCompanyMenu(),
'dashboard': this.getDashboardMenu(),
'meeting-booking': this.getSystemManagementMenu(),
'permission-management': this.getSystemManagementMenu(),
'menu-permission-management': this.getSystemManagementMenu(),
'user-role-management': this.getSystemManagementMenu(),
'widget-management': this.getSystemManagementMenu(),
'dashboard-management': this.getSystemManagementMenu(),
};
}
items = new BehaviorSubject<Menu[]>(this.MENUITEMS);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment