Skip to content

Commit

Permalink
Merge pull request #7007 from ever-co/fix/#6823-github-2way-sync
Browse files Browse the repository at this point in the history
Fix :: #6823 GitHub Automation Sync
  • Loading branch information
rahul-rocket authored Oct 18, 2023
2 parents c418f71 + 668b071 commit 73f6cde
Show file tree
Hide file tree
Showing 51 changed files with 1,360 additions and 195 deletions.
2 changes: 1 addition & 1 deletion .env.compose
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ CLIENT_BASE_URL=http://localhost:4200
#set to Website Platform
PLATFORM_WEBSITE_URL=https://gauzy.co

# DB_TYPE: sqlite | postgres
# DB_TYPE: sqlite | postgres | better-sqlite3
DB_TYPE=postgres
DB_SYNCHRONIZE=false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<nb-card-body>
<form [formGroup]="form">
<nb-tabset>
<nb-tab [tabTitle]="'ORGANIZATIONS_PAGE.MAIN' | translate">
<nb-tab [tabTitle]="'ORGANIZATIONS_PAGE.MAIN' | translate" [tabIcon]="'person-outline'">
<div class="project-tab-container">
<div class="project-image-container">
<div class="project-image-photo">
Expand Down Expand Up @@ -601,40 +601,102 @@
</div>
</div>
</div>

</nb-tab>
<nb-tab *ngIf="integration" [tabTitle]="'ORGANIZATIONS_PAGE.AUTOMATION' | translate">
<form [formGroup]="projectSettingForm">
<div class="fields">
<div class="row">
<div class="col-4">
<div class="form-group">
<label for="isTasksAutoSync" class="label">
{{ 'FORM.LABELS.AUTO_SYNC_TASKS' | translate }}
</label>
<nb-toggle
id="isTasksAutoSync"
class="d-block"
formControlName="isTasksAutoSync"
status="primary"
labelPosition="start"
(change)="updateProjectAutoSyncSetting()"
>
{{ 'FORM.PLACEHOLDERS.AUTO_SYNC_TASKS' | translate }}
</nb-toggle>
</div>
</div>
<div class="col-4">
<div class="form-group">
<label for="isTasksAutoSyncOnLabel" class="label">
{{ 'FORM.LABELS.AUTO_SYNC_TASKS_BASED_ON_LABEL' | translate }}
</label>
<nb-toggle
id="isTasksAutoSyncOnLabel"
class="d-block"
formControlName="isTasksAutoSyncOnLabel"
status="primary"
labelPosition="start"
(change)="updateProjectAutoSyncSetting()"
>
{{ 'FORM.PLACEHOLDERS.AUTO_SYNC_TASKS_BASED_ON_LABEL' | translate }}
</nb-toggle>
</div>
</div>
<div class="col-4">
<div class="form-group">
<label for="syncTag" class="label">
{{ 'FORM.LABELS.AUTO_SYNC_TAG' | translate }}
</label>
<input
id="syncTag"
type="text"
nbInput
fullWidth
formControlName="syncTag"
[placeholder]="'FORM.PLACEHOLDERS.AUTO_SYNC_TAG' | translate"
(change)="changeSyncTag($event)"
/>
</div>
</div>
</div>
</div>
</form>
</nb-tab>
</nb-tabset>
<div class="form-group action-buttons">
<button
class="mr-3"
(click)="navigateToCancelProject()"
nbButton
status="basic"
outline
>
{{ 'BUTTONS.CANCEL' | translate }}
</button>
<button
class="mr-3"
nbButton
status="success"
[disabled]="form.invalid"
(click)="onSubmit()"
>
{{ 'BUTTONS.SAVE' | translate }}
</button>
<button
*ngIf="
form.get('taskListType').value ===
TaskListTypeEnum.SPRINT && project
"
nbButton
class="float-right"
status="success"
(click)="openTasksSettings()"
>
{{ 'BUTTONS.MANAGE_SPRINTS' | translate }}
</button>
</div>
<ng-container [ngTemplateOutlet]="actionButtons"></ng-container>
</form>
</nb-card-body>
</nb-card>

<ng-template #actionButtons >
<div class="form-group action-buttons">
<button
class="mr-3"
(click)="navigateToCancelProject()"
nbButton
status="basic"
outline
>
{{ 'BUTTONS.CANCEL' | translate }}
</button>
<button
class="mr-3"
nbButton
status="success"
[disabled]="form.invalid"
(click)="onSubmit()"
>
{{ 'BUTTONS.SAVE' | translate }}
</button>
<ng-template [ngIf]="project">
<button
*ngIf="form.get('taskListType').value === TaskListTypeEnum.SPRINT"
nbButton
class="float-right"
status="success"
(click)="openTasksSettings()"
>
{{ 'BUTTONS.MANAGE_SPRINTS' | translate }}
</button>
</ng-template>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import {
AfterViewInit,
Component,
EventEmitter,
Input,
OnInit,
Output,
TemplateRef,
ViewChild
} from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import {
IEmployee,
IOrganization,
Expand All @@ -23,14 +32,14 @@ import {
import { TranslateService } from '@ngx-translate/core';
import { Router } from '@angular/router';
import { uniq } from 'underscore';
import { EMPTY } from 'rxjs';
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 { environment as ENV } from '../../../../environments/environment';
import {
ErrorHandlingService,
OrganizationContactService,
Expand All @@ -51,7 +60,7 @@ import { ckEditorConfig } from "../../ckeditor.config";
styleUrls: ['./project-mutation.component.scss']
})
export class ProjectMutationComponent extends TranslationBaseComponent
implements OnInit {
implements AfterViewInit, OnInit {

public FormHelpers: typeof FormHelpers = FormHelpers;
public OrganizationProjectBudgetTypeEnum = OrganizationProjectBudgetTypeEnum;
Expand Down Expand Up @@ -84,7 +93,7 @@ export class ProjectMutationComponent extends TranslationBaseComponent
name: [null, Validators.required],
organizationContact: [],
billing: [ProjectBillingEnum.RATE],
currency: [ENV.DEFAULT_CURRENCY],
currency: [environment.DEFAULT_CURRENCY],
startDate: [],
endDate: [],
owner: [ProjectOwnerEnum.CLIENT],
Expand All @@ -95,13 +104,17 @@ export class ProjectMutationComponent extends TranslationBaseComponent
budget: [],
budgetType: [OrganizationProjectBudgetTypeEnum.HOURS],
openSource: [],
projectUrl: [null, Validators.compose([
Validators.pattern(new RegExp(patterns.websiteUrl))
])
projectUrl: [
null,
Validators.compose([
Validators.pattern(new RegExp(patterns.websiteUrl))
])
],
openSourceProjectUrl: [null, Validators.compose([
Validators.pattern(new RegExp(patterns.websiteUrl))
])
openSourceProjectUrl: [
null,
Validators.compose([
Validators.pattern(new RegExp(patterns.websiteUrl))
])
]
}, {
validators: [
Expand All @@ -112,6 +125,20 @@ export class ProjectMutationComponent extends TranslationBaseComponent
return form;
}

/*
* Project Setting Mutation Form
*/

public projectSettingForm: FormGroup = ProjectMutationComponent.buildSettingForm(this._fb);
static buildSettingForm(fb: FormBuilder): FormGroup {
const form = fb.group({
isTasksAutoSync: [],
isTasksAutoSyncOnLabel: [],
syncTag: []
});
return form;
}

/**
* Represents an integration tenant or a boolean value.
*/
Expand Down Expand Up @@ -140,6 +167,11 @@ export class ProjectMutationComponent extends TranslationBaseComponent
@Output() canceled = new EventEmitter();
@Output() onSubmitted = new EventEmitter();

/*
* Actions Buttons directive
*/
@ViewChild('actionButtons', { static: true }) actionButtons: TemplateRef<any>;

constructor(
private readonly _router: Router,
private readonly _fb: FormBuilder,
Expand Down Expand Up @@ -170,14 +202,39 @@ export class ProjectMutationComponent extends TranslationBaseComponent
.subscribe();
}

/**
* Lifecycle hook that is called after the component's view has been initialized.
* It sets up an event listener for changes to the 'syncTag' form control.
*/
ngAfterViewInit(): void {
// Get a reference to the 'isTasksAutoSyncOnLabel' form control within the 'projectSettingForm'.
const isTasksAutoSyncOnLabelControl = <FormControl>this.projectSettingForm.get('isTasksAutoSyncOnLabel');
const syncTagControl = <FormControl>this.projectSettingForm.get('syncTag');

isTasksAutoSyncOnLabelControl.valueChanges
.pipe(
switchMap((value: boolean) => {
if (value) {
syncTagControl.enable();
} else {
syncTagControl.disable();
}
syncTagControl.updateValueAndValidity();
return of(value); // Emit the same value.
}),
untilDestroyed(this) // Automatically unsubscribe when the component is destroyed.
)
.subscribe();
}

/**
* Load default organization currency
*/
private _loadDefaultCurrency() {
if (!this.organization) {
return;
}
const { currency = ENV.DEFAULT_CURRENCY } = this.organization;
const currency = this.organization.currency || environment.DEFAULT_CURRENCY;
if (currency) {
this.form.get('currency').setValue(currency);
this.form.get('currency').updateValueAndValidity();
Expand Down Expand Up @@ -276,6 +333,14 @@ export class ProjectMutationComponent extends TranslationBaseComponent

});
this.form.updateValueAndValidity();

/** Project Integration Setting Patch Value*/
this.projectSettingForm.patchValue({
isTasksAutoSync: project.isTasksAutoSync || false,
isTasksAutoSyncOnLabel: project.isTasksAutoSyncOnLabel || false,
syncTag: project.syncTag || ''
});
this.projectSettingForm.updateValueAndValidity();
}

/**
Expand Down Expand Up @@ -519,4 +584,71 @@ export class ProjectMutationComponent extends TranslationBaseComponent
this._errorHandler.handleError(error);
}
}

/**
*
*/
public changeSyncTag() {
this.updateProjectAutoSyncSetting();
}


/**
* Updates project auto-sync settings.
* This method is typically invoked in response to user actions.
*/
public updateProjectAutoSyncSetting() {
// Check if the 'organization' or 'integration' properties are not available.
if (!this.organization || !this.integration) {
return; // Abort the method execution.
}

/** */
try {
// Set the 'loading' property to 'false' to indicate that data loading is not in progress.
this.loading = false;

// Extract the 'organizationId' and 'tenantId' from the 'organization' property.
const { id: organizationId, tenantId } = this.organization;

// Extract the 'projectId' from the 'project' property.
const { id: projectId } = this.project;

// Create a 'request' object of type 'IOrganizationProjectSetting'.
// It contains 'organizationId', 'tenantId', and auto-sync settings taken from 'this.projectSettingForm.value'.
const request: IOrganizationProjectSetting = {
organizationId,
tenantId,
...this.projectSettingForm.value
}

// Call the 'updateProjectSetting' method of the '_organizationProjectsService'
// to update project settings with 'projectId' and the 'request'
this._organizationProjectsService.updateProjectSetting(projectId, request).pipe(
tap((response: any) => {
if (response['status'] == HttpStatus.BAD_REQUEST) {
throw new Error(`${response['message']}`);
}
}),
tap(() => {
this._toastrService.success('NOTES.ORGANIZATIONS.EDIT_ORGANIZATIONS_PROJECTS.AUTO_SYNC_SETTING', {
project: this.project.name
});
}),
catchError((error) => {
this._errorHandler.handleError(error);
return EMPTY;
}),
// Execute the following code block when the observable completes or errors
finalize(() => {
// Set the 'loading' flag to false to indicate that data loading is complete
this.loading = false;
}),
// Automatically unsubscribe when the component is destroyed
untilDestroyed(this)
).subscribe();
} catch (error) {
this._errorHandler.handleError(error);
}
}
}
Loading

0 comments on commit 73f6cde

Please sign in to comment.