Skip to content

Commit

Permalink
Merge pull request #7565 from ever-co/fix/#7246-gauzy-ai-integration
Browse files Browse the repository at this point in the history
[Fix] #7246 Gauzy AI Integration
  • Loading branch information
rahul-rocket authored Feb 22, 2024
2 parents 84ca23b + 1b695de commit f8e24d7
Show file tree
Hide file tree
Showing 24 changed files with 603 additions and 226 deletions.
14 changes: 10 additions & 4 deletions apps/gauzy/src/app/@core/services/gauzy-ai/gauzy-ai.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@ import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/internal/Observable';
import { IIntegrationAICreateInput, IIntegrationTenant } from '@gauzy/contracts';
import { API_PREFIX } from '../../constants';
import { CrudService } from '../crud/crud.service';

@Injectable({
providedIn: 'root',
})
export class GauzyAIService {
export class GauzyAIService extends CrudService<IIntegrationTenant> {

static readonly API_URL = `${API_PREFIX}/integration/gauzy-ai`;

constructor(
private readonly _http: HttpClient
) { }
) {
super(_http, GauzyAIService.API_URL);
}

/**
* Create a new integration AI.
*
* @param input
* @returns
* @param input - Data for creating the integration AI, of type IIntegrationAICreateInput.
* @returns An Observable of type IIntegrationTenant representing the created integration AI.
*/
create(input: IIntegrationAICreateInput): Observable<IIntegrationTenant> {
return this._http.post<IIntegrationTenant>(`${API_PREFIX}/integration/gauzy-ai`, input);
Expand Down
1 change: 1 addition & 0 deletions apps/gauzy/src/app/@core/services/integration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './integration-entity-setting-store.service';
export * from './integration-entity-setting.service';
export * from './integration-map.service';
export * from './integration-tenant.service';
export * from './integration-setting.service';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { IIntegrationSetting } from '@gauzy/contracts';
import { API_PREFIX } from '../../constants';
import { CrudService } from '../crud/crud.service';

@Injectable({
providedIn: 'root'
})
export class IntegrationSettingService extends CrudService<IIntegrationSetting> {

static readonly API_URL = `${API_PREFIX}/integration-setting`;

constructor(
readonly _http: HttpClient
) {
super(_http, IntegrationSettingService.API_URL)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<ng-container *ngIf="items.length">
<nb-card class="mb-3">
<nb-card-body>
<div class="row">
<div class="col-12 mb-3">
<div class="row">
<div class="col-6 text-left">
<header>{{ title }}</header>
</div>
<div class="col-6 text-right">
<ng-template [ngIf]="isIntegrationAISettingsEdit" [ngIfElse]="editButtonTemplate">
<button
status="basic"
outline
nbButton
size="tiny"
class="mr-2"
(click)="toggleIntegrationAISettings()"
>
{{ 'BUTTONS.CANCEL' | translate }}
</button>
<button
nbButton
type="button"
status="success"
size="tiny"
(click)="saveSettings()"
>
{{ 'BUTTONS.SAVE' | translate }}
</button>
</ng-template>
<ng-template #editButtonTemplate>
<button
nbButton
type="button"
status="success"
size="tiny"
(click)="toggleIntegrationAISettings()"
>
<nb-icon class="mr-1" icon="edit-outline"></nb-icon>
{{ 'BUTTONS.EDIT' | translate }}
</button>
</ng-template>
</div>
</div>
</div>
<div class="col-12">
<div class="integration-container">
<ng-container
*ngTemplateOutlet="settingTemplate; context: {
$implicit: items,
isEdit: isIntegrationAISettingsEdit
}">
</ng-container>
</div>
</div>
</div>
</nb-card-body>
</nb-card>
</ng-container>

<ng-template let-settings let-isEdit="isEdit" #settingTemplate>
<div class="integration-row" *ngFor="let setting of settings">
<div class="integration-label-container">
<div class="integration-label">
{{ getTitleForSetting(setting) }}
<nb-icon icon="info-outline" size="small" [nbTooltip]="getTooltipForSetting(setting)"></nb-icon>
</div>
<div class="date">
{{ 'INTEGRATIONS.GAUZY_AI_PAGE.GENERATED' | translate }} {{ setting.createdAt | dateFormat }}
</div>
</div>
<div class="integration-value">
<ng-template [ngIf]="isEdit" [ngIfElse]="integrationMaskTemplate">
<div class="form-group">
<input
nbInput
[(ngModel)]="setting.newSettingsValue"
[placeholder]="setting.settingsValue"
required
fullWidth
/>
</div>
</ng-template>
<ng-template #integrationMaskTemplate>
{{ setting.settingsValue }}
</ng-template>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
:host {
header {
font-size: 18px;
font-weight: 600;
line-height: 30px;
letter-spacing: 0em;
}
.integration-container {
display: flex;
flex-direction: column;
gap: 0.5rem;
.date {
color: var(--gauzy-text-color-2);
font-size: 12px;
}
.integration-row {
background: var(--gauzy-card-2);
padding: 1rem;
border-radius: var(--border-radius);
display: flex;
justify-content: space-between;
.integration-label {
nb-icon {
font-size: 1rem;
}
}
.integration-value {
display: flex;
gap: 0.25rem;

nb-icon {
cursor: pointer;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { TranslateService } from '@ngx-translate/core';
import { firstValueFrom } from 'rxjs';
import { IIntegrationSetting } from "@gauzy/contracts";
import { IntegrationSettingService } from "../../../../../@core/services";
import { TranslationBaseComponent } from "../../../../../@shared/language-base";

export enum SettingTitlesEnum {
API_KEY = 'apiKey',
API_SECRET = 'apiSecret',
OPEN_AI_API_SECRET_KEY = 'openAiSecretKey',
OPEN_AI_ORGANIZATION_ID = 'openAiOrganizationId'
}

@Component({
selector: 'ngx-integration-setting-card',
styleUrls: ['./integration-setting-card.component.scss'],
templateUrl: './integration-setting-card.component.html',
})
export class IntegrationSettingCardComponent extends TranslationBaseComponent {
public isIntegrationAISettingsEdit: boolean = false;

// Define a mapping object for setting names to titles and information
public settingTitles: Record<string, string>[] = [
{
settingTitle: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.API_KEY'),
settingMatching: SettingTitlesEnum.API_KEY,
settingInformation: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.TOOLTIP.API_KEY')
},
{
settingTitle: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.API_SECRET'),
settingMatching: SettingTitlesEnum.API_SECRET,
settingInformation: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.TOOLTIP.API_SECRET')
},
{
settingTitle: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.OPEN_AI_API_SECRET_KEY'),
settingMatching: SettingTitlesEnum.OPEN_AI_API_SECRET_KEY,
settingInformation: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.TOOLTIP.OPEN_AI_API_SECRET_KEY')
},
{
settingTitle: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.OPEN_AI_ORGANIZATION_ID'),
settingMatching: SettingTitlesEnum.OPEN_AI_ORGANIZATION_ID,
settingInformation: this.getTranslation('INTEGRATIONS.GAUZY_AI_PAGE.TOOLTIP.OPEN_AI_ORGANIZATION_ID')
}
];

/**
* Input property for the title of the component.
*/
@Input() title: string;

/**
* Input property for an array of integration settings.
* Adjust the type accordingly based on the actual type of integration settings.
*/
_items: IIntegrationSetting[] = [];
get items(): IIntegrationSetting[] {
return this._items;
}
@Input() set items(value: IIntegrationSetting[]) {
this._items = value;
}

/**
* Output property to emit an event when the component has saved data.
* This allows the parent component to listen for the 'saved' event.
*/
@Output() saved = new EventEmitter();

constructor(
public readonly translateService: TranslateService,
private readonly _integrationSettingService: IntegrationSettingService,
) {
super(translateService);
}

/**
* Gets the title for a given integration setting.
*
* @param setting - The integration setting for which to retrieve the title.
* @returns The title for the integration setting, or the original setting name if not found.
*/
public getTitleForSetting(setting: IIntegrationSetting): string {
// Find the key configuration that matches the setting name
const keyConfig = this.settingTitles.find((key) => key.settingMatching === setting.settingsName);

// If a key configuration is found, return its title; otherwise, return the original setting name
return keyConfig?.settingTitle || setting.settingsName;
}

/**
* Gets the tooltip content for a given integration setting.
*
* @param setting - The integration setting for which to retrieve the tooltip content.
* @returns The tooltip content for the integration setting, or an empty string if not found.
*/
public getTooltipForSetting(setting: IIntegrationSetting): string {
// Find the key configuration that matches the setting name
const keyConfig = this.settingTitles.find((key) => key.settingMatching === setting.settingsName);

// If a key configuration is found, return its information; otherwise, return an empty string
return keyConfig?.settingInformation || '';
}

/**
* Save settings.
*/
async saveSettings(): Promise<void> {
try {
// Use Promise.all to wait for all update operations to complete
const settings = await Promise.all(
this.items.map(async (setting: IIntegrationSetting) => {
// Update each setting
return await firstValueFrom(
this._integrationSettingService.update(
setting.id,
this._mapIntegrationSettingPayload(setting)
)
);
})
);

// Update the items array with the updated settings
this.items = settings;

// Emit an event indicating that the settings have been saved
this.saved.emit();
} finally {
// Toggle integration AI settings edit mode, whether success or error
this.toggleIntegrationAISettings();
}
}

/**
* Map integration setting payload data to the required format.
*
* @param setting - An integration setting object.
* @returns Mapped integration setting payload data.
*/
private _mapIntegrationSettingPayload(setting: IIntegrationSetting): Partial<IIntegrationSetting> {
return ({
settingsName: setting['settingsName'],
settingsValue: setting['newSettingsValue'],
organizationId: setting['organizationId'],
tenantId: setting['tenantId'],
});
}

/**
* Toggle integration AI settings edit mode.
*/
public toggleIntegrationAISettings() {
// Toggle the value of isIntegrationAISettingsEdit
this.isIntegrationAISettingsEdit = !this.isIntegrationAISettingsEdit;
}
}
Loading

0 comments on commit f8e24d7

Please sign in to comment.