Commit 3140f8f1 by Ooh-Ao

ย้าย path widgets

parent 3d8e88bc
......@@ -44,7 +44,7 @@
"builder": "@angular-devkit/build-angular:application",
"options": {
"allowedCommonJsDependencies": [
"dragula","can-use-dom","moment","leaflet","filepond","dropzone","apexcharts","sweetalert"
"dragula","can-use-dom","moment","leaflet","filepond","dropzone","apexcharts","sweetalert","ng-drag-drop","quill"
],
"outputPath": "dist",
"index": "src/index.html",
......@@ -71,13 +71,13 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "20mb",
"maximumError": "20mb"
"maximumWarning": "8mb",
"maximumError": "15mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "20mb",
"maximumError": "20mb"
"maximumWarning": "3mb",
"maximumError": "5mb"
}
],
"fileReplacements": [
......
......@@ -21,10 +21,11 @@ import { HttpRequestInterceptor } from './shared/services/http-request.intercept
import { AuthService } from './shared/services/auth.service';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { DashboardDataService } from './shared/services/dashboard-data.service';
import { provideStore, provideState } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import { provideStoreDevtools } from '@ngrx/store-devtools';
import { DashboardDataService } from './portal-manage/dashboard-management/services/dashboard-data.service';
import { DatasetService } from './portal-manage/dashboard-management/services/dataset.service';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
......@@ -76,7 +77,6 @@ export const appConfig: ApplicationConfig = {
DialogModule
),
httpInterceptorProviders,
DashboardDataService,
provideStore(),
provideStoreDevtools({ maxAge: 25, logOnly: environment.production })
]
......
......@@ -11,7 +11,7 @@ import { LoginComponent } from './authentication/login/login.component';
import { CoverComponent } from './components/authentication/reset-password/cover/cover.component';
import { HomeComponent } from './portal-manage/home/home.component';
import { FramelessLayoutComponent } from './shared/layouts/frameless-layout.component';
import { DashboardViewerComponent } from './portal-manage/dashboard-viewer/dashboard-viewer.component';
import { DashboardViewerComponent } from './portal-manage/dashboard-management/dashboard-viewer/dashboard-viewer.component';
import { UnauthorizedComponent } from './core/components/unauthorized.component';
export const App_Route: Route[] = [
......
......@@ -10,31 +10,32 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { NotificationService } from '../../shared/services/notification.service';
import { DialogModule, DialogComponent } from '@syncfusion/ej2-angular-popups';
import { DashboardModel, WidgetModel, DatasetModel } from '../models/widgets.model';
import { MenuItemsWidget } from '../models/m-menuitems-widget.model';
import { DashboardDataService } from '../services/dashboard-data.service';
import { MMenuitemsWidgetService } from '../services/m-menuitems-widget.service';
import { DashboardStateService, SelectedDataset } from '../services/dashboard-state.service';
import { WidgetStateService } from '../services/widget-state.service'; // Import WidgetStateService
import { WidgetComponentRegistryService } from '../services/widget-component-registry.service';
import { DashboardModel, WidgetModel, DatasetModel } from './models/widgets.model';
import { MenuItemsWidget } from './models/m-menuitems-widget.model';
import { DashboardDataService } from './services/dashboard-data.service';
import { MMenuitemsWidgetService } from './services/m-menuitems-widget.service';
import { DashboardStateService, SelectedDataset } from './services/dashboard-state.service';
import { WidgetStateService } from './services/widget-state.service'; // Import WidgetStateService
import { WidgetConfigComponent } from './widget-config/widget-config.component';
// Import all the widget components
import { CompanyInfoWidgetComponent } from '../widgets/company-info-widget.component';
import { HeadcountWidgetComponent } from '../widgets/headcount-widget.component';
import { AttendanceOverviewWidgetComponent } from '../widgets/attendance-overview-widget.component';
import { PayrollSummaryWidgetComponent } from '../widgets/payroll-summary-widget.component';
import { EmployeeDirectoryWidgetComponent } from '../widgets/employee-directory-widget.component';
import { WelcomeWidgetComponent } from '../widgets/welcome-widget/welcome-widget.component';
import { QuickLinksWidgetComponent } from '../widgets/quick-links-widget/quick-links-widget.component';
import { SyncfusionDatagridWidgetComponent } from '../widgets/syncfusion-datagrid-widget/syncfusion-datagrid-widget.component';
import { SyncfusionPivotWidgetComponent } from '../widgets/syncfusion-pivot-widget/syncfusion-pivot-widget.component';
import { SyncfusionChartWidgetComponent } from '../widgets/syncfusion-chart-widget/syncfusion-chart-widget.component';
import { CompanyInfoWidgetComponent } from './widgets/company-info-widget.component';
import { HeadcountWidgetComponent } from './widgets/headcount-widget.component';
import { AttendanceOverviewWidgetComponent } from './widgets/attendance-overview-widget.component';
import { PayrollSummaryWidgetComponent } from './widgets/payroll-summary-widget.component';
import { EmployeeDirectoryWidgetComponent } from './widgets/employee-directory-widget.component';
import { WelcomeWidgetComponent } from './widgets/welcome-widget/welcome-widget.component';
import { QuickLinksWidgetComponent } from './widgets/quick-links-widget/quick-links-widget.component';
import { SyncfusionDatagridWidgetComponent } from './widgets/syncfusion-datagrid-widget/syncfusion-datagrid-widget.component';
import { SyncfusionPivotWidgetComponent } from './widgets/syncfusion-pivot-widget/syncfusion-pivot-widget.component';
import { SyncfusionChartWidgetComponent } from './widgets/syncfusion-chart-widget/syncfusion-chart-widget.component';
import { DatasetPickerComponent } from './dataset-picker.component';
import { SimpleKpiWidgetComponent } from '../widgets/simple-kpi-widget/simple-kpi-widget.component';
import { SimpleKpiWidgetComponent } from './widgets/simple-kpi-widget/simple-kpi-widget.component';
import { ChartAllModule, AccumulationChartAllModule } from '@syncfusion/ej2-angular-charts';
import { HttpClientModule } from '@angular/common/http';
import { WidgetComponentRegistryService } from './services/widget-component-registry.service';
export interface DashboardPanel extends PanelModel {
componentType: Type<any>;
......
......@@ -50,7 +50,7 @@ export interface DashboardPanel extends PanelModel {
selector: 'app-dashboard-viewer',
standalone: true,
imports: [
CommonModule, RouterModule, DashboardLayoutModule, NgComponentOutlet,
CommonModule, RouterModule, DashboardLayoutModule, NgComponentOutlet,
// Add all widget components here to make them available for NgComponentOutlet
CompanyInfoWidgetComponent, HeadcountWidgetComponent, AttendanceOverviewWidgetComponent, PayrollSummaryWidgetComponent, EmployeeDirectoryWidgetComponent, KpiWidgetComponent, WelcomeWidgetComponent, ChartWidgetComponent, QuickLinksWidgetComponent, SyncfusionDatagridWidgetComponent, SyncfusionPivotWidgetComponent, SyncfusionChartWidgetComponent, DataTableWidgetComponent, AreaChartWidgetComponent, BarChartWidgetComponent, PieChartWidgetComponent, ScatterBubbleChartWidgetComponent, MultiRowCardWidgetComponent, ComboChartWidgetComponent, DoughnutChartWidgetComponent, FunnelChartWidgetComponent, GaugeChartWidgetComponent, SimpleKpiWidgetComponent, FilledMapWidgetComponent, MatrixWidgetComponent, SlicerWidgetComponent, SimpleTableWidgetComponent, WaterfallChartWidgetComponent, TreemapWidgetComponent
],
......
......@@ -3,8 +3,8 @@ import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Observable } from 'rxjs';
import { DatasetModel } from '../models/widgets.model';
import { DatasetService } from '../services/dataset.service';
import { DatasetModel } from './models/widgets.model';
import { DatasetService } from './services/dataset.service';
@Component({
selector: 'app-dataset-picker',
......
import { environment } from "../../../environments/environment";
import { TagModel } from "./tag.mmodel"
import { GroupModel } from "./group.mmodel"
export interface IDataset {
itemId: string;
......
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { DashboardModel, WidgetModel } from '../models/widgets.model';
import { ApiService } from '../../../app/core/services/api.service'; // Corrected import path
import { HttpParams } from '@angular/common/http'; // Keep HttpParams if still used
import { ApiService } from '../../../core/services/api.service';
@Injectable({
providedIn: 'root'
......
......@@ -3,8 +3,9 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators'; // Removed tap
import { MenuItemsWidget } from '../models/m-menuitems-widget.model';
import { environment } from '../../../environments/environment';
import { TokenService } from '../../shared/services/token.service'; // Import TokenService
import { TokenService } from '../../../shared/services/token.service';
import { environment } from '../../../../environments/environment';
// Import TokenService
@Injectable({
providedIn: 'root'
......
import { Injectable } from '@angular/core';
import { environment } from "../../../environments/environment";
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { WidgetModel } from '../models/widgets.model';
import { DocumentContentModel } from '../models/document-content.model';
import { TokenService } from '../../shared/services/token.service';
import { TokenService } from '../../../shared/services/token.service';
import { environment } from '../../../../environments/environment';
import { DocumentContentModel } from '../../models/document-content.model';
@Injectable({
......
......@@ -9,8 +9,8 @@ import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms';
import { WidgetConfigGeneratorService } from '../../services/widget-config-generator.service';
import { WidgetModel } from '../../models/widgets.model';
import { WidgetConfigGeneratorService } from '../services/widget-config-generator.service';
import { WidgetModel } from '../models/widgets.model';
export interface WidgetConfigDialogData {
widget: WidgetModel;
......
......@@ -9,13 +9,12 @@ import { DialogComponent, DialogModule } from '@syncfusion/ej2-angular-popups';
import { GridComponent, GridModule, PageService, SelectionService } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { NotificationService } from '../../shared/services/notification.service';
import { NotificationService } from '../../../shared/services/notification.service';
import { WidgetService } from '../services/widgets.service';
import { MMenuitemsWidgetService } from '../services/m-menuitems-widget.service';
import { DatasetService } from '../services/dataset.service';
import { WidgetModel, DatasetModel } from '../models/widgets.model';
import { MenuItemsWidget } from '../models/m-menuitems-widget.model';
import { WidgetConfigComponent } from '../dashboard-management/widget-config/widget-config.component';
import { take } from 'rxjs/operators';
import { DashboardStateService } from '../services/dashboard-state.service';
......@@ -52,6 +51,7 @@ import { SlicerWidgetComponent } from '../widgets/slicer-widget/slicer-widget.co
import { SimpleTableWidgetComponent } from '../widgets/simple-table-widget/simple-table-widget.component';
import { WaterfallChartWidgetComponent } from '../widgets/waterfall-chart-widget/waterfall-chart-widget.component';
import { TreemapWidgetComponent } from '../widgets/treemap-widget/treemap-widget.component';
import { WidgetConfigComponent } from '../widget-config/widget-config.component';
// Interface for the panel object used by ngComponentOutlet
export interface DashboardPanel extends PanelModel {
......
......@@ -29,7 +29,7 @@ import { QuickLinksWidgetComponent } from '../widgets/quick-links-widget/quick-l
import { SyncfusionDatagridWidgetComponent } from '../widgets/syncfusion-datagrid-widget/syncfusion-datagrid-widget.component';
import { SyncfusionPivotWidgetComponent } from '../widgets/syncfusion-pivot-widget/syncfusion-pivot-widget.component';
import { SyncfusionChartWidgetComponent } from '../widgets/syncfusion-chart-widget/syncfusion-chart-widget.component';
import { NotificationService } from '../../shared/services/notification.service';
import { NotificationService } from '../../../shared/services/notification.service';
import { WidgetModel } from '../models/widgets.model';
import { WidgetService } from '../services/widgets.service';
import { SimpleKpiWidgetComponent } from '../widgets/simple-kpi-widget/simple-kpi-widget.component';
......
......@@ -33,7 +33,7 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy {
} else {
// If no dataset is selected, just keep showing the initial config with a loading state.
// The initial state is set by applyInitialConfig().
this.isLoading = true;
this.isLoading = true;
}
},
error: (err) => {
......
......@@ -13,7 +13,7 @@ declare var ApexCharts: any;
})
export class ChartWidgetComponent extends BaseWidgetComponent implements AfterViewInit {
@ViewChild('chart') chartElement!: ElementRef;
private chartInstance: any;
constructor(protected override dashboardStateService: DashboardStateService) {
......@@ -55,7 +55,7 @@ export class ChartWidgetComponent extends BaseWidgetComponent implements AfterVi
data: [10, 41, 35, 51, 49, 62, 69, 91, 148]
}];
const defaultCategories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'];
if (this.chartInstance) {
this.chartInstance.updateOptions(this.getChartOptions(defaultSeries, defaultCategories));
}
......
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DashboardStateService } from '../services/dashboard-state.service';
import { BaseWidgetComponent } from './base-widget.component';
import { DashboardStateService } from '../services/dashboard-state.service';
@Component({
selector: 'app-payroll-summary-widget',
......
......@@ -23,9 +23,9 @@ export class QuickLinksWidgetComponent extends BaseWidgetComponent {
onDataUpdate(data: any[]): void {
if (this.config.nameField && this.config.urlField) {
this.quickLinks = data.map(item => ({
name: item[this.config.nameField],
url: item[this.config.urlField],
this.quickLinks = data.map(item => ({
name: item[this.config.nameField],
url: item[this.config.urlField],
icon: this.config.iconField ? item[this.config.iconField] : 'link-45deg'
}));
}
......
......@@ -23,7 +23,7 @@ export class TreemapWidgetComponent extends BaseWidgetComponent {
applyInitialConfig(): void {
this.title = this.config.title || 'Treemap';
this.weightValuePath = this.config.valueField;
this.leafItemSettings = {
this.leafItemSettings = {
labelPath: this.config.groupField,
showLabels: true
};
......@@ -45,7 +45,7 @@ export class TreemapWidgetComponent extends BaseWidgetComponent {
{ group: 'North America', country: 'Canada', value: 38 },
];
this.weightValuePath = 'value';
this.leafItemSettings = {
this.leafItemSettings = {
labelPath: 'country',
showLabels: true
};
......
import { Routes } from '@angular/router';
import { DashboardManagementComponent } from './dashboard-management/dashboard-management.component';
import { DashboardViewerComponent } from './dashboard-viewer/dashboard-viewer.component';
import { WidgetListComponent } from './widget-management/widget-list.component';
import { WidgetFormComponent } from './widget-management/widget-form.component';
import { DashboardViewerComponent } from './dashboard-management/dashboard-viewer/dashboard-viewer.component';
import { WidgetListComponent } from './dashboard-management/widget-management/widget-list.component';
import { WidgetFormComponent } from './dashboard-management/widget-management/widget-form.component';
import { moduleAccessGuard } from '../core/guards/module-access.guard';
import { DatasetWidgetLinkerComponent } from './widget-management/dataset-widget-linker.component';
import { DatasetWidgetLinkerComponent } from './dashboard-management/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';
......@@ -99,7 +99,7 @@ export const portalManageRoutes: Routes = [
{
path: 'widget-management',
canActivate: [moduleAccessGuard],
loadChildren: () => import('./widget-management/widget-management.module').then(m => m.WidgetManagementModule)
loadChildren: () => import('./dashboard-management/widget-management/widget-management.module').then(m => m.WidgetManagementModule)
},
// Dashboard Management
......
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
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 { MatCardModule } from '@angular/material/card';
import { MatTabsModule } from '@angular/material/tabs';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { TranslateModule } from '@ngx-translate/core';
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',
standalone: true,
imports: [
CommonModule,
FormsModule,
MatTableModule,
MatButtonModule,
MatIconModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatCardModule,
MatTabsModule,
MatDialogModule,
MatSnackBarModule,
TranslateModule
],
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;
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
.badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
}
.badge-success {
background-color: #28a745;
color: white;
}
.badge-danger {
background-color: #dc3545;
color: white;
}
.badge-info {
background-color: #17a2b8;
color: white;
}
`]
})
export class UserRoleManagementComponent implements OnInit {
users: User[] = [];
filteredUsers: User[] = [];
roles: Role[] = [];
departments: Department[] = [];
positions: Position[] = [];
userFilter: UserFilter = {
search: '',
roleId: '',
departmentId: '',
positionId: '',
status: ''
};
userColumns: string[] = ['name', 'email', 'role', 'department', 'position', 'status', 'actions'];
roleColumns: string[] = ['name', 'description', 'permissions', 'actions'];
constructor() { }
ngOnInit(): void {
this.loadData();
}
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];
}
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());
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;
return matchesSearch && matchesRole && matchesDepartment && matchesPosition && matchesStatus;
});
}
getRoleName(roleId: string): string {
const role = this.roles.find(r => r.id === roleId);
return role ? role.name : 'ไม่ระบุ';
}
getDepartmentName(departmentId: string): string {
const dept = this.departments.find(d => d.id === departmentId);
return dept ? dept.name : 'ไม่ระบุ';
}
getPositionName(positionId: string): string {
const pos = this.positions.find(p => p.id === positionId);
return pos ? pos.name : 'ไม่ระบุ';
}
editUser(user: User): void {
console.log('Edit user:', user);
}
deleteUser(user: User): void {
console.log('Delete user:', user);
}
editRole(role: Role): void {
console.log('Edit role:', role);
}
deleteRole(role: Role): void {
console.log('Delete role:', role);
}
}
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { DashboardModel, WidgetModel, DatasetModel } from '../../portal-manage/models/widgets.model';
@Injectable({
providedIn: 'root'
})
export class DashboardDataService {
constructor() { }
// // Dashboard methods
// getDashboards(): Observable<DashboardModel[]> {
// return of(this.mockDashboards).pipe(catchError(this.handleError));
// }
// addDashboard(dashboard: DashboardModel): Observable<DashboardModel> {
// this.mockDashboards.push(dashboard);
// return of(dashboard).pipe(catchError(this.handleError));
// }
// Widget methods
// getWidgets(): Observable<WidgetModel[]> {
// return of(this.mockWidgets).pipe(catchError(this.handleError));
// }
// // Dataset methods
// getDatasets(): Observable<DatasetModel[]> {
// return of(this.mockDatasets).pipe(catchError(this.handleError));
// }
// getDatasetById(id: string): Observable<DatasetModel | undefined> {
// return of(this.mockDatasets.find(ds => ds.id === id)).pipe(catchError(this.handleError));
// }
private handleError(error: any) {
console.error(error);
return throwError(() => new Error('Something went wrong. Please try again later.'));
}
}
export interface Environment {
production: boolean;
apiUrl: string;
baseUrl: string;
baseUrlMylearn: string;
url: string;
jbossUrl: string;
portalFixedToken: string;
googleMapsApiKey: string;
firebase: {
apiKey: string;
authDomain: string;
projectId: string;
storageBucket: string;
messagingSenderId: string;
appId: string;
measurementId: string;
};
}
export const environment = {
production: true,
apiUrl: '/api' // Example API URL for production
};
import { Environment } from './environment.interface';
export const environment: Environment = {
production: true,
// baseUrl: window.location.origin + '/api',
apiUrl: 'https://portal.myhr.co.th/api/',
baseUrl: 'https://myjob-uat.myhr.co.th/api',
baseUrlMylearn: 'https://mylearn-uat.myhr.co.th/api',
url: 'https://portal.myhr.co.th/api/',
jbossUrl: 'https://hrplus.myhr.co.th/hr', //add
jbossUrl: 'https://hrplus.myhr.co.th/hr',
portalFixedToken: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJBdXRoIiwidWlkIjoiOGFhNDUzMzAtMzE0Yy0xMWU3LWJhZjMtMmQ3ZDA5ODc3NzQ0Iiwicm9sZSI6InVzZXIiLCJpc3MiOiJDb21wdXRlciBTY2llbmNlIENvcnBvcmF0aW9uIExpbWl0ZWQiLCJmdWxsTmFtZSI6InRlZXJhZGFjaCBrdWhhdGFuYXNhdGllbiIsIm1lbWJlcklkIjoiOGFhNDUzMzAtMzE0Yy0xMWU3LWJhZjMtMmQ3ZDA5ODc3NzQ0In0.FO7u8g7KfzkmZFTuuniBCEQxduPjcvzMbH7iug3DT90',
googleMapsApiKey: window.location.origin.includes("-uat") ? 'AIzaSyAZRyv6aSLDeNffbU7ObFolluUdvTMnA-Q' : 'AIzaSyCUlaZdILvqCw5WoVsHWYREPDBrCkOfv3I'
}
googleMapsApiKey: window.location.origin.includes("-uat") ? 'AIzaSyAZRyv6aSLDeNffbU7ObFolluUdvTMnA-Q' : 'AIzaSyCUlaZdILvqCw5WoVsHWYREPDBrCkOfv3I',
firebase: {
apiKey: "***************************************",
authDomain: "************************",
projectId: "***********************************",
storageBucket: "************************",
messagingSenderId: "*********************",
appId: "*******************************************",
measurementId: "*********************"
}
};
import { Environment } from './environment.interface';
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
export const environment: Environment = {
production: false,
apiUrl: 'https://portal.myhr.co.th/api/', // Example API URL for development
apiUrl: 'https://portal.myhr.co.th/api/',
baseUrl: 'https://myjob-uat.myhr.co.th/api',
baseUrlMylearn: 'https://mylearn-uat.myhr.co.th/api',
// baseScormUrl: 'http://localhost/vsscorm',
// api: '9357268c262a35e41df4cb3774d28301',
url: 'https://portal.myhr.co.th/api/',
jbossUrl: 'https://hrplus.myhr.co.th/hr', //add
jbossUrl: 'https://hrplus.myhr.co.th/hr',
portalFixedToken: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJBdXRoIiwidWlkIjoiOGFhNDUzMzAtMzE0Yy0xMWU3LWJhZjMtMmQ3ZDA5ODc3NzQ0Iiwicm9sZSI6InVzZXIiLCJpc3MiOiJDb21wdXRlciBTY2llbmNlIENvcnBvcmF0aW9uIExpbWl0ZWQiLCJmdWxsTmFtZSI6InRlZXJhZGFjaCBrdWhhdGFuYXNhdGllbiIsIm1lbWJlcklkIjoiOGFhNDUzMzAtMzE0Yy0xMWU3LWJhZjMtMmQ3ZDA5ODc3NzQ0In0.FO7u8g7KfzkmZFTuuniBCEQxduPjcvzMbH7iug3DT90',
googleMapsApiKey: 'AIzaSyAZRyv6aSLDeNffbU7ObFolluUdvTMnA-Q',
firebase: {
apiKey: "***************************************",
authDomain: "************************",
......@@ -20,7 +20,7 @@ export const environment = {
messagingSenderId: "*********************",
appId: "*******************************************",
measurementId: "*********************"
},
}
};
/*
......
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