Commit 2181a307 by DESKTOP-E0VCCBD\zedan

update

parent 7aa10f5a
<p>admin-project-home works!</p>
<app-page-header [title]="'จัดการโครงการ'" [activeTitle]="'ผู้ดูแลระบบ'" [title1]="'จัดการโครงการ'"></app-page-header>
<div class="grid grid-cols-12 gap-6">
<div class="xl:col-span-12 col-span-12">
<div class="box">
<div class="box-header justify-between">
<div class="box-title">
{{ 'All List' | translate}} <span
class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle">{{itemsList.length}}</span>
</div>
<div class="flex flex-wrap gap-2">
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-primary-full me-2" (click)="new()"
data-hs-overlay="#modal-detail"><i class="ri-add-line font-semibold align-middle"></i>{{ 'Create' |
translate}}
</a>
<!-- <a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-success-full me-2" *ngIf="someSelected"
(click)="adjustSelect(1)"><i class="ri-user-follow-line font-semibold align-middle"></i>{{ 'Active' |
translate}}
</a> -->
<!-- <a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-secondary-full me-2"
*ngIf="someSelected" (click)="adjustSelect(0)"><i
class="ri-user-unfollow-line font-semibold align-middle"></i>{{ 'Unactive' |
translate}}
</a> -->
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-danger-full me-2" *ngIf="someSelected"
(click)="deleteSelect()"><i class="ri-delete-bin-line font-semibold align-middle"></i>{{ 'Delete' |
translate}}
</a>
<div>
<input class="form-control form-control" type="text" placeholder="ค้นหาโครงการ"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div>
<!-- <div>
<input class="form-control form-control" type="text" placeholder="กรองตามโครงการ"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div> -->
<!-- <a href="javascript:void(0);" class="ti-btn ti-btn-primary-full !py-1 !px-2" aria-expanded="false">
เรียงตาม<i class="ri-arrow-down-s-line align-middle ms-1 inline-block"></i>
</a>
<ul class="hs-dropdown-menu ti-dropdown-menu hidden" role="menu">
<li><a class="ti-dropdown-item" href="javascript:void(0);">Newest</a></li>
<li><a class="ti-dropdown-item" href="javascript:void(0);">Oldest</a></li>
</ul> -->
</div>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-12 gap-x-6">
@for(item of filterList;track filterList){
<div class="xxl:col-span-3 xl:col-span-4 md:col-span-6 col-span-12">
<div class="box custom-box">
<div class="box-header items-center !justify-start flex-wrap !flex">
<div class="me-2">
<span class="avatar avatar-rounded p-1 bg-danger/10 text-danger">
<img src="{{item.getPicture()}}" alt="">
</span>
</div>
<div class="flex-grow">
<a href="javascript:void(0);"
class="font-semibold text-[.875rem] block text-truncate project-list-title">{{item.project_name}}</a>
<span class="text-[#8c9097] dark:text-white/50 block text-[0.75rem]">{{item.project_code}}</span>
</div>
<div class="hs-dropdown ti-dropdown">
<a aria-label="anchor" href="javascript:void(0);" class="ti-btn ti-btn-sm ti-btn-light !mb-0"
aria-expanded="false">
<i class="fe fe-more-vertical"></i>
</a>
<ul class="hs-dropdown-menu ti-dropdown-menu hidden">
<li><a class="ti-dropdown-item" routerLink="/company/home/{{item.projectId}}"><i
class="ri-eye-line align-middle me-1 inline-flex"></i>View</a></li>
<li><a class="ti-dropdown-item" (click)="view(item)" data-hs-overlay="#modal-detail"><i
class="ri-edit-line align-middle me-1 inline-flex"></i>Edit</a></li>
<li><a class="ti-dropdown-item" (click)="delete(item)"><i
class="ri-delete-bin-line me-1 align-middle inline-flex"></i>Delete</a></li>
</ul>
</div>
</div>
<div class="box-body">
<div class="font-semibold mb-1">รายละเอียดโครงการ :</div>
<p class="text-[#8c9097] dark:text-white/50 mb-3">{{item.project_desc}}</p>
<div class="flex items-center justify-between mb-3">
<div>
<div class="font-semibold mb-1">ผู้รับผิดชอบ :</div>
<span class="badge bg-success/10 text-success">{{item.responsible}}</span>
</div>
<div class="text-end">
<div class="font-semibold mb-1">ติดต่อ :</div>
<span class="badge bg-success/10 text-success">{{item.contact}}</span>
</div>
<div>
<button data-hs-overlay="#modal-stock" type="button" aria-label="button" title="View" routerLink="/company/home/{{item.projectId}}"
class="ti-btn ti-btn-sm ti-btn-light me-[0.375rem]">
<i class="fe fe-eye"></i>
</button>
</div>
</div>
</div>
<!-- <div class="box-footer flex items-center justify-between">
<div>
<span class="text-[#8c9097] dark:text-white/50 text-[0.6875rem] block">ผู้รับผิดชอบ :</span>
<span class="font-semibold block">{{item.responsible}}</span>
</div>
<div class="text-end">
<span class="text-[#8c9097] dark:text-white/50 text-[0.6875rem] block">การติดต่อ :</span>
<span class="font-semibold block">{{item.contact}}</span>
</div>
</div> -->
</div>
</div>
}
</div>
<nav aria-label="Page navigation">
<ul class="ti-pagination ltr:float-right rtl:float-left mb-4">
<li class="page-item disabled"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);">Previous</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);">1</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);">2</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);">Next</a></li>
</ul>
</nav>
<!-- Start:: Create Contact -->
<div id="modal-detail" class="hs-overlay hidden ti-modal [--overlay-backdrop:static]">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out">
<div class="ti-modal-content">
<div class="ti-modal-header">
<h6 class="modal-title text-[1rem] font-semibold text-defaulttextcolor" id="mail-ComposeLabel">{{
'รายละเอียดโครงการ' }}
</h6>
<button type="button" class="hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay="#modal-detail" #closeModal>
<span class="sr-only">{{'Close' | translate}}</span>
<i class="ri-close-line"></i>
</button>
</div>
<div class="ti-modal-body px-4">
<div class="grid grid-cols-12 gap-4">
<div class="xl:col-span-12 col-span-12">
<div class="mb-0 text-center">
<span class="avatar avatar-xxl avatar-rounded">
<img [src]="selectModel.getPicture()" alt="" id="profile-img">
<span class="badge rounded-full bg-primary avatar-badge">
<input ng2FileSelect [uploader]="uploaderProfile" type="file" name="photo"
class="absolute w-full h-full opacity-[0]" id="profile-change">
<i class="fe fe-camera text-[.625rem]"></i>
</span>
</span>
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'ชื่อโครงการ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder=""
[(ngModel)]="selectModel.project_name">
<div class="text-danger" *ngIf="!selectModel.project_name">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'รหัสโครงการ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder=""
[(ngModel)]="selectModel.project_code">
<div class="text-danger" *ngIf="!selectModel.project_code">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'ผู้รับผิดชอบ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder=""
[(ngModel)]="selectModel.responsible">
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'การติดต่อ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="" [(ngModel)]="selectModel.contact">
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'รายละเอียดโครงการ' | translate}}</label>
<textarea class="form-control" id="job-description" [(ngModel)]="selectModel.project_desc"
rows="4"></textarea>
<!-- <input type="text" class="form-control" id="deal-title" placeholder=""
[(ngModel)]="selectModel.project_desc">
<div class="text-danger" *ngIf="!selectModel.project_desc">
{{'Please fill in information' | translate}}
</div> -->
</div>
<!-- <div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'ที่อยู่' | translate}}</label>
<textarea type="text" class="form-control" id="deal-title" placeholder=""
[(ngModel)]="selectModel.address"></textarea>
</div> -->
<!-- <div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'เบอร๋ติดต่อ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="" [(ngModel)]="selectModel.contact">
</div> -->
<!-- <div class="xl:col-span-12 col-span-12">
<label class="form-label">{{'Status' | translate}}</label>
<ng-select name="choices-multiple-remove-button2" id="choices-multiple-remove-button2" placeholder=""
[(ngModel)]="selectModel.status">
<ng-option [value]="0">{{'Pending' | translate}}</ng-option>
<ng-option [value]="1" selected>{{'Public' | translate}}</ng-option>
</ng-select>
</div> -->
</div>
</div>
<div class="ti-modal-footer">
<button type="button" class="hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay="#modal-detail">
{{'Cancel' | translate}}
</button>
<button type="button" (click)="save()" class="ti-btn bg-primary text-white !font-medium">{{'Save' |
translate}}</button>
</div>
</div>
</div>
</div>
<!-- End:: Create Contact -->
import { Component } from '@angular/core';
import { Component, ElementRef, ViewChild } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { SharedModule } from '../../../shared/shared.module';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import swal from 'sweetalert';
import { CompanyService } from '../../services/company.service';
import { MatPaginator } from '@angular/material/paginator';
import { FormsModule } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { CommonModule } from '@angular/common';
import { FileUploadModule } from 'ng2-file-upload';
import { FileItem, FileUploader, ParsedResponseHeaders } from "ng2-file-upload";
import { environment } from '../../../../environments/environment';
import { TokenService } from '../../../shared/services/token.service';
import { ProjectService } from '../../services/project.service';
import { ProjectModel } from '../../models/project.model';
@Component({
selector: 'app-admin-project-home',
standalone: true,
imports: [],
imports: [
CommonModule,
SharedModule,
TranslateModule,
NgSelectModule,
FormsModule,
MatPaginator,
RouterModule,
FileUploadModule
],
templateUrl: './admin-project-home.component.html',
styleUrl: './admin-project-home.component.scss'
})
export class AdminProjectHomeComponent {
}
@ViewChild('closeModal') public childModal?: ElementRef;
@ViewChild('modalDetail') public modalDetail?: ElementRef;
action = "new";
allSelected = false;
someSelected = false;
itemsList: ProjectModel[] = []
filterList: ProjectModel[] = []
selectModel: ProjectModel = new ProjectModel()
selectedItems = new Map<string, boolean>();
empList: ProjectModel[] = []
descName = 'engName'
pageIndex = 0;
uploaderProfile: FileUploader | undefined;
uploadErrorMsg: string = "";
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this.pageIndex = 0;
this.allSelected = false
this._searchTerm = val;
if (val != '') {
this.filterList = this.filter(val);
} else {
this.updatePagedItems()
}
}
_searchTerm = "";
constructor(private projectService: ProjectService, public translate: TranslateService, private tokenService: TokenService) {
this.uploadConfig()
}
uploadConfig() {
this.uploaderProfile = new FileUploader({
url: environment.baseUrl + "/api/upload-image",
isHTML5: true,
authToken: this.tokenService.getToken()!,
});
this.uploaderProfile.onAfterAddingFile = (fileItem: FileItem) => {
fileItem.withCredentials = false;
this.uploadErrorMsg = "";
while (this.uploaderProfile!.queue.length > 1) {
this.uploaderProfile!.queue[0].remove();
}
if (fileItem.file.size > 5000000) {
this.uploadErrorMsg = "maximum file size 5mb.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
fileItem.isCancel = true;
return;
}
if (fileItem.file.type!.indexOf("image") === -1) {
this.uploadErrorMsg = "please upload image only.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
fileItem.isCancel = true;
return;
}
fileItem.upload();
};
this.uploaderProfile.onCompleteItem = (
item: FileItem,
response: string,
status: number,
headers: ParsedResponseHeaders
) => {
if (item.isSuccess) {
const res = JSON.parse(response);
console.log("res", res);
this.selectModel.picture = res.filename
swal(res.message, "บันทึกสำเร็จ", "success");
} else {
this.uploadErrorMsg = "cannot upload file.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
}
};
}
ngOnInit(): void {
this.projectService.getLists().subscribe(result => {
this.itemsList = result
this.updatePagedItems()
})
}
filter(v: string) {
return this.itemsList?.filter(
(x) =>
x.projectId?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.project_name?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.project_desc?.toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
delete(item: ProjectModel) {
swal({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
dangerMode: true,
buttons: ["Cancel", "Yes,Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.projectService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit()
})
}
});
}
new() {
this.action = 'add'
this.selectModel = new ProjectModel()
this.selectModel.picture = ""
}
view(item: ProjectModel) {
this.action = 'edit'
this.selectModel = new ProjectModel(item)
console.log(this.selectModel)
}
save() {
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
if (this.action == 'add') {
this.projectService.save(this.selectModel).subscribe(result => {
console.log(result)
swal("Save Success!!", "บันทึกข้อมูลสมาชิก", "success");
this.ngOnInit()
this.childModal?.nativeElement.click()
})
} else if (this.action == 'edit') {
this.projectService.update(this.selectModel).subscribe(result => {
console.log(result)
swal("Update Success!!", "บันทึกข้อมูลสมาชิก", "success");
this.ngOnInit()
this.childModal?.nativeElement.click()
})
}
}
});
}
updatePagedItems() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
this.filterList = this.itemsList.slice(startIndex, endIndex);
}
toggleAll(event: any) {
this.allSelected = event.target.checked;
this.selectedItems.clear();
this.itemsList.forEach(item => {
this.selectedItems.set(item.projectId!, this.allSelected);
});
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.projectId!));
}
onCheckboxChange(projectId: string) {
const isSelected = this.selectedItems.get(projectId) || false;
this.selectedItems.set(projectId, !isSelected);
this.allSelected = this.itemsList.every(item => this.selectedItems.get(item.projectId!));
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.projectId!));
}
deleteSelect() {
let employeeInfo = '';
this.selectedItems.forEach((isSelected, projectId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.projectId === projectId);
if (item) {
employeeInfo += `${this.translate.instant('บริษัท')}: ${item.project_name}\n`;
}
}
});
swal({
title: "Are you sure?",
text: employeeInfo,
icon: "warning",
dangerMode: true,
buttons: ["Cancel", "Yes, Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.selectedItems.forEach((isSelected, projectId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.projectId === projectId);
if (item) {
this.projectService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit();
});
}
}
});
}
});
}
// adjustSelect(status: number) {
// let title = "Are you sure?"
// let employeeInfo = ''; // ตัวแปรสำหรับเก็บข้อมูลพนักงาน
// this.selectedItems.forEach((isSelected, memberId) => {
// if (isSelected) {
// const company = this.itemsList.find(project => project.projectId === memberId);
// if (project) {
// employeeInfo += `${this.translate.instant('Fullname')}: ${project.projectName}\n`;
// }
// }
// });
// swal({
// title: title,
// text: employeeInfo,
// icon: "warning",
// dangerMode: false,
// buttons: ["Cancel", "Confirm"],
// })
// .then((willDelete: any) => {
// if (willDelete) {
// this.selectedItems.forEach((isSelected, projectId) => {
// if (isSelected) {
// const project = this.itemsList.find(project => project.projectId === projectId);
// if (project) {
// project.status = status
// this.projectService.update(project).subscribe(result => {
// swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
// this.ngOnInit();
// });
// }
// }
// });
// }
// });
// }
}
<app-page-header [title]="'การเบิกอุปกรณ์'" [activeTitle]="'ผู้ดูแลระบบ'" [title1]="'การเบิกอุปกรณ์'"></app-page-header>
<app-page-header [title]="'การเบิกอุปกรณ์'" [activeTitle]="'ผู้ใช้งาน'" [title1]="'การเบิกอุปกรณ์'"></app-page-header>
<div class="grid grid-cols-12 gap-x-6">
<div class="xl:col-span-12 col-span-12">
......
......@@ -89,7 +89,7 @@
</tr>
</thead>
<tbody>
@for(product of filteredList; track product.peId){
@for(product of filteredList;track filterList){
<tr class="product-list">
<td>{{ product.project_equipment?.project?.project_name }}
</td>
......@@ -125,7 +125,7 @@
{{ getStatusText(product.status) }}
</span>
</td>
<td>{{ product.approved_by_member?.getFullname() || "-" }}</td>
<td>{{ product.approved_by_member?.getFullname()}}</td>
<td>
<div class="flex gap-1">
......@@ -209,7 +209,7 @@
id="deal-name"
placeholder="ชื่ออุปกรณ์"
[ngModel]="
selectedBorrowItem.project_equipment?.equipment?.equipmentName
selectedBorrowItem.project_equipment.equipment.equipmentName
"
/>
</div>
......@@ -276,7 +276,7 @@
readonly
type="text"
class="form-control"
[value]="selectedBorrowItem.member?.getFullname() || '-'"
[value]="selectedBorrowItem.member.getFullname() || '-'"
/>
</div>
......@@ -286,7 +286,7 @@
readonly
type="text"
class="form-control"
[value]="selectedBorrowItem.member?.phoneNumber || '-'"
[value]="selectedBorrowItem.member.phoneNumber || '-'"
/>
</div>
......@@ -298,8 +298,7 @@
type="text"
class="form-control"
[value]="
selectedBorrowItem.project_equipment?.equipment
?.equipmentName || '-'
selectedBorrowItem.project_equipment.equipment.equipmentName
"
/>
</div>
......
......@@ -66,7 +66,6 @@
</div>
</div>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table whitespace-nowrap table-bordered min-w-full">
......
<p>
emp-borrow-transaction works!
</p>
<app-page-header [title]="'จัดการสมาชิก'" [activeTitle]="'ผู้ดูแลระบบ'" [title1]="'จัดการสมาชิก'"></app-page-header>
<div class="grid grid-cols-12 gap-6">
<div class="xl:col-span-12 col-span-12">
<div class="box">
<div class="box-header justify-between">
<div class="box-title">
{{ 'All List' | translate}} <span
class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle">{{itemsList.length}}</span>
</div>
<div class="flex flex-wrap gap-2">
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-primary-full me-2" (click)="new()"
data-hs-overlay="#modal-detail"><i class="ri-add-line font-semibold align-middle"></i>{{ 'Create' |
translate}}
</a>
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-success-full me-2" *ngIf="someSelected"
(click)="adjustSelect(1)"><i class="ri-user-follow-line font-semibold align-middle"></i>{{ 'Active' |
translate}}
</a>
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-secondary-full me-2"
*ngIf="someSelected" (click)="adjustSelect(0)"><i
class="ri-user-unfollow-line font-semibold align-middle"></i>{{ 'Unactive' |
translate}}
</a>
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-danger-full me-2" *ngIf="someSelected"
(click)="deleteSelect()"><i class="ri-delete-bin-line font-semibold align-middle"></i>{{ 'Delete' |
translate}}
</a>
<div>
<input class="form-control form-control" type="text" placeholder="ค้นหาสมาชิก"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div>
<!-- <div>
<input class="form-control form-control" type="text" placeholder="กรองตามบริษัท"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div> -->
<!-- <a href="javascript:void(0);" class="ti-btn ti-btn-primary-full !py-1 !px-2" aria-expanded="false">
เรียงตาม<i class="ri-arrow-down-s-line align-middle ms-1 inline-block"></i>
</a>
<ul class="hs-dropdown-menu ti-dropdown-menu hidden" role="menu">
<li><a class="ti-dropdown-item" href="javascript:void(0);">Newest</a></li>
<li><a class="ti-dropdown-item" href="javascript:void(0);">Oldest</a></li>
</ul> -->
</div>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table whitespace-nowrap min-w-full ti-custom-table-hover">
<thead>
<tr class="border-b border-defaultborder">
<th scope="col" class="!text-start">
<input class="form-check-input check-all" type="checkbox" id="all-products"
(change)="toggleAll($event)" [checked]="allSelected" aria-label="...">
</th>
<th scope="col" class="text-start">{{ 'Username' | translate}}</th>
<th scope="col" class="text-start">{{ 'Fullname' | translate}}</th>
<th scope="col" class="text-start">{{ 'Email' | translate}}</th>
<th scope="col" class="text-start">{{ 'Mobile' | translate}}</th>
<th scope="col" class="text-start">{{ 'User Group' | translate}}</th>
<th scope="col" class="text-start">{{ 'Status' | translate}}</th>
<th scope="col" class="text-start">{{ 'Update Date' | translate}}</th>
<th scope="col" class="text-start"></th>
</tr>
</thead>
<tbody>
@for(item of filterList;track filterList){
<tr class="border border-defaultborder dark:border-defaultborder/10">
<td class="product-checkbox"><input class="form-check-input" type="checkbox" [checked]="selectedItems.get(item.memberId)"
(change)="onCheckboxChange(item.memberId)" aria-label="..." value="">
</td>
<td>
<div class="flex items-center">
<span class="avatar avatar-sm p-1 me-1 bg-light !rounded-full">
<img
[src]="item.getPicture()"
alt="" id="profile-img">
</span>
<div class="ms-2">
<p class="font-semibold mb-0 flex items-center text-primary"><a (click)="view(item)">
{{item.username}}</a></p>
<p class="text-[0.75rem] text-muted mb-0">{{item.memberId}}</p>
</div>
</div>
</td>
<!-- <td>
<div class="flex">
<div class="ms-2">
<p class="font-semibold mb-0 flex items-center text-primary"><a (click)="view(item)"
data-hs-overlay="#modal-detail">
{{item.username}}</a></p>
<p class="text-[0.75rem] text-muted mb-0">{{item.memberId}}</p>
</div>
</div>
</td> -->
<td> {{item.firstName}} {{item.lastName}}</td>
<td>
<div>
<span class="block mb-1"><i
class="ri-mail-line me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"></i>{{item.email}}</span>
</div>
</td>
<td>
<div>
<span class="block"><i
class="ri-phone-line me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"></i>{{item.phoneNumber}}</span>
</div>
</td>
<td> <span
class="badge bg-{{ item.role == 1 ? 'primary' : 'info'}} text-white">{{item.getRole()}}</span>
</td>
<td> <span
class="badge bg-{{ item.status == 1 ? 'primary' : 'danger'}} text-white">{{item.getStatus()}}</span>
</td>
<td><span class="badge bg-info/10 text-primary"><i
class="bi bi-clock me-1"></i>{{item.updatedAt | date : 'medium'}}</span></td>
<td>
<td>
<div class="flex flex-row items-center !gap-2 ">
<a aria-label="anchor" (click)="view(item)" data-hs-overlay="#modal-detail"
class="ti-btn ti-btn-wave !gap-0 !m-0 bg-info/10 text-info hover:bg-info hover:text-white hover:border-info"><i
class="ri-pencil-line"></i></a>
<a aria-label="anchor" href="javascript:void(0);" (click)="delete(item)"
class="ti-btn ti-btn-wave product-btn !gap-0 !m-0 bg-danger/10 text-danger hover:bg-danger hover:text-white hover:border-danger"><i
class="ri-delete-bin-line"></i></a>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="box-footer">
<div class="flex items-center flex-wrap overflow-auto" *ngIf="filterList.length > 0">
<div class="mb-2 sm:mb-0">
<div>
{{'Showing' | translate}} {{filterList.length}} {{'entries'
| translate}} <i class="bi bi-arrow-right ms-2 font-semibold"></i>
</div>
</div>
<div class="ms-auto">
<nav aria-label="Page navigation">
<ul class="ti-pagination mb-0">
<li *ngIf="pageIndex>0" class="page-item {{pageIndex==0 ? 'disabled' : ''}}"><a
class="page-link px-3 py-[0.375rem]"
(click)="pageIndex = pageIndex-1;updatePagedItems()">{{'Previous' | translate}}</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);"
*ngIf="pageIndex-1>0" (click)="pageIndex = pageIndex-2;updatePagedItems()">{{pageIndex-1}}</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);"
*ngIf="pageIndex>0 && ((pageIndex-1)*10 < (searchTerm == '' ? itemsList.length : filterList.length))"
(click)="pageIndex = pageIndex-1;updatePagedItems()">{{pageIndex}}</a></li>
<li class="page-item"><a class="page-link active px-3 py-[0.375rem]"
href="javascript:void(0);">{{pageIndex +1}}</a>
</li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);"
*ngIf="(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(click)="pageIndex = pageIndex+1;updatePagedItems()">{{pageIndex +2}}</a></li>
<li class="page-item"><a class="page-link px-3 py-[0.375rem]" href="javascript:void(0);"
*ngIf="(pageIndex+2)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(click)="pageIndex = pageIndex+2;updatePagedItems()">{{pageIndex +3}}</a></li>
<li *ngIf="(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
class="page-item"><a class="page-link px-3 py-[0.375rem]"
(click)="pageIndex = pageIndex+1;updatePagedItems()">{{'Next' |
translate}}</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Start:: Create Contact -->
<div id="modal-detail" class="hs-overlay hidden ti-modal [--overlay-backdrop:static]">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out">
<div class="ti-modal-content">
<div class="ti-modal-header">
<h6 class="modal-title text-[1rem] font-semibold text-defaulttextcolor" id="mail-ComposeLabel">{{ 'Create' |
translate }} {{ 'User' | translate }}
</h6>
<button type="button" class="hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay="#modal-detail" #closeModal>
<span class="sr-only">{{'Close' | translate}}</span>
<i class="ri-close-line"></i>
</button>
</div>
<div class="ti-modal-body px-4">
<div class="grid grid-cols-12 gap-4">
<div class="xl:col-span-12 col-span-12">
<div class="mb-0 text-center">
<span class="avatar avatar-xxl avatar-rounded">
<img [src]="selectModel.getPicture()" alt="" id="profile-img">
<span class="badge rounded-full bg-primary avatar-badge">
<input ng2FileSelect [uploader]="uploaderProfile" type="file" name="photo" class="absolute w-full h-full opacity-[0]" id="profile-change">
<i class="fe fe-camera text-[.625rem]"></i>
</span>
</span>
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'Username' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="กรอก{{'Username' | translate}}" [(ngModel)]="selectModel.username">
<div class="text-danger" *ngIf="!selectModel.username">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'Password' | translate}}</label>
<input type="password" class="form-control" id="deal-title" placeholder="กรอก{{'Password' | translate}}"
[(ngModel)]="selectModel.password">
<div class="text-danger" *ngIf="!selectModel.password">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-title" class="form-label">{{'Confirm Password' | translate}}</label>
<input type="password" class="form-control" id="deal-title" placeholder="{{'Confirm Password' | translate}}" [(ngModel)]="confirmPassword">
<div class="text-danger" *ngIf="!confirmPassword">
{{'Please fill in information' | translate}}
</div>
<div class="text-danger" *ngIf="confirmPassword && (confirmPassword != selectModel.password)">
{{'Password Not Match' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="deal-title" class="form-label">{{'ชื่อ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="กรอก{{'ชื่อ' | translate}}" [(ngModel)]="selectModel.firstName">
<div class="text-danger" *ngIf="!selectModel.firstName">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="deal-title" class="form-label">{{'นามสกุล' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="กรอก{{'นามสกุล' | translate}}" [(ngModel)]="selectModel.lastName">
<div class="text-danger" *ngIf="!selectModel.lastName">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="deal-title" class="form-label">{{'อีเมล' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="กรอก{{'อีเมล' | translate}}" [(ngModel)]="selectModel.email">
<div class="text-danger" *ngIf="!selectModel.email">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="deal-title" class="form-label">{{'เบอร์ติดต่อ' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="กรอก{{'เบอร์ติดต่อ' | translate}}"
[(ngModel)]="selectModel.phoneNumber">
<div class="text-danger" *ngIf="!selectModel.phoneNumber">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-12 col-span-12">
<label class="form-label">{{'User Role' | translate}}</label>
<ng-select name="choices-multiple-remove-button1" id="choices-multiple-remove-button1" placeholder="เลือก"
[(ngModel)]="selectModel.role">
<ng-option [value]="0">{{'ผู้ใช้งานทั่วไป' | translate}}</ng-option>
<ng-option [value]="1">{{'ผู้ดูแลบริษัท' | translate}}</ng-option>
</ng-select>
</div>
<div class="xl:col-span-12 col-span-12">
<label class="form-label">{{'Status' | translate}}</label>
<ng-select name="choices-multiple-remove-button2" id="choices-multiple-remove-button2" placeholder="เลือก"
[(ngModel)]="selectModel.status">
<ng-option [value]="0">{{'Unactive' | translate}}</ng-option>
<ng-option [value]="1">{{'Active' | translate}}</ng-option>
</ng-select>
</div>
</div>
</div>
<div class="ti-modal-footer">
<button type="button" class="hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay="#modal-detail">
{{'Cancel' | translate}}
</button>
<button type="button" (click)="save()" class="ti-btn bg-primary text-white !font-medium">{{'Save' |
translate}}</button>
</div>
</div>
</div>
</div>
<!-- End:: Create Contact -->
import { Component, OnInit } from '@angular/core';
import { UserService } from './../../services/user.service';
import { HttpClient } from '@angular/common/http';
import { Component, ElementRef, ViewChild } from '@angular/core';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { FileItem, FileUploader, FileUploadModule, ParsedResponseHeaders } from 'ng2-file-upload';
import { TokenService } from '../../../shared/services/token.service';
import { BorrowTransactionsModel } from '../../models/borrow-transactions';
import { EquipmentModel, EquipmentStockModel } from '../../models/equipments.model';
import { ProjectEquipmentModel } from '../../models/project-equipments';
import { ProjectMemberModel } from '../../models/project-members';
import { BorrowTransactionsService } from '../../services/borrow-transactions.service';
import { EquipmentService } from '../../services/equirement.service';
import { ProjectEquipmentService } from '../../services/project-equipments.service';
import { ProjectMemberService } from '../../services/project-members.service';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../../../shared/shared.module';
import { NgSelectModule } from '@ng-select/ng-select';
import { FormsModule } from '@angular/forms';
import { MatPaginator } from '@angular/material/paginator';
import swal from 'sweetalert';
import { UserRoleModel } from '../../models/user-role-model';
import { UserProfileModel } from '../../models/user.model';
import { environment } from '../../../../environments/environment';
@Component({
selector: 'app-emp-borrow-transaction',
standalone: true,
imports: [],
imports: [CommonModule,
SharedModule,
TranslateModule,
NgSelectModule,
FormsModule,
MatPaginator,
FileUploadModule],
templateUrl: './emp-borrow-transaction.component.html',
styleUrls: ['./emp-borrow-transaction.component.scss']
})
export class EmpBorrowTransactionComponent implements OnInit {
export class EmpBorrowTransactionComponent {
@ViewChild('closeModal') public childModal?: ElementRef;
@ViewChild('modalDetail') public modalDetail?: ElementRef;
action = "new";
allSelected = false;
someSelected = false;
confirmPassword = ""
itemsList: UserProfileModel[] = []
filterList: UserProfileModel[] = []
selectModel: UserProfileModel = new UserProfileModel()
selectedItems = new Map<string, boolean>();
roleList: UserRoleModel[] = []
descName = 'engName'
pageIndex = 0;
uploaderProfile: FileUploader | undefined;
uploadErrorMsg: string = "";
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this.pageIndex = 0;
this.allSelected = false
this._searchTerm = val;
if (val != '') {
this.filterList = this.filter(val);
} else {
this.updatePagedItems()
}
}
_searchTerm = "";
empList: ProjectMemberModel[] = []
hisList: BorrowTransactionsModel[] = []
constructor(private http: HttpClient, private userService: UserService, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService, private projectEquipmentService: ProjectEquipmentService, private borrowTransactionsService: BorrowTransactionsService, private projectMemberService: ProjectMemberService) {
}
// โหลดรายการเบิกอุปกรณ์
// loadBorrowTransactions(): void {
// const memberId = this.tokenService.getUser().member.memberId;
// this.borrowTransactionsService.search({memberId : memberId}).subscribe({
// next: (result: BorrowTransactionsModel[]) => {
// // กรองเฉพาะรายการของสมาชิกคนนี้
// this.hisList = result
// this.applyFilter();
// },
// error: (err) => {
// console.error('เกิดข้อผิดพลาดในการโหลดรายการเบิกอุปกรณ์:', err);
// swal("ผิดพลาด", "ไม่สามารถโหลดข้อมูลได้", "error");
// }
// });
// }
uploadConfig() {
this.uploaderProfile = new FileUploader({
url: environment.baseUrl + "/api/upload-image",
isHTML5: true,
authToken: this.tokenService.getToken()!,
});
this.uploaderProfile.onAfterAddingFile = (fileItem: FileItem) => {
fileItem.withCredentials = false;
this.uploadErrorMsg = "";
while (this.uploaderProfile!.queue.length > 1) {
this.uploaderProfile!.queue[0].remove();
}
if (fileItem.file.size > 5000000) {
this.uploadErrorMsg = "maximum file size 5mb.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
fileItem.isCancel = true;
return;
}
if (fileItem.file.type!.indexOf("image") === -1) {
this.uploadErrorMsg = "please upload image only.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
fileItem.isCancel = true;
return;
}
fileItem.upload();
};
this.uploaderProfile.onCompleteItem = (
item: FileItem,
response: string,
status: number,
headers: ParsedResponseHeaders
) => {
if (item.isSuccess) {
const res = JSON.parse(response);
console.log("res", res);
this.selectModel.picture = res.filename
swal(res.message, "บันทึกสำเร็จ", "success");
} else {
this.uploadErrorMsg = "cannot upload file.";
swal("Opp!!", "ไม่สามารถอัพโหลดได้", "info");
}
};
}
ngOnInit(): void {
this.userService.getLists().subscribe(result => {
this.itemsList = result
this.updatePagedItems()
})
}
filter(v: string) {
return this.itemsList?.filter(
(x) =>
x.memberId?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.username?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.email?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.phoneNumber?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.getRole()?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.getStatus()?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.getFullname()?.toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
delete(item: UserProfileModel) {
swal({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
dangerMode: true,
buttons: ["Cancel", "Yes,Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.userService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit()
})
}
});
}
new() {
this.action = 'add'
this.selectModel = new UserProfileModel()
}
view(item: UserProfileModel) {
this.action = 'edit'
this.confirmPassword = ''
this.selectModel = new UserProfileModel(item)
console.log(this.selectModel)
}
save() {
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
if (this.action == 'add') {
this.userService.save(this.selectModel).subscribe(result => {
console.log(result)
swal("Save Success!!", "บันทึกข้อมูลสมาชิก", "success");
this.ngOnInit()
this.childModal?.nativeElement.click()
})
} else if (this.action == 'edit') {
this.userService.update(this.selectModel).subscribe(result => {
console.log(result)
swal("Update Success!!", "บันทึกข้อมูลสมาชิก", "success");
this.ngOnInit()
this.childModal?.nativeElement.click()
})
}
constructor() { }
}
});
}
updatePagedItems() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
this.filterList = this.itemsList.slice(startIndex, endIndex);
}
toggleAll(event: any) {
this.allSelected = event.target.checked;
this.selectedItems.clear();
this.itemsList.forEach(item => {
this.selectedItems.set(item.memberId, this.allSelected);
});
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.memberId));
}
ngOnInit() {
onCheckboxChange(memberId: string) {
const isSelected = this.selectedItems.get(memberId) || false;
this.selectedItems.set(memberId, !isSelected);
this.allSelected = this.itemsList.every(item => this.selectedItems.get(item.memberId));
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.memberId));
}
deleteSelect() {
let employeeInfo = '';
this.selectedItems.forEach((isSelected, memberId) => {
if (isSelected) {
const user = this.itemsList.find(user => user.memberId === memberId);
if (user) {
employeeInfo += `${this.translate.instant('Fullname')}: ${user.getFullname()}\n`;
}
}
});
swal({
title: "Are you sure?",
text: employeeInfo,
icon: "warning",
dangerMode: true,
buttons: ["Cancel", "Yes, Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.selectedItems.forEach((isSelected, memberId) => {
if (isSelected) {
const user = this.itemsList.find(user => user.memberId === memberId);
if (user) {
this.userService.delete(user).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit();
});
}
}
});
}
});
}
adjustSelect(status: number) {
let title = "Are you sure?"
let employeeInfo = ''; // ตัวแปรสำหรับเก็บข้อมูลพนักงาน
this.selectedItems.forEach((isSelected, memberId) => {
if (isSelected) {
const user = this.itemsList.find(user => user.memberId === memberId);
if (user) {
employeeInfo += `${this.translate.instant('Fullname')}: ${user.getFullname()}\n`;
}
}
});
swal({
title: title,
text: employeeInfo,
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
this.selectedItems.forEach((isSelected, memberId) => {
if (isSelected) {
const user = this.itemsList.find(user => user.memberId === memberId);
if (user) {
user.status = status
this.userService.update(user).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit();
});
}
}
});
}
});
}
// filterEmp(empId: string) {
// this.selectModel = this.empList.filter(e => e.memberId == empId)[0]
// }
}
......@@ -35,4 +35,14 @@ export class BorrowTransactionsModel extends BaseModel {
this.approved_by_member = data?.approved_by_member ? new UserProfileModel(data.approved_by_member) : new UserProfileModel();
this.project_equipment = data?.project_equipment ? new ProjectEquipmentModel(data.project_equipment) : new ProjectEquipmentModel();
}
getStatusText(): string {
switch(this.status) {
case 'requested': return 'รออนุมัติ';
case 'approved': return 'อนุมัติแล้ว';
case 'rejected': return 'ไม่อนุมัติ';
case 'returned': return 'คืนแล้ว';
default: return this.status;
}
}
}
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