Commit d2625cfd by Ooh-Ao

projectEmp

parent 6abfc78e
# myproject/controllers/project_member_controller.py
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import selectinload
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from uuid import UUID from uuid import UUID
...@@ -25,15 +24,17 @@ async def create_project_member(db: AsyncSession, pm_in: ProjectMemberCreate): ...@@ -25,15 +24,17 @@ async def create_project_member(db: AsyncSession, pm_in: ProjectMemberCreate):
raise HTTPException(status_code=400, detail=str(e.orig)) raise HTTPException(status_code=400, detail=str(e.orig))
return new_pm return new_pm
# READ ALL # READ ALL (โหลดข้อมูลของ Project ด้วย)
async def get_all_project_members(db: AsyncSession): async def get_all_project_members(db: AsyncSession):
result = await db.execute(select(ProjectMember)) stmt = select(ProjectMember).options(selectinload(ProjectMember.project))
result = await db.execute(stmt)
return result.scalars().all() return result.scalars().all()
# READ ONE # READ ONE (โหลดข้อมูลของ Project ด้วย)
async def get_project_member_by_id(db: AsyncSession, pm_id: UUID): async def get_project_member_by_id(db: AsyncSession, pm_id: UUID):
pm_db = await db.get(ProjectMember, pm_id) stmt = select(ProjectMember).options(selectinload(ProjectMember.project)).where(ProjectMember.pmId == pm_id)
return pm_db result = await db.execute(stmt)
return result.scalar_one_or_none()
# UPDATE # UPDATE
async def update_project_member(db: AsyncSession, pm_id: UUID, pm_in: ProjectMemberCreate): async def update_project_member(db: AsyncSession, pm_id: UUID, pm_in: ProjectMemberCreate):
...@@ -72,8 +73,8 @@ async def delete_project_member(db: AsyncSession, pm_id: UUID): ...@@ -72,8 +73,8 @@ async def delete_project_member(db: AsyncSession, pm_id: UUID):
return {"message": "ProjectMember deleted successfully"} return {"message": "ProjectMember deleted successfully"}
# READ Projects by MemberId # READ Projects by MemberId (โหลดข้อมูล Project ที่สัมพันธ์กับ ProjectMember ด้วย)
async def get_projects_by_member_id(db: AsyncSession, member_id: UUID): async def get_projects_by_member_id(db: AsyncSession, member_id: UUID):
stmt = select(ProjectMember).where(ProjectMember.memberId == member_id) stmt = select(ProjectMember).options(selectinload(ProjectMember.project)).where(ProjectMember.memberId == member_id)
result = await db.execute(stmt) result = await db.execute(stmt)
return result.scalars().all() return result.scalars().all()
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from pydantic import BaseModel from pydantic import BaseModel
from typing import Optional from typing import Optional
from uuid import UUID from uuid import UUID
from .project_schema import ProjectResponse # Import schema ของ Project
class ProjectMemberBase(BaseModel): class ProjectMemberBase(BaseModel):
memberId: UUID memberId: UUID
...@@ -11,12 +12,10 @@ class ProjectMemberBase(BaseModel): ...@@ -11,12 +12,10 @@ class ProjectMemberBase(BaseModel):
class ProjectMemberCreate(ProjectMemberBase): class ProjectMemberCreate(ProjectMemberBase):
projectId: UUID projectId: UUID
class ProjectMemberResponse(ProjectMemberBase): class ProjectMemberResponse(ProjectMemberBase):
pmId: UUID pmId: UUID
projectId: UUID projectId: UUID
project: Optional[ProjectResponse] = None # เพิ่ม field นี้เพื่อแสดงข้อมูลของ Project
class Config: class Config:
orm_mode = True orm_mode = True
...@@ -58,12 +58,12 @@ export class AdminManageComponent { ...@@ -58,12 +58,12 @@ export class AdminManageComponent {
this.updatePagedItems() this.updatePagedItems()
} }
} }
companyId = "" projectId = ""
_searchTerm = ""; _searchTerm = "";
isEdit = false; isEdit = false;
constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService) { constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService) {
this.uploadConfig() this.uploadConfig()
this.companyId = this.tokenService.getSelectCompany().companyId; this.projectId = this.tokenService.getSelectCompany().projectId!;
} }
@ViewChild('video') video: ElementRef; @ViewChild('video') video: ElementRef;
......
...@@ -31,16 +31,6 @@ export const admin: Routes = [ ...@@ -31,16 +31,6 @@ export const admin: Routes = [
}, },
//////////////emp///////////////// //////////////emp/////////////////
{ {
path: 'emp/department',
loadComponent: () =>
import('./employee/department/department.component').then((m) => m.DepartmentComponent),
},
{
path: 'emp/position',
loadComponent: () =>
import('./employee/position/position.component').then((m) => m.PositionComponent),
},
{
path: 'borrow-management', path: 'borrow-management',
loadComponent: () => loadComponent: () =>
import('./borrow-management/borrow-management.component').then((m) => m.BorrowManagementComponent), import('./borrow-management/borrow-management.component').then((m) => m.BorrowManagementComponent),
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
<i class="fe fe-more-vertical"></i> <i class="fe fe-more-vertical"></i>
</a> </a>
<ul class="hs-dropdown-menu ti-dropdown-menu hidden"> <ul class="hs-dropdown-menu ti-dropdown-menu hidden">
<li><a class="ti-dropdown-item" routerLink="/admin/manage-companys/{{item.projectId}}"><i <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> 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 <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> class="ri-edit-line align-middle me-1 inline-flex"></i>Edit</a></li>
......
<app-page-header [title]="'Department'" [activeTitle]="'จัดการบริษัท'" [title1]="'Department'"></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-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="{{ 'Search' | translate}}"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div>
</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">{{ 'ID' | translate}}</th>
<th scope="col" class="text-start">{{ 'ชื่อแผนก' | 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.departmentId)" (change)="onCheckboxChange(item.departmentId)"
aria-label="..." value="">
</td>
<td><span class="font-semibold text-primary">{{item.departmentId}}</span></td>
<td> {{item.thName}}</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 }} {{ 'Department' | 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-6 col-span-12">
<label for="contact-lead-score" class="form-label">{{'Name (TH)' | translate}}</label>
<input type="text" class="form-control" id="contact-lead-score" placeholder=""
[(ngModel)]="selectModel.thName">
<div class="text-danger" *ngIf="!selectModel.thName">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="contact-mail" class="form-label">{{'Name (EN)' | translate}}</label>
<input type="text" class="form-control" id="contact-mail" placeholder="" [(ngModel)]="selectModel.engName">
<div class="text-danger" *ngIf="!selectModel.engName">
{{'Please fill in information' | translate}}
</div>
</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" [disabled]="!selectModel.thName || !selectModel.engName"
class="ti-btn bg-primary text-white !font-medium {{!selectModel.thName || !selectModel.engName ? 'ti-btn-disabled' : ''}}"
(click)="save()">{{'Save' |
translate}}</button>
</div>
</div>
</div>
</div>
<!-- End:: Create Contact -->
import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core';
import { NgSelectModule } from "@ng-select/ng-select";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { SharedModule } from "../../../../shared/shared.module";
import { DepartmentService } from "../../../services/department.service";
import { DepartmentModel } from "../../../models/department.model";
import { FormsModule } from "@angular/forms";
import swal from 'sweetalert';
import { MatPaginator, PageEvent } from "@angular/material/paginator";
import { ActivatedRoute } from "@angular/router";
import { TokenService } from "../../../../shared/services/token.service";
@Component({
selector: 'app-department',
standalone: true,
imports: [
CommonModule,
SharedModule,
TranslateModule,
NgSelectModule,
FormsModule,
MatPaginator
],
templateUrl: './department.component.html',
styleUrl: './department.component.css'
})
export class DepartmentComponent {
@ViewChild('closeModal') public childModal?: ElementRef;
@ViewChild('modalDetail') public modalDetail?: ElementRef;
allSelected = false;
someSelected = false;
companyId = ""
itemsList: DepartmentModel[] = []
filterList: DepartmentModel[] = [];
selectModel: DepartmentModel = new DepartmentModel()
selectedItems = new Map<string, boolean>();
pageIndex = 0;
isEdit = false;
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 departmentService: DepartmentService, private tokenService: TokenService, public translate: TranslateService) {
this.companyId = this.tokenService.getSelectCompany().companyId;;
this.getDepartment()
}
getDepartment() {
this.departmentService.getLists(this.companyId).subscribe(result => {
this.itemsList = result
this.updatePagedItems()
})
}
filter(v: string) {
this.pageIndex = 0;
return this.itemsList?.filter(
(x) =>
x.departmentId?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.thName?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.engName?.toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
delete(item: DepartmentModel) {
swal({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
timer: 1000,
dangerMode: true,
buttons: ["Cancel", "Yes,Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.departmentService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getDepartment()
})
}
});
}
new() {
this.isEdit = false
this.selectModel = new DepartmentModel()
}
view(item: DepartmentModel) {
this.isEdit = true;
this.selectModel = new DepartmentModel(item)
}
save() {
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
this.selectModel.companyId = this.companyId
if (!this.isEdit) {
this.departmentService.save(this.selectModel).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getDepartment()
this.childModal?.nativeElement.click()
})
} else {
this.departmentService.update(this.selectModel).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getDepartment()
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.departmentId, this.allSelected);
});
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.departmentId));
}
onCheckboxChange(departmentId: string) {
const isSelected = this.selectedItems.get(departmentId) || false;
this.selectedItems.set(departmentId, !isSelected);
this.allSelected = this.itemsList.every(item => this.selectedItems.get(item.departmentId));
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.departmentId));
}
deleteSelect() {
let employeeInfo = '';
this.selectedItems.forEach((isSelected, departmentId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.departmentId === departmentId);
if (item) {
employeeInfo += `${this.translate.instant('ชื่อตำแหน่ง')}: ${item.getName()}\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, departmentId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.departmentId === departmentId);
if (item) {
this.departmentService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getDepartment();
});
}
}
});
}
});
}
}
<app-page-header [title]="'Position'" [activeTitle]="'จัดการบริษัท'" [title1]="'Position'"></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-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="{{ 'Search' | translate}}"
aria-label=".form-control-sm example" [(ngModel)]='searchTerm'>
</div>
</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">{{ 'ID' | translate}}</th>
<th scope="col" class="text-start">{{ 'ชื่อตำแหน่ง' | translate}}</th>
<!-- <th scope="col" class="text-start">{{ 'Name (EN)' | 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.positionId)" (change)="onCheckboxChange(item.positionId)"
aria-label="..." value="">
</td>
<td><span class="font-semibold text-primary">{{item.positionId}}</span></td>
<td> {{item.thName}}</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 }} {{ 'Position' | 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">
<label for="deal-title" class="form-label">{{'ID' | translate}}</label>
<input type="text" class="form-control" id="deal-title" placeholder="" [(ngModel)]="selectModel.positionId">
<div class="text-danger" *ngIf="!selectModel.positionId">
{{'Please fill in information' | translate}}
</div>
</div> -->
<div class="xl:col-span-6 col-span-12">
<label for="contact-lead-score" class="form-label">{{'Name (TH)' | translate}}</label>
<input type="text" class="form-control" id="contact-lead-score" placeholder=""
[(ngModel)]="selectModel.thName">
<div class="text-danger" *ngIf="!selectModel.thName">
{{'Please fill in information' | translate}}
</div>
</div>
<div class="xl:col-span-6 col-span-12">
<label for="contact-mail" class="form-label">{{'Name (EN)' | translate}}</label>
<input type="text" class="form-control" id="contact-mail" placeholder="" [(ngModel)]="selectModel.engName">
<div class="text-danger" *ngIf="!selectModel.engName">
{{'Please fill in information' | translate}}
</div>
</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" [disabled]="!selectModel.thName || !selectModel.engName"
class="ti-btn bg-primary text-white !font-medium {{!selectModel.thName || !selectModel.engName ? 'ti-btn-disabled' : ''}}"
(click)="save()">{{'Save' |
translate}}</button>
</div>
</div>
</div>
</div>
<!-- End:: Create Contact -->
import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core';
import { NgSelectModule } from "@ng-select/ng-select";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { SharedModule } from "../../../../shared/shared.module";
import { PositionService } from "../../../services/position.service";
import { PositionModel } from "../../../models/position.model";
import { FormsModule } from "@angular/forms";
import swal from 'sweetalert';
import { MatPaginator, PageEvent } from "@angular/material/paginator";
import { ActivatedRoute } from "@angular/router";
import { TokenService } from "../../../../shared/services/token.service";
@Component({
selector: 'app-position',
standalone: true,
imports: [
CommonModule,
SharedModule,
TranslateModule,
NgSelectModule,
FormsModule,
MatPaginator
],
templateUrl: './position.component.html',
styleUrl: './position.component.css'
})
export class PositionComponent {
@ViewChild('closeModal') public childModal?: ElementRef;
@ViewChild('modalDetail') public modalDetail?: ElementRef;
allSelected = false;
someSelected = false;
companyId = ""
itemsList: PositionModel[] = []
filterList: PositionModel[] = [];
selectModel: PositionModel = new PositionModel()
selectedItems = new Map<string, boolean>();
pageIndex = 0;
isEdit = false;
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 positionService: PositionService, private tokenService: TokenService, public translate: TranslateService) {
this.companyId = this.tokenService.getSelectCompany().companyId;;
this.getPosition()
}
ngOnInit(): void {
}
getPosition() {
this.positionService.getLists(this.companyId).subscribe(result => {
this.itemsList = result
this.updatePagedItems()
})
}
filter(v: string) {
this.pageIndex = 0;
return this.itemsList?.filter(
(x) =>
x.positionId?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.thName?.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.engName?.toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
delete(item: PositionModel) {
swal({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
timer: 1000,
dangerMode: true,
buttons: ["Cancel", "Yes,Delete it!"],
})
.then((willDelete: any) => {
if (willDelete) {
this.positionService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getPosition()
})
}
});
}
new() {
this.isEdit = false
this.selectModel = new PositionModel()
}
view(item: PositionModel) {
this.isEdit = true;
this.selectModel = new PositionModel(item)
}
save() {
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
this.selectModel.companyId = this.companyId
if (!this.isEdit) {
this.positionService.save(this.selectModel).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getPosition()
this.getPosition()
this.childModal?.nativeElement.click()
})
} else {
this.positionService.update(this.selectModel).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getPosition()
this.getPosition()
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.positionId, this.allSelected);
});
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.positionId));
}
onCheckboxChange(positionId: string) {
const isSelected = this.selectedItems.get(positionId) || false;
this.selectedItems.set(positionId, !isSelected);
this.allSelected = this.itemsList.every(item => this.selectedItems.get(item.positionId));
this.someSelected = this.itemsList.some(item => this.selectedItems.get(item.positionId));
}
deleteSelect() {
let employeeInfo = '';
this.selectedItems.forEach((isSelected, positionId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.positionId === positionId);
if (item) {
employeeInfo += `${this.translate.instant('ชื่อตำแหน่ง')}: ${item.getName()}\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, positionId) => {
if (isSelected) {
const item = this.itemsList.find(item => item.positionId === positionId);
if (item) {
this.positionService.delete(item).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getPosition();
});
}
}
});
}
});
}
}
...@@ -57,12 +57,12 @@ export class AdminProjectEquirementComponent { ...@@ -57,12 +57,12 @@ export class AdminProjectEquirementComponent {
this.updatePagedItems() this.updatePagedItems()
} }
} }
companyId = "" projectId = ""
_searchTerm = ""; _searchTerm = "";
isEdit = false; isEdit = false;
constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService) { constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService) {
this.uploadConfig() this.uploadConfig()
this.companyId = this.tokenService.getSelectCompany().companyId; this.projectId = this.tokenService.getSelectCompany().projectId!;
} }
@ViewChild('video') video: ElementRef; @ViewChild('video') video: ElementRef;
......
...@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; ...@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { TokenService } from '../../shared/services/token.service'; import { TokenService } from '../../shared/services/token.service';
import { CompanyService } from '../services/company.service'; import { CompanyService } from '../services/company.service';
import { ProjectService } from '../services/project.service';
@Component({ @Component({
selector: 'app-company-management', selector: 'app-company-management',
...@@ -9,16 +10,17 @@ import { CompanyService } from '../services/company.service'; ...@@ -9,16 +10,17 @@ import { CompanyService } from '../services/company.service';
styleUrls: ['./company-management.component.css'] styleUrls: ['./company-management.component.css']
}) })
export class InstallManagementComponent implements OnInit { export class InstallManagementComponent implements OnInit {
companyId = "" projectId = ""
constructor(private router: Router, private route: ActivatedRoute, private comService: CompanyService, private tokenService: TokenService) { constructor(private router: Router, private route: ActivatedRoute, private projectService: ProjectService, private tokenService: TokenService) {
} }
ngOnInit() { ngOnInit() {
this.companyId = this.route.snapshot.paramMap.get('companyId')!; this.projectId = this.route.snapshot.paramMap.get('projectId')!;
this.comService.getById(this.companyId).subscribe(result => { this.projectService.getById(this.projectId).subscribe(result => {
console.log("SAVEEE")
this.tokenService.saveSelectCompany(result); this.tokenService.saveSelectCompany(result);
// this.router.navigate(["/company",""]); // this.router.navigate(["/company"]);
}) })
} }
} }
...@@ -6,7 +6,7 @@ import { RouterModule, Routes } from '@angular/router'; ...@@ -6,7 +6,7 @@ import { RouterModule, Routes } from '@angular/router';
export const companyRoutes: Routes = [ export const companyRoutes: Routes = [
{ {
path: 'company/home/:companyId', path: 'company/home/:projectId',
loadComponent: () => loadComponent: () =>
import('./home-installer/home-installer.component').then((m) => m.HomeInstallerComponent), import('./home-installer/home-installer.component').then((m) => m.HomeInstallerComponent),
}, },
......
...@@ -6,6 +6,7 @@ import { TranslateModule } from '@ngx-translate/core'; ...@@ -6,6 +6,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { CompanyService } from '../../services/company.service'; import { CompanyService } from '../../services/company.service';
import { TokenService } from '../../../shared/services/token.service'; import { TokenService } from '../../../shared/services/token.service';
import { ProjectService } from '../../services/project.service';
@Component({ @Component({
selector: 'app-home-installer', selector: 'app-home-installer',
...@@ -15,10 +16,10 @@ import { TokenService } from '../../../shared/services/token.service'; ...@@ -15,10 +16,10 @@ import { TokenService } from '../../../shared/services/token.service';
styleUrls: ['./home-installer.component.css'] styleUrls: ['./home-installer.component.css']
}) })
export class HomeInstallerComponent implements OnInit { export class HomeInstallerComponent implements OnInit {
companyId = "" projectId = ""
constructor(private router: Router, private route: ActivatedRoute, private comService: CompanyService, private tokenService: TokenService) { constructor(private router: Router, private route: ActivatedRoute, private projectService: ProjectService, private tokenService: TokenService) {
this.companyId = this.route.snapshot.paramMap.get('companyId')!; this.projectId = this.route.snapshot.paramMap.get('projectId')!;
this.comService.getById(this.companyId).subscribe(result => { this.projectService.getById(this.projectId).subscribe(result => {
console.log("SAVEEE") console.log("SAVEEE")
this.tokenService.saveSelectCompany(result); this.tokenService.saveSelectCompany(result);
// this.router.navigate(["/company"]); // this.router.navigate(["/company"]);
......
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
<img [src]="tokenService.getSelectCompany().getPicture()" alt=""> <img [src]="tokenService.getSelectCompany().getPicture()" alt="">
</span> </span>
<div class="ms-2"> <div class="ms-2">
<h5 class="font-semibold mb-0 flex items-center"><a>{{tokenService.getSelectCompany().companyName}} <i <h5 class="font-semibold mb-0 flex items-center"><a>{{tokenService.getSelectCompany().project_name}} <i
class="bi bi-check-circle-fill text-success text-base" title="Verified company"></i></a></h5> class="bi bi-check-circle-fill text-success text-base" title="Verified company"></i></a></h5>
<div class="flex gap-2"> <div class="flex gap-2">
<p class="mb-0 text-[#8c9097] dark:text-white/50">{{tokenService.getSelectCompany().companyCode}} <p class="mb-0 text-[#8c9097] dark:text-white/50">{{tokenService.getSelectCompany().project_code}}
</p> </p>
</div> </div>
</div> </div>
......
...@@ -170,7 +170,7 @@ export class SidebarComponent { ...@@ -170,7 +170,7 @@ export class SidebarComponent {
changeMenu() { changeMenu() {
if (this.isInstallerRoute) { if (this.isInstallerRoute) {
if(this.tokenService.getUser().member.role==1){ if(this.tokenService.getUser().member.role==1 || this.tokenService.getUser().member.role==99){
this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => { this.menuitemsSubscribe$ = this.navServices.items.subscribe((items) => {
this.menuItems = this.navServices.getProjectAdminMenu(); this.menuItems = this.navServices.getProjectAdminMenu();
}); });
......
...@@ -5,6 +5,7 @@ import { jwtDecode } from "jwt-decode"; ...@@ -5,6 +5,7 @@ import { jwtDecode } from "jwt-decode";
import { ProfileModel, UserModel } from "../user-auth.model"; import { ProfileModel, UserModel } from "../user-auth.model";
import { UserProfileModel } from "../../DPU/models/user.model"; import { UserProfileModel } from "../../DPU/models/user.model";
import { CompanyModel } from "../../DPU/models/company.model"; import { CompanyModel } from "../../DPU/models/company.model";
import { ProjectModel } from "../../DPU/models/project.model";
// import jwt_decode from "jwt-decode"; // import jwt_decode from "jwt-decode";
const TOKEN_KEY = 'auth-token'; const TOKEN_KEY = 'auth-token';
...@@ -77,17 +78,17 @@ export class TokenService { ...@@ -77,17 +78,17 @@ export class TokenService {
return new UserProfileModel(); return new UserProfileModel();
} }
public saveSelectCompany(company: CompanyModel): void { public saveSelectCompany(company: ProjectModel): void {
window.localStorage.removeItem(COMPANY); window.localStorage.removeItem(COMPANY);
window.localStorage.setItem(COMPANY, JSON.stringify(new CompanyModel(company))); window.localStorage.setItem(COMPANY, JSON.stringify(new ProjectModel(company)));
} }
public getSelectCompany(): CompanyModel { public getSelectCompany(): ProjectModel {
const company = window.localStorage.getItem(COMPANY); const company = window.localStorage.getItem(COMPANY);
if (company) { if (company) {
return new CompanyModel(JSON.parse(company)); return new ProjectModel(JSON.parse(company));
} }
return new CompanyModel(); return new ProjectModel();
} }
} }
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