-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
909292b
commit 182a513
Showing
12 changed files
with
471 additions
and
28 deletions.
There are no files selected for viewing
15 changes: 12 additions & 3 deletions
15
src/components/request-vacation-popup/request-vacation-popup.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
src/components/vacation-list-popup/vacation-list-popup.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
<div class="flex flex-col" cdkDrag cdkDragRootElement=".cdk-overlay-pane"> | ||
<!-- Dialog Header --> | ||
<div class="bg-primary text-white p-4"> | ||
<span class="text-lg">{{ lang.locals.vacations_list }}</span> | ||
<button type="button" cdkDragHandle> | ||
<svg width="24px" class="absolute cursor-move top-1 left-1 mt-4 ml-4" fill="currentColor" viewBox="0 0 24 24"> | ||
<path | ||
d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path> | ||
<path d="M0 0h24v24H0z" fill="none"></path> | ||
</svg> | ||
</button> | ||
</div> | ||
|
||
<div #vacationWrapper class="relative max-h-96"> | ||
<table class="min-w-full border-collapse"> | ||
<!-- Sticky Header --> | ||
<thead class="bg-primary text-white text-center sticky top-0 z-10"> | ||
<tr> | ||
<th class="px-4 py-2">{{ lang.locals.employee_name }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.manager_name }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.department }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.start_date }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.end_date }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.total_days }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.status }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.comments }}</th> | ||
<th class="px-4 py-2">{{ lang.locals.actions }}</th> | ||
</tr> | ||
</thead> | ||
|
||
<!-- Table Body --> | ||
<tbody class="text-center"> | ||
@for (vacation of data; track $index) { | ||
<tr> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Employee_Name }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Employee_Name }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Manager_Name }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Manager_Name }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Department }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Department }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Start_Date | date: 'short' }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Start_Date | date: 'short' }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.End_Date | date: 'short' }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.End_Date | date: 'short' }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Total_Days }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Total_Days }} | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
[matTooltip]="getStatus(vacation)" | ||
matTooltipPosition="above"> | ||
<span | ||
[ngClass]="{ | ||
'bg-green-500': isApproved(vacation), | ||
'bg-red-500': isRejected(vacation), | ||
'bg-yellow-500': isPending(vacation), | ||
}" | ||
class="p-1 text-xs text-white rounded-md lowercase" | ||
>{{ getStatus(vacation) }}</span | ||
> | ||
</td> | ||
<td | ||
class="px-4 py-2 border-b truncate break-words max-w-40" | ||
matTooltip="{{ vacation.Comments }}" | ||
matTooltipPosition="above"> | ||
{{ vacation.Comments }} | ||
</td> | ||
<td class="px-4 py-2 border-b text-center flex justify-center items-center gap-4"> | ||
@if (!isApproved(vacation)) { | ||
<button | ||
type="button" | ||
(click)="approveVacation(vacation)" | ||
class="size-8 bg-green-500 hover:bg-green-600 disabled:bg-green-300 text-white rounded-full flex items-center justify-center" | ||
[matTooltip]="lang.locals.approved" | ||
matTooltipPosition="above"> | ||
<svg fill="currentColor" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> | ||
<path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" /> | ||
</svg> | ||
</button> | ||
} | ||
@if (!isRejected(vacation)) { | ||
<button | ||
type="button" | ||
(click)="rejectVacation(vacation)" | ||
class="size-8 bg-red-500 hover:bg-red-600 disabled:bg-red-300 text-white rounded-full flex items-center justify-center" | ||
[matTooltip]="lang.locals.rejected" | ||
matTooltipPosition="above"> | ||
<svg fill="currentColor" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> | ||
<path | ||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" /> | ||
</svg> | ||
</button> | ||
} | ||
@if (!isPending(vacation)) { | ||
<button | ||
type="button" | ||
(click)="pendingVacation(vacation)" | ||
class="size-8 bg-yellow-500 hover:bg-yellow-600 disabled:bg-yellow-300 text-white rounded-full flex items-center justify-center" | ||
[matTooltip]="lang.locals.pending" | ||
matTooltipPosition="above"> | ||
<svg fill="currentColor" class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> | ||
<path | ||
d="M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z" /> | ||
</svg> | ||
</button> | ||
} | ||
</td> | ||
</tr> | ||
} | ||
</tbody> | ||
</table> | ||
</div> | ||
<!-- Table Wrapper --> | ||
</div> |
Empty file.
87 changes: 87 additions & 0 deletions
87
src/components/vacation-list-popup/vacation-list-popup.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { ChatActionResultContract } from '@/contracts/chat-action-result-contract' | ||
import { VacationResultContract } from '@/contracts/vacation-result-contract' | ||
import { VacationStatus } from '@/enums/vacation-status' | ||
import { OnDestroyMixin } from '@/mixins/on-destroy-mixin' | ||
import { InteractiveChatService } from '@/services/interactive-chat.service' | ||
import { LocalService } from '@/services/local.service' | ||
import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop' | ||
import { DatePipe, NgClass } from '@angular/common' | ||
import { Component, effect, ElementRef, inject, viewChild } from '@angular/core' | ||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog' | ||
import { MatTooltipModule } from '@angular/material/tooltip' | ||
import PerfectScrollbar from 'perfect-scrollbar' | ||
import { takeUntil, tap } from 'rxjs' | ||
|
||
@Component({ | ||
selector: 'app-vacation-list-popup', | ||
standalone: true, | ||
imports: [MatTooltipModule, DatePipe, CdkDrag, CdkDragHandle, MatDialogModule, NgClass], | ||
templateUrl: './vacation-list-popup.component.html', | ||
styleUrl: './vacation-list-popup.component.scss', | ||
}) | ||
export class VacationListPopupComponent extends OnDestroyMixin(class {}) { | ||
vacationWrapper = viewChild<ElementRef<HTMLDivElement>>('vacationWrapper') | ||
lang = inject(LocalService) | ||
data = inject<VacationResultContract[]>(MAT_DIALOG_DATA) | ||
ref = inject(MatDialogRef) | ||
interactiveChatService = inject(InteractiveChatService) | ||
declare scrollbarRef: PerfectScrollbar | ||
|
||
chatBodyContainerEffect = effect(() => { | ||
if (this.vacationWrapper()) { | ||
this.scrollbarRef = new PerfectScrollbar(this.vacationWrapper()!.nativeElement, { suppressScrollX: true }) | ||
} else { | ||
this.scrollbarRef && this.scrollbarRef.destroy() | ||
} | ||
}) | ||
|
||
isPending(element: VacationResultContract) { | ||
return element.Status === VacationStatus.PENDING | ||
} | ||
isApproved(element: VacationResultContract) { | ||
return element.Status === VacationStatus.APPROVED | ||
} | ||
isRejected(element: VacationResultContract) { | ||
return element.Status === VacationStatus.REJECTED | ||
} | ||
getStatus(element: VacationResultContract) { | ||
if (element.Status === VacationStatus.PENDING) return this.lang.locals.pending | ||
else if (element.Status === VacationStatus.APPROVED) return this.lang.locals.approved | ||
else return this.lang.locals.rejected | ||
} | ||
|
||
approveVacation(element: VacationResultContract) { | ||
this.interactiveChatService | ||
.approveVacation({ employee_ID: element.Employee_ID }) | ||
.pipe(takeUntil(this.destroy$)) | ||
.pipe(tap(res => this.handelVacationStatus(res, element.Employee_ID, VacationStatus.APPROVED))) | ||
.subscribe() | ||
} | ||
rejectVacation(element: VacationResultContract) { | ||
this.interactiveChatService | ||
.rejectVacation({ employee_ID: element.Employee_ID }) | ||
.pipe(takeUntil(this.destroy$)) | ||
.pipe(tap(res => this.handelVacationStatus(res, element.Employee_ID, VacationStatus.REJECTED))) | ||
.subscribe() | ||
} | ||
pendingVacation(element: VacationResultContract) { | ||
this.interactiveChatService | ||
.pendingVacation({ employee_ID: element.Employee_ID }) | ||
.pipe(takeUntil(this.destroy$)) | ||
.pipe(tap(res => this.handelVacationStatus(res, element.Employee_ID, VacationStatus.PENDING))) | ||
.subscribe() | ||
} | ||
|
||
changeStatus(elementId: number, status: VacationStatus) { | ||
const vacation = this.data.find(el => el.Employee_ID === elementId) | ||
if (vacation) { | ||
vacation.Status = status | ||
} | ||
} | ||
|
||
handelVacationStatus(res: ChatActionResultContract<string>, employeeId: number, status: VacationStatus) { | ||
if (res.status_code === 200) { | ||
this.changeStatus(employeeId, status) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { ChatMessageResultContract } from './chat-message-result-contract' | ||
|
||
export interface ChatActionResultContract<TActionResult = unknown> { | ||
status_code: number | ||
status: string | ||
message: string | ||
data: Data<TActionResult> | ||
} | ||
|
||
export interface Data<TActionResult> { | ||
action_results: TActionResult | ||
final_message: ChatMessageResultContract | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { VacationStatus } from '@/enums/vacation-status' | ||
|
||
export interface VacationResultContract { | ||
PartitionKey: string | ||
RowKey: string | ||
Vacation_Type: string | ||
Employee_ID: number | ||
Employee_Name: string | ||
Manager_Name: string | ||
Department: string | ||
Start_Date: Date | string | ||
End_Date: Date | string | ||
Total_Days: number | ||
Status: VacationStatus | ||
Comments: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export enum VacationStatus { | ||
APPROVED = 0, | ||
REJECTED = 1, | ||
PENDING = 2, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.