Commit ec6babb4 by Nattana Chaiyamat

ข้อมูลทั่วไป ปัจจัยการประเมินสมรรถนะ

parent d4c487e6
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" id="hs-leading-icon" name="hs-leading-icon"
class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 " placeholder="Search by No. or Name"
[(ngModel)]="search" (ngModelChange)="searchChange()">
<div
class="absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4">
<i class="ri-search-line text-gray"></i>
</div>
</div>
</div>
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-success h-45px m-0 shadow-md"
data-hs-overlay="#define-evaluation-factors-alert-modal">
<i class="ri-save-3-line"></i>
Save
</button>
</div>
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md" (click)="clear()">
<svg class="svg-indigo" width="16" height="16" viewBox="0 0 64.00 64.00"
xmlns="http://www.w3.org/2000/svg" fill="none" stroke="#595BEA" stroke-width="3.84"
transform="rotate(45)matrix(-1, 0, 0, 1, 0, 0)">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<path d="M15 49A24 24 0 0 1 32 8"></path>
<path d="M49 15a24 24 0 0 1-17 41"></path>
<polyline points="15.03 40 15.03 48.97 8 48.97"></polyline>
<polyline points="48.97 24 48.97 15.03 56 15.03"></polyline>
</g>
</svg>
Clear
</button>
</div>
<!-- <div class="px-1">
<button href="javascript:void(0);" class="ti-btn ti-btn-soft-warning h-45px m-0 shadow-md">
<i class="ti ti-book fs-l"></i>
Help
</button>
</div> -->
</div>
</div>
</div>
<div class="page px-rem">
<div class="overflow-auto rounded-top-0.65rem">
<table class="ti-custom-table ti-custom-table-head ti-custom-table-hover">
<thead class="height-50px">
<tr class="font-size-12px">
<ng-container *ngFor="let item of pmsEaluationFactorsTableHeader; let f = first; let l = last">
<th scope="col" class="relative px-10px py-10px bg-soft-secondary text-primary"
[class.!text-center]="f||l">
<span class="font-size-12px font-weight-700">{{ item }}</span>
<div class="absolute top-1/2 transform -translate-y-1/2 right-0" *ngIf="!l">
<i class="ti ti-dots-vertical fs-l"></i>
</div>
</th>
</ng-container>
</tr>
</thead>
<tbody *ngIf="pmsEaluationFactors.loading">
<tr>
<td class="text-center" colspan="100%">
<div *ngFor="let item of [1,2,3]" class="ti-spinner w-8 h-8 text-secondary mx-1" role="status"
aria-label="loading">
<span class="sr-only">Loading...</span>
</div>
</td>
</tr>
</tbody>
<tbody *ngIf="!pmsEaluationFactors.loading&&!dataListFilter().length">
<tr>
<td class="text-center" colspan="100%">
ไม่พบข้อมูล
</td>
</tr>
</tbody>
<tbody *ngIf="!pmsEaluationFactors.loading&&dataListFilter().length">
<tr
*ngFor="let pmsEaluationFactors of dataListFilter() | slice:((currentPage-1) * 10) : (((currentPage-1) * 10) + 10);let i = index">
<td class="text-center">
<span>
{{pmsEaluationFactors.personalLevel.plId }}
</span>
</td>
<td *ngFor="let item of pmsEaluationFactors.pmsEvaluationFactors1ModelList">
<input type="text" class="ti-form-input" oninput="this.value = this.value.replace(/\D/g, '')"
[(ngModel)]="item.pmsScore">
</td>
<td class="text-center">
{{calPmsEaluationFactors1Total(pmsEaluationFactors.pmsEvaluationFactors1ModelList) }} </td>
</tr>
</tbody>
</table>
</div>
<nav class="pagination-style-3 overflow-auto my-5" *ngIf="page.length">
<ul class="ti-pagination">
<li>
<a aria-label="anchor" class="page-link" href="javascript:void(0);"
(click)="currentPage = (currentPage-1 || 1)">
<i class="ri-arrow-left-s-line align-middle rtl:rotate-180"></i>
</a>
</li>
<li *ngFor="let item of page;let f = first;let l = last">
<ng-container *ngIf="item==3&&currentPage!=1&&currentPage!=2&&currentPage!=3">
<a aria-label="anchor" class="page-link" href="javascript:void(0);"><i class="ri-more-line"></i>
</a>
</ng-container>
<ng-container *ngIf="(f||l)||(item==currentPage-1||item==currentPage||item==currentPage+1)">
<a class="page-link" href="javascript:void(0);" [class.active]="item==currentPage"
(click)="currentPage=item">{{item}}
</a>
</ng-container>
<ng-container
*ngIf="item==page.length-2&&currentPage!=page.length&&currentPage!=page.length-1&&currentPage!=page.length-2">
<a aria-label="anchor" class="page-link" href="javascript:void(0);"><i class="ri-more-line"></i>
</a>
</ng-container>
</li>
<li>
<a aria-label="anchor" class="page-link" href="javascript:void(0);"
(click)="currentPage = (currentPage > page.length-1 ? currentPage: currentPage+1 )">
<i class="ri-arrow-right-s-line align-middle rtl:rotate-180"></i>
</a>
</li>
</ul>
<ul class="nav-tabs mt-3">
<span>Show {{((currentPage-1) * 10)+1}} to {{dataListFilter().length<10 ?dataListFilter().length:
(currentPage==page.length ? ((currentPage * 10) - ((currentPage * 10) - dataListFilter().length) )
:(currentPage * 10) ) }} of {{dataListFilter().length}} items</span>
</ul>
</nav>
</div>
<div id="define-evaluation-factors-alert-modal" class="hs-overlay hidden ti-modal">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out h-[calc(100%-3.5rem)] flex items-center">
<div class="max-h-full overflow-hidden ti-modal-content w-full">
<div class="ti-modal-header">
<h3 class="text-xxl font-bold text-primary">
แจ้งเตือน
</h3>
<div class="flex justify-end">
<button type="button" class="hs-dropdown-toggle ti-modal-clode-btn text-danger"
data-hs-overlay="#define-evaluation-factors-alert-modal">
<span class="sr-only">Close</span>
<i class="ti ti-circle-x fs-xxl"></i>
</button>
</div>
</div>
<div class="ti-modal-body ">
<p class="mt-1 text-gray-800 dark:text-white/70">
ยืนยันการบันทึกข้อมูลหรือไม่
</p>
<div class="flex justify-end mt-2rem mb-1rem">
<button type="button"
class="hs-dropdown-toggle ti-btn ti-border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:ring-offset-white focus:ring-primary dark:bg-bgdark dark:hover:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-white dark:focus:ring-offset-white/10"
data-hs-overlay="#define-evaluation-factors-alert-modal">
ย้อนกลับ
</button>
<a class="ti-btn ti-btn-success" href="javascript:void(0);"
data-hs-overlay="#define-evaluation-factors-alert-modal" (click)="savePmsEaluationFactors()">
บันทึกข้อมูล
</a>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { ChangeDetectorRef, Component } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { MyPmsEvaluationFactorsModel, PmsEvaluationFactorsModel } from 'src/app/shared/model/pms-ealuation-factors.model';
import { MyPmsEaluationFactors1Model, PmsEaluationFactors1Model } from 'src/app/shared/model/pms-ealuation-factors1.model';
import { MyPmstypeModel } from 'src/app/shared/model/pmstype.model';
import { PmsEaluationFactorsService } from 'src/app/shared/services/pms-ealuation-factors.service';
@Component({
selector: 'app-competency-define-evaluation-factors',
templateUrl: './competency-define-evaluation-factors.component.html',
styleUrls: ['./competency-define-evaluation-factors.component.scss']
})
export class CompetencyDefineEvaluationFactorsComponent {
currentPage = 1
page = Array.from({ length: 1 }, (_, i) => i + 1);
search = ""
pmsEaluationFactors: { loading: boolean, dataList: PmsEvaluationFactorsModel[] } = { loading: false, dataList: [] }
pmsEaluationFactorsTableHeader: string[] = ['ลักษณะงาน']
constructor(private pmsEaluationFactorsService: PmsEaluationFactorsService,
private toastr: ToastrService,
private cdr: ChangeDetectorRef
) { }
ngOnInit(): void {
this.getPmsEaluationFactorsList()
}
getPmsEaluationFactorsList() {
this.pmsEaluationFactors.loading = true
this.pmsEaluationFactorsTableHeader = ['ลักษณะงาน']
this.pmsEaluationFactorsService.getList().subscribe({
next: response => {
this.pmsEaluationFactors.dataList = response.map(x => new MyPmsEvaluationFactorsModel(x))
this.pmsEaluationFactors.loading = false
const maxItem = this.pmsEaluationFactors.dataList.reduce((max, item) =>
item.pmsEvaluationFactors1ModelList.length > max.pmsEvaluationFactors1ModelList.length ? item : max,
this.pmsEaluationFactors.dataList[0]
);
const pmsTypeIds = maxItem?.pmsEvaluationFactors1ModelList.map(x => x.pmsType.pmsTypeId) || [];
this.pmsEaluationFactorsTableHeader = this.pmsEaluationFactorsTableHeader.concat(maxItem?.pmsEvaluationFactors1ModelList.map(x => x.pmsType.tdesc) || []).concat(['รวม'])
this.pmsEaluationFactors.dataList.forEach(x => {
while (x.pmsEvaluationFactors1ModelList.length < 5) {
const usedTypes = x.pmsEvaluationFactors1ModelList.map(y => y.pmsType.pmsTypeId);
const remainingTypes = pmsTypeIds.filter(type => !usedTypes.includes(type));
if (remainingTypes.length === 0) { break }
const pmsTypeId = remainingTypes[0];
x.pmsEvaluationFactors1ModelList.push(
new MyPmsEaluationFactors1Model({ pmsType: new MyPmstypeModel({ pmsTypeId }) })
)
}
x.pmsEvaluationFactors1ModelList.sort((a, b) => +(a.pmsType.pmsTypeId) - +(b.pmsType.pmsTypeId))
})
this.searchChange()
this.cdr.detectChanges()
}, error: error => {
this.pmsEaluationFactors.loading = false
this.cdr.detectChanges()
}
})
}
savePmsEaluationFactors() {
this.pmsEaluationFactors.loading = true
const body = this.pmsEaluationFactors.dataList.map(x => new MyPmsEvaluationFactorsModel({
...x,
pmsEvaluationFactors1ModelList: x.pmsEvaluationFactors1ModelList.map(y => new MyPmsEaluationFactors1Model({
...y,
pmsScore: +(y.pmsScore)
}))
}))
this.pmsEaluationFactorsService.post(body).subscribe({
next: response => {
if (response.success) {
this.showAlert(response.message, 'success')
this.getPmsEaluationFactorsList()
} else {
this.showAlert(response.message, 'error')
this.pmsEaluationFactors.loading = false
this.cdr.detectChanges()
}
}, error: error => {
this.showAlert(error.message, 'error')
this.pmsEaluationFactors.loading = false
this.cdr.detectChanges()
}
})
}
clear() {
this.pmsEaluationFactors.dataList = this.pmsEaluationFactors.dataList.map(x => new MyPmsEvaluationFactorsModel({
...x,
pmsEvaluationFactors1ModelList: x.pmsEvaluationFactors1ModelList.map(y => new MyPmsEaluationFactors1Model({
...y,
pmsScore: 0
}))
}))
}
calPmsEaluationFactors1Total(data: PmsEaluationFactors1Model[]) {
return data.reduce((sum, num) => sum + +(num.pmsScore), 0);
}
dataListFilter() {
return this.pmsEaluationFactors.dataList.filter(x => x.personalLevel.plId.toLowerCase().includes(this.search.toLowerCase()))
}
searchChange() {
this.currentPage = 1;
const filteredData = this.dataListFilter();
this.page = Array.from({ length: Math.ceil(filteredData.length / 10) }, (_, i) => i + 1);
}
showAlert(text: string, type: 'success' | 'error') {
this.toastr[type](text, 'แจ้งเตือน', {
timeOut: 3000,
positionClass: 'toast-top-right',
})
}
}
<app-page-header [pathTitle]="pathTitle"></app-page-header>
<div class="bg-card-white">
</div>
<div class="block-main-content">
<div class="font-size-18px font-weight-700 pt-1.5rem text-primary px-2rem">
ปัจจัยการประเมินสมรรถนะ
</div>
<div class="page pt-0.75rem">
<div class="border-b border-gray-200 dark:border-white/10 px-2rem">
<nav class="-mb-0.5 flex space-x-6 rtl:space-x-reverse">
<a class="text-base font-medium hs-tab-active:border-secondary hs-tab-active:text-secondary pb-3 inline-flex items-center gap-2 border-b-[3px] border-transparent whitespace-nowrap text-gray-500 dark:text-white/70 hover:text-secondary active"
href="javascript:void(0);" id="underline-item-1" data-hs-tab="#underline-1"
aria-controls="underline-1">
กำหนดปัจจัยการประเมินสมรรถนะ
</a>
</nav>
</div>
<div class="px-2rem pt-50px">
<div id="underline-1" role="tabpanel" aria-labelledby="underline-item-1">
<app-competency-define-evaluation-factors></app-competency-define-evaluation-factors>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component } from '@angular/core';
@Component({
selector: 'app-competency-evaluation-factors',
templateUrl: './competency-evaluation-factors.component.html',
styleUrls: ['./competency-evaluation-factors.component.scss']
})
export class CompetencyEvaluationFactorsComponent {
pathTitle = ['การประเมินสมรรถนะ', 'ปัจจัยการประเมินสมรรถนะ', 'กำหนดปัจจัยการประเมินสมรรถนะ']
}
\ No newline at end of file
......@@ -57,6 +57,7 @@ import { ExcelReportComponent } from '../excel-report/excel-report.component';
import { SettingIndividualKpiComponent } from '../setting-individual-kpi/setting-individual-kpi.component';
import { SettingIndividualKpiSupervisorComponent } from '../setting-individual-kpi-supervisor/setting-individual-kpi-supervisor.component';
import { JobDescriptionEssComponent } from '../job-description-ess/job-description-ess.component';
import { CompetencyEvaluationFactorsComponent } from '../competency-assessment/competency-evaluation-factors/competency-evaluation-factors.component';
......@@ -107,6 +108,7 @@ const routes: Routes = [
{ path: "ess/pms-evaluation", title: 'ประเมินผล PMS', component: PmsFormEmployeeComponent },
{ path: "admin/employee-registration", title: 'ทะเบียนพนักงาน', component: EmployeeRegistrationComponent },
{ path: "admin/name-registration-perfomance", title: 'ทะเบียนกำหนดชื่อ', component: NameRegistrationPerfomanceComponent },
{ path: "admin/competency-evaluation-factors", title: 'ปัจจัยการประเมินสมรรถนะ', component: CompetencyEvaluationFactorsComponent },
{ path: "admin/evaluation-factors", title: 'การประเมินจัดการประสิทธิภาพ', component: EvaluationFactorsComponent },
{ path: "admin/grade-registration", title: 'ทะเบียนเกรด', component: GradeRegistrationComponent },
{ path: "admin/grade-registration-sub", title: 'ทะเบียนเกรด', component: PmsGradeRegistrationComponent },
......
......@@ -149,9 +149,20 @@
<label for="detail_eng" class="ti-form-label mt-2rem">ตำแหน่งผู้บังคับบัญชา</label>
<ng-select class="ti-form-select" data-trigger name="choices-single-position"
id="choices-single-position" [(ngModel)]="supervisorPositionId"
(ngModelChange)="changSupervisorPosition()">
<ng-option *ngFor="let item of positionList" [value]="item.positionId">{{item.tdesc}}</ng-option>
id="choices-single-position" [(ngModel)]="jd" (ngModelChange)="changSupervisorJd()">
<ng-option *ngFor="let item of jdList" [value]="item.jobCodeId">{{item.tdesc}}</ng-option>
</ng-select>
<label for="detail_eng" class="ti-form-label mt-2rem">ระดับพนักงาน</label>
<ng-select class="ti-form-select" data-trigger name="choices-single-position"
id="choices-single-position" [(ngModel)]="jl" (ngModelChange)="changJl()">
<ng-option *ngFor="let item of jlList" [value]="item.plId">{{item.tdesc}}</ng-option>
</ng-select>
<label for="detail_eng" class="ti-form-label mt-2rem">ระดับความคาดหวัง</label>
<ng-select class="ti-form-select" data-trigger name="choices-single-position"
id="choices-single-position" [(ngModel)]="empLevel" (ngModelChange)="changEmpLevel()">
<ng-option *ngFor="let item of ['1','2','3','4','5']" [value]="item">{{item}}</ng-option>
</ng-select>
<label for="detail_eng" class="ti-form-label mt-2rem">วัตถุประสงค์ของตำแหน่งงาน (Objective)</label>
......
......@@ -10,6 +10,8 @@ import { Bu6Model, MyBu6Model } from 'src/app/shared/model/bu6.model';
import { Bu7Model, MyBu7Model } from 'src/app/shared/model/bu7.model';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { JobCodeModel, MyJobCodeModel } from 'src/app/shared/model/job-code.model';
import { JobcodeModel, MyJobcodeModel } from 'src/app/shared/model/jobcode.model';
import { MyPLModel, PLModel } from 'src/app/shared/model/pl.model';
import { MyPositionModel, PositionModel } from 'src/app/shared/model/position.model';
import { Bu1Service } from 'src/app/shared/services/bu1.service';
import { Bu2Service } from 'src/app/shared/services/bu2.service';
......@@ -21,6 +23,8 @@ import { Bu7Service } from 'src/app/shared/services/bu7.service';
import { EmployeeService } from 'src/app/shared/services/employee.service';
import { FileService } from 'src/app/shared/services/file.service';
import { JobCodeService } from 'src/app/shared/services/job-code.service';
import { JobcodeService } from 'src/app/shared/services/jobcode.service';
import { PLService } from 'src/app/shared/services/pl.service';
import { PositionService } from 'src/app/shared/services/position.service';
@Component({
......@@ -62,10 +66,17 @@ export class ImportDataComponent {
bu7List: Bu7Model[] = []
bu7Id = ''
supervisorPositionId = ''
jdList: JobcodeModel[] = []
jd = ''
employeeList: EmployeeModel[] = []
checkJobCodeId = false
jlList: PLModel[] = []
jl = ''
empLevel = ''
currentModal: 'add' | 'edit' | 'delete' = "add"
columns: ColumnModel[] = [{
field: "jobcodeId",
......@@ -92,7 +103,9 @@ export class ImportDataComponent {
constructor(
private toastr: ToastrService,
private fileService: FileService,
private jobcodeService: JobCodeService,
private jobCodeService: JobCodeService,
private jobcodeService: JobcodeService,
private pLService: PLService,
private cdr: ChangeDetectorRef,
private positionService: PositionService,
private bu1Service: Bu1Service,
......@@ -102,11 +115,12 @@ export class ImportDataComponent {
private bu5Service: Bu5Service,
private bu6Service: Bu6Service,
private bu7Service: Bu7Service,
private employeeService: EmployeeService
private employeeService: EmployeeService,
) { }
ngOnInit(): void {
this.getJlList();
this.getJdList();
this.getListJob();
this.getPositionList();
this.getBu1List();
this.getBu2List();
......@@ -129,10 +143,30 @@ export class ImportDataComponent {
}
getJdList() {
this.jobcodeService.getGroupAssessmentList().subscribe({
next: response => {
this.jdList = response.map(x => new MyJobcodeModel(x))
this.cdr.detectChanges()
}, error: error => {
this.cdr.detectChanges()
}
})
}
getJlList() {
this.pLService.getList().subscribe({
next: response => {
this.jlList = response.map(x => new MyPLModel(x))
this.cdr.detectChanges()
}, error: error => {
this.cdr.detectChanges()
}
})
}
getListJob() {
this.loading = false
this.selectedItems.data.clear()
this.jobcodeService.getList().subscribe({
this.jobCodeService.getList().subscribe({
next: response => {
this.jobCodeList = response.map((x: any) => {
this.selectedItems.data.set(x.jobcodeId, false)
......@@ -158,7 +192,7 @@ export class ImportDataComponent {
this.selectJob = new MyJobCodeModel(item)
this.positionId = item.position.positionId
this.supervisorPositionId = item.supervisorPosition.positionId
this.jd = item.supervisorPosition.positionId
this.bu1Id = item.bu1.bu1id
this.bu2Id = item.bu2.bu2id
this.bu3Id = item.bu3.bu3id
......@@ -171,7 +205,7 @@ export class ImportDataComponent {
this.selectJob = new MyJobCodeModel({})
this.checkJobCodeId = false
this.positionId = ''
this.supervisorPositionId = ''
this.jd = ''
this.bu1Id = ''
this.bu2Id = ''
this.bu3Id = ''
......@@ -186,7 +220,7 @@ export class ImportDataComponent {
this.selectJob.jobObjective = ''
this.selectJob.supervisorPosition = new MyPositionModel({})
this.supervisorPositionId = ''
this.jd = ''
this.selectJob.position = new MyPositionModel({})
this.positionId = ''
......@@ -213,7 +247,7 @@ export class ImportDataComponent {
this.bu7Id = ''
}
save() {
this.jobcodeService.post(this.selectJob).subscribe((response: any) => {
this.jobCodeService.post(this.selectJob).subscribe((response: any) => {
if (response.success) {
this.showAlert(response.message, 'success')
this.selectJob = new MyJobCodeModel({})
......@@ -227,7 +261,7 @@ export class ImportDataComponent {
deleteJob() {
const selectedKeys = Array.from(this.selectedItems.data.keys());
const body = this.jobCodeList.filter(x => selectedKeys.includes(x.jobcodeId) && this.selectedItems.data.get(x.jobcodeId)).map(x => new MyJobCodeModel(x))
this.jobcodeService.delete(body).subscribe((response: any) => {
this.jobCodeService.delete(body).subscribe((response: any) => {
if (response.success) {
this.showAlert(response.message, 'success')
this.selectJob = new MyJobCodeModel({})
......@@ -312,14 +346,25 @@ export class ImportDataComponent {
this.selectJob.position = new MyPositionModel({})
}
}
changSupervisorPosition() {
let value = this.positionList.find(x => x.positionId == this.supervisorPositionId);
changSupervisorJd() {
let value = this.jdList.find(x => x.jobCodeId == this.jd);
if (value) {
this.selectJob.supervisorPosition = value
// this.selectJob.supervisorJD = value
} else {
this.selectJob.supervisorPosition = new MyPositionModel({})
// this.selectJob.supervisorJD = new MyJobcodeModel({})
}
}
changJl() {
let value = this.jlList.find(x => x.plId == this.jd);
if (value) {
// this.selectJob.supervisorJD = value
} else {
// this.selectJob.supervisorJD = new MyJobcodeModel({})
}
}
changEmpLevel() {
// this.selectJob.supervisorJD = this.empLevel
}
getBu1List() {
this.bu1Service.getList().subscribe({
......
......@@ -223,6 +223,7 @@ export class NavService implements OnDestroy {
{ id: 'm44', path: 'admin/tool-register', title: 'ทะเบียนเครื่องมือ', type: 'link', show: true },
{ id: 'm45', path: 'admin/course-registration', title: 'ทะเบียนหลักสูตร', type: 'link', show: true },
{ id: 'm46', path: 'admin/idp-development-plan', title: 'แผนพัฒนา IDP', type: 'link', show: true },
{ id: 'm465', path: 'admin/competency-evaluation-factors', title: 'ปัจจัยการประเมินสมรรถนะ', type: 'link', show: true },
{ id: 'm47', path: 'admin/competency-management', title: 'การจัดการสมรรถนะ', type: 'link', show: true },
{ id: 'm48', path: 'admin/evaluation-cycle-manager', title: 'การจัดการรอบการประเมิน', type: 'link', show: true },
],
......
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