Commit 396dec01 by Nattana Chaiyamat

แก้ไข Individual KPI ตัวเอง

parent 9bae4e07
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
[dataSource]="indicatorsCoursesList" [checkBoxSetting]="false" [columns]="columns" [childView]="true" [dataSource]="indicatorsCoursesList" [checkBoxSetting]="false" [columns]="columns" [childView]="true"
[canDownload]="true" (sendNextPageView)="onViewClicked($event)" [canDownload]="true" (sendNextPageView)="onViewClicked($event)"
(sendSelectData)="selectIndicatorsCourses($event); onEditClicked($event)" (sendSelectData)="selectIndicatorsCourses($event); onEditClicked($event)"
(sendFileDownload)="dowloadExam($event)"> (sendFileDownload)="downloadExam($event)">
</app-datagrid-syncfution> </app-datagrid-syncfution>
</div> </div>
</ng-container> </ng-container>
......
...@@ -63,8 +63,8 @@ export class IndicatorsAndCurriculumComponent { ...@@ -63,8 +63,8 @@ export class IndicatorsAndCurriculumComponent {
this.getIndicatorsCoursesList() this.getIndicatorsCoursesList()
} }
dowloadExam(data: CompetencytopicModel) { downloadExam(data: CompetencytopicModel) {
this.fileService.dowloadFiles(data.competencyFiles).subscribe({ this.fileService.downloadFiles(data.competencyFiles).subscribe({
next: response => { next: response => {
const url = window.URL.createObjectURL(response); const url = window.URL.createObjectURL(response);
const a = document.createElement("a"); const a = document.createElement("a");
......
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
<div class="flex" *ngIf="examFileName==competencyTopic.select.competencyFiles"> <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 <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" text-center text-secondary border-secondary border-b-2 align-items-end"
(click)="dowloadExam(examFileName)"> (click)="downloadExam(examFileName)">
ดาวน์โหลดไฟล์ข้อสอบ</h1> ดาวน์โหลดไฟล์ข้อสอบ</h1>
</div> </div>
</mat-dialog-content> </mat-dialog-content>
......
...@@ -102,12 +102,12 @@ export class CompetencyTopic implements OnInit { ...@@ -102,12 +102,12 @@ export class CompetencyTopic implements OnInit {
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private fileService: FileService, private fileService: FileService,
private competencytopicService: CompetencytopicService, private competencytopicService: CompetencytopicService,
// private competencytypeService: CompetencytypeService, private competencytypeService: CompetencytypeService,
private tokenService: TokenService private tokenService: TokenService
) { } ) { }
ngOnInit(): void { ngOnInit(): void {
this.getCompetencytopicList() this.getCompetencytopicList()
// this.getCompetencytypeList() this.getCompetencytypeList()
} }
onExamSelected(event: any) { onExamSelected(event: any) {
...@@ -140,8 +140,8 @@ export class CompetencyTopic implements OnInit { ...@@ -140,8 +140,8 @@ export class CompetencyTopic implements OnInit {
dowloadExam(fileName: string) { downloadExam(fileName: string) {
this.fileService.dowloadFiles(fileName).subscribe({ this.fileService.downloadFiles(fileName).subscribe({
next: response => { next: response => {
const url = window.URL.createObjectURL(response); const url = window.URL.createObjectURL(response);
const a = document.createElement("a"); const a = document.createElement("a");
...@@ -176,7 +176,7 @@ export class CompetencyTopic implements OnInit { ...@@ -176,7 +176,7 @@ export class CompetencyTopic implements OnInit {
next: response => { next: response => {
if (response.success) { if (response.success) {
this.showAlert(response.message, 'success') this.showAlert(response.message, 'success')
// this.getCompetencytypeList() this.getCompetencytypeList()
this.getCompetencytopicList() this.getCompetencytopicList()
} else { } else {
this.showAlert(response.message, 'error') this.showAlert(response.message, 'error')
...@@ -211,23 +211,20 @@ export class CompetencyTopic implements OnInit { ...@@ -211,23 +211,20 @@ export class CompetencyTopic implements OnInit {
} }
getCompetencytypeList() { getCompetencytypeList() {
// this.competencytypeListLoading = true this.competencytypeListLoading = true
// this.selectedItems.data.clear() this.selectedItems.data.clear()
// this.competencytypeService.getList().subscribe({ this.competencytypeService.getList().subscribe({
// next: response => { next: response => {
// this.typeList = response.map(x => { this.typeList = response.map(x => {
// this.selectedItems.data.set(x.competencyTypeId, false) return new MyCompetencytypeModel(x)
// return new MyCompetencytypeModel(x) })
// }) this.competencytypeListLoading = false
// this.selectedItems.key = 'competencyTypeId' this.cdr.detectChanges()
// this.selectedItems.count = 0 }, error: error => {
// this.competencytypeListLoading = false this.competencytypeListLoading = false
// this.cdr.detectChanges() this.cdr.detectChanges()
// }, error: error => { }
// this.competencytypeListLoading = false })
// this.cdr.detectChanges()
// }
// })
} }
...@@ -280,7 +277,7 @@ export class CompetencyTopic implements OnInit { ...@@ -280,7 +277,7 @@ export class CompetencyTopic implements OnInit {
this.uploadExam(); this.uploadExam();
return; return;
} }
const user = this.tokenService.getUser(); const user = this.tokenService.getUser();
const body = new MyCompetencytopicModel({ const body = new MyCompetencytopicModel({
...this.competencyTopic.select, ...this.competencyTopic.select,
...@@ -292,7 +289,7 @@ export class CompetencyTopic implements OnInit { ...@@ -292,7 +289,7 @@ export class CompetencyTopic implements OnInit {
next: response => { next: response => {
if (response.success) { if (response.success) {
this.showAlert(response.message, 'success'); this.showAlert(response.message, 'success');
// this.getCompetencytypeList(); this.getCompetencytypeList();
this.getCompetencytopicList(); this.getCompetencytopicList();
this.closeDialog() this.closeDialog()
} else { } else {
...@@ -326,51 +323,51 @@ export class CompetencyTopic implements OnInit { ...@@ -326,51 +323,51 @@ export class CompetencyTopic implements OnInit {
} }
deleteCompetency_topic() { deleteCompetency_topic() {
if (!this.numSelectItem()) { if (!this.numSelectItem()) {
this.showAlert('กรุณาเลือกข้อมูลที่ต้องการลบ', 'error'); this.showAlert('กรุณาเลือกข้อมูลที่ต้องการลบ', 'error');
return; return;
} }
Swal.fire({ Swal.fire({
icon: 'question', icon: 'question',
title: 'แจ้งเตือน', title: 'แจ้งเตือน',
text: 'ยืนยันการลบข้อมูลหรือไม่', text: 'ยืนยันการลบข้อมูลหรือไม่',
showCancelButton: true, showCancelButton: true,
confirmButtonText: 'ลบข้อมูล', confirmButtonText: 'ลบข้อมูล',
cancelButtonText: 'ย้อนกลับ', cancelButtonText: 'ย้อนกลับ',
reverseButtons: true, reverseButtons: true,
}).then(result => { }).then(result => {
if (result.isConfirmed) { if (result.isConfirmed) {
let body: MyCompetencytopicModel[] = []; let body: MyCompetencytopicModel[] = [];
if (this.currentModal === "delete") { if (this.currentModal === "delete") {
const selectedKeys = Array.from(this.selectedItems.data.keys()); const selectedKeys = Array.from(this.selectedItems.data.keys());
body = this.competencyTopic.dataList body = this.competencyTopic.dataList
.filter(x => selectedKeys.includes(x.competencyTopicId) && this.selectedItems.data.get(x.competencyTopicId)) .filter(x => selectedKeys.includes(x.competencyTopicId) && this.selectedItems.data.get(x.competencyTopicId))
.map(x => new MyCompetencytopicModel(x)); .map(x => new MyCompetencytopicModel(x));
} }
this.competencyTopic.loading = true; this.competencyTopic.loading = true;
this.competencytopicService.delete(body).subscribe({ this.competencytopicService.delete(body).subscribe({
next: response => { next: response => {
this.competencyTopic.loading = false; this.competencyTopic.loading = false;
if (response.success) { if (response.success) {
this.showAlert(response.message, 'success'); this.showAlert(response.message, 'success');
// this.getCompetencytypeList(); this.getCompetencytypeList();
this.getCompetencytopicList(); this.getCompetencytopicList();
} else { } else {
this.showAlert(response.message, 'error'); this.showAlert(response.message, 'error');
this.cdr.detectChanges();
}
},
error: error => {
this.competencyTopic.loading = false;
this.showAlert(error.message, 'error');
this.cdr.detectChanges(); this.cdr.detectChanges();
} }
}, });
error: error => { }
this.competencyTopic.loading = false; });
this.showAlert(error.message, 'error'); }
this.cdr.detectChanges();
}
});
}
});
}
showAlert(text: string, type: 'success' | 'error') { showAlert(text: string, type: 'success' | 'error') {
......
...@@ -289,7 +289,7 @@ ...@@ -289,7 +289,7 @@
<ng-container *ngIf="true"> <ng-container *ngIf="true">
<button type="button" class="flex text-start items-center cursor-default"> <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;" <i class="ti ti-circle-plus text-green-500 cursor-pointer" style="font-size: 20px;"
data-hs-overlay="#assessment-table-modal"></i> (click)="assessmentDialogOpen()"></i>
</button> </button>
</ng-container> </ng-container>
<ng-container *ngIf="false"> <ng-container *ngIf="false">
...@@ -373,7 +373,8 @@ ...@@ -373,7 +373,8 @@
</tr> </tr>
<tr> <tr>
<td class="py-2 text-center" style="vertical-align: center;justify-items:center" colspan="6"> <td class="py-2 text-center" style="vertical-align: center;justify-items:center" colspan="6">
<button type="button" class="flex text-start items-center cursor-default"> <button type="button" class="flex text-start items-center cursor-default"
(click)="competencyTopicDialogOpen()">
<i class="ti ti-circle-plus text-green-500 cursor-pointer" style="font-size: 20px;"></i> <i class="ti ti-circle-plus text-green-500 cursor-pointer" style="font-size: 20px;"></i>
</button> </button>
</td> </td>
...@@ -387,137 +388,230 @@ ...@@ -387,137 +388,230 @@
</ng-template> </ng-template>
<div id="assessment-table-modal" class="hs-overlay hidden ti-modal"> <ng-template #assessmentDialog let-modal>
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out lg:!max-w-4xl lg:w-full m-3 lg:!mx-auto !max-w-3/4"> <h3 mat-dialog-title>
<div class="max-h-full overflow-hidden ti-modal-content"> รายการประเมิน
<div class="ti-modal-header"> </h3>
<h3 class="text-xxl font-bold text-primary"> <mat-dialog-content>
รายการประเมิน <div class="flex justify-end pb-1rem">
</h3> <div class="px-1">
<div class="flex justify-end"> <div class="relative shadow-md">
<button type="button" class="hs-dropdown-toggle ti-modal-clode-btn text-danger" <input type="text" id="hs-leading-icon" name="hs-leading-icon"
data-hs-overlay="#assessment-table-modal"> class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 " placeholder="Search by No. or Name"
<span class="sr-only">Close</span> [(ngModel)]="modalData.search">
<i class="ti ti-circle-x fs-xxl"></i> <div
</button> class="absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4">
<i class="ri-search-line text-gray"></i>
</div>
</div> </div>
</div> </div>
<div class="ti-modal-body"> </div>
<div class="flex justify-end pb-1rem"> <div class="overflow-auto border">
<div class="px-1"> <table class="ti-custom-table ti-custom-table-head ti-custom-table-hover">
<div class="relative shadow-md"> <thead>
<input type="text" id="hs-leading-icon" name="hs-leading-icon" <tr>
class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 " placeholder="Search by No. or Name" <ng-container
[(ngModel)]="modal.search" (ngModelChange)="searchModalChange(pmstopicListFilter())"> *ngFor="let item of ['รหัส','ชื่อหัวข้อ','ประเภท','น้ำหนัก','การจัดการ']; let f = first; let l = last; let i = index">
<div <th scope="col" class=" px-10px py-10px bg-soft-secondary text-primary !text-center">
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"> <span class="font-size-12px font-weight-700">{{ item }}</span>
<i class="ri-search-line text-gray"></i> <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> </div>
</div> </td>
</div> </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
</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">
<i class="ti ti-eraser text-base"></i>
Clear
</button>
</div>
</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>
<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="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)="selectCompetencytype()">
<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)="competencyTypeDialogOpen()">
<i class="ri-search-line cursor-pointer text-gray"></i>
</button>
</div> </div>
<div class="page px-rem"> </div>
<div class="overflow-auto table-bordered rounded-t-md"> </div>
<div class="overflow-auto shadow-md rounded-t-md"> <label class="ti-form-label mt-2rem">แนบไฟล์ข้อสอบ</label>
<table class="ti-custom-table ti-custom-table-head ti-custom-table-hover"> <div class="flex rounded-md">
<thead> <label class="sr-only">อัปโหลดไฟล์</label>
<tr> <input #fileInputMedium id="fileInputMedium" type="file" (change)="onExamSelected($event)" hidden>
<ng-container <input type="text" [value]="examFileName" readonly onclick="fileInputMedium.click();"
*ngFor="let item of ['รหัส','ชื่อหัวข้อ','ประเภท','น้ำหนัก','การจัดการ']; let f = first; let l = last; let i = index"> 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">
<th scope="col" class=" px-10px py-10px bg-soft-secondary text-primary !text-center"> <span
<span class="font-size-12px font-weight-700">{{ item }}</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">
<div class="absolute top-1/2 transform -translate-y-1/2 right-0"> <button class="text-sm text-gray-500 dark:text-white/70" onclick="fileInputMedium.click();">Browse</button>
<i class="ti ti-dots-vertical fs-l"></i> </span>
</div> <div class="flex items-center ml-2">
</th> <button href="javascript:void(0);" class="ti-btn ti-btn-soft-danger h-10px m-0 shadow-md rounded-md"
</ng-container> (click)="fileInputMedium.value = '';examFile=null;examFileName = 'กรุณาเลือกไฟล์'">
</tr> <i class="ri-delete-bin-6-line"></i>
</thead> Delete
<tbody *ngIf="pmstopic.loading"> </button>
<tr> </div>
<td class="text-center" colspan="100%"> </div>
<div *ngFor="let item of [1,2,3]" class="ti-spinner w-8 h-8 text-secondary mx-1" role="status" <div class="flex" *ngIf="examFileName==competencyTopic.select.competencyFiles">
aria-label="loading"> <h1 class="cursor-pointer justify-center -mb-px inline-flex items-center gap-2 font-weight-500 font-size-12px
<span class="sr-only">Loading...</span> text-center text-secondary border-secondary border-b-2 align-items-end"
</div> (click)="downloadExam(examFileName)">
</td> ดาวน์โหลดไฟล์ข้อสอบ</h1>
</tr> </div>
</tbody> </mat-dialog-content>
<tbody *ngIf="!pmstopic.loading&&!pmstopicListFilter().length"> <mat-dialog-actions align="end">
<tr> <button type="button" mat-button [mat-dialog-close]
<td class="text-center" colspan="100%"> 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">
ไม่พบข้อมูล ย้อนกลับ
</td> </button>
</tr> <button type="button" class="ti-btn ti-btn-success" mat-button (click)="confirmCompetencyTopic()"
</tbody> [class.ti-btn-disabled]="!competencyTopic.select.competencyType.competencyTypeId||!competencyTopic.select.tdesc||!competencyTopic.select.competencyType.shortName"
<tbody *ngIf="!pmstopic.loading&&pmstopicListFilter().length"> [disabled]="!competencyTopic.select.competencyType.competencyTypeId||!competencyTopic.select.tdesc||!competencyTopic.select.competencyType.shortName">
<tr บันทึกข้อมูล
*ngFor="let item of pmstopicListFilter() | slice:((modal.currentPage-1) * 10) : (((modal.currentPage-1) * 10) + 10);let i = index"> </button>
<td class="text-center"> </mat-dialog-actions>
{{item.data.pmsTopicId}} </ng-template>
</td>
<td>{{item.data.tdesc}}</td> <ng-template #competencyTypeDialog let-modal>
<td>{{item.data.pmsType.tdesc}}</td> <h3 mat-dialog-title>
<td>{{item.data.weight}}</td> ประเภทสมรรถนะ
<td class="text-center"> <button type="button" </h3>
class="ti-btn ti-btn-soft-secondary h-20px m-0 shadow-md" <mat-dialog-content>
data-hs-overlay="#assessment-table-modal" (click)="selectPmstopic(item.data)"> <div class="flex justify-end pb-1rem">
<i class="ri-add-line"></i> <div class="px-1">
Select <div class="relative shadow-md">
</button></td> <input type="text" id="hs-leading-icon" name="hs-leading-icon"
</tr> class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 " placeholder="Search by No. or Name"
</tbody> [(ngModel)]="modalData.search">
</table> <div
</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>
<nav class="pagination-style-3 my-5" *ngIf="modal.page.length">
<ul class="ti-pagination">
<li>
<a aria-label="anchor" class="page-link" href="javascript:void(0);"
(click)="modal.currentPage = (modal.currentPage-1 || 1)">
<i class="ri-arrow-left-s-line align-middle rtl:rotate-180"></i>
</a>
</li>
<li *ngFor="let item of modal.page;let f = first;let l = last">
<ng-container *ngIf="item==3&&modal.currentPage!=1&&modal.currentPage!=2&&modal.currentPage!=3">
<a aria-label="anchor" class="page-link" href="javascript:void(0);"><i class="ri-more-line"></i>
</a>
</ng-container>
<ng-container
*ngIf="(f||l)||(item==modal.currentPage-1||item==modal.currentPage||item==modal.currentPage+1)">
<a class="page-link" href="javascript:void(0);" [class.active]="item==modal.currentPage"
(click)="modal.currentPage=item">{{item}}
</a>
</ng-container>
<ng-container
*ngIf="item==modal.page.length-2&&modal.currentPage!=modal.page.length&&modal.currentPage!=modal.page.length-1&&modal.currentPage!=modal.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)="modal.currentPage = (modal.currentPage > modal.page.length-1 ? modal.currentPage: modal.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 {{((modal.currentPage-1) * 10)+1}} to {{pmstopicListFilter().length<10
?pmstopicListFilter().length: (modal.currentPage==modal.page.length ? ((modal.currentPage * 10) -
((modal.currentPage * 10) - pmstopicListFilter().length) ) :(modal.currentPage * 10) ) }} of
{{pmstopicListFilter().length}} items</span>
</ul>
</nav>
</div>
<div class="flex justify-end mt-2rem mb-1rem space-x-4">
<button type="button"
class="hs-dropdown-toggle ti-btn ti-border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:ring-offset-white focus:ring-primary dark:bg-bgdark dark:hover:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-white dark:focus:ring-offset-white/10"
data-hs-overlay="#assessment-table-modal">
ย้อนกลับ
</button>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="overflow-auto border">
</div> <table class="ti-custom-table ti-custom-table-head ti-custom-table-hover">
\ No newline at end of file <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
</button>
</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>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
class="hs-dropdown-toggle ti-btn ti-border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:ring-offset-white focus:ring-primary dark:bg-bgdark dark:hover:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-white dark:focus:ring-offset-white/10">
ย้อนกลับ
</button>
</mat-dialog-actions>
</ng-template>
\ No newline at end of file
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Router, ActivatedRoute } from '@angular/router'; 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 { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { MyPmsGroupAssessment1Model } from 'src/app/shared/model/pms-group-assessment1.model'; import { MyPmsGroupAssessment1Model } from 'src/app/shared/model/pms-group-assessment1.model';
import { MyPmstopicModel, PmstopicModel } from 'src/app/shared/model/pmstopic.model'; import { MyPmstopicModel, PmstopicModel } from 'src/app/shared/model/pmstopic.model';
import { AppraisalService } from 'src/app/shared/services/appraisal.service'; 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 { EmployeeService } from 'src/app/shared/services/employee.service';
import { FileService } from 'src/app/shared/services/file.service'; import { FileService } from 'src/app/shared/services/file.service';
import { PmstopicService } from 'src/app/shared/services/pmstopic.service'; import { PmstopicService } from 'src/app/shared/services/pmstopic.service';
import { TokenService } from 'src/app/shared/services/token.service'; import { TokenService } from 'src/app/shared/services/token.service';
export interface DataModal { import Swal from 'sweetalert2';
export interface ModalData {
search: string, search: string,
currentPage: number, currentPage: number,
page: number[] pageSize: number
} }
@Component({ @Component({
selector: 'app-setting-individual-kpi', selector: 'app-setting-individual-kpi',
...@@ -20,20 +26,31 @@ export interface DataModal { ...@@ -20,20 +26,31 @@ export interface DataModal {
}) })
export class SettingIndividualKpiComponent { export class SettingIndividualKpiComponent {
@Input() evaluateeId = "" @Input() evaluateeId = ""
individualKPI: { loading: boolean, list: any[] } = { loading: false, list: [] }
@Input() evaluationForm: 'self' | 'sup' = "self" @Input() evaluationForm: 'self' | 'sup' = "self"
@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>() menuClose: Map<string, boolean> = new Map<string, boolean>()
tableHover: Map<string, boolean> = new Map<string, boolean>() tableHover: Map<string, boolean> = new Map<string, boolean>()
evaluatee: { loading: boolean, data: EmployeeModel } = { loading: false, data: new MyEmployeeModel() } modalData: ModalData = {
@Output() sendReturnPath: EventEmitter<any> = new EventEmitter<any>();
modal: DataModal = {
search: "", search: "",
currentPage: 1, currentPage: 1,
page: Array.from({ length: 1 }, (_, i) => i + 1) pageSize: 10
} }
pmstopic: { loading: boolean, select: PmstopicModel, dataList: { check: boolean, data: PmstopicModel }[] } = { loading: false, select: new MyPmstopicModel(), dataList: [] }
constructor( constructor(
private dialog: MatDialog,
private router: Router, private router: Router,
private employeeService: EmployeeService, private employeeService: EmployeeService,
private appraisalService: AppraisalService, private appraisalService: AppraisalService,
...@@ -41,47 +58,43 @@ export class SettingIndividualKpiComponent { ...@@ -41,47 +58,43 @@ export class SettingIndividualKpiComponent {
private tokenService: TokenService, private tokenService: TokenService,
private route: ActivatedRoute, private route: ActivatedRoute,
private fileService: FileService, private fileService: FileService,
private pmstopicService: PmstopicService private pmstopicService: PmstopicService,
) { private competencytopicService: CompetencytopicService,
} private competencytypeService: CompetencytypeService
) { }
ngOnInit(): void { ngOnInit(): void {
this.getEvaluatee() this.getEvaluatee()
this.getPmstopicList() this.getPmstopicList()
this.getCompetencytypeList()
} }
getEvaluatee() { getCompetencytypeList() {
this.evaluatee.loading = true this.competencytype.loading = true
this.employeeService.getWorkingById(this.evaluateeId).subscribe({ this.competencytypeService.getList().subscribe({
next: response => { next: response => {
this.evaluatee.data = new MyEmployeeModel(response) this.competencytype.dataList = response.map(x => {
this.evaluatee.loading = false return new MyCompetencytypeModel(x)
})
this.competencytype.loading = false
this.cdr.detectChanges() this.cdr.detectChanges()
}, error: error => { }, error: error => {
this.evaluatee.loading = false this.competencytype.loading = false
this.cdr.detectChanges() this.cdr.detectChanges()
} }
}) })
} }
returnPath() { competencytypeListFilter() {
this.sendReturnPath.emit() return this.competencytype.dataList.filter(x =>
} x.competencyTypeId.toLowerCase().includes(this.modalData.search.toLowerCase()) ||
x.tdesc.toLowerCase().includes(this.modalData.search.toLowerCase()) ||
getImg(text: string) { x.shortName.toLowerCase().includes(this.modalData.search.toLowerCase()))
return this.fileService.getImg(text)
} }
selectCompetencytype(data?: CompetencytypeModel) {
onImageError(event: Event) { this.competencyTopic.select.competencyType = new MyCompetencytypeModel(data)
const imgElement = event.target as HTMLImageElement;
imgElement.src = './assets/img/users/defaultperson.jpg';
}
searchModalChange(dataList: any[]) {
this.modal.currentPage = 1
this.modal.page = Array.from({ length: Math.ceil(dataList.length / 10) }, (_, i) => i + 1);
this.cdr.markForCheck() this.cdr.markForCheck()
this.competencyTypeDialogClose()
} }
getPmstopicList() { getPmstopicList() {
this.pmstopic.loading = true this.pmstopic.loading = true
this.pmstopicService.getList().subscribe({ this.pmstopicService.getList().subscribe({
...@@ -98,14 +111,353 @@ export class SettingIndividualKpiComponent { ...@@ -98,14 +111,353 @@ export class SettingIndividualKpiComponent {
pmstopicListFilter() { pmstopicListFilter() {
return this.pmstopic.dataList.filter(x => { return this.pmstopic.dataList.filter(x => {
const data = x.data const data = x.data
const match = data.pmsTopicId.toLowerCase().includes(this.modal.search.toLowerCase()) || const match = data.pmsTopicId.toLowerCase().includes(this.modalData.search.toLowerCase()) ||
data.tdesc.toLowerCase().includes(this.modal.search.toLowerCase()) || data.tdesc.toLowerCase().includes(this.modalData.search.toLowerCase()) ||
data.pmsType.tdesc.toLowerCase().includes(this.modal.search.toLowerCase()) || data.pmsType.tdesc.toLowerCase().includes(this.modalData.search.toLowerCase()) ||
(data.weight + "").toLowerCase().includes(this.modal.search.toLowerCase()) (data.weight + "").toLowerCase().includes(this.modalData.search.toLowerCase())
return match return match
}) })
} }
selectPmstopic(data?: PmstopicModel) { selectPmstopic(data?: PmstopicModel) {
this.cdr.markForCheck() this.cdr.markForCheck()
} }
assessmentDialogOpen() {
this.modalData.search = ''
this.modalData.currentPage = 1
this.modalData.pageSize = 10
this.assessmentDialogRef = this.dialog.open(this.assessmentDialog, {
width: '80vw',
disableClose: false,
});
}
assessmentDialogClose() {
this.assessmentDialogRef?.close()
}
competencyTypeDialogOpen() {
this.modalData.search = ''
this.modalData.currentPage = 1
this.modalData.pageSize = 10
this.competencyTypeDialogRef = this.dialog.open(this.competencyTypeDialog, {
width: '80vw',
disableClose: false,
});
}
competencyTypeDialogClose() {
this.competencyTypeDialogRef?.close()
}
competencyTopicDialogOpen() {
if (this.fileInputMedium) {
this.fileInputMedium.value = ""
}
this.competencyTopicDialogRef = this.dialog.open(this.competencyTopicDialog, {
width: '50vw',
disableClose: false,
});
}
competencyTopicDialogClose() {
this.competencyTypeDialogRef?.close()
}
getEvaluatee() {
this.evaluatee.loading = true
this.employeeService.getWorkingById(this.evaluateeId).subscribe({
next: response => {
this.evaluatee.data = new MyEmployeeModel(response)
this.evaluatee.loading = false
this.cdr.detectChanges()
}, error: error => {
this.evaluatee.loading = false
this.cdr.detectChanges()
}
})
}
getImg(text: string) {
return this.fileService.getImg(text)
}
onImageError(event: Event) {
const imgElement = event.target as HTMLImageElement;
imgElement.src = './assets/img/users/defaultperson.jpg';
}
returnPath() {
this.sendReturnPath.emit()
}
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()
}
})
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
title: 'แจ้งเตือน',
text: text,
icon: type,
confirmButtonText: 'ตกลง',
});
}
confirmCompetencyTopic() {
Swal.fire({
icon: 'question',
title: 'แจ้งเตือน',
text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
showCancelButton: true,
confirmButtonText: 'บันทึกข้อมูล',
cancelButtonText: 'ย้อนกลับ',
reverseButtons: true,
}).then(result => {
if (result.isConfirmed) {
this.addCompetencyTopic();
}
});
}
addCompetencyTopic(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.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();
}
});
}
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.addCompetencyTopic(response.resultObject);
} else {
this.showAlert(response.message, 'error');
this.cdr.detectChanges();
}
},
error: error => {
this.showAlert(error.message, 'error');
this.cdr.detectChanges();
}
});
}
//
//
// 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));
// }
} }
...@@ -12,7 +12,7 @@ export class FileService { ...@@ -12,7 +12,7 @@ export class FileService {
uploadFiles(formData: any): Observable<AlertModel> { uploadFiles(formData: any): Observable<AlertModel> {
return this.http.post<AlertModel>(environment.baseUrl + '/files/upload', formData) return this.http.post<AlertModel>(environment.baseUrl + '/files/upload', formData)
} }
dowloadFiles(filename: string) { downloadFiles(filename: string) {
return this.http.get(environment.baseUrl + '/files/download/' + filename, { responseType: "blob" }) return this.http.get(environment.baseUrl + '/files/download/' + filename, { responseType: "blob" })
} }
uploadExcel(formData: any, table: string): Observable<AlertModel> { uploadExcel(formData: any, table: string): Observable<AlertModel> {
......
...@@ -122,26 +122,26 @@ export class NavService implements OnDestroy { ...@@ -122,26 +122,26 @@ export class NavService implements OnDestroy {
// { id: 'm12', path: 'ess/supervisor-evaluation', title: 'ประเมินโดยหัวหน้า', type: 'link', show: true }, // { id: 'm12', path: 'ess/supervisor-evaluation', title: 'ประเมินโดยหัวหน้า', type: 'link', show: true },
// ], // ],
}, },
// { {
// title: 'แก้ไข Individual KPI ตนเอง', title: 'แก้ไข Individual KPI ตนเอง',
// type: 'link', type: 'link',
// selected: false, selected: false,
// active: false, active: false,
// path: 'ess/self-setting-individual-kpi', path: 'ess/self-setting-individual-kpi',
// id: 'm3', id: 'm3',
// show: false, show: true,
// icon: '' icon: ''
// }, },
// { {
// title: 'แก้ไข Individual KPI โดยหัวหน้า', title: 'แก้ไข Individual KPI โดยหัวหน้า',
// type: 'link', type: 'link',
// selected: false, selected: false,
// active: false, active: false,
// path: 'ess/supervisor-setting-individual-kpi', path: 'ess/supervisor-setting-individual-kpi',
// id: 'm4', id: 'm4',
// show: false, show: true,
// icon: '' icon: ''
// }, },
]; ];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment