Commit 8e8e7ae4 by Nattana Chaiyamat

แปลภาษา หน้าจอใหม่ jobgrade jobgradegroup jobfamily

parent 066553f0
{
"turboConsoleLog.logMessagePrefix": "🥷🏿"
}
\ No newline at end of file
......@@ -38,6 +38,24 @@
(click)="currentPath = 5;pathTitle = ['menu.Organization','menu.JobDescription','JobLevelJL']">
{{'JobLevelJL' | translate}}
</a>
<a class="text-base font-medium hs-tab-active:text-lg hs-tab-active:font-bold hs-tab-active:border-secondary hs-tab-active:text-secondary pb-3 px-1 inline-flex items-center gap-2 border-b-[3px] border-transparent whitespace-nowrap text-gray-500 dark:text-white/70 hover:text-secondary"
href="javascript:void(0);" id="underline-item-6" data-hs-tab="#underline-6"
aria-controls="underline-6"
(click)="currentPath = 6;pathTitle = ['menu.Organization','menu.JobDescription','JobFamily']">
{{'JobFamily' | translate}}
</a>
<a class="text-base font-medium hs-tab-active:text-lg hs-tab-active:font-bold hs-tab-active:border-secondary hs-tab-active:text-secondary pb-3 px-1 inline-flex items-center gap-2 border-b-[3px] border-transparent whitespace-nowrap text-gray-500 dark:text-white/70 hover:text-secondary"
href="javascript:void(0);" id="underline-item-7" data-hs-tab="#underline-7"
aria-controls="underline-7"
(click)="currentPath = 7;pathTitle = ['menu.Organization','menu.JobDescription','JobGradeGroup']">
{{'JobGradeGroup' | translate}}
</a>
<a class="text-base font-medium hs-tab-active:text-lg hs-tab-active:font-bold hs-tab-active:border-secondary hs-tab-active:text-secondary pb-3 px-1 inline-flex items-center gap-2 border-b-[3px] border-transparent whitespace-nowrap text-gray-500 dark:text-white/70 hover:text-secondary"
href="javascript:void(0);" id="underline-item-8" data-hs-tab="#underline-8"
aria-controls="underline-8"
(click)="currentPath = 8;pathTitle = ['menu.Organization','menu.JobDescription','JobGrade']">
{{'JobGrade' | translate}}
</a>
</nav>
</div>
<div class="mt-3 px-2rem !-mt-3 pt-50px">
......@@ -60,6 +78,18 @@
aria-labelledby="underline-item-5">
<app-employee-level></app-employee-level>
</div>
<div *ngIf="currentPath == 6" id="underline-6" class="hidden" role="tabpanel"
aria-labelledby="underline-item-6">
<app-job-family></app-job-family>
</div>
<div *ngIf="currentPath == 7" id="underline-7" class="hidden" role="tabpanel"
aria-labelledby="underline-item-7">
<app-job-grade-group></app-job-grade-group>
</div>
<div *ngIf="currentPath == 8" id="underline-8" class="hidden" role="tabpanel"
aria-labelledby="underline-item-8">
<app-job-grade></app-job-grade>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="search">
<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=" h-45px ti-btn ti-btn bg-pink-500/10 text-pink-500 hover:text-white hover:bg-pink-500 ring-offset-white focus:ring-pink-500 dark:focus:ring-offset-white/10 h-10 m-0 shadow-md"
data-hs-overlay="#job-family-component-upload-modal"
(click)="fileInput.value = '';selectedFile=null;selectedFileName = 'กรุณาเลือกไฟล์'">
<i class="ti ti-file-plus"></i>
{{'Import' | translate}}
</button>
</div>
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-secondary h-45px m-0 shadow-md"
(click)="currentModal='add';selectPosition();openDialog()">
<i class="ri-add-line"></i>
{{'Add' | translate}}
</button>
</div>
<div class="px-1">
<button href="javascript:void(0);" class="ti-btn ti-btn-soft-danger h-45px m-0 shadow-md"
(click)="currentModal='delete';selectPosition();deletePosition()">
<i class="ri-delete-bin-6-line"></i>
{{'Delete' | translate}}
</button>
</div>
</div>
</div>
<div class="page px-rem">
<app-datagrid-syncfution [searchSettings]="searchSettings" [searchText]="search" [dataSource]="position.dataList"
[columns]="columns" [selectedItems]="selectedItems"
(sendSelectData)="currentModal='edit';selectPosition($event);openDialog()"
(sendSelectedItems)="onSelectItemChange($event)">
</app-datagrid-syncfution>
</div>
<ng-template #jobFamilyModal let-modal>
<h3 mat-dialog-title>
{{(currentModal=='add'?'AddJobFamily':'EditJobFamily') | translate}}
</h3>
<div class="w-full flex justify-end mb-1rem">
<div class="absolute flex">
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md" (click)="selectPosition()">
<i class="ti ti-eraser text-base"></i>
{{'Clear' |translate}}
</button>
</div>
</div>
</div>
<mat-dialog-content>
<label for="input-label" class="ti-form-label mt-2rem">
{{'JobFamilyCode' | translate}}
<span class="text-danger">
*
<ng-container *ngIf="currentModal=='add'&&checkPrimary()">
{{'DuplicateJobFamilyCode' | translate}}
</ng-container>
</span></label>
<input type="text" id="input-label" class="ti-form-input w-1/2 "
[ngClass]="{'bg-input-readonly':currentModal=='edit'}" [readonly]="currentModal=='edit'"
[(ngModel)]="position.select.positionId">
<label for="detail_th" class="ti-form-label mt-2rem">{{'JobFamilyNameThai' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_th" class="ti-form-input h-16" [(ngModel)]="position.select.tdesc">
<label for="detail_eng" class="ti-form-label mt-2rem">{{'JobFamilyNameEng' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_eng" class="ti-form-input h-16" [(ngModel)]="position.select.edesc">
<label for="detail_short" class="ti-form-label mt-2rem">{{'JobFamilyAbbr' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_short" class="ti-form-input h-16" [(ngModel)]="position.select.edesc">
<div class="grid grid-cols-12 gap-x-6 mt-2rem">
<label class="col-span-3 ti-form-label text-primary mt-2 align-center">{{'Image' |
translate}}</label>
<div class="flex flex-row col-span-5" style="align-items: end;">
<div style="width: 10rem;">
<div *ngIf="imgLoading" class="ti-spinner w-8 h-8 text-secondary mx-1" role="status"
aria-label="loading" style="height: 9rem;width: 9rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- [src]="employee.select.picture?getImg(employee.select.picture):'./assets/img/users/defaultperson.jpg'" -->
<img *ngIf="!imgLoading" [src]="'./assets/img/users/defaultperson.jpg'"
(error)="onImageError($event)" class="rounded-full ring-4 ring-white/10 mx-auto object-cover"
id="profile-img" alt="profile-img" style="height: 10rem;width: 10rem;">
</div>
<div *ngIf="!imgLoading" class="relative" style="margin-left:-30px">
<i class="ri ri-pencil-line cursor-pointer" (click)="fileImg.click()"></i>
<input #fileImg id="fileImg" type="file" (change)="onImgSelected($event)" hidden>
<i class="ri-delete-bin-6-line text-danger cursor-pointer"></i>
<!-- (click)="employee.select.picture = ''"> -->
</div>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
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">
{{'Back' | translate}}
</button>
<button type="button" class="ti-btn ti-btn-success" mat-button (click)="addPosition()"
[class.ti-btn-disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())"
[disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())">
{{'SaveData' | translate}}
</button>
</mat-dialog-actions>
</ng-template>
<div id="job-family-component-upload-modal" class="hs-overlay hidden ti-modal">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out rounded-md">
<div class="ti-modal-header bg-primary !rounded-none !rounded-t-sm">
<h5 class="text-xxl font-bold text-white">
{{'ImportJobFamily' | translate}}
</h5>
</div>
<div class="ti-modal-body max-h-full overflow-hidden ti-modal-content !rounded-t-none !rounded-b-sm">
<h1 class="mt-2" style="text-align: center;">{{'File' | translate}}</h1>
<div class="mt-2 p-2">
<div class="flex rounded-md">
<input #fileInput id="fileInput" type="file" (change)="onFileSelected($event)" hidden>
<input type="text" [value]="selectedFileName | translate" readonly (click)="fileInput.click()"
class="ti-form-input rounded-none ltr:rounded-l-md rtl:rounded-r-md focus:z-10 cursor-pointer">
<button type="button" (click)="fileInput.click()"
class="inline-flex flex-shrink-0 justify-center items-center h-[2.875rem] w-[2.875rem] ltr:rounded-r-md rtl:rounded-l-md border border-transparent font-semibold bg-secondary text-white hover:bg-secondary focus:z-10 focus:outline-none focus:ring-0 focus:ring-secondary transition-all text-sm">
<i class="ti ti-upload"></i>
</button>
</div>
<div class="flex justify-center mt-2rem ">
<h1 class="cursor-pointer justify-center -mb-px inline-flex items-center gap-2 font-weight-500 font-size-12px
text-center text-secondary border-secondary border-b-2 align-items-end" (click)="downloadFile()">
{{'DownloadSampleFile' | translate}}</h1>
</div>
<div class="flex justify-center mt-2rem mb-1rem space-x-4">
<button type="submit" class="ti-btn ti-btn-secondary"
data-hs-overlay="#job-family-component-upload-modal" [class.ti-btn-disabled]="!selectedFile"
(click)="uploadFile()" [disabled]="!selectedFile" [disabled]="!selectedFile">
{{'Upload' | translate}}
</button>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { MyPositionModel, PositionModel } from 'src/app/shared/model/position.model';
import { FileService } from 'src/app/shared/services/file.service';
import { PositionService } from 'src/app/shared/services/position.service';
import Swal from 'sweetalert2';
@Component({
selector: 'app-job-family',
templateUrl: './job-family.component.html',
styleUrls: ['./job-family.component.scss']
})
export class JobFamilyComponent implements OnInit {
selectedFile: File | null = null;
selectedFileName: string = 'selectedFileName';
currentModal: 'add' | 'edit' | 'delete' = 'add'
position: { loading: boolean, select: PositionModel, dataList: PositionModel[] } = { loading: false, select: new MyPositionModel(), dataList: [] }
columns: ColumnModel[] = [{
field: "positionId",
headerText: "JobFamilyCode",
type: "string",
isPrimaryKey: true,
},
{
field: "tdesc",
headerText: "JobFamilyNameThai",
type: "string"
},
{
field: "edesc",
headerText: "JobFamilyNameEng",
type: "string"
}]
searchSettings = {
fields: ['positionId', 'tdesc', 'edesc'],
operator: 'contains',
ignoreCase: false
};
search = ''
selectedItems: { key: string, count: number, data: Map<string, boolean> } = { key: '', count: 0, data: new Map<string, boolean>() };
@ViewChild("jobFamilyModal") jobFamilyModal: any;
dialogRef: any
selectedImg: File | null = null;
imgLoading = false
constructor(private positionService: PositionService,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private fileService: FileService,
private dialog: MatDialog
) { }
ngOnInit(): void {
this.getPositionList()
}
openDialog() {
this.dialogRef = this.dialog.open(this.jobFamilyModal, {
width: '500px',
})
}
closeDialog() {
this.dialogRef.close()
}
onFileSelected(event: any) {
this.selectedFile = event.target.files.length > 0 ? event.target.files[0] : null;
this.selectedFileName = this.selectedFile?.name || "selectedFileName"
}
uploadFile() {
// if (!this.selectedFile) {
// alert('กรุณาเลือกไฟล์ก่อนอัปโหลด')
// return
// }
// const formData = new FormData();
// formData.append('file', this.selectedFile);
// this.position.loading = true
// this.fileService.uploadExcel(formData, 'mposition').subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// })
}
downloadFile() {
// const fileName = 'IMPORT_MPOSITION.xlsx'
// this.fileService.downloadTemplate(fileName).subscribe({
// next: response => {
// const url = window.URL.createObjectURL(response);
// const a = document.createElement("a");
// a.href = url;
// a.download = fileName;
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
// window.URL.revokeObjectURL(url);
// }, error: error => {
// this.showAlert(error.message, 'error')
// }
// })
}
getPositionList() {
this.position.loading = true
this.selectedItems.data.clear()
this.positionService.getList().subscribe({
next: response => {
this.position.dataList = response.map(x => {
this.selectedItems.data.set(x.positionId, false)
return new MyPositionModel(x)
})
this.selectedItems.key = 'positionId'
this.selectedItems.count = 0
this.position.loading = false
this.cdr.detectChanges();
}, error: error => {
this.position.loading = false
console.error('Error fetching employee types:', error);
this.cdr.detectChanges()
}
})
}
selectPosition(position?: PositionModel) {
if (position) {
this.position.select = new MyPositionModel(position)
} else if (this.currentModal == 'add') {
this.position.select = new MyPositionModel()
} else if (this.currentModal == 'edit') {
this.position.select = new MyPositionModel({ positionId: this.position.select.positionId })
}
}
addPosition() {
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ยืนยัน',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// this.positionService.post(this.position.select).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// this.closeDialog()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// })
// }
// })
}
deletePosition() {
// if (this.numSelectItem() == 0) {
// this.showAlert('กรุณาเลือกข้อมูลที่จะลบ', 'error')
// return
// }
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการลบข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ลบข้อมูล',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// const selectedKeys = Array.from(this.selectedItems.data.keys());
// const body = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).map(x => new MyPositionModel(x))
// this.positionService.delete(body).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// })
// }
// })
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
icon: type,
title: 'แจ้งเตือน',
text: text,
showCancelButton: false,
confirmButtonText: 'ยืนยัน',
})
}
checkPrimary() {
return this.position.dataList.find(x => x.positionId == this.position.select.positionId)
}
numSelectItem() {
const selectedKeys = Array.from(this.selectedItems.data.keys());
const num = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).length
return num
}
onSelectItemChange(arg: any) {
this.selectedItems = arg
}
onImgSelected(event: any) {
this.selectedImg = event.target.files.length > 0 ? event.target.files[0] : null;
this.uploadImg()
}
uploadImg() {
if (this.selectedImg) {
this.imgLoading = true
const formData = new FormData();
formData.append('file', this.selectedImg);
this.fileService.uploadImg(formData).subscribe({
next: response => {
if (response.success) {
this.showAlert(response.message, 'success')
// this.employee.select.picture = response.resultObject
} else {
this.showAlert(response.message, 'error')
// this.employee.select.picture = ''
}
this.imgLoading = false
this.cdr.detectChanges()
}, error: error => {
this.showAlert(error.message, 'error')
// this.employee.select.picture = ''
this.imgLoading = false
this.cdr.detectChanges()
}
})
}
}
getImg(text: string) {
return this.fileService.getImg(text)
}
onImageError(event: Event) {
const imgElement = event.target as HTMLImageElement;
imgElement.src = './assets/img/users/defaultperson.jpg';
}
}
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="search">
<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=" h-45px ti-btn ti-btn bg-pink-500/10 text-pink-500 hover:text-white hover:bg-pink-500 ring-offset-white focus:ring-pink-500 dark:focus:ring-offset-white/10 h-10 m-0 shadow-md"
data-hs-overlay="#job-grade-group-component-upload-modal"
(click)="fileInput.value = '';selectedFile=null;selectedFileName = 'กรุณาเลือกไฟล์'">
<i class="ti ti-file-plus"></i>
{{'Import' | translate}}
</button>
</div>
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-secondary h-45px m-0 shadow-md"
(click)="currentModal='add';selectPosition();openDialog()">
<i class="ri-add-line"></i>
{{'Add' | translate}}
</button>
</div>
<div class="px-1">
<button href="javascript:void(0);" class="ti-btn ti-btn-soft-danger h-45px m-0 shadow-md"
(click)="currentModal='delete';selectPosition();deletePosition()">
<i class="ri-delete-bin-6-line"></i>
{{'Delete' | translate}}
</button>
</div>
</div>
</div>
<div class="page px-rem">
<app-datagrid-syncfution [searchSettings]="searchSettings" [searchText]="search" [dataSource]="position.dataList"
[columns]="columns" [selectedItems]="selectedItems"
(sendSelectData)="currentModal='edit';selectPosition($event);openDialog()"
(sendSelectedItems)="onSelectItemChange($event)">
</app-datagrid-syncfution>
</div>
<ng-template #jobGradeGroupModal let-modal>
<h3 mat-dialog-title>
{{(currentModal=='add'?'AddJobGradeGroup':'EditJobGradeGroup') | translate}}
</h3>
<div class="w-full flex justify-end mb-1rem">
<div class="absolute flex">
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md" (click)="selectPosition()">
<i class="ti ti-eraser text-base"></i>
{{'Clear' |translate}}
</button>
</div>
</div>
</div>
<mat-dialog-content>
<label for="input-label" class="ti-form-label mt-2rem">
{{'JobGradeGroupCode' | translate}}
<span class="text-danger">
*
<ng-container *ngIf="currentModal=='add'&&checkPrimary()">
{{'DuplicateJobGradeGroupCode' | translate}}
</ng-container>
</span></label>
<input type="text" id="input-label" class="ti-form-input w-1/2 "
[ngClass]="{'bg-input-readonly':currentModal=='edit'}" [readonly]="currentModal=='edit'"
[(ngModel)]="position.select.positionId">
<label for="detail_th" class="ti-form-label mt-2rem">{{'JobGradeGroupDescThai' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_th" class="ti-form-input h-16" [(ngModel)]="position.select.tdesc">
<label for="detail_eng" class="ti-form-label mt-2rem">{{'JobGradeGroupDescEng' | translate}}</label>
<input type="text" id="detail_eng" class="ti-form-input h-16" [(ngModel)]="position.select.edesc">
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
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">
{{'Back' | translate}}
</button>
<button type="button" class="ti-btn ti-btn-success" mat-button (click)="addPosition()"
[class.ti-btn-disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())"
[disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())">
{{'SaveData' | translate}}
</button>
</mat-dialog-actions>
</ng-template>
<div id="job-grade-group-component-upload-modal" class="hs-overlay hidden ti-modal">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out rounded-md">
<div class="ti-modal-header bg-primary !rounded-none !rounded-t-sm">
<h5 class="text-xxl font-bold text-white">
{{'ImportJobGradeGroup' | translate}}
</h5>
</div>
<div class="ti-modal-body max-h-full overflow-hidden ti-modal-content !rounded-t-none !rounded-b-sm">
<h1 class="mt-2" style="text-align: center;">{{'File' | translate}}</h1>
<div class="mt-2 p-2">
<div class="flex rounded-md">
<input #fileInput id="fileInput" type="file" (change)="onFileSelected($event)" hidden>
<input type="text" [value]="selectedFileName | translate" readonly (click)="fileInput.click()"
class="ti-form-input rounded-none ltr:rounded-l-md rtl:rounded-r-md focus:z-10 cursor-pointer">
<button type="button" (click)="fileInput.click()"
class="inline-flex flex-shrink-0 justify-center items-center h-[2.875rem] w-[2.875rem] ltr:rounded-r-md rtl:rounded-l-md border border-transparent font-semibold bg-secondary text-white hover:bg-secondary focus:z-10 focus:outline-none focus:ring-0 focus:ring-secondary transition-all text-sm">
<i class="ti ti-upload"></i>
</button>
</div>
<div class="flex justify-center mt-2rem ">
<h1 class="cursor-pointer justify-center -mb-px inline-flex items-center gap-2 font-weight-500 font-size-12px
text-center text-secondary border-secondary border-b-2 align-items-end" (click)="downloadFile()">
{{'DownloadSampleFile' | translate}}</h1>
</div>
<div class="flex justify-center mt-2rem mb-1rem space-x-4">
<button type="submit" class="ti-btn ti-btn-secondary"
data-hs-overlay="#job-grade-group-component-upload-modal"
[class.ti-btn-disabled]="!selectedFile" (click)="uploadFile()" [disabled]="!selectedFile"
[disabled]="!selectedFile">
{{'Upload' | translate}}
</button>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { MyPositionModel, PositionModel } from 'src/app/shared/model/position.model';
import { FileService } from 'src/app/shared/services/file.service';
import { PositionService } from 'src/app/shared/services/position.service';
import Swal from 'sweetalert2';
@Component({
selector: 'app-job-grade-group',
templateUrl: './job-grade-group.component.html',
styleUrls: ['./job-grade-group.component.scss']
})
export class JobGradeGroupComponent implements OnInit {
selectedFile: File | null = null;
selectedFileName: string = 'selectedFileName';
currentModal: 'add' | 'edit' | 'delete' = 'add'
position: { loading: boolean, select: PositionModel, dataList: PositionModel[] } = { loading: false, select: new MyPositionModel(), dataList: [] }
columns: ColumnModel[] = [{
field: "positionId",
headerText: "JobGradeGroupCode",
type: "string",
isPrimaryKey: true,
},
{
field: "tdesc",
headerText: "JobGradeGroupDescThai",
type: "string"
},
{
field: "edesc",
headerText: "JobGradeGroupDescEng",
type: "string"
}]
searchSettings = {
fields: ['positionId', 'tdesc', 'edesc'],
operator: 'contains',
ignoreCase: false
};
search = ''
selectedItems: { key: string, count: number, data: Map<string, boolean> } = { key: '', count: 0, data: new Map<string, boolean>() };
@ViewChild("jobGradeGroupModal") jobGradeGroupModal: any;
dialogRef: any
constructor(private positionService: PositionService,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private fileService: FileService,
private dialog: MatDialog
) { }
ngOnInit(): void {
this.getPositionList()
}
openDialog() {
this.dialogRef = this.dialog.open(this.jobGradeGroupModal, {
width: '500px',
})
}
closeDialog() {
this.dialogRef.close()
}
onFileSelected(event: any) {
this.selectedFile = event.target.files.length > 0 ? event.target.files[0] : null;
this.selectedFileName = this.selectedFile?.name || "selectedFileName"
}
uploadFile() {
// if (!this.selectedFile) {
// alert('กรุณาเลือกไฟล์ก่อนอัปโหลด')
// return
// }
// const formData = new FormData();
// formData.append('file', this.selectedFile);
// this.position.loading = true
// this.fileService.uploadExcel(formData, 'mposition').subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// })
}
downloadFile() {
// const fileName = 'IMPORT_MPOSITION.xlsx'
// this.fileService.downloadTemplate(fileName).subscribe({
// next: response => {
// const url = window.URL.createObjectURL(response);
// const a = document.createElement("a");
// a.href = url;
// a.download = fileName;
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
// window.URL.revokeObjectURL(url);
// }, error: error => {
// this.showAlert(error.message, 'error')
// }
// })
}
getPositionList() {
this.position.loading = true
this.selectedItems.data.clear()
this.positionService.getList().subscribe({
next: response => {
this.position.dataList = response.map(x => {
this.selectedItems.data.set(x.positionId, false)
return new MyPositionModel(x)
})
this.selectedItems.key = 'positionId'
this.selectedItems.count = 0
this.position.loading = false
this.cdr.detectChanges();
}, error: error => {
this.position.loading = false
console.error('Error fetching employee types:', error);
this.cdr.detectChanges()
}
})
}
selectPosition(position?: PositionModel) {
if (position) {
this.position.select = new MyPositionModel(position)
} else if (this.currentModal == 'add') {
this.position.select = new MyPositionModel()
} else if (this.currentModal == 'edit') {
this.position.select = new MyPositionModel({ positionId: this.position.select.positionId })
}
}
addPosition() {
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ยืนยัน',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// this.positionService.post(this.position.select).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// this.closeDialog()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// })
// }
// })
}
deletePosition() {
// if (this.numSelectItem() == 0) {
// this.showAlert('กรุณาเลือกข้อมูลที่จะลบ', 'error')
// return
// }
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการลบข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ลบข้อมูล',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// const selectedKeys = Array.from(this.selectedItems.data.keys());
// const body = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).map(x => new MyPositionModel(x))
// this.positionService.delete(body).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// })
// }
// })
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
icon: type,
title: 'แจ้งเตือน',
text: text,
showCancelButton: false,
confirmButtonText: 'ยืนยัน',
})
}
checkPrimary() {
return this.position.dataList.find(x => x.positionId == this.position.select.positionId)
}
numSelectItem() {
const selectedKeys = Array.from(this.selectedItems.data.keys());
const num = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).length
return num
}
onSelectItemChange(arg: any) {
this.selectedItems = arg
}
}
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="search">
<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=" h-45px ti-btn ti-btn bg-pink-500/10 text-pink-500 hover:text-white hover:bg-pink-500 ring-offset-white focus:ring-pink-500 dark:focus:ring-offset-white/10 h-10 m-0 shadow-md"
data-hs-overlay="#job-grade-component-upload-modal"
(click)="fileInput.value = '';selectedFile=null;selectedFileName = 'กรุณาเลือกไฟล์'">
<i class="ti ti-file-plus"></i>
{{'Import' | translate}}
</button>
</div>
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-secondary h-45px m-0 shadow-md"
(click)="currentModal='add';selectPosition();openDialog()">
<i class="ri-add-line"></i>
{{'Add' | translate}}
</button>
</div>
<div class="px-1">
<button href="javascript:void(0);" class="ti-btn ti-btn-soft-danger h-45px m-0 shadow-md"
(click)="currentModal='delete';selectPosition();deletePosition()">
<i class="ri-delete-bin-6-line"></i>
{{'Delete' | translate}}
</button>
</div>
</div>
</div>
<div class="page px-rem">
<app-datagrid-syncfution [searchSettings]="searchSettings" [searchText]="search" [dataSource]="position.dataList"
[columns]="columns" [selectedItems]="selectedItems"
(sendSelectData)="currentModal='edit';selectPosition($event);openDialog()"
(sendSelectedItems)="onSelectItemChange($event)">
</app-datagrid-syncfution>
</div>
<ng-template #jobGradeModal let-modal>
<h3 mat-dialog-title>
{{(currentModal=='add'?'AddJobGrade':'EditJobGrade') | translate}}
</h3>
<div class="w-full flex justify-end mb-1rem">
<div class="absolute flex">
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md" (click)="selectPosition()">
<i class="ti ti-eraser text-base"></i>
{{'Clear' |translate}}
</button>
</div>
</div>
</div>
<mat-dialog-content>
<label for="input-label" class="ti-form-label mt-2rem">
{{'JobGradeCode' | translate}}
<span class="text-danger">
*
<ng-container *ngIf="currentModal=='add'&&checkPrimary()">
{{'DuplicateJobGradeCode' | translate}}
</ng-container>
</span></label>
<input type="text" id="input-label" class="ti-form-input w-1/2 "
[ngClass]="{'bg-input-readonly':currentModal=='edit'}" [readonly]="currentModal=='edit'"
[(ngModel)]="position.select.positionId">
<label for="detail_th" class="ti-form-label mt-2rem">{{'JobGradeGroupCode' | translate}}<span
class="text-danger">*</span></label>
<div class="relative flex rounded-md w-1/2">
<input type="text" class="ti-form-input rounded-sm ltr:rounded-r-sm rtl:rounded-l-sm focus:z-10 " readonly
style="padding-right: 3.5rem;" (click)="openJobGradeGroupDialog()">
<div class="absolute inset-y-0 ltr:right-0 rtl:left-0 flex items-center z-20 ltr:pr-4 rtl:pl-4 space-x-2">
<button type="button" class="flex items-center text-red-500">
<i class="ti ti-circle-x cursor-pointer"></i>
</button>
<button type="button" class="flex items-center text-gray-500 dark:text-white/70"
(click)="openJobGradeGroupDialog()">
<i class="ri-search-line cursor-pointer text-gray"></i>
</button>
</div>
</div>
<label for="detail_th" class="ti-form-label mt-2rem">{{'JobGradeDescThai' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_th" class="ti-form-input h-16" [(ngModel)]="position.select.tdesc">
<label for="detail_eng" class="ti-form-label mt-2rem">{{'JobGradeDescEng' | translate}}<span
class="text-danger">*</span></label>
<input type="text" id="detail_eng" class="ti-form-input h-16" [(ngModel)]="position.select.edesc">
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
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">
{{'Back' | translate}}
</button>
<button type="button" class="ti-btn ti-btn-success" mat-button (click)="addPosition()"
[class.ti-btn-disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())"
[disabled]="!position.select.positionId||!position.select.tdesc||(currentModal=='add'&&checkPrimary())">
{{'SaveData' | translate}}
</button>
</mat-dialog-actions>
</ng-template>
<div id="job-grade-component-upload-modal" class="hs-overlay hidden ti-modal">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out rounded-md">
<div class="ti-modal-header bg-primary !rounded-none !rounded-t-sm">
<h5 class="text-xxl font-bold text-white">
{{'ImportJobGrade' | translate}}
</h5>
</div>
<div class="ti-modal-body max-h-full overflow-hidden ti-modal-content !rounded-t-none !rounded-b-sm">
<h1 class="mt-2" style="text-align: center;">{{'File' | translate}}</h1>
<div class="mt-2 p-2">
<div class="flex rounded-md">
<input #fileInput id="fileInput" type="file" (change)="onFileSelected($event)" hidden>
<input type="text" [value]="selectedFileName | translate" readonly (click)="fileInput.click()"
class="ti-form-input rounded-none ltr:rounded-l-md rtl:rounded-r-md focus:z-10 cursor-pointer">
<button type="button" (click)="fileInput.click()"
class="inline-flex flex-shrink-0 justify-center items-center h-[2.875rem] w-[2.875rem] ltr:rounded-r-md rtl:rounded-l-md border border-transparent font-semibold bg-secondary text-white hover:bg-secondary focus:z-10 focus:outline-none focus:ring-0 focus:ring-secondary transition-all text-sm">
<i class="ti ti-upload"></i>
</button>
</div>
<div class="flex justify-center mt-2rem ">
<h1 class="cursor-pointer justify-center -mb-px inline-flex items-center gap-2 font-weight-500 font-size-12px
text-center text-secondary border-secondary border-b-2 align-items-end" (click)="downloadFile()">
{{'DownloadSampleFile' | translate}}</h1>
</div>
<div class="flex justify-center mt-2rem mb-1rem space-x-4">
<button type="submit" class="ti-btn ti-btn-secondary"
data-hs-overlay="#job-grade-component-upload-modal" [class.ti-btn-disabled]="!selectedFile"
(click)="uploadFile()" [disabled]="!selectedFile" [disabled]="!selectedFile">
{{'Upload' | translate}}
</button>
</div>
</div>
</div>
</div>
</div>
<ng-template #jobGradeGroupModal let-modal>
<h3 mat-dialog-title>
{{'JobGradeGroup' | translate}}
</h3>
<mat-dialog-content>
<div class="flex justify-end pb-1rem">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate">
<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>
<div class="overflow-auto border">
<table class="ti-custom-table ti-custom-table-head ti-custom-table-hover">
<thead>
<tr>
<ng-container
*ngFor="let item of ['No.','JobGradeGroupCode','JobGradeGroupDescThai','JobGradeGroupDescEng']; let f = first; let l = last">
<th scope="col" class="relative px-10px py-10px bg-soft-secondary text-primary"
[class.!text-center]="f">
<span class="text-sm">{{ item | translate}}</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="false">
<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="!false&&!position.dataList.length">
<tr>
<td class="text-center" colspan="100%">
{{'NoInformation' | translate}}
</td>
</tr>
</tbody>
<tbody *ngIf="!false&&position.dataList.length">
<!-- <tr *ngFor="let item of position.dataList | slice:((currentPage-1) * pageSize) : (((currentPage-1) * pageSize) + pageSize);let i = index"
class="cursor-pointer" (click)="selectBu1(item);closeBu1Dialog()">
<td class="flex justify-center">
{{((currentPage-1) * pageSize)+(i+1)}}
</td>
<td>{{item.bu1id}}</td>
<td>{{item.tdesc}}</td>
<td>{{item.edesc}}</td>
</tr> -->
</tbody>
</table>
</div>
<!-- <app-pagination [totalItems]="position.dataList.length" [pageSize]="pageSize" (pageChange)="currentPage = $event"
(pageSizeChange)="pageSize = $event;currentPage = 1"></app-pagination> -->
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
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">
{{'Back' | translate}}
</button>
</mat-dialog-actions>
</ng-template>
\ No newline at end of file
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { MyPositionModel, PositionModel } from 'src/app/shared/model/position.model';
import { FileService } from 'src/app/shared/services/file.service';
import { PositionService } from 'src/app/shared/services/position.service';
import Swal from 'sweetalert2';
@Component({
selector: 'app-job-grade',
templateUrl: './job-grade.component.html',
styleUrls: ['./job-grade.component.scss']
})
export class JobGradeComponent implements OnInit {
selectedFile: File | null = null;
selectedFileName: string = 'selectedFileName';
currentModal: 'add' | 'edit' | 'delete' = 'add'
position: { loading: boolean, select: PositionModel, dataList: PositionModel[] } = { loading: false, select: new MyPositionModel(), dataList: [] }
columns: ColumnModel[] = [{
field: "positionId",
headerText: "JobGradeCode",
type: "string",
isPrimaryKey: true,
},
{
field: "tdesc",
headerText: "JobGradeDescThai",
type: "string"
},
{
field: "edesc",
headerText: "JobGradeDescEng",
type: "string"
}]
searchSettings = {
fields: ['positionId', 'tdesc', 'edesc'],
operator: 'contains',
ignoreCase: false
};
search = ''
selectedItems: { key: string, count: number, data: Map<string, boolean> } = { key: '', count: 0, data: new Map<string, boolean>() };
@ViewChild("jobGradeModal") jobGradeModal: any;
dialogRef: any
@ViewChild('jobGradeGroupModal') jobGradeGroupModal: any
jobGradeGroupDialogRef: any
constructor(private positionService: PositionService,
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private fileService: FileService,
private dialog: MatDialog
) { }
ngOnInit(): void {
this.getPositionList()
}
openDialog() {
this.dialogRef = this.dialog.open(this.jobGradeModal, {
width: '500px',
})
}
closeDialog() {
this.dialogRef.close()
}
onFileSelected(event: any) {
this.selectedFile = event.target.files.length > 0 ? event.target.files[0] : null;
this.selectedFileName = this.selectedFile?.name || "selectedFileName"
}
uploadFile() {
// if (!this.selectedFile) {
// alert('กรุณาเลือกไฟล์ก่อนอัปโหลด')
// return
// }
// const formData = new FormData();
// formData.append('file', this.selectedFile);
// this.position.loading = true
// this.fileService.uploadExcel(formData, 'mposition').subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges();
// }
// })
}
downloadFile() {
// const fileName = 'IMPORT_MPOSITION.xlsx'
// this.fileService.downloadTemplate(fileName).subscribe({
// next: response => {
// const url = window.URL.createObjectURL(response);
// const a = document.createElement("a");
// a.href = url;
// a.download = fileName;
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
// window.URL.revokeObjectURL(url);
// }, error: error => {
// this.showAlert(error.message, 'error')
// }
// })
}
getPositionList() {
this.position.loading = true
this.selectedItems.data.clear()
this.positionService.getList().subscribe({
next: response => {
this.position.dataList = response.map(x => {
this.selectedItems.data.set(x.positionId, false)
return new MyPositionModel(x)
})
this.selectedItems.key = 'positionId'
this.selectedItems.count = 0
this.position.loading = false
this.cdr.detectChanges();
}, error: error => {
this.position.loading = false
console.error('Error fetching employee types:', error);
this.cdr.detectChanges()
}
})
}
selectPosition(position?: PositionModel) {
if (position) {
this.position.select = new MyPositionModel(position)
} else if (this.currentModal == 'add') {
this.position.select = new MyPositionModel()
} else if (this.currentModal == 'edit') {
this.position.select = new MyPositionModel({ positionId: this.position.select.positionId })
}
}
addPosition() {
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ยืนยัน',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// this.positionService.post(this.position.select).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// this.closeDialog()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// this.closeDialog()
// }
// })
// }
// })
}
deletePosition() {
// if (this.numSelectItem() == 0) {
// this.showAlert('กรุณาเลือกข้อมูลที่จะลบ', 'error')
// return
// }
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการลบข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'ลบข้อมูล',
// }).then((result) => {
// if (result.isConfirmed) {
// this.position.loading = true
// const selectedKeys = Array.from(this.selectedItems.data.keys());
// const body = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).map(x => new MyPositionModel(x))
// this.positionService.delete(body).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success')
// this.getPositionList()
// } else {
// this.showAlert(response.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.position.loading = false
// this.cdr.detectChanges()
// }
// })
// }
// })
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
icon: type,
title: 'แจ้งเตือน',
text: text,
showCancelButton: false,
confirmButtonText: 'ยืนยัน',
})
}
checkPrimary() {
return this.position.dataList.find(x => x.positionId == this.position.select.positionId)
}
numSelectItem() {
const selectedKeys = Array.from(this.selectedItems.data.keys());
const num = this.position.dataList.filter(x => selectedKeys.includes(x.positionId) && this.selectedItems.data.get(x.positionId)).length
return num
}
onSelectItemChange(arg: any) {
this.selectedItems = arg
}
openJobGradeGroupDialog() {
this.jobGradeGroupDialogRef = this.dialog.open(this.jobGradeGroupModal, {
width: '800px',
})
}
}
......@@ -211,6 +211,9 @@ import { TranslateModule } from '@ngx-translate/core';
import { ReportCompetencySummaryComponent } from '../report-component/report-com/report-competency-summary/report-competency-summary.component';
import { JobDescriptionEmpComponent } from '../job-description-emp/job-description-emp.component';
import { CompetencyMappingComponent } from '../competency-mapping/competency-mapping.component';
import { JobFamilyComponent } from '../company-components/job-description/job-family/job-family.component';
import { JobGradeComponent } from '../company-components/job-description/job-grade/job-grade.component';
import { JobGradeGroupComponent } from '../company-components/job-description/job-grade-group/job-grade-group.component';
export const MY_DATE_FORMATS = {
parse: {
......@@ -361,7 +364,10 @@ export class CustomDateAdapter extends NativeDateAdapter {
SettingIndividualKpiSupervisorComponent,
JobDescriptionEmpComponent,
MoneyInputDirective,
CompetencyMappingComponent
CompetencyMappingComponent,
JobFamilyComponent,
JobGradeComponent,
JobGradeGroupComponent
], imports: [
TranslateModule,
CommonModule,
......
......@@ -20,9 +20,9 @@
</ng-container>
<div class="flex justify-around !items-center border bg-white p-2 text-right"
style="border-radius:20px;width: 100px;margin-left: auto;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));">
<i title="แสดงทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-down"
<i [title]="'ShowAll' | translate" class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:5px;font-size:27px" (click)="allBiOpen(true)"></i>
<i title="ปิดทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-up"
<i [title]="'HideAll' | translate" class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:5px;font-size:27px" (click)="allBiOpen(false)"></i>
</div>
</div>
......@@ -56,7 +56,7 @@
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">Behavior Indicator (BI)</th>
<th scope="col">เครื่องมือ
<th scope="col">{{'Tools' | translate}}
<div class="hs-tooltip ti-main-tooltip [--trigger:hover]">
<a class="hs-tooltip-toggle ti-main-tooltip-toggle" href="javascript:;">
<i class="ti ti-help-circle"></i>
......@@ -75,7 +75,7 @@
</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col" style="width:500px">
คะแนน
{{'TargetDegree' | translate}}
<div class="hs-tooltip ti-main-tooltip [--trigger:hover]">
<a class="hs-tooltip-toggle ti-main-tooltip-toggle" href="javascript:;">
<i class="ti ti-help-circle"></i>
......@@ -111,7 +111,7 @@
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col" style="width:325px">
คะแนน
{{'TargetDegree' | translate}}
<div class="hs-tooltip ti-main-tooltip [--trigger:hover]">
<a class="hs-tooltip-toggle ti-main-tooltip-toggle" href="javascript:;">
<i class="ti ti-help-circle"></i>
......@@ -216,24 +216,21 @@
style=" border-radius:20px"
(click)="scrollToMenu(appraisalCompentencyFilter().length);allBiOpen(!biOpen.get('สรุป'),'สรุป')">
<span style="padding-left:50px">
สรุป
</span>
&nbsp;
<span>
คะแนนประเมิน
{{'Summary' | translate}}
</span>
</button>
<ng-container *ngIf="biOpen.get('สรุป')">
<div class="pb-1rem px-2rem">
<div class="py-2 grid grid-cols-11">
<div class="col-span-8" style="font-size: 1rem;font-weight: 500; border-radius:20px">ระดับความสามารถ (Target
Degree)</div>
<div class="col-span-8" style="font-size: 1rem;font-weight: 500; border-radius:20px">
{{'TargetDegree' | translate}}
</div>
<div class="col-span-3 grid grid-cols-5">
<div class="col-span-1 text-center" *ngFor="let item of [5,4,3,2,1]">{{item}}</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">รวมจำนวนเครื่องหมายแต่ละช่อง (1)</div>
<div class="col-span-8">{{'TallyOfMarksPerRatingLevel1' | translate}}</div>
<div class="col-span-3 grid grid-cols-5">
<!-- <div class="col-span-1 text-center">
{{appraisalCompentencyList[appraisalCompentencyIndex].masfromEvaluationAssessment1List[0].weightScore7Boss}}
......@@ -259,7 +256,7 @@
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">ตัวคูณคะแนนในแต่ละช่อง (2)</div>
<div class="col-span-8">{{'ScoreMultiplierPerLevel2' | translate}}</div>
<div class="col-span-3 grid grid-cols-5">
<!-- <div class="col-span-1 text-center">{{setting.data.settingScore7}}</div>
<div class="col-span-1 text-center">{{setting.data.settingScore6}}</div> -->
......@@ -271,14 +268,14 @@
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">ถ่วงน้ำหนักผลรวม 1X2</div>
<div class="col-span-8">{{'WeightedScore1x2' | translate}}</div>
<div class="col-span-3 grid grid-cols-5">
<div class="col-span-1 text-center" *ngFor="let item of [5,4,3,2,1]">{{calWeightScoreBoss(item)}}
</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8 font-semibold" style=" border-radius:20px">คะแนนรวมหลังถ่วงน้ำหนัก
<div class="col-span-8 font-semibold" style=" border-radius:20px">{{'TotalWeightedScore' | translate}}
</div>
<div class="col-span-3 grid grid-cols-1">
<div class="col-span-5 text-center text-indigo-600 font-semibold">
......@@ -287,7 +284,7 @@
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8 font-semibold" style=" border-radius:20px">คะแนนเฉลี่ยคิดเป็น
<div class="col-span-8 font-semibold" style=" border-radius:20px">{{'FinalAverageScore' | translate}}
</div>
<div class="col-span-3 grid grid-cols-1">
<div class="col-span-5 text-center text-indigo-600 font-semibold">
......@@ -302,17 +299,17 @@
<thead class="height-50px">
<tr class="font-size-12px">
<ng-container
*ngFor="let item of ['เกณฑ์การให้คะแนนการประเมิน','ผลประเมิน (A)','สรุปผล Gap'];let f = first ;let l = last">
*ngFor="let item of ['CompetencyRatingScale','AssessmentResultA','GapResultEva'];let f = first ;let l = last">
<th scope="col" [attr.rowspan]="f?'1':'2'" [attr.colspan]="f?'2':'1'"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
<span class="font-size-12px font-weight-700 ">{{ item }}</span>
<span class="font-size-12px font-weight-700 ">{{ item | translate}}</span>
</th>
</ng-container>
</tr>
<tr class="font-size-12px">
<ng-container *ngFor="let item of ['เกณฑ์การให้คะแนน','เงื่อนไข']">
<ng-container *ngFor="let item of ['RatingCriteria','Conditions']">
<th scope="col" class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
{{item}}
{{ item | translate}}
</th>
</ng-container>
</tr>
......@@ -322,12 +319,12 @@
(mouseleave)="hoveredCode2 = null" [ngClass]="{ 'table-hover2': 'true' === hoveredCode2 }">
<td class="align-start" rowspan="2">
<div *ngFor="let item2 of item.score">
<span>{{item2}} </span><br>
<span>{{item2 | translate}} </span><br>
</div>
</td>
<td class="align-start" rowspan="2">
<div *ngFor="let item2 of item.condition">
<span>{{item2}} </span><br>
<span>{{item2 | translate}} </span><br>
</div>
</td>
<td class="align-start text-center text-indigo-600 font-semibold">
......
......@@ -52,8 +52,8 @@ export class PmsCompetencyComponent {
score: string[],
condition: string[]
}[] = [{
score: ["หากได้คะแนน 90 - 100% ถือว่า Gap +1", "หากได้คะแนน 80 - 89% ถือว่า ไม่มี Gap", "หากได้คะแนน 60 - 79% ถือว่า Gap - 1", "หากได้คะแนน 40 - 59% ถือว่า Gap -2", "หากได้คะแนน 0 - 39% ถือว่า Gap - 3"],
condition: ["1.หากได้คะแนนสูงกว่า 80% แต่มี 3 2 หรือ 1 ด้วย ถือว่า Gap -1", "2.หากได้คะแนนต่ำกว่า 80% แต่มี 4 และ 5 ให้คิด Gap ตาม %", "3.คะแนนต่ำกว่า 80% แต่มี 2 และ 1 ให้คิด Gap ตาม %"],
score: ["IfScore90to100", "IfScore80to89", "IfScore60to79", "IfScore40to59", "IfScore0to39"],
condition: ["Condition1", "Condition2", "Condition3"],
}]
scoreDescriptions = [
'',
......
......@@ -11,11 +11,11 @@
class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 shadow-md hover:shadow-xl transition text-blue-500 bg-white"
(click)="returnPath()">
<i class="ti ti-chevron-left"></i>
ย้อนกลับ
{{'Back' | translate}}
</button>
</div>
<span class="whitespace-nowrap relative" [ngStyle]="{'left': evaluationForm=='sup' ? '105px':'0px'}">
ประเมินผลประจำปี {{currentDate.getFullYear()}}
{{'AnnualEvaluation' | translate}} {{currentDate.getFullYear()}}
</span>
</div>
</div>
......@@ -28,14 +28,14 @@
<span class="cursor-pointer"
[ngClass]="{'text-secondary border-secondary border-b':compentency.data?.tdesc==item.tdesc,'hover:text-gray-900':!(compentency.data?.tdesc==item.tdesc)}"
(click)="compentency.data?.tdesc !== item.tdesc && changeForm(item)">
{{item.tdesc}}
{{translateText(item.tdesc,item.edesc)}}
</span>
</div>
</ng-container>
</div>
<div class="w-1/2">
<div class="font-size-18px font-weight-700 text-primary text-right">
สถานะผู้ประเมิน&nbsp;:&nbsp;{{currentStepTextShow()}}
{{'EvaluatorStatus' | translate}}&nbsp;:&nbsp;{{currentStepTextShow() | translate}}
</div>
</div>
</div>
......@@ -68,24 +68,25 @@
</div>
<div class="w-full">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('ข้อมูลพนักงาน')">
<div class="box-header" [class.border-none]="menuClose.get('EmployeeInformation')">
<div class="flex justify-between">
<h5 class="box-title align-center">ข้อมูลพนักงาน</h5>
<i *ngIf="menuClose.get('ข้อมูลพนักงาน')" title="แสดง"
<h5 class="box-title align-center">{{'EmployeeInformation' | translate}}</h5>
<i *ngIf="menuClose.get('EmployeeInformation')" title="แสดง"
class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('ข้อมูลพนักงาน',false)"></i>
<i *ngIf="!menuClose.get('ข้อมูลพนักงาน')" title="ปิด"
(click)="menuClose.set('EmployeeInformation',false)"></i>
<i *ngIf="!menuClose.get('EmployeeInformation')" title="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('ข้อมูลพนักงาน',true)"></i>
(click)="menuClose.set('EmployeeInformation',true)"></i>
</div>
</div>
<div class="box-body py-2" [class.hidden]="menuClose.get('ข้อมูลพนักงาน')">
<div class="box-body py-2" [class.hidden]="menuClose.get('EmployeeInformation')">
<table class="ti-custom-table border-0 ellipsis-text">
<tbody>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">รหัสพนักงาน
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">
{{'EmployeeCode' | translate}}
</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
......@@ -93,43 +94,49 @@
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">ชื่อ - สกุล
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">
{{'NameSurname' | translate}}
</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.thFullName}}
{{translateText(evaluatee.data.thFullName,evaluatee.data.engFullName)}}
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">ตำเเหน่ง</td>
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">{{'Position'
| translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.position.tdesc}}
{{translateText(evaluatee.data.position.tdesc,evaluatee.data.position.edesc)}}
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">ฝ่าย</td>
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">{{'Division'
| translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu1.tdesc}}
{{translateText(evaluatee.data.bu1.tdesc,evaluatee.data.bu1.edesc)}}
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">แผนก</td>
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">
{{'Department' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu2.tdesc}}
{{translateText(evaluatee.data.bu2.tdesc,evaluatee.data.bu2.edesc)}}
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">ระดับ</td>
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">{{'Level' |
translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.pl.tdesc}}
{{translateText(evaluatee.data.pl.tdesc,evaluatee.data.pl.edesc)}}
</td>
</tr>
<tr class="!border-0">
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">E-mail</td>
<td class="!p-2 align-start" style="font-size: 1rem;font-weight: 500;color:black;">{{'Email' |
translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.email}}
......@@ -140,22 +147,22 @@
</div>
</div>
</div>
<div class="w-full" *ngIf="currentTap=='แบบประเมินสมรรถนะ'&&(evaluaterId!=evaluateeId||complete)">
<div class="w-full" *ngIf="currentTap=='CompetencyEva'&&(evaluaterId!=evaluateeId||complete)">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')">
<div class="box-header" [class.border-none]="menuClose.get('WeightedScoreByTargetDegree')">
<div class="flex justify-between">
<h5 class="box-title align-center">ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ</h5>
<i *ngIf="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')" title="แสดง"
<h5 class="box-title align-center">{{'WeightedScoreByTargetDegree' | translate}}</h5>
<i *ngIf="menuClose.get('WeightedScoreByTargetDegree')" title="แสดง"
class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px;height:33px"
(click)="menuClose.set('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ',false)"></i>
<i *ngIf="!menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')" title="ปิด"
(click)="menuClose.set('WeightedScoreByTargetDegree',false)"></i>
<i *ngIf="!menuClose.get('WeightedScoreByTargetDegree')" title="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px;height:33px"
(click)="menuClose.set('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ',true)"></i>
(click)="menuClose.set('WeightedScoreByTargetDegree',true)"></i>
</div>
</div>
<div class="box-body py-2" [class.hidden]="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')">
<div class="box-body py-2" [class.hidden]="menuClose.get('WeightedScoreByTargetDegree')">
<div class="w-full flex flex-col gap-2" *ngIf="compentency.data">
<div class="w-full flex flex-col gap-2 mt-2">
<div class="w-full flex flex-row gap-2">
......@@ -183,7 +190,7 @@
</div>
</div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center">
คะแนนเฉลี่ย
{{'AvgScore' | translate}}
</div>
<div class="flex-1 flex justify-center items-center">
<div
......@@ -193,7 +200,7 @@
</div>
</div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center">
ผล Gap
{{'Gap' | translate}}
</div>
<div class="flex-1 flex justify-center items-center">
<div
......@@ -208,13 +215,13 @@
</div>
</div>
</div>
<div class="w-full" *ngIf="currentTap=='แบบประเมินสมรรถนะ'&&false">
<div class="w-full" *ngIf="currentTap=='CompetencyEva'&&false">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header"
[class.border-none]="menuClose.get('ค่าถ่วงน้ำหนักตนเองของความสามารถในแต่ละระดับ')">
<div class="flex justify-between">
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<h5 class="box-title align-center">ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ</h5>
<h5 class="box-title align-center">{{'WeightedScoreByTargetDegree' | translate}}</h5>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<h5 class="box-title align-center">ค่าถ่วงน้ำหนักตนเองของความสามารถในแต่ละระดับ</h5>
......@@ -258,7 +265,7 @@
</div>
</div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center">
คะแนนเฉลี่ย
{{'AvgScore' | translate}}
</div>
<div class="flex-1 flex justify-center items-center">
<div
......@@ -268,7 +275,7 @@
</div>
</div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center">
ผล Gap
{{'Gap' | translate}}
</div>
<div class="flex-1 flex justify-center items-center">
<div
......@@ -284,22 +291,22 @@
</div>
</div>
<div class="w-full"
*ngIf="findMenu('ประเมินผลการปฏิบัติงาน')&&(currentTap=='ประเมินผลการปฏิบัติงาน'||currentTap=='สรุปคะแนนและข้อเสนอแนะ')&&(evaluaterId!=evaluateeId||complete)">
*ngIf="findMenu('Performance')&&(currentTap=='Performance'||currentTap=='SummaryAndFeedback')&&(evaluaterId!=evaluateeId||complete)">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('สรุปผลประเมิน')">
<div class="box-header" [class.border-none]="menuClose.get('EvaluationSummary')">
<div class="flex justify-between">
<h5 class="box-title align-center">สรุปผลประเมิน</h5>
<i *ngIf="menuClose.get('สรุปผลประเมิน')" title="แสดง"
<h5 class="box-title align-center">{{'EvaluationSummary' | translate}}</h5>
<i *ngIf="menuClose.get('EvaluationSummary')" title="แสดง"
class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สรุปผลประเมิน',false)"></i>
<i *ngIf="!menuClose.get('สรุปผลประเมิน')" title="ปิด"
(click)="menuClose.set('EvaluationSummary',false)"></i>
<i *ngIf="!menuClose.get('EvaluationSummary')" title="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สรุปผลประเมิน',true)"></i>
(click)="menuClose.set('EvaluationSummary',true)"></i>
</div>
</div>
<div class="box-body py-2 flex flex-col gap-6 " [class.hidden]="menuClose.get('สรุปผลประเมิน')">
<div class="box-body py-2 flex flex-col gap-6 " [class.hidden]="menuClose.get('EvaluationSummary')">
<div class='flex-1 flex flex-row gap-2'>
<div class="flex-1 flex flex-col gap-2">
<ng-container *ngFor="let item of kpiScorePartBoss; let i=index">
......@@ -321,7 +328,7 @@
<ng-container *ngIf="i>=4 && i< kpiScorePartBoss.length-2">
<div class="flex flex-row">
<div class="flex-1" style="align-content:center">
{{item.text}}
{{item.text | translate}}
</div>
<div class="flex-1 border border-secondary text-center align-center"
style="border-radius:10px;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));height: 30px;">
......@@ -338,7 +345,7 @@
<div class="flex-1 flex flex-col gap-2">
<div class="flex flex-row">
<div class="flex-1 font-size-18px font-weight-700" style="align-content:center">
{{item.text}}
{{item.text | translate}}
</div>
<div
class="flex-1 border border-secondary text-center align-center text-indigo-600 font-semibold"
......@@ -354,12 +361,12 @@
</div>
</div>
<div class="w-full"
*ngIf="findMenu('ประเมินผลการปฏิบัติงาน')&&(currentTap=='ประเมินผลการปฏิบัติงาน'||currentTap=='สรุปคะแนนและข้อเสนอแนะ')">
*ngIf="findMenu('Performance')&&(currentTap=='Performance'||currentTap=='SummaryAndFeedback')">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('สรุปผลประเมินตนเอง')">
<div class="flex justify-between">
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<h5 class="box-title align-center">สรุปผลประเมิน</h5>
<h5 class="box-title align-center">{{'EvaluationSummary' | translate}}</h5>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<h5 class="box-title align-center">สรุปผลประเมินตนเอง</h5>
......@@ -396,7 +403,7 @@
<ng-container *ngIf="i>=4 && i< kpiScorePart.length-2">
<div class="flex flex-row">
<div class="flex-1" style="align-content:center">
{{item.text}}
{{item.text | translate}}
</div>
<div class="flex-1 border border-secondary text-center align-center"
style="border-radius:10px;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));height: 30px;">
......@@ -413,7 +420,7 @@
<div class="flex-1 flex flex-col gap-2">
<div class="flex flex-row">
<div class="flex-1 font-size-18px font-weight-700" style="align-content:center">
{{item.text}}
{{item.text | translate}}
</div>
<div
class="flex-1 border border-secondary text-center align-center text-indigo-600 font-semibold"
......@@ -430,20 +437,20 @@
</div>
<div class="w-full" *ngIf="compentency.data">
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('สถานะการประเมิน')">
<div class="box-header" [class.border-none]="menuClose.get('StatusEva')">
<div class="flex justify-between">
<h5 class="box-title align-center">สถานะการประเมิน</h5>
<i *ngIf="menuClose.get('สถานะการประเมิน')" title="แสดง"
<h5 class="box-title align-center">{{'StatusEva' | translate}}</h5>
<i *ngIf="menuClose.get('StatusEva')" title="แสดง"
class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สถานะการประเมิน',false)"></i>
<i *ngIf="!menuClose.get('สถานะการประเมิน')" title="ปิด"
(click)="menuClose.set('StatusEva',false)"></i>
<i *ngIf="!menuClose.get('StatusEva')" title="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สถานะการประเมิน',true)"></i>
(click)="menuClose.set('StatusEva',true)"></i>
</div>
</div>
<div class="box-body space-y-4 text-center" [class.hidden]="menuClose.get('สถานะการประเมิน')">
<div class="box-body space-y-4 text-center" [class.hidden]="menuClose.get('StatusEva')">
<ng-container
*ngFor="let apsEmp of ['apsassessy','apsapprove1','apsapprove2','apsapprove3','apsapprove4','apsapprove5']; let i=index ; let f=first">
<div class="flex flex-row" *ngIf="returnField(compentency.data,apsEmp+'.thFullName')">
......@@ -469,14 +476,14 @@
</p>
<p class="font-medium ">
<ng-container *ngIf="i==0">
ผู้รับการประเมิน
{{'Appraisee' | translate}}
</ng-container>
<ng-container *ngIf="i>0">
ผู้อนุมัติลำดับที่ {{i}}
{{'Approver'+i+'Eva' | translate}}
</ng-container>
</p>
<p class="font-medium ">
{{returnField(compentency.data,apsEmp+'.thFullName')}}
{{translateText(returnField(compentency.data,apsEmp+'.thFullName'),returnField(compentency.data,apsEmp+'.enFullName'))}}
</p>
</h3>
</div>
......@@ -491,7 +498,7 @@
<div class="box shadow-md hover:shadow-xl transition m-0" style="border-radius:20px">
<div class="box-header" [class.border-none]="menuClose.get('Timeline')">
<div class="flex justify-between">
<h5 class="box-title align-center">Timeline</h5>
<h5 class="box-title align-center">{{'Timeline' | translate}}</h5>
<i *ngIf="menuClose.get('Timeline')" title="แสดง"
class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px"
......@@ -521,7 +528,7 @@
<div class="w-full">
<h3 class="text-start my-auto text-gray-500 " style="line-height: 1.5">
<p style="font-size: 1rem;font-weight: 500;color:black;white-space: nowrap;">
{{statusCompetencyText(item.statusType)}}
{{statusCompetencyText(item.statusType) | translate}}
</p>
<p class="font-medium">
{{item.thFullName}}
......@@ -564,13 +571,13 @@
<ng-container *ngFor="let item of menuList">
<button type="button" class="flex-1 flex flex-row border bg-white p-2 justify-center"
style="border-radius:20px"
(click)="currentTap=item.text;(currentTap=='ประเมินผลการปฏิบัติงาน'||currentTap=='สรุปคะแนนและข้อเสนอแนะ'?currentPart='':null);"
(click)="currentTap=item.text;(currentTap=='Performance'||currentTap=='SummaryAndFeedback'?currentPart='':null);"
[ngClass]="{'!bg-primary text-white':currentTap==item.text}"
[routerLink]="evaluationForm=='sup'?null:'../'+item.link">
<span class="overflow-hidden text-ellipsis whitespace-nowrap align-center">
{{item.text}}
{{item.text | translate}}
</span>
<ng-container *ngIf="item.text=='แบบประเมินสมรรถนะ'">
<ng-container *ngIf="item.text=='CompetencyEva'">
&nbsp;
<span class="flex align-center justify-content-center rounded-circle text-white"
[class.bg-danger]="compentencyFormRemain" [class.bg-success]="!compentencyFormRemain">
......@@ -580,7 +587,7 @@
<i *ngIf="!compentencyFormRemain" class="ti ti-check"></i>
</span>
</ng-container>
<ng-container *ngIf="item.text=='ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="item.text=='Performance'">
&nbsp;
<span class="flex align-items-center justify-content-center rounded-circle text-white"
[class.bg-danger]="kpiFormRemain" [class.bg-success]="!kpiFormRemain">
......@@ -596,7 +603,7 @@
</div>
<div #scrollContainer class="box-body pt-0" *ngIf="compentency.data&&evaluaterId&&evaluateeId"
style="overflow-y: auto; height: calc(100vh - 253px)">
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='ข้อมูลการประเมิน'">
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='EvaluationInfo'">
<app-pms-information [statusType]="compentency.data.statusType" [canSave]="canSave"
[appraisalPms]="compentency.data.pms" [appraisalCompentencyList]="compentency.data.competency"
[inforGapBoss]="inforGapBoss" [inforWeightBoss]="inforWeightBoss" [inforGap]="inforGap"
......@@ -608,7 +615,7 @@
(sendCurrentPart)="currentPart=$event" [evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId"
[currentStep]="compentency.data.currentStep" [complete]="complete"></app-pms-information>
</div>
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='แบบประเมินสมรรถนะ'">
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='CompetencyEva'">
<app-pms-competency [currentTap]="currentTap" [canSave]="canSave" [fCurrentPart]="currentPart"
[appraisalCompentencyList]="compentency.data.competency" [evaluaterId]="evaluaterId"
[evaluateeId]="evaluateeId" [canEdit]="canEdit" [currentStep]="compentency.data.currentStep"
......@@ -626,7 +633,7 @@
[complete]="complete"></app-pms-competency>
</div>
<div class="min-height: calc(100vh - 406px);"
[class.hidden]="currentTap!='ประเมินผลการปฏิบัติงาน'&&currentTap!='สรุปคะแนนและข้อเสนอแนะ'">
[class.hidden]="currentTap!='Performance'&&currentTap!='SummaryAndFeedback'">
<app-pms-kpi [canSave]="canSave" [appraisalPms]="compentency.data.pms" [currentTap]="currentTap"
[currentPart]="currentTap" [evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId"
[canEdit]="canEdit" [currentStep]="compentency.data.currentStep" [dateIso]="dateIso"
......@@ -635,7 +642,7 @@
(scrollToMenuId)="scrollToMenu($event)" [inforWeight]="inforWeightBoss"
[compentencyFormRemain]="compentencyFormRemain" [complete]="complete"></app-pms-kpi>
</div>
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='แผนพัฒนาบุคลากร'">
<div class="min-height: calc(100vh - 406px);" [class.hidden]="currentTap!='IDP'">
<app-pms-idp [currentTap]="currentTap" [canSave]="canSave" [appraisalIdp]="compentency.data.idp"
[evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId"
[canEdit]="evaluationForm=='sup'?canEdit:false" [currentStep]="compentency.data.currentStep"
......@@ -645,11 +652,11 @@
<div class="box-footer text-end space-x-3 rtl:space-x-reverse"
style="margin: 0.5rem -24px -24px -24px;">
<div class="pb-4 space-y-3 dark:border-white/10">
<textarea type="text" class="ti-form-input" rows="2" placeholder="ใส่ Comment ที่นี่"
<textarea type="text" class="ti-form-input" rows="2" [placeholder]="'CommentHere' | translate"
[(ngModel)]="comment"></textarea>
</div>
<!-- <button (click)="toggleStatusPdfPrint()" class="ti-btn m-0 ti-btn-soft-warning"
*ngIf="currentTap == 'แผนพัฒนาบุคลากร'">
*ngIf="currentTap == 'IDP'">
<i class="ri-draft-fill"></i>
PDF
</button> -->
......@@ -658,7 +665,7 @@
[class.ti-btn-disabled]="compentencyFormRemain||kpiFormRemain">
<i class="ri-save-3-fill"></i>
<ng-container *ngIf="compentency.data.currentStep == '0'">
ยืนยันข้อมูล
{{'Confirm' | translate}}
</ng-container>
<ng-container *ngIf="compentency.data.currentStep != '0'">
อนุมัติ
......@@ -667,7 +674,7 @@
<button (click)="save('draft')" class="ti-btn m-0 ti-btn-soft-success"
*ngIf="compentency.data.currentStep == '0'||compentency.data.currentStep == '1'">
<i class="ri-draft-fill"></i>
บันทึกร่าง
{{'SaveDraft' | translate }}
</button>
<button (click)="save('noApprove')" class="ti-btn m-0 ti-btn-soft-danger"
*ngIf="compentency.data.currentStep != '0' && compentency.data.currentStep != '1'">
......
......@@ -9,6 +9,7 @@ import Swal from 'sweetalert2';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { environment } from 'src/environments/environment';
import { FileService } from 'src/app/shared/services/file.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-pms-form-employee',
......@@ -16,7 +17,7 @@ import { FileService } from 'src/app/shared/services/file.service';
styleUrls: ['./pms-form-employee.component.scss']
})
export class PmsFormEmployeeComponent {
@Input() currentTap = "ข้อมูลการประเมิน"
@Input() currentTap = "EvaluationInfo"
firstCurrentTap = ""
@Input() evaluateeId = ""
@Input() evaluaterId = ""
......@@ -78,11 +79,11 @@ export class PmsFormEmployeeComponent {
@ViewChild('scrollContainer') scrollContainer!: ElementRef;
menuList: { text: string, link: string }[] = [
{ text: 'ข้อมูลการประเมิน', link: 'info' },
{ text: 'แบบประเมินสมรรถนะ', link: 'com' },
{ text: 'ประเมินผลการปฏิบัติงาน', link: 'kpi' },
{ text: 'สรุปคะแนนและข้อเสนอแนะ', link: 'kpi-sum' },
{ text: 'แผนพัฒนาบุคลากร', link: 'idp' }]
{ text: 'EvaluationInfo', link: 'info' },
{ text: 'CompetencyEva', link: 'com' },
{ text: 'Performance', link: 'kpi' },
{ text: 'SummaryAndFeedback', link: 'kpi-sum' },
{ text: 'IDP', link: 'idp' }]
constructor(
private router: Router,
......@@ -91,6 +92,7 @@ export class PmsFormEmployeeComponent {
private cdr: ChangeDetectorRef,
private tokenService: TokenService,
private route: ActivatedRoute,
private translateService: TranslateService,
private fileService: FileService
) {
}
......@@ -102,17 +104,17 @@ export class PmsFormEmployeeComponent {
currentStepText = () => {
if (this.compentency.data) {
if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) {
return "ผู้รับการประเมิน"
return "Appraisee"
} else if (this.compentency.data.apsapprove1.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 1"
return "Approver1Eva"
} else if (this.compentency.data.apsapprove2.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 2"
return "Approver2Eva"
} else if (this.compentency.data.apsapprove3.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 3"
return "Approver3Eva"
} else if (this.compentency.data.apsapprove4.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 4"
return "Approver4Eva"
} else if (this.compentency.data.apsapprove5.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 5"
return "Approver5Eva"
}
}
return ""
......@@ -120,17 +122,17 @@ export class PmsFormEmployeeComponent {
currentStepTextShow = () => {
if (this.compentency.data) {
if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) {
return "ผู้ประเมิน"
return "Assessor"
} else if (this.compentency.data.apsapprove1.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 1"
return "Approver1Eva"
} else if (this.compentency.data.apsapprove2.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 2"
return "Approver2Eva"
} else if (this.compentency.data.apsapprove3.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 3"
return "Approver3Eva"
} else if (this.compentency.data.apsapprove4.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 4"
return "Approver4Eva"
} else if (this.compentency.data.apsapprove5.employeeId == this.evaluaterId) {
return "ผู้อนุมัติลำดับที่ 5"
return "Approver5Eva"
}
}
return ""
......@@ -153,13 +155,13 @@ export class PmsFormEmployeeComponent {
statusCompetencyText = (status: string) => {
if (status === "no access") {
return "ยังไม่ถึงขั้นตอนดำเนินการ"
return "NotStarted"
} else if (status === "pending") {
return "รอดำเนินการ"
return "Pending"
} else if (status === "evaluating") {
return "อยู่ระหว่างดำเนินการ"
return "InProgress"
} else if (status === "completed") {
return "ดำเนินการเสร็จสิ้น"
return "Completed"
} else if (status === "rejected") {
return "ส่งกลับ"
} else {
......@@ -298,15 +300,15 @@ export class PmsFormEmployeeComponent {
this.route.paramMap.subscribe((params: ParamMap) => {
const pathLink = params.get('part')
if (pathLink == 'info') {
this.firstCurrentTap = 'ข้อมูลการประเมิน'
this.firstCurrentTap = 'EvaluationInfo'
} else if (pathLink == 'com') {
this.firstCurrentTap = 'แบบประเมินสมรรถนะ'
this.firstCurrentTap = 'CompetencyEva'
} else if (pathLink?.includes('kpi-sum')) {
this.firstCurrentTap = 'สรุปคะแนนและข้อเสนอแนะ'
this.firstCurrentTap = 'SummaryAndFeedback'
} else if (pathLink?.includes('kpi')) {
this.firstCurrentTap = 'ประเมินผลการปฏิบัติงาน'
this.firstCurrentTap = 'Performance'
} else if (pathLink == 'idp') {
this.firstCurrentTap = 'แผนพัฒนาบุคลากร'
this.firstCurrentTap = 'IDP'
}
});
this.companyId = this.tokenService.getUser()?.companyid || ""
......@@ -333,10 +335,10 @@ export class PmsFormEmployeeComponent {
this.selectDataList(this.compentency.dataList[0])
}
this.compentency.loading = false
this.cdr.detectChanges()
this.cdr.markForCheck()
}, error: error => {
this.compentency.loading = false
this.cdr.detectChanges()
this.cdr.markForCheck()
}
})
}
......@@ -344,21 +346,27 @@ export class PmsFormEmployeeComponent {
selectDataList(data: CompetencyModel) {
this.compentency.originalData = this.deepClone(data)
this.compentency.data = this.deepClone(data)
this.menuList = [
{ text: 'EvaluationInfo', link: 'info' },
{ text: 'CompetencyEva', link: 'com' },
{ text: 'Performance', link: 'kpi' },
{ text: 'SummaryAndFeedback', link: 'kpi-sum' },
{ text: 'IDP', link: 'idp' }]
const checkMenu = Array.from({ length: 7 }, (_, i) => i + 1)
.filter(i => (this.compentency.data?.pms?.[`part${i}Detail` as keyof Pms] as any)?.length).length
if (!checkMenu) {
this.menuList.splice(2, 1)
}
this.complete = this.compentency.data?.statusType == 'complete'
this.cdr.detectChanges()
this.cdr.markForCheck()
if (this.compentency.data) {
this.currentTap = this.firstCurrentTap || "ข้อมูลการประเมิน"
this.currentTap = this.firstCurrentTap || "EvaluationInfo"
this.firstCurrentTap = ''
this.compentency.data.commentAll.sort((a, b) => new Date(b.commentDate).getTime() - new Date(a.commentDate).getTime());
this.canSave = this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating"
this.canDraft = +this.compentency.data.currentStep <= 1 && (this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating")
this.canEdit = +this.compentency.data.currentStep <= 1 && (this.compentency.data.statusType == "pending" || this.compentency.data.statusType == "evaluating")
this.cdr.detectChanges()
this.cdr.markForCheck()
}
}
......@@ -368,10 +376,10 @@ export class PmsFormEmployeeComponent {
next: response => {
this.evaluatee.data = new MyEmployeeModel(response)
this.evaluatee.loading = false
this.cdr.detectChanges()
this.cdr.markForCheck()
}, error: error => {
this.evaluatee.loading = false
this.cdr.detectChanges()
this.cdr.markForCheck()
}
})
}
......@@ -624,6 +632,10 @@ export class PmsFormEmployeeComponent {
'!competency[].masfromEvaluationAssessment1List[].weightScore5',
'!competency[].masfromEvaluationAssessment1List[].weightedTotal',
'!competency[].masfromEvaluationAssessment1List[].averageScore',
'!competency[].masfromEvaluationAssessment1List[].weightScore6Boss',
'!competency[].masfromEvaluationAssessment1List[].weightScore7Boss',
'!competency[].masfromEvaluationAssessment1List[].scoreGab',
'!competency[].masfromEvaluationAssessment1List[].scoreGabBoss',
'pms',
'!pms.gradeScore',
'!pms.apsassessyDate',
......@@ -786,4 +798,8 @@ export class PmsFormEmployeeComponent {
imgElement.src = './assets/img/users/defaultperson.jpg';
}
translateText(th?: string, en?: string) {
return this.translateService.getCurrentLang() == 'th' ? (th || '') : (en || '')
}
}
......@@ -13,7 +13,7 @@
<ng-container>
<div class="pb-2 flex justify-between items-center">
<div class="font-size-18px font-weight-700 text-gray-500">
ส่วนที่ 1: ข้อมูลทั่วไป
{{'Part1GeneralInformation' | translate}}
</div>
<!-- <button class="ti-btn m-0 ti-btn-soft-warning" *ngIf="pdfPrintCheck == 0" (click)="exportPdf()" >
<i class="ri-draft-fill"></i>
......@@ -29,34 +29,35 @@
<div class="w-1/2 border flex flex-col shadow" style="border-radius: 20px;">
<div class="w-full bg-soft-secondary text-primary p-3"
style="border-radius: 20px 20px 0 0;">
<span class="font-size-18px font-weight-700">ผู้ใต้บังคับบัญชา</span>
<span class="font-size-18px font-weight-700">{{'SubordinatePart9' | translate}}</span>
</div>
<div class="w-full p-2">
<table class="ti-custom-table border-0 ellipsis-text">
<tbody>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ชื่อ - สกุล</td>
<td class="font-medium !p-2 align-start">{{'NameSurname' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start">
{{appraisalIdp.apsassessy.thFullName || ''}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ตำเเหน่ง</td>
<td class="font-medium !p-2 align-start">{{'Position' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.apsassessy.position.tdesc || ''}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">งาน</td>
<td class="font-medium !p-2 align-start">{{'Job' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.apsassessy.job.tdesc || ""}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ฝ่าย</td>
<td class="font-medium !p-2 align-start">{{'DivisionPart9' | translate}}
</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.apsassessy.bu1.tdesc}}
......@@ -66,37 +67,39 @@
</table>
</div>
</div>
<div class="w-1/2 border flex flex-col shadow" style="border-radius: 20px;" *ngIf="appraisalIdp.boss">
<div class="w-1/2 border flex flex-col shadow" style="border-radius: 20px;"
*ngIf="appraisalIdp.boss">
<div class="w-full bg-soft-secondary text-primary p-3"
style="border-radius: 20px 20px 0 0;">
<span class="font-size-18px font-weight-700">ผู้บังคับบัญชา</span>
<span class="font-size-18px font-weight-700">{{'SubordinatePart9' | translate}}</span>
</div>
<div class="w-full p-2">
<table class="ti-custom-table border-0 ellipsis-text">
<tbody>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ชื่อ - สกุล</td>
<td class="font-medium !p-2 align-start">{{'NameSurname' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start">
{{appraisalIdp.boss.thFullName || ''}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ตำเเหน่ง</td>
<td class="font-medium !p-2 align-start">{{'Position' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.boss.position.tdesc || ''}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">งาน</td>
<td class="font-medium !p-2 align-start">{{'Job' | translate}}</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.boss.job.tdesc || ""}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ฝ่าย</td>
<td class="font-medium !p-2 align-start">{{'DivisionPart9' | translate}}
</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{appraisalIdp.boss.bu1.tdesc}}
......@@ -110,12 +113,12 @@
</div>
<div class="pb-2">
<div class="font-size-18px font-weight-700 text-gray-500">
ส่วนที่ 2: แนวทางการพัฒนา
{{'Section2DevelopmentPlan' | translate}}
</div>
</div>
<div class="pb-2">
<div class="py-2 grid grid-cols-6 gap-3">
<div class="col-span-6">หมายเหตุ : กรณี HR จัดอบรมให้ต้องเป็นไปตามเกณฑ์ที่ส่วนกลางกำหนดขึ้น
<div class="col-span-6">{{'RemarkHRTraining' | translate}}
</div>
<div class="col-span-6 grid grid-cols-6 gap-2">
<div class="grid col-span-1 grid-cols-6 gap-2">
......@@ -129,7 +132,7 @@
<div class="col-span-5">
<label for="idpStatus-0" class="text-sm text-gray-500"
[class.pointer-events-none]="appraisalIdp.masfromEvaluationIdp.idpStatus=='0'||!canEdit ||appraisalIdp.checkStep!='1'">
IDP มาตรฐาน
{{'StandardIDP'| translate }}
</label>
</div>
</div>
......@@ -144,7 +147,7 @@
<div class="col-span-5">
<label for="idpStatus-1" class="text-sm text-gray-500"
[class.pointer-events-none]="appraisalIdp.masfromEvaluationIdp.idpStatus=='1'||!canEdit ||appraisalIdp.checkStep!='1'">
IDP ปรับแก้ไข
{{'RevisedIDP' | translate}}
</label>
</div>
</div>
......@@ -159,8 +162,8 @@
<th scope="col" rowspan="3"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center"
style="border-radius: 20px 0 0 0;">
<span
class="font-size-12px font-weight-700 ">{{'สมรรถนะที่พัฒนา\n(Competency)'}}</span>
<span class="font-size-12px font-weight-700 ">{{'CompetencyPart9' |
translate}}</span>
<div class="absolute top-1/2 transform -translate-y-1/2 right-0">
<i class="ti ti-dots-vertical fs-l"></i>
</div>
......@@ -168,7 +171,7 @@
<th scope="col" rowspan="3"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
<span class="font-size-12px font-weight-700 ">
{{'ประเด็นตัวชี้พฤติกรรมที่ต้องพัฒนา\n(Behavior Indicators : BIs)'}}
{{'BehaviorIndicatorsBIs' | translate}}
</span>
<div class="absolute top-1/2 transform -translate-y-1/2 right-0">
<i class="ti ti-dots-vertical fs-l"></i>
......@@ -176,7 +179,8 @@
</th>
<th scope="col" colspan="3"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
<span class="font-size-12px font-weight-700 ">เครื่องมือพัฒนา</span>
<span class="font-size-12px font-weight-700 ">{{'AssessmentToolsPart9'|
translate}}</span>
</th>
<th scope="col" rowspan="3"
class="relative bg-soft-secondary text-primary !text-center !p-0">
......@@ -186,7 +190,7 @@
</th>
<th scope="col" colspan="2" rowspan="2"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
<span class="font-size-12px font-weight-700 ">หลักสูตรพัฒนาตาม CDR</span>
<span class="font-size-12px font-weight-700 ">{{'CDRPart9'| translate}}</span>
</th>
<th scope="col" rowspan="3"
class="relative bg-soft-secondary text-primary !text-center !p-0">
......@@ -196,7 +200,8 @@
</th>
<th scope="col" rowspan="3" style="border-radius: 0 20px 0 0;min-width: 175px"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
<span class="font-size-12px font-weight-700 ">ระยะเวลาที่พัฒนา</span>
<span class="font-size-12px font-weight-700 ">{{'DevelopmentPeriod'|
translate}}</span>
</th>
</tr>
<tr class="font-size-12px">
......@@ -228,18 +233,18 @@
</th>
<th scope="col"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
รหัส
{{'Code' | translate}}
</th>
<th scope="col"
class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
ชื่อหลักสูตร
{{'CDRName' | translate}}
</th>
</tr>
</thead>
<tbody *ngIf="!appraisalIdp.competencyIndicatorsCourses1.length">
<tr class="hover:table-hover2-hover">
<td class="text-center" colspan="100%">
ไม่พบข้อมูล
{{'NoInformation' | translate}}
</td>
</tr>
</tbody>
......@@ -364,7 +369,8 @@
</ng-container> -->
</ng-container>
<ng-container *ngIf="pdfPrintCheck != 0 && (data.idpDevelopmentPlan&&(data.idpDevelopmentPlan.training || data.idpDevelopmentPlan.ojtJobAssignment ||data.idpDevelopmentPlan.coachMentor )&& appraisalIdp.apsapprove1.employeeId == evaluaterId)">
<ng-container
*ngIf="pdfPrintCheck != 0 && (data.idpDevelopmentPlan&&(data.idpDevelopmentPlan.training || data.idpDevelopmentPlan.ojtJobAssignment ||data.idpDevelopmentPlan.coachMentor )&& appraisalIdp.apsapprove1.employeeId == evaluaterId)">
{{convertDateFormat(data.startDate)}}
<ng-container *ngIf="data.startDate &&data.endDate">
<p></p>ถึง&nbsp;
......@@ -398,8 +404,9 @@
<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]="'SearchByNoOrName' | translate"
[(ngModel)]="competencycourseTable.search" (ngModelChange)="onCompetencycourseSearch()">
class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="competencycourseTable.search"
(ngModelChange)="onCompetencycourseSearch()">
<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>
......
......@@ -3,28 +3,28 @@
<button type="button"
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px" (click)="menuClose.set('Compentency',!menuClose.get('Compentency'))">
รายละเอียดประเมินสมรรถนะ (Compentency)
{{'CompetencyDetail' | translate}}
</button>
</div>
<ng-container *ngIf="!menuClose.get('Compentency')">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">แบบการประเมิน</th>
<th scope="col text-center">วันที่เริ่มต้น</th>
<th scope="col text-center">วันที่สิ้นสุด</th>
<th scope="col">{{'EvaluationForm' | translate}}</th>
<th scope="col text-center">{{'StartDate'| translate}}</th>
<th scope="col text-center">{{'EndDate' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col text-center">คะแนนเฉลี่ย</th>
<th scope="col text-center">ผล GAP</th>
<th scope="col text-center">{{'AverageScore' | translate}}</th>
<th scope="col text-center">{{'GapResult'| translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col text-center">คะแนนเฉลี่ยตนเอง
</th>
<th scope="col text-center">คะแนนเฉลี่ย</th>
<th scope="col text-center">{{'AverageScore' | translate}}</th>
<th scope="col text-center">ผล GAP ตนเอง</th>
<th scope="col text-center">ผล GAP</th>
<th scope="col text-center">{{'GapResult' | translate}}</th>
</ng-container>
<th scope="col text-center">การจัดการ</th>
<th scope="col text-center">{{'Action' | translate}}</th>
</tr>
</thead>
<tbody>
......@@ -84,25 +84,25 @@
<button type="button"
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px" (click)="menuClose.set('PMS',!menuClose.get('PMS'))">
รายละเอียดประเมินผลการปฏิบัติงาน (PMS)
{{'PerformanceManagementSystem(PMS)' | translate}}
</button>
</div>
<ng-container *ngIf="appraisalPms&&!menuClose.get('PMS')">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">แบบการประเมิน</th>
<th scope="col text-center">วันที่เริ่มต้น</th>
<th scope="col text-center">วันที่สิ้นสุด</th>
<th scope="col">{{'EvaluationForm' | translate}}</th>
<th scope="col text-center">{{'StartDate'| translate}}</th>
<th scope="col text-center">{{'EndDate' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col text-center">ผลการประเมิน</th>
<th scope="col text-center">{{'EvaluationResult'| translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col text-center">ผลการประเมินตนเอง</th>
<th scope="col text-center">ผลการประเมิน</th>
<th scope="col text-center">{{'EvaluationResult' | translate}}</th>
</ng-container>
<th scope="col text-center">เกรด</th>
<th scope="col text-center">การจัดการ</th>
<th scope="col text-center">{{'Grade' | translate}}</th>
<th scope="col text-center">{{'Action' | translate}}</th>
</tr>
</thead>
<tbody>
......
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Competency, Pms } from 'src/app/shared/model/competency.model';
@Component({
......@@ -27,6 +28,8 @@ export class PmsInformationComponent {
@Output() sendCurrentPart: EventEmitter<any> = new EventEmitter<any>();
tableHover: Map<string, boolean> = new Map<string, boolean>()
menuClose: Map<string, boolean> = new Map<string, boolean>()
constructor(private translateService: TranslateService) { }
statusButtonClass = (status: string) => {
if (status === "no access") {
return "ti-btn-soft-mute"
......@@ -44,6 +47,7 @@ export class PmsInformationComponent {
}
formatThaiDate(dateStr?: string): string {
if (!dateStr) return ''
if (this.translateService.getCurrentLang() == 'th') {
const months = [
'', 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน',
'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
......@@ -54,5 +58,22 @@ export class PmsInformationComponent {
const thaiMonth = months[month];
return `${day} ${thaiMonth} ${thaiYear}`;
} else {
return this.formatEngDate(dateStr)
}
}
formatEngDate(dateStr?: string): string {
if (!dateStr) return '';
const months = [
'', 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
const [year, month, day] = dateStr.split('-').map(Number);
const engMonth = months[month];
return `${day} ${engMonth} ${year}`;
}
}
......@@ -4,7 +4,7 @@
<ng-container *ngIf="appraisalPms">
<div class="flex flex-col">
<div class="flex py-2 flex-row gap-2 sticky" style="top:0;z-index:2;background: white;">
<ng-container *ngIf="currentTap == 'ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="currentTap == 'Performance'">
<ng-container *ngFor="let item of partShow;let i=index">
<button type="button"
class="flex justify-center !items-center border bg-white p-1 text-center font-semibold"
......@@ -25,7 +25,7 @@
</button>
</ng-container>
</ng-container>
<ng-container *ngIf="currentTap != 'ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="currentTap != 'Performance'">
<ng-container *ngFor="let item of partShow;let i=index">
<button type="button"
class="flex justify-center !items-center border bg-white p-1 text-center font-semibold"
......@@ -47,7 +47,7 @@
</div>
</div>
<div class="flex flex-col gap-2" style="min-height: calc(100vh - 479px);">
<ng-container *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="currentTap=='Performance'">
<ng-container *ngIf="appraisalPms?.part1Detail?.length then part1 else noData"></ng-container>
<ng-container *ngIf="appraisalPms?.part2Detail?.length then part2 else noData"></ng-container>
<ng-container *ngIf="appraisalPms?.part3Detail?.length then part3 else noData"></ng-container>
......@@ -56,7 +56,7 @@
<ng-container *ngIf="appraisalPms?.part6Detail?.length then part6 else noData"></ng-container>
<ng-container *ngIf="appraisalPms?.part7Detail?.length then part7 else noData"></ng-container>
</ng-container>
<ng-container *ngIf="currentTap=='สรุปคะแนนและข้อเสนอแนะ'">
<ng-container *ngIf="currentTap=='SummaryAndFeedback'">
<ng-container *ngIf="data8List.length">
<ng-container *ngTemplateOutlet="part8"></ng-container>
</ng-container>
......@@ -77,23 +77,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-1');toggleAllParts(!partOpen.get('PART 1'),'PART 1');">
PART&nbsp;1&nbsp;:&nbsp;ประเมินผลการปฏิบัติงานตามนโยบายบริษัท&nbsp;(Corporate KPI)
{{"PART 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 1')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">ตัวชี้วัด</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px">ค่าเป้าหมาย</th>
<th scope="col">{{'PerformanceIndicator' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -127,7 +127,7 @@
</div>
<div class="text-start flex flex-row">
<div style="width: 100px;">
ตัวชี้วัด
{{'PerformanceIndicator' | translate}}
</div>
<div class="px-1">
&nbsp;:&nbsp;
......@@ -229,15 +229,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScore(appraisalPms?.part1Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigth(appraisalPms?.part1Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScore(appraisalPms?.part1Detail)}}</span>
</div>
</div>
......@@ -261,14 +261,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part1Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBoss(appraisalPms?.part1Detail),calRawScore(appraisalPms?.part1Detail))}}</span>
</div>
</div>
......@@ -289,23 +290,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-2');toggleAllParts(!partOpen.get('PART 2'),'PART 2')">
PART&nbsp;2&nbsp;:&nbsp;ประเมินผลการปฏิบัติงานประจำ&nbsp;(Department KPI)
{{"PART 2 : ประเมินตัวชี้วัดของหน่วยงาน (Department KPI)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 2')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">ตัวชี้วัด</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">{{'PerformanceIndicator' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -441,15 +442,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScore(appraisalPms?.part2Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigth(appraisalPms?.part2Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScore(appraisalPms?.part2Detail)}}</span>
</div>
</div>
......@@ -472,14 +473,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part2Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBoss(appraisalPms?.part2Detail),calRawScore(appraisalPms?.part2Detail))}}</span>
</div>
</div>
......@@ -500,23 +502,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-3');toggleAllParts(!partOpen.get('PART 3'),'PART 3')">
PART&nbsp;3&nbsp;:&nbsp;ประเมินผลการปฏิบัติงานประจำ&nbsp;(Individual KPI)
{{"PART 3 : ประเมินตัวชี้วัดรายบุคคล (Individual KPI)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 3')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">ตัวชี้วัด</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">{{'PerformanceIndicator' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -652,15 +654,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScore(appraisalPms?.part3Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigth(appraisalPms?.part3Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScore(appraisalPms?.part3Detail)}}</span>
</div>
</div>
......@@ -683,14 +685,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part3Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBoss(appraisalPms?.part3Detail),calRawScore(appraisalPms?.part3Detail))}}</span>
</div>
</div>
......@@ -711,17 +714,17 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-4');toggleAllParts(!partOpen.get('PART 4'),'PART 4')">
PART&nbsp;4&nbsp;:&nbsp;ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน&nbsp;(Competency)
{{"PART 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 4')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">สมรรถนะ</th>
<th scope="col">น้ำหนัก</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'CompetencyPart4' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<th scope="col">{{'Score' | translate}}</th>
</tr>
</thead>
<tbody>
......@@ -768,15 +771,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="3">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScorePart4(appraisalPms?.part4Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigthPart4(appraisalPms?.part4Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScorePart4(appraisalPms?.part4Detail)}}</span>
</div>
</div>
......@@ -789,14 +792,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="3">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part4Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBossPart4(appraisalPms?.part4Detail),calRawScorePart4(appraisalPms?.part4Detail))}}</span>
</div>
</div>
......@@ -816,23 +820,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-5');toggleAllParts(!partOpen.get('PART 5'),'PART 5')">
PART&nbsp;5&nbsp;:&nbsp;อัตราการเข้างาน&nbsp;(Time Attendance)
{{"PART 5 : อัตราการเข้างาน (Time Attendance)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 5')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">อัตราการเข้างาน</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">{{'TimeAttendancePart5' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -945,15 +949,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScorePart5(appraisalPms?.part5Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigthPart5(appraisalPms?.part5Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScorePart5(appraisalPms?.part5Detail)}}</span>
</div>
</div>
......@@ -976,14 +980,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part5Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBossPart5(appraisalPms?.part5Detail),calRawScorePart5(appraisalPms?.part5Detail))}}</span>
</div>
</div>
......@@ -1004,23 +1009,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-6');toggleAllParts(!partOpen.get('PART 6'),'PART 6')">
PART&nbsp;6&nbsp;:&nbsp;งานที่ได้รับมอบหมายเพิ่มเติม&nbsp;(Cross Functional Project Assignment)
{{"PART 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 6')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">งานที่ได้รับมอบหมายเพิ่มเติม</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">{{'CrossFunctionalProjectAssignment' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -1156,15 +1161,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScore(appraisalPms?.part6Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigth(appraisalPms?.part6Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScore(appraisalPms?.part6Detail)}}</span>
</div>
</div>
......@@ -1187,14 +1192,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part6Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBoss(appraisalPms?.part6Detail),calRawScore(appraisalPms?.part6Detail))}}</span>
</div>
</div>
......@@ -1215,23 +1221,23 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-7');toggleAllParts(!partOpen.get('PART 7'),'PART 7')">
PART&nbsp;7&nbsp;:&nbsp;กิจกรรมพิเศษ&nbsp;(Special Activities)
{{"PART 7 : กิจกรรมพิเศษ (Special Activities)" | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 7')">
<div class="relative">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">กิจกรรมพิเศษ</th>
<th scope="col">น้ำหนัก</th>
<th scope="col">เพิ่มเติม</th>
<th scope="col" style="width: 300px;">ค่าเป้าหมาย</th>
<th scope="col">{{'SpecialActivities' | translate}}</th>
<th scope="col">{{'Weight' | translate}}</th>
<th scope="col">{{'Detail' | translate}}</th>
<th scope="col" style="width: 300px;">{{'TargetDegreeKpi' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเอง</th>
<th scope="col">คะแนน</th>
<th scope="col">{{'Score' | translate}}</th>
</ng-container>
</tr>
</thead>
......@@ -1367,15 +1373,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบ&nbsp;:&nbsp;<span
{{'RawScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calRawScore(appraisalPms?.part7Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คำนวนถ่วงน้ำหนัก&nbsp;:&nbsp;<span
{{'SumOfWeights' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calWeigth(appraisalPms?.part7Detail)}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนประเมินที่ได้&nbsp;:&nbsp;<span
{{'AchievedScore' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calExpectationScore(appraisalPms?.part7Detail)}}</span>
</div>
</div>
......@@ -1398,14 +1404,15 @@
<td class="align-start text-start !white-space-normal py-2" colspan="4">
<div class="flex flex-row gap-2">
<div class="flex-1 font-semibold">
คะแนนดิบคิดเป็นร้อยละ&nbsp;:&nbsp;<span class="text-indigo-600 ">100</span>
{{'RawScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">100</span>
</div>
<div class="flex-1 font-semibold">
ร้อยละของปัจจัย&nbsp;:&nbsp;<span
{{'FactorPercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{appraisalPms?.part6Percentage}}</span>
</div>
<div class="flex-1 font-semibold">
คะแนนที่ได้คิดเป็นร้อยละ&nbsp;:&nbsp;<span
{{'AchievedScorePercent' | translate}}&nbsp;:&nbsp;<span
class="text-indigo-600 ">{{calPercentage(calExpectationTotalScoreBoss(appraisalPms?.part7Detail),calRawScore(appraisalPms?.part7Detail))}}</span>
</div>
</div>
......@@ -1426,24 +1433,24 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-8');toggleAllParts(!partOpen.get('PART 8'),'PART 8')">
PART&nbsp;8&nbsp;:&nbsp;สรุปผลการปฏิบัติงาน&nbsp;(Summary)
{{'PART 8 : สรุปผลการปฏิบัติงาน (Summary)' | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 8')">
<table style="table-layout: fixed; width: 100%;">
<thead class="border-b border-gray-200">
<tr style="height:35px">
<th scope="col">การประเมินผล</th>
<th scope="col">คะแนนดิบคิดเป็นร้อยละ</th>
<th scope="col">ร้อยละของปัจจัย</th>
<th scope="col">{{'EvaluationFactor' | translate}}</th>
<th scope="col">{{'RawScore%' | translate}}</th>
<th scope="col">{{'Factor%' | translate}}</th>
<ng-container *ngIf="evaluaterId==evaluateeId&&!complete">
<th scope="col">คะแนนคิดเป็นร้อยละ</th>
<th scope="col">คะแนนสุทธิ</th>
<th scope="col">{{'AchievedScore%' | translate}}</th>
<th scope="col">{{'NetScorePart8' | translate}}</th>
</ng-container>
<ng-container *ngIf="evaluaterId!=evaluateeId||complete">
<th scope="col">ประเมินตนเองคิดเป็นร้อยละ</th>
<th scope="col">คะแนนคิดเป็นร้อยละ</th>
<th scope="col">คะแนนสุทธิลูกน้อง</th>
<th scope="col">คะแนนสุทธิ</th>
<th scope="col">{{'DirectReportScore%' | translate}}</th>
<th scope="col">{{'AchievedScore%' | translate}}</th>
<th scope="col">{{'DirectReportNetScore' | translate}}</th>
<th scope="col">{{'NetScorePart8' | translate}}</th>
</ng-container>
</tr>
......@@ -1488,7 +1495,7 @@
</ng-container>
<tr class="bg-table-soft-gray" style="height:35px">
<td class="py-2 align-start text-center font-semibold">
รวม
{{'SummaryPart8' | translate}}
</td>
<td class="py-2 align-start text-center">
</td>
......@@ -1530,8 +1537,7 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-9');toggleAllParts(!partOpen.get('PART 9'),'PART 9')">
PART&nbsp;9&nbsp;:&nbsp;พฤติกรรมบุคคลที่เป็นจุดแข็ง จุดอ่อน และการพัฒนา&nbsp;(EMPLOYEE STRENGTHS ,
WEAKNESSES AND PLAN TO IMPROVED)
{{'PART 9 : name' | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 9')">
<div class="space-y-4">
......@@ -1539,7 +1545,7 @@
<div class="pb-2 grid grid-cols-2">
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
พฤติกรรมที่เป็นจุดแข็ง (EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS)
{{'EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1549,7 +1555,7 @@
</div>
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับจุดแข็ง)
{{'Suggested Learning Topics' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1561,7 +1567,7 @@
<div class="pb-2 grid grid-cols-2">
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
พฤติกรรมที่เป็นจุดอ่อน (PERFORMANCE AREAS WHICH NEED IMPROVEMENT)
{{ 'PERFORMANCE AREAS WHICH NEED IMPROVEMENT' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1571,7 +1577,7 @@
</div>
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับจุดอ่อน)
{{ 'Suggested Learning Topics2' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1583,7 +1589,7 @@
<div class="pb-2 grid grid-cols-2">
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
พฤติกรรมที่ควรได้รับการพัฒนา (PLAN OF ACTION TOWARD IMPROVED PERFORMANCE)
{{ 'PLAN OF ACTION TOWARD IMPROVED PERFORMANCE' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1593,7 +1599,7 @@
</div>
<div class="col-span-1 grid-cols-1 text-gray-400">
<div class="col-span-1 bg-soft-secondary p-2" style="min-height: 55px;">
หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับพฤติกรรมที่ควรได้รับการพัฒนา)
{{ 'Suggested Learning Topics3' | translate}}
</div>
<div class="col-span-1 p-2">
<textarea type="text" rows="2" class="ti-form-input"
......@@ -1614,7 +1620,7 @@
class="p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
style="border-radius:20px"
(click)="scrollToMenu('menu-part-10');toggleAllParts(!partOpen.get('PART 10'),'PART 10')">
PART&nbsp;10&nbsp;:&nbsp;คำชมหรือรางวัลที่ได้รับ&nbsp;(Conversation, Feedback, Recognise : CFR)
{{'PART 10 : คำชมหรือรางวัลที่ได้รับ (Conversation, Feedback, Recognise : CFR)' | translate}}
</button>
<ng-container *ngIf="partOpen.get('PART 10')">
<div class="space-y-4">
......
......@@ -35,7 +35,7 @@ export class PmsKpiComponent {
@Input() inforWeight: Map<string, string> = new Map<string, string>()
data8List: Part8Model[] = [{
id: 1,
evaluationFactor: "Part 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)",
evaluationFactor: "PART 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -44,7 +44,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 2,
evaluationFactor: "Part 2 : ประเมินผลการปฏิบัติงานประจำ (Department KPI)",
evaluationFactor: "PART 2 : ประเมินตัวชี้วัดของหน่วยงาน (Department KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -53,7 +53,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 3,
evaluationFactor: "Part 3 : ประเมินผลการปฏิบัติงานประจำ (Individual KPI)",
evaluationFactor: "PART 3 : ประเมินตัวชี้วัดรายบุคคล (Individual KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -62,7 +62,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 4,
evaluationFactor: "Part 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)",
evaluationFactor: "PART 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -71,7 +71,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 5,
evaluationFactor: "Part 5 : อัตราการเข้างาน (Time Attendance)",
evaluationFactor: "PART 5 : อัตราการเข้างาน (Time Attendance)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -80,7 +80,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 6,
evaluationFactor: "Part 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)",
evaluationFactor: "PART 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -89,7 +89,7 @@ export class PmsKpiComponent {
netScore: 0,
}, {
id: 7,
evaluationFactor: "Part 7 : กิจกรรมพิเศษ (Special Activities)",
evaluationFactor: "PART 7 : กิจกรรมพิเศษ (Special Activities)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
......@@ -126,7 +126,72 @@ export class PmsKpiComponent {
private route: ActivatedRoute
) {
}
resetData8List() {
this.data8List = [{
id: 1,
evaluationFactor: "Part 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 2,
evaluationFactor: "Part 2 : ประเมินผลการปฏิบัติงานประจำ (Department KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 3,
evaluationFactor: "Part 3 : ประเมินผลการปฏิบัติงานประจำ (Individual KPI)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 4,
evaluationFactor: "Part 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 5,
evaluationFactor: "Part 5 : อัตราการเข้างาน (Time Attendance)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 6,
evaluationFactor: "Part 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}, {
id: 7,
evaluationFactor: "Part 7 : กิจกรรมพิเศษ (Special Activities)",
rawScore: 100,
factors: 0,
scoreObtainedBoss: 0,
netScoreBoss: 0,
scoreObtained: 0,
netScore: 0,
}]
}
getTargetDetailValue(item: any): string {
const targetDetail = ['', 'targetEdetail', 'targetDdetail', 'targetCdetail', 'targetBdetail', 'targetAdetail']
const index = this.partScore.get(item.groupAssessment1.pmsTopic.pmsTopicId) ?? item.scoreTopicExpectation;
......@@ -141,11 +206,12 @@ export class PmsKpiComponent {
}
ngOnInit(): void {
this.partOpen.clear()
this.resetData8List()
const menuList = Array.from({ length: 7 }, (_, i) => i + 1)
.filter(i => (this.appraisalPms?.[`part${i}Detail` as keyof Pms] as any)?.length)
.map(i => `PART ${i}`)
this.data8List = this.data8List.filter(e => menuList.some(e2 => e.id == +e2.replace('PART ', '')))
if (this.currentTap == 'ประเมินผลการปฏิบัติงาน') {
if (this.currentTap == 'Performance') {
this.partShow = menuList
} else {
if (this.data8List.length) {
......@@ -165,11 +231,12 @@ export class PmsKpiComponent {
ngOnChanges(changes: SimpleChanges): void {
if (changes['currentTap']?.currentValue || changes['appraisalPms']?.currentValue) {
this.partOpen.clear()
this.resetData8List()
const menuList = Array.from({ length: 7 }, (_, i) => i + 1)
.filter(i => (this.appraisalPms?.[`part${i}Detail` as keyof Pms] as any)?.length)
.map(i => `PART ${i}`)
this.data8List = this.data8List.filter(e => menuList.some(e2 => e.id == +e2.replace('PART ', '')))
if (this.currentTap == 'ประเมินผลการปฏิบัติงาน') {
if (this.currentTap == 'Performance') {
this.partShow = menuList
} else {
if (this.data8List.length) {
......@@ -181,6 +248,7 @@ export class PmsKpiComponent {
this.partShow.forEach(x => {
this.partOpen.set(x, false)
})
this.getAppraisalPmsForm()
this.allFormRemain()
this.sendScorePart()
......@@ -651,9 +719,9 @@ export class PmsKpiComponent {
if (this.appraisalPms) {
const gradeScore = this.groupGrade.dataList.find(item => Math.ceil(+this.calNetScoreBoss()) >= item.gradeMinScore && Math.ceil(+this.calNetScoreBoss()) <= item.gradeMaxScore);
const scoreBoss = this.data8List.map((x, i) => ({ text: x.evaluationFactor.match(/Part\s*\d+/)?.[0].toUpperCase(), score: this.numberFixed2(x.netScoreBoss) }))
.concat([{ text: "สุทธิ", score: this.calNetScoreBoss() + '' }, { text: "Grade", score: gradeScore?.gradeDetail || '' }])
.concat([{ text: "NetScore", score: this.calNetScoreBoss() + '' }, { text: "Grade", score: gradeScore?.gradeDetail || '' }])
const score = this.data8List.map((x, i) => ({ text: x.evaluationFactor.match(/Part\s*\d+/)?.[0].toUpperCase(), score: this.numberFixed2(x.netScore) }))
.concat([{ text: "สุทธิ", score: this.calNetScore() + '' }, { text: "Grade", score: gradeScore?.gradeDetail || '' }])
.concat([{ text: "NetScore", score: this.calNetScore() + '' }, { text: "Grade", score: gradeScore?.gradeDetail || '' }])
this.scorePartBoss.emit(scoreBoss)
this.scorePart.emit(score)
}
......
......@@ -7,7 +7,7 @@
<div class="absolute " style="transform:translateY(-9px)">
</div>
<span class="whitespace-nowrap relative" style="left:0px">
ประเมินผลประจำปี {{currentDate.getFullYear()}}
{{'AnnualEvaluation' | translate}} {{currentDate.getFullYear()}}
</span>
</div>
</div>
......@@ -35,7 +35,7 @@
<div class="flex flex-col">
<div class="flex">
<span class="font-size-18px font-weight-700 flex items-center" style="height:50px">
ผู้ใต้บังคับบัญชาประเมิน
{{'Subordinate' | translate}}
</span>
</div>
<div class="flex flex-row">
......@@ -50,10 +50,14 @@
<div class="flex flex-col w-1/2 gap-2"
style="height: 200px;justify-content: center;align-items: start;">
<span>
ประเมินแล้ว <span class="text-indigo-600">{{subordinateApprove()}}</span> คน
{{'CompletedEmployees' | translate}} <span
class="text-indigo-600">{{subordinateApprove()}}</span> {{'Employees' |
translate}}
</span>
<span>
ทั้งหมด <span class="text-indigo-600">{{subordinateAll()}}</span> คน
{{'TotalEmployees' | translate}} <span
class="text-indigo-600">{{subordinateAll()}}</span> {{'Employees' |
translate}}
</span>
</div>
</div>
......@@ -67,7 +71,7 @@
<div class="flex flex-col">
<div class="flex">
<span class="font-size-18px font-weight-700 flex items-center" style="height:50px">
การอนุมัติ
{{'Approval' | translate}}
</span>
</div>
<div class="flex flex-row">
......@@ -81,10 +85,14 @@
<div class="flex flex-col w-1/2 gap-2"
style="height: 200px;justify-content: center;align-items: start;">
<span>
อนุมัติแล้ว <span class="text-indigo-600">{{myApprove()}}</span> คน
{{'ApprovedEmployees' | translate}} <span
class="text-indigo-600">{{myApprove()}}</span> {{'EmployeesEva' |
translate}}
</span>
<span>
ทั้งหมด <span class="text-indigo-600">{{subordinateAll()}}</span> คน
{{'TotalEmployees' | translate}} <span
class="text-indigo-600">{{subordinateAll()}}</span> {{'EmployeesEva' |
translate}}
</span>
</div>
</div>
......@@ -98,7 +106,7 @@
<div class="flex flex-col">
<div class="flex">
<span class="font-size-18px font-weight-700 flex items-center" style="height:50px">
ภาพรวม PMS
{{'PmsOverview' | translate}}
</span>
</div>
<div class="flex flex-row">
......@@ -115,10 +123,12 @@
&nbsp;&nbsp;</span>
</div>
<div class="flex" style="width: 55px">
Grade&nbsp;{{item}}
{{'Grade'+item | translate}}
</div>
<div class="flex">
<span class="text-indigo-600">{{gradeFindLength(item)}}</span>&nbsp;คน
<span
class="text-indigo-600">{{gradeFindLength(item)}}</span>&nbsp;{{'EmployeesEva'
| translate}}
</div>
<div class="flex">
<span class="text-indigo-600">{{gradeFindPer(item)}}</span>&nbsp;%
......@@ -136,7 +146,7 @@
<div class="box-body py-2">
<div class="flex item-center w-full font-size-18px font-weight-700 text-primary px-5 mt-1 mb-4"
style="height: 50px;align-items: center;border-width: 1px;background: #eff6fe; border-radius:20px">
รายชื่อผู้ใต้บังคับบัญชา
{{'SubordinateList' | translate}}
</div>
<div class="flex w-full mb-4">
<div class="flex w-1/4 justify-between">
......@@ -146,7 +156,8 @@
id="hs-default-checkbox" [checked]="selectEmp.size-1 > 0">
<label for="hs-default-checkbox"
class="text-sm text-gray-500 mx-2 pointer-events-none">
{{selectEmp.size-1 < 0 ? 0 : selectEmp.size-1}} Selected</label>
{{selectEmp.size-1 < 0 ? 0 : selectEmp.size-1}} {{'Selected' | translate}}
</label>
</div>
<div class="mx-1 flex items-center">
<button (click)="toggleSelectAll()"
......@@ -155,7 +166,8 @@
[ngClass]="{'ri-checkbox-multiple-line text-gray-500': !selectEmp.get('selectAll'), 'ri-checkbox-multiple-fill text-primary': selectEmp.get('selectAll')}"></i>
</button>
<label (click)="toggleSelectAll()"
class="text-sm text-gray-500 ml-2 cursor-pointer">Select All</label>
class="text-sm text-gray-500 ml-2 cursor-pointer">
{{'SelectAll' |translate}}</label>
</div>
</div>
</div>
......@@ -164,7 +176,7 @@
<button type="button" class="ti-btn ti-btn-soft-secondary h-45px m-0 shadow-md"
[class.ti-btn-disabled]="selectEmp.size-1 <= 0" [disabled]="selectEmp.size-1 <= 0"
(click)="postBossApproveAll()">
ยืนยันการอนุมัติ
{{'ApproveAll' | translate}}
</button>
</div>
<div class="px-1">
......@@ -200,13 +212,13 @@
<ng-template #Datagrid>
<ejs-grid #grid id='Grid' [dataSource]="dataSourceSearch" [allowFiltering]="true" [filterSettings]="filterSettings"
[selectionSettings]="selectionOptions" [searchSettings]="syncfution.searchSettings"
[groupSettings]="groupSettings" [toolbar]="toolbarOptions" [editSettings]="editSettings"
[loadingIndicator]='loadingIndicator' [query]="query" [columnMenuItems]="columnMenuItems"
[pageSettings]="initialPage" [allowMultiSorting]="true" [allowPaging]="true" [allowGrouping]="true"
[allowSorting]="true" [showColumnMenu]="true" [allowPdfExport]="true" [allowExcelExport]="true"
[allowReordering]="true" width="auto" rowHeight="60" allowEditing="false"
<ejs-grid #grid id='Grid' [locale]="locale" [dataSource]="dataSourceSearch" [allowFiltering]="true"
[filterSettings]="filterSettings" [selectionSettings]="selectionOptions"
[searchSettings]="syncfution.searchSettings" [groupSettings]="groupSettings" [toolbar]="toolbarOptions"
[editSettings]="editSettings" [loadingIndicator]='loadingIndicator' [query]="query"
[columnMenuItems]="columnMenuItems" [pageSettings]="initialPage" [allowMultiSorting]="true" [allowPaging]="true"
[allowGrouping]="true" [allowSorting]="true" [showColumnMenu]="true" [allowPdfExport]="true"
[allowExcelExport]="true" [allowReordering]="true" width="auto" rowHeight="60" allowEditing="false"
(actionComplete)="actionComplete($event)" (columnMenuClick)="onColumnMenuClick($event)"
(toolbarClick)='toolbarClick($event)'>
<e-columns>
......@@ -217,9 +229,10 @@
[visible]="col.visible" [editType]="false" [allowEditing]="false" [allowFiltering]="true"
[allowSorting]="true" [type]="col.type" textAlign="center">
<ng-template #headerTemplate let-data>
<span class="font-size-12px font-weight-700 text-primary">{{ col.headerText }}</span>
<span class="font-size-12px font-weight-700 text-primary">{{ col.headerText |
translate}}</span>
</ng-template>
<ng-template #template let-data *ngIf="col.headerText=='รหัสพนักงาน'">
<ng-template #template let-data *ngIf="col.headerText=='EmployeeCode'">
<div class="flex-col gap-2">
<input
[disabled]="!(data.apsapproveType.code!='Apsapprove1'&&(data.masfromStatusType.code=='evaluating'||data.masfromStatusType.code=='pending'))"
......@@ -250,13 +263,13 @@
</ng-container>
</div>
</ng-template>
<ng-template #template let-data *ngIf="col.headerText=='ประเมิน'">
<ng-template #template let-data *ngIf="col.headerText=='Status'">
<div class="flex justify-center">
<button type="button" class="ti-btn rounded-sm "
[class]="statusButtonClass(data.statusIdp.statusType)"
style="height: 30px; width: auto; font-size: 12px; display: flex; align-items: center; justify-content: center;margin-left:4px;"
(click)="selectSubordinate(data,'',subordinate.select?.evaluationRoundId,data.statusIdp.statusType);pageEvalution='open'">
{{statusCompetencyText(data.statusIdp.statusType)}}
{{statusCompetencyText(data.statusIdp.statusType) | translate}}
</button>
</div>
</ng-template>
......
......@@ -43,6 +43,7 @@ import {
import { GroupSettingsModel, FilterSettingsModel, ColumnModel } from '@syncfusion/ej2-angular-grids';
import { DataManager, Query } from '@syncfusion/ej2-data';
import { L10n, setCulture } from '@syncfusion/ej2-base';
import { TranslateService } from '@ngx-translate/core';
setCulture('th-TH');
@Component({
selector: 'app-supervisor-evaluation',
......@@ -85,13 +86,13 @@ export class SupervisorEvaluationComponent {
}
statusCompetencyText = (status: string) => {
if (status === "no access") {
return "ยังไม่ถึงขั้นตอนดำเนินการ"
return "NotStarted"
} else if (status === "pending") {
return "รอดำเนินการ"
return "Pending"
} else if (status === "evaluating") {
return "อยู่ระหว่างดำเนินการ"
return "InProgress"
} else if (status === "completed") {
return "ดำเนินการเสร็จสิ้น"
return "Completed"
} else if (status === "rejected") {
return "ส่งกลับ"
} else {
......@@ -119,7 +120,7 @@ export class SupervisorEvaluationComponent {
searchSettings: {
fields: [
'employeeId',
'thFullName',
'fullName',
'position',
'statusIdp',
'sumScore',
......@@ -136,7 +137,7 @@ export class SupervisorEvaluationComponent {
filterSettings: FilterSettingsModel = { type: 'Excel' };
selectionOptions: SelectionSettingsModel = { checkboxOnly: true };
groupSettings: GroupSettingsModel = { allowReordering: true, showGroupedColumn: true, showDropArea: false };
toolbarOptions: ToolbarItems[] = ['Print', 'ExcelExport', 'CsvExport'];
toolbarOptions: any[] = ['Print', 'ExcelExport', 'CsvExport'];
editSettings? = { allowEditing: true, mode: 'Batch' };
loadingIndicator: LoadingIndicatorModel = { indicatorType: 'Shimmer' };
query: Query = new Query().addParams('dataCount', '1000');
......@@ -157,13 +158,38 @@ export class SupervisorEvaluationComponent {
aggregatesMin: any[] = [];
aggregatesMax: any[] = [];
locale = 'th-TH'
constructor(private appraisalService: AppraisalService,
private fileService: FileService,
private translateService: TranslateService,
private cdr: ChangeDetectorRef) {
this.locale = this.translateService.getCurrentLang() == 'th' ? 'th-TH' : 'en-US'
this.translateService.onLangChange.subscribe((event) => {
if (event.lang === 'th') {
setCulture('th-TH');
this.locale = 'th-TH'
} else if (event.lang === 'en') {
setCulture('en-US');
this.locale = 'en-US'
}
this.toolbarOptions = [
{ text: this.translateService.instant('Print'), prefixIcon: 'e-print', id: 'Print' },
{ text: this.translateService.instant('ExcelExport'), prefixIcon: 'e-excelexport', id: 'ExcelExport' },
{ text: this.translateService.instant('CSVExport'), prefixIcon: 'e-csvexport', id: 'CsvExport' }
];
if (this.subordinate.select?.showPms) {
this.setSyncfutionDataList()
this.searchDataGrid(this.search)
this.cdr.markForCheck()
}
});
}
ngOnInit(): void {
this.formEvaluation.evaluaterId = this.decodeJWT(sessionStorage.getItem("accessToken") || '').employeeid
this.getBossList()
}
getBossList() {
this.syncfution = {
......@@ -171,7 +197,7 @@ export class SupervisorEvaluationComponent {
searchSettings: {
fields: [
'employeeId',
'thFullName',
'fullName',
'position',
'statusIdp',
'sumScore',
......@@ -183,28 +209,44 @@ export class SupervisorEvaluationComponent {
columns: []
}
this.appraisalService.getBossList().subscribe({
next: response => {
next: async response => {
this.subordinate.dataList = JSON.parse(JSON.stringify(response))
this.cdr.detectChanges()
this.cdr.markForCheck()
if (this.subordinate.dataList.length) {
this.subordinate.select = JSON.parse(JSON.stringify(this.subordinate.dataList[0]))
this.setSyncfution()
this.setEcharts()
this.cdr.detectChanges()
}
const grid = await this.waitForGrid();
if (grid) {
this.searchDataGrid(this.search)
}
this.cdr.markForCheck()
}, error: error => {
this.cdr.detectChanges()
this.cdr.markForCheck()
}
})
}
waitForGrid(): Promise<GridComponent> {
return new Promise(resolve => {
const check = () => {
if (this.grid) resolve(this.grid);
else setTimeout(check, 50); // ตรวจสอบซ้ำทุก 50ms
};
check();
});
}
setSyncfution() {
this.syncfution = {
dataList: [],
searchSettings: {
fields: [
'employeeId',
'thFullName',
'fullName',
'position',
'statusIdp',
'sumScore',
......@@ -220,38 +262,38 @@ export class SupervisorEvaluationComponent {
this.syncfution.columns =
[{
field: "employeeId",
headerText: "รหัสพนักงาน",
headerText: "EmployeeCode",
type: "string",
isPrimaryKey: true,
},
{
field: "thFullName",
headerText: "ชื่อพนักงาน",
field: "fullName",
headerText: "EmployeeName",
type: "string"
},
{
field: "position",
headerText: "ตำเเหน่งงาน",
headerText: "Position",
type: "string"
},
{
field: "statusType",
headerText: "ประเมิน",
headerText: "Status",
type: "string"
},
{
field: "sumScore",
headerText: "ผลประเมิน",
headerText: "Result",
type: "string"
},
{
field: "grade",
headerText: "เกรด",
headerText: "Grade",
type: "string"
},
{
field: "apsapproveType",
headerText: "สถานะผู้ประเมิน",
headerText: "AppraiserStatus",
type: "string"
}]
}
......@@ -261,16 +303,17 @@ export class SupervisorEvaluationComponent {
if (this.subordinate.select?.showPms) {
this.syncfution.dataList = this.subordinate.select.masfromevaluationassessment.map(e => ({
employeeId: e.apsassessy.employeeId,
thFullName: e.apsassessy.thFullName,
position: e.apsassessy.position.tdesc,
fullName: this.translateText(e.apsassessy.thFullName, e.apsassessy.engFullName),
position: this.translateText(e.apsassessy.position.tdesc, e.apsassessy.position.edesc),
statusType: this.statusCompetencyText(e.statusIdp.statusType),
statusIdp: e.statusIdp,
sumScore: e.sumScore,
grade: e.grade,
apsapproveType: e.apsapproveType.tdesc,
apsapproveType: this.translateText(e.apsapproveType.tdesc, e.apsapproveType.edesc),
apsassessy: e.apsassessy,
masfromStatusType: e.masfromStatusType
}))
this.cdr.markForCheck()
}
}
selectDataList(data?: AppraisalSubordinateModel) {
......@@ -278,8 +321,8 @@ export class SupervisorEvaluationComponent {
this.subordinate.select = JSON.parse(JSON.stringify(data))
this.setSyncfutionDataList()
this.setEcharts()
this.cdr.detectChanges()
this.searchDataGrid(this.search)
this.cdr.markForCheck()
}
subordinateAll() {
......@@ -429,7 +472,7 @@ export class SupervisorEvaluationComponent {
this.formEvaluation.evaluationRoundId = evaluationRoundId
this.formEvaluation.masfromStatusType = masfromStatusType || ''
this.formEvaluation.allCompetencyTypeId = data.typeList
this.cdr.detectChanges()
this.cdr.markForCheck()
}
}
......@@ -593,7 +636,7 @@ export class SupervisorEvaluationComponent {
footerTemplate: 'Sum: ${Sum}'
});
}
this.cdr.detectChanges()
this.cdr.markForCheck()
}
else if (selectedAgg === 'count') {
this.aggregatesCount.push({
......@@ -644,9 +687,9 @@ export class SupervisorEvaluationComponent {
}));
this.grid?.csvExport({ columns: exportColumns as Column[] });
} else if (args.item.id === 'Grid_print') {
this.cdr.detectChanges()
this.cdr.markForCheck()
setTimeout(() => {
this.cdr.detectChanges()
this.cdr.markForCheck()
}, 1000)
}
}
......@@ -654,4 +697,8 @@ export class SupervisorEvaluationComponent {
checkSubordinate(employeeId: string) {
return this.subordinate.select?.masfromevaluationassessment.find(x => x.apsassessy.employeeId == employeeId)
}
translateText(th?: string, en?: string) {
return this.translateService.getCurrentLang() == 'th' ? (th || '') : (en || '')
}
}
......@@ -715,11 +715,11 @@
</a> -->
<a routerLink="/ess/my-skill-x-module" class="ti-dropdown-item cursor-pointer">
<i class="ti ti-home text-lg"></i>
หน้าหลัก
{{'Home' | translate}}
</a>
<a routerLink="/ess/profile" class="ti-dropdown-item">
<i class="ti ti-user-circle text-lg"></i>
ข้อมูลพนักงาน
{{'Profile' | translate}}
</a>
<!-- <a *ngIf="!router.url.includes('/self-evaluation')" (click)="onNextPartClick('/self-evaluation')"
class="ti-dropdown-item cursor-pointer">
......@@ -733,7 +733,7 @@
</a> -->
<a (click)="onNextPartClick('dashboard/projects')" class="ti-dropdown-item cursor-pointer">
<i class="ti ti-settings text-lg"></i>
หน้าผู้ดูแลระบบ
{{'AdminSettings' | translate}}
</a>
<!-- <a routerLink="/dashboard/crypto" class="ti-dropdown-item">
<i class="ti ti-wallet text-lg"></i>
......@@ -741,7 +741,7 @@
</a> -->
<a (click)="logOut()" routerLink="/auth/login" class="ti-dropdown-item">
<i class="ti ti-logout text-lg"></i>
Log Out
{{'LogOut' | translate}}
</a>
</div>
</div>
......
......@@ -95,7 +95,7 @@ export class NavService implements OnDestroy {
getCustomerMenu() {
return [
{
title: 'ประเมินตนเอง',
title: 'SelfEvaluate',
type: 'link',
selected: false,
active: false,
......@@ -109,7 +109,7 @@ export class NavService implements OnDestroy {
// ],
},
{
title: 'ประเมินโดยหัวหน้า',
title: 'SupervisorEvaluate',
type: 'link',
selected: false,
active: false,
......
......@@ -229,5 +229,166 @@
"SubSection4DescThai": "Sub Section 4 Desc. (Thai)",
"SubSection4DescEng": "Sub Section 4 Desc. (Eng)",
"CompetencyFactorsSetting": "Competency Factors Setting",
"JobLevel(JL)": "Job Level (JL)"
"JobLevel(JL)": "Job Level (JL)",
"JobFamily": "Job Family",
"JobFamilyCode": "Job Family Code",
"JobFamilyNameThai": "Job Family Name (Thai)",
"JobFamilyNameEng": "Job Family Name (Eng)",
"JobFamilyAbbr": "Job Family Abbr.",
"AddJobFamily": "Add Job Family",
"EditJobFamily": "Edit Job Family",
"DuplicateJobFamilyCode": "Duplicate Job Family Code",
"ImportJobFamily": "Import Job Family",
"Image": "Image",
"JobGrade": "Job Grade",
"JobGradeCode": "Job Grade Code",
"DuplicateJobGradeCode": "Duplicate Job Grade Code",
"JobGradeDescThai": "Job Grade Desc. (Thai)",
"JobGradeDescEng": "Job Grade Desc. (Eng)",
"AddJobGrade": "Add Job Grade",
"EditJobGrade": "Edit Job Grade",
"ImportJobGrade": "Import Job Grade",
"JobGradeGroup": "Job Grade Group",
"JobGradeGroupCode": "Job Grade Group Code",
"JobGradeGroupDescThai": "Job Grade Group Desc. (Thai)",
"JobGradeGroupDescEng": "Job Grade Group Desc. (Eng)",
"AddJobGradeGroup": "Add Job Grade Group",
"EditJobGradeGroup": "Edit Job Grade Group",
"ImportJobGradeGroup": "Import Job Grade Group",
"Home": "Home",
"Profile": "Profile",
"AdminSettings": "Admin Settings",
"LogOut": "Log Out",
"SelfEvaluate": "Self-Evaluate",
"SupervisorEvaluate": "Supervisor Evaluate",
"AnnualEvaluation": "Annual Evaluation",
"EvaluatorStatus": "Evaluator Status",
"Approver1Eva": "Approver 1",
"Approver2Eva": "Approver 2",
"Approver3Eva": "Approver 3",
"Approver4Eva": "Approver 4",
"Approver5Eva": "Approver 5",
"EvaluationInfo": "Evaluation Info.",
"CompetencyEva": "Competency",
"Performance": "Performance",
"SummaryAndFeedback": "Summary and Feedback",
"IDP": "IDP",
"CompetencyDetail": "Competency",
"EvaluationForm": "Evaluation Form",
"AverageScore": "Average Score",
"GapResult": "Gap Result",
"PerformanceManagementSystem(PMS)": "Performance Management System (PMS)",
"EvaluationResult": "Evaluation Result",
"Grade": "Grade",
"EmployeeInformation": "Employee Information",
"NameSurname": "Name-Surname",
"Email": "E-mail",
"StatusEva": "Status",
"NotStarted": "Not Started",
"Pending": "Pending",
"InProgress": "In Progress",
"Completed": "Completed",
"Appraisee": "Appraisee",
"Approver1To5": "Evaluator Status : Approver 1-5",
"Timeline": "Timeline",
"CommentHere": "Comment Here",
"Confirm": "Confirm",
"SaveDraft": "Save Draft",
"Assessor": "Assessor",
"ShowAll": "Show All",
"HideAll": "Hide All",
"WeightedScoreByTargetDegree": "Weighted Score by Target Degree",
"AvgScore": "Avg. Score",
"Gap": "Gap",
"Tools": "Tools",
"Summary": "Summary",
"TargetDegree": "Target Degree",
"TallyOfMarksPerRatingLevel1": "Tally of Marks per rating Level (1)",
"ScoreMultiplierPerLevel2": "Score Multiplier per Level (2)",
"WeightedScore1x2": "Weighted Score (1x2)",
"TotalWeightedScore": "Total Weighted Score",
"FinalAverageScore": "Final Average Score",
"CompetencyRatingScale": "Competency Rating Scale",
"RatingCriteria": "Rating Criteria",
"IfScore90to100": "If the score is between 90 - 100% = Gap +1",
"IfScore80to89": "If the score is between 80 - 89% = No Gap",
"IfScore60to79": "If the score is between 60 - 79% = Gap – 1",
"IfScore40to59": "If the score is between 40 - 59% = Gap -2",
"IfScore0to39": "If the score is between 0 - 39% = Gap – 3",
"Conditions": "Conditions",
"Condition1": "1. If the total score exceeds 80% but contains any rating of 3, 2, or 1, the final outcome is Gap -1.",
"Condition2": "2. If the total score is below 80% but contains any rating of 4 or 5, the Gap is determined by the percentage score.",
"Condition3": "3. If the total score is below 80% but contains any rating of 2 or 1, the Gap is determined by the percentage score.",
"AssessmentResultA": "Assessment Result",
"GapResultEva": "Gap Result",
"EvaluationSummary": "Evaluation Summary",
"NetScore": "Net Score",
"PART 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)": "Corporate KPI",
"PART 2 : ประเมินตัวชี้วัดของหน่วยงาน (Department KPI)": "Department KPI",
"PART 3 : ประเมินตัวชี้วัดรายบุคคล (Individual KPI)": "Individual KPI",
"PART 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)": "Competency",
"PART 5 : อัตราการเข้างาน (Time Attendance)": "Time Attendance",
"PART 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)": "Cross Functional Project Assignment",
"PART 7 : กิจกรรมพิเศษ (Special Activities)": "Special Activities",
"PerformanceIndicator": "Performance Indicator",
"Detail": "Detail",
"TargetDegreeKpi": "Target Degree",
"RawScore": "Raw Score",
"SumOfWeights": "Sum of Weights",
"AchievedScore": "Achieved Score",
"RawScorePercent": "Raw Score %",
"FactorPercent": "Factor %",
"AchievedScorePercent": "Achieved Score %",
"CompetencyPart4": "Competency",
"TimeAttendancePart5": "Time Attendance",
"CrossFunctionalProjectAssignment": "Cross Functional Project Assignment",
"SpecialActivities": "Special Activities",
"PART 8 : สรุปผลการปฏิบัติงาน (Summary)": "PART 8 : Summary",
"EvaluationFactor": "Evaluation Factor",
"RawScore%": "Raw Score %",
"Factor%": "Factor %",
"AchievedScore%": "Achieved Score %",
"NetScorePart8": "Net Score",
"SummaryPart8": "Summary",
"PART 9 : name": "PART 9 : EMPLOYEE STRENGTHS , WEAKNESSES AND PLAN TO IMPROVED",
"EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS": "EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS",
"Suggested Learning Topics": "Suggested Learning Topics",
"PERFORMANCE AREAS WHICH NEED IMPROVEMENT": "PERFORMANCE AREAS WHICH NEED IMPROVEMENT",
"Suggested Learning Topics2": "Suggested Learning Topics",
"PLAN OF ACTION TOWARD IMPROVED PERFORMANCE": "PLAN OF ACTION TOWARD IMPROVED PERFORMANCE",
"Suggested Learning Topics3": "Suggested Learning Topics",
"PART 10 : คำชมหรือรางวัลที่ได้รับ (Conversation, Feedback, Recognise : CFR)": "PART 10 : Conversation, Feedback, Recognise : CFR",
"Subordinate": "Subordinate",
"CompletedEmployees": "Completed",
"TotalEmployees": "Total",
"Approval": "Approval",
"ApprovedEmployees": "Approved",
"EmployeesEva": "Employees",
"PmsOverview": "PMS Overview",
"GradeA": "Grade A",
"GradeB": "Grade B",
"GradeC": "Grade C",
"GradeD": "Grade D",
"GradeE": "Grade E",
"SubordinateList": "Subordinate List",
"ApproveAll": "Approve All",
"Result": "Result",
"AppraiserStatus": "Appraiser Status",
"JobPosition": "Position",
"DirectReportScore%": "Direct Report's Score %",
"DirectReportNetScore": "Direct Report's Net Score",
"Part1GeneralInformation": "Part 1: General Information",
"SubordinatePart": "Subordinate",
"Supervisor": "Supervisor",
"Section2DevelopmentPlan": "Section 2: Development Plan",
"RemarkHRTraining": "Remark : HR-provided training must comply with the criteria set by the Head Office.",
"StandardIDP": "Standard IDP",
"RevisedIDP": "Revised IDP",
"CompetencyPart": "Competency",
"BehaviorIndicatorsBIs": "Behavior Indicators : BIs",
"AssessmentToolsPart": "Assessment Tools",
"CDR": "CDR",
"DevelopmentPeriod": "Development Period",
"Job": "Job",
"DivisionPart9": "Division"
}
\ No newline at end of file
......@@ -29,11 +29,12 @@
"AssessmentPeriod": "รอบการประเมิน",
"PerformanceManagementSystem": "ประเมินการจัดการประสิทธิภาพ",
"DataBankPms": "คลังข้อมูลการบริหารผลงาน",
"TimeAttendance": "ทะเบียนการประเมินเวลาทำงาน",
"Part5": "ทะเบียนการประเมินเวลาทำงาน",
"PmsFactors": "ปัจจัยการประเมินผล",
"PmsManage": "การจัดการการประเมินผล",
"EvaluationPeriod": "รอบการประเมิน"
},
"PerformanceManagementSystem": "ประเมินการจัดการประสิทธิภาพ",
"SearchByNoOrName": "ค้นหาตามรหัสหรือชื่อ",
"Import": "นำเข้า",
"Add": "เพิ่ม",
......@@ -94,7 +95,7 @@
"SetPassword": "กำหนดรหัสผ่าน",
"ManageUsers": "จัดการผู้ใช้งาน",
"LoginName": "ชื่อล็อคอิน",
"Status": "สถานะ",
"Eva": "สถานะ",
"Level": "ระดับ",
"DescriptionJobTypeThai": "รายละเอียด (ไทย)",
"DescriptionJobTypeEng": "รายละเอียด (อังกฤษ)",
......@@ -182,17 +183,17 @@
"Competency": "แสดงผลประเมินสมรรถนะ",
"DisplayResults": "แสดงผล",
"NotDisplay": "ไม่แสดงผล",
"TimeAttendance": "แสดงผลประเมินเวลาทำงาน",
"Part5": "แสดงผลประเมินเวลาทำงาน",
"PmsTypes": "ประเภทการประเมิน",
"PmsTopics": "หัวข้อการประเมิน",
"TopicName": "ชื่อหัวข้อ",
"TimeAttendance_head": "การประเมินเวลาทำงาน",
"TimeAttendanceManage": "การจัดการหัวข้อการประเมินเวลาทำงาน",
"Part5_head": "การประเมินเวลาทำงาน",
"Part5Manage": "การจัดการหัวข้อการประเมินเวลาทำงาน",
"WorkingTimeDataManage": "การจัดการข้อมูลสถิติเวลาทำงาน",
"Unit": "หน่วยนับ",
"ImportWorkingTimeData": "นำเข้าข้อมูลสถิติเวลาทำงาน",
"PMSFactorsSetting": "กำหนดปัจจัยการประเมินผล",
"Total": "รวม",
"Employees": "รวม",
"PMSManage": "การจัดการประเมิน",
"GroupingKPI": "จัดกลุ่มการประเมิน",
"Report": "รายงาน",
......@@ -228,5 +229,166 @@
"SubSection4DescThai": "รายละเอียดย่อย4 (ไทย)",
"SubSection4DescEng": "รายละเอียดย่อย4 (อังกฤษ)",
"CompetencyFactorsSetting": "กำหนดปัจจัยการประเมินสมรรถนะ",
"JobLevel(JL)": "ลักษณะงาน"
"JobLevel(JL)": "ลักษณะงาน",
"JobFamily": "กลุ่มงานตามวิชาชีพ",
"JobFamilyCode": "รหัสกลุ่มงานตามวิชาชีพ",
"JobFamilyNameThai": "ชื่อกลุ่มงานตามวิชาชีพ (ไทย)",
"JobFamilyNameEng": "ชื่อกลุ่มงานตามวิชาชีพ (อังกฤษ)",
"JobFamilyAbbr": "ชื่อย่อกลุ่มงานตามวิชาชีพ",
"AddJobFamily": "เพิ่มข้อมูลกลุ่มงานตามวิชาชีพ",
"EditJobFamily": "แก้ไขข้อมูลกลุ่มงานตามวิชาชีพ",
"DuplicateJobFamilyCode": "รหัสกลุ่มงานตามวิชาชีพซ้ำ",
"ImportJobFamily": "นำเข้าข้อมูลกลุ่มงานตามวิชาชีพ",
"Image": "รูปภาพ",
"JobGrade": "ระดับตำแหน่งงาน",
"DuplicateJobGradeCode": "ระดับตำแหน่งงานซ้ำ",
"JobGradeCode": "รหัสระดับตำแหน่งงาน",
"JobGradeDescThai": "รายละเอียดระดับตำแหน่งงาน (ไทย)",
"JobGradeDescEng": "รายละเอียดระดับตำแหน่งงาน (อังกฤษ)",
"AddJobGrade": "เพิ่มข้อมูลระดับตำแหน่งงาน",
"EditJobGrade": "แก้ไขข้อมูลระดับตำแหน่งงาน",
"ImportJobGrade": "นำเข้าข้อมูลระดับตำแหน่งงาน",
"JobGradeGroup": "กลุ่มระดับตำแหน่งงาน",
"JobGradeGroupCode": "รหัสกลุ่มระดับตำแหน่งงาน",
"JobGradeGroupDescThai": "รายละเอียดกลุ่มระดับตำแหน่งงาน (ไทย)",
"JobGradeGroupDescEng": "รายละเอียดกลุ่มระดับตำแหน่งงาน (อังกฤษ)",
"AddJobGradeGroup": "เพิ่มข้อมูลกลุ่มระดับตำแหน่งงาน",
"EditJobGradeGroup": "แก้ไขข้อมูลกลุ่มระดับตำแหน่งงาน",
"ImportJobGradeGroup": "นำเข้าข้อมูลกลุ่มระดับตำแหน่งงาน",
"Home": "หน้าหลัก",
"Profile": "ข้อมูลพนักงาน",
"AdminSettings": "หน้าผู้ดูแลระบบ",
"LogOut": "ออกจากระบบ",
"SelfEvaluate": "ประเมินตนเอง",
"SupervisorEvaluate": "ประเมินโดยหัวหน้า",
"AnnualEvaluation": "ประเมินผลประจำปี",
"EvaluatorStatus": "สถานะผู้ประเมิน",
"Approver1Eva": "ผู้อนุมัติลำดับที่ 1",
"Approver2Eva": "ผู้อนุมัติลำดับที่ 2",
"Approver3Eva": "ผู้อนุมัติลำดับที่ 3",
"Approver4Eva": "ผู้อนุมัติลำดับที่ 4",
"Approver5Eva": "ผู้อนุมัติลำดับที่ 5",
"EvaluationInfo": "ข้อมูลการประเมิน",
"CompetencyEva": "ประเมินสมรรถนะ",
"Performance": "ประเมินผลการปฏิบัติงาน",
"SummaryAndFeedback": "สรุปคะแนนและข้อเสนอแนะ",
"IDP": "แผนพัฒนาบุคลากร",
"CompetencyDetail": "รายละเอียดการประเมินสมรรถนะ (Competency)",
"EvaluationForm": "แบบการประเมิน",
"AverageScore": "คะแนนเฉลี่ย",
"GapResult": "ผล Gap",
"PerformanceManagementSystem(PMS)": "รายละเอียดประเมินผลการปฏิบัติงาน (PMS)",
"EvaluationResult": "ผลการประเมิน",
"Grade": "เกรด",
"EmployeeInformation": "ข้อมูลพนักงาน",
"NameSurname": "ชื่อ-สกุล",
"Email": "E-mail",
"StatusEva": "สถานะประเมิน",
"NotStarted": "ยังไม่ถึงขั้นตอนดำเนินการ",
"Pending": "รอดำเนินการ",
"InProgress": "อยู่ระหว่างดำเนินการ",
"Completed": "ดำเนินการเสร็จสิ้น",
"Appraisee": "ผู้รับการประเมิน",
"Timeline": "Timeline",
"CommentHere": "ใส่ Comment ที่นี่",
"Confirm": "ยืนยันข้อมูล",
"SaveDraft": "บันทึกร่าง",
"Assessor": "ผู้ประเมิน",
"ShowAll": "แสดงทั้งหมด",
"HideAll": "ปิดทั้งหมด",
"WeightedScoreByTargetDegree": "ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ",
"AvgScore": "คะแนนเฉลี่ย",
"Gap": "ผล Gap",
"Tools": "เครื่องมือ",
"Summary": "สรุป คะแนนประเมิน",
"TargetDegree": "ระดับความสามารถ (Target Degree)",
"TallyOfMarksPerRatingLevel1": "รวมจำนวนเครื่องหมายแต่ละช่อง (1)",
"ScoreMultiplierPerLevel2": "ตัวคูณคะแนนในแต่ละช่อง (2)",
"WeightedScore1x2": "ถ่วงน้ำหนักผลรวม 1X2",
"EmployeesWeightedScore": "คะแนนรวมหลังถ่วงน้ำหนัก",
"FinalAverageScore": "คะแนนเฉลี่ยคิดเป็น",
"CompetencyRatingScale": "เกณฑ์การให้คะแนนการประเมิน",
"RatingCriteria": "เกณฑ์การให้คะแนน",
"IfScore90to100": "หากได้คะแนน 90 - 100% ถือว่า Gap +1",
"IfScore80to89": "หากได้คะแนน 80 - 89% ถือว่า ไม่มี Gap",
"IfScore60to79": "หากได้คะแนน 60 - 79% ถือว่า Gap – 1",
"IfScore40to59": "หากได้คะแนน 40 - 59% ถือว่า Gap -2",
"IfScore0to39": "หากได้คะแนน 0 - 39% ถือว่า Gap – 3",
"Conditions": "เงื่อนไข",
"Condition1": "1.หากได้คะแนนสูงกว่า 80% แต่มี 3 2 หรือ 1 ด้วย ถือว่า Gap -1",
"Condition2": "2.หากได้คะแนนต่ำกว่า 80% แต่มี 4 และ 5 ให้คิด Gap ตาม %",
"Condition3": "3.คะแนนต่ำกว่า 80% แต่มี 2 และ 1 ให้คิด Gap ตาม %",
"AssessmentResultA": "ผลประเมิน (A)",
"GapResultEva": "สรุปผล Gap",
"EvaluationSummary": "สรุปผลประเมิน",
"NetScore": "สุทธิ",
"PART 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)": "PART 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)",
"PART 2 : ประเมินตัวชี้วัดของหน่วยงาน (Department KPI)": "PART 2 : ประเมินตัวชี้วัดของหน่วยงาน (Department KPI)",
"PART 3 : ประเมินตัวชี้วัดรายบุคคล (Individual KPI)": "PART 3 : ประเมินตัวชี้วัดรายบุคคล (Individual KPI)",
"PART 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)": "PART 4 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน (Competency)",
"PART 5 : อัตราการเข้างาน (Time Attendance)": "PART 5 : อัตราการเข้างาน (Time Attendance)",
"PART 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)": "PART 6 : งานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)",
"PART 7 : กิจกรรมพิเศษ (Special Activities)": "PART 7 : กิจกรรมพิเศษ (Special Activities)",
"PerformanceIndicator": "ตัวชี้วัด",
"Detail": "เพิ่มเติม",
"TargetDegreeKpi": "ค่าเป้าหมาย",
"RawScore": "คะแนนดิบ",
"SumOfWeights": "คำนวนถ่วงน้ำหนัก",
"AchievedScore": "คะแนนประเมินที่ได้",
"RawScorePercent": "คะแนนดิบคิดเป็นร้อยละ",
"FactorPercent": "ร้อยละของปัจจัย",
"AchievedScorePercent": "คะแนนที่ได้คิดเป็นร้อยละ",
"CompetencyPart4": "สมรรถนะ",
"TimeAttendancePart5": "อัตราการเข้างาน",
"CrossFunctionalProjectAssignment": "งานที่ได้รับมอบหมายเพิ่มเติม",
"SpecialActivities": "กิจกรรมพิเศษ",
"PART 8 : สรุปผลการปฏิบัติงาน (Summary)": "PART 8 : สรุปผลการปฏิบัติงาน (Summary)",
"EvaluationFactor": "การประเมินผล",
"RawScore%": "คะแนนดิบคิดเป็นร้อยละ",
"Factor%": "ร้อยละของปัจจัย",
"AchievedScore%": "คะแนนที่ได้คิดเป็นร้อยละ",
"NetScorePart8": "คะแนนสุทธิ",
"SummaryPart8": "รวม",
"PART 9 : name": "PART 9 : พฤติกรรมบุคคลที่เป็นจุดแข็ง จุดอ่อน และการพัฒนา (EMPLOYEE STRENGTHS , WEAKNESSES AND PLAN TO IMPROVED)",
"EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS": "พฤติกรรมที่เป็นจุดแข็ง (EMPLOYEE STRENGTHS AND ACCOMPLISHMENTS)",
"Suggested Learning Topics": "หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับจุดแข็ง)",
"PERFORMANCE AREAS WHICH NEED IMPROVEMENT": "พฤติกรรมที่เป็นจุดอ่อน (PERFORMANCE AREAS WHICH NEED IMPROVEMENT)",
"Suggested Learning Topics2": "หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับจุดอ่อน)",
"PLAN OF ACTION TOWARD IMPROVED PERFORMANCE": "พฤติกรรมที่ควรได้รับการพัฒนา (PLAN OF ACTION TOWARD IMPROVED PERFORMANCE)",
"Suggested Learning Topics3": "หัวข้อที่ต้องเรียนรู้เพิ่มเติม (สำหรับพฤติกรรมที่ควรได้รับการพัฒนา)",
"PART 10 : คำชมหรือรางวัลที่ได้รับ (Conversation, Feedback, Recognise : CFR)": "PART 10 : คำชมหรือรางวัลที่ได้รับ (Conversation, Feedback, Recognise : CFR)",
"Subordinate": "ผู้ใต้บังคับบัญชาประเมิน",
"CompletedEmployees": "ประเมินแล้ว",
"TotalEmployees": "ทั้งหมด",
"Approval": "การอนุมัติ",
"ApprovedEmployees": "อนุมัติแล้ว",
"EmployeesEva": "คน",
"PmsOverview": "ภาพรวม PMS",
"GradeA": "Grade A",
"GradeB": "Grade B",
"GradeC": "Grade C",
"GradeD": "Grade D",
"GradeE": "Grade E",
"SubordinateList": "รายชื่อผู้ใต้บังคับบัญชา",
"ApproveAll": "ยืนยันการอนุมัติ",
"Status": "ประเมิน",
"Result": "ผลประเมิน",
"AppraiserStatus": "สถานะผู้ประเมิน",
"JobPosition": "ตำแหน่งงาน",
"DirectReportScore%": "ประเมินตนเองคิดเป็นร้อยละ",
"DirectReportNetScore": "คะแนนสุทธิลูกน้อง",
"Part1GeneralInformation": "ส่วนที่ 1: ข้อมูลทั่วไป",
"SubordinatePart9": "ผู้ใต้บังคับบัญชา",
"Supervisor": "ผู้บังคับบัญชา",
"Section2DevelopmentPlan": "ส่วนที่ 2: แนวทางการพัฒนา",
"RemarkHRTraining": "หมายเหตุ : กรณี HR จัดอบรมให้ต้องเป็นไปตามเกณฑ์ที่ส่วนกลางกำหนดขึ้น",
"StandardIDP": "IDP มาตรฐาน",
"RevisedIDP": "IDP ปรับแก้ไข",
"CompetencyPart9": "สมรรถนะที่พัฒนา",
"BehaviorIndicatorsBIs": "ประเด็นตัวชี้พฤติกรรมที่ต้องพัฒนา",
"AssessmentToolsPart9": "เครื่องมือพัฒนา",
"CDRPart9": "หลักสูตรพัฒนาตาม CDR",
"DevelopmentPeriod": "ระยะเวลาที่พัฒนา",
"Job": "งาน",
"DivisionPart9": "ฝ่าย"
}
\ No newline at end of file
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