Skip to content

Commit

Permalink
Feat/#6409 away active switch user (#6446)
Browse files Browse the repository at this point in the history
* feat: add new attribute to employee

* feat: alter table employee adding isAway column

* feat: update update profile dto

* feat: add new translation (en.json)

* feat: import spinner module

* fix: translation

* feat: update view
  • Loading branch information
adkif authored Jul 1, 2023
1 parent d43a016 commit d567c02
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div gauzyOutside (clickOutside)="onClickOutside($event)" class="main-menu">
<div class="left-menu">
<!-- TODO: Implement commented features -->
<!-- <div underConstruction class="sub-menu">
<div [nbSpinner]="isSubmit$ | async" class="left-menu">
<!-- TODO: Implement commented features -->
<!-- <div underConstruction class="sub-menu">
<span><i class="far fa-smile"></i>
{{ 'USER_MENU.STATUS' | translate }}</span>
<div class="status">
Expand Down Expand Up @@ -32,48 +32,69 @@
</div>
</div>
</div> -->
<div class="links">
<p class="link" underConstruction>
{{ 'USER_MENU.SET_YOURSELF_AS_AWAY' | translate }}
</p>
<p class="link" routerLink="/pages/auth/profile">
{{ 'USER_MENU.PROFILE' | translate }}
</p>
<p class="link" routerLink="/auth/logout">
{{ 'USER_MENU.SIGN_OUT' | translate }}
</p>
</div>
<div class="sub-user-menu">
<gauzy-user showIdentity="true" [user]="user" (clicked)="onClick()"></gauzy-user>
</div>
</div>
<div class="links">
<p
*ngIf="employee$ | async"
[ngClass]="{'disabled-table': (isSubmit$ | async)}"
class="link"
[innerHTML]="
((employee$ | async)?.isAway
?
'USER_MENU.SET_YOURSELF_AS_ACTIVE'
: 'USER_MENU.SET_YOURSELF_AS_AWAY'
) | translate
"
(click)="onChangeStatus()"
></p>
<p class="link" routerLink="/pages/auth/profile">
{{ 'USER_MENU.PROFILE' | translate }}
</p>
<p class="link" routerLink="/auth/logout">
{{ 'USER_MENU.SIGN_OUT' | translate }}
</p>
</div>
<div class="sub-user-menu">
<gauzy-user
showIdentity="true"
[user]="user$ | async"
(clicked)="onClick()"
></gauzy-user>
</div>
</div>

<div class="right-menu">
<span><i (click)="onClick()" class="fas fa-times"></i></span>
<div class="download-apps-content">
<span class="download-apps-label">Download Apps:</span>
<span class="download-apps-icons">
<a *ngFor="let app of downloadApps" target="_blank" [href]="app.link" rel="noopener">
<i [class]="app.icon"></i>
</a>
</span>
</div>
<p>
<a target="_blank" href="https://gauzy.co">{{
'USER_MENU.HELP' | translate
}}</a>
</p>
<p class="link" underConstruction>
{{ 'USER_MENU.HOTKEYS' | translate }}
</p>
<p>
<ngx-theme-language-selector class="theme"></ngx-theme-language-selector>
</p>
<p>
<gauzy-switch-theme class="theme"></gauzy-switch-theme>
</p>
<p>
<gauzy-theme-selector class="theme"></gauzy-theme-selector>
</p>
</div>
<div class="right-menu">
<span><i (click)="onClick()" class="fas fa-times"></i></span>
<div class="download-apps-content">
<span class="download-apps-label">Download Apps:</span>
<span class="download-apps-icons">
<a
*ngFor="let app of downloadApps"
target="_blank"
[href]="app.link"
rel="noopener"
>
<i [class]="app.icon"></i>
</a>
</span>
</div>
<p>
<a target="_blank" href="https://gauzy.co">{{
'USER_MENU.HELP' | translate
}}</a>
</p>
<p class="link" underConstruction>
{{ 'USER_MENU.HOTKEYS' | translate }}
</p>
<p>
<ngx-theme-language-selector
class="theme"
></ngx-theme-language-selector>
</p>
<p>
<gauzy-switch-theme class="theme"></gauzy-switch-theme>
</p>
<p>
<gauzy-theme-selector class="theme"></gauzy-theme-selector>
</p>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,8 @@
}
}
}
.disabled-table {
pointer-events: none;
opacity: 0.5;
}
}
112 changes: 95 additions & 17 deletions apps/gauzy/src/app/@theme/components/user-menu/user-menu.component.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,129 @@
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { NbDialogService } from '@nebular/theme';
import { IUser } from '@gauzy/contracts';
import { IEmployee, IUser, IEmployeeUpdateInput } from '@gauzy/contracts';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { BehaviorSubject, tap, Observable, filter, firstValueFrom } from 'rxjs';
import { EmployeesService, ErrorHandlingService } from '../../../@core';

@UntilDestroy({ checkProperties: true })
@Component({
selector: 'gauzy-user-menu',
templateUrl: './user-menu.component.html',
styleUrls: ['./user-menu.component.scss']
styleUrls: ['./user-menu.component.scss'],
})
export class UserMenuComponent implements OnInit {
@Input() user: IUser;
@Output() close: EventEmitter<any> = new EventEmitter<any>(null);
private _user$: BehaviorSubject<IUser>;
private _employee$: BehaviorSubject<IEmployee>;
private _isSubmit$: BehaviorSubject<boolean>;

clicks: boolean[] = [];
@Output()
public close: EventEmitter<any> = new EventEmitter<any>(null);

downloadApps = [
public clicks: boolean[] = [];

public downloadApps = [
{
link: 'https://web.gauzy.co/downloads#desktop/apple',
icon: 'fab fa-apple'
icon: 'fab fa-apple',
},
{
link: 'https://web.gauzy.co/downloads#desktop/windows',
icon: 'fa-brands fa-windows'
icon: 'fa-brands fa-windows',
},
{
link: 'https://web.gauzy.co/downloads#desktop/linux',
icon: 'fa-brands fa-linux'
icon: 'fa-brands fa-linux',
},
{
link: 'https://web.gauzy.co/downloads#mobile',
icon: 'fas fa-mobile'
icon: 'fas fa-mobile',
},
{
link: 'https://web.gauzy.co/downloads#extensions',
icon: 'fa-brands fa-chrome'
}
icon: 'fa-brands fa-chrome',
},
];

constructor(private dialogService: NbDialogService) {}
constructor(
private readonly _employeeService: EmployeesService,
private readonly _errorHandler: ErrorHandlingService
) {
this._user$ = new BehaviorSubject(null);
this._employee$ = new BehaviorSubject(null);
this._isSubmit$ = new BehaviorSubject(false);
}

ngOnInit(): void {
this.user$
.pipe(
filter(({ employee }) => !!employee),
tap(async (user: IUser) => {
this._isSubmit$.next(true);
const employee = await firstValueFrom(
this._employeeService.getEmployeeById(user.employeeId)
);
this._employee$.next(employee);
this._isSubmit$.next(false);

}),

ngOnInit(): void {}
untilDestroyed(this)
)
.subscribe();
}

onClick() {
public onClick() {
this.close.emit();
}

onClickOutside(event: boolean) {
public onClickOutside(event: boolean) {
this.clicks.push(event);
if (!event && this.clicks.length > 1) this.onClick();
}

public async onChangeStatus(): Promise<void> {
try {
if (!this.employee) {
return;
}
this._isSubmit$.next(true);
const { id, isAway, tenantId, organizationId } = this.employee;
const payload: IEmployeeUpdateInput = {
isAway: !isAway,
tenantId,
organizationId,
};
await this._employeeService.updateProfile(id, payload);
this._employee$.next({ ...this.employee, ...payload });
} catch (error) {
this._errorHandler.handleError(error);
}
this._isSubmit$.next(false);
}

public get employee(): IEmployee {
return this._employee$.getValue();
}

public get employee$(): Observable<IEmployee> {
return this._employee$.asObservable();
}

@Input()
public set user(value: IUser) {
if (value) {
this._user$.next(value);
}
}

public get user(): IUser {
return this._user$.getValue();
}

public get user$(): Observable<IUser> {
return this._user$.asObservable();
}

public get isSubmit$(): Observable<boolean> {
return this._isSubmit$.asObservable();
}
}
6 changes: 4 additions & 2 deletions apps/gauzy/src/app/@theme/theme.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
NbThemeModule,
NbPopoverModule,
NbTooltipModule,
NbLayoutDirectionService
NbLayoutDirectionService,
NbSpinnerModule
} from '@nebular/theme';
import { NbEvaIconsModule } from '@nebular/eva-icons';
import { NbSecurityModule } from '@nebular/security';
Expand Down Expand Up @@ -88,7 +89,8 @@ const NB_MODULES = [
NbEvaIconsModule,
NbAccordionModule,
NbToggleModule,
NbCardModule
NbCardModule,
NbSpinnerModule
];

const MODULES = [
Expand Down
3 changes: 2 additions & 1 deletion apps/gauzy/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4085,7 +4085,8 @@
"UNTIL_TOMORROW": "Until tomorrow",
"CUSTOM": "Custom",
"SET_AS_NOTIFICATION_SCHEDULE": "Set as notification schedule",
"SET_YOURSELF_AS_AWAY": "Set yourself as away",
"SET_YOURSELF_AS_AWAY": "Set yourself as <strong>away</strong> 😴",
"SET_YOURSELF_AS_ACTIVE": "Set yourself as <strong>active</strong>",
"HOTKEYS": "Hotkeys",
"HELP": "Help",
"SIGN_OUT": "Sign Out",
Expand Down
8 changes: 8 additions & 0 deletions packages/contracts/src/employee.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export interface IEmployee extends IBasePerTenantAndOrganizationEntityModel {
isOnline?: boolean;
/** Employee time tracking status */
isTrackingTime?: boolean;
// True mean active, false away
isAway?: boolean;
}

export type IEmployeeJobsStatisticsResponse = IEmployee & IEmployeeJobsStatistics;
Expand All @@ -119,6 +121,8 @@ export interface IEmployeeFindInput {
isOnline?: boolean;
/** Employee time tracking status */
isTrackingTime?: boolean;
// True mean active, false away
isAway?: boolean;
}

export interface IEmployeeUpdateInput extends IBasePerTenantAndOrganizationEntityModel {
Expand Down Expand Up @@ -157,6 +161,8 @@ export interface IEmployeeUpdateInput extends IBasePerTenantAndOrganizationEntit
isOnline?: boolean;
/** Employee time tracking status */
isTrackingTime?: boolean;
// True mean active, false away
isAway?: boolean;
}

export interface IEmployeeCreateInput extends IBasePerTenantAndOrganizationEntityModel {
Expand All @@ -182,6 +188,8 @@ export interface IEmployeeCreateInput extends IBasePerTenantAndOrganizationEntit
isOnline?: boolean;
/** Employee time tracking status */
isTrackingTime?: boolean;
// True mean active, false away
isAway?: boolean;
}

export interface ISelectedEmployee {
Expand Down
Loading

0 comments on commit d567c02

Please sign in to comment.