Commit 1e5e6bae by Nattana Chaiyamat

บันทึกผลงานดีเด่น บันทึกวินัยและการลงโทษ

parent d8822afa
...@@ -10,7 +10,14 @@ ...@@ -10,7 +10,14 @@
<div class="col-span-12 xxl:col-span-8"> <div class="col-span-12 xxl:col-span-8">
<div class="box" style="border-radius:20px"> <div class="box" style="border-radius:20px">
<div class="box-header"> <div class="box-header">
<div class="grid grid-cols-12 gap-x-6 mb-3 mt-3"> <div class="grid grid-cols-12 gap-x-6 mb-3 mt-3 relative">
<div class="absolute">
<button type="button" class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 "
style="border-radius:20px" (click)="back()">
<i class="ti ti-chevron-left"></i>
{{'Back' | translate}}
</button>
</div>
<div class="col-span-12"> <div class="col-span-12">
<h5 class="box-title mb-3 text-center">ตาราง Mapping ระดับความคาดหวังกับตำแหน่งงาน</h5> <h5 class="box-title mb-3 text-center">ตาราง Mapping ระดับความคาดหวังกับตำแหน่งงาน</h5>
</div> </div>
......
import { ViewportScroller } from '@angular/common'; import { ViewportScroller } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core'; import { ChangeDetectorRef, Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ToastrService } from 'ngx-toastr'; import { ToastrService } from 'ngx-toastr';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model'; import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
...@@ -35,7 +36,8 @@ export class CompetencyMappingComponent { ...@@ -35,7 +36,8 @@ export class CompetencyMappingComponent {
private fileService: FileService, private fileService: FileService,
private eventgrpService: EventgrpService, private eventgrpService: EventgrpService,
private jobcode: JobcodeService, private jobcode: JobcodeService,
private translateService: TranslateService private translateService: TranslateService,
private router: Router
) { ) {
this.translateService.onLangChange.subscribe((event) => { this.translateService.onLangChange.subscribe((event) => {
}); });
...@@ -56,4 +58,9 @@ export class CompetencyMappingComponent { ...@@ -56,4 +58,9 @@ export class CompetencyMappingComponent {
} }
}) })
} }
back() {
this.router.navigate(['/ess/employee-self-service']);
}
} }
\ No newline at end of file
...@@ -64,6 +64,8 @@ import { Widget1Component } from '../widget1/widget1.component'; ...@@ -64,6 +64,8 @@ import { Widget1Component } from '../widget1/widget1.component';
import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapping.component'; import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapping.component';
import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix.component'; import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix.component';
import { DocumentUploadManagerComponent } from '../company-components/account-settings/document-upload-manager/document-upload-manager.component'; import { DocumentUploadManagerComponent } from '../company-components/account-settings/document-upload-manager/document-upload-manager.component';
import { DisciplinaryActionComponent } from '../disciplinary-action/disciplinary-action.component';
import { OutstandingPerformanceComponent } from '../outstanding-performance/outstanding-performance.component';
...@@ -143,6 +145,8 @@ const routes: Routes = [ ...@@ -143,6 +145,8 @@ const routes: Routes = [
{ path: "ess/competency-mapping", title: 'รายละเอียดของงาน', component: CompetencyMappingComponent }, { path: "ess/competency-mapping", title: 'รายละเอียดของงาน', component: CompetencyMappingComponent },
{ path: "ess/job-family-mapping", title: 'รายละเอียดกลุ่มงานตามวิชาชีพ', component: JobFamilyMappingComponent }, { path: "ess/job-family-mapping", title: 'รายละเอียดกลุ่มงานตามวิชาชีพ', component: JobFamilyMappingComponent },
{ path: "ess/job-family-matrix", title: 'รายละเอียดกลุ่มงานตามวิชาชีพ', component: JobFamilyMatrixComponent }, { path: "ess/job-family-matrix", title: 'รายละเอียดกลุ่มงานตามวิชาชีพ', component: JobFamilyMatrixComponent },
{ path: "ess/disciplinary-action", title: 'วินัยและการลงโทษ', component: DisciplinaryActionComponent },
{ path: "ess/outstanding-performance", title: 'ผลงานดีเด่น', component: OutstandingPerformanceComponent },
] ]
} }
]; ];
......
...@@ -217,6 +217,8 @@ import { JobGradeGroupComponent } from '../company-components/job-description/jo ...@@ -217,6 +217,8 @@ import { JobGradeGroupComponent } from '../company-components/job-description/jo
import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapping.component'; import { JobFamilyMappingComponent } from '../job-family-mapping/job-family-mapping.component';
import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix.component'; import { JobFamilyMatrixComponent } from '../job-family-matrix/job-family-matrix.component';
import { DocumentUploadManagerComponent } from '../company-components/account-settings/document-upload-manager/document-upload-manager.component'; import { DocumentUploadManagerComponent } from '../company-components/account-settings/document-upload-manager/document-upload-manager.component';
import { DisciplinaryActionComponent } from '../disciplinary-action/disciplinary-action.component';
import { OutstandingPerformanceComponent } from '../outstanding-performance/outstanding-performance.component';
export const MY_DATE_FORMATS = { export const MY_DATE_FORMATS = {
parse: { parse: {
...@@ -373,7 +375,9 @@ export class CustomDateAdapter extends NativeDateAdapter { ...@@ -373,7 +375,9 @@ export class CustomDateAdapter extends NativeDateAdapter {
JobGradeGroupComponent, JobGradeGroupComponent,
JobFamilyMappingComponent, JobFamilyMappingComponent,
JobFamilyMatrixComponent, JobFamilyMatrixComponent,
DocumentUploadManagerComponent DocumentUploadManagerComponent,
DisciplinaryActionComponent,
OutstandingPerformanceComponent
], imports: [ ], imports: [
TranslateModule, TranslateModule,
CommonModule, CommonModule,
......
...@@ -28,6 +28,16 @@ ...@@ -28,6 +28,16 @@
</ng-container> </ng-container>
</ng-template> </ng-template>
</e-column> </e-column>
<e-column headerText='checkboxSelect' [textAlign]="'center'" width='160' [editType]="false" [allowEditing]="false"
*ngIf="!checkBoxSetting&&showImg">
<ng-template #headerTemplate let-data>
</ng-template>
<ng-template #template let-data>
<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)">
</ng-template>
</e-column>
<ng-container *ngFor="let col of columns"> <ng-container *ngFor="let col of columns">
<e-column *ngIf="col.headerText!=''" [field]="col.field" [headerText]="col.headerText" [width]="col.width" <e-column *ngIf="col.headerText!=''" [field]="col.field" [headerText]="col.headerText" [width]="col.width"
[format]="col.format" [textAlign]="'center'" [isPrimaryKey]="col.isPrimaryKey" [editType]="false" [format]="col.format" [textAlign]="'center'" [isPrimaryKey]="col.isPrimaryKey" [editType]="false"
......
<div class="relative">
<div class="flex relative before:absolute before:w-full before:h-full bg-gradient-custom"
style="margin-top: -50px;margin-left: -100px;margin-right: -100px">
<div class="h-[500px] w-full rounded-sm"></div>
</div>
<div class="main-content " style="margin-top:-29rem">
<div class="grid grid-cols-12 gap-x-6">
<div class="col-span-12 xxl:col-span-2">
</div>
<div class="col-span-12 xxl:col-span-8">
<div class="box" style="border-radius:20px">
<div class="box-header">
<div class="grid grid-cols-12 gap-x-6 mb-3 mt-3 relative">
<div class="absolute">
<button type="button" class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 "
style="border-radius:20px" (click)="back()">
<i class="ti ti-chevron-left"></i>
{{'Back' | translate}}
</button>
</div>
<div class="col-span-12">
<h5 class="box-title mb-3 text-center">วินัย และการลงโทษ</h5>
</div>
</div>
<nav class="sm:flex sm:space-x-2 space-y-2 sm:space-y-0 rtl:space-x-reverse block"
aria-label="Tabs" role="tablist" style="max-width: 250px;">
<button type="button" style="border-radius:20px"
class="py-2 px-3 inline-flex items-center w-full justify-center gap-2 text-sm font-medium text-center border text-gray-500 rounded-sm hover:text-gray-700 active"
id="part-item-1" data-hs-tab="#part-1" aria-controls="part-1" role="tab">
<!-- hs-tab-active:text-white hs-tab-active:bg-primary hs-tab-active:border-primary -->
{{'รายชื่อผู้ใต้บังคับบัญชา' | translate}}
</button>
</nav>
</div>
<div class="box-body">
<div id="part-1" class="" role="tabpanel" aria-labelledby="part-item-1">
<ng-container *ngTemplateOutlet="part1"></ng-container>
</div>
</div>
</div>
</div>
<div class="col-span-12 xxl:col-span-2">
</div>
</div>
</div>
</div>
<ng-template #part1>
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="search">
<div
class="absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4">
<i class="ri-search-line text-gray"></i>
</div>
</div>
</div>
</div>
</div>
<div class="p-2 pt-0">
<app-datagrid-syncfution [searchSettings]="searchSettings" [searchText]="search" [dataSource]="employee.list"
[columns]="columns" [showImg]="true" (sendSelectData)="selectEmployee($event);openEmployeeDialog()"
[initialPage]="{ pageSizes: true, pageSize: 5 }" [checkBoxSetting]="false">
</app-datagrid-syncfution>
</div>
<ng-template #employeeDialog let-modal>
<h3 mat-dialog-title>
{{'บันทึกการลงโทษทางวินัย' | translate}}
</h3>
<div class="w-full flex justify-end mb-1rem">
<div class="absolute flex">
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md">
<i class="ti ti-eraser text-base"></i>
Clear
</button>
</div>
</div>
</div>
<mat-dialog-content>
<div class="space-y-3">
<div class="row">
<div class="col-6 p-2">
<label class="ti-form-label">วันที่เกิดเหตุ</label>
<mat-form-field>
<input matInput [matDatepicker]="dateIncident" type="text" readonly
class="ti-form-input rounded-l-none focus:z-10 flatpickr-input !text-gray-500 !bg-white"
id="datetime" [(ngModel)]="dateSelectIso.dateIncident"
(ngModelChange)="changeDate(this.dateSelect, 'dateIncident', dateSelectIso.dateIncident);">
<mat-datepicker-toggle matSuffix [for]="dateIncident"></mat-datepicker-toggle>
<mat-datepicker #dateIncident></mat-datepicker>
</mat-form-field>
</div>
<div class="col-6 p-2">
<label class="ti-form-label">วันที่มีผล</label>
<mat-form-field>
<input matInput [matDatepicker]="dateEffective" type="text" readonly
class="ti-form-input rounded-l-none focus:z-10 flatpickr-input !text-gray-500 !bg-white"
id="datetime" [(ngModel)]="dateSelectIso.dateEffective"
(ngModelChange)="changeDate(this.dateSelect, 'dateEffective', dateSelectIso.dateEffective);">
<mat-datepicker-toggle matSuffix [for]="dateEffective"></mat-datepicker-toggle>
<mat-datepicker #dateEffective></mat-datepicker>
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">ประเภทของการกระทำผิด</label>
<div class="row col-6" style="align-content: start;">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox1">
</div>
<div class="col-6">
<label for="checkbox1" class="text-sm text-gray-500" style="cursor: pointer;">
ปัญหาการมาทำงาน
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox2">
</div>
<div class="col-6">
<label for="checkbox2" class="text-sm text-gray-500" style="cursor: pointer;">
ฝ่าฝืนนโยบายบริษัท
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox3">
</div>
<div class="col-6">
<label for="checkbox3" class="text-sm text-gray-500" style="cursor: pointer;">
อื่น ๆ
</label>
</div>
</div>
</div>
<div class="row col-6" style="align-content: start;">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox4">
</div>
<div class="col-6">
<label for="checkbox4" class="text-sm text-gray-500" style="cursor: pointer;">
ความประพฤติไม่เหมาะสม
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox5">
</div>
<div class="col-6">
<label for="checkbox5" class="text-sm text-gray-500" style="cursor: pointer;">
ไม่เชื่อฟังคําสั่ง
</label>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">ประเภทของการกระทำผิด</label>
<textarea type="text" rows="3" class="ti-form-input col-12"
placeholder="กรอกรายละเอียดของเหตุการณ์..."></textarea>
</div>
</div>
<div class="row">
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">การลงโทษที่ดําาเนินการ</label>
<div class="row col-6" style="align-content: start;">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox21">
</div>
<div class="col-6">
<label for="checkbox21" class="text-sm text-gray-500" style="cursor: pointer;">
ตักเตือนด้วยวาจา
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox22">
</div>
<div class="col-6">
<label for="checkbox22" class="text-sm text-gray-500" style="cursor: pointer;">
ตักเตือนขั้นสุดท้าย
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox23">
</div>
<div class="col-6">
<label for="checkbox23" class="text-sm text-gray-500" style="cursor: pointer;">
เลิกจ้าง
</label>
</div>
</div>
</div>
<div class="row col-6" style="align-content: start;">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox24">
</div>
<div class="col-6">
<label for="checkbox24" class="text-sm text-gray-500" style="cursor: pointer;">
ตักเตือนเป็นลายลักษณ์อักษร
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox25">
</div>
<div class="col-6">
<label for="checkbox25" class="text-sm text-gray-500" style="cursor: pointer;">
พักงาน
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="checkbox" class="ti-form-checkbox" style="cursor: pointer;"
id="checkbox2ุ">
</div>
<div class="col-6">
<label for="checkbox2ุ" class="text-sm text-gray-500" style="cursor: pointer;">
อื่น ๆ
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
class="hs-dropdown-toggle ti-btn ti-border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:ring-offset-white focus:ring-primary dark:bg-bgdark dark:hover:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-white dark:focus:ring-offset-white/10">
ย้อนกลับ
</button>
<button type="button" class="ti-btn ti-btn-success" (click)="save()">
บันทึกข้อมูล
</button>
</mat-dialog-actions>
</ng-template>
</ng-template>
\ No newline at end of file
.bg-gradient-custom {
background: linear-gradient(135deg, #4f46e5, #ec4899 60%, #f59e0b);
-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
mask-size: 100% 100%;
mask-repeat: no-repeat;
}
.row {
display: flex;
flex-wrap: wrap;
}
.col {
flex: 1;
}
@for $i from 1 through 12 {
$width: (
$i / 12) * 100%;
.col-#{$i} {
flex: 0 0 $width;
max-width: $width;
}
}
@for $i from 1 through 100 {
.m-#{$i}rem {
margin: #{$i}rem;
}
.mt-#{$i}rem {
margin-top: #{$i}rem;
}
.ml-#{$i}rem {
margin-left: #{$i}rem;
}
.mb-#{$i}rem {
margin-bottom: #{$i}rem;
}
.mr-#{$i}rem {
margin-right: #{$i}rem;
}
.p-#{$i}rem {
padding: #{$i}rem;
}
.pt-#{$i}rem {
padding-top: #{$i}rem;
}
.pl-#{$i}rem {
padding-left: #{$i}rem;
}
.pb-#{$i}rem {
padding-bottom: #{$i}rem;
}
.pr-#{$i}rem {
padding-right: #{$i}rem;
}
}
\ No newline at end of file
import { ViewportScroller } from '@angular/common';
import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { JobCodeModel, MyJobCodeModel } from 'src/app/shared/model/job-code.model';
import { MyStatusModel, StatusModel } from 'src/app/shared/model/status.model';
import { EmpStatusService } from 'src/app/shared/services/emp-status.service';
import { EmployeeService } from 'src/app/shared/services/employee.service';
import { EventgrpService } from 'src/app/shared/services/eventgrp.service';
import { FileService } from 'src/app/shared/services/file.service';
import { JobcodeService } from 'src/app/shared/services/jobcode.service';
import { PmsWorkingTimeService } from 'src/app/shared/services/pms-working-time.service';
import Swal from 'sweetalert2';
export interface BiModel {
name: string,
tools: string[],
degree: string
}
@Component({
selector: 'app-disciplinary-action',
templateUrl: './disciplinary-action.component.html',
styleUrls: ['./disciplinary-action.component.scss']
})
export class DisciplinaryActionComponent {
currentPage = 1
empDetail: { loading: boolean, data: JobCodeModel } = { loading: false, data: new MyJobCodeModel({}) }
columns: ColumnModel[] = [
{
field: "picture",
headerText: "",
type: "string",
}, {
field: "employeeId",
headerText: "EmployeeCode",
type: "string",
isPrimaryKey: true,
},
{
field: "fname",
headerText: "FirstName",
type: "string"
},
{
field: "lname",
headerText: "LastName",
type: "string"
},
{
field: "position.tdesc",
headerText: "Position",
type: "string"
}]
searchSettings = {
fields: ['employeeId', 'fname', 'lname', 'position.tdesc'],
operator: 'contains',
ignoreCase: false
}
search = ''
employee: { loading: boolean, select: EmployeeModel, list: EmployeeModel[] } = { loading: false, select: new MyEmployeeModel(), list: [] }
@ViewChild('employeeDialog') employeeDialog: any
employeeDialogRef: any
dateSelectIso = {
dateIncident: '',
dateEffective: ''
}
dateSelect = {
dateIncident: '',
dateEffective: ''
}
constructor(
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private dialog: MatDialog,
private fileService: FileService,
private eventgrpService: EventgrpService,
private jobcode: JobcodeService,
private employeeService: EmployeeService,
private translateService: TranslateService,
private router: Router
) {
this.translateService.onLangChange.subscribe((event) => {
});
}
ngOnInit(): void {
this.getEmployeeList()
}
getEmployeeList() {
this.employee.loading = true
this.employeeService.getList().subscribe({
next: response => {
this.employee.list = response.map((x: any) => new MyEmployeeModel(x))
this.employee.loading = false
this.cdr.detectChanges()
}, error: error => {
this.employee.loading = false
this.cdr.detectChanges()
}
})
}
selectEmployee(data?: EmployeeModel) {
this.employee.select = new MyEmployeeModel(data)
}
openEmployeeDialog() {
this.employeeDialogRef = this.dialog.open(this.employeeDialog, {
width: '800px',
})
}
closeEmployeeDialog() {
this.employeeDialogRef.close()
}
toISODate(dateInput?: string | null): string {
if (!dateInput) return "";
const parsedDate = new Date(dateInput);
return isNaN(parsedDate.getTime()) ? new Date().toISOString() : parsedDate.toISOString();
}
changeDate(target: { [key: string]: any }, field: string, dateIso: string) {
target[field] = this.toYYYYMMDD(dateIso)
}
toYYYYMMDD(dateInput?: string | null): string {
if (!dateInput) return "";
const parsedDate = new Date(dateInput);
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
};
const formattedDate = parsedDate.toLocaleDateString('en-GB', options);
const [day, month, year] = formattedDate.split('/');
return `${year}-${month}-${day}`;
}
save() {
Swal.fire({
icon: 'question',
title: 'แจ้งเตือน',
text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
showCancelButton: true,
confirmButtonText: 'บันทึกข้อมูล',
cancelButtonText: 'ย้อนกลับ',
reverseButtons: true,
}).then((result) => {
if (result.isConfirmed) {
this.showAlert('บันทึกข้อมูลสำเร็จ', 'success')
this.closeEmployeeDialog();
}
});
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
title: 'แจ้งเตือน',
text: text,
icon: type,
confirmButtonText: 'ตกลง',
});
}
back() {
this.router.navigate(['/ess/employee-self-service']);
}
}
\ No newline at end of file
...@@ -37,8 +37,8 @@ export class EmployeeSelfServiceComponent { ...@@ -37,8 +37,8 @@ export class EmployeeSelfServiceComponent {
{ text: "Profile พนักงาน", link: "/ess/profile" }, { text: "Profile พนักงาน", link: "/ess/profile" },
{ text: "Job Family", link: "/ess/job-family-mapping" }, { text: "Job Family", link: "/ess/job-family-mapping" },
{ text: "Time Attendance", description: "หน้าใหม่ แสดงข้อมูล TA" }, { text: "Time Attendance", description: "หน้าใหม่ แสดงข้อมูล TA" },
{ text: "วินัย และการลงโทษ", description: "หน้าใหม่ คล้าย เมนูความดีความผิดของ myHR plus" }, { text: "วินัย และการลงโทษ", link: "/ess/disciplinary-action" },
{ text: "ผลงานดีเด่น", description: "หน้าใหม่" }, { text: "ผลงานดีเด่น", link: "/ess/outstanding-performance" },
{ text: "Feedback", link: "/ess/self-evaluation/kpi-sum10" }, { text: "Feedback", link: "/ess/self-evaluation/kpi-sum10" },
{ text: "ดูข้อมูลย้อนหลัง", description: "หน้าใหม่ แสดงListรอบประเมินตั้งแต่รอบล่าสุดถึงย้อนหลัง3ปี" }, { text: "ดูข้อมูลย้อนหลัง", description: "หน้าใหม่ แสดงListรอบประเมินตั้งแต่รอบล่าสุดถึงย้อนหลัง3ปี" },
{ text: "Calibrate คะแนน", description: "หน้ารายงานที่มีการ Calibrate และแสดงค่า K" }, { text: "Calibrate คะแนน", description: "หน้ารายงานที่มีการ Calibrate และแสดงค่า K" },
......
<div class="relative">
<div class="flex relative before:absolute before:w-full before:h-full bg-gradient-custom"
style="margin-top: -50px;margin-left: -100px;margin-right: -100px">
<div class="h-[500px] w-full rounded-sm"></div>
</div>
<div class="main-content " style="margin-top:-29rem">
<div class="grid grid-cols-12 gap-x-6">
<div class="col-span-12 xxl:col-span-2">
</div>
<div class="col-span-12 xxl:col-span-8">
<div class="box" style="border-radius:20px">
<div class="box-header">
<div class="grid grid-cols-12 gap-x-6 mb-3 mt-3 relative">
<div class="absolute">
<button type="button" class="ti-btn ti-btn-outline ti-btn-outline-light h-20px m-0 "
style="border-radius:20px" (click)="back()">
<i class="ti ti-chevron-left"></i>
{{'Back' | translate}}
</button>
</div>
<div class="col-span-12">
<h5 class="box-title mb-3 text-center">ผลงานดีเด่น</h5>
</div>
</div>
<nav class="sm:flex sm:space-x-2 space-y-2 sm:space-y-0 rtl:space-x-reverse block"
aria-label="Tabs" role="tablist" style="max-width: 250px;">
<button type="button" style="border-radius:20px"
class="py-2 px-3 inline-flex items-center w-full justify-center gap-2 text-sm font-medium text-center border text-gray-500 rounded-sm hover:text-gray-700 active"
id="part-item-1" data-hs-tab="#part-1" aria-controls="part-1" role="tab">
<!-- hs-tab-active:text-white hs-tab-active:bg-primary hs-tab-active:border-primary -->
{{'รายชื่อผู้ใต้บังคับบัญชา' | translate}}
</button>
</nav>
</div>
<div class="box-body">
<div id="part-1" class="" role="tabpanel" aria-labelledby="part-item-1">
<ng-container *ngTemplateOutlet="part1"></ng-container>
</div>
</div>
</div>
</div>
<div class="col-span-12 xxl:col-span-2">
</div>
</div>
</div>
</div>
<ng-template #part1>
<div class="w-full min-height-50px mb-10px justify-between items-center">
<div class="flex justify-end">
<div class="px-1">
<div class="relative shadow-md">
<input type="text" class="ti-form-input ltr:pl-11 rtl:pr-11 focus:z-10 "
[placeholder]="'SearchByNoOrName' | translate" [(ngModel)]="search">
<div
class="absolute inset-y-0 ltr:left-0 rtl:right-0 flex items-center pointer-events-none z-20 ltr:pl-4 rtl:pr-4">
<i class="ri-search-line text-gray"></i>
</div>
</div>
</div>
</div>
</div>
<div class="p-2 pt-0">
<app-datagrid-syncfution [searchSettings]="searchSettings" [searchText]="search" [dataSource]="employee.list"
[columns]="columns" [showImg]="true" (sendSelectData)="selectEmployee($event);openEmployeeDialog()"
[initialPage]="{ pageSizes: true, pageSize: 5 }" [checkBoxSetting]="false">
</app-datagrid-syncfution>
</div>
<ng-template #employeeDialog let-modal>
<h3 mat-dialog-title>
{{'บันทึก ผลงานดีเด่น' | translate}}
</h3>
<div class="w-full flex justify-end mb-1rem">
<div class="absolute flex">
<div class="px-1">
<button type="button" class="ti-btn ti-btn-soft-indigo h-45px m-0 shadow-md">
<i class="ti ti-eraser text-base"></i>
Clear
</button>
</div>
</div>
</div>
<mat-dialog-content>
<div class="space-y-3">
<div class="row">
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">1. ประเภทผลงานดีเด่น</label>
<div class="row col-6" style="align-content: start;">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio1"
id="radio1">
</div>
<div class="col-6">
<label for="radio1" class="text-sm text-gray-500" style="cursor: pointer;">
งานตาม Job description
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio1"
id="radio2">
</div>
<div class="col-6">
<label for="radio2" class="text-sm text-gray-500" style="cursor: pointer;">
งานตาม Action plan
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio1"
id="radio3">
</div>
<div class="col-6">
<label for="radio3" class="text-sm text-gray-500" style="cursor: pointer;">
งานมอบหมายพิเศษ
</label>
</div>
</div>
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio1"
id="radio3">
</div>
<div class="col-6">
<label for="radio3" class="text-sm text-gray-500" style="cursor: pointer;">
งานนวัตกรรม
</label>
</div>
</div>
</div>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">2. วัตถุประสงค์ของงาน</label>
<div class="row col-6" style="align-content: start;">
<ng-container *ngFor="let item of
['เพื่อปรับปรุงงาน เพิ่มผลผลิต',
'เพิ่มยอดขาย / กำไร',
'ลดต้นทุน',
'เพื่อพัฒนาพ',
'เพิ่อดูแลลูกค้า',
'เพื่อดูแลพนักงาน',
'เพิ่อดูแลสังคม'];let i = index">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio2"
[id]="'radio2'+i">
</div>
<div class="col-6">
<label [for]="'radio2'+i" class="text-sm text-gray-500"
style="cursor: pointer;">
{{item}}
</label>
</div>
</div>
</ng-container>
</div>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">3. สรุปงานดีเด่นโดยย่อ</label>
<textarea type="text" rows="3" class="ti-form-input col-12"></textarea>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">4. ระยะเวลาที่สร้างผลงานดีเด่น</label>
<div class="col-6 p-2">
<label class="ti-form-label">วันที่เรื่มต้น<span class="text-danger">*</span></label>
<mat-form-field>
<input matInput [matDatepicker]="dateIncident" type="text" readonly
class="ti-form-input rounded-l-none focus:z-10 flatpickr-input !text-gray-500 !bg-white"
id="datetime" [(ngModel)]="dateSelectIso.dateIncident"
(ngModelChange)="changeDate(this.dateSelect, 'dateIncident', dateSelectIso.dateIncident);">
<mat-datepicker-toggle matSuffix [for]="dateIncident"></mat-datepicker-toggle>
<mat-datepicker #dateIncident></mat-datepicker>
</mat-form-field>
</div>
<div class="col-6 p-2">
<label class="ti-form-label">วันสิ้นสุด<span class="text-danger">*</span></label>
<mat-form-field>
<input matInput [matDatepicker]="dateEffective" type="text" readonly
class="ti-form-input rounded-l-none focus:z-10 flatpickr-input !text-gray-500 !bg-white"
id="datetime" [(ngModel)]="dateSelectIso.dateEffective"
(ngModelChange)="changeDate(this.dateSelect, 'dateEffective', dateSelectIso.dateEffective);">
<mat-datepicker-toggle matSuffix [for]="dateEffective"></mat-datepicker-toggle>
<mat-datepicker #dateEffective></mat-datepicker>
</mat-form-field>
</div>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">5. บทบาทในงานดีเด่น</label>
<div class="row col-6" style="align-content: start;">
<ng-container *ngFor="let item of
['เป็นเจ้าของงาน / โครงการ 100%',
'เป็นสมาชิกของทีม'];let i = index">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio5"
[id]="'radio5'+i">
</div>
<div class="col-6">
<label [for]="'radio5'+i" class="text-sm text-gray-500"
style="cursor: pointer;">
{{item}}
</label>
</div>
</div>
</ng-container>
</div>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">6. ระดับการเผยแพร่ผลงานดีเด่น</label>
<div class="row col-6" style="align-content: start;">
<ng-container *ngFor="let item of
['ระดับ International',
'ระดับประเทศ',
'ระดับองค์กร',
'ระดับสายงาน',
'ระดับหน่วยงานที่ค่ากว่าสายงาน'] ;let i = index">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio6"
[id]="'radio6'+i">
</div>
<div class="col-6">
<label [for]="'radio6'+i" class="text-sm text-gray-500"
style="cursor: pointer;">
{{item}}
</label>
</div>
</div>
</ng-container>
<div class="row col-12">
<label class="text-sm text-gray-500">
หมายเหตุ โปรดระบุชื่อองค์กรที่ได้รับการเผยแพร่ผลงานดีเด่น
</label>
</div>
</div>
</div>
<div class="col-12 p-2 row">
<label class="col-12 ti-form-label">7. ผลประเมินงานดีเด่น อยู่ในเกรด</label>
<div class="row col-6" style="align-content: start;">
<ng-container *ngFor="let item of
['A-สูงกว่ามาตรฐานมาก',
'B-สูงกว่ามาตรฐาน',
'C -มาตรฐาน'] ;let i = index">
<div class="row col-12">
<div class="col-auto pr-1rem">
<input type="radio" class="ti-form-radio" style="cursor: pointer;" name="radio7"
[id]="'radio7'+i">
</div>
<div class="col-6">
<label [for]="'radio7'+i" class="text-sm text-gray-500"
style="cursor: pointer;">
{{item}}
</label>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button type="button" mat-button [mat-dialog-close]
class="hs-dropdown-toggle ti-btn ti-border font-medium bg-white text-gray-700 shadow-sm align-middle hover:bg-gray-50 focus:ring-offset-white focus:ring-primary dark:bg-bgdark dark:hover:bg-black/20 dark:border-white/10 dark:text-white/70 dark:hover:text-white dark:focus:ring-offset-white/10">
ย้อนกลับ
</button>
<button type="button" class="ti-btn ti-btn-success" (click)="save()">
บันทึกข้อมูล
</button>
</mat-dialog-actions>
</ng-template>
</ng-template>
\ No newline at end of file
.bg-gradient-custom {
background: linear-gradient(135deg, #4f46e5, #ec4899 60%, #f59e0b);
-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
mask-size: 100% 100%;
mask-repeat: no-repeat;
}
.row {
display: flex;
flex-wrap: wrap;
}
.col {
flex: 1;
}
@for $i from 1 through 12 {
$width: (
$i / 12) * 100%;
.col-#{$i} {
flex: 0 0 $width;
max-width: $width;
}
}
@for $i from 1 through 100 {
.m-#{$i}rem {
margin: #{$i}rem;
}
.mt-#{$i}rem {
margin-top: #{$i}rem;
}
.ml-#{$i}rem {
margin-left: #{$i}rem;
}
.mb-#{$i}rem {
margin-bottom: #{$i}rem;
}
.mr-#{$i}rem {
margin-right: #{$i}rem;
}
.p-#{$i}rem {
padding: #{$i}rem;
}
.pt-#{$i}rem {
padding-top: #{$i}rem;
}
.pl-#{$i}rem {
padding-left: #{$i}rem;
}
.pb-#{$i}rem {
padding-bottom: #{$i}rem;
}
.pr-#{$i}rem {
padding-right: #{$i}rem;
}
}
\ No newline at end of file
import { ViewportScroller } from '@angular/common';
import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { ColumnModel } from '@syncfusion/ej2-grids';
import { ToastrService } from 'ngx-toastr';
import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model';
import { JobCodeModel, MyJobCodeModel } from 'src/app/shared/model/job-code.model';
import { MyStatusModel, StatusModel } from 'src/app/shared/model/status.model';
import { EmpStatusService } from 'src/app/shared/services/emp-status.service';
import { EmployeeService } from 'src/app/shared/services/employee.service';
import { EventgrpService } from 'src/app/shared/services/eventgrp.service';
import { FileService } from 'src/app/shared/services/file.service';
import { JobcodeService } from 'src/app/shared/services/jobcode.service';
import { PmsWorkingTimeService } from 'src/app/shared/services/pms-working-time.service';
import Swal from 'sweetalert2';
export interface BiModel {
name: string,
tools: string[],
degree: string
}
@Component({
selector: 'app-outstanding-performance',
templateUrl: './outstanding-performance.component.html',
styleUrls: ['./outstanding-performance.component.scss']
})
export class OutstandingPerformanceComponent {
currentPage = 1
empDetail: { loading: boolean, data: JobCodeModel } = { loading: false, data: new MyJobCodeModel({}) }
columns: ColumnModel[] = [
{
field: "picture",
headerText: "",
type: "string",
}, {
field: "employeeId",
headerText: "EmployeeCode",
type: "string",
isPrimaryKey: true,
},
{
field: "fname",
headerText: "FirstName",
type: "string"
},
{
field: "lname",
headerText: "LastName",
type: "string"
},
{
field: "position.tdesc",
headerText: "Position",
type: "string"
}]
searchSettings = {
fields: ['employeeId', 'fname', 'lname', 'position.tdesc'],
operator: 'contains',
ignoreCase: false
}
search = ''
employee: { loading: boolean, select: EmployeeModel, list: EmployeeModel[] } = { loading: false, select: new MyEmployeeModel(), list: [] }
@ViewChild('employeeDialog') employeeDialog: any
employeeDialogRef: any
dateSelectIso = {
dateIncident: '',
dateEffective: ''
}
dateSelect = {
dateIncident: '',
dateEffective: ''
}
constructor(
private toastr: ToastrService,
private cdr: ChangeDetectorRef,
private dialog: MatDialog,
private fileService: FileService,
private eventgrpService: EventgrpService,
private jobcode: JobcodeService,
private employeeService: EmployeeService,
private translateService: TranslateService,
private router: Router
) {
this.translateService.onLangChange.subscribe((event) => {
});
}
ngOnInit(): void {
this.getEmployeeList()
}
getEmployeeList() {
this.employee.loading = true
this.employeeService.getList().subscribe({
next: response => {
this.employee.list = response.map((x: any) => new MyEmployeeModel(x))
this.employee.loading = false
this.cdr.detectChanges()
}, error: error => {
this.employee.loading = false
this.cdr.detectChanges()
}
})
}
selectEmployee(data?: EmployeeModel) {
this.employee.select = new MyEmployeeModel(data)
}
openEmployeeDialog() {
this.employeeDialogRef = this.dialog.open(this.employeeDialog, {
width: '800px',
})
}
closeEmployeeDialog() {
this.employeeDialogRef.close()
}
toISODate(dateInput?: string | null): string {
if (!dateInput) return "";
const parsedDate = new Date(dateInput);
return isNaN(parsedDate.getTime()) ? new Date().toISOString() : parsedDate.toISOString();
}
changeDate(target: { [key: string]: any }, field: string, dateIso: string) {
target[field] = this.toYYYYMMDD(dateIso)
}
toYYYYMMDD(dateInput?: string | null): string {
if (!dateInput) return "";
const parsedDate = new Date(dateInput);
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
};
const formattedDate = parsedDate.toLocaleDateString('en-GB', options);
const [day, month, year] = formattedDate.split('/');
return `${year}-${month}-${day}`;
}
save() {
Swal.fire({
icon: 'question',
title: 'แจ้งเตือน',
text: 'ยืนยันการบันทึกข้อมูลหรือไม่',
showCancelButton: true,
confirmButtonText: 'บันทึกข้อมูล',
cancelButtonText: 'ย้อนกลับ',
reverseButtons: true,
}).then((result) => {
if (result.isConfirmed) {
this.showAlert('บันทึกข้อมูลสำเร็จ', 'success')
this.closeEmployeeDialog();
}
});
}
showAlert(text: string, type: 'success' | 'error') {
Swal.fire({
title: 'แจ้งเตือน',
text: text,
icon: type,
confirmButtonText: 'ตกลง',
});
}
back() {
this.router.navigate(['/ess/employee-self-service']);
}
}
\ No newline at end of file
...@@ -101,6 +101,8 @@ export class SidebarComponent { ...@@ -101,6 +101,8 @@ export class SidebarComponent {
this.currentUrl.includes('ess/competency-mapping') || this.currentUrl.includes('ess/competency-mapping') ||
this.currentUrl.includes('ess/job-family-mapping') || this.currentUrl.includes('ess/job-family-mapping') ||
this.currentUrl.includes('ess/job-family-matrix') || this.currentUrl.includes('ess/job-family-matrix') ||
this.currentUrl.includes('ess/disciplinary-action') ||
this.currentUrl.includes('ess/outstanding-performance') ||
this.currentUrl.includes('ess/job-description') this.currentUrl.includes('ess/job-description')
if (this.showSideMenu) { if (this.showSideMenu) {
const html: any = this.elementRef.nativeElement.ownerDocument.documentElement;; const html: any = this.elementRef.nativeElement.ownerDocument.documentElement;;
...@@ -176,6 +178,8 @@ export class SidebarComponent { ...@@ -176,6 +178,8 @@ export class SidebarComponent {
this.currentUrl.includes('ess/competency-mapping') || this.currentUrl.includes('ess/competency-mapping') ||
this.currentUrl.includes('ess/job-family-mapping') || this.currentUrl.includes('ess/job-family-mapping') ||
this.currentUrl.includes('ess/job-family-matrix') || this.currentUrl.includes('ess/job-family-matrix') ||
this.currentUrl.includes('ess/disciplinary-action') ||
this.currentUrl.includes('ess/outstanding-performance') ||
this.currentUrl.includes('ess/job-description') this.currentUrl.includes('ess/job-description')
if (this.showSideMenu) { if (this.showSideMenu) {
const html: any = this.elementRef.nativeElement.ownerDocument.documentElement;; const html: any = this.elementRef.nativeElement.ownerDocument.documentElement;;
......
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