Commit d829e571 by Nattana Chaiyamat

ประเมินตนเอง

parent bb296e71
...@@ -72,8 +72,8 @@ export class ManageUserComponent { ...@@ -72,8 +72,8 @@ export class ManageUserComponent {
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
...@@ -60,8 +60,8 @@ export class RolePermissionConfigComponent { ...@@ -60,8 +60,8 @@ export class RolePermissionConfigComponent {
this.getConfigList() this.getConfigList()
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
...@@ -75,8 +75,8 @@ export class SetAPasswordComponent { ...@@ -75,8 +75,8 @@ export class SetAPasswordComponent {
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
...@@ -82,8 +82,8 @@ export class UserSettingsComponent { ...@@ -82,8 +82,8 @@ export class UserSettingsComponent {
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
...@@ -672,8 +672,8 @@ export class SubEmployeeRegistrationComponent { ...@@ -672,8 +672,8 @@ export class SubEmployeeRegistrationComponent {
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
<ng-container *ngTemplateOutlet="newCompetency"></ng-container> <ng-container *ngTemplateOutlet="competency"></ng-container>
<!-- <ng-container *ngTemplateOutlet="competency"></ng-container> --> <ng-template #competency>
<ng-template #newCompetency>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<div class="flex flex-row gap-2"> <div class="flex flex-row gap-2 relative">
<ng-container *ngFor="let appraisalCompentency of appraisalCompentencyList ;let i=index"> <ng-container *ngFor="let appraisalCompentency of appraisalCompentencyList ;let i=index">
<button type="button" class="flex justify-center !items-center border bg-white p-2 text-center" <button type="button" class="flex justify-center !items-center border bg-white p-2 text-center"
style="border-radius:20px;width: 100px" style="border-radius:20px;width: 100px"
...@@ -21,13 +20,13 @@ ...@@ -21,13 +20,13 @@
</ng-container> </ng-container>
<div class="flex justify-around !items-center border bg-white p-2 text-right" <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));"> style="border-radius:20px;width: 100px;margin-left: auto;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));">
<i class="bg-white cursor-pointer border ti ti-chevron-down" <i title="แสดงทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:10px;font-size:27px" (click)="allBiOpen(true)"></i> style="padding: 1px;border-radius:5px;font-size:27px" (click)="allBiOpen(true)"></i>
<i class="bg-white cursor-pointer border ti ti-chevron-up" <i title="ปิดทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px" (click)="allBiOpen(false)"></i> style="padding: 1px;border-radius:5px;font-size:27px" (click)="allBiOpen(false)"></i>
</div> </div>
</div> </div>
<div #scrollContainer class="flex flex-col gap-2 relative" style="height:40vh;overflow-y: auto;"> <div #scrollContainer class="flex flex-col gap-2 relative" style="overflow-y: auto;" [ngStyle]="{'height': canSave?'calc(100vh - 472px)':'calc(100vh - 343px)'}">
<ng-container *ngFor="let item2 of appraisalCompentencyFilter();let i = index;let f= first"> <ng-container *ngFor="let item2 of appraisalCompentencyFilter();let i = index;let f= first">
<button type="button" [attr.id]="'menu-' + i" class="p-4 w-full bg-secondary text-white text-left" <button type="button" [attr.id]="'menu-' + i" class="p-4 w-full bg-secondary text-white text-left"
style="border-radius:20px" style="border-radius:20px"
...@@ -134,7 +133,7 @@ ...@@ -134,7 +133,7 @@
</table> </table>
</ng-container> </ng-container>
</ng-container> </ng-container>
<button [attr.id]="'menu-' + appraisalCompentencyFilter().length" type="button" <button *ngIf="appraisalCompentencyFilter().length" [attr.id]="'menu-' + appraisalCompentencyFilter().length" type="button"
class="p-4 w-full bg-secondary text-white text-left" style="border-radius:20px" class="p-4 w-full bg-secondary text-white text-left" style="border-radius:20px"
(click)="scrollToMenu(appraisalCompentencyFilter().length);allBiOpen(!biOpen.get('สรุป'),'สรุป')"> (click)="scrollToMenu(appraisalCompentencyFilter().length);allBiOpen(!biOpen.get('สรุป'),'สรุป')">
<span style="padding-left:50px"> <span style="padding-left:50px">
...@@ -261,256 +260,4 @@ ...@@ -261,256 +260,4 @@
</ng-container> </ng-container>
</div> </div>
</div> </div>
</ng-template>
<ng-template #competency>
<div class="flex w-full">
<div class="ltr:border-r rtl:border-l border-gray-200 dark:border-white/10" style="width: 5rem">
<nav class="flex flex-col space-y-2 whitespace-nowrap" aria-label="Tabs" [attr.data-hs-tabs-vertical]="true">
<button *ngFor="let appraisalCompentency of appraisalCompentencyList ;let i=index"
(click)="getAppraisalCompentencyForm(i)" [class.active]="currentPart==appraisalCompentency.comType"
type="button"
class="hs-tab-active:bg-primary ltr:hs-tab-active:border-r-transparent rtl:hs-tab-active:border-l-transparent hs-tab-active:text-white dark:hs-tab-active:bg-transparent ltr:dark:hs-tab-active:border-r-gray-800 rtl:dark:hs-tab-active:border-l-gray-800 dark:hs-tab-active:text-primary -mr-px py-2 px-3 inline-flex items-center gap-2 text-sm font-medium text-center border text-gray-500 ltr:rounded-l-lg rtl:rounded-r-lg hover:text-gray-700 dark:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-gray-300 !p-2"
[id]="'hs-tab-js-vertical-item-'+i" [attr.data-hs-tab]="'#hs-tab-js-vertical-'+i"
[attr.aria-controls]="'hs-tab-js-vertical-'+i">
<div class="w-full flex items-center " style="justify-content :space-between;">
{{appraisalCompentency.comType}}
<span class="d-flex align-items-center justify-content-center rounded-circle text-white"
[class.bg-danger]="formRemain(i)" [class.bg-success]="!formRemain(i)">
<ng-container *ngIf="formRemain(i)">
{{formRemain(i)}}
</ng-container>
<i *ngIf="!formRemain(i)" class="ti ti-check"></i>
</span>
</div>
</button>
</nav>
</div>
<div class="flex-1 w-full">
<div *ngFor="let appraisalCompentency of appraisalCompentencyList ;let i=index" [id]="'hs-tab-js-vertical-'+i"
role="tabpanel" [class.hidden]="currentPart!=appraisalCompentency.comType"
[attr.aria-labelledby]="'hs-tab-js-vertical-item-'+i">
<div class="hs-accordion-group w-full" *ngIf="appraisalCompentency">
<ng-container>
<div class="pb-2rem px-2rem text-center">
<div class="font-size-18px font-weight-700 text-primary">
แบบประเมินสมรรถนะพนักงาน
</div>
</div>
<div class="pb-2rem px-2rem">
<div class="p-2 flex" style="justify-content :space-between;">
<div class="grid-cols-1">
<div class="text-gray-400">เครื่องมือประเมิน</div>
<div class="text-gray-400">O = แบบสังเกต</div>
<div class="text-gray-400">P = แบบการปฏิบัติงาน</div>
<div class="text-gray-400">D = การบันทึก/เอกสาร</div>
<div class="text-gray-400">I = การสัมภาษณ์</div>
<div class="text-gray-400">T = แบบทดสอบ</div>
</div>
<div class="grid-cols-1">
<div class="text-gray-400">คำชี้แจง</div>
<div class="text-gray-400">- ใช้วิธีประเมินโดย ผู้บังคับบัญชา = 100 %</div>
</div>
<div class="col-span-3 grid-cols-1">
<div class="text-gray-400">ระดับความสามารถ (Target Degree)</div>
<div class="text-gray-400">ระดับ 1 = ไม่มีความรู้พื้นฐานเลย ขาดทักษะในงาน</div>
<div class="text-gray-400">ระดับ 2 = มีความรู้ในงานบ้างแต่ยังไม่สามารถ ประยุกต์ใช้ในงานได้</div>
<div class="text-gray-400">ระดับ 3 = นำความรู้มาประยุกต์ใช้ในงานได้ ปฏิบัติงานเองได้ด้วยตัวเอง
แก้ไขปัญหาหน้างานได้</div>
<div class="text-gray-400">ระดับ 4 = สอนผู้อื่นได้ มีความคล่องตัว เชื่อมโยง ความรู้ในงานได้</div>
<div class="text-gray-400">ระดับ 5 = มีความชำนาญ เชี่ยวชาญ เป็นที่ยอมรับ ในองค์กร</div>
</div>
</div>
</div>
<div class="pb-2rem px-2rem">
<div *ngIf="appraisalCompentencyFilter().length">
<div class="hs-accordion-group w-full" data-hs-accordion-always-open>
<ng-container *ngFor="let item2 of appraisalCompentencyFilter();let i = index;let f= first">
<div
class="hs-accordion overflow-hidden bg-white border -mt-px first:rounded-t-sm last:rounded-b-sm dark:bg-bgdark dark:border-white/10"
[id]="'hs-primary-heading-'+i">
<button
class="hs-accordion-toggle hs-accordion-active:text-white hs-accordion-active:bg-secondary group py-4 px-5 inline-flex items-center justify-between gap-x-3 w-full font-semibold text-start text-gray-800 transition hover:text-gray-500 dark:hs-accordion-active:text-white dark:text-gray-200 dark:hover:text-white/80"
[attr.aria-controls]="'hs-primary-collapse-'+i" type="button">
<span class="d-flex align-items-center justify-content-center rounded-circle text-white"
[class.bg-danger]="inFormRemain(item2)" [class.bg-success]="!inFormRemain(item2)">
<ng-container *ngIf="inFormRemain(item2)">
{{inFormRemain(item2)}}
</ng-container>
<i *ngIf="!inFormRemain(item2)" class="ti ti-check"></i>
</span>
<span>
{{item2.groupAssessment1.competencyIndicatorsCourses1Mini.competencyIndicatorsCourses0.competencyTopic.competencyTopicId}}
:
{{item2.groupAssessment1.competencyIndicatorsCourses1Mini.competencyIndicatorsCourses0.competencyTopic.tdesc}}
</span>
<svg
class="hs-accordion-active:hidden hs-accordion-active:text-white hs-accordion-active:group-hover:text-white block w-3 h-3 text-gray-600 group-hover:text-gray-500 dark:text-white/70"
width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 5L8.16086 10.6869C8.35239 10.8637 8.64761 10.8637 8.83914 10.6869L15 5"
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
<svg
class="hs-accordion-active:block hs-accordion-active:text-white hs-accordion-active:group-hover:text-white hidden w-3 h-3 text-gray-600 group-hover:text-gray-500 dark:text-white/70"
width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 11L8.16086 5.31305C8.35239 5.13625 8.64761 5.13625 8.83914 5.31305L15 11"
stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
</button>
<div [id]="'hs-primary-collapse-'+i"
class="hs-accordion-content hidden !w-full overflow-hidden transition-[height] duration-300"
[attr.aria-labelledby]="'hs-primary-heading-'+i">
<div class="box-body">
<div class="space-y-4">
<ng-container
*ngFor="let bi of item2.groupAssessment1.competencyIndicatorsCourses1Mini.behavioralIndicatorsList;let i2 = index;let f = first">
<div class="p-4 border border-gray-200 dark:border-white/10 rounded-sm">
<div class="grid grid-cols-12 gap-6 space-y-4">
<div class="col-span-12 my-auto">
<p class="text-base mb-1 font-semibold">
{{bi.behavioralIndicators}}&nbsp;{{bi.assessmentId}}
</p>
</div>
<div class="col-span-12">
<div class="space-y-2">
<div class="grid grid-cols-12 gap-6 space-y-4 md:text-end">
<div class="col-span-12 my-auto">
<div class="flex items-center justify-center">
<div id="stars-busytext">
<bar-rating [ngClass]="{ 'no-interaction': !canEdit }"
[ngStyle]="{'opacity':bi.competencyBehavioral.scoreTopicExpectation?1:0.8}"
[rate]="bi.competencyBehavioral.scoreTopicExpectation" [max]="5"
[theme]="'square'"
[(ngModel)]="bi.competencyBehavioral.scoreTopicExpectation"
(ngModelChange)="calnumberCheck()"></bar-rating>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
<div class="pb-1rem px-2rem">
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">ระดับความสามารถ (Target Degree)</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-3 grid grid-cols-5">
<div class="col-span-1 text-center">
{{appraisalCompentency.masfromEvaluationAssessment1lList[0].numberCheck5}}</div>
<div class="col-span-1 text-center">
{{appraisalCompentency.masfromEvaluationAssessment1lList[0].numberCheck4}}</div>
<div class="col-span-1 text-center">
{{appraisalCompentency.masfromEvaluationAssessment1lList[0].numberCheck3}}</div>
<div class="col-span-1 text-center">
{{appraisalCompentency.masfromEvaluationAssessment1lList[0].numberCheck2}}</div>
<div class="col-span-1 text-center">
{{appraisalCompentency.masfromEvaluationAssessment1lList[0].numberCheck1}}</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">ตัวคูณคะแนนในแต่ละช่อง (2)</div>
<div class="col-span-3 grid grid-cols-5">
<div class="col-span-1 text-center">{{setting.data.settingScore5}}</div>
<div class="col-span-1 text-center">{{setting.data.settingScore4}}</div>
<div class="col-span-1 text-center">{{setting.data.settingScore3}}</div>
<div class="col-span-1 text-center">{{setting.data.settingScore2}}</div>
<div class="col-span-1 text-center">{{setting.data.settingScore1}}</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">ถ่วงน้ำหนักผลรวม 1X2</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]">{{calWeightScore(item)}}</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">คะแนนรวมหลังถ่วงน้ำหนัก</div>
<div class="col-span-3 grid grid-cols-5">
<div class="col-span-5 text-center">
{{showNumber(appraisalCompentency.masfromEvaluationAssessment1lList[0].weightedTotal)}}
</div>
</div>
</div>
<div class="py-2 grid grid-cols-11">
<div class="col-span-8">คะแนนเฉลี่ยคิดเป็น</div>
<div class="col-span-3 grid grid-cols-5">
<div class="col-span-5 text-center">
{{showNumber(appraisalCompentency.masfromEvaluationAssessment1lList[0].averageScore)}}
</div>
</div>
</div>
</div>
<div class="pb-2rem px-2rem">
<div class="overflow-auto rounded-top-0.65rem">
<table class="ti-custom-table ti-custom-table-head ti-custom-table-hover2">
<thead class="height-50px">
<tr class="font-size-12px">
<ng-container
*ngFor="let item of ['เกณฑ์การให้คะแนนการประเมิน','ผลประเมิน (A)','สรุปผล Gap'];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>
</th>
</ng-container>
</tr>
<tr class="font-size-12px">
<ng-container *ngFor="let item of ['เกณฑ์การให้คะแนน','เงื่อนไข']">
<th scope="col" class="relative px-10px py-10px bg-soft-secondary text-primary !text-center">
{{item}}
</th>
</ng-container>
</tr>
</thead>
<tbody *ngIf="checkSheet.length">
<tr *ngFor="let item of checkSheet;let i = index" (mouseenter)="hoveredCode2 = 'true'"
(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>
</div>
</td>
<td class="align-start" rowspan="2">
<div *ngFor="let item2 of item.condition">
<span>{{item2}} </span><br>
</div>
</td>
<td class="align-start text-center">
{{calAverage(appraisalCompentency.masfromEvaluationAssessment1lList[0].averageScore)}}
</td>
<td class="align-start text-center">
{{calGap(appraisalCompentency.masfromEvaluationAssessment1lList[0].averageScore)}}
</td>
</tr>
<tr (mouseenter)="hoveredCode2 = 'true'" (mouseleave)="hoveredCode2 = null"
[ngClass]="{ 'table-hover2': 'true' === hoveredCode2 }">
<td class="align-start !white-space-normal" colspan="4">
หมายเหตุ<br>
ผลการประเมินอาจมีการเปลี่ยนแปลงเงื่อนไขข้อ 1-3 เนื่องจากมีคะแนนต่ำกว่าเกณฑ์ในบางข้อ
</td>
</tr>
</tbody>
</table>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
</ng-template> </ng-template>
\ No newline at end of file
import { ViewportScroller } from '@angular/common'; import { ViewportScroller } from '@angular/common';
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { Competency, MasfromEvaluationAssessment2List } from 'src/app/shared/model/competency.model'; import { Competency, MasfromEvaluationAssessment2List } from 'src/app/shared/model/competency.model';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model'; import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { SettingAssessmentModel, MySettingAssessmentModel } from 'src/app/shared/model/setting-assessment.model'; import { SettingAssessmentModel, MySettingAssessmentModel } from 'src/app/shared/model/setting-assessment.model';
...@@ -13,7 +13,9 @@ import Swal from 'sweetalert2'; ...@@ -13,7 +13,9 @@ import Swal from 'sweetalert2';
styleUrls: ['./pms-competency.component.scss'] styleUrls: ['./pms-competency.component.scss']
}) })
export class PmsCompetencyComponent { export class PmsCompetencyComponent {
@Input() fCurrentPart = ""
currentPart = "" currentPart = ""
@Input() canSave = false
@Input() evaluateeId = "" @Input() evaluateeId = ""
@Input() evaluaterId = "" @Input() evaluaterId = ""
@Input() appraisalCompentencyList: Competency[] = [] @Input() appraisalCompentencyList: Competency[] = []
...@@ -24,9 +26,12 @@ export class PmsCompetencyComponent { ...@@ -24,9 +26,12 @@ export class PmsCompetencyComponent {
@Output() compentencyScore: EventEmitter<any> = new EventEmitter<any>(); @Output() compentencyScore: EventEmitter<any> = new EventEmitter<any>();
@Output() compentencyWeightScore: EventEmitter<any> = new EventEmitter<any>(); @Output() compentencyWeightScore: EventEmitter<any> = new EventEmitter<any>();
@Output() compentencyGap: EventEmitter<any> = new EventEmitter<any>(); @Output() compentencyGap: EventEmitter<any> = new EventEmitter<any>();
@Output() sendInforWeight: EventEmitter<any> = new EventEmitter<any>();
@Output() sendInforGap: EventEmitter<any> = new EventEmitter<any>();
@Input() canEdit = false @Input() canEdit = false
@Input() currentStep = "" @Input() currentStep = ""
@Input() dateIso = "" @Input() dateIso = ""
@Input() currentTap = ""
hoveredCode: string | null = null; hoveredCode: string | null = null;
hoveredCode2: string | null = null; hoveredCode2: string | null = null;
...@@ -53,6 +58,8 @@ export class PmsCompetencyComponent { ...@@ -53,6 +58,8 @@ export class PmsCompetencyComponent {
biScore: Map<string, number> = new Map<string, number>() biScore: Map<string, number> = new Map<string, number>()
@ViewChild('scrollContainer') scrollContainer!: ElementRef; @ViewChild('scrollContainer') scrollContainer!: ElementRef;
inforWeight: Map<string, string> = new Map<string, string>()
inforGap: Map<string, string> = new Map<string, string>()
constructor(private appraisalService: AppraisalService, constructor(private appraisalService: AppraisalService,
private employeeService: EmployeeService, private employeeService: EmployeeService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
...@@ -62,12 +69,20 @@ export class PmsCompetencyComponent { ...@@ -62,12 +69,20 @@ export class PmsCompetencyComponent {
} }
ngOnInit(): void { ngOnInit(): void {
if (this.appraisalCompentencyList.length) { if (this.appraisalCompentencyList.length) {
this.currentPart = this.currentPart == '' ? this.appraisalCompentencyList[0].comType : this.currentPart this.currentPart = this.fCurrentPart == '' ? this.appraisalCompentencyList[0].comType : this.fCurrentPart
} }
this.getAppraisalCompentencyForm(0) this.getAppraisalCompentencyForm(0)
this.getSettingList() this.getSettingList()
this.getEvaluatee() this.getEvaluatee()
} }
ngOnChanges(changes: SimpleChanges): void {
if (changes['currentTap']?.currentValue||changes['appraisalCompentencyList']?.currentValue) {
if (this.appraisalCompentencyList.length) {
this.currentPart = this.fCurrentPart == '' ? this.appraisalCompentencyList[0].comType : this.fCurrentPart
}
this.getAppraisalCompentencyForm(0)
}
}
getEvaluatee() { getEvaluatee() {
this.evaluatee.loading = true this.evaluatee.loading = true
...@@ -99,7 +114,12 @@ export class PmsCompetencyComponent { ...@@ -99,7 +114,12 @@ export class PmsCompetencyComponent {
getAppraisalCompentencyForm(index: number) { getAppraisalCompentencyForm(index: number) {
if (this.appraisalCompentencyList.length) { if (this.appraisalCompentencyList.length) {
this.appraisalCompentencyIndex = index this.appraisalCompentencyIndex = index
this.currentPart = this.appraisalCompentencyList[this.appraisalCompentencyIndex].comType if (this.fCurrentPart) {
this.currentPart = this.fCurrentPart
this.fCurrentPart = ''
} else {
this.currentPart = this.appraisalCompentencyList[this.appraisalCompentencyIndex].comType
}
this.biOpen.clear() this.biOpen.clear()
this.appraisalCompentencyFilter().forEach((x, i) => { this.appraisalCompentencyFilter().forEach((x, i) => {
this.biOpen.set(x.groupAssessment1.competencyIndicatorsCourses1Mini.competencyIndicatorsCourses0.competencyTopic.competencyTopicId, false) this.biOpen.set(x.groupAssessment1.competencyIndicatorsCourses1Mini.competencyIndicatorsCourses0.competencyTopic.competencyTopicId, false)
...@@ -270,6 +290,7 @@ export class PmsCompetencyComponent { ...@@ -270,6 +290,7 @@ export class PmsCompetencyComponent {
this.inFormRemain(data) this.inFormRemain(data)
).filter(data => data != 0).length ).filter(data => data != 0).length
this.allFormRemain() this.allFormRemain()
this.allWeightGap()
return remain return remain
} }
allFormRemain() { allFormRemain() {
...@@ -285,6 +306,14 @@ export class PmsCompetencyComponent { ...@@ -285,6 +306,14 @@ export class PmsCompetencyComponent {
this.compentencyForm.emit(this.appraisalCompentencyList) this.compentencyForm.emit(this.appraisalCompentencyList)
this.compentencyFormRemain.emit(remain) this.compentencyFormRemain.emit(remain)
} }
allWeightGap() {
this.appraisalCompentencyList.forEach(x => {
this.inforWeight.set(x.comType, x.masfromEvaluationAssessment1lList[0].averageScore + '')
this.inforGap.set(x.comType, this.calGap(x.masfromEvaluationAssessment1lList[0].averageScore) ?? '')
})
this.sendInforWeight.emit(this.inforWeight)
this.sendInforGap.emit(this.inforGap)
}
allBiOpen(status: boolean, part?: string) { allBiOpen(status: boolean, part?: string) {
this.biOpen.forEach((_, key) => { this.biOpen.forEach((_, key) => {
......
<ng-container *ngTemplateOutlet="evaluation"></ng-container> <ng-container *ngTemplateOutlet="evaluation"></ng-container>
<ng-template #evaluation> <ng-template #evaluation>
<div *ngIf="evaluationForm=='sup'" class="pt-1.5rem w-full min-height-50px justify-between items-center">
<div class="flex">
<button type="button"
class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 shadow-md text-blue-500 bg-white"
(click)="returnPath()">
<i class="ti ti-chevron-left"></i>
ย้อนกลับ
</button>
<div class="font-size-18px font-weight-700 align-center hover:text-primary pl-1rem hover:text-gray-900">
ประเมินผล PMS
</div>
</div>
</div>
<div class=" pt-1.5rem"> <div class=" pt-1.5rem">
<div class="flex flex-row gap-2"> <div class="flex flex-col gap-2">
<div class="flex flex-col gap-2 w-1/4"> <div class="flex flex-row gap-2">
<div class="w-full mb-2"> <div class="flex flex-col gap-2 w-1/4">
<div class="font-size-18px font-weight-700 text-primary"> <div class="w-full mb-2">
ประเมินผลประจำปี {{currentDate.getFullYear()}} <div class="font-size-18px font-weight-700 text-primary">
<div class="absolute " style="transform:translateY(-9px)">
<button type="button" *ngIf="evaluationForm=='sup'"
class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 shadow-md text-blue-500 bg-white"
(click)="returnPath()">
<i class="ti ti-chevron-left"></i>
ย้อนกลับ
</button>
</div>
<span class="whitespace-nowrap relative" [ngStyle]="{'left': evaluationForm=='sup' ? '105px':'0px'}">
ประเมินผลประจำปี {{currentDate.getFullYear()}}
</span>
</div>
</div> </div>
</div> </div>
<div class="flex flex-col gap-2" style="height:81vh;overflow-y: auto;"> <div class="flex flex-col w-3/4 gap-2">
<div class="w-full" *ngIf="compentency.data"> <div class="w-full mb-2 flex">
<div class="box m-0" style="border-radius:20px"> <div class="w-1/2 flex flex-row gap-2">
<div class="box-body py-2"> <ng-container *ngFor="let item of compentency.dataList; let i=index ; let f= first">
<div class="flex flex-row gap-2" <div class="font-size-18px font-weight-700">
[ngStyle]="{'justify-content': compentency.data.pms.gradeScore?'space-between':'center'}"> <span class="cursor-pointer"
<div [ngClass]="{'w-full': !compentency.data.pms.gradeScore,'w-1/2':compentency.data.pms.gradeScore}"> [ngClass]="{'text-secondary border-secondary border-b':compentency.data?.tdesc==item.tdesc,'hover:text-gray-900':!(compentency.data?.tdesc==item.tdesc)}"
<img [src]="evaluationForm=='sup'?'./assets/img/users/woman2.PNG':'./assets/img/users/man.PNG'" (click)="compentency.data?.tdesc !== item.tdesc && changeForm(item)">
class="w-24 h-24 rounded-full ring-4 ring-white/10 mx-auto" id="profile-img" alt="profile-img" /> {{item.tdesc}}
</div> </span>
<div *ngIf="compentency.data.pms.gradeScore" class="w-1/2 flex flex-col justify-center"
style="align-self: center;">
<div class="flex-1 flex flex-row gap-1 justify-center">
<div *ngFor="let item of [1,2,3,4,5]">
<i class="ti" style="font-size:20px"
[ngClass]="item <= gradeStar(compentency.data.pms.gradeScore) ? 'ti-star-filled text-warning' : 'ti-star text-gray-300'"></i>
</div>
</div>
<div class="flex-1 text-center">
{{compentency.data.pms.gradeScore? "GRADE : " + compentency.data.pms.gradeScore : ''}}
</div>
</div>
</div> </div>
</ng-container>
</div>
<div class="w-1/2">
<div class="font-size-18px font-weight-700 text-primary text-right">
สถานะผู้ประเมิน&nbsp;:&nbsp;{{currentStepText()}}
</div> </div>
</div> </div>
</div> </div>
<div class="w-full"> </div>
<div class="box m-0" style="border-radius:20px"> </div>
<div class="box-header"> <div class="flex flex-row gap-2">
<div class="flex justify-between"> <div class="flex flex-col gap-2 w-1/4" [class.hidden]="menuClose.get('ข้อมูลรายละเอียด')">
<h5 class="box-title">ข้อมูลพนักงาน</h5> <div class="flex flex-col gap-2" style="height:calc(100vh - 177px);overflow-y: auto;">
<div class="w-full" *ngIf="kpiScorePart.length > 0">
<div class="box m-0" style="border-radius:20px">
<div class="box-body py-2">
<div class="flex flex-row gap-2"
[ngStyle]="{'justify-content':kpiScorePart[kpiScorePart.length-1].score?'space-between':'center'}">
<div
[ngClass]="{'w-full': !kpiScorePart[kpiScorePart.length-1].score,'w-1/2':kpiScorePart[kpiScorePart.length-1].score}">
<img [src]="evaluationForm=='sup'?'./assets/img/users/woman2.png':'./assets/img/users/man.PNG'"
class="w-24 h-24 rounded-full ring-4 ring-white/10 mx-auto" id="profile-img"
alt="profile-img" />
</div>
<div *ngIf="kpiScorePart[kpiScorePart.length-1].score" class="w-1/2 flex flex-col justify-center"
style="align-self: center;">
<div class="flex-1 flex flex-row gap-1 justify-center">
<div *ngFor="let item of [1,2,3,4,5]">
<i class="ti" style="font-size:20px"
[ngClass]="item <= gradeStar(kpiScorePart[kpiScorePart.length-1].score) ? 'ti-star-filled text-warning' : 'ti-star text-gray-300'"></i>
</div>
</div>
<div class="flex-1 text-center">
{{kpiScorePart[kpiScorePart.length-1].score ? ("GRADE : " +
kpiScorePart[kpiScorePart.length-1].score) : ''}}
</div>
</div>
</div>
</div> </div>
</div> </div>
<div class="box-body py-2">
<table class="ti-custom-table border-0 ellipsis-text">
<tbody>
<tr class="!border-0">
<td class="font-medium !p-2">รหัสพนักงาน</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2">
{{evaluatee.data.employeeId}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">ตำเเหน่ง</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.position.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">ฝ่าย</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.bu1.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">แผนก</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.bu2.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">ส่วน</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.bu3.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">ส่วนย่อย 1</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.bu4.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2">ส่วนย่อย 2</td>
<td class="!p-2">:</td>
<td class="font-medium !p-2 !text-warp">
{{evaluatee.data.bu5.tdesc}}
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
</div> <div class="w-full">
<div class="w-full" *ngIf="currentTap=='แบบประเมินสมรรถนะ'"> <div class="box m-0" style="border-radius:20px">
<div class="box m-0" style="border-radius:20px"> <div class="box-header" [class.border-none]="menuClose.get('ข้อมูลพนักงาน')">
<div class="box-header"> <div class="flex justify-between">
<div class="flex justify-between"> <h5 class="box-title align-center">ข้อมูลพนักงาน</h5>
<h5 class="box-title">ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ</h5> <i *ngIf="menuClose.get('ข้อมูลพนักงาน')" 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="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('ข้อมูลพนักงาน',true)"></i>
</div>
</div>
<div class="box-body py-2" [class.hidden]="menuClose.get('ข้อมูลพนักงาน')">
<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="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start">
{{evaluatee.data.employeeId}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ตำเเหน่ง</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.position.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ฝ่าย</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu1.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">แผนก</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu2.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ส่วน</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu3.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ส่วนย่อย 1</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu4.tdesc}}
</td>
</tr>
<tr class="!border-0">
<td class="font-medium !p-2 align-start">ส่วนย่อย 2</td>
<td class="!p-2 align-start">:</td>
<td class="font-medium !p-2 align-start !text-warp">
{{evaluatee.data.bu5.tdesc}}
</td>
</tr>
</tbody>
</table>
</div> </div>
</div> </div>
<div class="box-body py-2"> </div>
<div class="w-full flex flex-col gap-2" *ngIf="compentency.data"> <div class="w-full" *ngIf="currentTap=='แบบประเมินสมรรถนะ'">
<div class="w-full flex flex-col gap-2 mt-2"> <div class="box m-0" style="border-radius:20px">
<div class="w-full flex flex-row gap-2"> <div class="box-header" [class.border-none]="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')">
<div class="flex-1 text-center font-size-18px font-weight-700" *ngFor="let item of [5,4,3,2,1]"> <div class="flex justify-between">
{{item}}</div> <h5 class="box-title align-center">ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ</h5>
</div> <i *ngIf="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')" title="แสดง"
<div class="w-full flex flex-row gap-2"> class="bg-white cursor-pointer border ti ti-chevron-down"
<div *ngFor="let item of [5,4,3,2,1]" style="padding: 1px;border-radius:10px;font-size:27px;height:33px"
class="flex-1 border border-secondary text-center align-center" (click)="menuClose.set('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ',false)"></i>
style="border-radius:10px;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));height: 30px;"> <i *ngIf="!menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')" title="ปิด"
{{compentencyScore[item-1]}} class="bg-white cursor-pointer border ti ti-chevron-up"
</div> style="padding: 1px;border-radius:10px;font-size:27px;height:33px"
</div> (click)="menuClose.set('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ',true)"></i>
</div> </div>
<div class="w-full mt-2 flex justify-center"> </div>
<div class="flex flex-row gap-2" style="width:80%"> <div class="box-body py-2" [class.hidden]="menuClose.get('ค่าถ่วงน้ำหนักของความสามารถในแต่ละระดับ')">
<div class="flex-1 font-size-18px font-weight-700 text-right align-center"> <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">
<div class="flex-1 text-center font-size-18px font-weight-700" *ngFor="let item of [5,4,3,2,1]">
{{item}}</div>
</div> </div>
<div class="flex-1 flex justify-center"> <div class="w-full flex flex-row gap-2">
<div class="w-3/4 border border-secondary text-center align-center" <div *ngFor="let item of [5,4,3,2,1]"
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;"> style="border-radius:10px;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));height: 30px;">
{{compentencyWeightScore}} {{compentencyScore[item-1]}}
</div> </div>
</div> </div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center"> </div>
ผล Gap <div class="w-full mt-2 flex justify-center">
</div> <div class="flex flex-row gap-2" style="width:80%">
<div class="flex-1 flex justify-center"> <div class="flex-1 font-size-18px font-weight-700 text-right align-center">
<div class="w-3/4 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;"> </div>
{{compentencyGap}} <div class="flex-1 flex justify-center items-center">
<div class="w-3/4 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;">
{{compentencyWeightScore}}
</div>
</div>
<div class="flex-1 font-size-18px font-weight-700 text-right align-center">
ผล Gap
</div>
<div class="flex-1 flex justify-center items-center">
<div class="w-3/4 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;">
{{compentencyGap}}
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -158,127 +200,152 @@ ...@@ -158,127 +200,152 @@
</div> </div>
</div> </div>
</div> </div>
</div> <div class="w-full" *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'||currentTap=='สรุปคะแนนและข้อเสนอแนะ'">
<div class="w-full" *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'||currentTap=='สรุปคะแนนและข้อเสนอแนะ'"> <div class="box m-0" style="border-radius:20px">
<div class="box m-0" style="border-radius:20px"> <div class="box-header" [class.border-none]="menuClose.get('สรุปผลประเมิน')">
<div class="box-header"> <div class="flex justify-between">
<div class="flex justify-between"> <h5 class="box-title align-center">สรุปผลประเมิน</h5>
<h5 class="box-title">สรุปผลประเมิน</h5> <i *ngIf="menuClose.get('สรุปผลประเมิน')" 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="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สรุปผลประเมิน',true)"></i>
</div>
</div> </div>
</div> <div class="box-body py-2" [class.hidden]="menuClose.get('สรุปผลประเมิน')">
<div class="box-body py-2"> <div class='flex flex-col' *ngFor="let item of kpiScorePart; let i=index">
<div class='flex flex-col' *ngFor="let item of kpiScorePart; let i=index"> <div class='flex flex-row'>
<div class='flex flex-row'> <div style="width: 25%;">
<div style="width: 25%;"> {{item.text}}
{{item.text}} </div>
</div> <div style="width: 10%;">
<div style="width: 10%;"> :
: </div>
</div> <div style="width: 65%;">
<div style="width: 65%;"> {{item.score}}
{{item.score}} </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="w-full" *ngIf="compentency.data">
<div class="w-full" *ngIf="compentency.data"> <div class="box m-0" style="border-radius:20px">
<div class="box m-0" style="border-radius:20px"> <div class="box-header" [class.border-none]="menuClose.get('สถานะการประเมิน')">
<div class="box-header"> <div class="flex justify-between">
<div class="flex justify-between"> <h5 class="box-title align-center">สถานะการประเมิน</h5>
<h5 class="box-title">สถานะการประเมิน</h5> <i *ngIf="menuClose.get('สถานะการประเมิน')" 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="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('สถานะการประเมิน',true)"></i>
</div>
</div>
<div class="box-body space-y-4 text-center" [class.hidden]="menuClose.get('สถานะการประเมิน')">
<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')">
<div class="mx-auto relative">
<div class="h-full flex items-center justify-center pb-4" style="width: 32px;">
<div class="h-full w-[3px] bg-gray-100 pointer-events-none"></div>
</div>
<div class="absolute rounded-full text-center align-center"
style="justify-items:center;top:-5px">
<span class="flex align-items-center justify-content-center rounded-circle text-white"
[class]="assessmentStatusClass(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))">
<i
[class]="assessmentStatusIcon(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))"></i>
</span>
</div>
</div>
<div class="flex w-full pb-4">
<div class="ltr:ml-5 rtl:mr-5 rounded-sm ltr:mr-auto rtl:ml-auto my-auto w-full space-y-3">
<div class="sm:flex">
<h3 class="text-start my-auto text-gray-500 dark:text-white/70" style="line-height: 1.5">
<span class="text-dark dark:text-white">
<ng-container *ngIf="i==0">
ผู้รับการประเมิน
</ng-container>
<ng-container *ngIf="i>0">
ผู้อนุมัติลำดับที่ {{i}}
</ng-container>
</span>
<br>
<span class="text-dark dark:text-white">
{{returnField(compentency.data,apsEmp+'.thFullName')}}
</span>
<br>
<p class="text-xs text-gray-500 dark:text-white/70">
{{assessmentStatusText(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))}}
</p>
</h3>
</div>
</div>
</div>
</div>
</ng-container>
</div> </div>
</div> </div>
<div class="box-body space-y-4 text-center"> </div>
<ng-container <div class="w-full" *ngIf="commentAllFilter().length">
*ngFor="let apsEmp of ['apsassessy','apsapprove1','apsapprove2','apsapprove3','apsapprove4','apsapprove5']; let i=index ; let f=first"> <div class="box m-0" style="border-radius:20px">
<div class="flex flex-row" *ngIf="returnField(compentency.data,apsEmp+'.thFullName')"> <div class="box-header" [class.border-none]="menuClose.get('Timeline')">
<div class="flex justify-between">
<h5 class="box-title align-center">Timeline</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"
(click)="menuClose.set('Timeline',false)"></i>
<i *ngIf="!menuClose.get('Timeline')" title="ปิด"
class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:10px;font-size:27px"
(click)="menuClose.set('Timeline',true)"></i>
</div>
</div>
<div class="box-body space-y-4 text-center" [class.hidden]="menuClose.get('Timeline')">
<div class="flex flex-row" *ngFor="let item of commentAllFilter(); let i=index">
<div class="mx-auto relative"> <div class="mx-auto relative">
<div class="h-full flex items-center justify-center pb-4" style="width: 32px;"> <div class="h-full flex items-center justify-center pb-4" style="width: 32px;">
<div class="h-full w-[3px] bg-gray-100 pointer-events-none"></div> <div class="h-full w-[3px] bg-gray-100 pointer-events-none"></div>
</div> </div>
<div class="absolute rounded-full text-center align-center" <div class="absolute rounded-full text-center align-center"
style="justify-items:center;top:-5px"> style="justify-items:center;top:-5px">
<span class="d-flex align-items-center justify-content-center rounded-circle text-white" <span class="flex align-items-center justify-content-center rounded-circle text-white"
[class]="assessmentStatusClass(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))"> [class]="statusCompetencyClass(item.statusType)">
<i <i [class]="statusCompetencyIcon(item.statusType)"></i>
[class]="assessmentStatusIcon(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))"></i>
</span> </span>
</div> </div>
</div> </div>
<div class="flex w-full pb-4"> <div class="flex w-full pb-4">
<div class="ltr:ml-5 rtl:mr-5 rounded-sm ltr:mr-auto rtl:ml-auto my-auto w-full space-y-3"> <div class="ltr:ml-5 rtl:mr-5 rounded-sm ltr:mr-auto rtl:ml-auto my-auto w-full space-y-3">
<div class="sm:flex"> <div class="w-full">
<h3 class="text-start my-auto text-gray-500 dark:text-white/70" style="line-height: 1.5"> <h3 class="text-start my-auto text-gray-500 dark:text-white/70" style="line-height: 1.5">
<span class="text-dark dark:text-white"> <span class="text-dark dark:text-white" style="white-space: nowrap;">
<ng-container *ngIf="i==0"> {{item.thFullName}}
ผู้รับการประเมิน
</ng-container>
<ng-container *ngIf="i>0">
ผู้อนุมัติลำดับที่ {{i}}
</ng-container>
</span> </span>
<br> <br>
<span class="text-dark dark:text-white"> <div style="display: flex;justify-content :space-between;">
{{returnField(compentency.data,apsEmp+'.thFullName')}} <p class="text-xs text-gray-500 dark:text-white/70">
</span> {{statusCompetencyText(item.statusType)}}
<br> </p>
<p class="text-xs text-gray-500 dark:text-white/70"> <p class="my-auto ltr:ml-auto rtl:mr-auto text-gray-500 dark:text-white/70 text-xs">
{{assessmentStatusText(compentency.data.currentStep,i,returnField(compentency.data,apsEmp+'.status'))}} {{convertDate(item.commentDate)}}
</p> </p>
</div>
</h3> </h3>
</div> </div>
</div> <div *ngIf="item.comment"
</div> class="border border-gray-200 bg-gray-50 dark:bg-black/20 dark:border-white/10 p-4 rounded-sm">
</div> <p class="text-start text-xs text-gray-500 dark:text-white/70" style="line-height: 1.5">
</ng-container> {{item.comment}}
</div> </p>
</div> </div>
</div>
<div class="w-full" *ngIf="commentAllFilter().length">
<div class="box m-0" style="border-radius:20px">
<div class="box-header">
<div class="flex justify-between">
<h5 class="box-title">Timeline</h5>
</div>
</div>
<div class="box-body space-y-4 text-center">
<div class="flex flex-row" *ngFor="let item of commentAllFilter(); let i=index">
<div class="mx-auto relative">
<div class="h-full flex items-center justify-center pb-4" style="width: 32px;">
<div class="h-full w-[3px] bg-gray-100 pointer-events-none"></div>
</div>
<div class="absolute rounded-full text-center align-center" style="justify-items:center;top:-5px">
<span class="d-flex align-items-center justify-content-center rounded-circle text-white"
[class]="statusCompetencyClass(item.statusType)">
<i [class]="statusCompetencyIcon(item.statusType)"></i>
</span>
</div>
</div>
<div class="flex w-full pb-4">
<div class="ltr:ml-5 rtl:mr-5 rounded-sm ltr:mr-auto rtl:ml-auto my-auto w-full space-y-3">
<div class="w-full">
<h3 class="text-start my-auto text-gray-500 dark:text-white/70" style="line-height: 1.5">
<span class="text-dark dark:text-white" style="white-space: nowrap;">
{{item.thFullName}}
</span>
<br>
<div style="display: flex;justify-content :space-between;">
<p class="text-xs text-gray-500 dark:text-white/70">
{{statusCompetencyText(item.statusType)}}
</p>
<p class="my-auto ltr:ml-auto rtl:mr-auto text-gray-500 dark:text-white/70 text-xs">
{{convertDate(item.commentDate)}}
</p>
</div>
</h3>
</div>
<div *ngIf="item.comment"
class="border border-gray-200 bg-gray-50 dark:bg-black/20 dark:border-white/10 p-4 rounded-sm">
<p class="text-start text-xs text-gray-500 dark:text-white/70" style="line-height: 1.5">
{{item.comment}}
</p>
</div> </div>
</div> </div>
</div> </div>
...@@ -287,143 +354,120 @@ ...@@ -287,143 +354,120 @@
</div> </div>
</div> </div>
</div> </div>
</div> <div class="flex flex-col gap-2"
<div class="flex flex-col w-3/4 gap-2"> [ngClass]="{ 'w-3/4': !menuClose.get('ข้อมูลรายละเอียด'), 'w-full':menuClose.get('ข้อมูลรายละเอียด')}">
<div class="w-full mb-2 flex"> <div class="w-full relative">
<div class="w-3/4 flex flex-row gap-2"> <div class="absolute h-full hover-visible" style="z-index: 1;transform: translateX(-15%);">
<ng-container *ngFor="let item of compentency.dataList; let i=index ; let f= first"> <div [title]="menuClose.get('ข้อมูลรายละเอียด')?'แสดงข้อมูลรายละเอียด':'ปิดข้อมูลรายละเอียด'"
<div class="font-size-18px font-weight-700"> (click)="menuClose.get('ข้อมูลรายละเอียด')?menuClose.set('ข้อมูลรายละเอียด',false):menuClose.set('ข้อมูลรายละเอียด',true)"
<span class="cursor-pointer" class="cursor-pointer hover-show h-full border"
[ngClass]="{'text-secondary border-secondary border-b':compentency.data?.tdesc==item.tdesc,'hover:text-gray-900':!(compentency.data?.tdesc==item.tdesc)}" style="border-right:0 ;align-content:center;background: linear-gradient(to right, rgb(237, 237, 237), rgb(245 , 245 , 245 ),rgb(255, 255, 255 , 0));border-radius:20px 0 0 20px">
(click)="selectDataList(item)"> <i *ngIf="menuClose.get('ข้อมูลรายละเอียด')" class="cursor-pointer ti ti-chevron-right "
{{item.tdesc}} style="padding: 1px;font-size:27px;height:33px" (click)="menuClose.set('ข้อมูลรายละเอียด',true)"></i>
</span> <i *ngIf="!menuClose.get('ข้อมูลรายละเอียด')" class="cursor-pointer ti ti-chevron-left "
style="padding: 1px;font-size:27px;height:33px" (click)="menuClose.set('ข้อมูลรายละเอียด',false)"></i>
</div> </div>
</ng-container>
</div>
<div class="w-1/4">
<div class="font-size-18px font-weight-700 text-primary text-right">
สถานะผู้ประเมิน&nbsp;:&nbsp;{{currentStepText()}}
</div> </div>
</div> <div class="box m-0" style="border-radius:20px">
</div> <div class="box-header">
<div class="w-full"> <div class="flex flex-row gap-2">
<div class="box m-0" style="border-radius:20px"> <ng-container
<div class="box-header"> *ngFor="let item of ['ข้อมูลการประเมิน','แบบประเมินสมรรถนะ','ประเมินผลการปฏิบัติงาน','สรุปคะแนนและข้อเสนอแนะ','แผนพัฒนาบุคคลากร']">
<div class="flex gap-2"> <button type="button" class="flex-1 flex flex-row border bg-white p-2 justify-center"
<button type="button" class="flex-1 border bg-white p-2 text-center" style="border-radius:20px" style="border-radius:20px" (click)="currentTap=item"
(click)="currentTap='ข้อมูลการประเมิน'" [ngClass]="{'!bg-primary text-white':currentTap==item}">
[ngClass]="{'!bg-primary text-white':currentTap=='ข้อมูลการประเมิน'}"> <span class="overflow-hidden text-ellipsis whitespace-nowrap align-center">
ข้อมูลการประเมิน {{item}}
</button> </span>
<button type="button" class="flex-1 flex justify-center !items-center border bg-white p-2 text-center" <ng-container *ngIf="item=='แบบประเมินสมรรถนะ'">
style="border-radius:20px" (click)="currentTap='แบบประเมินสมรรถนะ'" &nbsp;
[ngClass]="{'!bg-primary text-white':currentTap=='แบบประเมินสมรรถนะ'}"> <span class="flex align-center justify-content-center rounded-circle text-white"
แบบประเมินสมรรถนะ [class.bg-danger]="compentencyFormRemain" [class.bg-success]="!compentencyFormRemain">
&nbsp; <ng-container *ngIf="compentencyFormRemain">
<span class="d-flex align-items-center justify-content-center rounded-circle text-white" {{compentencyFormRemain}}
[class.bg-danger]="compentencyFormRemain" [class.bg-success]="!compentencyFormRemain"> </ng-container>
<ng-container *ngIf="compentencyFormRemain"> <i *ngIf="!compentencyFormRemain" class="ti ti-check"></i>
{{compentencyFormRemain}} </span>
</ng-container> </ng-container>
<i *ngIf="!compentencyFormRemain" class="ti ti-check"></i> <ng-container *ngIf="item=='ประเมินผลการปฏิบัติงาน'">
</span> &nbsp;
</button> <span class="flex align-items-center justify-content-center rounded-circle text-white"
<button type="button" class="flex-1 flex justify-center !items-center border bg-white p-2 text-center" [class.bg-danger]="kpiFormRemain" [class.bg-success]="!kpiFormRemain">
style="border-radius:20px" (click)="currentTap='ประเมินผลการปฏิบัติงาน'" <ng-container *ngIf="kpiFormRemain">
[ngClass]="{'!bg-primary text-white':currentTap=='ประเมินผลการปฏิบัติงาน'}"> {{kpiFormRemain}}
ประเมินผลการปฏิบัติงาน </ng-container>
&nbsp; <i *ngIf="!kpiFormRemain" class="ti ti-check"></i>
<span class="d-flex align-items-center justify-content-center rounded-circle text-white" </span>
[class.bg-danger]="kpiFormRemain" [class.bg-success]="!kpiFormRemain"> </ng-container>
<ng-container *ngIf="kpiFormRemain"> </button>
{{kpiFormRemain}} </ng-container>
</ng-container> </div>
<i *ngIf="!kpiFormRemain" class="ti ti-check"></i>
</span>
</button>
<button type="button" class="flex-1 border bg-white p-2 text-center" style="border-radius:20px"
(click)="currentTap='สรุปคะแนนและข้อเสนอแนะ'"
[ngClass]="{'!bg-primary text-white':currentTap=='สรุปคะแนนและข้อเสนอแนะ'}">
สรุปคะแนนและข้อเสนอแนะ
</button>
<button type="button" class="flex-1 border bg-white p-2 text-center" style="border-radius:20px"
(click)="currentTap='แผนพัฒนาบุคคลากร'"
[ngClass]="{'!bg-primary text-white':currentTap=='แผนพัฒนาบุคคลากร'}">
แผนพัฒนาบุคคลากร
</button>
</div> </div>
</div> <div class="box-body pt-2" *ngIf="compentency.data&&evaluaterId&&evaluateeId" [class.pb-0]="canSave">
<div class="box-body"> <div [class.hidden]="currentTap!='ข้อมูลการประเมิน'">
<ng-container *ngIf="currentTap=='ข้อมูลการประเมิน'"> <app-pms-information [statusType]="compentency.data.statusType" [canSave]="canSave"
<app-pms-information></app-pms-information> [appraisalPms]="compentency.data.pms" [appraisalCompentencyList]="compentency.data.competency"
</ng-container> [inforGap]="inforGap" [inforWeight]="inforWeight"
<ng-container *ngIf="currentTap=='แบบประเมินสมรรถนะ'&&compentency.data&&evaluaterId&&evaluateeId"> [kpiScore]="kpiScorePart.length > 1 ?kpiScorePart[kpiScorePart.length-2].score : ''"
<app-pms-competency [appraisalCompentencyList]="compentency.data.competency" [evaluaterId]="evaluaterId" [kpiGrade]="kpiScorePart.length > 0 ?kpiScorePart[kpiScorePart.length-1].score : ''"
[evaluateeId]="evaluateeId" [canEdit]="canEdit" [currentStep]="compentency.data.currentStep" [kpiName]="compentency.data.tdesc" (sendCurrentTap)="currentTap=$event"
[dateIso]="dateIso" (compentencyScore)="compentencyScore=$event" (sendCurrentPart)="currentPart=$event"></app-pms-information>
(compentencyWeightScore)="compentencyWeightScore=$event" (compentencyGap)="compentencyGap=$event" </div>
(compentencyFormRemain)="compentencyFormRemain=$event" <div [class.hidden]="currentTap!='แบบประเมินสมรรถนะ'">
(compentencyForm)="compentency.data.competency=$event"></app-pms-competency> <app-pms-competency [currentTap]="currentTap" [canSave]="canSave" [fCurrentPart]="currentPart"
</ng-container> [appraisalCompentencyList]="compentency.data.competency" [evaluaterId]="evaluaterId"
<ng-container *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'&&compentency.data&&evaluateeId&&evaluaterId"> [evaluateeId]="evaluateeId" [canEdit]="canEdit" [currentStep]="compentency.data.currentStep"
<ng-container *ngIf="compentency.data&&evaluateeId&&evaluaterId"> [dateIso]="dateIso" (compentencyScore)="compentencyScore=$event"
<app-pms-kpi [appraisalPms]="compentency.data.pms" [currentTap]="currentTap" (compentencyWeightScore)="compentencyWeightScore=$event" (compentencyGap)="compentencyGap=$event"
(compentencyFormRemain)="compentencyFormRemain=$event"
(compentencyForm)="compentency.data.competency=$event" (sendInforGap)="inforGap=$event"
(sendInforWeight)="inforWeight=$event"></app-pms-competency>
</div>
<div [class.hidden]="currentTap!='ประเมินผลการปฏิบัติงาน'&&currentTap!='สรุปคะแนนและข้อเสนอแนะ'">
<app-pms-kpi [canSave]="canSave" [appraisalPms]="compentency.data.pms" [currentTap]="currentTap"
[evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId" [canEdit]="canEdit" [evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId" [canEdit]="canEdit"
[currentStep]="compentency.data.currentStep" [dateIso]="dateIso" [currentStep]="compentency.data.currentStep" [dateIso]="dateIso"
(kpiFormRemain)="kpiFormRemain=$event" (scorePart)="kpiScorePart=$event" (kpiFormRemain)="kpiFormRemain=$event" (scorePart)="kpiScorePart=$event"
(kpiForm)="compentency.data.pms=$event"></app-pms-kpi> (kpiForm)="compentency.data.pms=$event"></app-pms-kpi>
</ng-container> </div>
</ng-container> <div [class.hidden]="currentTap!='แผนพัฒนาบุคคลากร'">
<ng-container *ngIf="currentTap=='สรุปคะแนนและข้อเสนอแนะ'&&compentency.data&&evaluateeId&&evaluaterId"> <app-pms-idp [currentTap]="currentTap" [canSave]="canSave" [appraisalIdp]="compentency.data.idp"
<app-pms-kpi [appraisalPms]="compentency.data.pms" [currentTap]="currentTap" [evaluaterId]="evaluaterId" [evaluaterId]="evaluaterId" [evaluateeId]="evaluateeId"
[evaluateeId]="evaluateeId" [canEdit]="canEdit" [currentStep]="compentency.data.currentStep" [canEdit]="evaluationForm=='sup'?canEdit:false" [currentStep]="compentency.data.currentStep"
[dateIso]="dateIso" (kpiFormRemain)="kpiFormRemain=$event" (scorePart)="kpiScorePart=$event" [dateIso]="dateIso" (idpForm)="compentency.data.idp=$event"></app-pms-idp>
(kpiForm)="compentency.data.pms=$event"></app-pms-kpi> </div>
</ng-container> </div>
<ng-container *ngIf="currentTap=='แผนพัฒนาบุคคลากร'&&compentency.data&&evaluateeId&&evaluaterId"> <div *ngIf="compentency.data&&canSave" class="box-footer text-end space-x-3 rtl:space-x-reverse">
<app-pms-idp [appraisalIdp]="compentency.data.idp" [evaluaterId]="evaluaterId" <div class="pb-4 space-y-3 dark:border-white/10">
[evaluateeId]="evaluateeId" [canEdit]="evaluationForm=='sup'?canEdit:false" <textarea type="text" class="ti-form-input" rows="2" placeholder="ใส่ Comment ที่นี่"
[currentStep]="compentency.data.currentStep" [dateIso]="dateIso" [(ngModel)]="comment"></textarea>
(idpForm)="compentency.data.idp=$event"></app-pms-idp> </div>
</ng-container> <button (click)="save('approve')" class="ti-btn m-0 ti-btn-soft-secondary"
</div> [disabled]="compentencyFormRemain||kpiFormRemain"
<div *ngIf="compentency.data&&canSave" class="box-footer text-end space-x-3 rtl:space-x-reverse"> [class.ti-btn-disabled]="compentencyFormRemain||kpiFormRemain">
<div class="py-4 space-y-3 border-t border-gray-200 dark:border-white/10"> <i class="ri-save-3-fill"></i>
<textarea type="text" class="ti-form-input" rows="4" placeholder="ใส่ Comment ที่นี่" <ng-container *ngIf="compentency.data.currentStep == '0'">
[(ngModel)]="comment"></textarea> ยืนยันข้อมูล
</ng-container>
<ng-container *ngIf="compentency.data.currentStep != '0'">
อนุมัติ
</ng-container>
</button>
<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>
บันทึกร่าง
</button>
<button (click)="save('noApprove')" class="ti-btn m-0 ti-btn-soft-danger"
*ngIf="compentency.data.currentStep != '0' && compentency.data.currentStep != '1'">
<i class="ri-reply-fill"></i>
ไม่อนุมัติ
</button>
</div> </div>
<button (click)="save('approve')" class="ti-btn m-0 ti-btn-soft-secondary"
[disabled]="compentencyFormRemain||kpiFormRemain"
[class.ti-btn-disabled]="compentencyFormRemain||kpiFormRemain">
<i class="ri-save-3-fill"></i>
<ng-container *ngIf="compentency.data.currentStep == '0'">
ยืนยันข้อมูล
</ng-container>
<ng-container *ngIf="compentency.data.currentStep != '0'">
อนุมัติ
</ng-container>
</button>
<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>
บันทึกร่าง
</button>
<button (click)="save('noApprove')" class="ti-btn m-0 ti-btn-soft-danger"
*ngIf="compentency.data.currentStep != '0' && compentency.data.currentStep != '1'">
<i class="ri-reply-fill"></i>
ไม่อนุมัติ
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</ng-template> </ng-template>
\ No newline at end of file
<div class="hidden" *ngIf="compentency.data">
<app-pms-competency [appraisalCompentencyList]="compentency.data.competency"
(compentencyFormRemain)="compentencyFormRemain=$event"></app-pms-competency>
<app-pms-kpi [appraisalPms]="compentency.data.pms" (kpiFormRemain)="kpiFormRemain=$event"></app-pms-kpi>
</div>
\ No newline at end of file
.hover-visible {
.hover-show {
opacity: 0;
}
}
.hover-visible:hover {
.hover-show {
opacity: 1;
}
}
...@@ -18,12 +18,11 @@ export class PmsFormEmployeeComponent { ...@@ -18,12 +18,11 @@ export class PmsFormEmployeeComponent {
@Input() evaluaterId = "" @Input() evaluaterId = ""
@Input() evaluationForm: 'self' | 'sup' = "self" @Input() evaluationForm: 'self' | 'sup' = "self"
evaluatee: { loading: boolean, data: EmployeeModel } = { loading: false, data: new MyEmployeeModel() } evaluatee: { loading: boolean, data: EmployeeModel } = { loading: false, data: new MyEmployeeModel() }
currentPart = ""
@Output() sendReturnPath: EventEmitter<any> = new EventEmitter<any>(); @Output() sendReturnPath: EventEmitter<any> = new EventEmitter<any>();
starRate = 5; starRate = 5;
url1 = ''; url1 = '';
url2 = ''; url2 = '';
selectedItems = []; selectedItems = [];
dropdownSettings = {}; dropdownSettings = {};
...@@ -39,8 +38,7 @@ export class PmsFormEmployeeComponent { ...@@ -39,8 +38,7 @@ export class PmsFormEmployeeComponent {
{ id: '5', itemName: 'Bootstrap' }, { id: '5', itemName: 'Bootstrap' },
]; ];
compentency: { loading: boolean, originalData?: CompetencyModel, data?: CompetencyModel, dataList: CompetencyModel[] } = { loading: false, data: undefined, dataList: [] }
compentency: { loading: boolean, data?: CompetencyModel, dataList: CompetencyModel[] } = { loading: false, data: undefined, dataList: [] }
canSave = false canSave = false
canEdit = false canEdit = false
canDraft = false canDraft = false
...@@ -54,8 +52,25 @@ export class PmsFormEmployeeComponent { ...@@ -54,8 +52,25 @@ export class PmsFormEmployeeComponent {
compentencyWeightScore = "" compentencyWeightScore = ""
compentencyGap = "" compentencyGap = ""
inforWeight: Map<string, string> = new Map<string, string>()
inforGap: Map<string, string> = new Map<string, string>()
kpiScorePart: { text: string, score: string }[] = [] kpiScorePart: { text: string, score: string }[] = []
menuClose: Map<string, boolean> = new Map<string, boolean>()
hasPushedState = false;
companyId = ""
constructor(
private router: Router,
private employeeService: EmployeeService,
private appraisalService: AppraisalService,
private cdr: ChangeDetectorRef,
private tokenService: TokenService
) {
}
currentStepText = () => { currentStepText = () => {
if (this.compentency.data) { if (this.compentency.data) {
if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) { if (this.compentency.data.apsassessy.employeeId == this.evaluaterId) {
...@@ -223,24 +238,11 @@ export class PmsFormEmployeeComponent { ...@@ -223,24 +238,11 @@ export class PmsFormEmployeeComponent {
year: 'numeric' year: 'numeric'
}); });
}; };
hasPushedState = false;
companyId = ""
handleBack = (event: PopStateEvent) => { handleBack = (event: PopStateEvent) => {
this.returnPath() this.returnPath()
this.router.navigate(['/supervisor-evaluation']); this.router.navigate(['/supervisor-evaluation']);
}; };
constructor(
private router: Router,
private employeeService: EmployeeService,
private appraisalService: AppraisalService,
private cdr: ChangeDetectorRef,
private tokenService: TokenService
) {
}
ngOnDestroy() { ngOnDestroy() {
window.removeEventListener('popstate', this.handleBack); window.removeEventListener('popstate', this.handleBack);
...@@ -280,7 +282,9 @@ export class PmsFormEmployeeComponent { ...@@ -280,7 +282,9 @@ export class PmsFormEmployeeComponent {
} }
selectDataList(data: CompetencyModel) { selectDataList(data: CompetencyModel) {
this.compentency.data = JSON.parse(JSON.stringify(data)) this.compentency.originalData = this.deepClone(data)
this.compentency.data = this.deepClone(data)
this.cdr.detectChanges()
if (this.compentency.data) { if (this.compentency.data) {
this.currentTap = "ข้อมูลการประเมิน" this.currentTap = "ข้อมูลการประเมิน"
this.compentency.data.commentAll.sort((a, b) => new Date(b.commentDate).getTime() - new Date(a.commentDate).getTime()); this.compentency.data.commentAll.sort((a, b) => new Date(b.commentDate).getTime() - new Date(a.commentDate).getTime());
...@@ -425,7 +429,7 @@ export class PmsFormEmployeeComponent { ...@@ -425,7 +429,7 @@ export class PmsFormEmployeeComponent {
type StepKey = 'apsassessy' | 'apsapprove1' | 'apsapprove2' | 'apsapprove3' | 'apsapprove4' | 'apsapprove5'; type StepKey = 'apsassessy' | 'apsapprove1' | 'apsapprove2' | 'apsapprove3' | 'apsapprove4' | 'apsapprove5';
const steps: StepKey[] = ['apsassessy', 'apsapprove1', 'apsapprove2', 'apsapprove3', 'apsapprove4', 'apsapprove5']; const steps: StepKey[] = ['apsassessy', 'apsapprove1', 'apsapprove2', 'apsapprove3', 'apsapprove4', 'apsapprove5'];
const stepIndex = parseInt(this.compentency.data.currentStep, 10); const stepIndex = parseInt(this.compentency.data.currentStep, 10);
const updatedData = JSON.parse(JSON.stringify(this.compentency.data)); const updatedData = this.deepClone(this.compentency.data)
if (approveStatus === '3' && stepIndex >= 2) { if (approveStatus === '3' && stepIndex >= 2) {
const prevKey: StepKey = steps[stepIndex - 1]; const prevKey: StepKey = steps[stepIndex - 1];
updatedData[prevKey] = { updatedData[prevKey] = {
...@@ -531,4 +535,162 @@ export class PmsFormEmployeeComponent { ...@@ -531,4 +535,162 @@ export class PmsFormEmployeeComponent {
} }
} }
} changeForm(item: CompetencyModel) {
const ignorePart = [
'competency',
'!competency[].apsassessy',
'!competency[].apsapprove1',
'!competency[].apsapprove2',
'!competency[].apsapprove3',
'!competency[].apsapprove4',
'!competency[].apsapprove5',
'!competency[].masfromEvaluationAssessment1lList[].apsassessyDate',
'!competency[].masfromEvaluationAssessment1lList[].apsapprove1Date',
'!competency[].masfromEvaluationAssessment1lList[].apsapprove2Date',
'!competency[].masfromEvaluationAssessment1lList[].apsapprove3Date',
'!competency[].masfromEvaluationAssessment1lList[].apsapprove4Date',
'!competency[].masfromEvaluationAssessment1lList[].apsapprove5Date',
'!competency[].masfromEvaluationAssessment1lList[].numberCheck1',
'!competency[].masfromEvaluationAssessment1lList[].numberCheck2',
'!competency[].masfromEvaluationAssessment1lList[].numberCheck3',
'!competency[].masfromEvaluationAssessment1lList[].numberCheck4',
'!competency[].masfromEvaluationAssessment1lList[].numberCheck5',
'!competency[].masfromEvaluationAssessment1lList[].weightedTotal',
'!competency[].masfromEvaluationAssessment1lList[].averageScore',
'pms',
'!pms.gradeScore',
'!pms.apsassessyDate',
'!pms.apsapprove1Date',
'!pms.apsapprove2Date',
'!pms.apsapprove3Date',
'!pms.apsapprove4Date',
'!pms.apsapprove5Date',
'!pms.netScore',
'!pms.part1SumScore',
'!pms.part2SumScore',
'!pms.part3SumScore',
'!pms.part4SumScore',
'!pms.part5SumScore',
'!pms.part6SumScore',
'!pms.part7SumScore',
]
const diffs = this.findDifferencesInclude(
this.compentency.data,
this.compentency.originalData,
ignorePart
);
if (diffs.mini.length) {
Swal.fire({
icon: 'warning',
title: 'มีการประเมินโดยที่ยังไม่มีการบันทึก',
text: 'คุณต้องการเปลี่ยนรอบการประเมินหรือไม่',
showCancelButton: true,
confirmButtonText: 'ยืนยัน',
cancelButtonText: 'ยกเลิก',
customClass: {
title: '!swal2-title-mt-20px',
actions: '!swal2-actions-mt-20px',
confirmButton: '!swal2-button-bg-green',
cancelButton: '!swal2-button-bg-gray',
},
}).then((result) => {
if (result.isConfirmed) {
this.selectDataList(item)
} else if (result.dismiss === Swal.DismissReason.cancel) {
}
})
} else {
this.selectDataList(item)
}
}
deepClone(obj: any) {
return JSON.parse(JSON.stringify(obj));
}
findDifferencesInclude(
obj1: any,
obj2: any,
rawPaths: string[] = [''],
prefix = ''
): { full: string[]; mini: string[] } {
const full: string[] = [];
const mini: string[] = [];
const includePaths = rawPaths.filter(p => !p.startsWith('!'));
const excludePaths = rawPaths
.filter(p => p.startsWith('!'))
.map(p => p.slice(1));
// แปลง excludePaths เป็น regex สำหรับตรวจสอบ
const excludePatterns = excludePaths.map(p => {
const pattern = p.replace(/\./g, '\\.').replace(/\[\]/g, '\\[\\d+\\]');
return new RegExp(`^${pattern}`);
});
const isExcluded = (path: string) => excludePatterns.some(r => r.test(path));
const isIncluded = (path: string) => {
if (includePaths.length === 0) return true;
return includePaths.some(inc => path.startsWith(inc));
};
// ฟังก์ชันช่วยสร้าง path ใหม่
const makePath = (base: string, key: string | number) =>
base ? (typeof key === 'number' ? `${base}[${key}]` : `${base}.${key}`) : String(key);
// เช็คกรณี array
if (Array.isArray(obj1) && Array.isArray(obj2)) {
const maxLength = Math.max(obj1.length, obj2.length);
for (let i = 0; i < maxLength; i++) {
const fullPath = makePath(prefix, i);
if (isExcluded(fullPath) || !isIncluded(fullPath)) continue;
const val1 = obj1[i];
const val2 = obj2[i];
if (val1 === val2) continue;
if (val1 && val2 && typeof val1 === 'object' && typeof val2 === 'object') {
const diffs = this.findDifferencesInclude(val1, val2, rawPaths, fullPath);
full.push(...diffs.full);
mini.push(...diffs.mini);
} else {
full.push(`${fullPath}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
const cleanFieldName = String(i);
mini.push(`${cleanFieldName}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
}
}
return { full, mini };
}
// กรณี object
const keys = new Set([
...(obj1 && typeof obj1 === 'object' ? Object.keys(obj1) : []),
...(obj2 && typeof obj2 === 'object' ? Object.keys(obj2) : []),
]);
for (const key of keys) {
const fullPath = makePath(prefix, key);
if (isExcluded(fullPath) || !isIncluded(fullPath)) continue;
const val1 = obj1?.[key];
const val2 = obj2?.[key];
if (val1 === val2) continue;
const bothAreObjects = val1 && val2 && typeof val1 === 'object' && typeof val2 === 'object';
if (bothAreObjects) {
const diffs = this.findDifferencesInclude(val1, val2, rawPaths, fullPath);
full.push(...diffs.full);
mini.push(...diffs.mini);
} else {
full.push(`${fullPath}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
const fieldName = String(key).replace(/\[\d+\]/g, '');
mini.push(`${fieldName}: ${JSON.stringify(val1)} !== ${JSON.stringify(val2)}`);
}
}
return { full, mini };
}
}
\ No newline at end of file
<ng-container *ngTemplateOutlet="idpEvaluation"></ng-container> <ng-container *ngTemplateOutlet="idpEvaluation"></ng-container>
<ng-template #idpEvaluation> <ng-template #idpEvaluation>
<ng-container *ngIf="appraisalIdp"> <ng-container *ngIf="appraisalIdp">
<div style="height: 46vh;overflow-y: auto;"> <div style="overflow-y: auto;" [ngStyle]="{'height': canSave?'calc(100vh - 414px)':'calc(100vh - 285pxpx)'}">
<div class="pb-2rem px-2rem"> <div class="pb-2rem">
<div class="font-size-18px font-weight-700 text-primary"> <div class="font-size-18px font-weight-700 text-primary">
แผนพัฒนาบุคคลากรรายบุคคล แผนพัฒนาบุคคลากรรายบุคคล
</div> </div>
</div> </div>
<div class="pb-2rem px-2rem"> <div class="pb-2rem">
<div class="font-size-18px font-weight-700 text-gray-500"> <div class="font-size-18px font-weight-700 text-gray-500">
ส่วนที่ 1: ข้อมูลทั่วไป ส่วนที่ 1: ข้อมูลทั่วไป
</div> </div>
</div> </div>
<div class="pb-2rem px-2rem"> <div class="pb-2rem">
<div class="grid grid-cols-6"> <div class="grid grid-cols-6">
<div class="col-span-6 grid grid-cols-6"> <div class="col-span-6 grid grid-cols-6">
<div class="col-span-3 border p-2 pb-4"> <div class="col-span-3 border p-2 pb-4">
...@@ -84,12 +84,12 @@ ...@@ -84,12 +84,12 @@
</div> </div>
</div> </div>
</div> </div>
<div class="pb-2rem px-2rem"> <div class="pb-2rem">
<div class="font-size-18px font-weight-700 text-gray-500"> <div class="font-size-18px font-weight-700 text-gray-500">
ส่วนที่ 2: แนวทางการพัฒนา ส่วนที่ 2: แนวทางการพัฒนา
</div> </div>
</div> </div>
<div class="py-1rem px-2rem"> <div class="py-1rem">
<div class="py-2 grid grid-cols-6 gap-3"> <div class="py-2 grid grid-cols-6 gap-3">
<div class="col-span-6">หมายเหตุ : กรณี HR จัดอบรมให้ต้องเป็นไปตามเกณฑ์ที่ส่วนกลางกำหนดขึ้น</div> <div class="col-span-6">หมายเหตุ : กรณี HR จัดอบรมให้ต้องเป็นไปตามเกณฑ์ที่ส่วนกลางกำหนดขึ้น</div>
<div class="col-span-6 grid grid-cols-6 gap-2"> <div class="col-span-6 grid grid-cols-6 gap-2">
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="pb-2rem px-2rem"> <div class="pb-2rem">
<div class=" rounded-top-0.65rem"> <div class=" rounded-top-0.65rem">
<table class="ti-custom-table ti-custom-table-head ti-custom-table-hover2"> <table class="ti-custom-table ti-custom-table-head ti-custom-table-hover2">
<thead class="height-50px"> <thead class="height-50px">
......
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, Output, SimpleChanges, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { Idp } from 'src/app/shared/model/competency.model'; import { Idp } from 'src/app/shared/model/competency.model';
import { CompetencycourseMiniModel, MyCompetencycourseMiniModel } from 'src/app/shared/model/competencycourse-mini.model'; import { CompetencycourseMiniModel, MyCompetencycourseMiniModel } from 'src/app/shared/model/competencycourse-mini.model';
...@@ -19,6 +19,7 @@ interface table { ...@@ -19,6 +19,7 @@ interface table {
styleUrls: ['./pms-idp.component.scss'] styleUrls: ['./pms-idp.component.scss']
}) })
export class PmsIdpComponent { export class PmsIdpComponent {
@Input() canSave = false
@Input() pathTitle: string[] = [] @Input() pathTitle: string[] = []
@Input() evaluationRoundId = "" @Input() evaluationRoundId = ""
@Input() evaluateeId = "" @Input() evaluateeId = ""
...@@ -31,6 +32,7 @@ export class PmsIdpComponent { ...@@ -31,6 +32,7 @@ export class PmsIdpComponent {
@Input() canEdit = false @Input() canEdit = false
@Input() dateIso = "" @Input() dateIso = ""
@Input() currentStep = "" @Input() currentStep = ""
@Input() currentTap = ""
@Output() idpForm: EventEmitter<any> = new EventEmitter<any>(); @Output() idpForm: EventEmitter<any> = new EventEmitter<any>();
competencycourse: { loading: boolean, data: CompetencycourseMiniModel[] } = { loading: false, data: [] } competencycourse: { loading: boolean, data: CompetencycourseMiniModel[] } = { loading: false, data: [] }
...@@ -54,6 +56,11 @@ export class PmsIdpComponent { ...@@ -54,6 +56,11 @@ export class PmsIdpComponent {
this.getFormIdp() this.getFormIdp()
this.getCompetencycourseMiniList() this.getCompetencycourseMiniList()
} }
ngOnChanges(changes: SimpleChanges): void {
if (changes['currentTap']?.currentValue||changes['appraisalIdp']?.currentValue) {
this.getFormIdp()
}
}
getCompetencycourseMiniList() { getCompetencycourseMiniList() {
this.competencycourse.loading = false this.competencycourse.loading = false
this.competencycourseService.getMiniList().subscribe({ this.competencycourseService.getMiniList().subscribe({
......
<p>pms-information works!</p> <div class="flex flex-col gap-2" style="overflow-y: auto;"
[ngStyle]="{'height': canSave?'calc(100vh - 414px)':'calc(100vh - 285px)'}">
<div class="flex">
<button type="button" class="p-4 w-full bg-secondary text-white text-left" style="border-radius:20px"
(click)="menuClose.set('Compentency',!menuClose.get('Compentency'))">
รายละเอียดประเมินสมรรถนะ (Compentency)
</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 text-center">คะแนนเฉลี่ย</th>
<th scope="col text-center">ผล GAP</th>
<th scope="col text-center">การจัดการ</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let item of appraisalCompentencyList; let i=index">
<tr class="border-b border-gray-200">
<td class="py-2" style="vertical-align: top">
{{item.masfromEvaluationAssessment1lList[0].competencyType.tdesc}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{formatThaiDate(item.masfromEvaluationRound.apsPeriodStart)}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{formatThaiDate(item.masfromEvaluationRound.apsPeriodEnd)}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{inforWeight.get(item.comType) !=='null'?inforWeight.get(item.comType): ''}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{inforGap.get(item.comType)!=='null'?inforGap.get(item.comType): ''}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
<div class="flex justify-center">
<button type="button" class="ti-btn rounded-sm"
[class]="statusButtonClass(statusType)"
(click)="sendCurrentTap.emit('แบบประเมินสมรรถนะ');sendCurrentPart.emit(statusType)"
style="height: 15px; width: 45px; font-size: 12px; display: flex; align-items: center; justify-content: center;margin-left:4px;">
{{item.comType}}
</button>
</div>
</td>
</tr>
</ng-container>
</tbody>
</table>
</ng-container>
<div class="flex" *ngIf="appraisalPms">
<button type="button" class="p-4 w-full bg-secondary text-white text-left" style="border-radius:20px"
(click)="menuClose.set('PMS',!menuClose.get('PMS'))">
รายละเอียดประเมินผลการปฏิบัติงาน (PMS)
</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 text-center">ผลการประเมิน</th>
<th scope="col text-center">เกรด</th>
<th scope="col text-center">การจัดการ</th>
</tr>
</thead>
<tbody>
<tr class="border-b border-gray-200">
<td class="py-2" style="vertical-align: top">
{{kpiName}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{formatThaiDate(appraisalPms.pmsMasfromEvaluationRoundModel.apsPeriodStart)}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{formatThaiDate(appraisalPms.pmsMasfromEvaluationRoundModel.apsPeriodEnd)}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{kpiScore}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
{{kpiGrade}}
</td>
<td class="py-2 text-center" style="vertical-align: top">
<div class="flex justify-center">
<button type="button" class="ti-btn rounded-sm" [class]="statusButtonClass(statusType)"
(click)="sendCurrentTap.emit('ประเมินผลการปฏิบัติงาน');sendCurrentPart.emit(statusType)"
style="height: 15px; width: 45px; font-size: 12px; display: flex; align-items: center; justify-content: center;margin-left:4px;">
PMS
</button>
</div>
</td>
</tr>
</tbody>
</table>
</ng-container>
</div>
\ No newline at end of file
import { Component } from '@angular/core'; import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Competency, Pms } from 'src/app/shared/model/competency.model';
@Component({ @Component({
selector: 'app-pms-information', selector: 'app-pms-information',
...@@ -6,5 +7,44 @@ import { Component } from '@angular/core'; ...@@ -6,5 +7,44 @@ import { Component } from '@angular/core';
styleUrls: ['./pms-information.component.scss'] styleUrls: ['./pms-information.component.scss']
}) })
export class PmsInformationComponent { export class PmsInformationComponent {
@Input() canSave = false
@Input() statusType = ''
@Input() inforWeight: Map<string, string> = new Map<string, string>()
@Input() inforGap: Map<string, string> = new Map<string, string>()
@Input() appraisalCompentencyList: Competency[] = []
@Input() appraisalPms?: Pms
@Input() kpiScore: string = ""
@Input() kpiGrade: string = ""
@Input() kpiName: string = ""
@Output() sendCurrentTap: EventEmitter<any> = new EventEmitter<any>();
@Output() sendCurrentPart: EventEmitter<any> = new EventEmitter<any>();
menuClose: Map<string, boolean> = new Map<string, boolean>()
statusButtonClass = (status: string) => {
if (status === "no access") {
return "ti-btn-soft-mute"
} else if (status === "pending") {
return "ti-btn-soft-secondary"
} else if (status === "evaluating") {
return "ti-btn-soft-warning"
} else if (status === "completed") {
return "ti-btn-soft-success"
} else if (status === "rejected") {
return "ti-btn-soft-danger"
} else {
return ""
}
}
formatThaiDate(dateStr?: string): string {
if (!dateStr) return ''
const months = [
'', 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน',
'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
];
const [year, month, day] = dateStr.split('-').map(Number);
const thaiYear = year + 543;
const thaiMonth = months[month];
return `${day} ${thaiMonth} ${thaiYear}`;
}
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
(click)="scrollToMenu(currentTap == 'ประเมินผลการปฏิบัติงาน'?('menu-part-'+(i+1)):('menu-part-'+(i+8)));currentPart=item;toggleAllParts(true,item)" (click)="scrollToMenu(currentTap == 'ประเมินผลการปฏิบัติงาน'?('menu-part-'+(i+1)):('menu-part-'+(i+8)));currentPart=item;toggleAllParts(true,item)"
style="border-radius:20px;width: 100px" style="border-radius:20px;width: 100px"
[ngClass]="{'!bg-primary text-white':currentPart==item}"> [ngClass]="{'!bg-primary text-white':currentPart==item}">
{{item}} <span class="leading-none">{{ item }}</span>
<ng-container *ngIf="currentTap == 'ประเมินผลการปฏิบัติงาน'"> <ng-container *ngIf="currentTap == 'ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="remainList()[i]>=0"> <ng-container *ngIf="remainList()[i]>=0">
&nbsp; &nbsp;
...@@ -26,15 +26,16 @@ ...@@ -26,15 +26,16 @@
</ng-container> </ng-container>
<div class="flex justify-around !items-center border bg-white p-2 text-right" <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));"> style="border-radius:20px;width: 100px;margin-left: auto;--tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity));">
<i class="bg-white cursor-pointer border ti ti-chevron-down" <i title="แสดงทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-down"
style="padding: 1px;border-radius:5px;font-size:27px" style="padding: 1px;border-radius:5px;font-size:27px"
(click)="toggleAllParts(true);currentPart=''"></i> (click)="toggleAllParts(true);currentPart=''"></i>
<i class="bg-white cursor-pointer border ti ti-chevron-up" <i title="ปิดทั้งหมด" class="bg-white cursor-pointer border ti ti-chevron-up"
style="padding: 1px;border-radius:5px;font-size:27px" style="padding: 1px;border-radius:5px;font-size:27px"
(click)="toggleAllParts(false);currentPart=''"></i> (click)="toggleAllParts(false);currentPart=''"></i>
</div> </div>
</div> </div>
<div #scrollContainer class="flex flex-col gap-2" style="height:40vh;overflow-y: auto;"> <div #scrollContainer class="flex flex-col gap-2" style="overflow-y: auto;"
[ngStyle]="{'height': canSave?'calc(100vh - 471px)':'calc(100vh - 342px)'}">
<ng-container *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'"> <ng-container *ngIf="currentTap=='ประเมินผลการปฏิบัติงาน'">
<ng-container *ngIf="appraisalPms?.part1Detail?.length then part1 else noData"></ng-container> <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?.part2Detail?.length then part2 else noData"></ng-container>
......
...@@ -27,6 +27,7 @@ export interface LevelStarModel { ...@@ -27,6 +27,7 @@ export interface LevelStarModel {
styleUrls: ['./pms-kpi.component.scss'] styleUrls: ['./pms-kpi.component.scss']
}) })
export class PmsKpiComponent { export class PmsKpiComponent {
@Input() canSave = false
data8List: Part8Model[] = [{ data8List: Part8Model[] = [{
id: 1, id: 1,
evaluationFactor: "Part 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)", evaluationFactor: "Part 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท (Corporate KPI)",
...@@ -114,11 +115,6 @@ export class PmsKpiComponent { ...@@ -114,11 +115,6 @@ export class PmsKpiComponent {
const key = targetDetail[index ?? 0] as keyof Part5Detail; const key = targetDetail[index ?? 0] as keyof Part5Detail;
return item[key]; return item[key];
} }
// ngOnChanges(changes: SimpleChanges): void {
// if (changes['evaluateeId']?.currentValue || changes['evaluaterId']?.currentValue) {
// this.toggleAllParts(this.evaluateeId == this.evaluaterId)
// }
// }
ngOnInit(): void { ngOnInit(): void {
this.partOpen.clear() this.partOpen.clear()
this.partShow = this.currentTap == 'ประเมินผลการปฏิบัติงาน' ? ['PART 1', 'PART 2', 'PART 3', 'PART 4', 'PART 5', 'PART 6', 'PART 7'] : ['PART 8', 'PART 9', 'PART 10'] this.partShow = this.currentTap == 'ประเมินผลการปฏิบัติงาน' ? ['PART 1', 'PART 2', 'PART 3', 'PART 4', 'PART 5', 'PART 6', 'PART 7'] : ['PART 8', 'PART 9', 'PART 10']
...@@ -128,8 +124,20 @@ export class PmsKpiComponent { ...@@ -128,8 +124,20 @@ export class PmsKpiComponent {
this.getPmsGroupGradeList() this.getPmsGroupGradeList()
this.getAppraisalPmsForm() this.getAppraisalPmsForm()
this.allFormRemain() this.allFormRemain()
this.sendScorePart()
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['currentTap']?.currentValue || changes['appraisalPms']?.currentValue) {
this.partOpen.clear()
this.partShow = this.currentTap == 'ประเมินผลการปฏิบัติงาน' ? ['PART 1', 'PART 2', 'PART 3', 'PART 4', 'PART 5', 'PART 6', 'PART 7'] : ['PART 8', 'PART 9', 'PART 10']
this.partShow.forEach(x => {
this.partOpen.set(x, false)
})
this.getAppraisalPmsForm()
this.allFormRemain()
this.sendScorePart()
}
} }
getAppraisalPmsForm() { getAppraisalPmsForm() {
this.data8List.forEach((x, i) => { this.data8List.forEach((x, i) => {
if (x.id == 1 && this.appraisalPms?.part1Percentage) { if (x.id == 1 && this.appraisalPms?.part1Percentage) {
...@@ -527,7 +535,8 @@ export class PmsKpiComponent { ...@@ -527,7 +535,8 @@ export class PmsKpiComponent {
sendScorePart() { sendScorePart() {
if (this.appraisalPms) { if (this.appraisalPms) {
const score = this.data8List.map((x, i) => ({ text: "PART " + (i + 1), score: this.numberFixed2(x.netScore) })).concat([{ text: "สุทธิ", score: this.calNetScore() + '' }, { text: "Grade", score: this.appraisalPms.gradeScore }]) const gradeScore = this.groupGrade.dataList.find(item => Math.ceil(+this.calNetScore()) >= item.gradeMinScore && Math.ceil(+this.calNetScore()) <= item.gradeMaxScore);
const score = this.data8List.map((x, i) => ({ text: "PART " + (i + 1), score: this.numberFixed2(x.netScore) })).concat([{ text: "สุทธิ", score: this.calNetScore() + '' }, { text: "Grade", score: gradeScore?.gradeDetail || '' }])
this.scorePart.emit(score) this.scorePart.emit(score)
} }
} }
......
<ng-container *ngIf="!onEdit"> <ng-container *ngIf="!onEdit">
<!-- <app-page-header [pathTitle]="pathTitle"></app-page-header> -->
<ng-container *ngTemplateOutlet="selfEvaluation"></ng-container> <ng-container *ngTemplateOutlet="selfEvaluation"></ng-container>
</ng-container> </ng-container>
<ng-template #selfEvaluation> <ng-template #selfEvaluation>
......
...@@ -95,8 +95,8 @@ export class SupervisorEvaluationComponent { ...@@ -95,8 +95,8 @@ export class SupervisorEvaluationComponent {
} }
decodeJWT(token: string) { decodeJWT(token: string) {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload let base64Url = token.split('.')[1];
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
......
...@@ -164,8 +164,8 @@ export class SidebarComponent { ...@@ -164,8 +164,8 @@ export class SidebarComponent {
} }
// decodeJWT(token: string) { // decodeJWT(token: string) {
// let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload // let base64Url = token.split('.')[1];
// let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง // let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
// let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { // let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
// return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); // return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
// }).join('')); // }).join(''));
......
...@@ -25111,14 +25111,14 @@ div:where(.swal2-container) div:where(.swal2-validation-message) { ...@@ -25111,14 +25111,14 @@ div:where(.swal2-container) div:where(.swal2-validation-message) {
} }
.text-soft-secondary { .text-soft-secondary {
color: rgb(var(--color-secondary) / 0.1); color: rgb(var(--color-secondary) / 0.25);
} }
.text-soft-secondary:hover { .text-soft-secondary:hover {
color: rgb(var(--color-secondary)); color: rgb(var(--color-secondary));
} }
.\!text-soft-secondary { .\!text-soft-secondary {
color: rgb(var(--color-secondary) / 0.1) !important; color: rgb(var(--color-secondary) / 0.25) !important;
} }
.\!text-soft-secondary:hover { .\!text-soft-secondary:hover {
color: rgb(var(--color-secondary)) !important; color: rgb(var(--color-secondary)) !important;
......
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