Skip to content

Commit

Permalink
Merge pull request #7827 from ever-co/fix/timezone-filters
Browse files Browse the repository at this point in the history
[Feat] Apply Time Format (12 / 24 hours)
  • Loading branch information
rahul-rocket committed May 25, 2024
2 parents 32d1025 + 33dd6e9 commit 8d5b18a
Show file tree
Hide file tree
Showing 24 changed files with 523 additions and 476 deletions.
30 changes: 20 additions & 10 deletions apps/gauzy/src/app/@shared/pipes/time-format.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import { Pipe, PipeTransform, OnDestroy } from '@angular/core';
import { Store } from '../../@core/services/store.service';
import { IOrganization } from '@gauzy/contracts';
import { filter, tap } from 'rxjs/operators';
import * as moment from 'moment';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { filter } from 'rxjs/operators';
import { IOrganization, TimeFormatEnum } from '@gauzy/contracts';
import { Store } from '../../@core/services/store.service';

@UntilDestroy({ checkProperties: true })
@Pipe({
name: 'timeFormat',
pure: false
})
export class TimeFormatPipe implements PipeTransform, OnDestroy {
private format: 12 | 24;
private format: TimeFormatEnum;

constructor(private store: Store) {
constructor(private readonly store: Store) {
this.store.selectedOrganization$
.pipe(
filter((organization: IOrganization) => !!organization),
tap((organization: IOrganization) => {
this.format = organization?.timeFormat ?? TimeFormatEnum.FORMAT_12_HOURS;
}),
untilDestroyed(this)
)
.subscribe((org: IOrganization) => {
this.format = org ? org.timeFormat : 12;
});
.subscribe();
}

transform(value: any, seconds: boolean = false): any {
/**
* Transforms a given value into a formatted time string.
* @param value The value to transform into a time string. This can be a string, number, Date object, or any value parsable by moment.js.
* @param timeFormat The time format to use. If not provided, it defaults to `this.format`.
* @param seconds Optional. If true, include seconds in the formatted time string. Defaults to false.
* @returns A formatted time string based on the input value and format options.
*/
transform(value: any, timeFormat: number = this.format, seconds: boolean = false): any {
let format = 'HH:mm' + (seconds ? ':ss' : '');
if (this.format === 12) {

if (timeFormat === TimeFormatEnum.FORMAT_12_HOURS) {
format = 'hh:mm' + (seconds ? ':ss' : '') + ' A';
}

let date = moment(value);
if (!date.isValid()) {
date = moment.utc(value, 'HH:mm');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ $status: 'basic';
}
.filter-item-list {
.filter-item {
max-width: 263px;
min-width: 220px;
}
.select-box,
nb-select {
Expand All @@ -51,23 +51,17 @@ $status: 'basic';
}

&:focus {
background-color: nb-theme(
select-outline-#{$status}-focus-background-color
);
background-color: nb-theme(select-outline-#{$status}-focus-background-color);
border-color: nb-theme(select-outline-#{$status}-focus-border-color);
}
&:hover {
background-color: nb-theme(
select-outline-#{$status}-hover-background-color
);
background-color: nb-theme(select-outline-#{$status}-hover-background-color);
border-color: nb-theme(select-outline-#{$status}-hover-border-color);
}

&[disabled] {
color: nb-theme(select-outline-#{$status}-disabled-text-color);
background-color: nb-theme(
select-outline-#{$status}-disabled-background-color
);
background-color: nb-theme(select-outline-#{$status}-disabled-background-color);
border-color: nb-theme(select-outline-#{$status}-disabled-border-color);

nb-icon {
Expand All @@ -81,14 +75,10 @@ $status: 'basic';
}

&.top {
border-top-color: nb-theme(
select-outline-#{$status}-adjacent-border-color
);
border-top-color: nb-theme(select-outline-#{$status}-adjacent-border-color);
}
&.bottom {
border-bottom-color: nb-theme(
select-outline-#{$status}-adjacent-border-color
);
border-bottom-color: nb-theme(select-outline-#{$status}-adjacent-border-color);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
<div class="col-auto ml-auto">
<div class="row filter-item-list align-items-end">
<ng-container *ngIf="hasTimeZoneFilter">
<div class="col-auto filter-item single-filter-wrapper">
<ga-timezone-filter></ga-timezone-filter>
<div class="col-auto single-filter-wrapper">
<ga-timezone-filter
[isTimeformat]="isTimeformat"
(timeFormatChange)="timeFormatChanged($event)"
(timeZoneChange)="timeZoneChanged($event)"
></ga-timezone-filter>
</div>
</ng-container>
<ng-container *ngIf="hasSourceFilter">
Expand All @@ -27,29 +31,22 @@
nbButton
status="basic"
outline
[nbPopover]="templateRef"
nbPopoverPlacement="bottom"
[nbPopover]="activityLevelSliderTemplate"
nbPopoverTrigger="click"
>
<span *ngIf="activityLevel?.start > 0 || activityLevel?.end < 100; else selectLabel">
<span
*ngIf="activityLevel?.start > 0 || activityLevel?.end < 100; else selectActivityLevelLabel"
>
{{ 'TIMESHEET.ACTIVITY_LEVEL' | translate }} : {{ activityLevel?.start }}% -
{{ activityLevel?.end }}%
</span>
<ng-template #selectLabel>
{{ 'TIMESHEET.SELECT_ACTIVITY_LEVEL' | translate }}
</ng-template>
<nb-icon icon="chevron-down-outline"></nb-icon>
</button>
<ng-template #templateRef>
<div class="p-3 slider-dropdown">
<ngx-slider
[value]="activityLevel?.start"
[highValue]="activityLevel?.end"
(userChange)="setActivityLevel($event)"
[options]="sliderOptions"
></ngx-slider>
</div>
</ng-template>
</div>
<ng-template #selectActivityLevelLabel>
{{ 'TIMESHEET.SELECT_ACTIVITY_LEVEL' | translate }}
</ng-template>
</ng-container>
<ng-container *ngIf="hasLogTypeFilter">
<div class="col-auto filter-item single-filter-wrapper">
Expand All @@ -75,3 +72,14 @@
</div>
</div>
</div>

<ng-template #activityLevelSliderTemplate>
<div class="p-3 slider-dropdown">
<ngx-slider
[value]="activityLevel?.start"
[highValue]="activityLevel?.end"
(userChange)="setActivityLevel($event)"
[options]="sliderOptions"
></ngx-slider>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -50,6 +50,7 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A
*/
private filters$: Subject<any> = new Subject();
private _filters: ITimeLogFilters = {
timeFormat: TimeFormatEnum.FORMAT_12_HOURS,
source: [],
logType: [],
activityLevel: ActivityLevel
Expand All @@ -67,6 +68,7 @@ export class GauzyFiltersComponent extends TranslationBaseComponent implements A
}
this.cd.detectChanges();
}
@Input() isTimeformat: boolean = false;

@Output() filtersChange: EventEmitter<ITimeLogFilters> = new EventEmitter();

Expand Down Expand Up @@ -108,24 +110,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) ||
Expand All @@ -135,11 +151,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
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -16,6 +16,7 @@ import { TimezoneFilterModule } from './timezone-filter/timezone-filter.module';
FormsModule,
NbButtonModule,
NbIconModule,
NbPopoverModule,
NbSelectModule,
NgxSliderModule,
PipesModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
<button
class="timezone-filter"
status="basic"
class="popover-button"
nbButton
size="small"
status="basic"
nbPopoverPlacement="bottom"
[nbPopover]="timezone"
[nbPopover]="nbPopoverTemplate"
nbPopoverTrigger="click"
nbButton
>
<div>{{ getTimeZoneWithOffset() }} / {{ selectedTimeFormat }} hour</div>
<div>
<ng-template [ngIf]="isTimezone"> {{ getTimeZoneWithOffset() }} </ng-template>
<ng-template [ngIf]="isTimeformat"> / {{ selectedTimeFormat }} hour </ng-template>
</div>
<nb-icon icon="more-vertical-outline"></nb-icon>
</button>

<!-- Manage Widgets -->
<ng-template #timezone>
<div class="timezone-popover">
<ng-template #nbPopoverTemplate>
<div class="popover-body">
<ng-container *ngIf="isTimezone">
<div class="category">
<div class="view">Time Zone</div>
Expand All @@ -33,7 +35,7 @@
</ng-container>
<ng-container *ngIf="isTimeformat">
<div class="category">
<div class="view">Time Format</div >
<div class="view">Time Format</div>
<ng-container *ngFor="let timeFormatsOption of timeFormatsOptions">
<div class="title" (click)="updateSelectedTimeFormat(timeFormatsOption)">
<i
Expand Down

0 comments on commit 8d5b18a

Please sign in to comment.