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
d6b931f3
Commit
d6b931f3
authored
Oct 27, 2025
by
Nattana Chaiyamat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
แก้ไข Individual KPI ตัวเอง
parent
55b00685
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
2365 additions
and
948 deletions
+2365
-948
dashboard-routing.module.ts
src/app/components/dashboard/dashboard-routing.module.ts
+2
-0
dashboard.module.ts
src/app/components/dashboard/dashboard.module.ts
+3
-1
employee-self-service.component.ts
.../employee-self-service/employee-self-service.component.ts
+1
-1
job-family-mapping.component.html
...ents/job-family-mapping/job-family-mapping.component.html
+40
-0
job-family-mapping.component.scss
...ents/job-family-mapping/job-family-mapping.component.scss
+184
-0
job-family-mapping.component.ts
...onents/job-family-mapping/job-family-mapping.component.ts
+34
-0
assessment-topics.component.ts
...rfomance/assessment-topics/assessment-topics.component.ts
+1
-1
setting-individual-kpi-supervisor.component.html
...pervisor/setting-individual-kpi-supervisor.component.html
+105
-143
setting-individual-kpi-supervisor.component.scss
...pervisor/setting-individual-kpi-supervisor.component.scss
+48
-0
setting-individual-kpi-supervisor.component.ts
...supervisor/setting-individual-kpi-supervisor.component.ts
+230
-56
setting-individual-kpi.component.html
...ting-individual-kpi/setting-individual-kpi.component.html
+198
-323
setting-individual-kpi.component.ts
...etting-individual-kpi/setting-individual-kpi.component.ts
+283
-379
sidebar.component.ts
src/app/shared/components/sidebar/sidebar.component.ts
+2
-0
money-input.directive.ts
...app/shared/directive/money-input/money-input.directive.ts
+51
-24
appraisal-kpi-setting-emp.model.ts
src/app/shared/model/appraisal-kpi-setting-emp.model.ts
+538
-0
appraisal-kpi-setting.model.ts
src/app/shared/model/appraisal-kpi-setting.model.ts
+602
-0
appraisal.service.ts
src/app/shared/services/appraisal.service.ts
+21
-0
navservice.ts
src/app/shared/services/navservice.ts
+20
-20
th.json
src/assets/i18n/th.json
+2
-0
No files found.
src/app/components/dashboard/dashboard-routing.module.ts
View file @
d6b931f3
...
...
@@ -61,6 +61,7 @@ import { ReportCompetencySummaryComponent } from '../report-component/report-com
import
{
JobDescriptionEmpComponent
}
from
'../job-description-emp/job-description-emp.component'
;
import
{
CompetencyMappingComponent
}
from
'../competency-mapping/competency-mapping.component'
;
import
{
Widget1Component
}
from
'../widget1/widget1.component'
;
import
{
JobFamilyMappingComponent
}
from
'../job-family-mapping/job-family-mapping.component'
;
...
...
@@ -137,6 +138,7 @@ const routes: Routes = [
// { path: "admin/job-description-emp", title: 'รายละเอียดของงาน', component: JobDescriptionEmpComponent },
{
path
:
"ess/job-description-emp"
,
title
:
'รายละเอียดของงาน'
,
component
:
JobDescriptionEmpComponent
},
{
path
:
"ess/competency-mapping"
,
title
:
'รายละเอียดของงาน'
,
component
:
CompetencyMappingComponent
},
{
path
:
"ess/job-family-mapping"
,
title
:
'รายละเอียดกลุ่มงานตามวิชาชีพ'
,
component
:
JobFamilyMappingComponent
},
]
}
];
...
...
src/app/components/dashboard/dashboard.module.ts
View file @
d6b931f3
...
...
@@ -214,6 +214,7 @@ import { CompetencyMappingComponent } from '../competency-mapping/competency-map
import
{
JobFamilyComponent
}
from
'../company-components/job-description/job-family/job-family.component'
;
import
{
JobGradeComponent
}
from
'../company-components/job-description/job-grade/job-grade.component'
;
import
{
JobGradeGroupComponent
}
from
'../company-components/job-description/job-grade-group/job-grade-group.component'
;
import
{
JobFamilyMappingComponent
}
from
'../job-family-mapping/job-family-mapping.component'
;
export
const
MY_DATE_FORMATS
=
{
parse
:
{
...
...
@@ -367,7 +368,8 @@ export class CustomDateAdapter extends NativeDateAdapter {
CompetencyMappingComponent
,
JobFamilyComponent
,
JobGradeComponent
,
JobGradeGroupComponent
JobGradeGroupComponent
,
JobFamilyMappingComponent
],
imports
:
[
TranslateModule
,
CommonModule
,
...
...
src/app/components/employee-self-service/employee-self-service.component.ts
View file @
d6b931f3
...
...
@@ -30,7 +30,7 @@ export class EmployeeSelfServiceComponent {
generalPages
=
[
{
text
:
"JD"
,
link
:
"/ess/job-description-emp"
},
{
text
:
"Profile พนักงาน"
,
link
:
"/ess/profile"
},
{
text
:
"Job Family"
,
description
:
"หน้าใหม่ Job Family
"
},
{
text
:
"Job Family"
,
link
:
"/ess/job-family-mapping
"
},
{
text
:
"Time Attendance"
,
description
:
"หน้าใหม่ แสดงข้อมูล TA"
},
{
text
:
"วินัย และการลงโทษ"
,
description
:
"หน้าใหม่ คล้าย เมนูความดีความผิดของ myHR plus"
},
{
text
:
"ผลงานดีเด่น"
,
description
:
"หน้าใหม่"
},
...
...
src/app/components/job-family-mapping/job-family-mapping.component.html
0 → 100644
View file @
d6b931f3
<div
class=
"row m-2"
>
<div
class=
"col-12 row w-full"
>
<div
class=
"col-12"
>
<div
class=
"row-center col-center"
style=
"padding-bottom: 2rem;"
>
<div
class=
"text-title text-blue"
>
Job family
</div>
</div>
</div>
</div>
<div
class=
"menu-box"
>
<div
class=
"col-12 row p-2"
>
<ng-container
*
ngFor=
"let item of items; let i = index"
>
<div
class=
"col-3 box-menu"
>
<div
[
style
.
background-color
]="
colors
[
i
]"
class=
"row row-center h-full sub-box-menu"
>
<div
class=
"col-auto p-5"
>
<img
src=
"./assets/img/brand-logos/new_logo_mySkillX.png"
alt=
"mySkillX"
class=
"bg-white sub-box-menu"
style=
"width: 9rem;height: 9rem;pointer-events: none"
/>
</div>
<div
class=
"col-6 row row-space-between h-full"
style=
"padding: 2rem 0 1rem 0;"
>
<div
class=
"col-12"
>
<div
class=
"text-card-title text-gray-500"
>
รหัส
</div>
</div>
<div
class=
"col-12"
>
<div
class=
"col-12"
>
<div
class=
"text-sub-title text-gray-500"
>
ชื่อย่อ
</div>
</div>
<div
class=
"col-12"
>
<div
class=
"text-sub-title text-gray-500"
>
กลุ่ม
</div>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</div>
</div>
<div
class=
"col-12 row col-center w-full"
style=
"padding-top: 2rem;"
>
<button
class=
"link-btn"
style=
"height: 80px;"
>
JOB FAMILY MATRIX
</button>
</div>
</div>
\ No newline at end of file
src/app/components/job-family-mapping/job-family-mapping.component.scss
0 → 100644
View file @
d6b931f3
/* ===== base variables ===== */
$size-card
:
150px
;
// ( ≥1280px จะขยายเป็น 170 )
$col-hero
:
280px
;
// ความกว้างคอลัมน์ซ้าย
$gap-main
:
2
.5rem
;
$radius-main
:
28px
;
$radius-sub
:
20px
;
$dur
:
.35s
;
$easing
:
cubic-bezier
(
.4
,
0
,
.2
,
1
);
$shadow-base
:
0
14px
30px
-12px
rgba
(
0
,
0
,
0
,
.18
);
$shadow-deep
:
0
20px
42px
-16px
rgba
(
0
,
0
,
0
,
.24
);
// div {
// border: black 1px solid;
// min-height: 20px;
// }
.link-btn
{
@apply
bg-blue-600
hover
:bg-blue-700
text-white
font-semibold
rounded-full
px-10
py-2
transition
;
transition
:
transform
$dur
$easing
,
box-shadow
$dur
$easing
;
&
:hover
{
transform
:
translateY
(
-6px
);
box-shadow
:
$shadow-deep
;
}
}
.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
;
}
}
.col-start
{
display
:
flex
;
justify-content
:
start
;
}
.col-center
{
display
:
flex
;
justify-content
:
center
;
}
.row-top
{
display
:
flex
;
align-items
:
start
;
align-content
:
start
;
}
.row-center
{
display
:
flex
;
align-items
:
center
;
align-content
:
center
;
}
.row-space-between
{
display
:
flex
;
align-items
:
space-between
;
align-content
:
space-between
;
}
.relative
{
position
:
relative
;
}
.absolute
{
position
:
absolute
;
}
.text-blue
{
color
:
#3b82f6
;
}
.text-title
{
font-weight
:
500
;
font-size
:
3
.5rem
;
line-height
:
2
.25rem
;
pointer-events
:
none
;
word-break
:
break-word
;
}
.text-card-title
{
font-weight
:
800
;
font-size
:
3
.5rem
;
line-height
:
2
.25rem
;
pointer-events
:
none
;
word-break
:
break-word
;
}
.text-sub-title
{
font-weight
:
300
;
font-size
:
1rem
;
line-height
:
2
.25rem
;
pointer-events
:
none
;
word-break
:
break-word
;
}
.text-menu
{
font-weight
:
500
;
font-size
:
1rem
;
transition
:
color
.25s
;
}
.box-menu
{
padding
:
1rem
;
}
.sub-box-menu
{
border-radius
:
15px
;
transition
:
transform
$dur
$easing
,
box-shadow
$dur
$easing
;
// box-shadow: $shadow-deep;
// &:hover {
// transform: translateY(-6px
// );
// box-shadow: $shadow-deep;
// }
}
.menu-box
{
box-shadow
:
0
0
10px
3px
rgba
(
0
,
0
,
0
,
0
.2
);
border
:
1px
solid
transparent
;
border-radius
:
30px
;
background-image
:
linear-gradient
(
white
,
white
)
,
linear-gradient
(
135deg
,
#4f46e5
,
#ec4899
60%
,
#f59e0b
);
background-origin
:
border-box
;
background-clip
:
content-box
,
border-box
;
transition
:
transform
$dur
$easing
,
box-shadow
$dur
$easing
;
// &:hover {
// transform: translateY(-6px);
// box-shadow: $shadow-deep;
// }
// &:hover::before {
// content: '';
// position: absolute;
// inset: -3px;
// border-radius: inherit;
// // background: linear-gradient(135deg, #4f46e5, #ec4899 60%, #f59e0b);
// filter: blur(34px);
// opacity: .17;
// z-index: -1;
// transition: opacity $dur;
// opacity: .27;
// border: 1px solid;
// }
.sub-box
{
padding
:
15px
;
}
}
.color-box
{
transition
:
filter
0
.2s
ease
;
&
:hover
{
filter
:
brightness
(
0
.9
);
}
}
\ No newline at end of file
src/app/components/job-family-mapping/job-family-mapping.component.ts
0 → 100644
View file @
d6b931f3
import
{
Component
,
EventEmitter
,
Input
,
Output
}
from
'@angular/core'
;
import
{
DomSanitizer
,
SafeHtml
}
from
'@angular/platform-browser'
;
@
Component
({
selector
:
'app-job-family-mapping'
,
templateUrl
:
'./job-family-mapping.component.html'
,
styleUrls
:
[
'./job-family-mapping.component.scss'
]
})
export
class
JobFamilyMappingComponent
{
items
=
Array
.
from
({
length
:
10
},
(
_
,
i
)
=>
`PART
${
i
+
1
}
`
);
colors
:
string
[]
=
[];
ngOnInit
()
{
this
.
colors
=
this
.
generateUniqueColors
(
this
.
items
.
length
);
}
generateUniqueColors
(
count
:
number
):
string
[]
{
const
usedColors
=
new
Set
<
string
>
();
const
colors
:
string
[]
=
[];
while
(
colors
.
length
<
count
)
{
const
hue
=
Math
.
floor
(
Math
.
random
()
*
360
);
// 0–360 องศา
const
saturation
=
60
+
Math
.
random
()
*
10
;
// 60–70%
const
lightness
=
80
+
Math
.
random
()
*
10
;
// 80–90%
const
color
=
`hsl(
${
hue
}
,
${
saturation
}
%,
${
lightness
}
%)`
;
if
(
!
usedColors
.
has
(
color
))
{
usedColors
.
add
(
color
);
colors
.
push
(
color
);
}
}
return
colors
;
}
}
src/app/components/performance-management-evaluation/name-registration-perfomance/assessment-topics/assessment-topics.component.ts
View file @
d6b931f3
...
...
@@ -159,7 +159,7 @@ export class AssessmentTopicsComponent {
}
selectPmstopic
(
dataSelect
?:
any
)
{
const
data
=
this
.
pmstopic
.
dataList
.
find
(
e
=>
e
.
pmsTopicId
==
dataSelect
.
pmsTopicId
)
const
data
=
this
.
pmstopic
.
dataList
.
find
(
e
=>
e
.
pmsTopicId
==
dataSelect
?
.
pmsTopicId
)
if
(
data
)
{
this
.
pmstopic
.
select
=
new
MyPmstopicModel
(
data
)
}
else
if
(
this
.
modalStatus
==
'add'
)
{
...
...
src/app/components/setting-individual-kpi-supervisor/setting-individual-kpi-supervisor.component.html
View file @
d6b931f3
...
...
@@ -10,29 +10,30 @@
</div>
<div
class=
"flex w-full mb-4"
>
<div
class=
"flex w-1/4 justify-between"
>
<div
class=
"flex"
>
<
!-- <
div class="flex">
<div class="flex items-center">
<input type="checkbox" class="ti-form-checkbox pointer-events-none" id="hs-default-checkbox"
[checked]="selectEmp.size-1 > 0">
<label for="hs-default-checkbox" class="text-sm text-gray-500 mx-2 pointer-events-none">
{{selectEmp.size-1
<
0
?
0
:
selectEmp
.
size-1
}}
Selected
</
label
>
{{selectEmp.size-1 < 0 ? 0 : selectEmp.size-1}}
{{'Selected' | translate}}
</label>
</div>
<div class="mx-1 flex items-center">
<button
id=
'check-boxall'
(
click
)="
toggleSelectAll
()"
<button (click)="toggleSelectAll()"
class="focus:ring-2 focus:ring-primary rounded-sm flex item-center">
<i class="fs-l transition-all duration-200"
[ngClass]="{'ri-checkbox-multiple-line text-gray-500': !selectEmp.get('selectAll'), 'ri-checkbox-multiple-fill text-primary': selectEmp.get('selectAll')}"></i>
</button>
<label
class=
"text-sm text-gray-500 ml-2 cursor-pointer"
for=
"check-boxall"
(
click
)="
toggleSelectAll
()"
>
Select All
</label>
</div>
<label (click)="toggleSelectAll()" class="text-sm text-gray-500 ml-2 cursor-pointer">
{{'SelectAll' |translate}}</label>
</div>
</div> -->
</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
"
>
[
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>
...
...
@@ -42,140 +43,9 @@
</div>
</div>
<div
class=
"flex flex-col w-100"
>
<div
class=
"overflow-auto rounded-t-md"
>
<div
id=
"card-type-1"
role=
"tabpanel"
aria-labelledby=
"card-type-item-1"
>
<div
class=
"overflow-auto shadow-md"
>
<table
class=
"ti-custom-table ti-custom-table-head ti-custom-table-hover"
>
<thead>
<tr>
<ng-container
*
ngFor=
"let item of ['รหัสพนักงาน','ชื่อพนักงาน','ตำเเหน่งงาน','สถานะ']; let f = first; let l = last; let i = index"
>
<th
scope=
"col"
class=
"relative px-10px py-10px bg-soft-secondary text-primary !text-center"
[
ngClass
]="{'!
p-0
'
:f
,
'!
pl-0
'
:i=
=1}"
[
colSpan
]="
f
?
2:1
"
>
<span
class=
"text-sm"
>
{{ item }}
</span>
<div
*
ngIf=
"!l"
class=
"absolute top-1/2 transform -translate-y-1/2 right-0"
>
<svg
class=
"head-table-icon"
xmlns=
"http://www.w3.org/2000/svg"
width=
"50"
height=
"16"
fill=
"currentColor"
viewBox=
"0 0 16 16"
>
<path
d=
"M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"
>
</path>
</svg>
</div>
</th>
</ng-container>
</tr>
</thead>
<tbody
*
ngIf=
"subordinate.loading"
>
<tr>
<td
class=
"text-center"
colspan=
"100%"
>
<div
*
ngFor=
"let item of [1,2,3]"
class=
"ti-spinner w-8 h-8 text-secondary mx-1"
role=
"status"
aria-label=
"loading"
>
<span
class=
"sr-only"
>
Loading...
</span>
</div>
</td>
</tr>
</tbody>
<tbody
*
ngIf=
"!subordinate.loading&&!subordinateFilter().length"
>
<tr>
<td
class=
"text-center"
colspan=
"100%"
>
ไม่พบข้อมูล
</td>
</tr>
</tbody>
<tbody
*
ngIf=
"!subordinate.loading&&subordinateFilter().length"
>
<tr
*
ngFor=
"let item of subordinateFilter();let i = index"
>
<td
class=
"text-center !pr-1"
style=
"font-size: 12px;width: 90px;;min-width: 90px;max-width: 90px;"
>
<div
class=
"flex-col gap-2"
>
<input
[
disabled
]="!(
item
.
apsapproveType
.
code
!='
Apsapprove1
'&&(
item
.
masfromStatusType
.
code=
='evaluating'||item.masfromStatusType.code=='pending'))"
[
class
.
cursor-not-allowed
]="!(
item
.
apsapproveType
.
code
!='
Apsapprove1
'&&(
item
.
masfromStatusType
.
code=
='evaluating'||item.masfromStatusType.code=='pending'))"
[
class
.
accent-gray-400
]="!(
item
.
apsapproveType
.
code
!='
Apsapprove1
'&&(
item
.
masfromStatusType
.
code=
='evaluating'||item.masfromStatusType.code=='pending'))"
[
class
.
opacity-50
]="!(
item
.
apsapproveType
.
code
!='
Apsapprove1
'&&(
item
.
masfromStatusType
.
code=
='evaluating'||item.masfromStatusType.code=='pending'))"
type=
"checkbox"
class=
"ti-form-checkbox cursor-pointer"
[
checked
]="
selectEmp
.
get
(
item
.
apsassessy
.
employeeId
)"
(
click
)="!
selectEmp
.
get
(
item
.
apsassessy
.
employeeId
)?
selectEmp
.
set
(
item
.
apsassessy
.
employeeId
,
true
)
:selectEmp
.
delete
(
item
.
apsassessy
.
employeeId
);
checkSelectAll
()"
>
<ng-container
*
ngIf=
"item.apsapproveType.code!='Apsapprove1'&&(item.masfromStatusType.code=='evaluating'||item.masfromStatusType.code=='pending')"
>
<img
(
click
)="!
selectEmp
.
get
(
item
.
apsassessy
.
employeeId
)?
selectEmp
.
set
(
item
.
apsassessy
.
employeeId
,
true
)
:selectEmp
.
delete
(
item
.
apsassessy
.
employeeId
);
checkSelectAll
()"
class=
"cursor-pointer avatar shadow-none rounded-full !ring-transparent object-cover h-12 w-12"
[
src
]="
item
.
apsassessy
.
picture
?
getImg
(
item
.
apsassessy
.
picture
)
:
'./
assets
/
img
/
users
/
defaultperson
.
jpg
'"
(
error
)="
onImageError
($
event
)"
>
</ng-container>
<ng-container
*
ngIf=
"!(item.apsapproveType.code!='Apsapprove1'&&(item.masfromStatusType.code=='evaluating'||item.masfromStatusType.code=='pending'))"
>
<img
class=
"cursor-pointer avatar shadow-none rounded-full !ring-transparent object-cover h-12 w-12"
[
src
]="
item
.
apsassessy
.
picture
?
getImg
(
item
.
apsassessy
.
picture
)
:
'./
assets
/
img
/
users
/
defaultperson
.
jpg
'"
(
error
)="
onImageError
($
event
)"
>
</ng-container>
<div
class=
"mb-4"
>
<ng-container
*
ngTemplateOutlet=
"Datagrid"
></ng-container>
</div>
</td>
<td
class=
"text-left"
style=
"font-size: 12px;width: 90px;min-width: 90px;max-width: 90px;padding-left: 10px;"
>
{{item.apsassessy.employeeId}}
</td>
<td
style=
"font-size: 12px; width: 175px;"
>
{{item.apsassessy.thFullName}}
</td>
<td
style=
"font-size: 12px;"
>
{{item.apsassessy.position.tdesc}}
</td>
<td
class=
"text-center"
>
<div
class=
"flex justify-center"
>
<button
type=
"button"
class=
"ti-btn rounded-sm "
[
class
]="
statusButtonClass
(
item
.
statusIdp
.
statusType
)"
style=
"height: 30px; width: auto; font-size: 12px; display: flex; align-items: center; justify-content: center;margin-left:4px;"
(
click
)="
settingIndividualKpi=
true"
>
{{statusCompetencyText(item.statusIdp.statusType)}}
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<nav
class=
"pagination-style-3 my-5"
*
ngIf=
"page.length"
>
<ul
class=
"ti-pagination"
>
<li>
<a
aria-label=
"anchor"
class=
"page-link"
href=
"javascript:void(0);"
(
click
)="
currentPage =
(currentPage-1
||
1
)"
>
<i
class=
"ri-arrow-left-s-line align-middle rtl:rotate-180"
></i>
</a>
</li>
<li
*
ngFor=
"let item of page;let f = first;let l = last"
>
<ng-container
*
ngIf=
"item==3&¤tPage!=1&¤tPage!=2&¤tPage!=3"
>
<a
aria-label=
"anchor"
class=
"page-link"
href=
"javascript:void(0);"
><i
class=
"ri-more-line"
></i>
</a>
</ng-container>
<ng-container
*
ngIf=
"(f||l)||(item==currentPage-1||item==currentPage||item==currentPage+1)"
>
<a
class=
"page-link"
href=
"javascript:void(0);"
[
class
.
active
]="
item=
=currentPage"
(
click
)="
currentPage=
item"
>
{{item}}
</a>
</ng-container>
<ng-container
*
ngIf=
"item==page.length-2&¤tPage!=page.length&¤tPage!=page.length-1&¤tPage!=page.length-2"
>
<a
aria-label=
"anchor"
class=
"page-link"
href=
"javascript:void(0);"
><i
class=
"ri-more-line"
></i>
</a>
</ng-container>
</li>
<li>
<a
aria-label=
"anchor"
class=
"page-link"
href=
"javascript:void(0);"
(
click
)="
currentPage =
(currentPage
>
page.length-1 ? currentPage: currentPage+1 )">
<i
class=
"ri-arrow-right-s-line align-middle rtl:rotate-180"
></i>
</a>
</li>
</ul>
<ul
class=
"nav-tabs mt-3"
>
<span>
Show {{((currentPage-1) * 10)+1}} to {{subordinateFilter().length
<10
?
subordinateFilter
().
length:
(
currentPage=
=page.length
?
((
currentPage
*
10
)
-
((
currentPage
*
10
)
-
subordinateFilter
().
length
)
)
:
(
currentPage
*
10
)
)
}}
of
{{
subordinateFilter
().
length
}}
items
</
span
>
</ul>
</nav>
</div>
</div>
</div>
...
...
@@ -183,7 +53,98 @@
</div>
</div>
</ng-container>
<ng-container
*
ngIf=
"settingIndividualKpi"
>
<app-setting-individual-kpi
[
evaluationForm
]="'
sup
'
"
(
sendReturnPath
)="
get
BossList
();
settingIndividualKpi=
false"
></app-setting-individual-kpi>
<ng-container
*
ngIf=
"settingIndividualKpi
&&subordinate.select
"
>
<app-setting-individual-kpi
[
bossId
]="
bossId
"
[
employeeId
]="
subordinate
.
select
.
apsassessy
.
employeeId
"
(
sendReturnPath
)="
get
EmpKpi
();
settingIndividualKpi=
false"
></app-setting-individual-kpi>
</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"
>
<!-- <input [disabled]="data.statusCode!='1'" [class.cursor-not-allowed]="data.statusCode!='1'"
[class.accent-gray-400]="data.statusCode!='1'" [class.opacity-50]="data.statusCode!='1'"
type="checkbox" class="ti-form-checkbox cursor-pointer" [checked]="selectEmp.get(data.employeeId)"
(click)="!selectEmp.get(data.employeeId)?selectEmp.set(data.employeeId , true):selectEmp.delete(data.employeeId);checkSelectAll()">
-->
<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-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>
\ No newline at end of file
src/app/components/setting-individual-kpi-supervisor/setting-individual-kpi-supervisor.component.scss
View file @
d6b931f3
// 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
;
}
src/app/components/setting-individual-kpi-supervisor/setting-individual-kpi-supervisor.component.ts
View file @
d6b931f3
import
{
ChangeDetectorRef
,
Component
,
Input
}
from
'@angular/core'
;
import
{
ChangeDetectorRef
,
Component
,
Input
,
ViewChild
,
ViewEncapsulation
}
from
'@angular/core'
;
import
{
Router
,
ActivatedRoute
}
from
'@angular/router'
;
import
{
TranslateService
}
from
'@ngx-translate/core'
;
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
{
setCulture
}
from
'@syncfusion/ej2-base'
;
import
{
Query
}
from
'@syncfusion/ej2-data'
;
import
{
MyAppraisalKpiSettingEmpModel
}
from
'src/app/shared/model/appraisal-kpi-setting-emp.model'
;
import
{
AppraisalKpiSettingModel
,
ApsassessyModel
,
MyAppraisalKpiSettingModel
,
MyApsassessyModel
}
from
'src/app/shared/model/appraisal-kpi-setting.model'
;
import
{
AppraisalSubordinateModel
,
Masfromevaluationassessment
}
from
'src/app/shared/model/appraisal-subordinate.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
{
TokenService
}
from
'src/app/shared/services/token.service'
;
interface
Row
{
label
:
string
;
value
:
number
|
string
;
}
@
Component
({
selector
:
'app-setting-individual-kpi-supervisor'
,
templateUrl
:
'./setting-individual-kpi-supervisor.component.html'
,
styleUrls
:
[
'./setting-individual-kpi-supervisor.component.scss'
]
styleUrls
:
[
'./setting-individual-kpi-supervisor.component.scss'
],
providers
:
[
AggregateService
,
SortService
,
GroupService
,
ColumnMenuService
,
PageService
,
FilterService
,
ToolbarService
,
PdfExportService
,
ExcelExportService
,
DetailRowService
,
ReorderService
,
EditService
,
SearchService
],
encapsulation
:
ViewEncapsulation
.
None
})
export
class
SettingIndividualKpiSupervisorComponent
{
subordinate
:
{
loading
:
false
,
select
?:
AppraisalSubordinateModel
,
dataList
:
AppraisalSubordinateModel
[]
}
=
{
loading
:
false
,
select
:
undefined
,
dataList
:
[]
}
selectEmp
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
()
currentPage
=
1
page
=
Array
.
from
({
length
:
1
},
(
_
,
i
)
=>
i
+
1
)
search
=
""
bossId
=
''
subordinate
:
{
loading
:
false
,
select
?:
AppraisalKpiSettingModel
,
dataList
:
AppraisalKpiSettingModel
[]
}
=
{
loading
:
false
,
select
:
undefined
,
dataList
:
[]
}
settingIndividualKpi
=
false
search
=
""
selectEmp
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
()
syncfution
:
{
dataList
:
any
[],
searchSettings
:
{
fields
:
string
[],
operator
:
'contains'
,
ignoreCase
:
false
},
columns
:
ColumnModel
[]
}
=
{
dataList
:
[],
searchSettings
:
{
fields
:
[
'employeeId'
,
'fullName'
,
'position'
,
'status'
],
operator
:
'contains'
,
ignoreCase
:
false
},
columns
:
[{
field
:
"employeeId"
,
headerText
:
"EmployeeCode"
,
type
:
"string"
,
isPrimaryKey
:
true
,
},
{
field
:
"fullName"
,
headerText
:
"EmployeeName"
,
type
:
"string"
},
{
field
:
"position"
,
headerText
:
"Position"
,
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'
constructor
(
private
appraisalService
:
AppraisalService
,
private
fileService
:
FileService
,
private
translateService
:
TranslateService
,
private
tokenService
:
TokenService
,
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
.
getBossList
()
this
.
bossId
=
this
.
tokenService
.
getUserData
().
employeeId
this
.
getEmpKpi
()
}
getBossList
()
{
this
.
appraisalService
.
getBossList
().
subscribe
({
getEmpKpi
()
{
this
.
selectEmp
.
set
(
'selectAll'
,
false
)
this
.
syncfution
.
dataList
=
[]
this
.
appraisalService
.
getEmpKpi
().
subscribe
({
next
:
response
=>
{
this
.
subordinate
.
dataList
=
JSON
.
parse
(
JSON
.
stringify
(
response
))
this
.
cdr
.
detectChanges
()
if
(
this
.
subordinate
.
dataList
.
length
)
{
this
.
subordinate
.
select
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
subordinate
.
dataList
[
0
]))
this
.
cdr
.
detectChanges
()
}
this
.
searchChange
()
this
.
subordinate
.
dataList
=
response
.
map
(
e
=>
new
MyAppraisalKpiSettingModel
(
e
))
this
.
setSyncfutionDataList
()
this
.
cdr
.
markForCheck
()
},
error
:
error
=>
{
this
.
cdr
.
detectChanges
()
}
})
}
searchChange
()
{
this
.
currentPage
=
1
this
.
page
=
Array
.
from
({
length
:
Math
.
ceil
(
this
.
subordinateFilter
().
length
/
10
)
},
(
_
,
i
)
=>
i
+
1
);
this
.
cdr
.
markForCheck
()
}
toggleSelectAll
()
{
if
(
this
.
subordinateFilter
().
filter
(
e
=>
e
.
apsapproveType
.
code
!=
'Apsapprove1'
&&
(
e
.
masfromStatusType
.
code
==
'evaluating'
||
e
.
masfromStatusType
.
code
==
'pending'
)).
length
>
0
)
{
if
(
!
this
.
selectEmp
.
get
(
'selectAll'
))
{
this
.
selectEmp
.
set
(
'selectAll'
,
true
)
this
.
subordinateFilter
().
filter
(
e
=>
e
.
apsapproveType
.
code
!=
'Apsapprove1'
&&
(
e
.
masfromStatusType
.
code
==
'evaluating'
||
e
.
masfromStatusType
.
code
==
'pending'
)).
forEach
(
e
=>
{
this
.
selectEmp
.
set
(
e
.
apsassessy
.
employeeId
,
true
)
})
}
else
{
this
.
selectEmp
.
set
(
'selectAll'
,
false
)
this
.
selectEmp
.
clear
()
}
}
}
subordinateFilter
()
{
if
(
this
.
subordinate
.
select
)
{
return
this
.
subordinate
.
select
.
masfromevaluationassessment
.
filter
(
x
=>
{
return
this
.
subordinate
.
dataList
.
filter
(
x
=>
{
return
x
.
apsassessy
.
employeeId
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
apsassessy
.
thFullName
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
apsassessy
.
position
.
tdesc
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
this
.
statusCompetencyText
(
x
.
apsassessy
.
position
.
tdesc
)
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
grade
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
apsapproveType
.
t
desc
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
x
.
apsassessy
.
position
.
edesc
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
statusApprove
.
tdesc
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
||
x
.
statusApprove
.
e
desc
.
toLowerCase
().
includes
(
this
.
search
.
toLowerCase
())
})
}
return
[]
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
.
checkSelectAll
()
}
translateText
(
th
?:
string
,
en
?:
string
)
{
return
this
.
translateService
.
getCurrentLang
()
==
'th'
?
(
th
||
''
)
:
(
en
||
''
)
}
statusCompetencyText
=
(
status
:
string
)
=>
{
if
(
status
===
"no access"
)
{
return
"ยังไม่ถึงขั้นตอนดำเนินการ"
...
...
@@ -88,15 +178,16 @@ export class SettingIndividualKpiSupervisorComponent {
}
}
statusButtonClass
=
(
status
:
string
)
=>
{
if
(
status
===
"no access"
)
{
const
text
=
status
.
toLowerCase
().
trim
()
if
(
text
===
"no access"
)
{
return
"ti-btn-soft-mute"
}
else
if
(
status
===
"pending"
)
{
}
else
if
(
text
===
"pending"
)
{
return
"ti-btn-soft-secondary"
}
else
if
(
status
===
"evaluating"
)
{
}
else
if
(
text
===
"evaluating"
)
{
return
"ti-btn-soft-warning"
}
else
if
(
status
===
"completed"
)
{
}
else
if
(
text
===
"completed"
)
{
return
"ti-btn-soft-success"
}
else
if
(
status
===
"rejected"
)
{
}
else
if
(
text
===
"rejected"
)
{
return
"ti-btn-soft-danger"
}
else
{
return
""
...
...
@@ -112,19 +203,102 @@ export class SettingIndividualKpiSupervisorComponent {
imgElement
.
src
=
'./assets/img/users/defaultperson.jpg'
;
}
selectSubordinate
(
data
:
any
)
{
this
.
subordinate
.
select
=
new
MyAppraisalKpiSettingModel
(
this
.
subordinate
.
dataList
.
find
(
e
=>
e
.
apsassessy
.
employeeId
==
data
.
employeeId
))
this
.
settingIndividualKpi
=
true
this
.
cdr
.
markForCheck
()
}
toggleSelectAll
()
{
if
(
!
this
.
selectEmp
.
get
(
'selectAll'
))
{
this
.
selectEmp
.
set
(
'selectAll'
,
true
)
this
.
syncfution
.
dataList
.
filter
(
e
=>
e
.
statusCode
==
'1'
).
forEach
(
e
=>
{
this
.
selectEmp
.
set
(
e
.
employeeId
,
true
)
})
}
else
{
this
.
selectEmp
.
set
(
'selectAll'
,
false
)
this
.
syncfution
.
dataList
.
filter
(
e
=>
e
.
statusCode
==
'1'
).
forEach
(
e
=>
{
this
.
selectEmp
.
set
(
e
.
employeeId
,
false
)
})
this
.
selectEmp
.
clear
()
}
}
checkSelectAll
()
{
this
.
selectEmp
.
set
(
'selectAll'
,
(
this
.
subordinateFilter
().
filter
(
e
=>
e
.
apsapproveType
.
code
!=
'Apsapprove1'
&&
(
e
.
masfromStatusType
.
code
==
'evaluating'
||
e
.
masfromStatusType
.
code
==
'pending'
)).
length
>
0
&&
this
.
subordinateFilter
().
filter
(
e
=>
e
.
apsapproveType
.
code
!=
'Apsapprove1'
&&
(
e
.
masfromStatusType
.
code
==
'evaluating'
||
e
.
masfromStatusType
.
code
==
'pending'
)).
length
==
this
.
selectEmp
.
size
-
1
))
this
.
selectEmp
.
set
(
'selectAll'
,
(
this
.
syncfution
.
dataList
.
filter
(
e
=>
e
.
statusCode
==
'1'
).
length
>
0
&&
(
this
.
selectEmp
.
size
-
1
)
==
this
.
syncfution
.
dataList
.
filter
(
e
=>
e
.
statusCode
==
'1'
).
length
))
}
selectSubordinate
(
data
:
Masfromevaluationassessment
,
competencyTypeId
:
string
,
evaluationRoundId
?:
string
,
masfromStatusType
?:
string
)
{
if
(
data
&&
evaluationRoundId
)
{
// this.formEvaluation.evaluateeId = data.apsassessy.employeeId
// this.formEvaluation.competencyTypeId = competencyTypeId
// this.formEvaluation.evaluationRoundId = evaluationRoundId
// this.formEvaluation.masfromStatusType = masfromStatusType || ''
// this.formEvaluation.allCompetencyTypeId = data.typeList
this
.
cdr
.
detectChanges
()
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
)
}
}
}
src/app/components/setting-individual-kpi/setting-individual-kpi.component.html
View file @
d6b931f3
<ng-container
*
ngTemplateOutlet=
"
evaluation
"
></ng-container>
<ng-template
#
evaluation
>
<ng-container
*
ngTemplateOutlet=
"
newDesige
"
></ng-container>
<ng-template
#
newDesige
>
<div
class=
" pt-1.5rem"
>
<div
class=
"flex flex-col gap-2"
>
<div
class=
"flex flex-row gap-2"
>
...
...
@@ -7,19 +7,34 @@
<div
class=
"w-full mb-2"
>
<div
class=
"font-size-18px font-weight-700 text-primary"
>
<div
class=
"absolute "
style=
"transform:translateY(-9px)"
>
<button
type=
"button"
*
ngIf=
"
evaluationForm=='sup'
"
<button
type=
"button"
*
ngIf=
"
bossId
"
class=
"ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 shadow-md hover:shadow-xl transition text-blue-500 bg-white"
(
click
)="
returnPath
()"
>
<i
class=
"ti ti-chevron-left"
></i>
ย้อนกลับ
</button>
</div>
<span
class=
"whitespace-nowrap relative"
[
ngStyle
]="{'
left
'
:
evaluationForm=
='sup'
?
'
105px
'
:
'
0px
'}"
>
แก้ไข Individual KPI {{
evaluationForm=='sup'
?'โดยหัวหน้า':'ตัวเอง'}}
<span
class=
"whitespace-nowrap relative"
[
ngStyle
]="{'
left
'
:
bossId
?
'
105px
'
:
'
0px
'}"
>
แก้ไข Individual KPI {{
bossId
?'โดยหัวหน้า':'ตัวเอง'}}
</span>
</div>
</div>
</div>
<div
class=
"flex flex-col w-3/4 gap-2"
>
<div
class=
"w-full mb-2 flex"
>
<div
class=
"w-full flex flex-row gap-2"
>
<ng-container
*
ngFor=
"let item of appraisalKpiSettingEmp.list; let i=index ; let f= first"
>
<div
class=
"font-size-18px font-weight-700"
>
<span
class=
"cursor-pointer"
[
ngClass
]="{'
text-secondary
border-secondary
border-b
'
:appraisalKpiSettingEmp
.
select
.
pmsEvaluationRoundId=
=item.pmsEvaluationRoundId,'hover:text-gray-900':!(appraisalKpiSettingEmp.select.pmsEvaluationRoundId==item.pmsEvaluationRoundId)}"
(
click
)="
appraisalKpiSettingEmp
.
select
.
pmsEvaluationRoundId
!==
item
.
pmsEvaluationRoundId
&&
selectAppraisalKpiSettingEmp
(
item
)"
>
{{item.pmsEvaluationRoundId}}
</span>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div
class=
"flex flex-row gap-2"
>
<div
class=
"flex flex-col gap-2 w-1/4"
[
class
.
hidden
]="
menuClose
.
get
('ข้อมูลรายละเอียด')"
>
...
...
@@ -29,7 +44,7 @@
<div
class=
"box-body py-2"
>
<div
class=
"flex flex-col items-center gap-3"
>
<img
[
src
]="
e
valuatee
.
data
.
picture
?
getImg
(
evaluat
ee
.
data
.
picture
)
:
'./
assets
/
img
/
users
/
defaultperson
.
jpg
'"
[
src
]="
e
mployee
.
data
.
picture
?
getImg
(
employ
ee
.
data
.
picture
)
:
'./
assets
/
img
/
users
/
defaultperson
.
jpg
'"
(
error
)="
onImageError
($
event
)"
class=
"h-24 w-24 rounded-full ring-4 ring-primary object-cover"
alt=
"profile-img"
/>
</div>
...
...
@@ -38,71 +53,78 @@
</div>
<div
class=
"w-full"
>
<div
class=
"box shadow-md hover:shadow-xl transition m-0"
style=
"border-radius:20px"
>
<div
class=
"box-header"
[
class
.
border-none
]="
menuClose
.
get
('
ข้อมูลพนักงาน
')"
>
<div
class=
"box-header"
[
class
.
border-none
]="
menuClose
.
get
('
EmployeeInformation
')"
>
<div
class=
"flex justify-between"
>
<h5
class=
"box-title align-center"
>
ข้อมูลพนักงาน
</h5>
<i
*
ngIf=
"menuClose.get('
ข้อมูลพนักงาน
')"
title=
"แสดง"
<h5
class=
"box-title align-center"
>
{{'EmployeeInformation' | translate}}
</h5>
<i
*
ngIf=
"menuClose.get('
EmployeeInformation
')"
title=
"แสดง"
class=
"bg-white cursor-pointer border ti ti-chevron-down"
style=
"padding: 1px;border-radius:10px;font-size:27px"
(
click
)="
menuClose
.
set
('
ข้อมูลพนักงาน
',
false
)"
></i>
<i
*
ngIf=
"!menuClose.get('
ข้อมูลพนักงาน
')"
title=
"ปิด"
(
click
)="
menuClose
.
set
('
EmployeeInformation
',
false
)"
></i>
<i
*
ngIf=
"!menuClose.get('
EmployeeInformation
')"
title=
"ปิด"
class=
"bg-white cursor-pointer border ti ti-chevron-up"
style=
"padding: 1px;border-radius:10px;font-size:27px"
(
click
)="
menuClose
.
set
('
ข้อมูลพนักงาน
',
true
)"
></i>
(
click
)="
menuClose
.
set
('
EmployeeInformation
',
true
)"
></i>
</div>
</div>
<div
class=
"box-body py-2"
[
class
.
hidden
]="
menuClose
.
get
('
ข้อมูลพนักงาน
')"
>
<div
class=
"box-body py-2"
[
class
.
hidden
]="
menuClose
.
get
('
EmployeeInformation
')"
>
<table
class=
"ti-custom-table border-0 ellipsis-text"
>
<tbody>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
รหัสพนักงาน
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'EmployeeCode' | translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{e
valuat
ee.data.employeeId}}
{{e
mploy
ee.data.employeeId}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
ชื่อ - สกุล
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'NameSurname' | translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{
evaluatee.data.thFullName
}}
{{
translateText(employee.data.thFullName,employee.data.engFullName)
}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
ตำเเหน่ง
</td>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'Position'
| translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{
evaluatee.data.position.tdesc
}}
{{
translateText(employee.data.position.tdesc,employee.data.position.edesc)
}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
ฝ่าย
</td>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'Division'
| translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{
evaluatee.data.bu1.tdesc
}}
{{
translateText(employee.data.bu1.tdesc,employee.data.bu1.edesc)
}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
แผนก
</td>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'Department' | translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{
evaluatee.data.bu2.tdesc
}}
{{
translateText(employee.data.bu2.tdesc,employee.data.bu2.edesc)
}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
ระดับ
</td>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'Level' |
translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{
evaluatee.data.pl.tdesc
}}
{{
translateText(employee.data.pl.tdesc,employee.data.pl.edesc)
}}
</td>
</tr>
<tr
class=
"!border-0"
>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
E-mail
</td>
<td
class=
"!p-2 align-start"
style=
"font-size: 1rem;font-weight: 500;color:black;"
>
{{'Email' |
translate}}
</td>
<td
class=
"!p-2 align-start"
>
:
</td>
<td
class=
"font-medium !p-2 align-start !text-warp"
>
{{e
valuat
ee.data.email}}
{{e
mploy
ee.data.email}}
</td>
</tr>
</tbody>
...
...
@@ -129,16 +151,24 @@
<div
class=
"box shadow-md hover:shadow-xl transition m-0"
style=
"border-radius:20px;"
>
<div
class=
"box-header"
style=
"border:0"
>
</div>
<div
#
scrollContainer
class=
"box-body pt-0"
style=
"overflow-y: auto; height: calc(100vh - 2
53
px)"
>
<div
class=
"min-height: calc(100vh - 406
px);"
>
<ng-container
*
ngTemplateOutlet=
"
pmsEvaluation
"
></ng-container>
<div
#
scrollContainer
class=
"box-body pt-0"
style=
"overflow-y: auto; height: calc(100vh - 2
02
px)"
>
<div
style=
"overflow-x: hidden;min-height: calc(100vh - 281
px);"
>
<ng-container
*
ngTemplateOutlet=
"
kpiTable
"
></ng-container>
</div>
<div
class=
"box-footer text-end space-x-3 rtl:space-x-reverse"
style=
"margin: 0.5rem -24px -24px -24px;"
>
<button
class=
"ti-btn m-0 ti-btn-soft-secondary"
>
<div
class=
"box-footer text-end space-x-3 rtl:space-x-reverse"
style=
"margin: 0.5rem -24px -24px -24px;"
*
ngIf=
"appraisalKpiSettingEmp.select.currentTopic.length"
>
<button
class=
"ti-btn m-0 ti-btn-soft-secondary"
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code!='1' || lastConfirmBySelf"
(
click
)="
savePmsTopic
()"
>
<i
class=
"ri-save-3-fill"
></i>
ยืนยันข้อมูล
</button>
<button
class=
"ti-btn m-0 ti-btn-soft-secondary"
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code=='1' && !lastConfirmBySelf"
(
click
)="
approvePmsTopic
()"
>
<i
class=
"ri-save-3-fill"
></i>
อนุมัติข้อมูล
</button>
</div>
</div>
</div>
...
...
@@ -147,12 +177,11 @@
</div>
</div>
</div>
</ng-template>
<ng-template
#
pmsEvaluation
>
<ng-template
#
kpiTable
>
<div
class=
"flex flex-col"
>
<div
class=
"flex flex-col gap-2"
style=
"min-height: calc(100vh - 479px);
"
>
<div
class=
"flex flex-col gap-2
"
>
<div
class=
" flex flex-col gap-2"
[
attr
.
id
]="'
menu-part-3
'"
>
<button
type=
"button"
class=
"p-4 w-full bg-gradient-to-r from-primary to-secondary text-white text-left font-semibold"
...
...
@@ -169,25 +198,36 @@
<th
scope=
"col"
>
หน่วยนับ
</th>
<th
scope=
"col"
>
กำหนดเสร็จ
</th>
<th
scope=
"col"
>
เพิ่มเติม
</th>
<th
scope=
"col"
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code!='1' || lastConfirmBySelf"
>
การจัดการ
</th>
</tr>
</thead>
<tbody>
<ng-container
*
ngFor=
"let item of individualKPI.list;let i = index"
>
<tr
class=
"border-b border-gray-200"
(
mouseenter
)="
tableHover
.
set
(
item
.
groupAssessment1
.
pmsTopic
.
indicatorsDetail
,
true
)"
<ng-container
*
ngFor=
"let item of appraisalKpiSettingEmp.select.currentTopic;let i = index"
>
<tr
class=
"border-b border-gray-200"
(
mouseenter
)="
tableHover
.
set
(
item
.
pmsTopicId
,
true
)"
(
mouseleave
)="
tableHover
.
clear
()"
[
ngStyle
]="{'
background
'
:tableHover
.
get
(
item
.
groupAssessment1
.
pmsTopic
.
indicatorsDetail
)?'#
f1f5f9
'
:
'#
ffffff
'
}"
>
[
ngStyle
]="{'
background
'
:tableHover
.
get
(
item
.
pmsTopicId
)?'#
f1f5f9
'
:currentTopicColor
(
item
.
approveTopicStatus
)
}"
>
<td
class=
"py-2"
style=
"vertical-align: top"
>
{{item.groupAssessment1.pmsTopic.indicatorsDetail}}
</td>
<ng-container
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code=='1'&&item.approveTopicStatus!=2 && !lastConfirmBySelf"
>
<input
type=
"checkbox"
class=
"ti-form-checkbox cursor-pointer"
[
checked
]="
pmsTopicApprove
.
get
(
item
.
pmsTopicId
)"
(
click
)="!
pmsTopicApprove
.
get
(
item
.
pmsTopicId
)?
pmsTopicApprove
.
set
(
item
.
pmsTopicId
,
true
)
:pmsTopicApprove
.
delete
(
item
.
pmsTopicId
);"
>
</ng-container>
{{item.pmsTopicId}}
</td>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
>
{{item.weight}}
</td>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
>
{{item.groupAssessment1.pmsTopic
.performanceGoalsDetail}}
{{item
.performanceGoalsDetail}}
</td>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
>
{{item.groupAssessment1.pmsTopic
.detailUnit}}
{{item
.detailUnit}}
</td>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
>
{{item.groupAssessment1.pmsTopic
.completionDate}}
{{item
.completionDate}}
</td>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
>
<div
class=
"hs-tooltip ti-main-tooltip [--trigger:hover]"
>
...
...
@@ -204,7 +244,7 @@
:
</div>
<div
class=
"flex-1"
>
{{item.groupAssessment1.pmsTopic
.tdesc}}
{{item
.tdesc}}
</div>
</div>
<div
class=
"text-start flex flex-row"
>
...
...
@@ -215,7 +255,7 @@
:
</div>
<div
class=
"flex-1"
>
{{item.groupAssessment1.pmsTopic
.indicatorsDetail}}
{{item
.indicatorsDetail}}
</div>
</div>
<div
class=
"text-start flex flex-row"
>
...
...
@@ -226,7 +266,7 @@
:
</div>
<div
class=
"flex-1"
>
{{item.groupAssessment1.pmsTopic
.performanceGoalsDetail}}
{{item
.performanceGoalsDetail}}
</div>
</div>
<div
class=
"text-start flex flex-row"
>
...
...
@@ -237,7 +277,7 @@
:
</div>
<div
class=
"flex-1"
>
{{item.groupAssessment1.pmsTopic
.detailUnit}}
{{item
.detailUnit}}
</div>
</div>
<div
class=
"text-start flex flex-row"
>
...
...
@@ -248,7 +288,7 @@
:
</div>
<div
class=
"flex-1"
>
{{item.groupAssessment1.pmsTopic
.completionDate}}
{{item
.completionDate}}
</div>
</div>
<div
class=
"text-start flex flex-row"
>
...
...
@@ -267,114 +307,27 @@
</div>
</div>
</td>
</tr>
<td
class=
"py-2 text-center"
style=
"vertical-align: top"
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code!='1' || lastConfirmBySelf"
>
<ng-container
*
ngIf=
"item.approveTopicStatus==0"
>
<button
type=
"button"
class=
" cursor-default"
(
click
)="
addPmsTopic
(
item
.
pmsTopicId
)"
>
<i
class=
"ti ti-circle-plus text-green-500 cursor-pointer"
style=
"font-size: 20px;"
></i>
</button>
</ng-container>
<tr>
<td
class=
"py-2 text-center"
>
<input
type=
"text"
id=
"input-label"
class=
"ti-form-input"
>
</td>
<td
class=
"py-2 text-center"
>
<input
type=
"text"
id=
"input-label"
class=
"ti-form-input"
>
</td>
<td
class=
"py-2 text-center"
>
<input
type=
"text"
id=
"input-label"
class=
"ti-form-input"
>
</td>
<td
class=
"py-2 text-center"
>
<input
type=
"text"
id=
"input-label"
class=
"ti-form-input"
>
</td>
<td
class=
"py-2 text-center"
>
<input
type=
"text"
id=
"input-label"
class=
"ti-form-input"
>
</td>
<td
class=
"py-2 text-center"
style=
"justify-items:center"
>
<ng-container
*
ngIf=
"true"
>
<button
type=
"button"
class=
"flex text-start items-center cursor-default"
>
<i
class=
"ti ti-circle-plus text-green-500 cursor-pointer"
style=
"font-size: 20px;"
(
click
)="
assessmentDialogOpen
()"
></i>
<ng-container
*
ngIf=
"item.approveTopicStatus!=0"
>
<button
type=
"button"
class=
" cursor-default"
(
click
)="
deletePmsTopic
(
i
)"
>
<i
class=
"ti ti-trash text-danger cursor-pointer"
style=
"font-size: 20px;"
></i>
</button>
</ng-container>
<ng-container
*
ngIf=
"false"
>
<div
class=
"hs-tooltip ti-main-tooltip [--trigger:hover]"
>
<div
class=
"hs-tooltip-toggle ti-main-tooltip-toggle"
>
<i
class=
"ti ti-help-circle"
></i>
<div
class=
"hs-tooltip-content ti-main-tooltip-content border-secondary"
role=
"tooltip"
>
<div
class=
"flex flex-col gap-2 font-weight-700"
>
<div>
รายละเอียดข้อมูล
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
ที่มาของนโยบาย
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
ตัวชี้วัด
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
เป้าหมาย
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
หน่วยนับ
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
กำหนดเสร็จ
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
<div
class=
"text-start flex flex-row"
>
<div
style=
"width: 100px;"
>
น้ำหนัก
</div>
<div
class=
"px-1"
>
:
</div>
<div
class=
"flex-1"
>
</div>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</td>
</tr>
<tr>
<td
class=
"py-2 text-center"
style=
"vertical-align: center;justify-items:center"
colspan=
"6"
>
</ng-container>
<tr
*
ngIf=
"appraisalKpiSettingEmp.select.statusAll.code!='1' || lastConfirmBySelf"
>
<td
class=
"py-2 text-center"
style=
"vertical-align: center;justify-items:center"
colspan=
"7"
>
<button
type=
"button"
class=
"flex text-start items-center cursor-default"
(
click
)="
competency
TopicDialogOpen
()"
>
(
click
)="
pms
TopicDialogOpen
()"
>
<i
class=
"ti ti-circle-plus text-green-500 cursor-pointer"
style=
"font-size: 20px;"
></i>
</button>
</td>
...
...
@@ -385,97 +338,16 @@
</div>
</div>
</div>
</ng-template>
</ng-template>
<ng-template
#
assessment
Dialog
let-modal
>
<ng-template
#
pmsTopic
Dialog
let-modal
>
<h3
mat-dialog-title
>
รายการประเมิน
</h3>
<mat-dialog-content>
<div
class=
"flex justify-end pb-1rem"
>
<div
class=
"px-1"
>
<div
class=
"relative shadow-md"
>
<input
type=
"text"
id=
"hs-leading-icon"
name=
"hs-leading-icon"
class=
"ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[
placeholder
]="'
SearchByNoOrName
'
|
translate
"
[(
ngModel
)]="
modalData
.
search
"
>
<div
class=
"absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4"
>
<i
class=
"ri-search-line text-gray"
></i>
</div>
</div>
</div>
</div>
<div
class=
"overflow-auto border"
>
<table
class=
"ti-custom-table ti-custom-table-head ti-custom-table-hover"
>
<thead>
<tr>
<ng-container
*
ngFor=
"let item of ['รหัส','ชื่อหัวข้อ','ประเภท','น้ำหนัก','การจัดการ']; let f = first; let l = last; let i = index"
>
<th
scope=
"col"
class=
" px-10px py-10px bg-soft-secondary text-primary !text-center"
>
<span
class=
"font-size-12px font-weight-700"
>
{{ item }}
</span>
<div
class=
"absolute top-1/2 transform -translate-y-1/2 right-0"
>
<i
class=
"ti ti-dots-vertical fs-l"
></i>
</div>
</th>
</ng-container>
</tr>
</thead>
<tbody
*
ngIf=
"pmstopic.loading"
>
<tr>
<td
class=
"text-center"
colspan=
"100%"
>
<div
*
ngFor=
"let item of [1,2,3]"
class=
"ti-spinner w-8 h-8 text-secondary mx-1"
role=
"status"
aria-label=
"loading"
>
<span
class=
"sr-only"
>
Loading...
</span>
</div>
</td>
</tr>
</tbody>
<tbody
*
ngIf=
"!pmstopic.loading&&!pmstopicListFilter().length"
>
<tr>
<td
class=
"text-center"
colspan=
"100%"
>
ไม่พบข้อมูล
</td>
</tr>
</tbody>
<tbody
*
ngIf=
"!pmstopic.loading&&pmstopicListFilter().length"
>
<tr
*
ngFor=
"let item of pmstopicListFilter() | slice:((modalData.currentPage-1) * 10) : (((modalData.currentPage-1) * 10) + 10);let i = index"
>
<td
class=
"text-center"
>
{{item.data.pmsTopicId}}
</td>
<td>
{{item.data.tdesc}}
</td>
<td>
{{item.data.pmsType.tdesc}}
</td>
<td>
{{item.data.weight}}
</td>
<td
class=
"text-center"
>
<button
type=
"button"
class=
"ti-btn ti-btn-soft-secondary h-20px m-0 shadow-md"
data-hs-overlay=
"#assessment-table-modal"
(
click
)="
selectPmstopic
(
item
.
data
)"
>
<i
class=
"ri-add-line"
></i>
Select
</button></td>
</tr>
</tbody>
</table>
</div>
<app-pagination
[
totalItems
]="
pmstopicListFilter
().
length
"
[
pageSize
]="
modalData
.
pageSize
"
(
pageChange
)="
modalData
.
currentPage =
$event"
(
pageSizeChange
)="
modalData
.
pageSize =
$event;modalData.currentPage
=
1
"
></app-pagination>
</mat-dialog-content>
<mat-dialog-actions
align=
"end"
>
<button
type=
"button"
mat-button
[
mat-dialog-close
]
(
click
)="
assessmentDialogClose
()"
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>
</mat-dialog-actions>
</ng-template>
<ng-template
#
competencyTopicDialog
let-modal
>
<h3
mat-dialog-title
>
เพิ่ม Individual KPI
{{'เพิ่ม Individual KPI'}}
</h3>
<div
class=
"w-full flex justify-end mb-1rem"
>
<div
class=
"absolute flex"
>
<div
class=
"px-1"
>
<button
type=
"button"
class=
"ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md
"
>
<button
type=
"button"
class=
"ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md"
(
click
)="
selectPmsTopic
()
"
>
<i
class=
"ti ti-eraser text-base"
></i>
Clear
</button>
...
...
@@ -483,72 +355,77 @@
</div>
</div>
<mat-dialog-content>
<label
for=
"detail_th"
class=
"ti-form-label mt-2rem"
>
ชื่อหัวข้อ (ไทย)
<span
class=
"text-danger"
>
*
</span></label>
<input
type=
"text"
id=
"detail_th"
class=
"ti-form-input h-10"
[(
ngModel
)]="
competencyTopic
.
select
.
tdesc
"
>
<label
for=
"detail_eng"
class=
"ti-form-label mt-2rem"
>
ชื่อหัวข้อ (อังกฤษ)
</label>
<input
type=
"text"
id=
"detail_eng"
class=
"ti-form-input h-10"
[(
ngModel
)]="
competencyTopic
.
select
.
edesc
"
>
<label
for=
"detail_eng"
class=
"ti-form-label mt-2rem"
>
นิยามสมรรถนะ
</label>
<textarea
type=
"text"
id=
"detail_eng"
class=
"ti-form-input"
rows=
"4"
cols=
"50"
[(
ngModel
)]="
competencyTopic
.
select
.
competencyDetail
"
>
</textarea>
<label
class=
"ti-form-label mt-2rem"
>
ประเภท Competency
<span
class=
"text-danger"
>
*
</span></label>
<button
type=
"button"
class=
"ti-btn ti-btn-success h-45px m-0 shadow-md"
(
click
)="
pmsTopicTableDialogOpen
()"
>
เพิ่มจากหัวข้อการประเมิน
</button>
<!-- <label class="ti-form-label mt-2rem">ประเภทการประเมินผล<span class="text-danger">*</span></label>
<div class="flex">
<div
class=
"relative flex rounded-md w-1/2"
>
<input
type=
"text"
id=
"hs-leading-button-add-on-with-icon-and-button"
name=
"hs-leading-button-add-on-with-icon-and-button"
class=
"ti-form-input rounded-md ltr:rounded-r-md rtl:rounded-l-md focus:z-10"
style=
"padding-right: 2.5rem;"
readonly
[(
ngModel
)]="
competencyTopic
.
select
.
competencyType
.
shortName
"
>
<div class="relative flex rounded-md">
<input type="text" class="ti-form-input rounded-sm ltr:rounded-r-sm rtl:rounded-l-sm focus:z-10" readonly
style="padding-right: 3.5rem;" [(ngModel)]="pmsTopic.select.pmsType.tdesc">
<div class="absolute inset-y-0 ltr:right-0 rtl:left-0 flex items-center z-20 ltr:pr-4 rtl:pl-4 space-x-2">
<button
type=
"button"
class=
"flex items-center text-red-500"
(
click
)="
selectCompetencyt
ype
()"
>
<button type="button" class="flex items-center text-red-500" (click)="selectPmsT
ype()">
<i class="ti ti-circle-x cursor-pointer"></i>
</button>
<button type="button" class="flex items-center text-gray-500 dark:text-white/70"
(
click
)="
competencyTyp
eDialogOpen
()"
>
(click)="pmsTypeTabl
eDialogOpen()">
<i class="ri-search-line cursor-pointer text-gray"></i>
</button>
</div>
</div>
</div>
<label
class=
"ti-form-label mt-2rem"
>
แนบไฟล์ข้อสอบ
</label>
<div
class=
"flex rounded-md"
>
<label
class=
"sr-only"
>
อัปโหลดไฟล์
</label>
<input
#
fileInputMedium
id=
"fileInputMedium"
type=
"file"
(
change
)="
onExamSelected
($
event
)"
hidden
>
<input
type=
"text"
[
value
]="
examFileName
"
readonly
onclick=
"fileInputMedium.click();"
class=
" cursor-pointer block w-full border border-gray-200 focus:shadow-sm dark:focus:shadow-white/10 ltr:rounded-l-md rtl:rounded-r-none text-sm focus:z-10 focus:outline-0 focus:border-gray-200 dark:focus:border-white/10 dark:border-white/10 dark:text-white/70 file:border-0 file:bg-gray-100 ltr:file:mr-4 rtl:file:ml-4 file:py-3 file:px-4 dark:file:bg-black/20 dark:file:text-white/70"
>
<span
class=
"px-4 inline-flex items-center min-w-fit ltr:rounded-r-md rtl:rounded-l-none border ltr:border-l-0 rtl:border-r-0 border-gray-200 bg-gray-50 text-sm dark:bg-black/20 dark:border-white/10"
>
<button
class=
"text-sm text-gray-500 dark:text-white/70"
onclick=
"fileInputMedium.click();"
>
Browse
</button>
</span>
<div
class=
"flex items-center ml-2"
>
<button
href=
"javascript:void(0);"
class=
"ti-btn ti-btn-soft-danger h-10px m-0 shadow-md rounded-md"
(
click
)="
fileInputMedium
.
value =
''
;
examFile=
null;examFileName
=
'กรุณาเลือกไฟล์'"
>
<i
class=
"ri-delete-bin-6-line"
></i>
Delete
</button>
</div>
</div>
<div
class=
"flex"
*
ngIf=
"examFileName==competencyTopic.select.competencyFiles"
>
<h1
class=
"cursor-pointer justify-center -mb-px inline-flex items-center gap-2 font-weight-500 font-size-12px
text-center text-secondary border-secondary border-b-2 align-items-end"
(
click
)="
downloadExam
(
examFileName
)"
>
ดาวน์โหลดไฟล์ข้อสอบ
</h1>
</div> -->
<label
class=
"ti-form-label mt-2rem"
>
ชื่อหัวข้อ
<span
class=
"text-danger"
>
*
</span></label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
tdesc
"
>
<label
class=
"ti-form-label mt-2rem"
>
ชื่อหัวข้อ (อังกฤษ)
</label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
edesc
"
>
<label
class=
"ti-form-label mt-2rem"
>
ตัวชี้วัดผลงานหลัก
</label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
indicatorsDetail
"
>
<label
class=
"ti-form-label mt-2rem"
>
เป้าหมายผลงาน
</label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
performanceGoalsDetail
"
>
<label
class=
"ti-form-label mt-2rem"
>
หน่วยนับ
</label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
detailUnit
"
>
<label
class=
"ti-form-label mt-2rem"
>
กำหนดเวลาแล้วเสร็จ
</label>
<input
type=
"text"
class=
"ti-form-input"
[(
ngModel
)]="
pmsTopic
.
select
.
completionDate
"
>
<label
class=
"ti-form-label mt-2rem"
>
น้ำหนัก
</label>
<input
type=
"text"
class=
"ti-form-input"
appMoneyInput
[(
ngModel
)]="
pmsTopic
.
select
.
weight
"
>
<label
class=
"ti-form-label mt-2rem"
>
ค่าเป้าหมาย
</label>
<div
class=
"grid grid-cols-12 gap-x-2 mt-2rem"
>
<label
class=
"ti-form-label col-span-3 align-center m-0"
>
A (5 คะแนน)
</label>
<input
type=
"text"
class=
"ti-form-input col-span-9"
[(
ngModel
)]="
pmsTopic
.
select
.
targetAdetail
"
>
</div>
<div
class=
"grid grid-cols-12 gap-x-2 mt-2rem"
>
<label
class=
"ti-form-label col-span-3 align-center m-0"
>
B (4 คะแนน)
</label>
<input
type=
"text"
class=
"ti-form-input col-span-9"
[(
ngModel
)]="
pmsTopic
.
select
.
targetBdetail
"
>
</div>
<div
class=
"grid grid-cols-12 gap-x-2 mt-2rem"
>
<label
class=
"ti-form-label col-span-3 align-center m-0"
>
C (3 คะแนน)
</label>
<input
type=
"text"
class=
"ti-form-input col-span-9"
[(
ngModel
)]="
pmsTopic
.
select
.
targetCdetail
"
>
</div>
<div
class=
"grid grid-cols-12 gap-x-2 mt-2rem"
>
<label
class=
"ti-form-label col-span-3 align-center m-0"
>
D (2 คะแนน)
</label>
<input
type=
"text"
class=
"ti-form-input col-span-9"
[(
ngModel
)]="
pmsTopic
.
select
.
targetDdetail
"
>
</div>
<div
class=
"grid grid-cols-12 gap-x-2 mt-2rem"
>
<label
class=
"ti-form-label col-span-3 align-center m-0"
>
E (1 คะแนน)
</label>
<input
type=
"text"
class=
"ti-form-input col-span-9"
[(
ngModel
)]="
pmsTopic
.
select
.
targetEdetail
"
>
</div>
</mat-dialog-content>
<mat-dialog-actions
align=
"end"
>
<button
type=
"button"
mat-button
[
mat-dialog-close
]
<button
type=
"button"
(
click
)="
pmsTopicDialogClose
()"
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"
class=
"ti-btn ti-btn-success"
mat-button
(
click
)="
confirmCompetencyTopic
()"
[
class
.
ti-btn-disabled
]="!
competencyTopic
.
select
.
competencyType
.
competencyTypeId
||!
competencyTopic
.
select
.
tdesc
||!
competencyTopic
.
select
.
competencyType
.
shortName
"
[
disabled
]="!
competencyTopic
.
select
.
competencyType
.
competencyTypeId
||!
competencyTopic
.
select
.
tdesc
||!
competencyTopic
.
select
.
competencyType
.
shortName
"
>
<button
type=
"button"
class=
"ti-btn ti-btn-success"
(
click
)="
addPmsTopic
();
pmsTopicDialogClose
()"
[
class
.
ti-btn-disabled
]="!
pmsTopic
.
select
.
tdesc
"
[
disabled
]="!
pmsTopic
.
select
.
tdesc
"
>
บันทึกข้อมูล
</button>
</mat-dialog-actions>
</ng-template>
</ng-template>
<ng-template
#
competencyTyp
eDialog
let-modal
>
<ng-template
#
pmsTopicTabl
eDialog
let-modal
>
<h3
mat-dialog-title
>
ประเภทสมรรถนะ
รายการหัวข้อการประเมิน
</h3>
<mat-dialog-content>
<div
class=
"flex justify-end pb-1rem"
>
...
...
@@ -556,7 +433,7 @@
<div
class=
"relative shadow-md"
>
<input
type=
"text"
id=
"hs-leading-icon"
name=
"hs-leading-icon"
class=
"ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[
placeholder
]="'
SearchByNoOrName
'
|
translate
"
[(
ngModel
)]="
modalData
.
search
"
>
[(
ngModel
)]="
syncfutionPmsTopic
.
search
"
>
<div
class=
"absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4"
>
<i
class=
"ri-search-line text-gray"
></i>
...
...
@@ -564,54 +441,51 @@
</div>
</div>
</div>
<div
class=
"overflow-auto border"
>
<table
class=
"ti-custom-table ti-custom-table-head ti-custom-table-hover"
>
<thead>
<tr>
<ng-container
*
ngFor=
"let item of ['รหัส','ชื่อประเภท','ชื่อย่อ','การจัดการ']; let f = first; let l = last"
>
<th
scope=
"col"
class=
"relative px-10px py-10px bg-soft-secondary text-primary !text-center"
>
<span
class=
"text-sm"
>
{{ item }}
</span>
<div
class=
"absolute top-1/2 transform -translate-y-1/2 right-0"
*
ngIf=
"!l"
>
<i
class=
"ti ti-dots-vertical fs-l"
></i>
</div>
</th>
</ng-container>
</tr>
</thead>
<tbody
*
ngIf=
"!competencytypeListFilter().length"
>
<tr>
<td
class=
"text-center"
colspan=
"100%"
>
ไม่พบข้อมูล
</td>
</tr>
</tbody>
<tbody
*
ngIf=
"competencytypeListFilter().length"
>
<tr
*
ngFor=
"let item of competencytypeListFilter()| slice:((modalData.currentPage-1) * 10) : (((modalData.currentPage-1) * 10) + 10);let i = index"
>
<td>
{{item.competencyTypeId}}
</td>
<td>
{{item.tdesc}}
</td>
<td>
{{item.shortName}}
</td>
<td
class=
"flex justify-center"
>
<div
class=
"px-1"
>
<button
type=
"button"
class=
"ti-btn ti-btn-soft-secondary h-20px m-0 shadow-md"
(
click
)="
selectCompetencytype
(
item
)"
>
<i
class=
"ri-add-line"
></i>
Select
<app-datagrid-syncfution
[
searchSettings
]="
syncfutionPmsTopic
.
searchSettings
"
[
searchText
]="
syncfutionPmsTopic
.
search
"
[
dataSource
]="
syncfutionPmsTopic
.
list
"
[
columns
]="
syncfutionPmsTopic
.
columns
"
[
checkBoxSetting
]="
false
"
(
sendSelectData
)="
selectPmsTopic
($
event
);
addPmsTopic
();
pmsTopicTableDialogClose
();
pmsTopicDialogClose
()"
>
</app-datagrid-syncfution>
</mat-dialog-content>
<mat-dialog-actions
align=
"end"
>
<button
type=
"button"
(
click
)="
pmsTopicTableDialogClose
()"
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>
</mat-dialog-actions>
</ng-template>
<ng-template
#
pmsTypeTableDialog
let-modal
>
<h3
mat-dialog-title
>
รายการประเภทการประเมิน
</h3>
<mat-dialog-content>
<div
class=
"flex justify-end pb-1rem"
>
<div
class=
"px-1"
>
<div
class=
"relative shadow-md"
>
<input
type=
"text"
id=
"hs-leading-icon"
name=
"hs-leading-icon"
class=
"ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[
placeholder
]="'
SearchByNoOrName
'
|
translate
"
[(
ngModel
)]="
syncfutionPmsType
.
search
"
>
<div
class=
"absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4"
>
<i
class=
"ri-search-line text-gray"
></i>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<app-pagination
[
totalItems
]="
competencytypeListFilter
().
length
"
[
pageSize
]="
modalData
.
pageSize
"
(
pageChange
)="
modalData
.
currentPage =
$event"
(
pageSizeChange
)="
modalData
.
pageSize =
$event;modalData.currentPage
=
1
"
></app-pagination>
</div>
<app-datagrid-syncfution
[
searchSettings
]="
syncfutionPmsType
.
searchSettings
"
[
searchText
]="
syncfutionPmsType
.
search
"
[
dataSource
]="
syncfutionPmsType
.
list
"
[
columns
]="
syncfutionPmsType
.
columns
"
[
checkBoxSetting
]="
false
"
(
sendSelectData
)="
selectPmsType
($
event
);
pmsTypeTableDialogClose
()"
>
</app-datagrid-syncfution>
</mat-dialog-content>
<mat-dialog-actions
align=
"end"
>
<button
type=
"button"
mat-button
[
mat-dialog-close
]
<button
type=
"button"
(
click
)="
pmsTypeTableDialogClose
()"
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>
</mat-dialog-actions>
</ng-template>
</ng-template>
\ No newline at end of file
src/app/components/setting-individual-kpi/setting-individual-kpi.component.ts
View file @
d6b931f3
import
{
ChangeDetectorRef
,
Component
,
EventEmitter
,
Input
,
Output
,
ViewChild
}
from
'@angular/core'
;
import
{
MatDialog
,
MatDialogRef
}
from
'@angular/material/dialog'
;
import
{
Router
,
ActivatedRoute
}
from
'@angular/router'
;
import
{
CompetencytopicModel
,
MyCompetencytopicModel
}
from
'src/app/shared/model/competencytopic.model'
;
import
{
CompetencytypeModel
,
MyCompetencytypeModel
}
from
'src/app/shared/model/competencytype.model'
;
import
{
EmployeeModel
,
MyEmployeeModel
}
from
'src/app/shared/model/employee.model'
;
import
{
MyPmsGroupAssessment1Model
}
from
'src/app/shared/model/pms-group-assessment1.model'
;
import
{
MyPmstopicModel
,
PmstopicModel
}
from
'src/app/shared/model/pmstopic.model'
;
import
{
AppraisalService
}
from
'src/app/shared/services/appraisal.service'
;
import
{
CompetencytopicService
}
from
'src/app/shared/services/competencytopic.service'
;
import
{
CompetencytypeService
}
from
'src/app/shared/services/competencytype.service'
;
import
{
EmployeeService
}
from
'src/app/shared/services/employee.service'
;
import
{
FileService
}
from
'src/app/shared/services/file.service'
;
import
{
PmstopicService
}
from
'src/app/shared/services/pmstopic.service'
;
import
{
TokenService
}
from
'src/app/shared/services/token.service'
;
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'
;
export
interface
ModalData
{
search
:
string
,
currentPage
:
number
,
pageSize
:
number
}
@
Component
({
selector
:
'app-setting-individual-kpi'
,
templateUrl
:
'./setting-individual-kpi.component.html'
,
styleUrls
:
[
'./setting-individual-kpi.component.scss'
]
})
export
class
SettingIndividualKpiComponent
{
@
Input
()
evaluatee
Id
=
""
@
Input
()
e
valuationForm
:
'self'
|
'sup'
=
"self"
@
Input
()
boss
Id
=
""
@
Input
()
e
mployeeId
=
this
.
tokenService
.
getUserData
().
employeeId
@
Output
()
sendReturnPath
:
EventEmitter
<
any
>
=
new
EventEmitter
<
any
>
();
@
ViewChild
(
"assessmentDialog"
)
assessmentDialog
:
any
;
@
ViewChild
(
"competencyTypeDialog"
)
competencyTypeDialog
:
any
;
@
ViewChild
(
"competencyTopicDialog"
)
competencyTopicDialog
:
any
;
@
ViewChild
(
"fileInputMedium"
)
fileInputMedium
:
any
;
examFile
:
File
|
null
=
null
;
examFileName
:
string
=
'กรุณาเลือกไฟล์'
;
assessmentDialogRef
?:
MatDialogRef
<
unknown
,
any
>
competencyTypeDialogRef
?:
MatDialogRef
<
unknown
,
any
>
competencyTopicDialogRef
?:
MatDialogRef
<
unknown
,
any
>
competencytype
:
{
loading
:
boolean
,
select
:
CompetencytypeModel
,
dataList
:
CompetencytypeModel
[]
}
=
{
loading
:
false
,
select
:
new
MyCompetencytypeModel
({}),
dataList
:
[]
}
competencyTopic
:
{
loading
:
boolean
,
select
:
CompetencytopicModel
,
dataList
:
CompetencytopicModel
[]
}
=
{
loading
:
false
,
select
:
new
MyCompetencytopicModel
({}),
dataList
:
[]
}
evaluatee
:
{
loading
:
boolean
,
data
:
EmployeeModel
}
=
{
loading
:
false
,
data
:
new
MyEmployeeModel
()
}
pmstopic
:
{
loading
:
boolean
,
select
:
PmstopicModel
,
dataList
:
{
check
:
boolean
,
data
:
PmstopicModel
}[]
}
=
{
loading
:
false
,
select
:
new
MyPmstopicModel
(),
dataList
:
[]
}
individualKPI
:
{
loading
:
boolean
,
list
:
any
[]
}
=
{
loading
:
false
,
list
:
[]
}
menuClose
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
()
tableHover
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
()
modalData
:
ModalData
=
{
search
:
""
,
currentPage
:
1
,
pageSize
:
10
}
pmsTopicApprove
:
Map
<
string
,
boolean
>
=
new
Map
<
string
,
boolean
>
()
employee
:
{
loading
:
boolean
,
data
:
EmployeeModel
}
=
{
loading
:
false
,
data
:
new
MyEmployeeModel
()
}
appraisalKpiSettingEmp
:
{
loading
:
boolean
,
select
:
AppraisalKpiSettingEmpModel
,
list
:
AppraisalKpiSettingEmpModel
[]
}
=
{
loading
:
false
,
select
:
new
MyAppraisalKpiSettingEmpModel
(),
list
:
[]
}
@
ViewChild
(
"pmsTopicDialog"
)
pmsTopicDialog
:
any
pmsTopicDialogRef
?:
MatDialogRef
<
unknown
,
any
>
pmsTopic
:
{
loading
:
boolean
,
select
:
TopicModel
,
list
:
TopicModel
[]
}
=
{
loading
:
false
,
select
:
new
MyTopicModel
(),
list
:
[]
}
@
ViewChild
(
"pmsTopicTableDialog"
)
pmsTopicTableDialog
:
any
pmsTopicTableDialogRef
?:
MatDialogRef
<
unknown
,
any
>
syncfutionPmsTopic
=
{
list
:
[]
as
any
,
columns
:
[{
field
:
"pmsTopicId"
,
headerText
:
"Code"
,
type
:
"string"
,
isPrimaryKey
:
true
,
},
{
field
:
"name"
,
headerText
:
"TopicName"
,
type
:
"string"
},
{
field
:
"pmsType"
,
headerText
:
"PmsTypes"
,
type
:
"string"
}],
search
:
''
,
searchSettings
:
{
fields
:
[
'pmsTopicId'
,
'name'
,
'pmsType'
],
operator
:
'contains'
,
ignoreCase
:
false
}
}
pmsType
:
{
loading
:
boolean
,
list
:
PmsTypeModel
[]
}
=
{
loading
:
false
,
list
:
[]
}
@
ViewChild
(
"pmsTypeTableDialog"
)
pmsTypeTableDialog
:
any
pmsTypeTableDialogRef
?:
MatDialogRef
<
unknown
,
any
>
syncfutionPmsType
=
{
list
:
[]
as
any
,
columns
:
[{
field
:
"pmsTypeId"
,
headerText
:
"Code"
,
type
:
"string"
,
isPrimaryKey
:
true
,
},
{
field
:
"name"
,
headerText
:
"TopicName"
,
type
:
"string"
},
{
field
:
"shortName"
,
headerText
:
"Abbreviations"
,
type
:
"string"
}],
search
:
''
,
searchSettings
:
{
fields
:
[
'pmsTypeId'
,
'name'
,
'shortName'
],
operator
:
'contains'
,
ignoreCase
:
false
}
}
lastConfirmBySelf
=
false
constructor
(
private
toastr
:
ToastrService
,
private
dialog
:
MatDialog
,
private
router
:
Router
,
private
employeeService
:
EmployeeService
,
...
...
@@ -58,406 +97,271 @@ export class SettingIndividualKpiComponent {
private
tokenService
:
TokenService
,
private
route
:
ActivatedRoute
,
private
fileService
:
FileService
,
private
pmstopicService
:
PmstopicService
,
private
competencytopicService
:
CompetencytopicService
,
private
competencytypeService
:
CompetencytypeService
)
{
}
private
pmsTypeService
:
PmstypeService
,
private
translateService
:
TranslateService
)
{
this
.
translateService
.
onLangChange
.
subscribe
((
event
)
=>
{
this
.
setSyncfutionPmsTopic
()
this
.
setSyncfutionPmsType
()
});
}
ngOnInit
():
void
{
this
.
getEvaluatee
()
this
.
getPmstopicList
()
this
.
getCompetencytypeList
()
this
.
getPmsTopicList
()
this
.
getPmsTypeList
()
this
.
getWorkingById
()
this
.
getEmpPmsKpi
()
}
returnPath
()
{
this
.
sendReturnPath
.
emit
()
}
get
CompetencytypeList
()
{
this
.
competencytyp
e
.
loading
=
true
this
.
competencytypeService
.
getList
(
).
subscribe
({
get
WorkingById
()
{
this
.
employe
e
.
loading
=
true
this
.
employeeService
.
getWorkingById
(
this
.
employeeId
).
subscribe
({
next
:
response
=>
{
this
.
competencytype
.
dataList
=
response
.
map
(
x
=>
{
return
new
MyCompetencytypeModel
(
x
)
})
this
.
competencytype
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
employee
.
data
=
new
MyEmployeeModel
(
response
)
this
.
employee
.
loading
=
false
this
.
cdr
.
markForCheck
()
},
error
:
error
=>
{
this
.
competencytyp
e
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
employe
e
.
loading
=
false
this
.
cdr
.
markForCheck
()
}
})
}
competencytypeListFilter
()
{
return
this
.
competencytype
.
dataList
.
filter
(
x
=>
x
.
competencyTypeId
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
||
x
.
tdesc
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
||
x
.
shortName
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
()))
getImg
(
text
:
string
)
{
return
this
.
fileService
.
getImg
(
text
)
}
selectCompetencytype
(
data
?:
CompetencytypeModel
)
{
this
.
competencyTopic
.
select
.
competencyType
=
new
MyCompetencytypeModel
(
data
)
this
.
cdr
.
markForCheck
()
this
.
competencyTypeDialogClose
()
onImageError
(
event
:
Event
)
{
const
imgElement
=
event
.
target
as
HTMLImageElement
;
imgElement
.
src
=
'./assets/img/users/defaultperson.jpg'
;
}
translateText
(
th
?:
string
,
en
?:
string
)
{
return
this
.
translateService
.
getCurrentLang
()
==
'th'
?
(
th
||
''
)
:
(
en
||
''
)
}
get
PmstopicList
()
{
this
.
pmstopic
.
loading
=
true
this
.
pmstopicService
.
getList
(
).
subscribe
({
get
EmpPmsKpi
()
{
this
.
appraisalKpiSettingEmp
.
loading
=
true
this
.
appraisalService
.
getEmpPmsKpi
(
this
.
employeeId
,
this
.
bossId
).
subscribe
({
next
:
response
=>
{
this
.
pmstopic
.
dataList
=
response
.
map
(
x
=>
({
check
:
false
,
data
:
new
MyPmstopicModel
(
x
)
}))
this
.
pmstopic
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
appraisalKpiSettingEmp
.
list
=
response
.
map
(
e
=>
new
MyAppraisalKpiSettingEmpModel
(
e
))
this
.
selectAppraisalKpiSettingEmp
(
this
.
appraisalKpiSettingEmp
.
list
[
0
])
if
(
this
.
appraisalKpiSettingEmp
.
select
.
statusAll
.
code
==
'1'
)
{
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
.
forEach
(
e
=>
{
if
(
e
.
approveTopicStatus
!=
2
)
this
.
pmsTopicApprove
.
set
(
e
.
pmsTopicId
,
true
)
})
}
if
((
this
.
bossId
&&
this
.
appraisalKpiSettingEmp
.
select
.
confirmBy
==
'boss'
)
||
(
!
this
.
bossId
&&
this
.
appraisalKpiSettingEmp
.
select
.
confirmBy
!=
'boss'
))
{
this
.
lastConfirmBySelf
=
true
}
this
.
appraisalKpiSettingEmp
.
loading
=
false
this
.
cdr
.
markForCheck
()
},
error
:
error
=>
{
this
.
pmstopic
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
appraisalKpiSettingEmp
.
loading
=
false
this
.
cdr
.
markForCheck
()
}
})
}
pmstopicListFilter
()
{
return
this
.
pmstopic
.
dataList
.
filter
(
x
=>
{
const
data
=
x
.
data
const
match
=
data
.
pmsTopicId
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
||
data
.
tdesc
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
||
data
.
pmsType
.
tdesc
.
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
||
(
data
.
weight
+
""
).
toLowerCase
().
includes
(
this
.
modalData
.
search
.
toLowerCase
())
return
match
selectAppraisalKpiSettingEmp
(
data
?:
AppraisalKpiSettingEmpModel
)
{
this
.
appraisalKpiSettingEmp
.
select
=
new
MyAppraisalKpiSettingEmpModel
(
data
)
}
currentTopicFilter
()
{
return
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
.
filter
(
e
=>
e
.
approveTopicStatus
!=
0
)
}
currentTopicColor
(
approveTopicStatus
:
number
):
string
{
switch
(
approveTopicStatus
)
{
case
0
:
return
'#fb923c52'
;
case
1
:
return
'#2564eb4f'
;
case
2
:
return
'#ffffff'
;
default
:
return
''
;
}
}
getPmsTopicList
()
{
this
.
pmsTopic
.
loading
=
true
this
.
appraisalService
.
getKpi
().
subscribe
({
next
:
response
=>
{
this
.
pmsTopic
.
list
=
response
.
map
(
x
=>
new
MyTopicModel
(
x
))
this
.
pmsTopic
.
loading
=
false
this
.
cdr
.
markForCheck
()
},
error
:
error
=>
{
this
.
pmsTopic
.
loading
=
false
this
.
cdr
.
markForCheck
()
}
})
}
selectPmstopic
(
data
?:
PmstopicModel
)
{
pmsTopicFilter
()
{
return
this
.
pmsTopic
.
list
.
filter
(
b
=>
!
this
.
currentTopicFilter
().
some
(
a
=>
a
.
pmsTopicId
===
b
.
pmsTopicId
));
}
selectPmsTopic
(
data
?:
any
)
{
this
.
pmsTopic
.
select
=
new
MyTopicModel
(
this
.
pmsTopicFilter
().
find
(
e
=>
e
.
pmsTopicId
==
data
?.
pmsTopicId
))
this
.
cdr
.
markForCheck
()
}
assessmentDialogOpen
()
{
this
.
modalData
.
search
=
''
this
.
modalData
.
currentPage
=
1
this
.
modalData
.
pageSize
=
10
this
.
assessmentDialogRef
=
this
.
dialog
.
open
(
this
.
assessmentDialog
,
{
width
:
'80vw'
,
pmsTopicDialogOpen
()
{
this
.
selectPmsTopic
()
this
.
pmsTopicDialogRef
=
this
.
dialog
.
open
(
this
.
pmsTopicDialog
,
{
width
:
'50vw'
,
disableClose
:
false
,
});
}
assessment
DialogClose
()
{
this
.
assessment
DialogRef
?.
close
()
pmsTopic
DialogClose
()
{
this
.
pmsTopic
DialogRef
?.
close
()
}
competencyTypeDialogOpen
()
{
this
.
modalData
.
search
=
''
this
.
modalData
.
currentPage
=
1
this
.
modalData
.
pageSize
=
10
this
.
competencyTypeDialogRef
=
this
.
dialog
.
open
(
this
.
competencyTypeDialog
,
{
width
:
'80vw'
,
pmsTopicTableDialogOpen
()
{
this
.
setSyncfutionPmsTopic
()
this
.
pmsTopicTableDialogRef
=
this
.
dialog
.
open
(
this
.
pmsTopicTableDialog
,
{
width
:
'50vw'
,
disableClose
:
false
,
});
}
competencyTypeDialogClose
()
{
this
.
competencyTypeDialogRef
?.
close
()
pmsTopicTableDialogClose
()
{
this
.
pmsTopicTableDialogRef
?.
close
()
}
setSyncfutionPmsTopic
()
{
this
.
syncfutionPmsTopic
.
list
=
this
.
pmsTopicFilter
().
map
(
e
=>
({
pmsTopicId
:
e
.
pmsTopicId
,
name
:
this
.
translateText
(
e
.
tdesc
,
e
.
edesc
),
pmsType
:
this
.
translateText
(
e
.
pmsType
?.
tdesc
,
e
.
pmsType
?.
edesc
)
}))
}
addPmsTopic
(
pmsTopicId
?:
string
)
{
const
currentTopics
=
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
;
const
selectedTopicId
=
pmsTopicId
||
this
.
pmsTopic
.
select
.
pmsTopicId
;
const
index
=
currentTopics
.
findIndex
(
t
=>
t
.
pmsTopicId
===
selectedTopicId
);
if
(
index
>
-
1
&&
selectedTopicId
)
{
currentTopics
[
index
].
approveTopicStatus
=
2
;
}
else
{
currentTopics
.
push
({
...
this
.
pmsTopic
.
select
,
approveTopicStatus
:
1
});
}
competencyTopicDialogOpen
()
{
if
(
this
.
fileInputMedium
)
{
this
.
fileInputMedium
.
value
=
""
this
.
setSyncfutionPmsTopic
()
this
.
cdr
.
markForCheck
()
}
this
.
competencyTopicDialogRef
=
this
.
dialog
.
open
(
this
.
competencyTopicDialog
,
{
width
:
'50vw'
,
disableClose
:
false
,
});
deletePmsTopic
(
index
:
number
)
{
const
currentTopics
=
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
;
if
(
currentTopics
[
index
].
approveTopicStatus
===
1
)
{
currentTopics
.
splice
(
index
,
1
);
}
else
if
(
index
>
-
1
)
{
currentTopics
[
index
].
approveTopicStatus
=
0
;
}
competencyTopicDialogClose
()
{
this
.
competencyTypeDialogRef
?.
close
()
this
.
cdr
.
markForCheck
()
}
getEvaluatee
()
{
this
.
evaluatee
.
loading
=
true
this
.
employeeService
.
getWorkingById
(
this
.
evaluateeId
).
subscribe
({
getPmsTypeList
()
{
this
.
pmsType
.
loading
=
true
this
.
pmsTypeService
.
getList
().
subscribe
({
next
:
response
=>
{
this
.
evaluatee
.
data
=
new
MyEmployeeModel
(
response
)
this
.
evaluatee
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
pmsType
.
list
=
response
.
map
(
x
=>
new
MyPmsTypeModel
(
x
))
this
.
setSyncfutionPmsType
()
this
.
pmsType
.
loading
=
false
this
.
cdr
.
markForCheck
()
},
error
:
error
=>
{
this
.
evaluate
e
.
loading
=
false
this
.
cdr
.
detectChanges
()
this
.
pmsTyp
e
.
loading
=
false
this
.
cdr
.
markForCheck
()
}
})
}
getImg
(
text
:
string
)
{
return
this
.
fileService
.
getImg
(
text
)
selectPmsType
(
data
?:
any
)
{
this
.
pmsTopic
.
select
.
pmsType
=
new
MyPmsTypeModel
(
this
.
pmsType
.
list
.
find
(
e
=>
e
.
pmsTypeId
==
data
?.
pmsTypeId
))
this
.
cdr
.
markForCheck
()
}
onImageError
(
event
:
Event
)
{
const
imgElement
=
event
.
target
as
HTMLImageElement
;
imgElement
.
src
=
'./assets/img/users/defaultperson.jpg'
;
pmsTypeTableDialogOpen
()
{
this
.
pmsTypeTableDialogRef
=
this
.
dialog
.
open
(
this
.
pmsTypeTableDialog
,
{
width
:
'50vw'
,
disableClose
:
false
,
});
}
returnPath
()
{
this
.
sendReturnPath
.
emit
()
pmsTypeTableDialogClose
()
{
this
.
pmsTypeTableDialogRef
?.
close
()
}
setSyncfutionPmsType
()
{
this
.
syncfutionPmsType
.
list
=
this
.
pmsType
.
list
.
map
(
e
=>
({
pmsTypeId
:
e
.
pmsTypeId
,
name
:
this
.
translateText
(
e
.
tdesc
,
e
.
edesc
),
shortName
:
e
.
shortName
}))
}
onExamSelected
(
event
:
any
)
{
this
.
examFile
=
event
.
target
.
files
.
length
>
0
?
event
.
target
.
files
[
0
]
:
null
;
this
.
examFileName
=
this
.
examFile
?.
name
||
"กรุณาเลือกไฟล์"
savePmsTopic
()
{
Swal
.
fire
({
icon
:
'question'
,
title
:
'แจ้งเตือน'
,
text
:
'ยืนยันการบันทึกข้อมูลหรือไม่'
,
showCancelButton
:
true
,
confirmButtonText
:
'บันทึกข้อมูล'
,
cancelButtonText
:
'ย้อนกลับ'
,
reverseButtons
:
true
,
}).
then
((
result
)
=>
{
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
.
forEach
(
obj
=>
{
if
(
obj
.
approveTopicStatus
!=
2
)
{
obj
.
createStatusBy
=
this
.
bossId
?
'boss'
:
'employee'
;
}
downloadExam
(
fileName
:
string
)
{
this
.
fileService
.
downloadFiles
(
fileName
).
subscribe
({
});
this
.
appraisalService
.
postEmpPmsKpi
(
new
MyAppraisalKpiSettingEmpModel
(
this
.
appraisalKpiSettingEmp
.
select
)
).
subscribe
({
next
:
response
=>
{
const
url
=
window
.
URL
.
createObjectURL
(
response
);
const
a
=
document
.
createElement
(
"a"
);
a
.
href
=
url
;
a
.
download
=
fileName
;
document
.
body
.
appendChild
(
a
);
a
.
click
();
document
.
body
.
removeChild
(
a
);
window
.
URL
.
revokeObjectURL
(
url
);
this
.
cdr
.
detectChanges
()
if
(
response
.
success
)
{
this
.
getEmpPmsKpi
()
this
.
showAlert
(
response
.
message
,
'success'
)
}
else
{
this
.
showAlert
(
response
.
message
,
'error'
)
}
},
error
:
error
=>
{
this
.
showAlert
(
error
.
message
,
'error'
)
this
.
cdr
.
detectChanges
()
}
})
})
}
showAlert
(
text
:
string
,
type
:
'success'
|
'error'
)
{
Swal
.
fire
({
title
:
'แจ้งเตือน'
,
text
:
text
,
icon
:
type
,
confirmButtonText
:
'ตกลง'
,
});
}
confirmCompetencyTopic
()
{
approvePmsTopic
()
{
Swal
.
fire
({
icon
:
'question'
,
title
:
'แจ้งเตือน'
,
text
:
'ยืนยันการ
บันทึก
ข้อมูลหรือไม่'
,
text
:
'ยืนยันการ
อนุมัติ
ข้อมูลหรือไม่'
,
showCancelButton
:
true
,
confirmButtonText
:
'
บันทึก
ข้อมูล'
,
confirmButtonText
:
'
อนุมัติ
ข้อมูล'
,
cancelButtonText
:
'ย้อนกลับ'
,
reverseButtons
:
true
,
}).
then
(
result
=>
{
if
(
result
.
isConfirmed
)
{
this
.
addCompetencyTopic
();
}
});
}).
then
(
(
result
)
=>
{
this
.
appraisalKpiSettingEmp
.
select
.
currentTopic
.
forEach
(
obj
=>
{
if
(
this
.
pmsTopicApprove
.
get
(
obj
.
pmsTopicId
))
{
if
(
obj
.
approveTopicStatus
==
1
)
{
obj
.
approveTopicStatus
=
2
}
addCompetencyTopic
(
competencyFiles
?:
string
)
{
if
(
this
.
examFile
)
{
this
.
uploadExam
();
return
;
if
(
obj
.
approveTopicStatus
==
0
)
{
obj
.
approveTopicStatus
=
0
}
const
user
=
this
.
tokenService
.
getUser
();
const
body
=
new
MyCompetencytopicModel
({
...
this
.
competencyTopic
.
select
,
companyId
:
user
?.
companyid
,
competencyFiles
:
competencyFiles
||
((
this
.
examFileName
==
this
.
competencyTopic
.
select
.
competencyFiles
)
?
this
.
competencyTopic
.
select
.
competencyFiles
:
''
)
});
this
.
competencyTopic
.
loading
=
true
;
this
.
competencytopicService
.
post
(
body
).
subscribe
({
next
:
response
=>
{
if
(
response
.
success
)
{
this
.
showAlert
(
response
.
message
,
'success'
);
this
.
getCompetencytypeList
();
this
.
competencyTopicDialogClose
()
}
else
{
this
.
showAlert
(
response
.
message
,
'error'
);
this
.
competencyTopic
.
loading
=
false
;
this
.
cdr
.
detectChanges
();
}
},
error
:
error
=>
{
this
.
showAlert
(
error
.
message
,
'error'
);
this
.
competencyTopic
.
loading
=
false
;
this
.
cdr
.
detectChanges
();
if
(
obj
.
approveTopicStatus
!=
2
)
{
obj
.
approveTopicStatus
=
3
}
});
}
uploadExam
()
{
if
(
!
this
.
examFile
)
return
;
const
formData
=
new
FormData
();
formData
.
append
(
'file'
,
this
.
examFile
);
this
.
fileService
.
uploadFiles
(
formData
).
subscribe
({
})
this
.
appraisalService
.
postEmpPmsKpiApprove
(
new
MyAppraisalKpiSettingEmpModel
(
this
.
appraisalKpiSettingEmp
.
select
)).
subscribe
({
next
:
response
=>
{
if
(
response
.
success
)
{
this
.
examFile
=
null
;
this
.
addCompetencyTopic
(
response
.
resultObject
);
this
.
getEmpPmsKpi
()
this
.
showAlert
(
response
.
message
,
'success'
)
}
else
{
this
.
showAlert
(
response
.
message
,
'error'
);
this
.
cdr
.
detectChanges
();
this
.
showAlert
(
response
.
message
,
'error'
)
}
},
error
:
error
=>
{
this
.
showAlert
(
error
.
message
,
'error'
);
this
.
cdr
.
detectChanges
();
},
error
:
error
=>
{
this
.
showAlert
(
error
.
message
,
'error'
)
}
})
});
}
showAlert
(
text
:
string
,
type
:
'success'
|
'error'
)
{
this
.
toastr
[
type
](
text
,
'แจ้งเตือน'
,
{
timeOut
:
3000
,
positionClass
:
'toast-top-right'
,
});
}
//
//
// modal: DataModal = {
// search: "",
// currentPage: 1,
// page: Array.from({ length: 1 }, (_, i) => i + 1)
// }
//
// @ViewChild("addKpiDialog") addKpiDialog: any;
// addKpiDialogRef: any
// @ViewChild("competencyTypeTableDialog") competencyTypeTableDialog: any;
// competencyTypeTableDialogRef: any
// @ViewChild("fileInputMedium") fileInputMedium: any;
// examFile: File | null = null;
// examFileName: string = 'กรุณาเลือกไฟล์';
// typeModal: table = {
// currentPage: 1,
// page: Array.from({ length: 1 }, (_, i) => i + 1),
// search: "",
// pageSize: 10
// }
// constructor(
// private dialog: MatDialog,
// private router: Router,
// private employeeService: EmployeeService,
// private appraisalService: AppraisalService,
// private cdr: ChangeDetectorRef,
// private tokenService: TokenService,
// private route: ActivatedRoute,
// private fileService: FileService,
// private pmstopicService: PmstopicService,
// private competencytopicService: CompetencytopicService,
// private competencytypeService: CompetencytypeService
// ) {
// }
// getCompetencytypeList() {
// this.competencytype.loading = true
// this.competencytypeService.getList().subscribe({
// next: response => {
// this.competencytype.dataList = response.map(x => {
// return new MyCompetencytypeModel(x)
// })
// this.competencytype.loading = false
// this.cdr.detectChanges()
// }, error: error => {
// this.competencytype.loading = false
// this.cdr.detectChanges()
// }
// })
// }
// selectPmstopic(data?: PmstopicModel) {
// this.cdr.markForCheck()
// }
// searchCompetencytypeChange() {
// this.typeModal.currentPage = 1
// this.typeModal.page = Array.from({ length: Math.ceil(this.competencytypeListFilter().length / 10) }, (_, i) => i + 1);
// }
// openAddKpiDialog() {
// this.addKpiDialogRef = this.dialog.open(this.addKpiDialog, {
// width: '500px',
// disableClose: false,
// });
// }
// openCompetencyTypeTableDialog() {
// this.competencyTypeTableDialogRef = this.dialog.open(this.competencyTypeTableDialog, {
// width: '500px',
// disableClose: false,
// });
// }
// showAlert(text: string, type: 'success' | 'error') {
// Swal.fire({
// title: 'แจ้งเตือน',
// text: text,
// icon: type,
// confirmButtonText: 'ตกลง',
// });
// }
// onExamSelected(event: any) {
// this.examFile = event.target.files.length > 0 ? event.target.files[0] : null;
// this.examFileName = this.examFile?.name || "กรุณาเลือกไฟล์"
// }
// downloadExam(fileName: string) {
// this.fileService.downloadFiles(fileName).subscribe({
// next: response => {
// const url = window.URL.createObjectURL(response);
// const a = document.createElement("a");
// a.href = url;
// a.download = fileName;
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
// window.URL.revokeObjectURL(url);
// this.cdr.detectChanges()
// }, error: error => {
// this.showAlert(error.message, 'error')
// this.cdr.detectChanges()
// }
// })
// }
// confirmAddCompetency_topic() {
// Swal.fire({
// icon: 'question',
// title: 'แจ้งเตือน',
// text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
// showCancelButton: true,
// confirmButtonText: 'บันทึกข้อมูล',
// cancelButtonText: 'ย้อนกลับ',
// reverseButtons: true,
// }).then(result => {
// if (result.isConfirmed) {
// this.addCompetency_topic();
// }
// });
// }
// addCompetency_topic(competencyFiles?: string) {
// if (this.examFile) {
// this.uploadExam();
// return;
// }
// const user = this.tokenService.getUser();
// const body = new MyCompetencytopicModel({
// ...this.competencyTopic.select,
// companyId: user?.companyid,
// competencyFiles: competencyFiles || ((this.examFileName == this.competencyTopic.select.competencyFiles) ? this.competencyTopic.select.competencyFiles : '')
// });
// this.competencyTopic.loading = true;
// this.competencytopicService.post(body).subscribe({
// next: response => {
// if (response.success) {
// this.showAlert(response.message, 'success');
// // this.getCompetencytopicList();
// // this.closeDialog()
// } else {
// this.showAlert(response.message, 'error');
// this.competencyTopic.loading = false;
// this.cdr.detectChanges();
// }
// },
// error: error => {
// this.showAlert(error.message, 'error');
// this.competencyTopic.loading = false;
// this.cdr.detectChanges();
// }
// });
// }
// uploadExam() {
// if (!this.examFile) return;
// const formData = new FormData();
// formData.append('file', this.examFile);
// this.fileService.uploadFiles(formData).subscribe({
// next: response => {
// if (response.success) {
// this.examFile = null;
// this.addCompetency_topic(response.resultObject);
// } else {
// this.showAlert(response.message, 'error');
// this.cdr.detectChanges();
// }
// },
// error: error => {
// this.showAlert(error.message, 'error');
// this.cdr.detectChanges();
// }
// });
// }
// selectCompetencytype(data: CompetencytypeModel) {
// this.competencyTopic.select.competencyType = JSON.parse(JSON.stringify(data));
// }
}
src/app/shared/components/sidebar/sidebar.component.ts
View file @
d6b931f3
...
...
@@ -99,6 +99,7 @@ export class SidebarComponent {
this
.
currentUrl
.
includes
(
'employee-self-service'
)
||
this
.
currentUrl
.
includes
(
'ess/profile'
)
||
this
.
currentUrl
.
includes
(
'ess/competency-mapping'
)
||
this
.
currentUrl
.
includes
(
'ess/job-family-mapping'
)
||
this
.
currentUrl
.
includes
(
'ess/job-description'
)
if
(
this
.
showSideMenu
)
{
const
html
:
any
=
this
.
elementRef
.
nativeElement
.
ownerDocument
.
documentElement
;;
...
...
@@ -172,6 +173,7 @@ export class SidebarComponent {
this
.
currentUrl
.
includes
(
'employee-self-service'
)
||
this
.
currentUrl
.
includes
(
'ess/profile'
)
||
this
.
currentUrl
.
includes
(
'ess/competency-mapping'
)
||
this
.
currentUrl
.
includes
(
'ess/job-family-mapping'
)
||
this
.
currentUrl
.
includes
(
'ess/job-description'
)
if
(
this
.
showSideMenu
)
{
const
html
:
any
=
this
.
elementRef
.
nativeElement
.
ownerDocument
.
documentElement
;;
...
...
src/app/shared/directive/money-input/money-input.directive.ts
View file @
d6b931f3
...
...
@@ -14,12 +14,13 @@ import { NgControl } from '@angular/forms';
})
export
class
MoneyInputDirective
{
@
Input
()
allowEmpty
:
boolean
=
false
;
constructor
(
private
el
:
ElementRef
<
HTMLInputElement
>
)
{
}
constructor
(
private
el
:
ElementRef
<
HTMLInputElement
>
)
{}
ngAfterViewInit
()
{
setTimeout
(()
=>
{
this
.
formatValue
(
this
.
el
.
nativeElement
.
value
);
this
.
onBlur
()
this
.
onBlur
()
;
});
}
...
...
@@ -30,40 +31,66 @@ export class MoneyInputDirective {
@
HostListener
(
'blur'
)
onBlur
()
{
let
val
=
this
.
el
.
nativeElement
.
value
.
replace
(
/,/g
,
''
);
let
val
=
this
.
el
.
nativeElement
.
value
.
replace
(
/,/g
,
''
)
.
trim
()
;
if
(
!
val
)
return
;
let
num
=
parseFloat
(
val
);
if
(
isNaN
(
num
))
return
;
let
[
intPart
,
decimalPart
=
''
]
=
val
.
split
(
'.'
);
// จำกัดทศนิยมไม่เกิน 2 หลัก
decimalPart
=
decimalPart
.
substring
(
0
,
2
);
// เติม .00 ถ้าไม่มีทศนิยม
if
(
decimalPart
===
''
)
decimalPart
=
'00'
;
let
parts
=
num
.
toFixed
(
2
).
split
(
'.'
);
let
intPart
=
parts
[
0
].
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
','
);
this
.
el
.
nativeElement
.
value
=
`
${
intPart
}
.
${
parts
[
1
]}
`
;
// ใส่ comma ให้จำนวนเต็ม
intPart
=
intPart
.
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
','
);
this
.
el
.
nativeElement
.
value
=
`
${
intPart
}
.
${
decimalPart
}
`
;
}
formatValue
(
value
:
string
)
{
let
cleaned
=
value
.
replace
(
/
[^
0-9.
]
/g
,
''
).
replace
(
/^0+/
,
''
);
const
dotIndex
=
cleaned
.
indexOf
(
'.'
);
if
(
dotIndex
==
0
)
{
cleaned
=
`0.`
;
}
else
if
(
dotIndex
!==
-
1
)
{
const
beforeDot
=
cleaned
.
slice
(
0
,
dotIndex
);
let
afterDot
=
cleaned
.
slice
(
dotIndex
+
1
).
replace
(
/
\.
/g
,
''
);
afterDot
=
afterDot
.
substring
(
0
,
2
);
// หลังจุด 2 ตัว
cleaned
=
`
${
beforeDot
}
.
${
afterDot
}
`
;
}
if
(
!
this
.
allowEmpty
&&
cleaned
==
''
)
{
cleaned
=
'0'
// เก็บจุดไว้ ถ้ามีอยู่แล้วในข้อความ
const
hasDot
=
value
.
includes
(
'.'
);
// ลบอักขระที่ไม่ใช่ตัวเลขหรือจุด
let
cleaned
=
value
.
replace
(
/
[^
0-9.
]
/g
,
''
);
// จำกัดให้มีจุดทศนิยมได้แค่ 1 จุด
const
firstDot
=
cleaned
.
indexOf
(
'.'
);
if
(
firstDot
!==
-
1
)
{
cleaned
=
cleaned
.
slice
(
0
,
firstDot
+
1
)
+
cleaned
.
slice
(
firstDot
+
1
).
replace
(
/
\.
/g
,
''
);
}
let
[
intPart
,
decimalPart
]
=
cleaned
.
split
(
'.'
);
i
ntPart
=
intPart
.
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
','
)
;
// กรณีเริ่มด้วยจุด เช่น ".5" → "0.5"
i
f
(
cleaned
.
startsWith
(
'.'
))
cleaned
=
'0'
+
cleaned
;
this
.
el
.
nativeElement
.
value
=
decimalPart
!==
undefined
?
`
${
intPart
}
.
${
decimalPart
}
`
:
intPart
;
// ลบศูนย์นำหน้า (ถ้าไม่ใช่ "0." และยาวเกิน 1)
if
(
!
cleaned
.
startsWith
(
'0.'
)
&&
cleaned
.
length
>
1
)
{
cleaned
=
cleaned
.
replace
(
/^0+/
,
''
);
}
if
(
!
this
.
allowEmpty
&&
cleaned
===
''
)
cleaned
=
'0'
;
let
[
intPart
,
decimalPart
=
''
]
=
cleaned
.
split
(
'.'
);
// จำกัดทศนิยมไม่เกิน 2 หลัก
decimalPart
=
decimalPart
.
substring
(
0
,
2
);
// ใส่ comma ให้จำนวนเต็ม
intPart
=
intPart
.
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
','
);
// รวมกลับ โดยถ้าผู้ใช้เพิ่งพิม "." ให้คงไว้ (เพื่อให้พิมพ์ต่อได้)
this
.
el
.
nativeElement
.
value
=
hasDot
&&
!
value
.
endsWith
(
'.'
)
&&
decimalPart
===
''
?
`
${
intPart
}
.`
:
decimalPart
!==
''
?
`
${
intPart
}
.
${
decimalPart
}
`
:
value
.
endsWith
(
'.'
)
?
`
${
intPart
}
.`
:
intPart
;
}
}
...
...
src/app/shared/model/appraisal-kpi-setting-emp.model.ts
0 → 100644
View file @
d6b931f3
export
interface
AppraisalKpiSettingEmpModel
{
apsassessy
:
ApsassessyModel
apsyear
:
string
currentTopic
:
TopicModel
[]
defendTopic
:
TopicModel
[]
jd
:
string
pmsEvaluationRoundId
:
string
statusAll
:
StatusAllModel
confirmBy
:
string
}
export
class
MyAppraisalKpiSettingEmpModel
implements
AppraisalKpiSettingEmpModel
{
apsassessy
:
ApsassessyModel
apsyear
:
string
currentTopic
:
TopicModel
[]
defendTopic
:
TopicModel
[]
jd
:
string
pmsEvaluationRoundId
:
string
statusAll
:
StatusAllModel
confirmBy
:
string
constructor
(
data
?:
Partial
<
AppraisalKpiSettingEmpModel
>
)
{
this
.
apsassessy
=
new
MyApsassessyModel
(
data
?.
apsassessy
)
this
.
apsyear
=
data
?.
apsyear
||
''
this
.
currentTopic
=
(
data
?.
currentTopic
||
[]).
map
(
e
=>
new
MyTopicModel
(
e
))
this
.
defendTopic
=
(
data
?.
defendTopic
||
[]).
map
(
e
=>
new
MyTopicModel
(
e
))
this
.
jd
=
data
?.
jd
||
''
this
.
pmsEvaluationRoundId
=
data
?.
pmsEvaluationRoundId
||
''
this
.
statusAll
=
new
MyStatusAllModel
(
data
?.
statusAll
)
this
.
confirmBy
=
data
?.
confirmBy
||
''
}
}
export
interface
StatusAllModel
{
code
:
string
edesc
:
string
tdesc
:
string
}
export
class
MyStatusAllModel
implements
StatusAllModel
{
code
:
string
edesc
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusAllModel
>
)
{
this
.
code
=
data
?.
code
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- GradeDetailModel ----------------
export
interface
GradeDetailModel
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
}
export
class
MyGradeDetailModel
implements
GradeDetailModel
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
constructor
(
data
?:
Partial
<
GradeDetailModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
gradeDetail
=
data
?.
gradeDetail
||
''
this
.
gradeId
=
data
?.
gradeId
||
''
this
.
gradeMaxScore
=
data
?.
gradeMaxScore
??
0
this
.
gradeMinScore
=
data
?.
gradeMinScore
??
0
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
weight
=
data
?.
weight
??
0
}
}
// ---------------- GradeModel ----------------
// Note: Grade2 is considered same as Grade -> we use GradeModel
export
interface
GradeModel
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetailModel
[]
}
export
class
MyGradeModel
implements
GradeModel
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetailModel
[]
constructor
(
data
?:
Partial
<
GradeModel
>
)
{
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
gradeDetail
=
(
data
?.
gradeDetail
||
[]).
map
(
e
=>
new
MyGradeDetailModel
(
e
))
}
}
// ---------------- Bu1Model ----------------
export
interface
Bu1Model
{
bu1id
:
string
companyId
:
string
edesc
:
string
grade
:
GradeModel
tdesc
:
string
}
export
class
MyBu1Model
implements
Bu1Model
{
bu1id
:
string
companyId
:
string
edesc
:
string
grade
:
GradeModel
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu1Model
>
)
{
this
.
bu1id
=
data
?.
bu1id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
grade
=
new
MyGradeModel
(
data
?.
grade
)
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- Bu2Model ----------------
export
interface
Bu2Model
{
bu2id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu2Model
implements
Bu2Model
{
bu2id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu2Model
>
)
{
this
.
bu2id
=
data
?.
bu2id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- Bu3Model ----------------
export
interface
Bu3Model
{
bu3id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu3Model
implements
Bu3Model
{
bu3id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu3Model
>
)
{
this
.
bu3id
=
data
?.
bu3id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- Bu4Model ----------------
export
interface
Bu4Model
{
bu4id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu4Model
implements
Bu4Model
{
bu4id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu4Model
>
)
{
this
.
bu4id
=
data
?.
bu4id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- Bu5Model ----------------
export
interface
Bu5Model
{
bu5id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu5Model
implements
Bu5Model
{
bu5id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu5Model
>
)
{
this
.
bu5id
=
data
?.
bu5id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- JobModel ----------------
export
interface
JobModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
}
export
class
MyJobModel
implements
JobModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
constructor
(
data
?:
Partial
<
JobModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
jobCodeId
=
data
?.
jobCodeId
||
''
this
.
statusCom
=
data
?.
statusCom
??
false
this
.
statusPms
=
data
?.
statusPms
??
false
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- PmsTypeModel ----------------
export
interface
PmsTypeModel
{
companyId
:
string
edesc
:
string
pmsTypeId
:
string
shortName
:
string
tdesc
:
string
weight
:
number
}
export
class
MyPmsTypeModel
implements
PmsTypeModel
{
companyId
:
string
edesc
:
string
pmsTypeId
:
string
shortName
:
string
tdesc
:
string
weight
:
number
constructor
(
data
?:
Partial
<
PmsTypeModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
pmsTypeId
=
data
?.
pmsTypeId
||
''
this
.
shortName
=
data
?.
shortName
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
weight
=
data
?.
weight
??
0
}
}
export
interface
TopicModel
{
approveTopicStatus
:
number
companyId
:
string
completionDate
:
string
createStatusBy
:
string
detailUnit
:
string
edesc
:
string
indicatorsDetail
:
string
jl
:
string
lineNo
:
number
performanceGoalsDetail
:
string
pmsTopicId
:
string
pmsType
:
PmsTypeModel
|
null
scoreTopicExpectation
:
number
scoreTopicExpectationBoss
:
number
statusApprove
:
string
targetAdetail
:
string
targetBdetail
:
string
targetCdetail
:
string
targetDdetail
:
string
targetEdetail
:
string
tdesc
:
string
weight
:
number
}
export
class
MyTopicModel
implements
TopicModel
{
approveTopicStatus
:
number
companyId
:
string
completionDate
:
string
createStatusBy
:
string
detailUnit
:
string
edesc
:
string
indicatorsDetail
:
string
jl
:
string
lineNo
:
number
performanceGoalsDetail
:
string
pmsTopicId
:
string
pmsType
:
PmsTypeModel
|
null
scoreTopicExpectation
:
number
scoreTopicExpectationBoss
:
number
statusApprove
:
string
targetAdetail
:
string
targetBdetail
:
string
targetCdetail
:
string
targetDdetail
:
string
targetEdetail
:
string
tdesc
:
string
weight
:
number
constructor
(
data
?:
Partial
<
TopicModel
>
)
{
this
.
approveTopicStatus
=
data
?.
approveTopicStatus
??
0
this
.
companyId
=
data
?.
companyId
||
''
this
.
completionDate
=
data
?.
completionDate
||
''
this
.
createStatusBy
=
data
?.
createStatusBy
||
''
this
.
detailUnit
=
data
?.
detailUnit
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
indicatorsDetail
=
data
?.
indicatorsDetail
||
''
this
.
jl
=
data
?.
jl
||
''
this
.
lineNo
=
data
?.
lineNo
??
0
this
.
performanceGoalsDetail
=
data
?.
performanceGoalsDetail
||
''
this
.
pmsTopicId
=
data
?.
pmsTopicId
||
''
this
.
pmsType
=
data
?.
pmsType
?
new
MyPmsTypeModel
(
data
?.
pmsType
)
:
null
this
.
scoreTopicExpectation
=
data
?.
scoreTopicExpectation
??
0
this
.
scoreTopicExpectationBoss
=
data
?.
scoreTopicExpectationBoss
??
0
this
.
statusApprove
=
data
?.
statusApprove
||
''
this
.
targetAdetail
=
data
?.
targetAdetail
||
''
this
.
targetBdetail
=
data
?.
targetBdetail
||
''
this
.
targetCdetail
=
data
?.
targetCdetail
||
''
this
.
targetDdetail
=
data
?.
targetDdetail
||
''
this
.
targetEdetail
=
data
?.
targetEdetail
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
weight
=
data
?.
weight
??
0
}
}
// ---------------- PositionModel ----------------
export
interface
PositionModel
{
companyId
:
string
consolidate
:
string
edesc
:
string
positionId
:
string
shortName
:
string
tdesc
:
string
}
export
class
MyPositionModel
implements
PositionModel
{
companyId
:
string
consolidate
:
string
edesc
:
string
positionId
:
string
shortName
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PositionModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
consolidate
=
data
?.
consolidate
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
positionId
=
data
?.
positionId
||
''
this
.
shortName
=
data
?.
shortName
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- PrefixModel ----------------
export
interface
PrefixModel
{
edesc
:
string
prefixId
:
string
tdesc
:
string
}
export
class
MyPrefixModel
implements
PrefixModel
{
edesc
:
string
prefixId
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PrefixModel
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
prefixId
=
data
?.
prefixId
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- StatusModel ----------------
export
interface
StatusModel
{
edesc
:
string
statusCode
:
string
statusType
:
string
tdesc
:
string
}
export
class
MyStatusModel
implements
StatusModel
{
edesc
:
string
statusCode
:
string
statusType
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusModel
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
statusCode
=
data
?.
statusCode
||
''
this
.
statusType
=
data
?.
statusType
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- Time0Model ----------------
export
interface
Time0Model
{
edesc
:
string
hourD
:
number
stickTm
:
string
tdesc
:
string
time0id
:
string
}
export
class
MyTime0Model
implements
Time0Model
{
edesc
:
string
hourD
:
number
stickTm
:
string
tdesc
:
string
time0id
:
string
constructor
(
data
?:
Partial
<
Time0Model
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
hourD
=
data
?.
hourD
??
0
this
.
stickTm
=
data
?.
stickTm
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
time0id
=
data
?.
time0id
||
''
}
}
// ---------------- PlModel ----------------
export
interface
PlModel
{
companyId
:
string
edesc
:
string
grade
:
GradeModel
plId
:
string
tdesc
:
string
}
export
class
MyPlModel
implements
PlModel
{
companyId
:
string
edesc
:
string
grade
:
GradeModel
plId
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PlModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
grade
=
new
MyGradeModel
(
data
?.
grade
)
this
.
plId
=
data
?.
plId
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// ---------------- ApsassessyModel (root) ----------------
export
interface
ApsassessyModel
{
bossId
:
string
bu1
:
Bu1Model
bu2
:
Bu2Model
bu3
:
Bu3Model
bu4
:
Bu4Model
bu5
:
Bu5Model
efname
:
string
elname
:
string
employeeId
:
string
endWorkDate
:
string
engFullName
:
string
fname
:
string
job
:
JobModel
lname
:
string
picture
:
string
pl
:
PlModel
position
:
PositionModel
prefix
:
PrefixModel
resignDate
:
string
startDate
:
string
status
:
StatusModel
thFullName
:
string
time0
:
Time0Model
}
export
class
MyApsassessyModel
implements
ApsassessyModel
{
bossId
:
string
bu1
:
Bu1Model
bu2
:
Bu2Model
bu3
:
Bu3Model
bu4
:
Bu4Model
bu5
:
Bu5Model
efname
:
string
elname
:
string
employeeId
:
string
endWorkDate
:
string
engFullName
:
string
fname
:
string
job
:
JobModel
lname
:
string
picture
:
string
pl
:
PlModel
position
:
PositionModel
prefix
:
PrefixModel
resignDate
:
string
startDate
:
string
status
:
StatusModel
thFullName
:
string
time0
:
Time0Model
constructor
(
data
?:
Partial
<
ApsassessyModel
>
)
{
this
.
bossId
=
data
?.
bossId
||
''
this
.
bu1
=
new
MyBu1Model
(
data
?.
bu1
)
this
.
bu2
=
new
MyBu2Model
(
data
?.
bu2
)
this
.
bu3
=
new
MyBu3Model
(
data
?.
bu3
)
this
.
bu4
=
new
MyBu4Model
(
data
?.
bu4
)
this
.
bu5
=
new
MyBu5Model
(
data
?.
bu5
)
this
.
efname
=
data
?.
efname
||
''
this
.
elname
=
data
?.
elname
||
''
this
.
employeeId
=
data
?.
employeeId
||
''
this
.
endWorkDate
=
data
?.
endWorkDate
||
''
this
.
engFullName
=
data
?.
engFullName
||
''
this
.
fname
=
data
?.
fname
||
''
this
.
job
=
new
MyJobModel
(
data
?.
job
)
this
.
lname
=
data
?.
lname
||
''
this
.
picture
=
data
?.
picture
||
''
this
.
pl
=
new
MyPlModel
(
data
?.
pl
)
this
.
position
=
new
MyPositionModel
(
data
?.
position
)
this
.
prefix
=
new
MyPrefixModel
(
data
?.
prefix
)
this
.
resignDate
=
data
?.
resignDate
||
''
this
.
startDate
=
data
?.
startDate
||
''
this
.
status
=
new
MyStatusModel
(
data
?.
status
)
this
.
thFullName
=
data
?.
thFullName
||
''
this
.
time0
=
new
MyTime0Model
(
data
?.
time0
)
}
}
src/app/shared/model/appraisal-kpi-setting.model.ts
0 → 100644
View file @
d6b931f3
export
interface
AppraisalKpiSettingModel
{
apsassessy
:
ApsassessyModel
pmsEvaluationRound
:
PmsEvaluationRoundModel
statusApprove
:
StatusApproveModel
}
export
class
MyAppraisalKpiSettingModel
implements
AppraisalKpiSettingModel
{
apsassessy
:
ApsassessyModel
pmsEvaluationRound
:
PmsEvaluationRoundModel
statusApprove
:
StatusApproveModel
constructor
(
data
?:
Partial
<
AppraisalKpiSettingModel
>
)
{
this
.
apsassessy
=
new
MyApsassessyModel
(
data
?.
apsassessy
)
this
.
pmsEvaluationRound
=
new
MyPmsEvaluationRoundModel
(
data
?.
pmsEvaluationRound
)
this
.
statusApprove
=
new
MyStatusApproveModel
(
data
?.
statusApprove
)
}
}
export
interface
ApsassessyModel
{
bossId
:
string
bu1
:
Bu1Model
bu2
:
Bu2Model
bu3
:
Bu3Model
bu4
:
Bu4Model
bu5
:
Bu5Model
efname
:
string
elname
:
string
employeeId
:
string
endWorkDate
:
string
engFullName
:
string
fname
:
string
job
:
JobModel
lname
:
string
picture
:
string
pl
:
PlModel
position
:
PositionModel
prefix
:
PrefixModel
resignDate
:
string
startDate
:
string
status
:
StatusModel
thFullName
:
string
time0
:
TimeModel
}
export
class
MyApsassessyModel
implements
ApsassessyModel
{
bossId
:
string
bu1
:
Bu1Model
bu2
:
Bu2Model
bu3
:
Bu3Model
bu4
:
Bu4Model
bu5
:
Bu5Model
efname
:
string
elname
:
string
employeeId
:
string
endWorkDate
:
string
engFullName
:
string
fname
:
string
job
:
JobModel
lname
:
string
picture
:
string
pl
:
PlModel
position
:
PositionModel
prefix
:
PrefixModel
resignDate
:
string
startDate
:
string
status
:
StatusModel
thFullName
:
string
time0
:
TimeModel
constructor
(
data
?:
Partial
<
ApsassessyModel
>
)
{
this
.
bossId
=
data
?.
bossId
||
''
this
.
bu1
=
new
MyBu1Model
(
data
?.
bu1
)
this
.
bu2
=
new
MyBu2Model
(
data
?.
bu2
)
this
.
bu3
=
new
MyBu3Model
(
data
?.
bu3
)
this
.
bu4
=
new
MyBu4Model
(
data
?.
bu4
)
this
.
bu5
=
new
MyBu5Model
(
data
?.
bu5
)
this
.
efname
=
data
?.
efname
||
''
this
.
elname
=
data
?.
elname
||
''
this
.
employeeId
=
data
?.
employeeId
||
''
this
.
endWorkDate
=
data
?.
endWorkDate
||
''
this
.
engFullName
=
data
?.
engFullName
||
''
this
.
fname
=
data
?.
fname
||
''
this
.
job
=
new
MyJobModel
(
data
?.
job
)
this
.
lname
=
data
?.
lname
||
''
this
.
picture
=
data
?.
picture
||
''
this
.
pl
=
new
MyPlModel
(
data
?.
pl
)
this
.
position
=
new
MyPositionModel
(
data
?.
position
)
this
.
prefix
=
new
MyPrefixModel
(
data
?.
prefix
)
this
.
resignDate
=
data
?.
resignDate
||
''
this
.
startDate
=
data
?.
startDate
||
''
this
.
status
=
new
MyStatusModel
(
data
?.
status
)
this
.
thFullName
=
data
?.
thFullName
||
''
this
.
time0
=
new
MyTimeModel
(
data
?.
time0
)
}
}
// -------------------- BU1 --------------------
export
interface
Bu1Model
{
bu1id
:
string
companyId
:
string
edesc
:
string
grade
:
GradeModel
tdesc
:
string
}
export
class
MyBu1Model
implements
Bu1Model
{
bu1id
:
string
companyId
:
string
edesc
:
string
grade
:
GradeModel
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu1Model
>
)
{
this
.
bu1id
=
data
?.
bu1id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
grade
=
new
MyGradeModel
(
data
?.
grade
)
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- GRADE --------------------
export
interface
GradeModel
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetailModel
[]
}
export
class
MyGradeModel
implements
GradeModel
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetailModel
[]
constructor
(
data
?:
Partial
<
GradeModel
>
)
{
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
gradeDetail
=
(
data
?.
gradeDetail
||
[]).
map
(
e
=>
new
MyGradeDetailModel
(
e
))
}
}
export
interface
GradeDetailModel
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
}
export
class
MyGradeDetailModel
implements
GradeDetailModel
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
constructor
(
data
?:
Partial
<
GradeDetailModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
gradeDetail
=
data
?.
gradeDetail
||
''
this
.
gradeId
=
data
?.
gradeId
||
''
this
.
gradeMaxScore
=
data
?.
gradeMaxScore
??
0
this
.
gradeMinScore
=
data
?.
gradeMinScore
??
0
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
weight
=
data
?.
weight
??
0
}
}
// -------------------- BU2-BU5 --------------------
export
interface
Bu2Model
{
bu2id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu2Model
implements
Bu2Model
{
bu2id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu2Model
>
)
{
this
.
bu2id
=
data
?.
bu2id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
export
interface
Bu3Model
{
bu3id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu3Model
implements
Bu3Model
{
bu3id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu3Model
>
)
{
this
.
bu3id
=
data
?.
bu3id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
export
interface
Bu4Model
{
bu4id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu4Model
implements
Bu4Model
{
bu4id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu4Model
>
)
{
this
.
bu4id
=
data
?.
bu4id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
export
interface
Bu5Model
{
bu5id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
}
export
class
MyBu5Model
implements
Bu5Model
{
bu5id
:
string
companyId
:
string
edesc
:
string
parent
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
Bu5Model
>
)
{
this
.
bu5id
=
data
?.
bu5id
||
''
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
parent
=
data
?.
parent
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- JOB --------------------
export
interface
JobModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
}
export
class
MyJobModel
implements
JobModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
constructor
(
data
?:
Partial
<
JobModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
jobCodeId
=
data
?.
jobCodeId
||
''
this
.
statusCom
=
data
?.
statusCom
??
false
this
.
statusPms
=
data
?.
statusPms
??
false
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- PL + Grade2 --------------------
export
interface
PlModel
{
companyId
:
string
edesc
:
string
grade
:
Grade2Model
plId
:
string
tdesc
:
string
}
export
class
MyPlModel
implements
PlModel
{
companyId
:
string
edesc
:
string
grade
:
Grade2Model
plId
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PlModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
grade
=
new
MyGrade2Model
(
data
?.
grade
)
this
.
plId
=
data
?.
plId
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
export
interface
Grade2Model
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetail2Model
[]
}
export
class
MyGrade2Model
implements
Grade2Model
{
countAverage
:
string
countEmployee
:
string
countScore
:
string
gradeDetail
:
GradeDetail2Model
[]
constructor
(
data
?:
Partial
<
Grade2Model
>
)
{
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
gradeDetail
=
(
data
?.
gradeDetail
||
[]).
map
(
e
=>
new
MyGradeDetail2Model
(
e
))
}
}
export
interface
GradeDetail2Model
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
}
export
class
MyGradeDetail2Model
implements
GradeDetail2Model
{
companyId
:
string
countAverage
:
string
countEmployee
:
string
countScore
:
string
edesc
:
string
gradeDetail
:
string
gradeId
:
string
gradeMaxScore
:
number
gradeMinScore
:
number
tdesc
:
string
weight
:
number
constructor
(
data
?:
Partial
<
GradeDetail2Model
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
countAverage
=
data
?.
countAverage
||
''
this
.
countEmployee
=
data
?.
countEmployee
||
''
this
.
countScore
=
data
?.
countScore
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
gradeDetail
=
data
?.
gradeDetail
||
''
this
.
gradeId
=
data
?.
gradeId
||
''
this
.
gradeMaxScore
=
data
?.
gradeMaxScore
??
0
this
.
gradeMinScore
=
data
?.
gradeMinScore
??
0
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
weight
=
data
?.
weight
??
0
}
}
// -------------------- POSITION --------------------
export
interface
PositionModel
{
companyId
:
string
consolidate
:
string
edesc
:
string
positionId
:
string
shortName
:
string
tdesc
:
string
}
export
class
MyPositionModel
implements
PositionModel
{
companyId
:
string
consolidate
:
string
edesc
:
string
positionId
:
string
shortName
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PositionModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
consolidate
=
data
?.
consolidate
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
positionId
=
data
?.
positionId
||
''
this
.
shortName
=
data
?.
shortName
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- PREFIX --------------------
export
interface
PrefixModel
{
edesc
:
string
prefixId
:
string
tdesc
:
string
}
export
class
MyPrefixModel
implements
PrefixModel
{
edesc
:
string
prefixId
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
PrefixModel
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
prefixId
=
data
?.
prefixId
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- STATUS --------------------
export
interface
StatusModel
{
edesc
:
string
statusCode
:
string
statusType
:
string
tdesc
:
string
}
export
class
MyStatusModel
implements
StatusModel
{
edesc
:
string
statusCode
:
string
statusType
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusModel
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
statusCode
=
data
?.
statusCode
||
''
this
.
statusType
=
data
?.
statusType
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- TIME0 --------------------
export
interface
TimeModel
{
edesc
:
string
hourD
:
number
stickTm
:
string
tdesc
:
string
time0id
:
string
}
export
class
MyTimeModel
implements
TimeModel
{
edesc
:
string
hourD
:
number
stickTm
:
string
tdesc
:
string
time0id
:
string
constructor
(
data
?:
Partial
<
TimeModel
>
)
{
this
.
edesc
=
data
?.
edesc
||
''
this
.
hourD
=
data
?.
hourD
??
0
this
.
stickTm
=
data
?.
stickTm
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
this
.
time0id
=
data
?.
time0id
||
''
}
}
// -------------------- PmsEvaluationRound --------------------
export
interface
PmsEvaluationRoundModel
{
active
:
number
apsPeriodEnd
:
string
apsPeriodStart
:
string
apsyear
:
string
checkForm
:
number
companyId
:
string
edesc
:
string
jd
:
JdModel
[]
jdId
:
string
pmsEvaluationRoundId
:
string
statusCode
:
StatusCodeModel
statusFrom
:
StatusFromModel
tdesc
:
string
}
export
class
MyPmsEvaluationRoundModel
implements
PmsEvaluationRoundModel
{
active
:
number
apsPeriodEnd
:
string
apsPeriodStart
:
string
apsyear
:
string
checkForm
:
number
companyId
:
string
edesc
:
string
jd
:
JdModel
[]
jdId
:
string
pmsEvaluationRoundId
:
string
statusCode
:
StatusCodeModel
statusFrom
:
StatusFromModel
tdesc
:
string
constructor
(
data
?:
Partial
<
PmsEvaluationRoundModel
>
)
{
this
.
active
=
data
?.
active
??
0
this
.
apsPeriodEnd
=
data
?.
apsPeriodEnd
||
''
this
.
apsPeriodStart
=
data
?.
apsPeriodStart
||
''
this
.
apsyear
=
data
?.
apsyear
||
''
this
.
checkForm
=
data
?.
checkForm
??
0
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
jd
=
(
data
?.
jd
||
[]).
map
(
e
=>
new
MyJdModel
(
e
))
this
.
jdId
=
data
?.
jdId
||
''
this
.
pmsEvaluationRoundId
=
data
?.
pmsEvaluationRoundId
||
''
this
.
statusCode
=
new
MyStatusCodeModel
(
data
?.
statusCode
)
this
.
statusFrom
=
new
MyStatusFromModel
(
data
?.
statusFrom
)
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- JD --------------------
export
interface
JdModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
}
export
class
MyJdModel
implements
JdModel
{
companyId
:
string
edesc
:
string
jobCodeId
:
string
statusCom
:
boolean
statusPms
:
boolean
tdesc
:
string
constructor
(
data
?:
Partial
<
JdModel
>
)
{
this
.
companyId
=
data
?.
companyId
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
jobCodeId
=
data
?.
jobCodeId
||
''
this
.
statusCom
=
data
?.
statusCom
??
false
this
.
statusPms
=
data
?.
statusPms
??
false
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- StatusCode --------------------
export
interface
StatusCodeModel
{
code
:
string
edesc
:
string
tdesc
:
string
}
export
class
MyStatusCodeModel
implements
StatusCodeModel
{
code
:
string
edesc
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusCodeModel
>
)
{
this
.
code
=
data
?.
code
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- StatusFrom --------------------
export
interface
StatusFromModel
{
code
:
string
edesc
:
string
tdesc
:
string
}
export
class
MyStatusFromModel
implements
StatusFromModel
{
code
:
string
edesc
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusFromModel
>
)
{
this
.
code
=
data
?.
code
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
// -------------------- StatusApprove --------------------
export
interface
StatusApproveModel
{
code
:
string
edesc
:
string
tdesc
:
string
}
export
class
MyStatusApproveModel
implements
StatusApproveModel
{
code
:
string
edesc
:
string
tdesc
:
string
constructor
(
data
?:
Partial
<
StatusApproveModel
>
)
{
this
.
code
=
data
?.
code
||
''
this
.
edesc
=
data
?.
edesc
||
''
this
.
tdesc
=
data
?.
tdesc
||
''
}
}
src/app/shared/services/appraisal.service.ts
View file @
d6b931f3
...
...
@@ -8,6 +8,8 @@ import { AppraisalSubordinateModel } from '../model/appraisal-subordinate.model'
import
{
AppraisalPmsFormModel
}
from
'../model/appraisal-pms-form.model'
;
import
{
AppraisalPmsModel
}
from
'../model/appraisal-pms.model'
;
import
{
CompetencyModel
}
from
'../model/competency.model'
;
import
{
AppraisalKpiSettingModel
}
from
'../model/appraisal-kpi-setting.model'
;
import
{
AppraisalKpiSettingEmpModel
,
TopicModel
}
from
'../model/appraisal-kpi-setting-emp.model'
;
@
Injectable
({
providedIn
:
'root'
})
...
...
@@ -51,4 +53,22 @@ export class AppraisalService {
}):
Observable
<
AlertModel
>
{
return
this
.
http
.
post
<
AlertModel
>
(
this
.
urlApi
+
"/approveAll"
,
body
)
}
getEmpKpi
():
Observable
<
AppraisalKpiSettingModel
[]
>
{
return
this
.
http
.
get
<
AppraisalKpiSettingModel
[]
>
(
this
.
urlApi
+
"/boss/emp-kpi"
)
}
getKpi
():
Observable
<
TopicModel
[]
>
{
return
this
.
http
.
get
<
TopicModel
[]
>
(
environment
.
baseUrl
+
`/pmstopic/kpi`
)
}
getEmpPmsKpi
(
apsassessy
:
string
,
bossid
?:
string
):
Observable
<
AppraisalKpiSettingEmpModel
[]
>
{
return
this
.
http
.
get
<
AppraisalKpiSettingEmpModel
[]
>
(
this
.
urlApi
+
`/pms-all-kpi?apsassessy=
${
apsassessy
}
`
+
(
bossid
?
`&bossid=
${
bossid
}
`
:
''
))
}
postEmpPmsKpi
(
body
:
AppraisalKpiSettingEmpModel
):
Observable
<
AlertModel
>
{
return
this
.
http
.
post
<
AlertModel
>
(
this
.
urlApi
+
`/pms-all-kpi`
,
body
)
}
postEmpPmsKpiApprove
(
body
:
AppraisalKpiSettingEmpModel
):
Observable
<
AlertModel
>
{
return
this
.
http
.
post
<
AlertModel
>
(
this
.
urlApi
+
`/pms-all-kpi/approve`
,
body
)
}
}
\ No newline at end of file
src/app/shared/services/navservice.ts
View file @
d6b931f3
...
...
@@ -122,26 +122,26 @@ export class NavService implements OnDestroy {
// { id: 'm12', path: 'ess/supervisor-evaluation', title: 'ประเมินโดยหัวหน้า', type: 'link', show: true },
// ],
},
//
{
//
title: 'แก้ไข Individual KPI ตนเอง',
//
type: 'link',
//
selected: false,
//
active: false,
//
path: 'ess/self-setting-individual-kpi',
//
id: 'm3',
//
show: true,
//
icon: ''
//
},
//
{
//
title: 'แก้ไข Individual KPI โดยหัวหน้า',
//
type: 'link',
//
selected: false,
//
active: false,
//
path: 'ess/supervisor-setting-individual-kpi',
//
id: 'm4',
//
show: true,
//
icon: ''
//
},
{
title
:
'แก้ไข Individual KPI ตนเอง'
,
type
:
'link'
,
selected
:
false
,
active
:
false
,
path
:
'ess/self-setting-individual-kpi'
,
id
:
'm3'
,
show
:
true
,
icon
:
''
},
{
title
:
'แก้ไข Individual KPI โดยหัวหน้า'
,
type
:
'link'
,
selected
:
false
,
active
:
false
,
path
:
'ess/supervisor-setting-individual-kpi'
,
id
:
'm4'
,
show
:
true
,
icon
:
''
},
];
}
...
...
src/assets/i18n/th.json
View file @
d6b931f3
...
...
@@ -34,6 +34,8 @@
"PmsManage"
:
"การจัดการการประเมินผล"
,
"EvaluationPeriod"
:
"รอบการประเมิน"
},
"TimeAttendance_head"
:
"ทะเบียนเครื่องมือ"
,
"TimeAttendanceManage"
:
"เครื่องมือประเมิน"
,
"PerformanceManagementSystem"
:
"ประเมินการจัดการประสิทธิภาพ"
,
"SearchByNoOrName"
:
"ค้นหาตามรหัสหรือชื่อ"
,
"Import"
:
"นำเข้า"
,
...
...
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