From ad1d3e02847986063f553f1cd0d34e6711d62392 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 23 May 2024 17:53:07 +0530 Subject: [PATCH 1/7] fix: only allowed query parameters if have value --- packages/common-angular/src/utils/shared-utils.ts | 9 +++++++++ packages/ui-sdk/src/lib/common/src/utils/shared-utils.ts | 9 +++++++++ .../core/src/services/navigation/navigation.service.ts | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/common-angular/src/utils/shared-utils.ts b/packages/common-angular/src/utils/shared-utils.ts index ef82e28376..1d20e02fc3 100644 --- a/packages/common-angular/src/utils/shared-utils.ts +++ b/packages/common-angular/src/utils/shared-utils.ts @@ -24,6 +24,15 @@ export function isNotNullOrUndefined(value: T | undefined | null): value is T return value !== undefined && value !== null; } +/** + * Check if a value is null, undefined, or an empty string. + * @param value The value to check. + * @returns true if the value is null, undefined, or an empty string, false otherwise. + */ +export function isNotNullOrUndefinedOrEmpty(value: T | undefined | null): boolean { + return isNotNullOrUndefined(value) && value !== ''; +} + // It will use for pass nested object or array in query params in get method. export function toParams(query) { let params: HttpParams = new HttpParams(); diff --git a/packages/ui-sdk/src/lib/common/src/utils/shared-utils.ts b/packages/ui-sdk/src/lib/common/src/utils/shared-utils.ts index 465b63161d..52ba986b1e 100644 --- a/packages/ui-sdk/src/lib/common/src/utils/shared-utils.ts +++ b/packages/ui-sdk/src/lib/common/src/utils/shared-utils.ts @@ -25,6 +25,15 @@ export function isNotNullOrUndefined(value: T | undefined | null): value is T return value !== undefined && value !== null; } +/** + * Check if a value is null, undefined, or an empty string. + * @param value The value to check. + * @returns true if the value is null, undefined, or an empty string, false otherwise. + */ +export function isNotNullOrUndefinedOrEmpty(value: T | undefined | null): boolean { + return isNotNullOrUndefined(value) && value !== ''; +} + // It will use for pass nested object or array in query params in get method. export function toParams(query: any) { let params: HttpParams = new HttpParams(); diff --git a/packages/ui-sdk/src/lib/core/src/services/navigation/navigation.service.ts b/packages/ui-sdk/src/lib/core/src/services/navigation/navigation.service.ts index e8197d75cf..7300454a43 100644 --- a/packages/ui-sdk/src/lib/core/src/services/navigation/navigation.service.ts +++ b/packages/ui-sdk/src/lib/core/src/services/navigation/navigation.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute, QueryParamsHandling, Router } from '@angular/router'; import { Location } from '@angular/common'; +import { isNotNullOrUndefinedOrEmpty } from '@gauzy/ui-sdk/common'; @Injectable({ providedIn: 'root' @@ -70,7 +71,7 @@ export class NavigationService { const uniqueQueryParams: { [key: string]: string | string[] | boolean } = {}; for (const key in finalQueryParams) { const value = finalQueryParams[key]; - if (typeof value != 'undefined') { + if (isNotNullOrUndefinedOrEmpty(value)) { if (Array.isArray(value)) { uniqueQueryParams[key] = Array.from(new Set(value)); } else { From fe6ceb10248ae6f438200af0d4aff5b239f7fa7c Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Thu, 23 May 2024 18:06:41 +0530 Subject: [PATCH 2/7] fix: update query parameters without navigating away --- .../timezone-filter.component.ts | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts index c89edd3d78..9d57f76268 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.ts @@ -1,10 +1,11 @@ import { AfterViewInit, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; -import { ActivatedRoute, Params, Router } from '@angular/router'; +import { ActivatedRoute, Params } from '@angular/router'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { combineLatest, filter } from 'rxjs'; import { tap } from 'rxjs/operators'; import * as moment from 'moment-timezone'; import { distinctUntilChange } from '@gauzy/ui-sdk/common'; +import { NavigationService } from '@gauzy/ui-sdk/core'; import { DEFAULT_TIME_FORMATS, IOrganization, @@ -53,24 +54,13 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy this._isTimeformat = value; } - /* - * Getter & Setter - */ - private _navigate: boolean = true; - get navigate(): boolean { - return this._navigate; - } - @Input() set navigate(value: boolean) { - this._navigate = value; - } - @Output() timeZoneChange = new EventEmitter(); @Output() timeFormatChange = new EventEmitter(); constructor( private readonly _route: ActivatedRoute, - private readonly _router: Router, - private readonly _store: Store + private readonly _store: Store, + private readonly _navigationService: NavigationService ) {} ngOnInit(): void { @@ -190,14 +180,10 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy this.timeFormatChange.emit(timeFormat); - if (this.navigate) { - // Update query parameter 'time_format' - await this._router.navigate([], { - relativeTo: this._route, - queryParams: { time_format: timeFormat.toString() }, - queryParamsHandling: 'merge' - }); - } + // Updates the query parameters of the current route without navigating away. + await this._navigationService.updateQueryParams({ + time_format: timeFormat.toString() + }); } /** @@ -211,14 +197,10 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy this.timeZoneChange.emit(this.getTimeZone(this.selectedTimeZone)); - if (this.navigate) { - // Update query parameter 'time_zone' - await this._router.navigate([], { - relativeTo: this._route, - queryParams: { time_zone: timeZone.toString() }, - queryParamsHandling: 'merge' - }); - } + // Updates the query parameters of the current route without navigating away. + await this._navigationService.updateQueryParams({ + time_zone: timeZone.toString() + }); } /** From 779188be46cf22c034d01aa9219ba84a286eee33 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Fri, 24 May 2024 22:11:58 +0530 Subject: [PATCH 3/7] fix: missing nb popover module for time tracking filter --- .../@shared/timesheet/gauzy-filters/gauzy-filters.module.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.module.ts b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.module.ts index 06fbfd428d..09d9682e6c 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.module.ts +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { NbButtonModule, NbIconModule, NbSelectModule } from '@nebular/theme'; +import { NbButtonModule, NbIconModule, NbPopoverModule, NbSelectModule } from '@nebular/theme'; import { NgxSliderModule } from '@angular-slider/ngx-slider'; import { TranslateModule } from '@gauzy/ui-sdk/i18n'; import { PipesModule } from '../../pipes/pipes.module'; @@ -16,6 +16,7 @@ import { TimezoneFilterModule } from './timezone-filter/timezone-filter.module'; FormsModule, NbButtonModule, NbIconModule, + NbPopoverModule, NbSelectModule, NgxSliderModule, PipesModule, From be63308cf43ba2d9e46aafc9f695457f371d107b Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Fri, 24 May 2024 22:48:45 +0530 Subject: [PATCH 4/7] fix: apply time format on screenshot items --- .../screenshots-item.component.html | 43 ++---- .../screenshots-item.component.ts | 4 +- .../time-tracking.component.html | 1 + .../time-tracking/time-tracking.component.ts | 134 +++++++++++++----- .../screenshot/screenshot.component.html | 35 ++--- .../screenshot/screenshot.component.scss | 2 +- .../screenshot/screenshot.component.ts | 5 +- 7 files changed, 127 insertions(+), 97 deletions(-) diff --git a/apps/gauzy/src/app/@shared/timesheet/screenshots/screenshots-item/screenshots-item.component.html b/apps/gauzy/src/app/@shared/timesheet/screenshots/screenshots-item/screenshots-item.component.html index c75193353d..5cbcc035d8 100644 --- a/apps/gauzy/src/app/@shared/timesheet/screenshots/screenshots-item/screenshots-item.component.html +++ b/apps/gauzy/src/app/@shared/timesheet/screenshots/screenshots-item/screenshots-item.component.html @@ -1,18 +1,12 @@ -
+
- +
- + {{ employees.length }} @@ -46,9 +40,7 @@ [message]="'ACTIVITY.DELETE_CONFIRM' | translate" (confirm)="deleteSlot(timeSlot)" > - + - -
- -
-
+ + {{ 'TIMESHEET.SELECT_ACTIVITY_LEVEL' | translate }} +
@@ -65,6 +53,15 @@
+ +
+ +
+
+ + +
+ +
+
diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts index 88997b9de7..b67a3887e2 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts @@ -8,15 +8,15 @@ import { OnInit, Output } from '@angular/core'; -import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; -import { Options, ChangeContext } from '@angular-slider/ngx-slider'; -import { ITimeLogFilters, PermissionsEnum, TimeLogSourceEnum, TimeLogType } from '@gauzy/contracts'; import { Subject } from 'rxjs'; import { debounceTime, take, tap } from 'rxjs/operators'; +import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService } from '@ngx-translate/core'; import { pick } from 'underscore'; -import { ActivityLevel, TimesheetFilterService } from '../timesheet-filter.service'; +import { Options, ChangeContext } from '@angular-slider/ngx-slider'; +import { ITimeLogFilters, PermissionsEnum, TimeFormatEnum, TimeLogSourceEnum, TimeLogType } from '@gauzy/contracts'; import { TranslationBaseComponent } from '@gauzy/ui-sdk/shared'; +import { ActivityLevel, TimesheetFilterService } from '../timesheet-filter.service'; @UntilDestroy({ checkProperties: true }) @Component({ @@ -50,6 +50,7 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A */ private filters$: Subject = new Subject(); private _filters: ITimeLogFilters = { + timeFormat: TimeFormatEnum.FORMAT_12_HOURS, source: [], logType: [], activityLevel: ActivityLevel @@ -68,6 +69,17 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A this.cd.detectChanges(); } + /* + * Getter & Setter + */ + private _isTimeformat: boolean = false; + get isTimeformat(): boolean { + return this._isTimeformat; + } + @Input() set isTimeformat(value: boolean) { + this._isTimeformat = value; + } + @Output() filtersChange: EventEmitter = new EventEmitter(); /** @@ -108,24 +120,38 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A this.cd.detectChanges(); } - setActivityLevel($event: ChangeContext): void { + /** + * + * @param activity + */ + setActivityLevel(activity: ChangeContext): void { this.filters.activityLevel = { - start: $event.value, - end: $event.highValue + start: activity.value, + end: activity.highValue }; this.activityLevel = this.filters.activityLevel; this.triggerFilterChange(); } + /** + * + */ triggerFilterChange(): void { this.filters$.next(true); } + /** + * + */ clearFilters(): void { this.filters = this.timesheetFilterService.clear(); this.triggerFilterChange(); } + /** + * + * @returns + */ hasFilter(): boolean { return ( (this._filters.source && this._filters.source.length >= 1) || @@ -135,11 +161,35 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A ); } + /** + * + * @returns + */ arrangedFilters(): ITimeLogFilters { Object.keys(this.filters).forEach((key) => (this.filters[key] === undefined ? delete this.filters[key] : {})); return this.filters; } + /** + * Handles the event when the time format is changed. + * + * @param timeformat The new time format. + */ + timeFormatChanged(timeFormat: TimeFormatEnum): void { + this.filters.timeFormat = timeFormat; + this.triggerFilterChange(); + } + + /** + * Handles the event when the time zone is changed. + * + * @param timezone The new time zone. + */ + timeZoneChanged(timeZone: string): void { + this.filters.timeZone = timeZone; + this.triggerFilterChange(); + } + /** * Generate Dynamic Timelog Source Selector */ diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.html b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.html index 24e0bbf2bb..4d95a18722 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.html +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/timezone-filter/timezone-filter.component.html @@ -1,19 +1,21 @@ - - -
+ +
Time Zone
@@ -33,7 +35,7 @@
-
Time Format
+
Time Format
{ - this.applyTimeFormat(queryParams, organization.timeFormat); - this.applyTimeZone(queryParams, TimeZoneEnum.ORG_TIMEZONE); + if (this.isTimeformat) this.applyTimeFormat(queryParams, organization.timeFormat); + if (this.isTimezone) this.applyTimeZone(queryParams, TimeZoneEnum.ORG_TIMEZONE); }), // Handle component lifecycle to avoid memory leaks untilDestroyed(this) @@ -100,8 +100,8 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy .pipe( distinctUntilChange(), tap(([queryParams, user]) => { - this.applyTimeFormat(queryParams, user.timeFormat); - this.applyTimeZone(queryParams, TimeZoneEnum.MINE_TIMEZONE); + if (this.isTimeformat) this.applyTimeFormat(queryParams, user.timeFormat); + if (this.isTimezone) this.applyTimeZone(queryParams, TimeZoneEnum.MINE_TIMEZONE); }), // Handle component lifecycle to avoid memory leaks untilDestroyed(this) @@ -120,9 +120,9 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy // Apply query parameters first if (time_format) { - this.selectTimeFormat(time_format); + this.updateSelectedTimeFormat(parseInt(time_format, 10)); } else { - this.selectTimeFormat(timeFormat); + this.updateSelectedTimeFormat(timeFormat); } } @@ -136,9 +136,9 @@ export class TimezoneFilterComponent implements AfterViewInit, OnInit, OnDestroy // Apply query parameters first if (time_zone) { - this.selectTimeZone(time_zone); + this.updateSelectedTimeZone(time_zone); } else { - this.selectTimeZone(timeZone); + this.updateSelectedTimeZone(timeZone); } } diff --git a/packages/contracts/src/timesheet.model.ts b/packages/contracts/src/timesheet.model.ts index 11d06f24db..d0599f6ca8 100644 --- a/packages/contracts/src/timesheet.model.ts +++ b/packages/contracts/src/timesheet.model.ts @@ -1,21 +1,11 @@ -import { - IBasePerTenantAndOrganizationEntityModel, - IBaseRelationsEntityModel, -} from './base-entity.model'; -import { - IOrganizationContact, - OrganizationContactBudgetTypeEnum, -} from './organization-contact.model'; +import { IBasePerTenantAndOrganizationEntityModel, IBaseRelationsEntityModel } from './base-entity.model'; +import { IOrganizationContact, OrganizationContactBudgetTypeEnum } from './organization-contact.model'; import { IOrganizationProject, IRelationalOrganizationProject, - OrganizationProjectBudgetTypeEnum, + OrganizationProjectBudgetTypeEnum } from './organization-projects.model'; -import { - IEmployee, - IEmployeeFindInput, - IRelationalEmployee, -} from './employee.model'; +import { IEmployee, IEmployeeFindInput, IRelationalEmployee } from './employee.model'; import { ITask } from './task.model'; import { ITag } from './tag.model'; import { IPaginationInput } from './core.model'; @@ -23,6 +13,7 @@ import { ReportGroupByFilter } from './report.model'; import { IUser } from './user.model'; import { IRelationalOrganizationTeam } from './organization-team.model'; import { IScreenshot } from './screenshot.model'; +import { TimeFormatEnum } from './organization.model'; export interface ITimesheet extends IBasePerTenantAndOrganizationEntityModel { employee: IEmployee; @@ -78,17 +69,15 @@ export enum TimesheetStatus { PENDING = 'PENDING', IN_REVIEW = 'IN REVIEW', DENIED = 'DENIED', - APPROVED = 'APPROVED', + APPROVED = 'APPROVED' } -export interface IUpdateTimesheetStatusInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface IUpdateTimesheetStatusInput extends IBasePerTenantAndOrganizationEntityModel { ids: string | string[]; status?: TimesheetStatus; } -export interface ISubmitTimesheetInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface ISubmitTimesheetInput extends IBasePerTenantAndOrganizationEntityModel { ids: string | string[]; status: 'submit' | 'unsubmit'; } @@ -106,7 +95,10 @@ export interface IDateRange { start: Date; end: Date; } -export interface ITimeLog extends IBasePerTenantAndOrganizationEntityModel, IRelationalOrganizationProject, IRelationalOrganizationTeam { +export interface ITimeLog + extends IBasePerTenantAndOrganizationEntityModel, + IRelationalOrganizationProject, + IRelationalOrganizationTeam { employee: IEmployee; employeeId: IEmployee['id']; timesheet?: ITimesheet; @@ -133,8 +125,7 @@ export interface ITimeLog extends IBasePerTenantAndOrganizationEntityModel, IRel isEdited?: boolean; } -export interface ITimeLogCreateInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeLogCreateInput extends IBasePerTenantAndOrganizationEntityModel { employeeId: string; timesheetId?: string; taskId?: string; @@ -148,8 +139,7 @@ export interface ITimeLogCreateInput isBilled?: boolean; } -export interface ITimeSlotCreateInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeSlotCreateInput extends IBasePerTenantAndOrganizationEntityModel { employeeId: string; duration: number; keyboard: number; @@ -163,12 +153,12 @@ export enum TimeLogType { TRACKED = 'TRACKED', MANUAL = 'MANUAL', IDLE = 'IDLE', - RESUMED = 'RESUMED', + RESUMED = 'RESUMED' } export enum ManualTimeLogAction { ADDED = 'ADDED', - EDITED = 'EDITED', + EDITED = 'EDITED' } export enum TimeLogSourceEnum { @@ -178,11 +168,10 @@ export enum TimeLogSourceEnum { BROWSER_EXTENSION = 'BROWSER_EXTENSION', HUBSTAFF = 'HUBSTAFF', UPWORK = 'UPWORK', - TEAMS = 'TEAMS', + TEAMS = 'TEAMS' } -export interface ITimeLogFilters - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeLogFilters extends IBasePerTenantAndOrganizationEntityModel { date?: Date | string; startDate?: Date | string; endDate?: Date | string; @@ -199,11 +188,12 @@ export interface ITimeLogFilters taskIds?: string[]; defaultRange?: boolean; unitOfTime?: any; - categoryId?: string + categoryId?: string; + timeZone?: string; + timeFormat?: TimeFormatEnum; } -export interface ITimeLogTodayFilters - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeLogTodayFilters extends IBasePerTenantAndOrganizationEntityModel { todayStart?: Date | string; todayEnd?: Date | string; } @@ -231,16 +221,14 @@ export interface ITimeSlot extends IBasePerTenantAndOrganizationEntityModel { isAllowDelete?: boolean; } -export interface ITimeSlotTimeLogs - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeSlotTimeLogs extends IBasePerTenantAndOrganizationEntityModel { timeLogs: ITimeLog[]; timeSlots: ITimeSlot[]; timeLogId: string; timeSlotId: string; } -export interface ITimeSlotMinute - extends IBasePerTenantAndOrganizationEntityModel { +export interface ITimeSlotMinute extends IBasePerTenantAndOrganizationEntityModel { timeSlot?: ITimeSlot; timeSlotId?: string; keyboard?: number; @@ -282,8 +270,7 @@ export interface IDailyActivity { childItems?: IDailyActivity[]; } -export interface ICreateActivityInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface ICreateActivityInput extends IBasePerTenantAndOrganizationEntityModel { employeeId?: string; projectId?: string; duration?: number; @@ -300,7 +287,7 @@ export interface ICreateActivityInput export enum ActivityType { URL = 'URL', - APP = 'APP', + APP = 'APP' } export interface IURLMetaData { @@ -310,9 +297,11 @@ export interface IURLMetaData { [x: string]: any; } - - -export interface ITimerStatusInput extends ITimeLogTodayFilters, IBaseRelationsEntityModel, IRelationalEmployee, IRelationalOrganizationTeam { +export interface ITimerStatusInput + extends ITimeLogTodayFilters, + IBaseRelationsEntityModel, + IRelationalEmployee, + IRelationalOrganizationTeam { source?: TimeLogSourceEnum; employeeIds?: string[]; } @@ -340,7 +329,7 @@ export interface ITimerPosition { export interface ITimerToggleInput extends IBasePerTenantAndOrganizationEntityModel, - Pick { + Pick { projectId?: string; taskId?: string; organizationContactId?: string; @@ -382,32 +371,24 @@ export interface IGetTimeLogReportInput extends IGetTimeLogInput { isEdited?: boolean; } -export interface IGetTimeLogConflictInput - extends IBasePerTenantAndOrganizationEntityModel, - IBaseRelationsEntityModel { +export interface IGetTimeLogConflictInput extends IBasePerTenantAndOrganizationEntityModel, IBaseRelationsEntityModel { ignoreId?: string | string[]; startDate: string | Date; endDate: string | Date; employeeId: string; } -export interface IGetTimeSlotInput - extends ITimeLogFilters, - IBaseRelationsEntityModel { +export interface IGetTimeSlotInput extends ITimeLogFilters, IBaseRelationsEntityModel { [x: string]: any; } -export interface IGetActivitiesInput - extends ITimeLogFilters, - IPaginationInput, - IBaseRelationsEntityModel { +export interface IGetActivitiesInput extends ITimeLogFilters, IPaginationInput, IBaseRelationsEntityModel { types?: string[]; titles?: string[]; groupBy?: string; } -export interface IBulkActivitiesInput - extends IBasePerTenantAndOrganizationEntityModel { +export interface IBulkActivitiesInput extends IBasePerTenantAndOrganizationEntityModel { employeeId: string; projectId?: string; activities: IActivity[]; @@ -528,13 +509,11 @@ export interface IClientBudgetLimitReport { remainingBudget?: number; } -export interface IDeleteTimeSlot - extends IBasePerTenantAndOrganizationEntityModel { +export interface IDeleteTimeSlot extends IBasePerTenantAndOrganizationEntityModel { ids: string[]; } -export interface IDeleteTimeLog - extends IBasePerTenantAndOrganizationEntityModel { +export interface IDeleteTimeLog extends IBasePerTenantAndOrganizationEntityModel { logIds: string[]; forceDelete: boolean; } From 55bfe9c4962278e6ec21b44c7123b0b3b4c0e639 Mon Sep 17 00:00:00 2001 From: "Rahul R." Date: Sat, 25 May 2024 12:15:15 +0530 Subject: [PATCH 6/7] fix: set the 24-hour time format for slot labels (full calendar) --- .../gauzy-filters.component.html | 18 ++++++------- .../gauzy-filters/gauzy-filters.component.ts | 12 +-------- .../timezone-filter.component.ts | 25 +++---------------- .../calendar/calendar/calendar.component.html | 13 +++------- .../calendar/calendar/calendar.component.ts | 18 +++++++++++-- 5 files changed, 32 insertions(+), 54 deletions(-) diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.html b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.html index 2dc704e4b9..8024c77b21 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.html +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.html @@ -1,6 +1,15 @@
+ +
+ +
+
- -
- -
-
@@ -20,6 +12,7 @@
Date: Sat, 25 May 2024 12:51:29 +0530 Subject: [PATCH 7/7] fix: timezone & timeformat filter --- .../gauzy-filters/gauzy-filters.component.ts | 2 +- .../calendar/calendar/calendar.component.ts | 10 +- .../expenses-report.component.html | 33 ++- .../expenses-report.component.scss | 19 +- .../manual-time/manual-time.component.html | 196 ++++++++++-------- 5 files changed, 131 insertions(+), 129 deletions(-) diff --git a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts index 9601a9bfe8..d89dae548e 100644 --- a/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts +++ b/apps/gauzy/src/app/@shared/timesheet/gauzy-filters/gauzy-filters.component.ts @@ -68,7 +68,7 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A } this.cd.detectChanges(); } - @Input() isTimeformat: boolean = true; + @Input() isTimeformat: boolean = false; @Output() filtersChange: EventEmitter = new EventEmitter(); diff --git a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts index 6ab639dee9..011ce04ea1 100644 --- a/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts +++ b/apps/gauzy/src/app/pages/employees/timesheet/calendar/calendar/calendar.component.ts @@ -177,15 +177,19 @@ export class CalendarComponent extends BaseSelectorFilterComponent implements On this.calendar.getApi().refetchEvents(); } - getEvents(arg: any, callback: Function) { + /** + * Fetches events based on the provided arguments and invokes the callback with the events. + * @param {Object} arg - The argument containing the start and end dates. + * @param {Function} callback - The callback function to be called with the fetched events. + * @returns {Promise} + */ + getEvents(arg: any, callback: Function): Promise { if (!this.organization || isEmpty(this.request)) { return; } const startDate = moment(arg.start).startOf('day').format('YYYY-MM-DD HH:mm:ss'); const endDate = moment(arg.end).subtract(1, 'days').endOf('day').format('YYYY-MM-DD HH:mm:ss'); - const appliedFilter = pick(this.filters, 'source', 'activityLevel', 'logType'); - const request: IGetTimeLogInput = { ...appliedFilter, ...this.getFilterRequest({ diff --git a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.html b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.html index 27c4ec3eb8..adad39f1b0 100644 --- a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.html +++ b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.html @@ -1,18 +1,11 @@ - +

{{ 'REPORT_PAGE.EXPENSES_REPORT' | translate }}

- + [saveFilters]="(datePickerConfig$ | async).isSaveDatePicker" (filtersChange)="filtersChange($event)" >
- +
+ +
@@ -41,15 +36,11 @@

- +
- +

diff --git a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.scss b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.scss index 9a2c779e47..097ba829b5 100644 --- a/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.scss +++ b/apps/gauzy/src/app/pages/reports/expenses-report/expenses-report/expenses-report.component.scss @@ -2,33 +2,28 @@ @import 'gauzy/_gauzy-overrides'; :host { - ::ng-deep { - .action-select button { - background-color: nb-theme(gauzy-card-1) !important; - border-radius: nb-theme(select-rectangle-border-radius); - } + ::ng-deep { + .action-select button { + background-color: nb-theme(gauzy-card-1) !important; + border-radius: nb-theme(select-rectangle-border-radius); } + } } :host { .filters { display: flex; justify-content: flex-end; - gap: 5px; } ::ng-deep { ng-select { min-width: 10rem; } - @include ng-select-overrides( - 2rem, - $default-button-radius, - $default-box-shadow - ); + @include ng-select-overrides(2rem, $default-button-radius, $default-box-shadow); } } .report-body { - height: calc(100% - 8rem) !important; + height: calc(100% - 8rem) !important; } diff --git a/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.html b/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.html index 65ecc47554..d9b783c117 100644 --- a/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.html +++ b/apps/gauzy/src/app/pages/reports/manual-time/manual-time/manual-time.component.html @@ -1,13 +1,11 @@ - -

- - {{ 'REPORT_PAGE.MANUAL_TIME_EDIT_REPORT' | translate }} - + +

+ + {{ 'REPORT_PAGE.MANUAL_TIME_EDIT_REPORT' | translate }} +

- + [hasActivityLevelFilter]="false" (filtersChange)="filtersChange($event)" > - +
+ +

@@ -49,75 +49,91 @@

-
+
-
{{ 'REPORT_PAGE.EMPLOYEE' | translate }}
+
+ {{ 'REPORT_PAGE.EMPLOYEE' | translate }} +
+ employeeEl; + context: { $implicit: timeLogRow?.employee } + " + >
-
{{ 'REPORT_PAGE.PROJECT' | translate }}
+
+ {{ 'REPORT_PAGE.PROJECT' | translate }} +
+ projectEl; + context: { $implicit: timeLogRow?.project } + " + >
-
{{ 'REPORT_PAGE.TO_DO' | translate }}
+
+ {{ 'REPORT_PAGE.TO_DO' | translate }} +
+ taskEl; + context: { $implicit: timeLogRow?.task } + " + >
-
{{ 'REPORT_PAGE.REASON' | translate }}
+
+ {{ 'REPORT_PAGE.REASON' | translate }} +
{{ timeLogRow.reason || '—' }}
-
{{ 'REPORT_PAGE.FROM' | translate }}
+
+ {{ 'REPORT_PAGE.FROM' | translate }} +
{{ timeLogRow.createdAt | timeFormat }}
-
{{ 'REPORT_PAGE.TIME_SPAN' | translate }}
+
+ {{ 'REPORT_PAGE.TIME_SPAN' | translate }} +
{{ timeLogRow.duration | durationFormat }}
-
{{ 'REPORT_PAGE.CHANGED_AT' | translate }}
+
+ {{ 'REPORT_PAGE.CHANGED_AT' | translate }} +
{{ timeLogRow.editedAt | dateTimeFormat }}
+
+ {{ 'REPORT_PAGE.ACTION' | translate }} +
{{ 'REPORT_PAGE.ACTION' | translate }}
-
+ class="responsive-table-content day-col" + [ngSwitch]="timeLogRow.isEdited" + >
- - - - {{ 'REPORT_PAGE.NO_PROJECT' | translate }} - + + + {{ 'REPORT_PAGE.NO_PROJECT' | translate }} + - {{ task?.title }} - - {{ 'REPORT_PAGE.NO_TASK' | translate }} - + {{ task?.title }} + + {{ 'REPORT_PAGE.NO_TASK' | translate }} + -
- -
- - {{ 'REPORT_PAGE.NO_EMPLOYEE' | translate }} - +
+ +
+ + {{ 'REPORT_PAGE.NO_EMPLOYEE' | translate }} +
-
-
-
- {{ 'REPORT_PAGE.EMPLOYEE' | translate }} -
-
- {{ 'REPORT_PAGE.PROJECT' | translate }} -
-
- {{ 'REPORT_PAGE.TO_DO' | translate }} -
-
- {{ 'REPORT_PAGE.REASON' | translate }} -
-
- {{ 'REPORT_PAGE.FROM' | translate }} -
-
- {{ 'REPORT_PAGE.TIME_SPAN' | translate }} -
-
- {{ 'REPORT_PAGE.CHANGED_AT' | translate }} -
-
- {{ 'REPORT_PAGE.ACTION' | translate }} -
-
-
+
+
+
+ {{ 'REPORT_PAGE.EMPLOYEE' | translate }} +
+
+ {{ 'REPORT_PAGE.PROJECT' | translate }} +
+
+ {{ 'REPORT_PAGE.TO_DO' | translate }} +
+
+ {{ 'REPORT_PAGE.REASON' | translate }} +
+
+ {{ 'REPORT_PAGE.FROM' | translate }} +
+
+ {{ 'REPORT_PAGE.TIME_SPAN' | translate }} +
+
+ {{ 'REPORT_PAGE.CHANGED_AT' | translate }} +
+
+ {{ 'REPORT_PAGE.ACTION' | translate }} +
+
+