Commit e8b711e4 by DESKTOP-E3GSHH7\myhr

หน้ารายงาน excel

parent f956c40e
...@@ -84,6 +84,11 @@ export const admin: Routes = [ ...@@ -84,6 +84,11 @@ export const admin: Routes = [
}, },
//////////////MyPortal///////////////// //////////////MyPortal/////////////////
{ {
path: 'excel-report',
loadComponent: () =>
import('./myportal/excel-report/excel-report.component').then((m) => m.ExcelReportComponent),
},
{
path: 'excel-list', path: 'excel-list',
loadComponent: () => loadComponent: () =>
import('./myportal/set-excel-reports/excel-list/excel-list.component').then((m) => m.ExcelListComponent), import('./myportal/set-excel-reports/excel-list/excel-list.component').then((m) => m.ExcelListComponent),
......
<app-page-header [title]="'รายงาน Excel'" [activeTitle]="'ผู้ดูแลระบบ'" [title1]="'รายงาน Excel'"></app-page-header>
<div class="box">
<div class="relative w-full max-w-4xl mx-auto my-8 font-sans">
<button (click)="toggleDropdown()"
class="w-full bg-white bg-gradient-to-r from-blue-600 to-blue-800 text-white font-semibold py-4 px-6 rounded-xl shadow-lg hover:from-blue-700 hover:to-blue-900 focus:outline-none focus:ring-4 focus:ring-blue-300 transition-all duration-300 ease-in-out flex items-center justify-between">
<span class="text-xl sm:text-2xl text-primary">
{{ selectedTemplate ? selectedTemplate.tdesc + ' (' + selectedTemplate.fileName + ')' : 'รายงาน Excel' }}
</span>
<svg class="w-6 h-6 transform transition-transform duration-300 text-primary" [class.rotate-180]="isDropdownOpen"
fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
<div *ngIf="isDropdownOpen"
class="absolute z-10 w-full mt-2 bg-white border border-gray-200 rounded-md shadow-lg overflow-hidden max-h-60 overflow-y-auto">
<ul class="py-1">
<li *ngFor="let template of excelReportTemplates" (click)="selectTemplate(template)"
class="px-4 py-2 hover:bg-gray-100 cursor-pointer text-gray-800 text-lg">
{{ template.tdesc }} ({{ template.fileName }}) </li>
<li *ngIf="excelReportTemplates.length === 0 && !loadingTemplates" class="px-4 py-2 text-gray-500 text-lg">
ไม่พบรายการ Template
</li>
<li *ngIf="loadingTemplates" class="px-4 py-2 text-gray-500 text-lg">
กำลังโหลด...
</li>
</ul>
</div>
</div>
<div *ngIf="selectedTemplate && excelReport"
class="p-6 bg-gray-100 rounded-b-xl shadow-inner transition-all duration-300 ease-in-out"
[class.max-h-0]="!selectedTemplate" [class.max-h-screen]="selectedTemplate">
<div class="pt-6 border-t border-gray-200 bg-white p-3 rounded-xl">
<h2 class="text-2xl font-bold text-gray-800 mb-4">รายงาน Excel: {{ selectedTemplate.tdesc }}</h2>
<p class="mb-4 text-gray-700">ชื่อไฟล์: {{ selectedTemplate.fileName }}</p>
<!-- <p class="mb-4 text-gray-700">รหัส Template: {{ selectedTemplate.templateId }}</p> -->
<div *ngIf="variableSheet.length > 0" class="grid grid-cols-1 md:grid-cols-2 gap-4 items-end mb-4 mt-4">
<ng-container *ngFor="let sheetVar of variableSheet">
<div [ngSwitch]="sheetVar.type">
<label [for]="sheetVar.key" class="block text-gray-700 text-sm font-medium mb-1">{{ sheetVar.label
}}</label>
<ng-container *ngSwitchCase="'text'">
<input type="text" [id]="sheetVar.key" [(ngModel)]="sheetVar.value" [placeholder]="sheetVar.tname"
class="mt-1 block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" />
</ng-container>
<ng-container *ngSwitchCase="'calendar'">
<input type="date" [id]="sheetVar.key" [(ngModel)]="sheetVar.displayValue"
(ngModelChange)="formatNgbDate(sheetVar.key, $event)"
class="mt-1 block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" />
</ng-container>
<ng-container *ngSwitchCase="'list'">
<select [id]="sheetVar.key" [(ngModel)]="sheetVar.value"
class="mt-1 block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
<option *ngFor="let opt of sheetVar.option" [value]="opt.value">{{ opt.text }}</option>
</select>
</ng-container>
<ng-container *ngSwitchCase="'radio'">
<div class="flex flex-wrap gap-4 mt-1">
<label *ngFor="let opt of sheetVar.option" class="inline-flex items-center">
<input type="radio" [name]="sheetVar.key" [value]="opt.value" [(ngModel)]="sheetVar.value"
class="form-radio text-blue-600" />
<span class="ml-2 text-gray-700">{{ opt.text }}</span>
</label>
</div>
</ng-container>
<ng-container *ngSwitchCase="'help'">
<div class="relative">
<input type="text" [id]="sheetVar.key" [(ngModel)]="sheetVar.value.tdesc"
class="mt-1 block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" />
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<button type="button" (click)="selectData(sheetVar.key)"
class="p-1 rounded-full bg-blue-500 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
<svg class="h-5 w-5 text-black" fill="none" stroke="currentColor" viewBox="0 0 24 24"
(click)="openModal(sheetVar, detailModal); $event.stopPropagation();"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</button>
</div>
</div>
</ng-container>
</div>
</ng-container>
</div>
<div class="flex justify-end gap-3 mt-6">
<!-- <button (click)="dowloadExcelReport()"
class="bg-primary py-3 px-6 bg-green-600 text-white font-semibold rounded-lg shadow-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 transition duration-300 ease-in-out transform hover:scale-105">
Download Excel
</button> -->
<button (click)="printExcelReport()"
class="bg-primary py-3 px-6 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition duration-300 ease-in-out transform hover:scale-105">
Print Excel
</button>
</div>
</div>
</div>
</div>
<ng-template #detailModal>
<h2 mat-dialog-title clas>
<div class="text-primary">รายชื่อพนักงาน</div>
</h2>
<mat-dialog-content>
<div class="box">
<div class="box-header justify-between">
<div class="box-title">
รายการทั้งหมด
</div>
<div class="flex flex-wrap gap-2">
<div>
<input class="form-control form-control" type="text" placeholder="Search..."
aria-label=".form-control-sm example" [(ngModel)]="searchModal" (ngModelChange)="updateModalPagedItems()">
</div>
</div>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table whitespace-nowrap min-w-full ti-custom-table-hover">
<thead>
<tr class="border-b border-defaultborder bg-primary">
<th scope="col" *ngFor="let head of modalDetail.text.tableHead" class="text-start text-white">{{ head }}
</th>
</tr>
</thead>
<tbody>
@if (modalFilterList.length > 0) {
@for (item of modalFilterList; track item.id) {
<tr class="border border-defaultborder dark:border-defaultborder/10 cursor-pointer hover:bg-gray-100"
(click)="selectData(item)">
<td>{{ item.id }}</td>
<td>{{ item.tdesc }}</td>
<td>{{ item.edesc }}</td>
</tr>
}
} @else {
<tr>
<td [attr.colspan]="modalDetail.text.tableHead.length" class="text-center py-4 text-gray-500">
ไม่พบข้อมูล
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<!-- <input type="text" [(ngModel)]="searchModal" placeholder="Search..."
(ngModelChange)="updateModalPagedItems()"
class="mt-1 block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm mb-4" /> -->
<!-- <div class="box-body">
<div class="table-responsive">
<table class="table whitespace-nowrap min-w-full ti-custom-table-hover">
<thead>
<tr class="border-b border-defaultborder bg-primary">
<th scope="col" *ngFor="let head of modalDetail.text.tableHead" class="text-start text-white">{{ head }}
</th>
</tr>
</thead>
<tbody>
@if (modalFilterList.length > 0) {
@for (item of modalFilterList; track item.id) {
<tr class="border border-defaultborder dark:border-defaultborder/10 cursor-pointer hover:bg-gray-100"
(click)="selectData(item)">
<td>{{ item.id }}</td>
<td>{{ item.tdesc }}</td>
<td>{{ item.edesc }}</td>
</tr>
}
} @else {
<tr>
<td [attr.colspan]="modalDetail.text.tableHead.length" class="text-center py-4 text-gray-500">
ไม่พบข้อมูล
</td>
</tr>
}
</tbody>
</table>
</div>
</div> -->
<div class="box-footer">
<div class="mb-2 sm:mb-0">
<div>
{{'Showing' | translate}} {{ (modalPageIndex * modalPageSize) + 1 }} {{'to' | translate}} {{
Math.min((modalPageIndex + 1) * modalPageSize, totalModalItemsCount) }} {{'of' | translate}} {{
totalModalItemsCount }} {{'entries' | translate}} <i class="bi bi-arrow-right ms-2 font-semibold"></i>
</div>
</div>
<div class="flex items-center flex-wrap overflow-auto mt-3" *ngIf="totalModalItemsCount > 0">
<div class="ms-auto">
<nav aria-label="Page navigation">
<ul class="ti-pagination mb-0">
<li class="page-item" [class.disabled]="modalPageIndex === 0">
<a class="page-link px-3 py-[0.375rem] cursor-pointer"
(click)="onModalPageChange(modalPageIndex - 1)">{{'Previous' | translate}}</a>
</li>
@for (pageNumber of totalPagesArrayInModal; track pageNumber) {
<li class="page-item" [class.active]="modalPageIndex === (pageNumber - 1)">
<a class="page-link px-3 py-[0.375rem] cursor-pointer" (click)="onModalPageChange(pageNumber - 1)">
{{ pageNumber }}
</a>
</li>
}
<li class="page-item" [class.disabled]="modalPageIndex === (totalPagesArrayInModal.length - 1)">
<a class="page-link px-3 py-[0.375rem] cursor-pointer" (click)="onModalPageChange(modalPageIndex + 1)">
{{'Next' | translate}}
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions style="justify-content: end; padding: 16px 20px;">
<button type="button" class="hs-dropdown-toggle ti-btn ti-btn-light align-middle" mat-button
(click)="closeDialog()">Close</button>
</mat-dialog-actions>
</ng-template>
\ No newline at end of file
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ExcelReportComponent } from './excel-report.component';
describe('ExcelReportComponent', () => {
let component: ExcelReportComponent;
let fixture: ComponentFixture<ExcelReportComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ExcelReportComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExcelReportComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
import { SharedModule } from '../../../../shared/shared.module';
import { ExcelReportService } from '../../../services/excel-report.service';
import { NgbDate } from '@ng-bootstrap/ng-bootstrap';
import FileSaver from 'file-saver';
import { TemplateFileMiniModel } from '../../../models/template-file-mini.model';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
export interface ValueDetailItem {
id: string;
tdesc: string;
edesc: string;
}
export interface ModalDetail {
text: { cardHead: string, search: string[], tableHead: string[] }
}
@Component({
selector: 'app-excel-report',
standalone: true,
imports: [
CommonModule,
FormsModule,
RouterModule,
NgSelectModule,
SharedModule,
MatDialogModule,
TranslateModule,
],
templateUrl: './excel-report.component.html',
styleUrls: ['./excel-report.component.css']
})
export class ExcelReportComponent implements OnInit {
isDropdownOpen: boolean = false;
excelReportStartDate: string = '2025-07-09';
employeeId: string = '';
// ลบ pageIndex และ _searchTerm ถ้าไม่ได้ใช้สำหรับส่วนอื่นนอก Modal
// pageIndex = 0;
// _searchTerm = "";
dialogRef: any
// ตัวแปรสำหรับ Pagination ของ Modal
modalPageIndex = 0; // เริ่มที่ index 0 เหมือนต้นฉบับ
modalPageSize = 10; // 10 รายการต่อหน้า
Math = Math; // เพื่อให้ template เข้าถึง Math ได้
readonly maxPageButtons = 15;
changeDate = new Date();
select: any = {}
excelReport?: any
variableSheet: any = []
loading = false
loadingExcel = false
valueDetail: ValueDetailItem[] = [] // ข้อมูลทั้งหมดที่ได้จาก API สำหรับ Modal
modalFilterList: ValueDetailItem[] = []; // <--- เพิ่มตัวแปรนี้: ข้อมูลที่ถูกแบ่งหน้าแล้วสำหรับแสดงในตาราง Modal
modalDetail: ModalDetail = {
text: {
cardHead: '',
search: [],
tableHead: []
}
}
keySelect = ""
searchModal = "" // ใช้เป็น searchTerm สำหรับ Modal
// ลบ page และ pageSize ถ้าไม่ได้ใช้สำหรับส่วนอื่นนอก Modal
// page = 1
// pageSize = 10
// ** Updated properties for dropdown **
excelReportTemplates: TemplateFileMiniModel[] = [];
loadingTemplates: boolean = false;
selectedTemplate: TemplateFileMiniModel | null = null;
constructor(private route: ActivatedRoute,
private excelReportService: ExcelReportService,
private cdr: ChangeDetectorRef,
private dialog: MatDialog,
public translate: TranslateService, // ต้อง inject TranslateService เพื่อให้ translate pipe ทำงาน
) { }
ngOnInit(): void {
// Existing route parameter handling (if needed for direct links)
this.route.paramMap.subscribe(params => {
const rawId = params.get('id');
if (rawId) {
const [id, queryString] = rawId.split('?');
const searchParams = new URLSearchParams(queryString); // Changed to searchParams for clarity
const template = searchParams.get('template');
const name = searchParams.get('name');
// If you want to pre-select a template based on URL params:
if (template && name) {
// This assumes the list of templates is already loaded or will be loaded
// You might need to adjust this to wait for excelReportTemplates to be populated
this.excelReportService.getTemplateFileLists().subscribe(
templates => {
this.excelReportTemplates = templates;
const preselected = templates.find(t => t.templateId === template && t.fileName === name);
if (preselected) {
this.selectedTemplate = preselected;
this.getDataExcelReport(preselected.templateId, preselected.fileName);
}
}
);
}
}
});
// Load templates for the dropdown when the component initializes
this.loadExcelReportTemplates();
}
openModal(data: any, modal: any) {
this.searchModal = ''; // รีเซ็ต search
this.modalPageIndex = 0; // รีเซ็ต index หน้าเมื่อเปิด Modal
this.valueDetail = data.valueDetail.map((x: any) => ({ id: x.id || '', tdesc: x.tdesc || '', edesc: x.edesc || '' })) as ValueDetailItem[];
this.keySelect = data.key;
this.modalDetail = {
text: {
cardHead: "Table " + data.table,
search: ["Table " + data.table],
tableHead: ['ID', 'detailTH', 'detailENG']
}
}
this.updateModalPagedItems(); // <--- เรียก updateModalPagedItems() หลังจากโหลดข้อมูล Modal ครั้งแรก
this.dialogRef = this.dialog.open(modal,{
width: '1100px',
height: '650px'
});
}
closeDialog() {
console.log('closeDialog() called.');
if (this.dialogRef) {
this.dialogRef.close();
this.dialogRef = undefined;
console.log('Modal closed and dialogRef cleared.');
} else {
console.log('closeDialog() called, but dialogRef is undefined.');
}
}
// ลบ updatePagedItems() ออกไป ถ้าไม่ได้ใช้สำหรับส่วนอื่นนอก Modal
// updatePagedItems() {
// const startIndex = this.pageIndex * 10;
// const endIndex = startIndex + 10;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
// }
loadExcelReportTemplates(): void {
this.loadingTemplates = true;
this.excelReportService.getTemplateFileLists().subscribe({
next: (data) => {
this.excelReportTemplates = data;
this.loadingTemplates = false;
this.cdr.detectChanges();
// ลบการเรียก updatePagedItems() ออกจากตรงนี้ด้วย ถ้าไม่ได้ใช้กับส่วนหลัก
// this.updatePagedItems();
},
error: (err) => {
console.error('Failed to load Excel report templates for dropdown', err);
this.loadingTemplates = false;
this.excelReportTemplates = [];
this.cdr.detectChanges();
}
});
}
toggleDropdown(): void {
this.isDropdownOpen = !this.isDropdownOpen;
}
selectTemplate(template: TemplateFileMiniModel): void {
this.selectedTemplate = template;
this.isDropdownOpen = false;
this.cdr.detectChanges();
this.getDataExcelReport(this.selectedTemplate.templateId, this.selectedTemplate.fileName);
}
getDataExcelReport(templateId: string, fileName: string) {
this.loading = true
this.excelReport = undefined
this.variableSheet = []
this.valueDetail = []
this.excelReportService.getTemplateFile(templateId, fileName).subscribe((res: any) => {
console.log('response', res);
this.excelReport = res;
if (this.excelReport && this.excelReport.param && this.excelReport.param.variableSheet) {
Object.entries(this.excelReport.param.variableSheet).forEach(([key, value]) => {
const data = value as any
if (data.type == 'text') {
this.variableSheet.push({
...data, value: data.valueDefault || '', key: key
})
} else if (data.type == 'list') {
this.variableSheet.push({
...data, value: data.valueDefault || '', key: key, option: data.option.split('customize|')[1].split(',').map((x: any) => {
const [value, text] = x.split('#')
return { value: value || '', text: text || '' }
})
})
} else if (data.type == 'radio') {
this.variableSheet.push({
...data, value: data.valueDefault || '', key: key, option: data.option.split('customize|')[1].split(',').map((x: any) => {
const [value, text] = x.split('#')
return { value: value || '', text: text || '' }
})
})
} else if (data.type == 'help') {
this.variableSheet.push({ ...data, value: data.valueDefault ? { id: data.valueDefault, tdesc: data.valueDefault, edesc: data.valueDefault } : { id: "", tdesc: "", edesc: "" }, key: key })
} else if (data.type == 'calendar') {
let initialValueForInput: string = ''; // ค่าสำหรับ input type="date" (YYYY-MM-DD)
let initialValueForModel: string = ''; // ค่าสำหรับ sheetVar.value (DD-MM-YYYY, ตามที่คุณต้องการส่งกลับไป)
let initialNgbDate: NgbDate | null = null;
if (data.valueDefault) {
// ถ้ามี valueDefault ให้ใช้ค่าจาก API
initialValueForModel = data.valueDefault;
const [d, m, y] = data.valueDefault.split('-').map(Number);
initialNgbDate = new NgbDate(y, m, d);
initialValueForInput = `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
} else {
// ถ้าไม่มี valueDefault ให้กำหนดเป็นวันที่ปัจจุบัน
const today = new Date();
const day = String(today.getDate()).padStart(2, '0');
const month = String(today.getMonth() + 1).padStart(2, '0');
const year = today.getFullYear();
initialValueForModel = `${day}-${month}-${year}`;
initialValueForInput = `${year}-${month}-${day}`;
initialNgbDate = new NgbDate(year, today.getMonth() + 1, today.getDate());
}
this.variableSheet.push({
...data,
value: initialValueForModel,
key: key,
displayValue: initialValueForInput
});
this.select[key] = initialNgbDate;
}
})
}
this.loading = false
this.cdr.detectChanges()
}, error => {
console.error("Error fetching detailed excel report:", error);
this.loading = false
// Handle error, maybe show a message to the user
this.cdr.detectChanges()
})
}
formatNgbDate(key: string, date?: NgbDate) {
if (date) {
const day = String(date.day).padStart(2, '0');
const month = String(date.month).padStart(2, '0');
const year = date.year;
const item = this.variableSheet.find((i: any) => i.key === key);
if (item) item.value = `${day}-${month}-${year}`
} else {
const item = this.variableSheet.find((i: any) => i.key === key);
if (item) item.value = ''
}
}
valueDetailFilter(): ValueDetailItem[] {
return this.valueDetail.filter((item: ValueDetailItem) =>
item.id.toLowerCase().includes(this.searchModal.toLowerCase()) ||
item.tdesc.toLowerCase().includes(this.searchModal.toLowerCase()) ||
item.edesc.toLowerCase().includes(this.searchModal.toLowerCase())
)
}
// >>>>>> เมธอดสำหรับแบ่งหน้าใน Modal (คล้าย updatePagedItems ของต้นฉบับ)
updateModalPagedItems() {
const filteredData = this.valueDetailFilter(); // ใช้ข้อมูลที่กรองแล้ว
const startIndex = this.modalPageIndex * this.modalPageSize;
const endIndex = startIndex + this.modalPageSize;
this.modalFilterList = filteredData.slice(startIndex, endIndex);
}
// >>>>>> Getter สำหรับจำนวนรายการทั้งหมดหลังจาก filter (คล้าย itemsList.length / filterList.length)
get totalModalItemsCount(): number {
return this.valueDetailFilter().length;
}
// >>>>>> Getter สำหรับ Array ของเลขหน้า (คล้าย Math.ceil(total / pageSize) ของต้นฉบับ)
get totalPagesArrayInModal(): number[] {
const totalPages = Math.ceil(this.totalModalItemsCount / this.modalPageSize);
const pageButtons: number[] = [];
// กำหนดขอบเขตของปุ่มที่จะแสดง
let startPage: number, endPage: number;
if (totalPages <= this.maxPageButtons) {
// ถ้าจำนวนหน้าน้อยกว่าหรือเท่ากับจำนวนปุ่มสูงสุดที่กำหนดไว้ ให้แสดงทั้งหมด
startPage = 1;
endPage = totalPages;
} else {
// ถ้าจำนวนหน้ามากกว่าจำนวนปุ่มสูงสุด
const halfButtons = Math.floor(this.maxPageButtons / 2);
if (this.modalPageIndex < halfButtons) {
// อยู่ใกล้จุดเริ่มต้น
startPage = 1;
endPage = this.maxPageButtons;
} else if (this.modalPageIndex >= totalPages - halfButtons) {
// อยู่ใกล้จุดสิ้นสุด
startPage = totalPages - this.maxPageButtons + 1;
endPage = totalPages;
} else {
// อยู่กลางๆ
startPage = this.modalPageIndex - halfButtons + 1;
endPage = this.modalPageIndex + halfButtons;
}
}
// สร้าง Array ของเลขหน้าตามขอบเขตที่คำนวณได้
for (let i = startPage; i <= endPage; i++) {
pageButtons.push(i);
}
return pageButtons;
}
// ... (เมธอดอื่นๆ ที่เหลือเหมือนเดิม)
selectData(data: any) {
const item = this.variableSheet.find((i: any) => i.key === this.keySelect);
if (item) item.value = data;
this.closeDialog();
}
dowloadExcelReport() {
this.loadingExcel = true
if (!this.excelReport || !this.excelReport.param || !this.excelReport.param.excelFile) {
console.error("No excel report selected or missing excelFile parameter.");
this.loadingExcel = false;
return;
}
const fileName = this.excelReport.param.excelFile
this.excelReportService.downloadTemplateFile(fileName).subscribe((res: any) => {
const blob = new Blob([res], { type: 'application/octet-stream' });
FileSaver.saveAs(blob, fileName);
this.loadingExcel = false
this.cdr.detectChanges()
}, (err) => {
console.error("Error downloading excel report:", err);
this.loadingExcel = false
this.cdr.detectChanges()
})
}
printExcelReport(): void {
if (!this.selectedTemplate || !this.excelReport || !this.excelReport.param) {
alert('Please select an Excel report template first.');
return;
}
this.loadingExcel = true; // Use loadingExcel for print as well
const fileName = this.excelReport.param.excelFile;
const paramObj: { [key: string]: string } = {}; // Object to hold parameters
this.variableSheet.forEach((item: any) => {
if (item.type === 'help') {
paramObj["__" + item.key] = item.value.id || '';
} else if (item.type === 'calendar' || item.type === 'list' || item.type === 'radio' || item.type === 'text') {
paramObj["__" + item.key] = item.value || '';
}
});
// Convert paramObj to string based on backend expectation, typically JSON.stringify
// Or if backend expects a pipe-separated string, adjust accordingly.
const paramString = JSON.stringify(paramObj); // Common format
// const paramString = Object.entries(paramObj).map(([key, value]) => `${key}=${value}`).join('|'); // If backend expects old format
this.excelReportService.printExcelReport({ fileName: fileName, paramObj: paramString }).subscribe(
(res: any) => {
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // Correct MIME type for .xlsx
FileSaver.saveAs(blob, fileName);
this.loadingExcel = false;
this.cdr.detectChanges();
},
(err) => {
console.error('Error printing Excel report:', err);
this.loadingExcel = false;
this.cdr.detectChanges();
}
);
}
// >>>>>> เมธอดสำหรับเปลี่ยนหน้าใน Modal (คล้าย onCheckboxChange)
onModalPageChange(newPageIndex: number): void {
this.modalPageIndex = newPageIndex;
this.updateModalPagedItems(); // เรียก updateModalPagedItems() เมื่อเปลี่ยนหน้า
}
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
import { TemplateFileModel, TemplateModel } from '../models/template.model';
import { ModuleModel } from '../models/module.model';
import { ExcelPortalGroupModel, ExcelPortalModel, ExcelPortalTagsModel } from '../models/excel-portal.model';
import { AlertModel } from '../models/alert.model';
import { TemplateFileMiniModel } from '../models/template-file-mini.model';
@Injectable({
providedIn: 'root'
})
export class ExcelReportService {
constructor(private http: HttpClient,
private translateService: TranslateService
) { }
getExcelList(): Observable<TemplateModel[]> {
return this.http.get<TemplateModel[]>(environment.url + "template/lists?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47")
}
getModuleList(): Observable<ModuleModel[]> {
return this.http.get<ModuleModel[]>(environment.url + "template/lists/module?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47")
}
getExcelPortalList(): Observable<ExcelPortalModel[]> {
return this.http.get<ExcelPortalModel[]>(environment.url + "excel-center/content/lists")
}
getExcelPortalgGroupList(): Observable<ExcelPortalGroupModel[]> {
return this.http.get<ExcelPortalGroupModel[]>(environment.url + "portal-group/lists")
}
getExcelPortalTagsList(): Observable<ExcelPortalTagsModel[]> {
return this.http.get<ExcelPortalTagsModel[]>(environment.url + "tag/lists")
}
postTemplate(body: {
templateId: string,
tname: string,
ename: string,
tdesc: string,
edesc: string,
module: string
}) {
return this.http.post(environment.url + "template?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", body)
}
deleteTemplate(body: TemplateModel): Observable<AlertModel> {
let option = {
headers: new HttpHeaders({
"Content-Type": "application/json",
}),
body: body
}
return this.http.delete<AlertModel>(environment.url + "template?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", option)
}
postTemplateFile(body: TemplateFileModel): Observable<AlertModel> {
return this.http.post<AlertModel>(environment.url + "template-file?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", body)
}
deleteTemplateFile(body: TemplateFileModel): Observable<AlertModel> {
let option = {
headers: new HttpHeaders({
"Content-Type": "application/json",
}),
body: body
}
return this.http.delete<AlertModel>(environment.url + "template-file?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", option)
}
downloadTemplateFile(fileName: string) {
return this.http.get(environment.url + "template-file/download/excel/" + fileName + "?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", { responseType: 'blob' })
}
printExcelReport(body: {
fileName: string,
paramObj: string
}) {
return this.http.post(environment.url + "template-file/export-to-excel?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47", body, { responseType: 'blob' })
}
getTemplateFile(templateid: string, filename: string): Observable<AlertModel> {
return this.http.get<AlertModel>(environment.url + "template-file/" + templateid + "/" + filename + "?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47",)
}
getTemplateFileLists(): Observable<TemplateFileMiniModel[]> {
return this.http.get<TemplateFileMiniModel[]>(environment.url + "template-file/menuitem/mini/lists?companyid=eb2f4f30-edaf-11ee-a69a-c7680edc0e47",)
}
}
\ No newline at end of file
...@@ -6,12 +6,15 @@ import { NavigationEnd, Router } from '@angular/router'; ...@@ -6,12 +6,15 @@ import { NavigationEnd, Router } from '@angular/router';
import { checkHoriMenu, switcherArrowFn } from './sidebar'; import { checkHoriMenu, switcherArrowFn } from './sidebar';
import { TokenService } from '../../services/token.service'; import { TokenService } from '../../services/token.service';
import { CompanyModel } from '../../../DPU/models/company.model'; import { CompanyModel } from '../../../DPU/models/company.model';
import { MyTemplateFileMiniModel, TemplateFileMiniModel } from '../../../DPU/models/template-file-mini.model';
import { ExcelReportService } from '../../../DPU/services/excel-report.service';
@Component({ @Component({
selector: 'app-sidebar', selector: 'app-sidebar',
templateUrl: './sidebar.component.html', templateUrl: './sidebar.component.html',
styleUrl: './sidebar.component.scss' styleUrl: './sidebar.component.scss'
}) })
export class SidebarComponent { export class SidebarComponent {
localStorage: any; localStorage: any;
// Addding sticky-pin // Addding sticky-pin
...@@ -68,20 +71,22 @@ export class SidebarComponent { ...@@ -68,20 +71,22 @@ export class SidebarComponent {
isInstallerRoute: boolean = false; isInstallerRoute: boolean = false;
previousUrl: string = ''; previousUrl: string = '';
currentUrl: string = ''; currentUrl: string = '';
submenuExcel: TemplateFileMiniModel[] = []; // เพิ่ม property สำหรับเก็บข้อมูลรายงาน Excel
constructor( constructor(
private navServices: NavService, private navServices: NavService,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
public router: Router, public router: Router,
public renderer: Renderer2, public renderer: Renderer2,
private elementRef: ElementRef, private elementRef: ElementRef,
public tokenService: TokenService public tokenService: TokenService,
private excelReportService: ExcelReportService // Inject ExcelReportService
) { ) {
// this.companyModel = new CompanyModel(this.tokenService.getSelectCompany())
this.screenWidth = window.innerWidth; this.screenWidth = window.innerWidth;
} }
ngOnInit() { ngOnInit() {
let bodyElement: any = document.querySelector('.main-content'); let bodyElement: any = document.querySelector('.main-content');
bodyElement.onclick = () => { bodyElement.onclick = () => {
...@@ -102,9 +107,10 @@ export class SidebarComponent { ...@@ -102,9 +107,10 @@ export class SidebarComponent {
this.currentUrl = this.router.url this.currentUrl = this.router.url
this.isCommonRoute = this.currentUrl.includes('/admin'); this.isCommonRoute = this.currentUrl.includes('/admin');
this.isInstallerRoute = this.currentUrl.includes('/company'); this.isInstallerRoute = this.currentUrl.includes('/company');
this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => {
this.changeMenu() // ดึงข้อมูล Excel Report ก่อน แล้วค่อยอัปเดตเมนู
}); this.fetchExcelReportsAndAddToMenu();
this.ParentActive(); this.ParentActive();
this.checkUrlChanges(); this.checkUrlChanges();
...@@ -113,7 +119,6 @@ export class SidebarComponent { ...@@ -113,7 +119,6 @@ export class SidebarComponent {
if (WindowResize) { if (WindowResize) {
this.windowSubscribe$ = WindowResize.subscribe(() => { this.windowSubscribe$ = WindowResize.subscribe(() => {
// to check and adjst the menu on screen size change // to check and adjst the menu on screen size change
checkHoriMenu(); checkHoriMenu();
}); });
} }
...@@ -121,7 +126,6 @@ export class SidebarComponent { ...@@ -121,7 +126,6 @@ export class SidebarComponent {
checkHoriMenu(); checkHoriMenu();
if (document.documentElement.getAttribute('data-nav-layout') == 'horizontal' && window.innerWidth > 992) { if (document.documentElement.getAttribute('data-nav-layout') == 'horizontal' && window.innerWidth > 992) {
this.closeNavActive() this.closeNavActive()
} }
} }
...@@ -136,7 +140,6 @@ export class SidebarComponent { ...@@ -136,7 +140,6 @@ export class SidebarComponent {
} }
checkUrlChanges(): void { checkUrlChanges(): void {
this.router.events.subscribe((event) => { this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) { if (event instanceof NavigationEnd) {
this.ParentActive(); this.ParentActive();
...@@ -163,22 +166,60 @@ export class SidebarComponent { ...@@ -163,22 +166,60 @@ export class SidebarComponent {
// Log to console for verification // Log to console for verification
console.log('Current URL:', this.currentUrl); console.log('Current URL:', this.currentUrl);
console.log('Previous URL:', this.previousUrl); console.log('Previous URL:', this.previousUrl);
this.changeMenu() this.changeMenu() // เรียก changeMenu อีกครั้งเมื่อ URL เปลี่ยน
} }
}); });
} }
// เมธอดสำหรับดึงข้อมูล Excel Report และเพิ่มเข้าเมนู
fetchExcelReportsAndAddToMenu() {
this.excelReportService.getTemplateFileLists().subscribe(response => {
this.submenuExcel = response.map(e => new MyTemplateFileMiniModel(e));
this.changeMenu(); // เรียก changeMenu เพื่ออัปเดตเมนูหลังจากดึงข้อมูล Excel ได้
}, error => {
console.error('Error fetching Excel template files:', error);
this.changeMenu(); // เรียก changeMenu แม้จะมีข้อผิดพลาดเพื่อโหลดเมนูพื้นฐาน
});
}
changeMenu() { changeMenu() {
// กำหนดเมนูพื้นฐาน (Common หรือ Installer)
if (this.isInstallerRoute) { if (this.isInstallerRoute) {
this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => { this.menuItems = this.navServices.getCompanyMenu();
this.menuItems = this.navServices.getCompanyMenu();
});
} else { } else {
this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => { this.menuItems = this.navServices.getCommonMenu();
this.menuItems = this.navServices.getCommonMenu();
});
} }
this.ParentActive()
// เพิ่มรายการรายงาน Excel เข้าไปในเมนู หากมีข้อมูลและยังไม่ได้เพิ่ม
if (this.submenuExcel.length > 0) {
const excelMenuExists = this.menuItems.some(item => item.title === 'รายงาน Excel');
if (!excelMenuExists) {
const excelSubmenuItems: Menu[] = this.submenuExcel.map(e2 => ({
path: '/apps/excel-export/' + e2.itemId + "?template=" + e2.templateId + "&name=" + e2.fileName,
title: e2.itemId + '.' + e2.tdesc,
icon: '', // ไม่มีไอคอนสำหรับเมนูย่อย
type: 'link', // กำหนดเป็น 'link' สำหรับการนำทางโดยตรง
active: false,
selected: false,
children: []
}));
const excelMenuItem: Menu = {
path: '', // ไม่มี path โดยตรงสำหรับเมนูหลัก
title: 'รายงาน Excel',
icon: 'file-earmark-excel', // ไอคอนสำหรับรายงาน Excel (ตัวอย่าง: Boxicons)
type: 'sub', // กำหนดเป็น 'sub' เนื่องจากมีเมนูย่อย
active: false,
selected: false,
children: excelSubmenuItems
};
// เพิ่มรายการเมนู Excel เข้าไปใน menuItems ที่มีอยู่
this.menuItems.push(excelMenuItem);
}
}
this.ParentActive(); // ประเมินสถานะ active อีกครั้งหลังจากเมนูมีการเปลี่ยนแปลง
} }
...@@ -270,17 +311,29 @@ export class SidebarComponent { ...@@ -270,17 +311,29 @@ export class SidebarComponent {
} }
ParentActive() { ParentActive() {
this.menuItems.map((element: any) => { this.menuItems.map((element: any) => {
if (element.children) { if (element.children) {
element.active = false; element.active = false;
element.selected = false; element.selected = false;
element.children.map((ele: any) => { element.children.map((ele: any) => {
// ตรวจสอบ path ที่ตรงกับ currentUrl
if (ele.path == this.currentUrl) { if (ele.path == this.currentUrl) {
element.active = true; element.active = true;
element.selected = true; element.selected = true;
} }
// ตรวจสอบ path สำหรับ Excel Report ที่มี query parameters
if (ele.path && this.currentUrl.startsWith(ele.path.split('?')[0])) {
const currentUrlBase = this.currentUrl.split('?')[0];
const elePathBase = ele.path.split('?')[0];
if (currentUrlBase === elePathBase) {
element.active = true;
element.selected = true;
ele.active = true; // ทำให้เมนูย่อย active ด้วย
ele.selected = true; // ทำให้เมนูย่อย selected ด้วย
}
}
if (ele.children) { if (ele.children) {
ele.active = false; ele.active = false;
ele.children.map((child1: any) => { ele.children.map((child1: any) => {
...@@ -290,6 +343,19 @@ export class SidebarComponent { ...@@ -290,6 +343,19 @@ export class SidebarComponent {
ele.active = true; ele.active = true;
ele.selected = true; ele.selected = true;
} }
// ตรวจสอบ path สำหรับ Excel Report ที่มี query parameters ในระดับที่ 3
if (child1.path && this.currentUrl.startsWith(child1.path.split('?')[0])) {
const currentUrlBase = this.currentUrl.split('?')[0];
const child1PathBase = child1.path.split('?')[0];
if (currentUrlBase === child1PathBase) {
element.active = true;
element.selected = true;
ele.active = true;
ele.selected = true;
child1.active = true; // ทำให้เมนูย่อย active ด้วย
child1.selected = true; // ทำให้เมนูย่อย selected ด้วย
}
}
}); });
} }
}); });
...@@ -312,8 +378,8 @@ export class SidebarComponent { ...@@ -312,8 +378,8 @@ export class SidebarComponent {
return this.sanitizer.bypassSecurityTrustHtml(svgContent); return this.sanitizer.bypassSecurityTrustHtml(svgContent);
} }
ngOnDestroy() { ngOnDestroy() {
this.menuitemsSubscribe$.unsubscribe(); this.menuitemsSubscribe$?.unsubscribe(); // ใช้ ?. เพื่อป้องกัน error ถ้ายังไม่ได้ subscribe
this.windowSubscribe$.unsubscribe(); this.windowSubscribe$?.unsubscribe(); // ใช้ ?. เพื่อป้องกัน error ถ้ายังไม่ได้ subscribe
this.elementRef.nativeElement.ownerDocument.documentElement, this.elementRef.nativeElement.ownerDocument.documentElement,
'data-nav-layout', 'data-nav-layout',
'vertical'; 'vertical';
...@@ -400,3 +466,409 @@ export class SidebarComponent { ...@@ -400,3 +466,409 @@ export class SidebarComponent {
} }
} }
} }
//อันเก่า
// import { Component, ViewChild, ElementRef, Renderer2, HostListener, ChangeDetectionStrategy } from '@angular/core';
// import { Menu, NavService } from '../../services/nav.service';
// import { Subscription, fromEvent } from 'rxjs';
// import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
// import { NavigationEnd, Router } from '@angular/router';
// import { checkHoriMenu, switcherArrowFn } from './sidebar';
// import { TokenService } from '../../services/token.service';
// import { CompanyModel } from '../../../DPU/models/company.model';
// @Component({
// selector: 'app-sidebar',
// templateUrl: './sidebar.component.html',
// styleUrl: './sidebar.component.scss'
// })
// export class SidebarComponent {
// localStorage: any;
// // Addding sticky-pin
// scrolled = false;
// screenWidth: number;
// eventTriggered: boolean = false;
// public localdata = localStorage;
// // options = { autoHide: false, scrollbarMinSize: 100 };
// @HostListener('window:scroll', [])
// onWindowScroll() {
// const navScrollElement =
// this.elementRef.nativeElement.querySelector('.nav-scroll');
// this.scrolled = window.scrollY > 10;
// const sections = document.querySelectorAll('.side-menu__item');
// const scrollPos =
// window.scrollY ||
// this.elementRef.nativeElement.ownerDocument.documentElement.scrollTop ||
// document.body.scrollTop;
// sections.forEach((ele, i) => {
// const currLink = sections[i];
// const val: any = currLink.getAttribute('value');
// const refElement: any = document.querySelector('#' + val);
// // Add a null check here before accessing properties of refElement
// if (refElement !== null) {
// const scrollTopMinus = scrollPos + 73;
// if (
// refElement.offsetTop <= scrollTopMinus &&
// refElement.offsetTop + refElement.offsetHeight > scrollTopMinus
// ) {
// if (navScrollElement) {
// this.renderer.removeClass(navScrollElement, 'active');
// }
// currLink.classList.add('active');
// } else {
// currLink.classList.remove('active');
// }
// }
// });
// }
// //////
// public windowSubscribe$!: Subscription;
// options = { autoHide: false, scrollbarMinSize: 100 };
// icon!: SafeHtml;
// public menuItems!: Menu[];
// public menuitemsSubscribe$!: Subscription;
// companyModel: CompanyModel = new CompanyModel()
// isCommonRoute: boolean = false;
// isInstallerRoute: boolean = false;
// previousUrl: string = '';
// currentUrl: string = '';
// constructor(
// private navServices: NavService,
// private sanitizer: DomSanitizer,
// public router: Router,
// public renderer: Renderer2,
// private elementRef: ElementRef,
// public tokenService: TokenService
// ) {
// // this.companyModel = new CompanyModel(this.tokenService.getSelectCompany())
// this.screenWidth = window.innerWidth;
// }
// ngOnInit() {
// let bodyElement: any = document.querySelector('.main-content');
// bodyElement.onclick = () => {
// if (
// localStorage.getItem('ynex-menu-style') == 'icon-click' ||
// localStorage.getItem('ynex-menu-style') == 'menu-click' ||
// localStorage.getItem('ynex-menu-style') == 'icon-hover' ||
// localStorage.getItem('valexlayout') == 'horizontal'
// ) {
// document
// .querySelectorAll('.main-menu .slide-menu.child1')
// .forEach((ele: any) => {
// ele.style.display = 'none';
// });
// }
// };
// this.menuResizeFn();
// this.currentUrl = this.router.url
// this.isCommonRoute = this.currentUrl.includes('/admin');
// this.isInstallerRoute = this.currentUrl.includes('/company');
// this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => {
// this.changeMenu()
// });
// this.ParentActive();
// this.checkUrlChanges();
// const WindowResize = fromEvent(window, 'resize');
// // subscribing the Observable
// if (WindowResize) {
// this.windowSubscribe$ = WindowResize.subscribe(() => {
// // to check and adjst the menu on screen size change
// checkHoriMenu();
// });
// }
// switcherArrowFn();
// checkHoriMenu();
// if (document.documentElement.getAttribute('data-nav-layout') == 'horizontal' && window.innerWidth > 992) {
// this.closeNavActive()
// }
// }
// checkInitialUrl(): void {
// this.isCommonRoute = this.currentUrl.includes('/admin');
// this.isInstallerRoute = this.currentUrl.includes('/company');
// this.checkUrlChanges()
// // Log to console for verification
// console.log('Initial URL:', this.currentUrl);
// console.log('Is Common Route:', this.isCommonRoute);
// console.log('Is Installer Route:', this.isInstallerRoute);
// }
// checkUrlChanges(): void {
// this.router.events.subscribe((event) => {
// if (event instanceof NavigationEnd) {
// this.ParentActive();
// }
// });
// this.router.events.subscribe((event) => {
// if (event instanceof NavigationEnd) {
// this.previousUrl = this.currentUrl; // Save the previous URL
// this.currentUrl = event.url; // Update to the new URL
// // Check if there's a change between /installer and /admin
// if (
// (this.previousUrl.includes('/company') && this.currentUrl.includes('/admin')) ||
// (this.previousUrl.includes('/admin') && this.currentUrl.includes('/company'))
// ) {
// console.log('URL changed between /installer and /admin.');
// // Implement any logic needed when changing between /installer and /admin
// }
// // Update the boolean values
// this.isCommonRoute = this.currentUrl.includes('/admin');
// this.isInstallerRoute = this.currentUrl.includes('/company');
// // Log to console for verification
// console.log('Current URL:', this.currentUrl);
// console.log('Previous URL:', this.previousUrl);
// this.changeMenu()
// }
// });
// }
// changeMenu() {
// if (this.isInstallerRoute) {
// this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => {
// this.menuItems = this.navServices.getCompanyMenu();
// });
// } else {
// this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => {
// this.menuItems = this.navServices.getCommonMenu();
// });
// }
// this.ParentActive()
// }
// //Active Nav State
// setNavActive(item: any) {
// this.menuItems?.filter((menuItem) => {
// if (menuItem !== item) {
// menuItem.active = false;
// this.navServices.collapseSidebar = false;
// }
// if (menuItem.children && menuItem.children.includes(item)) {
// menuItem.active = true;
// menuItem.selected = true;
// }
// if (menuItem.children) {
// menuItem.children?.filter((submenuItems) => {
// if (submenuItems.children && submenuItems.children.includes(item)) {
// menuItem.active = true;
// submenuItems.active = true;
// menuItem.selected = true;
// submenuItems.selected = true;
// }
// if (submenuItems.children) {
// submenuItems.children?.forEach((subsubmenuItems) => {
// if (
// subsubmenuItems.children &&
// subsubmenuItems.children.includes(item)
// ) {
// menuItem.active = true;
// submenuItems.active = true;
// subsubmenuItems.active = true;
// menuItem.selected = true;
// submenuItems.selected = true;
// subsubmenuItems.selected = true;
// }
// });
// }
// });
// }
// });
// }
// // Toggle menu
// toggleNavActive(item: any) {
// if (localStorage.getItem('ynex-sidemenu-styles') == 'icontext') {
// document.querySelector('html')?.setAttribute('icon-text', 'open')
// } else {
// document.querySelector('html')?.removeAttribute('icon-text')
// }
// if (localStorage.getItem('ynex-sidemenu-styles') == 'doublemenu') {
// if (item.active) return;
// } else {
// }
// if (!item.active) {
// this.menuItems?.forEach((a: any) => {
// if (this.menuItems.includes(item)) {
// a.active = false;
// }
// a?.children?.forEach((b: any) => {
// if (a.children.includes(item)) {
// b.active = false;
// } else {
// b.active = false;
// }
// b?.children?.forEach((c: any) => {
// if (b.children.includes(item)) {
// c.active = false;
// }
// });
// });
// });
// }
// item.active = !item.active;
// }
// // Close Nav menu
// closeNavActive() {
// this.menuItems?.forEach((a: any) => {
// if (this.menuItems) {
// a.active = false;
// }
// a?.children?.forEach((b: any) => {
// if (a.children) {
// b.active = false;
// }
// });
// });
// }
// ParentActive() {
// this.menuItems.map((element: any) => {
// if (element.children) {
// element.active = false;
// element.selected = false;
// element.children.map((ele: any) => {
// if (ele.path == this.currentUrl) {
// element.active = true;
// element.selected = true;
// }
// if (ele.children) {
// ele.active = false;
// ele.children.map((child1: any) => {
// if (child1.path == this.currentUrl) {
// element.active = true;
// element.selected = true;
// ele.active = true;
// ele.selected = true;
// }
// });
// }
// });
// }
// });
// }
// @ViewChild('iconContainer', { static: true }) iconContainer!: ElementRef;
// getSanitizedSVG(svgContent: string, menu: any): SafeHtml {
// const svg = this.renderer.createElement(
// 'svg',
// 'http://www.w3.org/2000/svg'
// );
// svg.innerHTML = svgContent;
// svg.classList.add('side-menu__icon');
// this.renderer.listen(svg, 'click', () => {
// this.toggleNavActive(menu);
// });
// // return svg;
// return this.sanitizer.bypassSecurityTrustHtml(svgContent);
// }
// ngOnDestroy() {
// this.menuitemsSubscribe$.unsubscribe();
// this.windowSubscribe$.unsubscribe();
// this.elementRef.nativeElement.ownerDocument.documentElement,
// 'data-nav-layout',
// 'vertical';
// const WindowResize = fromEvent(window, 'resize');
// // subscribing the Observable
// if (WindowResize) {
// this.windowSubscribe$ = WindowResize.subscribe(() => {
// // to check and adjst the menu on screen size change
// checkHoriMenu();
// });
// }
// }
// menuOpen() {
// const mainContent = document.querySelector('.main-content') as HTMLElement;
// if (localStorage['Ynexverticalstyles'] === 'icontext' && localStorage['iconText'] !== 'open') {
// // Assuming you have a service or method to update the theme
// this.updateTheme({ ...this.getCurrentTheme(), iconText: 'open' });
// mainContent?.addEventListener('click', (_event) => {
// // Assuming you have a service or method to update the theme
// this.updateTheme({ ...this.getCurrentTheme(), iconText: '' });
// });
// }
// if (localStorage['Ynexverticalstyles'] === 'doublemenu' && this.getCurrentTheme().dataToggled !== 'double-menu-open') {
// // Assuming you have a service or method to update the theme
// this.updateTheme({ ...this.getCurrentTheme(), dataToggled: 'double-menu-open' });
// }
// }
// // Replace this method with your actual method or service call to update the theme
// updateTheme(updatedTheme: any) {
// // Implement the logic to update the theme in your application
// // This might involve a service or a method that dispatches an action to update the theme state
// console.log('Update Theme:', updatedTheme);
// }
// // Replace this method with your actual method or service call to get the current theme
// getCurrentTheme(): any {
// // Implement the logic to get the current theme from your application state or service
// // Return the current theme object
// return {};
// }
// @HostListener('window:resize', ['$event'])
// onResize(event: any): void {
// this.menuResizeFn();
// this.screenWidth = window.innerWidth;
// // Check if the event hasn't been triggered and the screen width is less than or equal to your breakpoint
// if (!this.eventTriggered && this.screenWidth <= 992) {
// document.documentElement?.setAttribute('data-toggled', 'close')
// // Trigger your event or perform any action here
// this.eventTriggered = true; // Set the flag to true to prevent further triggering
// } else if (this.screenWidth > 992) {
// // Reset the flag when the screen width goes beyond the breakpoint
// this.eventTriggered = false;
// }
// }
// WindowPreSize: number[] = [window.innerWidth];
// menuResizeFn(): void {
// this.WindowPreSize.push(window.innerWidth);
// if (this.WindowPreSize.length > 2) {
// this.WindowPreSize.shift();
// }
// if (this.WindowPreSize.length > 1) {
// const html = document.documentElement;
// if (this.WindowPreSize[this.WindowPreSize.length - 1] < 992 && this.WindowPreSize[this.WindowPreSize.length - 2] >= 992) {
// // less than 992
// html.setAttribute('data-toggled', 'close');
// }
// if (this.WindowPreSize[this.WindowPreSize.length - 1] >= 992 && this.WindowPreSize[this.WindowPreSize.length - 2] < 992) {
// // greater than 992
// html.removeAttribute('data-toggled');
// document.querySelector('#responsive-overlay')?.classList.remove('active');
// }
// }
// }
// }
...@@ -149,19 +149,10 @@ export class NavService implements OnDestroy { ...@@ -149,19 +149,10 @@ export class NavService implements OnDestroy {
type: 'link', type: 'link',
}, },
{ {
icon: 'buildings', icon: 'receipt',
path: '/admin/company-departments', path: '/admin/excel-report',
title: 'ทะเบียนบริษัท', title: 'รายงาน Excel',
type: 'sub', type: 'link',
children: [
{ path: '/admin/career-cluster', title: 'จัดการกลุ่มอาชีพ', type: 'link' },
{ path: '/admin/position', title: 'จัดการตำแหน่ง', type: 'link' },
{ path: '/admin/job-types', title: 'จัดการประเภทงาน', type: 'link' },
{ path: '/admin/category-company', title: 'จัดการประเภทธุรกิจ', type: 'link' },
{ path: '/admin/degree-manage', title: 'จัดการระดับการศึกษา', type: 'link' },
{ path: '/admin/country-registration', title: 'จัดการประเทศ', type: 'link' },
{ path: '/admin/provinces', title: 'จัดการจังหวัด', type: 'link' },
],
}, },
// { headTitle: 'User Management' }, // { headTitle: 'User Management' },
......
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