Skip to content

Commit

Permalink
Merge pull request #107 from sancsoft/102-charge-code-admin-crud
Browse files Browse the repository at this point in the history
102 charge code admin crud
  • Loading branch information
rmaffitsancsoft authored Jun 10, 2024
2 parents 6521cc1 + 7748dee commit a5ee089
Show file tree
Hide file tree
Showing 23 changed files with 1,438 additions and 24 deletions.
38 changes: 38 additions & 0 deletions src/angular/hq/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,44 @@ export const routes: Routes = [
loadComponent: () =>
import('./callback.component').then((m) => m.CallbackComponent),
},
{
path: 'chargecodes',
title: 'Charge Codes',
canActivate: [AutoLoginPartialRoutesGuard, userRoleGuard(HQRole.Administrator)],
loadComponent: () =>
import('.//charge-code/charge-code.component').then(
(m) => m.ChargeCodeComponent
),
children: [
{
path: '',
title: 'Charge Code List',
canActivate: [userRoleGuard(HQRole.Administrator)],
loadComponent: () =>
import('./charge-code/charge-code-list/charge-code-list.component').then(
(m) => m.ChargeCodeListComponent
),
},
{
path: 'create',
title: 'Charge Code Create',
canActivate: [userRoleGuard(HQRole.Administrator)],
loadComponent: () =>
import('./charge-code/charge-code-create/charge-code-create.component').then(
(m) => m.ChargeCodeCreateComponent
),
},
{
path: 'edit/:chargeCodeId',
title: 'Charge Code Edit',
canActivate: [userRoleGuard(HQRole.Administrator)],
loadComponent: () =>
import('./charge-code/charge-code-edit/charge-code-edit.component').then(
(m) => m.ChargeCodeEditComponent
),
}
]
},
{
path: 'clients',
title: 'Clients',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<div class="flex w-full flex-1 items-center gap-[20px] mb-[8px] xl:mb-0">
@if(ChargeCodeListService.showSearch$ | async) {
<!-- search bar -->
<div class="relative flex items-stretch border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px] w-full max-w-[395px]">
<span class="relative flex items-center justify-center text-center whitespace-nowrap w-[36px] hover:cursor-pointer after:block after:w-[1px] after:absolute after:right-[1px] after:top-[6px] after:bottom-[6px] after:bg-gray-100">
<i class="bi bi-search text-[14px]"></i>
</span>
<input type="text" [formControl]="ChargeCodeListService.search" class="w-[100%] block text-[14px] px-2 py-1 appearance-none focus:outline-none hover:cursor-pointer font-medium bg-inherit rounded" name="" />
</div>
} @if(ChargeCodeListService.staffMembers$ && ChargeCodeListService.showStaffMembers$ | async) {
<div class="grid relative w-full max-w-[220px]">
<select [formControl]="ChargeCodeListService.staffMember" class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]">
<option [ngValue]="null">Select Staff Member</option>
@for (staffMember of ChargeCodeListService.staffMembers$ | async; track $index)
{
<option [value]="staffMember.id">
{{ staffMember.name }}
</option>
}
</select>
<span class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100">
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div>
} @if(ChargeCodeListService.showIsSubmitted$ | async) {
<div class="grid relative w-full max-w-[220px]">
<select [formControl]="ChargeCodeListService.isSubmitted" class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]">
<option [ngValue]="null">Is Submitted?</option>

<option [ngValue]="true">
Yes
</option>
<option [ngValue]="false">
No
</option>
</select>
<span class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100">
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div>
} @if (ChargeCodeListService.showRoaster$ | async) {
<!-- <div class="relative flex items-stretch border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px] w-[205px]">
<input type="text" class="w-[100%] block text-[14px] text-center px-2 py-1 appearance-none focus:outline-none hover:cursor-pointer font-medium bg-inherit rounded" name="" value="Roster" />
</div> -->
} @if ( ChargeCodeListService.showActivityName$ | async ) {
<!-- <div class="grid relative w-[290px]">
<select class="w-[100%] pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]">
<option [value]="ChargeCodeListService.ActivityName.Development">Development</option>
<option [value]="ChargeCodeListService.ActivityName.Todo">Todo</option>
<option [value]="ChargeCodeListService.ActivityName.Support">Support</option>
</select>
<span class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100">
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div> -->
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ChargeCodeListService } from './../services/ChargeCodeListService';
import { CommonModule } from "@angular/common";
import { Component } from "@angular/core";
import { ReactiveFormsModule, FormsModule } from "@angular/forms";
import { PsrService } from "../../psr/psr-service";


@Component({
selector: 'hq-psr-search-filter',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, FormsModule],
templateUrl: './charge-code-search-filter.component.html',
})
export class ChargeCodeSearchFilterComponent {
constructor(public ChargeCodeListService: ChargeCodeListService) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="h-[calc(100dvh-106px)] fixed top-70 left-0 w-full flex flex-col">
<div class="px-5">
<h1 class="font-rajdhani font-semibold text-3xl">Create Charge Code</h1>

<div class="py-3">
<a href="/chargecodes" class="text-gray-50 underline">Charge codes List</a>
</div>
</div>

<div class="overflow-hidden flex-auto">
<div class="grid gap-0 relative">
<main class="flex flex-col bg-black-alt overflow-y-auto h-[calc(100dvh-(192px))]">
<div class="bg-black-alt border-steel-blue-600 border-t sticky top-0 flex h-[53px] z-50">
<div class="w-full flex flex-row border-b border-black justify-between pe-5">
<div class="flex pt-[23px]">
<a href="#" routerLink="projects" routerLinkActive="border-gray-100" class="w-full min-w-[107px] text-center whitespace-nowrap px-3 py-1 font-bold border-b border-gray-100 hover:border-gray-100">Details</a
>
</div>
<div class="flex flex-column justify-center items-center">
<button
type="submit"
class="h-[36px] px-2 py-2 border border-orange-500 bg-orange-500 hover:bg-orange-600 hover:border-orange-600 text-white rounded min-w-[120px]"
>
Save
</button>
</div>
</div>
</div>
<div class="grid flex-1">
<div class="p-5 pr-0">
<div class="grid gap-[20px]">
<hq-error-display [errors]="apiErrors"></hq-error-display>

<!-- row grid -->
<div
class="grid gap-[20px] grid-flow-col auto-cols-[minmax(200px,395px)] pr-5"
>
<!-- column -->
<!-- column -->
<div>
<div>Charge Code Activity</div>
<div class="grid relative w-full max-w-[220px]">
<select
formControlName="Activity"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null" selected>
Select Activity
</option>
<option [ngValue]="ChargeCodeActivity.General">
General
</option>
<option [ngValue]="ChargeCodeActivity.Project">
Project
</option>
<option [ngValue]="ChargeCodeActivity.Quote">
Quote
</option>
<option [ngValue]="ChargeCodeActivity.Service">
Service
</option>
</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div>
</div>
@if (showProjects$ | async) {
<div class="mt-4 grid relative w-full max-w-[220px]">
<select
[class.border-red-700]="form.get('ProjectId')?.touched &&
form.get('ProjectId')?.errors?.['required']"
formControlName="ProjectId"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null">Select Project</option>
@for (project of (projects$ | async); track
$index) {
<option [ngValue]="project.id">
{{ project.name }}
</option>
}

</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
@if(form.get('ProjectId')?.touched &&
form.get('ProjectId')?.errors?.['required']) {
<span class="text-red-700 text-xs leading-normal inline-block"
>Selecting Project is required.</span
>
}
</div>
}
@if (showQuotes$ | async) {
<div class="mt-4 grid relative w-full max-w-[220px]">
<select
[class.border-red-700]="form.get('QuoteId')?.touched &&
form.get('QuoteId')?.errors?.['required']"
formControlName="QuoteId"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null">Select Quote</option>
@for (quote of (quotes$ | async); track
$index) {
<option [ngValue]="quote.id">
{{ quote.name }}
</option>
}
</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
@if(form.get('QuoteId')?.touched &&
form.get('QuoteId')?.errors?.['required']) {
<span class="text-red-700 text-xs leading-normal inline-block"
>Selecting Quote is required.</span
>
}
</div>
}
@if (showServices$ | async) {
<div class="mt-4 grid relative w-full max-w-[220px]">
<select
[class.border-red-700]="form.get('ServiceAgreementId')?.touched &&
form.get('ServiceAgreementId')?.errors?.['required']"
formControlName="ServiceAgreementId"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null">Select Service Agreement</option>
@for (service of (services$ | async); track
$index) {
<option [ngValue]="service.id">
{{ service.name }}
</option>
}
</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
@if(form.get('ServiceAgreementId')?.touched &&
form.get('ServiceAgreementId')?.errors?.['required']) {
<span class="text-red-700 text-xs leading-normal inline-block"
>Selecting Service Agreement is required.</span
>
}
</div>
}

<!-- column -->
</div>
<!-- row grid -->
<div
class="grid gap-[20px] grid-flow-col grid-cols-[395px_minmax(200px,395px)] pr-5"
>
<!-- column -->
<div>
<div class="grid relative w-full max-w-[220px]">
<select
formControlName="Billable"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null" selected>
Billable?
</option>
<option [ngValue]="true">
Yes
</option>
<option [ngValue]="false">
No
</option>
</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div>
</div>
<div>
<div class="grid relative w-full max-w-[220px]">
<select
formControlName="Active"
class="w-full pl-2 pr-[43px] appearance-none focus:outline-none hover:cursor-pointer font-medium row-start-1 col-start-1 border border-steel-blue-600 text-gray-100 bg-blue-900 rounded h-[36px]"
>
<option [ngValue]="null" selected>
Active?
</option>
<option [ngValue]="true">
Yes
</option>
<option [ngValue]="false">
No
</option>
</select>
<span
class="flex items-center justify-center h-full pointer-events-none z-10 right-0 relative col-start-1 row-start-1 self-center justify-self-end w-[36px] after:block after:w-[1px] after:absolute after:left-[1px] after:top-[7px] after:bottom-[7px] after:bg-gray-100"
>
<i class="bi bi-arrow-down-short text-[24px]"></i>
</span>
</div>
</div>
<div>
<!-- text input -->
<input
[class.border-red-700]="form.get('Description')?.touched &&
form.get('Description')?.errors?.['required']"
type="text"
name="Description"
id="Description"
class="w-[100%] max-w-[395px] block text-[14px] px-2 py-1 border border-black appearance-none focus:outline-none placeholder:text-gray-100 bg-blue-900 rounded h-[36px]"
placeholder="Enter Description"
formControlName="Description"
/>
@if(form.get('Description')?.touched &&
form.get('Description')?.errors?.['required']) {
<span
class="text-red-700 text-xs leading-normal inline-block"
>Description is required.</span
>
}
</div>
</div>

</div>
</div>
</div>
</main>
</div>
</div>
</div>

</form>
Loading

0 comments on commit a5ee089

Please sign in to comment.