From e56133eff24e85af3197b69b5b0335ff334236f2 Mon Sep 17 00:00:00 2001 From: amrmahdyy Date: Fri, 9 Aug 2024 13:09:30 -0400 Subject: [PATCH 1/5] Added month for staff dashboard UI --- .../staff-dashboard-search-filter.component.html | 2 ++ .../hq/src/app/staff-dashboard/staff-dashboard.component.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html index bb36cd68..284396bc 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html @@ -44,6 +44,8 @@ > + + From e92fe2027f7c266a0a3fd75a67be8f3cc592f5ea Mon Sep 17 00:00:00 2001 From: amrmahdyy Date: Fri, 27 Sep 2024 12:03:50 -0400 Subject: [PATCH 2/5] Added View by month logic in server side --- .../service/staff-dashboard.service.ts | 12 +- .../staff-dashboard-month-view.component.html | 112 ++++++++++ .../staff-dashboard-month-view.component.ts | 78 +++++++ ...aff-dashboard-search-filter.component.html | 2 - .../staff-dashboard-time-entry.component.html | 2 +- .../staff-dashboard-time-entry.component.ts | 5 +- .../staff-dashboard.component.html | 208 ++++++++++-------- .../staff-dashboard.component.ts | 2 + .../Times/GetDashboardTimeV1.cs | 9 + .../HQ.Server/Services/TimeEntryServiceV1.cs | 112 +++++++--- 10 files changed, 404 insertions(+), 138 deletions(-) create mode 100644 src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.html create mode 100644 src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts diff --git a/src/angular/hq/src/app/staff-dashboard/service/staff-dashboard.service.ts b/src/angular/hq/src/app/staff-dashboard/service/staff-dashboard.service.ts index 8eb0b93a..a2e50250 100644 --- a/src/angular/hq/src/app/staff-dashboard/service/staff-dashboard.service.ts +++ b/src/angular/hq/src/app/staff-dashboard/service/staff-dashboard.service.ts @@ -1,3 +1,4 @@ +import { SortColumn } from './../../models/times/get-time-v1'; import { Injectable, OnDestroy } from '@angular/core'; import { FormControl } from '@angular/forms'; import { HQService } from '../../services/hq.service'; @@ -26,9 +27,10 @@ import { Period } from '../../enums/period'; import { HQRole } from '../../enums/hqrole'; import { GetChargeCodeRecordV1, - SortColumn, + SortColumn as ChargeCodeSortColumn, } from '../../models/charge-codes/get-chargecodes-v1'; import { GetProjectActivityRecordV1 } from '../../models/projects/get-project-activity-v1'; +import { SortDirection } from '../../models/common/sort-direction'; @Injectable({ providedIn: 'root', @@ -60,6 +62,10 @@ export class StaffDashboardService implements OnDestroy { refresh$ = new Subject(); canEdit$: Observable; canEditPoints$: Observable; + public sortOption$ = new BehaviorSubject(SortColumn.Date); + public sortDirection$ = new BehaviorSubject( + SortDirection.Desc, + ); constructor( private hqService: HQService, @@ -97,7 +103,7 @@ export class StaffDashboardService implements OnDestroy { this.hqService.getChargeCodeseV1({ active: true, staffId, - sortBy: SortColumn.IsProjectMember, + sortBy: ChargeCodeSortColumn.IsProjectMember, }), ), ); @@ -143,6 +149,8 @@ export class StaffDashboardService implements OnDestroy { search: search$, date: date$, status: timeStatus$, + sortBy: this.sortOption$, + sortDirection: this.sortDirection$, }).pipe(shareReplay({ bufferSize: 1, refCount: false })); const time$ = request$.pipe( diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.html new file mode 100644 index 00000000..d28d046e --- /dev/null +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.html @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + @if (this.staffDashboardService.canEdit$ | async) { + + } + @for (date of dashboard.dates; track date.date) { + @for (time of date.times; track time.id) { + + } + } + +
+ Hrs + + + Date + + + Chrg Code + + + Client + + + Project + + + Activity / Task + + Description +
diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts new file mode 100644 index 00000000..2075ba08 --- /dev/null +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts @@ -0,0 +1,78 @@ +import { StaffDashboardService } from './../service/staff-dashboard.service'; +/* eslint-disable rxjs/no-ignored-error */ +/* eslint-disable rxjs-angular/prefer-async-pipe */ +import { CommonModule } from '@angular/common'; +import { + Component, + EventEmitter, + Input, + OnDestroy, + Output, +} from '@angular/core'; +import { GetChargeCodeRecordV1 } from '../../models/charge-codes/get-chargecodes-v1'; +import { GetDashboardTimeV1Response } from '../../models/staff-dashboard/get-dashboard-time-v1'; +import { TimeStatus } from '../../enums/time-status'; +import { + HQTimeChangeEvent, + HQTimeDeleteEvent, + StaffDashboardTimeEntryComponent, +} from '../staff-dashboard-time-entry/staff-dashboard-time-entry.component'; +import { SortColumn } from '../../models/times/get-time-v1'; +import { SortDirection } from '../../models/common/sort-direction'; +import { ReplaySubject } from 'rxjs'; +import { SortIconComponent } from '../../common/sort-icon/sort-icon.component'; +import { localISODate } from '../../common/functions/local-iso-date'; + +@Component({ + selector: 'hq-staff-dashboard-month-view', + standalone: true, + imports: [CommonModule, StaffDashboardTimeEntryComponent, SortIconComponent], + templateUrl: './staff-dashboard-month-view.component.html', +}) +export class StaffDashboardMonthViewComponent implements OnDestroy { + @Input() dashboard!: GetDashboardTimeV1Response; + @Input() chargeCodes: GetChargeCodeRecordV1[] | null = []; + @Input() showAllRejectedTimes: boolean | null = false; + @Input() canEdit: boolean | null = false; + + timeStatus = TimeStatus; + sortColumn = SortColumn; + localISODate = localISODate(); // represent current day + + @Output() timeChange = new EventEmitter(); + @Output() timeDelete = new EventEmitter(); + @Output() timeDuplicate = new EventEmitter(); + private destroyed$: ReplaySubject = new ReplaySubject(1); + + constructor(public staffDashboardService: StaffDashboardService) {} + + ngOnDestroy(): void { + this.destroyed$.next(true); + this.destroyed$.complete(); + } + + upsertTime(event: HQTimeChangeEvent) { + this.timeChange.emit(event); + } + + deleteTime(event: HQTimeDeleteEvent) { + this.timeDelete.emit(event); + } + + duplicateTime(event: HQTimeChangeEvent) { + this.timeDuplicate.emit(event); + } + + onSortClick(sortColumn: SortColumn) { + if (this.staffDashboardService.sortOption$.value === sortColumn) { + this.staffDashboardService.sortDirection$.next( + this.staffDashboardService.sortDirection$.value === SortDirection.Asc + ? SortDirection.Desc + : SortDirection.Asc, + ); + } else { + this.staffDashboardService.sortOption$.next(sortColumn); + this.staffDashboardService.sortDirection$.next(SortDirection.Asc); + } + } +} diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html index e7897be6..988e133f 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-search-filter/staff-dashboard-search-filter.component.html @@ -45,8 +45,6 @@ - - diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.ts b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.ts index 920e7b82..39712dc7 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.ts +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.ts @@ -95,7 +95,8 @@ export class StaffDashboardTimeEntryComponent time?: Partial; @Input() chargeCodes: GetChargeCodeRecordV1[] | null = []; - + @Input() + enableChooseDate: boolean = false; @Output() hqTimeChange = new EventEmitter(); @@ -354,7 +355,7 @@ export class StaffDashboardTimeEntryComponent this.form.reset({ date: this.form.controls.date.value }); } async chooseDate() { - if (!this.form.value.id || !this.form.valid) { + if (!(this.form.value.id && this.form.valid) && !this.enableChooseDate) { return; } diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html index e490934e..37d5cc44 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html @@ -208,104 +208,120 @@ " > @if (staffDashboardService.time$ | async; as dashboard) { - @for (date of dashboard.dates; track date.date) { - @if (dashboard.dates.length > 1) { -
+ } @else { + @for (date of dashboard.dates; track date.date) { + @if (dashboard.dates.length > 1) { +
+
{{ date.date | date: "EEEE" }} | {{ date.date }}
+
{{ date.totalHours | number: "1.2-2" }} hours
+
+ } + -
{{ date.date | date: "EEEE" }} | {{ date.date }}
-
{{ date.totalHours | number: "1.2-2" }} hours
- + + + + + + + + + + + + + + + + @if ( + (staffDashboardService.showAllRejectedTimes$ | async) === + false && + (staffDashboardService.canEdit$ | async) && + date.canCreateTime + ) { + + } + @for (time of date.times; track time.id) { + + } + +
+ Hrs + + Date + + Chrg Code + + Client + + Project + + Activity / Task + + Description +
} - - - - - - - - - - - - - - - - - @if ( - (staffDashboardService.showAllRejectedTimes$ | async) === - false && - (staffDashboardService.canEdit$ | async) && - date.canCreateTime - ) { - - } - @for (time of date.times; track time.id) { - - } - -
- Hrs - - Date - - Chrg Code - - Client - - Project - - Activity / Task - - Description -
} }
diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.ts b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.ts index d3323bc5..7b544ab0 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.ts +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.ts @@ -63,6 +63,7 @@ import { ButtonComponent } from '../core/components/button/button.component'; import { StaffDashboardPlanningComponent } from './staff-dashboard-planning/staff-dashboard-planning.component'; import { GetPrevPlanResponseV1 } from '../models/Plan/get-previous-PSR-v1'; import { ButtonState } from '../enums/button-state'; +import { StaffDashboardMonthViewComponent } from './staff-dashboard-month-view/staff-dashboard-month-view.component'; export interface PointForm { id: FormControl; @@ -93,6 +94,7 @@ export interface PointForm { StaffDashboardPlanningPointComponent, ButtonComponent, StaffDashboardPlanningComponent, + StaffDashboardMonthViewComponent, ], providers: [StaffDashboardService], templateUrl: './staff-dashboard.component.html', diff --git a/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs b/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs index edcd1760..e3435ce9 100644 --- a/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs +++ b/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs @@ -2,6 +2,8 @@ using HQ.Abstractions.Enumerations; +using static HQ.Abstractions.Times.GetTimesV1; + namespace HQ.Abstractions.Times; public class GetDashboardTimeV1 @@ -11,6 +13,9 @@ public class Request public Guid StaffId { get; set; } public DateOnly Date { get; set; } public Period Period { get; set; } + public SortColumn SortBy { get; set; } = SortColumn.Date; + public SortDirection SortDirection {get; set;} = SortDirection.Desc; + public string? Search { get; set; } public TimeStatus? Status { get; set; } } @@ -39,6 +44,10 @@ public class TimeForDate { public bool CanCreateTime { get; set; } public DateOnly Date { get; set; } + public DateOnly StartDate { get; set; } + + public DateOnly EndDate { get; set; } + public List Times { get; set; } = new List(); public decimal TotalHours { get; set; } } diff --git a/src/dotnet/HQ.Server/Services/TimeEntryServiceV1.cs b/src/dotnet/HQ.Server/Services/TimeEntryServiceV1.cs index 3db5767d..10c2a273 100644 --- a/src/dotnet/HQ.Server/Services/TimeEntryServiceV1.cs +++ b/src/dotnet/HQ.Server/Services/TimeEntryServiceV1.cs @@ -530,6 +530,8 @@ public TimeEntryServiceV1(HQDbContext context, ILogger logge .Where(t => t.StaffId == request.StaffId && (request.Status == null ? (t.Date >= startDate && t.Date <= endDate) : (t.Status == request.Status))) .AsQueryable(); + + var hrsThisWeekQuery = _context.Times .AsNoTracking() .Where(t => t.StaffId == request.StaffId && t.Date >= request.Date.GetPeriodStartDate(Period.Week) && t.Date <= request.Date.GetPeriodEndDate(Period.Week)) @@ -568,7 +570,7 @@ public TimeEntryServiceV1(HQDbContext context, ILogger logge ); } - var times = await timesQuery + var times = timesQuery .Select(t => new GetDashboardTimeV1.TimeEntry() { Id = t.Id, @@ -588,45 +590,71 @@ public TimeEntryServiceV1(HQDbContext context, ILogger logge RejectionNotes = t.RejectionNotes, ProjectId = t.ChargeCode.ProjectId, ClientId = t.ChargeCode.Project != null ? t.ChargeCode.Project.ClientId : null - }) - .GroupBy(t => t.Date) - .ToDictionaryAsync(t => t.Key, t => t.OrderByDescending(x => x.CreatedAt).ToList()); - - var response = new GetDashboardTimeV1.Response(); - response.StartDate = startDate; - response.EndDate = endDate; - response.TotalHours = await timesQuery.SumAsync(t => t.Hours, ct); - response.BillableHours = await timesQuery.Where(t => t.ChargeCode.Billable).SumAsync(t => t.Hours, ct); - response.HoursThisWeek = await hrsThisWeekQuery.SumAsync(t => t.Hours, ct); - response.HoursLastWeek = await hrsLastWeekQuery.SumAsync(t => t.Hours, ct); - response.HoursThisMonth = await hrsThisMonthQuery.SumAsync(t => t.Hours, ct); - response.Vacation = vacationHours; - response.NextDate = nextDate; - response.PreviousDate = previousDate; - response.StaffName = staff.Name; - response.RejectedCount = await _context.Times.Where(t => t.StaffId == request.StaffId && t.Status == TimeStatus.Rejected).CountAsync(ct); - response.TimeEntryCutoffDate = staff.TimeEntryCutoffDate; - if (request.Status.HasValue) - { - foreach (var date in times) - { - var timeForDate = new GetDashboardTimeV1.TimeForDate(); - timeForDate.Date = date.Key; - timeForDate.Times = date.Value; - timeForDate.TotalHours = timeForDate.Times.Sum(t => t.Hours); - response.Dates.Add(timeForDate); - } + }); + + + var sortMap = new Dictionary() + { + { Abstractions.Times.GetTimesV1.SortColumn.Hours, "Hours" }, + { Abstractions.Times.GetTimesV1.SortColumn.Date, "Date" }, + { Abstractions.Times.GetTimesV1.SortColumn.ChargeCode, "ChargeCode" }, + { Abstractions.Times.GetTimesV1.SortColumn.ClientName, "ClientName" }, + { Abstractions.Times.GetTimesV1.SortColumn.ProjectName, "ProjectName" }, + }; + + + if (sortMap.ContainsKey(request.SortBy)) + { + var sortProperty = sortMap[request.SortBy]; + + times = request.SortDirection == SortDirection.Asc + ? times.OrderBy(t => EF.Property(t, sortProperty)) + : times.OrderByDescending(t => EF.Property(t, sortProperty)); } - else + + var timeEntriesList = await times.ToListAsync(ct); + + var groupedTimes = request.Period switch + { + Period.Today => timeEntriesList.GroupBy(t => t.Date).ToDictionary(g => g.Key, g => g.ToList()), + Period.Week => timeEntriesList.GroupBy(t => t.Date).ToDictionary(g => g.Key, g => g.ToList()), + Period.Month => timeEntriesList.GroupBy(t => t.Date.GetPeriodStartDate(Period.Month)).ToDictionary(g => g.Key, g => g.ToList()), + _ => new Dictionary>() + }; + + + var response = new GetDashboardTimeV1.Response + { + StartDate = startDate, + EndDate = endDate, + TotalHours = await timesQuery.SumAsync(t => t.Hours, ct), + BillableHours = await timesQuery.Where(t => t.ChargeCode.Billable).SumAsync(t => t.Hours, ct), + HoursThisWeek = await hrsThisWeekQuery.SumAsync(t => t.Hours, ct), + HoursLastWeek = await hrsLastWeekQuery.SumAsync(t => t.Hours, ct), + HoursThisMonth = await hrsThisMonthQuery.SumAsync(t => t.Hours, ct), + Vacation = vacationHours, + NextDate = nextDate, + PreviousDate = previousDate, + StaffName = staff.Name, + RejectedCount = await _context.Times.Where(t => t.StaffId == request.StaffId && t.Status == TimeStatus.Rejected).CountAsync(ct), + TimeEntryCutoffDate = staff.TimeEntryCutoffDate + }; + + if (request.Period == Period.Today || request.Period == Period.Week) { DateOnly date = endDate; do { - var timeForDate = new GetDashboardTimeV1.TimeForDate(); - timeForDate.Date = date; - if (times.ContainsKey(date)) + var timeForDate = new GetDashboardTimeV1.TimeForDate { - timeForDate.Times = times[date]; + Date = date, + StartDate = startDate, + EndDate = endDate + }; + + if (groupedTimes.ContainsKey(date)) + { + timeForDate.Times = groupedTimes[date]; timeForDate.TotalHours = timeForDate.Times.Sum(t => t.Hours); } @@ -637,8 +665,22 @@ public TimeEntryServiceV1(HQDbContext context, ILogger logge } while (date >= startDate); } + else if (request.Period == Period.Month) + { + var timeForMonth = new GetDashboardTimeV1.TimeForDate + { + Date = startDate, + StartDate = startDate, + EndDate = endDate, + Times = groupedTimes.Values.SelectMany(v => v).ToList(), + TotalHours = timeEntriesList.Sum(t => t.Hours), + CanCreateTime = !staff.TimeEntryCutoffDate.HasValue || endDate >= staff.TimeEntryCutoffDate.Value + }; + + response.Dates.Add(timeForMonth); + } + response.CanSubmit = groupedTimes.Count > 0 && !groupedTimes.Any(t => t.Value.Any(x => x.Hours == 0 || String.IsNullOrEmpty(x.Notes))) && groupedTimes.Any(t => t.Value.Any(x => x.TimeStatus == TimeStatus.Unsubmitted || x.TimeStatus == TimeStatus.Rejected)); - response.CanSubmit = times.Count > 0 && !times.Any(t => t.Value.Any(x => x.Hours == 0 || String.IsNullOrEmpty(x.Notes))) && times.Any(t => t.Value.Any(x => x.TimeStatus == TimeStatus.Unsubmitted || x.TimeStatus == TimeStatus.Rejected)); return response; } From 16f6de775b4c764197060cb5651eacaa0ea4f7d0 Mon Sep 17 00:00:00 2001 From: amrmahdyy Date: Fri, 27 Sep 2024 12:09:06 -0400 Subject: [PATCH 3/5] Cleaned some lines --- .../staff-dashboard-month-view.component.ts | 2 -- src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts index 2075ba08..59344847 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-month-view/staff-dashboard-month-view.component.ts @@ -1,6 +1,4 @@ import { StaffDashboardService } from './../service/staff-dashboard.service'; -/* eslint-disable rxjs/no-ignored-error */ -/* eslint-disable rxjs-angular/prefer-async-pipe */ import { CommonModule } from '@angular/common'; import { Component, diff --git a/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs b/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs index e3435ce9..4c62b359 100644 --- a/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs +++ b/src/dotnet/HQ.Abstractions/Times/GetDashboardTimeV1.cs @@ -14,7 +14,7 @@ public class Request public DateOnly Date { get; set; } public Period Period { get; set; } public SortColumn SortBy { get; set; } = SortColumn.Date; - public SortDirection SortDirection {get; set;} = SortDirection.Desc; + public SortDirection SortDirection { get; set; } = SortDirection.Desc; public string? Search { get; set; } public TimeStatus? Status { get; set; } From 1e9aae40a1d3148a0117ace3522a23eb8a156412 Mon Sep 17 00:00:00 2001 From: amrmahdyy Date: Fri, 27 Sep 2024 12:10:20 -0400 Subject: [PATCH 4/5] Fixed prettier warning --- .../hq/src/app/staff-dashboard/staff-dashboard.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html index b3f77d61..935970ce 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard.component.html @@ -208,7 +208,9 @@ Date: Fri, 27 Sep 2024 14:02:50 -0400 Subject: [PATCH 5/5] removed autocomplete chargecode for time entry read only status --- .../staff-dashboard-time-entry.component.html | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.html b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.html index 99dd8604..2db081b1 100644 --- a/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.html +++ b/src/angular/hq/src/app/staff-dashboard/staff-dashboard-time-entry/staff-dashboard-time-entry.component.html @@ -211,29 +211,16 @@ {{ time?.date }} - -
- +
+