Skip to content

Commit

Permalink
Merge pull request #7023 from ever-co/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Oct 21, 2023
2 parents 0d5167f + c702fdd commit 0a318ba
Show file tree
Hide file tree
Showing 103 changed files with 2,152 additions and 704 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

We released [Ever Teams](https://github.com/ever-co/ever-teams) platform for Work & Project Management.
Please check <https://github.com/ever-co/ever-teams> and make it ⭐ on GitHub!
It's built with React / ReactNative (Expo) stack and connects to headless Ever Gauzy Platform APIs.
It's built with a React / ReactNative (Expo) stack and connects to headless [Ever Gauzy Platform APIs](https://api.gauzy.co/swg).

## 🌟 What is it

Expand Down Expand Up @@ -41,6 +41,7 @@ Main features:

A more detailed list of the features available in the platform:

- [Headless APIs](https://api.gauzy.co/swg)
- Dashboard (provides an overview of different metrics, such as company income/expenses, employee bonuses, etc.)
- Time Management / Time Tracking / Activity Tracking / Timesheets
- Employees Management (register of company employees/contractors, rates of employees, etc.)
Expand Down
8 changes: 7 additions & 1 deletion apps/gauzy/src/app/@core/services/email.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { IEmailHistory, IEmailFindInput, IEmailUpdateInput, IPagination } from '@gauzy/contracts';
import { IEmailHistory, IEmailFindInput, IEmailUpdateInput, IPagination, IResendEmailInput } from '@gauzy/contracts';
import { toParams } from '@gauzy/common-angular';
import { firstValueFrom } from 'rxjs';
import { API_PREFIX } from '../constants/app.constants';
Expand Down Expand Up @@ -35,4 +35,10 @@ export class EmailService {
this.http.put<IEmailHistory>(`${API_PREFIX}/email/${id}`, body)
);
}

resend(emailInput: IResendEmailInput): Promise<any> {
return firstValueFrom(
this.http.post<IEmailHistory>(`${API_PREFIX}/email/resend/`, emailInput)
);
}
}
12 changes: 12 additions & 0 deletions apps/gauzy/src/app/@core/services/github/github.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
IGithubIssue,
IGithubRepository,
IGithubRepositoryResponse,
IIntegrationMapSyncRepository,
IIntegrationTenant,
IOrganization,
IOrganizationGithubRepository,
IOrganizationProject
} from '@gauzy/contracts';
import { Observable, firstValueFrom } from 'rxjs';
Expand Down Expand Up @@ -130,4 +132,14 @@ export class GithubService {
body
}));
}

/**
* Synchronize a GitHub repository.
* @param input The synchronization input data.
* @returns An Observable of the synchronized IntegrationMap.
*/
syncGithubRepository(input: IIntegrationMapSyncRepository): Observable<IOrganizationGithubRepository> {
const url = `${API_PREFIX}/integration/github/repository/sync`;
return this._http.post<IOrganizationGithubRepository>(url, input);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@
<div class="col-4">
<div class="h-12 w-12 flex-shrink-0">
<ngx-github-repository-selector
[sourceId]="project?.externalRepositoryId"
[sourceId]="project?.repository?.repositoryId"
[integration]="integration"
(onChanged)="selectRepository($event)"
></ngx-github-repository-selector>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import {
ViewChild
} from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { EMPTY, of, switchMap } from 'rxjs';
import { catchError, debounceTime, filter, finalize, tap } from 'rxjs/operators';
import { CKEditor4 } from 'ckeditor4-angular/ckeditor';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateService } from '@ngx-translate/core';
import { Router } from '@angular/router';
import { uniq } from 'underscore';
import { environment } from '@env/environment';
import {
IEmployee,
IOrganization,
Expand All @@ -27,21 +35,16 @@ import {
IIntegrationTenant,
IGithubRepository,
IOrganizationProjectSetting,
HttpStatus
HttpStatus,
IIntegrationMapSyncRepository,
IOrganizationGithubRepository
} from '@gauzy/contracts';
import { TranslateService } from '@ngx-translate/core';
import { Router } from '@angular/router';
import { uniq } from 'underscore';
import { EMPTY, of, switchMap } from 'rxjs';
import { catchError, debounceTime, filter, finalize, tap } from 'rxjs/operators';
import { distinctUntilChange } from '@gauzy/common-angular';
import { CKEditor4 } from 'ckeditor4-angular/ckeditor';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { environment } from '@env/environment';
import { TranslationBaseComponent } from '../../language-base/translation-base.component';
import { patterns } from '../../regex/regex-patterns.const';
import {
ErrorHandlingService,
GithubService,
OrganizationContactService,
OrganizationProjectsService,
OrganizationTeamsService,
Expand Down Expand Up @@ -181,6 +184,7 @@ export class ProjectMutationComponent extends TranslationBaseComponent
private readonly _errorHandler: ErrorHandlingService,
private readonly _organizationTeamService: OrganizationTeamsService,
private readonly _organizationContactService: OrganizationContactService,
private readonly _githubService: GithubService,
private readonly _organizationProjectsService: OrganizationProjectsService,
) {
super(translateService);
Expand Down Expand Up @@ -547,16 +551,24 @@ export class ProjectMutationComponent extends TranslationBaseComponent

const { id: organizationId, tenantId } = this.organization;
const { id: projectId } = this.project;
const externalRepositoryId = repository.id;
const integrationId = this.integration['id'];

/** */
const request: IOrganizationProjectSetting = {
const request: IIntegrationMapSyncRepository = {
organizationId,
tenantId,
externalRepositoryId
integrationId,
repository
}

this._organizationProjectsService.updateProjectSetting(projectId, request).pipe(
// Fetch entity settings by integration ID and handle the result as an observable
this._githubService.syncGithubRepository(request).pipe(
switchMap(({ id: repositoryId }: IOrganizationGithubRepository) => {
return this._organizationProjectsService.updateProjectSetting(projectId, {
organizationId,
tenantId,
repositoryId
});
}),
tap((response: any) => {
if (response['status'] == HttpStatus.BAD_REQUEST) {
throw new Error(`${response['message']}`);
Expand Down Expand Up @@ -586,7 +598,8 @@ export class ProjectMutationComponent extends TranslationBaseComponent
}

/**
*
* Trigger a change in the synchronization tag for project auto-sync settings.
* This function updates the project's auto-sync settings.
*/
public changeSyncTag() {
this.updateProjectAutoSyncSetting();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</div>
</div>
</div>
<div class="col-1">
<div *ngIf="member?.isWorkingToday" class="col-1">
<nb-badge
[status]="progressStatus(member?.activity || 0)"
[text]="(member?.activity || 0) + '%'"
Expand All @@ -75,10 +75,10 @@
>
</nb-progress-bar>
</div>
<div class="col-3 text-right">
<div [class]="member?.isWorkingToday ? 'col-3 text-right' : 'col-4'">
{{member?.todayWorkDuration > 0 ? humanize(member?.todayWorkDuration) : ('ORGANIZATIONS_PAGE.NOT_WORKED'|translate)}}
</div>
<div class="col-1">
<div *ngIf="member?.isWorkingToday" class="col-1">
<nb-badge
[status]="progressStatus(member?.activity || 0)"
[text]="(member?.activity || 0) + '%'"
Expand Down
42 changes: 31 additions & 11 deletions apps/gauzy/src/app/pages/dashboard/team/team.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ITimeLog,
ReportGroupFilterEnum
} from '@gauzy/contracts';
import { debounceTime, tap } from 'rxjs';
import { combineLatest, debounceTime, tap } from 'rxjs';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateService } from '@ngx-translate/core';
import { DateRangePickerBuilderService, OrganizationTeamsService, Store } from '../../../@core';
Expand All @@ -27,6 +27,7 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
private _countsStatistics: any;
private _dailyLogs: any[] = [];
private _selectedEmployee: ISelectedEmployee;
private _selectedOrganizationTeam: IOrganizationTeam;

constructor(
private readonly _organizationTeamsService: OrganizationTeamsService,
Expand All @@ -42,6 +43,7 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
isSelected: false
};
this._isLoading = false;
this._selectedOrganizationTeam = null;
}

private _isLoading: boolean;
Expand Down Expand Up @@ -132,10 +134,14 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
untilDestroyed(this)
)
.subscribe();
this._store.selectedEmployee$
combineLatest([
this._store.selectedEmployee$,
this._store.selectedTeam$,
])
.pipe(
tap((employee: ISelectedEmployee) => {
tap(([employee, organizationTeam]) => {
this._selectedEmployee = employee;
this._selectedOrganizationTeam = organizationTeam;
}),
tap(() => this.subject$.next(true)),
untilDestroyed(this)
Expand Down Expand Up @@ -191,16 +197,24 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
this._todayTeamsWorkers = this._teams
.map((team) => {
const isTeamMember = team.members.some((member) => member.employeeId === this._selectedEmployee.id);
if (!isTeamMember && this._selectedEmployee.id) {
if (
(!isTeamMember && this._selectedEmployee?.id) ||
(this._selectedOrganizationTeam.id &&
team.id !== this._selectedOrganizationTeam.id)
) {
return null;
}
const members = team.members.map((member) => {
const memberDailyLog = this._dailyLogs.filter(
(dailyLog) => dailyLog.employee.userId === member.employee.userId
)[0];
const logs = this._logs
.map((log) => (log.employee.userId === member.employee.userId ? log : null))
.filter((log) => !!log);
const [memberDailyLog] = this._dailyLogs.filter(
(dailyLog) =>
dailyLog.employee.userId === member.employee.userId
);
const logs = this._logs.filter(
(log) =>
!!log &&
log.employee.userId === member.employee.userId &&
log.organizationTeamId === team.id
);
const isWorkingToday = logs.length > 0;
const groupByTask = isWorkingToday ? this._groupBy('taskId', logs) : [];
const groupByProject = isWorkingToday ? this._groupBy('projectId', logs) : [];
Expand All @@ -214,6 +228,12 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
}, 0)
};
});
const todayWorkDuration = tasks.reduce(
(accumulator: number, task) => {
return accumulator + task?.duration || 0;
},
0
);
const proj = projectKeys.map((value: string) => {
return {
...groupByProject[value][0].project
Expand All @@ -223,7 +243,7 @@ export class TeamComponent extends BaseSelectorFilterComponent implements OnInit
return {
...member,
isRunningTimer: isWorkingToday ? logs.reverse()[0].isRunning : false,
todayWorkDuration: memberDailyLog ? memberDailyLog.sum : null,
todayWorkDuration,
isWorkingToday: isWorkingToday,
tasks: tasks,
projects: proj,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h5>{{ 'INTEGRATIONS.GITHUB_PAGE.NAME' | translate }}</h5>
</div>
<div class="issues-container">
<ngx-github-repository-selector
[sourceId]="(project$ | async)?.externalRepositoryId"
[sourceId]="(project$ | async)?.repository?.repositoryId"
[integration]="integration"
(onChanged)="selectRepository($event)"
[selected]="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class GithubViewComponent extends TranslationBaseComponent implements Aft
// Extract project properties
const { id: projectId } = this.project = project;

return this._organizationProjectsService.getById(projectId).pipe(
return this._organizationProjectsService.getById(projectId, ['repository']).pipe(
catchError((error) => {
// Handle and log errors
this._errorHandlingService.handleError(error);
Expand Down
25 changes: 25 additions & 0 deletions apps/gauzy/src/app/pages/jobs/search/search/search.component.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import 'gauzy/_gauzy-table.scss';
@import 'gauzy/_gauzy-overrides';
@import 'gauzy/_gauzy-cards.scss';

:host {
.form-group {
nb-select,
Expand Down Expand Up @@ -140,3 +141,27 @@
@include input-appearance(2rem, var(--gauzy-card-4));
}
}

nb-tabset {
// browse tab
nb-tab:nth-child(2) {
& div:nth-child(1) {
padding-right: 0;
--scrollbar-width: 0;
}
}
// search tab
nb-tab:nth-child(3) {
overflow-y: scroll;

& div:nth-child(1) {
margin-right: 0 !important;
}

& div:nth-child(2) {
padding-right: 0;
--scrollbar-width: 0;
min-height: 80%;
}
}
}
3 changes: 2 additions & 1 deletion apps/gauzy/src/app/pages/projects/projects-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ const routes: Routes = [
'organization',
'members.user',
'tags',
'teams'
'teams',
'repository'
],
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ <h4 class="email-history-header">
*ngFor="let email of emails"
>
<div
class="email-list-item"
class="email-list-item w-100"
[ngClass]="{
selected: selectedEmail.id === email.id
}"
Expand All @@ -51,9 +51,9 @@ <h4 class="email-history-header">
[name]="
email?.user?.name
? email?.user?.name
: '...'
: ('SETTINGS.EMAIL_HISTORY.SYSTEM' | translate)
"
[src]="getUrl(email?.email)"
[src]="getUrl(email)"
></ngx-avatar>
</div>
<div class="date" [title]="email?.email">
Expand Down Expand Up @@ -130,17 +130,19 @@ <h4 class="email-history-header">
}}</b>
</span>
</div>
<button
*ngIf="selectedEmail"
class="email-history-archive"
status="primary"
outline
nbButton
size="small"
(click)="archive()"
>
{{ 'SETTINGS.EMAIL_HISTORY.ARCHIVE' | translate }}
</button>
<div class="email-history-archive">
<button status="basic" *ngIf="
selectedEmail?.status &&
selectedEmail?.status == EmailStatusEnum.FAILED
" outline nbButton size="small" (click)="resend()">
{{ 'SETTINGS.EMAIL_HISTORY.RESEND' | translate }}
</button>

<button *ngIf="selectedEmail" status="primary" outline nbButton size="small" (click)="archive()">
{{ 'SETTINGS.EMAIL_HISTORY.ARCHIVE' | translate }}
</button>
</div>

<ng-container *ngIf="selectedEmail; else emailNotSelected">
<div class="custom-parent-email-content">
<div
Expand Down
Loading

0 comments on commit 0a318ba

Please sign in to comment.