Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mySkill-x
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
angular
mySkill-x
Commits
2abf8a01
Commit
2abf8a01
authored
Oct 31, 2025
by
Nattana Chaiyamat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ติดตามหลังการประเมิน
parent
1e5e6bae
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1075 additions
and
5 deletions
+1075
-5
dashboard-routing.module.ts
src/app/components/dashboard/dashboard-routing.module.ts
+3
-1
dashboard.module.ts
src/app/components/dashboard/dashboard.module.ts
+5
-1
disciplinary-action.component.ts
...ents/disciplinary-action/disciplinary-action.component.ts
+1
-1
outstanding-performance.component.ts
...standing-performance/outstanding-performance.component.ts
+1
-1
supervisor-evaluation.component.html
...upervisor-evaluation/supervisor-evaluation.component.html
+1
-1
evaluation-confirmation.component.html
...ation-confirmation/evaluation-confirmation.component.html
+388
-0
evaluation-confirmation.component.scss
...ation-confirmation/evaluation-confirmation.component.scss
+144
-0
evaluation-confirmation.component.ts
...luation-confirmation/evaluation-confirmation.component.ts
+418
-0
post-evaluation-tracking.component.html
...aluation-tracking/post-evaluation-tracking.component.html
+46
-0
post-evaluation-tracking.component.scss
...aluation-tracking/post-evaluation-tracking.component.scss
+10
-0
post-evaluation-tracking.component.ts
...evaluation-tracking/post-evaluation-tracking.component.ts
+30
-0
setting-individual-kpi-supervisor.component.html
...pervisor/setting-individual-kpi-supervisor.component.html
+7
-0
employee.service.ts
src/app/shared/services/employee.service.ts
+3
-0
navservice.ts
src/app/shared/services/navservice.ts
+10
-0
style.css
src/assets/css/style.css
+8
-0
No files found.
src/app/components/dashboard/dashboard-routing.module.ts
View file @
2abf8a01
...
@@ -65,7 +65,8 @@ import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapp
...
@@ -65,7 +65,8 @@ import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapp
import
{
JobFamilyMatrixComponent
}
from
'../job-family-matrix/job-family-matrix.component'
;
import
{
JobFamilyMatrixComponent
}
from
'../job-family-matrix/job-family-matrix.component'
;
import
{
DocumentUploadManagerComponent
}
from
'../company-components/account-settings/document-upload-manager/document-upload-manager.component'
;
import
{
DocumentUploadManagerComponent
}
from
'../company-components/account-settings/document-upload-manager/document-upload-manager.component'
;
import
{
DisciplinaryActionComponent
}
from
'../disciplinary-action/disciplinary-action.component'
;
import
{
DisciplinaryActionComponent
}
from
'../disciplinary-action/disciplinary-action.component'
;
import
{
OutstandingPerformanceComponent
}
from
'../outstanding-performance/outstanding-performance.component'
;
import
{
OutstandingPerformanceComponent
}
from
'../outstanding-performance/outstanding-performance.component'
;
import
{
PostEvaluationTrackingComponent
}
from
'../post-evaluation-tracking/post-evaluation-tracking.component'
;
...
@@ -147,6 +148,7 @@ const routes: Routes = [
...
@@ -147,6 +148,7 @@ const routes: Routes = [
{
path
:
"ess/job-family-matrix"
,
title
:
'รายละเอียดกลุ่มงานตามวิชาชีพ'
,
component
:
JobFamilyMatrixComponent
},
{
path
:
"ess/job-family-matrix"
,
title
:
'รายละเอียดกลุ่มงานตามวิชาชีพ'
,
component
:
JobFamilyMatrixComponent
},
{
path
:
"ess/disciplinary-action"
,
title
:
'วินัยและการลงโทษ'
,
component
:
DisciplinaryActionComponent
},
{
path
:
"ess/disciplinary-action"
,
title
:
'วินัยและการลงโทษ'
,
component
:
DisciplinaryActionComponent
},
{
path
:
"ess/outstanding-performance"
,
title
:
'ผลงานดีเด่น'
,
component
:
OutstandingPerformanceComponent
},
{
path
:
"ess/outstanding-performance"
,
title
:
'ผลงานดีเด่น'
,
component
:
OutstandingPerformanceComponent
},
{
path
:
"ess/post-evaluation-tracking"
,
title
:
'ผลงานดีเด่น'
,
component
:
PostEvaluationTrackingComponent
},
]
]
}
}
];
];
...
...
src/app/components/dashboard/dashboard.module.ts
View file @
2abf8a01
...
@@ -219,6 +219,8 @@ import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix
...
@@ -219,6 +219,8 @@ import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix
import
{
DocumentUploadManagerComponent
}
from
'../company-components/account-settings/document-upload-manager/document-upload-manager.component'
;
import
{
DocumentUploadManagerComponent
}
from
'../company-components/account-settings/document-upload-manager/document-upload-manager.component'
;
import
{
DisciplinaryActionComponent
}
from
'../disciplinary-action/disciplinary-action.component'
;
import
{
DisciplinaryActionComponent
}
from
'../disciplinary-action/disciplinary-action.component'
;
import
{
OutstandingPerformanceComponent
}
from
'../outstanding-performance/outstanding-performance.component'
;
import
{
OutstandingPerformanceComponent
}
from
'../outstanding-performance/outstanding-performance.component'
;
import
{
PostEvaluationTrackingComponent
}
from
'../post-evaluation-tracking/post-evaluation-tracking.component'
;
import
{
EvaluationConfirmationComponent
}
from
'../post-evaluation-tracking/evaluation-confirmation/evaluation-confirmation.component'
;
export
const
MY_DATE_FORMATS
=
{
export
const
MY_DATE_FORMATS
=
{
parse
:
{
parse
:
{
...
@@ -377,7 +379,9 @@ export class CustomDateAdapter extends NativeDateAdapter {
...
@@ -377,7 +379,9 @@ export class CustomDateAdapter extends NativeDateAdapter {
JobFamilyMatrixComponent
,
JobFamilyMatrixComponent
,
DocumentUploadManagerComponent
,
DocumentUploadManagerComponent
,
DisciplinaryActionComponent
,
DisciplinaryActionComponent
,
OutstandingPerformanceComponent
OutstandingPerformanceComponent
,
PostEvaluationTrackingComponent
,
EvaluationConfirmationComponent
],
imports
:
[
],
imports
:
[
TranslateModule
,
TranslateModule
,
CommonModule
,
CommonModule
,
...
...
src/app/components/disciplinary-action/disciplinary-action.component.ts
View file @
2abf8a01
...
@@ -93,7 +93,7 @@ export class DisciplinaryActionComponent {
...
@@ -93,7 +93,7 @@ export class DisciplinaryActionComponent {
}
}
getEmployeeList
()
{
getEmployeeList
()
{
this
.
employee
.
loading
=
true
this
.
employee
.
loading
=
true
this
.
employeeService
.
getList
().
subscribe
({
this
.
employeeService
.
get
Subordinates
List
().
subscribe
({
next
:
response
=>
{
next
:
response
=>
{
this
.
employee
.
list
=
response
.
map
((
x
:
any
)
=>
new
MyEmployeeModel
(
x
))
this
.
employee
.
list
=
response
.
map
((
x
:
any
)
=>
new
MyEmployeeModel
(
x
))
this
.
employee
.
loading
=
false
this
.
employee
.
loading
=
false
...
...
src/app/components/outstanding-performance/outstanding-performance.component.ts
View file @
2abf8a01
...
@@ -93,7 +93,7 @@ export class OutstandingPerformanceComponent {
...
@@ -93,7 +93,7 @@ export class OutstandingPerformanceComponent {
}
}
getEmployeeList
()
{
getEmployeeList
()
{
this
.
employee
.
loading
=
true
this
.
employee
.
loading
=
true
this
.
employeeService
.
getList
().
subscribe
({
this
.
employeeService
.
get
Subordinates
List
().
subscribe
({
next
:
response
=>
{
next
:
response
=>
{
this
.
employee
.
list
=
response
.
map
((
x
:
any
)
=>
new
MyEmployeeModel
(
x
))
this
.
employee
.
list
=
response
.
map
((
x
:
any
)
=>
new
MyEmployeeModel
(
x
))
this
.
employee
.
loading
=
false
this
.
employee
.
loading
=
false
...
...
src/app/components/performance-evaluation/supervisor-evaluation/supervisor-evaluation.component.html
View file @
2abf8a01
...
@@ -204,7 +204,7 @@
...
@@ -204,7 +204,7 @@
</div>
</div>
</div>
</div>
<ng-container
*
ngIf=
"pageEvalution!=''"
>
<ng-container
*
ngIf=
"pageEvalution!=''"
>
<app-pms-form-employee
[
evaluationForm
]="'
sup
'"
[
currentTap
]="'
ข้อมูลการประเมิน
'"
<app-pms-form-employee
[
evaluationForm
]="'
sup
'"
[
currentTap
]="'
EvaluationInfo
'"
(
sendReturnPath
)="
pageEvalution=
''
;
getBossList
()
;
pathTitle =
['การประเมินผล',
'ประเมินโดยหัวหน้า']"
(
sendReturnPath
)="
pageEvalution=
''
;
getBossList
()
;
pathTitle =
['การประเมินผล',
'ประเมินโดยหัวหน้า']"
[
evaluaterId
]="
formEvaluation
.
evaluaterId
"
[
evaluateeId
]="
formEvaluation
.
evaluateeId
"
></app-pms-form-employee>
[
evaluaterId
]="
formEvaluation
.
evaluaterId
"
[
evaluateeId
]="
formEvaluation
.
evaluateeId
"
></app-pms-form-employee>
</ng-container>
</ng-container>
...
...
src/app/components/post-evaluation-tracking/evaluation-confirmation/evaluation-confirmation.component.html
0 → 100644
View file @
2abf8a01
<ng-container
*
ngIf=
"page==1"
>
<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"
>
รายละเอียดการประเมิน
</div>
<div
class=
"flex w-full mb-4"
>
<div
class=
"flex w-1/4 justify-between"
>
</div>
<div
class=
"flex w-3/4 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
"
(
ngModelChange
)="
setSyncfutionDataList
()"
>
<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>
<div
class=
"flex flex-col w-100"
>
<div
class=
"mb-4"
>
<ng-container
*
ngTemplateOutlet=
"Datagrid"
></ng-container>
</div>
</div>
</ng-container>
<ng-container
*
ngIf=
"page==2"
>
<app-pms-form-employee
[
evaluationForm
]="'
sup
'"
[
currentTap
]="'
EvaluationInfo
'"
(
sendReturnPath
)="
page=
1"
[
evaluaterId
]="
evaluaterId
"
[
evaluateeId
]="
evaluaterId
"
></app-pms-form-employee>
</ng-container>
<ng-template
#
Datagrid
>
<ejs-grid
#
grid
id=
'Grid'
[
locale
]="
locale
"
[
dataSource
]="
syncfution
.
dataList
"
[
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"
(
columnMenuClick
)="
onColumnMenuClick
($
event
)"
(
toolbarClick
)='
toolbarClick
($
event
)'
>
<e-columns>
<ng-container
*
ngFor=
"let col of syncfution.columns"
>
<ng-container
*
ngIf=
"col.headerText"
>
<e-column
[
field
]="
col
.
field
"
[
headerText
]="
col
.
headerText
"
[
width
]="
col
.
width
"
[
format
]="
col
.
format
"
[
isPrimaryKey
]="
col
.
isPrimaryKey
"
[
validationRules
]="
col
.
validationRules
"
[
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 | translate}}
</span>
</ng-template>
<!-- <ng-template #template let-data *ngIf="col.headerText=='EmployeeCode'">
<div class="flex-col gap-2">
<img class=" avatar shadow-none rounded-full !ring-transparent object-cover h-12 w-12"
[src]="data.picture?getImg(data.picture):'./assets/img/users/defaultperson.jpg'"
(error)="onImageError($event)">
{{data.employeeId}}
</div>
</ng-template>
<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.statusEdesc)"
style="height: 30px; width: auto; font-size: 12px; display: flex; align-items: center; justify-content: center;margin-left:4px;"
(click)="selectSubordinate(data);">
{{data.status}}
</button>
</div>
</ng-template> -->
</e-column>
</ng-container>
</ng-container>
<e-column
headerText=
'action'
textAlign=
'Center'
>
<ng-template
#
headerTemplate
let-data
>
<span
class=
"font-size-12px font-weight-700 text-primary"
>
{{'Action' | translate}}
</span>
</ng-template>
<ng-template
#
template
let-data
>
<i
class=
"ti ti-eye cursor-pointer i-gray fs-l px-1"
(
click
)="
page=
2"
></i>
<i
class=
"ti ti-file cursor-pointer i-gray fs-l px-1"
(
click
)="
openEmployeeDialog
()"
></i>
</ng-template>
</e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column
*
ngFor=
"let col of aggregatesSum"
[
field
]="
col
.
field
"
[
type
]="'
Sum
'"
[
footerTemplate
]="'
Sum:
${
Sum
}'"
[
groupFooterTemplate
]="'
Sum:
${
Sum
}'"
[
groupCaptionTemplate
]="
col
.
groupCaptionTemplate
"
[
format
]="
col
.
format
"
>
</e-column>
</e-columns>
</e-aggregate>
<e-aggregate>
<e-columns>
<e-column
*
ngFor=
"let col of aggregatesCount"
[
field
]="
col
.
field
"
[
type
]="'
Count
'"
[
footerTemplate
]="'
Count:
${
Count
}'"
[
groupFooterTemplate
]="'
Count:
${
Count
}'"
[
groupCaptionTemplate
]="
col
.
groupCaptionTemplate
"
[
format
]="
col
.
format
"
>
</e-column>
</e-columns>
</e-aggregate>
<e-aggregate>
<e-columns>
<e-column
*
ngFor=
"let col of aggregatesAvg"
[
field
]="
col
.
field
"
[
type
]="'
Average
'"
[
footerTemplate
]="'
Average:
${
Average
}'"
[
groupFooterTemplate
]="'
Average:
${
Average
}'"
[
groupCaptionTemplate
]="
col
.
groupCaptionTemplate
"
[
format
]="
col
.
format
"
>
</e-column>
</e-columns>
</e-aggregate>
<e-aggregate>
<e-columns>
<e-column
*
ngFor=
"let col of aggregatesMin"
[
field
]="
col
.
field
"
[
type
]="'
Min
'"
[
footerTemplate
]="'
Min:
${
Min
}'"
[
groupFooterTemplate
]="'
Min:
${
Min
}'"
[
groupCaptionTemplate
]="
col
.
groupCaptionTemplate
"
[
format
]="
col
.
format
"
>
</e-column>
</e-columns>
</e-aggregate>
<e-aggregate>
<e-columns>
<e-column
*
ngFor=
"let col of aggregatesMax"
[
field
]="
col
.
field
"
[
type
]="'
Max
'"
[
footerTemplate
]="'
Max:
${
Max
}'"
[
groupFooterTemplate
]="'
Max:
${
Max
}'"
[
groupCaptionTemplate
]="
col
.
groupCaptionTemplate
"
[
format
]="
col
.
format
"
>
</e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</ng-template>
<ng-template
#
employeeDialog
let-modal
>
<h3
mat-dialog-title
>
<!-- {{'รายงานสรุปผลการประเมิน' | translate}} -->
<div
class=
"relative"
>
<div
class=
"absolute"
style=
"top: -43px;"
>
{{'รายงานสรุปผลการประเมิน' | translate}}
</div>
<div
class=
"absolute"
style=
"right: 0;top: -43px;"
>
<button
type=
"button"
class=
"hs-dropdown-toggle ti-modal-clode-btn text-danger"
mat-button
[
mat-dialog-close
]
>
<span
class=
"sr-only"
>
Close
</span>
<i
class=
"ti ti-circle-x fs-xxl"
></i>
</button>
</div>
</div>
</h3>
<div
class=
"w-full flex justify-end mb-1rem"
>
<div
class=
"absolute flex"
style=
"z-index: 9;"
>
<div
class=
"px-1"
>
<button
type=
"button"
class=
"ti-btn ti-btn-soft-info h-45px m-0 shadow-md"
(
click
)="
exportPdf
()"
>
<span
class=
"e-btn-icon e-print e-icons e-icon-left"
></span>
Print
</button>
</div>
</div>
</div>
<mat-dialog-content>
<div
#
pdfArea
class=
"row w-full pdf-container"
style=
"justify-content: center;align-content: start;"
>
<div
class=
"row"
style=
"height: 1123px; width: 794px;justify-content: center;align-content: space-between;"
>
<div
class=
"row col-12"
>
<div
class=
"row col-12 pb-3"
style=
"background-color: hsl(214 58% 86% / 1);justify-content: center;align-content: start;"
>
<div
class=
"col-12 flex p-3 pt-0 "
style=
"justify-content: end;font-size:small;font-weight: bold;"
>
Performance Management System
</div>
<div
class=
"col-12 flex pb-3"
style=
"justify-content: center;font-size:x-large;font-weight: bold;"
>
Performance Management System ประจําปี 2568
</div>
<div
class=
"col-12 flex"
style=
"justify-content: center;font-size:larger;font-weight: bold;"
>
รหัส 60177 ชื่อพนักงาน น.ส.แววตา อาสา
</div>
<div
class=
"col-12 flex"
style=
"justify-content: center;font-size:larger;font-weight: bold;"
>
สังกัด/ฝ่าย/หน่วยงาน Administration
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-12 pb-3 pt-3"
style=
"font-size:larger;font-weight: bold;"
>
ส่วนที่ 1: ประวัติพนักงาน
</div>
<div
class=
"col-12 border row p-1"
>
<div
class=
"col-6 row"
>
<div
class=
"col-12"
style=
"align-content: center"
>
ตำแหน่งงาน : Payroll Officer
</div>
<div
class=
"col-12"
style=
"align-content: center"
>
ระดับ : S1
</div>
</div>
<div
class=
"col-6 row"
style=
"justify-content: end;"
>
<img
class=
"border"
[
src
]="'./
assets
/
img
/
users
/
defaultperson
.
jpg
'"
>
</div>
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-12 pb-3 pt-3"
style=
"font-size:larger;font-weight: bold;"
>
ส่วนที่ 2: ผลดําาเนินงานประจําปี 2568
</div>
<div
class=
"col-12 border row p-1"
>
<div
class=
"row col-12"
style=
"background-color: hsl(180.47deg 100% 25.29%);color: white;"
>
<div
class=
"col-9 row"
>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
การประเมินผล (Evaluation Factor)
</div>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
คะแนนดิบคิดเป็นร้อยละ
</div>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
ร้อยละของปัจจัย
</div>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
คะแนนที่ได้คิดเป็นร้อยละ
</div>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
คะแนนสุทธิ
</div>
</div>
<div
class=
"col-3"
></div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-9 row"
>
<ng-container
*
ngFor=
"let item of ['Part 1 : ประเมินผลการปฏิบัติงานตามนโยบายบริษัท',
'Part 2 : ประเมินผลการปฏิบัติงานประจํา (Job based KPIs)',
'Part 3 : ประเมินผลสมรรถนะที่สนับสนุนการปฏิบัติงาน',
'Part 4 : จํานวนการเข้างาน( Time Attendance)',
'Part 5: จานที่ได้รับมอบหมายเพิ่มเติม (Cross Functional Project Assignment)',
'Part 6: กิจกรรมพิเศษ (Special Activities)'],let i = index;let o = odd"
>
<div
class=
"col-12 row"
[
ngStyle
]="{'
background-color
'
:o
?'
hsl
(
0deg
0
%
90
.
2
%)'
:
'
white
'}"
>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
{{item}}
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
{{i}}
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
{{i}}
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
{{i}}
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
{{i}}
</div>
</div>
</ng-container>
<div
class=
"col-12 row"
>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
รวม
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
6
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
6
</div>
<div
class=
"col-2 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
6
</div>
</div>
</div>
<div
class=
"col-3 row"
>
<div
class=
"col-12"
style=
"align-content: center;"
>
<div
class=
"row border pl-1 pr-1 pb-3 pt-2"
>
<div
class=
"col-12 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
Final การประเมิน PMS
</div>
<div
class=
"col-12 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;background-color: hsl(214 58% 86% / 1)"
>
สรุปปี 2568
</div>
<div
class=
"col-12 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
คะแนน 75.76
</div>
<div
class=
"col-12 row pl-1 pr-1 pb-3 pt-2"
style=
"justify-content: center;"
>
Grade C
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-12 pb-3 pt-3"
style=
"font-size:larger;font-weight: bold;"
>
ส่วนที่ 3 : โปรดระบุรายละเอียดที่สําคัญของพนักงาน
</div>
<div
class=
"col-12 border-b row p-1"
>
เช่น รางวัล หรือผลงานดีเด่นในช่วงเวลาของการประเมิน(ผู้บังคับบัญชากรอก)
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-12 pb-3 pt-3"
style=
"font-size:larger;font-weight: bold;"
>
ส่วนที่ 4 จุดแข็ง จุดอ่อน ที่ต้องพัฒนา (ผู้บังคับบัญชากรอก)
</div>
<div
class=
"col-12 border row p-1"
>
<div
class=
"row col-12"
style=
"background-color: hsl(180.47deg 100% 25.29%);color: white;"
>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
วิเคราะห์
</div>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
รายละเอียด จุดแข็ง/จุดอ่อน
</div>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
หัวข้อที่ต้องเรียนรู้เพิ่มเติม
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
ผู้เสนอ
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
ผู้อนุมัติ
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
1. จุดแข็ง
</div>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
2. จุดอ่อนที่ต้องพัฒนา
</div>
<div
class=
"col-4 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-3 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
</div>
<div
class=
"col-1 pl-1 pr-1 pb-3 pt-2"
>
</div>
</div>
</div>
</div>
<div
class=
"row col-12"
>
<div
class=
"col-12 pb-3 pt-3"
>
หมายเหตุ: เกณฑ์การสรุปคะแนน
</div>
<div
class=
"col-12 row"
style=
"justify-content: center;"
>
<div
class=
"col-8 border p-1 row"
>
<ng-container
*
ngFor=
"let item of [{a:'A',b:'ดีเลิศ (Outstanding)',c:'>91'},
{a:'B',b:'ดีมาก (Above Expectations)',c:'>81-90'},
{a:'C',b:'ดี (Meet Expectations)',c:'>61-80'},
{a:'D',b:'ควรปรับปรุง (Below Expectations)' ,c:'>51-60'},
{a:'E',b:'ไม่น่าพอใจ (Unsatisfactory)',c:'<50'},]"
>
<div
class=
"row col-12"
>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
{{item.a}}
</div>
<div
class=
"col-8 pl-1 pr-1 pb-3 pt-2"
>
{{item.b}}
</div>
<div
class=
"col-2 pl-1 pr-1 pb-3 pt-2"
>
{{item.c}}
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div
class=
"row col-12 pb-3"
style=
"justify-content: space-between;margin-top: 2rem;"
>
<div
class=
"col-auto"
>
ลงชื่อ ............................ พนักงาน
</div>
<div
class=
"col-auto"
>
ลงชื่อ ............................ ผู้ตรวจสอบ
</div>
<div
class=
"col-auto"
>
ลงชื่อ ............................ ผู้อนุมัติ
</div>
</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"
>
ย้อนกลับ
</button>
<button
type=
"button"
(
click
)="
save
()"
class=
"ti-btn ti-btn-success"
>
รับทราบผล
</button>
</mat-dialog-actions>
</ng-template>
\ No newline at end of file
src/app/components/post-evaluation-tracking/evaluation-confirmation/evaluation-confirmation.component.scss
0 → 100644
View file @
2abf8a01
// th{
// position: relative; // เทียบเท่า class "relative"
// padding: 10px; // เทียบเท่า class "px-10px py-10px" (อาจเปลี่ยนตามต้องการ)
// background-color: rgb(96 165 250 / 0.1); // ตัวอย่างแทน "bg-soft-secondary"
// color: #2b2b2b; // ตัวอย่างแทน "text-primary"
// text-align: center !important; // เทียบเท่า "!text-center"
// // หากต้องการดีไซน์อื่น ๆ เพิ่มเติมก็ใส่ในนี้ได้เลย เช่น:
// font-weight: 600;
// border-bottom: 1px solid #eee;
// }
.e-headercell
,
.e-detailheadercell
{
background-color
:
rgb
(
96
165
250
/
0
.1
)
!
important
;
}
.e-pager
.e-currentitem
,
.e-pager
.e-currentitem
:hover
{
background
:
rgb
(
96
165
250
)
!
important
;
color
:
#fff
;
opacity
:
1
!
important
;
}
.e-checkbox-wrapper
.e-frame.e-check
,
.e-css.e-checkbox-wrapper
.e-frame.e-check
{
background-color
:
rgb
(
96
165
250
)
!
important
;
border-color
:
transparent
;
color
:
#fff
;
}
.e-checkbox-wrapper
.e-frame
,
.e-css.e-checkbox-wrapper
.e-frame
{
border
:
1px
solid
!
important
;
border-radius
:
2px
;
box-sizing
:
border-box
;
cursor
:
pointer
;
display
:
inline-block
;
font-family
:
"e-icons"
;
height
:
18px
;
line-height
:
10px
;
padding
:
2px
0
;
text-align
:
center
;
vertical-align
:
middle
;
width
:
1rem
!
important
;
border-color
:
#64748b
!
important
;
}
.e-grid
td
.e-selectionbackground
{
background-color
:
#aec2ec
!
important
;
}
.row
{
display
:
flex
;
flex-wrap
:
wrap
;
}
.col
{
flex
:
1
;
}
@for
$i
from
1
through
12
{
$width
:
(
$i
/
12
)
*
100%
;
.col-
#{
$i
}
{
flex
:
0
0
$width
;
max-width
:
$width
;
}
}
@for
$i
from
1
through
100
{
.m-
#{
$i
}
rem
{
margin
:
#{
$i
}
rem
;
}
.mt-
#{
$i
}
rem
{
margin-top
:
#{
$i
}
rem
;
}
.ml-
#{
$i
}
rem
{
margin-left
:
#{
$i
}
rem
;
}
.mb-
#{
$i
}
rem
{
margin-bottom
:
#{
$i
}
rem
;
}
.mr-
#{
$i
}
rem
{
margin-right
:
#{
$i
}
rem
;
}
.p-
#{
$i
}
rem
{
padding
:
#{
$i
}
rem
;
}
.pt-
#{
$i
}
rem
{
padding-top
:
#{
$i
}
rem
;
}
.pl-
#{
$i
}
rem
{
padding-left
:
#{
$i
}
rem
;
}
.pb-
#{
$i
}
rem
{
padding-bottom
:
#{
$i
}
rem
;
}
.pr-
#{
$i
}
rem
{
padding-right
:
#{
$i
}
rem
;
}
}
@media
print
{
body
*
{
visibility
:
hidden
;
/* ซ่อนทุก element */
}
#printArea
,
#printArea
*
{
visibility
:
visible
;
/* แสดงเฉพาะ #printArea */
}
#printArea
{
position
:
absolute
;
left
:
0
;
top
:
0
;
width
:
100%
;
}
}
.pdf-container
{
transform
:
translateZ
(
0
);
}
\ No newline at end of file
src/app/components/post-evaluation-tracking/evaluation-confirmation/evaluation-confirmation.component.ts
0 → 100644
View file @
2abf8a01
import
{
ChangeDetectorRef
,
Component
,
ElementRef
,
EventEmitter
,
Input
,
Output
,
SimpleChanges
,
ViewChild
}
from
"@angular/core"
;
import
{
MatDialog
,
MatDialogRef
}
from
"@angular/material/dialog"
;
import
{
Router
,
ActivatedRoute
}
from
"@angular/router"
;
import
{
TranslateService
}
from
"@ngx-translate/core"
;
import
{
AppraisalKpiSettingEmpModel
,
MyAppraisalKpiSettingEmpModel
,
MyPmsTypeModel
,
MyTopicModel
,
PmsTypeModel
,
TopicModel
}
from
"src/app/shared/model/appraisal-kpi-setting-emp.model"
;
import
{
EmployeeModel
,
MyEmployeeModel
}
from
"src/app/shared/model/employee.model"
;
import
{
AppraisalService
}
from
"src/app/shared/services/appraisal.service"
;
import
{
EmployeeService
}
from
"src/app/shared/services/employee.service"
;
import
{
FileService
}
from
"src/app/shared/services/file.service"
;
import
{
PmstypeService
}
from
"src/app/shared/services/pmstype.service"
;
import
{
TokenService
}
from
"src/app/shared/services/token.service"
;
import
{
ToastrService
}
from
'ngx-toastr'
;
import
Swal
from
'sweetalert2'
;
import
{
AggregateService
,
Column
,
ColumnMenuClickEventArgs
,
ColumnMenuService
,
ColumnModel
,
DetailRowService
,
EditService
,
ExcelExportProperties
,
ExcelExportService
,
FilterService
,
FilterSettingsModel
,
GridComponent
,
GroupService
,
GroupSettingsModel
,
LoadingIndicatorModel
,
PageService
,
PdfExportService
,
ReorderService
,
SearchService
,
SelectionSettingsModel
,
SortService
,
ToolbarService
}
from
"@syncfusion/ej2-angular-grids"
;
import
{
Query
}
from
'@syncfusion/ej2-data'
;
import
{
setCulture
}
from
'@syncfusion/ej2-base'
;
@
Component
({
selector
:
'app-evaluation-confirmation'
,
templateUrl
:
'./evaluation-confirmation.component.html'
,
providers
:
[
AggregateService
,
SortService
,
GroupService
,
ColumnMenuService
,
PageService
,
FilterService
,
ToolbarService
,
PdfExportService
,
ExcelExportService
,
DetailRowService
,
ReorderService
,
EditService
,
SearchService
],
styleUrls
:
[
'./evaluation-confirmation.component.scss'
]
})
export
class
EvaluationConfirmationComponent
{
page
=
1
search
=
''
syncfution
:
{
dataList
:
any
[],
searchSettings
:
{
fields
:
string
[],
operator
:
'contains'
,
ignoreCase
:
false
},
columns
:
ColumnModel
[]
}
=
{
dataList
:
[],
searchSettings
:
{
fields
:
[
'round'
,
'year'
,
'status'
],
operator
:
'contains'
,
ignoreCase
:
false
},
columns
:
[{
field
:
"round"
,
headerText
:
"รอบการประเมิน"
,
type
:
"string"
,
isPrimaryKey
:
true
,
},
{
field
:
"year"
,
headerText
:
"ปีการประเมิน"
,
type
:
"string"
},
{
field
:
"status"
,
headerText
:
"Status"
,
type
:
"string"
}]
}
@
ViewChild
(
'grid'
)
public
grid
?:
GridComponent
;
filterSettings
:
FilterSettingsModel
=
{
type
:
'Excel'
};
selectionOptions
:
SelectionSettingsModel
=
{
checkboxOnly
:
true
};
groupSettings
:
GroupSettingsModel
=
{
allowReordering
:
true
,
showGroupedColumn
:
true
,
showDropArea
:
false
};
toolbarOptions
:
any
[]
=
[
'Print'
,
'ExcelExport'
,
'CsvExport'
];
editSettings
?
=
{
allowEditing
:
true
,
mode
:
'Batch'
};
loadingIndicator
:
LoadingIndicatorModel
=
{
indicatorType
:
'Shimmer'
};
query
:
Query
=
new
Query
().
addParams
(
'dataCount'
,
'1000'
);
columnMenuItems
:
any
[]
=
[
'AutoFit'
,
'AutoFitAll'
,
'SortAscending'
,
'SortDescending'
,
'Group'
,
'Ungroup'
,
'ColumnChooser'
,
'Filter'
,
{
text
:
'Sum'
,
id
:
'aggregate_sum'
},
{
text
:
'Count'
,
id
:
'aggregate_count'
},
{
text
:
'Average'
,
id
:
'aggregate_average'
},
{
text
:
'Min'
,
id
:
'aggregate_min'
},
{
text
:
'Max'
,
id
:
'aggregate_max'
}
];
initialPage
?
=
{
pageSizes
:
true
,
pageSize
:
10
};
aggregatesSum
:
any
[]
=
[];
aggregatesCount
:
any
[]
=
[];
aggregatesAvg
:
any
[]
=
[];
aggregatesMin
:
any
[]
=
[];
aggregatesMax
:
any
[]
=
[];
locale
=
'th-TH'
@
ViewChild
(
'employeeDialog'
)
employeeDialog
:
any
employeeDialogRef
:
any
evaluaterId
=
''
constructor
(
private
appraisalService
:
AppraisalService
,
private
fileService
:
FileService
,
private
translateService
:
TranslateService
,
private
tokenService
:
TokenService
,
private
dialog
:
MatDialog
,
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'
}
]
this
.
setSyncfutionDataList
()
this
.
cdr
.
markForCheck
()
});
}
ngOnInit
():
void
{
this
.
evaluaterId
=
this
.
decodeJWT
(
sessionStorage
.
getItem
(
"accessToken"
)
||
''
).
employeeid
this
.
getEmpKpi
()
}
decodeJWT
(
token
:
string
)
{
let
base64Url
=
token
.
split
(
'.'
)[
1
];
let
base64
=
base64Url
.
replace
(
/-/g
,
'+'
).
replace
(
/_/g
,
'/'
);
let
jsonPayload
=
decodeURIComponent
(
atob
(
base64
).
split
(
''
).
map
(
function
(
c
)
{
return
'%'
+
(
'00'
+
c
.
charCodeAt
(
0
).
toString
(
16
)).
slice
(
-
2
);
}).
join
(
''
));
return
JSON
.
parse
(
jsonPayload
);
}
openEmployeeDialog
()
{
this
.
employeeDialogRef
=
this
.
dialog
.
open
(
this
.
employeeDialog
,
{
width
:
'1000px'
,
})
}
closeEmployeeDialog
()
{
this
.
employeeDialogRef
.
close
()
}
getEmpKpi
()
{
this
.
syncfution
.
dataList
=
[]
this
.
setSyncfutionDataList
()
// this.appraisalService.getEmpKpi().subscribe({
// next: response => {
// this.subordinate.dataList = response.map(e => new MyAppraisalKpiSettingModel(e))
// this.setSyncfutionDataList()
// this.cdr.markForCheck()
// }, error: error => {
// this.cdr.markForCheck()
// }
// })
}
setSyncfutionDataList
()
{
// this.syncfution.dataList = this.subordinateFilter().map(e => ({
// employeeId: e.apsassessy.employeeId,
// fullName: this.translateText(e.apsassessy.thFullName, e.apsassessy.engFullName),
// position: this.translateText(e.apsassessy.position.tdesc, e.apsassessy.position.edesc),
// status: this.translateText(e.statusApprove.tdesc, e.statusApprove.edesc),
// statusCode: e.statusApprove.code,
// statusEdesc: e.statusApprove.edesc,
// picture: e.apsassessy.picture
// }))
this
.
syncfution
.
dataList
=
this
.
dataFilter
().
map
(
e
=>
({
round
:
e
,
year
:
e
,
status
:
e
}))
}
dataFilter
()
{
return
[
1
,
2
,
3
,
4
].
filter
(
x
=>
{
return
(
x
+
''
).
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
})
}
onColumnMenuClick
(
args
:
ColumnMenuClickEventArgs
):
void
{
if
(
!
args
.
item
.
id
)
{
return
;
}
if
(
args
.
item
.
id
.
startsWith
(
'aggregate_'
))
{
const
colField
=
(
args
.
column
as
any
)?.
field
;
if
(
!
colField
)
{
return
;
}
const
selectedAgg
=
args
.
item
.
id
.
split
(
'_'
)[
1
];
if
(
selectedAgg
===
'sum'
)
{
if
(
this
.
aggregatesSum
.
find
(
a
=>
a
.
field
===
colField
))
{
this
.
aggregatesSum
=
this
.
aggregatesSum
.
filter
(
a
=>
a
.
field
!==
colField
);
}
else
{
this
.
aggregatesSum
.
push
({
field
:
colField
,
type
:
'Sum'
,
footerTemplate
:
'Sum: ${Sum}'
});
}
this
.
cdr
.
markForCheck
()
}
else
if
(
selectedAgg
===
'count'
)
{
this
.
aggregatesCount
.
push
({
field
:
colField
,
type
:
'Count'
,
footerTemplate
:
'Count: ${Count}'
});
}
else
if
(
selectedAgg
===
'average'
)
{
this
.
aggregatesAvg
.
push
({
field
:
colField
,
type
:
'Average'
,
footerTemplate
:
'Avg: ${Average}'
});
}
else
if
(
selectedAgg
===
'min'
)
{
this
.
aggregatesMin
.
push
({
field
:
colField
,
type
:
'Min'
,
footerTemplate
:
'Min: ${Min}'
});
}
else
if
(
selectedAgg
===
'max'
)
{
this
.
aggregatesMax
.
push
({
field
:
colField
,
type
:
'Max'
,
footerTemplate
:
'Max: ${Max}'
});
}
setTimeout
(()
=>
{
this
.
grid
?.
refresh
();
},
500
);
}
}
toolbarClick
(
args
:
any
):
void
{
if
(
args
.
item
.
id
===
'Grid_excelexport'
)
{
let
exportProperties
:
ExcelExportProperties
=
{
columns
:
this
.
syncfution
.
columns
.
map
(
col
=>
({
field
:
col
.
field
,
headerText
:
col
.
headerText
}))
as
Column
[]
};
this
.
grid
?.
excelExport
(
exportProperties
);
}
else
if
(
args
.
item
.
id
===
'Grid_csvexport'
)
{
let
exportColumns
=
this
.
syncfution
.
columns
.
map
(
col
=>
({
field
:
col
.
field
||
''
,
headerText
:
col
.
headerText
||
''
}));
this
.
grid
?.
csvExport
({
columns
:
exportColumns
as
Column
[]
});
}
else
if
(
args
.
item
.
id
===
'Grid_print'
)
{
this
.
cdr
.
markForCheck
()
setTimeout
(()
=>
{
this
.
cdr
.
markForCheck
()
},
1000
)
}
}
@
ViewChild
(
'pdfArea'
)
pdfArea
!
:
ElementRef
<
HTMLElement
>
;
async
exportPdf
()
{
const
el
=
this
.
pdfArea
?.
nativeElement
;
if
(
!
el
)
return
;
// 👉 ลบ shadow ออกจากทุก element ที่มี shadow class
const
shadowEls
=
el
.
querySelectorAll
(
'.shadow'
);
shadowEls
.
forEach
(
e
=>
e
.
classList
.
remove
(
'shadow'
));
const
mod
:
any
=
await
import
(
'html2pdf.js'
);
const
html2pdf
=
mod
.
default
??
mod
;
const
cleanupScale
=
this
.
expandToFullWidthThenScale
(
el
);
const
cleanupUnclip
=
this
.
unclipOverflows
(
el
);
const
prevBodyOverflow
=
document
.
body
.
style
.
overflow
;
document
.
body
.
style
.
overflow
=
'hidden'
;
const
fullW
=
el
.
scrollWidth
;
const
fullH
=
el
.
scrollHeight
;
const
epsilon
=
2
;
console
.
log
(
'🥷🏿Math.max(0, fullH - epsilon) --->'
,
Math
.
max
(
0
,
fullH
-
epsilon
));
const
opt
=
{
margin
:
[
10
,
10
,
10
,
10
],
filename
:
`test.pdf`
,
image
:
{
type
:
'jpeg'
,
quality
:
0.96
},
html2canvas
:
{
scale
:
2
,
useCORS
:
true
,
logging
:
false
,
scrollX
:
0
,
scrollY
:
-
window
.
scrollY
,
width
:
794
,
// height: Math.max(0, fullH - epsilon),
height
:
1123
,
windowWidth
:
794
,
// windowHeight: Math.max(0, fullH - epsilon),
windowHeight
:
1123
,
},
jsPDF
:
{
unit
:
'mm'
,
format
:
'a4'
,
orientation
:
'portrait'
},
pagebreak
:
{
mode
:
[
'css'
,
'legacy'
],
avoid
:
[
'.no-break'
,
'table'
,
'img'
]
},
onclone
:
(
doc
:
any
)
=>
{
doc
.
querySelectorAll
(
'[data-hide-in-pdf]'
).
forEach
((
el
:
any
)
=>
el
.
remove
());
},
};
try
{
await
html2pdf
().
from
(
el
).
set
(
opt
).
save
();
}
finally
{
cleanupUnclip
();
cleanupScale
();
document
.
body
.
style
.
overflow
=
prevBodyOverflow
;
// 👉 คืน class shadow กลับ
shadowEls
.
forEach
(
e
=>
e
.
classList
.
add
(
'shadow'
));
}
}
expandToFullWidthThenScale
(
el
:
HTMLElement
)
{
const
A4_PX
=
794
;
// ≈ 210mm @ 96dpi
const
full
=
el
.
scrollWidth
;
// ความกว้างจริงทั้งหมด (รวมพื้นที่ต้องเลื่อนขวา)
const
scale
=
Math
.
min
(
1
,
A4_PX
/
full
);
// สเกลลงให้พอดี A4 (ถ้ากว้างกว่า)
// เก็บค่าเดิมไว้คืนทีหลัง
const
prev
=
{
width
:
el
.
style
.
width
,
maxWidth
:
el
.
style
.
maxWidth
,
overflowX
:
el
.
style
.
overflowX
,
transform
:
el
.
style
.
transform
,
transformOrigin
:
el
.
style
.
transformOrigin
,
};
// คลี่ความกว้างออกทั้งหมด แล้วสเกลให้พอดี A4
el
.
style
.
width
=
`
${
full
}
px`
;
el
.
style
.
maxWidth
=
'none'
;
el
.
style
.
overflowX
=
'visible'
;
el
.
style
.
transformOrigin
=
'top left'
;
el
.
style
.
transform
=
`scale(
${
scale
}
)`
;
// คืนค่า
return
()
=>
{
el
.
style
.
width
=
prev
.
width
;
el
.
style
.
maxWidth
=
prev
.
maxWidth
;
el
.
style
.
overflowX
=
prev
.
overflowX
;
el
.
style
.
transform
=
prev
.
transform
;
el
.
style
.
transformOrigin
=
prev
.
transformOrigin
;
};
}
private
unclipOverflows
(
el
:
HTMLElement
)
{
const
patched
:
Array
<
{
node
:
HTMLElement
,
prev
:
Partial
<
CSSStyleDeclaration
>
}
>
=
[];
const
walker
=
document
.
createTreeWalker
(
el
,
NodeFilter
.
SHOW_ELEMENT
);
const
patchNode
=
(
node
:
HTMLElement
)
=>
{
const
style
=
window
.
getComputedStyle
(
node
);
const
needOverflowPatch
=
style
.
overflowX
!==
'visible'
||
style
.
overflow
!==
'visible'
;
const
isSticky
=
style
.
position
===
'sticky'
;
if
(
needOverflowPatch
||
isSticky
)
{
const
prev
=
{
overflow
:
node
.
style
.
overflow
,
overflowX
:
node
.
style
.
overflowX
,
overflowY
:
node
.
style
.
overflowY
,
position
:
node
.
style
.
position
,
clipPath
:
(
node
.
style
as
any
).
clipPath
,
};
patched
.
push
({
node
,
prev
});
node
.
style
.
overflow
=
'visible'
;
node
.
style
.
overflowX
=
'visible'
;
node
.
style
.
overflowY
=
'visible'
;
if
(
isSticky
)
node
.
style
.
position
=
'static'
;
(
node
.
style
as
any
).
clipPath
=
'none'
;
}
};
// รวม el เองด้วย
patchNode
(
el
as
HTMLElement
);
while
(
walker
.
nextNode
())
{
patchNode
(
walker
.
currentNode
as
HTMLElement
);
}
// ฟังก์ชันคืนค่าเดิม
return
()
=>
{
for
(
const
{
node
,
prev
}
of
patched
)
{
node
.
style
.
overflow
=
prev
.
overflow
||
''
;
node
.
style
.
overflowX
=
prev
.
overflowX
||
''
;
node
.
style
.
overflowY
=
prev
.
overflowY
||
''
;
node
.
style
.
position
=
prev
.
position
||
''
;
(
node
.
style
as
any
).
clipPath
=
prev
.
clipPath
||
''
;
}
};
}
save
()
{
Swal
.
fire
({
icon
:
'question'
,
title
:
'แจ้งเตือน'
,
text
:
'ยืนยันการบันทึกข้อมูลหรือไม่'
,
showCancelButton
:
true
,
confirmButtonText
:
'บันทึกข้อมูล'
,
cancelButtonText
:
'ย้อนกลับ'
,
reverseButtons
:
true
,
}).
then
((
result
)
=>
{
if
(
result
.
isConfirmed
)
{
this
.
showAlert
(
'บันทึกข้อมูลสำเร็จ'
,
'success'
)
this
.
closeEmployeeDialog
();
}
});
}
showAlert
(
text
:
string
,
type
:
'success'
|
'error'
)
{
Swal
.
fire
({
title
:
'แจ้งเตือน'
,
text
:
text
,
icon
:
type
,
confirmButtonText
:
'ตกลง'
,
});
}
}
src/app/components/post-evaluation-tracking/post-evaluation-tracking.component.html
0 → 100644
View file @
2abf8a01
<div
class=
" pt-1.5rem mb-2"
>
<div
class=
"flex flex-col gap-2"
>
<div
class=
"flex flex-col gap-2 w-full"
>
<div
class=
"w-full mb-2"
>
<div
class=
"font-size-18px font-weight-700 text-primary"
>
<span
class=
"whitespace-nowrap relative"
>
ติดตามหลังการประเมิน
</span>
</div>
</div>
<div
class=
"box shadow-md hover:shadow-xl transition m-0"
style=
"border-radius:20px"
>
<div
class=
"box-body py-2"
>
<nav
class=
"flex rtl:space-x-reverse space-x-2"
>
<a
style=
"border-radius: 20px;width: 210px;height: 35px;"
class=
" border justify-center rounded-4px hs-tab-active:!bg-primary hs-tab-active:border-primary hs-tab-active:!text-white -mb-px py-2 px-3 inline-flex items-center gap-2 font-size-16px font-weight-500 text-center text-gray-600 hover:text-gray-900 active"
href=
"javascript:void(0);"
id=
"card-type-item-1"
data-hs-tab=
"#card-type-1"
aria-controls=
"card-type-1"
>
{{'ผลการประเมิน' | translate}}
</a>
<a
style=
"border-radius: 20px;width: 210px;height: 35px;"
class=
"border justify-center rounded-4px hs-tab-active:!bg-primary hs-tab-active:border-primary hs-tab-active:!text-white -mb-px py-2 px-3 inline-flex items-center gap-2 font-size-16px font-weight-500 text-center text-gray-600 hover:text-gray-900"
href=
"javascript:void(0);"
id=
"card-type-item-2"
data-hs-tab=
"#card-type-2"
aria-controls=
"card-type-2"
>
{{'การติดตามผล Gap' | translate}}
</a>
<a
style=
"border-radius: 20px;width: 210px;height: 35px;"
class=
"border justify-center rounded-4px hs-tab-active:!bg-primary hs-tab-active:border-primary hs-tab-active:!text-white -mb-px py-2 px-3 inline-flex items-center gap-2 font-size-16px font-weight-500 text-center text-gray-600 hover:text-gray-900"
href=
"javascript:void(0);"
id=
"card-type-item-3"
data-hs-tab=
"#card-type-3"
aria-controls=
"card-type-3"
>
{{'ติดตามผล Gap โดยหัวหน้า' | translate}}
</a>
</nav>
<div
class=
"pt-20px"
>
<div
id=
"card-type-1"
role=
"tabpanel"
aria-labelledby=
"card-type-item-1"
>
<app-evaluation-confirmation></app-evaluation-confirmation>
</div>
<div
id=
"card-type-2"
class=
"hidden"
role=
"tabpanel"
aria-labelledby=
"card-type-item-2"
>
<app-evaluation-confirmation></app-evaluation-confirmation>
</div>
<div
id=
"card-type-3"
class=
"hidden"
role=
"tabpanel"
aria-labelledby=
"card-type-item-3"
>
<app-evaluation-confirmation></app-evaluation-confirmation>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
src/app/components/post-evaluation-tracking/post-evaluation-tracking.component.scss
0 → 100644
View file @
2abf8a01
.hover-visible
{
.hover-show
{
opacity
:
0
;
}
}
.hover-visible
:hover
{
.hover-show
{
opacity
:
1
;
}
}
src/app/components/post-evaluation-tracking/post-evaluation-tracking.component.ts
0 → 100644
View file @
2abf8a01
import
{
ChangeDetectorRef
,
Component
,
EventEmitter
,
Input
,
Output
,
SimpleChanges
,
ViewChild
}
from
"@angular/core"
;
import
{
MatDialog
,
MatDialogRef
}
from
"@angular/material/dialog"
;
import
{
Router
,
ActivatedRoute
}
from
"@angular/router"
;
import
{
TranslateService
}
from
"@ngx-translate/core"
;
import
{
AppraisalKpiSettingEmpModel
,
MyAppraisalKpiSettingEmpModel
,
MyPmsTypeModel
,
MyTopicModel
,
PmsTypeModel
,
TopicModel
}
from
"src/app/shared/model/appraisal-kpi-setting-emp.model"
;
import
{
EmployeeModel
,
MyEmployeeModel
}
from
"src/app/shared/model/employee.model"
;
import
{
AppraisalService
}
from
"src/app/shared/services/appraisal.service"
;
import
{
EmployeeService
}
from
"src/app/shared/services/employee.service"
;
import
{
FileService
}
from
"src/app/shared/services/file.service"
;
import
{
PmstypeService
}
from
"src/app/shared/services/pmstype.service"
;
import
{
TokenService
}
from
"src/app/shared/services/token.service"
;
import
{
ToastrService
}
from
'ngx-toastr'
;
import
Swal
from
'sweetalert2'
;
import
{
Column
,
ColumnMenuClickEventArgs
,
ColumnModel
,
ExcelExportProperties
,
FilterSettingsModel
,
GridComponent
,
GroupSettingsModel
,
LoadingIndicatorModel
,
SelectionSettingsModel
}
from
"@syncfusion/ej2-angular-grids"
;
import
{
Query
}
from
'@syncfusion/ej2-data'
;
import
{
setCulture
}
from
'@syncfusion/ej2-base'
;
@
Component
({
selector
:
'app-post-evaluation-tracking'
,
templateUrl
:
'./post-evaluation-tracking.component.html'
,
styleUrls
:
[
'./post-evaluation-tracking.component.scss'
]
})
export
class
PostEvaluationTrackingComponent
{
@
Output
()
sendPathTitle
:
EventEmitter
<
string
[]
>
=
new
EventEmitter
<
string
[]
>
();
currentTab
=
1
onSendPathTitle
(
pathTitle
:
string
)
{
this
.
sendPathTitle
.
emit
([
'menu.Organization'
,
'menu.Company'
,
'BusinessUnit'
,
pathTitle
])
}
}
src/app/components/setting-individual-kpi-supervisor/setting-individual-kpi-supervisor.component.html
View file @
2abf8a01
...
@@ -2,6 +2,13 @@
...
@@ -2,6 +2,13 @@
<div
class=
" pt-1.5rem mb-2"
>
<div
class=
" pt-1.5rem mb-2"
>
<div
class=
"flex flex-col gap-2"
>
<div
class=
"flex flex-col gap-2"
>
<div
class=
"flex flex-col gap-2 w-full"
>
<div
class=
"flex flex-col gap-2 w-full"
>
<div
class=
"w-full mb-2"
>
<div
class=
"font-size-18px font-weight-700 text-primary"
>
<span
class=
"whitespace-nowrap relative"
>
แก้ไข Individual KPI โดยหัวหน้า
</span>
</div>
</div>
<div
class=
"box shadow-md hover:shadow-xl transition m-0"
style=
"border-radius:20px"
>
<div
class=
"box shadow-md hover:shadow-xl transition m-0"
style=
"border-radius:20px"
>
<div
class=
"box-body py-2"
>
<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"
<div
class=
"flex item-center w-full font-size-18px font-weight-700 text-primary px-5 mt-1 mb-4"
...
...
src/app/shared/services/employee.service.ts
View file @
2abf8a01
...
@@ -27,6 +27,9 @@ export class EmployeeService {
...
@@ -27,6 +27,9 @@ export class EmployeeService {
);
);
}
}
getSubordinatesList
():
Observable
<
EmployeeModel
[]
>
{
return
this
.
http
.
get
<
EmployeeModel
[]
>
(
this
.
baseUrlapi
+
"/subordinates-list"
)
}
getList
():
Observable
<
EmployeeModel
[]
>
{
getList
():
Observable
<
EmployeeModel
[]
>
{
return
this
.
http
.
get
<
EmployeeModel
[]
>
(
this
.
baseUrlapi
+
"/profile/create-short/lists"
)
return
this
.
http
.
get
<
EmployeeModel
[]
>
(
this
.
baseUrlapi
+
"/profile/create-short/lists"
)
}
}
...
...
src/app/shared/services/navservice.ts
View file @
2abf8a01
...
@@ -142,6 +142,16 @@ export class NavService implements OnDestroy {
...
@@ -142,6 +142,16 @@ export class NavService implements OnDestroy {
show
:
true
,
show
:
true
,
icon
:
''
icon
:
''
},
},
{
title
:
'ติดตามหลังการประเมิน'
,
type
:
'link'
,
selected
:
false
,
active
:
false
,
path
:
'ess/post-evaluation-tracking'
,
id
:
'm4'
,
show
:
true
,
icon
:
''
},
];
];
}
}
...
...
src/assets/css/style.css
View file @
2abf8a01
...
@@ -7602,6 +7602,14 @@ select option:focus {
...
@@ -7602,6 +7602,14 @@ select option:focus {
padding-top: 0.25rem;
padding-top: 0.25rem;
}
}
.pr-1 {
padding-right: 0.25rem;
}
.pl-1 {
padding-left: 0.25rem;
}
.pt-2 {
.pt-2 {
padding-top: 0.5rem;
padding-top: 0.5rem;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment