From 944a9b2d8e9e513ca50052af95a1f5b5d988e6b9 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 30 Apr 2026 08:59:55 +0200 Subject: [PATCH 01/30] config --- .gitignore | 5 +++++ .nvmrc | 1 + .vscode/settings.json | 3 ++- angular.json | 3 ++- src/environments/environment.ts | 39 +++++++++++++++++---------------- 5 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 .nvmrc diff --git a/.gitignore b/.gitignore index 38a9c0952..a1a2c40b2 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,8 @@ Thumbs.db /src/environments/real_data settings.json docs + +# Local dev config (do not commit) +src/environments/real_data/cds-config-local.json +.claude +CLAUDE.md diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..48b14e6b2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.14.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 75897dd05..ec8f5a5fb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "workbench.editorAssociations": { "*.json": "default", "*.svg": "default" - } + }, + "typescript.tsdk": "node_modules/typescript/lib" } \ No newline at end of file diff --git a/angular.json b/angular.json index d3c61f8f6..4431500ed 100644 --- a/angular.json +++ b/angular.json @@ -38,7 +38,8 @@ "src/environments/real_data/cds-config-firebase.json", "src/environments/real_data/cds-config-native-prod.json", "src/environments/real_data/cds-config-native-collaudo.json", - "src/environments/real_data/cds-config-aws-stage.json" + "src/environments/real_data/cds-config-aws-stage.json", + { "glob": "cds-config-local.json", "input": "src/environments/real_data", "output": "/real_data" } ], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.css", diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 8e3faa17b..94e1927a6 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,25 +1,26 @@ export const environment = { - production: true, - t2y12PruGU9wUtEGzBJfolMIgK: 'CHANGEIT', + production: false, + t2y12PruGU9wUtEGzBJfolMIgK: 'tokenKey', VERSION: require('../../package.json').version, - remoteConfig: false, - remoteConfigUrl: './design-studio-config.json', - apiUrl: 'CHANGEIT', - widgetBaseUrl: 'CHANGEIT', - dashboardBaseUrl: 'CHANGEIT', + remoteConfig: true, + remoteConfigUrl: './real_data/cds-config-local.json', + apiUrl: 'http://localhost:3000/', + widgetBaseUrl: 'http://localhost:4200/', + dashboardBaseUrl: 'http://localhost:4200/', wsUrl: 'ws://localhost:3000/', uploadEngine: 'native', - baseImageUrl: 'CHANGEIT', - logLevel: 'error', - storage_prefix: "CHANGEIT", + baseImageUrl: 'http://localhost:3000/', + logLevel: 'debug', + storage_prefix: 'tiledesk_', firebaseConfig: { - apiKey: 'CHANGEIT', - authDomain: 'CHANGEIT', - databaseURL: 'CHANGEIT', - projectId: 'CHANGEIT', - storageBucket: 'CHANGEIT', - messagingSenderId: 'CHANGEIT', - appId: 'CHANGEIT', - vapidKey: 'CHANGEIT' + apiKey: '', + authDomain: '', + databaseURL: '', + projectId: '', + storageBucket: '', + messagingSenderId: '', + appId: '', + vapidKey: '' } -}; \ No newline at end of file +}; + From 55e4585b77b1c31163c4e1ce680a21b39e728674 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 30 Apr 2026 09:30:08 +0200 Subject: [PATCH 02/30] Migrazione del Design Studio alla versione 3. Il modello semplificato prevede blocchi (intent) con una sola action, drag & drop ridotto al solo trascinamento dal pannello sullo stage, e rimozione dei controlli di editing inline sulle action. --- REFACTORING.md | 46 +++++ .../cds-canvas/cds-canvas.component.ts | 38 +---- .../cds-intent/cds-intent.component.html | 72 +------- .../cds-intent/cds-intent.component.ts | 157 +----------------- src/app/models/faq_kb-model.ts | 1 + src/app/services/faq-kb.service.ts | 3 + src/environments/environment.pre.ts | 1 + src/environments/environment.prod.ts | 1 + src/environments/environment.ts | 1 + 9 files changed, 63 insertions(+), 257 deletions(-) create mode 100644 REFACTORING.md diff --git a/REFACTORING.md b/REFACTORING.md new file mode 100644 index 000000000..d95b77070 --- /dev/null +++ b/REFACTORING.md @@ -0,0 +1,46 @@ +# Design Studio v3 — Refactoring + +Migrazione del Design Studio alla versione 3. Il modello semplificato prevede blocchi (intent) con una sola action, drag & drop ridotto al solo trascinamento dal pannello sullo stage, e rimozione dei controlli di editing inline sulle action. + +--- + +## Changelog + +- **[v3] Versioning** — Introdotto `DS_VERSION = '3'` negli environment; campo `cds_version` scritto sul chatbot ad ogni salvataggio +- **[v3] 1 action per blocco** — Limite universale: ogni intent accetta al massimo una action +- **[v3] Drag interno rimosso** — Eliminato il riordino delle action all'interno dello stesso blocco +- **[v3] Drag cross-intent rimosso** — Eliminato lo spostamento di action tra blocchi diversi +- **[v3] Drag action→stage rimosso** — Eliminata la creazione di un nuovo blocco trascinando una action da un blocco esistente sullo stage +- **[v3] Drop su blocco rimosso** — I blocchi non accettano più drop di nessun tipo (rimosso `cdkDropList` dall'intent) +- **[v3] cds-action-controls rimosso** — Rimosso il menu edit/delete/copy inline su ogni action +- **[v3] Add action rimosso** — Rimossi il placeholder e il bottone "Add action" nei blocchi (vuoti e non) + +--- + +## Dettaglio modifiche + +### Versioning (`DS_VERSION`) +Aggiunto `DS_VERSION: '3'` in tutti i file environment (`environment.ts`, `environment.prod.ts`, `environment.pre.ts`). Aggiunto campo `cds_version?: string` al modello `Chatbot`. In `FaqKbService.updateFaqKb()` e `updateChatbot()`, il valore viene scritto su `chatbot.cds_version` prima di ogni salvataggio, così ogni JSON di chatbot porta traccia della versione del Design Studio con cui è stato generato. + +### 1 action per blocco +Rimossa la condizione `isNewChatbot` che limitava a 1 action solo i chatbot creati dopo una certa data. Il limite è ora universale e applicato a tutti i blocchi indipendentemente dalla data di creazione. La proprietà `isNewChatbot` rimane nel componente per eventuali usi non legati al drag, ma non condiziona più la logica di drop. + +### Drag interno rimosso +Rimossi da `cds-intent.component.html` gli attributi `cdkDrag`, `(cdkDragStarted)`, `(cdkDragReleased)`, `(cdkDragMoved)` da ogni `div.box-action`. Rimossi `*cdkDragPreview`, `*cdkDragPlaceholder` e `cdkDragHandle`. In `cds-intent.component.ts` eliminati i metodi `onDragStarted()`, `onDragEnded()`, `onDragMove()` e le proprietà `isDragging`, `actionDragPlaceholderWidth`, `hideActionDragPlaceholder`, `dragDisabled`. + +### Drag cross-intent rimosso +Rimosso il case 2 di `onDropAction()` che chiamava `intentService.moveActionBetweenDifferentIntents()`. Con il limite di 1 action per blocco e senza `cdkDrag` sulle action, questo flusso non è più raggiungibile né necessario. + +### Drag action→stage rimosso +In `cds-canvas.component.ts`, rimosso il branch `else if (action)` di `onDroppedElementToStage()` che gestiva il trascinamento di una action da un blocco esistente sullo stage (con conseguente creazione di un nuovo blocco). Rimosso il metodo `createNewIntentDraggingActionFromAnotherIntent()`. Rimane attivo solo il branch `if (action.value && action.value.type)` che gestisce il drag dal pannello sinistro. + +### Drop su blocco rimosso +Rimosso il contenitore `cdkDropList` dall'actions list in `cds-intent.component.html`. I blocchi non ricevono più drop di nessun tipo. Rimossi di conseguenza `onDropAction()` e `canEnterDropList()` da `cds-intent.component.ts`, e l'import `@angular/cdk/drag-drop` (non più usato nel componente). + +### cds-action-controls rimosso +Rimosso il tag `` dal template di ogni action in `cds-intent.component.html`. Il componente forniva il menu contestuale edit/delete/copy inline su ogni action. La condizione `*ngIf="!isNewChatbot"` che lo controllava è stata rimossa insieme al tag. + +### Add action rimosso +Rimossi da `cds-intent.component.html`: +- Il `div.add--action-placeholder` (mostrato nei blocchi vuoti) con testo descrittivo e bottone "+ Add action" +- Il `div.footer-intent` contenente il bottone "+ Add action" mostrato in fondo ai blocchi con almeno una action diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.ts index c75db234a..5638a206c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.ts @@ -1154,21 +1154,9 @@ export class CdsCanvasComponent implements OnInit, AfterViewInit{ let action: any = event.previousContainer.data[event.previousIndex]; if (action.value && action.value.type) { this.logger.log('[CDS-CANVAS] ho draggato una action da panel element sullo stage'); - this.closeAllPanels(); - this.closeActionDetailPanel(); - // this.removeConnectorDraftAndCloseFloatMenu(); + this.closeAllPanels(); + this.closeActionDetailPanel(); this.createNewIntentFromPanelElement(pos, action.value.type); - } else if (action) { - this.logger.log('[CDS-CANVAS] ho draggato una action da un intent sullo stage'); - let prevIntentOfaction = this.listOfIntents.find((intent) => intent.actions.some((act) => act._tdActionId === action._tdActionId)); - prevIntentOfaction.actions = prevIntentOfaction.actions.filter((act) => act._tdActionId !== action._tdActionId); - this.connectorService.deleteConnectorsFromActionByActionId(action._tdActionId); - this.connectorService.updateConnector(prevIntentOfaction.intent_id); - this.intentService.refreshIntent(prevIntentOfaction); - this.listOfIntents = this.listOfIntents.map(obj => obj.intent_id === prevIntentOfaction.intent_id ? prevIntentOfaction : obj); - this.createNewIntentDraggingActionFromAnotherIntent(pos, action); - // this.intentService.refreshIntents(); - // // this.updateIntent(intentPrevious, 0, false); } } @@ -1233,28 +1221,6 @@ export class CdsCanvasComponent implements OnInit, AfterViewInit{ - /** - * createNewIntentDraggingActionFromAnotherIntent - * @param pos - * @param action - */ - async createNewIntentDraggingActionFromAnotherIntent(pos, action){ - // let nowIntent = this.listOfIntents.find((intent) => intent.actions.some((act) => act._tdActionId === action._tdActionId)); - let prevIntent = this.intentService.prevListOfIntent.find((intent) => intent.actions.some((act) => act._tdActionId === action._tdActionId)); - let nowIntent = this.listOfIntents.find((obj) => obj.intent_id === prevIntent.intent_id); - // let nowIntent = this.listOfIntents.find((intent) => intent.actions.some((act) => act._tdActionId === action._tdActionId)); - this.logger.log('[CDS-CANVAS] createNewIntentDraggingActionFromAnotherIntent: ', prevIntent, nowIntent, this.listOfIntents); - let intent = this.intentService.createNewIntent(this.id_faq_kb, action, pos); - this.intentService.addNewIntentToListOfIntents(intent); - const newIntent = await this.settingAndSaveNewIntent(pos, intent, nowIntent, prevIntent); - // if (newIntent) { - // // this.logger.log('[CDS-CANVAS] cancello i connettori della action draggata'); - // // this.connectorService.deleteConnectorsFromActionByActionId(action._tdActionId); - // // const elementID = this.intentService.previousIntentId; - // // this.logger.log("[CDS-CANVAS] aggiorno i connettori dell'intent", elementID); - // // this.connectorService.updateConnector(elementID); - // } - } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index d080edf4a..578b2f268 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -70,51 +70,14 @@ -
+
- - -
- - -
- {{ 'CDSCanvas.AddAnActionToBlock' | translate}} - - {{ 'CDSCanvas.AddAnActionToBlockDescription' | translate}} - -
- -
-
- + {{ 'CDSCanvas.AddAction' | translate}} -
- -
-
-
-
- - -
- -
- - -
+
- - - + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts index ef638a0ae..5886c5dbd 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts @@ -1,7 +1,6 @@ import { Renderer2, Component, OnInit, Input, Output, EventEmitter, SimpleChanges, ViewChild, ElementRef, OnChanges, OnDestroy } from '@angular/core'; import { firstValueFrom, Subject, Subscription } from 'rxjs'; import { takeUntil, timeInterval } from 'rxjs/operators'; -import { CdkDragDrop, CdkDrag, moveItemInArray, CdkDragMove, transferArrayItem, CdkDropListGroup, CdkDropList, CdkDragHandle } from '@angular/cdk/drag-drop'; import { Form, Intent } from 'src/app/models/intent-model'; import { Action, ActionIntentConnected } from 'src/app/models/action-model'; import { IntentService } from '../../../services/intent.service'; @@ -73,11 +72,7 @@ export class CdsIntentComponent implements OnInit, OnDestroy, OnChanges { isDefaultFallback = false; startAction: any; - isDragging: boolean = false; - actionDragPlaceholderWidth: number; - hideActionDragPlaceholder: boolean; newActionCreated: Action; - dragDisabled: boolean = true; connectorIsOverAnIntent: boolean = false; // Track mouse movement to distinguish click from drag private mouseDownX: number = 0; @@ -511,7 +506,7 @@ export class CdsIntentComponent implements OnInit, OnDestroy, OnChanges { for (const entry of entries) { const nuovaAltezza = entry.contentRect.height; this.logger.log('[CDS-INTENT] ngAfterViewInit Nuova altezza del div:', nuovaAltezza); - if(!this.isDragging)this.connectorService.updateConnector(this.intent.intent_id); + this.connectorService.updateConnector(this.intent.intent_id); } }); const elementoDom = this.resizeElement.nativeElement; @@ -850,160 +845,10 @@ export class CdsIntentComponent implements OnInit, OnDestroy, OnChanges { } - public onDragMove(event: CdkDragMove): void { - const element = document.getElementById('customDragPreview'); - if (element) { - const xPos = event.pointerPosition.x - 122; - const yPos = event.pointerPosition.y - 20; - element.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`; - } -} - - - /** !!! IMPORTANT - * when the drag of an action starts, I save the starting intent. - * Useful in case I move an action between different intents - * */ - onDragStarted(event, previousIntentId, index) { - this.controllerService.closeActionDetailPanel(); - this.logger.log('[CDS-INTENT] onDragStarted event ', event, 'previousIntentId ', previousIntentId); - this.logger.log('[CDS-INTENT] onDragStarted index ', index); - this.intentService.setPreviousIntentId(previousIntentId); - this.isDragging = true; - this.logger.log('[CDS-INTENT] isDragging - onDragStarted', this.isDragging) - - // ---------------------------------- - // Hide action arrow on drag started - // ---------------------------------- - // const actionArrowElem = document.querySelector(`#action-arrow-${index}`); - // actionArrowElem.style.display = 'none'; - // this.logger.log('[CDS-INTENT] onDragStarted actionArrowElem', actionArrowElem) - // const actionDragPlaceholderWidth = actionDragPlaceholder.offsetWidth; - // this.logger.log('[CDS-INTENT] onDragStarted actionDragPlaceholderWidth', actionDragPlaceholderWidth) - - // -------------------------------------------------------------------------------------------------- - // Bug fix: When an action is dragged, the "drag placeholder" moves up and changes size to full width - // -------------------------------------------------------------------------------------------------- - const actionDragPlaceholder = document.querySelector('.action-drag-placeholder'); - const addActionPlaceholderEl = document.querySelector('.add--action-placeholder'); - - this.logger.log('[CDS-INTENT] onDragStarted actionDragPlaceholder', actionDragPlaceholder) - this.logger.log('[CDS-INTENT] onDragStarted addActionPlaceholderEl ', addActionPlaceholderEl) - const myObserver = new ResizeObserver(entries => { - // this will get called whenever div dimension changes - entries.forEach(entry => { - this.actionDragPlaceholderWidth = entry.contentRect.width - this.logger.log('[CDS-INTENT] width actionDragPlaceholderWidth', this.actionDragPlaceholderWidth); - if (this.actionDragPlaceholderWidth <= 270) { - this.hideActionDragPlaceholder = false; - this.logger.log('[CDS-INTENT] Hide action drag placeholder', this.hideActionDragPlaceholder); - if (actionDragPlaceholder instanceof HTMLElement) { - actionDragPlaceholder.style.opacity = '1'; - } - if (addActionPlaceholderEl instanceof HTMLElement) { - addActionPlaceholderEl.style.opacity = '0'; - } - this.logger.log('[CDS-INTENT] HERE 1 !!!! '); - } else { - this.hideActionDragPlaceholder = true; - this.logger.log('[CDS-INTENT] Hide action drag placeholder', this.hideActionDragPlaceholder); - if (actionDragPlaceholder instanceof HTMLElement) { - actionDragPlaceholder.style.opacity = '0'; - } - if (addActionPlaceholderEl instanceof HTMLElement) { - addActionPlaceholderEl.style.opacity = '1'; - } - this.logger.log('[CDS-INTENT] HERE 2 !!!! '); - } - }); - }); - myObserver.observe(actionDragPlaceholder); - } - - - - /** onDragEnded - * get the action moved and update its connectors */ - onDragEnded(event, index) { - this.logger.log('[CDS-INTENT] onDragEnded: ', event, this.intent.intent_id); - this.isDragging = false; - this.connectorService.updateConnector(this.intent.intent_id); - /** - // const previousIntentId = this.intentService.previousIntentId; - // if(previousIntentId){ - // this.logger.log("[CDS-INTENT] onDropAction previousIntentId: ", previousIntentId); - // this.connectorService.updateConnector(previousIntentId); - // } - // this.connectorService.updateConnector(this.intent.intent_id); - // */ - } - - - /** Predicate function that only allows type='intent' to be dropped into a list. */ - canEnterDropList(action: any) { - return (item: CdkDrag) => { - // Se il chatbot è nuovo, disabilita il drop se c'è già un'action nell'intent - // Mantiene il limite di una action per blocco intent per i chatbot nuovi - if (this.isNewChatbot && this.intent.actions && this.intent.actions.length > 0) { - return false; - } - // Per i chatbot esistenti, permette il drop normalmente - return true; - } - } - - /** on Drop Action check the three possible cases: - * chaimata quando muovo la action in un intent - * 1 - moving action in the same intent - * 2 - moving action from another intent - * 3 - moving new action in intent from panel elements - */ - async onDropAction(event: CdkDragDrop) { - this.logger.log('[CDS-INTENT] onDropAction: ', event, this.intent.actions); - - // Se il chatbot è nuovo, impedisce il drop se c'è già un'action nell'intent - // Mantiene il limite di una action per blocco intent per i chatbot nuovi - if (this.isNewChatbot && this.intent.actions && this.intent.actions.length > 0) { - this.logger.log('[CDS-INTENT] onDropAction: impedito drop - chatbot nuovo e c\'è già un\'action nell\'intent'); - return; - } - - // Per i chatbot esistenti, esegue il drop normalmente - this.controllerService.closeAllPanels(); - this.intentService.setIntentSelected(this.intent.intent_id); - if (event.previousContainer === event.container) { - // moving action in the same intent - moveItemInArray(this.intent.actions, event.previousIndex, event.currentIndex); - this.intentService.updateIntent(this.intent, null); - /** //const response = await this.intentService.onUpdateIntentWithTimeout(this.intent); */ - } else { - try { - let action: any = event.previousContainer.data[event.previousIndex]; - if (event.previousContainer.data.length > 0) { - if (action._tdActionType) { - // moving action from another intent - this.logger.log("[CDS-INTENT] onDropAction sposto la action tra 2 intent differenti"); - this.intentService.moveActionBetweenDifferentIntents(event, action, this.intent.intent_id); - this.intentService.updateIntent(this.intent, null); - this.connectorService.updateConnectorsOfBlock(this.intent.intent_id) - } else if (action.value?.type) { - // moving new action in intent from panel elements - this.logger.log("[CDS-INTENT] onDropAction aggiungo una nuova action all'intent da panel elements - action ", this.newActionCreated); - this.intentService.moveNewActionIntoIntent(event.currentIndex, action, this.intent.intent_id); - // this.onSelectAction(newAction, event.currentIndex, newAction._tdActionId) - } - } - } catch (error) { - console.error(error); - } - } - } - - /** onUpdateAndSaveAction: * function called by all actions in @output whenever they are modified! * called when the connector is created or deleted diff --git a/src/app/models/faq_kb-model.ts b/src/app/models/faq_kb-model.ts index 04c5d5e6c..1e0edaa01 100755 --- a/src/app/models/faq_kb-model.ts +++ b/src/app/models/faq_kb-model.ts @@ -23,6 +23,7 @@ export interface FaqKb { export interface Chatbot extends FaqKb { attributes?: any + cds_version?: string; public?: boolean; certified?: boolean; tags?: any; diff --git a/src/app/services/faq-kb.service.ts b/src/app/services/faq-kb.service.ts index dce2c0662..fbf8ed642 100755 --- a/src/app/services/faq-kb.service.ts +++ b/src/app/services/faq-kb.service.ts @@ -9,6 +9,7 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; import { AppConfigService } from './app-config'; import { AppStorageService } from 'src/chat21-core/providers/abstract/app-storage.service'; +import { environment } from 'src/environments/environment'; @Injectable() export class FaqKbService { @@ -144,6 +145,7 @@ export class FaqKbService { // chatbot['webhook_url'] = webhookurl // chatbot['language'] = resbotlanguage // } + chatbot.cds_version = environment.DS_VERSION; this.logger.log('[FAQ-KB.SERV] updateFaqKb - BODY ', chatbot); return this._httpClient.put(url, JSON.stringify(chatbot), httpOptions) } @@ -205,6 +207,7 @@ export class FaqKbService { let url = this.FAQKB_URL + chatbot._id; this.logger.log('update BOT - URL ', url); + chatbot.cds_version = environment.DS_VERSION; this.logger.log('[FAQ-KB.SERV] updateFaqKb - BODY ', chatbot); return this._httpClient.put(url, JSON.stringify(chatbot), httpOptions) diff --git a/src/environments/environment.pre.ts b/src/environments/environment.pre.ts index a50fe8320..059b35cab 100644 --- a/src/environments/environment.pre.ts +++ b/src/environments/environment.pre.ts @@ -2,6 +2,7 @@ export const environment = { production: false, t2y12PruGU9wUtEGzBJfolMIgK: 'CHANGEIT', VERSION: require('../../package.json').version, + DS_VERSION: '3', remoteConfig: false, remoteConfigUrl: './design-studio-config.json', apiUrl: 'CHANGEIT', diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index f15cee489..9876a9e9f 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -2,6 +2,7 @@ export const environment = { production: true, t2y12PruGU9wUtEGzBJfolMIgK: 'CHANGEIT', VERSION: require('../../package.json').version, + DS_VERSION: '3', remoteConfig: true, remoteConfigUrl: './design-studio-config.json', apiUrl: 'CHANGEIT', diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 94e1927a6..2fedc1a3b 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -2,6 +2,7 @@ export const environment = { production: false, t2y12PruGU9wUtEGzBJfolMIgK: 'tokenKey', VERSION: require('../../package.json').version, + DS_VERSION: '3', remoteConfig: true, remoteConfigUrl: './real_data/cds-config-local.json', apiUrl: 'http://localhost:3000/', From b9f92d7be8ad7e4667d4530e870eb5243b383c52 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 30 Apr 2026 12:27:33 +0200 Subject: [PATCH 03/30] refactoring intent - step 1 --- .gitignore | 1 + REFACTORING.md | 46 - .../cds-connector.component.scss | 2 +- .../cds-canvas/cds-canvas.component.scss | 9 +- .../cds-intent/cds-intent.component.html | 899 +++++++++--------- .../cds-intent/cds-intent.component.scss | 878 ++++++----------- .../cds-intent/cds-intent.component.ts | 16 +- .../panel-intent-controls.component.scss | 136 ++- .../panel-intent-header.component.html | 3 - .../panel-intent-header.component.scss | 416 ++------ src/assets/sass/_ds-tokens.scss | 27 + src/assets/sass/cds/_variables.scss | 6 +- src/assets/sass/cds/connector-styles.scss | 8 +- src/assets/sass/cds/styles.scss | 18 + src/styles.scss | 1 + 15 files changed, 913 insertions(+), 1553 deletions(-) delete mode 100644 REFACTORING.md create mode 100644 src/assets/sass/_ds-tokens.scss diff --git a/.gitignore b/.gitignore index a1a2c40b2..6d7633429 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,4 @@ docs src/environments/real_data/cds-config-local.json .claude CLAUDE.md +.docs diff --git a/REFACTORING.md b/REFACTORING.md deleted file mode 100644 index d95b77070..000000000 --- a/REFACTORING.md +++ /dev/null @@ -1,46 +0,0 @@ -# Design Studio v3 — Refactoring - -Migrazione del Design Studio alla versione 3. Il modello semplificato prevede blocchi (intent) con una sola action, drag & drop ridotto al solo trascinamento dal pannello sullo stage, e rimozione dei controlli di editing inline sulle action. - ---- - -## Changelog - -- **[v3] Versioning** — Introdotto `DS_VERSION = '3'` negli environment; campo `cds_version` scritto sul chatbot ad ogni salvataggio -- **[v3] 1 action per blocco** — Limite universale: ogni intent accetta al massimo una action -- **[v3] Drag interno rimosso** — Eliminato il riordino delle action all'interno dello stesso blocco -- **[v3] Drag cross-intent rimosso** — Eliminato lo spostamento di action tra blocchi diversi -- **[v3] Drag action→stage rimosso** — Eliminata la creazione di un nuovo blocco trascinando una action da un blocco esistente sullo stage -- **[v3] Drop su blocco rimosso** — I blocchi non accettano più drop di nessun tipo (rimosso `cdkDropList` dall'intent) -- **[v3] cds-action-controls rimosso** — Rimosso il menu edit/delete/copy inline su ogni action -- **[v3] Add action rimosso** — Rimossi il placeholder e il bottone "Add action" nei blocchi (vuoti e non) - ---- - -## Dettaglio modifiche - -### Versioning (`DS_VERSION`) -Aggiunto `DS_VERSION: '3'` in tutti i file environment (`environment.ts`, `environment.prod.ts`, `environment.pre.ts`). Aggiunto campo `cds_version?: string` al modello `Chatbot`. In `FaqKbService.updateFaqKb()` e `updateChatbot()`, il valore viene scritto su `chatbot.cds_version` prima di ogni salvataggio, così ogni JSON di chatbot porta traccia della versione del Design Studio con cui è stato generato. - -### 1 action per blocco -Rimossa la condizione `isNewChatbot` che limitava a 1 action solo i chatbot creati dopo una certa data. Il limite è ora universale e applicato a tutti i blocchi indipendentemente dalla data di creazione. La proprietà `isNewChatbot` rimane nel componente per eventuali usi non legati al drag, ma non condiziona più la logica di drop. - -### Drag interno rimosso -Rimossi da `cds-intent.component.html` gli attributi `cdkDrag`, `(cdkDragStarted)`, `(cdkDragReleased)`, `(cdkDragMoved)` da ogni `div.box-action`. Rimossi `*cdkDragPreview`, `*cdkDragPlaceholder` e `cdkDragHandle`. In `cds-intent.component.ts` eliminati i metodi `onDragStarted()`, `onDragEnded()`, `onDragMove()` e le proprietà `isDragging`, `actionDragPlaceholderWidth`, `hideActionDragPlaceholder`, `dragDisabled`. - -### Drag cross-intent rimosso -Rimosso il case 2 di `onDropAction()` che chiamava `intentService.moveActionBetweenDifferentIntents()`. Con il limite di 1 action per blocco e senza `cdkDrag` sulle action, questo flusso non è più raggiungibile né necessario. - -### Drag action→stage rimosso -In `cds-canvas.component.ts`, rimosso il branch `else if (action)` di `onDroppedElementToStage()` che gestiva il trascinamento di una action da un blocco esistente sullo stage (con conseguente creazione di un nuovo blocco). Rimosso il metodo `createNewIntentDraggingActionFromAnotherIntent()`. Rimane attivo solo il branch `if (action.value && action.value.type)` che gestisce il drag dal pannello sinistro. - -### Drop su blocco rimosso -Rimosso il contenitore `cdkDropList` dall'actions list in `cds-intent.component.html`. I blocchi non ricevono più drop di nessun tipo. Rimossi di conseguenza `onDropAction()` e `canEnterDropList()` da `cds-intent.component.ts`, e l'import `@angular/cdk/drag-drop` (non più usato nel componente). - -### cds-action-controls rimosso -Rimosso il tag `` dal template di ogni action in `cds-intent.component.html`. Il componente forniva il menu contestuale edit/delete/copy inline su ogni action. La condizione `*ngIf="!isNewChatbot"` che lo controllava è stata rimossa insieme al tag. - -### Add action rimosso -Rimossi da `cds-intent.component.html`: -- Il `div.add--action-placeholder` (mostrato nei blocchi vuoti) con testo descrittivo e bottone "+ Add action" -- Il `div.footer-intent` contenente il bottone "+ Add action" mostrato in fondo ai blocchi con almeno una action diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss index d114a0a8f..984727daa 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss @@ -100,7 +100,7 @@ cursor: default; &::before { inset: 0px; - border: 1px solid rgb(168, 168, 174); + // border: 1px solid rgb(168, 168, 174); transition: inset 0.1s ease 0s, border 0.1s ease 0s; position: absolute; content: ""; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss index 1d46268d6..d434bad6f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss @@ -359,10 +359,11 @@ cds-fulfillment { .tds-drag-container { position: absolute; display: block; - background-size: 16px 16px; - background-image: radial-gradient(var(--container-background) 1.14286px, var(--container-points-color) 1.14286px); - // background-image: radial-gradient(rgb(218, 226, 226) 1.14286px, rgb(244, 246, 246) 1.14286px); - background-position: 593.4px -230.4px; + background-color: var(--container-points-color); + background-image: radial-gradient(circle, var(--container-background) 0.8px, transparent 0.8px); + background-size: 22px 22px; + background-position: 0 0; + opacity: 1; &.note-mode-active { cursor: text; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 578b2f268..a387bf29d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -1,495 +1,494 @@ - -
+ + + +
- - - - - + [style.--intent-color]="intentColor"> + + + + + + -
- - -
+ +
+ +
+ +
+ rocket_launch +
- - + +
+ +
+ +
+ + +
+ {{ (firstActionElement?.name | translate) || listOfActions?.[0]?._tdActionType || 'intent' }} + {{ firstActionElement.badge }} +
+
- +
-
Question
-
Form
- -
boy
-
- +
+ boy +
+ + +
+
-
- - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - + +
+
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
-
- + + - - + - +
-
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss index 7d802f196..9e7c2bed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss @@ -1,646 +1,374 @@ @import "./src/assets/sass/animations.scss"; -:host{ - --action-background: #{var(--action-item-background)}; - --action-no-featured-backgroud: #{var(--action-no-featured-item-background)}; - --intent-background: #{var(--intent-preview-background)}; - --intent-border-color: #{var(--intent-preview-borderColor)}; - --intent-header-background: transparent; - --base-border-radius-preview: #{var(--border-radius-base-preview)}; - --base-padding-preview: #{var(--padding-base-preview)}; - --action-selected-color: #{var(--action-color-selected)}; - --add-action-btn-background: #{var(--add-action-btn-background-preview)}; - --add-action-btn-color: #{var(--add-action-btn-color-preview)}; - --add-action-btn-hover-color: #{var(--add-action-btn-hover-color-preview)}; - --base-color: #{var(--blu)}; - --startIntentMaxWith: 160px; - --base-border-radius-base: #{var(--button-border-radius-base)}; -} - +// ============================================================ +// NODE CARD — shell principale del blocco intent +// ============================================================ -#customDragPreview { +:host { display: block; - position:absolute; - pointer-events: none; - user-select: none; - opacity: 0.8; - background-color: var(--drag-preview-background); - max-width: 244px; - width: 100%; -} - - -.action-element{ - width: 100%; + position: relative; + overflow: visible; } - -.panel-intent-content { - transition: background-color 0.15s ease 0s; +.node { + background: var(--ds-surface, #fff); + border: 2px solid rgba(var(--intent-color), 0.5); + border-radius: var(--ds-radius, 10px); + box-shadow: var(--ds-shadow-card, 0 1px 2px rgba(20,20,18,.04), 0 0 0 1px rgba(20,20,18,.05)); width: 264px; - cursor: grab; + cursor: pointer; position: relative; - margin: 0px; - padding: var(--base-padding-preview); - border-radius: var(--base-border-radius-preview); - // outline: 1px solid var(--intent-border-color); - &::before { - display: block; - border-radius: 10px; - position: absolute; - content: ""; - transition: box-shadow 0.15s ease 0s; - } - &.outline-border { - outline: 2px solid var(--brown); - border-radius: var(--base-border-radius-preview); + transition: box-shadow 0.15s ease, border-color 0.15s ease; + padding: 0; + margin: 0; + + &:hover { + box-shadow: var(--ds-shadow-pop, 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05), 0 0 0 1px rgba(20,20,18,.06)); } - &.ripple-effect { - animation-name: ripple_effect; - animation-duration: 1s; - animation-iteration-count: 1s; - border-radius: var(--base-border-radius-preview); + + &.node--selected { + border-color: rgba(var(--intent-color), 1); + box-shadow: 0 0 0 3px rgba(var(--intent-color), 0.15), + var(--ds-shadow-pop, 0 8px 24px -8px rgba(20,20,18,.12)); } - &.isStart{ - position: absolute; - height: 100%; - background-color: unset!important; - padding: 0; - border-radius: unset; - border: unset; - max-width: var(--startIntentMaxWith); - outline: unset!important; - .intent-background-overlay { - background-color: transparent!important; - outline: unset!important; + + // Blocco start: pill chiara minimal + &.node--start { + background: var(--ds-surface, #fff); + border-color: var(--ds-border, #ececea); + border-radius: 999px; + width: 160px; + min-width: unset; + max-width: unset; + + .node-icon, + .node-type-row { + display: none; } - .header-draggable { - height: 100%; - width: 100%; + + .node-header { + padding: 6px 14px 6px 8px; + min-height: unset; + gap: 6px; } - .pic-header { - height: 100%; - display: block; - position: absolute; - margin: 0; - padding: 0; + + .node-meta { + flex: unset; } } + // Overlay bianco per il z-index layering (lasciato per compatibilità TiledeskStage) .intent-background-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: #fff; - z-index: -1; + position: absolute; + top: 0; left: 0; + width: 100%; height: 100%; + background-color: transparent; + z-index: -1; + pointer-events: none; + border-radius: inherit; } + // Drag handle trasparente in alto .header-draggable { position: absolute; background-color: transparent; width: calc(100% - 20px); height: 40px; + top: 0; left: 0; + z-index: 1; } - .pic-header { - display: flex; - justify-content: space-between; - width: auto; - margin: 0; - padding: 0 0 10px 0; - background-color: var(--intent-header-background); - overflow: hidden; - justify-content: flex-end; - } - - .agents-available { - margin-top: -70px; - margin-left: -10px; - display: block; - position: absolute; - &.isStart{ - margin-top: -25px; - margin-left: 10px; - } - span.material-icons{ - color: var(--intent-header-icon-color) - } - } - // -------------------------------- - // https://stackoverflow.com/questions/9476923/css3-animate-border-color - - .flashBorder { - // border: 3px solid #fff; - animation-name: flash_border; - animation-duration: 2s; - animation-timing-function: linear; - animation-iteration-count: 2s; //infinite; - -webkit-animation-name: flash_border; - -webkit-animation-duration: 2s; - -webkit-animation-timing-function: linear; - -webkit-animation-iteration-count: 2s; //infinite; - -moz-animation-name: flash_border; - -moz-animation-duration: 2s; - -moz-animation-timing-function: linear; - -moz-animation-iteration-count: 2s //infinite; - } +} - &.live-active-intent-pulse { - cursor: pointer; - animation: pulse-blu 1s 2 forwards; - outline: 2px solid var(--action-selected-color); - } +// ============================================================ +// NODE HEADER +// ============================================================ - &.live-active-intent2 { - cursor: pointer; - box-shadow: 0 0 0 rgba(204, 169, 44, 0.4); - outline: 3px solid var(--blu); - outline-offset: 9px; - } - - &.live-start-intent { - cursor: pointer; - box-shadow: 0 0 0 rgba(204, 169, 44, 0.4); - min-height: 44px; - border-radius: 20px; - animation: pulse 1s infinite; - } +.node-header { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 12px; + position: relative; + min-height: 44px; +} - .cds-start { - transition: box-shadow .15s ease 0s, background-color .15s ease 0s; - position: absolute; - box-shadow: #00000052 0 -1px inset; - background-color: #4b5052; - border-radius: 22px; - max-width: var(--startIntentMaxWith); - right: 0; - cursor: pointer; - opacity: 1; +// Icona tipo-nodo (box colorato 24×24) +.node-icon { + width: 24px; + height: 24px; + border-radius: 6px; + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink-2, #4a4a47); + flex-shrink: 0; + display: grid; + place-items: center; - .cds-intent-options { - margin-right: 30px; - } + &:not(:has(img))::after { + content: ""; + display: block; + width: 8px; + height: 8px; + border-radius: 2px; + background: currentColor; + opacity: 0.6; } - .cds-start-content { - position: relative; - display: flex; - justify-content: flex-end; - align-items: center; - align-content: center; - flex-direction: row; - height: 100%; - right: 11px; - .title-label { - display: none; - } + // default: icona scurita rispetto al canvas (#f7f6f3 → tono ~#6b6960) + img { + width: 16px; + height: 16px; + object-fit: contain; + filter: brightness(0) saturate(100%) invert(41%) sepia(8%) saturate(400%) hue-rotate(20deg) brightness(95%) contrast(90%); } - .pic-header-title { - border-radius: 5px; - overflow-x: hidden; - margin: auto 0; + &.node-icon--blue { + background: var(--ds-blue-soft, oklch(0.95 0.03 245)); + color: var(--ds-blue, oklch(0.62 0.13 245)); + img { filter: brightness(0) saturate(100%) invert(38%) sepia(60%) saturate(500%) hue-rotate(190deg) brightness(90%) contrast(90%); } } - - // .pic-title-text:hover { - // /* background: rgb(221, 212, 183); */ - // } - - .pic-title-text { - transition: background 0.15s ease 0s; - padding: 4px 8px; - border-radius: 5px; - font-size: 15px; - font-weight: 600; - cursor: grab; - box-sizing: border-box; - max-width: 100%; - width: 100%; - color: rgb(108, 104, 89); - display: inline-block; - white-space: pre-wrap; - overflow-wrap: break-word; - pointer-events: auto; - &.isStart{ - height: 100%; - display:flex; - align-items: center; - } - .header { - padding:0px!important; - } + &.node-icon--amber { + background: var(--ds-accent-soft, oklch(0.95 0.04 60)); + color: var(--ds-accent-ink, oklch(0.45 0.15 45)); + img { filter: brightness(0) saturate(100%) invert(30%) sepia(50%) saturate(700%) hue-rotate(20deg) brightness(90%) contrast(90%); } + } + &.node-icon--red { + background: var(--ds-red-soft, oklch(0.95 0.03 28)); + color: var(--ds-red, oklch(0.62 0.16 28)); + img { filter: brightness(0) saturate(100%) invert(35%) sepia(60%) saturate(700%) hue-rotate(340deg) brightness(90%) contrast(90%); } + } + &.node-icon--green { + background: var(--ds-green-soft, oklch(0.95 0.04 155)); + color: var(--ds-green, oklch(0.68 0.13 155)); + img { filter: brightness(0) saturate(100%) invert(40%) sepia(50%) saturate(500%) hue-rotate(120deg) brightness(85%) contrast(90%); } } - } +// Icona play blocco start +.node-start-icon { + width: 26px; + height: 26px; + border-radius: 8px; + background: var(--ds-green-soft, oklch(0.95 0.04 155)); + color: var(--ds-green, oklch(0.68 0.13 155)); + display: grid; + place-items: center; + flex-shrink: 0; + + span.material-icons { + font-size: 16px; + } +} - - - - -/* Actions list -/* ***************************** */ -.actions-list-wpr { +// Meta: nome + tipo +.node-meta { display: flex; flex-direction: column; - // gap: 10px; // nk - gap: 18px; // nk - //min-height: 200px; - //width: 200px; - // border: 1px solid #ccc; - //padding: 10px; - padding-top: 0px; + gap: 1px; + min-width: 0; + flex: 1; } -.box-action { - position: relative; +.node-type-row { display: flex; - flex-direction: column; align-items: center; - width: 100%; - min-height: 30px; - border-radius: var(--base-border-radius-preview); - border: 2px solid rgb(255, 255, 255); - // padding: 0 10px 10px 10px; - background-color: var(--action-background); - &.isFirst{ - // height: 1px!important; - display: none; - } + gap: 4px; } -/* Drag placeholder -/* ******************************** */ -.cdk-drag-preview { - box-sizing: border-box; +.node-badge { + font-size: 9px; + font-weight: 400; + letter-spacing: 0.5px; + padding: 0 5px; + height: 14px; border-radius: 4px; - box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12); -} - - -.cdk-drag-animating { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); -} - -// .box-action:last-child { -// border: none; -// } + display: inline-flex; + align-items: center; + color: #fff; + background: linear-gradient(45deg, #3167e2, #a736ff); + flex-shrink: 0; -.actions-list-wpr.cdk-drop-list-dragging .box-action:not(.cdk-drag-placeholder) { - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + &.badge-NEW { background: linear-gradient(45deg, #3167e2, #a736ff); } + &.badge-BETA { background: linear-gradient(45deg, #e23131, #ff8736); } + &.badge-DEP { background: linear-gradient(45deg, #e23131, #640b0b); } } -.action-drag-placeholder { - // background: #ccc; - background: var(--drop-zone-background); - // border: dotted 3px #999; - border: dashed 1px var(----drop-zone-color-border); - min-height: 60px; - transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); - border-radius: 8px; - opacity: 0; +// Il tipo viene iniettato tramite panel-intent-header — sovrascriviamo il suo stile +cds-panel-intent-header { + display: block; + min-width: 0; + width: 100%; } -.cdk-action-placeholder { - opacity: 1; +.node--start cds-panel-intent-header { + width: auto; } -.hide-drag-action-palceholder { - display: none; -} +.node-type { + font-family: "Geist Mono", ui-monospace, "SF Mono", monospace; + font-size: 10.5px; + color: var(--ds-muted, #8a8884); + text-transform: lowercase; + line-height: 1.2; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; -.cdk-drag-placeholder { - opacity: 1; } -.cds-no-featured-action { - // background-color: var(--action-no-featured-backgroud); - background-color: rgba(255, 255, 255, 0.7); -} +// ============================================================ +// NODE BODY (area contenuto / action) +// ============================================================ -.footer-intent { - cursor: pointer; - margin-bottom: -10px; - min-height: 12px; - .csd-open-action-menu-btn-wpr { - bottom: -28px; - } +.node-body { + border-top: 1px solid var(--ds-border, #ececea); + padding: 10px 12px 12px; } -.last-action-intent { - display: block; - float: inline-end; - // margin: 6px -12px 0 0; - // padding: 0 24px 0 0; - margin: 6px 0 0 0; - padding: 0; -} -/* Btn add action -/* --------------------------------- */ -.csd-open-action-menu-btn-wpr { - text-align: center; - position: absolute; - display: block; - bottom: -41px; - left: 0px; - right: 0px; - padding-top: 20px; -} -.footer-intent>.csd-open-action-menu-btn-wpr, -.add--action-placeholder .csd-open-action-menu-btn-wpr -{ - opacity: 0; -} +// ============================================================ +// ACTIONS LIST +// ============================================================ -.footer-intent:hover>.csd-open-action-menu-btn-wpr, -.add--action-placeholder:hover .csd-open-action-menu-btn-wpr { - opacity: 1; - transform: translate3d(0, 00px, 0); - transition: 0.25s all ease-in-out; +.actions-list-wpr { + display: flex; + flex-direction: column; + gap: 8px; } - -// .cds-last-action>.csd-open-action-menu-btn-wpr { -// opacity: 0; -// } - -// .cds-last-action:hover>.csd-open-action-menu-btn-wpr { -// opacity: 1; -// } - -.body-action { +.box-action { position: relative; display: flex; flex-direction: column; + align-items: center; width: 100%; - // background-color: #ffffff80; // nk - // box-shadow: #0000000f 0 0 0 1px; // nk - border-radius: 6px; // nk + min-height: 30px; + border-radius: var(--ds-radius-sm, 6px); + border: none; + background-color: var(--ds-surface, #fff); } -// .cds-featured-action { -// background-color: #e3e1f1; -// } +.cds-no-featured-action { + background-color: var(--ds-canvas, #f7f6f3); + border-color: transparent; +} + +.action-element { + width: 100%; +} .header-action { position: relative; - min-height: 54px; - /* padding: 0px 10px; */ - padding: 0px 0px; + padding: 0; width: 100%; - position: relative; display: flex; align-items: center; - // flex-direction: column; min-height: 25px; - // border-radius: 6px; - // background-color: rgb(255 255 255 / 50%); - // box-shadow: rgba(0, 0, 0, 0.06) 0px 0px 0px 1px; - &.isLast{ - display: none; - } -} - -.icon-action { - transition: opacity .15s ease 0s; - width: 20px; - height: 20px; - border-radius: 4px; - margin-right: 6px; - align-self: start; - color: #718497; - opacity: .85; - background: var(--brown); } -.label-action { - overflow-x: clip; - white-space: nowrap; - text-overflow: ellipsis; - font-size: 14px; -} - - -.tds_connectable { - width: 30px; - height: 30px; - background-color: #ff4000; +.body-action { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + border-radius: 6px; } -.unselectable { - -moz-user-select: -moz-none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; - user-select: none; +.cds-action-arrow { + position: absolute; + bottom: -15px; } -.button-intent { - display: block; - text-align: center; - user-select: none; - box-sizing: border-box; - outline: none; - border: 0.1em dashed #d2d2d2; - border-radius: 20px; - color: #fff; - cursor: pointer; - font-size: 1em; - font-weight: normal; - height: auto; - line-height: 32px; - margin: 10px 5px 0; - font-family: var(--font-family-poppins); - padding: 10px; - transition: all 0.1s; - - // min-width: 100px; - &:hover { - background-color: #d2d2d2; - color: #333333; - } +.cds-action-arrow > span { + transform: rotate(-90deg); + color: var(--ds-border-strong, #d8d6d2); } +// ============================================================ +// LAST ACTION INTENT (connettore implicito) +// ============================================================ -.button-intent-active { - // background-color: #d2d2d2; - // color: #333333; - - outline: 2px solid rgba(236, 182, 6, .6901960784) !important; - +.last-action-intent { + display: block; + float: inline-end; + margin: 6px 0 0 0; + padding: 0; } -// .button-intent:hover svg { -// fill: #333333; -// } +// ============================================================ +// FOOTER +// ============================================================ -.button-intent-active { - background-color: #d2d2d2; - color: #333333; -} - -.intent--action { - display: block; - text-align: center; - user-select: none; - box-sizing: border-box; - outline: none; - border: 0.1em dashed #d2d2d2; - border-radius: 20px; - color: #fff; +.footer-intent { cursor: pointer; - font-size: 1em; - font-weight: normal; - height: auto; - line-height: 32px; - margin: 10px 5px 0; - font-family: var(--font-family-poppins); - padding: 10px; - transition: all 0.3s; - width: 96px; + min-height: 8px; } -.actions-btn-active { - background-color: #fff; - color: #333333; - border: 1px solid #fff !important; -} -.cds-action-title { - position: absolute; - width: 155px; - margin-top: -57px; - text-align: center; - line-height: 15px; - height: 18px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - font-size: 11px; - font-size: 10px; - font-weight: 400; -} +// ============================================================ +// AGENTS AVAILABLE BADGE +// ============================================================ -.action-wpr { - height: 18px; - display: flex; - align-items: center; - justify-content: center; -} +.agents-available { + position: absolute; + top: -8px; + left: -8px; + display: block; -.cds-action-icon-wpr { - display: flex; - margin-right: 10px; + &.isStart { + top: -4px; + left: 8px; + } - img { - width: 18px; - filter: brightness(0) saturate(100%) invert(97%) sepia(66%) saturate(6656%) hue-rotate(177deg) brightness(102%) contrast(98%); + span.material-icons { + color: var(--ds-accent, oklch(0.66 0.15 50)); + font-size: 18px; } } -// .header__center { -// font-size: 2rem; -// display: grid; -// grid-template-columns: 1fr max-content 1fr; -// grid-column-gap: 1.2rem; -// align-items: center; -// margin-top: 24px; -// margin-bottom: 0px; -// padding-left: 12px; -// padding-right: 12px; -// } - -// .header__center::before, -// .header__center::after { -// content: ""; -// display: block; -// height: 1px; -// background-color: currentColor; -// } +// ============================================================ +// START BLOCK — connettore esterno alla pill +// ============================================================ -.cds-action-arrow { +.cds-start-connector { position: absolute; - // display: flex; - bottom: -15px -} + right: 5px; + top: 50%; + transform: translateY(-50%); + pointer-events: auto; -.cds-action-arrow>span { - transform: rotate(-90deg); - color: #d2e3fc; -} - - - - -.cds-add-action-btn { - margin: 0px; - padding: 0 10px; - background: var(--add-action-btn-background); - box-shadow: #001b4714 0 3px 8px; - border-radius: var(--base-border-radius-base); - color: var(--add-action-btn-color); - cursor: pointer; - font-size: 0.7em; - font-weight: 400; - transition: all .3s; - line-height: 20px; - width: 100%; - // outline: 2px solid var(--base-color) !important; - // z-index: 2; -} - -.cds-add-action-btn>span { - font-size: 16px; - color: var(--base-color); -} - -.cds-add-action-btn:hover { - opacity: 0.8; - // color: var(--add-action-btn-hover-color) -} - -cds-action-description.header-action ::ng-deep{ - .action-title{ - max-width: 100% + ::ng-deep .previewContent .title-label { + display: none; } } -cds-panel-intent-header.isStart ::ng-deep{ - input { - color: white !important; - } -} +// ============================================================ +// INTENT OPTIONS (brain / form) +// ============================================================ -//** FLOATING MENU - start**// .cds-intent-options { display: flex; - justify-content: center; - align-items: flex-end; - gap: 5px; - height: 33px; + align-items: center; + gap: 4px; .option { display: flex; cursor: pointer; + opacity: 0.5; + transition: opacity 0.12s; - &:hover { - opacity: 0.85; - } + &:hover { opacity: 1; } &[active=true] { + opacity: 1; img { filter: brightness(0) saturate(100%) invert(39%) sepia(19%) saturate(1139%) hue-rotate(184deg) brightness(91%) contrast(85%); } @@ -648,72 +376,27 @@ cds-panel-intent-header.isStart ::ng-deep{ } img { - width: 24px; - height: 24px; - filter: brightness(0) saturate(100%) invert(99%) sepia(8%) saturate(403%) hue-rotate(225deg) brightness(117%) contrast(100%); + width: 18px; + height: 18px; + filter: brightness(0) saturate(100%) invert(60%) sepia(0%) saturate(0%) hue-rotate(216deg) brightness(94%) contrast(91%); } } -//** FLOATING MENU - end**// - - - - -.add--action-placeholder { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - width: 100%; - min-height: 30px; - border-radius: 10px; - border: 1px solid var(--brown); - padding: 12px 6px; - border-style: dashed; - // background: rgba(62, 169, 245, 0.1); - background: rgba(221, 228, 234, .8); -} - -.add--action-placeholder-add-icon span { - color: var(--brown); - font-size: 30px; -} - -.add--action-placeholder-text { - font-weight: 400; - color: var(--brown); - font-size: 14px; - text-align: center; -} - -.add--action-placeholder:hover .add--action-placeholder-add-icon span { - color: #3ea9f5; -} -.add--action-placeholder:hover .add--action-placeholder-text { - color: #3ea9f5; -} +// ============================================================ +// LIVE ACTIVE ANIMATIONS (invariate) +// ============================================================ -.add--action-placeholder:hover { - border: 1px solid #3ea9f5; - border-style: dashed; -} - -.add--action-placeholder>.add-action-from-placeholder-btn-wpr { - opacity: 0; - position: absolute; - top: 99px; -} - -.add--action-placeholder:hover>.add-action-from-placeholder-btn-wpr { - opacity: 1; +.live-active-intent-pulse { + cursor: pointer; + animation: pulse-blu 1s 2 forwards; + outline: 2px solid var(--ds-accent, oklch(0.66 0.15 50)); } - -/** INTENT BORDER ANIMATION **/ .live-active-intent { position: relative; } + .live-active-intent::before { content: ""; position: absolute; @@ -725,47 +408,30 @@ cds-panel-intent-header.isStart ::ng-deep{ from var(--outline-angle), var(--blu) 60%, rgba(255, 255, 255, 0.5) 90%, - transparent 10%, - var(--blu) 80% + transparent 10%, + var(--blu) 80% ); animation: outline-spin 3s linear infinite; } + @property --outline-angle { syntax: ""; inherits: false; initial-value: 0turn; } + @keyframes outline-spin { - to { - --outline-angle: -1turn; - } + to { --outline-angle: -1turn; } } -/** SLIM INTENT **/ -.tds-slim-intent { - padding: 2px; - .pic-header { - padding: 0px; - } - .pic-title-text { - padding: 4px 8px 10px; - } - .footer-intent{ - min-height: 0px; - margin: 0; - } - .tds-drop-element { - width: calc(100% - 4px); - } -} - -.tds-drop-element { - position: absolute; - height: 30px; - width: calc(100% - 20px); - z-index: 1; - cursor: move; -} +// ============================================================ +// cds-panel-intent-header override (nel contesto del nodo) +// ============================================================ +cds-action-description.header-action ::ng-deep { + .action-title { + max-width: 100%; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts index 5886c5dbd..6165a9c98 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.ts @@ -11,7 +11,7 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; import { AppStorageService } from 'src/chat21-core/providers/abstract/app-storage.service'; import { TYPE_ACTION, TYPE_ACTION_VXML, ACTIONS_LIST, TYPE_CHATBOT } from 'src/app/chatbot-design-studio/utils-actions'; -import { INTENT_COLORS, TYPE_INTENT_NAME, replaceItemInArrayForKey, checkInternalIntent, generateShortUID, UNTITLED_BLOCK_PREFIX, DATE_NEW_CHATBOT } from 'src/app/chatbot-design-studio/utils'; +import { INTENT_COLORS, TYPE_INTENT_NAME, replaceItemInArrayForKey, checkInternalIntent, generateShortUID, UNTITLED_BLOCK_PREFIX, DATE_NEW_CHATBOT, INTENT_ELEMENT } from 'src/app/chatbot-design-studio/utils'; import { AppConfigService } from 'src/app/services/app-config'; import { DashboardService } from 'src/app/services/dashboard.service'; import { WebhookService } from 'src/app/chatbot-design-studio/services/webhook-service.service'; @@ -94,6 +94,20 @@ export class CdsIntentComponent implements OnInit, OnDestroy, OnChanges { /** INTENT ATTRIBUTES */ intentColor: any = INTENT_COLORS.COLOR1; + get firstActionElement(): any { + const type = this.listOfActions?.[0]?._tdActionType; + if (!type) return null; + if (type === 'form' || type === 'question' || type === 'answer') { + return Object.values(INTENT_ELEMENT).find((el: any) => el.type === type) ?? null; + } + if (type === 'jsoncondition') { + return 'noelse' in (this.listOfActions[0] as any) + ? ACTIONS_LIST.CONDITION + : ACTIONS_LIST.JSON_CONDITION; + } + return Object.values(ACTIONS_LIST).find((el: any) => el.type === type) ?? null; + } + private readonly logger: LoggerService = LoggerInstance.getInstance(); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.scss index 9d15bfe1a..ba499f154 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.scss @@ -1,89 +1,61 @@ @import "./src/assets/sass/animations.scss"; -/* Intent header actions -/* ***************************** */ -.intent-header-actions-container { - position: absolute; - top: -10px; - right: 0px; - height: 30px; - padding-left: 12px; - opacity: 0; - cursor: default; - transform: translate3d(0, 20px, 0); - transition: 0.25s all ease-in-out; - } - - - .intent-header-action-btn { - mat-icon { - height: 100%; - display: flex; - align-items: center; - ::ng-deep svg { - fill: var(--gray); - } - } - } +// Il container è ora inline nell'header del nodo (non più absolute/floating). +// La visibilità è controllata dal genitore via opacity transition. - - .intent-header-action-btn:hover { - mat-icon { - ::ng-deep svg { - fill: var(--blu); - } - } - } - - - .panel-intent-content:hover .intent-header-actions-container-on-start { - top: -19px !important; - right: 12px !important; - } - - - .intent-header-actions-wpr { - background: #fff; - height: 25px; - border-radius: 14px; - box-shadow: #001b4714 0 3px 8px; - outline: 1px solid #0000000a; +.intent-header-actions-container { + display: flex; + align-items: center; + justify-content: flex-end; + height: 28px; + padding-bottom: 4px; + + &.intent-header-actions-container-on-start { + // nessuna differenza visiva necessaria nella nuova struttura + } +} + +.intent-header-actions-wpr { + display: flex; + align-items: center; + gap: 0; + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + border-radius: var(--ds-radius-sm, 6px); + box-shadow: var(--ds-shadow-card, 0 1px 2px rgba(20,20,18,.04)); + padding: 2px; + height: 26px; +} + +button.intent-header-action-btn { + width: 22px; + height: 22px; + border: none; + background: none; + border-radius: 4px; + display: grid; + place-items: center; + cursor: pointer; + padding: 0; + color: var(--ds-muted, #8a8884); + transition: background 0.12s, color 0.12s; + + &:hover { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #1a1a19); + } + + mat-icon { + width: 14px; + height: 14px; + font-size: 14px; display: flex; - padding: 3px 0px; - } - - button.intent-header-action-btn { - border: none; - border-left: solid 1px var(--gray-light-02); - background-color: rgba(255, 255, 255, 0); + align-items: center; - img { - width: auto; - height: 100%; + ::ng-deep svg { + fill: currentColor; + width: 14px; + height: 14px; } } - - .intent-header-action-btn { - cursor: pointer; - border-left: solid 1px var(--gray-light-02); - padding: 2px 3px; - display: flex; - - } - - .intent-header-action-btn:first-child { - border-left: unset; - } - - .icon.webhook-enabled img { - filter: brightness(0) saturate(100%) invert(41%) sepia(79%) saturate(1263%) hue-rotate(121deg) brightness(101%) contrast(82%); - } - - .icon img { - filter: brightness(0) saturate(100%) invert(46%) sepia(0%) saturate(0%) hue-rotate(216deg) brightness(94%) contrast(91%); - } - .icon:hover { - img { - filter: brightness(0) saturate(100%) invert(39%) sepia(19%) saturate(1139%) hue-rotate(184deg) brightness(91%) contrast(85%); - } - } \ No newline at end of file +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html index e42641fa4..351224755 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html @@ -1,8 +1,5 @@
-
- rocket_launch -
undo
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.scss index baa5b1521..8f9c6df52 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.scss @@ -1,378 +1,90 @@ -:host{ - --width-title: 80%; +:host { + display: block; + min-width: 0; + width: 100%; } .header { - display: flex; - justify-content: space-between; - gap: 10px; - width: 100%; - height: var(--height-header-panel-intent); - max-height: var(--height-header-panel-intent); - padding-top: 6px; - .onff-intent-webhook { - font-size: 13px; - line-height: normal; - color: #ffffffb3; - font-weight: normal; - font-family: var(--font-family-poppins); - } - - .has--error { - background-color: var(--color-red-hex); - } - - .form-group { - width: 100%; - margin: 0; - padding: 0; - &.is-start { - margin-left: -40px; - input { - padding-left: 30px; - filter: none; - } - } - &.is-error { - .form-control { - background-image: linear-gradient(var(--color-red-hex), var(--color-red-hex)), - linear-gradient(var(--gray-light-01), var(--gray-light-01)); - background-size: 100% 2px, 100% 1px; - transition-duration: 0.3s; - } - } - &.is-focused:not(.is-error) { - .form-control { - background-image: linear-gradient(var(--blu), var(--blu)), - linear-gradient(var(--gray-light-01), var(--gray-light-01)); - background-size: 100% 2px, 100% 1px; - transition-duration: 0.3s; - } - } - .form-control { - height: auto; - border: 0; - background-size: 0 2px, 100% 0px; - background-image: linear-gradient(var(--gray-light-01), var(--gray-light-01)); - transition-duration: 0.2s; - &[readonly]{ - cursor: grab; - background-image: none !important; - } - } - label.title { - position: absolute; - display: block; - width: var(--width-title); - top: 0; - margin: 0; - padding: 0 0 0 10px; - font-weight: 400; - font-size: 1.0em; - line-height: var(--height-header-panel-intent); - color: var(--gray-light-01); - &.noDisplay { - display: none; - } - } - input { - display: block; - top: 0; - padding: 0; - margin:0; - font-size: 1.0em; - position: relative; - filter: brightness(70%); - } - .btn-save { - position: absolute; - width: calc(100% - var(--width-title)); - max-width: 100px; - right: 10px; - padding: 8px; - } - - } -} - -.header.is-start { - padding: 0; -} + display: flex; + align-items: center; + gap: 6px; + width: 100%; + cursor: grab; -.error---msg { - position: absolute; - top: 39px; - font-size: 11px; - color: var(--color-red-hex); - font-weight: 500; } +.intent-icon { + flex-shrink: 0; + display: flex; + align-items: center; -.onff-intent-webhook { - align-self: center; -} + span.rocket { color: var(--ds-green, oklch(0.68 0.13 155)); } + span.undo, + span.call_end { color: var(--ds-red, oklch(0.62 0.16 28)); } + span.webhook { color: var(--ds-accent, oklch(0.66 0.15 50)); } -.switch-label { - position: relative; - top: -22px; - right: -40px; - font-size: 14px; - color: #e8eaed; + .material-icons { font-size: 16px; } } +.form-group { + width: 100%; + margin: 0; + padding: 0; + position: relative; -// Config -$circle-size: 40px; - -// Unfortunatly we need a wrapper element containing the fixed width for centering the button within the animtion (you could also apply the width as an inline style). -.loading-btn-wrapper { - display: inline-block; - width: 150px; - height: $circle-size; - text-align: center; - right: 0px; - margin: 5px 10px 5px 5px; -} + &.is-start { + margin-left: 0; -.loading-btn { - $root: &; - position: relative; - display: inline-block; - width: 100%; - height: 100%; - &#cds-save-intent-btn{ - background: #3ea9f5; - border: 1px solid #3ea9f5; - box-shadow: none; - } - margin: 0px; - cursor: pointer; - transition: all .33s ease-in-out; - &#cds-save-intent-btn:hover { - background: rgba(138, 180, 248, 0.8); - box-shadow: none; - background-color: #1e293b; - border: 1px solid white; - } - &, &:focus { - outline: none; - } - - // Styles for all states - &--pending, - &--success, - &--fail { - // Morph button to circle (width equals height) - // width: $circle-size; - - // Prevent any further clicks triggering events during animation - pointer-events: none; - cursor: default; - margin: 0; - padding: 0px; - width: 100%; - height: 100%; - - // Hide text - #{$root}__text { - opacity: 0; + input { + padding-left: 0; + filter: none; } } - - // State "pending" - // Show loading indicator - &--pending:before { - content: ''; - - position: absolute; - top: 50%; - left: 50%; - - display: inline-block; - // Can't use percentage here as we already show this icon during morph animation - height: #{$circle-size * .7}; - width: #{$circle-size * .7}; - - border: 3px solid rgba(255, 255, 255, .33); - border-top-color: #fff; - border-radius: 50%; - - animation: - loading-btn--fade-in .33s ease, - loading-btn--rotation .66s linear 0s infinite; + &.is-error .form-control { + background-image: linear-gradient(var(--color-red-hex, #e53935), var(--color-red-hex, #e53935)), + linear-gradient(var(--ds-border, #ececea), var(--ds-border, #ececea)); + background-size: 100% 2px, 100% 1px; + background-repeat: no-repeat; + background-position: center bottom, center calc(100% - 0px); + transition-duration: 0.3s; } - - // Success state - show check icon - &--success { - // Different background color (also on hover) - &, &:hover { - background: #8bc34a !important; - // border: 1px solid #8bc34a; - } - - // Use "after" pseudo to trigger new fade in animation, as "before" is already used on "--pending" - &:after { - content: ''; - - position: absolute; - top: 50%; - left: 50%; - - // Simulate checkmark icon - display: inline-block; - height: 25%; - width: 20%; //50%; - border: 3px solid #fff; - border-top-width: 0; - border-right-width: 0; - outline: none; - transform: translate(-50%, -75%) rotate(-45deg); - - animation: - loading-btn--fade-in .6s ease; - } - } - - // Fail state - show cross icon - &--fail { - - // Different background color (also on hover) - &, &:hover { - background: #ff5722; - // border: 1px solid #ff5722; - } - - // Use "after" pseudo to trigger new fade in animation, as "before" is already used on "--pending" - &:after { - content: ''; - - position: absolute; - top: 50%; - left: 50%; - - // Simulate cross icon - display: inline-block; - height: 50%; - width: 25%; - - // Using background gradient is the only solution creating a cross with a single element - background: - linear-gradient( - to bottom, - transparent 44%, - #fff 44%, - #fff 56%, - transparent 56% - ), - - linear-gradient( - to right, - transparent 44%, - #fff 44%, - #fff 56%, - transparent 56% - ); - - transform: translate(-50%, -50%) rotate(-45deg); - - animation: - loading-btn--fade-in .6s ease; - } - } - - // Text has to be positioned absolute in order prevent line-breaks or trimming of text when morphing button to circle. - &__text { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - + .form-control { + height: auto; + border: 0; + background: none; + width: 100%; + display: block; + padding: 0; + margin: 0; + font-size: 13px; + font-weight: 500; + letter-spacing: -0.005em; + color: var(--ds-ink, #1a1a19); + line-height: 1.3; overflow: hidden; - white-space: nowrap; text-overflow: ellipsis; - - font-size: 13px; - color: #fff; - - transition: inherit; - } -} - - -/** - * Animations - */ - -@keyframes loading-btn--fade-in { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} - -@keyframes loading-btn--rotation { - 0% { - transform: translate(-50%, -50%) rotate(0deg); - } + white-space: nowrap; + transition-duration: 0.2s; - 100% { - transform: translate(-50%, -50%) rotate(360deg); + &:focus { + outline: none; + white-space: normal; } -} - -/** - * Optical stuff - has nothing todo with button animation. - */ - - .state-list { - margin-bottom: 12px; - - .loading-btn-wrapper { - background: repeating-linear-gradient( - 45deg, - #fff, - #fff 10px, - #f0f0f0 10px, - #f0f0f0 20px - ); - } -} - -.loading-btn-wrapper { - & + & { - margin-left: 8px; + &[readonly] { + cursor: grab; } + } } -.btns-wpr { - display: flex; - background: rgba(255,255,255,.2392156863); - margin-top: 10px; - margin-right: 12px; - padding: 10px; - border-radius: 30px; - height: 30px; - min-width: 190px; - justify-content: center; +.error---msg { + position: absolute; + top: 100%; + margin-top: 2px; + font-size: 11px; + color: var(--ds-red, oklch(0.62 0.16 28)); + font-weight: 500; + white-space: nowrap; } - -.intent-icon { - position: relative; - top: 0px; - span.rocket { - color: var(--color-green-hex); - } - span.undo, - span.call_end { - color: var(--color-red-hex) - } - span.webhook { - color: var(--color-yellow-hex) - } -} \ No newline at end of file diff --git a/src/assets/sass/_ds-tokens.scss b/src/assets/sass/_ds-tokens.scss new file mode 100644 index 000000000..51dee5239 --- /dev/null +++ b/src/assets/sass/_ds-tokens.scss @@ -0,0 +1,27 @@ +// Design Studio v3 — Design tokens +// Ispirato al design minimalista prodotto in Claude Design (OpenAI Agent Builder / n8n) + +:root { + --ds-bg: #fbfbfa; + --ds-canvas: #f7f6f3; + --ds-surface: #ffffff; + --ds-border: #ececea; + --ds-border-strong: #d8d6d2; + --ds-ink: #1a1a19; + --ds-ink-2: #4a4a47; + --ds-muted: #8a8884; + --ds-muted-2: #b3b1ac; + --ds-accent: oklch(0.66 0.15 50); + --ds-accent-soft: oklch(0.95 0.04 60); + --ds-accent-ink: oklch(0.45 0.15 45); + --ds-green: oklch(0.68 0.13 155); + --ds-green-soft: oklch(0.95 0.04 155); + --ds-blue: oklch(0.62 0.13 245); + --ds-blue-soft: oklch(0.95 0.03 245); + --ds-red: oklch(0.62 0.16 28); + --ds-red-soft: oklch(0.95 0.03 28); + --ds-shadow-card: 0 1px 2px rgba(20, 20, 18, 0.04), 0 0 0 1px rgba(20, 20, 18, 0.05); + --ds-shadow-pop: 0 8px 24px -8px rgba(20, 20, 18, 0.12), 0 2px 6px rgba(20, 20, 18, 0.05), 0 0 0 1px rgba(20, 20, 18, 0.06); + --ds-radius: 10px; + --ds-radius-sm: 6px; +} diff --git a/src/assets/sass/cds/_variables.scss b/src/assets/sass/cds/_variables.scss index 963e26b29..62711eabc 100644 --- a/src/assets/sass/cds/_variables.scss +++ b/src/assets/sass/cds/_variables.scss @@ -121,9 +121,9 @@ --scrollbar-thumb-background: var(--blu); --scrollbar-thumb-border-radius: 3px; - /** CANVAS CONTAINER COLORS */ - --container-background: rgb(152 153 153 / 40%); - --container-points-color: rgb(240 233 233 / 25%); + /** CANVAS CONTAINER COLORS — Design Studio v3 */ + --container-background: rgb(179 177 172 / 55%); + --container-points-color: #f7f6f3; /** PANEL ACTION DETAIL **/ --header-panel-action-detail-height: 44px; diff --git a/src/assets/sass/cds/connector-styles.scss b/src/assets/sass/cds/connector-styles.scss index 98b688415..c1320dd24 100644 --- a/src/assets/sass/cds/connector-styles.scss +++ b/src/assets/sass/cds/connector-styles.scss @@ -32,11 +32,9 @@ cds-connector.connector { right: -28px; top: calc(50% - 10px); } -// cds-connector.connector-isStart { -// position: absolute; -// right: -20px; -// top: calc(50% - 13px); -// } +cds-connector.connector-isStart { + display: block; +} cds-connector.connector-isLast { position: absolute; right: -32px; diff --git a/src/assets/sass/cds/styles.scss b/src/assets/sass/cds/styles.scss index 1bd257dc3..bf49f881c 100644 --- a/src/assets/sass/cds/styles.scss +++ b/src/assets/sass/cds/styles.scss @@ -197,6 +197,24 @@ emoji-mart { /* Intent Controls /* ------------------------ */ +cds-intent > cds-panel-intent-controls { + position: absolute; + top: -32px; + right: 0; + z-index: 10; +} + +cds-intent > cds-panel-intent-controls > .intent-header-actions-container { + visibility: hidden; + transition: visibility 0s 0.15s; +} + +cds-intent:hover > cds-panel-intent-controls > .intent-header-actions-container { + visibility: visible; + transition-delay: 0s; +} + +/* legacy fallback (rimosso con v3) */ .panel-intent-content:hover cds-panel-intent-controls>.intent-header-actions-container-on-start { top: -30px !important; right: 12px !important; diff --git a/src/styles.scss b/src/styles.scss index 3da599bfa..389184ae5 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,4 +1,5 @@ /* You can add global styles to this file, and also import other style files */ +@import "./assets/sass/ds-tokens"; .ng-dropdown-panel { From 9ad90259f249b8fe430e8d3ba941428640ee906f Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 30 Apr 2026 16:40:15 +0200 Subject: [PATCH 04/30] rifattorizzate le sidebar e l'header --- .../cds-canvas/cds-canvas.component.html | 43 +- .../cds-canvas/cds-canvas.component.scss | 86 ++- .../cds-canvas/cds-canvas.component.ts | 23 +- .../cds-canvas/cds-canvas.module.ts | 2 + .../cds-panel-intent-list.component.html | 221 ++++--- .../cds-panel-intent-list.component.scss | 566 +++++++---------- .../cds-panel-intent-list.component.ts | 15 +- .../cds-panel-library.component.html | 116 ++++ .../cds-panel-library.component.scss | 419 +++++++++++++ .../cds-panel-library.component.ts | 185 ++++++ .../cds-dashboard.component.scss | 26 +- .../cds-header/cds-header.component.html | 307 ++++----- .../cds-header/cds-header.component.scss | 593 +++++++++--------- .../cds-sidebar/cds-sidebar.component.html | 368 +++-------- .../cds-sidebar/cds-sidebar.component.scss | 320 +++------- src/assets/sass/cds/_variables.scss | 32 + 16 files changed, 1848 insertions(+), 1474 deletions(-) create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.ts diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html index 19a250a58..867784222 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html @@ -1,10 +1,9 @@ -
+ - -
+
-->
- +
+ + +
+ + + + + + +
- -
- {{ 'Blocks' | translate }} + +
+
{{ 'Blocks' | translate }}
+
+ + +
+
+
+ rocket_launch + undo + + + + + + + +
- -
-
- -
-
- -
- {{onGetIconForName(intent)}} -
- -
-
-

boy{{intent.intent_display_name}}

-
- -

Ai

- - - - - - - - - -
- - -

{{ intent.actions?.length }}

-
-
-
- - -
- -
+
+
{{ intent.intent_display_name }}
+
+
+
+ + +
+ +
+ + +
+ + +
+ +
+
+
+
+ + + + +
+
+
+ + {{ intent.intent_display_name }}
- +
+ + + + {{ intent.actions?.length }} +
+
+
- - - \ No newline at end of file +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss index 44092a0a9..7b98ff991 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss @@ -1,380 +1,274 @@ @import "./src/assets/sass/cds/_variables.scss"; +:host { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + background: var(--ds-bg, #fbfbfa); + user-select: none; + font-family: var(--font-family-poppins); +} + +.mono { + font-family: 'Roboto Mono', 'Geist Mono', ui-monospace, monospace; + font-feature-settings: normal; +} + + +// ── Title header ────────────────────────────────────────────────────────────── + +.lib-head-title { + padding: 14px 16px 12px; + border-bottom: 1px solid var(--ds-border, #ececea); + flex-shrink: 0; +} + +.lib-title-text { + font-size: 13px; + font-weight: 600; + color: var(--ds-ink, #1a1a19); + letter-spacing: -0.01em; +} + -:host{ - --text-color: #{var(--gray)}; - --text-color-hover: #{var(--blu)}; - --background-color-hover: #{var(--blu)}; - --text-color-active: #{var(--blu)}; - --background-color-active: var(--icon-active-background); - --icon-color-active: #{var(--blu)}; +// ── Pinned / Core blocks ────────────────────────────────────────────────────── + +.pinned-blocks { + padding: 8px 8px 12px; + display: flex; + flex-direction: column; + gap: 2px; + flex-shrink: 0; } -.content { - width: 100%; - display: flex; - flex-direction: column; - justify-content: center; - color: #728087; - padding: 6px; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + +// ── Search (lib-head with top border) ───────────────────────────────────────── + +.lib-head { + padding: 12px; + border-top: 1px solid var(--ds-border, #ececea); + flex-shrink: 0; } -.list-title{ +.search { + display: flex; + align-items: center; + gap: 8px; + height: 34px; + border: 1px solid var(--ds-border, #ececea); + border-radius: 999px; + background: var(--ds-surface, #fff); + padding: 0 12px; + color: var(--ds-muted, #8a8884); + width: 100%; + transition: border-color 0.12s, box-shadow 0.12s; + + &:focus-within { + box-shadow: 0 0 0 3px oklch(0.85 0.05 240 / 0.55); + } + + .i { + width: 14px; + height: 14px; + flex-shrink: 0; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + + input { + border: none; + outline: none; + background: none; + flex: 1; font-size: 13px; + color: var(--ds-ink, #1a1a19); + font-family: inherit; + text-align: left; + font-weight: 200; + &::placeholder { color: var(--ds-muted, #8a8884); } + } } -.search-box { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - width: 100%; - margin-top: 25px; - padding-left: 10px; - - .icon-container { - padding-right: 3px; - } - - .custom-input { - background-color: transparent; - border-radius: 6px; - border: none; - color: var(--icon-color-active); - text-align: left; - - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - - &::placeholder { - color: var(--icon-color-active); - font-weight: 300; - opacity: 1; /* Firefox */ - } - } - - .input-box-search-input-wpr{ - width: 100%; - } + +// ── Lib body ────────────────────────────────────────────────────────────────── + +.lib-body { + flex: 1; + overflow-y: auto; + padding: 6px 8px 16px; + border-top: 1px solid var(--ds-border, #ececea); + scrollbar-width: thin; + scrollbar-color: var(--ds-border, #ececea) transparent; } +// ── Block items (shared between pinned and accordion) ───────────────────────── -// .intents-list { -// .topic-internal { +.block-item { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 7px 10px; + border-radius: var(--ds-radius-sm, 6px); + cursor: pointer; + transition: background 0.12s; -// } -// } + &:hover { background: var(--ds-canvas, #f7f6f3); } + &--active { + background: var(--ds-canvas, #f7f6f3); -.rocket_launch { - font-size: 20px; - font-weight: 600; - span { - font-size: 20px; - position: relative; - top: 2px; - left: 3px; - } + .block-name { font-weight: 600; } + } } -.undo { - font-size: 20px; - font-weight: 600; +.block-icon { + width: 22px; + height: 22px; + display: grid; + place-items: center; + color: var(--ds-muted, #8a8884); + flex-shrink: 0; + margin-top: 1px; + + // color overrides for system blocks + &.green { color: var(--ds-green, oklch(0.68 0.13 155)); } + &.red { color: var(--ds-red, oklch(0.62 0.16 28)); } + + .i-sm { + width: 14px; + height: 14px; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + + .sys-icon { + font-size: 15px; + width: 15px; + height: 15px; + line-height: 15px; + color: inherit; + } } -.title-box { - width: 100%; - display: flex; - flex-direction: row; - justify-content: flex-end; - padding: 10px 0px; - - .title { - color: var(--text-color); - font-weight: 500; - font-size: 14px; - } - - .new-intent-button { - display: flex; - flex-direction: row; - font-size: 14px; - align-items: center; - padding: 0px 14px 0px 10px; - border-radius: 16px; - cursor: pointer; - - .plus-icon { - font-size: 16px; - color: var(--text-color); - } - - .button-text { - margin-bottom: 0px; - color: var(--text-color); - } - } - - .new-intent-button:hover { - background-color: var(--background-color-hover); - - .plus-icon { - font-size: 16px; - color: var(--text-color); - } - - .button-text { - color: var(--text-color); - } - } +.block-text { + display: flex; + flex-direction: column; + gap: 1px; + min-width: 0; + flex: 1; } +.block-name { + font-size: 13px; + color: var(--ds-ink, #1a1a19); + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: flex; + align-items: center; + gap: 4px; +} -.icon-container { - width: 30px; - display: flex; - height: 100%; - align-items: center; - color: var(--icon-color-active); - mat-icon { - height: 100%; - display: flex; - // align-items: center; - align-items: flex-start; - ::ng-deep svg { - width: 18px; - height: 18px; - fill: var(--gray); - } - } - - img { - width: 18px; - filter: brightness(0) saturate(100%) invert(96%) sepia(0%) saturate(504%) hue-rotate(151deg) brightness(92%) contrast(88%); - } - - .material-icons{ - font-size: 18px; - color: var(--text-color); - } - - img.active-icon { - filter: brightness(0) saturate(100%) invert(39%) sepia(19%) saturate(1139%) hue-rotate(184deg) brightness(91%) contrast(85%); - - } +.block-default { + color: var(--ds-muted, #8a8884); + font-weight: 400; + font-family: 'Roboto Mono', 'Geist Mono', ui-monospace, monospace; + font-size: 12px; } -.custom-divider-search { - background-color: var(--color-white-hex); - width: 90%; - height: 1px; - box-shadow: 0px 0px 20px #334754c9; - margin: 6px 0px 14px 0px; +.block-meta { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 10.5px; + color: var(--ds-muted, #8a8884); } -.intent { - display: flex; - flex-direction: row; - justify-content: flex-start; - border-radius: 6px; - min-height: 38px; - margin-bottom: 8px; - cursor: pointer; - transition: all 0.3s; - align-items: flex-start; - height: 20px; - padding-left: 10px; - opacity: 0.7; - - mat-icon { - height: 100%; - display: flex; - align-items: center; - ::ng-deep svg { - height: 12px; - fill: var(--gray); - } - } - - .icon-container { - mat-icon { - ::ng-deep svg { - width: 18px; - height: 18px; - fill: var(--gray); - } - } - } - - .item-box { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - align-items: center; - position: relative; - } - - .delete-box { - display: none; - margin-right: 4px; - position: absolute; - right: 0px; - } - - .intent-display-name { - color: rgba($color: var(--text-color), $alpha: 1); - font-weight: 500; - margin-bottom: 0px; - font-size: 14px; - overflow: hidden; - max-width: 170px; - display: flex; - align-items: center; - } - - .icon-list { - display: flex; - flex-direction: row; - gap: 3px; - .ai-icon, - .webhook-icon, - .list-alt-icon, - .bolt-icon { - line-height: 100%; - font-size: 12px; - } - .ai-icon { - width: 14px; - } - .actions { - display: flex; - align-items: flex-start; - width: 24px; - height: fit-content; - justify-content: center; - mat-icon { - width: 12px; - } - } - - .action-counter { - font-size: 10px; - line-height: 12px; - padding: 0px; - margin: 0px; - } - - } +.agents-icon { + width: 13px; + height: 13px; + flex-shrink: 0; + color: var(--ds-muted, #8a8884); + + ::ng-deep svg { + width: 13px; + height: 13px; + fill: currentColor; + } } -.intent:hover { - box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - opacity: 1; - - .delete-box { - display: block; - - .delete-icon { - font-size: 20px; - } - } - - .delete-box:hover { - .delete-icon { - font-size: 20px; - color: var(--color-white-hex); - transition: 0.3s; - } - } - - .icon-list { - mat-icon { - ::ng-deep svg { - fill: var(--blu); - } - } - } - - .icon-container { - color: var(--text-color-hover) !important; - mat-icon { - ::ng-deep svg { - fill: var(--blu); - } - } - img{ - filter: brightness(0) saturate(100%) invert(39%) sepia(19%) saturate(1139%) hue-rotate(184deg) brightness(91%) contrast(85%); - } - .material-icons{ - color: var(--text-color-hover) !important; - } - } - - .intent-display-name { - color: var(--text-color-hover); - } - - .ai-icon, - .webhook-icon, - .list-alt-icon, - .bolt-icon, - .action-counter{ - // // color: var(--gray-light-01); - color: var(--blu); - } -} +// ── Accordion ───────────────────────────────────────────────────────────────── -.active { - opacity: 1; - .intent-display-name { - color: var(--text-color-active); - font-weight: 600; - margin-bottom: 0px; - } - - .icon-container{ - color: var(--icon-color-active) !important; - .material-icons{ - color: var(--icon-color-active) !important; - } - - } +.acc { + border-bottom: 1px solid var(--ds-border, #ececea); + &:last-child { border-bottom: none; } } +.acc-header { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + padding: 10px 8px; + border: none; + background: none; + border-radius: var(--ds-radius-sm, 6px); + transition: background 0.12s; + + &:hover { background: var(--ds-canvas, #f7f6f3); } +} +.acc-name { + flex: 1; + text-align: left; + font-size: 13px; + font-weight: 500; + color: var(--ds-ink, #1a1a19); + letter-spacing: -0.005em; +} -.add-start { - width: 100%; - border: dashed 1px grey; - height: 40px; - display: flex; - align-items: center; - padding: 0px 15px; - border-radius: 10px; +.acc-count { + font-family: 'Roboto Mono', 'Geist Mono', ui-monospace, monospace; + font-size: 10.5px; + color: var(--ds-muted, #8a8884); } -.hidden { - display: none; +.acc-chev { + width: 12px; + height: 12px; + stroke: var(--ds-muted, #8a8884); + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + flex-shrink: 0; + transition: transform 0.2s; + + &--open { transform: rotate(180deg); } } +.acc-body { + overflow: hidden; + max-height: 0; + transition: max-height 0.25s ease; -mat-icon.agents-available { - ::ng-deep svg { - height: 16px; - } + &--open { max-height: 2000px; } } -.agents-available { - font-size: 16px; -} \ No newline at end of file +.acc-inner { + padding: 2px 0 8px; + display: flex; + flex-direction: column; + gap: 1px; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts index 2a219cbec..a87761c82 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts @@ -35,7 +35,11 @@ export class CdsPanelIntentListComponent implements OnInit, OnChanges { internalIntents: Intent[] = []; defaultIntents: Intent[] = []; filteredIntents: Intent[] = []; - + untitledIntents: Intent[] = []; + + isRenamedExpanded = true; + isDefaultExpanded = false; + idSelectedIntent: string; @@ -105,6 +109,7 @@ export class CdsPanelIntentListComponent implements OnInit, OnChanges { this.internalIntents = intents.filter(obj => obj.attributes && obj.attributes.readonly === true && !obj.intent_display_name?.startsWith(UNTITLED_BLOCK_PREFIX)); this.logger.log('[cds-panel-intent-list] --- internalIntents ',this.internalIntents); this.defaultIntents = intents.filter(obj => obj.attributes && obj.attributes.readonly !== true && !obj.intent_display_name?.startsWith(UNTITLED_BLOCK_PREFIX)); + this.untitledIntents = intents.filter(obj => obj.attributes && obj.attributes.readonly !== true && obj.intent_display_name?.startsWith(UNTITLED_BLOCK_PREFIX)); this.logger.log('[cds-panel-intent-list] --- defaultIntents ',this.defaultIntents); this.internalIntents = moveItemToPosition(this.internalIntents, TYPE_INTENT_NAME.START, 0); this.internalIntents = moveItemToPosition(this.internalIntents, TYPE_INTENT_NAME.DEFAULT_FALLBACK, 1); @@ -171,5 +176,13 @@ export class CdsPanelIntentListComponent implements OnInit, OnChanges { this.deleteIntent.emit(intent); } + /** Returns css color-variant class for the lib-icon of a system intent */ + getIconColorClass(intent: Intent): string { + const icon = this.onGetIconForName(intent); + if (icon === this.ICON_ROCKET) return 'green'; + if (icon === this.ICON_UNDO) return 'red'; + return ''; + } + } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html new file mode 100644 index 000000000..a30ea934b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html @@ -0,0 +1,116 @@ + +
+ +
+ + +
+ +
+ + + +
+
+ +
+ +
+ +
+ +
+ +
{{ item.value.name | translate }}
+ + PRO + {{ item.value.badge }} + +
+ + + + + +
+
+ +
+
+ +
+ +
+ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.scss new file mode 100644 index 000000000..ac2358c12 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.scss @@ -0,0 +1,419 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host { + display: flex; + flex-direction: column; + height: 100%; + overflow: visible; + background: var(--ds-bg, #fbfbfa); + user-select: none; + font-family: var(--font-family-poppins); +} + + +// ── Head ────────────────────────────────────────────────────────────────────── + +.lib-head { + padding: 12px; + border-bottom: 1px solid var(--ds-border, #ececea); + flex-shrink: 0; + display: flex; + align-items: center; + gap: 8px; +} + +.search { + flex: 1; + display: flex; + align-items: center; + gap: 8px; + height: 34px; + border: 1px solid var(--ds-border, #ececea); + border-radius: 999px; + background: var(--ds-surface, #fff); + padding: 0 12px; + color: var(--ds-muted, #8a8884); + transition: border-color 0.12s, box-shadow 0.12s; + + &:focus-within { + box-shadow: 0 0 0 3px oklch(0.85 0.05 240 / 0.55); + } + + .i { + width: 14px; + height: 14px; + flex-shrink: 0; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + + input { + border: none; + outline: none; + background: none; + flex: 1; + font-size: 13px; + color: var(--ds-ink, #1a1a19); + font-family: inherit; + + &::placeholder { color: var(--ds-muted, #8a8884); } + } +} + + +// ── Body ────────────────────────────────────────────────────────────────────── + +.lib-body { + flex: 1; + overflow-y: auto; + padding: 6px 8px 16px; + scrollbar-width: thin; + scrollbar-color: var(--ds-border, #ececea) transparent; + overscroll-behavior: contain; +} + + +// ── Accordion ───────────────────────────────────────────────────────────────── + +.acc { + border-bottom: 1px solid var(--ds-border, #ececea); + + &:last-child { border-bottom: none; } +} + +.acc-header { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + padding: 10px 8px; + border: none; + background: none; + border-radius: var(--ds-radius-sm, 6px); + cursor: pointer; + transition: background 0.12s; + + &:hover { background: var(--ds-canvas, #f7f6f3); } +} + +.acc-dot { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; + background: var(--cat-color, var(--ds-muted, #8a8884)); + box-shadow: 0 0 0 3px var(--cat-soft, var(--ds-canvas, #f7f6f3)); +} + +.acc[data-cat="MOST_USED"] { --cat-color: oklch(0.55 0.02 90); --cat-soft: oklch(0.94 0.01 90); } +.acc[data-cat="AI"] { --cat-color: oklch(0.66 0.15 50); --cat-soft: oklch(0.95 0.04 60); } +.acc[data-cat="FLOW"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); } +.acc[data-cat="INTEGRATIONS"] { --cat-color: oklch(0.62 0.14 195); --cat-soft: oklch(0.95 0.04 195); } +.acc[data-cat="SPECIAL"] { --cat-color: oklch(0.6 0.14 290); --cat-soft: oklch(0.95 0.04 290); } +.acc[data-cat="VOICE"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); } +.acc[data-cat="VOICE_TWILIO"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); } + +.acc-name { + flex: 1; + text-align: left; + font-size: 13px; + font-weight: 500; + color: var(--ds-ink, #1a1a19); + letter-spacing: -0.005em; +} + +.acc-count { + font-family: 'Roboto Mono', 'Geist Mono', ui-monospace, monospace; + font-size: 10.5px; + color: var(--ds-muted, #8a8884); +} + +.acc-chev { + width: 12px; + height: 12px; + stroke: var(--ds-muted, #8a8884); + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + flex-shrink: 0; + transition: transform 0.2s; + + &--open { transform: rotate(180deg); } +} + +.acc-body { + overflow: hidden; + max-height: 0; + transition: max-height 0.25s ease; + + &--open { max-height: 2000px; } +} + +.acc-inner { + padding: 2px 0 8px; + display: flex; + flex-direction: column; + gap: 1px; +} + + +// ── Items ───────────────────────────────────────────────────────────────────── + +.lib-item { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 8px; + border-radius: var(--ds-radius-sm, 6px); + cursor: grab; + transition: background 0.12s; + + &:hover { background: var(--ds-canvas, #f7f6f3); } + &:active { cursor: grabbing; } +} + +.lib-icon { + width: 22px; + height: 22px; + border-radius: 5px; + display: grid; + place-items: center; + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + color: var(--ds-ink-2, #4a4a47); + flex-shrink: 0; + overflow: hidden; + + mat-icon, .lib-svg-icon { + width: 13px !important; + height: 13px !important; + min-width: 13px; + min-height: 13px; + font-size: 13px; + line-height: 13px; + display: flex; + align-items: center; + justify-content: center; + + ::ng-deep svg { + width: 13px; + height: 13px; + fill: currentColor; + } + } +} + + +.lib-name { + font-size: 13px; + color: var(--ds-ink, #1a1a19); + flex: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.lib-badge-pro { + font-size: 10px; + font-weight: 600; + color: var(--ds-accent-ink, oklch(0.45 0.15 45)); + background: var(--ds-accent-soft, oklch(0.95 0.04 60)); + padding: 1px 5px; + border-radius: 4px; + flex-shrink: 0; +} + +.lib-info-btn { + width: 22px; + height: 22px; + flex-shrink: 0; + display: grid; + place-items: center; + border-radius: var(--ds-radius-sm, 6px); + cursor: pointer; + opacity: 0; + transition: opacity 0.12s, background 0.12s; + + svg { + width: 13px; + height: 13px; + stroke: var(--ds-muted, #8a8884); + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + flex-shrink: 0; + } + + &:hover { + background: var(--ds-border, #ececea); + + svg { stroke: var(--ds-ink, #1a1a19); } + } +} + +.lib-item:hover .lib-info-btn { + opacity: 1; +} + +.lib-badge { + font-size: 10px; + font-weight: 600; + padding: 1px 5px; + border-radius: 4px; + flex-shrink: 0; + color: var(--ds-muted, #8a8884); + background: var(--ds-canvas, #f7f6f3); +} + + +// ── Info tooltip ───────────────────────────────────────────────────────────── + +.info-tooltip { + position: fixed; + width: 270px; + z-index: 1000; + padding: 0 10px; + animation: .15s ease fadein, .15s ease movein; +} + +@keyframes fadein { from { opacity: 0 } to { opacity: 1 } } +@keyframes movein { from { transform: translateX(-6px) } to { transform: none } } + +.tooltip-wrp { + position: relative; + padding: 14px; + border-radius: 8px; + background: #181f29; + display: flex; + flex-direction: column; + gap: 8px; + font-family: var(--font-family-poppins); +} + +.tooltip-caret { + position: absolute; + left: -4px; + top: 12px; + width: 8px; + height: 8px; + background: #181f29; + transform: rotate(45deg); +} + +.tooltip-header { + display: flex; + align-items: center; + gap: 6px; +} + +.tooltip-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + color: #fff; + + .lib-svg-icon { + width: 13px; + height: 13px; + filter: brightness(0) invert(1); + } +} + +.tooltip-title { + font-size: 13px; + font-weight: 500; + color: #fff; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.tooltip-content { + display: flex; + flex-direction: column; + gap: 5px; +} + +.tooltip-text-title { + font-size: 13px; + font-weight: 600; + color: #fff; +} + +.tooltip-text-desc { + font-size: 12px; + color: rgba(255,255,255,.7); + line-height: 1.5; +} + +.tooltip-image { + object-fit: cover; + width: 100%; + border-radius: 4px; + margin-top: 2px; +} + +.tooltip-footer { + display: flex; + align-items: center; + justify-content: space-between; + flex-direction: row-reverse; + font-size: 12px; + + a { + color: rgba(255,255,255,.6); + text-decoration: none; + padding: 4px 8px; + + &:hover { color: #fff; } + } +} + +.tooltip-video-btn { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 12px; + font-weight: 400; + background: #fff; + color: #1a1a19; + border: none; + border-radius: 6px; + padding: 4px 8px; + cursor: pointer; + + &:hover { background: #f7f6f3; } +} + + +// ── CDK drag ────────────────────────────────────────────────────────────────── + +.lib-drag-placeholder { + height: 32px; + border-radius: var(--ds-radius-sm, 6px); + background: var(--ds-canvas, #f7f6f3); + border: 1px dashed var(--ds-border-strong, #d8d6d2); +} + +::ng-deep .cdk-drag-preview { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 8px; + border-radius: var(--ds-radius-sm, 6px); + background: var(--ds-surface, #fff); + box-shadow: var(--ds-shadow-pop); + font-size: 13px; + font-family: var(--font-family-poppins); + color: var(--ds-ink, #1a1a19); + cursor: grabbing; +} + +::ng-deep .cdk-drag-animating { + transition: transform 0.2s cubic-bezier(0.2, 0, 0, 1); +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.ts new file mode 100644 index 000000000..b6d3aad25 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.ts @@ -0,0 +1,185 @@ +import { Component, OnInit, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core'; +import { CdkDragStart, CdkDragEnd } from '@angular/cdk/drag-drop'; +import { TranslateService } from '@ngx-translate/core'; + +import { TYPE_OF_MENU } from '../../../utils'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { TYPE_CHATBOT, ACTIONS_LIST, TYPE_ACTION_CATEGORY, ACTION_CATEGORY } from 'src/app/chatbot-design-studio/utils-actions'; +import { ProjectPlanUtils } from 'src/app/utils/project-utils'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { ControllerService } from '../../../services/controller.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +interface ActionItem { + type: string; + value: any; + canLoad: boolean; +} + +interface CategoryEntry { + type: string; + name: string; + src: string; +} + + +@Component({ + selector: 'cds-panel-library', + templateUrl: './cds-panel-library.component.html', + styleUrls: ['./cds-panel-library.component.scss'] +}) +export class CdsPanelLibraryComponent implements OnInit { + + @Output() hideActionPlaceholderOfActionPanel = new EventEmitter(); + + @ViewChild('tooltipEl') tooltipEl: ElementRef; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + BRAND_BASE_INFO = BRAND_BASE_INFO; + + categories: CategoryEntry[] = ACTION_CATEGORY as CategoryEntry[]; + actionsByCategory: Record = {}; + filteredActionsByCategory: Record = {}; + expandedCategories = new Set(); + searchText = ''; + isDragging = false; + + hoveredElement: any = null; + tooltipPos = { x: 0, y: 0 }; + isTooltipOpen = false; + + constructor( + private readonly projectPlanUtils: ProjectPlanUtils, + private readonly dashboardService: DashboardService, + private readonly controllerService: ControllerService, + private readonly translate: TranslateService, + ) {} + + ngOnInit(): void { + this.buildActionsByCategory(); + if (this.categories.length > 0) { + this.expandedCategories.add(this.categories[0].type); + } + this.applyFilter(); + } + + private buildActionsByCategory(): void { + const subtype = (this.dashboardService.selectedChatbot?.subtype ?? TYPE_CHATBOT.CHATBOT) as TYPE_CHATBOT; + this.projectPlanUtils.checkIfActionIsInChatbotType(subtype); + + this.categories.forEach(cat => { + const items = Object.values(ACTIONS_LIST) + .filter(el => el.category === TYPE_ACTION_CATEGORY[cat.type] && el.status !== 'inactive') + .map(el => ({ + type: TYPE_OF_MENU.ACTION, + value: el, + canLoad: el.plan ? this.projectPlanUtils.checkIfCanLoad(el.type, el.plan) : true, + })); + if (items.length > 0) { + this.actionsByCategory[cat.type] = items; + } + }); + this.logger.log('[CDS-PANEL-LIBRARY] actionsByCategory', this.actionsByCategory); + } + + onSearch(text: string): void { + this.searchText = text; + this.applyFilter(); + } + + applyFilter(): void { + const q = this.searchText.toLowerCase().trim(); + if (!q) { + this.filteredActionsByCategory = { ...this.actionsByCategory }; + return; + } + this.filteredActionsByCategory = {}; + Object.entries(this.actionsByCategory).forEach(([cat, items]) => { + const filtered = items.filter(i => { + const translated = this.translate.instant(i.value.name as string).toLowerCase(); + return translated.includes(q); + }); + if (filtered.length > 0) { + this.filteredActionsByCategory[cat] = filtered; + this.expandedCategories.add(cat); + } + }); + } + + toggleCategory(type: string): void { + if (this.expandedCategories.has(type)) { + this.expandedCategories.delete(type); + } else { + this.expandedCategories.add(type); + } + } + + isExpanded(type: string): boolean { + return this.expandedCategories.has(type); + } + + visibleCategories(): CategoryEntry[] { + return this.categories.filter(c => !!this.filteredActionsByCategory[c.type]); + } + + itemCount(type: string): number { + return this.filteredActionsByCategory[type]?.length ?? 0; + } + + onDragStarted(event: CdkDragStart, index: number): void { + this.isDragging = true; + this.controllerService.closeActionDetailPanel(); + + const actionDragPlaceholder = document.querySelector('.lib-drag-placeholder') as HTMLElement; + const addActionPlaceholderEl = document.querySelector('.add--action-placeholder') as HTMLElement; + + if (actionDragPlaceholder) { + const observer = new ResizeObserver(entries => { + entries.forEach(entry => { + const w = entry.contentRect.width; + const hide = w !== 258; + this.hideActionPlaceholderOfActionPanel.emit(hide); + if (actionDragPlaceholder) { actionDragPlaceholder.style.opacity = hide ? '0' : '1'; } + if (addActionPlaceholderEl) { addActionPlaceholderEl.style.opacity = hide ? '1' : '0'; } + }); + }); + observer.observe(actionDragPlaceholder); + } + } + + onDragEnd(event: CdkDragEnd): void { + this.isDragging = false; + this.hideActionPlaceholderOfActionPanel.emit(false); + } + + openInfo(e: HTMLElement, element: any): void { + this.logger.log('[CDS-PANEL-LIBRARY] openInfo!', element); + + if (!BRAND_BASE_INFO['DOCS']) { return; } + + if (!element.doc || element.doc === '') { + this.closeInfo(); + return; + } + + setTimeout(() => { + this.hoveredElement = element; + const rect = e.getBoundingClientRect(); + this.isTooltipOpen = true; + this.tooltipPos = { x: rect.right + 10, y: rect.top }; + }, 0); + } + + closeInfo(): void { + if (!BRAND_BASE_INFO['DOCS']) { return; } + setTimeout(() => { this.isTooltipOpen = false; }, 0); + this.hoveredElement = null; + } + + onVideoUrlClick(): void { + const url = this.translate.instant(this.hoveredElement.doc + '.VIDEO_URL'); + window.open(url, '_blank'); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-dashboard.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-dashboard.component.scss index 466f89d3b..96eb51cb6 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-dashboard.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-dashboard.component.scss @@ -4,12 +4,10 @@ cds-header { height: var(--header-height); font-family: var(--font-family-poppins); - line-height: var(--header-height); - font-size: 21px; - color: var(--blu); - background: white; - border-bottom: 1px solid var(--gray-light-02); - display: flex; + font-size: 14px; + color: var(--ds-ink, #1a1a19); + background: var(--ds-bg, #fbfbfa); + border-bottom: 1px solid var(--ds-border, #ececea); } .chatboat-dashboard { @@ -56,8 +54,8 @@ cds-support { } cds-sidebar { - background-color: var(--blu-light-04); - border-right: 1px solid var(--gray-light-02); + background-color: var(--ds-bg); + border-right: 1px solid var(--ds-border); width: var(--sidebar-base-width); transition: 0.3s; display: flex; @@ -66,21 +64,9 @@ cds-sidebar { z-index: 100; } -// .cds-content { -// display: flex; -// width: calc(100% - var(--sidebar-base-width)); -// overflow: hidden; -// } - - - - .loader{ display: block; z-index: 99; - // margin-top: 40vh; - // margin-left: auto; - // margin-right: auto; width: 100px; height: 100px; border: 3px solid var(--base-brand-color); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.html index c5070226e..2d876a73b 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.html @@ -1,194 +1,147 @@ -
-
- - - more_vert +
+ + + + + +
+
{{ (BRAND_BASE_INFO['COMPANY_NAME'] + '').charAt(0) || 'T' }}
+
+ {{ BRAND_BASE_INFO['COMPANY_NAME'] }} / {{ BRAND_BASE_INFO['META_TITLE'] }}
- -
-
- - -
- - {{BRAND_BASE_INFO['COMPANY_NAME']}} - {{BRAND_BASE_INFO['META_TITLE']}} -
-
- {{ selectedChatbot?.name }} - ios_share -
-
- -
- - - - - - - - - - - - -
- -
- -
- -
-
- {{webhookUrl}} -
- {{ messageWebhookUrl }} -
-
-
- -
- - -
- - - - - - - +
+ + +
+ / + + {{ selectedChatbot?.name }} + + + Draft +
-
+ +
+ + +
+
+ +
+ + +
+ {{ webhookUrl }} +
+ {{ messageWebhookUrl }} +
+
+ + + + + + + + +
+ + + + + +
+ + + +
- - +
- - - - + + + - - - - + + + + - - - - - - - - \ No newline at end of file + + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.scss index dbdbbbc0b..fde61a424 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-header/cds-header.component.scss @@ -1,316 +1,333 @@ @import "./src/assets/sass/cds/styles.scss"; @import "./src/assets/sass/cds/tooltip-styles.scss"; -.header-left { - // border-right: 2px solid #394f5a; - max-width: 60px; - width: 100%; - // display: flex; - // justify-content: center; - // align-items: center; - transition: 0.3s; - // background-color: var(--blu); - border-right: 1px solid var(--gray-light-02); - padding: 10px; - - &.is_opened{ - max-width: 175px; - transition: 0.3s; - img{ - width: 100px; - } - } - - div { - display: flex; - justify-content: center; - align-items: center; - position: relative; - width: 100%; - height: 100%; - border-radius: 50%; - box-shadow: rgba(17, 49, 96, 0.16) 0px 8px 16px 0px, rgba(17, 49, 96, 0.06) 0px 0px 0px 1px; ; - .logo{ - opacity: 1; - width: 25px; - position: absolute; - transition: opacity 0.2s ease-in-out; - } - span.material-icons{ - opacity: 0; - position: absolute; - color: var(--blu) - } - - &:hover{ - .logo{ - opacity: 0; - } - span.material-icons{ - opacity: 1; - transition: opacity 0.5s ease-in-out; - cursor:pointer; - } - } - } + +// ── Layout ──────────────────────────────────────────────────────────────────── + +:host { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + padding: 0 16px; + gap: 16px; + width: 100%; + box-sizing: border-box; } -.header-right { - // display: flex; - display: grid; - grid-template-columns: 3fr 3fr 3fr; - align-items: center; - justify-content: space-between; - width: 100%; - padding: 0px 10px; - box-sizing: border-box; - z-index: 11; - .right-opts{ - display: flex; - align-items: center; - justify-content: flex-end; - gap: 10px; - height: 100%; - } - - .header-go-back { - cursor: pointer; - position: relative; - - - .cds-text{ - font-weight: 700; - color: var(--base-brand-color); - - &.title{ - font-weight: 200; - } - } - } - .toggle-setting-sidebar-icon-wpr { - position: absolute; - z-index: 1050; - width: 22px; - height: 22px; - // background: #1e293b; - left: 49px; - transition: 0.3s; - - &.is_opened { - left: 164px; - transition: 0.3s; - } - } - - .toggle-setting-sidebar-icon { - background: #1e293b; - border: 1px solid #394f5a !important; - border-radius: 50%; - width: 20px; - height: 20px; - cursor: pointer; - font-size: 18px; - display: block; - } - - .toggle-setting-sidebar-icon:hover { - background: #f5f8fa; - color: #1e293b; - } - - .header-title { - display: flex; - align-items: center; - justify-content: center; - gap: 5px; - font-weight: 300; - - span.material-icons{ - font-size: 20px; - cursor: pointer; - &:hover{ - opacity: 0.8; - } - } - } +.topbar-left, +.topbar-right { + display: flex; + align-items: center; + gap: 10px; } -// #cds-publish-btn { -// border-bottom-right-radius: 0px; -// border-top-right-radius: 0px; -// margin-right: 0.5px; -// } +.topbar-right { justify-content: flex-end; } -#cds-publish-btn-wrp { - position: relative; - - .publish-badge { - position: absolute; - top: -5px; - right: -3px; - background-color: #dc362e; - border-radius: 50%; - width: 14px; - height: 14px; - display: block; - border: 2px solid white; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - z-index: 1; - } + +// ── Brand ───────────────────────────────────────────────────────────────────── + +.brand { + display: flex; + align-items: center; + gap: 10px; + padding: 4px 8px; + border-radius: var(--ds-radius-sm, 6px); +} + +.brand-mark { + width: 22px; + height: 22px; + border-radius: 6px; + background: var(--ds-ink, #1a1a19); + color: var(--ds-bg, #fbfbfa); + display: grid; + place-items: center; + font-weight: 600; + font-size: 12px; + letter-spacing: -0.02em; + flex-shrink: 0; + text-transform: uppercase; } -// .custom-mat-icon-btn { -// height: 33px; -// line-height: 33px; -// background: var(--blu-02); -// width: 33px; -// color: #fff; -// border-bottom-left-radius: 0px; -// border-top-left-radius: 0px; -// } - -// #cds-publish-btn-option { -// background: #006cff; -// color: #fff; -// box-shadow: none; -// font-weight: 500; -// font-family: Poppins, Roboto, Arial, sans-serif; -// text-transform: capitalize; -// font-size: 14px; -// padding: 6px 12px; -// border-radius: 10px; -// } - -// #cds-publish-btn-option:hover { -// opacity: .8!important; -// } - -#cds-test-it-wab-out-btn{ - background-color: #45c351; - color: #fff; - img { - width: 14px; - vertical-align: text-top; - filter: brightness(0) saturate(100%) invert(99%) sepia(0%) saturate(2%) hue-rotate(182deg) brightness(111%) contrast(101%) - } +.brand-name { + font-size: 13.5px; + font-weight: 500; + letter-spacing: -0.01em; + color: var(--ds-ink, #1a1a19); + white-space: nowrap; + .dim { + color: var(--ds-muted, #8a8884); + font-weight: 400; + } } -#cds-test-it-out-btn{ - background-color: transparent; - border: 2px solid var(--blu-02); - // outline-offset: -1px; - color: var(--blu-02); - border-radius: 50%; - display: flex; + +// ── Breadcrumb ──────────────────────────────────────────────────────────────── + +.crumb { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: var(--ds-muted, #8a8884); + + .sep { color: var(--ds-border-strong, #d8d6d2); } + + .here { + color: var(--ds-ink, #1a1a19); + font-weight: 500; + display: inline-flex; align-items: center; - justify-content: center; - padding: 6px 6px; - width: 33px; - height: 33px; - &.button-stop { - padding: 0px 0px 0 0; - } + gap: 6px; + padding: 4px 8px; + border-radius: var(--ds-radius-sm, 6px); + + &:hover { background: var(--ds-canvas, #f7f6f3); } + } + + .share-trigger { + display: inline-flex; + cursor: pointer; + opacity: 0.6; + &:hover { opacity: 1; } + } } -::ng-deep .mat-menu-panel.menuElement { - min-width: 100px; - max-width: 400px; - width: 185px; - color: var(--blu); - font-size: 15px; - line-height: 18px; - list-style: none; - overflow: hidden; - padding: 0; - // box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - border-radius: 8px; - background: rgb(255,255,255); - will-change: transform; - animation: .15s ease 0s 1 normal none running fadein, .15s ease 0s 1 normal none running movein, .1s ease 0s 1 normal none running scaleY; - margin: 0; - position: absolute; - top: -35px; - left: 35px; - border: 2px solid var(--gray-02); - box-shadow: none; - - &.shareMenu{ - width: unset; - top: 10px; - left: -100px; - } - - &.playMenu{ - width: 200px; - top: 10px; - left: -170px; - min-height: unset; - } +.draft-pill { + font-size: 11px; + padding: 2px 7px; + border-radius: 999px; + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink-2, #4a4a47); + border: 1px solid var(--ds-border, #ececea); + font-weight: 500; } -::ng-deep { - .mat-menu-content{ - padding: 0 !important; - } + +// ── Center tools ────────────────────────────────────────────────────────────── + +.center-tools { + display: flex; + align-items: center; + gap: 4px; + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + border-radius: 999px; + padding: 3px; + min-height: 38px; } -.box-url { - /* display: flex -; */ - /* position: absolute; */ - background: transparent; - justify-content: flex-end; - flex-direction: row; - /* float: right; */ +.tool-tab { + padding: 5px 14px; + border-radius: 999px; + font-size: 12.5px; + color: var(--ds-muted, #8a8884); + font-weight: 500; + transition: all 0.15s; + background: none; + border: none; + cursor: pointer; + + &:hover { color: var(--ds-ink, #1a1a19); } + + &.active { + background: var(--ds-ink, #1a1a19); + color: var(--ds-bg, #fbfbfa); + } +} + + +// ── Icon button ─────────────────────────────────────────────────────────────── + +.icon-btn { + width: 32px; + height: 32px; + display: grid; + place-items: center; + border-radius: var(--ds-radius-sm, 6px); + color: var(--ds-ink-2, #4a4a47); + background: none; + border: none; + cursor: pointer; + transition: all 0.15s; + flex-shrink: 0; + + &:hover { background: var(--ds-canvas, #f7f6f3); color: var(--ds-ink, #1a1a19); } + + &--active { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #1a1a19); + } + + .i { width: 16px; height: 16px; } + + ::ng-deep mat-icon { width: 16px; height: 16px; } +} + + +// ── Ghost button ────────────────────────────────────────────────────────────── + +.ghost-btn { + height: 32px; + padding: 0 12px; + border-radius: var(--ds-radius-sm, 6px); + color: var(--ds-ink-2, #4a4a47); + font-size: 13px; + display: inline-flex; + align-items: center; + gap: 6px; + font-weight: 500; + transition: all 0.15s; + background: none; + border: none; + cursor: pointer; + white-space: nowrap; + + &:hover { background: var(--ds-canvas, #f7f6f3); color: var(--ds-ink, #1a1a19); } +} + + +// ── Topbar divider ──────────────────────────────────────────────────────────── + +.topbar-divider { + width: 1px; + height: 20px; + background: var(--ds-border, #ececea); + margin: 0 4px; + flex-shrink: 0; +} + + +// ── Split publish button ────────────────────────────────────────────────────── + +.split-btn { + display: inline-flex; + align-items: stretch; + height: 32px; + border-radius: var(--ds-radius-sm, 6px); + overflow: hidden; + background: var(--ds-ink, #1a1a19); + color: var(--ds-bg, #fbfbfa); + position: relative; + + &:hover { opacity: 0.88; } + + &__main { + padding: 0 14px; + font-size: 13px; + font-weight: 500; + display: inline-flex; + align-items: center; + gap: 6px; + background: none; + border: none; + color: inherit; + cursor: pointer; + position: relative; + font-family: inherit; + } + + &__sep { + width: 1px; + background: rgba(255, 255, 255, 0.18); + flex-shrink: 0; + align-self: stretch; + } + + &__arrow { + padding: 0 8px; + display: inline-flex; align-items: center; - width: 100%; - /* margin-top: 60px; */ - font-size: 12px; - height: 30px; - z-index: 3; - - .button-url { - height: 62px; - position: relative; - margin: 28px 0 0 0; - max-width: 600px; - .span-url { - border: 1px solid var(--gray-02); - border-radius: 6px; - padding: 6px; - cursor: pointer; - background: #fff; - line-height: normal; - top: 0; - display: block; - overflow: hidden; - } - .webhook-message { - position: relative; - top: 4px; - float: right; - border: 1px solid var(--gray-02); - border-radius: 6px; - height: 30px; - background-color: #fff; - padding: 4px 6px; - font-weight: 500; - line-height: 22px; - width: -moz-fit-content; - } - } + background: none; + border: none; + color: inherit; + cursor: pointer; + } + + .publish-badge { + position: absolute; + top: -4px; + right: -4px; + background-color: #dc362e; + border-radius: 50%; + width: 8px; + height: 8px; + display: block; + border: 1.5px solid var(--ds-bg, #fbfbfa); + z-index: 1; + } } -.btn-play-webhook { - pointer-events: initial; - opacity: 1; - &.disabled { - pointer-events: none; - opacity: 0.5; - } + +// ── SVG icon helper ─────────────────────────────────────────────────────────── + +.i { + width: 16px; + height: 16px; + flex-shrink: 0; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + + &.i-sm { width: 14px; height: 14px; } } +// ── Webhook URL box ─────────────────────────────────────────────────────────── +.box-url { + max-width: 300px; + font-size: 12px; + position: relative; + cursor: pointer; + .span-url { + border: 1px solid var(--ds-border, #ececea); + border-radius: var(--ds-radius-sm, 6px); + padding: 4px 8px; + background: var(--ds-surface, #fff); + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + max-width: 260px; + } + + .webhook-message { + position: absolute; + top: calc(100% + 4px); + right: 0; + border: 1px solid var(--ds-border, #ececea); + border-radius: var(--ds-radius-sm, 6px); + background: var(--ds-surface, #fff); + padding: 4px 8px; + font-weight: 500; + white-space: nowrap; + } +} + + +// ── Mat-menu overrides ──────────────────────────────────────────────────────── + +::ng-deep .mat-menu-panel.menuElement { + min-width: 100px; + max-width: 400px; + width: 185px; + font-size: 14px; + overflow: hidden; + padding: 0; + border-radius: var(--ds-radius-sm, 6px); + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + box-shadow: var(--ds-shadow-pop, 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05)); + + &.shareMenu { width: unset; } + &.playMenu { width: 200px; min-height: unset; } +} + +::ng-deep .mat-menu-content { + padding: 0 !important; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.html index e2e5964e1..3c0209cfb 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.html @@ -1,284 +1,88 @@ - - - -
- -
- -
- - - - - -

- {{ 'Blocks' | translate }} -

-
- - - -
- - - - - -

- {{'Rules' | translate}} -

-
- - - -
- - lock - -

- {{'Globals' | translate}} -

-
- -
- - history - -

- {{'ReleaseHistory' | translate}} -

-
- -
- - - - - -

- {{'Settings' | translate}} -

-
-
- -
-
- - - - - -

- {{'HelpCenter' | translate}} -

-
-
- -
- - - + + + - - - - + + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.scss index f6ff01535..93dfd3f7d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-sidebar/cds-sidebar.component.scss @@ -2,256 +2,86 @@ @import "./src/assets/sass/cds/_variables.scss"; @import "./src/assets/sass/cds/tooltip-styles.scss"; -.settings-sidebar-wpr { - position: relative; - //display: flex; - display: none; - flex-direction: column; - flex: 1 0 auto; - font-size: 12px; - margin-top: 5px; - // padding-right: 10px; - width: 40px; - &.is_opened{ - width: 140px; - } - - // width: 140px; - // background-color: aliceblue; - // min-height: calc(100% - 123px); - // min-height: 100% ; - // background: rgb(245, 247, 249); - // padding-top: 13px; - - // padding-right: 5px; - // padding-left: 7px; - // top: -9px; - // left: -13px; - // height: calc(100% + 39px); -} - -.settings-sidebar-wpr-opened { - width: 215px; - min-width: 215px; - max-width: 215px; -} -.settings-sidebar-wpr-closed { - width: 40px; - min-width: 40px; - max-width: 40px; -} - -.settings-sidebar > li { - // height: 40px; - height: 35px; - border-radius: 4px; - // margin-right: 6px; - font-weight: 400; - cursor: pointer; - width: 100%; - // padding-right: 6px; - display: flex; - align-items: center; - // margin-bottom: 3px; -} - -.active-item { - background-color: rgb(220, 233, 255); - font-weight: 500 !important; -} - -.custom_paragraph { - color: rgb(100, 116, 145); - - line-height: 1.2; - margin-bottom: 0px; - padding-left: 8px; - display: inline-block; - vertical-align: middle; - // width: 170px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.settings-sidebar-icons { - color: rgb(100, 116, 145); - vertical-align: middle; - font-size: 18px; - margin-left: 6px; -} - -.settings-sidebar > li:hover { - background-color: rgba(100, 116, 145, 0.08); - color: rgb(8, 15, 26); -} - - -.settings-sidebar > li:hover .custom_paragraph { - // background-color: rgba(100, 116, 145, 0.08); - color: rgb(8, 15, 26); -} - -.settings-sidebar > li:hover .settings-sidebar-icons { - color: rgb(8, 15, 26); -} - -li.active a p.custom_paragraph { - color: $brand-sidebar-active-item-text-color !important; -} - -li.active a i.settings-sidebar-icons { - color: $brand-sidebar-active-item-text-color !important; -} - -li > a { - /* margin: 5px 15px !important; */ - - margin-top: 5px !important; - margin-right: 5px !important; - margin-bottom: 5px !important; - margin-left: 0px !important; - // width: 60px; - border-radius: 0px; -} - -.bot-lang-badge { - // font-weight: 400; - background-color: #3ea9f5; - /* border-color: #e3e7fa; */ - padding: 1px 6px; - border-radius: 4px; - font-size: 10px; - color: #fff; - position: relative; - // top: -1px; - text-transform: uppercase; -} - - - -.toggle-setting-sidebar-icon { - background: #fff; - border: 1px solid #e5effe !important; - border-radius: 50%; - width: 20px; - height: 20px; - cursor: pointer; - font-size: 18px; -} - -.toggle-setting-sidebar-icon:hover { - background: #f5f8fa; -} - -::ng-deep .custom-mat-tooltip-in-settings-sidebar { - background-color: #fff !important; - color: #555555 !important; - font-size: 12px !important; - border-radius: 2px !important; - font-family: var(--font-family-poppins) !important; - padding-top:8px!important; - padding-bottom:8px!important; - border: 1px solid #e5effe!important; -} - -.sidebar-bot-profile-img { - width: 25px; - height: 25px; - border-radius: 50%; - object-fit: cover; - border: 1px solid #eee; - margin-left: 3px; -} - -/// - -.content { - width: 100%; - display: flex; - justify-content: space-between; - //display: none; - flex-direction: column; - align-items: center; - // padding-left: 5px; - // padding-right: 5px; - - &.is_opened { - - // display: block; - // padding-left: 5px; - // padding-right: 5px; - width: 175px;; - - .section { - width: 100%; - justify-content: flex-start; - } +// ── Rail — specchio fedele del design reference ─────────────────────────────── + +.rail { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 0; + gap: 2px; + background: var(--ds-bg, #fbfbfa); +} + +.rail-spacer { + flex: 1; +} + +.rail-btn { + width: 36px; + height: 36px; + border-radius: var(--ds-radius-sm, 6px); + display: grid; + place-items: center; + color: var(--ds-muted, #8a8884); + transition: all 0.15s; + position: relative; + cursor: pointer; + + // icone SVG stroke-based + .i { + width: 16px; + height: 16px; + flex-shrink: 0; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + + &:hover { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #1a1a19); + } + + &.active { + color: var(--ds-ink, #1a1a19); + background: var(--ds-canvas, #f7f6f3); + + &::before { + content: ""; + position: absolute; + left: -8px; + top: 6px; + bottom: 6px; + width: 2px; + background: var(--ds-ink, #1a1a19); + border-radius: 2px; } + } } -.section { - display: flex; - justify-content: center; - align-items: center; - // margin-bottom: 10px; - // padding: 0px 12px; - // border-radius: 4px; - transition: all .3s; - width: 100%; - cursor: pointer; - height: var(--sidebar-base-width); - - .item-label { - margin-bottom: 0px; - color: white; - margin-left: 6px; - } - - .item-icon { - color: var(--blu-03); - fill: var(--blu-03); - display: flex; - } - -} -.section:hover, -.is_active { - background-color: var(--blu); - .item-icon { - color: white; - fill: white; - } -} +// ── Mat-menu Support ────────────────────────────────────────────────────────── ::ng-deep .mat-menu-panel.menuElementSupport { - min-width: 100px; - max-width: 400px; - min-height: unset; - width: 220px; - color: var(--blu); - font-size: 15px; - line-height: 18px; - list-style: none; - overflow: hidden; - padding: 0; - // box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - border-radius: 8px; - background: rgb(255,255,255); - will-change: transform; - animation: .15s ease 0s 1 normal none running fadein, .15s ease 0s 1 normal none running movein, .1s ease 0s 1 normal none running scaleY; - margin: 0; - position: absolute; - bottom: 10px; - left: 45px; - border: 2px solid var(--gray-02); - box-shadow: none; -} - -::ng-deep { - .mat-menu-content{ - padding: 0 !important; - } + min-width: 100px; + max-width: 400px; + min-height: unset; + width: 220px; + font-size: 14px; + overflow: hidden; + padding: 0; + border-radius: var(--ds-radius-sm, 6px); + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + box-shadow: var(--ds-shadow-pop, 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05), 0 0 0 1px rgba(20,20,18,.06)); +} + +::ng-deep .mat-menu-content { + padding: 0 !important; } diff --git a/src/assets/sass/cds/_variables.scss b/src/assets/sass/cds/_variables.scss index 62711eabc..c51d3602a 100644 --- a/src/assets/sass/cds/_variables.scss +++ b/src/assets/sass/cds/_variables.scss @@ -107,6 +107,38 @@ --header-height: 60px; --sidebar-base-width: 60px; + /** DESIGN STUDIO v2 — token palette (Design Studio.html) **/ + --ds-bg: #fbfbfa; + --ds-canvas: #f7f6f3; + --ds-surface: #ffffff; + --ds-border: #ececea; + --ds-border-strong: #d8d6d2; + --ds-ink: #1a1a19; + --ds-ink-2: #4a4a47; + --ds-muted: #8a8884; + --ds-muted-2: #b3b1ac; + + --ds-accent: oklch(0.66 0.15 50); + --ds-accent-soft: oklch(0.95 0.04 60); + --ds-accent-ink: oklch(0.45 0.15 45); + + --ds-green: oklch(0.68 0.13 155); + --ds-green-soft: oklch(0.95 0.04 155); + + --ds-blue: oklch(0.62 0.13 245); + --ds-blue-soft: oklch(0.95 0.03 245); + + --ds-red: oklch(0.62 0.16 28); + --ds-red-soft: oklch(0.95 0.03 28); + + --ds-purple: oklch(0.6 0.14 290); + + --ds-shadow-card: 0 1px 2px rgba(20,20,18,.04), 0 0 0 1px rgba(20,20,18,.05); + --ds-shadow-pop: 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05), 0 0 0 1px rgba(20,20,18,.06); + + --ds-radius: 10px; + --ds-radius-sm: 6px; + /** CONNECTOR **/ --success-connector: rgb(44, 191, 35); --failure-connector: rgb(191, 35, 35); From bc7da4b4c9071fedf2fe698e0ae5bf77c5e6dca6 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 30 Apr 2026 18:13:50 +0200 Subject: [PATCH 05/30] updated intent action --- .../cds-canvas/cds-canvas.component.html | 23 ++----- .../cds-canvas/cds-canvas.component.scss | 60 ++++--------------- .../cds-intent/cds-intent.component.html | 6 +- .../cds-intent/cds-intent.component.scss | 48 +++++++-------- .../cds-intent/cds-intent.component.ts | 24 +++++++- .../cds-panel-intent-list.component.html | 4 +- .../cds-panel-intent-list.component.scss | 7 +-- .../cds-panel-intent-list.component.ts | 2 +- 8 files changed, 64 insertions(+), 110 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html index 867784222..754082880 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html @@ -1,26 +1,11 @@ - - -
- - -
- - - -
@@ -28,7 +13,6 @@
-
-
{{item?.value?.name | translate}}
-
-
-
-
+
+
-
\ No newline at end of file + +
{{ item.value.name | translate }}
+ +
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.scss index 0b8a4901d..30c75b309 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.scss @@ -1,131 +1,130 @@ - -.menu-context-add-search { - border-bottom: 1px solid #e8eef3; - // margin-bottom: 15px; -} -.actions-drawer{ - overflow-y: scroll; - max-height: calc(100vh - 140px); +@import "./src/assets/sass/cds/_variables.scss"; + +:host { + display: flex; + flex-direction: column; + width: 230px; + max-height: 420px; + background: var(--ds-bg, #fbfbfa); + border-radius: var(--ds-radius, 10px); + border: 1px solid var(--ds-border, #ececea); + box-shadow: var(--ds-shadow-pop, 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05), 0 0 0 1px rgba(20,20,18,.06)); + font-family: var(--font-family-poppins); + user-select: none; } -.action-menu-search span { - color: rgba(155, 164, 197, .8); - font-size: 24px; - position: absolute; - right: 10px; - top: 10px; - -webkit-transition: color .3s; - transition: color .3s; +// ── Head: search ────────────────────────────────────────────────────────────── + +.lib-head { + padding: 10px; + border-bottom: 1px solid var(--ds-border, #ececea); + flex-shrink: 0; } -.action-menu-search input { - background: #fff; - border-radius: 4px; - color: #22272d; - height: 40px; - padding: 9px 35px 9px 17px; - -webkit-transition: border .3s; - transition: border .3s; - width: 100%; - border: 0; - font-size: 16px; - line-height: 20px; +.search { + display: flex; + align-items: center; + gap: 8px; + height: 32px; + border: 1px solid var(--ds-border, #ececea); + border-radius: 999px; + background: var(--ds-surface, #fff); + padding: 0 12px; + color: var(--ds-muted, #8a8884); + transition: box-shadow 0.12s; + + &:focus-within { + box-shadow: 0 0 0 3px oklch(0.85 0.05 240 / 0.55); + } + + .i { + width: 13px; + height: 13px; + flex-shrink: 0; + stroke: currentColor; + fill: none; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + + input { + border: none; + outline: none; + background: none; + flex: 1; + font-size: 13px; + color: var(--ds-ink, #1a1a19); + font-family: inherit; + + &::placeholder { color: var(--ds-muted, #8a8884); } + } } +// ── Body ────────────────────────────────────────────────────────────────────── -#panel-actions-div{ - padding: 0px; - // box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - .menu-dragging { - overflow: hidden; - padding: 6px; - } - .section-title { - padding-top: 3px; - font-size: 11px; - font-weight: 600; - font-family: var(--font-family-poppins); - color: #394f5a; - height: 30px; - padding: 6px; - background-color: #e7eeefcc; - margin: 2px; - border-radius: 6px; - } +.lib-body { + flex: 1; + overflow-y: auto; + padding: 4px 6px 8px; + scrollbar-width: thin; + scrollbar-color: var(--ds-border, #ececea) transparent; + overscroll-behavior: contain; } -.actions--btns-wpr { - // width: 136px; // dp - width: 100%; // nk - height: 33px; - border-radius: 6px; - display: flex; - align-items: center; - user-select: none; - &:hover{ - // cursor: -webkit-grab; cursor: grab; - box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - } -} -::ng-deep .cdk-drag-preview { - .actions--btns-wpr { - background-color: #ffffff; - // transform: rotate(-5deg)!important; - box-shadow: #1321440a 0 12px 24px, #1321440a 0 8px 12px, #13214405 0 4px 4px, #13214403 0 2px 2px, #13214403 0 1px 1px, #11316008 0 0, #1131600f 0 0 0 1px; - } -} +// ── Items ───────────────────────────────────────────────────────────────────── -.action-btn-icon { - display: inline-flex; - color: #394f5a; - padding: 0; - vertical-align: middle; - margin: 0 6px; - .btn-tdblu-no-boxshadow { - margin: 0; - padding: 0!important; - background: transparent !important; - font-size: 12px; - width: 25px; - height: 25px; - display: flex; - justify-content: center; - align-items: center; - box-shadow: none; - } -} - -.action-btn img { - width: 18px; - filter: brightness(0) saturate(100%) invert(28%) sepia(8%) saturate(1693%) hue-rotate(156deg) brightness(93%) contrast(87%); -} +.lib-item { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 8px; + border-radius: var(--ds-radius-sm, 6px); + cursor: pointer; + transition: background 0.12s; -.action--btn-text{ - display: inline-flex; - color: #394f5a; - padding: 0; - vertical-align: middle; - font-size: 14px; - font-weight: 400; + &:hover { background: var(--ds-canvas, #f7f6f3); } } +.lib-icon { + width: 22px; + height: 22px; + border-radius: 5px; + display: grid; + place-items: center; + background: var(--ds-surface, #fff); + border: 1px solid var(--ds-border, #ececea); + color: var(--ds-ink-2, #4a4a47); + flex-shrink: 0; + overflow: hidden; + + mat-icon, .lib-svg-icon { + width: 13px !important; + height: 13px !important; + min-width: 13px; + min-height: 13px; + font-size: 13px; + line-height: 13px; + display: flex; + align-items: center; + justify-content: center; -.example-custom-placeholder { - height: 30px; - width: 100%; - border-radius: 6px; - display: block; - background: #e7eeefcc; + ::ng-deep svg { + width: 13px; + height: 13px; + fill: currentColor; + } + } } - -.add-action-menu-content { - background: hsla(0,0%,100%,.95); - border-radius: 5px; - -webkit-box-shadow: 0 6px 24px 0 rgba(0,0,0,.3); - box-shadow: 0 6px 24px 0 rgba(0,0,0,.3); - // height: calc(100vh - 100px); +.lib-name { + font-size: 13px; + color: var(--ds-ink, #1a1a19); + flex: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.ts index 332c9161b..4d1b8f5f8 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-add-action-menu/cds-add-action-menu.component.ts @@ -74,13 +74,7 @@ export class CdsAddActionMenuComponent implements OnInit, OnChanges { if(this.menuItemsList){ this.filterMenuItemsList = this.menuItemsList.sort((el1, el2)=> this.translate.instant(el1.value.name).localeCompare(this.translate.instant(el2.value.name))); } - //set autofocus on search input element (only when component is active) - if(this.isActive){ - setTimeout(()=>{ - // this will make the execution after the above boolean has changed - this.searchElement.nativeElement.focus(); - },500); - } + setTimeout(() => { this.searchElement?.nativeElement?.focus(); }, 50); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html index 754082880..27a15c390 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.html @@ -4,39 +4,42 @@ class="panel-intent-list" [IS_OPEN]="IS_OPEN_INTENTS_LIST" (selectIntent)=onSelectIntent($event) - (deleteIntent)="onDeleteIntent($event)"> + (deleteIntent)="onDeleteIntent($event)" + (close)="IS_OPEN_INTENTS_LIST = false"> -
- -
- - -
- -
+
+ + +
+ [isBlocksOpen]="IS_OPEN_INTENTS_LIST" + (hideActionPlaceholderOfActionPanel)="onHideActionPlaceholderOfActionPanel($event)" + (closePanel)="IS_OPEN_LIBRARY = false" + (openBlocks)="onToogleSidebarIntentsList()">
{{ 'Blocks' | translate }}
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss index 67d7b66c1..60a669580 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.scss @@ -19,9 +19,12 @@ // ── Title header ────────────────────────────────────────────────────────────── .lib-head-title { - padding: 14px 16px 12px; + padding: 10px 10px 10px 16px; border-bottom: 1px solid var(--ds-border, #ececea); flex-shrink: 0; + display: flex; + align-items: center; + justify-content: space-between; } .lib-title-text { @@ -31,6 +34,35 @@ letter-spacing: -0.01em; } +.lib-close-btn { + width: 26px; + height: 26px; + display: grid; + place-items: center; + border: none; + background: none; + border-radius: var(--ds-radius-sm, 6px); + cursor: pointer; + color: var(--ds-muted, #8a8884); + flex-shrink: 0; + transition: background 0.12s, color 0.12s; + + svg { + width: 14px; + height: 14px; + stroke: currentColor; + fill: none; + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + } + + &:hover { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #1a1a19); + } +} + // ── Pinned / Core blocks ────────────────────────────────────────────────────── diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts index 595651192..cc6da458d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-intent-list/cds-panel-intent-list.component.ts @@ -28,6 +28,7 @@ export class CdsPanelIntentListComponent implements OnInit, OnChanges { @Input() intent_id: string; @Output() selectIntent = new EventEmitter(); @Output() deleteIntent = new EventEmitter(); + @Output() close = new EventEmitter(); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html index a30ea934b..3ff677a26 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-library/cds-panel-library.component.html @@ -1,3 +1,28 @@ + +
+
{{ 'Actions' | translate }}
+ +
+ + + +
-
+
Date: Mon, 4 May 2026 14:54:46 +0200 Subject: [PATCH 11/30] cambiato lo stile di cds-options --- .../cds-options/cds-options.component.scss | 354 +++++++++--------- 1 file changed, 183 insertions(+), 171 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-options/cds-options.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-options/cds-options.component.scss index 490c8670c..eda989ea6 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-options/cds-options.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-options/cds-options.component.scss @@ -1,75 +1,106 @@ -.container{ - display: flex; - flex-direction: row; - gap: 8px; - padding: 0px; +// ============================================================ +// CDS-OPTIONS — toolbar flottante canvas +// ============================================================ + +.container { + display: flex; + flex-direction: row; + gap: 0; + background: #ffffff; + border: 1px solid var(--ds-border, #ececea); + border-radius: 6px; + box-shadow: 0 1px 2px rgba(20,20,18,.04), 0 0 0 1px rgba(20,20,18,.05); + overflow: hidden; + padding: 0; } .cds-elements { - padding: 4px; - border-radius: 8px; - background-color: white; - box-shadow: rgba(19, 33, 68, 0.01) 0px 1px 3px 1px, rgba(19, 33, 68, 0.12) 0px 5px 8px -8px, rgba(19, 33, 68, 0.12) 0px 2px 4px -3px, rgba(19, 33, 68, 0.03) 0px 0px 0px 1px; - overflow: hidden; - transition: height 0.15s ease 0s; - border: 2px solid var(--gray-02); - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; + padding: 0; + border: none; + background: transparent; + box-shadow: none; + border-radius: 0; + overflow: hidden; + + & + .cds-elements { + border-left: 1px solid var(--ds-border, #ececea); + } } .cds-button-element { - animation: 0.1s ease-in-out 0s 1 normal both running; - &.is_disabled { - opacity: 0.2; - } - &.is_active { - .cds-box-button { - background-color: var(--gray-02); - } + &.is_disabled { + opacity: 0.2; + pointer-events: none; + } + &.is_active { + .cds-box-button { + background: var(--ds-canvas, #f7f6f3); } + } } .cds-box-button { - transition: background-color 0.15s ease 0s; - width: 35px; - height: 35px; - flex-direction: column; - text-align: center; - cursor: pointer; - border-radius: 6px; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; + width: 32px; + height: 32px; + display: grid; + place-items: center; + cursor: pointer; + border-radius: 0; + color: var(--ds-ink-2, #4a4a47); + transition: background 0.12s, color 0.12s; + + &:hover, + &:focus { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #14140e); + outline: none; + } } -.cds-box-button:hover, -.cds-box-button:focus { - background-color: var(--gray-02); +.box-img { + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + user-select: none; } -.box-img { - transition: opacity 0.15s ease 0s, background-color 0.15s ease 0s, color 0.15s ease 0s, transform 0.15s ease 0s; - box-sizing: content-box; - width: 24px; - height: 24px; - background: transparent; - user-select: none; +mat-icon { + width: 16px; + height: 16px; + font-size: 16px; + display: flex; + align-items: center; + color: inherit; + + ::ng-deep svg { + fill: var(--ds-ink-2, #4a4a47); + } } -// --------------------------------------------------------------------------- -// NOTE TYPE MENU (DIV custom) - mantiene gli stessi stili già impostati -// --------------------------------------------------------------------------- +.material-icons-outlined { + font-size: 16px; + color: var(--ds-ink-2, #4a4a47); +} + + +// ============================================================ +// NOTE TYPE MENU +// ============================================================ + .note-type-menu-backdrop { display: none; position: fixed; inset: 0; z-index: 1000; background: transparent; -} -.note-type-menu-backdrop.is-open { - display: block; + &.is-open { + display: block; + } } .note-type-menu.menuElement.noteTypeMenu { @@ -79,155 +110,136 @@ min-width: 185px; max-width: 400px; width: 185px; - border-radius: 8px; - background: rgb(255, 255, 255); - border: 3px solid var(--gray-02); - box-shadow: none; + border-radius: 6px; + background: #ffffff; + border: 1px solid var(--ds-border, #ececea); + box-shadow: 0 4px 16px rgba(20,20,18,.08), 0 0 0 1px rgba(20,20,18,.05); overflow: visible; - padding: 6px !important; - // offsets left/top sono gestiti da TS tramite noteTypeMenuPos + tuoi valori (-5/-10) -} + padding: 4px !important; -.note-type-menu.menuElement.noteTypeMenu.is-open { - display: block; -} + &.is-open { + display: block; + } -.note-type-menu.menuElement.noteTypeMenu .note-type-menu-item { - color: var(--blu); - padding: 0px 8px; - vertical-align: middle; - font-size: 10px; - font-weight: 400; - font-family: var(--font-family-poppins); - display: flex; - align-items: center; - height: 30px; - line-height: 30px; - gap: 10px; - border-radius: 6px; - .label { - background-color: transparent; + .note-type-menu-item { + color: var(--ds-ink-2, #4a4a47); + padding: 0 8px; + font-size: 12px; + font-weight: 400; + font-family: "Geist", system-ui, -apple-system, sans-serif; + display: flex; + align-items: center; + height: 30px; + line-height: 30px; + gap: 8px; + border-radius: 4px; + cursor: pointer; + transition: background 0.1s; + + .label { + background-color: transparent; + } + + &:hover { + background: var(--ds-canvas, #f7f6f3); + box-shadow: none; + } } -} -// Durante il drag: l'item nel menu resta al suo posto ma lo rendiamo meno invasivo -.note-type-menu.menuElement.noteTypeMenu .note-type-menu-item.cdk-drag-dragging { - opacity: 1; - background-color: #fff!important; -} + .note-type-menu-item.cdk-drag-dragging { + opacity: 1; + background-color: #fff !important; + } -// Ghost sotto al cursore (il preview viene appeso al body => serve ::ng-deep) -::ng-deep .note-drag-ghost { - background-color: #112233; - opacity: 1; -} + .material-icons-outlined { + font-size: 16px; + width: 16px; + height: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--ds-ink-2, #4a4a47); + } + .note-type-menu-item.cdk-drag { + cursor: grab; + } -.note-type-menu.menuElement.noteTypeMenu .note-type-menu-item:hover { - background-color: transparent; - box-shadow: rgba(19, 33, 68, 0.0392156863) 0 12px 24px, rgba(19, 33, 68, 0.0392156863) 0 8px 12px, rgba(19, 33, 68, 0.0196078431) 0 4px 4px, rgba(19, 33, 68, 0.0117647059) 0 2px 2px, rgba(19, 33, 68, 0.0117647059) 0 1px 1px, rgba(17, 49, 96, 0.031372549) 0 0, rgba(17, 49, 96, 0.0588235294) 0 0 0 1px; -} -// Cursori drag&drop (solo palette note nel mat-menu) -.note-type-menu.menuElement.noteTypeMenu .note-type-menu-item.cdk-drag { - cursor: grab; + .note-type-menu-item.cdk-drag.cdk-drag-dragging { + cursor: grabbing; + } } -.note-type-menu.menuElement.noteTypeMenu .note-type-menu-item.cdk-drag.cdk-drag-dragging { - cursor: grabbing; +::ng-deep .note-drag-ghost { + opacity: 0.5; } -// Durante il drag: forziamo il cursore globale a grabbing per evitare "cursor flicker" ::ng-deep body.cds-note-palette-dragging, ::ng-deep body.cds-note-palette-dragging * { - cursor: grabbing !important; + cursor: grabbing !important; } -.note-type-menu.menuElement.noteTypeMenu .material-icons-outlined { - font-size: 18px; - width: 18px; - height: 18px; - display: inline-flex; - align-items: center; - justify-content: center; - color: var(--blu); -} + +// ============================================================ +// POPOVERS +// ============================================================ ::ng-deep .mouse-trackpad-tips-panel { - // position: relative; - box-shadow: 0 0 20px 4px #9aa1b126, 0 4px 80px -8px #24282f40, 0 4px 4px -2px #5b5e6926; - background: rgb(255,255,255); - border-radius: 4px; - margin: 10px; - max-height: 80%; - min-height: 370px; + box-shadow: 0 4px 24px rgba(20,20,18,.12), 0 0 0 1px rgba(20,20,18,.06); + background: #ffffff; + border-radius: 8px; + margin: 10px; + max-height: 80%; + min-height: 370px; } ::ng-deep .alpha-color-connectors-panel { - // position: relative; - box-shadow: 0 0 20px 4px #9aa1b126, 0 4px 80px -8px #24282f40, 0 4px 4px -2px #5b5e6926; - background: rgb(255,255,255); - border-radius: 4px; + box-shadow: 0 4px 24px rgba(20,20,18,.12), 0 0 0 1px rgba(20,20,18,.06); + background: #ffffff; + border-radius: 8px; margin: 10px; max-height: 80%; min-height: 100px; } +// ============================================================ +// VERTICAL SLIDER (invariato) +// ============================================================ + +.vertical-slider { + appearance: none; + width: 90px; + height: 4px; + transform: rotate(-90deg); + transform-origin: center; + margin: 0; + background: #506493; + border-radius: 2px; +} + +.vertical-slider::-webkit-slider-thumb { + appearance: none; + width: 20px; + height: 20px; + margin-top: -8px; + background-color: #ffffff; + border-radius: 50%; + cursor: pointer; + border: 1px solid #d3d3d3; + box-shadow: -2px 0px 4px rgba(0,0,0,.2); +} -// .vertical-slider-container { -// display: flex; -// justify-content: center; -// align-items: center; -// height: 120px; -// width: 47px; -// border-radius: 8px; -// position: absolute; -// bottom: 55px; -// } - - .vertical-slider { - appearance: none; - width: 90px; - height: 4px; - transform: rotate(-90deg); - transform-origin: center; - margin: 0; - background: #506493; - border-radius: 2px; - } - - .vertical-slider::-webkit-slider-thumb { - appearance: none; - width: 20px; - height: 20px; - margin-top: -8px; - background-color: #ffffff; - border-radius: 50%; - cursor: pointer; - border: 1px solid #d3d3d3; - box-shadow: -2px 0px 4px rgba(0, 0, 0, 0.2); - } - .vertical-slider::-webkit-slider-runnable-track { - width: 100%; - height: 4px; - background: #506493; - border-radius: 4px; - } - - .vertical-slider::-moz-range-track { - width: 100%; - height: 4px; - background: #506493; - border-radius: 4px; - } - + width: 100%; + height: 4px; + background: #506493; + border-radius: 4px; +} - mat-icon { - height: 100%; - display: flex; - align-items: center; - ::ng-deep svg { - fill: var(--blu); - } - } +.vertical-slider::-moz-range-track { + width: 100%; + height: 4px; + background: #506493; + border-radius: 4px; +} From 26d3b70e689f74d3fc7480a4b3a37d6aeddc2a9e Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Mon, 4 May 2026 15:10:36 +0200 Subject: [PATCH 12/30] aggiunte la configurazione action nel nuovo pannello di dettaglio del blocco --- .../cds-panel-detail.component.html | 467 +++++++++++++++++- .../cds-panel-detail.component.scss | 29 +- .../cds-panel-detail.component.ts | 111 ++++- 3 files changed, 598 insertions(+), 9 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.html index fe7c05fd8..ecd95da0d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.html @@ -117,7 +117,470 @@
- -
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ lock +

+ +
+ +
+ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.scss index 821c081bb..f98d9e844 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.scss @@ -388,9 +388,36 @@ padding: 4px 0; } -// ===== BODY (vuoto) ===== +// ===== BODY ===== .insp-body { flex: 1; overflow-y: auto; + overflow-x: hidden; +} + +.panel-response { + display: block; +} + +.block-overlay { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 12px; + padding: 32px 24px; + text-align: center; + color: var(--ink-2); + font-size: 13px; + + .lock-icon { + font-size: 32px; + color: var(--muted); + } + + p { + margin: 0; + line-height: 1.5; + } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.ts index 3cd3b1c8c..5610cae9c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-panel-detail/cds-panel-detail.component.ts @@ -1,4 +1,5 @@ -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { Subscription } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { Intent } from 'src/app/models/intent-model'; import { AppConfigService } from 'src/app/services/app-config'; @@ -9,8 +10,11 @@ import { StageService } from 'src/app/chatbot-design-studio/services/stage.servi import { WebhookService } from 'src/app/chatbot-design-studio/services/webhook-service.service'; import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; -import { RESERVED_INTENT_NAMES, INTENT_ELEMENT, INTENT_COLORS, STAGE_SETTINGS } from 'src/app/chatbot-design-studio/utils'; -import { ACTIONS_LIST, TYPE_ACTION, TYPE_CHATBOT } from 'src/app/chatbot-design-studio/utils-actions'; +import { ProjectPlanUtils } from 'src/app/utils/project-utils'; +import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service'; +import { PLAN_NAME } from 'src/chat21-core/utils/constants'; +import { RESERVED_INTENT_NAMES, INTENT_ELEMENT, INTENT_COLORS, STAGE_SETTINGS, TYPE_INTENT_ELEMENT } from 'src/app/chatbot-design-studio/utils'; +import { ACTIONS_LIST, TYPE_ACTION, TYPE_ACTION_VXML, TYPE_CHATBOT } from 'src/app/chatbot-design-studio/utils-actions'; import { PanelIntentHeaderComponent } from '../cds-intent/panel-intent-header/panel-intent-header.component'; const swal = require('sweetalert'); @@ -20,7 +24,7 @@ const swal = require('sweetalert'); templateUrl: './cds-panel-detail.component.html', styleUrls: ['./cds-panel-detail.component.scss'] }) -export class CdsPanelDetailComponent implements OnInit, OnChanges { +export class CdsPanelDetailComponent implements OnInit, OnChanges, OnDestroy { @Input() intent: Intent; @Input() project_id: string; @Output() closePanel = new EventEmitter(); @@ -43,6 +47,15 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { webhookUrlDev = ''; messageText = ''; + // action detail + typeIntentElement = TYPE_INTENT_ELEMENT; + TYPE_ACTION = TYPE_ACTION; + TYPE_ACTION_VXML = TYPE_ACTION_VXML; + elementSelected: any; + elementIntentSelectedType: string; + canShowActionByPlan: { plan: PLAN_NAME; enabled: boolean } = { plan: PLAN_NAME.A, enabled: true }; + + private subscriptionIntent: Subscription; private readonly logger: LoggerService = LoggerInstance.getInstance(); constructor( @@ -52,12 +65,15 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { private readonly webhookService: WebhookService, private readonly appConfigService: AppConfigService, private readonly dashboardService: DashboardService, - private readonly translate: TranslateService + private readonly translate: TranslateService, + private readonly projectPlanUtils: ProjectPlanUtils, + private readonly tiledeskAuthService: TiledeskAuthService ) {} ngOnInit(): void { this.maximize = this.stageService.getMaximize(); this.initialize(); + this.initSubscriptions(); } ngOnChanges(changes: SimpleChanges): void { @@ -67,6 +83,10 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { } } + ngOnDestroy(): void { + this.subscriptionIntent?.unsubscribe(); + } + get intentColor(): string { return this.intent?.attributes?.color ?? INTENT_COLORS.COLOR1; } @@ -92,6 +112,8 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { this.webhookUrlDev = ''; this.selectedNextIntent = null; this.listOfIntents = []; + this.elementSelected = null; + this.elementIntentSelectedType = null; if (!this.intent) { return; } @@ -105,6 +127,13 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { if (!this.isStart && !this.isWebhook) { this.initializeConnectorSelect(); } + + // Initialize action detail + if (this.intent.actions?.length > 0) { + this.elementSelected = this.intent.actions[0]; + this.elementIntentSelectedType = TYPE_INTENT_ELEMENT.ACTION; + this.checkActionAvailability(); + } } private initializeWebhook(): void { @@ -128,6 +157,38 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { } } + private initSubscriptions(): void { + this.subscriptionIntent = this.intentService.behaviorIntent.subscribe((int: Intent) => { + const intent = this.intentService.listOfIntents.find(obj => obj.intent_id === int.intent_id); + if (!intent || !this.intent) { return; } + if (intent.intent_id === this.intent.intent_id) { + if (this.elementIntentSelectedType === TYPE_INTENT_ELEMENT.ACTION && this.elementSelected) { + const updated = intent.actions.find(a => a._tdActionId === this.elementSelected._tdActionId); + if (updated) { this.elementSelected = updated; } + } + } else { + this.closePanel.emit(); + } + }); + } + + private checkActionAvailability(): void { + if (!this.elementSelected?._tdActionType) { return; } + const action = Object.values(ACTIONS_LIST).find(el => el.type === this.elementSelected._tdActionType); + if (action?.plan) { + this.canShowActionByPlan = { + plan: action.plan, + enabled: this.projectPlanUtils.checkIfCanLoad(action.type, action.plan) + }; + } + if (action?.type === TYPE_ACTION.CODE) { + this.canShowActionByPlan = { + plan: action.plan, + enabled: this.projectPlanUtils.checkIfIsEnabledInProject(action.type) + }; + } + } + onToggleMaximize(): void { this.maximize = !this.maximize; this.stageService.saveSettings(this.dashboardService.id_faq_kb, STAGE_SETTINGS.Maximize, this.maximize); @@ -138,7 +199,11 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { this.onSaveIntent(); } - onSaveIntent(): void { + onSaveIntent(event?: any): void { + if (this.elementIntentSelectedType === TYPE_INTENT_ELEMENT.ACTION && this.elementSelected) { + const index = this.intent.actions.findIndex(a => a._tdActionId === this.elementSelected._tdActionId); + if (index >= 0) { this.intent.actions[index] = this.elementSelected; } + } this.savePanelIntentDetail.emit(this.intent); } @@ -171,6 +236,27 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { } } + onConnectorChange(type: 'create' | 'delete', idConnector: string, toIntentId: string): void { + this.connectorService.updateConnectorAttributes(idConnector, null); + switch (type) { + case 'create': { + let toId = toIntentId; + if (toIntentId.includes('#')) { + toId = toIntentId.split('#')[1]; + if (toIntentId.includes('{')) { + toId = toIntentId.split('#')[1].split('{')[0]; + } + } + this.connectorService.deleteConnectorWithIDStartingWith(idConnector, false, true); + this.connectorService.createNewConnector(idConnector, toId); + break; + } + case 'delete': + this.connectorService.deleteConnectorWithIDStartingWith(idConnector, false, true); + break; + } + } + getWebhook(): void { this.webhookService.getWebhook(this.chatbot_id).subscribe({ next: (resp: any) => { @@ -237,6 +323,19 @@ export class CdsPanelDetailComponent implements OnInit, OnChanges { } } + goToContactSales(): void { + const user = this.tiledeskAuthService.getCurrentUser(); + window.open(`mailto:sales@tiledesk.com?subject=Upgrade to Tiledesk ${this.canShowActionByPlan.plan}`); + try { + (window as any)['analytics'].track(`Contact us to upgrade plan to ${this.canShowActionByPlan.plan}`, { + email: user.email, + action: this.elementSelected + }, { context: { groupId: this.dashboardService.projectID } }); + } catch (err) { + this.logger.error('track contact us to upgrade plan error', err); + } + } + private showMessage(msg: string): void { this.messageText = msg; setTimeout(() => { this.messageText = ''; }, 5000); From 65ea429026f327d94dc12679e1f6de2b37812b2b Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Mon, 4 May 2026 17:35:09 +0200 Subject: [PATCH 13/30] bug fixing css --- .../filter/filter.component.scss | 2 +- .../cds-action-audio-record.component.scss | 2 +- .../cds-action-blind-transfer.component.scss | 2 +- .../cds-action-dtmf-form.component.scss | 2 +- .../cds-action-dtmf-menu.component.scss | 2 +- .../cds-action-play-prompt.component.scss | 2 +- .../cds-action-speech-form.component.scss | 2 +- .../cds-action-voice.component.scss | 2 +- .../operand/operand.component.scss | 2 +- .../operation/operation.component.scss | 2 +- .../operand/operand.component.scss | 2 +- .../operation/operation.component.scss | 2 +- .../base-filter/base-filter.component.scss | 2 +- .../cds-action-lead-update.component.scss | 2 +- .../cds-action-reply.component.scss | 2 +- .../cds-action-reply.component.scss | 2 +- .../whatsapp-receiver.component.scss | 2 +- .../form-edit-add.component.scss | 2 +- .../cds-widget-logs.component.scss | 2 +- .../cds-canvas/cds-canvas.component.scss | 6 +- .../cds-intent/cds-intent.component.html | 5 +- .../cds-intent/cds-intent.component.scss | 63 ++++++++++++------- .../panel-intent-controls.component.html | 18 +----- .../panel-intent-header.component.html | 1 - ...-panel-button-configuration.component.scss | 2 +- .../cds-panel-detail.component.ts | 2 +- .../cds-panel-library.component.scss | 14 ++--- .../cds-sidebar/cds-sidebar.component.html | 6 +- src/assets/sass/cds/styles.scss | 4 +- 29 files changed, 81 insertions(+), 78 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss index b2170c188..5c8f64bf4 100644 --- a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss @@ -1,6 +1,6 @@ :host{ --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --border-radius-base: 8px; --button-border-radius: #{var(--button-border-radius-base)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss index d49daf09a..6ac7973c7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss index d952fcafb..9bbfcaed5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss @@ -92,7 +92,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss index c1cbd9e6f..4e7cd68aa 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss @@ -3,7 +3,7 @@ :host{ --icon-color: #{var(--blu)}; --text-color: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss index da2c725e9..d5f15dc85 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss @@ -3,7 +3,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss index 6551ee381..7de469476 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss @@ -3,7 +3,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss index da2c725e9..d5f15dc85 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss @@ -3,7 +3,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss index adba32c81..be6fe8a12 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss @@ -1,7 +1,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss index a25d4dfac..24ddcf0d1 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss @@ -1,7 +1,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss index 2ae91e917..ea9c9b378 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss @@ -94,7 +94,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss index ab9ed34c5..227639009 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss @@ -94,7 +94,7 @@ $margin-bottom: 15px; .box-up { display: flex; padding: 5px 10px; - background: var(--blu-light-04); + background: var(--ds-canvas, #f7f6f3); position: relative; /* top: 0; */ width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss index 26559e159..5c64b8cd6 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss @@ -1,7 +1,7 @@ :host{ --icon-color: #{var(--blu)}; --textColor: #{var(--blu)}; - --backGroundColor: #{var(--blu-light-04)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss index 0eac12323..c0e4f8d33 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss @@ -1,5 +1,5 @@ :host { - --background-color: #{var(--blu-light-04)}; + --background-color: #{var(--ds-canvas, #f7f6f3)}; --text-color: #{var(--blu)}; --icon-color: #{var(--blu-light-02)}; --selected-row-background: #{var(--blu-light-02)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss index 43fc838b5..d87dd9d50 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss @@ -26,7 +26,7 @@ .resize-handle { width: 100%; height: 30px; - // background-color: var(--blu-light-04); + // background-color: var(--ds-canvas, #f7f6f3); background-color: white; border-top: 1px solid var(--gray-light-02); border-bottom: 1px solid var(--gray-light-02); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss index ecdaf33e8..82963f5bf 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss @@ -387,7 +387,7 @@ svg:not(:root) { right: 0; z-index: 999; pointer-events: all; - background-color: var(--blu-light-04); + background-color: var(--ds-canvas, #f7f6f3); display: flex; align-items: center; justify-content: center; @@ -466,13 +466,13 @@ cds-widget-logs { cursor: pointer; border: 1px solid var(--ds-border, #ececea); border-left: none; - background: var(--ds-surface, #fff); - color: var(--ds-muted, #8a8884); box-shadow: 2px 1px 4px rgba(20,20,18,.06); transition: background 0.12s, color 0.12s; white-space: nowrap; user-select: none; overflow: hidden; + background: var(--ds-ink, #1a1a19); + color: var(--ds-bg, #fbfbfa); span { max-width: 0; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index b88075f98..259c5c13e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -12,6 +12,7 @@ (mousemove)="onIntentMouseMove($event)" (click)="$event.stopPropagation();onOpenIntentPanel(intent)" [class.node--start]="isStart" + [class.node--fallback]="isDefaultFallback" [id]="'intent-content-'+ intent?.intent_id" [style.--intent-color]="intentColor"> @@ -73,8 +74,8 @@
- -
+ +
boy
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss index cb25d9631..46df4399a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.scss @@ -30,8 +30,10 @@ // Blocco start: pill chiara minimal &.node--start { - background: var(--ds-surface, #fff); - border-color: var(--ds-border, #ececea); + background: var(--ds-link, #1a1a19); + color: var(--ds-bg, #fbfbfa); + // border-color: var(--ds-border, #ececea); + border: 0px solid var(--ds-border, #ececea); border-radius: 999px; width: 160px; min-width: unset; @@ -53,6 +55,14 @@ } } + // Blocco defaultfallback: nasconde icona e tipo + &.node--fallback { + .node-icon, + .node-type-row { + display: none; + } + } + // Overlay bianco per il z-index layering (lasciato per compatibilità TiledeskStage) .intent-background-overlay { position: absolute; @@ -68,7 +78,7 @@ .header-draggable { position: absolute; background-color: transparent; - width: calc(100% - 20px); + width: calc(100% - 0px); height: 40px; top: 0; left: 0; z-index: 1; @@ -95,7 +105,8 @@ width: 24px; height: 24px; border-radius: 6px; - background: var(--ds-canvas, #f7f6f3); + // background: var(--ds-canvas, #f7f6f3); + background: var(--ds-bg, #fbfbfa); color: var(--ds-ink-2, #4a4a47); flex-shrink: 0; display: grid; @@ -119,31 +130,31 @@ } &[data-cat] { - background: var(--cat-soft); + // bacxkground: var(--cat-soft); color: var(--cat-color); } } -// hue 90 = warm grey/tan -.node-icon[data-cat="MOST_USED"] { --cat-color: oklch(0.55 0.02 90); --cat-soft: oklch(0.94 0.01 90); --cat-filter: brightness(0) saturate(100%) invert(40%) sepia(10%) saturate(300%) hue-rotate(25deg) brightness(95%); } -// hue 50 = amber -.node-icon[data-cat="AI"] { --cat-color: oklch(0.66 0.15 50); --cat-soft: oklch(0.95 0.04 60); --cat-filter: brightness(0) saturate(100%) invert(55%) sepia(90%) saturate(600%) hue-rotate(5deg) brightness(95%); } -// hue 245 = blue -.node-icon[data-cat="FLOW"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); --cat-filter: brightness(0) saturate(100%) invert(38%) sepia(60%) saturate(500%) hue-rotate(190deg) brightness(90%); } -// hue 195 = teal -.node-icon[data-cat="INTEGRATIONS"] { --cat-color: oklch(0.62 0.14 195); --cat-soft: oklch(0.95 0.04 195); --cat-filter: brightness(0) saturate(100%) invert(45%) sepia(60%) saturate(500%) hue-rotate(155deg) brightness(90%); } -// hue 290 = purple -.node-icon[data-cat="SPECIAL"] { --cat-color: oklch(0.6 0.14 290); --cat-soft: oklch(0.95 0.04 290); --cat-filter: brightness(0) saturate(100%) invert(35%) sepia(60%) saturate(600%) hue-rotate(250deg) brightness(90%); } -// hue 245 = blue (voice) -.node-icon[data-cat="VOICE"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); --cat-filter: brightness(0) saturate(100%) invert(38%) sepia(60%) saturate(500%) hue-rotate(190deg) brightness(90%); } -.node-icon[data-cat="VOICE_TWILIO"] { --cat-color: oklch(0.62 0.13 245); --cat-soft: oklch(0.95 0.03 245); --cat-filter: brightness(0) saturate(100%) invert(38%) sepia(60%) saturate(500%) hue-rotate(190deg) brightness(90%); } +// #8bc73e = green +.node-icon[data-cat="MOST_USED"] { --cat-color: oklch(0.74 0.17 128); --cat-soft: oklch(0.96 0.05 128); --cat-filter: brightness(0) saturate(100%) invert(68%) sepia(50%) saturate(500%) hue-rotate(50deg) brightness(100%); } +// #34afed = sky blue +.node-icon[data-cat="AI"] { --cat-color: oklch(0.67 0.17 225); --cat-soft: oklch(0.95 0.04 225); --cat-filter: brightness(0) saturate(100%) invert(55%) sepia(60%) saturate(500%) hue-rotate(180deg) brightness(100%); } +// #f59217 = orange +.node-icon[data-cat="FLOW"] { --cat-color: oklch(0.73 0.18 62); --cat-soft: oklch(0.96 0.05 62); --cat-filter: brightness(0) saturate(100%) invert(65%) sepia(80%) saturate(800%) hue-rotate(5deg) brightness(100%); } +// #6c2d8f = purple +.node-icon[data-cat="INTEGRATIONS"] { --cat-color: oklch(0.38 0.18 300); --cat-soft: oklch(0.95 0.04 300); --cat-filter: brightness(0) saturate(100%) invert(20%) sepia(80%) saturate(600%) hue-rotate(265deg) brightness(85%); } +// #fddc02 = yellow +.node-icon[data-cat="SPECIAL"] { --cat-color: oklch(0.82 0.18 96); --cat-soft: oklch(0.97 0.05 96); --cat-filter: brightness(0) saturate(100%) invert(90%) sepia(60%) saturate(600%) hue-rotate(10deg) brightness(105%); } +// #34afed = sky blue (voice) +.node-icon[data-cat="VOICE"] { --cat-color: oklch(0.67 0.17 225); --cat-soft: oklch(0.95 0.04 225); --cat-filter: brightness(0) saturate(100%) invert(55%) sepia(60%) saturate(500%) hue-rotate(180deg) brightness(100%); } +.node-icon[data-cat="VOICE_TWILIO"] { --cat-color: oklch(0.67 0.17 225); --cat-soft: oklch(0.95 0.04 225); --cat-filter: brightness(0) saturate(100%) invert(55%) sepia(60%) saturate(500%) hue-rotate(180deg) brightness(100%); } // Icona play blocco start .node-start-icon { width: 26px; height: 26px; border-radius: 8px; - background: var(--ds-green-soft, oklch(0.95 0.04 155)); + // background: var(--ds-green-soft, oklch(0.95 0.04 155)); color: var(--ds-green, oklch(0.68 0.13 155)); display: grid; place-items: center; @@ -196,6 +207,10 @@ cds-panel-intent-header { .node--start cds-panel-intent-header { width: auto; + + ::ng-deep .form-control { + color: var(--ds-bg, #fbfbfa); + } } .node-type { @@ -301,17 +316,17 @@ cds-panel-intent-header { .agents-available { position: absolute; - top: -8px; - left: -8px; + top: -14px; + left: -14px; display: block; &.isStart { - top: -4px; - left: 8px; + top: -10px; + left: -10px; } span.material-icons { - color: var(--ds-accent, oklch(0.66 0.15 50)); + color: var(--ds-ink-2, oklch(0.66 0.15 50)); font-size: 18px; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.html index 46f1f4650..55b903e27 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-controls/panel-intent-controls.component.html @@ -1,21 +1,9 @@ -
- - - - + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html index 351224755..5ff8ef8fb 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/panel-intent-header/panel-intent-header.component.html @@ -16,7 +16,6 @@
- -
+
Date: Mon, 4 May 2026 17:51:23 +0200 Subject: [PATCH 14/30] changelog + package ver 2.0.1 --- CHANGELOG.md | 5 +++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c2d4302b..9119cfad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ ### **Copyrigth**: *Tiledesk SRL* + +# 2.0.1 +- **changed**: new version v3 + + # 1.39.40 - **added**: added PINECONE_RERANKING in environment to set reranking diff --git a/package-lock.json b/package-lock.json index 41dc2496e..c7803d851 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tiledesk/cds", - "version": "1.39.40", + "version": "2.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@tiledesk/cds", - "version": "1.39.40", + "version": "2.0.1", "license": "MIT", "dependencies": { "@angular/animations": "^14.2.0", diff --git a/package.json b/package.json index b40a35f11..2d2a31c6c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@tiledesk/cds", "author": "Tiledesk SRL", - "version": "1.39.40", + "version": "2.0.1", "license": "MIT", "homepage": "https://www.tiledesk.com", "repository": { From 040a0885737ec52799d1922dc1cdfdb771df1ae5 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Tue, 5 May 2026 17:55:29 +0200 Subject: [PATCH 15/30] Activate cds-action-reply-new component in templates Replace cds-action-reply with cds-action-reply-new in three template files: - cds-intent.component.html: REPLY and RANDOM_REPLY cases - cds-panel-action-detail.component.html: REPLY and RANDOM_REPLY cases - cds-panel-detail.component.html: REPLY and RANDOM_REPLY cases This switches the UI to use the refactored DS V3 component with new layout, styling, and pixel-perfect Reply Inspector design. Build verified without errors. Co-Authored-By: Claude Haiku 4.5 --- clone-actions.sh | 129 +++ fix-selectors-v2.sh | 27 + fix-selectors.sh | 38 + .../list-new/answer/answer-new.component.html | 14 + .../list-new/answer/answer-new.component.scss | 69 ++ .../list-new/answer/answer-new.component.ts | 25 + .../list-new/answer/answer.component.spec.ts | 23 + ...s-action-add-kb-content-new.component.html | 118 +++ ...s-action-add-kb-content-new.component.scss | 114 +++ ...cds-action-add-kb-content-new.component.ts | 185 ++++ ...ds-action-add-kb-content.component.spec.ts | 23 + .../cds-action-add-tag-new.component.html | 85 ++ .../cds-action-add-tag-new.component.scss | 70 ++ .../cds-action-add-tag-new.component.ts | 142 +++ .../cds-action-add-tag.component.spec.ts | 23 + ...ds-action-agent-handoff-new.component.html | 40 + ...ds-action-agent-handoff-new.component.scss | 6 + .../cds-action-agent-handoff-new.component.ts | 23 + ...cds-action-agent-handoff.component.spec.ts | 23 + .../ai-condition-new.component.html | 40 + .../ai-condition-new.component.scss | 73 ++ .../ai-condition-new.component.ts | 60 ++ .../ai-condition.component.spec.ts | 23 + .../attributes-dialog-new.component.html | 36 + .../attributes-dialog-new.component.scss | 151 +++ .../attributes-dialog-new.component.ts | 81 ++ .../attributes-dialog.component.spec.ts | 23 + ...cds-action-ai-condition-new.component.html | 401 ++++++++ ...cds-action-ai-condition-new.component.scss | 684 +++++++++++++ .../cds-action-ai-condition-new.component.ts | 709 ++++++++++++++ .../cds-action-ai-condition.component.spec.ts | 23 + .../attributes-dialog-new.component.html | 36 + .../attributes-dialog-new.component.scss | 161 +++ .../attributes-dialog-new.component.ts | 81 ++ .../attributes-dialog.component.spec.ts | 23 + .../cds-action-ai-prompt-new.component.html | 472 +++++++++ .../cds-action-ai-prompt-new.component.scss | 680 +++++++++++++ .../cds-action-ai-prompt-new.component.ts | 754 ++++++++++++++ .../cds-action-ai-prompt.component.spec.ts | 23 + .../mcp-server-edit-dialog-new.component.html | 150 +++ .../mcp-server-edit-dialog-new.component.scss | 390 ++++++++ .../mcp-server-edit-dialog-new.component.ts | 496 ++++++++++ .../mcp-server-edit-dialog.component.spec.ts | 26 + .../mcp-servers-dialog-new.component.html | 92 ++ .../mcp-servers-dialog-new.component.scss | 363 +++++++ .../mcp-servers-dialog-new.component.ts | 218 +++++ .../mcp-servers-dialog.component.spec.ts | 26 + .../cds-action-askgpt-v2-new.component.html | 714 ++++++++++++++ .../cds-action-askgpt-v2-new.component.scss | 669 +++++++++++++ .../cds-action-askgpt-v2-new.component.ts | 766 +++++++++++++++ .../cds-action-askgpt-v2.component.spec.ts | 23 + .../addkb-dialog-new.component.html | 44 + .../addkb-dialog-new.component.scss | 126 +++ .../addkb-dialog-new.component.ts | 74 ++ .../addkb-dialog.component.spec.ts | 23 + .../cds-action-askgpt-new.component.html | 169 ++++ .../cds-action-askgpt-new.component.scss | 117 +++ .../cds-action-askgpt-new.component.ts | 349 +++++++ .../cds-action-askgpt.component.spec.ts | 23 + ...-action-assign-function-new.component.html | 30 + ...-action-assign-function-new.component.scss | 61 ++ ...ds-action-assign-function-new.component.ts | 51 + ...s-action-assign-function.component.spec.ts | 23 + ...tion-assign-variable-v2-new.component.html | 70 ++ ...tion-assign-variable-v2-new.component.scss | 151 +++ ...action-assign-variable-v2-new.component.ts | 106 ++ ...ction-assign-variable-v2.component.spec.ts | 23 + .../operand/operand-new.component.html | 71 ++ .../operand/operand-new.component.scss | 133 +++ .../operand/operand-new.component.ts | 123 +++ .../operand/operand.component.spec.ts | 23 + .../operation/operation-new.component.html | 32 + .../operation/operation-new.component.scss | 107 ++ .../operation/operation-new.component.ts | 78 ++ .../operation/operation.component.spec.ts | 23 + .../operator/operator-new.component.html | 9 + .../operator/operator-new.component.scss | 27 + .../operator/operator-new.component.ts | 26 + .../operator/operator.component.spec.ts | 23 + ...-action-assign-variable-new.component.html | 71 ++ ...-action-assign-variable-new.component.scss | 167 ++++ ...ds-action-assign-variable-new.component.ts | 104 ++ ...s-action-assign-variable.component.spec.ts | 23 + .../operand/operand-new.component.html | 39 + .../operand/operand-new.component.scss | 92 ++ .../operand/operand-new.component.ts | 107 ++ .../operand/operand.component.spec.ts | 23 + .../operation/operation-new.component.html | 32 + .../operation/operation-new.component.scss | 107 ++ .../operation/operation-new.component.ts | 79 ++ .../operation/operation.component.spec.ts | 23 + .../operator/operator-new.component.html | 9 + .../operator/operator-new.component.scss | 27 + .../operator/operator-new.component.ts | 26 + .../operator/operator.component.spec.ts | 23 + .../cds-action-brevo-new.component.html | 184 ++++ .../cds-action-brevo-new.component.scss | 103 ++ .../cds-action-brevo-new.component.ts | 230 +++++ .../cds-action-brevo.component.spec.ts | 23 + ...tion-capture-user-reply-new.component.html | 80 ++ ...tion-capture-user-reply-new.component.scss | 13 + ...action-capture-user-reply-new.component.ts | 153 +++ ...ction-capture-user-reply.component.spec.ts | 23 + ...ction-change-department-new.component.html | 39 + ...ction-change-department-new.component.scss | 0 ...-action-change-department-new.component.ts | 51 + ...action-change-department.component.spec.ts | 23 + ...action-clear-transcript-new.component.html | 9 + ...action-clear-transcript-new.component.scss | 5 + ...s-action-clear-transcript-new.component.ts | 22 + ...-action-clear-transcript.component.spec.ts | 23 + .../cds-action-close-new.component.html | 9 + .../cds-action-close-new.component.scss | 5 + .../cds-action-close-new.component.ts | 23 + .../cds-action-close.component.spec.ts | 23 + .../cds-action-code-new.component.html | 25 + .../cds-action-code-new.component.scss | 6 + .../cds-action-code-new.component.ts | 38 + .../cds-action-code.component.spec.ts | 23 + ...ds-action-connect-block-new.component.html | 40 + ...ds-action-connect-block-new.component.scss | 0 .../cds-action-connect-block-new.component.ts | 129 +++ ...cds-action-connect-block.component.spec.ts | 23 + .../cds-action-customerio-new.component.html | 166 ++++ .../cds-action-customerio-new.component.scss | 105 ++ .../cds-action-customerio-new.component.ts | 205 ++++ .../cds-action-customerio.component.spec.ts | 23 + ...-action-delete-variable-new.component.html | 36 + ...-action-delete-variable-new.component.scss | 2 + ...ds-action-delete-variable-new.component.ts | 60 ++ ...s-action-delete-variable.component.spec.ts | 23 + .../cds-action-description-new.component.html | 99 ++ .../cds-action-description-new.component.scss | 269 +++++ .../cds-action-description-new.component.ts | 86 ++ .../cds-action-description.component.spec.ts | 23 + .../cds-action-email-new.component.html | 121 +++ .../cds-action-email-new.component.scss | 19 + .../cds-action-email-new.component.ts | 80 ++ .../cds-action-email.component.spec.ts | 23 + .../cds-action-flow-log-new.component.html | 56 ++ .../cds-action-flow-log-new.component.scss | 9 + .../cds-action-flow-log-new.component.ts | 58 ++ .../cds-action-flow-log.component.spec.ts | 23 + ...ds-action-gpt-assistant-new.component.html | 179 ++++ ...ds-action-gpt-assistant-new.component.scss | 9 + .../cds-action-gpt-assistant-new.component.ts | 169 ++++ ...cds-action-gpt-assistant.component.spec.ts | 23 + .../attributes-dialog-new.component.html | 36 + .../attributes-dialog-new.component.scss | 151 +++ .../attributes-dialog-new.component.ts | 81 ++ .../attributes-dialog.component.spec.ts | 23 + .../cds-action-gpt-task-new.component.html | 393 ++++++++ .../cds-action-gpt-task-new.component.scss | 459 +++++++++ .../cds-action-gpt-task-new.component.ts | 574 +++++++++++ .../cds-action-gpt-task.component.spec.ts | 23 + ...cds-action-hide-message-new.component.html | 36 + ...cds-action-hide-message-new.component.scss | 0 .../cds-action-hide-message-new.component.ts | 33 + .../cds-action-hide-message.component.spec.ts | 23 + .../cds-action-hubspot-new.component.html | 150 +++ .../cds-action-hubspot-new.component.scss | 75 ++ .../cds-action-hubspot-new.component.ts | 196 ++++ .../cds-action-hubspot.component.spec.ts | 23 + .../cds-action-intent-new.component.html | 59 ++ .../cds-action-intent-new.component.scss | 34 + .../cds-action-intent-new.component.ts | 159 +++ .../cds-action-intent.component.spec.ts | 23 + .../cds-action-iteration-new.component.html | 131 +++ .../cds-action-iteration-new.component.scss | 9 + .../cds-action-iteration-new.component.ts | 238 +++++ .../cds-action-iteration.component.spec.ts | 24 + .../base-condition-row-new.component.html | 65 ++ .../base-condition-row-new.component.scss | 360 +++++++ .../base-condition-row-new.component.ts | 198 ++++ .../base-condition-row.component.spec.ts | 23 + .../base-filter-new.component.html | 63 ++ .../base-filter-new.component.scss | 223 +++++ .../base-filter/base-filter-new.component.ts | 18 + .../base-filter/base-filter.component.spec.ts | 23 + ...s-action-json-condition-new.component.html | 181 ++++ ...s-action-json-condition-new.component.scss | 264 +++++ ...cds-action-json-condition-new.component.ts | 276 ++++++ ...ds-action-json-condition.component.spec.ts | 23 + .../variable-list-new.component.html | 82 ++ .../variable-list-new.component.scss | 220 +++++ .../variable-list-new.component.ts | 220 +++++ .../variable-list.component.spec.ts | 23 + .../cds-action-lead-update-new.component.html | 92 ++ .../cds-action-lead-update-new.component.scss | 149 +++ .../cds-action-lead-update-new.component.ts | 144 +++ .../cds-action-lead-update.component.spec.ts | 23 + .../cds-action-make-new.component.html | 166 ++++ .../cds-action-make-new.component.scss | 75 ++ .../cds-action-make-new.component.ts | 200 ++++ .../cds-action-make.component.spec.ts | 23 + ...-action-move-unassigned-new.component.html | 9 + ...-action-move-unassigned-new.component.scss | 5 + ...ds-action-move-unassigned-new.component.ts | 22 + ...s-action-move-unassigned.component.spec.ts | 23 + .../cds-action-n8n-new.component.html | 166 ++++ .../cds-action-n8n-new.component.scss | 108 ++ .../cds-action-n8n-new.component.ts | 204 ++++ .../cds-action-n8n.component.spec.ts | 23 + ...ds-action-online-agents-new.component.html | 161 +++ ...ds-action-online-agents-new.component.scss | 13 + .../cds-action-online-agents-new.component.ts | 239 +++++ ...cds-action-online-agents.component.spec.ts | 23 + ...ds-action-online-agents-new.component.html | 96 ++ ...ds-action-online-agents-new.component.scss | 0 .../cds-action-online-agents-new.component.ts | 198 ++++ ...cds-action-online-agents.component.spec.ts | 23 + .../cds-action-open-hours-new.component.html | 149 +++ .../cds-action-open-hours-new.component.scss | 8 + .../cds-action-open-hours-new.component.ts | 205 ++++ .../cds-action-open-hours.component.spec.ts | 23 + .../cds-action-qapla-new.component.html | 172 ++++ .../cds-action-qapla-new.component.scss | 9 + .../cds-action-qapla-new.component.ts | 184 ++++ .../cds-action-qapla.component.spec.ts | 23 + .../cds-action-replace-bot-new.component.html | 43 + .../cds-action-replace-bot-new.component.scss | 1 + .../cds-action-replace-bot-new.component.ts | 58 ++ .../cds-action-replace-bot.component.spec.ts | 23 + ...s-action-replace-bot-v2-new.component.html | 73 ++ ...s-action-replace-bot-v2-new.component.scss | 1 + ...cds-action-replace-bot-v2-new.component.ts | 106 ++ ...ds-action-replace-bot-v2.component.spec.ts | 23 + ...s-action-replace-bot-v3-new.component.html | 88 ++ ...s-action-replace-bot-v3-new.component.scss | 3 + ...cds-action-replace-bot-v3-new.component.ts | 212 ++++ ...ds-action-replace-bot-v3.component.spec.ts | 23 + .../cds-action-reply-new.component.html | 254 +++++ .../cds-action-reply-new.component.scss | 338 +++++++ .../cds-action-reply-new.component.ts | 353 +++++++ .../cds-action-reply.component.spec.ts | 23 + .../cds-action-reply-new.component.html | 248 +++++ .../cds-action-reply-new.component.scss | 323 ++++++ .../cds-action-reply-new.component.ts | 478 +++++++++ .../cds-action-reply.component.spec.ts | 23 + ...cds-action-reply-button-new.component.html | 34 + ...cds-action-reply-button-new.component.scss | 157 +++ .../cds-action-reply-button-new.component.ts | 33 + .../cds-action-reply-button.component.spec.ts | 23 + .../cds-action-reply-frame-new.component.html | 107 ++ .../cds-action-reply-frame-new.component.scss | 104 ++ .../cds-action-reply-frame-new.component.ts | 155 +++ .../cds-action-reply-frame.component.spec.ts | 23 + ...ds-action-reply-gallery-new.component.html | 339 +++++++ ...ds-action-reply-gallery-new.component.scss | 922 ++++++++++++++++++ .../cds-action-reply-gallery-new.component.ts | 651 +++++++++++++ ...cds-action-reply-gallery.component.spec.ts | 23 + .../cds-action-reply-image-new.component.html | 158 +++ .../cds-action-reply-image-new.component.scss | 257 +++++ .../cds-action-reply-image-new.component.ts | 326 +++++++ .../cds-action-reply-image.component.spec.ts | 23 + ...ction-reply-jsonbuttons-new.component.html | 52 + ...ction-reply-jsonbuttons-new.component.scss | 104 ++ ...-action-reply-jsonbuttons-new.component.ts | 108 ++ ...action-reply-jsonbuttons.component.spec.ts | 23 + ...s-action-reply-redirect-new.component.html | 93 ++ ...s-action-reply-redirect-new.component.scss | 113 +++ ...cds-action-reply-redirect-new.component.ts | 115 +++ ...ds-action-reply-redirect.component.spec.ts | 23 + ...s-action-reply-settings-new.component.html | 131 +++ ...s-action-reply-settings-new.component.scss | 120 +++ ...cds-action-reply-settings-new.component.ts | 274 ++++++ ...ds-action-reply-settings.component.spec.ts | 23 + .../cds-action-reply-text-new.component.html | 112 +++ .../cds-action-reply-text-new.component.scss | 62 ++ .../cds-action-reply-text-new.component.ts | 272 ++++++ .../cds-action-reply-text.component.spec.ts | 23 + .../cds-action-reply-tools-new.component.html | 31 + .../cds-action-reply-tools-new.component.scss | 29 + .../cds-action-reply-tools-new.component.ts | 135 +++ .../cds-action-reply-tools.component.spec.ts | 23 + ...ds-action-send-whatsapp-new.component.html | 168 ++++ ...ds-action-send-whatsapp-new.component.scss | 41 + .../cds-action-send-whatsapp-new.component.ts | 223 +++++ ...cds-action-send-whatsapp.component.spec.ts | 23 + .../whatsapp-receiver-new.component.html | 295 ++++++ .../whatsapp-receiver-new.component.scss | 409 ++++++++ .../whatsapp-receiver-new.component.ts | 530 ++++++++++ .../whatsapp-receiver.component.spec.ts | 23 + .../cds-action-wait-new.component.html | 56 ++ .../cds-action-wait-new.component.scss | 208 ++++ .../cds-action-wait-new.component.ts | 57 ++ .../cds-action-wait.component.spec.ts | 23 + ...s-action-web-request-v2-new.component.html | 279 ++++++ ...s-action-web-request-v2-new.component.scss | 308 ++++++ ...cds-action-web-request-v2-new.component.ts | 391 ++++++++ ...ds-action-web-request-v2.component.spec.ts | 23 + .../form-data/form-data-new.component.html | 60 ++ .../form-data/form-data-new.component.scss | 115 +++ .../form-data/form-data-new.component.ts | 87 ++ .../form-data/form-data.component.spec.ts | 23 + .../cds-action-web-request-new.component.html | 103 ++ .../cds-action-web-request-new.component.scss | 274 ++++++ .../cds-action-web-request-new.component.ts | 170 ++++ .../cds-action-web-request.component.spec.ts | 23 + ...cds-action-web-response-new.component.html | 94 ++ ...cds-action-web-response-new.component.scss | 246 +++++ .../cds-action-web-response-new.component.ts | 221 +++++ .../cds-action-web-response.component.spec.ts | 23 + ...tion-whatsapp-attribute-new.component.html | 35 + ...tion-whatsapp-attribute-new.component.scss | 75 ++ ...action-whatsapp-attribute-new.component.ts | 31 + ...ction-whatsapp-attribute.component.spec.ts | 23 + ...-action-whatsapp-static-new.component.html | 157 +++ ...-action-whatsapp-static-new.component.scss | 183 ++++ ...ds-action-whatsapp-static-new.component.ts | 237 +++++ ...s-action-whatsapp-static.component.spec.ts | 23 + .../list-new/cds-actions-new.module.ts | 309 ++++++ .../form-edit-add-new.component.html | 129 +++ .../form-edit-add-new.component.scss | 171 ++++ .../form-edit-add-new.component.ts | 324 ++++++ .../form-edit-add.component.spec.ts | 23 + .../form-field/form-field-new.component.html | 58 ++ .../form-field/form-field-new.component.scss | 118 +++ .../form-field/form-field-new.component.ts | 54 + .../form-field/form-field.component.spec.ts | 23 + .../list-new/form/form-models-factory.ts | 142 +++ .../list-new/form/form-new.component.html | 115 +++ .../list-new/form/form-new.component.scss | 134 +++ .../list-new/form/form-new.component.ts | 512 ++++++++++ .../list-new/form/form.component.spec.ts | 23 + .../modal-window-new.component.html | 41 + .../modal-window-new.component.scss | 42 + .../modal-window-new.component.ts | 27 + .../modal-window.component.spec.ts | 23 + .../question/question-new.component.html | 42 + .../question/question-new.component.scss | 135 +++ .../question/question-new.component.ts | 84 ++ .../question/question.component.spec.ts | 23 + .../cds-intent/cds-intent.component.html | 8 +- .../cds-panel-action-detail.component.html | 8 +- .../cds-panel-detail.component.html | 8 +- src/assets/sass/cds/REPLY_INSPECTOR_SPEC.md | 298 ++++++ src/assets/sass/cds/SCSS_ARCHITECTURE.md | 460 +++++++++ src/assets/sass/cds/_mixins.scss | 288 ++++++ src/assets/sass/cds/_variables.scss | 32 +- src/assets/sass/cds/action-styles.scss | 149 +++ src/assets/sass/cds/styles.scss | 1 + .../providers/abstract/upload.service.ts | 2 +- src/environments/environment.ts | 59 +- 344 files changed, 41047 insertions(+), 48 deletions(-) create mode 100755 clone-actions.sh create mode 100755 fix-selectors-v2.sh create mode 100755 fix-selectors.sh create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-actions-new.module.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-models-factory.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window.component.spec.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.html create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.ts create mode 100644 src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question.component.spec.ts create mode 100644 src/assets/sass/cds/REPLY_INSPECTOR_SPEC.md create mode 100644 src/assets/sass/cds/SCSS_ARCHITECTURE.md create mode 100644 src/assets/sass/cds/_mixins.scss diff --git a/clone-actions.sh b/clone-actions.sh new file mode 100755 index 000000000..c752e07c0 --- /dev/null +++ b/clone-actions.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +# Clone actions/list/ → actions/list-new/ + rename all selectors/classes/files with "-new" suffix + +set -e + +ACTIONS_DIR="src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions" +SOURCE_DIR="$ACTIONS_DIR/list" +TARGET_DIR="$ACTIONS_DIR/list-new" + +echo "🔄 Cloning $SOURCE_DIR → $TARGET_DIR..." + +# 1. Copy entire list/ directory +if [ -d "$TARGET_DIR" ]; then + echo "⚠️ $TARGET_DIR already exists. Removing..." + rm -rf "$TARGET_DIR" +fi + +cp -r "$SOURCE_DIR" "$TARGET_DIR" +echo "✅ Directory cloned" + +# 2. Find all .component.ts files and update them +echo "🔧 Renaming component files and updating selectors..." + +find "$TARGET_DIR" -name "*.component.ts" | while read file; do + dir=$(dirname "$file") + base=$(basename "$file" .component.ts) + newbase="${base}-new" + newfile="$dir/${newbase}.component.ts" + + # Rename file + mv "$file" "$newfile" + + # Extract component class name pattern: cds-action-* → CdsAction*Component + # Example: cds-action-reply → CdsActionReplyComponent → CdsActionReplyNewComponent + + selector_old=$(grep "selector:" "$newfile" | head -1 | sed -E "s/.*selector:\s*['\"]([^'\"]*)['\"].*/\1/") + if [ -n "$selector_old" ]; then + selector_new="${selector_old}-new" + sed -i "" "s|selector: '$selector_old'|selector: '$selector_new'|g" "$newfile" + sed -i "" "s|selector: \"$selector_old\"|selector: \"$selector_new\"|g" "$newfile" + fi + + # Update templateUrl and styleUrls + sed -i "" "s|templateUrl: '[^']*\.component\.html'|templateUrl: './${newbase}.component.html'|g" "$newfile" + sed -i "" "s|templateUrl: \"[^\"]*\.component\.html\"|templateUrl: \"./${newbase}.component.html\"|g" "$newfile" + sed -i "" "s|styleUrls: \['[^']*\.component\.scss'|styleUrls: ['./${newbase}.component.scss'|g" "$newfile" + sed -i "" "s|styleUrls: \[\"[^\"]*\.component\.scss\"|styleUrls: [\"./${newbase}.component.scss\"|g" "$newfile" + + echo " ✓ $newfile" +done + +# 3. Rename .html and .scss files +echo "🔧 Renaming .html and .scss files..." + +find "$TARGET_DIR" -name "*.component.html" -o -name "*.component.scss" | while read file; do + dir=$(dirname "$file") + base=$(basename "$file" .component.html) + base=$(basename "$base" .component.scss) + ext="${file##*.}" + newfile="$dir/${base}-new.component.${ext}" + + if [ "$file" != "$newfile" ]; then + mv "$file" "$newfile" + echo " ✓ $newfile" + fi +done + +# 4. Update all class names in .ts files (CdsActionXComponent → CdsActionXNewComponent) +echo "🔧 Updating TypeScript class names..." + +find "$TARGET_DIR" -name "*-new.component.ts" | while read file; do + # Extract old class name from file path: cds-action-reply-new → CdsActionReplyNew + # Pattern: kebab-case to PascalCase + + # Read file and update class declarations + # Example: export class CdsActionReplyComponent → export class CdsActionReplyNewComponent + + sed -i "" 's/export class \(CdsAction[A-Za-z]*\)Component/export class \1NewComponent/g' "$file" + sed -i "" 's/export class \(CdsOption[A-Za-z]*\)Component/export class \1NewComponent/g' "$file" + sed -i "" 's/implements \(CdsAction[A-Za-z]*Component\)/implements \1New/g' "$file" + + echo " ✓ $(basename $file)" +done + +# 5. Update .html files: replace selector references like +echo "🔧 Updating HTML selector references..." + +find "$TARGET_DIR" -name "*-new.component.html" | while read file; do + # Replace all cds-action-* selectors with cds-action-*-new + # But be careful: should NOT become + # Only direct selectors should be updated + + sed -i "" 's///g' "$file" + sed -i "" 's/<\/cds-action-\([a-z-]*\)>/<\/cds-action-\1-new>/g' "$file" + sed -i "" 's/\[\(cds-action-[a-z-]*\)\]/[\1-new]/g' "$file" + sed -i "" 's/"cds-action-\([a-z-]*\)"/"cds-action-\1-new"/g' "$file" + + echo " ✓ $(basename $file)" +done + +# 6. Create cds-actions-new.module.ts +echo "🔧 Creating cds-actions-new.module.ts..." + +# Copy original module and rename it +cp "$TARGET_DIR/cds-actions.module.ts" "$TARGET_DIR/cds-actions-new.module.ts" + +# Update class name: CdsActionsModule → CdsActionsNewModule +sed -i "" 's/export class CdsActionsModule/export class CdsActionsNewModule/g' "$TARGET_DIR/cds-actions-new.module.ts" + +# Update all component declarations to use -new versions +sed -i "" 's/CdsAction\([A-Za-z]*\)Component/CdsAction\1NewComponent/g' "$TARGET_DIR/cds-actions-new.module.ts" +sed -i "" 's/CdsOption\([A-Za-z]*\)Component/CdsOption\1NewComponent/g' "$TARGET_DIR/cds-actions-new.module.ts" + +echo " ✓ cds-actions-new.module.ts created" + +# 7. Clean up: remove old cds-actions.module.ts from list-new +rm "$TARGET_DIR/cds-actions.module.ts" + +echo "" +echo "✅ Clone complete! Summary:" +echo " • Source: $SOURCE_DIR (unchanged)" +echo " • Target: $TARGET_DIR (renamed with -new suffix)" +echo " • Module: $TARGET_DIR/cds-actions-new.module.ts" +echo "" +echo "Next steps:" +echo " 1. Import CdsActionsNewModule in parent module" +echo " 2. Update templates to use new selectors where needed" +echo " 3. Refactor SCSS files incrementally" diff --git a/fix-selectors-v2.sh b/fix-selectors-v2.sh new file mode 100755 index 000000000..24aa6bb86 --- /dev/null +++ b/fix-selectors-v2.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Fix: Update selectors properly in all -new components + +TARGET_DIR="src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new" + +echo "🔧 Fixing selectors (round 2)..." + +find "$TARGET_DIR" -name "*-new.component.ts" -type f | while read file; do + # Use perl for safer multi-line editing + # Pattern: selector: 'cds-action-X' → selector: 'cds-action-X-new' + + perl -i -pe "s/selector:\s*['\"]([cds\-a-z]+[^'\"]*)['\"]/ + my \$sel = \$1; + \$sel =~ s/-new\$//; # Remove -new if exists + \"selector: '\${sel}-new'\" + /e" "$file" + + echo " ✓ $(basename $file)" +done + +echo "✅ Done!" + +# Verify one +echo "" +echo "Verifying: cds-action-reply-new selector..." +grep "selector:" "$TARGET_DIR/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts" | head -1 diff --git a/fix-selectors.sh b/fix-selectors.sh new file mode 100755 index 000000000..bdeaca390 --- /dev/null +++ b/fix-selectors.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Fix selectors in -new components: cds-action-X → cds-action-X-new + +set -e + +TARGET_DIR="src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new" + +echo "🔧 Fixing selectors in all -new components..." + +# Find all *-new.component.ts files and update their selectors +find "$TARGET_DIR" -name "*-new.component.ts" | while read file; do + echo " Processing: $(basename $file)" + + # Extract the component filename (e.g., cds-action-reply-new) + base=$(basename "$file" .component.ts) + + # Generate selector name from filename + # cds-action-reply-new → cds-action-reply-new + # (It's already -new, but we need to extract the part before -new) + + # Extract the selector from the original file + selector=$(grep -h "selector:" "$file" | head -1 | sed -E "s/.*selector:\s*['\"]([^'\"]*)['\"].*/\1/") + + if [ -n "$selector" ]; then + # Remove -new if it's already there, then add it back + selector_base="${selector%-new}" + selector_new="${selector_base}-new" + + if [ "$selector" != "$selector_new" ]; then + sed -i "" "s/selector: '[^']*'/selector: '$selector_new'/g" "$file" + sed -i "" "s/selector: \"[^\"]*\"/selector: \"$selector_new\"/g" "$file" + echo " ✓ Updated selector from '$selector' to '$selector_new'" + fi + fi +done + +echo "✅ Selectors fixed!" diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.html new file mode 100644 index 000000000..6d9dc14cf --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.html @@ -0,0 +1,14 @@ +
+
+ + + +
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss new file mode 100644 index 000000000..7d4e33f16 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss @@ -0,0 +1,69 @@ +.text-editor-wrapper { + padding: 50px 0px 20px 0px; + .text-editor { + position: relative; + margin: 0; + padding: 0; + .response-controls { + position: absolute; + top: 10px; + left: 0px; + opacity: 0; + transition: opacity 0.3s ease-in-out; + } + } +} + +.text-editor-wrapper:hover { + .text-editor { + .response-controls { + opacity: 1; + } + } +} + +.box-textarea { + width: calc(100% - 40px); + margin-left: 20px; + textarea { + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--color-white-hex); + overflow-x: hidden; + overflow-y: auto; + width: calc(100% - 2.5em); + padding: 20px 20px; + color: var(--gray); + font-size: 1.15em; + line-height: 25px; + resize: vertical; + } +} + +/** TEXT AREA **/ +mat-form-field.mat-focused ::ng-deep { + .mat-form-field-wrapper { + .mat-form-field-flex { + .mat-form-field-infix { + textarea { + border: 1px solid var(--blu) !important; + outline: 1px solid var(--blu) !important; + transition: border .3s; + } + } + } + } +} +mat-form-field.box-textarea ::ng-deep { + .mat-form-field-wrapper { + padding-bottom:0; + .mat-form-field-flex { + border-radius: 4px 4px 0 0; + padding: 0 0.75em 0 0.75em; + margin: 0; + } + } + .mat-form-field-underline { + display: none; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.ts new file mode 100644 index 000000000..becc7d2a8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: ' selector: 'cds-answer-new',-new', + templateUrl: './answer-new.component.html', + styleUrls: ['./answer-new.component.scss'] +}) +export class CdsAnswerComponent implements OnInit { + @Input() intentSelected: any; + @Output() updateAnswerIntentSelected = new EventEmitter(); + + public answer: string; + + constructor() { } + + ngOnInit(): void { + // this.answer = JSON.parse(JSON.stringify(this.intentSelected.answer)); + this.answer = this.intentSelected.answer + } + + onChangeText(_answer:string) { + this.updateAnswerIntentSelected.emit(_answer); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer.component.spec.ts new file mode 100644 index 000000000..5bf4dbffb --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsAnswerComponent } from './answer.component'; + +describe('PanelAnswerComponent', () => { + let component: CdsAnswerComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsAnswerComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsAnswerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.html new file mode 100644 index 000000000..458f2b6cf --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.html @@ -0,0 +1,118 @@ +
+
+
+ +
+
+ {{action?.name}} +
+
+ {{'CDSCanvas.EnterQuestion' | translate}} +
+
+ +
+ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss new file mode 100644 index 000000000..35902d8d0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss @@ -0,0 +1,114 @@ +.field-description { + display: block; +} + +.tags-input-row { + display: flex; + align-items: center; + gap: 8px; + border: 1px solid var(--blu-light-02, #d2d4d6); + border-radius: var(--input-border-radius-base, 8px); + padding: 0 4px 0 12px; + background: #fff; + box-sizing: border-box; + + .tags-input { + flex: 1; + min-width: 0; + border: none; + outline: none; + padding: 5px 0; + font-size: 14px; + background: transparent; + color: var(--gray); + &::placeholder { + color: #9aa0a6; + } + } + + .tags-send-btn { + flex-shrink: 0; + padding: 3px 7px; + border: none; + border-radius: 6px; + background: var(--blu); + color: #fff; + font-size: 12px; + line-height: 12px; + font-weight: 500; + cursor: pointer; + height: 26px; + + &:hover { + opacity: 0.9; + } + } +} + +.models--container { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 4px; +} + +.model-name-and-btn-wpr { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 0px; + border-radius: 4px; + background-color: var(--blu-light-01); + border: 0px solid #d2d4d6; + font-size: 12px; +} + +.model-name { + margin: 0; + font-weight: 300; + color: var(--blu); + padding-left: 6px; +} + +.delete-model { + display: flex; + align-items: center; + justify-content: center; + padding: 6px; + margin: 0; + height: 100%; + min-width: 14px; + min-height: 14px; + border: none; + background: transparent; + color: #3d4047; + cursor: pointer; + border-radius: 0px 4px 4px 0px; + + &:hover { + background: var(--blu); + .remove-tag-icon { + fill: var(--color-white-hex); + } + } +} + +.remove-tag-icon { + width: 12px; + height: 12px; + min-width: 12px; + min-height: 12px; + fill: currentColor; +} + +.link-container { + margin-bottom: 20px; + a.link { + font-size: 14px; + font-weight: 400; + } + a.link:hover { + cursor: pointer; + text-decoration: underline; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.ts new file mode 100644 index 000000000..c406d3009 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.ts @@ -0,0 +1,185 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ActionKBContent } from 'src/app/models/action-model'; +import { AppConfigService } from 'src/app/services/app-config'; +import { DOCS_LINK, TYPE_UPDATE_ACTION, TYPE_GPT_MODEL } from 'src/app/chatbot-design-studio/utils'; + +import { DashboardService } from 'src/app/services/dashboard.service'; +import { OpenaiService } from 'src/app/services/openai.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; + +@Component({ + selector: ' selector: 'cds-action-add-kb-content-new',-new', + templateUrl: './cds-action-add-kb-content-new.component.html', + styleUrls: ['./cds-action-add-kb-content-new.component.scss'] +}) +export class CdsActionAddKbContentNewComponent implements OnInit { + + @Input() action: ActionKBContent; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + project_id: string; + selectedNamespace: string; + listOfNamespaces: Array<{name: string, displayName: string, kbTypeLabel: string, value: string, icon?:string, hybrid?: boolean}>; + autocompleteOptions: Array<{label: string, value: string}> = []; + tagInputValue = ''; + + + BRAND_BASE_INFO = BRAND_BASE_INFO; + DOCS_LINK = DOCS_LINK.ADD_TO_KB; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private openaiService: OpenaiService, + private dashboardService: DashboardService, + private appConfigService: AppConfigService + ) { } + + ngOnInit(): void { + this.project_id = this.dashboardService.projectID + this.ensureTags(); + this.getListNamespaces(); + } + + private ensureTags(): void { + if (!Array.isArray(this.action.tags)) { + this.action.tags = []; + } + } + + addTag(): void { + const value = this.tagInputValue?.trim() || ''; + if (!value) return; + this.ensureTags(); + if (this.action.tags.indexOf(value) === -1) { + this.action.tags.push(value); + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.ACTION, element: this.action }); + } + this.tagInputValue = ''; + } + + removeTag(tag: string): void { + this.ensureTags(); + const index = this.action.tags.indexOf(tag); + if (index !== -1) { + this.action.tags.splice(index, 1); + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.ACTION, element: this.action }); + } + } + + onChangeTextarea($event: string, property: string) { + this.logger.log("[ACTION-ADD_KBCONTENT] onEditableDivTextChange event", $event); + this.logger.log("[ACTION-ADD_KBCONTENT] onEditableDivTextChange property", property); + if(property === 'namespace'){ + this.action[property] = $event; + } + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + private getListNamespaces(){ + this.openaiService.getAllNamespaces().subscribe((namaspaceList) => { + this.logger.log("[ACTION-ASKGPTV2] getListNamespaces", namaspaceList) + this.listOfNamespaces = namaspaceList.map((el) => { + const isHybrid = (el as any).hybrid ? (el as any).hybrid : false; + const kbTypeLabel = isHybrid ? 'Hybrid' : 'Semantic'; + return { name: el.name, displayName: el.name, kbTypeLabel, value: el.id, hybrid: isHybrid }; + }) + namaspaceList.forEach(el => this.autocompleteOptions.push({label: el.name, value: el.name})) + this.initializeNamespaceSelector(); + }) + } + + async initializeNamespaceSelector() { + if (!this.action.namespaceAsName) { + if (!this.action.namespace) { + this.action.namespace = this.project_id; + return; + } + } else { + if (!this.action.namespace) { + this.action.namespace = await this.idToName(this.project_id); + } + } + } + + async idToName(id: string): Promise { + return new Promise((resolve) => { + let name = this.listOfNamespaces.find(n => n.value === id).name; + resolve(name) + }) + } + + async nameToId(name: string): Promise { + return new Promise((resolve) => { + let selected = this.listOfNamespaces.find(n => n.name === name); + if(selected){ + resolve(selected.value) + } + resolve(this.project_id) + }) + } + + + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'namespace') { + if(event){ + if (type === 'namespace') { + if (!this.action.namespaceAsName) { + this.action[type]=event.value + } else { + this.action[type] = this.listOfNamespaces.find(n => n.value === event.value).name; + } + this.selectedNamespace = event.value; + } else { + this.action[type]=event.value + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'namespace') { + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + async onChangeCheckbox(event, target){ + try { + this.action[target] = !this.action[target]; + if (target === "namespaceAsName") { + if (this.action[target]) { + if (this.action.namespace) { + this.action.namespace = await this.idToName(this.action.namespace); + } + } else { + this.action.namespace = await this.nameToId(this.action.namespace); + } + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + + onBlur(event, property){ + if(property === 'source'){ + this.action.content = this.action.name? this.action.name + '\n'+this.action[property] : this.action[property]; + } else if(property === 'namespace'){ + // this.action.namespace = event.target.value; + this.action[property] = event; + } + // this.updateAndSaveAction.emit() + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToKNB(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + window.open(url, '_blank'); + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content.component.spec.ts new file mode 100644 index 000000000..d3e6c5ab0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAddKbContentComponent } from './cds-action-add-kb-content.component'; + +describe('CdsActionAddKbContentComponent', () => { + let component: CdsActionAddKbContentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAddKbContentComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAddKbContentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.html new file mode 100644 index 000000000..b553f7db5 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.html @@ -0,0 +1,85 @@ +
+ + +
+
+ {{'CDSCanvas.Target' | translate }}: +
+
+
+ {{ (radioOptions | find:{key: 'value', value: action?.target }).name | translate }} +
+
+
+ + + +
+
+ + + + +
+
+ {{item | getVariableName }} +
+
+ +
+ + +
+
+ +
+ + + + +
+ +
+ + + + + +
+ + {{"CDSCanvas.PushTagsToList" | translate}} + + +
+
+ + +
+ + +
+ + + +
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss new file mode 100644 index 000000000..583b15c3e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss @@ -0,0 +1,70 @@ +.cds-input-group { + flex-wrap: nowrap; + display: flex; + + cds-text{ + width: 90%; + } + .cds-group-addon-question-right{ + width: 10%; + } + +} + +cds-text#text.sx-input ::ng-deep { + input{ + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +} + +.cds-group-addon-question-right { + background: var(--blu); + // height: 47px; + border-radius: 0; + // padding-left: 6px; + // padding-right: 6px; + padding-top: 0px; + border-top-right-radius: var(--input-border-radius-base); + border-bottom-right-radius: var(--input-border-radius-base); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} + +.cds-group-addon-question-right:hover { + opacity: 0.8 !important; +} + +.cds-group-addon-question-right-btn-icon { + color: #fff; + position: relative; +} + +.add-question-btn-disabled { + pointer-events: none; + background: #aaa; +} + +.cds-action-preview{ + .action-row-left{ + width: unset; + } + + .set-attribute-label { + color: #6c6859d9; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; + // background: #e8e6dd; + padding: 0px 3px; + height: inherit; + } + + .set-option-value { + font-weight: 600; + background: unset; + color: unset; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.ts new file mode 100644 index 000000000..36f9612d9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.ts @@ -0,0 +1,142 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { MatChipInputEvent } from '@angular/material/chips'; +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { tagsList } from 'src/app/chatbot-design-studio/utils-variables'; +import { ActionAddTags, ActionCode } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { AppConfigService } from 'src/app/services/app-config'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-add-tag-new', + templateUrl: './cds-action-add-tag-new.component.html', + styleUrls: ['./cds-action-add-tag-new.component.scss'] +}) +export class CdsActionAddTagNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionAddTags; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + newTag: string = ''; + autocompleteOptions: Array = []; + tagsList: Array = [] + + project_id: string; + dashboardLabelUrl: string; + + radioOptions: Array<{name: string, value: string, disabled: boolean, checked: boolean}>= [ + {name: 'CDSCanvas.Conversation', value: 'request', disabled: false, checked: true }, + {name: 'CDSCanvas.Contact', value: 'lead', disabled: false, checked: false }, + ] + BRAND_BASE_INFO = BRAND_BASE_INFO + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private dashboardService: DashboardService, + private appConfigService: AppConfigService + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION-ADD-TAG] action", this.action) + // this.checkIfTagAlreadyExist() + this.logger.log("[ACTION-ADD-TAG] tagsList", tagsList) + this.project_id = this.dashboardService.projectID + this.tagsList = this.action.tags.split(',') + + this.setDasboardTagsUrl() + } + + setDasboardTagsUrl(){ + this.dashboardLabelUrl = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/labels'; + } + + onChangeButtonSelect(event: {label: string, value: string, disabled: boolean, checked: boolean}){ + this.radioOptions.forEach(el => { el.value ===event.value? el.checked= true: el.checked = false }) + this.action.target = event.value + + /** rebuild autocomplete options for input field based on new radio option selected */ + this.autocompleteOptions = []; + tagsList.find(el => el.key === this.action.target).elements.forEach(el => this.autocompleteOptions.push(el.name)) + + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + onChangeText(text: string){ + this.logger.log("[ACTION-ADD-TAG] onChangeText", text) + this.newTag = text + } + + onChangeTextarea(event: string, property: string) { + this.logger.log("[ACTION-ADD-TAG] onEditableDivTextChange event", event, this.tagsList) + this.logger.log("[ACTION-ADD-TAG] onEditableDivTextChange property", property) + this.action[property] = event + this.tagsList = event.split(',')// this.action[property] =Object.assign('', $event).split(',').map(el => el.trim()) + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + // onAddTag(){ + // this.logger.log("[ACTION-ADD-TAG] onAddTag", this.newTag) + // /**if tag already exsit to not add to autocomplete options and tags list */ + // let exist = this.autocompleteOptions.some(el => el.includes(this.newTag)) + // if(!exist){ + // this.autocompleteOptions.push(this.newTag); + // tagsList.find(el => el.key === this.action.target).elements.unshift({name: this.newTag}) + // } + // /**if same key already exist in action tags array, do not add again */ + // let existInAction = this.action.tags.some(el => el.includes(this.newTag)) + // if(!existInAction){ + // this.action.tags.push(this.newTag) + // } + // this.newTag = ''; //reset tag for new add + // this.updateAndSaveAction.emit(); + // } + + async onChangeCheckbox(event, target){ + try { + this.action[target] = !this.action[target]; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + // removeTag(tag: string){ + // this.logger.log("[ACTION-ADD-TAG] removeTag", tag) + // let index = this.action.tags.findIndex(el => el === tag) + // if(index > -1){ + // this.action.tags.splice(index, 1) + // } + + // let autocompleteIndex = this.autocompleteOptions.findIndex(el => el === tag) + // console.log('indexxxxx', autocompleteIndex) + // if(autocompleteIndex > -1 ){ + // this.autocompleteOptions.splice(autocompleteIndex, 1) + // } + // this.updateAndSaveAction.emit(); + // } + + + // checkIfTagAlreadyExist(){ + // this.autocompleteOptions = []; + // this.action.tags.forEach((tag) => { + // let index = tagsList.find(el => el.key === this.action.target).elements.findIndex(el => el.name === tag) + + // if(index === -1){ + // tagsList.find(el => el.key === this.action.target).elements.push({name: tag}) + // } + // }); + // console.log('checkIfTagAlreadyExist', tagsList) + // tagsList.find(el => el.key === this.action.target).elements.forEach(el => this.autocompleteOptions.push(el.name)) + // } + + onBlur(){ + this.updateAndSaveAction.emit(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag.component.spec.ts new file mode 100644 index 000000000..f2fe71d62 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAddTagComponent } from './cds-action-add-tag.component'; + +describe('CdsActionAddTagComponent', () => { + let component: CdsActionAddTagComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAddTagComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAddTagComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.html new file mode 100644 index 000000000..221262082 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.html @@ -0,0 +1,40 @@ +
+ + + +
+ +
+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.scss new file mode 100644 index 000000000..d32e98260 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.scss @@ -0,0 +1,6 @@ +.cds-action-preview{ + .action-row{ + justify-content: center; + } +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.ts new file mode 100644 index 000000000..57f776fa2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff-new.component.ts @@ -0,0 +1,23 @@ +import { ACTIONS_LIST } from '../../../../../utils-actions'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ActionAgent } from 'src/app/models/action-model'; + +@Component({ + selector: ' selector: 'cds-action-agent-new',-new', + templateUrl: './cds-action-agent-handoff-new.component.html', + styleUrls: ['./cds-action-agent-handoff-new.component.scss'] +}) +export class CdsActionAgentHandoffNewComponent implements OnInit { + + @Input() action: ActionAgent; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + actions = ACTIONS_LIST + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff.component.spec.ts new file mode 100644 index 000000000..dd40f1423 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-agent-handoff/cds-action-agent-handoff.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAgentHandoffComponent } from './cds-action-agent-handoff.component'; + +describe('CdsActionAgentHandoffComponent', () => { + let component: CdsActionAgentHandoffComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAgentHandoffComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAgentHandoffComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.html new file mode 100644 index 000000000..3450f091b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.html @@ -0,0 +1,40 @@ +
+
+ + +
+ + +
+ +
+
+
+ +
+ +
+ + +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss new file mode 100644 index 000000000..2dadd07a5 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss @@ -0,0 +1,73 @@ +.ai-condition-container { + position: relative; + display: flex; + flex-direction: column; + gap: 4px; + // padding: 16px; + margin-bottom: 20px; + // border: 1px solid #e9ecef; + // border-radius: 8px; + // background-color: #ffffff; + transition: all 0.2s ease; + + &:hover { + // border-color: #dee2e6; + // box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + + .delete-condition-btn { + opacity: 1; + visibility: visible; + } + } +} + +.condition-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 6px; +} + +.condition-number { + font-size: 14px; + font-weight: 600; + color: var(--blu); +} + +.delete-condition-btn { + background-color: #dc3545; + color: white; + border: none; + border-radius: 50%; + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + opacity: 0; + visibility: hidden; + transition: all 0.2s ease; + position: absolute; + top: 30px; + left: -24px; + &:hover { + background-color: #c82333; + transform: scale(1.1); + } + .material-icons { + font-size: 16px; + } +} + +.ai-condition-select{ + display: flex; + flex-direction: row; + justify-content: flex-end; + .condition-text { + font-weight: unset; + } + cds-select { + width: 50%; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.ts new file mode 100644 index 000000000..c8ec91330 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.ts @@ -0,0 +1,60 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +@Component({ + selector: 'app-ai-condition', + templateUrl: './ai-condition-new.component.html', + styleUrls: ['./ai-condition-new.component.scss'] +}) +export class AiConditionComponent implements OnInit { + @Input() intent: any; + @Input() index: number; + @Input() listOfIntents: Array<{name: string, value: string, icon?:string}>; + @Output() updateAndSaveAction = new EventEmitter; + @Output() updateAndSaveConnectors = new EventEmitter; + @Output() deleteCondition = new EventEmitter; + + label: string; + propmt: string; + conditionIntentId: string; + placeholder: string = "Go down this path if"; + constructor() { } + + ngOnInit(): void { + this.label = this.intent.label; + this.propmt = this.intent.prompt; + this.conditionIntentId = this.intent.conditionIntentId; + } + + onBlur(event: any) { + this.propmt = this.intent.prompt; + this.updateAndSaveAction.emit({ + value: event + }); + } + + onChangeTextarea(event: any) { + this.intent.prompt = event; + } + + onChangeBlockSelect(event: any) { + this.intent.conditionIntentId = event.value; + this.updateAndSaveConnectors.emit({ + value: event, + type: 'create' + }); + } + + onResetBlockSelect(event: any) { + this.intent.conditionIntentId = null; + this.updateAndSaveConnectors.emit({ + value: event, + type: 'delete' + }); + } + + onDeleteCondition() { + this.deleteCondition.emit({ + value: this.intent + }); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition.component.spec.ts new file mode 100644 index 000000000..69bddc375 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AiConditionComponent } from './ai-condition.component'; + +describe('AiConditionComponent', () => { + let component: AiConditionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AiConditionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AiConditionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.html new file mode 100644 index 000000000..e5fe163ca --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.html @@ -0,0 +1,36 @@ +
+
+
+ Set Attributes +
+ close + +
+ +
+ +
+
+ +
+
{{ attr.name }}
+ + +
+ +
+
+ + +
+
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss new file mode 100644 index 000000000..c758611f4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss @@ -0,0 +1,151 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/styles.scss"; + +::ng-deep .custom-setattribute-dialog-container { + width: 40vw!important; + min-width: 500px; + max-width: 1000px!important; + height: 80vh; + + .tpl-modal-box { + + border-radius: 6px; + flex-direction: column; + background: rgb(255, 255, 255); + } + .tpl-modal-header { + align-items: flex-start; + align-items: center; + display: flex; + flex-shrink: 0; + justify-content: center; + width: 100%; + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + } + } + + .tpl-modal-header-text { + flex-grow: 1; + text-align: center; + width: 0; + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 18px; + } + } + + .tpl-modal-content { + flex-grow: 1; + padding: 30px 0px; + width: 100%; + } + + .tpl-info { + border-radius: 4px; + display: flex; + margin-bottom: 20px; + padding: 12px 15px; + width: 100%; + color: #333; + background: var(--icon-color); + .tpl-info-icon { + font-size: 20px; + height: 20px; + flex-shrink: 0; + width: 35px; + } + } + .tpl-label-textarea { + margin-bottom: 5px; + color: #22272d; + font-size: 15px; + line-height: 19px; + } + + input { + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--blu-light-02); + color: var(--gray); + font-size: 1.15em; + line-height: 25px; + + -webkit-transition: border .3s; + transition: border .3s; + width: 100%; + + padding: 10px; + padding-top: 4px; + padding-bottom: 4px; + margin: 0px; + // resize: none; + + &::placeholder { + opacity: 0.5; + } + &.invalid{ + border: 2px solid red !important; + outline: 0px solid red !important; + transition: border 0.3s; + } + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: flex-end; + color: #333; + gap: 5px; + .cds-yellow-button{ + margin-left: 10px; + min-width: 80px; + background-color: var(--icon-color); + height: 100%; + color: #333; + } + } +} + +.input-error { + position: absolute; + font-size: 14px; + color: red; +} + +.attr-container { + font-size: 14px; + font-weight: 400; + background: #ecb606; + width: -moz-fit-content; + width: fit-content; + padding: 2px 6px; + border-radius: 4px; + color: #fff; + line-height: 1.5; + margin-bottom: 2px; +} + +#cds-publish-btn:hover:enabled { + opacity: .8 !important; +} + +#cds-publish-btn:disabled { + opacity: 0.5; + cursor: default; +} + +#cds-cancel-btn { + background: #e5e5e5; + color: #4b5052; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.ts new file mode 100644 index 000000000..7d6824b7c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.ts @@ -0,0 +1,81 @@ +import { Component, Inject, OnInit, inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + + +@Component({ + selector: 'appdashboard-attributes-dialog-new', + templateUrl: './attributes-dialog-new.component.html', + styleUrls: ['./attributes-dialog-new.component.scss'] +}) +export class AttributesDialogAiConditionComponent implements OnInit { + + btn_disabled: boolean = false; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + ngOnInit(): void { + this.logger.debug("[AttributesDialog] data: ", this.data); + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onCloseDialog(): void { + this.logger.log("[AttributesDialog] - modal CLOSED"); + this.dialogRef.close(); + } + + onChangeTextarea(text, key) { + this.btn_disabled = false; + this.data.attributes.find(a => a.name === key).value = text + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onGenerateClick() { + this.data.attributes.forEach((attr) => { + let old_value = "{{" + attr.name + "}}"; + this.data.question = this.data.question.replace(old_value, attr.value); + if(this.data.namespace){ + this.data.namespace = this.data.namespace.replace(old_value, attr.value); + } + }) + + this.logger.log("[AttributesDialog] - onGenerateClick return data: ", this.data); + this.dialogRef.close(this.data); + } + + + // createConditionGroup(): FormGroup { + // return this.formBuilder.group({ + // attributes: this.formBuilder.array([ + // this.createAttributesGroup() + // ]) + // }) + // } + + // createAttributesGroup(): FormGroup { + // return this.formBuilder.group({ + // name: ['', Validators.required], + // value: ['', Validators.required] + // }) + // } + + // setFormValue() { + // let attributesControl = this.varsForm.controls.attributes; + // this.data.attributes.forEach((v) => { + // attributesControl.push(v) + // // this.varsForm.patchValue({ attributes: this.data.attributes }); + // }) + // this.logger.log("varsForm: ", this.varsForm); + // } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.spec.ts new file mode 100644 index 000000000..465bc5025 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AttributesDialogAiConditionComponent } from './attributes-dialog.component'; + +describe('AttributesDialogAiConditionComponent', () => { + let component: AttributesDialogAiConditionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AttributesDialogAiConditionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AttributesDialogAiConditionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.html new file mode 100644 index 000000000..be721b7e3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.html @@ -0,0 +1,401 @@ +
+ + +
+
+ + +
+
+
+ {{ (llm_models | find:{key: 'value', value: action?.llm }).name }} ({{action?.model}}) +
+
+ {{'CDSCanvas.ChooseTheAIModel' | translate }} +
+
+
+ + + +
+
+
+
+ {{intent.prompt}} +
+
+ No prompt defined +
+
+
+
+ + + +
+
+
+ + +
+ +
+ + + + +
+ + + + +
+ + + +
+ + + +
+ +
+ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss new file mode 100644 index 000000000..d22530235 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss @@ -0,0 +1,684 @@ +@import "./src/assets/sass/cds/_variables.scss"; + + +:host { + --background-color: #{var(--blu-light-01)}; + --slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; +} + +::-webkit-scrollbar { + width: 0px; +} + +.custom-divider { + border-top: 1px solid var(--blu); +} + + +div { + + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + } + div.tag-replyto { + display: flex; + width: fit-content; + border-radius: 4px; + font-size: 10px; + margin: 3px; + height: -moz-fit-content; + height: fit-content; + padding: 0px 6px; + max-width: calc(100% - 25px); + background-color: var(--blu); + color: var(--color-white-hex); + flex-wrap: nowrap; + text-align: end; + } +} + +a#router-link{ + cursor: pointer; + &:hover{ + text-decoration: underline; + } +} + + +#cds-addkb-btn { + background: #006cff; + color: #fff; + box-shadow: none; + font-weight: 500; + font-family: var(--font-family-poppins); + text-transform: capitalize; + font-size: 14px; + padding: 6px 12px; + border-radius: 10px; +} + +#cds-addkb-btn:hover { + opacity: .8 !important; +} + +.custom-icon { + margin-right: 6px; + font-size: 15px; +} + +.animated-icon { + animation: rotate 1.5s linear infinite; +} + +@keyframes rotate { + to { + transform: rotate(360deg); + } +} + + + +.variable-container { + display: flex; + height: 35px; + flex-direction: row; + align-items: center; + border: solid 1px black; + background-color: white; + padding: 0px 20px; + border-radius: 10px; + font-size: 14px; +} + +/////////////////////////////////////// +/////////////////////////////////////// + + + +// *********** AI SETTINGS --start *********** // + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} + +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 10px !important; + } + + .title-and-parameters-container { + display: flex; + flex-direction: column; + width: 100%; + } + + .parameters-preview { + font-size: 11px; + height: 24px; + line-height: normal; + span { + line-height: 16px; + margin-right: 5px; + } + .preview-badge { + color: #fff; + background-color: var(--blu); + display: inline-block; + padding: 1px 5px; + border-radius: 4px; + .preview-badge-text { + padding: 0; + margin:0; + } + } + .preview-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 12px; + height: 12px; + font-size: 12px; + line-height: 12px; + margin: 0; + vertical-align: middle; + color: var(--color-white-hex); + } + .preview-flag{ + margin:0; + } + } + +} + +cds-select#model-condition ::ng-deep{ + .select-item-wrp{ + justify-content: space-between; + } +} + +mat-checkbox ::ng-deep { + .mat-checkbox-ripple{ + display: none; + } +} + +::ng-deep .ng-dropdown-panel { + .ng-option .select-item-wrp[additionalText = true]{ + .select-item-wrp{ + justify-content: space-between; + } + } +} + +.action-wait-content { + display: flex; + flex-direction: row; + align-items: center; + gap: 5px; +} + +.action-wait-range { + color: var(--text-color); + font-size: 11px; + font-weight: 500; +} + +.action-wait-slider { + align-items: center; + background: var(--slider-background-color); + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 9px; + width: 100%; + text-align: center; + transition: width 0.3s ease-in; + font-size: 14px; + &.disabled { + opacity: 0.5; + } +} + +.action-wait-slider>mat-slider { + width: 100%; + margin-left: 6px; +} +.action-wait-slider.disabled { + opacity: 0.4; +} + +.action-wait-slider ::ng-deep{ + .mat-accent .mat-slider-track-fill { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label-text{ + color: var(--background-color) !important; + font-size: 10px !important; + } + .mat-slider-thumb { + background-color: var(--text-color) !important; + } +} + +.gpt-setting-input { + color: var(--text-color); + text-align: center; + width: 45px; + border: none; + height: 26px; + border-radius: 12px; + background-color: white; + border: 1px solid var(--text-color); + + // Hide number input spinner arrows + /* Chrome, Safari, Edge, Opera */ + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + &[type=number] { + -moz-appearance: textfield; + appearance: textfield; + } +} + +.slider-input ::ng-deep { + width: 60px; + min-width: 60px; + font-size: 12px; + input { + text-align: center; + } +} + +// *********** AI SETTINGS --end *********** // + +.header-answer-preview { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + + .close-button { + cursor: pointer; + font-size: 18px; + font-weight: 600; + color: #ffffff80; + + &:hover { + color: white; + } + } + +} + +.link-container { + margin-bottom: 20px; + + a.link { + font-size: 14px; + font-weight: 400; + } + + a.link:hover { + cursor: pointer; + text-decoration: underline; + } + +} + +// PREVIEW SECTION --- start **************** // +.preview-container { + width: 100%; + max-height: 37px; + overflow: hidden; + transition: max-height 0.5s ease-out; + border-radius: var(--input-border-radius-base); + background-color: var(--color-white-hex); + padding: 6px 12px; + font-size: 14px; + border: 1px solid var(--blu-light-02); + color: var(--gray); +} + +.preview-container-extended { + max-height: 300px; + overflow-y: auto; +} + +.placeholder-container { + display: flex; + align-items: center; +} + +loading-spinner.custom-spinner ::ng-deep { + .sk-fading-circle { + width: 20px ; + height: 20px ; + margin: 0px ; + } + + .sk-fading-circle .sk-circle:before { + background-color: var(--blu) ; + } +} + +.label-and-button-container { + + width: 100%; + display: flex; + align-items: center; + margin-bottom: 6px; + + + .title-label { + margin-bottom: 0px; + } + +} + +.set-var-btn { + font-weight: 300 !important; + font-size: 12px !important; + height: 20px; + display: flex; + align-items: center; + padding: 6px 6px 6px 12px !important; + margin: 0px 0px 0px 6px !important; +} + +// .content#variables .opened { +// left: 0px; +// } + + + +.variables-content-header { + display: flex; + flex-direction: row; + align-items: center; + + .back-button { + cursor: pointer; + font-size: 20px; + font-weight: 600; + margin-right: 6px; + color: #ffffff80; + + &:hover { + color: white; + } + } + + .title-label { + font-size: 18px; + margin-bottom: 0px; + } +} + +.single-variable { + display: flex; + align-items: center; + margin: 14px 0px; + + .variable-name { + background-color: #ecb608; + color: white; + font-weight: 400; + padding: 6px 12px; + border-radius: 7px; + margin-right: 10px; + } + +} + +.usage-container { + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 6px; + padding: 0px 4px; + color: #a6a6a6; + font-size: 11px; + width: 100%; +} + +// PREVIEW SECTION --- start **************** // + +.condition-header { + display: flex; + justify-content: flex-start; + margin-bottom: 8px; +} + + +.condition-number { + font-size: 14px; + font-weight: 600; + color: var(--blu); +} + +// .condition-number2 { +// background-color: var(--blu); +// color: white; +// padding: 4px 12px; +// border-radius: 16px; +// font-size: 12px; +// font-weight: 500; +// text-transform: uppercase; +// letter-spacing: 0.5px; +// } + +.add-intent-container { + display: flex; + justify-content: center; + margin: 6px 0 0 0; +} + +.add-intent-btn { + float: right; + -webkit-user-select: none; + user-select: none; + box-sizing: border-box; + outline: none; + border: 1px dashed var(--blu-light-02); + border-radius: var(--button-border-radius-base); + color: var(--blu-light-02); + cursor: pointer; + font-size: 0.7em; + font-weight: 400; + line-height: var(--button-height-base); + order: 1; + padding: 0 10px; + transition: all 0.3s; + min-width: 100px; + text-align: center; + width: fit-content; + background-color: #ffffff; + text-transform: none; + box-shadow:none; + &:hover { + border-color: var(--blu-light-02); + color: var(--color-white-hex); + background-color: var(--blu); + } + + .material-icons { + font-size: 18px; + } +} + +// Intent preview styles +.intent-preview-info { + display: flex; + flex-direction: column; + gap: 4px; + flex: 1; + padding-top: 10px; + width: 100%; +} + +.intent-prompt-preview { + display: flex; + flex-direction: column; + gap: 2px; + padding: 4px 0; + + .prompt-label { + font-size: 11px; + font-weight: 600; + color: var(--blu); + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .prompt-text { + font-size: 12px; + color: #333; + line-height: 1.3; + word-wrap: break-word; + // max-width: 200px; + } + + &.empty { + .prompt-text { + color: #999; + font-style: italic; + } + } +} + +.connector-condition { + margin-left: auto; +} + +.ai-condition-instructions { + padding-bottom: 40px; +} + + +// Prompt text truncation +.prompt-text { + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + line-height: 1.4; + max-height: 2.8em; /* 2 righe * 1.4 line-height */ +} + + + +cds-select#model-condition.not-configured ::ng-deep { + .ng-select .ng-select-container { + border: 1px solid var(--empty-value-text-color); + } + .ng-select .ng-select-container .ng-value span.label-select{ + color: var(--empty-value-text-color); + } +} + + +.select-container { + &.not-configured { + ::ng-deep .ng-select .ng-select-container { + .ng-value { + span.label-select { + color: var(--empty-value-text-color); + } + } + } + ::ng-deep .text-editor-wrapper .text-editor .box-input input { + color: var(--empty-value-text-color)!important; + border: 1px solid var(--empty-value-text-color)!important; + } + } + .status-indicator { + width: 8px; + height: 8px; + background-color: var(--empty-value-text-color); + border-radius: 50%; + margin: 0px; + position: absolute; + left: 0px; + top: 96px; + } +} + +// Bottom row styles for model selection +.bottom-row { + display: flex; + align-items: center; + margin-top: 0px; + padding-left: 0px; + flex-direction: row-reverse; +} + +.multiplier-container { + color: var(--gray); + font-size: 12px; + display: inline-block; +} + +.configure-model-button { + cursor: pointer; + color: #007bff; + font-size: 12px; + text-decoration: underline; + display: inline-block; + &:hover { + opacity: 0.7; + } +} +// PREVIEW SECTION --- start **************** // \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.ts new file mode 100644 index 000000000..149d9a0b7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.ts @@ -0,0 +1,709 @@ +import { Component, ElementRef, EventEmitter, HostListener, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { firstValueFrom, Observable, Subscription } from 'rxjs'; + +//MODELS +import { ActionAiCondition } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; + +//SERVICES +import { OpenaiService } from 'src/app/services/openai.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { MatDialog } from '@angular/material/dialog'; +import { AppConfigService } from 'src/app/services/app-config'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; + +//UTILS +import { AttributesDialogAiConditionComponent } from './attributes-dialog/attributes-dialog.component'; +import { AiConditionComponent } from './ai-condition/ai-condition.component'; +import { DOCS_LINK, generateShortUID, TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { PLAN_NAME } from 'src/chat21-core/utils/constants'; +import { TranslateService } from '@ngx-translate/core'; +import { loadTokenMultiplier } from 'src/app/utils/util'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { ANTHROPIC_MODEL, COHERE_MODEL, DEEPSEEK_MODEL, DEFAULT_MODEL, GOOGLE_MODEL, GROQ_MODEL, LLM_MODEL, OLLAMA_MODEL, OPENAI_MODEL, generateLlmModelsFlat } from 'src/app/chatbot-design-studio/utils-ai_models'; +import { checkConnectionStatusOfAction, checkConnectionStatusByConnector, updateConnector, updateSingleConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { ProjectService } from 'src/app/services/projects.service'; +import { sortAutocompleteOptions, getModelsByName, getIntegrations, setModel, initLLMModels, getIntegrationModels, LlmModel } from 'src/app/chatbot-design-studio/utils-llm-models'; +import { FormatNumberPipe } from 'src/app/pipe/format-number.pipe'; + +@Component({ + selector: 'cds-action-ai-condition-new', + templateUrl: './cds-action-ai-condition-new.component.html', + styleUrls: ['./cds-action-ai-condition-new.component.scss'] +}) +export class CdsActionAiConditionNewComponent implements OnInit { + private readonly DEFAULT_MAX_TOKENS = 10000; + + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + + @Input() intentSelected: Intent; + @Input() action: ActionAiCondition; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + panelOpenState = false; + + llm_models: Array<{ name: string, value: string, src: string, models: Array<{ name: string, value: string, status: "active" | "inactive" }> }> = []; + llm_options_models: Array<{ name: string, value: string, status: "active" | "inactive" }> = []; + ai_setting: { [key: string] : {name: string, min: number, max: number, step: number, disabled: boolean}} = { + "max_tokens": { name: "max_tokens", min: 10, max: 100000, step: 1, disabled: false}, + "temperature" : { name: "temperature", min: 0, max: 1, step: 0.05, disabled: false}, + } + + ai_response: string = ""; + ai_error: string = "Oops! Something went wrong. Check your GPT Key or retry in a few moment." + + showPreview: boolean = false; + missingVariables: boolean = true; + showVariablesBtn: boolean = false; + showVariablesSection: boolean = false; + showAiError: boolean = false; + searching: boolean = false; + temp_variables = []; + actionLabelModel: string = ""; + + + + // Connectors + idIntentSelected: string; + listOfConnectors: any = {}; + +// idConnectorTrue: Array = []; +// idConnectionTrue: Array = []; +// isConnectedTrue: Array = []; + + idConnectorFallback: string; + idConnectorError: string; + idConnectionFallback: string; + idConnectionError: string; + isConnectedFallback: boolean = false; + isConnectedError: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + projectPlan: PLAN_NAME + PLAN_NAME = PLAN_NAME + BRAND_BASE_INFO = BRAND_BASE_INFO; + DOCS_LINK = DOCS_LINK.GPT_TASK; + + default_model = DEFAULT_MODEL; + llm_model = LLM_MODEL; + llm_models_flat: Array; + llm_model_selected: LlmModel = {} as LlmModel; + + private isInitializing = { + 'llm_model': true, + 'context': true, + 'question': true + }; + browserLang: string = 'it'; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly dialog: MatDialog, + private readonly openaiService: OpenaiService, + private readonly intentService: IntentService, + private readonly appConfigService: AppConfigService, + private readonly translate: TranslateService, + private readonly dashboardService: DashboardService, + private readonly projectService: ProjectService, + private readonly formatNumberPipe: FormatNumberPipe + ) { } + + + async ngOnInit(): Promise { + // Locale for Angular number pipe (we only register 'it' explicitly; fallback to 'en') + const lang = this.translate.getBrowserLang() || 'en'; + this.browserLang = lang.startsWith('it') ? 'it' : 'en'; + this.logger.log("[ACTION AI_CONDITION] ngOnInit action: ", this.action); + this.project_id = this.dashboardService.projectID; + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'ollama'); + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'vllm'); + + this.llm_models = this.llm_model.filter(el => el.status === 'active'); + this.projectPlan = this.dashboardService.project.profile.name; + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION AI_CONDITION] isChangedConnector -->', connector); + //this.logger.log('[ACTION AI_CONDITION] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.logger.log('[ACTION AI_CONDITION] connectorId -->', connectorId); + this.connector = connector; + if(connector.idCondition){ + this.refreshConnector(connector.fromId, connector.idCondition); + } else { + this.updateConnectionFalse(); + this.updateConnectionTrue(); + } + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + this.initializeAttributes(); + if (!this.action.preview) { + this.action.preview = []; + } + await this.initialize(); + this.isInitializing = { + 'llm_model': false, + 'context': false, + 'question': false + }; + } + + + ngOnChanges(changes: SimpleChanges) { + // empty + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + + private async initialize(){ + await this.initLLMModels(); + this.setModel(this.action.modelName ? this.action.modelName : this.default_model.name, { + resetMaxTokens: false, + resetTemperature: false + }); + this.logger.log("[ACTION AI_PROMPT] initialize llm_options_models: ", this.action); + } + + + async initLLMModels(){ + const result = await initLLMModels({ + projectService: this.projectService, + dashboardService: this.dashboardService, + appConfigService: this.appConfigService, + logger: this.logger, + componentName: 'ACTION AI_PROMPT' + }); + this.llm_models_flat = result; + } + + setModel( + modelName: string, + options?: { resetMaxTokens?: boolean; resetTemperature?: boolean } + ) { + const { resetMaxTokens = true, resetTemperature = true } = options ?? {}; + const result = setModel(modelName, this.llm_models_flat, this.logger); + this.llm_model_selected = result ?? ({} as LlmModel); + this.logger.log("[ACTION AI_PROMPT] llm_model_selected: ", this.llm_model_selected); + this.action.llm = result?.llm ? result.llm : ''; + this.action.model = result?.model ? result.model : ''; + this.action.modelName = result?.modelName ? result.modelName : ''; + this.logger.log("[ACTION AI_PROMPT] action: ", this.action); + if (result) { + this.ai_setting['max_tokens'].max = result.max_output_tokens; + this.ai_setting['max_tokens'].min = result.min_tokens; + const min = this.ai_setting['max_tokens'].min; + const max = this.ai_setting['max_tokens'].max; + + const currentMaxTokens = + typeof this.action?.max_tokens === 'number' ? this.action.max_tokens : Number(this.action?.max_tokens); + if (resetMaxTokens || !Number.isFinite(currentMaxTokens)) { + let next = Math.min(this.DEFAULT_MAX_TOKENS, max); + if (next < min) next = min; + this.action.max_tokens = next; + } else { + this.action.max_tokens = Math.min(Math.max(currentMaxTokens, min), max); + } + + const isGpt5 = modelName.startsWith('gpt-5') || modelName.startsWith('Gpt-5'); + if (isGpt5) { + this.ai_setting['temperature'].disabled = true; + const currentTemp = + typeof this.action?.temperature === 'number' ? this.action.temperature : Number(this.action?.temperature); + if (resetTemperature || !Number.isFinite(currentTemp)) { + this.action.temperature = 1; + } + } else { + this.ai_setting['temperature'].disabled = false; + } + } + } + + async getIntegrationByName(){ + const projectID = this.dashboardService.projectID; + const integrationName = 'ollama'; + try { + const response = await firstValueFrom(this.projectService.getIntegrationByName(projectID, integrationName)); + this.logger.log('[ACTION AI_CONDITION] - integration response:', response.value); + return response; + } catch (error) { + this.logger.log('[ACTION AI_CONDITION] getIntegrationByName ERROR:', error); + } + } + + refreshConnector(idConnector, idCondition) { + this.listOfConnectors[idCondition] = { + idConnector: idConnector, + idConnection: null, + isConnected: false + }; + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + //this.listOfConnectors = {}; + this.action.intents.forEach((element, index) => { + this.logger.log("[ACTION AI_CONDITION] initializeConnector element: ", index, element); + let idConnector = ''; + let idConnection = ''; + let isConnected = false; + if(element.label){ + idConnector = this.idIntentSelected + "/" + this.action._tdActionId + "/" + element.label + "/true"; + } + if(element.conditionIntentId){ + isConnected = true; + let toIntentId = element.conditionIntentId.replace('#', ''); + idConnection = idConnector+"/"+toIntentId; + } + this.listOfConnectors[element.label] = { + idConnector: idConnector, + idConnection: idConnection, + isConnected: isConnected + } + }); + this.idConnectorFallback = this.idIntentSelected + "/" + this.action._tdActionId + "/fallback"; + if (this.action.fallbackIntent) { + this.isConnectedFallback = true; + this.idConnectionFallback =this.idConnectorFallback + "/" + this.action.fallbackIntent.replace('#', ''); + } + this.idConnectorError = this.idIntentSelected + "/" + this.action._tdActionId + "/error"; + if (this.action.errorIntent) { + this.isConnectedError = true; + this.idConnectionError = this.idConnectorError + "/" + this.action.errorIntent.replace('#', ''); + } + this.listOfIntents = this.intentService.getListOfIntents(); + //this.checkConnectionStatus(); + } + + + private updateConnectionTrue(){ + this.logger.log('[ACTION AI_CONDITION] updateConnectionTrue:', this.connector); + const parts = this.connector.fromId.split("/"); + try { + const idCondition = parts[parts.length - 2]; + const found = this.action.intents.find(item => item.label === idCondition); + if (this.connector.deleted) { + if(this.listOfConnectors[idCondition]){ + this.listOfConnectors[idCondition].idConnection = null; + this.listOfConnectors[idCondition].isConnected = false; + } + if(found){ + found.conditionIntentId = null; + } + } else { + if(this.listOfConnectors[idCondition]){ + this.listOfConnectors[idCondition].idConnection = this.connector.id; + this.listOfConnectors[idCondition].isConnected = true; + } + if(found){ + found.conditionIntentId = '#'+this.connector.toId; + } + } + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } catch (error) { + this.logger.log('error: ', error); + } + } + + + private updateConnectionFalse(){ + this.logger.log('[ACTION AI_CONDITION] updateConnectorFalse:', this.connector, this.connector.id, this.idConnectionFallback); + if (this.connector.fromId === this.idConnectorFallback) { + if (this.connector.deleted) { + this.isConnectedFallback = false; + this.idConnectionFallback = null; + this.action.fallbackIntent = null; + this.logger.log('[ACTION AI_CONDITION] deleted:'); + } else { + this.isConnectedFallback = true; + this.idConnectionFallback = this.connector.id; + this.action.fallbackIntent = '#'+this.connector.toId; + this.logger.log('[ACTION AI_CONDITION] added:'); + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } else if (this.connector.fromId === this.idConnectorError) { + if (this.connector.deleted) { + this.isConnectedError = false; + this.idConnectionError = null; + this.action.errorIntent = null; + this.logger.log('[ACTION AI_CONDITION] deleted:'); + } else { + this.isConnectedError = true; + this.idConnectionError = this.connector.id; + this.action.errorIntent = '#'+this.connector.toId; + this.logger.log('[ACTION AI_CONDITION] added:'); + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'ai_reply')) { + new_attributes.push({ name: "ai_reply", value: "ai_reply" }); + } + variableList.find(el => el.key ==='userDefined').elements = [...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION AI_CONDITION] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + + onChangeTextarea(event: string, labelModel: string, property: string) { + this.logger.log("[ACTION AI_CONDITION] changeTextarea event: ", event, labelModel, property, this.isInitializing[property]); + // Ignora le chiamate durante l'inizializzazione per questa proprietà specifica + if (this.isInitializing[property]) { + this.isInitializing[property] = false; + return; + } + if(property === 'model'){ + this.action['labelModel'] = event; + if(event.startsWith('gpt-5') || event.startsWith('Gpt-5')){ + this.action.temperature = 1 + this.ai_setting['temperature'].disabled= true + } else { + this.ai_setting['temperature'].disabled= false + } + this.action['labelModel'] = event; + } else if (property === 'question'){ + this.action['question'] = event; + } else if (property === 'context'){ + this.action['context'] = event; + } else if (property === 'instructions'){ + this.action['instructions'] = event; + } + } + + + onUpdateAndSaveAction(intent: any) { + this.logger.log("[ACTION AI_CONDITION] onUpdateAndSaveAction event: ", intent); + // cerca nell'array action.intents l'elemento con label === intent.label e sostituiscilo con intent se non lo trova aggiungilo all'array + const found = this.action.intents.find(item => item.label === intent?.label); + if(found){ + this.action.intents[found.index] = intent; + } else { + this.action.intents.push(intent); + } + this.updateAndSaveAction.emit(); + } + + onUpdateAndSaveConnectors(intent: any, type: 'create' | 'delete') { + this.logger.log("[ACTION AI_CONDITION] onUpdateAndSaveConnectors event: ", intent, type); + let toId: string; + let fromId: string; + try { + //if(intent.conditionIntentId && intent.conditionIntentId !== null){ + if(type === 'delete'){ + this.listOfConnectors[intent.label].idConnection = null; + this.listOfConnectors[intent.label].isConnected = false; + toId = null; + fromId = this.listOfConnectors[intent.label].idConnector; + } else if(intent.conditionIntentId && intent.conditionIntentId !== null) { + this.listOfConnectors[intent.label].idConnection = this.listOfConnectors[intent.label].idConnector+"/"+intent.conditionIntentId.replace('#', ''); + this.listOfConnectors[intent.label].isConnected = true; + toId = intent.conditionIntentId.replace('#', ''); + fromId = this.listOfConnectors[intent.label].idConnector; + } + //} + let found = this.action.intents.find(item => item.label === intent.label); + if(found){ + found = intent; + } + this.logger.log("[ACTION AI_CONDITION] onUpdateAndSaveConnectors this.action: ", this.action); + this.onConnectorChange.emit({ type: type, fromId: fromId, toId: toId }); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("[ACTION AI_CONDITION] onUpdateAndSaveConnectors error: ", error); + } + } + + onOptionSelected(event: any, property: string){ + this.logger.log("[ACTION AI_CONDITION] onOptionSelected event: ", event, this.action); + this.actionLabelModel = event.label; + this.action[property] = event.value; + this.updateAndSaveAction.emit(); + } + + onBlur(event: string){ + this.logger.log("[ACTION AI_CONDITION] onBlur event: ", event, this.action); + this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION AI_CONDITION] onEditableDivTextChange event", event) + this.logger.log("[ACTION AI_CONDITION] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit(); + } + + onChangeSelect(event, target) { + this.logger.log("[ACTION AI_CONDITION] onChangeSelect event: ", event.value) + this.logger.log("[ACTION AI_CONDITION] onChangeSelect target: ", target) + this.action[target] = event.value; + if (target === 'llm_model'){ + this.setModel(event.modelName, { resetMaxTokens: true, resetTemperature: true }); + } + this.updateAndSaveAction.emit(); + } + + updateSliderValue(event, target) { + this.logger.log("[ACTION AI_CONDITION] updateSliderValue event: ", event) + this.logger.log("[ACTION AI_CONDITION] updateSliderValue target: ", target) + this.action[target] = event; + if(target === 'max_tokens'){ + if(event < this.ai_setting['max_tokens'].min){ + this.action.max_tokens = this.ai_setting['max_tokens'].min; + } else if(event > this.ai_setting['max_tokens'].max){ + this.action.max_tokens = this.ai_setting['max_tokens'].max; + } else { + this.action.max_tokens = event; + } + } + this.updateAndSaveAction.emit(); + } + + onChangeCheckbox(event: MatCheckboxChange, target){ + try { + this.action[target] = event.checked; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'errorIntent' | 'fallbackIntent' | string) { + this.logger.log("[ACTION AI_CONDITION] onChangeBlockSelect", event, type); + this.action[type]=event.value; + if(event){ + switch(type){ + case 'errorIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorError, toId: this.action.errorIntent}); + break; + case 'fallbackIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFallback, toId: this.action.fallbackIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'errorIntent' | 'fallbackIntent') { + this.action[type]=null; + switch(type){ + case 'errorIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorError, toId: this.action.errorIntent}); + break; + case 'fallbackIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFallback, toId: this.action.fallbackIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + scrollToBottom(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.log('scrollToBottom ERROR: ', error); + } + }, 300); + } + + execPreview() { + this.scrollToBottom(); + this.checkVariables().then((resp) => { + if (resp === true) { + this.getResponse(this.action.question); + } else { + this.openAttributesDialog(); + } + }) + } + + checkVariables() { + return new Promise((resolve, reject) => { + let regex: RegExp = /{{[^{}]*}}/g; + let string = this.action.question; + let matches = string.match(regex); + let response: boolean = true; + if (!matches || matches.length == 0) { + resolve(true); + } else { + this.temp_variables = []; + matches.forEach((m) => { + let name = m.slice(2, m.length - 2); + let attr = this.action.preview.find(v => v.name === name); + if (attr?.value) { + this.temp_variables.push({ name: name, value: attr.value }); + } else if (attr && !attr.value) { + this.temp_variables.push({ name: name, value: null }); + } else { + this.temp_variables.push({ name: name, value: null }); + this.action.preview.push({ name: name, value: null }); + } + }) + resolve(false); + } + }) + } + + getResponse(question) { + this.logger.log("getResponse called...") + let data = { + question: question, + llm: this.action.llm, + model: this.action.model, + max_tokens: this.action.max_tokens, + temperature: this.action.temperature, + } + this.showAiError = false; + this.searching = true; + this.showPreview = true; + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.remove('preview-container-extended') + }, 200) + this.openaiService.previewLLMPrompt(data).subscribe({ next: (ai_response: any) => { + this.searching = false; + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.ai_response = ai_response; + }, error: (err) => { + this.searching = false; + this.logger.error("[ACTION AI_CONDITION] previewPrompt error: ", err); + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.showAiError = true; + if(err.error.error_code === 13001){ + this.ai_error = this.translate.instant('CDSCanvas.AiQuotaExceeded') + return; + } + this.ai_error = this.translate.instant('CDSCanvas.AiError') + }, complete: () => { + this.logger.debug("[ACTION AI_CONDITION] preview prompt *COMPLETE*: "); + this.searching = false; + }}); + + } + + + getLlmIcon(llm: string): string { + this.logger.log("[ACTION AI_CONDITION] getLlmIcon ******: ", llm); + const filteredModel = this.llm_models.find((model) => model.value === llm); + this.logger.log("[ACTION AI_CONDITION] filteredModel ******: ", filteredModel); + return filteredModel ? filteredModel.value : ''; + } + + + openAttributesDialog() { + this.logger.log("temp_variables: ", this.temp_variables); + const dialogRef = this.dialog.open(AttributesDialogAiConditionComponent, { + panelClass: 'custom-setattribute-dialog-container', + data: { attributes: this.temp_variables, question: this.action.question } + }); + dialogRef.afterClosed().subscribe(result => { + this.logger.log("AttributesDialogComponent result: ", result); + if (result !== false) { + this.getResponse(result.question); + this.saveAttributes(result.attributes); + } + }); + } + + saveAttributes(attributes) { + this.logger.log("attributes: ", attributes); + attributes.forEach(a => { + let index = this.action.preview.findIndex(v => v.name === a.name) + if (index != -1) { + this.action.preview[index].value = a.value; + } else { + this.action.preview.push({ name: a.name, value: a.value }) + } + this.updateAndSaveAction.emit(); + }) + } + + goToIntegrations(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations' + window.open(url, '_blank') + } + + /** + * addNewCondition + * Adds a new condition to the intents array + */ + addNewCondition() { + this.logger.log("[ACTION AI_CONDITION] addNewCondition", this.action.intents); + + if (!this.action.intents) { + this.action.intents = []; + } + const idCondition = generateShortUID(); + this.action.intents.push({ + "label": idCondition, + "prompt": "", + "conditionIntentId": '' + }); + let idConnector = `${this.idIntentSelected}/${this.action._tdActionId}/${idCondition}/true`; + this.listOfConnectors[idCondition] = { + idConnector: idConnector, + idConnection: null, + isConnected: false + }; + //this.onConnectorChange.emit({ type: 'delete', fromId: idConnector, toId: ''}); + this.intentService.onChangedConnector({fromId: idConnector, idCondition: idCondition}); + this.logger.log("[ACTION AI_CONDITION] addNewCondition", this.listOfConnectors); + // this.updateAndSaveAction.emit(); + } + + onDeleteCondition(intent: any) { + this.logger.log("[ACTION AI_CONDITION] onDeleteCondition", intent); + const label = intent.value.label; + const foundIndex = this.action.intents.findIndex(item => item.label === label); + if (foundIndex !== -1) { + const intentToDelete = this.action.intents[foundIndex]; + // Remove from intents array + this.action.intents.splice(foundIndex, 1); + // Remove from connectors map + if (intentToDelete.label && this.listOfConnectors[intentToDelete.label]) { + delete this.listOfConnectors[intentToDelete.label]; + } + this.logger.log("[ACTION AI_CONDITION] onDeleteCondition - remaining intents:", this.action.intents); + this.logger.log("[ACTION AI_CONDITION] onDeleteCondition - remaining connectors:", this.listOfConnectors); + this.updateAndSaveAction.emit(); + } + } + + /** + * Formats the slider thumb label value with "k" notation for values > 999 + * Uses the FormatNumberPipe for consistent formatting across the app + * @param value - The numeric value to format + * @returns Formatted string with "k" for values > 999 (rounded to integers) + */ + formatSliderLabel = (value: number): string => { + return this.formatNumberPipe.transform(value); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition.component.spec.ts new file mode 100644 index 000000000..d58020d2b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAiConditionComponent } from './cds-action-ai-condition.component'; + +describe('CdsActionAiConditionComponent', () => { + let component: CdsActionAiConditionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAiConditionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAiConditionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.html new file mode 100644 index 000000000..a8449857f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.html @@ -0,0 +1,36 @@ +
+
+
+ Set Attributes +
+ close + +
+ +
+ +
+
+ +
+
{{ attr.name }}
+ + +
+ +
+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss new file mode 100644 index 000000000..fd606cd44 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss @@ -0,0 +1,161 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/styles.scss"; + +::ng-deep .custom-setattribute-dialog-container { + width: 40vw!important; + min-width: 500px; + max-width: 1000px!important; + height: 80vh; + + .tpl-modal-box { + + border-radius: 6px; + flex-direction: column; + background: rgb(255, 255, 255); + } + .tpl-modal-header { + align-items: flex-start; + align-items: center; + display: flex; + flex-shrink: 0; + justify-content: center; + width: 100%; + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + } + } + + .tpl-modal-header-text { + flex-grow: 1; + text-align: center; + width: 0; + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 18px; + } + } + + .tpl-modal-content { + flex-grow: 1; + padding: 30px 0px; + width: 100%; + } + + .tpl-info { + border-radius: 4px; + display: flex; + margin-bottom: 20px; + padding: 12px 15px; + width: 100%; + color: #333; + background: var(--icon-color); + .tpl-info-icon { + font-size: 20px; + height: 20px; + flex-shrink: 0; + width: 35px; + } + } + .tpl-label-textarea { + margin-bottom: 5px; + color: #22272d; + font-size: 15px; + line-height: 19px; + } + + input { + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--blu-light-02); + color: var(--gray); + font-size: 1.15em; + line-height: 25px; + + -webkit-transition: border .3s; + transition: border .3s; + width: 100%; + + padding: 10px; + padding-top: 4px; + padding-bottom: 4px; + margin: 0px; + // resize: none; + + &::placeholder { + opacity: 0.5; + } + &.invalid{ + border: 2px solid red !important; + outline: 0px solid red !important; + transition: border 0.3s; + } + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: flex-end; + color: #333; + gap: 5px; + .cds-yellow-button{ + margin-left: 10px; + min-width: 80px; + background-color: var(--icon-color); + height: 100%; + color: #333; + } + } +} + +.input-error { + position: absolute; + font-size: 14px; + color: red; +} + +.attr-container { + font-size: 14px; + font-weight: 400; + background: #ecb606; + width: -moz-fit-content; + width: fit-content; + padding: 2px 6px; + border-radius: 4px; + color: #fff; + line-height: 1.5; + margin-bottom: 2px; +} + +#cds-publish-btn:hover:enabled { + opacity: .8 !important; +} + +#cds-publish-btn:disabled { + opacity: 0.5; + cursor: default; +} + +#cds-cancel-btn { + background: #e5e5e5; + color: #4b5052; +} + +/* ---- Attributes dialog: moved from inline styles ---- */ +::ng-deep .custom-setattribute-dialog-container .attr-dialog__hr { + margin-top: 3px; + margin-bottom: 3px; +} + +::ng-deep .custom-setattribute-dialog-container .attr-dialog__item { + margin-bottom: 14px; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.ts new file mode 100644 index 000000000..5cb8d3340 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.ts @@ -0,0 +1,81 @@ +import { Component, Inject, OnInit, inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + + +@Component({ + selector: 'appdashboard-attributes-dialog-new', + templateUrl: './attributes-dialog-new.component.html', + styleUrls: ['./attributes-dialog-new.component.scss'] +}) +export class AttributesDialogAiPromptComponent implements OnInit { + + btn_disabled: boolean = false; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + ngOnInit(): void { + this.logger.debug("[AttributesDialog] data: ", this.data); + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onCloseDialog(): void { + this.logger.log("[AttributesDialog] - modal CLOSED"); + this.dialogRef.close(); + } + + onChangeTextarea(text, key) { + this.btn_disabled = false; + this.data.attributes.find(a => a.name === key).value = text + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onGenerateClick() { + this.data.attributes.forEach((attr) => { + let old_value = "{{" + attr.name + "}}"; + this.data.question = this.data.question.replace(old_value, attr.value); + if(this.data.namespace){ + this.data.namespace = this.data.namespace.replace(old_value, attr.value); + } + }) + + this.logger.log("[AttributesDialog] - onGenerateClick return data: ", this.data); + this.dialogRef.close(this.data); + } + + + // createConditionGroup(): FormGroup { + // return this.formBuilder.group({ + // attributes: this.formBuilder.array([ + // this.createAttributesGroup() + // ]) + // }) + // } + + // createAttributesGroup(): FormGroup { + // return this.formBuilder.group({ + // name: ['', Validators.required], + // value: ['', Validators.required] + // }) + // } + + // setFormValue() { + // let attributesControl = this.varsForm.controls.attributes; + // this.data.attributes.forEach((v) => { + // attributesControl.push(v) + // // this.varsForm.patchValue({ attributes: this.data.attributes }); + // }) + // this.logger.log("varsForm: ", this.varsForm); + // } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.spec.ts new file mode 100644 index 000000000..5e6f1a701 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AttributesDialogComponent } from './attributes-dialog.component'; + +describe('AttributesDialogComponent', () => { + let component: AttributesDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AttributesDialogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AttributesDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.html new file mode 100644 index 000000000..cc97c210a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.html @@ -0,0 +1,472 @@ +
+ +
+
+ + + + +
+ +
+
+ {{action?.question}} +
+
+ {{'CDSCanvas.EnterPrompt' | translate }} +
+
+ +
+ +
+
+ + +
+ +
+
+ {{ (llm_models | find:{key: 'value', value: action?.llm })?.name }} ({{action?.model}}) +
+
+ {{'CDSCanvas.ChooseTheAIModel' | translate }} +
+
+
+
+
+ {{action?.assignReplyTo}} +
+
+ + + + +
+
{{'CDSCanvas.ToolsUsed' | translate}}
+
+ + {{ server.name }} + +
+
+ + + +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss new file mode 100644 index 000000000..5b5394601 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss @@ -0,0 +1,680 @@ +@import "./src/assets/sass/cds/_variables.scss"; + + +:host { + --background-color: #{var(--blu-light-01)}; + --slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; +} + +::-webkit-scrollbar { + width: 0px; +} + +.custom-divider { + border-top: 1px solid var(--blu); +} + + +div { + + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } + + div.tag-replyto { + display: flex; + width: fit-content; + border-radius: 4px; + font-size: 10px; + margin: 0px; + height: fit-content; + padding: 0px 6px; + max-width: calc(100% - 25px); + background-color: var(--blu); + color: var(--color-white-hex); + flex-wrap: nowrap; + text-align: end; + } +} + +a#router-link{ + cursor: pointer; + &:hover{ + text-decoration: underline; + } +} + + +#cds-addkb-btn { + background: #006cff; + color: #fff; + box-shadow: none; + font-weight: 500; + font-family: var(--font-family-poppins); + text-transform: capitalize; + font-size: 14px; + padding: 6px 12px; + border-radius: 10px; +} + +#cds-addkb-btn:hover { + opacity: .8 !important; +} + +.custom-icon { + margin-right: 6px; + font-size: 15px; +} + +.animated-icon { + animation: rotate 1.5s linear infinite; +} + +@keyframes rotate { + to { + transform: rotate(360deg); + } +} + + + +.variable-container { + display: flex; + height: 35px; + flex-direction: row; + align-items: center; + border: solid 1px black; + background-color: white; + padding: 0px 20px; + border-radius: 10px; + font-size: 14px; +} + +/////////////////////////////////////// +/////////////////////////////////////// + + + +// *********** AI SETTINGS --start *********** // + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} + +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .title-and-parameters-container { + display: flex; + flex-direction: column; + width: 100%; + } + + .parameters-preview { + font-size: 11px; + height: 24px; + line-height: normal; + span { + line-height: 16px; + margin-right: 5px; + } + .preview-badge { + color: #fff; + background-color: var(--blu); + display: inline-block; + padding: 1px 5px; + border-radius: 4px; + .preview-badge-text { + padding: 0; + margin:0; + } + } + .preview-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 12px; + height: 12px; + font-size: 12px; + line-height: 12px; + margin: 0; + vertical-align: middle; + color: var(--color-white-hex); + } + .preview-flag{ + margin:0; + } + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 10px !important; + } + +} + +cds-select#model-condition ::ng-deep{ + .select-item-wrp{ + justify-content: space-between; + } +} + +mat-checkbox ::ng-deep { + .mat-checkbox-ripple{ + display: none; + } +} + +::ng-deep .ng-dropdown-panel { + .ng-option .select-item-wrp[additionalText = true]{ + .select-item-wrp{ + justify-content: space-between; + } + } +} + +.action-wait-content { + display: flex; + flex-direction: row; + align-items: center; + gap: 5px; +} + +.action-wait-range { + color: var(--text-color); + font-size: 11px; + font-weight: 500; +} + +.action-wait-slider { + align-items: center; + background: var(--slider-background-color); + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 9px; + width: 100%; + text-align: center; + transition: width 0.3s ease-in; + font-size: 14px; + &.disabled { + opacity: 0.5; + } +} + +.action-wait-slider>mat-slider { + width: 100%; + margin-left: 6px; +} +.action-wait-slider.disabled { + opacity: 0.4; +} + +.action-wait-slider ::ng-deep{ + .mat-accent .mat-slider-track-fill { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label-text{ + color: var(--background-color) !important; + font-size: 10px !important; + } + .mat-slider-thumb { + background-color: var(--text-color) !important; + } + +} + +.gpt-setting-input { + color: var(--text-color); + text-align: center; + width: 45px; + border: none; + height: 26px; + border-radius: 12px; + background-color: white; + border: 1px solid var(--text-color); + + // Hide number input spinner arrows + /* Chrome, Safari, Edge, Opera */ + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + &[type=number] { + -moz-appearance: textfield; + appearance: textfield; + } +} + +.slider-input ::ng-deep { + width: 60px; + min-width: 60px; + font-size: 12px; + input { + text-align: center; + } +} + +// *********** AI SETTINGS --end *********** // + +.header-answer-preview { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + + .close-button { + cursor: pointer; + font-size: 18px; + font-weight: 600; + color: #ffffff80; + + &:hover { + color: white; + } + } + +} + +.link-container { + margin-bottom: 20px; + + a.link { + font-size: 14px; + font-weight: 400; + } + + a.link:hover { + cursor: pointer; + text-decoration: underline; + } + +} + +// PREVIEW SECTION --- start **************** // +.preview-container { + width: 100%; + max-height: 37px; + overflow: hidden; + transition: max-height 0.5s ease-out; + border-radius: var(--input-border-radius-base); + background-color: var(--color-white-hex); + padding: 6px 12px; + font-size: 14px; + border: 1px solid var(--blu-light-02); + color: var(--gray); +} + +.preview-container-extended { + max-height: 300px; + overflow-y: auto; +} + +.placeholder-container { + display: flex; + align-items: center; +} + +loading-spinner.custom-spinner ::ng-deep { + .sk-fading-circle { + width: 20px ; + height: 20px ; + margin: 0px ; + } + + .sk-fading-circle .sk-circle:before { + background-color: var(--blu) ; + } +} + +.label-and-button-container { + + width: 100%; + display: flex; + align-items: center; + margin-bottom: 6px; + + + .title-label { + margin-bottom: 0px; + } + +} + +.set-var-btn { + font-weight: 300 !important; + font-size: 12px !important; + height: 20px; + display: flex; + align-items: center; + padding: 6px 6px 6px 12px !important; + margin: 0px 0px 0px 6px !important; +} + +// .content#variables .opened { +// left: 0px; +// } + + + +.variables-content-header { + display: flex; + flex-direction: row; + align-items: center; + + .back-button { + cursor: pointer; + font-size: 20px; + font-weight: 600; + margin-right: 6px; + color: #ffffff80; + + &:hover { + color: white; + } + } + + .title-label { + font-size: 18px; + margin-bottom: 0px; + } +} + +.single-variable { + display: flex; + align-items: center; + margin: 14px 0px; + + .variable-name { + background-color: #ecb608; + color: white; + font-weight: 400; + padding: 6px 12px; + border-radius: 7px; + margin-right: 10px; + } + +} + +.usage-container { + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 6px; + padding: 0px 4px; + color: #a6a6a6; + font-size: 11px; + width: 100%; +} + + +.configure-model-button { + color: var(--blu); + text-align: right; + padding: 0 5px; + text-decoration: underline; + font-size: 13px; + cursor: pointer; + transition: opacity 0.2s ease; + &:hover { + opacity: 0.7; + } +} + + + +cds-select#model-condition.not-configured ::ng-deep { + .ng-select .ng-select-container { + border: 1px solid var(--empty-value-text-color); + } + .ng-select .ng-select-container .ng-value span.label-select{ + color: var(--empty-value-text-color); + } +} + + +.select-container { + &.not-configured { + ::ng-deep .ng-select .ng-select-container { + .ng-value { + span.label-select { + color: var(--empty-value-text-color); + } + } + } + ::ng-deep .text-editor-wrapper .text-editor .box-input input { + color: var(--empty-value-text-color)!important; + border: 1px solid var(--empty-value-text-color)!important; + } + } + .status-indicator { + width: 8px; + height: 8px; + background-color: var(--empty-value-text-color); + border-radius: 50%; + margin: 0px; + position: absolute; + left: 0px; + top: 96px; + } +} + +// Bottom row styles for model selection +.bottom-row { + display: flex; + align-items: center; + margin-top: 0px; + padding-left: 0px; + flex-direction: row-reverse; +} + +.multiplier-container { + color: var(--gray); + font-size: 12px; + display: inline-block; +} + +.configure-model-button { + cursor: pointer; + color: var(--blu-02); + font-size: 12px; + text-decoration: underline; + display: inline-block; + &:hover { + opacity: 0.7; + } +} + +// MCP TOOLS PREVIEW --- start **************** // +.mcp-tools-preview-container { + padding: 8px 0px; + margin-top: 8px; +} + +.mcp-tools-header { + font-size: 11px; + font-weight: 500; + color: var(--gray); + text-transform: uppercase; +} + +.mcp-tools-preview { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.mcp-tool-tag { + background-color: #e8f4ff; + color: var(--blu-02); + padding: 0px 6px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + font-family: var(--font-family-poppins); + white-space: nowrap; + display: inline-block; +} +// MCP TOOLS PREVIEW --- end **************** // + +// MCP SERVERS SECTION --- start **************** // +.mcp-servers-section { + margin-top: 20px; + margin-bottom: 10px; +} + +.mcp-servers-grid { + display: flex; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 10px; + margin-top: 10px; + flex-wrap: wrap; +} + +.mcp-server-button { + background-color: #ffffff; + border: 0px solid var(--blu-02); + border-radius: 4px; + padding: 0px 10px; + font-size: 12px; + font-family: var(--font-family-poppins); + color: var(--blu-02); + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + font-weight: 500; + position: relative; + + &:hover { + background-color: #e8f4ff; + border-color: var(--blu); + color: var(--blu); + } + + &.selected { + background-color: #e8f4ff; + border-color: var(--blu-02); + padding-right: 30px; + justify-content: flex-start; + cursor: default; + .remove-icon { + position: absolute; + right: 4px; + font-size: 18px; + color: #666; + cursor: pointer; + transition: all 0.2s ease; + border-radius: 50%; + padding: 2px; + &:hover { + background-color: rgba(255, 0, 0, 0.1); + color: #ff0000; + } + } + } + + &.add-tool-button { + background-color: white; + border: 2px dashed #d0d0d0; + color: #999; + font-weight: 400; + + &:hover { + background-color: #fafafa; + border-color: #b0b0b0; + color: #666; + } + } +} +// MCP SERVERS SECTION --- end **************** // + +// PREVIEW SECTION --- start **************** // \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.ts new file mode 100644 index 000000000..3859ec1bc --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.ts @@ -0,0 +1,754 @@ +import { Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { firstValueFrom, Observable, Subscription } from 'rxjs'; + +//MODELS +import { ActionAiPrompt } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; + +//SERVICES +import { OpenaiService } from 'src/app/services/openai.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { MatDialog } from '@angular/material/dialog'; +import { AppConfigService } from 'src/app/services/app-config'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; + +//UTILS +import { AttributesDialogAiPromptComponent } from './attributes-dialog/attributes-dialog.component'; +import { McpServersDialogComponent } from './mcp-servers-dialog/mcp-servers-dialog.component'; +import { DOCS_LINK, TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { PLAN_NAME } from 'src/chat21-core/utils/constants'; +import { TranslateService } from '@ngx-translate/core'; +import { loadTokenMultiplier } from 'src/app/utils/util'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { ANTHROPIC_MODEL, COHERE_MODEL, DEEPSEEK_MODEL, DEFAULT_MODEL, GOOGLE_MODEL, GROQ_MODEL, LLM_MODEL, OLLAMA_MODEL, OPENAI_MODEL, generateLlmModelsFlat } from 'src/app/chatbot-design-studio/utils-ai_models'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { ProjectService } from 'src/app/services/projects.service'; +import { sortAutocompleteOptions, getModelsByName, getIntegrations, setModel, initLLMModels, getIntegrationModels, LlmModel } from 'src/app/chatbot-design-studio/utils-llm-models'; +import { FormatNumberPipe } from 'src/app/pipe/format-number.pipe'; + +@Component({ + selector: 'cds-action-ai-prompt-new', + templateUrl: './cds-action-ai-prompt-new.component.html', + styleUrls: ['./cds-action-ai-prompt-new.component.scss'] +}) +export class CdsActionAiPromptNewComponent implements OnInit, OnChanges { + private readonly DEFAULT_MAX_TOKENS = 10000; + + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + + @Input() intentSelected: Intent; + @Input() action: ActionAiPrompt; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + panelOpenState = false; + llm_models: Array<{ name: string, value: string, src: string, models: Array<{ name: string, value: string, status: "active" | "inactive" }> }> = []; + llm_options_models: Array<{ name: string, value: string, status: "active" | "inactive" }> = []; + + ai_setting: { [key: string] : {name: string, min: number, max: number, step: number, disabled: boolean}} = { + "max_tokens": { name: "max_tokens", min: 10, max: 8192, step: 1, disabled: false}, + "temperature" : { name: "temperature", min: 0, max: 1, step: 0.05, disabled: false}, + } + + ai_response: string = ""; + ai_error: string = "Oops! Something went wrong. Check your GPT Key or retry in a few moment." + // ai_error: string = "Oops! Something went wrong." + + showPreview: boolean = false; + missingVariables: boolean = true; + showVariablesBtn: boolean = false; + showVariablesSection: boolean = false; + showAiError: boolean = false; + searching: boolean = false; + temp_variables = []; + actionLabelModel: string = ""; + selectedModelConfigured: boolean = true; + + + default_model = DEFAULT_MODEL; + llm_model = LLM_MODEL; + llm_models_flat: Array; + llm_model_selected: LlmModel = {} as LlmModel; + + private isInitializing = { + 'llm_model': true, + 'context': true, + 'question': true + }; + + + // Connectors + idIntentSelected: string = ''; + idConnectorTrue: string = ''; + idConnectorFalse: string = ''; + idConnectionTrue: string = ''; + idConnectionFalse: string = ''; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + projectPlan: PLAN_NAME; + PLAN_NAME = PLAN_NAME; + BRAND_BASE_INFO = BRAND_BASE_INFO; + DOCS_LINK = DOCS_LINK.GPT_TASK; + private readonly logger: LoggerService = LoggerInstance.getInstance(); + browserLang: string = 'it'; + + mcpServers: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }>, selectedTools?: Array<{ name: string }> }> = []; + selectedMcpServers: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }> }> = []; + + constructor( + private readonly dialog: MatDialog, + private readonly openaiService: OpenaiService, + private readonly intentService: IntentService, + private readonly appConfigService: AppConfigService, + private readonly translate: TranslateService, + private readonly dashboardService: DashboardService, + private readonly projectService: ProjectService, + private readonly formatNumberPipe: FormatNumberPipe + ) { } + + + async ngOnInit(): Promise { + // Locale for Angular number pipe (we only register 'it' explicitly; fallback to 'en') + const lang = this.translate.getBrowserLang() || 'en'; + this.browserLang = lang.startsWith('it') ? 'it' : 'en'; + this.logger.log("[ACTION AI_PROMPT] ngOnInit action: ", this.action); + + this.project_id = this.dashboardService.projectID; + // const ai_models = loadTokenMultiplier(this.appConfigService.getConfig().aiModels); + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'ollama'); + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'vllm'); + + this.llm_models = this.llm_model.filter(el => el.status === 'active'); + this.projectPlan = this.dashboardService.project.profile.name + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION AI_PROMPT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + this.initializeAttributes(); + if (!this.action.preview) { + this.action.preview = []; + } + // Initialize selected MCP servers from action + if (this.action['servers']) { + this.selectedMcpServers = this.action['servers']; + } + await this.initialize(); + + // Fine dell'inizializzazione - reset di tutti i flag + this.isInitializing = { + 'llm_model': false, + 'context': false, + 'question': false + }; + } + + + ngOnChanges(changes: SimpleChanges): void { + // Aggiorna selectedMcpServers quando cambia l'action (selezione di un blocco diverso) + if (changes['action'] && changes['action'].currentValue) { + const currentAction = changes['action'].currentValue as ActionAiPrompt; + if (currentAction['servers']) { + this.selectedMcpServers = currentAction['servers']; + this.logger.log("[ACTION AI_PROMPT] ngOnChanges - Updated selectedMcpServers from action: ", this.selectedMcpServers); + } else { + this.selectedMcpServers = []; + this.logger.log("[ACTION AI_PROMPT] ngOnChanges - Reset selectedMcpServers (no servers in action)"); + } + } + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + + private async initialize(){ + await this.initLLMModels(); + this.setModel(this.action.modelName ? this.action.modelName : this.default_model.name, { + resetMaxTokens: false, + resetTemperature: false + }); + this.logger.log("[ACTION AI_PROMPT] initialize llm_options_models: ", this.action); + } + + async getIntegrationByName(){ + const projectID = this.dashboardService.projectID; + const integrationName = 'ollama'; + try { + const response = await firstValueFrom(this.projectService.getIntegrationByName(projectID, integrationName)); + this.logger.log('[ACTION AI_PROMPT] - integration response:', response.value); + return response; + } catch (error) { + this.logger.log('[ACTION AI_PROMPT] getIntegrationByName ERROR:', error); + } + } + + + + async getIntegrations(){ + const projectID = this.dashboardService.projectID; + try { + const response = await firstValueFrom(this.projectService.getIntegrations(projectID)); + this.logger.log('[ACTION AI_PROMPT] - integrations response:', response.value); + return response; + } catch (error) { + this.logger.log('[ACTION AI_PROMPT] getIntegrations ERROR:', error); + } + } + + async initLLMModels(){ + const result = await initLLMModels({ + projectService: this.projectService, + dashboardService: this.dashboardService, + appConfigService: this.appConfigService, + logger: this.logger, + componentName: 'ACTION AI_PROMPT' + }); + + const INTEGRATIONS = await this.getIntegrations(); + this.logger.log('[ACTION AI_PROMPT] 1 - integrations:', INTEGRATIONS); + if(INTEGRATIONS){ + INTEGRATIONS.forEach((el: any) => { + this.logger.log('[ACTION AI_PROMPT] 1 - integration:', el.name, el.value.apikey); + if(el.name && el.name === 'mcp'){ + this.mcpServers = el.value.servers; + } + }); + } + + this.llm_models_flat = result; + } + + + + + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.logger.log('[ACTION AI_PROMPT] listOfIntents:', this.listOfIntents); + this.logger.log('[ACTION AI_PROMPT] idIntentSelected:', this.idIntentSelected); + this.logger.log('[ACTION AI_PROMPT] idConnectorTrue:', this.idConnectorTrue); + this.logger.log('[ACTION AI_PROMPT] idConnectorFalse:', this.idConnectorFalse); + this.checkConnectionStatus(); + + // this.logger.log('[ACTION AI_PROMPT] isConnectedFalse:', this.isConnectedFalse); + // this.logger.log('[ACTION AI_PROMPT] idConnectionTrue:', this.idConnectionTrue); + // this.logger.log('[ACTION AI_PROMPT] idConnectionFalse:', this.idConnectionFalse); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.logger.log('[ACTION AI_PROMPT] checkConnectionStatusOfAction:',this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION AI_PROMPT] resp:',resp); + } + + private updateConnector(){ + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION AI_PROMPT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'ai_reply')) { + new_attributes.push({ name: "ai_reply", value: "ai_reply" }); + } + variableList.find(el => el.key ==='userDefined').elements = [...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION AI_PROMPT] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + + onChangeTextarea(event: string, labelModel: string, property: string) { + this.logger.log("[ACTION AI_PROMPT] changeTextarea event: ", event, labelModel, property, this.isInitializing[property]); + // Ignora le chiamate durante l'inizializzazione per questa proprietà specifica + if (this.isInitializing[property]) { + this.isInitializing[property] = false; + return; + } + if(property === 'model'){ + this.action['labelModel'] = event; + } else if (property === 'question'){ + this.action['question'] = event; + } else if (property === 'context'){ + this.action['context'] = event; + } + } + + + setModel( + modelName: string, + options?: { resetMaxTokens?: boolean; resetTemperature?: boolean } + ) { + const { resetMaxTokens = true, resetTemperature = true } = options ?? {}; + const result = setModel(modelName, this.llm_models_flat, this.logger); + this.llm_model_selected = result ?? ({} as LlmModel); + this.logger.log("[ACTION AI_PROMPT] llm_model_selected: ", this.llm_model_selected); + this.action.llm = result?.llm ? result.llm : ''; + this.action.model = result?.model ? result.model : ''; + this.action.modelName = result?.modelName ? result.modelName : ''; + this.logger.log("[ACTION AI_PROMPT] action: ", this.action); + if (result) { + this.ai_setting['max_tokens'].max = result.max_output_tokens; + this.ai_setting['max_tokens'].min = result.min_tokens; + const min = this.ai_setting['max_tokens'].min; + const max = this.ai_setting['max_tokens'].max; + + // Init/detail-panel open: keep saved max_tokens, just clamp into model range. + // User-triggered model change: reset to default (capped by model max). + const currentMaxTokens = + typeof this.action?.max_tokens === 'number' ? this.action.max_tokens : Number(this.action?.max_tokens); + if (resetMaxTokens || !Number.isFinite(currentMaxTokens)) { + let next = Math.min(this.DEFAULT_MAX_TOKENS, max); + if (next < min) next = min; + this.action.max_tokens = next; + } else { + this.action.max_tokens = Math.min(Math.max(currentMaxTokens, min), max); + } + + const isGpt5 = modelName.startsWith('gpt-5') || modelName.startsWith('Gpt-5'); + if (isGpt5) { + this.ai_setting['temperature'].disabled = true; + const currentTemp = + typeof this.action?.temperature === 'number' ? this.action.temperature : Number(this.action?.temperature); + if (resetTemperature || !Number.isFinite(currentTemp)) { + this.action.temperature = 1; + } + } else { + this.ai_setting['temperature'].disabled = false; + } + } +} + + + onBlur(event: string){ + this.logger.log("[ACTION AI_PROMPT] onBlur event: ", event, this.action); + this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION AI_PROMPT] onEditableDivTextChange event", event) + this.logger.log("[ACTION AI_PROMPT] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit(); + } + + onChangeSelect(event, target) { + this.logger.log("[ACTION AI_PROMPT] onChangeSelect event: ", event) + this.logger.log("[ACTION AI_PROMPT] onChangeSelect target: ", target) + this.action[target] = event.value; + if (target === 'llm_model'){ + this.setModel(event.modelName, { resetMaxTokens: true, resetTemperature: true }); + } + this.updateAndSaveAction.emit(); + } + + updateSliderValue(event, target) { + this.logger.log("[ACTION AI_PROMPT] updateSliderValue event: ", event) + this.logger.log("[ACTION AI_PROMPT] updateSliderValue target: ", target) + this.action[target] = event; + if(target === 'max_tokens'){ + if(event < this.ai_setting['max_tokens'].min){ + this.action.max_tokens = this.ai_setting['max_tokens'].min; + } else if(event > this.ai_setting['max_tokens'].max){ + this.action.max_tokens = this.ai_setting['max_tokens'].max; + } else { + this.action.max_tokens = event; + } + } + this.updateAndSaveAction.emit(); + } + + onChangeCheckbox(event: MatCheckboxChange, target){ + try { + this.action[target] = event.checked; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("[ACTION AI_PROMPT] Error: ", error); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + scrollToBottom(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.log('[ACTION AI_PROMPT] scrollToBottom ERROR: ', error); + } + }, 300); + } + + execPreview() { + // this.scrollToBottom(); + this.checkVariables().then((resp) => { + if (resp === true) { + this.getResponse(this.action.question); + } else { + this.openAttributesDialog(); + } + }) + } + + checkVariables() { + return new Promise((resolve, reject) => { + let regex: RegExp = /{{[^{}]*}}/g; + let string = this.action.question; + let matches = string.match(regex); + let response: boolean = true; + if (!matches || matches.length == 0) { + resolve(true); + } else { + this.temp_variables = []; + matches.forEach((m) => { + let name = m.slice(2, m.length - 2); + let attr = this.action.preview.find(v => v.name === name); + if (attr?.value) { + this.temp_variables.push({ name: name, value: attr.value }); + } else if (attr && !attr.value) { + this.temp_variables.push({ name: name, value: null }); + } else { + this.temp_variables.push({ name: name, value: null }); + this.action.preview.push({ name: name, value: null }); + } + }) + resolve(false); + } + }) + } + + getResponse(question) { + this.logger.log("[ACTION AI_PROMPT] getResponse called...") + + let data = { + question: question, + context: this.action.context, + llm: this.action.llm, + model: this.action.model, + max_tokens: this.action.max_tokens, + temperature: this.action.temperature, + } + + this.showAiError = false; + this.searching = true; + this.showPreview = true; + + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.remove('preview-container-extended') + }, 200) + + this.openaiService.previewLLMPrompt(data).subscribe({ next: (ai_response: any) => { + this.searching = false; + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.ai_response = ai_response; + }, error: (err) => { + this.searching = false; + this.logger.error("[ACTION AI_PROMPT] previewPrompt error: ", err); + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.showAiError = true; + if(err.error.error_code === 13001){ + this.ai_error = this.translate.instant('CDSCanvas.AiQuotaExceeded') + return; + } + this.ai_error = this.translate.instant('CDSCanvas.AiError') + }, complete: () => { + this.logger.debug("[ACTION AI_PROMPT] preview prompt *COMPLETE*: "); + this.searching = false; + }}); + + } + + + getLlmIcon(llm: string): string { + this.logger.log("[ACTION AI_PROMPT] getLlmIcon ******: ", llm); + const filteredModel = this.llm_models.find((model) => model.value === llm); + this.logger.log("[ACTION AI_PROMPT] filteredModel ******: ", filteredModel); + return filteredModel ? filteredModel.value : ''; + } + + + // getResponsePreview() { + + // this.showPreview = true; + // this.showAiError = false; + + // this.checkVariables().then((resp) => { + + // if (resp === false) { + // this.missingVariables = true; + + // } else { + // let temp_question = this.action.question; + // this.temp_variables.forEach((tv) => { + // let old_value = "{{" + tv.name + "}}"; + // temp_question = temp_question.replace(old_value, tv.value); + // }) + + // this.searching = true; + // this.missingVariables = false; + + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.remove('preview-container-extended') + // }, 200) + + // let data = { + // question: temp_question, + // context: this.action.context, + // model: this.action.model, + // max_tokens: this.action.max_tokens, + // temperature: this.action.temperature + // } + + // this.openaiService.previewPrompt(data).subscribe((ai_response: any) => { + // this.searching = false; + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.add('preview-container-extended') + // }, 200) + // this.ai_response = ai_response; + // }, (error) => { + // this.logger.error("[ACTION GPT-TASK] previewPrompt error: ", error); + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.add('preview-container-extended') + // }, 200) + // this.showAiError = true; + // this.searching = false; + // }, () => { + // this.logger.error("[ACTION GPT-TASK] preview prompt *COMPLETE*: "); + // this.searching = false; + // }) + // } + // }) + // } + + // _checkVariables() { + // return new Promise((resolve, reject) => { + // let regex: RegExp = /{{[^{}]*}}/g; + // let string = this.action.question; + // let matches = string.match(regex); + // let response: boolean = true; + + // if (!matches || matches.length == 0) { + // this.showVariablesBtn = false; + // resolve(response); + // } + + // if (matches.length > 0) { + // if (!this.action.preview) { + // this.action.preview = []; + // } + // this.showVariablesBtn = true; + // this.temp_variables = []; + + // matches.forEach((m) => { + // let name = m.slice(2, m.length - 2); + // let attr = this.action.preview.find(v => v.name === name); + // if (attr && attr.value) { + // this.temp_variables.push({ name: name, value: attr.value }); + // } else if (attr && !attr.value) { + // response = false; + // this.temp_variables.push({ name: name, value: null }); + // } else { + // response = false; + // this.temp_variables.push({ name: name, value: null }); + // this.action.preview.push({ name: name, value: null }); + // } + // }) + // this.logger.log("temp_variables: ", this.temp_variables) + // resolve(response); + // } + + // }) + // } + + // showHideVariablesSection() { + // this.showVariablesSection = !this.showVariablesSection; + // if (this.showVariablesSection == false) { + // this.getResponsePreview(); + // } + // } + + // onChangeVar(event, name) { + // let index = this.action.preview.findIndex(v => v.name === name); + // if (index != -1) { + // this.action.preview[index].value = event; + // } + // this.updateAndSaveAction.emit(); + // } + + // closePreview() { + // let element = document.getElementById("preview-container"); + // element.classList.remove('preview-container-extended') + + // this.showPreview = false; + // this.searching = false; + // } + + openAttributesDialog() { + this.logger.log("[ACTION AI_PROMPT] temp_variables: ", this.temp_variables); + const dialogRef = this.dialog.open(AttributesDialogAiPromptComponent, { + panelClass: 'custom-setattribute-dialog-container', + data: { attributes: this.temp_variables, question: this.action.question } + }); + dialogRef.afterClosed().subscribe(result => { + this.logger.log("[ACTION AI_PROMPT] AttributesDialogComponent result: ", result); + if (result !== false) { + this.getResponse(result.question); + this.saveAttributes(result.attributes); + } + }); + } + + openMcpServersDialog() { + this.logger.log("[ACTION AI_PROMPT] mcpServers: ", this.mcpServers); + this.logger.log("[ACTION AI_PROMPT] selectedMcpServers: ", this.selectedMcpServers); + + const dialogRef = this.dialog.open(McpServersDialogComponent, { + panelClass: 'custom-mcp-dialog-container', + data: { + mcpServers: this.mcpServers, + selectedServers: this.selectedMcpServers, + onUpdate: (updateData: any) => { + this.handleMcpServersUpdate(updateData); + } + } + }); + // No need to handle afterClosed since updates are real-time via callback + dialogRef.afterClosed().subscribe(() => { + this.logger.log("[ACTION AI_PROMPT] McpServersDialogComponent closed"); + }); + } + + handleMcpServersUpdate(updateData: any): void { + this.logger.log("[ACTION AI_PROMPT] Real-time update from dialog:", updateData); + + // Update the list of selected servers + this.selectedMcpServers = updateData.selectedServers.length > 0 ? [...updateData.selectedServers] : []; + + // Update the main server list with any modifications + if (updateData.allServers) { + this.mcpServers = [...updateData.allServers]; + } + + // Save selected servers to action + this.action['servers'] = this.selectedMcpServers; + this.logger.log("[ACTION AI_PROMPT] Real-time updated selected MCP servers: ", this.selectedMcpServers); + this.logger.log("[ACTION AI_PROMPT] Real-time updated all MCP servers: ", this.mcpServers); + + this.updateAndSaveAction.emit(); + } + + removeSelectedServer(server: { name: string, url: string, transport: string }, event: Event) { + event.stopPropagation(); + const index = this.selectedMcpServers.findIndex(s => s.name === server.name); + if (index > -1) { + this.selectedMcpServers.splice(index, 1); + // Update action + this.action['servers'] = this.selectedMcpServers; + this.logger.log("[ACTION AI_PROMPT] Removed server, updated list: ", this.selectedMcpServers); + + this.updateAndSaveAction.emit(); + } + } + + saveAttributes(attributes) { + this.logger.log("[ACTION AI_PROMPT] attributes: ", attributes); + attributes.forEach(a => { + let index = this.action.preview.findIndex(v => v.name === a.name) + if (index != -1) { + this.action.preview[index].value = a.value; + } else { + this.action.preview.push({ name: a.name, value: a.value }) + } + this.updateAndSaveAction.emit(); + }) + } + + goToIntegrations(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations' + window.open(url, '_blank') + } + + /** + * Formats the slider thumb label value with "k" notation for values > 999 + * Uses the FormatNumberPipe for consistent formatting across the app + * @param value - The numeric value to format + * @returns Formatted string with "k" for values > 999 (rounded to integers) + */ + formatSliderLabel = (value: number): string => { + return this.formatNumberPipe.transform(value); + } + +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt.component.spec.ts new file mode 100644 index 000000000..366e0ee5c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAiPromptComponent } from './cds-action-ai-prompt.component'; + +describe('CdsActionAiPromptComponent', () => { + let component: CdsActionAiPromptComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAiPromptComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAiPromptComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.html new file mode 100644 index 000000000..4b64b96b9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.html @@ -0,0 +1,150 @@ +
+ +
+
+
+ {{'CDSCanvas.Saving' | translate}}... +
+
+ +
+
+ {{ isNewServer ? ('CDSCanvas.AddMCPServer' | translate) : ('CDSCanvas.EditMCPServer' | translate) }} +
+ close +
+ + + +
+ +
+ error_outline + {{ errorMessage }} + close +
+ +
+ +
+ + + +
+ + +
+ + + +
+ + +
+ +
+ {{ editedServer.transport }} +
+ {{'CDSCanvas.OnlySupported' | translate}} +
+ + +
+ + + +
+ + {{'CDSCanvas.ToolsSelected' | translate}}: {{ selectedToolsCount }} / {{ totalToolsCount }} + + +
+ + +
+
+
+ +
+ + + + + + + +
+
+ + +
+
+ +
+
+
+
+ {{'CDSCanvas.AvailableTools' | translate}} ({{ totalToolsCount }}) +
+
+ {{'CDSCanvas.ToolsSelected' | translate}}: {{ selectedToolsCount }} / {{ totalToolsCount }} +
+
+ +
+ +
+ +
+ {{ tool.name }} + {{ tool.title }} + + {{ tool.description }} + +
+
+
+
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss new file mode 100644 index 000000000..7a0044449 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss @@ -0,0 +1,390 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/styles.scss"; + +::ng-deep .custom-mcp-edit-dialog-container { + width: 35vw!important; + min-width: 450px; + max-width: 600px!important; + max-height: 80vh; + + .tpl-modal-box { + border-radius: 6px; + display: flex; + flex-direction: column; + background: rgb(255, 255, 255); + max-height: 80vh; + position: relative; + } + + .tpl-modal-header { + align-items: flex-start; + align-items: center; + display: flex; + flex-shrink: 0; + justify-content: center; + width: 100%; + padding: 20px 20px 10px 20px; + + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + transition: opacity 0.2s; + + &:hover { + opacity: 0.7; + } + } + } + + .tpl-modal-header-text { + flex-grow: 1; + text-align: center; + width: 0; + + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 16px; + } + } + + .tpl-modal-content { + flex-grow: 1; + padding: 20px; + width: 100%; + overflow-y: auto; + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: flex-end; + padding: 15px 20px; + color: #333; + gap: 10px; + border-top: 1px solid #e5e5e5; + } +} + +.edit-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +.form-field { + display: flex; + flex-direction: column; + gap: 8px; +} + +.field-label { + font-size: 14px; + font-weight: 500; + color: #333; + margin: 0; +} + +.readonly-field { + padding: 10px 12px; + background-color: #f5f5f5; + border: 1px solid #d0d0d0; + border-radius: 6px; + color: #666; + font-size: 14px; + font-family: var(--font-family-poppins); +} + +.field-hint { + font-size: 12px; + color: #999; + font-style: italic; + margin-top: 4px; + display: block; +} + +/* ---- MCP Tools UI (moved from inline styles) ---- */ +.tools-header-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-top: 4px; +} + +.tools-select-btn { + padding: 6px 10px; + font-size: 12px; + background: var(--blu) !important; + color: #fff !important; + border-color: var(--blu) !important; + + &:hover:enabled { + opacity: 0.9; + } +} + +.btn-inline-spinner { + display: flex; + align-items: center; + gap: 8px; +} + +.tools-modal { + position: fixed; + inset: 0; + z-index: 2000; +} + +.tools-modal__backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.35); +} + +.tools-modal__panel { + position: relative; + margin: 6vh auto; + width: min(820px, 92vw); + max-height: 88vh; + background: #fff; + border-radius: 10px; + padding: 16px; + overflow: hidden; +} + +.tools-modal__header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.tools-modal__header-left { + display: flex; + flex-direction: column; + gap: 2px; +} + +.tools-modal__title { + font-weight: 700; +} + +.tools-modal__subtitle { + color: #6b7280; + font-size: 12px; +} + +.tools-modal__list { + margin-top: 12px; + overflow: auto; + max-height: calc(88vh - 92px); + padding-right: 6px; + overflow-x: hidden; + + /* Custom scrollbar styles (aligned with .custom-mcp-dialog-container .tpl-modal-content) */ + &::-webkit-scrollbar { + width: 8px; + } + + &::-webkit-scrollbar-track { + background: transparent; + border-radius: 4px; + } + + &::-webkit-scrollbar-thumb { + background: var(--blu-02); + border-radius: 4px; + + &:hover { + background: var(--blu); + } + } + + /* Firefox */ + scrollbar-width: thin; + scrollbar-color: var(--blu-02) transparent; +} + +::ng-deep .custom-mcp-edit-dialog-container .tools-modal__item { + display: block; + padding: 10px 0; + border-bottom: 1px solid #f1f5f9; +} + +.tools-modal__item-content { + display: flex; + flex-direction: column; +} + +.tools-modal__item-name { + font-weight: 700; +} + +.tools-modal__item-title { + color: #111827; + margin-top: 2px; +} + +.tools-modal__item-description { + color: #6b7280; + white-space: normal; + overflow-wrap: anywhere; + word-break: break-word; +} + +/* Ensure no horizontal scrollbar is introduced by long tokens */ +.tools-modal__panel, +.tools-modal__list, +.tools-modal__item-content { + overflow-x: hidden; +} + +/** + * Remove ANY background/ripple effect for checkboxes in Available tools list + * (hover, focus, active, etc.) + */ +::ng-deep .custom-mcp-edit-dialog-container .tools-modal__list .mat-checkbox-ripple, +::ng-deep .custom-mcp-edit-dialog-container .tools-modal__list .mat-checkbox-persistent-ripple, +::ng-deep .custom-mcp-edit-dialog-container .tools-modal__list .mat-ripple-element { + display: none !important; + background: transparent !important; +} + +/** + * Angular Material: remove background on hover for persistent ripple + * (requested: .mat-checkbox-persistent-ripple must NOT show background color on hover) + * Keep scope local to this dialog to avoid global regressions. + */ +::ng-deep .custom-mcp-edit-dialog-container mat-checkbox .mat-checkbox-persistent-ripple, +::ng-deep .custom-mcp-edit-dialog-container mat-checkbox:hover .mat-checkbox-persistent-ripple, +::ng-deep .custom-mcp-edit-dialog-container mat-checkbox.cdk-focused .mat-checkbox-persistent-ripple, +::ng-deep .custom-mcp-edit-dialog-container mat-checkbox:focus .mat-checkbox-persistent-ripple { + background-color: transparent !important; +} + +#cds-save-btn:hover:enabled { + opacity: .8 !important; +} + +#cds-save-btn:disabled { + opacity: 0.5; + cursor: default; +} + +#cds-cancel-btn { + background: #e5e5e5; + color: #4b5052; + + &:hover { + opacity: 0.8; + } +} + +.spinner { + width: 14px; + height: 14px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-top-color: white; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.loading-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.95); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + border-radius: 6px; +} + +.loading-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; +} + +.spinner-large { + width: 48px; + height: 48px; + border: 4px solid rgba(0, 108, 255, 0.2); + border-top-color: #006cff; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +.loading-text { + font-size: 16px; + font-weight: 500; + color: #006cff; +} + +.error-alert { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 12px 16px; + background-color: #fee; + border: 1px solid #fcc; + border-radius: 6px; + margin-bottom: 16px; + animation: slideDown 0.3s ease; + + .error-icon { + color: #d32f2f; + font-size: 24px; + flex-shrink: 0; + } + + .error-text { + color: #d32f2f; + font-size: 14px; + line-height: 1.5; + flex: 1; + } + + .close-error { + color: #d32f2f; + font-size: 20px; + cursor: pointer; + flex-shrink: 0; + transition: opacity 0.2s; + + &:hover { + opacity: 0.7; + } + } +} + +@keyframes slideDown { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.ts new file mode 100644 index 000000000..65a94ae67 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.ts @@ -0,0 +1,496 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { ProjectService } from 'src/app/services/projects.service'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { firstValueFrom } from 'rxjs'; + +interface McpTool { + name: string; + title?: string; + description?: string; +} + +interface McpServer { + name: string; + url: string; + transport: string; + /** Available tools (from Connect / integrations). Persisted on Save. */ + tools?: McpTool[]; + /** Selected tools for this server. Persisted in integration so selection is kept even when server is not selected. */ + selectedTools?: Array<{ name: string }>; +} + +interface McpIntegration { + id_project: string; + name: string; + value: { + servers: McpServer[]; + }; +} + + +@Component({ + selector: 'appdashboard-mcp-server-edit-dialog-new', + templateUrl: './mcp-server-edit-dialog-new.component.html', + styleUrls: ['./mcp-server-edit-dialog-new.component.scss'] +}) +export class McpServerEditDialogComponent implements OnInit { + + editedServer: McpServer; + originalServer: McpServer; + project_id: string; + isSaving: boolean = false; + showLoader: boolean = false; + allMcpServers: McpServer[] = []; + isNewServer: boolean = false; + errorMessage: string = ''; + showError: boolean = false; + + // --- Tools selection (per-server, per-action) --- + availableTools: McpTool[] = []; + private selectedToolNames: Set = new Set(); + isToolsModalOpen: boolean = false; + + // --- Tools discovery state (Connect -> fetch tools, Save -> persist integration) --- + isLoadingTools: boolean = false; + /** + * When true, tools have been successfully retrieved (or already exist on the server object). + * Save must stay hidden/disabled until this becomes true. + */ + toolsLoaded: boolean = false; + + /** + * EDIT MODE UX RULE: + * - Save is always visible but disabled until the user makes changes (dirty) + * - If URL is modified, Save must be hidden and Connect shown + * - After a successful Connect, Save becomes visible again + */ + urlChangedSinceLastConnect: boolean = false; + + private originalSnapshot: { name: string; url: string; transport: string } | null = null; + private originalSelectedToolsSnapshot: Set = new Set(); + /** Snapshot of available tool names when dialog opened (or after first load). Used to detect changes after Refresh. */ + private originalAvailableToolNames: Set = new Set(); + /** True when Refresh returned a different list of tools than the original, so Save should be enabled. */ + private availableToolsChangedAfterRefresh: boolean = false; + private lastUrlBlurValue: string = ''; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public dialogRef: MatDialogRef, + private projectService: ProjectService, + private dashboardService: DashboardService, + @Inject(MAT_DIALOG_DATA) public data: { + server?: McpServer; + allServers: McpServer[]; + isNew?: boolean; + /** + * Selected tools for THIS server in the action config (only {name} is allowed). + * Used to keep state when reopening the dialog. + */ + selectedTools?: Array<{ name: string }>; + } + ) { } + + ngOnInit(): void { + this.logger.debug("[McpServerEditDialog] data: ", this.data); + + // Check if we're creating a new server + this.isNewServer = this.data.isNew || false; + + if (this.isNewServer) { + // Initialize empty server for creation + this.editedServer = { + name: '', + url: '', + transport: 'streamable_http' // Default value + }; + this.originalServer = null; + } else { + // Create a copy of the server to edit + this.originalServer = this.data.server; + this.editedServer = { ...this.data.server }; + this.originalSnapshot = { + name: this.data.server?.name || '', + url: this.data.server?.url || '', + transport: this.data.server?.transport || '' + }; + } + + // Store all servers + this.allMcpServers = [...this.data.allServers]; + // Get project ID + this.project_id = this.dashboardService.projectID; + + // Tools: initialize selection and load available tools for the selected server + this.selectedToolNames = new Set((this.data.selectedTools || []).map(t => t?.name).filter(Boolean) as string[]); + this.originalSelectedToolsSnapshot = new Set(Array.from(this.selectedToolNames)); + this.refreshAvailableTools(); + this.toolsLoaded = Array.isArray(this.availableTools) && this.availableTools.length > 0; + this.originalAvailableToolNames = new Set((this.availableTools || []).map(t => t.name)); + this.urlChangedSinceLastConnect = false; + this.lastUrlBlurValue = (this.editedServer?.url || '').trim(); + + this.logger.log("[McpServerEditDialog] toolsLoaded:", this.toolsLoaded); + } + + onCloseDialog(): void { + this.logger.log("[McpServerEditDialog] - modal CLOSED"); + this.dialogRef.close(false); + } + + onChangeField(value: string, field: 'name' | 'url' | 'transport'): void { + // Guard: some inputs can emit "change" also during initialization with the same value. + // We must avoid triggering state transitions (especially URL -> Connect) if nothing really changed. + const prevValue = this.editedServer[field]; + if (prevValue === value) { + return; + } + + this.editedServer[field] = value; + this.logger.debug(`[McpServerEditDialog] Changed ${field}:`, value); + if (field === 'name') { + // If the user renames the server, the available tools could change (depending on integrations). + // Keep this as a safe refresh: tools are optional anyway. + this.refreshAvailableTools(); + } + if (field === 'url') { + // As soon as URL is modified: hide Save and show Connect (no need to wait for blur). + const current = (this.editedServer.url || '').trim(); + this.urlChangedSinceLastConnect = this.isNewServer ? true : (current !== ((this.originalSnapshot?.url || '').trim())); + } + } + + /** + * URL verification must happen on blur (not on change). + * If the URL really changed, we reset tools and show Connect (edit mode). + */ + onUrlBlur(): void { + const current = (this.editedServer?.url || '').trim(); + if (current === this.lastUrlBlurValue) { + return; + } + this.lastUrlBlurValue = current; + + // Reset tool selection + loaded tools only when URL changed. + this.selectedToolNames.clear(); + this.isToolsModalOpen = false; + this.toolsLoaded = false; + this.availableTools = []; + this.editedServer.tools = []; + + // In edit mode, show Connect only if URL differs from original. + // In add mode, Connect is the discovery step. + this.urlChangedSinceLastConnect = this.isNewServer ? true : (current !== ((this.originalSnapshot?.url || '').trim())); + } + + private refreshAvailableTools(): void { + // Prefer tools from the server currently being edited (after Connect/Refresh). + if (Array.isArray(this.editedServer?.tools)) { + this.availableTools = [...this.editedServer.tools].sort((a, b) => a.name.localeCompare(b.name)); + } else { + const serverName = this.isNewServer ? this.editedServer?.name : this.originalServer?.name; + if (!serverName) { + this.availableTools = []; + return; + } + const found = this.allMcpServers.find(s => s.name === serverName); + const tools = Array.isArray(found?.tools) ? found.tools : []; + this.availableTools = [...tools].sort((a, b) => a.name.localeCompare(b.name)); + } + + // Keep selection consistent: drop selected tools that are no longer available (avoid stale names). + if (this.availableTools.length > 0) { + const availableNames = new Set(this.availableTools.map(t => t.name)); + for (const name of Array.from(this.selectedToolNames)) { + if (!availableNames.has(name)) { + this.selectedToolNames.delete(name); + } + } + } + } + + get totalToolsCount(): number { + return this.availableTools?.length || 0; + } + + get selectedToolsCount(): number { + return this.selectedToolNames.size; + } + + isToolSelected(name: string): boolean { + return this.selectedToolNames.has(name); + } + + onToggleTool(name: string, checked: boolean): void { + if (!name) return; + if (checked) { + this.selectedToolNames.add(name); + } else { + this.selectedToolNames.delete(name); + } + } + + private areSetsEqual(a: Set, b: Set): boolean { + if (a.size !== b.size) return false; + for (const v of a) { + if (!b.has(v)) return false; + } + return true; + } + + /** + * Dirty state (edit mode): + * Save becomes enabled if the user changed name/transport, selected tools, or if Refresh returned a different tool list. + * NOTE: URL changes are handled separately (Save hidden -> Connect) and do NOT enable Save by themselves. + */ + get isDirty(): boolean { + if (this.isNewServer) { + // In create mode, "dirty" is not used to gate Save; Connect gates it. + return false; + } + const snap = this.originalSnapshot; + if (!snap) return false; + + const nameChanged = (this.editedServer?.name || '') !== snap.name; + const transportChanged = (this.editedServer?.transport || '') !== snap.transport; + const toolsSelectionChanged = !this.areSetsEqual(this.selectedToolNames, this.originalSelectedToolsSnapshot); + return nameChanged || transportChanged || toolsSelectionChanged || this.availableToolsChangedAfterRefresh; + } + + get showConnectButton(): boolean { + // Connect / Refresh button always visible (Connect when no tools, Refresh tools when loaded). + return true; + } + + get showSaveButton(): boolean { + // In Add: Save is shown only after tools are loaded via Connect. + if (this.isNewServer) return this.toolsLoaded; + // In Edit: Save is visible except when URL has been modified (then Connect must happen first). + return !this.urlChangedSinceLastConnect; + } + + get isSaveDisabled(): boolean { + if (this.isSaving || this.isLoadingTools) return true; + if (!this.isFormValid()) return true; + // Add mode: Save enabled only after Connect (tools loaded). + if (this.isNewServer) return !this.toolsLoaded; + // Edit mode: enable Save whenever any value except URL was modified (dirty). + return !this.isDirty; + } + + openToolsModal(): void { + this.isToolsModalOpen = true; + } + + closeToolsModal(): void { + this.isToolsModalOpen = false; + } + + get connectButtonLabelKey(): string { + return this.toolsLoaded ? 'CDSCanvas.RefreshTools' : 'CDSCanvas.Connect'; + } + + async onConnect(): Promise { + if (!this.isFormValid()) { + this.showError = true; + this.errorMessage = "Please fill Name and URL before connecting."; + return; + } + if (this.isLoadingTools) return; + + this.showError = false; + this.errorMessage = ''; + this.isLoadingTools = true; + this.toolsLoaded = false; + this.isToolsModalOpen = false; + + try { + const res = await firstValueFrom(this.projectService.getMcpTools(this.project_id, this.editedServer.url)); + const rawTools = Array.isArray(res) ? res : (Array.isArray(res?.tools) ? res.tools : []); + + const tools: McpTool[] = (rawTools || []) + .filter((t: any) => t && typeof t.name === 'string' && t.name.trim().length > 0) + .map((t: any) => ({ + name: String(t.name), + title: t.title ? String(t.title) : undefined, + description: t.description ? String(t.description) : undefined + })); + + if (!tools || tools.length === 0) { + this.showError = true; + this.errorMessage = "No tools returned by the server."; + this.isLoadingTools = false; + return; + } + + /** + * Requirement: persist tools on the MCP server object (in-memory now, persisted on Save). + * Also keep selection consistent if refreshing: keep only still-available tools selected. + */ + this.editedServer.tools = tools; + this.refreshAvailableTools(); + this.toolsLoaded = true; + this.urlChangedSinceLastConnect = false; + this.lastUrlBlurValue = (this.editedServer?.url || '').trim(); + + // If the list of available tools changed after Refresh, enable Save so user can persist it. + const newToolNames = new Set(this.availableTools.map(t => t.name)); + this.availableToolsChangedAfterRefresh = !this.areSetsEqual(newToolNames, this.originalAvailableToolNames); + + // Ensure selected tools are subset of available tools (refresh scenario). + const availableNames = new Set(this.availableTools.map(t => t.name)); + for (const name of Array.from(this.selectedToolNames)) { + if (!availableNames.has(name)) { + this.selectedToolNames.delete(name); + } + } + } catch (error) { + this.logger.error("[McpServerEditDialog] Error fetching MCP tools:", error); + this.showError = true; + this.errorMessage = "Error while loading tools. Please check the URL and try again."; + } finally { + this.isLoadingTools = false; + } + } + + private buildSelectedToolsPayload(): Array<{ name: string }> { + // Save ONLY {name}. No duplicates thanks to Set. + return Array.from(this.selectedToolNames) + .filter(Boolean) + .map(name => ({ name })); + } + + isFormValid(): boolean { + return !!(this.editedServer.name && + this.editedServer.url && + this.editedServer.transport); + } + + async onSave(): Promise { + if (!this.isFormValid()) { + this.logger.warn("[McpServerEditDialog] Form is not valid"); + return; + } + + if (this.isSaving) { + return; // Prevent double submission + } + + // Reset error state + this.showError = false; + this.errorMessage = ''; + this.isSaving = true; + this.showLoader = false; + this.logger.log("[McpServerEditDialog] Saving server:", this.editedServer); + + // Set a timer to show loader after 500ms if still saving + const loaderTimer = setTimeout(() => { + if (this.isSaving) { + this.showLoader = true; + } + }, 500); + + try { + const selectedTools = this.buildSelectedToolsPayload(); + // Persist total available tools count from last Connect/Refresh so list dialog can show correct "X available". + const availableToolsCount = this.availableTools?.length ?? 0; + const serverToSave = { + ...this.editedServer, + tools: selectedTools, + availableToolsCount + }; + + if (this.isNewServer) { + // Check if server name already exists + const nameExists = this.allMcpServers.some(s => s.name === this.editedServer.name); + if (nameExists) { + this.logger.warn("[McpServerEditDialog] Server name already exists"); + this.errorMessage = "A server with this name already exists"; + this.showError = true; + this.isSaving = false; + clearTimeout(loaderTimer); + return; + } + // Add new server to the array (include tools + selectedTools for persistence) + this.allMcpServers.push({ + ...this.editedServer, + tools: this.editedServer.tools, + selectedTools: this.buildSelectedToolsPayload() + }); + } else { + // Find and update the server in the array (include tools + selectedTools for persistence) + const serverIndex = this.allMcpServers.findIndex(s => s.name === this.originalServer.name); + if (serverIndex > -1) { + this.allMcpServers[serverIndex] = { + ...this.editedServer, + tools: this.editedServer.tools, + selectedTools: this.buildSelectedToolsPayload() + }; + } + } + + // Prepare the integration object + const mcpIntegration: McpIntegration = { + id_project: this.project_id, + name: "mcp", + value: { + servers: this.allMcpServers + } + }; + + this.logger.log("[McpServerEditDialog] Saving integration:", mcpIntegration); + + // Call service to save the entire MCP integration + const response = await firstValueFrom( + this.projectService.saveIntegration(this.project_id, mcpIntegration) + ); + + this.logger.log("[McpServerEditDialog] Integration saved successfully:", response); + + // Clear the loader timer and hide states + clearTimeout(loaderTimer); + this.isSaving = false; + this.showLoader = false; + + // Close with the edited data (server includes tools + selectedTools so list dialog can show and persist them) + const selectedToolsPayload = this.buildSelectedToolsPayload(); + this.dialogRef.close({ + server: { + ...this.editedServer, + tools: this.editedServer.tools, + selectedTools: selectedToolsPayload + }, + selectedTools: selectedToolsPayload + }); + } catch (error) { + this.logger.error("[McpServerEditDialog] Error saving integration:", error); + clearTimeout(loaderTimer); + this.isSaving = false; + this.showLoader = false; + + // Show error message to user + this.showError = true; + + // Extract error message with different fallback strategies + if (error?.error?.message) { + this.errorMessage = error.error.message; + } else if (error?.message) { + this.errorMessage = error.message; + } else if (error?.error?.error) { + this.errorMessage = error.error.error; + } else if (typeof error === 'string') { + this.errorMessage = error; + } else { + this.errorMessage = "An error occurred while saving the server. Please try again."; + } + + this.logger.log("[McpServerEditDialog] Error message displayed:", this.errorMessage); + } + } + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.spec.ts new file mode 100644 index 000000000..9f4c9e43c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.spec.ts @@ -0,0 +1,26 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { McpServerEditDialogComponent } from './mcp-server-edit-dialog.component'; + +describe('McpServerEditDialogComponent', () => { + let component: McpServerEditDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ McpServerEditDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(McpServerEditDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.html new file mode 100644 index 000000000..728a6e863 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.html @@ -0,0 +1,92 @@ +
+
+
+ {{'CDSCanvas.ChooseToolOrAddMCPServer' | translate}} +
+ close +
+ +
+ + +
+
+ {{'CDSCanvas.TotalMCPServers' | translate}}: {{ filteredServers.length }} +
+
+ + search +
+
+ +
+
+
+ cloud_off +

{{'CDSCanvas.NoMCPServerConfigured' | translate}}

+
+ +
+ search_off +

{{'CDSCanvas.NoServersMatchSearch' | translate}}

+
+ +
+ +
+ +
+
+ +
+ + +
+
+ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss new file mode 100644 index 000000000..314d196fd --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss @@ -0,0 +1,363 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/styles.scss"; + +::ng-deep .custom-mcp-dialog-container { + width: 40vw!important; + min-width: 500px; + max-width: 700px!important; + max-height: 80vh; + + .mat-dialog-container { + padding: 0px 10px; + } + + .tpl-modal-box { + border-radius: 6px; + display: flex; + flex-direction: column; + background: rgb(255, 255, 255); + max-height: 80vh; + min-height: 335px; + height: 80vh; + } + + .tpl-modal-header { + align-items: flex-start; + align-items: center; + display: flex; + flex-shrink: 0; + justify-content: center; + width: 100%; + padding: 20px 20px 10px 20px; + + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + transition: opacity 0.2s; + + &:hover { + opacity: 0.7; + } + } + } + + .tpl-modal-header-text { + flex-grow: 1; + text-align: center; + width: 0; + + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 16px; + } + } + + .search-section { + padding: 15px 20px; + // border-bottom: 1px solid #e5e5e5; + // background-color: #fafafa; + flex-shrink: 0; + } + + .tpl-modal-content { + flex-grow: 1; + padding: 0 20px 20px 20px; + width: 100%; + overflow-y: auto; + height: calc(100% - 400px); + border: none; + + // Custom scrollbar styles + &::-webkit-scrollbar { + width: 8px; + } + + &::-webkit-scrollbar-track { + background: transparent; + border-radius: 4px; + } + + &::-webkit-scrollbar-thumb { + background: var(--blu-02); + border-radius: 4px; + + &:hover { + background: var(--blu); + } + } + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: space-between; + padding: 15px 20px; + color: #333; + gap: 10px; + border-top: 1px solid #e5e5e5; + } +} + +.server-count { + font-size: 14px; + font-weight: 500; + color: #333; + margin-bottom: 10px; + + .count-number { + color: var(--blu-02); + font-weight: 600; + } +} + +.search-input-wrapper { + position: relative; + display: flex; + align-items: center; +} + +.search-input { + width: 100%; + padding: 10px 40px 10px 12px; + border: 1px solid #d0d0d0; + border-radius: 6px; + font-size: 14px; + font-family: var(--font-family-poppins); + outline: none; + transition: all 0.2s ease; + + &:focus { + border-color: var(--blu-02); + box-shadow: 0 0 0 3px rgba(0, 108, 255, 0.1); + } + + &::placeholder { + color: #999; + } +} + +.search-icon { + position: absolute; + right: 12px; + color: #999; + font-size: 20px; + pointer-events: none; +} + +.mcp-servers-list { + display: flex; + flex-direction: column; + gap: 4px; +} + +.mcp-server-item-wrapper { + position: relative; + display: flex; + align-items: center; + gap: 4px; + width: 100%; +} + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 20px; + text-align: center; + color: #999; + + .empty-icon { + font-size: 48px; + margin-bottom: 12px; + opacity: 0.5; + } + + .empty-message { + font-size: 14px; + margin: 0; + } +} + +.mcp-server-item { + background-color: #ffffff; + border: 2px solid var(--blu-light-01); + border-radius: 8px; + padding: 8px 12px; + font-size: 14px; + font-family: var(--font-family-poppins); + cursor: pointer; + transition: all 0.2s ease; + text-align: left; + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + flex: 1; + width: 100%; + min-height: 50px; + + &:hover { + background-color: var(--blu-light-01); + border-color: #b0b0b0; + } + + &.selected { + background-color: #e8f4ff; + border-color: var(--blu-02); + border-width: 2px; + } +} + +.server-info { + display: flex; + flex-direction: column; + gap: 0px; + flex: 1; + overflow: hidden; + min-width: 0; +} + +.server-name { + font-size: 14px; + font-weight: 500; + color: #333; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: normal; +} + +.server-url { + font-size: 12px; + color: #666; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: normal; +} + +.server-type { + font-size: 10px; + color: #999; + font-style: italic; + line-height: normal; +} + +.checkmark-icon { + color: var(--blu-02); + font-size: 24px !important; + flex-shrink: 0; +} + +.edit-button { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + width: 30px; + height: 30px; + background-color: #ffffff; + border: 0px solid #d0d0d0; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s ease; + padding: 0; + margin-top: 4px; + .material-icons { + font-size: 20px; + color: var(--blu); + } + + &:hover { + background-color: var(--white-hex); + border-color: #b0b0b0; + + .material-icons { + color: #333; + } + } + + &:active { + transform: scale(0.95); + } +} + +#cds-add-server-btn { + display: flex; + align-items: center; + justify-content: center; + + &:hover:enabled { + opacity: .8 !important; + } +} + +#cds-ok-btn { + background: #e5e5e5; + color: #4b5052; + + &:hover { + opacity: 0.8; + } +} + + +/* ---- MCP servers dialog: moved from inline styles (appended) ---- */ +::ng-deep .custom-mcp-dialog-container .mcp-dialog__hr { + margin-top: 3px; + margin-bottom: 3px; +} + +::ng-deep .custom-mcp-dialog-container .mcp-dialog__add-icon { + font-size: 18px; + margin-right: 6px; +} + +/* Anchor absolute edit badge */ +::ng-deep .custom-mcp-dialog-container .mcp-server-item { + position: relative; +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__edit-badge { + position: absolute; + top: 8px; + right: 8px; + z-index: 2; + margin-top: 0 !important; /* override .edit-button margin-top */ +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__edit-icon { + font-size: 16px; +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__status-badge { + margin-left: 8px; + font-size: 11px; + padding: 2px 6px; + border-radius: 10px; +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__status-badge--active { + background: #dbeafe; + color: #1d4ed8; +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__status-badge--available { + background: #f1f5f9; + color: #334155; +} + +::ng-deep .custom-mcp-dialog-container .mcp-server__tools-meta { + font-size: 12px; + color: #6b7280; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.ts new file mode 100644 index 000000000..61c08de6d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.ts @@ -0,0 +1,218 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { McpServerEditDialogComponent } from '../mcp-server-edit-dialog/mcp-server-edit-dialog.component'; + + +@Component({ + selector: 'mcp-servers-dialog', + templateUrl: './mcp-servers-dialog-new.component.html', + styleUrls: ['./mcp-servers-dialog-new.component.scss'] +}) +export class McpServersDialogComponent implements OnInit { + + selectedServers: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }> }> = []; + filteredServers: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }>, selectedTools?: Array<{ name: string }> }> = []; + searchFilter: string = ''; + onUpdateCallback: (data: any) => void; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public dialogRef: MatDialogRef, + private dialog: MatDialog, + @Inject(MAT_DIALOG_DATA) public data: { + // mcpServers from integrations: tools = available, selectedTools = last selection (kept even when server not selected). + mcpServers: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }>, selectedTools?: Array<{ name: string }> }>, + selectedServers?: Array<{ name: string, url: string, transport: string, tools?: Array<{ name: string }> }>, + onUpdate?: (data: any) => void + } + ) { } + + ngOnInit(): void { + this.logger.debug("[McpServersDialog] data: ", this.data); + // Pre-select servers that were already selected + if (this.data.selectedServers && this.data.selectedServers.length > 0) { + this.selectedServers = [...this.data.selectedServers]; + this.logger.debug("[McpServersDialog] Pre-selected servers: ", this.selectedServers); + } + // Store the update callback if provided + if (this.data.onUpdate) { + this.onUpdateCallback = this.data.onUpdate; + } + // Initialize filtered servers (alphabetically by name) + this.filteredServers = [...this.data.mcpServers].sort((a, b) => a.name.localeCompare(b.name)); + } + + onCloseDialog(): void { + this.logger.log("[McpServersDialog] - modal CLOSED"); + this.dialogRef.close(false); + } + + toggleServerSelection(server: { name: string, url: string, transport: string, selectedTools?: Array<{ name: string }> }, event?: Event): void { + if (event) { + event.stopPropagation(); // Prevent triggering the button click + } + const index = this.selectedServers.findIndex(s => s.name === server.name); + if (index > -1) { + this.selectedServers.splice(index, 1); + } else { + // Use stored selectedTools from integration when adding, so previous selection is restored + const stored = this.data.mcpServers?.find(s => s.name === server.name); + const tools = Array.isArray(stored?.selectedTools) ? [...stored.selectedTools] : []; + this.selectedServers.push({ + name: server.name, + url: server.url, + transport: server.transport, + tools + }); + } + this.logger.log("[McpServersDialog] selectedServers: ", this.selectedServers); + + // Notify parent component in real-time + this.notifyUpdate(); + } + + private notifyUpdate(): void { + if (this.onUpdateCallback) { + this.onUpdateCallback({ + selectedServers: this.selectedServers, + allServers: this.data.mcpServers + }); + } + } + + onSearchChange(): void { + const filter = this.searchFilter.toLowerCase().trim(); + + if (!filter) { + this.filteredServers = [...this.data.mcpServers].sort((a, b) => a.name.localeCompare(b.name)); + } else { + this.filteredServers = this.data.mcpServers + .filter(server => + server.name.toLowerCase().includes(filter) || + server.url.toLowerCase().includes(filter) || + server.transport.toLowerCase().includes(filter) + ) + .sort((a, b) => a.name.localeCompare(b.name)); + } + + this.logger.log("[McpServersDialog] Filtered servers:", this.filteredServers.length); + } + + isServerSelected(server: { name: string, url: string, transport: string }): boolean { + return this.selectedServers.some(s => s.name === server.name); + } + + /** + * Count of available tools for a server (from integrations -> data.mcpServers[].tools). + */ + getAvailableToolsCount(server: { name: string }): number { + const found = this.data?.mcpServers?.find(s => s.name === server.name); + return Array.isArray(found?.tools) ? found.tools.length : 0; + } + + /** + * Count of active/selected tools: from selectedServers when server is selected, else from stored selectedTools (integration). + */ + getActiveToolsCount(server: { name: string }): number { + const selected = this.selectedServers.find(s => s.name === server.name); + if (selected && Array.isArray(selected.tools)) { + return selected.tools.length; + } + const found = this.data?.mcpServers?.find(s => s.name === server.name); + return Array.isArray(found?.selectedTools) ? found.selectedTools.length : 0; + } + + onAddMcpServer(): void { + this.logger.log("[McpServersDialog] - onAddMcpServer clicked"); + + const dialogRef = this.dialog.open(McpServerEditDialogComponent, { + panelClass: 'custom-mcp-edit-dialog-container', + data: { + isNew: true, + allServers: this.data.mcpServers + } + }); + + dialogRef.afterClosed().subscribe(result => { + this.logger.log("[McpServerEditDialog] new server result:", result); + if (result !== false && result) { + const createdServer = result?.server ? result.server : result; + // Add the new server to the list + this.data.mcpServers.push(createdServer); + // Automatically select the new server + this.selectedServers.push({ + name: createdServer.name, + url: createdServer.url, + transport: createdServer.transport, + tools: result?.selectedTools || [] + }); + this.logger.log("[McpServersDialog] New server added:", createdServer); + + // Update filtered list + this.onSearchChange(); + + // Notify parent component in real-time + this.notifyUpdate(); + } + }); + } + + openEditServerDialog(server: { name: string, url: string, transport: string, tools?: Array<{ name: string }>, selectedTools?: Array<{ name: string }> }, event?: Event): void { + if (event) { + event.stopPropagation(); // Prevent any unwanted propagation + } + this.logger.log("[McpServersDialog] - openEditServerDialog for:", server); + // Use action selection if server is selected, else use stored selectedTools from integration + const selectedServer = this.selectedServers.find(s => s.name === server.name); + const initialSelectedTools = selectedServer?.tools?.length + ? selectedServer.tools + : (Array.isArray(server.selectedTools) ? server.selectedTools : []); + const dialogRef = this.dialog.open(McpServerEditDialogComponent, { + panelClass: 'custom-mcp-edit-dialog-container', + data: { + server: server, + allServers: this.data.mcpServers, + selectedTools: initialSelectedTools + } + }); + + dialogRef.afterClosed().subscribe(result => { + this.logger.log("[McpServerEditDialog] result:", result); + if (result !== false && result) { + const updatedServer = result?.server ? result.server : result; + const selectedTools: Array<{ name: string }> | undefined = result?.selectedTools; + // Update the server in the list (tools + selectedTools so they are shown and persisted) + const index = this.data.mcpServers.findIndex(s => s.name === server.name); + if (index > -1) { + this.data.mcpServers[index] = updatedServer; + // Update in selectedServers if it was selected + const selectedIndex = this.selectedServers.findIndex(s => s.name === server.name); + if (selectedIndex > -1) { + const unique = new Map(); + (selectedTools || this.selectedServers[selectedIndex].tools || []).forEach(t => { + if (t?.name) unique.set(t.name, { name: t.name }); + }); + this.selectedServers[selectedIndex] = { + name: updatedServer.name, + url: updatedServer.url, + transport: updatedServer.transport, + tools: Array.from(unique.values()) + }; + } + this.logger.log("[McpServersDialog] Server updated:", updatedServer); + + // Update filtered list + this.onSearchChange(); + + // Notify parent component in real-time + this.notifyUpdate(); + } + } + }); + } + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.spec.ts new file mode 100644 index 000000000..9abf452f4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.spec.ts @@ -0,0 +1,26 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { McpServersDialogComponent } from './mcp-servers-dialog.component'; + +describe('McpServersDialogComponent', () => { + let component: McpServersDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ McpServersDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(McpServersDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.html new file mode 100644 index 000000000..c2ce47620 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.html @@ -0,0 +1,714 @@ +
+
+
+ +
+
+ {{ action?.namespaceAsName + ? action?.namespace + : (listOfNamespaces | find:{ key: 'value', value: action?.namespace })?.name + }} +
+
+ +
+
+ +
+
+ {{action?.question}} +
+
+ {{'CDSCanvas.EnterTheQuestion' | translate}} +
+
+ +
+ +
+ +
+
+ + {{action?.modelName}} +
+
+ {{'CDSCanvas.SelectKnowledgeBaseModel' | translate}} +
+
+ +
+
+ {{action?.assignReplyTo}} +
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss new file mode 100644 index 000000000..38cb79185 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss @@ -0,0 +1,669 @@ + +@import "./src/assets/sass/cds/_variables.scss"; + + +:host { + --background-color: #{var(--blu-light-01)}; + --slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; + --text-color-gray: #{var(--gray)}; +} + +// ::-webkit-scrollbar { +// width: 0px; +// } + +.tags-input-row { + display: flex; + align-items: center; + gap: 8px; + border: 1px solid var(--blu-light-02, #d2d4d6); + border-radius: var(--input-border-radius-base, 8px); + padding: 0 4px 0 12px; + background: #fff; + box-sizing: border-box; + + .tags-input { + flex: 1; + min-width: 0; + border: none; + outline: none; + padding: 5px 0; + font-size: 14px; + background: transparent; + color: var(--gray); + &::placeholder { + color: #9aa0a6; + } + } + + .tags-send-btn { + flex-shrink: 0; + padding: 3px 7px; + border: none; + border-radius: 6px; + background: var(--blu); + color: #fff; + font-size: 12px; + line-height: 12px; + font-weight: 500; + cursor: pointer; + height: 26px; + + &:hover { + opacity: 0.9; + } + } +} + +.models--container { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 4px; +} + +.model-name-and-btn-wpr { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 0px; + border-radius: 4px; + background-color: var(--blu-light-01); + border: 0px solid #d2d4d6; + font-size: 12px; +} + +.model-name { + margin: 0; + font-weight: 300; + color: var(--blu); + padding-left: 6px; +} + +.delete-model { + display: flex; + align-items: center; + justify-content: center; + padding: 6px; + margin: 0; + height: 100%; + min-width: 14px; + min-height: 14px; + border: none; + background: transparent; + color: #3d4047; + cursor: pointer; + border-radius: 0px 4px 4px 0px; + + &:hover { + background: var(--blu); + .remove-tag-icon { + fill: var(--color-white-hex); + } + } +} + +.remove-tag-icon { + width: 12px; + height: 12px; + min-width: 12px; + min-height: 12px; + fill: currentColor; +} + +.link-container { + margin-bottom: 20px; + + a.link { + font-size: 14px; + font-weight: 400; + } + + a.link:hover { + cursor: pointer; + text-decoration: underline; + } + +} + +// *********** AI SETTINGS --start *********** // + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} + +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + .title-and-parameters-container { + display: flex; + flex-direction: column; + width: 100%; + } + .parameters-preview { + font-size: 11px; + height: 38px; + line-height: normal; + } + + .preview-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 14px; + height: 14px; + font-size: 14px; + line-height: 14px; + margin: 0; + vertical-align: middle; + color: var(--text-color); + } + + .preview-flag { + font-size: 10px; + + .label { + position: relative; + padding-left: 14px; // room for the check + } + + .label::before { + content: "✓"; + position: absolute; + left: 0; + top: 0; + color: var(--blu); + font-weight: 700; + font-size: 10px; + line-height: 1; + } + } +} + +cds-select#model-condition ::ng-deep{ + .select-item-wrp{ + justify-content: space-between; + } + .label-select-option { + font-weight: 400; + font-size: 12px; + } +} + + + +::ng-deep .ng-dropdown-panel { + + + .ng-dropdown-panel-items .ng-optgroup.ng-option-disabled { + cursor: default; + height: 30px; + display: flex; + align-items: center; + } + + .ng-dropdown-panel-items.scroll-host .ng-optgroup { + padding: 0 10px; + color: var(--blu); + font-weight: 500; + font-size: 14px; + background: var(--blu-light-03); + line-height: 20px; + } + + .ng-dropdown-panel-items .ng-option.ng-option-child{ + height: 30px; + } + .ng-option .select-item-wrp[additionalText = true]{ + .select-item-wrp{ + justify-content: space-between; + } + } + .label-select-option { + color: var(--text-color-gray); + font-weight: 400; + font-size: 12px; + line-height: normal; + } +} + + +.action-wait-content { + display: flex; + flex-direction: row; + align-items: center; + gap: 5px; +} + +.action-wait-range { + color: var(--text-color); + font-size: 11px; + font-weight: 500; +} + +.action-wait-slider { + align-items: center; + background: var(--slider-background-color); + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 9px; + width: 100%; + text-align: center; + transition: width 0.3s ease-in; + font-size: 14px; +} + +.action-wait-slider>mat-slider { + width: 100%; + margin-left: 6px; +} + +.action-wait-slider.disabled { + opacity: 0.4; +} + +.action-wait-slider ::ng-deep{ + .mat-accent .mat-slider-track-fill { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label-text{ + color: var(--background-color) !important; + font-size: 10px !important; + } + .mat-slider-thumb { + background-color: var(--text-color) !important; + } +} + + + +.gpt-setting-input { + color: var(--text-color); + text-align: center; + width: 45px; + border: none; + height: 26px; + border-radius: 12px; + background-color: white; + border: 1px solid var(--text-color); + + // Hide number input spinner arrows + /* Chrome, Safari, Edge, Opera */ + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + /* Firefox */ + &[type=number] { + -moz-appearance: textfield; + appearance: textfield; + } +} + +.slider-input ::ng-deep { + width: 60px; + min-width: 60px; + font-size: 12px; + input { + text-align: center; + } +} + +// *********** AI SETTINGS --end *********** // + + +// PREVIEW SECTION --- start **************** // + +.answer-preview { + margin-bottom: 30px; +} + +.preview-container { + width: 100%; + max-height: 37px; + overflow: hidden; + transition: max-height 0.5s ease-out; + border-radius: var(--input-border-radius-base); + background-color: var(--color-white-hex); + padding: 6px 12px; + font-size: 14px; + border: 1px solid var(--blu-light-02); + color: var(--gray); +} + +.preview-container-extended { + max-height: 300px; + overflow-y: auto; +} + +.placeholder-container { + display: flex; + align-items: center; +} + +loading-spinner.custom-spinner ::ng-deep { + .sk-fading-circle { + width: 20px ; + height: 20px ; + margin: 0px ; + } + + .sk-fading-circle .sk-circle:before { + background-color: var(--blu) ; + } +} + +.label-and-button-container { + + width: 100%; + display: flex; + align-items: center; + margin-bottom: 6px; + + + .title-label { + margin-bottom: 0px; + } + +} + +.set-var-btn { + font-weight: 300 !important; + font-size: 12px !important; + height: 20px; + display: flex; + align-items: center; + padding: 6px 6px 6px 12px !important; + margin: 0px 0px 0px 6px !important; +} + +// .content#variables .opened { +// left: 0px; +// } + + + +.variables-content-header { + display: flex; + flex-direction: row; + align-items: center; + + .back-button { + cursor: pointer; + font-size: 20px; + font-weight: 600; + margin-right: 6px; + color: #ffffff80; + + &:hover { + color: white; + } + } + + .title-label { + font-size: 18px; + margin-bottom: 0px; + } +} + +.single-variable { + display: flex; + align-items: center; + margin: 14px 0px; + + .variable-name { + background-color: #ecb608; + color: white; + font-weight: 400; + padding: 6px 12px; + border-radius: 7px; + margin-right: 10px; + } + +} + +.usage-container { + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 6px; + padding: 0px 4px; + color: #a6a6a6; + font-size: 11px; + width: 100%; +} + +mat-checkbox ::ng-deep { + .mat-checkbox-ripple{ + display: none; + } +} + + +.field-box { + &.advanced-prompt-container { + margin-top: -10px; + } + &.disabled { + pointer-events: none; + opacity: 0.5; + } +} + +.slider-description { + width: calc(100% - 70px); + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + color: var(--blu); + font-weight: 400; + font-size: 12px; +} + + + +// PREVIEW SECTION --- start **************** // +.content-chunks { + max-height: 300px; + overflow-y: auto; +} +.chunk--wpr { + .chunk { + border: 1px solid #ccc; + cursor: not-allowed; + color: #787f86; + padding: 8px 15px 6px; + border-radius: 4px; + font-family: monospace; + font-size: 11px; + margin-bottom: 3px; + } +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + font-family: var(--header-font-family) !important; + .mat-expansion-panel-header { + padding: 0; + &:hover { + background-color: transparent !important; + } + } +} + + + + +cds-select#model-condition.not-configured ::ng-deep { + .ng-select .ng-select-container { + border: 1px solid var(--empty-value-text-color); + } + .ng-select .ng-select-container .ng-value span.label-select{ + color: var(--empty-value-text-color); + } +} + + +.select-container { + &.not-configured { + ::ng-deep .ng-select .ng-select-container { + .ng-value { + span.label-select { + color: var(--empty-value-text-color); + } + } + } + ::ng-deep .text-editor-wrapper .text-editor .box-input input { + color: var(--empty-value-text-color)!important; + border: 1px solid var(--empty-value-text-color)!important; + } + } + .status-indicator { + width: 8px; + height: 8px; + background-color: var(--empty-value-text-color); + border-radius: 50%; + margin: 0px; + position: absolute; + left: 0px; + top: 96px; + } +} + +// Bottom row styles for model selection +.bottom-row { + display: flex; + align-items: center; + margin-top: 0px; + padding-left: 0px; + flex-direction: row-reverse; +} + +.multiplier-container { + color: var(--gray); + font-size: 12px; + display: inline-block; +} + +.configure-model-button { + cursor: pointer; + color: #007bff; + font-size: 12px; + text-decoration: underline; + display: inline-block; + &:hover { + opacity: 0.7; + } +} + +.tag-replyto { + display: flex; + width: fit-content; + border-radius: 4px; + font-size: 10px; + margin: 3px; + height: -moz-fit-content; + height: fit-content; + padding: 0px 6px; + max-width: calc(100% - 25px); + background-color: var(--blu); + color: var(--color-white-hex); + flex-wrap: nowrap; + text-align: end; +} + +.chunks-container { + margin-bottom: 20px; + .field-box { + margin-bottom: 10px; + } +} + + +.parameters-preview { + span { + line-height: 16px; + margin-right: 5px; + } + .preview-badge { + color: #fff; + background-color: var(--blu); + display: inline-block; + padding: 1px 5px; + border-radius: 4px; + .preview-badge-text { + padding: 0; + margin:0; + } + } + .preview-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 12px; + height: 12px; + font-size: 12px; + line-height: 12px; + margin: 0; + vertical-align: middle; + color: var(--color-white-hex); + } + .preview-flag{ + margin:0; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.ts new file mode 100644 index 000000000..f9c5fa9d7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.ts @@ -0,0 +1,766 @@ +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { MatDialog } from '@angular/material/dialog'; +import { ActionAskGPTV2 } from 'src/app/models/action-model'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; + +//SERVICES +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; +import { OpenaiService } from 'src/app/services/openai.service'; + +//UTILS +import { AttributesDialogComponent } from '../cds-action-gpt-task/attributes-dialog/attributes-dialog.component'; +import { DOCS_LINK, TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { TranslateService } from '@ngx-translate/core'; +import { loadTokenMultiplier } from 'src/app/utils/util'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { ANTHROPIC_MODEL, COHERE_MODEL, DEEPSEEK_MODEL, DEFAULT_MODEL, GOOGLE_MODEL, GROQ_MODEL, LLM_MODEL, OLLAMA_MODEL, OPENAI_MODEL, generateLlmModelsFlat } from 'src/app/chatbot-design-studio/utils-ai_models'; +import { firstValueFrom } from 'rxjs'; +import { ProjectService } from 'src/app/services/projects.service'; +import { sortAutocompleteOptions, getModelsByName, getIntegrations, setModel, initLLMModels, getIntegrationModels, LlmModel } from 'src/app/chatbot-design-studio/utils-llm-models'; +import { FormatNumberPipe } from 'src/app/pipe/format-number.pipe'; +import { environment } from 'src/environments/environment'; + + +@Component({ + selector: 'cds-action-askgpt-v2-new', + templateUrl: './cds-action-askgpt-v2-new.component.html', + styleUrls: ['./cds-action-askgpt-v2-new.component.scss'] +}) +export class CdsActionAskgptV2Component implements OnInit, OnChanges { + private readonly DEFAULT_MAX_TOKENS = 10000; + + @Input() intentSelected: Intent; + @Input() action: ActionAskGPTV2; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + listOfNamespaces: Array<{name: string, displayName: string, kbTypeLabel: string, value: string, icon?:string, hybrid:boolean}>; + + project_id: string; + selectedNamespace: string; + //selectedNamespace: any; + + // Connectors + idIntentSelected: string = ''; + idConnectorTrue: string = ''; + idConnectorFalse: string = ''; + idConnectionTrue: string = ''; + idConnectionFalse: string = ''; + + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + + showPreview: boolean = false; + showAiError: boolean = false; + searching: boolean = false; + // ai_response: string = ""; + ai_error: string = ""; + preview_response: any; + chunks: Array = []; + + chunksPanelOpenState: boolean = false; + aiSettingsPanelOpenState: boolean = false; + + temp_variables = []; + // autocompleteOptions: Array<{label: string, value: string}> = []; + + + // model_list: Array<{ name: string, value: string, multiplier: string}>; + ai_setting: { [key: string] : {name: string, min: number, max: number, step: number, disabled: boolean}} = { + "max_tokens": { name: "max_tokens", min: 10, max: 8192, step: 1, disabled: false}, + "temperature" : { name: "temperature", min: 0, max: 1, step: 0.05, disabled: false}, + "chunk_limit": { name: "chunk_limit", min: 1, max: 40, step: 1, disabled: false }, + "search_type": { name: "search_type", min: 0, max: 1, step: 0.05, disabled: false }, + "reranking_multiplier": { name: "reranking_multiplier", min: 2, max: 50, step: 1, disabled: false } + } + KB_HYBRID = false; + readonly pineconeRerankingEnabled: boolean = !!environment?.['pineconeReranking'] || false; + + get rerankingAvailable(): boolean { + return !!this.KB_HYBRID || this.pineconeRerankingEnabled; + } + + BRAND_BASE_INFO = BRAND_BASE_INFO; + DOCS_LINK = DOCS_LINK.ASKGPTV2; + + + default_model = DEFAULT_MODEL + llm_model = LLM_MODEL; + llm_models_flat: Array; + llm_model_selected: LlmModel = {} as LlmModel; + + tagInputValue = ''; + + private isInitializing = { + 'llm_model': true, + 'context': true, + 'question': true + }; + + + private subscriptionChangedConnector: Subscription; + private logger: LoggerService = LoggerInstance.getInstance(); + browserLang: string = 'it'; + + constructor( + private intentService: IntentService, + private appConfigService: AppConfigService, + private dashboardService: DashboardService, + private openaiService: OpenaiService, + private translate: TranslateService, + private dialog: MatDialog, + private readonly projectService: ProjectService, + private readonly formatNumberPipe: FormatNumberPipe + ) { } + + async ngOnInit(): Promise { + // Locale for Angular number pipe (we only register 'it' explicitly; fallback to 'en') + const lang = this.translate.getBrowserLang() || 'en'; + this.browserLang = lang.startsWith('it') ? 'it' : 'en'; + this.project_id = this.dashboardService.projectID + this.logger.log("[ACTION-ASKGPTV2] action detail action: ", this.action); + // aggiorno llm_model con i modelli dell'integration + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'ollama'); + await getIntegrationModels(this.projectService, this.dashboardService, this.logger, this.llm_model, 'vllm'); + + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-ASKGPTV2] isChangedConnector -->', connector); + this.connector = connector; + this.updateConnector(); + }); + if(this.intentSelected){ + this.initializeConnector(); + } + this.initializeAttributes(); + if (!this.action.preview) { + this.action.preview = []; // per retrocompatibilità + } + this.getListNamespaces(); + this.ensureTags(); + // this.patchActionsKey(); + await this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + // When the action changes while the detail panel stays mounted, + if (changes['action'] && this.llm_models_flat?.length) { + const modelName = this.resolveModelNameFromAction(); + this.setModel(modelName, { resetMaxTokens: false, resetTemperature: false }); + } + } + + // ensure the selected model + dependent UI constraints are updated. + private ensureTags(): void { + if (!Array.isArray(this.action.tags)) { + this.action.tags = []; + } + } + + addTag(): void { + const value = this.tagInputValue?.trim() || ''; + if (!value) return; + this.ensureTags(); + if (this.action.tags.indexOf(value) === -1) { + this.action.tags.push(value); + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.ACTION, element: this.action }); + } + this.tagInputValue = ''; + } + + removeTag(tag: string): void { + this.ensureTags(); + const index = this.action.tags.indexOf(tag); + if (index !== -1) { + this.action.tags.splice(index, 1); + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.ACTION, element: this.action }); + } + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + private async initialize(){ + await this.initLLMModels(); + this.logger.log("[ACTION ASKGPTV2] 0 initialize llm_options_models: ", this.action); + this.setModel(this.resolveModelNameFromAction(), { resetMaxTokens: false, resetTemperature: false }); + + } + + private resolveModelNameFromAction(): string { + // Prefer the explicit modelName when available (new format). + const explicitModelName = (this.action?.modelName ?? '').trim(); + if (explicitModelName) { + return explicitModelName; + } + + // Backward compatibility: some saved actions may have only `model` and/or `llm`. + const actionModel = (this.action?.model ?? '').trim(); + if (actionModel && this.llm_models_flat?.length) { + const actionLlm = (this.action?.llm ?? '').trim().toLowerCase(); + const match = this.llm_models_flat.find(m => { + const sameModel = (m?.model ?? '') === actionModel; + if (!sameModel) return false; + if (!actionLlm) return true; + return (m?.llm ?? '').toLowerCase() === actionLlm; + }); + if (match?.modelName) { + return match.modelName; + } + } + + return this.default_model?.name; + } + + + async initLLMModels(){ + const result = await initLLMModels({ + projectService: this.projectService, + dashboardService: this.dashboardService, + appConfigService: this.appConfigService, + logger: this.logger, + componentName: 'ACTION ASKGPTV2' + }); + this.llm_models_flat = result; + } + + + + + setModel( + modelName: string, + options?: { resetMaxTokens?: boolean; resetTemperature?: boolean } + ) { + const { resetMaxTokens = true, resetTemperature = true } = options ?? {}; + const result = setModel(modelName, this.llm_models_flat, this.logger); + this.llm_model_selected = result ?? ({} as LlmModel); + this.logger.log("[ACTION ASKGPTV2] llm_model_selected: ", this.llm_model_selected); + this.action.llm = result?.llm ? result.llm : ''; + this.action.model = result?.model ? result.model : ''; + this.action.modelName = result?.modelName ? result.modelName : ''; + this.logger.log("[ACTION ASKGPTV2] action: ", this.action); + if (result) { + this.ai_setting['max_tokens'].max = result.max_output_tokens; + // Preserve any higher min constraint (e.g. citations => min 1024) + const modelMin = result.min_tokens; + const citationsMin = this.action?.citations ? 1024 : 0; + this.ai_setting['max_tokens'].min = Math.max(modelMin, citationsMin); + + const min = this.ai_setting['max_tokens'].min; + const max = this.ai_setting['max_tokens'].max; + + // Init/detail-panel open: keep the saved max_tokens, just clamp it into the model range. + // User-triggered model change: reset to default (capped by model max). + const currentMaxTokens = typeof this.action?.max_tokens === 'number' ? this.action.max_tokens : Number(this.action?.max_tokens); + if (resetMaxTokens || !Number.isFinite(currentMaxTokens)) { + let next = Math.min(this.DEFAULT_MAX_TOKENS, max); + if (next < min) next = min; + this.action.max_tokens = next; + } else { + this.action.max_tokens = Math.min(Math.max(currentMaxTokens, min), max); + } + + const isGpt5 = modelName.startsWith('gpt-5') || modelName.startsWith('Gpt-5'); + if (isGpt5) { + this.ai_setting['temperature'].disabled = true; + const currentTemp = typeof this.action?.temperature === 'number' ? this.action.temperature : Number(this.action?.temperature); + if (resetTemperature || !Number.isFinite(currentTemp)) { + this.action.temperature = 1; + } + } else { + this.ai_setting['temperature'].disabled = false; + } + } + } + + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ASKGPTV2] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ASKGPTV2] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'kb_reply')) { + new_attributes.push({ name: "kb_reply", value: "kb_reply" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'kb_source')) { + new_attributes.push({ name: "kb_source", value: "kb_source" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'kb_chunks')) { + new_attributes.push({ name: "kb_chunks", value: "kb_chunks" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION-ASKGPTV2] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + + private getListNamespaces(){ + this.openaiService.getAllNamespaces().subscribe((namaspaceList) => { + this.logger.log("[ACTION-ASKGPTV2] getListNamespaces", namaspaceList) + this.listOfNamespaces = namaspaceList.map((el) => { + const isHybrid = el.hybrid ? el.hybrid : false; + const kbTypeLabel = isHybrid ? 'Hybrid' : 'Semantic'; + return { name: el.name, displayName: el.name, kbTypeLabel, value: el.id, hybrid: isHybrid }; + }) + // namaspaceList.forEach(el => this.autocompleteOptions.push({label: el.name, value: el.name})) + this.initializeNamespaceSelector(); + }) + } + + async initializeNamespaceSelector() { + if (!this.action.namespaceAsName) { + if (!this.action.namespace) { + this.action.namespace = this.project_id; + return; + } + } else { + if (!this.action.namespace) { + this.action.namespace = await this.idToName(this.project_id); + } + } + this.selectKB(this.action.namespace); + } + + selectKB(namespace){ + const type = this.action?.namespaceAsName ? 'name' : 'value'; + const result = this.listOfNamespaces?.find(el => type === 'value' ? el.value === namespace : el.name === namespace); + this.logger.log("[ACTION-ASKGPTV2] selectKB", namespace, this.listOfNamespaces, result); + if(result){ + this.KB_HYBRID = result.hybrid; + } + } + + + onChangeTextarea(event: string, property: string) { + this.logger.log("[ACTION-ASKGPTV2] onEditableDivTextChange event", event, this.listOfNamespaces); + this.logger.log("[ACTION-ASKGPTV2] onEditableDivTextChange property", property); + + if(property === 'namespace'){ + this.selectKB(event); + return; + } + const nextValue = (event ?? '').toString(); + const currentValue = ((this.action && (this.action as any)[property]) ?? '').toString(); + + /** + * NOTE: + * `cds-textarea` may emit `changeTextarea` during init only when it has a non-empty initial value. + * When the initial value is empty, the first real user input/paste is the first emission. + * The previous implementation always dropped the first emission, causing "context not saved" on first edit. + */ + if (this.isInitializing[property]) { + this.isInitializing[property] = false; + if (nextValue === currentValue) { + return; + } + } + + (this.action as any)[property] = nextValue; + this.logger.log("[ACTION-ASKGPTV2] updated action", this.action); + } + + onBlur(event, property){ + if(property === 'namespace'){ + this.action[property] = event; + } else { + this.action[property] = event.target.value; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(variableSelected: { name: string, value: string }, key) { + this.action[key] = variableSelected.value; + this.updateAndSaveAction.emit() +} + + + onChangeSelect(event, target) { + this.logger.log("[ACTION-ASKGPTV2] onChangeSelect event", event); + if (target === 'llm_model'){ + // User explicitly changed model from UI: apply model constraints and reset defaults. + this.setModel(event.modelName, { resetMaxTokens: true, resetTemperature: true }); + } + if (event.clickEvent === 'footer') { + // this.openAddKbDialog(); moved in knowledge base settings + } else { + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'namespace') { + if(event){ + if (type === 'namespace') { + this.logger.log("[ACTION-ASKGPTV2] onChangeBlockSelect ",event ); + if (!this.action.namespaceAsName) { + this.action[type]=event.value + } else { + const found = this.listOfNamespaces.find(n => n.value === event.value); + this.action[type] = found?.name || event.value; + } + this.selectedNamespace = event.value; + this.selectKB(this.selectedNamespace); + } else { + this.action[type]=event.value + } + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'namespace') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributes(attributes:any, type:'trueIntent' | 'falseIntent'){ + this.logger.log("type: ", type) + this.logger.log("attributes: ", attributes) + if (type === 'trueIntent') { + this.action.trueIntentAttributes = attributes; + } + if (type === 'falseIntent') { + this.action.falseIntentAttributes = attributes; + } + this.logger.log("action updated: ", this.action) + } + + async onChangeCheckbox(event, target){ + try { + this.action[target] = !this.action[target]; + if (target === "namespaceAsName") { + if (this.action[target]) { + if (this.action.namespace) { + this.action.namespace = await this.idToName(this.action.namespace); + } + } else { + this.action.namespace = await this.nameToId(this.action.namespace); + } + } else if(target === 'citations'){ + if (this.action[target]) { + this.ai_setting['max_tokens'].min=1024; + if(this.action.max_tokens<1024){ + this.action.max_tokens = 1024; + } + }else{ + this.ai_setting['max_tokens'].min=this.llm_model_selected.min_tokens; + } + } else if (target === 'reranking') { + // Initialize multiplier when reranking is enabled + if (this.action[target] && (this.action['reranking_multiplier'] === null || this.action['reranking_multiplier'] === undefined)) { + this.action['reranking_multiplier'] = this.ai_setting['reranking_multiplier'].min; // default = 2 + } + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + + } catch (error) { + this.logger.log("Error: ", error); + } + } + + updateSliderValue(event, target) { + this.logger.debug("[ACTION-ASKGPTV2] updateSliderValue event: ", event, target); + this.action[target] = event; + if(target === 'max_tokens'){ + if(event < this.ai_setting['max_tokens'].min){ + this.action.max_tokens = this.ai_setting['max_tokens'].min; + } else if(event > this.ai_setting['max_tokens'].max){ + this.action.max_tokens = this.ai_setting['max_tokens'].max; + } else { + this.action.max_tokens = event; + } + } else if (target === 'reranking_multiplier') { + const min = this.ai_setting['reranking_multiplier'].min; + const max = this.ai_setting['reranking_multiplier'].max; + const v = typeof event === 'number' ? event : Number(event); + if (Number.isFinite(v)) { + this.action.reranking_multiplier = Math.min(Math.max(v, min), max); + } else { + this.action.reranking_multiplier = min; + } + } + this.updateAndSaveAction.emit(); + } + + goToKNB(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/knowledge-bases' + window.open(url, '_blank') + } + + async execPreview() { + //this.scrollToBottom(); + this.temp_variables = []; + let resp = await this.checkVariables(); + this.logger.log("[ACTION-ASKGPTV2] execPreview: ", resp); + + let respNamespace = await this.checkNamespaceVariables() + if (resp && respNamespace){ + this.getResponse(this.action.question, this.action.namespace); + } else{ + this.openAttributesDialog(); + } + } + + checkVariables() { + return new Promise((resolve) => { + let regex: RegExp = /{{[^{}]*}}/g; + let string = this.action.question; + let matches = string.match(regex); + if (!matches || matches.length == 0) { + resolve(true); + } else { + matches.forEach((m) => { + let name = m.slice(2, m.length - 2); + let attr = this.action.preview.find(v => v.name === name); + const index = this.temp_variables.findIndex((e) => e.name === name); + if(index> -1 ){ //key already exist: do not add it again + return; + } + if (attr && attr.value) { + this.temp_variables.push({ name: name, value: attr.value }); + } else if (attr && !attr.value) { + this.temp_variables.push({ name: name, value: null }); + } else { + this.temp_variables.push({ name: name, value: null }); + this.action.preview.push({ name: name, value: null }); + } + }) + resolve(false); + } + }) + } + + checkNamespaceVariables() { + return new Promise((resolve) => { + let regex: RegExp = /{{[^{}]*}}/g; + let string = this.action.namespace; + let matches = string.match(regex); + + if (!matches || matches.length == 0) { + resolve(true); + + } else { + + matches.forEach((m) => { + let name = m.slice(2, m.length - 2); + let attr = this.action.preview.find(v => v.name === name); + + const index = this.temp_variables.findIndex((e) => e.name === name); + if(index> -1 ){ //key already exist: do not add it again + return; + } + + if (attr && attr.value) { + this.temp_variables.push({ name: name, value: attr.value }); + } else if (attr && !attr.value) { + this.temp_variables.push({ name: name, value: null }); + } else { + this.temp_variables.push({ name: name, value: null }); + this.action.preview.push({ name: name, value: null }); + } + }) + resolve(false); + } + }) + } + + async getResponse(question, namespace) { + this.logger.log("getResponse called...") + + let data = { + question: question, + system_context: this.action.context, + llm: this.action.llm, + model: this.action.model, + max_tokens: this.action.max_tokens, + temperature: this.action.temperature, + top_k: this.action.top_k, + alpha: this.action.alpha, + namespace: namespace, + advancedPrompt: this.action.advancedPrompt, + chunks_only: this.action?.chunks_only + } + // if(this.action?.chunks_only && this.action?.chunks_only === true){ + // data['search_type'] = 'chunks'; + // } + if(this.action.namespaceAsName){ + data.namespace = await this.nameToId(namespace) + } + this.showAiError = false; + this.searching = true; + this.showPreview = true; + + setTimeout(() => { + let element = document.getElementById("preview-container"); + element?.classList.remove('preview-container-extended') + }, 200) + + this.openaiService.previewAskPrompt(data).subscribe({ next: (preview_response: any)=> { + this.searching = false; + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + + this.logger.log("[ACTION GPT-TASK] previewPrompt ai_response: ", preview_response, preview_response.chunks); + + this.preview_response = preview_response; + + if(!preview_response.answer){ + this.showAiError = true; + this.ai_error = this.translate.instant('CDSCanvas.AiNoAnswer') + // return; + } + + if(preview_response.chunks){ + this.chunks = preview_response.chunks; + } else if(preview_response.content_chunks){ + this.chunks = preview_response.content_chunks; + } + + //this.ai_response = preview_response.answer; + + }, error: (err)=> { + this.searching = false; + this.logger.error("[ACTION GPT-TASK] previewPrompt error: ", err); + setTimeout(() => { + let element = document.getElementById("preview-container"); + element?.classList.add('preview-container-extended') + }, 200) + this.showAiError = true; + this.ai_error = this.translate.instant('CDSCanvas.AiError') + if(err.error.error_code === 13001){ + this.ai_error = this.translate.instant('CDSCanvas.AiQuotaExceeded') + return; + } + }, complete: ()=> { + this.logger.debug("[ACTION GPT-TASK] preview prompt *COMPLETE*: "); + this.searching = false; + }}); + } + + openAttributesDialog() { + this.logger.log("temp_variables: ", this.temp_variables); + const dialogRef = this.dialog.open(AttributesDialogComponent, { + panelClass: 'custom-setattribute-dialog-container', + data: { attributes: this.temp_variables, question: this.action.question, namespace: this.action.namespace } + }); + dialogRef.afterClosed().subscribe(result => { + this.logger.log("AttributesDialogComponent result: ", result); + if (result !== false) { + this.getResponse(result.question, result.namespace); + this.saveAttributes(result.attributes); + } + }); + } + + saveAttributes(attributes) { + attributes.forEach(a => { + let index = this.action.preview.findIndex(v => v.name === a.name) + if (index != -1) { + this.action.preview[index].value = a.value; + } else { + this.action.preview.push({ name: a.name, value: a.value }) + } + this.updateAndSaveAction.emit(); + }) + } + + async idToName(id: string): Promise { + return new Promise((resolve) => { + const found = this.listOfNamespaces?.find(n => n.value === id); + const name = found?.name || id; + resolve(name) + }) + } + + async nameToId(name: string): Promise { + return new Promise((resolve) => { + const selected = this.listOfNamespaces?.find(n => n.name === name); + if(selected){ + resolve(selected.value) + } else { + resolve(this.project_id) + } + }) + } + + + goToIntegrations(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations' + window.open(url, '_blank') + } + + /** + * Formats the slider thumb label value with "k" notation for values > 999 + * Uses the FormatNumberPipe for consistent formatting across the app + * @param value - The numeric value to format + * @returns Formatted string with "k" for values > 999 (rounded to integers) + */ + formatSliderLabel = (value: number): string => { + return this.formatNumberPipe.transform(value); + } + + /** + * Alias for formatSliderLabel to maintain compatibility with existing templates + */ + formatLabel = (value: number): string => { + return value?.toString() || ''; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2.component.spec.ts new file mode 100644 index 000000000..0f4f53d4a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAskgptV2Component } from './cds-action-askgpt-v2.component'; + +describe('CdsActionAskgptV2Component', () => { + let component: CdsActionAskgptV2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAskgptV2Component ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAskgptV2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.html new file mode 100644 index 000000000..2326ba868 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.html @@ -0,0 +1,44 @@ +
+
+
+ Add Knowledge Base for OpenAI +
+ close +
+
+
+
+ help_outline +
+

Set a name for the Knowledge Base and a valid URL to be indexed.

+

Note: you can add a maximum of 3 Knowledge Bases.

+
+
+ + + +
Name
+ + +
URL
+ + + + + + +
+
+ + + + +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.scss new file mode 100644 index 000000000..cf328cdab --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.scss @@ -0,0 +1,126 @@ +::ng-deep .custom-dialog-container { + width: 40vw!important; + min-width: 500px; + max-width: 1000px!important; + mat-dialog-container { + padding: 0; + } + + + .tpl-modal-box { + border-radius: 6px; + flex-direction: column; + background: rgb(255, 255, 255); + } + .tpl-modal-header { + align-items: flex-start; + align-items: center; + border-bottom: 1px solid #dbe1e8; + display: flex; + flex-shrink: 0; + justify-content: center; + padding: 15px; + width: 100%; + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + } + } + + .tpl-modal-header-text { + flex-grow: 1; + padding-right: 15px; + text-align: center; + width: 0; + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 18px; + } + } + + .tpl-modal-content { + flex-grow: 1; + padding: 30px 25px; + width: 100%; + } + + .tpl-info { + border-radius: 4px; + display: flex; + margin-bottom: 20px; + padding: 12px 15px; + width: 100%; + color: #333; + background: var(--icon-color); + .tpl-info-icon { + font-size: 20px; + height: 20px; + flex-shrink: 0; + width: 35px; + } + } + .tpl-label-textarea { + margin-bottom: 5px; + color: #22272d; + font-size: 15px; + line-height: 19px; + } + + .tpl-input { + background: #fff; + border: 2px solid #c6cdd4; + border-radius: 6px; + color: #22272d; + display: block; + font-weight: 400; + height: 37px; + line-height: 35px; + padding: 0 15px; + -webkit-transition: border .3s; + transition: border .3s; + width: 100%; + &::placeholder { + opacity: 0.5; + } + &.invalid{ + border: 2px solid red !important; + outline: 0px solid red !important; + transition: border 0.3s; + } + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: flex-end; + padding: 0 25px 20px; + color: #333; + .cds-yellow-button{ + margin-left: 10px; + min-width: 80px; + background-color: var(--icon-color); + height: 100%; + color: #333; + } + .btn-cancel { + min-width: 80px; + border: 0; + height: 100%; + } + } +} + +.input-error { + position: absolute; + font-size: 14px; + color: red; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.ts new file mode 100644 index 000000000..0b801b8a6 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog-new.component.ts @@ -0,0 +1,74 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: ' selector: 'cds-addkb-dialog-new',-new', + templateUrl: './addkb-dialog-new.component.html', + styleUrls: ['./addkb-dialog-new.component.scss'] +}) +export class AddkbDialogComponent implements OnInit { + + disableSubmit: boolean = true; + kbForm: FormGroup; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private formBuilder: FormBuilder, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + ) { } + + ngOnInit(): void { + this.logger.log("Add Knowledge base dialog - OPENED"); + this.kbForm = this.createConditionGroup(); + } + + onChangeInput(event, target):void { + // this.logger.log("----> event: ", event); + + // if (target === 'url') { + // const regexPattern = '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?'; + // let REGEX = new RegExp(regexPattern.replace(/\//gi, '')); + // if (REGEX.test(event) && event !== '' && this.data.name !== ''){ + // this.btnDisabled = false; + // } else { + // this.btnDisabled = true; + // } + // } + if (this.kbForm.valid) { + this.disableSubmit = false; + } else { + this.disableSubmit = true; + } + } + + createConditionGroup(): FormGroup { + return this.formBuilder.group({ + name: ['', Validators.required], + url: ['', [Validators.required, Validators.pattern('(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?')]] + }) + } + + onSubmitKb() { + this.logger.log("onSubmitKb: ", this.kbForm) + if (this.kbForm.valid) { + this.logger.log("abilita il bottone") + this.disableSubmit = false; + } else { + this.logger.log("disabilita il bottone") + this.disableSubmit = true; + } + } + + onCloseDialog(): void { + // ADD CONTROLS!!!! + // NOT NECESSARY??? + this.logger.log("Add Knowledge base dialog - CLOSED"); + this.dialogRef.close(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog.component.spec.ts new file mode 100644 index 000000000..811c5a380 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/addkb-dialog/addkb-dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddkbDialogComponent } from './addkb-dialog.component'; + +describe('AddkbDialogComponent', () => { + let component: AddkbDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AddkbDialogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AddkbDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.html new file mode 100644 index 000000000..9770eccd2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.html @@ -0,0 +1,169 @@ +
+werkwepkrpw +
+
+ + + + +
+
+ {{action?.question}} +
+
+ {{'CDSCanvas.EnterTheQuestion' | translate}} +
+
+ +
+
+ school +
+
+ + {{action?.kbName}} +
+
+ {{'CDSCanvas.SelectKnowledgeBase' | translate}} +
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss new file mode 100644 index 000000000..78820ca24 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss @@ -0,0 +1,117 @@ +.custom-divider { + border-top: 1px solid var(--blu); +} + + +div { + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } +} + + +.custom-icon { + margin-right: 6px; + font-size: 15px; +} + +.animated-icon { + animation: rotate 1.5s linear infinite; +} + +@keyframes rotate { + to { + transform: rotate(360deg); + } +} + +.play-button { + display: flex; + flex-direction: row; + align-items: center; + color: #cbcbcb; +} + +.play-button:hover { + cursor: pointer; + + .button-text { + text-decoration: underline; + } + + .play-icon { + font-size: 17px; + } +} + +.sync-div { + display: flex; + flex-direction: row; + align-items: center; + color: #cbcbcb; +} + +.indexing-hint { + color: #ff4e4e; + font-size: 14px; + filter: drop-shadow(2px 2px 6px black); +} + +.variable-container { + display: flex; + height: 35px; + flex-direction: row; + align-items: center; + border: solid 1px black; + background-color: white; + padding: 0px 20px; + border-radius: 10px; + font-size: 14px; +} + + +a.link{ + cursor: pointer; + text-decoration: underline; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.ts new file mode 100644 index 000000000..b5ecdea6d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.ts @@ -0,0 +1,349 @@ +import { Component, EventEmitter, HostListener, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//MODELS +import { ActionAskGPT } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; + +//SERVICES +import { MatDialog } from '@angular/material/dialog'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { KnowledgeBaseService } from 'src/app/services/knowledge-base.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; + +//UTILS +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: ' selector: 'cds-action-askgpt-new',-new', + templateUrl: './cds-action-askgpt-new.component.html', + styleUrls: ['./cds-action-askgpt-new.component.scss'] +}) +export class CdsActionAskgptNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionAskGPT; + @Input() previewMode: boolean = true; + @Input() project_id: string; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + kbs_list = []; + kb_selected_id: string = null; + status_code: number; + indexing_hint: string = null; + + + // gptkey: string = ""; + buttonDisabled: boolean = false; + buttonIcon: string = "add" + buttonText: string = "Add Knowledge Base"; + + idBot: string; + variableListUserDefined: Array<{ name: string, value: string }> // = variableList.userDefined + spinner: boolean = false; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly kbService: KnowledgeBaseService, + public dialog: MatDialog, + private readonly intentService: IntentService, + private readonly appConfigService: AppConfigService, + ) { } + + ngOnInit(): void { + this.logger.debug("[ACTION-ASKGPT] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-ASKGPT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + if (this.previewMode === false) { + this.onDetailModeLoad(); + } + } + + // ngOnChanges(changes: SimpleChanges) { + // if(this.intentSelected){ + // this.initializeConnector(); + // } + // } + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + onDetailModeLoad() { + this.getKnowledgeBaseSettings(); + this.initializeAttributes(); + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + // private checkConnectionStatus(){ + // if(this.action.trueIntent){ + // this.isConnectedTrue = true; + // } else { + // this.isConnectedTrue = false; + // } + // if(this.action.falseIntent){ + // this.isConnectedFalse = true; + // } else { + // this.isConnectedFalse = false; + // } + // } + + + // private checkConnectionStatus(){ + // if(this.action.trueIntent){ + // this.isConnectedTrue = true; + // const posId = this.action.trueIntent.indexOf("#"); + // if (posId !== -1) { + // const toId = this.action.trueIntent.slice(posId+1); + // this.idConnectionTrue = this.idConnectorTrue+"/"+toId; + // } + // } else { + // this.isConnectedTrue = false; + // this.idConnectionTrue = null; + // } + // if(this.action.falseIntent){ + // this.isConnectedFalse = true; + // const posId = this.action.falseIntent.indexOf("#"); + // if (posId !== -1) { + // const toId = this.action.falseIntent.slice(posId+1); + // this.idConnectionFalse = this.idConnectorFalse+"/"+toId; + // } + // } else { + // this.isConnectedFalse = false; + // this.idConnectionFalse = null; + // } + // } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ASKGPT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ASKGPT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // private updateConnector(){ + // try { + // const array = this.connector.fromId.split("/"); + // const idAction= array[1]; + // if(idAction === this.action._tdActionId){ + // if(this.connector.deleted){ + // if(array[array.length -1] === 'true'){ + // this.action.trueIntent = null; + // this.isConnectedTrue = false; + // this.idConnectionTrue = null; + // } + // if(array[array.length -1] === 'false'){ + // this.action.falseIntent = null; + // this.isConnectedFalse = false; + // this.idConnectionFalse = null; + // } + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } else { + // // TODO: verificare quale dei due connettori è stato aggiunto (controllare il valore della action corrispondente al true/false intent) + // this.logger.debug('[ACTION-ASKGPT] updateConnector', this.connector.toId, this.connector.fromId ,this.action, array[array.length-1]); + // if(array[array.length -1] === 'true'){ + // // this.action.trueIntent = '#'+this.connector.toId; + // this.isConnectedTrue = true; + // this.idConnectionTrue = this.connector.fromId+"/"+this.connector.toId; + // this.action.trueIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // if(array[array.length -1] === 'false'){ + // // this.action.falseIntent = '#'+this.connector.toId; + // this.isConnectedFalse = true; + // this.idConnectionFalse = this.connector.fromId+"/"+this.connector.toId; + // this.action.falseIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // } + // } + // } catch (error) { + // this.logger.error('[ACTION-ASKGPT] updateConnector error: ', error); + // } + // } + + getKnowledgeBaseSettings() { + this.logger.log("**** carico solo dopo aver aperto il dettaglio") + this.kbService.getKbSettings().subscribe((kbSettings: any) => { + this.logger.debug("[ACTION-ASKGPT] get kbSettings: ", kbSettings); + this.kbs_list = kbSettings.kbs.map(t => { + t.icon = "language" + return t; + }) + if (this.action.kbid) { + let kb_selected = kbSettings.kbs.find(k => k.url === this.action.kbid); + if (!kb_selected) { + this.action.kbid = null; + this.action.kbName = null; + } else { + this.kb_selected_id = kb_selected._id; + } + } + }, (error) => { + this.logger.error("[ACTION-ASKGPT] ERROR get kbSettings: ", error); + }, () => { + this.logger.info("[ACTION-ASKGPT] get kbSettings *COMPLETE*"); + }) + } + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'kb_reply')) { + new_attributes.push({ name: "kb_reply", value: "kb_reply" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'kb_source')) { + new_attributes.push({ name: "kb_source", value: "kb_source" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION ASKGPT] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + changeTextarea($event: string, property: string) { + this.logger.log("[ACTION-ASKGPT] onEditableDivTextChange event", $event) + this.logger.log("[ACTION-ASKGPT] onEditableDivTextChange property", property) + this.action[property] = $event + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-ASKGPT] onEditableDivTextChange event", event) + this.logger.log("[ACTION-ASKGPT] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeSelect(event) { + if (event.clickEvent === 'footer') { + // this.openAddKbDialog(); moved in knowledge base settings + } else { + this.logger.log("event: ", event); + this.action.kbid = event.url; + this.action.kbName = event.name; + let kb_selected = this.kbs_list.find(k => k.url === this.action.kbid); + if (kb_selected) { + this.kb_selected_id = kb_selected._id; + } + //this.checkKbStatus(this.action.kbid); + this.logger.log("[ACTION-ASKGPT] updated action", this.action); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributes(attributes:any, type:'trueIntent' | 'falseIntent'){ + this.logger.log("type: ", type) + this.logger.log("attributes: ", attributes) + if (type === 'trueIntent') { + this.action.trueIntentAttributes = attributes; + } + if (type === 'falseIntent') { + this.action.falseIntentAttributes = attributes; + } + this.logger.log("action updated: ", this.action) + } + + // getValue(key: string): string{ + // let value = '' + // if(this.kbs_list && this.kbs_list.length > 0) + // value = this.kbs_list.find(el => el.url === this.action.kbid) + // value? value = value[key]: value= '' + // return value + // } + + goToKNB(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/knowledge-bases' + window.open(url, '_blank') + } + + @HostListener('document:visibilitychange') + visibilitychange() { + if (!document.hidden && this.previewMode == false) { + this.getKnowledgeBaseSettings(); + } + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt.component.spec.ts new file mode 100644 index 000000000..5b2183847 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAskgptComponent } from './cds-action-askgpt.component'; + +describe('ActionAskgptComponent', () => { + let component: CdsActionAskgptComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAskgptComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAskgptComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.html new file mode 100644 index 000000000..6b74e11c1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.html @@ -0,0 +1,30 @@ +
+ +
+ + +
+ + +
+ + + +
+ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.scss new file mode 100644 index 000000000..097b7a075 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.scss @@ -0,0 +1,61 @@ +.material-icons{ + color: var(--icon-color); + font-size: 18px; +} + +// div.value-wrp{ +// position: relative; +// .flex{ +// position: absolute; +// top: 0px; +// bottom: 0px; +// right: 8px; +// display: flex; +// align-items: center; +// justify-content: center; + +// .close{ +// width: 17px; +// top: -7px; +// right: -7px; +// font-size: 15px; +// border-radius: 50%; +// background: white; +// cursor: pointer; +// position: absolute; +// display: flex; +// justify-content: center; +// align-items: center; +// opacity: 1; +// &:hover{ +// background: #ecb606; +// color: white; +// } +// } +// } + +// div.tag{ +// position: absolute; +// top: 0; +// bottom: 0; +// left: 8px; +// right: unset; +// border-radius: 7px; +// margin: 5px; +// padding: 5px 10px; +// background-color: #ecb606; +// color: white; + +// } +// } + +// cds-textarea#assignTo ::ng-deep { +// display: flex; +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.ts new file mode 100644 index 000000000..359896bad --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function-new.component.ts @@ -0,0 +1,51 @@ +import { ActionAssignFunction } from '../../../../../../models/action-model'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TYPE_FUNCTION_LIST_FOR_FUNCTIONS } from '../../../../../utils'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-assign-function-new', + templateUrl: './cds-action-assign-function-new.component.html', + styleUrls: ['./cds-action-assign-function-new.component.scss'] +}) +export class CdsActionAssignFunctionNewComponent implements OnInit { + + @Input() action: ActionAssignFunction; + @Output() updateAndSaveAction = new EventEmitter(); + + listOfFunctions: Array<{name: string, value: string, icon?:string}> = []; + openSlectFunction: boolean = true; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void { + // this.logger.log('-------> action:: ', this.action); + this.initialize(); + } + + ngOnChanges() { + } + + private initialize() { + for (let key in TYPE_FUNCTION_LIST_FOR_FUNCTIONS) { + this.listOfFunctions.push({name: TYPE_FUNCTION_LIST_FOR_FUNCTIONS[key].name, value: TYPE_FUNCTION_LIST_FOR_FUNCTIONS[key].type}); + } + } + + onSelectedFunction(event: any) { + // this.logger.log("onSelectedFunction::: ", event); + this.action.functionName = event.value; + this.updateAndSaveAction.emit() + } + + onSelectedAttribute(event: any){ + // this.logger.log("onSelectedAttribute::: ", event); + this.action.assignTo = event.name; + this.updateAndSaveAction.emit() + } + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function.component.spec.ts new file mode 100644 index 000000000..6be148097 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-function/cds-action-assign-function.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAssignFunctionComponent } from './cds-action-assign-function.component'; + +describe('ActionAssignFunctionComponent', () => { + let component: CdsActionAssignFunctionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAssignFunctionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAssignFunctionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.html new file mode 100644 index 000000000..cc2c0d758 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.html @@ -0,0 +1,70 @@ +
+ +
+
+ +
+
+ {{'CDSCanvas.AssignTo' | translate }}: +
+ +
+
+ {{action?.destination}} +
+
+ {{'CDSCanvas.SelectAttribute' | translate}} +
+
+
+ +
+
{{'CDSCanvas.Operations' | translate }}:
+
+
+
+
{{'CDSCanvas.Value' | translate }}
+
+ {{ operand?.value }} +
+
+
+
{{'CDSCanvas.Function' | translate }}:
+
+ {{ getValue(operand?.function, 'operands').name | translate }} +
+
+
+ +
+ {{ getValue(action?.operation?.operators[index], 'operators').name | translate }} +
+
+ +
+ +
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss new file mode 100644 index 000000000..96e291066 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss @@ -0,0 +1,151 @@ +::-webkit-scrollbar { + width: 0px; +} + + +div { + + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } +} + +// cds-textarea#assignTo ::ng-deep { +// display: flex; + +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } + +.set-attribute-destination-label-and-value-wpr { + // background: #e8e6dd; + // padding: 3px; + display: flex; + align-items: center; + gap: 6px; +} + +.set-attribute-operands-wpr { + padding: 0px 3px; +} + + +.set-attribute-label-and-value-wpr { + display: flex; + gap: 6px; + align-items: center; +} + +.set-attribute-function { + color: #ecb606; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; +} + +.set-attribute-operator { + text-align: center; + border-bottom: 1px solid #6c6859d9; + line-height: 0.1em; + margin: 15px 15px; + color: #6c6859d9; + font-size: 12px; + font-weight: 400; +} + +.set-attribute-operator span { + background: #f4f3ee; + padding: 0 10px; +} + +.set-attribute { + font-size: 12px; + color: #ff4001; + font-weight: 400; +} + +.set-attribute-placeholder-wpr { + display: flex; + align-items: center; + gap: 6px; +} + +.set-attribute-placeholder-icon { + height: 18px; +} + + +.cds-action-preview{ + .action-row-left{ + width: unset; + } + + .set-attribute-label { + color: #6c6859d9; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; + // background: #e8e6dd; + padding: 0px 3px; + height: inherit; + } + + .icon-action img { + height: 16px; + filter: brightness(0) saturate(100%) invert(42%) sepia(2%) saturate(2720%) hue-rotate(9deg) brightness(91%) contrast(81%); + } + +} + +.truncate { + display: -webkit-box; + -webkit-line-clamp: 8; + -webkit-box-orient: vertical; + overflow: hidden; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.ts new file mode 100644 index 000000000..6acfcaa78 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.ts @@ -0,0 +1,106 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { TYPE_FUNCTION_LIST_FOR_VARIABLES, TYPE_MATH_OPERATOR_LIST } from 'src/app/chatbot-design-studio/utils'; +import { ActionAssignVariableV2 } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-assign-variable-v2-new', + templateUrl: './cds-action-assign-variable-v2-new.component.html', + styleUrls: ['./cds-action-assign-variable-v2-new.component.scss'] +}) +export class CdsActionAssignVariableV2Component implements OnInit { + + @Input() action: ActionAssignVariableV2; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + listOfMathOperators: Array<{ name: string, value: string, icon?: string }> = []; + listOfFunctions: Array<{ name: string, value: string, icon?: string }> = []; + + + TYPE_FUNCTION_LIST_FOR_VARIABLES = TYPE_FUNCTION_LIST_FOR_VARIABLES + TYPE_MATH_OPERATOR_LIST = TYPE_MATH_OPERATOR_LIST + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor() { } + + ngOnInit(): void { + this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] action ', this.action) + const operands = this.action.operation.operands + const operators = this.action.operation.operators + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operands ', operands) + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators ', operators) + + // for (let i = 0; i < operands.length; i++) { + // for (let key in TYPE_FUNCTION_LIST_FOR_VARIABLES) { + // let _function = operands[i].function + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operand _function (2)' , _function) + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] TYPE_FUNCTION_LIST_FOR_VARIABLES key ' ,TYPE_FUNCTION_LIST_FOR_VARIABLES[key]) + // if (_function === TYPE_FUNCTION_LIST_FOR_VARIABLES[key].type) { + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] >>>>>> operand ', operands[i]) + // operands[i]['functionName'] = TYPE_FUNCTION_LIST_FOR_VARIABLES[key].name + // } + // } + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operands -xx', operands[i]) + // if (operands[i].value === '') { + // this.displaySetOperationPlaceholder = false + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] displaySetOperationPlaceholder -xx', this.displaySetOperationPlaceholder) + // } + // for (let j = 0; j < operators.length; j++) { + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operator ---xx>', operators) + // if (operands.length - 1) { + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators j -xx>', operators[j]) + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators i -xx>', operators[i]) + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators i TYPE_MATH_OPERATOR[operators[i]] -xx>', TYPE_MATH_OPERATOR[operators[i]]) + // // operands[i]['operator'] = TYPE_MATH_OPERATOR[operators[j]] + // for (let key in TYPE_MATH_OPERATOR_LIST) { + // if (operators[i] === TYPE_MATH_OPERATOR_LIST[key].type) { + // operands[i]['operator'] = TYPE_MATH_OPERATOR_LIST[key].name + // } + // } + + // } + // } + // } + + } + + getValue(key: string, type: 'operands' | 'operators'): any{ + // return TYPE_FUNCTION_LIST_FOR_VARIABLES[key] + if(type === 'operands'){ + return this.listOfFunctions.filter(el => el.value === key)[0] + } + if(type === 'operators'){ + return this.listOfMathOperators.filter(el => el.value === key)[0] + } + + } + + initialize() { + for (let key in TYPE_FUNCTION_LIST_FOR_VARIABLES) { + this.listOfFunctions.push({ name: TYPE_FUNCTION_LIST_FOR_VARIABLES[key].name, value: TYPE_FUNCTION_LIST_FOR_VARIABLES[key].type}); + } + for (let key in TYPE_MATH_OPERATOR_LIST) { + this.listOfMathOperators.push({ name: TYPE_MATH_OPERATOR_LIST[key].name, value: TYPE_MATH_OPERATOR_LIST[key].type, icon: TYPE_MATH_OPERATOR_LIST[key].src}); + } + } + + onSelectedAttribute(variableSelected: { name: string, value: string }) { + this.action.destination = variableSelected.value; + this.updateAndSaveAction.emit() + } + + onChangeOperation(event) { + // let temp = this.action.operation; + // this.action.operation.operators.push(TYPE_MATH_OPERATOR['addAsNumber']); + // this.action.operation.operands.push(new Operand()); + // this.action.operation = Object.assign({}, temp); + this.updateAndSaveAction.emit(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2.component.spec.ts new file mode 100644 index 000000000..64f1f3152 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAssignVariableV2Component } from './cds-action-assign-variable-v2.component'; + +describe('CdsActionAssignVariableV2Component', () => { + let component: CdsActionAssignVariableV2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAssignVariableV2Component ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAssignVariableV2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.html new file mode 100644 index 000000000..541771422 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.html @@ -0,0 +1,71 @@ +
+ +
+
+ + + +
+
+ + + + + + {{'CDSCanvas.Advanced' | translate }} + + +
+ + +
+ + + +
+ + +
+
+ + {{"CDSCanvas.TreatAsAttributeName" | translate}} + info + +
+
+ +
+
+
+ + + + + + + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss new file mode 100644 index 000000000..4e7cd68aa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss @@ -0,0 +1,133 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --icon-color: #{var(--blu)}; + --text-color: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +div.operand-wrp { + display: grid; + align-items: center; + grid-template-columns: 1fr; //11fr 1fr; + grid-column-gap: 0px; + grid-row-gap: 10px; + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + padding: 10px 10px 20px; + border-radius: 4px; + + + .material-icons { + font-size: 25px; + color: var(--icon-color); + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + margin-top: 20px; + } + + div.value-wrp{ + position: relative; + display: block; + } + + .applay-function-button{ + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + padding: 8px 15px; + border: 1px solid #c6cdd4; + border-radius: 4px; + height: 43px; + color: #c6cdd4; + cursor: pointer; + + &:hover{ + border-color: white; + color: white + } + } +} + +.disable-input-message { + display: none; + span.material-icons, + span.material-icons-outlined{ + font-size: 16px; + } +} + + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} + +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + + + +cds-select#selectOperand ::ng-deep { + .ng-value-container{ + font-family: var(--font-family-poppins); + .ng-placeholder { + font-size: 13px; + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.ts new file mode 100644 index 000000000..a7cef8d9f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.ts @@ -0,0 +1,123 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Operand } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + + +@Component({ + selector: 'operand-v2', + templateUrl: './operand-new.component.html', + styleUrls: ['./operand-new.component.scss'] +}) +export class OperandV2Component implements OnInit { + + @Input() operand: Operand; + @Input() listOfFunctions: Array<{name: string, value: string, icon?:string}>; + @Output() onChangeOperand = new EventEmitter(); + + operandForm: FormGroup; + // listOfFunctions: Array<{name: string, value: string, icon?:string}> = []; + openSelectFunction: boolean = false; + panelOpenState: boolean = false; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor(private formBuild: FormBuilder) {} + + ngOnInit(): void { } + + ngOnChanges(changes) { + this.initialize(); + } + + private initialize(){ + this.operandForm = this.createOperandGroup(); + this.operandForm.valueChanges.subscribe(data => { + if(data.value !== '') { + this.operand.value = data.value; + this.operand.isVariable = data.isVariable; + } + if (data.function !== null) { + this.operand.function = data.function; + this.openSelectFunction = true; + this.panelOpenState = true; + } else { + delete(this.operand.function); + this.panelOpenState = false; + } + }); + if (this.operand) { + this.operandForm.patchValue(this.operand); + } + } + + //to do validate form + private createOperandGroup(): FormGroup { + return this.formBuild.group({ + value: ['', Validators.required], + isVariable: [false], + function: [null, Validators.nullValidator] + }) + } + + /** START EVENTS TEXTAREA **/ + onChangeTextArea(text: string) { + // if(text && text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))){ + // text = text.replace(text, text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))[0]); + // this.operandForm.get('value').setValue(text); + // this.operandForm.get('isVariable').setValue(true); + // this.onChangeOperand.emit(this.operand) + // } + // if(text){ + // this.onChangeOperand.emit(this.operand) + // } + } + + onBlur(event){ + this.onChangeOperand.emit(this.operand); + } + + onSelectedAttribute(variableSelected: { name: string, value: string }){ + // this.operandForm.get('isVariable').setValue(true); + // this.operandForm.get('value').setValue('{{' + variableSelected.value + '}}'); + this.onChangeOperand.emit(this.operand) + } + onClearSelectedAttribute(){ + this.operandForm.get('value').setValue(''); + this.operandForm.get('isVariable').setValue(false); + this.operand = this.operandForm.value + this.onChangeOperand.emit(this.operand) + } + /** END EVENTS TEXTAREA */ + + + onChangeIsCheckbox(event){ + this.operandForm.get('isVariable').setValue(event.checked); + this.onChangeOperand.emit(this.operand) + } + + onSelectedFunction(event: any) { + this.logger.log('[operand-v2] onSelectedFunction', this.operand, event); + if(event){ + this.operandForm.get('function').setValue(event.value); + } else { + this.operandForm.get('function').setValue(null); + } + this.onChangeOperand.emit(this.operand) + } + + onResetFunction(event: any) { + this.logger.log('[operand-v2] onResetFunction', this.operand, event); + if(!event){ + this.operandForm.get('function').setValue(null); + this.onChangeOperand.emit(this.operand); + } + } + + + onToggleSelectFunction(){ + this.openSelectFunction = !this.openSelectFunction; + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand.component.spec.ts new file mode 100644 index 000000000..026961e56 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperandComponent } from './operand.component'; + +describe('OperandComponent', () => { + let component: OperandComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperandComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperandComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.html new file mode 100644 index 000000000..5b13afc4b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.html @@ -0,0 +1,32 @@ + + +
+
+
+
+
+ delete +
+
+ + +
+ +
+ + +
+ + +
+
+
+ add + {{'CDSCanvas.NewOperation' | translate}} +
+ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss new file mode 100644 index 000000000..d5f15dc85 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss @@ -0,0 +1,107 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +.block-wrp { + display: flex; + flex-direction: column; + margin-bottom: 10px; + margin-top: 10px; + gap: 25px; +} + +.add-filter-button{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + margin: auto; + + user-select: none; + box-sizing: border-box; + outline: none; + border: 1px dashed var(--blu-light-02); + border-radius: var(--button-border-radius-base); + color: var(--blu-light-02); + cursor: pointer; + font-size: 0.7em; + font-weight: 400; + line-height: var(--button-height-base); + // margin: 0px 5px 0; + order: 1; + padding: 0 10px; + transition: all .3s; + min-width: 100px; + text-align: center; + width: fit-content; + + + &:hover{ + border-color: var(--textColor); + color: var(--textColor); + } +} + +.base-operand { + position: relative; + &:hover{ + div.filter-remove{ + opacity: 1; + transition: opacity 0.3s ease 0s; + } + } +} + +.basic-operator{ + display: flex; + justify-content: center; +} + + +.control-buttons{ + height: 100%; + left: -44px; + position: absolute; + top: 0px; + width: 44px; + + div.filter-remove{ + position: absolute; + right: -8px; + top: -14px; + transition: opacity 0.3s ease 0s; + opacity: 0; + height: 28px; + width: 28px; + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background:white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + span.material-icons, + span.material-icons-outlined { + font-size: 20px; + color: var(--textColor); + } + &:hover { + background-color: var(--hoverBackgroundColor); + } + } +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.ts new file mode 100644 index 000000000..561427530 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.ts @@ -0,0 +1,78 @@ +import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; +import { TYPE_MATH_OPERATOR } from '../../../../../../utils'; +import { Operand, Operation } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'operation-v2', + templateUrl: './operation-new.component.html', + styleUrls: ['./operation-new.component.scss'] +}) +export class OperationV2Component implements OnInit { + + @Input() operation: Operation; + @Input() listOfFunctions: Array<{name: string, value: string, icon?:string}>; + @Output() onChangeOperation = new EventEmitter(); + + list: Array< TYPE_MATH_OPERATOR | Operand | ''> = []; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void {} + + ngOnChanges(changes) { + if (this.operation) { + this.setList(this.operation); + } + } + + private setList(operation: Operation) { + this.list = []; + for (let i = 0; i < operation.operands.length; i++) { + this.list.push(operation.operands[i]); + if (i < operation.operands.length - 1) { + this.list.push(operation.operators[i]); + } + } + } + + onClickOperator() { + this.operation.operators.push(TYPE_MATH_OPERATOR['addAsNumber']); + this.operation.operands.push(new Operand()); + this.setList(this.operation) + this.onChangeOperation.emit(); + } + + onSelectedOperator(event: any, index: number) { + this.list[index] = TYPE_MATH_OPERATOR[event.value]; + index = Math.floor(index / 2); + this.operation.operators[index] = TYPE_MATH_OPERATOR[event.value]; + this.onChangeOperation.emit(); + } + + onChangeOperand(event: any, index: string) { + this.onChangeOperation.emit(); + } + + trackByIndex(index: number, obj: any): any { + return index; + } + + onDeleteGroup(index: number, last: boolean){ + this.logger.log('onDeleteGroup', index, last, this.operation, this.list) + if(!last){ + this.operation.operators.splice(index/2, 1) + this.operation.operands.splice(index/2, 1) + }else if(last){ + this.operation.operands.splice(index/2, 1) + if(this.operation.operators.length > 0){ + this.operation.operators.splice((index-1)/2, 1) + } + } + this.setList(this.operation) + this.onChangeOperation.emit(); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation.component.spec.ts new file mode 100644 index 000000000..751021452 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperationComponent } from './operation.component'; + +describe('OperationComponent', () => { + let component: OperationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperationComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.html new file mode 100644 index 000000000..68b1b79c7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.scss new file mode 100644 index 000000000..44cb7f1fa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.scss @@ -0,0 +1,27 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +.select-operand-button{ + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + padding: 8px 15px; + border: 1px solid #c6cdd4; + border-radius: 4px; + height: 43px; + color: #c6cdd4; + cursor: pointer; + margin-top: 20px; + max-width: 406.245px; + + &:hover{ + border-color: white; + color: white + } +} + +span.material-icons{ + font-size: 25px; + color: #8ab4f8; + margin-left: 10px; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.ts new file mode 100644 index 000000000..71afeedc0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator-new.component.ts @@ -0,0 +1,26 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TYPE_MATH_OPERATOR, TYPE_MATH_OPERATOR_LIST } from '../../../../../../utils'; + +@Component({ + selector: 'operator-v2', + templateUrl: './operator-new.component.html', + styleUrls: ['./operator-new.component.scss'] +}) +export class OperatorV2Component implements OnInit { + + @Input() operator: TYPE_MATH_OPERATOR; + @Output() operatorChange = new EventEmitter(); + listOfOperators: Array<{name: string, value: string, icon?:string}> = []; + + constructor() { } + + ngOnInit(): void { + for (let key in TYPE_MATH_OPERATOR_LIST) { + this.listOfOperators.push({name: TYPE_MATH_OPERATOR_LIST[key].name, value: TYPE_MATH_OPERATOR_LIST[key].type}) + } + } + + onSelectedOperator(event: any) { + this.operatorChange.emit(event); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator.component.spec.ts new file mode 100644 index 000000000..9b8f7f542 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operator/operator.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperatorComponent } from './operator.component'; + +describe('OperatorComponent', () => { + let component: OperatorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperatorComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperatorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.html new file mode 100644 index 000000000..f0162a233 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.html @@ -0,0 +1,71 @@ +
+ +
+
+ +
+
+ {{'CDSCanvas.AssignTo' | translate }}: +
+ +
+
+ {{action?.destination}} +
+
+ {{'CDSCanvas.SelectAttribute' | translate}} +
+
+
+ +
+
{{'CDSCanvas.Operations' | translate }}:
+
+
+
+
{{'CDSCanvas.Value' | translate }}:
+
+ {{ operand?.value}} +
+
+
+
{{'CDSCanvas.Function' | translate }}:
+
+ {{ getValue(operand?.function, 'operands').name | translate}} +
+
+
+ +
+ {{ getValue(action?.operation?.operators[index], 'operators').name | translate}} +
+
+ +
+ +
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss new file mode 100644 index 000000000..1cad14757 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss @@ -0,0 +1,167 @@ +::-webkit-scrollbar { + width: 0px; +} + + + +.material-icons { + color: var(--blu); + font-size: 16px; +} + +div { + + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } +} + +// cds-textarea#assignTo ::ng-deep { +// display: flex; + +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } + +.set-attribute-destination-label-and-value-wpr { + // background: #e8e6dd; + // padding: 3px; + display: flex; + align-items: center; + gap: 6px; +} + +.set-attribute-operands-wpr { + padding: 0px 10px; +} + + +.set-attribute-label-and-value-wpr { + display: flex; + gap: 6px; + align-items: center; +} + +.set-attribute-function { + color: #ecb606; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; +} + +.set-attribute-operator { + text-align: center; + border-bottom: 1px solid #6c6859d9; + line-height: 0.1em; + margin: 15px 15px; + color: #6c6859d9; + font-size: 12px; + font-weight: 400; +} + +.set-attribute-operator span { + background: #f4f3ee; + padding: 0 10px; +} + +.set-attribute { + font-size: 12px; + color: #ff4001; + font-weight: 400; +} + +.set-attribute-placeholder-wpr { + display: flex; + align-items: center; + gap: 6px; +} + +.set-attribute-placeholder-icon { + height: 18px; +} + + +.cds-action-preview{ + .action-row-left{ + width: unset; + } + + .set-attribute-label { + color: #6c6859d9; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; + // background: #e8e6dd; + padding: 0px 3px; + height: inherit; + } + + .set-attribute-value { + font-size: 10px; + font-weight: 400; + background: #ecb606; + width: fit-content; + padding: 0px 6px; + border-radius: 4px; + color: #fff; + // height: 18px; + line-height: 1.5; + + overflow: hidden; + word-break: break-word; + + } + + .icon-action img { + height: 16px; + filter: brightness(0) saturate(100%) invert(42%) sepia(2%) saturate(2720%) hue-rotate(9deg) brightness(91%) contrast(81%); + } + +} + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.ts new file mode 100644 index 000000000..3f49f6377 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.ts @@ -0,0 +1,104 @@ +import { ActionAssignVariable, Operand } from 'src/app/models/action-model'; +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { TYPE_MATH_OPERATOR, TYPE_FUNCTION_LIST_FOR_VARIABLES, TYPE_MATH_OPERATOR_LIST } from '../../../../../utils'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-assign-variable-new', + templateUrl: './cds-action-assign-variable-new.component.html', + styleUrls: ['./cds-action-assign-variable-new.component.scss'] +}) +export class CdsActionAssignVariableNewComponent implements OnInit, OnChanges { + @Input() action: ActionAssignVariable; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + listOfMathOperators: Array<{ name: string, value: string, src?: string }> = []; + listOfFunctions: Array<{ name: string, value: string, src?: string }> = []; + + + TYPE_FUNCTION_LIST_FOR_VARIABLES = TYPE_FUNCTION_LIST_FOR_VARIABLES + TYPE_MATH_OPERATOR_LIST = TYPE_MATH_OPERATOR_LIST + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor() { } + + ngOnInit(): void { + this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] action ', this.action) + const operands = this.action.operation.operands + const operators = this.action.operation.operators + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operands ', operands) + this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators ', operators) + + // for (let i = 0; i < operands.length; i++) { + // for (let key in TYPE_FUNCTION_LIST_FOR_VARIABLES) { + // let _function = operands[i].function + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operand _function (2)' , _function) + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] TYPE_FUNCTION_LIST_FOR_VARIABLES key ' ,TYPE_FUNCTION_LIST_FOR_VARIABLES[key]) + // if (_function === TYPE_FUNCTION_LIST_FOR_VARIABLES[key].type) { + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] >>>>>> operand ', operands[i]) + // operands[i]['functionName'] = TYPE_FUNCTION_LIST_FOR_VARIABLES[key].name + // } + // } + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operands -xx', operands[i]) + // if (operands[i].value === '') { + // this.displaySetOperationPlaceholder = false + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] displaySetOperationPlaceholder -xx', this.displaySetOperationPlaceholder) + // } + // for (let j = 0; j < operators.length; j++) { + // // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operator ---xx>', operators) + // if (operands.length - 1) { + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators j -xx>', operators[j]) + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators i -xx>', operators[i]) + // this.logger.log('[CDS-ACTION-ASSIGN-VARIABLE] operators i TYPE_MATH_OPERATOR[operators[i]] -xx>', TYPE_MATH_OPERATOR[operators[i]]) + // // operands[i]['operator'] = TYPE_MATH_OPERATOR[operators[j]] + // for (let key in TYPE_MATH_OPERATOR_LIST) { + // if (operators[i] === TYPE_MATH_OPERATOR_LIST[key].type) { + // operands[i]['operator'] = TYPE_MATH_OPERATOR_LIST[key].name + // } + // } + + // } + // } + // } + + } + + getValue(key: string, type: 'operands' | 'operators'): any{ + // return TYPE_FUNCTION_LIST_FOR_VARIABLES[key] + if(type === 'operands'){ + return this.listOfFunctions.filter(el => el.value === key)[0] + } + if(type === 'operators'){ + return this.listOfMathOperators.filter(el => el.value === key)[0] + } + + } + + initialize() { + for (let key in TYPE_FUNCTION_LIST_FOR_VARIABLES) { + this.listOfFunctions.push({ name: TYPE_FUNCTION_LIST_FOR_VARIABLES[key].name, value: TYPE_FUNCTION_LIST_FOR_VARIABLES[key].type, src: TYPE_FUNCTION_LIST_FOR_VARIABLES[key].src}); + } + for (let key in TYPE_MATH_OPERATOR_LIST) { + this.listOfMathOperators.push({ name: TYPE_MATH_OPERATOR_LIST[key].name, value: TYPE_MATH_OPERATOR_LIST[key].type, src: TYPE_MATH_OPERATOR_LIST[key].src}); + } + } + + onSelectedAttribute(variableSelected: { name: string, value: string }) { + this.action.destination = variableSelected.value; + this.updateAndSaveAction.emit() + } + + onChangeOperation(event) { + // let temp = this.action.operation; + // this.action.operation.operators.push(TYPE_MATH_OPERATOR['addAsNumber']); + // this.action.operation.operands.push(new Operand()); + // this.action.operation = Object.assign({}, temp); + this.updateAndSaveAction.emit(); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable.component.spec.ts new file mode 100644 index 000000000..a001a8f77 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionAssignVariableComponent } from './cds-action-assign-variable.component'; + +describe('CdsActionAssignVariableComponent', () => { + let component: CdsActionAssignVariableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionAssignVariableComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionAssignVariableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.html new file mode 100644 index 000000000..34a647cc0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.html @@ -0,0 +1,39 @@ +
+ +
+
+ + + +
+
+ + settings +
+ + + +
+ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss new file mode 100644 index 000000000..7de469476 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss @@ -0,0 +1,92 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +div.operand-wrp { + display: grid; + align-items: center; + grid-template-columns: 11fr 1fr; + grid-column-gap: 0px; + grid-row-gap: 10px; + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + padding: 10px 10px 20px; + border-radius: 4px; + &.opened { + .select-function{ + display:block; + } + } + .select-function{ + display:none; + } + + .material-icons { + font-size: 25px; + color: var(--icon-color); + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + margin-top: 20px; + } + + div.value-wrp{ + position: relative; + display: block; + } + + .applay-function-button{ + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + padding: 8px 15px; + border: 1px solid #c6cdd4; + border-radius: 4px; + height: 43px; + color: #c6cdd4; + cursor: pointer; + + &:hover{ + border-color: white; + color: white + } + } +} + +// cds-textarea#operand ::ng-deep { +// display: flex; +// width: 100%; +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// width: calc(100% - 45px); +// } +// textarea::placeholder { +// font-family: var(--font-family-poppins) +// font-size: 13px; +// } +// } + + +cds-select#selectOperand ::ng-deep { + .ng-value-container{ + font-family: var(--font-family-poppins); + .ng-placeholder { + font-size: 13px; + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.ts new file mode 100644 index 000000000..a0385263a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.ts @@ -0,0 +1,107 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Operand } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + + +@Component({ + selector: 'operand', + templateUrl: './operand-new.component.html', + styleUrls: ['./operand-new.component.scss'] +}) +export class OperandComponent implements OnInit { + + @Input() operand: Operand; + @Input() listOfFunctions: Array<{name: string, value: string, icon?:string}>; + @Output() onChangeOperand = new EventEmitter(); + + operandForm: FormGroup; + // listOfFunctions: Array<{name: string, value: string, icon?:string}> = []; + openSlectFunction: boolean; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor(private formBuild: FormBuilder) {} + + ngOnInit(): void { + this.openSlectFunction = false; + // this.initialize(); + } + + ngOnChanges(changes){ + this.initialize(); + } + + private initialize(){ + this.operandForm = this.createOperandGroup(); + this.operandForm.valueChanges.subscribe(data => { + if(data.value !== '') { + this.operand.value = data.value; + this.operand.isVariable = data.isVariable; + } + if (data.function !== null) { + this.operand.function = data.function; + } else { + delete(this.operand.function); + } + }); + if (this.operand) { + this.operandForm.patchValue(this.operand); + } + } + + //to do validate form + private createOperandGroup(): FormGroup { + return this.formBuild.group({ + value: ['', Validators.required], + isVariable: [false], + function: [null, Validators.nullValidator] + }) + } + + /** START EVENTS TEXTAREA **/ + onChangeTextArea(text: string) { + // if(text && text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))){ + // text = text.replace(text, text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))[0]); + // this.operandForm.get('value').setValue(text); + // this.operandForm.get('isVariable').setValue(true); + // this.onChangeOperand.emit(this.operand) + // } + // if(text){ + // this.onChangeOperand.emit(this.operand) + // } + } + + onBlur(event){ + this.onChangeOperand.emit(this.operand); + } + + onSelectedAttribute(variableSelected: { name: string, value: string }){ + this.operandForm.get('isVariable').setValue(true); + this.operandForm.get('value').setValue(variableSelected.name); + this.onChangeOperand.emit(this.operand) + } + onClearSelectedAttribute(){ + this.operandForm.get('value').setValue(''); + this.operandForm.get('isVariable').setValue(false); + this.operand = this.operandForm.value + this.onChangeOperand.emit(this.operand) + } + /** END EVENTS TEXTAREA */ + + + onSelectedFunction(event: any) { + if(event){ + this.operandForm.get('function').setValue(event.value); + } else { + this.operandForm.get('function').setValue(null); + } + this.onChangeOperand.emit(this.operand) + } + + onToggleSelectFunction(){ + this.openSlectFunction = !this.openSlectFunction; + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand.component.spec.ts new file mode 100644 index 000000000..026961e56 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperandComponent } from './operand.component'; + +describe('OperandComponent', () => { + let component: OperandComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperandComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperandComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.html new file mode 100644 index 000000000..a7ef8a7c7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.html @@ -0,0 +1,32 @@ + + +
+
+
+
+
+ delete +
+
+ + +
+ +
+ + +
+ + +
+
+
+ add + {{'CDSCanvas.NewOperation' | translate}} +
+ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss new file mode 100644 index 000000000..d5f15dc85 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss @@ -0,0 +1,107 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +.block-wrp { + display: flex; + flex-direction: column; + margin-bottom: 10px; + margin-top: 10px; + gap: 25px; +} + +.add-filter-button{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + margin: auto; + + user-select: none; + box-sizing: border-box; + outline: none; + border: 1px dashed var(--blu-light-02); + border-radius: var(--button-border-radius-base); + color: var(--blu-light-02); + cursor: pointer; + font-size: 0.7em; + font-weight: 400; + line-height: var(--button-height-base); + // margin: 0px 5px 0; + order: 1; + padding: 0 10px; + transition: all .3s; + min-width: 100px; + text-align: center; + width: fit-content; + + + &:hover{ + border-color: var(--textColor); + color: var(--textColor); + } +} + +.base-operand { + position: relative; + &:hover{ + div.filter-remove{ + opacity: 1; + transition: opacity 0.3s ease 0s; + } + } +} + +.basic-operator{ + display: flex; + justify-content: center; +} + + +.control-buttons{ + height: 100%; + left: -44px; + position: absolute; + top: 0px; + width: 44px; + + div.filter-remove{ + position: absolute; + right: -8px; + top: -14px; + transition: opacity 0.3s ease 0s; + opacity: 0; + height: 28px; + width: 28px; + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background:white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + span.material-icons, + span.material-icons-outlined { + font-size: 20px; + color: var(--textColor); + } + &:hover { + background-color: var(--hoverBackgroundColor); + } + } +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.ts new file mode 100644 index 000000000..f7876459d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.ts @@ -0,0 +1,79 @@ +import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; +import { TYPE_MATH_OPERATOR } from '../../../../../../utils'; +import { Operand, Operation } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'operation', + templateUrl: './operation-new.component.html', + styleUrls: ['./operation-new.component.scss'] +}) +export class OperationComponent implements OnInit { + + @Input() operation: Operation; + @Input() listOfFunctions: Array<{name: string, value: string, icon?:string}>; + @Output() onChangeOperation = new EventEmitter(); + + list: Array< TYPE_MATH_OPERATOR | Operand | ''> = []; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void {} + + ngOnChanges(changes) { + if (this.operation) { + this.setList(this.operation); + } + } + + private setList(operation: Operation) { + this.list = []; + for (let i = 0; i < operation.operands.length; i++) { + this.list.push(operation.operands[i]); + if (i < operation.operands.length - 1) { + this.list.push(operation.operators[i]); + } + } + } + + onClickOperator() { + this.operation.operators.push(TYPE_MATH_OPERATOR['addAsNumber']); + this.operation.operands.push(new Operand()); + this.setList(this.operation) + this.onChangeOperation.emit(); + } + + onSelectedOperator(event: any, index: number) { + this.list[index] = TYPE_MATH_OPERATOR[event.value]; + index = Math.floor(index / 2); + this.operation.operators[index] = TYPE_MATH_OPERATOR[event.value]; + this.onChangeOperation.emit(); + } + + onChangeOperand(event: any, index: string) { + this.operation.operands[index]= event + this.onChangeOperation.emit(); + } + + trackByIndex(index: number, obj: any): any { + return index; + } + + onDeleteGroup(index: number, last: boolean){ + this.logger.log('onDeleteGroup', index, last, this.operation, this.list) + if(!last){ + this.operation.operators.splice(index/2, 1) + this.operation.operands.splice(index/2, 1) + }else if(last){ + this.operation.operands.splice(index/2, 1) + if(this.operation.operators.length > 0){ + this.operation.operators.splice((index-1)/2, 1) + } + } + this.setList(this.operation) + this.onChangeOperation.emit(); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation.component.spec.ts new file mode 100644 index 000000000..751021452 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperationComponent } from './operation.component'; + +describe('OperationComponent', () => { + let component: OperationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperationComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.html new file mode 100644 index 000000000..68b1b79c7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.scss new file mode 100644 index 000000000..44cb7f1fa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.scss @@ -0,0 +1,27 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +.select-operand-button{ + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + padding: 8px 15px; + border: 1px solid #c6cdd4; + border-radius: 4px; + height: 43px; + color: #c6cdd4; + cursor: pointer; + margin-top: 20px; + max-width: 406.245px; + + &:hover{ + border-color: white; + color: white + } +} + +span.material-icons{ + font-size: 25px; + color: #8ab4f8; + margin-left: 10px; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.ts new file mode 100644 index 000000000..8f841ad13 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator-new.component.ts @@ -0,0 +1,26 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TYPE_MATH_OPERATOR, TYPE_MATH_OPERATOR_LIST } from '../../../../../../utils'; + +@Component({ + selector: 'operator', + templateUrl: './operator-new.component.html', + styleUrls: ['./operator-new.component.scss'] +}) +export class OperatorComponent implements OnInit { + + @Input() operator: TYPE_MATH_OPERATOR; + @Output() operatorChange = new EventEmitter(); + listOfOperators: Array<{name: string, value: string, icon?:string}> = []; + + constructor() { } + + ngOnInit(): void { + for (let key in TYPE_MATH_OPERATOR_LIST) { + this.listOfOperators.push({name: TYPE_MATH_OPERATOR_LIST[key].name, value: TYPE_MATH_OPERATOR_LIST[key].type}) + } + } + + onSelectedOperator(event: any) { + this.operatorChange.emit(event); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator.component.spec.ts new file mode 100644 index 000000000..9b8f7f542 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operator/operator.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperatorComponent } from './operator.component'; + +describe('OperatorComponent', () => { + let component: OperatorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OperatorComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OperatorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.html new file mode 100644 index 000000000..418333a75 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.html @@ -0,0 +1,184 @@ +
+ +
+ + + {{ action.method}} + + +
+ + +
+ +
+ +
+ + + + +
+ +
+ +
+ + + +
+
+ + +
+ + +
+ + + +
+ + {{'CDSCanvas.ManageIntegration' | translate}} + +
+ +
+
+
+ +
+ {{'CDSCanvas.Success' | translate }} +
+ + +
+ +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + +
+ +
+ + + + + {{'CDSCanvas.Advanced' | translate }} + + +
+ +
+ + + +
+ +
+ + + +
+ + +
+ + + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss new file mode 100644 index 000000000..e4c355de6 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss @@ -0,0 +1,103 @@ +::-webkit-scrollbar { + width: 0px; +} +:host { + --background-color: #{var(--blu-light-01)}; + //--slider-background-color: #{$blu-light-03}; + --text-color: #{var(--blu)}; +} + + +/** button TOOGLE */ +mat-button-toggle-group ::ng-deep{ + border: unset; + border-radius: 0px; +} + +mat-button-toggle{ + background-color: transparent; + border: none; + color: var(--blu-light-02); + border-bottom: 2px solid transparent; + + &.mat-button-toggle-checked{ + border-color: var(--blu); + color: var(--blu); + font-weight: 400; + + } + + &.mat-button-toggle+mat-button-toggle.mat-button-toggle{ + border-left: none; + } + + &::ng-deep .mat-button-toggle-label-content { + line-height: 36px; + } + +} + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + + +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.ts new file mode 100644 index 000000000..7b44bab3f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.ts @@ -0,0 +1,230 @@ +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; +import { ActionBrevo } from 'src/app/models/action-model'; + +//SERVICES +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-brevo-new', + templateUrl: './cds-action-brevo-new.component.html', + styleUrls: ['./cds-action-brevo-new.component.scss'] +}) +export class CdsActionBrevoNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionBrevo; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonParameters: string; + errorMessage: string; + + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService, + private appConfigService: AppConfigService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-BREVO] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-BREVO] isChangedConnector -->', connector); + this.connector = connector; + this.updateConnector(); + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-BREVO] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-BREVO] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // private updateConnector(){ + // try { + // const array = this.connector.fromId.split("/"); + // const idAction= array[1]; + // if(idAction === this.action._tdActionId){ + // if(this.connector.deleted){ + // if(array[array.length -1] === 'true'){ + // this.action.trueIntent = null + // this.isConnectedTrue = false + // } + // if(array[array.length -1] === 'false'){ + // this.action.falseIntent = null + // this.isConnectedFalse = false; + // } + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } else { + // this.logger.debug('[ACTION-CUSTOMER] updateConnector', this.connector.toId, this.connector.fromId ,this.action, array[array.length-1]); + // if(array[array.length -1] === 'true'){ + // this.isConnectedTrue = true; + // this.action.trueIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // if(array[array.length -1] === 'false'){ + // this.isConnectedFalse = true; + // if(this.action.falseIntent !== '#'+this.connector.toId){ + // this.action.falseIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // } + // } + + // } + // } catch (error) { + // this.logger.error('[ACTION-ASKGPT] updateConnector error: ', error); + // } + // } + + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.jsonParameters = this.action.bodyParameters; + if(this.intentSelected){ + this.initializeConnector(); + } + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'brevo_status')) { + new_attributes.push({ name: "brevo_status", value: "brevo_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'brevo_error')) { + new_attributes.push({ name: "brevo_error", value: "brevo_error" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'brevo_result')) { + new_attributes.push({ name: "brevo_result", value: "brevo_result" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION-BREVO] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined').elements); + } + + + + + // EVENT FUNCTIONS // + onChangeTextarea(e, type){ + this.logger.log('type; ', type); + } + + + onChangeAttributes(attributes:any){ + this.logger.log('[ACTION-BREVO]onChangeAttributes ',attributes); + this.action.bodyParameters = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-BREVO] onEditableDivTextChange event", event) + this.logger.log("[ACTION-BREVO] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToIntegration(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + this.action._tdActionType + window.open(url, '_blank') + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo.component.spec.ts new file mode 100644 index 000000000..bd6fc2c3a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionBrevoComponent } from './cds-action-brevo.component'; + +describe('CdsActionBrevoComponent', () => { + let component: CdsActionBrevoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionBrevoComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionBrevoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.html new file mode 100644 index 000000000..f2286e5b9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.html @@ -0,0 +1,80 @@ +
+ + + + + +
+ + + + + +
+ +
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.scss new file mode 100644 index 000000000..0694a9e0a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.scss @@ -0,0 +1,13 @@ +.previewContent#capture-user-reply { + justify-content: flex-start; +} + +.title-preview-label > span{ + font-weight: 600; +} +.action-row-right.empty{ + font-style: italic; + color: var(--brown) !important; +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.ts new file mode 100644 index 000000000..3806b9a17 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply-new.component.ts @@ -0,0 +1,153 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { IntentService } from '../../../../../services/intent.service'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { ActionCaptureUserReply } from 'src/app/models/action-model'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; +import { checkConnectionStatusByConnector, updateSingleConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-capture-user-reply-new', + templateUrl: './cds-action-capture-user-reply-new.component.html', + styleUrls: ['./cds-action-capture-user-reply-new.component.scss'] +}) +export class CdsActionCaptureUserReplyNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionCaptureUserReply; + @Input() previewMode: boolean = true; + @Input() project_id: string; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnector: string; + idConnection: string; + isConnected: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService + ) { } + + ngOnInit(): void { + this.logger.debug("[ACTION-CAPTURE-USER-REPLY] action detail: ", this.action); + + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-CAPTURE-USER-REPLY] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateSingleConnector(); + } + }); + this.initializeConnector(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.logger.debug("Intent Selected: ", this.intentSelected); + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnector = this.idIntentSelected+'/'+this.action._tdActionId; + this.listOfIntents = this.intentService.getListOfIntents(); + this.listOfIntents.sort((a, b) => a.name.localeCompare(b.name)); + this.checkConnectionStatus(); + } + + // private checkConnectionStatus(){ + // if(this.action.goToIntent){ + // this.isConnected = true; + // const posId = this.action.goToIntent.indexOf("#"); + // if (posId !== -1) { + // const toId = this.action.goToIntent.slice(posId+1); + // this.idConnection = this.idConnector+"/"+toId; + // } + // } else { + // this.isConnected = false; + // this.idConnection = null; + // } + // } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusByConnector(this.action.goToIntent, this.idConnector); + this.isConnected = resp.isConnected; + this.idConnection = resp.idConnection; + } + + + /** */ + private updateSingleConnector(){ + this.logger.log('[ACTION-CAPTURE-USER-REPLY] updateSingleConnector:'); + const resp = updateSingleConnector(this.connector, this.action, this.isConnected, this.idConnection); + if(resp){ + this.isConnected = resp.isConnected; + this.idConnection = resp.idConnection; + this.logger.log('[ACTION-CAPTURE-USER-REPLY] updateSingleConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + // private updateConnector2(){ + // try { + // const array = this.connector.fromId.split("/"); + // const idAction= array[1]; + // if(idAction === this.action._tdActionId){ + // if(this.connector.deleted){ + // // DELETE + // this.action.goToIntent = null; + // this.isConnected = false; + // this.idConnection = null; + // } else { + // // ADD / EDIT + // this.isConnected = true; + // this.idConnection = this.connector.fromId+"/"+this.connector.toId; + // this.action.goToIntent = "#"+this.connector.toId; + // }; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // } catch (error) { + // this.logger.error('[ACTION-CAPTURE-USER-REPLY] updateConnector error: ', error); + // } + // } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-CAPTURE-USER-REPLY] onEditableDivTextChange event", event) + this.logger.log("[ACTION-CAPTURE-USER-REPLY] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: string) { + if(event){ + this.action[type] = event.value; + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnector, toId: this.action.goToIntent }); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: string) { + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnector, toId: this.action.goToIntent }); + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply.component.spec.ts new file mode 100644 index 000000000..70848f177 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-capture-user-reply/cds-action-capture-user-reply.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionCaptureUserReplyComponent } from './cds-action-capture-user-reply.component'; + +describe('CdsActionCaptureUserReplyComponent', () => { + let component: CdsActionCaptureUserReplyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionCaptureUserReplyComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionCaptureUserReplyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.html new file mode 100644 index 000000000..c18ce2790 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.html @@ -0,0 +1,39 @@ + +
+ +
+
+ + + + + +
+ +
+ {{action?.depName}} +
+
+ {{'CDSCanvas.SelectADepartment' | translate }} +
+
+ +
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.ts new file mode 100644 index 000000000..b788db021 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department-new.component.ts @@ -0,0 +1,51 @@ +import { DepartmentService } from 'src/app/services/department.service'; +import { ActionChangeDepartment } from 'src/app/models/action-model'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Department } from 'src/app/models/department-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { DashboardService } from 'src/app/services/dashboard.service'; + +@Component({ + selector: 'cds-action-change-department-new', + templateUrl: './cds-action-change-department-new.component.html', + styleUrls: ['./cds-action-change-department-new.component.scss'] +}) +export class CdsActionChangeDepartmentNewComponent implements OnInit { + + @Input() action: ActionChangeDepartment; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + departments: Department[] + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private dashboardService: DashboardService, + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION CHANGE DEPARTMENT] action: ", this.action) + + this.departments = this.dashboardService.departments + this.logger.log("[ACTION CHANGE DEPARTMENT] action: ", this.departments) + //FIX: if chatbot is imported from other env/project --> reset selectedDepartmentId + if(this.action.depName){ + let actionDepIndex = this.departments.findIndex(dep => dep.name === this.action.depName) + this.logger.log("[ACTION CHANGE DEPARTMENT] actionDepIndex: ", actionDepIndex) + if(actionDepIndex === -1){ + this.action.depName = null; + } + } + } + + + onChangeSelect(event: {name: string, value: string}) { + this.logger.log("[ACTION REPLACE BOT] onChangeActionButton event: ", event) + this.action.depName = event.name; + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action edited: ", this.action) + } + + +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department.component.spec.ts new file mode 100644 index 000000000..2d99f6e6f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-change-department/cds-action-change-department.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionChangeDepartmentComponent } from './cds-action-change-department.component'; + +describe('CdsActionChangeDepartmentComponent', () => { + let component: CdsActionChangeDepartmentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionChangeDepartmentComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionChangeDepartmentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.html new file mode 100644 index 000000000..ec154dbb2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.html @@ -0,0 +1,9 @@ +
+
+ +
+
+ +
+
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.scss new file mode 100644 index 000000000..280a86d19 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.scss @@ -0,0 +1,5 @@ +.cds-action-preview{ + .action-row{ + justify-content: center; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.ts new file mode 100644 index 000000000..f47e4c319 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript-new.component.ts @@ -0,0 +1,22 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { ActionClearTranscript } from 'src/app/models/action-model'; + +@Component({ + selector: ' selector: 'cds-action-clear-transcript-new',-new', + templateUrl: './cds-action-clear-transcript-new.component.html', + styleUrls: ['./cds-action-clear-transcript-new.component.scss'] +}) +export class CdsActionClearTranscriptNewComponent implements OnInit { + + @Input() action: ActionClearTranscript; + @Input() previewMode: boolean = true; + + actions = ACTIONS_LIST + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript.component.spec.ts new file mode 100644 index 000000000..77919298b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-clear-transcript/cds-action-clear-transcript.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionClearTranscriptComponent } from './cds-action-clear-transcript.component'; + +describe('CdsClearTranscriptComponent', () => { + let component: CdsActionClearTranscriptComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionClearTranscriptComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionClearTranscriptComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.html new file mode 100644 index 000000000..db47a66f9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.html @@ -0,0 +1,9 @@ +
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.scss new file mode 100644 index 000000000..280a86d19 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.scss @@ -0,0 +1,5 @@ +.cds-action-preview{ + .action-row{ + justify-content: center; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.ts new file mode 100644 index 000000000..e6228e971 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close-new.component.ts @@ -0,0 +1,23 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { ActionClose } from 'src/app/models/action-model'; + +@Component({ + selector: ' selector: 'cds-action-close-new',-new', + templateUrl: './cds-action-close-new.component.html', + styleUrls: ['./cds-action-close-new.component.scss'] +}) +export class CdsActionCloseNewComponent implements OnInit { + + @Input() action: ActionClose; + @Input() previewMode: boolean = true; + + actions = ACTIONS_LIST + + constructor() { } + + ngOnInit(): void { + // // empty + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close.component.spec.ts new file mode 100644 index 000000000..5e64a4584 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-close/cds-action-close.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionCloseComponent } from './cds-action-close.component'; + +describe('ActionCloseComponent', () => { + let component: CdsActionCloseComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionCloseComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionCloseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.html new file mode 100644 index 000000000..4400170bf --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.html @@ -0,0 +1,25 @@ +
+
{{action.source}}
+
{{'CDSCanvas.ClickToAddCodeSource' | translate }}
+
+ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.scss new file mode 100644 index 000000000..99029d25d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.scss @@ -0,0 +1,6 @@ + +.limit-content { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.ts new file mode 100644 index 000000000..251888e6d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code-new.component.ts @@ -0,0 +1,38 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { ActionCode } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-code-new', + templateUrl: './cds-action-code-new.component.html', + styleUrls: ['./cds-action-code-new.component.scss'] +}) +export class CdsActionCodeNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionCode; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void { + this.logger.log("[ACTION CODE] action:", this.action); + } + + + onChangeTextarea(text){ + this.action.source = text; + this.logger.log("[ACTION MAKE] this.action", this.action); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code.component.spec.ts new file mode 100644 index 000000000..629418ec1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-code/cds-action-code.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionCodeComponent } from './cds-action-code.component'; + +describe('CdsActionCodeComponent', () => { + let component: CdsActionCodeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionCodeComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionCodeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.html new file mode 100644 index 000000000..c17ddbdf8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.html @@ -0,0 +1,40 @@ +
+ +
+ + + +
+ +
+ +
+ + + +
+ + + + +
+ + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.ts new file mode 100644 index 000000000..41566bc2c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block-new.component.ts @@ -0,0 +1,129 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { ActionConnectBlock } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { checkConnectionStatusByConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-connect-block-new', + templateUrl: './cds-action-connect-block-new.component.html', + styleUrls: ['./cds-action-connect-block-new.component.scss'] +}) +export class CdsActionConnectBlockNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionConnectBlock; + @Input() previewMode: boolean = true; + + @Output() updateIntentFromConnectorModification = new EventEmitter(); + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter(); //{type: 'create' | 'delete', fromId: string, toId: string} + + intents: Array<{name: string, value: string, icon?:string}> + idIntentSelected: string; + idConnector: string; + idConnection: string; + isConnected: boolean = false; + connector: any; + element: any; + private subscriptionChangedConnector: Subscription; + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private intentService: IntentService + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.log('[CDS-ACTION-CONNECT-BLOCK] - subcribe to isChangedConnector$ >>', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusByConnector(this.action.intentName, this.idConnector); + this.isConnected = resp.isConnected; + this.idConnection = resp.idConnection; + } + + private initialize() { + // // this.logger.log('[CDS-ACTION-INTENT] - initialize - isConnected ', this.action.intentName); + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnector = this.idIntentSelected+'/'+this.action._tdActionId; + this.intents = this.intentService.getListOfIntents(); + this.intents.sort((a, b) => a.name.localeCompare(b.name)); + this.element = Object.values(ACTIONS_LIST).find(el => el.type === this.action._tdActionType); + this.checkConnectionStatus(); + this.logger.log('[CDS-ACTION-INTENT] - initialize - idIntentSelected ', this.idIntentSelected); + this.logger.log('[CDS-ACTION-INTENT] - initialize - idConnector ', this.idConnector); + this.logger.log('[CDS-ACTION-INTENT] - initialize - intents ', this.intents); + } + + private updateConnector(){ + this.logger.log('[CDS-ACTION-INTENT] **************************2222', this.action.intentName); + this.isConnected = this.action.intentName?true:false; + const array = this.connector.fromId.split("/"); + const idIntent= array[0]; + const idAction= array[1]; + if(this.idIntentSelected !== idIntent){ + return; + } + try { + if(!this.action.intentName)this.isConnected = false; + else this.isConnected = true; + if(idAction === this.action._tdActionId ){ + this.logger.log('[CDS-ACTION-INTENT] - updateConnector :: ', idAction, this.action._tdActionId, this.connector); + if(this.connector.deleted){ + this.action.intentName = null; + this.isConnected = false; + this.idConnection = null; + } else { + this.isConnected = true; + this.idConnection = this.connector.fromId+"/"+this.connector.toId; + this.action.intentName = "#"+this.connector.toId; + } + if(this.connector.save) + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + } + } catch (error) { + this.logger.log('error: ', error); + } + } + + onChangeSelect(event: {name: string, value: string}){ + if(event){ + this.action.intentName = event.value; + if(!this.action._tdActionTitle){ + this.action._tdActionTitle = this.intents.find(intent => intent.value === event.value).name; + } + let connector = { type: 'create', fromId: this.idConnector, toId: this.action.intentName }; + this.onConnectorChange.emit(connector); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: JSON.parse(JSON.stringify(this.action))}); + } + } + + onResetSelect(event:{name: string, value: string}) { + let connector = { type: 'delete', fromId: this.idConnector, toId: this.action.intentName }; + this.action.intentName = null; + this.onConnectorChange.emit(connector); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: JSON.parse(JSON.stringify(this.action))}); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block.component.spec.ts new file mode 100644 index 000000000..3da74a349 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-connect-block/cds-action-connect-block.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionConnectBlockComponent } from './cds-action-connect-block.component'; + +describe('CdsActionConnectBlockComponent', () => { + let component: CdsActionConnectBlockComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionConnectBlockComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionConnectBlockComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.html new file mode 100644 index 000000000..954ed92f8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.html @@ -0,0 +1,166 @@ +
+ +
+ + + {{ action.method}} + + +
+ +
+ {{action.formid}} +
+
+ {{'CDSCanvas.EntercustomerioFormId' | translate }} +
+
+ +
+ +
+ + + + +
+ +
+ +
+ + + +
+
+ + +
+ +
+ + + +
+ +
+ + + +
+ + {{'CDSCanvas.ManageIntegration' | translate}} + +
+ +
+
+
+ +
+ {{'CDSCanvas.Success' | translate }} +
+ + +
+ +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + +
+ +
+ + + + + {{'CDSCanvas.Advanced' | translate }} + + +
+ +
+ + + +
+ + +
+ + + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss new file mode 100644 index 000000000..a753caa1c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss @@ -0,0 +1,105 @@ + +::-webkit-scrollbar { + width: 0px; +} +:host { + --background-color: #{var(--blu-light-01)}; + //--slider-background-color: #{$blu-light-03}; + --text-color: #{var(--blu)}; +} + +/** button TOOGLE */ +mat-button-toggle-group ::ng-deep{ + border: unset; + border-radius: 0px; +} + +mat-button-toggle{ + background-color: transparent; + border: none; + color: var(--blu-light-02); + border-bottom: 2px solid transparent; + + &.mat-button-toggle-checked{ + border-color: var(--blu); + color: var(--blu); + font-weight: 400; + + } + + &.mat-button-toggle+mat-button-toggle.mat-button-toggle{ + border-left: none; + } + + &::ng-deep .mat-button-toggle-label-content { + line-height: 36px; + } + +} + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.ts new file mode 100644 index 000000000..c3f9849ef --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.ts @@ -0,0 +1,205 @@ +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; +import { ActionCustomerio } from 'src/app/models/action-model'; + +//SERVICES +import { IntentService } from '../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: ' selector: 'cds-action-customerio-new',-new', + templateUrl: './cds-action-customerio-new.component.html', + styleUrls: ['./cds-action-customerio-new.component.scss'] +}) +export class CdsActionCustomerioNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionCustomerio; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonParameters: string; + errorMessage: string; + + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService, + private appConfigService: AppConfigService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-CUSTOMERIO] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-CUSTOMERIO] isChangedConnector -->', connector); + this.connector = connector; + this.updateConnector(); + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-CUSTOMERIO] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-CUSTOMERIO] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.jsonParameters = this.action.bodyParameters; + if(this.intentSelected){ + this.initializeConnector(); + } + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'customerio_status')) { + new_attributes.push({ name: "customerio_status", value: "customerio_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'customerio_error')) { + new_attributes.push({ name: "customerio_error", value: "customerio_error" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION-CUSTOMERIO] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined').elements); + } + + + + + // EVENT FUNCTIONS // + onChangeTextarea(e, type){ + this.logger.log('type; ', type); + switch(type){ + // case 'token' : { + // this.action.token = e; + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + // } + // break; + case 'formid' : { + this.action.formid = e; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + this.logger.log("[ACTION-CUSTOMERIO] this.action", this.action); + } + break; + } + + } + + + onChangeAttributes(attributes:any){ + this.logger.log('[ACTION-CUSTOMERIO]onChangeAttributes ',attributes); + this.action.bodyParameters = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-CUSTOMERIO] onEditableDivTextChange event", event) + this.logger.log("[ACTION-CUSTOMERIO] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToIntegration(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + this.action._tdActionType + window.open(url, '_blank') + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio.component.spec.ts new file mode 100644 index 000000000..6e7b319e8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionCustomerioComponent } from './cds-action-customerio.component'; + +describe('CdsActionCustomerioComponent', () => { + let component: CdsActionCustomerioComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionCustomerioComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionCustomerioComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.html new file mode 100644 index 000000000..153fc2747 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.html @@ -0,0 +1,36 @@ +
+ +
+ +
+ {{action?.variableName}} +
+
+ {{'CDSCanvas.SetVariableToDelete' | translate }} +
+
+ +
+ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.scss new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.scss @@ -0,0 +1,2 @@ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.ts new file mode 100644 index 000000000..cf8c67711 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable-new.component.ts @@ -0,0 +1,60 @@ +import { Component, EventEmitter, Input, OnInit, Output, ElementRef } from '@angular/core'; + +//MODELS +import { ActionDeleteVariable } from 'src/app/models/action-model'; + +//SERVICES +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { TranslateService } from '@ngx-translate/core'; + +//UTILS +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; + +@Component({ + selector: ' selector: 'cds-action-delete-variable-new',-new', + templateUrl: './cds-action-delete-variable-new.component.html', + styleUrls: ['./cds-action-delete-variable-new.component.scss'] +}) +export class CdsActionDeleteVariableNewComponent implements OnInit { + + @Input() action: ActionDeleteVariable; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + variableListUserDefined: Array<{name: string, value: string}>; + variableListSystemDefined: Array<{ key: string, elements: Array<{name: string, value: string, description: string, src?: string}>}> //= variableList.systemDefined + filteredList: Array<{name: string, value: string, category: string}> = []; + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private translate: TranslateService + ) { } + + ngOnInit(): void { + } + + ngOnChanges() { + this.initialize(); + } + + private initialize() { + // this.logger.log('action: ', variableList.userDefined); + this.variableListUserDefined = variableList.find(el => el.key ==='userDefined').elements; + this.variableListSystemDefined = variableList.filter(el => (el.key !== 'userDefined' && el.key !== 'globals')); + + if(this.variableListUserDefined){ + this.filteredList.push(...this.variableListUserDefined.map(el => ({...el, icon: 'data_object', category: this.translate.instant('CDSvariablesList.userDefined')}))) + } + if(this.variableListSystemDefined){ + Object.values(this.variableListSystemDefined).forEach(obj => this.filteredList.push(...obj.elements.map(el => ({...el, category: this.translate.instant('CDSvariablesList.'+obj.key)})))) + } + } + + onChangeSelect(variableSelected: {name: string, value: string}){ + // this.logger.log('changeeeeee', variableSelected); + this.action.variableName = variableSelected.value; + this.updateAndSaveAction.emit() + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable.component.spec.ts new file mode 100644 index 000000000..8a9cc11d7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-delete-variable/cds-action-delete-variable.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionDeleteVariableComponent } from './cds-action-delete-variable.component'; + +describe('ActionDeleteVariableComponent', () => { + let component: CdsActionDeleteVariableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionDeleteVariableComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionDeleteVariableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.html new file mode 100644 index 000000000..1e15bea7e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.html @@ -0,0 +1,99 @@ +
+ + + + + + +
+
+
+ + + {{element?.badge}} +
+ +

{{element?.name | translate }}

+ + {{element?.badge}} + Beta + +
+ +
+ +
+ +
+
+ info +
+ +
+ + + + +
+
+ +
+ +
+ +
+ + +
+
+ + +
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss new file mode 100644 index 000000000..dffc89d52 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss @@ -0,0 +1,269 @@ +.action_wrp { + position: relative; + display: flex; + width: 100%; + justify-content: space-between; + gap: 10px; + padding: 10px; +} + +.preview { + padding: 5px !important; + border-bottom: 0 !important; + + .label-action { + font-size: 12px !important; + color: var(--blu) !important; + width: 100%; + } + + .icon-action { + // background: var(--brown) !important; + + img { + width: 18px; + height: auto; + } + } + + .action-title{ + justify-content: space-between; + width: 100%; + } + + .action-btn-icon { + display: inline-flex; + color: #394f5a; + padding: 0; + vertical-align: middle; + // margin: 0 6px; + .btn-tdblu-no-boxshadow { + margin: 0; + cursor: grab; + padding: 0!important; + background: transparent !important; + font-size: 12px; + width: 25px; + height: 25px; + display: flex; + justify-content: center; + align-items: center; + box-shadow: none; + } + .drag-btn img{ + width: 16px; + } + } + +} + +.trigger-beta-badge2 { + font-weight: 400; + background-color: #fff; + padding: 1px 8px; + border-radius: 10px; + font-size: 10px; + line-height: 13px; + color: #6c757d; + position: relative; + margin: 0px 3px; +} + +.trigger-beta-badge { + font-weight: 400; + background: linear-gradient(45deg, #3167e2, #a736ff); + padding: 1px 8px; + border-radius: 5px; + padding: 0px 6px; + height: 16px; + font-size: 9px; + letter-spacing: 1px; + color: #fff; + position: relative; + margin: 0px 3px; + display: flex; + align-items: center; +} + + +.badge-NEW { + background: linear-gradient(45deg, #3167e2, #a736ff); +} + +.badge-BETA { + background: linear-gradient(45deg, #e23131, #ff8736); +} + + +.deprecation-badge, +.badge-DEP { + background: linear-gradient(45deg, #e23131, #640b0b) +} + +.deprecation-message { + position: absolute; + bottom: -22px; + left: 0px; + right: 0px; + font-size: 10px; + font-weight: 400; + color: #cf2b2b; + text-align: center; +} + +.edit-mode-header-buttons { + float: right; + display: flex; + position: absolute; + right: 15px; + top: 15px; + cursor: pointer; + z-index: 1; + + .control-button { + align-items: center; + background: #dcdcdc; + border-radius: 4px; + color: #475e7a; + cursor: pointer; + display: flex; + flex-grow: 1; + flex-shrink: 0; + font-size: 13px; + height: 30px; + justify-content: center; + margin: 0 5px; + transition: all .3s; + width: 30px; + } +} + + +.section { + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 10px; + width: 100%; +} + +.action-title { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 5px; + max-width: calc(100% - 70px); + + .icon-action { + transition: opacity .15s ease 0s; + // width: 20px; + height: 20px; + border-radius: 4px; + // margin-right: 6px; + // align-self: start; + color: var(--blu); + background: none; + + display: flex; + align-items: center; + justify-content: center; + + img { + // width: 18px; + // margin: auto 6px auto 4px; + height: 16px; + } + } + + .label-action { + overflow-x: clip; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 14px; + font-weight: 500; + margin: 0; + color: var(--blu); + } +} + +.action-description { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + font-size: 11px; + color: var(--blu-light-02); + line-height: 1.5; + + span { + display: flex; + } + + &:hover { + cursor: pointer; + } +} + +div.action-description::ng-deep a { + word-break: break-word; +} + +input.action-input { + width: 100%; + border-radius: 4px; + border: 0; + padding: 5px 10px; + color: #22272d; + font-size: 1.15em; + line-height: 16px; +} + + + +// .custom-action-title { +// width: 100%; +// display: flex; +// flex-direction: row; +// align-items: center; + +// img { +// height: 36px; +// width: auto; +// margin-right: 16px; +// } + +// p { +// margin-bottom: 0px; +// color: #ffffff; +// font-weight: 400; +// } + +// input { +// font-size: 14px; +// padding: 0; +// background-color: transparent; +// color: #d2d2d2; +// } + +// ::placeholder { +// color: #d2d2d2; +// } + +// .custom-action-info-container { +// width: 100%; +// display: flex; +// flex-direction: row; +// justify-content: space-between; +// align-items: center; +// } + +// .custom-action-info { +// width: 100%; +// display: flex; +// flex-direction: column; +// } + +// .custom-icon { +// color: #d2d2d2; +// } +// } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.ts new file mode 100644 index 000000000..52f054dda --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.ts @@ -0,0 +1,86 @@ +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { INTENT_ELEMENT } from '../../../../../utils'; +import { Action } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { BrandService } from 'src/app/services/brand.service'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; + +@Component({ + selector: ' selector: 'cds-action-description-new',-new', + templateUrl: './cds-action-description-new.component.html', + styleUrls: ['./cds-action-description-new.component.scss'] +}) +export class CdsActionDescriptionNewComponent implements OnInit { + + @Input() actionSelected: Action; + @Input() elementType: string; + @Input() previewMode: boolean = true + @Input() showTip: boolean = false; + // @Output() closeIntent = new EventEmitter(); + // @Output() saveIntent = new EventEmitter(); + + titlePlaceholder: string = 'Set a title'; + element: any; + dataInput: string; + tparams: any; + BRAND_BASE_INFO = BRAND_BASE_INFO + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private brandService: BrandService + ) { + const brand = brandService.getBrand(); + this.tparams = brand; + } + + ngOnInit(): void { + } + + ngOnChanges(){ + // this.logger.log('[ActionDescriptionComponent] ngOnChanges:: ', this.actionSelected, this.elementType); + if(this.actionSelected){ + this.elementType = this.actionSelected._tdActionType; + if(this.actionSelected._tdActionTitle && this.actionSelected._tdActionTitle != ""){ + this.dataInput = this.actionSelected._tdActionTitle; + } + } + try { + switch(this.elementType){ + case 'form': + case 'question': + case 'answer': + this.element = Object.values(INTENT_ELEMENT).find(el => el.type === this.elementType) + break; + case 'jsoncondition': + this.element = ACTIONS_LIST.JSON_CONDITION + if('noelse' in this.actionSelected) { + this.element = ACTIONS_LIST.CONDITION + } + break; + default: + this.element = Object.values(ACTIONS_LIST).find(el => el.type === this.elementType) + break; + } + // this.element = ELEMENTS_LIST.find(item => item.type === this.elementType); + this.logger.log('[ActionDescriptionComponent] action:: ', this.element); + } catch (error) { + this.logger.log("[ActionDescriptionComponent] error ", error); + } + } + + // onCloseIntent(){ + // this.closeIntent.emit(); + // } + + // onSaveIntent(){ + // this.saveIntent.emit(); + // } + + onChangeText(text: string){ + this.logger.log('[ActionDescriptionComponent] onChangeText:: ', text); + this.actionSelected._tdActionTitle = text; + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description.component.spec.ts new file mode 100644 index 000000000..a3ab81434 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionDescriptionComponent } from './cds-action-description.component'; + +describe('CdsActionDescriptionComponent', () => { + let component: CdsActionDescriptionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionDescriptionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionDescriptionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.html new file mode 100644 index 000000000..fb948f23f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.html @@ -0,0 +1,121 @@ + +
+ +
+
+ + + + +
+
+ {{this.action.to}} +
+
+ {{'CDSCanvas.EnterEmailRecipient' | translate}} +
+
+ + +
+
+ + + + +
+
+ {{action.subject}} +
+
+ {{'CDSCanvas.EnterEmailSubject' | translate}} +
+
+ +
+
+ + + + + + +
+
+ {{action.text}} +
+
+ {{'CDSCanvas.EnterEmailBody' | translate}} +
+
+
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.scss new file mode 100644 index 000000000..b4b3a9296 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.scss @@ -0,0 +1,19 @@ +cds-textarea.subject-text-area ::ng-deep, +cds-textarea.to-text-area ::ng-deep { + textarea { + resize: none !important; + } +} + +::ng-deep .set-attributes-panel { + display: flex; + -ms-flex-direction: column; + flex-direction: column; + max-height: 600px; + min-height: 200px; + box-shadow: 0 0 20px 4px rgb(154 161 177 / 15%), 0 4px 80px -8px rgb(36 40 47 / 25%), + 0 4px 4px -2px rgb(91 94 105 / 15%); + background: rgb(255, 255, 255); + border-radius: 4px; + padding: 15px 0; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.ts new file mode 100644 index 000000000..777e909a2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email-new.component.ts @@ -0,0 +1,80 @@ +import { ActionEmail } from 'src/app/models/action-model'; +import { Component, OnInit, Input, ElementRef, OnChanges, Output, EventEmitter } from '@angular/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-email-new', + templateUrl: './cds-action-email-new.component.html', + styleUrls: ['./cds-action-email-new.component.scss'] +}) +export class CdsActionEmailNewComponent implements OnInit, OnChanges { + + @Input() action: ActionEmail; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + email_error: boolean = false; + // isOpenSetAttributesPanel: boolean = false + // intents = ['uno', 'due', 'tre']; + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void { + this.logger.log("[ACTION-EMAIL] elementSelected: ", this.action) + } + + ngOnChanges() { + this.logger.log("[CDS-ACTION-EMAIL] ngOnChanges: this.action", this.action) + } + + + onChangeTextarea($event: string, property: string) { + if($event){ + this.logger.log("[CDS-ACTION-EMAIL] onEditableDivTextChange event", $event) + this.logger.log("[CDS-ACTION-EMAIL] onEditableDivTextChange property", property) + this.action[property] = $event + // this.updateAndSaveAction.emit(); + } + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + + + // placeCaretAtEnd(el) { + // el.focus(); + // if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") { + // var range = document.createRange(); + // range.selectNodeContents(el); + // range.collapse(false); + // var sel = window.getSelection(); + // sel.removeAllRanges(); + // sel.addRange(range); + // } + // } + + + onChangeActionButton(event) { + //this.logger.log("event: ", event) + } + + onToChange(event) { + this.logger.log("[CDS-ACTION-EMAIL] onToChange event: ", event); + this.action.to = event; + } + + // https://stackoverflow.com/questions/45686432/need-to-add-tags-and-normal-text-in-same-input-box + // http://jsfiddle.net/timdown/jwvha/527/ + + + // onOpenActionDetails() { + // this.logger.log( '[CDS-ACTION-EMAIL] onOpenActionDetails' ) + // this.controllerService.openActionDetailPanel('email'); + // } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email.component.spec.ts new file mode 100644 index 000000000..b067225b1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-email/cds-action-email.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionEmailComponent } from './cds-action-email.component'; + +describe('CdsActionEmailComponent', () => { + let component: CdsActionEmailComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionEmailComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionEmailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.html new file mode 100644 index 000000000..eda5509ed --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.html @@ -0,0 +1,56 @@ +
+
+
+ +
+
+ {{action?.level}} +
+
+
+
+ +
+
+ {{action?.log}} +
+
+ {{'CDSCanvas.SetFlowLog' | translate }} +
+
+
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss new file mode 100644 index 000000000..3a65431a4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss @@ -0,0 +1,9 @@ +/** NG-SELECT **/ +// .ng-select ::ng-deep .ng-select-container { +// border-radius: var(--input-border-radius-base); +// border: 1px solid var(--blu-light-02); +// } +// .ng-select.ng-select-focused ::ng-deep .ng-select-container { +// border: 1px solid var(--blu-light-02); +// box-shadow: none; +// } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.ts new file mode 100644 index 000000000..e1f575793 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.ts @@ -0,0 +1,58 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { LOG_LEVELS } from 'src/app/chatbot-design-studio/utils'; +import { ActionFlowLog } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: ' selector: 'cds-action-flow-log-new',-new', + templateUrl: './cds-action-flow-log-new.component.html', + styleUrls: ['./cds-action-flow-log-new.component.scss'] +}) +export class CdsActionFlowLogNewComponent implements OnInit { + + @Input() action: ActionFlowLog; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + LOG_LEVELS = LOG_LEVELS; + selectedLogLevel: string = LOG_LEVELS.NATIVE; + /** Stable order for UI select options. */ + logLevelsArray = [ + { key: 'native', value: LOG_LEVELS.NATIVE, icon: 'code', iconColor: '#6b7280' }, + { key: 'debug', value: LOG_LEVELS.DEBUG, icon: 'bug_report', iconColor: '#8b5cf6' }, + { key: 'info', value: LOG_LEVELS.INFO, icon: 'info', iconColor: '#3b82f6' }, + { key: 'warn', value: LOG_LEVELS.WARN, icon: 'warning', iconColor: '#f59e0b' }, + { key: 'error', value: LOG_LEVELS.ERROR, icon: 'error', iconColor: '#ef4444' }, + ]; + filteredLogs: Array = []; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { + this.logger.log('[CdsActionFlowLogComponent]:: constructor', this.action); + } + + ngOnInit(): void { + this.selectedLogLevel = this.action.level; + this.logger.log('[CdsActionFlowLogComponent]:: ngOnInit', this.action); + } + + onChangeTextArea(text:string) { + this.logger.log('[CdsActionFlowLogComponent]:: onChangeTextarea ', text); + this.action.log = text; + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + onLogLevelChange(event: any) { + this.selectedLogLevel = event.value; + this.action.level = event.value; + this.logger.log('[CdsActionFlowLogComponent] onLogLevelChange:', event); + this.updateAndSaveAction.emit(); + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log.component.spec.ts new file mode 100644 index 000000000..7e9de6faa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionFlowLogComponent } from './cds-action-flow-log.component'; + +describe('CdsActionFlowLogComponent', () => { + let component: CdsActionFlowLogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionFlowLogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionFlowLogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.html new file mode 100644 index 000000000..de3ad3225 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.html @@ -0,0 +1,179 @@ +
+ +
+
+ + + + +
+ +
+
+ {{action?.prompt}} +
+
+ {{'CDSCanvas.EnterPrompt' | translate }} +
+
+ +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.scss new file mode 100644 index 000000000..1f97a61be --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.scss @@ -0,0 +1,9 @@ +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.ts new file mode 100644 index 000000000..006a8549a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant-new.component.ts @@ -0,0 +1,169 @@ +import { Intent } from 'src/app/models/intent-model'; +import { ActionGPTAssistant } from './../../../../../../models/action-model'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-gpt-assistant-new', + templateUrl: './cds-action-gpt-assistant-new.component.html', + styleUrls: ['./cds-action-gpt-assistant-new.component.scss'] +}) +export class CdsActionGptAssistantNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionGPTAssistant; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService, + ) { } + + ngOnInit(): void { + this.logger.debug("[ACTION GPT-ASSISTANT] ngOnInit action: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION GPT-ASSISTANT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + this.initializeAttributes(); + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-GPT-ASSISTANT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-GPT-ASSISTANT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'firstThread')) { + new_attributes.push({ name: "firstThread", value: "firstThread" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'assistantReply')) { + new_attributes.push({ name: "assistantReply", value: "assistantReply" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'assistantError')) { + new_attributes.push({ name: "assistantError", value: "assistantError" }); + } + variableList.find(el => el.key ==='userDefined').elements = [...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION GPT-ASSISTANT] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + onChangeTextarea($event: string, property: string) { + this.logger.debug("[ACTION GPT-ASSISTANT] changeTextarea event: ", $event); + this.logger.debug("[ACTION GPT-ASSISTANT] changeTextarea propery: ", property); + this.action[property] = $event; + // this.checkVariables(); + // this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION GPT-ASSISTANT] onEditableDivTextChange event", event) + this.logger.log("[ACTION GPT-ASSISTANT] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.logger.log("[ACTION GPT-ASSISTANT] Action updated: ", this.action); + this.updateAndSaveAction.emit(); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + onChangeSelect(event, target) { + this.logger.debug("[ACTION GPT-ASSISTANT] onChangeSelect event: ", event.value) + this.logger.debug("[ACTION GPT-ASSISTANT] onChangeSelect target: ", target) + this.action[target] = event.value; + this.updateAndSaveAction.emit(); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant.component.spec.ts new file mode 100644 index 000000000..428869bbc --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-assistant/cds-action-gpt-assistant.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionGptAssistantComponent } from './cds-action-gpt-assistant.component'; + +describe('CdsActionGptAssistantComponent', () => { + let component: CdsActionGptAssistantComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionGptAssistantComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionGptAssistantComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.html new file mode 100644 index 000000000..9893b559c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.html @@ -0,0 +1,36 @@ +
+
+
+ Set Attributes +
+ close + +
+ +
+ +
+
+ +
+
{{ attr.name }}
+ + +
+ +
+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss new file mode 100644 index 000000000..a7d4eec7d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss @@ -0,0 +1,151 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/styles.scss"; + +::ng-deep .custom-setattribute-dialog-container { + width: 40vw!important; + min-width: 500px; + max-width: 1000px!important; + height: 80vh; + + .tpl-modal-box { + + border-radius: 6px; + flex-direction: column; + background: rgb(255, 255, 255); + } + .tpl-modal-header { + align-items: flex-start; + align-items: center; + display: flex; + flex-shrink: 0; + justify-content: center; + width: 100%; + i { + flex-shrink: 0; + font-size: 24px; + line-height: 23px; + margin-left: auto; + cursor: pointer; + } + } + + .tpl-modal-header-text { + flex-grow: 1; + text-align: center; + width: 0; + span { + word-wrap: break-word; + display: -webkit-box; + line-height: 23px; + overflow: hidden; + text-overflow: ellipsis; + max-height: 69px; + font-weight: 600; + font-size: 18px; + } + } + + .tpl-modal-content { + flex-grow: 1; + padding: 30px 0px; + width: 100%; + } + + .tpl-info { + border-radius: 4px; + display: flex; + margin-bottom: 20px; + padding: 12px 15px; + width: 100%; + color: #333; + background: var(--icon-color); + .tpl-info-icon { + font-size: 20px; + height: 20px; + flex-shrink: 0; + width: 35px; + } + } + .tpl-label-textarea { + margin-bottom: 5px; + color: #22272d; + font-size: 15px; + line-height: 19px; + } + + input { + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--blu-light-02); + color: var(--gray); + font-size: 1.15em; + line-height: 25px; + + -webkit-transition: border .3s; + transition: border .3s; + width: 100%; + + padding: 10px; + padding-top: 4px; + padding-bottom: 4px; + margin: 0px; + // resize: none; + + &::placeholder { + opacity: 0.5; + } + &.invalid{ + border: 2px solid red !important; + outline: 0px solid red !important; + transition: border 0.3s; + } + } + + .tpl-modal-buttons { + display: flex; + flex-shrink: 0; + justify-content: flex-end; + color: #333; + gap: 5px; + .cds-yellow-button{ + margin-left: 10px; + min-width: 80px; + background-color: var(--icon-color); + height: 100%; + color: #333; + } + } +} + +.input-error { + position: absolute; + font-size: 14px; + color: red; +} + +.attr-container { + font-size: 14px; + font-weight: 400; + background: #ecb606; + width: -moz-fit-content; + width: fit-content; + padding: 2px 6px; + border-radius: 4px; + color: #fff; + line-height: 1.5; + margin-bottom: 2px; +} + +#cds-publish-btn:hover:enabled { + opacity: .8 !important; +} + +#cds-publish-btn:disabled { + opacity: 0.5; + cursor: default; +} + +#cds-cancel-btn { + background: #e5e5e5; + color: #4b5052; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.ts new file mode 100644 index 000000000..0006c4d1a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.ts @@ -0,0 +1,81 @@ +import { Component, Inject, OnInit, inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + + +@Component({ + selector: ' selector: 'appdashboard-attributes-dialog-new',-new', + templateUrl: './attributes-dialog-new.component.html', + styleUrls: ['./attributes-dialog-new.component.scss'] +}) +export class AttributesDialogComponent implements OnInit { + + btn_disabled: boolean = false; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + ngOnInit(): void { + this.logger.debug("[AttributesDialog] data: ", this.data); + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onCloseDialog(): void { + this.logger.log("[AttributesDialog] - modal CLOSED"); + this.dialogRef.close(); + } + + onChangeTextarea(text, key) { + this.btn_disabled = false; + this.data.attributes.find(a => a.name === key).value = text + if (this.data.attributes.find(a => a.value === null || a.value === '')){ + this.btn_disabled = true; + } + } + + onGenerateClick() { + this.data.attributes.forEach((attr) => { + let old_value = "{{" + attr.name + "}}"; + this.data.question = this.data.question.replace(old_value, attr.value); + if(this.data.namespace){ + this.data.namespace = this.data.namespace.replace(old_value, attr.value); + } + }) + + this.logger.log("[AttributesDialog] - onGenerateClick return data: ", this.data); + this.dialogRef.close(this.data); + } + + + // createConditionGroup(): FormGroup { + // return this.formBuilder.group({ + // attributes: this.formBuilder.array([ + // this.createAttributesGroup() + // ]) + // }) + // } + + // createAttributesGroup(): FormGroup { + // return this.formBuilder.group({ + // name: ['', Validators.required], + // value: ['', Validators.required] + // }) + // } + + // setFormValue() { + // let attributesControl = this.varsForm.controls.attributes; + // this.data.attributes.forEach((v) => { + // attributesControl.push(v) + // // this.varsForm.patchValue({ attributes: this.data.attributes }); + // }) + // this.logger.log("varsForm: ", this.varsForm); + // } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.spec.ts new file mode 100644 index 000000000..5e6f1a701 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AttributesDialogComponent } from './attributes-dialog.component'; + +describe('AttributesDialogComponent', () => { + let component: AttributesDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AttributesDialogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(AttributesDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.html new file mode 100644 index 000000000..07862fa26 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.html @@ -0,0 +1,393 @@ +
+ +
+
+ + + + +
+ +
+
+ {{action?.question}} +
+
+ {{'CDSCanvas.EnterPrompt' | translate }} +
+
+ +
+ +
+ +
+ +
+ +
+
+ {{action?.model}} +
+
+ {{'CDSCanvas.EnterTheQuestion' | translate }} +
+
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss new file mode 100644 index 000000000..3ac44e8dc --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss @@ -0,0 +1,459 @@ +@import "./src/assets/sass/cds/_variables.scss"; + + +:host { + --background-color: #{var(--blu-light-01)}; + --slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; +} + +::-webkit-scrollbar { + width: 0px; +} + +.custom-divider { + border-top: 1px solid var(--blu); +} + + +div { + + .flex { + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close { + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + + &:hover { + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } +} + +a#router-link{ + cursor: pointer; + &:hover{ + text-decoration: underline; + } +} + + +#cds-addkb-btn { + background: #006cff; + color: #fff; + box-shadow: none; + font-weight: 500; + font-family: var(--font-family-poppins); + text-transform: capitalize; + font-size: 14px; + padding: 6px 12px; + border-radius: 10px; +} + +#cds-addkb-btn:hover { + opacity: .8 !important; +} + +.custom-icon { + margin-right: 6px; + font-size: 15px; +} + +.animated-icon { + animation: rotate 1.5s linear infinite; +} + +@keyframes rotate { + to { + transform: rotate(360deg); + } +} + + + +.variable-container { + display: flex; + height: 35px; + flex-direction: row; + align-items: center; + border: solid 1px black; + background-color: white; + padding: 0px 20px; + border-radius: 10px; + font-size: 14px; +} + +/////////////////////////////////////// +/////////////////////////////////////// + + + +// *********** AI SETTINGS --start *********** // + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} + +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 10px !important; + } + + .title-and-parameters-container { + display: flex; + flex-direction: column; + width: 100%; + } + .parameters-preview { + font-size: 11px; + height: 24px; + line-height: normal; + span { + line-height: 16px; + margin-right: 5px; + } + .preview-badge { + color: #fff; + background-color: var(--blu); + display: inline-block; + padding: 1px 5px; + border-radius: 4px; + .preview-badge-text { + padding: 0; + margin:0; + } + } + .preview-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 12px; + height: 12px; + font-size: 12px; + line-height: 12px; + margin: 0; + vertical-align: middle; + color: var(--color-white-hex); + } + .preview-flag{ + margin:0; + } + } +} + +cds-select#model-condition ::ng-deep{ + .select-item-wrp{ + justify-content: space-between; + } +} + +mat-checkbox ::ng-deep { + .mat-checkbox-ripple{ + display: none; + } +} + +::ng-deep .ng-dropdown-panel { + .ng-option .select-item-wrp[additionalText = true]{ + .select-item-wrp{ + justify-content: space-between; + } + } +} + +.action-wait-content { + display: flex; + flex-direction: row; + align-items: center; + gap: 5px; +} + +.action-wait-range { + color: var(--text-color); + font-size: 11px; + font-weight: 500; +} + +.action-wait-slider { + align-items: center; + background: var(--slider-background-color); + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 9px; + width: 100%; + text-align: center; + transition: width 0.3s ease-in; + font-size: 14px; +} + +.action-wait-slider>mat-slider { + width: 100%; + margin-left: 6px; +} + +.action-wait-slider ::ng-deep{ + .mat-accent .mat-slider-track-fill { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label-text{ + color: var(--background-color) !important; + font-size: 8px!important; + } + .mat-slider-thumb { + background-color: var(--text-color) !important; + } +} + +.gpt-setting-input { + color: var(--text-color); + text-align: center; + width: 45px; + border: none; + height: 26px; + border-radius: 12px; + background-color: white; + border: 1px solid var(--text-color); +} + +.slider-input ::ng-deep { + width: 60px; + min-width: 60px; + font-size: 12px; + input { + text-align: center; + } +} + +// *********** AI SETTINGS --end *********** // + +.header-answer-preview { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + + .close-button { + cursor: pointer; + font-size: 18px; + font-weight: 600; + color: #ffffff80; + + &:hover { + color: white; + } + } + +} + +.link-container { + margin-bottom: 20px; + + a.link { + font-size: 14px; + font-weight: 400; + } + + a.link:hover { + cursor: pointer; + text-decoration: underline; + } + +} + +// PREVIEW SECTION --- start **************** // +.preview-container { + width: 100%; + max-height: 37px; + overflow: hidden; + transition: max-height 0.5s ease-out; + border-radius: var(--input-border-radius-base); + background-color: var(--color-white-hex); + padding: 6px 12px; + font-size: 14px; + border: 1px solid var(--blu-light-02); + color: var(--gray); +} + +.preview-container-extended { + max-height: 300px; + overflow-y: auto; +} + +.placeholder-container { + display: flex; + align-items: center; +} + +loading-spinner.custom-spinner ::ng-deep { + .sk-fading-circle { + width: 20px ; + height: 20px ; + margin: 0px ; + } + + .sk-fading-circle .sk-circle:before { + background-color: var(--blu) ; + } +} + +.label-and-button-container { + + width: 100%; + display: flex; + align-items: center; + margin-bottom: 6px; + + + .title-label { + margin-bottom: 0px; + } + +} + +.set-var-btn { + font-weight: 300 !important; + font-size: 12px !important; + height: 20px; + display: flex; + align-items: center; + padding: 6px 6px 6px 12px !important; + margin: 0px 0px 0px 6px !important; +} + +// .content#variables .opened { +// left: 0px; +// } + + + +.variables-content-header { + display: flex; + flex-direction: row; + align-items: center; + + .back-button { + cursor: pointer; + font-size: 20px; + font-weight: 600; + margin-right: 6px; + color: #ffffff80; + + &:hover { + color: white; + } + } + + .title-label { + font-size: 18px; + margin-bottom: 0px; + } +} + +.single-variable { + display: flex; + align-items: center; + margin: 14px 0px; + + .variable-name { + background-color: #ecb608; + color: white; + font-weight: 400; + padding: 6px 12px; + border-radius: 7px; + margin-right: 10px; + } + +} + +.usage-container { + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 6px; + padding: 0px 4px; + color: #a6a6a6; + font-size: 11px; + width: 100%; +} + +// PREVIEW SECTION --- start **************** // \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.ts new file mode 100644 index 000000000..3c64105f1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.ts @@ -0,0 +1,574 @@ +import { Component, ElementRef, EventEmitter, HostListener, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { Subscription } from 'rxjs'; + +//MODELS +import { ActionGPTTask } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; + +//SERVICES +import { OpenaiService } from 'src/app/services/openai.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { MatDialog } from '@angular/material/dialog'; +import { AppConfigService } from 'src/app/services/app-config'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; + +//UTILS +import { AttributesDialogComponent } from './attributes-dialog/attributes-dialog.component'; +import { DOCS_LINK, TYPE_GPT_MODEL, TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { PLAN_NAME } from 'src/chat21-core/utils/constants'; +import { TranslateService } from '@ngx-translate/core'; +import { loadTokenMultiplier } from 'src/app/utils/util'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { OPENAI_MODEL } from 'src/app/chatbot-design-studio/utils-ai_models'; +import { LlmModel } from 'src/app/chatbot-design-studio/utils-llm-models'; + +@Component({ + selector: ' selector: 'cds-action-gpt-task-new',-new', + templateUrl: './cds-action-gpt-task-new.component.html', + styleUrls: ['./cds-action-gpt-task-new.component.scss'] +}) +export class CdsActionGPTTaskNewComponent implements OnInit { + + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + + @Input() intentSelected: Intent; + @Input() action: ActionGPTTask; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + panelOpenState = false; + model_list: Array<{ name: string, value: string }>; + ai_setting: { [key: string] : {name: string, min: number, max: number, step: number}} = { + "max_tokens": { name: "max_tokens", min: 10, max: 100000, step: 1}, + "temperature" : { name: "temperature", min: 0, max: 1, step: 0.05} + } + ai_response: string = ""; + ai_error: string = "Oops! Something went wrong. Check your GPT Key or retry in a few moment." + // ai_error: string = "Oops! Something went wrong." + + showPreview: boolean = false; + missingVariables: boolean = true; + showVariablesBtn: boolean = false; + showVariablesSection: boolean = false; + showAiError: boolean = false; + searching: boolean = false; + temp_variables = []; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + projectPlan: PLAN_NAME + PLAN_NAME = PLAN_NAME + BRAND_BASE_INFO = BRAND_BASE_INFO; + DOCS_LINK = DOCS_LINK.GPT_TASK; + + private logger: LoggerService = LoggerInstance.getInstance(); + browserLang: string = 'en'; + constructor( + private dialog: MatDialog, + private openaiService: OpenaiService, + private intentService: IntentService, + private appConfigService: AppConfigService, + private translate: TranslateService, + private dashboardService: DashboardService + ) { } + + + ngOnInit(): void { + // Locale for Angular number pipe (we only register 'it' explicitly; fallback to 'en') + const lang = this.translate.getBrowserLang() || 'en'; + this.browserLang = lang.startsWith('it') ? 'it' : 'en'; + + // Filtra per aiModels solo i modelli GPT (id che inizia con 'gpt-'); gli altri restano tutti + const ai_models = loadTokenMultiplier(this.appConfigService.getConfig().aiModels); + const allowedModelIds = Object.keys(ai_models); + this.model_list = OPENAI_MODEL.filter(model => + allowedModelIds.includes(model.value) + ); + + this.model_list = this.model_list.map((model: any) => + ai_models[model.value] != null + ? { ...model, multiplier: ai_models[model.value] + ' x tokens' } + : { ...model, multiplier: null } + ); + + + // this.logger.debug("[ACTION GPT-TASK] ngOnInit action: ", this.action); + // const ai_models = loadTokenMultiplier(this.appConfigService.getConfig().aiModels) + + // this.model_list = TYPE_GPT_MODEL.filter(el => Object.keys(ai_models).includes(el.value)).map((el)=> { + // if(ai_models[el.value]) + // return { ...el, multiplier: ai_models[el.value] + ' x tokens' } + // else + // return { ...el, multiplier: null } + // }) + this.projectPlan = this.dashboardService.project.profile.name + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-ASKGPT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + this.initializeAttributes(); + + if (!this.action.preview) { + this.action.preview = []; // per retrocompatibilità + } + } + + ngOnChanges(changes: SimpleChanges) { + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ASKGPT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ASKGPT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // private updateConnector(){ + // try { + // const array = this.connector.fromId.split("/"); + // const idAction= array[1]; + // if(idAction === this.action._tdActionId){ + // if(this.connector.deleted){ + // if(array[array.length -1] === 'true'){ + // this.action.trueIntent = null; + // this.isConnectedTrue = false; + // this.idConnectionTrue = null; + // } + // if(array[array.length -1] === 'false'){ + // this.action.falseIntent = null; + // this.isConnectedFalse = false; + // this.idConnectionFalse = null; + // } + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } else { + // // TODO: verificare quale dei due connettori è stato aggiunto (controllare il valore della action corrispondente al true/false intent) + // this.logger.debug('[ACTION-ASKGPT] updateConnector', this.connector.toId, this.connector.fromId ,this.action, array[array.length-1]); + // if(array[array.length -1] === 'true'){ + // // this.action.trueIntent = '#'+this.connector.toId; + // this.isConnectedTrue = true; + // this.idConnectionTrue = this.connector.fromId+"/"+this.connector.toId; + // this.action.trueIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // if(array[array.length -1] === 'false'){ + // // this.action.falseIntent = '#'+this.connector.toId; + // this.isConnectedFalse = true; + // this.idConnectionFalse = this.connector.fromId+"/"+this.connector.toId; + // this.action.falseIntent = '#'+this.connector.toId; + // if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + // } + // } + // } + // } catch (error) { + // this.logger.error('[ACTION-ASKGPT] updateConnector error: ', error); + // } + // } + + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'gpt_reply')) { + new_attributes.push({ name: "gpt_reply", value: "gpt_reply" }); + } + variableList.find(el => el.key ==='userDefined').elements = [...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION GPT-TASK] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + onChangeTextarea($event: string, property: string) { + this.logger.debug("[ACTION GPT-TASK] changeTextarea event: ", $event); + this.logger.debug("[ACTION GPT-TASK] changeTextarea propery: ", property); + this.action[property] = $event; + // this.checkVariables(); + // this.updateAndSaveAction.emit(); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION GPT-TASK] onEditableDivTextChange event", event) + this.logger.log("[ACTION GPT-TASK] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit(); + } + + onChangeSelect(event, target) { + this.logger.debug("[ACTION GPT-TASK] onChangeSelect event: ", event.value) + this.logger.debug("[ACTION GPT-TASK] onChangeSelect target: ", target) + this.action[target] = event.value; + this.updateAndSaveAction.emit(); + } + + updateSliderValue(event, target) { + this.logger.debug("[ACTION GPT-TASK] updateSliderValue event: ", event) + this.logger.debug("[ACTION GPT-TASK] updateSliderValue target: ", target) + this.action[target] = event; + + this.updateAndSaveAction.emit(); + } + + onChangeCheckbox(event: MatCheckboxChange, target){ + try { + this.action[target] = event.checked; + switch(target){ + case 'formatType':{ + if(event.checked){ + this.action[target] = 'json_object' + }else{ + this.action[target] = 'none' + } + } + + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + scrollToBottom(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.log('scrollToBottom ERROR: ', error); + } + }, 300); + } + + execPreview() { + this.scrollToBottom(); + this.checkVariables().then((resp) => { + + if (resp === true) { + this.getResponse(this.action.question); + + } else { + this.openAttributesDialog(); + } + + }) + } + + checkVariables() { + return new Promise((resolve, reject) => { + let regex: RegExp = /{{[^{}]*}}/g; + let string = this.action.question; + let matches = string.match(regex); + let response: boolean = true; + + if (!matches || matches.length == 0) { + resolve(true); + + } else { + + this.temp_variables = []; + matches.forEach((m) => { + let name = m.slice(2, m.length - 2); + let attr = this.action.preview.find(v => v.name === name); + + if (attr && attr.value) { + this.temp_variables.push({ name: name, value: attr.value }); + + } else if (attr && !attr.value) { + this.temp_variables.push({ name: name, value: null }); + + } else { + this.temp_variables.push({ name: name, value: null }); + this.action.preview.push({ name: name, value: null }); + } + }) + resolve(false); + } + }) + } + + getResponse(question) { + this.logger.log("getResponse called...") + + let data = { + question: question, + context: this.action.context, + model: this.action.model, + max_tokens: this.action.max_tokens, + temperature: this.action.temperature, + formatType: this.action.formatType + } + + this.showAiError = false; + this.searching = true; + this.showPreview = true; + + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.remove('preview-container-extended') + }, 200) + + this.openaiService.previewPrompt(data).subscribe({ next: (ai_response: any) => { + this.searching = false; + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.ai_response = ai_response; + }, error: (err) => { + this.searching = false; + this.logger.error("[ACTION GPT-TASK] previewPrompt error: ", err); + setTimeout(() => { + let element = document.getElementById("preview-container"); + element.classList.add('preview-container-extended') + }, 200) + this.showAiError = true; + if(err.error.error_code === 13001){ + this.ai_error = this.translate.instant('CDSCanvas.AiQuotaExceeded') + return; + } + this.ai_error = this.translate.instant('CDSCanvas.AiError') + }, complete: () => { + this.logger.debug("[ACTION GPT-TASK] preview prompt *COMPLETE*: "); + this.searching = false; + }}); + + } + + + // getResponsePreview() { + + // this.showPreview = true; + // this.showAiError = false; + + // this.checkVariables().then((resp) => { + + // if (resp === false) { + // this.missingVariables = true; + + // } else { + // let temp_question = this.action.question; + // this.temp_variables.forEach((tv) => { + // let old_value = "{{" + tv.name + "}}"; + // temp_question = temp_question.replace(old_value, tv.value); + // }) + + // this.searching = true; + // this.missingVariables = false; + + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.remove('preview-container-extended') + // }, 200) + + // let data = { + // question: temp_question, + // context: this.action.context, + // model: this.action.model, + // max_tokens: this.action.max_tokens, + // temperature: this.action.temperature + // } + + // this.openaiService.previewPrompt(data).subscribe((ai_response: any) => { + // this.searching = false; + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.add('preview-container-extended') + // }, 200) + // this.ai_response = ai_response; + // }, (error) => { + // this.logger.error("[ACTION GPT-TASK] previewPrompt error: ", error); + // setTimeout(() => { + // let element = document.getElementById("preview-container"); + // element.classList.add('preview-container-extended') + // }, 200) + // this.showAiError = true; + // this.searching = false; + // }, () => { + // this.logger.error("[ACTION GPT-TASK] preview prompt *COMPLETE*: "); + // this.searching = false; + // }) + // } + // }) + // } + + // _checkVariables() { + // return new Promise((resolve, reject) => { + // let regex: RegExp = /{{[^{}]*}}/g; + // let string = this.action.question; + // let matches = string.match(regex); + // let response: boolean = true; + + // if (!matches || matches.length == 0) { + // this.showVariablesBtn = false; + // resolve(response); + // } + + // if (matches.length > 0) { + // if (!this.action.preview) { + // this.action.preview = []; + // } + // this.showVariablesBtn = true; + // this.temp_variables = []; + + // matches.forEach((m) => { + // let name = m.slice(2, m.length - 2); + // let attr = this.action.preview.find(v => v.name === name); + // if (attr && attr.value) { + // this.temp_variables.push({ name: name, value: attr.value }); + // } else if (attr && !attr.value) { + // response = false; + // this.temp_variables.push({ name: name, value: null }); + // } else { + // response = false; + // this.temp_variables.push({ name: name, value: null }); + // this.action.preview.push({ name: name, value: null }); + // } + // }) + // this.logger.log("temp_variables: ", this.temp_variables) + // resolve(response); + // } + + // }) + // } + + // showHideVariablesSection() { + // this.showVariablesSection = !this.showVariablesSection; + // if (this.showVariablesSection == false) { + // this.getResponsePreview(); + // } + // } + + // onChangeVar(event, name) { + // let index = this.action.preview.findIndex(v => v.name === name); + // if (index != -1) { + // this.action.preview[index].value = event; + // } + // this.updateAndSaveAction.emit(); + // } + + // closePreview() { + // let element = document.getElementById("preview-container"); + // element.classList.remove('preview-container-extended') + + // this.showPreview = false; + // this.searching = false; + // } + + openAttributesDialog() { + this.logger.log("temp_variables: ", this.temp_variables); + const dialogRef = this.dialog.open(AttributesDialogComponent, { + panelClass: 'custom-setattribute-dialog-container', + data: { attributes: this.temp_variables, question: this.action.question } + }); + dialogRef.afterClosed().subscribe(result => { + this.logger.log("AttributesDialogComponent result: ", result); + if (result !== false) { + this.getResponse(result.question); + this.saveAttributes(result.attributes); + } + }); + } + + saveAttributes(attributes) { + this.logger.log("attributes: ", attributes); + attributes.forEach(a => { + let index = this.action.preview.findIndex(v => v.name === a.name) + if (index != -1) { + this.action.preview[index].value = a.value; + } else { + this.action.preview.push({ name: a.name, value: a.value }) + } + this.updateAndSaveAction.emit(); + }) + } + + goToKNB(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=openai' + window.open(url, '_blank') + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task.component.spec.ts new file mode 100644 index 000000000..5d81d791e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionGPTTaskComponent } from './cds-action-gpt-task.component'; + +describe('ActionAskgptComponent', () => { + let component: CdsActionGPTTaskComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionGPTTaskComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionGPTTaskComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.html new file mode 100644 index 000000000..699614411 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.html @@ -0,0 +1,36 @@ +
+ +
+
+ + + + +
+
+ {{action?.text}} +
+
+ {{'CDSCanvas.SetHiddenMessage' | translate }} +
+
+
+ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.ts new file mode 100644 index 000000000..447e51caa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message-new.component.ts @@ -0,0 +1,33 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ActionHideMessage } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-hide-message-new', + templateUrl: './cds-action-hide-message-new.component.html', + styleUrls: ['./cds-action-hide-message-new.component.scss'] +}) +export class CdsActionHideMessageNewComponent implements OnInit { + + @Input() action: ActionHideMessage; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void { + } + + onChangeTextArea(text:string) { + // this.logger.log('onChangeTextarea:: ', text); + this.action.text = text; + } + + onBlur(event){ + this.updateAndSaveAction.emit() + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message.component.spec.ts new file mode 100644 index 000000000..c155f2995 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hide-message/cds-action-hide-message.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionHideMessageComponent } from './cds-action-hide-message.component'; + +describe('CdsActionHideMessageComponent', () => { + let component: CdsActionHideMessageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionHideMessageComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionHideMessageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.html new file mode 100644 index 000000000..a57961f59 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.html @@ -0,0 +1,150 @@ +
+ +
+ + + {{ action.method}} + + +
+ +
+ {{'CDSCanvas.EnterParameters' | translate }} +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+
+ + + +
+ + +
+ + + +
+ + {{'CDSCanvas.ManageIntegration' | translate}} + +
+ +
+
+
+ +
+ {{'CDSCanvas.Success' | translate }} +
+ + +
+ +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + +
+ +
+ + + + + + {{'CDSCanvas.Advanced' | translate }} + + + + +
+ + + +
+ +
+ + + +
+ +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss new file mode 100644 index 000000000..1729d508f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss @@ -0,0 +1,75 @@ +::-webkit-scrollbar { + width: 0px; +} +:host { + --background-color: var(--blu-light-01); + //--slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; +} + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.ts new file mode 100644 index 000000000..41b998b59 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.ts @@ -0,0 +1,196 @@ +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//SERVICES +import { Intent } from 'src/app/models/intent-model'; +import { ActionHubspot } from 'src/app/models/action-model'; +import { IntentService } from '../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: ' selector: 'cds-action-hubspot-new',-new', + templateUrl: './cds-action-hubspot-new.component.html', + styleUrls: ['./cds-action-hubspot-new.component.scss'] +}) +export class CdsActionHubspotNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionHubspot; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonParameters: { [key: string]: string}; + errorMessage: string; + + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService, + private appConfigService: AppConfigService, + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-HUBSPOT] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-HUBSPOT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-HUBSPOT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-HUBSPOT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.jsonParameters = this.action.bodyParameters; + if(this.intentSelected){ + this.initializeConnector(); + } + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'hubspot_status')) { + new_attributes.push({ name: "hubspot_status", value: "hubspot_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'hubspot_error')) { + new_attributes.push({ name: "hubspot_error", value: "hubspot_error" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION-HUBSPOT] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined').elements); + } + + + + + // EVENT FUNCTIONS // + onChangeTextarea(e, type: string){ + switch(type){ + case 'token' : { + this.action.token = e; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + this.logger.log("[ACTION-HUBSPOT] this.action", this.action); + } + } + } + + + onChangeAttributes(attributes:any){ + this.logger.log('[ACTION-HUBSPOT]onChangeAttributes ',attributes); + this.action.bodyParameters = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-HUBSPOT] onEditableDivTextChange event", event) + this.logger.log("[ACTION-HUBSPOT] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToIntegration(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + this.action._tdActionType + window.open(url, '_blank') + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot.component.spec.ts new file mode 100644 index 000000000..cb8dc42cb --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionHubspotComponent } from './cds-action-hubspot.component'; + +describe('CdsActionHubsppotComponent', () => { + let component: CdsActionHubspotComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionHubspotComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionHubspotComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.html new file mode 100644 index 000000000..c1802d36b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.html @@ -0,0 +1,59 @@ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + +
+ +
+ +
+ + + +
+ + + + +
+ + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.scss new file mode 100644 index 000000000..e6dee3fe3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.scss @@ -0,0 +1,34 @@ +.cds-action-preview { + padding: 0px; + margin: 0px; + position: relative; + &.isStart{ + // padding: 5px 10px; + padding: 0px; + } +} + + +.previewContent{ + // padding: 5px 5px; + // top: calc(50% - 14px); + .title-label{ + color: var(--brown); + font-size: 12px; + } +} + + + + + +/** NG-SELECT **/ +.ng-select.ng-select-focused>.ng-select-container { + border-color: var(--color-red-hex); + box-shadow: inset 0 1px 1px #00000013,0 0 0 3px #007eff1a; +} + + + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.ts new file mode 100644 index 000000000..602b3dfbf --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent-new.component.ts @@ -0,0 +1,159 @@ +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { Intent } from 'src/app/models/intent-model'; +import { ActionIntentConnected } from 'src/app/models/action-model'; +import { IntentService } from '../../../../../services/intent.service'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { checkConnectionStatusByConnector, updateSingleConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-intent-new', + templateUrl: './cds-action-intent-new.component.html', + styleUrls: ['./cds-action-intent-new.component.scss'] +}) +export class CdsActionIntentNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() isStart: boolean; + @Input() action: ActionIntentConnected; + @Input() previewMode: boolean = true; + @Input() isLast: boolean = false; + + @Output() updateIntentFromConnectorModification = new EventEmitter(); + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter(); //{type: 'create' | 'delete', fromId: string, toId: string} + + intents: Array<{name: string, value: string, icon?:string}> + idIntentSelected: string; + idConnector: string; + idConnection: string; + isConnected: boolean = false; + connector: any; + element: any; + private subscriptionChangedConnector: Subscription; + private logger: LoggerService = LoggerInstance.getInstance(); + + + constructor( + private intentService: IntentService + ) {} + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.log('[CDS-ACTION-INTENT] - subcribe to isChangedConnector$ >>', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusByConnector(this.action.intentName, this.idConnector); + this.logger.log('[ACTION-INTENT] - checkConnectionStatusByConnector:', this.action.intentName, this.idConnector, resp); + this.isConnected = resp.isConnected; + this.idConnection = resp.idConnection; + } + + /** */ + // private updateSingleConnector(){ + // if(!this.action.intentName)this.isConnected = false; + // else this.isConnected = true; + // this.isConnected = this.action.intentName?true:false; + + // this.logger.log('[ACTION-INTENT] updateSingleConnector:'); + // const resp = updateSingleConnector(this.connector, this.action, this.isConnected, this.idConnection); + // if(resp){ + // this.isConnected = resp.isConnected; + // this.idConnection = resp.idConnection; + // this.action = resp.action; + // this.logger.log('[ACTION-INTENT] updateSingleConnector:', resp); + // if (resp.emit) { + // this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + // } + // } + // } + + private initialize() { + // //this.logger.log('[CDS-ACTION-INTENT] - initialize - isConnected ', this.action.intentName); + // if(!this.action){ + // this.logger.log('[CDS-ACTION-INTENT] - ERROR ACTION ', this.intentSelected); + // } + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnector = this.idIntentSelected+'/'+this.action._tdActionId; + this.intents = this.intentService.getListOfIntents(); + this.intents.sort((a, b) => a.name.localeCompare(b.name)); + this.element = Object.values(ACTIONS_LIST).find(el => el.type === this.action._tdActionType); + // this.logger.log('[CDS-ACTION-INTENT] - initialize - element ', this.element); + this.checkConnectionStatus(); + this.logger.log('[CDS-ACTION-INTENT] - initialize - idIntentSelected ', this.idIntentSelected); + this.logger.log('[CDS-ACTION-INTENT] - initialize - idConnector ', this.idConnector); + this.logger.log('[CDS-ACTION-INTENT] - initialize - intents ', this.intents); + } + + + private updateConnector(){ + this.logger.log('[CDS-ACTION-INTENT] **************************2222', this.action.intentName); + this.isConnected = this.action.intentName?true:false; + const array = this.connector.fromId.split("/"); + const idIntent= array[0]; + const idAction= array[1]; + if(this.idIntentSelected !== idIntent){ + return; + } + try { + if(!this.action.intentName)this.isConnected = false; + else this.isConnected = true; + if(idAction === this.action._tdActionId ){ + this.logger.log('[CDS-ACTION-INTENT] - updateConnector :: ', idAction, this.action._tdActionId, this.connector); + if(this.connector.deleted){ + this.action.intentName = null; + this.isConnected = false; + this.idConnection = null; + } else { + this.isConnected = true; + this.idConnection = this.connector.fromId+"/"+this.connector.toId; + this.action.intentName = "#"+this.connector.toId; + } + if(this.connector.save) + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + } + } catch (error) { + this.logger.log('error: ', error); + } + } + + onChangeSelect(event: {name: string, value: string}){ + if(event){ + this.action.intentName = event.value; + if(!this.action._tdActionTitle){ + this.action._tdActionTitle = this.intents.find(intent => intent.value === event.value).name; + } + let connector = { type: 'create', fromId: this.idConnector, toId: this.action.intentName }; + this.onConnectorChange.emit(connector); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: JSON.parse(JSON.stringify(this.action))}); + } + } + + onResetSelect(event:{name: string, value: string}) { + let connector = { type: 'delete', fromId: this.idConnector, toId: this.action.intentName }; + this.action.intentName = null; + this.onConnectorChange.emit(connector); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: JSON.parse(JSON.stringify(this.action))}); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent.component.spec.ts new file mode 100644 index 000000000..88b25ce65 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-intent/cds-action-intent.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionIntentComponent } from './cds-action-intent.component'; + +describe('CdsActionIntentComponent', () => { + let component: CdsActionIntentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionIntentComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionIntentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.html new file mode 100644 index 000000000..01defcf15 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.html @@ -0,0 +1,131 @@ +
+ + + + + +
+ +
+
+ +
+ + +
+
+ + +
+ + + +
+ + + +
+ + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.scss new file mode 100644 index 000000000..02318684d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.scss @@ -0,0 +1,9 @@ +.action-row { + min-height: 24px; +} + +.title-preview-label > span{ + font-weight: 600; +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.ts new file mode 100644 index 000000000..9384f580f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration-new.component.ts @@ -0,0 +1,238 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { IntentService } from '../../../../../services/intent.service'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { ActionIteration } from 'src/app/models/action-model'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; + +@Component({ + selector: 'cds-action-iteration-new', + templateUrl: './cds-action-iteration-new.component.html', + styleUrls: ['./cds-action-iteration-new.component.scss'] +}) +export class CdsActionIterationNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionIteration; + @Input() previewMode: boolean = true; + @Input() project_id: string; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + /** CONNECTOR */ + idIntentSelected: string; + idConnectorGoTo: string; + idConnectorFallback: string; + idConnectionGoTo: string; + idConnectionFallback: string; + isConnectedGoTo: boolean = false; + isConnectedFallback: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private intentService: IntentService + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize() + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + private initialize() { + if(this.intentSelected){ + this.initializeConnector(); + this.checkConnectionStatus(); + } + this.logger.log('[ACTION-ITERATION] initialize action -->', this.action) + } + + private initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorGoTo = this.idIntentSelected+'/'+this.action._tdActionId + '/goto'; + this.idConnectorFallback = this.idIntentSelected+'/'+this.action._tdActionId + '/fallback'; + this.listOfIntents = this.intentService.getListOfIntents() + } + + private checkConnectionStatus(){ + // Check goToIntent connection + if(this.action.goToIntent){ + this.isConnectedGoTo = true; + const posId = this.action.goToIntent.indexOf("#"); + if (posId !== -1) { + const toId = this.action.goToIntent.slice(posId+1); + this.idConnectionGoTo = this.idConnectorGoTo+"/"+toId; + } + } else { + this.isConnectedGoTo = false; + this.idConnectionGoTo = null; + } + + // Check fallbackIntent connection + if(this.action.fallbackIntent){ + this.isConnectedFallback = true; + const posId = this.action.fallbackIntent.indexOf("#"); + if (posId !== -1) { + const toId = this.action.fallbackIntent.slice(posId+1); + this.idConnectionFallback = this.idConnectorFallback+"/"+toId; + } + } else { + this.isConnectedFallback = false; + this.idConnectionFallback = null; + } + + this.logger.log('[ACTION-ITERATION] checkConnectionStatus:', { + goToIntent: this.action.goToIntent, + fallbackIntent: this.action.fallbackIntent, + idConnectionGoTo: this.idConnectionGoTo, + idConnectionFallback: this.idConnectionFallback, + isConnectedGoTo: this.isConnectedGoTo, + isConnectedFallback: this.isConnectedFallback + }); + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ITERATION] updateConnector - connector:', this.connector); + + if (!this.connector?.fromId) { + this.logger.log('[ACTION-ITERATION] updateConnector - no fromId, returning'); + return; + } + + const segments = this.connector.fromId.split('/'); + if (segments.length < 2) { + this.logger.log('[ACTION-ITERATION] updateConnector - invalid segments, returning'); + return; + } + + const idAction = segments[1]; + if (idAction !== this.action._tdActionId) { + this.logger.log('[ACTION-ITERATION] updateConnector - actionId mismatch, returning'); + return; + } + + // Determina se è goTo (con /goto) o fallback (con /fallback) + const isGoToSegment = this.connector.fromId.endsWith('/goto'); + const isFallbackSegment = this.connector.fromId.endsWith('/fallback'); + + this.logger.log('[ACTION-ITERATION] updateConnector - type check:', { + fromId: this.connector.fromId, + isGoToSegment, + isFallbackSegment, + deleted: this.connector.deleted, + save: this.connector.save + }); + + let shouldEmit = false; + + // Gestione della cancellazione del connector + if (this.connector.deleted) { + if (isGoToSegment) { + this.logger.log('[ACTION-ITERATION] Deleting goToIntent connector'); + this.action.goToIntent = null; + this.isConnectedGoTo = false; + this.idConnectionGoTo = null; + } + if (isFallbackSegment) { + this.logger.log('[ACTION-ITERATION] Deleting fallbackIntent connector'); + this.action.fallbackIntent = null; + this.isConnectedFallback = false; + this.idConnectionFallback = null; + } + if (this.connector.save) { + shouldEmit = true; + } + } else { + // Aggiornamento del connector + if (isGoToSegment) { + this.logger.log('[ACTION-ITERATION] Updating goToIntent connector to:', this.connector.toId); + this.action.goToIntent = '#' + this.connector.toId; + this.isConnectedGoTo = true; + this.idConnectionGoTo = this.connector.id; + if (this.connector.save) { + shouldEmit = true; + } + } + if (isFallbackSegment) { + this.logger.log('[ACTION-ITERATION] Updating fallbackIntent connector to:', this.connector.toId); + this.action.fallbackIntent = '#' + this.connector.toId; + this.isConnectedFallback = true; + this.idConnectionFallback = this.connector.id; + if (this.connector.save) { + shouldEmit = true; + } + } + } + + this.logger.log('[ACTION-ITERATION] updateConnector result:', { + goToIntent: this.action.goToIntent, + fallbackIntent: this.action.fallbackIntent, + shouldEmit + }); + + if (shouldEmit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-ITERATION] onSelectedAttribute event", event) + this.logger.log("[ACTION-ITERATION] onSelectedAttribute property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeSelect(event:{name: string, value: string}, type: 'goToIntent' | 'fallbackIntent'){ + if(event){ + this.action[type]=event.value + switch(type){ + case 'goToIntent': + this.logger.log('[ACTION-ITERATION] onChangeSelect goToIntent - fromId:', this.idConnectorGoTo, 'toId:', this.action.goToIntent); + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorGoTo, toId: this.action.goToIntent}) + break; + case 'fallbackIntent': + this.logger.log('[ACTION-ITERATION] onChangeSelect fallbackIntent - fromId:', this.idConnectorFallback, 'toId:', this.action.fallbackIntent); + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFallback, toId: this.action.fallbackIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'goToIntent' | 'fallbackIntent') { + switch(type){ + case 'goToIntent': + this.logger.log('[ACTION-ITERATION] onResetBlockSelect goToIntent - fromId:', this.idConnectorGoTo, 'toId:', this.action.goToIntent); + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorGoTo, toId: this.action.goToIntent}) + break; + case 'fallbackIntent': + this.logger.log('[ACTION-ITERATION] onResetBlockSelect fallbackIntent - fromId:', this.idConnectorFallback, 'toId:', this.action.fallbackIntent); + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFallback, toId: this.action.fallbackIntent}) + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration.component.spec.ts new file mode 100644 index 000000000..25f33a188 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-iteration/cds-action-iteration.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionIterationComponent } from './cds-action-iteration.component'; + +describe('CdsActionIterationComponent', () => { + let component: CdsActionIterationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionIterationComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionIterationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.html new file mode 100644 index 000000000..7b8df208d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.html @@ -0,0 +1,65 @@ + +
+ + +
+ + +
+
+
+ data_object + + close +
+
+
+
{{'CDSCanvas.AttributeName' | translate }}
+
+ + +
+
+ +
+
{{'CDSCanvas.Condition' | translate }}
+
+
+ +
{{item.name | translate}}
+
+
+
+
+
{{'CDSCanvas.Value' | translate }}
+
+ + + +
+
+
+ +
+
+ +
+ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss new file mode 100644 index 000000000..629f31991 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss @@ -0,0 +1,360 @@ +#search { + display: flex; + flex-shrink: 0; + align-items: center; + border-bottom: 1px solid #e8eef3; + padding: 0px 15px; + gap: 10px; + input{ + background: transparent; + border: 0; + font-size: 16px; + height: 40px; + line-height: 20px; + width: 100%; + } +} + +.material-icons{ + color: var(--icon-color); + font-size: 18px; +} + +#scrollMe{ + max-height: calc(34vh - 50px); + overflow-y: scroll; +} + +#data{ + // padding: 15px 0px; + overflow-x: hidden; + &:first-child{ + margin-bottom: 20px; + padding-top: 15px; + } + + .category-name{ + margin-bottom: 10px; + padding: 0 15px; + color: #9ba6b3; + font-weight: 600; + font-size: 16px; + line-height: 20px; + } + + .category-row{ + display: flex; + align-items: center; + gap: 10px; + height: 32px; + padding: 0 15px; + transition: background-color .2s,opacity .2s; + + &:hover{ + background: #f0f4f7; + cursor: pointer; + } + } + + .category-row-name{ + color: #444a51; + font-size: 16px; + font-weight: 500; + line-height: 20px; + margin-right: 20px; + margin-bottom: 0px; + cursor: pointer; + } +} + +#no-data{ + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; + padding: 20px; + + -webkit-box-align: center; + -webkit-box-pack: center; + -webkit-box-flex: 1; + + div.no-result{ + display: flex; + align-items: center; + flex-direction: column; + + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-box-align: center; + + margin: 10px 0; + width: 100%; + + color: #516173; + } + + span.material-icons{ + color: #c6cdd4; + display: block; + font-size: 30px; + margin-bottom: 15px; + } + + span.text{ + text-align: center; + font-size: 16px; + line-height: 20px; + } +} + +#add-attribute{ + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 8px 15px; + width: 100%; + border-top: 1px solid rgb(232, 238, 243); + transition: all 0.3s ease 0s; + color: rgb(34, 39, 45); + font-size: 16px; + font-weight: 600; + line-height: 20px; + transition: color 0.3s ease 0s; + &:hover{ + color: #9ba6b3; + } +} + +.step2{ + // max-width: 90vw; + padding: 20px; + // width: 380px; +} + +.filter-item-drop-down{ + grid-row-gap: 20px; + display: grid; + grid-template-columns: minmax(0,1fr); + gap: 10px; + width: 100%; +} + +section.header{ + align-items: center; + display: grid; + grid-template-columns: auto 1fr auto; + grid-column-gap: 10px; + + label{ + font-size: 16px; + line-height: 20px; + font-weight: 600; + color: var(--blu); + margin: 0; + } + span.material-icons{ + font-size: 25px; + cursor: pointer; + color: var(--blu); + } +} + +section.attribute{ + &>div{ + margin-bottom: 5px; + color: #22272d; + font-weight: 500; + font-size: 16px; + line-height: 20px; + } + input { + background: #fff; + border: 1px solid #c6cdd4; + border-radius: 6px; + color: #22272d; + display: block; + font-family: Source Sans Pro,sans-serif; + font-weight: 400; + line-height: 26px; + padding: 4px 15px; + transition: border .3s; + width: 100%; + font-size: 15px; + height: 36px; + } + .operand-attribute{ + position: relative; + .close { + position: absolute; + display: flex; + top: 9px; + right: 0px; + width: 19px; + height: 19px; + font-size: 13px; + border-radius: 50%; + /* background: #fff; */ + /* border: 1px solid #ecb606; */ + color: #dde1e5; + cursor: pointer; + opacity: 1; + justify-content: center; + align-items: center; + padding: 0; + margin: auto 0; + } + } + +} + +section.condition{ + &>div{ + margin-bottom: 5px; + color: #22272d; + font-weight: 500; + font-size: 16px; + line-height: 20px; + } + + div.operators-list{ + display: flex; + flex-wrap: wrap; + margin: -5px; + } + + .operator{ + display: flex; + gap: 5px; + font-size: 15px; + font-weight: 400; + line-height: 19px; + align-items: center; + border-radius: 6px; + margin: 5px; + padding: 10px 15px; + transition: all 0.3s ease 0s; + background-color: var(--blu-light-01); + color: var(--blu); + cursor: pointer; + + &.active, + &:hover{ + background: var(--blu); + color: var(--blu-light-03); + img{ + filter: brightness(0) saturate(100%) invert(100%) sepia(20%) saturate(7023%) hue-rotate(179deg) brightness(106%) contrast(89%); + } + } + + + } +} + +section.value{ + &>div{ + margin-bottom: 5px; + color: #22272d; + font-weight: 500; + font-size: 16px; + line-height: 20px; + } + input { + background: #fff; + border: 1px solid #c6cdd4; + border-radius: 6px; + color: #22272d; + display: block; + font-family: Source Sans Pro,sans-serif; + font-weight: 400; + line-height: 26px; + padding: 4px 15px; + transition: border .3s; + width: 100%; + font-size: 15px; + height: 36px; + + &[readonly=true]{ + pointer-events: none; + cursor: default; + } + } + + div.value-wrp{ + position: relative; + + + .flex{ + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + + display: flex; + align-items: center; + justify-content: center; + + .close{ + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + &:hover{ + background: #ecb606; + color: white; + } + } + + } + + div.tag{ + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } + } +} + +section.submit{ + button{ + width: 100%; + padding: 0px 10px; + border-radius: 4px; + height: 37px; + line-height: 35px; + + } +} + + +cds-textarea#operand2 ::ng-deep { + display: flex; + textarea { + // border: 1px solid rgb(118, 118, 118) !important; + resize: none !important; + // padding: 8px 20px !important; + + // height: 25px !important; + // min-height: 25px !important; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.ts new file mode 100644 index 000000000..c39e7791f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.ts @@ -0,0 +1,198 @@ +import { SatPopover } from '@ncstate/sat-popover'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Component, Input, OnInit, SimpleChanges, EventEmitter, Output, HostListener, ViewChild, ElementRef } from '@angular/core'; +import { OPERATORS_LIST, OperatorValidator, TYPE_OPERATOR } from '../../../../../../utils'; +import { Condition } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'base-condition-row', + templateUrl: './base-condition-row-new.component.html', + styleUrls: ['./base-condition-row-new.component.scss'] +}) +export class BaseConditionRowComponent implements OnInit { + @ViewChild('operand1') inputOperand1: ElementRef; + @Input() condition: Condition; + @Output() close = new EventEmitter(); + + textVariable: string = ''; + filteredVariableList: Array<{name: string, value: string}> = [] + filteredIntentVariableList: Array<{name: string, value: string, src?: string}> + operatorsList: Array<{}> = [] + step: number = 0; + disableInput: boolean = true; + disableSubmit: boolean = true; + conditionForm: FormGroup; + readonlyTextarea: boolean = false; + setAttributeBtnOperand2: boolean = false; + canShowOperand2: boolean = true + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private formBuilder: FormBuilder + ) { } + + ngOnInit(): void { + this.logger.log('[BASE_CONDITION_ROW] ******* ngOnInit-->'); + } + + ngOnChanges(changes: SimpleChanges){ + this.logger.log('[BASE_CONDITION_ROW] ******* ngOnChanges-->'); + this.conditionForm = this.createConditionGroup() + this.step=0; + this.operatorsList = Object.keys(OPERATORS_LIST).map(key => (OPERATORS_LIST[key])) + if(this.condition){ + this.logger.log('[BASE_CONDITION_ROW] selectedConditionnnn-->', this.condition) + this.setFormValue() + this.step = 1; + } + } + + createConditionGroup(): FormGroup{ + return this.formBuilder.group({ + type: ["condition", Validators.required], + operand1 : [ '', Validators.required], + operator: ['equalAsNumbers', [Validators.required, OperatorValidator]], + operand2: this.formBuilder.group({ + type: ['const', Validators.required], + value: ['', Validators.nullValidator], + name: ['', Validators.nullValidator] + }) + }) + } + + setFormValue(){ + this.conditionForm.patchValue({ + operand1 : this.condition.operand1, + operator: this.condition.operator, + operand2: this.condition.operand2 + }); + if(this.condition.operand2){ + this.setAttributeBtnOperand2 = false; + if(this.condition.operand2.type === 'var'){ + this.readonlyTextarea = true + } + } else { + this.setAttributeBtnOperand2 = true; + this.readonlyTextarea = false; + } +} + +/** START EVENTS cds-textarea **/ + onChangeTextArea(text: string){ + this.logger.log('textttt', text, text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))); + if(text){ + this.disableSubmit = false; + this.setAttributeBtnOperand2 = false; + }else{ + this.disableSubmit = true; + this.setAttributeBtnOperand2 = true; + } + if(text && text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g))){ + text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g)).forEach(match => { + text = text.replace(text,match) + this.conditionForm.patchValue({ operand2: {type: 'const', name: text}}, {emitEvent: false}) + }); + } + } + + onSelectedAttribute(variableSelected: {name: string, value: string}, step: number){ + this.logger.log('1 onVariableSelected-->', step, this.conditionForm, variableSelected); + if(step === 0){ + this.conditionForm.patchValue({ operand1: variableSelected.value}, {emitEvent: false}) + this.step +=1; + }else if (step == 1){ + this.conditionForm.patchValue({ operand2: { type: 'var', name: variableSelected.name, value: variableSelected.value}}, {emitEvent: false}); + this.logger.log('formmmmm', this.conditionForm); + this.readonlyTextarea = true; + this.setAttributeBtnOperand2 = false; + this.disableSubmit = false; + } + this.logger.log('******* onVariableSelected-->', step, variableSelected); + } + + onClearSelectedAttribute(){ + this.logger.log('onClearSelectedAttribute-->'); + this.conditionForm.patchValue({ operand2: {type: 'const', name: '', value: ''}}, {emitEvent: false}) + this.disableSubmit = true; + this.readonlyTextarea = false; + this.setAttributeBtnOperand2 = true; + } + /** END EVENTS cds-textarea **/ + + + + onClearInput(){ + this.conditionForm.patchValue({ operand2: {type: 'const', name: '', value: ''}}, {emitEvent: false}) + } + + onAddCustomAttribute(){ + this.step +=1 + this.disableInput = false + setTimeout(()=>{ + this.inputOperand1.nativeElement.focus() + },300) + } + + onClickOperator(operator: {}){ + this.conditionForm.patchValue({ operator: operator['type']}) + + // this.disableSubmit = true; + this.readonlyTextarea = false; + this.setAttributeBtnOperand2 = true; + this.canShowOperand2 = true; + + //activate submit button and disable 'Value' textarea i operator is equal to 'isEmpty' + if(operator['type'] === TYPE_OPERATOR.isEmpty|| + operator['type'] === TYPE_OPERATOR.isNull || + operator['type'] === TYPE_OPERATOR.isUndefined ){ + + this.onClearInput() + this.canShowOperand2 = false + + this.disableSubmit = false; + this.readonlyTextarea = true; + this.setAttributeBtnOperand2 = false; + } + } + + onSubmitCondition(){ + this.logger.log('onSubmitCondition-->', this.conditionForm) + if(this.conditionForm.valid){ + let condition: Condition = new Condition() + condition = Object.assign(condition, this.conditionForm.value); + condition.operand2.type == 'var'? condition.operand2.name = condition.operand2.value: null; + this.step = 0; + this.conditionForm = this.createConditionGroup() + this.close.emit(condition) + } + } + + onClose(){ + this.logger.log('onClose pressed') + this.step = 0; + this.disableInput = true + this.conditionForm = this.createConditionGroup() + this.close.emit() // CLOSE BASE-FILTER POPOVER (IN PARENT) + } + + onDeleteInputField(){ + this.conditionForm.patchValue({ operand1:'' }, {emitEvent: false}); + } + + private _filter(value: string, array: Array): Array { + const filterValue = value.toLowerCase(); + return array.filter(option => option.name.toLowerCase().includes(filterValue)); + } + + @HostListener('document:keydown', ['$event']) + onKeyPress(event){ + const keyCode = event.which || event.keyCode; + if (keyCode === 27) { // Esc keyboard code + this.onClose(); + } + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row.component.spec.ts new file mode 100644 index 000000000..dd76a3c16 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseConditionRowComponent } from './base-condition-row.component'; + +describe('BaseConditionRowComponent', () => { + let component: BaseConditionRowComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ BaseConditionRowComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BaseConditionRowComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.html new file mode 100644 index 000000000..c87621b0f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.html @@ -0,0 +1,63 @@ +
+ +
+
+ +
+
+ delete +
+
+ data_object +
+
+ {{group?.operand1}} + {{OPERATORS_LIST[group?.operator].name | translate }} + {{group?.operand2?.value}} + {{group?.operand2?.name}} +
+
+ +
+ + +
+
+
+ +
+
+ add + {{'CDSCanvas.AddNewCondition' | translate }} +
+
+ +
+ + + + + + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss new file mode 100644 index 000000000..be6fe8a12 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss @@ -0,0 +1,223 @@ +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} +.base-filter{ + &:hover{ + div.filter-remove{ + opacity: 1; + transition: opacity 0.3s ease 0s; + } + } +} +.content{ + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + padding: 20px; + border-radius: 4px; + display: flex; + flex-direction: column; + gap: 10px; +} + +.control-buttons{ + height: 100%; + left: -44px; + position: absolute; + top: 0px; + width: 44px; + + div.filter-remove{ + position: absolute; + right: -8px; + top: -14px; + + opacity: 0; + + height: 28px; + width: 28px; + + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background: white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + + span.material-icons, + span.material-icons-outlined{ + font-size: 20px; + color: var(--backGroundColor); + } + + &:hover{ + background-color: var(--textColor); + span.material-icons, + span.material-icons-outlined{ + color: var(--backGroundColor); + } + } + } +} + +.basic-filter-wrp{ + // background: #fff; + // margin: 0 30px; + // padding: 20px 0px 0px; + grid-row-gap: 15px; + border-radius: 4px; + display: flex; + justify-content: center; + + .add-filter-button{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + + user-select: none; + box-sizing: border-box; + outline: none; + border: 1px dashed var(--blu-light-02); + border-radius: var(--button-border-radius-base); + color: var(--blu-light-02); + cursor: pointer; + font-size: 0.7em; + font-weight: 400; + line-height: var(--button-height-base); + // margin: 0px 5px 0; + order: 1; + padding: 0 10px; + transition: all .3s; + min-width: 100px; + text-align: center; + width: fit-content; + + + &:hover{ + border-color: var(--textColor); + color: var(--textColor); + } + } + +} + + +::ng-deep .base-filter--add-filter-panel { + // position: relative; + box-shadow: 0 0 20px 4px #9aa1b126, 0 4px 80px -8px #24282f40, 0 4px 4px -2px #5b5e6926; + background: rgb(255,255,255); + border-radius: 4px; + margin: auto; + width: 500px; + max-height: 80%; + min-height: 385px; + overflow: auto; + max-width: 500px; + display: inline-block; + top: 50%!important; + margin-top: -20%; + .category-row-name { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden !important; + } +} + +.filter-operator { + min-width: 100px; + width: fit-content; + margin: 10px auto; +} + +::ng-deep .filter-operator { + .select-bot-box { + width: max-content; + min-width: 70px; + text-align: center; + margin: 10px auto; + } +} + +.filter-condition{ + -webkit-box-align: center; + align-items: center; + display: flex; + position: relative; + border-radius: var(--border-radius-base); + padding: 4px 15px; + transition: background-color 0.3s ease 0s, border 0.3s ease 0s, opacity 0.3s ease 0s; + cursor: pointer; + background: var(--backGroundColor); + border-width: 1px; + border-style: solid; + border-color: var(--backGroundColor); + border-image: initial; + &:hover{ + background: var(--hoverBackgroundColor); + border-color: var(--textColor); + div.remove{ + opacity: 1; + } + } + + div.remove { + position: absolute; + right: -8px; + top: -14px; + transition: opacity 0.3s ease 0s; + opacity: 0; + height: 28px; + width: 28px; + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background:white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + span.material-icons { + font-size: 20px; + color: var(--textColor); + } + &:hover { + background-color: var(--hoverBackgroundColor); + } + } + + div.filter-icon { + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + color: var(--textColor); + display: flex; + font-size: 15px; + justify-content: center; + margin-right: 10px; + width: 15px; + transition: color 0.3s ease 0s; + } +} + +.ellips{ + line-height: 20px; + text-overflow: ellipsis; + white-space: nowrap; + transition: color 0.3s ease 0s; + overflow: hidden !important; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.ts new file mode 100644 index 000000000..df00dcab1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { CDSFilterComponent } from '../../../../../../cds-base-element/filter/filter.component'; + +@Component({ + selector: 'base-filter', + templateUrl: './base-filter-new.component.html', + styleUrls: ['./base-filter-new.component.scss'] +}) +export class BaseFilterComponent extends CDSFilterComponent { + + + constructor() { + super(); + } + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter.component.spec.ts new file mode 100644 index 000000000..59c02b687 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseFilterComponent } from './base-filter.component'; + +describe('BaseFilterComponent', () => { + let component: BaseFilterComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ BaseFilterComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BaseFilterComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.html new file mode 100644 index 000000000..2969d30aa --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.html @@ -0,0 +1,181 @@ +
+ +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + +
+ +
+ + +
+
+ +
+ +
+ +
+ +
+
+
delete
+
+ + +
+ + +
+
+ + +
+
+ +
+ +
+ +
+
+
add
+ {{'CDSCanvas.AddConditionsGroup' | translate }} +
+
+ + + +
+
+
+ +
+ MATCH +
+ + + +
+ + +
+
+ {{'CDSCanvas.Else' | translate | titlecase}} +
+ + + +
+ +
+ +
+ + +
+ + + +
{{'CDSCanvas.ClickAddCondition' | translate }}
+
+ + +
+
+ + +
+
+
+
+ data_object +
+
+ {{condition?.operand1}} + {{OPERATORS_LIST[condition?.operator].name | translate }} + {{condition?.operand2?.value}} + {{condition?.operand2?.name}} +
+ +
+
{{condition?.operator}}
+
+
+ + +
+ {{group.operator}} +
+
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss new file mode 100644 index 000000000..d0cc53f8d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss @@ -0,0 +1,264 @@ +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--blu-light-03)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --border-radius-base: 8px +} + +/* customize scrollbar */ +::-webkit-scrollbar { + width: 0px; +} + +.flex-element{ + display: flex; + width: 100%; + align-items: center; + justify-content: center; +} + + + + +// _________________CONDITION ::: START ___________________________ +::ng-deep .add-filter-panel { + display: flex; + -ms-flex-direction: column; + flex-direction: column; + // max-height: 600px; + min-height: 200px; + box-shadow: 0 0 20px 4px rgb(154 161 177 / 15%), 0 4px 80px -8px rgb(36 40 47 / 25%), + 0 4px 4px -2px rgb(91 94 105 / 15%); + background: rgb(255, 255, 255); + border-radius: 4px; + // padding: 15px; + margin-top: 10px; + width: 500px +} + + + +.filter-add-group-wrapper, +.group-operator-wrapper{ + align-items: center; + display: flex; + height: 40px; + justify-content: center; + width: 100%; + padding: 0; + .filter-add-group{ + cursor: pointer; + display: flex; + margin: 0px 10px; + transition: opacity 0.3s ease 0s; + span.text{ + color: var(--textColor); + font-weight: 600; + } + } + + .filter-add-group-plus{ + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + display: flex; + height: 22px; + justify-content: center; + margin-right: 10px; + width: 22px; + background: var(--action-item-background); + border-radius: 100%; + transition: background-color 0.3s ease 0s; + + span.material-icons{ + color: var(--textColor); + font-size: 20px; + transition: color 0.6s ease 0s; + } + } + + &::before{ + -webkit-box-flex: 1; + content: ""; + flex-grow: 1; + height: 0px; + width: 0px; + border-top: 1px solid var(--textColor); + } + + &::after{ + -webkit-box-flex: 1; + content: ""; + flex-grow: 1; + height: 0px; + width: 0px; + border-top: 1px solid var(--textColor); + } + + &:hover{ + opacity: 0.8; + } +} +.add-conditions-group { + margin: 0px 0 40px; +} + +.base-filter{ + position: relative; + &:hover{ + div.filter-remove{ + opacity: 1; + transition: opacity 0.3s ease 0s; + } + } +} + +form > div { + display: flex; + flex-direction: column; + gap: 5px; +} + +cds-select.operator ::ng-deep{ + min-width:70px; + .ng-select.ng-select-single .ng-select-container{ + height: 28px; + min-height: 28px; + } +} + +.control-buttons{ + height: 100%; + left: -44px; + position: absolute; + top: 0px; + width: 44px; + + div.filter-remove{ + position: absolute; + right: -8px; + top: -14px; + transition: opacity 0.3s ease 0s; + opacity: 0; + height: 28px; + width: 28px; + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background: white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + + span.material-icons, + span.material-icons-outlined{ + font-size: 20px; + color: var(--textColor); + } + + &:hover { + background-color: var(--hoverBackgroundColor); + } + } +} + +// _________________CONDITION ::: END ___________________________ + + + + +// _________________ TRUE/FALSE/STOP::: START ___________________________ + +.checkbox-condition{ + position: absolute; + bottom: 10px; + margin: 0; +} + +::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { + border-color: var(--blu) !important; +} + +// overwrite the checkbox background +::ng-deep .mat-checkbox-checked .mat-checkbox-background, +.mat-checkbox-indeterminate .mat-checkbox-background { + background-color: var(--blu) !important; + .mat-checkbox-checkmark { + background: var(--blu) !important;; + .mat-checkbox-checkmark-path { + stroke: white; + stroke-width: 5px; + } + } + +} + +// _________________ TRUE/FALSE/STOP::: END ___________________________ + + + +#conditions{ + display: flex; + flex-direction: column; + align-items: center; + + .group{ + display: flex; + width: 100%; + justify-content: center; + } + .group-operator{ + font-size: 9px; + align-self: center; + justify-self: center; + } + + .expression{ + font-size: 9px; + line-height: 15px; + background-color: var(--intent-preview-background); + padding: 3px; + border-radius: 4px; + width: 100%; + } + + .condition-group{ + display: flex; + align-items: center; + gap: 5px; + background: rgb(245, 245, 245); + border-radius: 3px; + padding: 2px; + } + + div.filter-icon { + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + color: var(--icon-color); + display: flex; + font-size: 15px; + justify-content: center; + width: 15px; + transition: color 0.3s ease 0s; + span.material-icons{ + font-size: 15px; + color: var(--icon-color); + } + } + + .ellips{ + line-height: 20px; + text-overflow: ellipsis; + white-space: nowrap; + transition: color 0.3s ease 0s; + overflow: hidden !important; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.ts new file mode 100644 index 000000000..a3b031f7e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.ts @@ -0,0 +1,276 @@ +import { TYPE_UPDATE_ACTION, OPERATORS_LIST, OperatorValidator } from '../../../../../utils'; +import { Intent } from 'src/app/models/intent-model'; +import { ActionJsonCondition, Expression, Operator } from 'src/app/models/action-model'; +import { Component, EventEmitter, Host, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { AbstractControl, FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms'; +import { SatPopover } from '@ncstate/sat-popover'; +import { IntentService } from '../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { ConnectorService } from 'src/app/chatbot-design-studio/services/connector.service'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-json-condition-new', + templateUrl: './cds-action-json-condition-new.component.html', + styleUrls: ['./cds-action-json-condition-new.component.scss'] +}) +export class CdsActionJsonConditionNewComponent implements OnInit { + + @ViewChild("addFilter", {static: false}) myPopover : SatPopover; + + @Input() intentSelected: Intent; + @Input() action: ActionJsonCondition; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + actionJsonConditionFormGroup: FormGroup + trueIntentAttributes: string = ""; + falseIntentAttributes: string = ""; + booleanOperators=[ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},] + OPERATORS_LIST = OPERATORS_LIST; + + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private formBuilder: FormBuilder, + private intentService: IntentService, + private connectorService: ConnectorService + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.log('CdsActionJsonConditionComponent isChangedConnector-->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // ngOnChanges() { + // this.initialize(); + // if(this.intentSelected){ + // this.initializeConnector(); + // } + // this.logger.log('[ACTION-JSON-CONDITION] actionnn-->', this.action) + // if (this.action) { + // this.setFormValue() + // } + // } + + + private initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-JSON-CONDITION] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-JSON-CONDITION] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + private initialize() { + this.actionJsonConditionFormGroup = this.buildForm(); + this.actionJsonConditionFormGroup.valueChanges.subscribe(form => { + this.logger.log('[ACTION-JSON-CONDITION] form valueChanges-->', form) + if(form && (form.trueIntent !== '' || form.falseIntent !== '' || form.stopOnConditionMet !== '')){ + this.action.trueIntent = this.actionJsonConditionFormGroup.value.trueIntent + this.action.falseIntent = this.actionJsonConditionFormGroup.value.falseIntent + this.action.stopOnConditionMet = this.actionJsonConditionFormGroup.value.stopOnConditionMet + // this.action = Object.assign(this.action, this.actionJsonConditionFormGroup.value) + } + }) + this.trueIntentAttributes = this.action.trueIntentAttributes; + this.falseIntentAttributes = this.action.falseIntentAttributes; + if(this.intentSelected){ + this.initializeConnector(); + } + this.logger.log('[ACTION-JSON-CONDITION] actionnn-->', this.action) + if (this.action) { + this.setFormValue() + } + // ordina listOfIntents per name + this.listOfIntents.sort((a, b) => a.name.localeCompare(b.name)); + } + + private setFormValue(){ + this.actionJsonConditionFormGroup.patchValue({ + trueIntent: this.action.trueIntent, + falseIntent: this.action.falseIntent, + stopOnConditionMet: this.action.stopOnConditionMet, + // groups: this.action.groups, + }) + } + + buildForm(): FormGroup{ + return this.formBuilder.group({ + trueIntent: ['', Validators.required], + falseIntent: ['', Validators.required], + stopOnConditionMet: [false, Validators.required], + // groups: this.formBuilder.array([ + // this.createExpressionGroup(), + // // this.createOperatorGroup() + // ]) + }) + } + + createExpressionGroup(): FormGroup{ + return this.formBuilder.group({ + type:["expression", Validators.required], + conditions: this.formBuilder.array([ + // this.createConditionGroup(), this.createOperatorGroup() + ]) + }) + } + + createConditionGroup(): FormGroup{ + return this.formBuilder.group({ + type: ["condition", Validators.required], + operand1 : [ '', Validators.required], + operator: ['', Validators.required, OperatorValidator], + operand2: ['', Validators.required] + }) + } + + createOperatorGroup(): FormGroup{ + return this.formBuilder.group({ + type: ["operator", Validators.required], + operator: [ '', Validators.required] + }) + } + + + onClickAddGroup(){ + this.action.groups.push(new Operator()) + this.action.groups.push(new Expression()) + this.logger.log('onClickAddGroup-->', this.action) + // let groups = this.actionJsonConditionFormGroup.get('groups') as FormArray + // groups.push(this.createOperatorGroup(), {emitEvent: false}) + // groups.push(this.createExpressionGroup(), {emitEvent: false}) + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onDeleteGroup(index: number, last: boolean){ + this.logger.log('onDeleteGroup', index, last, this.action.groups) + if(!last){ + this.action.groups.splice(index, 2) + }else if(last){ + this.action.groups.splice(index-1, 2) + } + if(this.action.groups.length === 0){ + this.action.groups.push(new Expression()); + // let groups = this.actionJsonConditionFormGroup.get('groups') as FormArray + // groups.push(this.createExpressionGroup(), {emitEvent: false}) + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeOperator(event, index: number){ + (this.action.groups[index] as Operator).operator = event['type'] + this.logger.log('onChangeOperator actionsss', this.action, this.actionJsonConditionFormGroup) + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeForm(event:{name: string, value: string}, type : 'trueIntent' | 'falseIntent'){ + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeExpression(event){ + // this.connectorService.updateConnector(this.intentSelected.intent_id); + this.logger.log('onChangeExpression actionsss', this.action, event) + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributes(attributes:any, type: 'trueIntent' | 'falseIntent'){ + if(type === 'trueIntent'){ + this.action.trueIntentAttributes = attributes; + } + if(type === 'falseIntent'){ + this.action.falseIntentAttributes = attributes; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onStopConditionMeet() { + try { + this.action.stopOnConditionMet = !this.action.stopOnConditionMet; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + } + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition.component.spec.ts new file mode 100644 index 000000000..b04228829 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionJsonConditionComponent } from './cds-action-json-condition.component'; + +describe('ActionFilterComponent', () => { + let component: CdsActionJsonConditionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionJsonConditionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionJsonConditionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.html new file mode 100644 index 000000000..cbd09de5d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.html @@ -0,0 +1,82 @@ + +
+ +
+ + + +
{{ 'CDSvariablesList.'+filteredVariableList[0].key | translate}}
+
+
+
+ data_object + + delete +
+
+
+ +
+ + + +
{{ 'CDSvariablesList.'+item.key | translate}}
+
+
+
+ {{variable?.icon}} + +
+ info +
+ + +
+
+
+ +
+ + + +
{{ 'CDSvariablesList.'+filteredGlobalsList[0].key | translate}}
+
+
+
+ lock + +
+
+
+ +
+
+ search + {{'CDSCanvas.NoVariableFound' | translate }} +
+
+
+ +
+ add +
{{'CDSCanvas.AddCustomAttributes' | translate }}
+
+ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss new file mode 100644 index 000000000..16c78ad65 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss @@ -0,0 +1,220 @@ +:host { + --background-color: #{var(--blu-light-01)}; + --column-color: var(--blu-02); + --text-color: var(--blu); + + --content-background: rgb(244, 246, 251, 0.4); + --base-radius: 8px +} + +#search { + display: flex; + flex-shrink: 0; + align-items: center; + border-bottom: 1px solid #e8eef3; + padding: 0px 15px; + gap: 10px; + + input{ + background: transparent; + border: 0; + font-size: 16px; + height: 40px; + line-height: 20px; + width: 100%; + } + + +} + +.material-icons, +.material-icons-outlined{ + color: var(--blu-light-02); + font-size: 18px; + + &:hover.delete{ + color: red !important; + } +} + +#variable-list-scrollMe { + // max-height: calc(34vh - 50px); + max-height: 60vh; + overflow-y: auto; +} + +#data{ + // padding: 15px 0px; + // overflow-x: hidden; + // &:first-child{ + // margin-bottom: 20px; + // padding-top: 15px; + // } + + .category-name{ + padding: 0 15px; + color: #9ba6b3; + font-weight: 600; + font-size: 16px; + line-height: 20px; + } + + .category-row{ + display: flex; + align-items: center; + gap: 10px; + height: 30px; + padding: 0 15px; + transition: background-color .2s,opacity .2s; + + &:hover{ + background: #f0f4f7; + cursor: pointer; + + .category-row-name { + font-weight: 500; + } + .material-icons, + .material-icons-outlined { + color: var(--blu); + } + } + } + + .category-row-name{ + color: var(--text-color); + font-size: 16px; + font-weight: 400; + line-height: 20px; + cursor: pointer; + width: 85%; + } +} + +#no-data{ + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; + padding: 20px; + + -webkit-box-align: center; + -webkit-box-pack: center; + -webkit-box-flex: 1; + + div.no-result{ + display: flex; + align-items: center; + flex-direction: column; + + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-box-align: center; + + margin: 10px 0; + width: 100%; + + color: #516173; + } + + span.material-icons, + span.material-icons-outlined{ + color: #c6cdd4; + display: block; + font-size: 30px; + margin-bottom: 15px; + } + + span.text{ + text-align: center; + font-size: 16px; + line-height: 20px; + } +} + + + + + +#add-attribute{ + border-top: 1px solid #e8eef3; + cursor: pointer; + flex-shrink: 0; + height: 43px; + transition: all .3s; + align-items: center; + display: flex; + justify-content: center; + .material-icons{ + margin-right: 15px; + color: var(--blu); + font-size: 24px; + font-weight: 500; + } + div { + color: var(--blu); + font-size: 16px; + font-weight: 600; + line-height: 20px; + transition: color .3s; + } +} + + +mat-expansion-panel { + box-shadow: none !important; + // background-color: var(--content-background); + border-bottom: 1px solid var(--gray-light-02); + overflow: visible; + border-radius: 0 !important; + &.open-block { + pointer-events: none; + } + mat-expansion-panel-header { + height: 40px; + } + &.mat-expanded { + ::ng-deep .mat-expansion-panel-body { + opacity: 1; + } + } + ::ng-deep { + + .mat-expansion-panel-body { + opacity: 0; + padding: 0; + } + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + } +} + +mat-expansion-panel#userDefined { + ::ng-deep { + .mat-expansion-panel-content{ + height: unset !important; + visibility: visible !important; + } + .mat-expansion-panel-content[style*="visibility: hidden"] * { + visibility: visible !important; + } + .mat-expansion-panel-body{ + opacity: 1 !important; + } + .mat-expansion-indicator::after { + display: none; + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.ts new file mode 100644 index 000000000..91b004303 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.ts @@ -0,0 +1,220 @@ +import { Component, Input, OnInit, Output, EventEmitter, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { DialogComponent } from '../../../../../../cds-base-element/dialog/dialog.component'; + +//SERVICES +import { FaqKbService } from 'src/app/services/faq-kb.service'; +import { DashboardService } from 'src/app/services/dashboard.service'; +//UTILS +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { variableList, TYPE_CHATBOT } from 'src/app/chatbot-design-studio/utils-variables'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'variable-list', + templateUrl: './variable-list-new.component.html', + styleUrls: ['./variable-list-new.component.scss'] +}) +export class VariableListComponent implements OnInit { + + @Output() onSelected = new EventEmitter() + + type_chatbot:TYPE_CHATBOT; + + variableListUserDefined: { key: string, elements: Array<{name: string, chatbot_types: string, value: string}>} // = variableList.userDefined + variableListGlobals: { key: string, elements: Array<{name: string, chatbot_types: string, value: string}>} + variableListSystemDefined: Array<{ key: string, elements: Array<{name: string, chatbot_types: string, value: string, description: string, src?: string}>}> //= variableList.systemDefined + + filteredVariableList: Array<{ key: string, elements: Array<{name: string, value: string}>}> //= [] + filteredGlobalsList: Array<{ key: string, elements: Array<{name: string, value: string}>}> //= [] + filteredIntentVariableList: Array<{ key: string, elements: Array<{name: string, value: string, description: string, src?: string}>}> + textVariable: string = ''; + idBot: string; + + isEmpty: boolean = false + isSearching: boolean = false + + BRAND_BASE_INFO = BRAND_BASE_INFO + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + public dialog: MatDialog, + private faqkbService: FaqKbService, + private dashboardService: DashboardService + ) { } + + ngOnInit(): void { + this.initialize(); + } + + ngOnChanges(){ + //this.initialize(); + } + + private initialize() { + // Ensure subtype is a valid TYPE_CHATBOT value, otherwise fallback to TYPE_CHATBOT.CHATBOT + if ( + this.dashboardService.selectedChatbot && + Object.values(TYPE_CHATBOT).includes(this.dashboardService.selectedChatbot.subtype as TYPE_CHATBOT) + ) { + this.type_chatbot = this.dashboardService.selectedChatbot.subtype as TYPE_CHATBOT; + } else { + this.type_chatbot = TYPE_CHATBOT.CHATBOT; + } + + + + this.idBot = this.dashboardService.id_faq_kb; + this.variableListUserDefined = variableList.find(el => el.key === 'userDefined'); + // Sort userDefined elements alphabetically by name + if (this.variableListUserDefined && this.variableListUserDefined.elements) { + this.variableListUserDefined.elements.sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }); + } + this.logger.log('[VARIABLE-LIST] initialize--> 1', this.type_chatbot, variableList); + + this.variableListGlobals = variableList.find(el => el.key === 'globals'); + // Sort globals elements alphabetically by name + if (this.variableListGlobals && this.variableListGlobals.elements) { + this.variableListGlobals.elements.sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }); + } + + this.variableListSystemDefined = variableList + .filter(el => (el.key !== 'userDefined' && el.key !== 'globals')) + .map(el => ({ + ...el, + elements: el.elements + .filter(elem => elem.chatbot_types?.includes(this.type_chatbot)) + .sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }) + })); + + // this.logger.log('[VARIABLE-LIST] initialize--> 2', this.variableListSystemDefined); + + this.filteredVariableList = [] + this.filteredGlobalsList = [] + this.filteredIntentVariableList = []; + if(this.variableListUserDefined){ + this.filteredVariableList.push(this.variableListUserDefined) + } + if(this.variableListGlobals){ + this.filteredGlobalsList.push(this.variableListGlobals) + } + variableList.filter(el => (el.key !== 'userDefined' && el.key !== 'globals')).map(el => { + // Sort elements alphabetically before adding to filteredIntentVariableList + const sortedElements = [...el.elements].sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }); + this.filteredIntentVariableList.push( { key: el.key, elements: sortedElements }) + }) + + + // if(this.variableListSystemDefined){ + // this.filteredIntentVariableList = this.variableListSystemDefined + // } + } + + openDialog() { + var that = this; + const dialogRef = this.dialog.open(DialogComponent, { + panelClass: 'custom-dialog-container', + data: {text: ''} + }); + dialogRef.afterClosed().subscribe(result => { + // this.logger.log(`Dialog result: ${result}`); + if(result && result !== undefined && result !== false){ + let variable = {name: result, chatbot_types:this.type_chatbot, value: result}; + that.variableListUserDefined.elements.push(variable); + // Sort elements alphabetically after adding new variable + that.variableListUserDefined.elements.sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }); + this.saveVariables(this.variableListUserDefined.elements); + } + }); + } + + onVariableDelete(variableSelected: {name: string, value: string}){ + let index = this.variableListUserDefined.elements.findIndex(el => el.name === variableSelected.name) + if(index > -1){ + this.variableListUserDefined.elements.splice(index, 1) + this.saveVariables(this.variableListUserDefined.elements) + } + } + + private saveVariables(variables){ + let jsonVar = {}; + variables.forEach(element => { + jsonVar[element.name] = element.name; + }); + this.faqkbService.addNodeToChatbotAttributes(this.idBot, 'variables', jsonVar).subscribe((data)=> { + if(data){ + //SUCCESS STATE + } + }, (error)=> { + //FAIL STATE + }, ()=>{ + // this.logger.debug('[RULES-ADD] faqkbService addRuleToChatbot - COMPLETE') + }) + } + + onVariableSelected(variableSelected: {name: string, value: string}){ + this.onSelected.emit(variableSelected); + } + + onChangeSearch(event){ + // this.logger.log('[VARIABLE-LIST] onChangeSearch-->', event, this.textVariable); + if(event && event.target){ + this.textVariable = event.target.value + }else { + this.textVariable = event + } + // this.logger.log('[VARIABLE-LIST] onChangeSearch--> 1', this.textVariable, this.variableListUserDefined, this.variableListGlobals, this.variableListSystemDefined); + this.filteredVariableList = this._filter2(this.textVariable, [this.variableListUserDefined]) + this.filteredGlobalsList = this._filter2(this.textVariable, [this.variableListGlobals]) + this.filteredIntentVariableList = this._filter2(this.textVariable, this.variableListSystemDefined) + // this.logger.log('[VARIABLE-LIST] onChangeSearch--> 2', this.filteredVariableList, this.filteredGlobalsList, this.filteredIntentVariableList); + this.isEmpty = (this.filteredIntentVariableList.every(el => el.elements.length === 0) && this.filteredVariableList[0].elements.length === 0 ) + this.isSearching = (this.textVariable !== '') + // this.logger.log('[VARIABLE-LIST] onChangeSearch--> 3', this.isEmpty, this.isSearching); + } + + private _filter(value: string, array: Array): Array { + const filterValue = value.toLowerCase(); + return array.filter(option => option.name.toLowerCase().includes(filterValue)); + } + + private _filter2(value: string, array: Array<{key: string, elements: Array}>): Array { + const filterValue = value.toLowerCase(); + return array.map(el => { + const filteredElements = el.elements.filter(option => option.name.toLowerCase().includes(filterValue)); + // Sort filtered elements alphabetically + filteredElements.sort((a, b) => { + const nameA = a.name?.toLowerCase() || ''; + const nameB = b.name?.toLowerCase() || ''; + return nameA.localeCompare(nameB); + }); + return { key: el.key, elements: filteredElements }; + }); + } + + onAddCustomAttribute(){ + this.openDialog(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list.component.spec.ts new file mode 100644 index 000000000..8d4e926ca --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { VariableListComponent } from './variable-list.component'; + +describe('VariableListComponent', () => { + let component: VariableListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ VariableListComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(VariableListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.html new file mode 100644 index 000000000..cbb766a49 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.html @@ -0,0 +1,92 @@ +
+ +
+
+
+ + + + +
+
+ {{item.key}} : {{item.value}} +
+
+
+ +
+
+
+ + + + +
+
+ {{ 'CDSCanvas.SelectProperty' | translate}} +
+
+
+ +
+ + +
+
+ + + +
+
+
add
+ {{'CDSCanvas.UpdateProperty' | translate }} +
+
+ +
+
+ + + + + +
+ +
+
+ delete +
+
+
+
+ + + + + +
+ +
+ + + + + +
+
+ +
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss new file mode 100644 index 000000000..24ddcf0d1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss @@ -0,0 +1,149 @@ +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +.content{ + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + padding: 20px; + border-radius: 4px; + display: flex; + flex-direction: column; + gap: 10px; + + &:not(:last-child){ + margin-bottom: 5px; + } +} + + +.setting-wrapper{ + display: grid; + grid-template-columns: repeat(2, 1fr); + justify-content: space-between; + gap: 5px; + + // this will target the last flashcard but only if there are an odd number of cards + & > *:nth-child(odd):last-child { + grid-column: span 2; + } +} + +.filter-add-group-wrapper, +.group-operator-wrapper{ + align-items: center; + display: flex; + height: 40px; + justify-content: center; + width: 100%; + padding: 0; + .filter-add-group{ + cursor: pointer; + display: flex; + margin: 0px 10px; + transition: opacity 0.3s ease 0s; + span.text{ + color: var(--textColor); + font-weight: 600; + } + } + + .filter-add-group-plus{ + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + display: flex; + height: 22px; + justify-content: center; + margin-right: 10px; + width: 22px; + background: var(--action-item-background); + border-radius: 100%; + transition: background-color 0.3s ease 0s; + + span.material-icons{ + color: var(--textColor); + font-size: 20px; + transition: color 0.6s ease 0s; + } + } + + &::before{ + -webkit-box-flex: 1; + content: ""; + flex-grow: 1; + height: 0px; + width: 0px; + border-top: 1px solid var(--textColor); + } + + &::after{ + -webkit-box-flex: 1; + content: ""; + flex-grow: 1; + height: 0px; + width: 0px; + border-top: 1px solid var(--textColor); + } + + &:hover{ + opacity: 0.8; + } +} + +.control-buttons{ + height: 100%; + left: -44px; + position: absolute; + top: 0px; + width: 44px; + + div.filter-remove{ + position: absolute; + right: -8px; + top: -14px; + transition: opacity 0.3s ease 0s; + opacity: 0; + height: 28px; + width: 28px; + -webkit-box-align: center; + -webkit-box-pack: center; + align-items: center; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + cursor: pointer; + display: flex; + justify-content: center; + background: white; + border-radius: 100%; + transition: background-color 0.3s ease 0s; + font-size: 12px; + + span.material-icons, + span.material-icons-outlined{ + font-size: 20px; + color: var(--textColor); + } + + &:hover { + background-color: var(--hoverBackgroundColor); + } + } +} + +.content{ + position: relative; + &:hover{ + div.filter-remove{ + opacity: 1; + transition: opacity 0.3s ease 0s; + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.ts new file mode 100644 index 000000000..cbc46d6e3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.ts @@ -0,0 +1,144 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { leadPropertyList } from 'src/app/chatbot-design-studio/utils-variables'; +import { ActionLeadUpdate } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-lead-update-new', + templateUrl: './cds-action-lead-update-new.component.html', + styleUrls: ['./cds-action-lead-update-new.component.scss'] +}) +export class CdsActionLeadUpdateNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionLeadUpdate; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + leadPropertyFormGroup: FormGroup + leadPropertyListFiltered = leadPropertyList; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private formBuilder: FormBuilder + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION-LEAD-UPDATE] action: ", this.action) + if(this.action && !this.action.update){ + this.action.update = {}; + } + this.initialize(); + this.populateForm(); + } + + + private initialize() { + this.leadPropertyFormGroup = this.buildForm(); + // Update the disabled status of the lead property list based on keys present in action.update + this.leadPropertyListFiltered.forEach(el => Object.keys(this.action.update).includes(el.name)? el.disabled= true: el.disabled = false) + } + + buildForm(): FormGroup { + return this.formBuilder.group({ + update: this.formBuilder.array([]) // <-- the dynamic array of key/value pairs + }); + } + + get update(): FormArray { + return this.leadPropertyFormGroup.get('update') as FormArray; + } + + populateForm() { + const entries = Object.entries(this.action.update || {}); + + if (entries.length === 0) { + // action.update is empty → add an empty row + this.update.push(this.formBuilder.group({ + key: [null, Validators.required], + value: [null, Validators.required] + })); + } else { + // action.update is not empty → populate the form with existing key/value pairs + entries.forEach(([key, value]) => { + this.update.push(this.formBuilder.group({ + key: [key, Validators.required], + value: [value, Validators.required] + })); + }); + } + } + + onChangeSelect(propertySelected: {name: string, value: string}, index: number ){ + this.logger.log("[ACTION-LEAD-UPDATE] onChangeSelect event: ", propertySelected, this.action) + + // Get the previous key in the form + const oldKey = this.update.at(index).get('key')?.value; + // Update the form + this.update.at(index).get('key')?.setValue(propertySelected.value); + // Update action.update + if (oldKey && this.action.update[oldKey] !== undefined) { + const oldValue = this.action.update[oldKey]; + delete this.action.update[oldKey]; // remove old key + this.action.update[propertySelected.value] = oldValue; // add new key with same value + } + this.updateAndSaveAction.emit() + } + + onChangeTextarea(text, index: number){ + this.logger.log("[ACTION-LEAD-UPDATE] onChangeTextarea event: ", text, this.action, this.update.at(index)) + this.update.at(index).get('value')?.setValue(text); + // this.action.update[this.selectedKey]=text; + } + + onBlur(event, index: number){ + const item = this.update.at(index); + if (item.valid) { + const key = item.get('key')!.value; + const value = item.get('value')!.value; + // Update action.update + this.action.update[key] = value; + // Update the disabled status on the lead property list + this.updateDisabledList() + + this.updateAndSaveAction.emit(); + } + } + + onAddNewProperty(){ + this.logger.log("[ACTION-LEAD-UPDATE] onAddNewProperty ADD ") + const group = this.formBuilder.group({ + key: [null, Validators.required], + value: [null, Validators.required] + }); + this.update.push(group); + // Update the disabled status on the lead property list + this.updateDisabledList(); + } + + onDeleteProperty(index: number, key: string){ + this.logger.log("[ACTION-LEAD-UPDATE] onDeleteProperty index:", index); + // 1. Remove the row from the form + this.update.removeAt(index); + // 2. Remove the key from action.update + delete this.action.update[key]; + // 3. Update the disabled status on the lead property list + this.updateDisabledList(); + // 4. UI handling if action.update is empty + + this.updateAndSaveAction.emit(); + } + + private updateDisabledList() { + const keys = Object.keys(this.action.update); + + this.leadPropertyListFiltered.forEach(el => { + el.disabled = keys.includes(el.name); + }); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update.component.spec.ts new file mode 100644 index 000000000..2f8d8948c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionLeadUpdateComponent } from './cds-action-lead-update.component'; + +describe('CdsActionLeadUpdateComponent', () => { + let component: CdsActionLeadUpdateComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionLeadUpdateComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionLeadUpdateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.html new file mode 100644 index 000000000..771617c05 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.html @@ -0,0 +1,166 @@ +
+ + +
+ {{action.url}} +
+
+ {{'CDSCanvas.EnterRequestURL' | translate }} +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+
+ + + +
+
+ + + +
+ + {{'CDSCanvas.Howitwork' | translate}} + +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ {{'CDSCanvas.Success' | translate }} +
+ + +
+ +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + +
+ +
+ + + + + + + {{'CDSCanvas.Advanced' | translate }} + + +
+ +
+ + + +
+ + +
+ + + +
+
+
+
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss new file mode 100644 index 000000000..247412e0c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss @@ -0,0 +1,75 @@ +::-webkit-scrollbar { + width: 0px; +} +:host { + --background-color: #{var(--blu-light-01)}; + //--slider-background-color: #{var(--blu-light-03)}; + --text-color: #{var(--blu)}; +} + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} + + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.ts new file mode 100644 index 000000000..c7443319a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.ts @@ -0,0 +1,200 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//SERVICES +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; +import { ActionMake } from 'src/app/models/action-model'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-make-new', + templateUrl: './cds-action-make-new.component.html', + styleUrls: ['./cds-action-make-new.component.scss'] +}) +export class CdsActionMakeNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionMake; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonParameters: { [ key: string]: string}; + errorMessage: string; + + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-MAKE] action detail: ", this.action, ACTIONS_LIST["MAKE"].plan); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-MAKE] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-MAKE] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-MAKE] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.jsonParameters = this.action.bodyParameters; + if(this.intentSelected){ + this.initializeConnector(); + } + } + + private initializeAttributes() { + let new_attributes = []; + //if (!variableList.userDefined.some(v => v.name === 'result')) { + //new_attributes.push({ name: "result", value: "result" }); + //} + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'make_status')) { + new_attributes.push({ name: "make_status", value: "make_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'make_error')) { + new_attributes.push({ name: "make_error", value: "make_error" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION MAKE] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined').elements); + } + + + + + // EVENT FUNCTIONS // + onChangeTextarea(e, type: 'url'){ + switch(type){ + case 'url' : { + this.action.url = e; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + this.logger.log("[ACTION MAKE] this.action", this.action); + } + } + + } + + + onChangeAttributes(attributes:any){ + this.logger.log('[ACTION-MAKE]onChangeAttributes ',attributes); + this.action.bodyParameters = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-MAKE] onEditableDivTextChange event", event) + this.logger.log("[ACTION-MAKE] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToHelp(){ + let url = "https://gethelp.tiledesk.com/articles/makecom-action/" + window.open(url, '_blank') + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make.component.spec.ts new file mode 100644 index 000000000..d3bc90a27 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionMakeComponent } from './cds-action-make.component'; + +describe('CdsActionMakeComponent', () => { + let component: CdsActionMakeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionMakeComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionMakeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.html new file mode 100644 index 000000000..40d1d7840 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.html @@ -0,0 +1,9 @@ +
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.scss new file mode 100644 index 000000000..280a86d19 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.scss @@ -0,0 +1,5 @@ +.cds-action-preview{ + .action-row{ + justify-content: center; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.ts new file mode 100644 index 000000000..520e70608 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned-new.component.ts @@ -0,0 +1,22 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; +import { ActionMoveToUnassigned } from 'src/app/models/action-model'; + +@Component({ + selector: 'cds-action-move-unassigned-new', + templateUrl: './cds-action-move-unassigned-new.component.html', + styleUrls: ['./cds-action-move-unassigned-new.component.scss'] +}) +export class CdsActionMoveUnassignedNewComponent implements OnInit { + + @Input() action: ActionMoveToUnassigned; + @Input() previewMode: boolean = true; + + actions = ACTIONS_LIST + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned.component.spec.ts new file mode 100644 index 000000000..f05c8c681 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-move-unassigned/cds-action-move-unassigned.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionMoveUnassignedComponent } from './cds-action-move-unassigned.component'; + +describe('CdsMoveUnassignedComponent', () => { + let component: CdsActionMoveUnassignedComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionMoveUnassignedComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionMoveUnassignedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.html new file mode 100644 index 000000000..935e6ded3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.html @@ -0,0 +1,166 @@ +
+ +
+ + + {{ action.method}} + + +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+
+ + +
+
+ + + +
+ + + + +
+ + +
+ + + +
+ + +
+
+
+ +
+ {{'CDSCanvas.Success' | translate }} +
+ + +
+ +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + +
+ +
+ + + + + {{'CDSCanvas.Advanced' | translate }} + + +
+ +
+ + + +
+ +
+ + + +
+ + +
+ + + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss new file mode 100644 index 000000000..bcd706cd1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss @@ -0,0 +1,108 @@ +::-webkit-scrollbar { + width: 0px; +} +:host { + --background-color: #{var(--blu-light-01)}; + //--slider-background-color: #{$blu-light-03}; + --text-color: #{var(--blu)}; +} + + +/** button TOOGLE */ +mat-button-toggle-group ::ng-deep{ + border: unset; + border-radius: 0px; +} + +mat-button-toggle{ + background-color: transparent; + border: none; + color: var(--blu-light-02); + border-bottom: 2px solid transparent; + + &.mat-button-toggle-checked{ + border-color: var(--blu); + color: var(--blu); + font-weight: 400; + + } + + &.mat-button-toggle+mat-button-toggle.mat-button-toggle{ + border-left: none; + } + + &::ng-deep .mat-button-toggle-label-content { + line-height: 36px; + } + +} + +.custom-expansion-panel { + background-color: transparent; + box-shadow: none; + color: white; +} +mat-expansion-panel ::ng-deep { + background-color: transparent; + box-shadow: none; + color: var(--text-color); + + .mat-expansion-panel-header { + padding: 0; + + &:hover { + background-color: transparent; + } + } + + .mat-expansion-panel-header-title { + color: var(--text-color); + } + + .mat-expansion-indicator::after { + color: var(--text-color) !important; + } + + .mat-expansion-panel-header-description, + .mat-expansion-indicator:after { + color: var(--text-color); + margin: 5px; + } + + ::ng-deep .mat-expansion-indicator, + .mat-expansion-indicator:after { + color: var(--text-color); + } + + .mat-expansion-panel-header.mat-expanded { + height: 48px; + } + + .disable_ripple:hover { + background: transparent !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } + + .mat-expansion-panel-body { + padding: 0 !important; + } +} + + +a.link{ + cursor: pointer; + text-decoration: underline; +} +.box { + display: flex; + flex-wrap: wrap; + flex-direction: column; + width: auto; + height: auto; + align-content: space-between; + } + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.ts new file mode 100644 index 000000000..fae28605d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.ts @@ -0,0 +1,204 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; +import { ActionN8n } from 'src/app/models/action-model'; + +//SERVICES +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { AppConfigService } from 'src/app/services/app-config'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-n8n-new', + templateUrl: './cds-action-n8n-new.component.html', + styleUrls: ['./cds-action-n8n-new.component.scss'] +}) +export class CdsActionN8nComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionN8n; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + + connector: any; + private subscriptionChangedConnector: Subscription; + + helpUrl = "https://gethelp.tiledesk.com/articles/n8nio-action/"; + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + limitCharsText = TEXT_CHARS_LIMIT; + jsonParameters: string; + errorMessage: string; + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly intentService: IntentService, + private readonly appConfigService: AppConfigService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.log("[ACTION-N8N] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.log('[ACTION-N8N] isChangedConnector -->', connector); + this.connector = connector; + this.updateConnector(); + }); + this.initialize(); + } + + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + /** */ + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + /** */ + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-N8N] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-N8N] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.jsonParameters = this.action.bodyParameters; + if(this.intentSelected){ + this.initializeConnector(); + } + } + + /** */ + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'n8n_status')) { + new_attributes.push({ name: "n8n_status", value: "n8n_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'n8n_error')) { + new_attributes.push({ name: "n8n_error", value: "n8n_error" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'n8n_result')) { + new_attributes.push({ name: "n8n_result", value: "n8n_result" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.log("[ACTION-N8N] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined').elements); + } + + + + + // EVENT FUNCTIONS // + onChangeTextarea(e, type: 'url'){ + this.logger.log('type; ', type); + if(type === 'url'){ + this.action.url = e; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + this.logger.log("[ACTION N8N] this.action", this.action); + } + } + + + onChangeAttributes(attributes:any){ + this.logger.log('[ACTION-N8N]onChangeAttributes ',attributes); + this.action.bodyParameters = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-N8N] onEditableDivTextChange event", event); + this.logger.log("[ACTION-N8N] onEditableDivTextChange property", property); + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value; + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + goToIntegration(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + this.action._tdActionType; + window.open(url, '_blank'); + } + + goToHelp(){ + let url = this.helpUrl; + window.open(url, '_blank'); + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n.component.spec.ts new file mode 100644 index 000000000..1003e24b9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionN8nComponent } from './cds-action-n8n.component'; + +describe('CdsActionN8nComponent', () => { + let component: CdsActionN8nComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionN8nComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionN8nComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.html new file mode 100644 index 000000000..1d8a2b238 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.html @@ -0,0 +1,161 @@ +
+ +
+
+ + + + + +
+ +
+ + {{ (radioOptions | find:{key: 'value', value: action.selectedOption}).name | translate }} + + + {{'SelectDepartment' | translate}} + {{ (departments | find:{key: 'id', value: action.selectedDepartmentId}).name }} + +
+
+ {{'CDSCanvas.SelectADepartment' | translate }} +
+
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ + + +
+ +
+ +
+
+ + +
+ + + + + +
+ + +
+
+ +
+
+ + {{"CDSCanvas.IgnoreOperatingHours" | translate}} + +
+ +
+ + +
+ + +
+
+
+ +
+ ONLINE +
+ + + +
+ + +
+
+ {{'CDSCanvas.Else' | translate }} +
+ + + +
+ +
+ + + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.scss new file mode 100644 index 000000000..889805a7d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.scss @@ -0,0 +1,13 @@ +.deps-wrp{ + display: flex; + justify-content: center; +} + +cds-select#list-deps{ + width: 80%; +} + +.action-row{ + // align-items: flex-start; + line-height: normal; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.ts new file mode 100644 index 000000000..45c35bd1c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents-new.component.ts @@ -0,0 +1,239 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { IntentService } from '../../../../../services/intent.service'; +import { Intent } from 'src/app/models/intent-model'; +import { ActionOnlineAgentV2 } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { Department } from 'src/app/models/department-model'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + + +@Component({ + selector: 'cds-action-online-agents-v2-new', + templateUrl: './cds-action-online-agents-new.component.html', + styleUrls: ['./cds-action-online-agents-new.component.scss'] +}) +export class CdsActionOnlineAgentsV2Component implements OnInit { + + // @Input() listOfActions: Array<{name: string, value: string, icon?:string}>; + @Input() intentSelected: Intent; + @Input() action: ActionOnlineAgentV2; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + radioOptions: Array<{name: string, value: string, disabled: boolean, checked: boolean}>= [ + {name: 'CDSCanvas.ProjectWide', value: 'all', disabled: false, checked: true }, + {name: 'CDSCanvas.CurrentDepartment', value: 'currentDep', disabled: false, checked: false }, + {name: 'CDSCanvas.SelectedDepartment', value: 'selectedDep', disabled: false, checked: false } + ] + + actionOnlineAgentsFormGroup: FormGroup + trueIntentAttributes: string = ""; + falseIntentAttributes: string = ""; + + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + departments: Department[] + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private formBuilder: FormBuilder, + private intentService: IntentService, + private dashboardService: DashboardService, + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // ngOnChanges() { + // this.initialize(); + // if(this.intentSelected){ + // this.initializeConnector(); + // } + // if (this.action && this.action.trueIntent) { + // this.setFormValue(); + // } + // } + + + private initialize() { + this.actionOnlineAgentsFormGroup = this.buildForm(); + this.actionOnlineAgentsFormGroup.valueChanges.subscribe(form => { + this.logger.log('[ACTION-ONLINE-AGENT] form valueChanges-->', form) + if (form && (form.trueIntent !== '')) + this.action = Object.assign(this.action, this.actionOnlineAgentsFormGroup.value); + }) + this.trueIntentAttributes = this.action.trueIntentAttributes; + this.falseIntentAttributes = this.action.falseIntentAttributes; + if(this.intentSelected){ + this.initializeConnector(); + } + if (this.action && this.action.trueIntent) { + this.setFormValue(); + } + this.departments = this.dashboardService.departments + + //FIX: if chatbot is imported from other env/project --> reset selectedDepartmentId + if(this.action.selectedDepartmentId){ + let actionDepIndex = this.departments.findIndex(dep => dep._id === this.action.selectedDepartmentId) + if(actionDepIndex === -1){ + this.action.selectedDepartmentId = null; + } + } + + } + + + private initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ONLINE-AGENT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ONLINE-AGENT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + onChangeCheckbox(target){ + try { + this.action[target] = !this.action[target]; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + + onChangeButtonSelect(event: {label: string, value: string, disabled: boolean, checked: boolean}){ + this.radioOptions.forEach(el => { el.value ===event.value? el.checked= true: el.checked = false }) + this.action.selectedOption= event.value + switch (event.value){ + case 'selectedDep': + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + buildForm(): FormGroup { + return this.formBuilder.group({ + selectedOption: ['all', Validators.required], + selectedDepartmentId : ['', Validators.nullValidator], + trueIntent: ['', Validators.required], + falseIntent: ['', Validators.required] + }) + } + + setFormValue() { + this.actionOnlineAgentsFormGroup.patchValue({ + selectedOption: this.action.selectedOption, + selectedDepartmentId: this.action.selectedDepartmentId, + trueIntent: this.action.trueIntent, + falseIntent: this.action.falseIntent + }) + } + + onChangeSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'selectedDepartmentId'){ + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + case 'selectedDepartmentId': + this.action.selectedDepartmentId = event['_id'] + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'selectedDepartmentId') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + onChangeAttributes(attributes:any, type: 'trueIntent' | 'falseIntent'){ + if(type === 'trueIntent'){ + this.action.trueIntentAttributes = attributes; + } + if(type === 'falseIntent'){ + this.action.falseIntentAttributes = attributes; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + /** */ + onStopConditionMeet() { + try { + this.action.stopOnConditionMet = !this.action.stopOnConditionMet; + } catch (error) { + this.logger.log("Error: ", error); + } + } + + +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents.component.spec.ts new file mode 100644 index 000000000..8798e408f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents-v2/cds-action-online-agents.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionOnlineAgentsComponent } from './cds-action-online-agents.component'; + +describe('ActionOnlineAgentsComponent', () => { + let component: CdsActionOnlineAgentsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionOnlineAgentsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionOnlineAgentsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.html new file mode 100644 index 000000000..33d749c2d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.html @@ -0,0 +1,96 @@ +
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ + + +
+ +
+ +
+
+ + +
+
+
+ +
+ ONLINE +
+ + + +
+ + +
+
+ {{'CDSCanvas.Else' | translate }} +
+ + + +
+ +
+ + + +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.ts new file mode 100644 index 000000000..3c24d4a99 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents-new.component.ts @@ -0,0 +1,198 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { IntentService } from '../../../../../services/intent.service'; +import { Intent } from 'src/app/models/intent-model'; +import { ActionOnlineAgent } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + + +@Component({ + selector: ' selector: 'cds-action-online-agents-new',-new', + templateUrl: './cds-action-online-agents-new.component.html', + styleUrls: ['./cds-action-online-agents-new.component.scss'] +}) +export class CdsActionOnlineAgentsNewComponent implements OnInit { + + // @Input() listOfActions: Array<{name: string, value: string, icon?:string}>; + @Input() intentSelected: Intent; + @Input() action: ActionOnlineAgent; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + actionOnlineAgentsFormGroup: FormGroup + trueIntentAttributes: string = ""; + falseIntentAttributes: string = ""; + + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private formBuilder: FormBuilder, + private intentService: IntentService, + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // ngOnChanges() { + // this.initialize(); + // if(this.intentSelected){ + // this.initializeConnector(); + // } + // if (this.action && this.action.trueIntent) { + // this.setFormValue(); + // } + // } + + + private initialize() { + this.actionOnlineAgentsFormGroup = this.buildForm(); + this.actionOnlineAgentsFormGroup.valueChanges.subscribe(form => { + this.logger.log('[ACTION-ONLINE-AGENT] form valueChanges-->', form) + if (form && (form.trueIntent !== '')) + this.action = Object.assign(this.action, this.actionOnlineAgentsFormGroup.value); + }) + this.trueIntentAttributes = this.action.trueIntentAttributes; + this.falseIntentAttributes = this.action.falseIntentAttributes; + if(this.intentSelected){ + this.initializeConnector(); + } + if (this.action && this.action.trueIntent) { + this.setFormValue(); + } + } + + + private initializeConnector() { + // this.isConnected = false; + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ONLINE-AGENT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ONLINE-AGENT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + + + + buildForm(): FormGroup { + return this.formBuilder.group({ + trueIntent: ['', Validators.required], + falseIntent: ['', Validators.required] + }) + } + + setFormValue() { + this.actionOnlineAgentsFormGroup.patchValue({ + trueIntent: this.action.trueIntent, + falseIntent: this.action.falseIntent + }) + } + + onChangeSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent'){ + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + onChangeAttributes(attributes:any, type: 'trueIntent' | 'falseIntent'){ + if(type === 'trueIntent'){ + this.action.trueIntentAttributes = attributes; + } + if(type === 'falseIntent'){ + this.action.falseIntentAttributes = attributes; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + /** */ + onStopConditionMeet() { + try { + this.action.stopOnConditionMet = !this.action.stopOnConditionMet; + } catch (error) { + this.logger.log("Error: ", error); + } + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents.component.spec.ts new file mode 100644 index 000000000..8798e408f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-online-agents/cds-action-online-agents.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionOnlineAgentsComponent } from './cds-action-online-agents.component'; + +describe('ActionOnlineAgentsComponent', () => { + let component: CdsActionOnlineAgentsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionOnlineAgentsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionOnlineAgentsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.html new file mode 100644 index 000000000..5e046f2d2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.html @@ -0,0 +1,149 @@ +
+ +
+
+ + + +
+ +
+ + {{ (radioOptions | find:{key: 'category', value: 'general'}).name | translate }} + + + {{ (timeSlots | find:{key: 'value', value: action.slotId}).name }} + +
+
+ {{ (radioOptions | find:{key: 'category', value: 'general'}).name | translate }} +
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + +
+
+ +
+ + + + + +
+ + +
+
+ +
+ + +
+
+
+ +
+ OPEN +
+ + + + + +
+ + +
+
+ {{'CDSCanvas.Else' | translate | titlecase }} +
+ + + +
+ +
+ + + +
+ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.scss new file mode 100644 index 000000000..004322fe8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.scss @@ -0,0 +1,8 @@ +.deps-wrp{ + display: flex; + justify-content: center; +} + +cds-select#list-deps{ + width: 80%; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.ts new file mode 100644 index 000000000..0262c3401 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours-new.component.ts @@ -0,0 +1,205 @@ +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Intent } from 'src/app/models/intent-model'; +import { ActionOpenHours } from 'src/app/models/action-model'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { IntentService } from '../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_UPDATE_ACTION } from '../../../../../utils'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: 'cds-action-open-hours-new', + templateUrl: './cds-action-open-hours-new.component.html', + styleUrls: ['./cds-action-open-hours-new.component.scss'] +}) +export class CdsActionOpenHoursNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionOpenHours; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + trueIntentAttributes: any = ""; + falseIntentAttributes: any = ""; + + /** CONNECTOR */ + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + radioOptions: Array<{name: string, category: string, value: string, disabled: boolean, checked: boolean}>= [ + {name: 'CDSCanvas.General', category: 'general', value: null, disabled: false, checked: true }, + {name: 'CDSCanvas.SelectedTimeSlot', category: 'timeSlot', value: '', disabled: false, checked: false }, + ] + radioOptionSelected = null; + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + timeSlots: Array<{name: string, value: string, hours: string, active: boolean}> + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private formBuilder: FormBuilder, + private intentService: IntentService, + private dashboardService: DashboardService, + ) { } + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize() + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // ngOnChanges() { + // this.initialize() + // if(this.intentSelected){ + // this.initializeConnector(); + // } + // if (this.action && this.action.trueIntent) { + // this.setFormValue() + // } + // } + + private initialize() { + if (this.dashboardService.project.timeSlots) { + this.timeSlots = Object.keys(this.dashboardService.project.timeSlots).map(key => ({ + value: key, + ...this.dashboardService.project.timeSlots[key] + })); + } + + this.trueIntentAttributes = this.action.trueIntentAttributes; + this.falseIntentAttributes = this.action.falseIntentAttributes; + if(this.intentSelected){ + this.initializeConnector(); + this.checkConnectionStatus(); + } + + this.radioOptionSelected = null; + if(this.action && this.action.slotId && this.action.slotId !== null){ + this.radioOptionSelected = '' + this.radioOptions.forEach(el => { el.category === 'timeSlot'? el.checked = true: el.checked = false }) + } + this.logger.log('[ACTION-OPEN-HOURS] initialize action -->', this.action) + } + + + private initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents() + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-OPEN-HOURS] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-OPEN-HOURS] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + onChangeButtonSelect(event: {label: string, category: string, value: string, disabled: boolean, checked: boolean}){ + this.radioOptions.forEach(el => { el.value ===event.value? el.checked= true: el.checked = false }) + this.action.slotId = null; + switch (event.category){ + case 'general': + this.action.slotId = null + this.radioOptionSelected = null + break; + default: + this.radioOptionSelected = '' + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + + onChangeSelect(event:{name: string, value: string}, type : 'trueIntent' | 'falseIntent' | 'slotId'){ + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent' | 'slotId') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributes(attributes:any, type: 'trueIntent' | 'falseIntent'){ + if(type === 'trueIntent'){ + this.action.trueIntentAttributes = attributes; + } + if(type === 'falseIntent'){ + this.action.falseIntentAttributes = attributes; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + /** */ + onStopConditionMeet() { + try { + this.action.stopOnConditionMet = !this.action.stopOnConditionMet; + } catch (error) { + this.logger.log("Error: ", error); + } + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours.component.spec.ts new file mode 100644 index 000000000..cb3cbbbe7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-open-hours/cds-action-open-hours.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionOpenHoursComponent } from './cds-action-open-hours.component'; + +describe('ActionOpenHoursComponent', () => { + let component: CdsActionOpenHoursComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionOpenHoursComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionOpenHoursComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.html new file mode 100644 index 000000000..f7b10de8b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.html @@ -0,0 +1,172 @@ +
+ +
+
+ + + + +
+
+ {{action?.trackingNumber}} +
+
+ {{'CDSCanvas.EnterTrackingNumber' | translate}} +
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.scss new file mode 100644 index 000000000..1f97a61be --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.scss @@ -0,0 +1,9 @@ +a.link { + cursor: pointer; + font-size: 14px; + font-weight: 400; +} + +a.link:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.ts new file mode 100644 index 000000000..065a05f47 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla-new.component.ts @@ -0,0 +1,184 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Subscription } from 'rxjs'; + +//SERVICES +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { AppConfigService } from 'src/app/services/app-config'; + +//MODELS +import { ActionQapla } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { Project } from 'src/app/models/project-model'; + +//UTILS +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; + +@Component({ + selector: ' selector: 'cds-action-qapla-new',-new', + templateUrl: './cds-action-qapla-new.component.html', + styleUrls: ['./cds-action-qapla-new.component.scss'] +}) +export class CdsActionQaplaNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionQapla; + @Input() project_id: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter; + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + project: Project; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private dashboardService: DashboardService, + private intentService: IntentService, + private appConfigService: AppConfigService, + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION QAPLA] action:", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-ASKGPT] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + if(this.intentSelected){ + this.initializeConnector(); + } + + this.initializeAttributes(); + this.project = this.dashboardService.project; + } + + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + + /** */ + private updateConnector(){ + this.logger.log('[ACTION-ASKGPT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION-ASKGPT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'qapla_status')) { + new_attributes.push({ name: "qapla_status", value: "qapla_status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'qapla_result')) { + new_attributes.push({ name: "qapla_result", value: "qapla_result" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'qapla_error')) { + new_attributes.push({ name: "qapla_error", value: "qapla_error" }); + } + variableList.find(el => el.key ==='userDefined').elements = [...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION GPT-TASK] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + changeTextarea($event: string, property: string) { + this.logger.debug("[ACTION QAPLA] changeTextarea event: ", $event); + this.logger.debug("[ACTION QAPLA] changeTextarea propery: ", property); + this.action[property] = $event; + this.logger.log("[ACTION QAPLA] Action updated: ", this.action); + // this.updateAndSaveAction.emit(); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION QAPLA] onEditableDivTextChange event", event) + this.logger.log("[ACTION QAPLA] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.logger.log("[ACTION QAPLA] Action updated: ", this.action); + this.updateAndSaveAction.emit(); + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}); + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}); + break; + } + this.action[type]=null + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + goToIntegration(){ + let url = this.appConfigService.getConfig().dashboardBaseUrl + '#/project/' + this.project_id +'/integrations?name=' + this.action._tdActionType + window.open(url, '_blank') + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla.component.spec.ts new file mode 100644 index 000000000..61c1183b9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-qapla/cds-action-qapla.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionQaplaComponent } from './cds-action-qapla.component'; + +describe('CdsActionQaplaComponent', () => { + let component: CdsActionQaplaComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionQaplaComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionQaplaComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.html new file mode 100644 index 000000000..fccc98939 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.html @@ -0,0 +1,43 @@ +
+ +
+
+ + + + + + + +
+ +
+ {{action.botName}} +
+
+ {{'CDSCanvas.ChooseAgent' | translate }} +
+ +
+
+ +
+ +
+ + + +
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.scss new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.scss @@ -0,0 +1 @@ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.ts new file mode 100644 index 000000000..f9a88301e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot-new.component.ts @@ -0,0 +1,58 @@ +import { Chatbot } from 'src/app/models/faq_kb-model'; +import { ActionReplaceBot } from 'src/app/models/action-model'; +import { FaqKbService } from 'src/app/services/faq-kb.service'; +import { Component, OnInit, Input, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: ' selector: 'cds-action-replace-bot-new',-new', + templateUrl: './cds-action-replace-bot-new.component.html', + styleUrls: ['./cds-action-replace-bot-new.component.scss'] +}) +export class CdsActionReplaceBotNewComponent implements OnInit, OnChanges { + + @Input() action: ActionReplaceBot; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + //bots: Chatbot[] = []; + chatbots_name_list: Array<{name: string, value: string, icon?:string}>; + bot_selected: Chatbot; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private chatbotService: FaqKbService + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION REPLACE BOT] action (on-init): ", this.action) + this.getAllBots(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log("[ACTION REPLACE BOT] action (on-changes): ", this.action) + } + + getAllBots() { + // this.chatbotService.getAllBotByProjectId().subscribe((chatbots) => { + this.chatbotService.getFaqKbByProjectId().subscribe((chatbots) => { + this.logger.log("[ACTION REPLACE BOT] chatbots: ", chatbots); + //this.bots = bots; + this.chatbots_name_list = chatbots.map(a => ({ name: a.name, value: a.name, icon: 'smart_toy'})); + }, (error) => { + this.logger.error("[ACTION REPLACE BOT] error get bots: ", error); + }, () => { + this.logger.log("[ACTION REPLACE BOT] get all chatbots completed."); + }) + } + + onChangeSelect(event: {name: string, value: string}) { + //this.logger.log("[ACTION REPLACE BOT] onChangeActionButton event: ", event) + this.action.botName = event.value; + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action edited: ", this.action) + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot.component.spec.ts new file mode 100644 index 000000000..55dd85e66 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplaceBotComponent } from './cds-action-replace-bot.component'; + +describe('CdsActionReplaceBotComponent', () => { + let component: CdsActionReplaceBotComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplaceBotComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplaceBotComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.html new file mode 100644 index 000000000..3e0ae73a1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.html @@ -0,0 +1,73 @@ +
+ +
+
+ + + + + + + +
+ +
+ {{action.botName}} +
+
+ {{'CDSCanvas.ChooseAgent' | translate }} +
+ +
+ +
+
+ +
+ +
+ {{action.blockName}} +
+
+ {{'CDSCanvas.ChooseBlock' | translate }} +
+ +
+
+ +
+ +
+ + + +
+ +
+ + + + +
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.scss new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.scss @@ -0,0 +1 @@ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.ts new file mode 100644 index 000000000..72369bb6c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2-new.component.ts @@ -0,0 +1,106 @@ +import { Chatbot } from 'src/app/models/faq_kb-model'; +import { ActionReplaceBotV2 } from 'src/app/models/action-model'; +import { FaqKbService } from 'src/app/services/faq-kb.service'; +import { Component, OnInit, Input, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { FaqService } from 'src/app/services/faq.service'; +import { Faq } from 'src/app/models/faq-model'; +import { Intent } from 'src/app/models/intent-model'; + +@Component({ + selector: ' selector: 'cds-action-replace-bot-v2-new',-new', + templateUrl: './cds-action-replace-bot-v2-new.component.html', + styleUrls: ['./cds-action-replace-bot-v2-new.component.scss'] +}) +export class CdsActionReplaceBotV2Component implements OnInit, OnChanges { + + @Input() action: ActionReplaceBotV2; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + //bots: Chatbot[] = []; + chatbots_name_list: Array<{name: string, value: string, id: string, icon?:string}>; + chatbots_block_name_list: Array<{name: string, value: string, icon?:string}>; + bot_selected: Chatbot; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private chatbotService: FaqKbService, + private faqService: FaqService + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION REPLACE BOT] action (on-init): ", this.action) + this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log("[ACTION REPLACE BOT] action (on-changes): ", this.action) + } + + async initialize(){ + await this.getAllBots(); + if(this.action && this.action.botName){ + let selectedChatbot = this.chatbots_name_list.find(el => el.name === this.action.botName) + if(selectedChatbot){ + this.getAllFaqById(selectedChatbot.id) + } + } + } + + async getAllBots() { + // this.chatbotService.getAllBotByProjectId().subscribe((chatbots) => { + return new Promise((resolve, reject) => { + this.chatbotService.getFaqKbByProjectId().subscribe({ next: (chatbots) => { + this.logger.log("[ACTION REPLACE BOT] chatbots: ", chatbots); + //this.bots = bots; + this.chatbots_name_list = chatbots.map(a => ({ name: a.name, value: a.name, id: a._id, icon: 'smart_toy'})); + resolve(true) + }, error: (error) => { + this.logger.error("[ACTION REPLACE BOT] error get bots: ", error); + reject(error) + }, complete: () => { + this.logger.log("[ACTION REPLACE BOT] get all chatbots completed."); + }}) + }) + + } + + + getAllFaqById(chatbotId: string){ + this.logger.log("[ACTION REPLACE BOT] get AllFaqById: ",chatbotId); + this.faqService.getAllFaqByFaqKbId(chatbotId).subscribe({ next: (faks: Intent[])=> { + this.chatbots_block_name_list = faks.map((el => ({name: el.intent_display_name, value: el.intent_display_name}))) + this.logger.log("[ACTION REPLACE BOT] get AllFaqById: ", this.chatbots_block_name_list); + }, error: (error)=> { + this.logger.error("[ACTION REPLACE BOT] error get AllFaqById: ", error); + }, complete: () => { + this.logger.log("[ACTION REPLACE BOT] get AllFaqById completed."); + }}) + } + + onChangeSelect(event: {name: string, value: string, id: string}) { + this.logger.log("[ACTION REPLACE BOT] onChangeActionButton event: ", event) + this.action.botName = event.value; + this.getAllFaqById(event.id) + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action edited: ", this.action) + } + + onChangeBlockSelect(event: {name: string, value: string}){ + this.action.blockName = event.value; + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action selet block to execute: ", this.action) + } + + onResetBlockSelect(event){ + this.action.blockName = null; + this.updateAndSaveAction.emit() + } + + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2.component.spec.ts new file mode 100644 index 000000000..e9f9a4cd0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplaceBotV2Component } from './cds-action-replace-bot-v2.component'; + +describe('CdsActionReplaceBotV2Component', () => { + let component: CdsActionReplaceBotV2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplaceBotV2Component ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplaceBotV2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.html new file mode 100644 index 000000000..8f0a23447 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.html @@ -0,0 +1,88 @@ +
+ +
+
+ + + + + + + +
+ +
+ {{ (chatbots_name_list | find:{key: 'id', value: action?.botId })?.name }}
{{ formatBotSlug(action?.botSlug) }}
+
+
+ {{'CDSCanvas.ChooseAgent' | translate }} +
+ +
+ +
+
+ +
+ +
+ {{action.blockName}} +
+
+ {{'CDSCanvas.ChooseBlock' | translate }} +
+ +
+
+ +
+
+ + + + + + +
+ + {{ 'CDSCanvas.UseBotSlug' | translate }} + +
+
+ +
+ + + + +
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.scss new file mode 100644 index 000000000..b50936069 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.scss @@ -0,0 +1,3 @@ +.slug { + display: inline; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.ts new file mode 100644 index 000000000..a67dd1de4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3-new.component.ts @@ -0,0 +1,212 @@ +import { Chatbot } from 'src/app/models/faq_kb-model'; +import { ActionReplaceBotV3 } from 'src/app/models/action-model'; +import { FaqKbService } from 'src/app/services/faq-kb.service'; +import { Component, OnInit, Input, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { FaqService } from 'src/app/services/faq.service'; +import { Faq } from 'src/app/models/faq-model'; +import { Intent } from 'src/app/models/intent-model'; +import { MatCheckbox } from '@angular/material/checkbox'; + +@Component({ + selector: ' selector: 'cds-action-replace-bot-v3-new',-new', + templateUrl: './cds-action-replace-bot-v3-new.component.html', + styleUrls: ['./cds-action-replace-bot-v3-new.component.scss'] +}) +export class CdsActionReplaceBotV3Component implements OnInit, OnChanges { + + @Input() action: ActionReplaceBotV3; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + //bots: Chatbot[] = []; + chatbots_name_list: Array<{name: string, value: string, id: string, slug: string, name2: string, icon?:string}> = []; + bot_selected: Chatbot; + + autocompleteOptions: Array<{label: string, value: string}> = []; + autocompleteOptionsBlockName: Array<{label: string, value: string}> = []; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private chatbotService: FaqKbService, + private faqService: FaqService + ) { } + + ngOnInit(): void { + this.logger.log("[ACTION REPLACE BOT] action (on-init): ", this.action) + this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log("[ACTION REPLACE BOT] action (on-changes): ", this.action) + } + + async initialize(){ + await this.getAllBots(); + if(this.action){ + let selectedChatbot = this.getChatbotByIdOrSlug() + if(selectedChatbot){ + this.getAllFaqById(selectedChatbot.id) + } + } + } + + async getAllBots() { + // this.chatbotService.getAllBotByProjectId().subscribe((chatbots) => { + return new Promise((resolve, reject) => { + + this.chatbotService.getFaqKbByProjectId().subscribe({ next: (chatbots) => { + this.logger.log("[ACTION REPLACE BOT] chatbots: ", chatbots, this.autocompleteOptions); + //this.bots = bots; + this.autocompleteOptions = []; + this.chatbots_name_list = chatbots.map(a => { + let name2 = a.name; + if(a.slug) {name2 = name2 + ' (' + a.slug + ')';} + return { name: a.name, value: a.name, slug: a.slug, id: a._id, name2: name2, icon: 'smart_toy' }; + }); + + chatbots.forEach(el => { + if(el.slug) + this.autocompleteOptions.push({label: el.name + ' (' + el.slug + ')', value: el.slug}) + }) + resolve(true) + }, error: (error) => { + this.logger.error("[ACTION REPLACE BOT] error get bots: ", error); + reject(error) + }, complete: () => { + this.logger.log("[ACTION REPLACE BOT] get all chatbots completed."); + }}) + }) + + } + + + getAllFaqById(chatbotId: string){ + this.logger.log("[ACTION REPLACE BOT] get AllFaqById: ",chatbotId); + + this.faqService.getAllFaqByFaqKbId(chatbotId).subscribe({ next: (faks)=> { + // faks.forEach(el => this.autocompleteOptionsBlockName.push({label: el.intent_display_name, value: el.intent_display_name})) + this.autocompleteOptionsBlockName = []; + this.autocompleteOptionsBlockName = faks.map((faq) => ({ + label: faq.intent_display_name, + value: faq.intent_display_name + })); + this.logger.log("[ACTION REPLACE BOT] get AllFaqById blocks: ", this.autocompleteOptionsBlockName); + }, error: (error)=> { + this.logger.error("[ACTION REPLACE BOT] error get AllFaqById: ", error); + }, complete: () => { + this.logger.log("[ACTION REPLACE BOT] get AllFaqById completed."); + }}) + } + + onChangeSelect(event: {name: string, value: string, slug: string, id: string}) { + this.logger.log("[ACTION REPLACE BOT] onChangeActionButton event: ", event) + this.action.botId = event.id; + this.action.botSlug = event.slug; + this.action.blockName = '' //rest blockName when chatbot is changed + this.getAllFaqById(event.id) + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action edited: ", this.action) + } + + async onChangeTextarea(event: string, property: string) { + this.logger.log("[ACTION REPLACE BOT] onEditableDivTextChange event", event) + this.logger.log("[ACTION REPLACE BOT] onEditableDivTextChange property", property) + switch(property){ + case 'botSlug': + this.action.botSlug = event; + (this.chatbots_name_list?.length === 0 || !this.chatbots_name_list)? await this.getAllBots(): null; + this.action.botId = this.chatbots_name_list.find(el => el.slug === event)?.id ?? null; + break; + case 'blockName': + this.action.blockName = event + break; + } + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onBlur(event){ + this.updateAndSaveAction.emit(); + } + + onAutocompleteOptionSelected(option: {label: string, value: string}, key: string){ + this.logger.log("[ACTION REPLACE BOT] onAutocompleteOptionSelected option:",option) + switch(key){ + case 'botSlug': + this.action.botId = this.chatbots_name_list.find(el => (el.slug === option.value))?.id ?? null + break; + } + } + + onChangeBlockSelect(event: {name: string, value: string}){ + this.action.blockName = event.value; + this.updateAndSaveAction.emit() + this.logger.log("[ACTION REPLACE BOT] action selet block to execute: ", this.action) + } + + onResetSelect(event, key: string){ + switch(key){ + case 'botId': + this.action.botId = null; + this.action.botSlug = null; + break; + case 'blockName': + this.action.blockName = null + break; + } + this.updateAndSaveAction.emit() + } + + onChangeCheckbox(event: MatCheckbox, target){ + this.action[target] = !this.action[target]; + this.chatbots_name_list = this.chatbots_name_list.map(a => { + let name2 = a.name; + if(a.slug) {name2 = name2 + ' (' + a.slug + ')';} + return { name: a.name, value: a.name, slug: a.slug, id: a.id, name2: name2, icon: 'smart_toy' }; + }); + // this.chatbots_name_list = this.chatbots_name_list.map(a => ({ name: a.name, value: a.name, slug: a.slug, id: a.id, name2: a.name+' ('+a.slug+')', icon: 'smart_toy'})); + if (target === "useSlg") { + if (this.action[target]) { + if (this.action.botId) { + this.action.botSlug = this.getChatbotByIdOrSlug().slug + } + } else { + this.action.botId = this.getChatbotByIdOrSlug().id + } + } + this.updateAndSaveAction.emit() + } + + getChatbotByIdOrSlug(){ + if(this.chatbots_name_list){ + let chatbotById = this.chatbots_name_list.find(el => el.id === this.action.botId) + if(chatbotById){ + return chatbotById + } + let chatbotBySlug = this.chatbots_name_list.find(el => el.slug === this.action.botSlug) + if(chatbotBySlug){ + return chatbotBySlug + } + } + } + + formatBotSlug(slug: string){ + if (slug.startsWith('{{') && slug.endsWith('}}')) { + //not use ( ) + return slug.slice(2, slug.length - 2); + } + + let matches = slug.match(new RegExp(/{{[^{}]*}}/g)); + if (matches && matches.length > 0) { + return slug; + } + + return '(' + slug + ')' + } + + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3.component.spec.ts new file mode 100644 index 000000000..ba67084f6 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplaceBotV3Component } from './cds-action-replace-bot-v3.component'; + +describe('CdsActionReplaceBotV3Component', () => { + let component: CdsActionReplaceBotV3Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplaceBotV3Component ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplaceBotV3Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html new file mode 100644 index 000000000..e8a2a1081 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html @@ -0,0 +1,254 @@ + +
+ + +
+
+ comment +
+
{{ action._tdActionTitle || 'Reply' }}
+ +
+ + +
+ + +
+ + +
+
+ {{ 'CDSCanvas.AddContentsToReply' | translate }} +
+
+ + +
+ +
+ + +
+ + + + +
+ +
+ + + + + +
+ + +
+ + +
+
+ + +
+
+ + + + + +
+ +
+ + +
+
+ + +
+
+ + + + + +
+ +
+ + +
+
+ + +
+
+ + + + + +
+ +
+ + +
+
+ + +
+
+ + + + + +
+ +
+ + +
+
+ + +
+ +
+ +
+ +
+ +
+ + +
+
+
+ {{ 'DisableUserInput' | translate }} +
+ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss new file mode 100644 index 000000000..7fc8bec90 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss @@ -0,0 +1,338 @@ +@import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/_mixins.scss"; + +// ============================================================================ +// cds-action-reply-v1-new Component +// Reply Inspector Layout (DS V3) +// ============================================================================ + +:host { + display: block; + font-family: var(--ds-font-family); +} + +.cds-action-content-new { + display: flex; + flex-direction: column; + height: 100%; + background: var(--ds-surface, #ffffff); + border: 1px solid var(--ds-border, #e8e6e0); + border-radius: var(--ds-radius-lg, 14px); + box-shadow: var(--ds-shadow-card, 0 1px 2px rgba(20, 20, 18, 0.04)); + overflow: hidden; +} + +// ============ Header ============ + +.insp-head { + @include flex-row(10px); + padding: 14px 18px; + border-bottom: 1px solid var(--ds-border, #e8e6e0); + background: var(--ds-surface, #ffffff); + flex-shrink: 0; + + .insp-icon { + width: 26px; + height: 26px; + border-radius: 7px; + background: var(--ds-canvas, #f7f6f3); + @include flex-row(0, center, center); + color: var(--ds-ink, #14140e); + flex-shrink: 0; + + mat-icon { + font-size: 14px; + width: 14px; + height: 14px; + } + } + + .insp-title { + flex: 1; + font-size: 15px; + font-weight: 600; + letter-spacing: -0.01em; + color: var(--ds-ink, #14140e); + } + + .icon-btn { + width: 30px; + height: 30px; + @include flex-row(0, center, center); + border: 1px solid transparent; + border-radius: 7px; + background: transparent; + color: var(--ds-ink-2, #3a3935); + cursor: pointer; + @include transition(); + + &:hover:not(:disabled) { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #14140e); + } + + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } + + mat-icon { + font-size: 16px; + width: 16px; + height: 16px; + } + } +} + +// ============ Toolbar ============ + +.insp-toolbar { + @include flex-row(4px); + padding: 10px 14px; + border-bottom: 1px solid var(--ds-border, #e8e6e0); + background: var(--ds-surface, #ffffff); + overflow-x: auto; + flex-shrink: 0; + + // Toolbar buttons inherited from cds-action-reply-tools-new + ::ng-deep { + .tool-btn { + width: 32px; + height: 32px; + @include flex-row(0, center, center); + border-radius: var(--ds-radius-sm, 6px); + border: 1px solid transparent; + background: transparent; + color: var(--ds-ink-2, #3a3935); + cursor: pointer; + flex-shrink: 0; + @include transition(); + + &:hover { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #14140e); + } + + &.active { + background: var(--ds-canvas, #f7f6f3); + color: var(--ds-ink, #14140e); + } + + svg, mat-icon { + width: 16px; + height: 16px; + } + } + + .tool-divider { + width: 1px; + height: 18px; + background: var(--ds-border, #e8e6e0); + margin: 0 4px; + flex-shrink: 0; + } + } +} + +// ============ Body (Content Area) ============ + +.insp-body { + flex: 1; + padding: 18px 14px 20px; + @include flex-column(28px); + background: var(--ds-surface, #ffffff); + overflow: auto; + + &.previewMode { + padding: 12px 14px; + } +} + +// ============ Empty State ============ + +.insp-empty-state { + @include empty-state(80px, 20px, 8px); + margin: 18px 14px; + + .insp-empty-text { + font-size: 13px; + color: var(--ds-muted, #8a8884); + } +} + +// ============ Message Block ============ + +.content { + @include flex-column(0); + width: 100%; + @include scrollbar-custom(); + + .msg { + @include response-grid(32px, 8px); + position: relative; + width: 100%; + } + + .msg-content { + @include flex-column(22px); + min-width: 0; + } +} + +// ============ Move Stack ============ + +.move-stack { + @include flex-column(2px); + margin-top: 4px; + flex-shrink: 0; + + .move-btn { + width: 24px; + height: 22px; + @include flex-row(0, center, center); + border: 1px solid transparent; + border-radius: 5px; + background: transparent; + color: var(--ds-muted-2, #b3b1ac); + cursor: pointer; + @include transition(); + flex-shrink: 0; + + svg { + width: 12px; + height: 12px; + stroke: currentColor; + stroke-width: 1.8; + fill: none; + } + + &:hover:not(:disabled) { + color: var(--ds-ink, #14140e); + background: var(--ds-canvas, #f7f6f3); + border-color: var(--ds-border, #e8e6e0); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &.trash-btn { + margin-bottom: 4px; + padding-bottom: 4px; + border-bottom: 1px solid var(--ds-border, #e8e6e0); + border-radius: 5px 5px 0 0; + color: var(--ds-muted-2, #b3b1ac); + + &:hover { + color: var(--ds-red, oklch(0.55 0.2 25)); + background: var(--ds-red-soft, oklch(0.98 0.02 25)); + border-color: oklch(0.88 0.06 25); + } + + mat-icon { + font-size: 14px; + width: 14px; + height: 14px; + } + } + } +} + +// ============ Message Separator ============ + +.msg-sep { + height: 1px; + background: var(--ds-border, #e8e6e0); + margin: 4px 0 4px 30px; + width: calc(100% - 30px); +} + +// ============ Footer ============ + +.insp-foot { + @include panel-footer(); + padding: 14px 18px; + border-top: 1px solid var(--ds-border, #e8e6e0); + background: var(--ds-surface, #ffffff); + flex-shrink: 0; + + .switch { + width: 32px; + height: 18px; + border-radius: 999px; + background: var(--ds-border, #e8e6e0); + position: relative; + cursor: pointer; + flex-shrink: 0; + @include transition(); + + &::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 14px; + height: 14px; + border-radius: 50%; + background: var(--ds-surface, #ffffff); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18); + @include transition(left); + } + + &.on { + background: var(--ds-green, oklch(0.68 0.14 155)); + + &::after { + left: 16px; + } + } + } + + .foot-label { + font-size: 13.5px; + color: var(--ds-ink-2, #3a3935); + } +} + +// ============ Sub-component Selectors ============ + +cds-action-reply-text-new, +cds-action-reply-image-new, +cds-action-reply-frame-new, +cds-action-reply-redirect-new, +cds-action-reply-gallery-new { + display: flex; + flex-direction: column; + gap: 10px; +} + +// ============ Preview Mode ============ + +.previewMode { + .insp-body { + gap: 0; + } + + .msg-sep { + margin-top: 10px; + margin-bottom: 10px; + } +} + +// ============ Remove Controls for RANDOM_REPLY ============ + +cds-action-reply-text-new.no-controls ::ng-deep, +cds-action-reply-image-new.no-controls ::ng-deep, +cds-action-reply-frame-new.no-controls ::ng-deep, +cds-action-reply-redirect-new.no-controls ::ng-deep, +cds-action-reply-gallery-new.no-controls ::ng-deep { + .text-editor-drop, + .move-stack { + display: none; + } + + .control-button:not(.delete) { + display: none; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts new file mode 100644 index 000000000..e8b8d70a0 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -0,0 +1,353 @@ +import { Component, OnInit, OnChanges, Input, ViewChild, ElementRef, Output, EventEmitter, SimpleChanges, ChangeDetectorRef } from '@angular/core'; +import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { Intent } from 'src/app/models/intent-model'; +import { Wait, Button, Message, Command, ActionReply, MessageAttributes } from 'src/app/models/action-model'; +import { + TYPE_UPDATE_ACTION, + TYPE_INTENT_ELEMENT, + TYPE_COMMAND, + TYPE_MESSAGE, + TYPE_BUTTON, + TYPE_URL, + generateShortUID +} from '../../../../../../utils'; +import { ControllerService } from '../../../../../../services/controller.service'; +import { IntentService } from '../../../../../../services/intent.service'; +import { ConnectorService } from '../../../../../../services/connector.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { TYPE_ACTION, ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; + +@Component({ + selector: 'cds-action-reply-new', + templateUrl: './cds-action-reply-new.component.html', + styleUrls: ['./cds-action-reply-new.component.scss'] +}) +export class CdsActionReplyNewComponent implements OnInit, OnChanges { + // ============ Inputs & Outputs ============ + @Input() action: ActionReply; + @Input() intentSelected: Intent; + @Input() previewMode: boolean = true; + + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{ type: 'create' | 'delete'; fromId: string; toId: string }>(); + + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + + // ============ State ============ + arrayResponses: Command[] = []; + typeAction: string; + idAction: string; + openCardButton: boolean = false; + textGrabbing: boolean = false; + intentName: string = ''; + intentNameResult: boolean = true; + + // ============ Constants (Type Enums) ============ + readonly typeCommand = TYPE_COMMAND; + readonly typeMessage = TYPE_MESSAGE; + readonly typeActions = TYPE_ACTION; + readonly actionList = ACTIONS_LIST; + + // ============ View Model ============ + element: any; + + // ============ Services ============ + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly intentService: IntentService, + private readonly controllerService: ControllerService, + private readonly connectorService: ConnectorService, + private readonly changeDetectorRef: ChangeDetectorRef + ) {} + + // ============ Lifecycle Hooks ============ + + ngOnInit(): void { + this.logger.log('CdsActionReplyNewComponent ngOnInit', this.action, this.intentSelected); + this.typeAction = this.action._tdActionType === TYPE_ACTION.RANDOM_REPLY + ? TYPE_ACTION.RANDOM_REPLY + : TYPE_ACTION.REPLY; + + try { + this.element = Object.values(ACTIONS_LIST).find(item => item.type === this.action._tdActionType); + } catch (error) { + this.logger.error('Failed to find action element', error); + } + + if (!this.action._tdActionId) { + this.action._tdActionId = generateShortUID(); + } + this.idAction = `${this.intentSelected.intent_id}/${this.action._tdActionId}`; + this.changeDetectorRef.detectChanges(); + } + + ngOnChanges(changes: SimpleChanges): void { + if (this.action && this.intentSelected) { + this.initialize(); + } + } + + // ============ Initialization ============ + + private initialize(): void { + this.openCardButton = false; + this.arrayResponses = []; + this.intentName = ''; + this.intentNameResult = true; + this.textGrabbing = false; + + try { + this.arrayResponses = this.action?.attributes?.commands ?? []; + } catch (error) { + this.logger.error('Failed to initialize arrayResponses', error); + this.arrayResponses = []; + } + + this.scrollToBottom(); + } + + private scrollToBottom(): void { + setTimeout(() => { + try { + const scrollElement = this.scrollContainer?.nativeElement; + if (scrollElement) { + scrollElement.scrollTop = scrollElement.scrollHeight; + } + } catch (error) { + this.logger.error('Failed to scroll to bottom', error); + } + }, 300); + } + + // ============ Drag & Drop Handlers ============ + + onMouseDown(): void { + this.textGrabbing = true; + } + + onMouseUp(): void { + this.textGrabbing = false; + } + + async drop(event: CdkDragDrop): Promise { + this.textGrabbing = false; + + try { + const currentPos = event.currentIndex * 2 + 1; + const previousPos = event.previousIndex * 2 + 1; + + // Swap wait + message pairs + const [waitCur, msgCur] = [this.arrayResponses[currentPos - 1], this.arrayResponses[currentPos]]; + const [waitPre, msgPre] = [this.arrayResponses[previousPos - 1], this.arrayResponses[previousPos]]; + + this.arrayResponses[currentPos - 1] = waitPre; + this.arrayResponses[currentPos] = msgPre; + this.arrayResponses[previousPos - 1] = waitCur; + this.arrayResponses[previousPos] = msgCur; + + this.connectorService.updateConnector(this.intentSelected.intent_id); + await this.onUpdateAndSaveAction(this.action); + } catch (error) { + this.logger.error('Drop operation failed', error); + } + } + + // ============ Response Handlers ============ + + onMoveUpResponse(index: number): void { + if (index < 2) return; + + try { + this.swapResponsePair(index - 2, index); + this.connectorService.updateConnector(this.intentSelected.intent_id); + this.onUpdateAndSaveAction(this.action); + } catch (error) { + this.logger.error('Failed to move response up', error); + } + } + + onMoveDownResponse(index: number): void { + if (index >= this.arrayResponses.length - 1) return; + + try { + this.swapResponsePair(index, index + 2); + this.connectorService.updateConnector(this.intentSelected.intent_id); + this.onUpdateAndSaveAction(this.action); + } catch (error) { + this.logger.error('Failed to move response down', error); + } + } + + private swapResponsePair(fromIndex: number, toIndex: number): void { + this.arrayResponses.splice(toIndex, 0, ...this.arrayResponses.splice(fromIndex, 2)); + } + + onAddNewActionReply(event: any): void { + this.logger.log('Adding new action reply', event); + + try { + const message = new Message(event.message.type, event.message.text); + if (event.message.attributes) { + message.attributes = event.message.attributes; + } + if (event.message.metadata) { + message.metadata = event.message.metadata; + } + + const command = new Command(event.type); + command.message = message; + + this.arrayResponses.push(new Wait()); + this.arrayResponses.push(command); + this.scrollToBottom(); + this.onUpdateAndSaveAction(this.action); + } catch (error) { + this.logger.error('Failed to add new action reply', error); + } + } + + onDeleteActionReply(index: number): void { + this.logger.log('Deleting action reply at index', index); + + try { + // Delete all connectors from buttons in this action + const intentId = this.idAction.substring(0, this.idAction.indexOf('/')); + const buttons = this.arrayResponses[index]?.message?.attributes?.attachment?.buttons; + + if (buttons && Array.isArray(buttons)) { + buttons.forEach(button => { + if (button.__isConnected) { + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + } + }); + } + + // Delete the wait + message pair + const waitElement = this.arrayResponses[index - 1]; + if (waitElement?.type === this.typeCommand.WAIT) { + this.arrayResponses.splice(index - 1, 2); + } else { + this.arrayResponses.splice(index, 1); + } + + this.onUpdateAndSaveAction(this.action); + } catch (error) { + this.logger.error('Failed to delete action reply', error); + } + } + + onChangeActionReply(event: any): void { + this.onUpdateAndSaveAction(this.action); + } + + onChangeJsonButtons(event: any, index: number): void { + this.logger.log('JSON buttons changed', event, index); + this.onChangeActionReply(event); + } + + // ============ Button Handlers ============ + + onCreateNewButton(index: number): void { + this.logger.log('Creating new button at index', index); + + try { + const response = this.arrayResponses[index]; + if (!response?.message?.attributes || !response.message.attributes.attachment) { + response.message.attributes = new MessageAttributes(); + } + + const newButton = this.createNewButton(); + if (newButton) { + response.message.attributes.attachment.buttons.push(newButton); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + this.onUpdateAndSaveAction(this.action); + } + } catch (error) { + this.logger.error('Failed to create new button', error); + } + } + + onDeleteButton(event: { buttons: Button[]; index: number }): void { + try { + const button = event.buttons[event.index]; + event.buttons.splice(event.index, 1); + + const intentId = this.idAction.substring(0, this.idAction.indexOf('/')); + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + this.updateAndSaveAction.emit(this.action); + } catch (error) { + this.logger.error('Failed to delete button', error); + } + } + + onOpenButtonPanel(buttonSelected: Button): void { + this.logger.log('Opening button panel', buttonSelected); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + this.controllerService.openButtonPanel(buttonSelected); + } + + onOpenPanelActionDetail(command: Command): void { + if (!this.controllerService.isOpenActionDetailPanel$) { + this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.controllerService.openActionDetailPanel(TYPE_INTENT_ELEMENT.ACTION, this.action); + } + } + + // ============ Settings Handlers ============ + + onChangeIntentName(name: string): void { + try { + this.intentName = name.replace(/[^A-Z0-9_]+/gi, ''); + } catch (error) { + this.logger.error('Failed to change intent name', error); + } + } + + onBlurIntentName(): void { + this.intentNameResult = true; + } + + onDisableInputMessage(): void { + try { + this.action.attributes.disableInputMessage = !this.action.attributes.disableInputMessage; + this.updateAndSaveAction.emit(this.action); + } catch (error) { + this.logger.error('Failed to toggle disable input message', error); + } + } + + // ============ Internal Helpers ============ + + private createNewButton(): Button | null { + const idButton = generateShortUID(); + + if (this.intentSelected?.intent_id) { + this.idAction = `${this.intentSelected.intent_id}/${this.action._tdActionId}`; + const idActionConnector = `${this.idAction}/${idButton}`; + + return new Button( + idButton, + idActionConnector, + false, + TYPE_BUTTON.TEXT, + 'Button', + '', + TYPE_URL.BLANK, + '', + '', + true + ); + } + + return null; + } + + // ============ Public Event Emitter ============ + + async onUpdateAndSaveAction(element: ActionReply): Promise { + this.logger.log('Saving action', element); + this.updateAndSaveAction.emit(element); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.spec.ts new file mode 100644 index 000000000..46fe62733 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyComponent } from './cds-action-reply.component'; + +describe('CdsActionReplyComponent', () => { + let component: CdsActionReplyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html new file mode 100644 index 000000000..d1492a830 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html @@ -0,0 +1,248 @@ +
+ +
+ + + + +
+ + + + +
+
+ {{'CDSCanvas.AddContentsToReply' | translate }} +
+
+ +
+ +
{{actionList.RANDOM_REPLY.doc+'.DESCRIPTION' | translate }}
+ +
+ +
+ +
+ + +
+ +
+ + +
+
+ + + + +
+ +
+ + +
+ + +
+
+
+ + +
+
+ + +
+ + +
+
+
+ + +
+
+ + +
+ + +
+
+
+ + +
+
+ + + +
+ + +
+
+
+ + +
+
+ +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+ + + + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss new file mode 100644 index 000000000..227639009 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss @@ -0,0 +1,323 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +$min-height-content: 376px; +$margin-left: 10px; +$padding: 10px; +$action-description-height: 100px; +$margin-bottom: 15px; + +.cds-action-content{ + // position: relative; + padding: 0px; +} + + +/**header**/ +.action_welcome { + margin-bottom: 5px; +} + +.action_welcome .action-description { + display:flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + font-size: 11px; + // color: #d2e3fc; + line-height: 1.5; +} + +.action_welcome em{ + font-size: 20px; + display: block; + margin: auto 4px auto 0; +} + + +.action_welcome input.action-input { + width: 100%; + border-radius: 4px; + border: 0; + padding: 5px 10px; + color: #22272d; + font-size: 1.15em; + line-height: 16px; +} + + + + + + +/**header**/ + + + + + + +/* customize scrollbar */ +::-webkit-scrollbar { + width: 0px; +} + +// .disable-input-message { +// position: absolute; +// bottom: 10px; +// left: 10px; +// color: white; +// } + +::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { + border-color: var(--blu) !important; +} + +// overwrite the checkbox background +::ng-deep .mat-checkbox-checked .mat-checkbox-background, +.mat-checkbox-indeterminate .mat-checkbox-background { + background-color: var(--blu) !important; + .mat-checkbox-checkmark { + background: var(--blu) !important;; + .mat-checkbox-checkmark-path { + stroke: white; + stroke-width: 5px; + } + } + +} + +// // overwrite the ripple overlay on hover and click +// ::ng-deep .mat-checkbox:not(.mat-checkbox-disabled) .mat-checkbox-ripple .mat-ripple-element { +// background-color: black !important; +// } + +.box-up { + display: flex; + padding: 5px 10px; + background: var(--ds-canvas, #f7f6f3); + position: relative; + /* top: 0; */ + width: 100%; + flex-direction: column; + align-content: flex-end; + align-items: flex-end; + flex-wrap: nowrap; + justify-content: flex-start; +} + +.box-dw { + // display: flex; + margin: 0px 5px; + .reply-info{ + color: var(--blu); + padding: 10px; + font-size: 14px; + text-align: center; + border: 1px solid var(--gray-light-01); + border-radius: 10px; + margin: 10px; + background: var(--blu-light-03); + } +} + +.cds-action-preview{ + padding: 10px 0px; +} + +.previewMode{ + &.box-dw{ + margin: 0px; + } + #scrollMe{ + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + overflow: unset; + // gap: 5px; + } + .content{ + min-height: unset; + max-height: unset; + overflow: unset; + } + // .draggable-box{ + // padding-top: $padding-base-preview; + // padding-bottom: $padding-base-preview; + // border-bottom: 3px solid #ebe2c6 + // } + .reply-info{ + max-width: calc(100% - 20px); + margin: 5px auto; + padding: 5px; + font-size: .7em; + line-height: 16px; + } + + .preview-divider { + margin: 10px 0px; + } +} + +.content { + position: relative; + display: block; + // display: flex; + // flex-direction: column; + // gap: 10px; + width: 100%; + min-height: $min-height-content; + margin-top: 0px; + overflow: auto; + max-height: calc(100vh - 180px); + .response { + display: block; + position: relative; + height: auto; + width: 100%; + min-height: auto; + margin: 0px; + .response-drop { + position: absolute; + display: flex; + align-content: space-around; + width: 24px; + height: 26px; + left: 0px; + top: 27px; + margin: 0; + color: var(--blu-04); + cursor: grab; + background-color: transparent; + z-index: 1; + } + .response-drop:hover { + color: var(--color-white-hex); + cursor: grab; + } + } + + + + /** START DRAG AND DROP **/ + // &.draggable-list { + // width: 500px; + // max-width: 100%; + // // border: solid 1px $color-txt-3-hex; + // min-height: 60px; + // display: block; + // background: var(--color-white-hex); + // border-radius: 4px; + // overflow: hidden; + // } + + .cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); + } + + .draggable-box:last-child { + border: none; + } + + .draggable-list.cdk-drop-list-dragging .draggable-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } + + .custom-placeholder { + opacity: 0.4; + background: #CCCCCC; + border: dotted 2px #858585; + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } + /** END DRAG AND DROP **/ +} + + + +.card-buttons { + position: absolute; + display: none; + top: 0; + right: 0; + margin: 0; + outline: none; + width: 380px; + height: 100%; + color: #fff; + justify-content: center; + align-items: center; + text-align: center; + background: transparent; + overflow: visible; + z-index: 14; + border-radius: 1em; + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), + 0 2px 2px 0 rgba(0, 0, 0, 0.14), + 0 1px 5px 0 rgba(0, 0, 0, 0.12); + &.active{ + display: block; + } +} + + +.reply--action-placeholder { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + min-height: 30px; + border-radius: var(--input-border-radius-base); + border: 1px dashed var(--brown); + padding: 6px 12px; + background: rgba(255,255,255,.8); + margin: 12px auto; + width: calc(100% - 5px); + .reply--action-placeholder-text { + font-weight: 400; + color: var(--brown); + font-size: 14px; + } +} + +#chart-container { + width: 100%; + height: 100%; +} +// cds-action-description { +// padding: 10px 0; +// margin-left: 10px; +// // margin-right: 30px; +// & ::ng-deep .action_welcome{ +// margin-bottom: 0px; +// } +// } + +cds-action-reply-text, +cds-action-reply-image, +cds-action-reply-frame, +cds-action-reply-redirect, +cds-action-reply-gallery{ + display: flex; + flex-direction: column; + gap: 10px; +} + + +/* REMOVE DROP AND MOVE_UP/MOVE_DOWN INDICATORS for RANDOM_REPLY type only */ +cds-action-reply-text.no-controls ::ng-deep, +cds-action-reply-image.no-controls ::ng-deep, +cds-action-reply-frame.no-controls ::ng-deep, +cds-action-reply-redirect.no-controls ::ng-deep, +cds-action-reply-gallery.no-controls ::ng-deep{ + .text-editor-drop{ + display: none; + } + .control-button:not(.delete){ + display: none; + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts new file mode 100644 index 000000000..f12be4dc8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts @@ -0,0 +1,478 @@ +import { Component, OnInit, Input, ViewChild, ElementRef, Output, EventEmitter, SimpleChanges, ChangeDetectorRef } from '@angular/core'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Intent } from 'src/app/models/intent-model'; +import { Wait, Button, Message, Command, ActionReply, MessageAttributes, Setting, ActionReplyV2 } from 'src/app/models/action-model'; +import { TYPE_UPDATE_ACTION, TYPE_INTENT_ELEMENT, TYPE_COMMAND, TYPE_RESPONSE, TYPE_BUTTON, TYPE_URL, TYPE_MESSAGE, generateShortUID } from '../../../../../../utils'; + +import { ControllerService } from '../../../../../../services/controller.service'; +import { IntentService } from '../../../../../../services/intent.service'; +import { ConnectorService } from '../../../../../../services/connector.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Observable, Subject, Subscription, takeUntil } from 'rxjs'; +import { TYPE_ACTION, ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-actions'; + + +@Component({ + selector: 'cds-action-reply-v2-new', + templateUrl: './cds-action-reply-new.component.html', + styleUrls: ['./cds-action-reply-new.component.scss'] +}) +export class CdsActionReplyV2Component implements OnInit { + + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + translateY: string; + + @Input() action: ActionReplyV2; + @Input() intentSelected: Intent; + @Input() previewMode: boolean = true + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + subscriptions: Array<{ key: string, value: Subscription }> = []; + private unsubscribe$: Subject = new Subject(); + eventActionChanges: Subject = new Subject(); + + // idIntentSelected: string; + idAction: string; + + openCardButton: boolean = false; + // buttonSelected: Button; + // newButton: boolean = false; + + typeCommand = TYPE_COMMAND; + typeResponse = TYPE_RESPONSE; + typeMessage = TYPE_MESSAGE; + typeActions = TYPE_ACTION; + actionList = ACTIONS_LIST; + + intentName: string; + intentNameResult: boolean; + textGrabbing: boolean; + arrayResponses: Array; + typeAction: string; + + element: any; + showTip: boolean = true; + descriptionTooltip: string = ""; + dataInput: string; + tipText: string; + titlePlaceholder: string; + + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private intentService: IntentService, + private controllerService: ControllerService, + private connectorService: ConnectorService, + private changeDetectorRef: ChangeDetectorRef + ) { + this.initSubscriptions(); + } + + // manageTooltip(){} + // onChangeText(event){} + // addElement(event){} + + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.log('ActionReplyComponent ngOnInit', this.action, this.intentSelected); + // // this.logger.log('ngOnInit panel-response::: ', this.typeAction); + this.typeAction = (this.action._tdActionType === TYPE_ACTION.RANDOM_REPLY ? TYPE_ACTION.RANDOM_REPLY : TYPE_ACTION.REPLY); + try { + this.element = Object.values(ACTIONS_LIST).find(item => item.type === this.action._tdActionType); + if(this.action._tdActionTitle && this.action._tdActionTitle != ""){ + this.dataInput = this.action._tdActionTitle; + } + // this.settings = { no_input: null, timeout: 20 } + // if(this.action.noInput){ + // this.settings = { no_input: this.action.noInput} + // } + this.logger.log('ActionDescriptionComponent action:: ', this.element); + } catch (error) { + this.logger.log("error ", error); + } + this.action._tdActionId = this.action._tdActionId?this.action._tdActionId:generateShortUID(); + this.idAction = this.intentSelected.intent_id+'/'+this.action._tdActionId; + // this.initialize(); + + this.changeDetectorRef.detectChanges(); + + + } + + /** + * + * @param changes + * IMPORTANT! serve per aggiornare il dettaglio della action nel pannello + */ + ngOnChanges(changes: SimpleChanges): void { + if(this.action && this.intentSelected) this.initialize(); + } + + ngOnDestroy() { + this.unsubscribe(); + } + + unsubscribe() { + this.unsubscribe$.next(null); + this.unsubscribe$.complete(); + + } + + + initSubscriptions() { + + let subscribtion: any; + let subscribtionKey: string; + + /** SUBSCRIBE TO THE INTENT CREATED OR UPDATED */ + subscribtionKey = 'behaviorIntent'; + subscribtion = this.subscriptions.find(item => item.key === subscribtionKey); + if (!subscribtion) { + subscribtion = this.intentService.behaviorIntent.pipe(takeUntil(this.unsubscribe$)).subscribe(intent => { + if (intent && this.intentSelected && intent.intent_id === this.intentSelected.intent_id) { + this.logger.log("[ActionReplyComponent] sto modifico l'intent: ", this.intentSelected, " con : ", intent); + let actionReply = intent.actions.find(el => el._tdActionId === this.action._tdActionId) + if(actionReply){ + this.eventActionChanges.next(this.action) + } + } + }); + const subscribe = { key: subscribtionKey, value: subscribtion }; + this.subscriptions.push(subscribe); + } + + } + + + + // CUSTOM FUNCTIONS // + /** */ + private initialize() { + this.openCardButton = false; + this.arrayResponses = []; + this.intentName = ''; + this.intentNameResult = true; + this.textGrabbing = false; + if (this.action) { + try { + this.arrayResponses = this.action.attributes.commands; + } catch (error) { + this.logger.log('error:::', error); + } + } + this.scrollToBottom(); + } + + + /** */ + scrollToBottom(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.log('scrollToBottom ERROR: ', error); + } + }, 300); + } + + + // EVENT FUNCTIONS // + + + // on drag // + /** */ + mouseDown() { + this.textGrabbing = true; + } + + /** */ + mouseUp() { + this.textGrabbing = false; + } + + /** */ + drop(event: CdkDragDrop) { + // this.logger.log( 'DROP REPLY ---> ',event, this.arrayResponses); + this.textGrabbing = false; + try { + let currentPos = event.currentIndex*2+1; + let previousPos = event.previousIndex*2+1; + const waitCur = this.arrayResponses[currentPos-1]; + const msgCur = this.arrayResponses[currentPos]; + const waitPre = this.arrayResponses[previousPos-1]; + const msgPre = this.arrayResponses[previousPos]; + this.arrayResponses[currentPos-1] = waitPre; + this.arrayResponses[currentPos] = msgPre; + this.arrayResponses[previousPos-1] = waitCur; + this.arrayResponses[previousPos] = msgCur; + // // this.logger.log( 'DROP REPLY ---> ', this.arrayResponses); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.intentSelected}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('drop ERROR', error); + } + } + + + // on action // + /** */ + onMoveUpResponse(index: number) { + if(index<2)return; + try { + let from = index - 1; + let to = from - 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + from = index; + to = from - 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + // this.logger.log( 'onMoveUpResponse ---> ', this.arrayResponses); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onAddNewResponse ERROR', error); + } + } + + /** */ + onMoveDownResponse(index: number) { + if(index === this.arrayResponses.length-1)return; + try { + let from = index; + let to = from + 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + from = index - 1; + to = from + 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + // this.logger.log( 'onMoveUpResponse ---> ', this.arrayResponses); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onAddNewResponse ERROR', error); + } + } + + + /** onAddNewActionReply */ + onAddNewActionReply(ele) { + this.logger.log('onAddNewActionReply: ', ele); + try { + let message = new Message(ele.message.type, ele.message.text); + if (ele.message.attributes) { + message.attributes = ele.message.attributes; + } + if (ele.message.metadata) { + message.metadata = ele.message.metadata; + } + const wait = new Wait(); + let command = new Command(ele.type); + command.message = message; + this.arrayResponses.push(wait); + this.arrayResponses.push(command); + this.scrollToBottom(); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onAddNewResponse ERROR', error); + } + } + + + /** onDeleteActionReply */ + onDeleteActionReply(index: number) { + this.logger.log('onDeleteActionReply: ', this.arrayResponses[index]); + // !!! cancello tutti i connettori di una action + var intentId = this.idAction.substring(0, this.idAction.indexOf('/')); + try { + let buttons = this.arrayResponses[index].message.attributes.attachment.buttons; + buttons.forEach(button => { + this.logger.log('button: ', button); + if(button.__isConnected){ + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + // this.connectorService.deleteConnector(button.__idConnector); + } + }); + } catch (error) { + this.logger.log('onAddNewResponse ERROR', error); + } + // cancello l'elemento wait precedente + this.logger.log('**** arrayResponses: ', this.arrayResponses, 'index-1: ', (index-1)); + const wait = this.arrayResponses[index-1]; + this.logger.log('wait: ', wait); + if( wait && wait.type === this.typeCommand.WAIT){ + this.logger.log('CANCELLO WAIT E MESSAGE'); + this.arrayResponses.splice(index-1, 2); + } else { + this.logger.log('CANCELLO SOLO MESSAGE'); + this.arrayResponses.splice(index, 1); + } + this.logger.log('onDeleteActionReply', this.arrayResponses); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } + + /** onChangingReplyAction */ + onChangeActionReply(event) { + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.logger.log('onChangeActionReply ************', element); + this.onUpdateAndSaveAction(element); + } + + /** onConnectorChangeReply */ + onConnectorChangeReply(event){ + this.logger.log('[cds-action-reply] onConnectorChangeReply ************', event, this.action); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + this.onConnectorChange.emit(event) + } + + + + // on button action // + + /** onCreateNewButton */ + onCreateNewButton(index){ + this.logger.log('[cds-action-reply] onCreateNewButton: ', index); + try { + if(!this.arrayResponses[index].message.attributes || !this.arrayResponses[index].message.attributes.attachment){ + this.arrayResponses[index].message.attributes = new MessageAttributes(); + } + } catch (error) { + this.logger.error('error: ', error); + } + let buttonSelected = this.createNewButton(); + if(buttonSelected){ + this.arrayResponses[index].message.attributes.attachment.buttons.push(buttonSelected); + this.logger.log('[cds-action-reply] onCreateNewButton: ', this.action, this.arrayResponses); + // this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + this.eventActionChanges.next(this.action) + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } + } + + private createNewButton() { + const idButton = generateShortUID(); + if(this.intentSelected.intent_id){ + this.idAction = this.intentSelected.intent_id+'/'+this.action._tdActionId; + const idActionConnector = this.idAction+'/'+idButton; + let buttonSelected = new Button( + idButton, + idActionConnector, + false, + TYPE_BUTTON.TEXT, + 'Button', + '', + TYPE_URL.BLANK, + '', + '', + true + ); + this.logger.log('[cds-action-reply] createNewButton: ', buttonSelected); + return buttonSelected; + } + return null; + } + + /** onDeleteButton */ + onDeleteButton(event){ + let button = event.buttons[event.index]; + event.buttons.splice(event.index, 1); + var intentId = this.idAction.substring(0, this.idAction.indexOf('/')); + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + this.eventActionChanges.next(this.action) + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } + + + /** onUpdateAndSaveAction: + * function called by all actions in @output whenever they are modified! + * 1 - update connectors + * 2 - update intent + * */ + public async onUpdateAndSaveAction(element) { + this.logger.log('[cds-action-reply] onUpdateAndSaveAction:::: ', this.action, element); + // this.connectorService.updateConnector(this.intentSelected.intent_id); + this.updateAndSaveAction.emit(this.action); + } + + // on intent name // + + /** onChangeIntentName */ + onChangeIntentName(name: string) { + name.toString(); + try { + this.intentName = name.replace(/[^A-Z0-9_]+/ig, ""); + } catch (error) { + this.logger.log('name is not a string', error) + } + } + + /** onBlurIntentName */ + onBlurIntentName(name: string) { + this.intentNameResult = true; + } + + /** onDisableInputMessage */ + onDisableInputMessage() { + try { + this.action.attributes.disableInputMessage = !this.action.attributes.disableInputMessage; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } catch (error) { + this.logger.log("Error: ", error); + } + } + + + /** appdashboard-button-configuration-panel: onOpenButtonPanel */ + onOpenButtonPanel(buttonSelected) { + this.logger.log('[cds-action-reply] onOpenButtonPanel 2 :: ', buttonSelected); + // this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + this.controllerService.openButtonPanel(buttonSelected); + } + + onOpenPanelActionDetail(event){ + this.logger.log('onOpenPanelActionDetail :: ',this.controllerService.isOpenActionDetailPanel$, event, this.action); + if(!this.controllerService.isOpenActionDetailPanel$){ + this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.controllerService.openActionDetailPanel(TYPE_INTENT_ELEMENT.ACTION, this.action); + } + } + + + + /** appdashboard-button-configuration-panel: Save button */ + onSaveButton(button) { + // this.logger.log('onSaveButton :: ', button, this.response); + // this.generateCommandsWithWaitOfElements(); + } + + + + /** appdashboard-button-configuration-panel: Close button panel */ + onCloseButtonPanel() { + this.logger.log('onCloseButtonPanel :: '); + this.openCardButton = false; + } + + onFocusOutEvent(event) { + // this.logger.log('onFocusOutEvent ::::::: ', event); + // this.onCloseButtonPanel() + } + + onChangeJsonButtons(event: any, i: number){ + this.logger.log('[cds-action-reply] onChangeJsonButtons ::::::: ', event, i); + // // this.arrayResponses[i].message = event; + this.onChangeActionReply(event); + } + +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.spec.ts new file mode 100644 index 000000000..46fe62733 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyComponent } from './cds-action-reply.component'; + +describe('CdsActionReplyComponent', () => { + let component: CdsActionReplyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.html new file mode 100644 index 000000000..4ce869104 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.html @@ -0,0 +1,34 @@ +
+
+ + + + + + + + + + + + + + + {{button?.value}} +
+
+ +
+ +
+ delete +
+
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss new file mode 100644 index 000000000..0da19eb5c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss @@ -0,0 +1,157 @@ +@import "./src/assets/sass/cds/_variables.scss"; + + +:host{ + --backgroundColor: var(--color-white-hex); + --textColor: #{var(--blu)}; + --hoverBackgroundColor: #{var(--blu)}; + --hoverTextColor: var(--color-white-hex); + --buttonFontSize: 0.7em; + --max-width: #{var(--button-max-width-base)}; +} +.previewMode{ + + .content-botton-reply { + height: unset; + } + + .button-reply{ + min-width: var(--button-min-width-preview); + max-width: var(--button-max-width-base); + padding: 2px 10px; + // max-width: calc(100% - 20px); + // margin: auto; + // background: transparent; + + // &.connected{ + // background: #ffff; + // border-color: #ffff; + // } + } +} + +.button-reply { + // float: right; + display: flex; + justify-content: center; + position: relative; + min-width: 100px; + text-align: center; + // margin: 0px 5px 0px; //10px 5px 0; + padding: 0px 10px; + user-select: none; + box-sizing: border-box; + outline: none; + background: var(--backgroundColor); + border: 1px solid var(--textColor); + border-radius: var(--button-border-radius-base); + color: var(--textColor); + cursor: pointer; + font-size: 0.7em; + font-weight: 500; + line-height: var(--button-height-base); + transition: all .3s; + + .icon-button-action { + position: absolute; + top: -1px; + right: 5px; + svg { + fill: var(--textColor); + } + } + .icon-button-action-self{ + position: absolute; + right: 1px; + svg { + fill: var(--textColor); + } + } + &:focus, + &:hover { + color: var(--hoverTextColor); + background: var(--hoverBackgroundColor); + .icon-button-action, .icon-button-action-self { + svg { + fill: var(--hoverTextColor); + } + } + } +} + + +.button-reply-wrp:hover { + // transform: scale(1.05); + .button-controls { + opacity: 1; + } +} + +.button-reply-text { + width: 100%; + height: 100%; + max-width: var(--max-width); + user-select: none; + color: var(--textColor); + cursor: pointer; + font-size: 1em; + font-weight: 500; + line-height: var(--button-height-base); + text-align: center; + box-sizing: border-box; + margin: 0; + padding: 0; + outline: none; + overflow: hidden!important; + text-overflow: ellipsis; + white-space: nowrap; +} + +.button-in-msg{ + display: flex; + width: 100%; + position: relative; + justify-content: center; +} + +.button-controls { + justify-content: space-between; + display: inline-flex; + position: absolute; + left: 5%; + top: -40%; + opacity: 0; + transition: opacity 0.3s ease-in-out; + .buttonsToMove{ + display: inline-flex; + } + .control-button { + cursor: pointer; + background: var(--blu-light-02); + color: var(--blu); + transition: color .3s; + height: 20px; + width: 20px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + em { + font-size: 1.15em; + color: var(--blu); + transition: color .3s; + } + } + .control-button:hover{ + color: var(--backgroundColor); + box-shadow: 0 2px 6px 0 rgb(255 255 255 / 15%); + em { + opacity: 0.8; + } + &.delete{ + em { + color: var(--color-red-hex); + } + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.ts new file mode 100644 index 000000000..9328f8608 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.ts @@ -0,0 +1,33 @@ +import { Component, Input, OnInit, EventEmitter, Output, SimpleChanges } from '@angular/core'; +import { TYPE_BUTTON } from '../../../../../../../utils'; + +@Component({ + selector: 'cds-action-reply-button-new', + templateUrl: './cds-action-reply-button-new.component.html', + styleUrls: ['./cds-action-reply-button-new.component.scss'] +}) +export class CdsActionReplyButtonNewComponent implements OnInit { + + @Input() button: any + @Input() previewMode: boolean = true; + @Output() onButtonControl = new EventEmitter() + + TYPE_BUTTON = TYPE_BUTTON + + constructor() { } + + ngOnInit(): void { + // empty + } + + onDeleteButton(){ + this.onButtonControl.emit('delete') + } + onMoveLeftButton(){ + this.onButtonControl.emit('moveLeft') + } + onMoveRightButton(){ + this.onButtonControl.emit('moveRight') + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.spec.ts new file mode 100644 index 000000000..02900903b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyButtonComponent } from './cds-action-reply-button.component'; + +describe('CdsActionReplyButtonComponent', () => { + let component: CdsActionReplyButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyButtonComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html new file mode 100644 index 000000000..735c634f7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html @@ -0,0 +1,107 @@ +
+ +
+ drag_indicator +
+ +
+
+ delete +
+
+ expand_less +
+
+ expand_more +
+
+ +
+ + +
+ +
+ + +
+ + +
+ filter_alt + {{'CDSCanvas.Filter' | translate }} +
+ +
+ + +
+ + + +
+ +
+ +
+
+
+ +
+
{{'CDSCanvas.ClickToAddFrame' | translate}}
+
+
+ + +
+ +
+
{{response.text}}
+
{{'CDSCanvas.ClickToAddText' | translate}}
+
+ +
+ +
+ + +
+ +
+ +
+ + +
+ + + + +
+ +
+ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss new file mode 100644 index 000000000..5c9a3a757 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss @@ -0,0 +1,104 @@ +@import "./src/assets/sass/cds/_variables.scss"; +$max-height: 230px; + +.extensions-response{ + display: flex; + flex-direction: row; + justify-content: flex-start; +} + +.delay-wrapper, .height-wrapper { + height: 32px; +} + +:host{ + --base-margin: #{var(--input-base-margin)}; +} + +.previewMode{ + .response-frame-panel{ + margin: 0; + max-width: 100%; + border-color: #8da2b5; + margin: 5px auto; + max-width: calc(100% - 5px); //calc(100% - 20px); + + &.no-image{ + display: flex; + gap: 10px; + align-items: center; + background: none; + + .image{ + width: 40px; + height: 40px; + // border-radius: 8px; + // box-shadow: rgba(0, 0, 0, 0.12) 0px -1px 0px 0px inset; + display: flex; + align-items: center; + justify-content: center; + mat-icon { + color: var(--blu); + } + img { + max-height: 90%; + max-width: 90%; + border-radius: inherit; + } + } + + .text{ + overflow-x: clip; + white-space: nowrap; + text-overflow: ellipsis; + font-size: .8em; + color: rgb(141, 162, 181) + } + } + + } + + .content-frame{ + margin: 0; + max-width: 100%; + border-color: #647283; + margin: 5px auto; + max-width: calc(100% - 5px); //calc(100% - 20px); + } +} + +.response-frame-wrapper{ + position: relative; + display: block; + border-radius: 8px; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + // margin-top: 10px; + margin-bottom: 10px; + padding: 0px; + background: rgba(255, 255, 255, 0.383); + overflow: visible; + // max-width: calc(100% - 66px); + width: auto; + height: auto; + + .frame-panel { + border-radius: 6px; + display: block; + overflow: hidden; + } +} + + +/** box-textarea **/ +cds-textarea.text-editable-div ::ng-deep{ + display: block; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + // width: calc(100% - 66px); + textarea { + line-height: 20px !important; + width: calc(100% - 20px) !important; + font-size: 0.9em !important; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts new file mode 100644 index 000000000..1ec8e8508 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts @@ -0,0 +1,155 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser' +import { Expression, Message, Wait } from 'src/app/models/action-model'; +import { TYPE_MESSAGE } from '../../../../../../../utils'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { TYPE_ACTION } from 'src/app/chatbot-design-studio/utils-actions'; + +@Component({ + selector: 'cds-action-reply-frame-new', + templateUrl: './cds-action-reply-frame-new.component.html', + styleUrls: ['./cds-action-reply-frame-new.component.scss'] +}) +export class CdsActionReplyFrameNewComponent implements OnInit { + + @Output() changeActionReply = new EventEmitter(); + @Output() deleteActionReply = new EventEmitter(); + @Output() moveUpResponse = new EventEmitter(); + @Output() moveDownResponse = new EventEmitter(); + + @Input() idAction: string; + @Input() response: Message; + @Input() wait: Wait; + @Input() index: number; + @Input() previewMode: boolean = true; + + // frame // + typeActions = TYPE_ACTION; + frameWidth: number | string; + frameHeight: number | string; + typeMessage = TYPE_MESSAGE; + // Textarea // + // Delay // + delayTime: number; + // Filter // + isOpenDelaySlider: boolean = false; + isOpenFilter: boolean = false; + isOpenHeightSlider: boolean = false; + heightIframe: any; + + canShowHeight: boolean = true; + canShowFilter: boolean = true; + filterConditionExist: boolean = false; + booleanOperators=[ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},] + + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + ) { } + + ngOnInit(): void { + this.initialize(); + } + + + private initialize(){ + this.delayTime = (this.wait?.time && this.wait?.time !== 0)? (this.wait.time/1000) : 500/1000; + if(this.response?._tdJSONCondition && this.response._tdJSONCondition.conditions.length > 0){ + this.filterConditionExist = true + } + if (typeof this.response?.metadata?.height === 'string') { + this.heightIframe = parseFloat(this.response.metadata.height); + } else { + this.heightIframe = this.response?.metadata?.height; + } + } + + + + // EVENT FUNCTIONS // + /** */ + onClickDelayTime(opened: boolean){ + this.isOpenDelaySlider = !this.isOpenDelaySlider; + // this.canShowFilter = !opened; + } + + onClickHeightIframe(opened: boolean){ + this.isOpenHeightSlider = !this.isOpenHeightSlider; + this.canShowHeight = !this.canShowHeight; + } + + + /** onChangeDelayTime */ + onChangeDelayTime(value:number){ + this.delayTime = value; + this.wait.time = value*1000; + this.isOpenDelaySlider = false; + // this.canShowFilter = true; + // this.logger.log("[ActionReplyFrameComponent] onChangeDelayTime: ", this.response.metadata); + this.changeActionReply.emit(); + } + + /** onChangeExpression */ + onChangeExpression(expression: Expression){ + this.response._tdJSONCondition = expression; + this.filterConditionExist = expression && expression.conditions.length > 0? true : false; + // this.logger.log("[ActionReplyFrameComponent] onChangeExpression: ", this.response.metadata); + this.changeActionReply.emit(); + } + + /** onDeleteActionReply */ + onDeleteActionReply(){ + this.deleteActionReply.emit(this.index); + } + + /** onMoveUpResponse */ + onMoveUpResponse(){ + this.moveUpResponse.emit(this.index); + } + + /** onMoveDownResponse */ + onMoveDownResponse(){ + this.moveDownResponse.emit(this.index); + } + + /** onChangeTextarea */ + onChangeTextarea(text:string) { + this.logger.log("[ActionReplyFrameComponent] onChangeTextarea: ", text); + if(!this.previewMode){ + this.response.text = text; + // this.changeActionReply.emit(); + } + } + + onBlur(event){ + // this.logger.log("[ActionReplyFrameComponent] onBlur: ", this.response.metadata); + this.changeActionReply.emit(); + } + + /** */ + onDeletedMetadata(){ + // this.logger.log("[ActionReplyFrameComponent] onDeletedMetadata: ", this.response.metadata); + this.response.metadata.src = ''; + this.changeActionReply.emit(); + } + + /** */ + onLoadPathElement(){ + this.response.metadata.height = this.heightIframe+'px'; + // this.logger.log("[ActionReplyFrameComponent] onLoadPathElement: ", this.response.metadata); + this.changeActionReply.emit(); + } + + /** */ + onChangeHeightIframe(height){ + this.heightIframe = height; + this.isOpenHeightSlider = false; + this.response.metadata.height = height+'px'; + // this.logger.log("[ActionReplyFrameComponent] onChangeHeightIframe: ", this.response.metadata); + this.changeActionReply.emit(); + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.spec.ts new file mode 100644 index 000000000..408a7d00d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyFrameComponent } from './cds-action-reply-frame.component'; + +describe('CdsActionReplyFrameComponent', () => { + let component: CdsActionReplyFrameComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyFrameComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyFrameComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html new file mode 100644 index 000000000..2c94b1be9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html @@ -0,0 +1,339 @@ +
+ +
+ drag_indicator +
+ +
+
+ delete +
+
+ expand_less +
+
+ expand_more +
+
+ +
+ + +
+ +
+ filter_alt + {{'CDSCanvas.Filter' | translate }} +
+
+ + +
+
+ + +
+
{{response.text}}
+
{{'CDSCanvas.ClickToAddText' | translate }}
+
+
+ + +
+ + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + +
+
+ + {{'CDSCanvas.AddButton' | translate }} +
+
+ +
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss new file mode 100644 index 000000000..f0b731201 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss @@ -0,0 +1,922 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --cardImageHeight: 150px; + --cardWidth: 220px; + --border-color: #{var(--blu-light-01)}; + --base-color: #{var(--blu-light-02)}; +} + +.previewMode{ + display: flex; + flex-direction: column; + gap: var(--base-element-gap); + + .galleryElement { + margin: 0; + // padding: 8px; + gap: var(--base-element-gap); + display: flex; + flex-direction: column; + // background-color: #ffffff80; // nk + // border-radius: 6px; + // box-shadow: #0000000f 0 0 0 1px; + } + + .gallery-preview-wrp{ + display: flex; + -webkit-box-align: center; + align-items: center; + padding: 0px 10px; + width: 100%; + gap: 10px; + + .image{ + width: 40px; + height: 40px; + border-radius: 8px; + box-shadow: rgba(0, 0, 0, 0.12) 0px -1px 0px 0px inset; + display: flex; + + + img { + max-height: 100%; + max-width: 100%; + border-radius: inherit; + object-fit: cover; + width: 100%; + height: 100%; + } + } + .no-image, + &#placeholder{ + align-items: center; + justify-content: center; + border-radius: unset; + box-shadow: unset; + + img { + max-height: 90%; + max-width: 90%; + border-radius: inherit; + } + + } + + .content{ + display: flex; + flex-direction: column; + -webkit-box-align: center; + align-items: flex-start; + width: calc(100% - 50px); + + .text{ + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 13px; + font-weight: 500; + width: 100%; + } + + .description{ + font-size: 11px; + } + } + + + + } + + + /** BUTTONS **/ + .buttons-response { + display: flex; + margin: 0px; //15px 0 0; + padding: 0px 0px 0px 0px; + gap: var(--base-element-gap); + width: 100%; + font-size: 14px; + // padding: 0 5px; + flex-direction: column; + flex-wrap: nowrap; + float: right; + justify-content: flex-start; + /* align-content: flex-end; */ + align-items: center; + + .button-reply-add{ + color: var(--base-color); + border-color: var(--base-color); + } + } + + .custom-placeholder { + margin: 10px 5px; + background: #dfdfdf; + border: dotted 0px #999; + height: var(--button-height-base); + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } + + .button-controls{ + top: -40%; + } + + .gallery-divider{ + height: 2px; + margin: 8px 0px; + background: #ebe2c6; + display: flex; + } + +} + + +/** BUTTONS **/ +.gallery-response { + display: flex; + overflow-y: visible; + gap: 10px; + margin: 0; + width: 100%; + font-size: var(--font-size-base); + padding: 0 32px 32px 32px; +} + + +.button-reply { + position: relative; + min-width: 100px; + // margin: 20px 0px 0; + // padding: 0 16px; + user-select: none; + box-sizing: border-box; + outline: none; + background: var(--color-white-hex); + border-radius: var(--button-border-radius-base); + cursor: pointer; + font-size: 1em; + font-weight: 500; + line-height: var(--button-height-base); + text-align: center; + transition: all .3s; + + &.custom-placeholder { + margin: 10px 5px; + background: #dfdfdf; + border: dotted 0px #999; + height: var(--button-height-base); + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } +} +.button-reply:hover{ + .button-controls { + opacity: 1; + } + .action-button-controls{ + opacity: 0; + } +} + + +//BUTTONS +.gallery-buttons{ + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + align-items: center; + cursor: pointer; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + flex-direction: column; + // height: 42px; + justify-content: center; + // padding: 0 10px; + -webkit-transition: all .3s; + transition: all .3s; + width: 100%; + + .single-button{ + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + justify-content: center; + border-top: 1px solid var(--base-color); + cursor: pointer; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + // height: 45px; + -webkit-transition: all .3s; + transition: all .3s; + width: 100%; + position: relative; + + line-height: var(--button-height-base); + padding: 5px 10px; + font-size: 0.7em; + font-weight: 500; + + &:after { + content: ""; + position: absolute; + width: 0; + height: 0; + top: 50%; + left: 50%; + transform-style: flat; + transform: translate3d(-50%,-50%,0); + background: rgba(white,.2); + border-radius: 100%; + transition: width .5s ease, height .5s ease; + } + + &:hover{ + .button-controls{ + opacity: 1; + } + } + + } +} + + + +// ADD button - ADD card +.gallery-buttons-add{ + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + // margin-bottom: 5px; + width: 100%; + + &.last{ + flex-direction: row; + + .gallery-buttons-add-lines{ + border-top: 1px dashed var(--base-color); + border-bottom: 1px dashed var(--base-color); + width: 20px; + height: 0; + } + } + + .gallery-buttons-add-lines{ + border-left: 1px dashed var(--base-color); + border-right: 1px dashed var(--base-color); + height: 28px; + width: 0; + } + + + .csd-add-button-btn-wpr{ + position: relative; + + .cds-add-action-btn { + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + align-items: center; + background: #fff; + border-radius: 100%; + -webkit-box-shadow: 0 1px 4px 0 rgba(0,0,0,.19); + box-shadow: 0 1px 4px 0 rgba(0,0,0,.19); + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 22px; + justify-content: center; + -webkit-transition: background-color .6s; + transition: background-color .6s; + width: 22px; + margin: 0; + padding: 0; + + } + + .cds-add-action-btn { + background-color: var(--base-color); + color: white; + } + + .cds-add-action-btn:hover, + .action--text:hover{ + opacity: 0.5; + } + + .action--text { + position: absolute; + top: 0; + left: 30px; + color: var(--base-color); + font-size: 14px; + white-space: nowrap; + // z-index: 1; + cursor: pointer; + } + + } + +} + + +.gallery-reply-card { + width: 100%; + height: 100%; + max-width: var(--cardWidth); + user-select: none; + cursor: pointer; + font-size: 1em; + font-weight: 500; + line-height: var(--button-height-base); + border: 1px solid var(--border-color); + border-radius: var(--button-border-radius-base); + text-align: center; + box-sizing: border-box; + margin: 0; + padding: 0; + outline: none; + overflow: hidden!important; + text-overflow: ellipsis; + white-space: nowrap; + + flex-shrink: 0; + opacity: 1; + position: relative; + -webkit-transition: opacity .3s; + transition: opacity .3s; + width: var(--cardWidth); + +} + +.cards-scroll-spacer{ + -ms-flex-negative: 0; + content: ""; + flex-shrink: 0; + width: 17px; +} + + +// --- PREVIEW SECTION --- +.gallery-image{ + height: 150px; + background: #fff; + overflow: hidden; + position: relative; + width: 100%; + border-radius: var(--button-border-radius-base) var(--button-border-radius-base) 0px 0px; + + .image-overlay{ + flex-direction: column; + align-items: stretch; + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + background-color: var(--border-color); + display: flex; + + .image-upload{ + width: 100%; + height: 100%; + } + + } + +} + +#image-url.text-editable-div, +cds-textarea#image-url { + display: block; + margin-top: 8px; + margin-bottom: 0; + margin-left: 0; + margin-right: 0; + width: 100%; + max-width: 100%; + min-width: 0; +} + +cds-image-upload ::ng-deep { + + div.wrapper{ + flex-direction: row; + div.toogle-wrp{ //hide Upload/link toogle + display: none; + } + } + + div.dropUploadImage{ + min-height: unset !important; + margin: 10px 10px 0; + // height: 64px; + } + div.image{ + height: 20px !important; + width: 20px !important; + } + div.labelDropUploadImage{ + font-size: 12px; + line-height: 15px; + } + div.image-wrp{ + height: var(--cardImageHeight); + img{ + height: 100% !important; + width: 100% !important; + -o-object-fit: contain; + object-fit: contain; + } + + &:hover{ + img{ opacity: 0.5; } + .control-button { + &.delete { + margin-right: 5px !important; + margin-top: 5px !important; + opacity: 1; + } + } + } + + .control-button { + cursor: pointer; + color: var(--blu-04); + transition: color .3s; + height: 20px; + opacity: 0; + &.delete{ + height: 24px; + width: 24px; + background: var(--base-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + position: absolute; + em { + font-size: 1.15em; + color: var(--blu); + transition: color .3s; + } + } + } + } + + + +} +// --- PREVIEW SECTION: end --- + + +.button-reply-add { + float: right; + user-select: none; + box-sizing: border-box; + outline: none; + border: 1px dashed var(--base-color); + border-radius: var(--button-border-radius-base); + color: var(--base-color); + cursor: pointer; + font-size: 0.7em; + font-weight: 400; + line-height: var(--button-height-base); + // margin: 0px 5px 0; + order: 1; + padding: 0 10px; + transition: all .3s; + min-width: 100px; + text-align: center; + width: fit-content; + // margin-right: 10px; +} + +.button-controls { + justify-content: space-between; + display: inline-flex; + // width: 28px; + height: 24px; + position: absolute; + left: 0; + // top: -5%; + top: 0; + opacity: 0; + transition: opacity 0.3s ease-in-out; + .buttonsToMove{ + display: inline-flex; + } + .control-button { + cursor: pointer; + background: var(--blu-light-02); + color: var(--blu); + transition: color .3s; + height: 24px; + width: 24px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 2px; + em { + font-size: 1.15em; + color: var(--blu); + transition: color .3s; + } + } + .control-button:hover{ + color: var(--color-white-hex); + box-shadow: 0 2px 6px 0 rgb(255 255 255 / 15%); + em { + opacity: 0.8; + } + &.delete{ + em { + color: var(--color-red-hex); + } + } + } +} + +.action-button-controls { + top: -12px; + opacity: 0; + .control-button:not(.delete){ + cursor: grab; + } +} + +//////////////////////////// +//----DRAG_DROP: start ---- +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + // box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + // 0 8px 10px 1px rgba(0, 0, 0, 0.14), + // 0 3px 14px 2px rgba(0, 0, 0, 0.12); + + &.single-button{ + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + justify-content: center; + border-top: 1px solid var(--border-color); + box-sizing: border-box; + cursor: pointer; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + font-weight: 600; + // height: 45px; + // padding: 0 10px; + -webkit-transition: all .3s; + transition: all .3s; + width: 100%; + position: relative; + + &:after { + content: ""; + position: absolute; + width: 0; + height: 0; + top: 50%; + left: 50%; + transform-style: flat; + transform: translate3d(-50%,-50%,0); + background: rgba(white,.2); + border-radius: 100%; + transition: width .5s ease, height .5s ease; + } + + &:hover{ + .button-controls{ + opacity: 1; + } + } + + } +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.draggable-box:last-child { + border: none; +} + +.draggable-list.cdk-drop-list-dragging .draggable-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +//----DRAG_DROP: end ---- +//////////////////////////// + +//////////////////////////// +/** TEXT AREA: start **/ +cds-textarea#title ::ng-deep, +cds-textarea#description ::ng-deep { + + .text-editor{ + display: flex; + } + + mat-form-field.mat-focused, + mat-form-field:hover { + textarea { + border-bottom: 1px solid var(--base-color) !important; + border-top: 1px solid var(--base-color) !important; + // outline: 0px solid rgb(242 205 111) !important; + transition: border 0.3s; + + } + } + + textarea { + border-left: 0px solid white !important; + border-right: 0px solid white !important; + border-bottom: 1px solid white!important; + border-top: 1px solid white!important; + border-radius: 0px; + resize: none !important; + padding: 5px 20px !important; + min-height: 25px !important; + line-height: 20px !important; + font-size: 0.9em !important; + + } +} + +cds-textarea#title ::ng-deep{ + textarea { + font-weight: 600; + } +} + +cds-textarea#description.noButtons ::ng-deep{ + textarea { + border-radius: 0px 0px var(--button-border-radius-base) var(--button-border-radius-base); + } +} + + +::ng-deep .cdk-drag-preview { + + #title{ + textarea { + font-weight: 600; + } + } + + cds-image-upload { + div.dropUploadImage{ + min-height: unset !important; + } + div.image-wrp{ + height: var(--cardImageHeight); + img{ + height: 100% !important; + width: 100% !important; + -o-object-fit: cover; + object-fit: cover; + } + } + + } +} + +.text-editable-div { + display: block; + margin-left: 30px; + margin-right: 30px; +} + +.action-reply-gallery .buttons-json-response { + width: 100%; + margin-bottom: -24px; + padding: 20px var(--input-base-margin); +} + +.json-text .text-editable-div{ + padding-top: 40px; +} + +.json-text .button-controls{ + padding-top: 40px; +} + + + +.image-from-url { + margin: 0px 10px 10px; + border: 2px dashed var(--blu-light-02); + border-radius: 6px; + padding: 2px 10px 10px; + text-align: center; +} + +.image-from-url ::ng-deep .image-url-textarea { + .liquidjs-menu { + display: none; + } + .box-textarea textarea { + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--blu-light-02); + outline: none; + overflow-x: hidden; + overflow-y: hidden; + color: var(--gray); + font-size: 13px; + line-height: 26px; + resize: none; + padding: 10px; + padding-top: 0px; + padding-bottom: 0px; + margin: 0px; + height: 26px; + min-height: 26px; + box-shadow: none; + width: 100%; + } +} + +.image-from-url ::ng-deep .image-url-textarea .box-textarea textarea { + white-space: nowrap; + overflow-x: hidden; + overflow-y: hidden; + resize: none; +} + +.image-from-url ::ng-deep .image-url-textarea .box-textarea textarea:focus { + border: 1px solid var(--gray-light-02)!important; + transition: border 0.3s; +} + +.image-load-or { + color: var(--blu-light-02); + font-size: 10px; + line-height: 12px; +} + + + +.buttons-json-response { + display: block; + position: relative; + width: max-content; + height: 36px; + margin-bottom: -20px; + &.json-shown { + width:fit-content; + z-index: 1; + } + .text-condition { + position: relative; + display: flex; + ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { + font-size: 12px; + display:block!important; + color: var(--blu); + } + ::ng-deep .ng-select .ng-select-container .ng-value-container { + // justify-content: flex-end; + margin-right: 10px; + font-weight: 500; + } + ::ng-deep .ng-select .ng-select-container { + // justify-content: flex-end; + border: 0px solid var(--blu-light-02); + box-shadow: none; + } + ::ng-deep .ng-select .ng-select-container:hover { + box-shadow: none; + } + ::ng-deep .ng-value .ng-star-inserted { + display:none!important; + } + ::ng-deep .ng-select .ng-select-container .ng-clear-wrapper { + display:none!important; + } + ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option span.label-select { + font-size: 12px!important; + } + ::ng-deep .ng-dropdown-panel .form-control-select .ng-star-inserted .ng-select-bottom { + border: none; + } + ::ng-deep .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value { + display:none!important; + } + } + .button-reply-add.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; + + &:hover { + background: var(--color-white-hex); + border-color: var(--border-color); + } + } +} + + +// .image-from-url ::ng-deep .mat-form-field-underline, +// .image-from-url ::ng-deep .mat-form-field-wrapper, +// .image-from-url ::ng-deep .mat-form-field-flex { +// display: none !important; +// } +/** TEXT AREA: end **/ +//////////////////////////// + +// Adatta la larghezza della select cds-select.text-condition al contenuto più largo +:host ::ng-deep cds-select.text-condition, +:host ::ng-deep cds-select.text-condition .ng-select-container { + min-width: max-content; + width: auto; + box-sizing: border-box; +} + + + + + + + +/* Contenitore principale con frecce fisse */ +.gallery-container { + position: relative; + width: 100%; + padding: 0 50px; +} + +/* Contenuto scrollabile interno */ +.gallery-replies { + display: flex; + overflow: hidden; + gap: 10px; + width: 100%; + padding: 10px 0; + scrollbar-width: thin; + scrollbar-color: var(--border-color) transparent; +} + +/* Frecce di navigazione fisse */ +.gallery-nav-arrow { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 40px; + height: 40px; + background: var(--base-color); + border: 1px solid var(--border-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + z-index: 10; + opacity: 0; + transition: all 0.3s ease; + .material-icons { + font-size: 20px; + color: var(--border-color); + transition: color 0.3s ease; + } + &:hover .material-icons { + color: white; + } +} + +.gallery-nav-arrow:hover { + color: white; + border-color: var(--base-color); +} + +.gallery-nav-left { + left: 0; +} + +.gallery-nav-right { + right: 0; +} + +/* Mostra le frecce al passaggio del mouse sul container */ +.gallery-container:hover .gallery-nav-arrow { + opacity: 1; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.ts new file mode 100644 index 000000000..ecb2fdf37 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.ts @@ -0,0 +1,651 @@ +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, AfterViewInit, OnDestroy, HostListener } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ConnectorService } from '../../../../../../../services/connector.service'; +import { IntentService } from '../../../../../../../services/intent.service'; +import { TEXT_CHARS_LIMIT, TYPE_BUTTON, TYPE_URL, generateShortUID } from '../../../../../../../utils'; +import { Button, Expression, GalleryElement, Message, Wait, Metadata, MessageAttributes } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { TYPE_ACTION } from 'src/app/chatbot-design-studio/utils-actions'; +import { LIST_JSON_MODEL_GALLERY } from 'src/app/chatbot-design-studio/utils-json-gallery'; + +@Component({ + selector: 'cds-action-reply-gallery-new', + templateUrl: './cds-action-reply-gallery-new.component.html', + styleUrls: ['./cds-action-reply-gallery-new.component.scss'] +}) +export class CdsActionReplyGalleryNewComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild('galleryContainer', { static: false }) scrollContainer: ElementRef; + + @Output() updateAndSaveAction = new EventEmitter(); + @Output() changeActionReply = new EventEmitter(); + @Output() deleteActionReply = new EventEmitter(); + @Output() moveUpResponse = new EventEmitter(); + @Output() moveDownResponse = new EventEmitter(); + @Output() openButtonPanel = new EventEmitter(); + + @Input() idAction: string; + @Input() response: Message; + @Input() wait: Wait; + @Input() index: number; + @Input() previewMode: boolean = true; + @Input() limitCharsText: number = TEXT_CHARS_LIMIT; + + // Connector // + idIntent: string; + connector: any; + private subscriptionChangedConnector: Subscription; + // Delay // + delayTime: number; + // Filter // + canShowFilter: boolean = true; + filterConditionExist: boolean = false; + booleanOperators=[ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},] + typeActions = TYPE_ACTION; + gallery: GalleryElement[]; + // Textarea // + activateEL: { [key: number]: {title: boolean, description: boolean} } = {}; + // Buttons // + buttons: Array + +
+ +
+ +
+ +
+ + + + +
+ + + + +
+ +
+ +
+ +
+ + + + + + + + + + + +
+ +
+ + {{'CDSCanvas.AddButton' | translate }} +
+
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss new file mode 100644 index 000000000..2fa3d6fef --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss @@ -0,0 +1,257 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --base-margin: #{var(--input-base-margin)}; +} + +.previewMode{ + &.image-editor-wrapper{ + + .response-image-uploader-wrapper{ + margin: 5px auto; + max-width: calc(100% - 5px); + + img{ + width: 100%; + border-radius: 8px; + } + + + &.no-image{ + display: flex; + gap: 10px; + align-items: center; + background: none; + + .image{ + width: 40px; + height: 40px; + // border-radius: 8px; + // box-shadow: rgba(0, 0, 0, 0.12) 0px -1px 0px 0px inset; + display: flex; + align-items: center; + justify-content: center; + + img { + max-height: 90%; + max-width: 90%; + border-radius: inherit; + } + } + + .text{ + overflow-x: clip; + white-space: nowrap; + text-overflow: ellipsis; + font-size: .8em; + color: rgb(141, 162, 181) + } + } + } + + cds-image-upload ::ng-deep { + .image-wrp:hover .control-button{ + opacity: 0; + } + } + + + } + + &.buttons-response{ + padding: 0px 0px 0px 0px; + margin: 0; + flex-direction: column; + flex-wrap: nowrap; + align-items: center; + .button-reply-add{ + color: var(--blu-light-02); + border-color: var(--blu-light-02); + } + } + +} + +.image-panel { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + border-radius: 8px; + margin: 0px; + padding: 0; + &:hover{ + background-color: #006cffc9; + transition: background-color 0.3s ease-in; + .image-response { + display: inline-block; + } + } +} +.bck-image{ + background-color: #006cffc9; + width: 100%; + height: 100%; + background-repeat: no-repeat; + background-size: cover; + background-position: center; +} + + + + + +.response-image-uploader-overlay { + background: #f0f4f7; +} + +.response-image-uploader label { + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; +} +.response-image-uploader label input { + display: none; +} + + + +/** response-image-uploader-wrapper **/ +.response-image-uploader-wrapper { + position: relative; + display: block; + border-radius: 8px; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + // margin-top: 10px; + margin-bottom: 10px; + padding: 0px; + background: rgba(255, 255, 255, 0.383); + overflow: visible; + // max-width: calc(100% - 66px); + width: auto; + height: auto; + .image-upload { + border-radius: 6px; + display: block; + overflow: hidden; + } + .control-button { + &.delete { + color: var(--blu); + position: absolute; + top: 0px; + right: 0px; + margin-right: 0px; + opacity: 0; + cursor: pointer; + transition: all .3s ease-in-out; + } + } + &:hover{ + .control-button { + &.delete { + margin-right: -24px; + opacity: 1; + } + } + } +} + + + + +/** box-textarea **/ +cds-textarea.text-editable-div ::ng-deep{ + display: block; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + // width: calc(100% - 66px); + textarea { + line-height: 20px !important; + width: calc(100% - 20px) !important; + font-size: 0.9em !important; + } +} + +.image-type-toggle, +.cds-toggle-group { + display: flex; + flex-direction: row; + gap: 4px; + margin: 0; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + justify-content: center; + align-items: center; + background: var(--blu-light-01); + border-radius: 8px; + padding: 3px; + box-shadow: none; + border: 0px solid var(--blu-light-02); + width: calc(100% - 2 * var(--base-margin)); + min-width: 0; +} + +.cds-toggle-btn { + flex: 1 1 0%; + width: 50%; + background: var(--blu-light-01); + color: var(--blu); + border: 0px solid var(--blu-light-02); + border-radius: 8px; + font-family: var(--font-family-poppins); + font-size: 12px; + font-weight: 400; + padding: 6px 0; + height: 26px; + min-width: 0; + min-height: 26px; + cursor: pointer; + outline: none; + box-shadow: none; + letter-spacing: 0.01em; + position: relative; + display: flex; + align-items: center; + justify-content: center; + z-index: 1; +} + +.cds-toggle-btn.selected, +.cds-toggle-btn:active { + background: #fff; + color: var(--blu); + font-weight: 500; + z-index: 2; + box-shadow: 0 1px 4px 0 rgba(80,100,147,0.04); + border: 0px solid var(--blu-light-02); +} + +.cds-toggle-btn:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.cds-toggle-btn:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.cds-toggle-btn:hover:not(.selected) { + color: var(--blu); +} + +.cds-toggle-label { + font-family: var(--font-family-poppins); + font-size: 1em; + font-weight: 400; + letter-spacing: 0.01em; + user-select: none; + text-align: center; + width: 100%; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.ts new file mode 100644 index 000000000..638c2bb14 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.ts @@ -0,0 +1,326 @@ +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Button, Expression, MessageAttributes, Message, Wait, Metadata } from 'src/app/models/action-model'; +import { TYPE_BUTTON } from '../../../../../../../utils'; +import { ConnectorService } from '../../../../../../../services/connector.service'; +import { IntentService } from '../../../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { Subscription } from 'rxjs/internal/Subscription'; + +@Component({ + selector: 'cds-action-reply-image-new', + templateUrl: './cds-action-reply-image-new.component.html', + styleUrls: ['./cds-action-reply-image-new.component.scss'] +}) +export class CdsActionReplyImageNewComponent implements OnInit { + + @Output() updateAndSaveAction = new EventEmitter(); + @Output() changeActionReply = new EventEmitter(); + @Output() deleteActionReply = new EventEmitter(); + @Output() moveUpResponse = new EventEmitter(); + @Output() moveDownResponse = new EventEmitter(); + @Output() createNewButton = new EventEmitter(); + @Output() deleteButton = new EventEmitter(); + @Output() openButtonPanel = new EventEmitter(); + @Output() changeJsonButtons = new EventEmitter(); + + @Input() idAction: string; + @Input() response: Message; + @Input() wait: Wait; + @Input() index: number; + @Input() previewMode: boolean = true + + idIntent: string; + // Connector // + connector: any; + private subscriptionChangedConnector: Subscription; + + // Delay // + delayTime: number; + + //Filter // + canShowFilter: boolean = true; + filterConditionExist: boolean = false; + booleanOperators=[ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},] + + // Buttons // + buttons: Array; + TYPE_BUTTON = TYPE_BUTTON; + jsonBody: string; + + imageType: 'upload' | 'link' = 'upload'; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly connectorService: ConnectorService, + private readonly intentService: IntentService + ) { } + + + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.log('CdsActionReplyImageComponent isChangedConnector-->', connector); + this.connector = connector; + this.updateConnector(); + }); + this.initialize(); + this.setInitialImageType(); + } + + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // PRIVATE FUNCTIONS // + + private initialize(){ + this.jsonBody = ''; + if(this.response?.attributes?.attachment?.json_buttons){ + this.jsonBody = this.response?.attributes?.attachment?.json_buttons; + } + this.delayTime = (this.wait && this.wait.time || this.wait.time === 0)? (this.wait.time/1000) : 500/1000; + this.checkButtons(); + this.buttons = this.intentService.patchButtons(this.buttons, this.idAction); + this.idIntent = this.idAction.split('/')[0]; + + if(this.response && this.response._tdJSONCondition && this.response._tdJSONCondition.conditions.length > 0){ + this.filterConditionExist = true + } + } + + + private checkButtons(){ + if(!this.response.attributes || !this.response.attributes.attachment){ + this.response.attributes = new MessageAttributes(); + } + if(this.response?.attributes?.attachment?.buttons){ + this.buttons = this.response?.attributes?.attachment?.buttons; + } else { + this.buttons = []; + } + } + + + private updateConnector(){ + try { + const array = this.connector.fromId.split("/"); + const idButton = array[array.length - 1]; + const idConnector = this.idAction+'/'+idButton; + this.logger.log(' updateConnector :: connector.fromId - idConnector: ', this.connector.fromId, idConnector); + const buttonChanged = this.buttons.find(obj => obj.uid === idButton); + if(idConnector === this.connector.fromId && buttonChanged){ + if(this.connector.deleted){ + // DELETE + buttonChanged.__isConnected = false; + buttonChanged.__idConnector = this.connector.fromId; + buttonChanged.__idConnection = null; + buttonChanged.action = ''; + buttonChanged.type = TYPE_BUTTON.TEXT; + this.updateAndSaveAction.emit(); + } else { + buttonChanged.__idConnector = this.connector.fromId; + buttonChanged.action = buttonChanged.action? buttonChanged.action : '#' + this.connector.toId; + buttonChanged.type = TYPE_BUTTON.ACTION; + if(!buttonChanged.__isConnected){ + buttonChanged.__isConnected = true; + buttonChanged.__idConnection = this.connector.fromId+"/"+this.connector.toId; + this.updateAndSaveAction.emit(); + } + } + } + } catch (error) { + this.logger.error('error: ', error); + } + } + + + + // EVENT FUNCTIONS // + + /** changeJsonButtons */ + onChangeJsonButtons(json:any){ + this.logger.log('[ACTION REPLY TEXT] onChangeJsonButtons', json); + if(json && json.trim() !== ''){ + this.response.attributes.attachment.json_buttons = json; + } else { + this.response.attributes.attachment.json_buttons = null; + } + this.jsonBody = json; + this.changeJsonButtons.emit( this.response); + } + + /** onClickDelayTime */ + onClickDelayTime(opened: boolean){ + this.canShowFilter = !opened; + } + + /** onChangeDelayTime */ + onChangeDelayTime(value:number){ + this.delayTime = value; + this.wait.time = value*1000; + this.canShowFilter = true; + this.changeActionReply.emit(); + } + + /** onChangeExpression */ + onChangeExpression(expression: Expression){ + this.response._tdJSONCondition = expression; + this.filterConditionExist = expression && expression.conditions.length > 0? true : false; + this.changeActionReply.emit(); + } + + /**onChangeMetadata */ + onChangeMetadata(metadata: Metadata){ + this.response.metadata = metadata; + this.changeActionReply.emit(); + } + + /** onDeleteActionReply */ + onDeleteActionReply(){ + this.deleteActionReply.emit(this.index); + } + + /** onMoveUpResponse */ + onMoveUpResponse(){ + this.moveUpResponse.emit(this.index); + } + + /** onMoveDownResponse */ + onMoveDownResponse(){ + this.moveDownResponse.emit(this.index); + } + + /** onChangeTextarea */ + onChangeTextarea(text:string) { + if(!this.previewMode){ + this.response.text = text; + } + } + + /** onOpenButtonPanel */ + onOpenButtonPanel(button){ + this.openButtonPanel.emit(button); + } + + /** onButtonControl */ + onButtonControl(action: string, index: number ){ + switch(action){ + + case 'delete': /** onDeleteButton */ + this.deleteButton.emit({index: index, buttons: this.buttons}); + break; + case 'moveLeft': + break; + case 'moveRight': + break; + case 'new': /** onCreateNewButton */ + this.createNewButton.emit(this.index); + break; + } + } + + /** dropButtons */ + dropButtons(event: CdkDragDrop) { + moveItemInArray(this.buttons, event.previousIndex, event.currentIndex); + this.connectorService.updateConnector(this.idIntent); + this.changeActionReply.emit(); + } + + /** onBlur */ + onBlur(event){ + this.changeActionReply.emit(); + } + + // EVENT FUNCTIONS // + /** */ + + + + + + + + + + + + /** */ + onCloseImagePanel(event){ + //if(event.url){ + //this.imagePath = event.url; + this.response.metadata.src = event.url; + //} + //if(event.width){ + //this.imageWidth = event.width; + this.response.metadata.width = event.width; + //} + //if(event.height){ + //this.imageHeight = event.height; + this.response.metadata.height = event.height; + //} + // this.logger.log('onCloseImagePanel:: ', event); + } + + /** */ + onDeletedMetadata(event){ + this.response.metadata.src = null; + this.changeActionReply.emit(); + } + + + + + // EVENT FUNCTIONS // + /** */ + onMoveLeftButton(fromIndex){ + let toIndex = fromIndex-1; + if(toIndex<0){ + toIndex = 0; + } + this.arraymove(this.buttons, fromIndex, toIndex); + } + + onMoveRightButton(fromIndex){ + let toIndex = fromIndex+1; + if(toIndex>this.buttons.length-1){ + toIndex = this.buttons.length-1; + } + this.arraymove(this.buttons, fromIndex, toIndex); + } + + private arraymove(buttons, fromIndex, toIndex) { + var element = buttons[fromIndex]; + buttons.splice(fromIndex, 1); + buttons.splice(toIndex, 0, element); + } + + setInitialImageType() { + if (this.response?.metadata?.src) { + // Semplice check: se inizia con http o https o contiene {{...}} consideriamo link + if (this.response.metadata.src.startsWith('http') || this.response.metadata.src.match(/\{\{.*\}\}/)) { + this.imageType = 'link'; + } else { + this.imageType = 'upload'; + } + } else { + this.imageType = 'upload'; + } + } + + onSelectImageType(type: 'upload' | 'link') { + this.imageType = type; + // Se cambio tipo, resetto i dati dell'immagine + if (type === 'upload') { + //this.response.metadata = { name: '', src: '', downloadURL: '' }; + } else if (type === 'link') { + //this.response.metadata = { name: '', src: '', downloadURL: '' }; + } + } +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.spec.ts new file mode 100644 index 000000000..ceab75312 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ImageResponseComponent } from './image-response.component'; + +describe('ImageResponseComponent', () => { + let component: ImageResponseComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ImageResponseComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ImageResponseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.html new file mode 100644 index 000000000..80050fcfc --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.html @@ -0,0 +1,52 @@ + +
+
+ + {{'CDSCanvas.JsonButtons' | translate }} +
+
+ + +
+ + +
+ + +
+ + + +
+
+ delete +
+
+
+ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss new file mode 100644 index 000000000..f770bb9b9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss @@ -0,0 +1,104 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +cds-textarea.text-editable-div { + display: block; + margin-left: 30px; + margin-right: 30px; +} + +::ng-deep .box-textarea { + textarea { + // line-height: 20px!important; + font-size: 0.9em!important; + // max-height: none!important; + } +} + + + + +.json-text { + position: relative; + padding: 0; + margin-top: 20px; + .button-controls { + top:20px; + } +} + +.field-description { + display: block; + text-align: right; + margin-top: 15px; + margin-left: 30px; + margin-right: 30px; +} + +.buttons-json-response { + display: block; + position: relative; + width: 100%; + height: 36px; + margin-bottom: -20px; + &.json-shown { + width:fit-content; + z-index: 1; + } + .text-condition { + position: relative; + display: flex; + ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { + font-size: 12px; + display:block!important; + color: var(--blu); + } + ::ng-deep .ng-select .ng-select-container .ng-value-container { + // justify-content: flex-end; + margin-right: 10px; + font-weight: 500; + } + ::ng-deep .ng-select .ng-select-container { + // justify-content: flex-end; + border: 0px solid var(--blu-light-02); + box-shadow: none; + } + ::ng-deep .ng-select .ng-select-container:hover { + box-shadow: none; + } + ::ng-deep .ng-value .ng-star-inserted { + display:none!important; + } + ::ng-deep .ng-select .ng-select-container .ng-clear-wrapper { + display:none!important; + } + ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option span.label-select { + font-size: 12px!important; + } + ::ng-deep .ng-dropdown-panel .form-control-select .ng-star-inserted .ng-select-bottom { + border: none; + } + ::ng-deep .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value { + display:none!important; + } + } + + .button-reply-add.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; + + &:hover { + background: var(--color-white-hex); + border-color: var(--border-color); + } + } + // ::ng-deep .select-item-wrp { + // justify-content: flex-end; + // } + + // ::ng-deep .ng-dropdown-panel .ng-dropdown-panel-items .ng-option span.label-select { + // font-size: 12px; + // } + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.ts new file mode 100644 index 000000000..c116bd6f3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.ts @@ -0,0 +1,108 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +import { LIST_JSON_MODEL_REPLY_V1, LIST_JSON_MODEL_REPLY_V2, JSON_MODEL_PLACEHOLDER } from 'src/app/chatbot-design-studio/utils-jsonbuttons'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { TYPE_ACTION } from 'src/app/chatbot-design-studio/utils-actions'; +import { DOCS_LINK } from 'src/app/chatbot-design-studio/utils'; + +@Component({ + selector: 'cds-action-reply-jsonbuttons-new', + templateUrl: './cds-action-reply-jsonbuttons-new.component.html', + styleUrls: ['./cds-action-reply-jsonbuttons-new.component.scss'] +}) +export class CdsActionReplyJsonbuttonsNewComponent implements OnInit { + @Input() jsonBody: string; + @Output() changeJsonButtons = new EventEmitter(); + + showJsonButton: boolean = false; + showJsonBody: boolean = false; + jsonPlaceholder: string = JSON_MODEL_PLACEHOLDER; + listType: any = {}; + link: any; + // exampleSelected: null; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly intentService: IntentService, + // private cdr: ChangeDetectorRef + ) { } + + ngOnInit(): void { + this.initialize(); + } + + ngAfterViewInit (): void { + // // this.cdr.detectChanges(); + } + + initialize(){ + this.listType = LIST_JSON_MODEL_REPLY_V1; + if(this.intentService.selectedAction._tdActionType !== TYPE_ACTION.REPLY){ + this.listType = LIST_JSON_MODEL_REPLY_V2; + }; + if(this.jsonBody && this.jsonBody.trim() !== ''){ + this.showJsonBody = true; + this.showJsonButton = true; + } else { + this.jsonBody = ''; + this.showJsonBody = false; + this.showJsonButton = false; + } + this.link = DOCS_LINK.JSON_BUTTONS; + } + + + // ACTIONS // + + /** onDeleteJsonButtons */ + onChangeJsonButtonsType(event){ + this.jsonBody = event['value']?event['value']:''; + this.showJsonBody = true; + this.showJsonButton = false; + this.changeJsonButtons.emit(this.jsonBody); + } + + /** onDeleteJsonButtons */ + onResetJsonButtonsType(event){ + this.logger.log('[ACTION REPLY jsonbuttons] onResetJsonButtonsType ', this.jsonBody); + this.changeJsonButtons.emit(this.jsonBody); + } + + /** onClickJsonButtons */ + onClickJsonButtons(){ + if(!this.showJsonBody){ + this.showJsonBody = true; + this.showJsonButton = true; + } + } + + /** onDeleteJsonButtons */ + onDeleteJsonButtons(){ + this.jsonBody = ''; + this.showJsonBody = false; + this.showJsonButton = false; + this.changeJsonButtons.emit(); + } + + /** onChangeJsonTextarea */ + onChangeJsonTextarea(text:string) { + if(!text || text.trim() === ''){ + this.showJsonButton = true; + } else { + this.jsonBody = text; + this.showJsonButton = false; + } + // // this.changeJsonButtons.emit(text); + } + + /** onBlurJsonTextarea */ + onBlurJsonTextarea(event:any){ + this.logger.log('[ACTION REPLY jsonbuttons] onBlurJsonTextarea ', event); + const json = event.target?.value; + this.changeJsonButtons.emit(json); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.spec.ts new file mode 100644 index 000000000..8b2480d63 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyJsonbuttonsComponent } from './cds-action-reply-jsonbuttons.component'; + +describe('CdsActionReplyJsonbuttonsComponent', () => { + let component: CdsActionReplyJsonbuttonsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyJsonbuttonsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyJsonbuttonsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.html new file mode 100644 index 000000000..f30616180 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.html @@ -0,0 +1,93 @@ +
+ +
+ drag_indicator +
+ +
+
+ delete +
+
+ expand_less +
+
+ expand_more +
+
+ + +
+ + +
+ +
+ filter_alt + {{'CDSCanvas.Filter' | translate }} +
+
+ + +
+
+ +
+ +
+
+ {{ 'url' | translate }}: +
{{metadata.src}}
+
{{ 'CDSCanvas.ClickToAddUrl' | translate }}
+
+
+ {{ 'OpenIn' | translate }}: + {{ 'SameWidgetWindow' | translate }} + {{ 'NewTabWindow' | translate }} +
+
+
+ + +
+ +
+ +
+ {{ 'url' | translate }}: +
+ + +
+
+ +
+ {{ 'OpenIn' | translate }}: + + {{ 'SameWidgetWindow' | translate }} + {{ 'NewTabWindow' | translate }} + +
+ + + + +
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss new file mode 100644 index 000000000..09cd9854c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss @@ -0,0 +1,113 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +:host{ + --base-margin: #{var(--input-base-margin)}; +} + +.previewMode{ + &.text-editor-wrapper{ + // padding: 0; + margin: 0px; + + .control-label{ + margin: 0px 10px; + font-size: 0.8em; + + } + + mat-button-toggle-group{ + margin: 0px 10px; + } + + mat-button-toggle ::ng-deep { + span{ + font-size: 0.7em; + line-height: 25px; + } + } + + .url-wrp{ + flex-direction: row; + align-items: center; + margin: 0px 10px; + span.control-label:first-child{ + width: 50px; + margin: 0; + text-align: end; + } + } + + } + + +} + + + + +.url-wrp{ + display: flex; + flex-direction: column; + margin: 5px 0 0 0; + align-items: flex-start; + gap: 5px; + + .form-check{ + display: flex; + align-items: center; + justify-content: center; + gap: 5px; + } +} +.toogle{ + margin-top: 10px; + margin-bottom: 10px; +} + +.control-label{ + font-family: var(--font-family-poppins); + color: var(--blu); + text-align: left; + line-height: 20px; + font-size: 14px; + box-sizing: border-box; + font-weight: 300; + + margin-left: 30px; + // margin-top: 10px; + // margin-bottom: 10px; +} + +cds-textarea.text-editable-div ::ng-deep{ + display: block; + margin-left: var(--base-margin); + margin-right: var(--base-margin); + // width: calc(100% - 66px); + textarea { + line-height: 20px !important; + width: calc(100% - 20px) !important; + font-size: 0.9em !important; + } +} + +mat-button-toggle ::ng-deep{ + .mat-button-toggle-button{ + span { + line-height: 36px; + } + } +} + +mat-button-toggle-group { + border: 1px solid var(--gray-light-02); + margin-left: var(--base-margin); + border-radius: var(--input-border-radius-base); +} +mat-button-toggle.mat-button-toggle-checked{ + background-color: var(--blu); + color: var(--blu-light-02); +} + +mat-button-toggle.mat-button-toggle{ + color: var(--blu-light-02); +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.ts new file mode 100644 index 000000000..86b5791d9 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.ts @@ -0,0 +1,115 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { TYPE_ACTION } from '../../../../../../../utils-actions'; +import { Expression, Message, Wait, Metadata } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-reply-redirect-new', + templateUrl: './cds-action-reply-redirect-new.component.html', + styleUrls: ['./cds-action-reply-redirect-new.component.scss'] +}) +export class CdsActionReplyRedirectNewComponent implements OnInit { + + @Output() changeActionReply = new EventEmitter(); + @Output() deleteActionReply = new EventEmitter(); + @Output() moveUpResponse = new EventEmitter(); + @Output() moveDownResponse = new EventEmitter(); + + @Input() idAction: string; + @Input() response: Message; + @Input() wait: Wait; + @Input() index: number; + @Input() previewMode: boolean = true; + + + // Delay // + delayTime: number; + // Filter // + canShowFilter: boolean = true; + filterConditionExist: boolean = false; + booleanOperators=[ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},] + typeActions = TYPE_ACTION; + metadata: Metadata; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + + ngOnInit(): void { + this.initialize(); + } + + private initialize(){ + this.delayTime = (this.wait?.time && this.wait?.time !== 0)? (this.wait.time/1000) : 500/1000; + try { + this.metadata = this.response.metadata; + + if(this.response?._tdJSONCondition && this.response._tdJSONCondition.conditions.length > 0){ + this.filterConditionExist = true + } + + } catch (error) { + this.logger.log("error ", error); + } + } + + + + // EVENT FUNCTIONS // + + /** onClickDelayTime */ + onClickDelayTime(opened: boolean){ + this.canShowFilter = !opened; + } + + /** onChangeDelayTime */ + onChangeDelayTime(value:number){ + this.delayTime = value; + this.wait.time = value*1000; + this.canShowFilter = true; + this.changeActionReply.emit(); + } + + /** onChangeExpression */ + onChangeExpression(expression: Expression){ + this.response._tdJSONCondition = expression; + this.filterConditionExist = expression && expression.conditions.length > 0? true : false; + this.changeActionReply.emit(); + } + + /** onDeleteActionReply */ + onDeleteActionReply(){ + this.deleteActionReply.emit(this.index); + } + + /** onMoveUpResponse */ + onMoveUpResponse(){ + this.moveUpResponse.emit(this.index); + } + + /** onMoveDownResponse */ + onMoveDownResponse(){ + this.moveDownResponse.emit(this.index); + } + + /** onChangeTextarea */ + onChangeTextarea(text:string) { + if(!this.previewMode){ + this.metadata.src = text; + // this.changeActionReply.emit(); + } + } + + onBlur(event){ + this.changeActionReply.emit(); + } + + /** onButtonToogleChange */ + onButtonToogleChange(event){ + this.metadata.target = event.value; + this.changeActionReply.emit(); + } + +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.spec.ts new file mode 100644 index 000000000..dc484b009 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyRedirectComponent } from './cds-action-reply-redirect.component'; + +describe('CdsActionReplyRedirectComponent', () => { + let component: CdsActionReplyRedirectComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyRedirectComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyRedirectComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.html new file mode 100644 index 000000000..cd823a2e4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.html @@ -0,0 +1,131 @@ + +
+ + + + + +
+ +
+ +
+ + + + + +
+ +
+ +
+ +
+ + + + + +
+ +
+ + +
+ + + + +
+ +
+ +
+
+
+ +
+ +
+ + + + +
+
+ + + + +
+ +
+
+
+ +
+ +
+ + + +
+ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss new file mode 100644 index 000000000..c2445b34c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss @@ -0,0 +1,120 @@ +.previewMode{ + .set-attribute-label-and-value-wpr { + display: flex; + gap: 6px; + align-items: center; + justify-content: flex-end; + margin: 5px 15px; + } + .set-attribute-label { + font-size: 12px; + margin-bottom: 0; + font-weight: 400; + // background: #e8e6dd; + padding: 0px 3px; + height: inherit; + } + + .response-wrp{ + width: calc(100% - 150px); + margin: unset; + + &.expand{ + width: calc(100% - 80px); + } + } + .no-text{ + border-color: var(--empty-element-property); + height: 30px; + } + + .previewContent{ + padding: 5px 10px; + margin: 0px; + position: relative; + + + &[disabled=true]{ + cursor: not-allowed; + opacity: 0.6; + pointer-events: none; + } + } +} + +/* ./ Preview mode +/* ****************************** */ + + +.editor-utils { + position: relative; + margin: -20px 50px 0px 0px; + float: right; + .num-chars { + background: var(--blu-light-01); + flex-shrink: 0; + padding: 0px 8px; + border-radius: 10px; + font-size: 0.8em; + color: var(--blu); + float: right; + line-height: 24px; + font-weight: 700; + // width: 40px; + text-align: center; + &.error { + background: var(--color-red-hex); + color: var(--color-white-hex); + } + } + .text-editor-insert-attribute { + float: right; + } + .moji-picker { + float: right; + } +} +.setting-wrapper{ + display: grid; + grid-template-columns: repeat(2, 1fr); + padding: 0 var(--input-base-margin); + justify-content: space-between; + gap: 5px; + + // this will target the last flashcard but only if there are an odd number of cards + & > *:nth-child(odd):last-child { + grid-column: span 2; + } +} + +.connector-wrapper{ + display: flex; + flex-direction: column; + padding: 0 var(--input-base-margin); + justify-content: space-between; + gap: 5px; +} + + + + +/** box-textarea **/ +cds-textarea.text-editable-div ::ng-deep{ + display: block; + // width: calc(100% - 66px); + textarea { + line-height: 20px !important; + width: calc(100% - 20px) !important; + font-size: 0.9em !important; + } +} + + +cds-select#noinput-condition[disabled=true] ::ng-deep, +cds-select#nomatch-condition[disabled=true] ::ng-deep{ + cursor: not-allowed; + opacity: 0.6; + .ng-select{ + pointer-events: none; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.ts new file mode 100644 index 000000000..4cbb70c72 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.ts @@ -0,0 +1,274 @@ + +import { Component, OnInit, ViewChild, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { CdkTextareaAutosize } from '@angular/cdk/text-field'; + +import { Message, Wait, Button, MessageAttributes, Expression, Setting, ActionReplyV2 } from 'src/app/models/action-model'; +import { TYPE_BUTTON, TYPE_COMMAND, TYPE_UPDATE_ACTION, replaceItemInArrayForKey } from '../../../../../../../utils'; +import { IntentService } from '../../../../../../../services/intent.service'; +import { ConnectorService } from '../../../../../../../services/connector.service'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { secondsToDhms } from 'src/app/utils/util'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'cds-action-reply-settings-new', + templateUrl: './cds-action-reply-settings-new.component.html', + styleUrls: ['./cds-action-reply-settings-new.component.scss'] +}) +export class CdsActionReplySettingsNewComponent implements OnInit { + @ViewChild('autosize') autosize: CdkTextareaAutosize; + + @Output() updateAndSaveAction = new EventEmitter(); + @Output() changeActionReply = new EventEmitter(); + + @Input() idAction: string; + @Input() action: ActionReplyV2; + @Input() index: number; + @Input() previewMode: boolean = true; + @Input() handleActionChanges: Observable + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors // + idIntentSelected: string; + idConnectorNoMatch: string; + idConnectorNoInput: string; + idConnectionNoMatch: string; + idConnectionNoInput: string; + isConnectedNoMatch: boolean = false; + isConnectedNoInput: boolean = false; + isConnectorInputDisabled: boolean = false; + isConnectorMatchDisabled: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private connectorService: ConnectorService, + private intentService: IntentService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION REPLY SETTINGS] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION REPLY SETTINGS] isChangedConnector -->', connector); + let connectorId = this.idAction; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initializeConnector(); + + this.handleActionChanges.subscribe(()=> this.checkButtonsInCommands()) + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // ngOnChanges(changes: SimpleChanges): void { + // this.logger.log('CdsActionReplyTextComponent ngOnChanges:: ', this.response); + // } + + initializeConnector() { + this.idIntentSelected = this.idAction.split('/')[0]; + this.idConnectorNoInput = this.idAction + '/noInput'; + this.idConnectorNoMatch = this.idAction + '/noMatch'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + this.checkButtonsInCommands(); + } + + private updateConnector(){ + try { + const array = this.connector.fromId.split("/"); + const idButton = array[0] + '/' + array[array.length - 2]; + if(idButton === this.idAction){ + if(this.connector.deleted){ + if(array[array.length -1] === 'noInput'){ + this.action.noInputIntent = null; + this.isConnectedNoInput = false; + this.idConnectionNoInput = null; + } + if(array[array.length -1] === 'noMatch'){ + this.action.noMatchIntent = null; + this.isConnectedNoMatch = false; + this.idConnectionNoMatch = null; + } + if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + } else { + // TODO: verificare quale dei due connettori è stato aggiunto (controllare il valore della action corrispondente al true/false intent) + this.logger.debug('[ACTION REPLY SETTINGS] updateConnector', this.connector.toId, this.connector.fromId ,this.action, array[array.length-1]); + if(array[array.length -1] === 'noInput'){ + // this.action.trueIntent = '#'+this.connector.toId; + this.isConnectedNoInput = true; + this.idConnectionNoInput = this.connector.fromId+"/"+this.connector.toId; + this.action.noInputIntent = '#'+this.connector.toId; + if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + } + if(array[array.length -1] === 'noMatch'){ + // this.action.falseIntent = '#'+this.connector.toId; + this.isConnectedNoMatch = true; + this.idConnectionNoMatch = this.connector.fromId+"/"+this.connector.toId; + this.action.noMatchIntent = '#'+this.connector.toId; + if(this.connector.save)this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector}); + } + } + } + } catch (error) { + this.logger.error('[ACTION REPLY SETTINGS] updateConnector error: ', error); + } + } + + private checkConnectionStatus(){ + if(this.action.noInputIntent){ + this.isConnectedNoInput = true; + const posId = this.action.noInputIntent.indexOf("#"); + if (posId !== -1) { + const toId = this.action.noInputIntent.slice(posId+1); + this.idConnectionNoInput = this.idConnectorNoInput+"/"+toId; + } + } else { + this.isConnectedNoInput = false; + this.idConnectionNoInput = null; + } + if(this.action.noMatchIntent){ + this.isConnectedNoMatch = true; + const posId = this.action.noMatchIntent.indexOf("#"); + if (posId !== -1) { + const toId = this.action.noMatchIntent.slice(posId+1); + this.idConnectionNoMatch = this.idConnectorNoMatch+"/"+toId; + } + } else { + this.isConnectedNoMatch = false; + this.idConnectionNoMatch = null; + } + } + + + formatLabel(value: number): string { + + const d = secondsToDhms(value).getDays(); + const h = secondsToDhms(value).getHours(); + const m = secondsToDhms(value).getMinutes(); + + let number = value + let unit = 's' + if(d > 0){ + number = d; + unit = 'd' + } else if(h > 0){ + number = h; + unit = 'h' + }else if( m> 0){ + number = m; + unit = 'm' + } + return number + unit + // return `${value}`+ 's'; + } + + // PRIVATE FUNCTIONS // + private checkButtonsInCommands(){ + let commands = this.action.attributes.commands + if(commands && commands.length > 0){ + let messages = commands.filter(command => command.type === TYPE_COMMAND.MESSAGE) + messages.forEach(el => { + if(!el || !el.message || !el.message.attributes){ + this.isConnectorInputDisabled = true; + this.isConnectorMatchDisabled = true; + return; + } + if(el.message.attributes.attachment && el.message.attributes.attachment.buttons && el.message.attributes.attachment.buttons.length > 0){ + this.isConnectorInputDisabled = false; + this.isConnectorMatchDisabled = false; + return; + + }else{ + //CASE: no buttons in message element + this.isConnectorInputDisabled = true; + this.isConnectorMatchDisabled = true; + return; + } + }) + } + } + + // EVENT FUNCTIONS // + + /** onClickDelayTime */ + onClickDelayTime(opened: boolean){ + // this.canShowFilter = !opened; + } + + /** onChangeDelayTime */ + onChangeDelayTime(value:number){ + this.action.noInputTimeout = value*1000; + // this.canShowFilter = true; + this.changeActionReply.emit(); + } + + /** onChangeTextarea */ + onChangeTextarea(text:string, key: string) { + if(!this.previewMode){ + this.action[key] = text; + // this.changeActionReply.emit(); + } + } + + onBlur(event){ + this.logger.log('[ACTION REPLY SETTINGS] onBlur', event.target.value, this.action); + // if(event.target.value !== this.response.text){ + this.changeActionReply.emit(); + // } + } + + onSelectedAttribute(variableSelected: {name: string, value: string}){ + } + + checkForVariablesInsideText(text: string){ + text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g, 'g')).forEach(match => { + let createTag = '' + match + '' + text = text.replace('{' + match + '}',createTag) + }); + return text + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'noInputIntent' | 'noMatchIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'noInputIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorNoInput, toId: this.action.noInputIntent}); + break; + case 'noMatchIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorNoMatch, toId: this.action.noMatchIntent}); + break; + } + // this.changeActionReply.emit() + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'noInputIntent' | 'noMatchIntent') { + switch(type){ + case 'noInputIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorNoInput, toId: this.action.noInputIntent}); + break; + case 'noMatchIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorNoMatch, toId: this.action.noMatchIntent}); + break; + } + this.action[type]=null + // this.changeActionReply.emit() + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.spec.ts new file mode 100644 index 000000000..d14b9757a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplySettingsComponent } from './cds-action-reply-settings.component'; + +describe('CdsActionReplyTextComponent', () => { + let component: CdsActionReplySettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplySettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplySettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.html new file mode 100644 index 000000000..d96736773 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.html @@ -0,0 +1,112 @@ +
+ +
+ drag_indicator +
+ +
+
+ delete +
+
+ expand_less +
+
+ expand_more +
+
+ +
+ + +
+ +
+ filter_alt + {{'CDSCanvas.Filter' | translate }} +
+
+ + +
+
+ + + +
+
{{response.text}}
+
{{'CDSCanvas.ClickToAddText' | translate }}
+
+ + +
+ + +
+ + + + + + + +
+
+ + + + + + + + + + +
+ +
+ + {{'CDSCanvas.AddButton' | translate }} +
+ +
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss new file mode 100644 index 000000000..21bbfa7c7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss @@ -0,0 +1,62 @@ +@import "./src/assets/sass/cds/_variables.scss"; + + +.previewMode{ + &.buttons-response{ + padding: 0px 0px 0px 0px; + margin: 0; + flex-direction: column; + flex-wrap: nowrap; + align-items: center; + .button-reply-add { + color: var(--blu-light-02); + border-color: var(--blu-light-02); + } + } + +} + +/* ./ Preview mode +/* ****************************** */ + + +.editor-utils { + position: relative; + margin: -20px 50px 0px 0px; + float: right; + .num-chars { + background: var(--blu-light-01); + flex-shrink: 0; + padding: 0px 8px; + border-radius: 10px; + font-size: 0.8em; + color: var(--blu); + float: right; + line-height: 24px; + font-weight: 700; + text-align: center; + &.error { + background: var(--color-red-hex); + color: var(--color-white-hex); + } + } + .text-editor-insert-attribute { + float: right; + } + .moji-picker { + float: right; + } +} + + +/** box-textarea **/ +cds-textarea.text-editable-div ::ng-deep{ + display: block; + margin-left: 30px; + margin-right: 30px; + textarea { + line-height: 20px !important; + width: calc(100% - 20px) !important; + font-size: 0.9em !important; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.ts new file mode 100644 index 000000000..3be29a4d4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.ts @@ -0,0 +1,272 @@ + +import { Component, OnInit, ViewChild, Input, Output, EventEmitter, SimpleChanges, ChangeDetectorRef } from '@angular/core'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { CdkTextareaAutosize } from '@angular/cdk/text-field'; + +import { Message, Wait, Button, MessageAttributes, Expression } from 'src/app/models/action-model'; +import { TEXT_CHARS_LIMIT, TYPE_BUTTON, replaceItemInArrayForKey } from '../../../../../../../utils'; +import { IntentService } from '../../../../../../../services/intent.service'; +import { ConnectorService } from '../../../../../../../services/connector.service'; +import { Subscription } from 'rxjs/internal/Subscription'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-reply-text-new', + templateUrl: './cds-action-reply-text-new.component.html', + styleUrls: ['./cds-action-reply-text-new.component.scss'] +}) +export class CdsActionReplyTextNewComponent implements OnInit { + @ViewChild('autosize') autosize: CdkTextareaAutosize; + + @Output() updateAndSaveAction = new EventEmitter(); + @Output() changeActionReply = new EventEmitter(); + @Output() deleteActionReply = new EventEmitter(); + @Output() moveUpResponse = new EventEmitter(); + @Output() moveDownResponse = new EventEmitter(); + @Output() createNewButton = new EventEmitter(); + @Output() deleteButton = new EventEmitter(); + @Output() openButtonPanel = new EventEmitter(); + @Output() changeJsonButtons = new EventEmitter(); + + @Input() idAction: string; + @Input() response: Message; + @Input() wait: Wait; + @Input() index: number; + @Input() limitCharsText: number = TEXT_CHARS_LIMIT; + @Input() previewMode: boolean = true; + + // Connector // + idIntent: string; + connector: any; + private subscriptionChangedConnector: Subscription; + // Textarea // + // Delay // + delayTime: number = 0; + // Filter // + canShowFilter: boolean = true; + filterConditionExist: boolean = false; + booleanOperators = [ { type: 'AND', operator: 'AND'},{ type: 'OR', operator: 'OR'},]; + // Buttons // + TYPE_BUTTON = TYPE_BUTTON; + buttons: Array; + activeFocus: boolean = true; + jsonBody: string; + + private readonly logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private readonly connectorService: ConnectorService, + private readonly intentService: IntentService, + private cdr: ChangeDetectorRef + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.connector = connector; + this.updateConnector(); + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + // PRIVATE FUNCTIONS // + private initialize(){ + this.jsonBody = ''; + if(this.response?.attributes?.attachment?.json_buttons){ + this.jsonBody = this.response?.attributes?.attachment?.json_buttons; + } + if(this.index == 1 && (this.wait?.time == 500 || this.wait?.time == 0)) { + this.delayTime = 0 + } else if(this.wait?.time && this.wait.time > 0){ + this.delayTime = this.wait.time/1000; + } else { + this.delayTime = 500/1000; + } + // //this.delayTime = (this.wait?.time || this.wait.time === 0)? (this.wait.time/1000) : 500/1000; + this.checkButtons(); + this.buttons = this.intentService.patchButtons(this.buttons, this.idAction); + this.idIntent = this.idAction.split('/')[0]; + if(this.response?._tdJSONCondition && this.response._tdJSONCondition.conditions.length > 0){ + this.filterConditionExist = true + } + } + + private checkButtons(){ + if(!this.response.attributes || !this.response.attributes.attachment){ + this.response.attributes = new MessageAttributes(); + } + if(this.response?.attributes?.attachment?.buttons){ + this.buttons = this.response?.attributes?.attachment?.buttons; + } else { + this.buttons = []; + } + } + + // private async patchButtons(){ + // this.logger.log('patchButtons:: ', this.response); + // let buttons = this.response?.attributes?.attachment?.buttons; + // if(!buttons)return; + // buttons.forEach(button => { + // if(!button.__uid || button.__uid === undefined){ + // button.__uid = generateShortUID(); + // } + // const idActionConnector = this.idAction+'/'+button.__uid; + // button.__idConnector = idActionConnector; + // if(button.action && button.action !== ''){ + // button.__isConnected = true; + // } else { + // button.__isConnected = false; + // } + // this.logger.log('[cds-action-reply-text ]:: button: ', button, button.__uid); + // // button.__isConnected = true; + + // }); + // } + + private updateConnector(){ + try { + const array = this.connector.fromId.split("/"); + const idButton = array[array.length - 1]; + const idConnector = this.idAction+'/'+idButton; + const buttonChanged = this.buttons.find(obj => obj.uid === idButton); + + if(idConnector === this.connector.fromId && buttonChanged){ + this.logger.log('updateConnector [CdsActionReplyTextComponent]:: buttonChanged: ', this.connector, buttonChanged, this.buttons, idButton); + if(this.connector.deleted){ + buttonChanged.__isConnected = false; + buttonChanged.__idConnector = this.connector.fromId; + buttonChanged.__idConnection = null; + buttonChanged.action = ''; + buttonChanged.type = TYPE_BUTTON.TEXT; + if(this.connector.save)this.updateAndSaveAction.emit(this.connector); + } else { + // ADD / EDIT + buttonChanged.__idConnector = this.connector.fromId; + buttonChanged.action = buttonChanged.action? buttonChanged.action : '#' + this.connector.toId; + buttonChanged.type = TYPE_BUTTON.ACTION; + if(!buttonChanged.__isConnected){ + buttonChanged.__isConnected = true; + buttonChanged.__idConnection = this.connector.fromId+"/"+this.connector.toId; + if(this.connector.save)this.updateAndSaveAction.emit(this.connector); + } + } + } + } catch (error) { + this.logger.error('error: ', error); + } + } + + + + // EVENT FUNCTIONS // + + + /** changeJsonButtons */ + onChangeJsonButtons(json:any){ + this.logger.log('[ACTION REPLY TEXT] onChangeJsonButtons', json); + this.jsonBody = json; + if(json && json.trim() !== ''){ + this.response.attributes.attachment.json_buttons = json; + } else { + this.response.attributes.attachment.json_buttons = null; + } + this.changeJsonButtons.emit(this.response); + } + + /** onClickDelayTime */ + onClickDelayTime(opened: boolean){ + this.canShowFilter = !opened; + } + + /** onChangeDelayTime */ + onChangeDelayTime(value:number){ + this.delayTime = value; + this.wait.time = value*1000; + this.canShowFilter = true; + this.changeActionReply.emit(); + } + + /** onChangeExpression */ + onChangeExpression(expression: Expression){ + this.response._tdJSONCondition = expression; + // // this.filterConditionExist = expression && expression?.conditions.length > 0?true:false; + this.filterConditionExist = !!(expression && expression?.conditions.length > 0); + this.changeActionReply.emit(); + } + + /** onDeleteActionReply */ + onDeleteActionReply(){ + this.deleteActionReply.emit(this.index); + } + + /** onMoveUpResponse */ + onMoveUpResponse(){ + this.moveUpResponse.emit(this.index); + } + + /** onMoveDownResponse */ + onMoveDownResponse(){ + this.moveDownResponse.emit(this.index); + } + + /** onChangeTextarea */ + onChangeTextarea(text:string) { + if(!this.previewMode){ + this.response.text = text; + } + } + + onBlur(event){ + this.logger.log('[ACTION REPLY TEXT] onBlur', event.target.value, this.response.text); + this.changeActionReply.emit(); + } + + onSelectedAttribute(variableSelected: {name: string, value: string}){ + } + + /** onOpenButtonPanel */ + onOpenButtonPanel(button){ + this.logger.log('[ACTION REPLY TEXT] onOpenButtonPanel ', button, this.response.attributes.attachment.buttons); + this.openButtonPanel.emit(button); + } + + /** onButtonControl */ + onButtonControl(action: string, index: number ){ + switch(action){ + case 'delete': /** onDeleteButton */ + this.deleteButton.emit({index: index, buttons: this.buttons}); + break; + case 'moveLeft': + break; + case 'moveRight': + break; + case 'new': /** onCreateNewButton */ + this.createNewButton.emit(this.index); + break; + } + } + + /** dropButtons */ + dropButtons(event: CdkDragDrop) { + moveItemInArray(this.buttons, event.previousIndex, event.currentIndex); + this.connectorService.updateConnector(this.idIntent); + this.changeActionReply.emit(); + } + + /** checkForVariablesInsideText */ + checkForVariablesInsideText(text: string){ + text.match(new RegExp(/(?<=\{\{)(.*)(?=\}\})/g, 'g')).forEach(match => { + let createTag = '' + match + '' + text = text.replace('{' + match + '}',createTag) + }); + return text + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.spec.ts new file mode 100644 index 000000000..14b669dd1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyTextComponent } from './cds-action-reply-text.component'; + +describe('CdsActionReplyTextComponent', () => { + let component: CdsActionReplyTextComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyTextComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyTextComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.html new file mode 100644 index 000000000..a87bb0cc1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.html @@ -0,0 +1,31 @@ +
+
+ + +
+ +
+ + +
+
+ + + +
+
+ + + +
+
+ + + +
+
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss new file mode 100644 index 000000000..3797e024c --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss @@ -0,0 +1,29 @@ +@import "./src/assets/sass/cds/_variables.scss"; + +.add-responses { + // grid-gap: 5px; + // display: grid;+ + display: flex; + float: right; + .add-response { + text-align: center; + cursor: pointer; + box-sizing: border-box; + outline: none; + margin: 0; + padding: 3px 6px; + display: flex; + + &:not(:first-child){ + border-left: 1px solid white; + } + + img{ + width: 16px; + &:hover{ + filter: brightness(0) saturate(100%) invert(83%) sepia(87%) saturate(3891%) hue-rotate(177deg) brightness(92%) contrast(89%); + } + } + + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.ts new file mode 100644 index 000000000..edbbc0f0e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.ts @@ -0,0 +1,135 @@ +import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core'; +import { TYPE_MESSAGE, TYPE_COMMAND, generateShortUID, TYPE_BUTTON, TYPE_URL } from '../../../../../../../utils'; +import { Message, Command, Button } from 'src/app/models/action-model'; + +@Component({ + selector: 'cds-action-reply-tools-new', + templateUrl: './cds-action-reply-tools-new.component.html', + styleUrls: ['./cds-action-reply-tools-new.component.scss'] +}) +export class CdsActionReplyToolsNewComponent implements OnInit { + + @Input() idAction: string; + @Output() addNewActionReply = new EventEmitter(); + + TypeMessage = TYPE_MESSAGE; + + constructor() { } + + ngOnInit(): void { + } + + + addElement(type: TYPE_MESSAGE){ + var newElement:Command; + switch (type) { + case TYPE_MESSAGE.TEXT: + newElement = { + type: TYPE_COMMAND.MESSAGE, + message: { + text: '', + type: TYPE_MESSAGE.TEXT + }, + } + break; + case TYPE_MESSAGE.IMAGE: + newElement = { + type: TYPE_COMMAND.MESSAGE, + message: { + text: '', + type: TYPE_MESSAGE.IMAGE, + metadata: { + src: '', + downloadURL: '' + // width: MESSAGE_METADTA_WIDTH, + // height: MESSAGE_METADTA_HEIGHT + } + }, + } + break; + case TYPE_MESSAGE.FRAME: + newElement = { + type: TYPE_COMMAND.MESSAGE, + message: { + text: '', + type: TYPE_MESSAGE.FRAME, + metadata: { + src: '', + downloadURL: '' + // width: MESSAGE_METADTA_WIDTH, + // height: MESSAGE_METADTA_HEIGHT + } + }, + } + break; + case TYPE_MESSAGE.GALLERY: + const idButton = generateShortUID(); + const idActionConnector = this.idAction+'/'+idButton; + newElement = { + type: TYPE_COMMAND.MESSAGE, + message: { + text: '', + type: TYPE_MESSAGE.GALLERY, + attributes: { + attachment: { + type: 'gallery', + gallery: [ + { + preview: { src: '', downloadURL: ''}, + title: 'Type title', + description: 'Type description', + buttons: [ + + new Button( + idButton, + idActionConnector, + false, + TYPE_BUTTON.TEXT, + 'Button', + '', + TYPE_URL.BLANK, + '', + '', + true + ) + // { + // 'uid': idButton, + // 'idConnector': idActionConnector, + // 'isConnected': false, + // 'value': 'Button', + // 'type': TYPE_BUTTON.TEXT, + // 'target': TYPE_URL.BLANK, + // 'link': '', + // 'action': '', + // 'show_echo': true + // } + ] + } + ] + } + } + }, + } + break; + case TYPE_MESSAGE.REDIRECT: + newElement = { + type: TYPE_COMMAND.MESSAGE, + message: { + text: '', + type: TYPE_MESSAGE.REDIRECT, + metadata: { + src : '', + downloadURL: '', + target: TYPE_URL.BLANK, + type: TYPE_MESSAGE.REDIRECT + } + }, + } + break; + default: + break; + } + this.addNewActionReply.emit(newElement); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools.component.spec.ts new file mode 100644 index 000000000..bcc6905a8 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionReplyToolsComponent } from './cds-action-reply-tools.component'; + +describe('CdsActionReplyToolsComponent', () => { + let component: CdsActionReplyToolsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionReplyToolsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionReplyToolsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.html new file mode 100644 index 000000000..3e378bad2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.html @@ -0,0 +1,168 @@ +
+ +
+
+ + + +
+
+ {{action.payload.receiver_list.length}} {{'CDSCanvas.ContactSelected' | translate }} +
+ + +
+ + + +
+
+ {{'CDSCanvas.AddContacts' | translate }} +
+ +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ +
+ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.scss new file mode 100644 index 000000000..1a00f85d2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.scss @@ -0,0 +1,41 @@ +.loader-container { + display: flex; + justify-content: center; + align-items: center; + height: 100px; + + #opt-train-wrp { + display: flex; + align-items: center; + + label { + font-weight: 500; + font-family: var(--font-family-poppins); + text-transform: capitalize; + font-size: 14px; + animation: blinker 1s linear infinite; + } + @keyframes blinker { + 50% { + opacity: 0; + } + } + } +} + +cds-whatsapp-receiver::ng-deep{ + + .whatsapp-receiver{ + padding: unset; + + .response-controls{ + position: absolute; + margin-left: -25px; + + .control-button.delete{ + display: none; + pointer-events: none; + } + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.ts new file mode 100644 index 000000000..1f261fabe --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp-new.component.ts @@ -0,0 +1,223 @@ +import { Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { ActionSendWhatsapp } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { DashboardService } from 'src/app/services/dashboard.service'; +import { WhatsappService } from 'src/app/services/whatsapp.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-send-whatsapp-new', + templateUrl: './cds-action-send-whatsapp-new.component.html', + styleUrls: ['./cds-action-send-whatsapp-new.component.scss'] +}) +export class CdsActionSendWhatsappNewComponent implements OnInit { + + @Input() action: ActionSendWhatsapp; + @Input() intentSelected: Intent; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + project_id: string; + + templates_list = []; + // receiver_list = []; + + phone_number_id: string; + showLoader: Boolean = false; + selected_template: any; + payload: any; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private dashboardService: DashboardService, + private intentService: IntentService, + private whatsapp: WhatsappService, + public el: ElementRef + ) { } + + ngOnInit(): void { + this.logger.debug("[ACTION-SEND WHATSAPP] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-SEND WHATSAPP] isChangedConnector -->', connector); + this.connector = connector; + this.updateConnector(); + }); + + } + + ngOnChanges(changes: SimpleChanges): void { + this.logger.log("[ACTION REPLACE BOT] action (on-changes): ", this.action) + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION REPLACE BOT] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION REPLACE BOT] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + + private initialize(){ + this.project_id = this.dashboardService.projectID + this.action.payload.id_project = this.project_id + if (this.previewMode === false) { + this.logger.log("Whatsapp static project_id: ", this.project_id); + this.showLoader = true; + this.getTemplates(); + } + if(this.intentSelected){ + this.initializeConnector(); + } + } + + getTemplates() { + this.whatsapp.getAllTemplates().subscribe({ next:(templates: any[]) => { + this.logger.log("[ACTION-SEND WHATSAPP] get templates: ", templates); + this.templates_list = templates.map(t => { + if (t.category === 'MARKETING') { + t.icon = "campaign" + } + else { + t.icon = "notifications_active" + } + t.description = t.components.find(c => c.type === 'BODY').text; + return t; + }) + + }, error: (error) => { + this.showLoader = false; + this.logger.log("[ACTION-SEND WHATSAPP] error get templates: ", error); + }, complete: () => { + + if (this.action.templateName) { + this.selected_template = this.templates_list.find(t => t.name === this.action.templateName); + } + this.logger.log("[ACTION-SEND WHATSAPP] get templates completed: ", this.action.templateName, this.templates_list, this.selected_template); + this.showLoader = false; + }}) + } + + onChangeSelect(event) { + this.logger.debug("[ACTION-SEND WHATSAPP] onChangeSelect event", event); + this.selected_template = event; + this.action.templateName = this.selected_template.name; + this.action.payload.template.name = this.selected_template.name; + this.action.payload.template.language = this.selected_template.language; + this.action.payload.receiver_list = []; + this.addReceiver(); + this.updateAndSaveAction.emit(); + } + + addReceiver() { + this.action.payload.receiver_list.push({ phone_number: null }); + } + + onChangeTextarea(event){ + if(event){ + this.phone_number_id = event + let element = document.getElementById('phone-number-id'); + element.classList.remove('is-invalid'); + var reg = new RegExp('^[0-9]+$'); + if (!reg.test(this.phone_number_id)) { + element.classList.add('is-invalid'); + } else { + this.action.payload.phone_number_id = this.phone_number_id; + this.updateAndSaveAction.emit(); + } + + this.logger.debug("[ACTION-SEND WHATSAPP] Action updated ", this.action.payload); + } + } + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onReceiverEmitted(event, index) { + // update receiver + this.action.payload.receiver_list[index] = event; + this.logger.log("[ACTION-SEND WHATSAPP] Action updated ", this.action.payload); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp.component.spec.ts new file mode 100644 index 000000000..4980466cb --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/cds-action-send-whatsapp.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionSendWhatsappComponent } from './cds-action-send-whatsapp.component'; + +describe('CdsActionSendWhatsappComponent', () => { + let component: CdsActionSendWhatsappComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionSendWhatsappComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionSendWhatsappComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.html new file mode 100644 index 000000000..b17003d20 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.html @@ -0,0 +1,295 @@ +
+ +
+
+ visibility +
+ +
+ visibility_off +
+ + +
+ delete + +
+ + +
+ + +
+ +
+
+
+ + +
+ {{ header_component?.text }} + + + + + +
+

PDF

+
+ + +
+ +
+

{{'CDSCanvas.Location' | translate }}

+
+ +
+
+ + +
+ {{ body_component?.text }} +
+ + + + + +
+ +
+ +
+ +
+ +
+
+ + +
+
+ +
+
+ + +
+

{{'CDSCanvas.PhoneNumber' | translate}}

+
+
+ + phone + +
+
+ + +
+
+
+ + + + + +
+

{{'CDSCanvas.HeaderParameters' | translate }}

+

{{'CDSCanvas.TheHeaderContainsMedia' | translate }}

+ + +
+
+ {{ i + 1 }} +
+
+ + + +
+
+ + +
+
+ + {{ i + 1 }} +
+
+ + + + + +
+ + + + +
+ +
+ +
+

{{'CDSCanvas.LocationHeadersNotSupported' | translate }}

+ +
+ + + +
+

{{'CDSCanvas.BodyParameters' | translate }}

+
+
+ + {{ i + 1 }} + +
+
+ + +
+
+
+ + + +
+

{{'CDSCanvas.NoParameters' | translate }}

+
+ + +
+

{{'CDSCanvas.ButtonsParameters' | translate }}

+
+
+ + {{ i + 1 }} +
+
+ + +
+ +
+
+
+ + +
+

{{ previsioning_url }}

+
+
+ + + + +
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss new file mode 100644 index 000000000..5c64b8cd6 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss @@ -0,0 +1,409 @@ +:host{ + --icon-color: #{var(--blu)}; + --textColor: #{var(--blu)}; + --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; + --hoverBackgroundColor: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); + --border-radius-base: 8px + +} + +::placeholder { + color: rgb(198, 198, 198); + opacity: 1; /* Firefox */ +} + +.whatsapp-receiver { + display: flex; + flex-direction: row; + padding: 0px 24px 0px 0px; + position: relative; +} + +.whatsapp-receiver:hover { + .response-controls { + opacity: 1; + } +} + +.highlighted { + box-shadow: 0px 0px 4px 0px var(--color-red-hex); +} + +.response-controls { + opacity: 0; + transition: opacity 0.3s ease-in-out; + display: flex; + flex-direction: column; + align-items: center; + margin-left: 2px; + margin-right: 6px; + + + // height: 100%; + // left: -44px; + // position: absolute; + // top: 0px; + // width: 44px; + + .control-button { + cursor: pointer; + &.delete, + &.copy { + height: 24px; + width: 24px; + background: white; + border-radius: 50%; + transition: background-color 0.3s ease 0s; + box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 6px; + em { + font-size: 1.15em; + color: var(--textColor); + transition: color 0.3s; + } + } + } + .control-button:hover { + color: var(--blu-light-02); + &.delete{ + em { + color: var(--color-red-hex); + } + } + &.copy { + background-color: var(--hoverBackgroundColor); + } + } +} + +loading-spinner.custom-spinner ::ng-deep { + margin-left: 4px; + width: 40px; + .sk-fading-circle { + width: 20px ; + height: 20px ; + margin: 0px ; + } + + .sk-fading-circle .sk-circle:before { + background-color: var(--blu) ; + } +} + +.parameters-container { + //margin-top: 16px; + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + border-radius: 4px; + padding: 6px; + //border: 2px solid transparent; + display: flex; + flex-direction: column; + width: 100%; + font-family: Roboto; + margin-bottom: 10px; + + + p { + margin-bottom: 0px; + } + + .parameters-title { + font-weight: 400; + margin-bottom: 2px; + font-size: 14px; + } + + .parameters-subtitle { + margin-bottom: 4px; + font-size: 14px; + color: #666565; + } + + .parameter { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 10px; + } + + .field-wrapper { + display: flex; + width: 100%; + cds-textarea{ + width: 100%; + } + } + + .param-number { + height: 36px; + width: 36px; + //background-color: var(--textColor); + color: var(--backGroundColor); + display: flex; + align-items: center; + margin-right: 10px; + justify-content: center; + font-weight: 500; + border: solid 1px var(--textColor); + border-radius: var(--input-border-radius-base); + font-style: italic; + + span { + color: var(--textColor); + font-size: 18px; + } + } + + input { + width: 100%; + height: 36px; + border-radius: var(--input-border-radius-base); + background: var(--color-white-hex); + border: 1px solid var(--blu-light-02) !important; + color: var(--gray); + padding: 4px 8px; + font-size: 14px; + } +} + +// PREVIEW SECTION + +.preview-container { + display: flex; + //background-color: bisque; + //background-image: url("/assets/images/whatsapp_background.png"); + background-image: url("../../../../../../../../assets/images/whatsapp_background.png"); + background-repeat: no-repeat; + background-size: cover; + border-radius: 6px; + margin-bottom: 8px; + max-height: 0px; + overflow: hidden; + transition: max-height 0.6s; + + .inner-preview-container { + padding: 6px 6px; + } +} + +.preview-container-active { + //min-height: 200px; + max-height: 500px; + // height: 100px; + + // .message-cloud { + // opacity: 1; + // } +} + +.message-cloud { + // transition-delay: 0.5s; + // transition: opacity 0.2s; + background-color: #fff; + width: 260px; + padding: 8px 10px 2px 10px; + border-radius: 8px; + box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.15); + font-size: 12px; + + .header-preview { + color: rgba(0, 0, 0, 0.76); + font-size: 13px; + font-weight: bold; + line-height: 19px; + padding-bottom: 8px; + + img { + max-width: 100%; + border-radius: 6px; + animation: fadein 1s; + } + + @keyframes fadein { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + + + .pdf-preview { + width: 100%; + height: 100%; + background-color: #d3dbe5; + border-radius: 6px; + padding: 26px; + display: flex; + justify-content: center; + + p { + padding: 10px; + color: white; + background-color: #80868b; + border-radius: 12px; + width: 70px; + text-align: center; + } + } + + .location-preview { + width: 100%; + height: 100%; + background-color: #d3dbe5; + border-radius: 6px; + padding: 26px; + display: flex; + justify-content: center; + background-image: url("https://media.istockphoto.com/id/1306807452/vector/map-city-vector-illustration.jpg?s=612x612&w=0&k=20&c=8efOIy-Ft3trEzeDk3PY2WRjWws8mvKXgkLqCZ2cP5A="); + background-size: contain; + + p { + padding: 10px; + color: white; + background-color: #80868b; + border-radius: 12px; + width: 100px; + text-align: center; + } + } + } + + .body-preview { + font-size: 12px; + color: #282828; + line-height: 19px; + } + + .footer-preview { + padding-top: 6px; + color: #00000073; + font-size: 11.6px; + line-height: 17px; + } + + .whatsapp-call-to-action { + background-color: #fff; + color: #00a5f4; + /* width: 200px; */ + width: 100%; + height: 26px; + font-size: 14px; + text-transform: none; + border-radius: 6px; + /* margin-bottom: 4px; */ + box-shadow: none; + padding: 0px; + margin: 2px 0px; + display: flex; + align-items: center; + justify-content: center; + } + + .call-to-action-icon { + font-size: 16px; + margin-right: 6px; + } +} + +button.icon-only { + height: 36px; + width: 40px; + margin-left: 4px; + border-radius: 8px; + background: var(--blu-light-02); + border: 1px solid var(--blu-light-02) !important; + color: var(--color-white-hex); + + display: flex; + align-items: center; + justify-content: center; + + &:hover { + opacity: 0.8; + } +} + +.message-cloud-buttons-container { + max-width: 260px; +} + +.message-cloud-buttons { + margin: 0 -1.5px; + border: none; + box-sizing: border-box; + display: flex; + flex-wrap: wrap; + width: 260px; +} + +.message-cloud-button { + margin: 3px 1.5px 0; + border-radius: 7.5px; + padding: 6px 7px 8px 9px; + min-width: calc(50% - 3px); + height: 36px; + flex-grow: 1; + background-color: white; + color: #00a5f4; + box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.15); + font-size: 14px; + font-weight: 400; + letter-spacing: 0px; + border: none; +} + +.url-button-previsioning { + padding: 8px 8px; + border-radius: 4px; + background-color: #1877f21a; + + .previsioning-url { + margin: 0px; + } + + .whatsapp-call-to-action { + background-color: #fff; + color: #00a5f4; + /* width: 200px; */ + width: 100%; + height: 26px; + font-size: 14px; + text-transform: none; + border-radius: 6px; + /* margin-bottom: 4px; */ + box-shadow: none; + padding: 0px; + margin: 2px 0px; + display: flex; + align-items: center; + justify-content: center; + border: none; + width: 200px; + font-weight: 400; + } + + .call-to-action-icon { + font-size: 16px; + margin-right: 6px; + } +} + +.header-image-container { + width: 100%; + //height: 120px; // set if background-image property is setted + background-color: #dcdcdc; + border-radius: 6px; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + overflow: hidden; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.ts new file mode 100644 index 000000000..3b0b893c4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.ts @@ -0,0 +1,530 @@ +import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { UploadModel } from 'src/chat21-core/models/upload'; +import { UserModel } from 'src/chat21-core/models/user'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { UploadService } from 'src/chat21-core/providers/abstract/upload.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service'; + +@Component({ + selector: 'cds-whatsapp-receiver-new', + templateUrl: './whatsapp-receiver-new.component.html', + styleUrls: ['./whatsapp-receiver-new.component.scss'] +}) +export class CdsWhatsappReceiverComponent implements OnInit { + + @Input() template: any; + @Input() receiver: any; + @Input() index: any; + @Output() deleteReceiver = new EventEmitter(); + @Output() receiverValue = new EventEmitter(); + + header_component: any; + body_component: any; + footer_component: any; + buttons_component: any; + url_button_component: any; + url_button_component_temp: any; + header_component_temp: any; + body_component_temp: any; + body_params = []; + header_params = []; + buttons_params = []; + previsioning_url: string; + sanitizedUrl: any; + fileUploadAccept: string = "image/*"; + src: any; + isFilePendingToUpload = false; + fileUploadedName: string; + displayPreview: boolean = false; + phone_number: string; + user: UserModel + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + public sanitizer: DomSanitizer, + public elementRef: ElementRef, + private uploadService: UploadService, + private tiledeskAuthService: TiledeskAuthService + ) { + + } + + ngOnInit(): void { + this.logger.log("onInit receiver: ", this.receiver); + this.user = this.tiledeskAuthService.getCurrentUser(); + this.onInputTemplate(); + } + + initialize() { + + if (this.receiver.phone_number) { + this.phone_number = this.receiver.phone_number; + } + if (this.receiver.header_params) { + this.header_params.forEach((hp, i) => { + + if (this.receiver.header_params[i].type === 'TEXT') { + hp.text = this.receiver.header_params[i].text; + } + if (this.receiver.header_params[i].type === 'IMAGE') { + hp.image.link = this.receiver.header_params[i].image.link; + // let decoded_url = decodeURIComponent(this.receiver.header_params[i].image.link); + // this.fileUploadedName = decoded_url.substring(decoded_url.lastIndexOf('/') + 1); + this.fileUploadedName = this.receiver.header_params[i].image.link; + } + if (this.receiver.header_params[i].type === 'DOCUMENT') { + hp.document.link = this.receiver.header_params[i].document.link; + this.fileUploadedName = this.receiver.header_params[i].document.link; + } + // hp.text = this.receiver.header_params[i].text; + //this.logger.log("this.receiver.header_params", this.receiver.header_params); + //this.logger.log("this.header_params", this.header_params); + }) + } + + if (this.receiver.body_params) { + this.body_params.forEach((bp, i) => { + bp.text = this.receiver.body_params[i].text + }) + } + + if (this.receiver.buttons_params) { + this.buttons_params.forEach((ubp, i) => { + ubp.text = this.receiver.buttons_params[i].text + }) + + } + + this.setUpPreview(); + + } + + setUpPreview() { + + // this.body_params.forEach((param, i) => { + // let index = i + 1; + // let regex = '{{' + index + '}}'; + // if (param.text) { + // this.body_component.text = this.body_component.text.replace(regex, param.text); + // } + // }) + + this.body_params.forEach((param, i) => { + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.body_component.text = this.body_component.text.replace(regex, param.text); + } + }) + + this.header_params.forEach((param, i) => { + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.header_component.text = this.header_component.text.replace(regex, param.text); + } + }) + + this.buttons_params.forEach((param, i) => { + //this.logger.log("buttons_params - param: ", param); + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.url_button_component.url = this.url_button_component.url.replace(regex, param.text); + } + let button_index = this.buttons_component.buttons.findIndex(b => b.type === 'URL'); + this.buttons_component.buttons[button_index] = this.url_button_component; + this.previsioning_url = this.url_button_component.url; + }) + + } + + onInputTemplate() { + let temp_template = JSON.parse(JSON.stringify(this.template)); + this.header_component = temp_template.components.find(c => c.type === 'HEADER'); + this.body_component = temp_template.components.find(c => c.type === 'BODY'); + this.footer_component = temp_template.components.find(c => c.type === 'FOOTER'); + this.buttons_component = temp_template.components.find(c => c.type === 'BUTTONS'); + if (this.buttons_component) { + this.url_button_component = this.buttons_component.buttons.find(c => c.type === 'URL') + } + + if (this.header_component) { + this.header_component_temp = JSON.parse(JSON.stringify(this.header_component)); + if (this.header_component.format === 'TEXT') { + if (this.header_component.example && + this.header_component.example.header_text) { + this.header_component.example.header_text.forEach((p, i) => { + this.header_params.push({ index: i + 1, type: this.header_component.format, text: null }) + }) + } + } + else if (this.header_component.format === 'IMAGE') { + if (this.header_component.example && + this.header_component.example.header_handle) { + this.header_component.example.header_handle.forEach((p, i) => { + this.header_params.push({ index: i + 1, type: this.header_component.format, image: { link: null } }) + }) + + } + } + else if (this.header_component.format === 'DOCUMENT') { + if (this.header_component.example && + this.header_component.example.header_handle) { + this.fileUploadAccept = ".pdf" + this.src = this.header_component.example.header_handle[0]; + this.sanitizeUrl(this.header_component.example.header_handle[0]); + this.header_component.example.header_handle.forEach((p, i) => { + this.header_params.push({ index: i + 1, type: this.header_component.format, document: { link: null } }) + }) + } + } + else if (this.header_component.format === 'LOCATION') { + this.header_params.push({ index: 1, type: this.header_component.format, location: { latitude: null, longitude: null, name: null, address: null } }) + } + else { + this.logger.log("[WHATSAPP RECEIVER] Check unrecognized Header: ", this.header_component) + } + } + + if (this.body_component) { + this.body_component_temp = JSON.parse(JSON.stringify(this.body_component)); + if (this.body_component.example) { + this.body_component.example.body_text[0].forEach((p, i) => { + this.body_params.push({ index: i + 1, type: "text", text: null }) + }) + } + } + + if (this.url_button_component) { + this.url_button_component_temp = JSON.parse(JSON.stringify(this.url_button_component)); + if (this.url_button_component.example) { + this.url_button_component.example.forEach((p, i) => { + this.buttons_params.push({ index: i + 1, type: "text", text: null }) + this.previsioning_url = this.url_button_component.url; + }) + } + } + + this.initialize(); + } + + sanitizeUrl(url) { + this.sanitizedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url); + } + + onPhoneNumberChange(event) { + // TODO - Aggiungere regex per controllare il numero inserito + this.phone_number = event; + // if(event){ + // this.invalidNumber = false; + // var reg = new RegExp('^\\+?(\\d{1,3})?[-.\\s]?\\(?\\d{1,4}\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$'); + // if (!reg.test(this.phone_number)) { + // this.invalidNumber = true + // } + // } + + } + + onParamBodyChange(event, param_num) { + this.body_component = JSON.parse(JSON.stringify(this.body_component_temp)); + this.body_params[param_num - 1].text = event; + this.body_params.forEach((param, i) => { + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.body_component.text = this.body_component.text.replace(regex, param.text); + } + }) + } + + onParamHeaderChange(event, param_num) { + this.logger.log('[WHATSAPP RECEIVER] onParamHeaderChange -->', event, param_num, this.header_params[param_num - 1]) + this.header_component = JSON.parse(JSON.stringify(this.header_component_temp)); + if (this.header_params[param_num - 1].type === 'TEXT') { + this.header_params[param_num - 1].text = event; + } + if (this.header_params[param_num - 1].type === 'IMAGE') { + this.header_params[param_num - 1].image.link = event; + this.fileUploadedName = event; + } + if (this.header_params[param_num - 1].type === 'DOCUMENT') { + this.header_params[param_num - 1].document.link = event; + this.fileUploadedName = event; + this.sanitizeUrl(event); + } + + this.header_params.forEach((param, i) => { + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.header_component.text = this.header_component.text.replace(regex, param.text); + } + }) + } + + onParamButtonChange(event, param_num) { + this.url_button_component = JSON.parse(JSON.stringify(this.url_button_component_temp)); + this.buttons_params[param_num - 1].text = event; + this.buttons_params.forEach((param, i) => { + let index = i + 1; + let regex = '{{' + index + '}}'; + if (param.text) { + this.url_button_component.url = this.url_button_component.url.replace(regex, param.text); + } + let button_index = this.buttons_component.buttons.findIndex(b => b.type === 'URL'); + this.buttons_component.buttons[button_index] = this.url_button_component; + this.previsioning_url = this.url_button_component.url; + }) + } + + // evaluate saving partial objects + checkParameters() { + // let text_header_result = this.header_params.find(p => !p.text || p.text == ''); + let media_header_result = this.header_params.find(p => (p.text == '') || (p.image && (!p.image.link || p.image.link == '')) || (p.document && (!p.document.link || p.document.link == '')) || (p.location && (!p.location.name || !p.location.address || !p.location.latitude || !p.location.longitude))); + let body_result = this.body_params.find(p => !p.text || p.text == ''); + let url_buttton_result = this.buttons_params.find(p => !p.text || p.text == ''); + + this.logger.log('[WHATSAPP RECEIVER] checkParameters media',media_header_result) + this.logger.log('[WHATSAPP RECEIVER] checkParameters body',body_result) + this.logger.log('[WHATSAPP RECEIVER] checkParameters url',url_buttton_result) + + if (( !media_header_result) && !body_result && !url_buttton_result) { + this.logger.log(" ** PARAMETRI COMPLETI **") + this.emitParams(); + let preview_container = this.elementRef.nativeElement.querySelector('#parameters-container'); + preview_container.classList.remove('highlighted'); + } else { + let preview_container = this.elementRef.nativeElement.querySelector('#parameters-container'); + preview_container.classList.add('highlighted'); + } + } + + emitParams() { + const new_header_params = this.header_params.map(({ index, ...keepAttrs }) => keepAttrs) + const new_body_params = this.body_params.map(({ index, ...keepAttrs }) => keepAttrs) + const new_buttons_param = this.buttons_params.map(({ index, ...keepAttrs }) => keepAttrs) + + this.body_params.forEach(param => { + this.logger.log("param: ", param); + }); + + + let receiver_out: any = { + phone_number: this.phone_number, + // header_params: new_header_params, + // body_params: new_body_params, + // buttons_params: new_buttons_param + } + + if (new_header_params.length > 0) { + receiver_out.header_params = new_header_params; + } + if (new_body_params.length > 0) { + receiver_out.body_params = new_body_params; + } + if (new_buttons_param.length > 0) { + receiver_out.buttons_params = new_buttons_param; + } + this.logger.log("[WHATSAPP RECEIVER] receiver_out: ", receiver_out, this.receiver); + // this.receiver = receiver_out; + this.receiverValue.emit(receiver_out); + } + + onBlur(event) { + this.checkParameters(); + } + + onChangeTextarea(text: string, key: string, index?: number){ + this.logger.log('[WHATSAPP RECEIVER] onChange input ->', key, text) + switch(key){ + case 'phone_number': + this.onPhoneNumberChange(text); + break; + case 'header_params': + this.onParamHeaderChange(text, index); + break; + case 'body_params': + this.onParamBodyChange(text, index); + break; + case 'buttons_params': + this.onParamButtonChange(text, index) + break; + } + } + + onSelectedAttribute(variable: {name: string, value: string}, key: string, index?: number){ + this.logger.log('[WHATSAPP RECEIVER] onSelectedAttribute input ->', key, variable) + switch(key){ + case 'phone_number': + break; + case 'header_params': + this.fileUploadedName = variable.name + break; + case 'body_params': + break; + case 'buttons_params': + break; + } + + } + + onFocus() { + let parameters_container = this.elementRef.nativeElement.querySelector('#parameters-container'); + parameters_container.classList.remove('highlighted'); + } + + onHeaderImageError(event) { + event.target.src = this.header_component.example.header_handle[0]; + } + + onDeleteReceiver() { + this.deleteReceiver.emit(this.index); + } + + showPreview() { + this.displayPreview = true; + let preview_container = this.elementRef.nativeElement.querySelector('#preview-container'); + preview_container.classList.add('preview-container-active') + } + + hidePreview() { + this.displayPreview = false; + let preview_container = this.elementRef.nativeElement.querySelector('#preview-container'); + preview_container.classList.remove('preview-container-active') + } + + + onFileSelected(event: any): void { + this.logger.log('[WHATSAPP-RECEIVER] onFileSelected IMAGE upload') + if (event) { + let selectedFiles = event.target.files; + this.logger.debug('[WHATSAPP-RECEIVER] AppComponent:detectFiles::selectedFiles', selectedFiles); + // this.onAttachmentButtonClicked.emit(this.selectedFiles) + if (selectedFiles == null) { + this.isFilePendingToUpload = false; + } else { + this.isFilePendingToUpload = true; + } + this.logger.debug('[WHATSAPP-RECEIVER] AppComponent:detectFiles::selectedFiles::isFilePendingToUpload', this.isFilePendingToUpload); + this.logger.debug('[WHATSAPP-RECEIVER] fileChange: ', event.target.files); + if (event.target.files.length <= 0) { + this.isFilePendingToUpload = false; + } else { + this.isFilePendingToUpload = true; + } + + const that = this; + if (event.target.files && event.target.files[0]) { + const nameFile = event.target.files[0].name; + const typeFile = event.target.files[0].type; + const reader = new FileReader(); + that.logger.debug('[WHATSAPP-RECEIVER] OK preload: ', nameFile, typeFile, reader); + reader.addEventListener('load', function () { + that.logger.debug('[WHATSAPP-RECEIVER] addEventListener load', reader.result); + // that.isFileSelected = true; + // se inizia con image + if (typeFile.startsWith('image') && !typeFile.includes('svg')) { + const imageXLoad = new Image; + that.logger.debug('[WHATSAPP-RECEIVER] onload ', imageXLoad); + imageXLoad.src = reader.result.toString(); + imageXLoad.title = nameFile; + imageXLoad.onload = function () { + that.logger.debug('[WHATSAPP-RECEIVER] onload image'); + // that.arrayFilesLoad.push(imageXLoad); + const uid = (new Date().getTime()).toString(36); // imageXLoad.src.substring(imageXLoad.src.length - 16); + that.uploadSingle(selectedFiles.item(0)) //GABBBBBBBB + }; + } + }, false); + + if (event.target.files[0]) { + reader.readAsDataURL(event.target.files[0]); + that.logger.debug('[WHATSAPP-RECEIVER] reader-result: ', event.target.files[0]); + } + } + + + } + + } + + private uploadSingle(file) { + const that = this; + // const send_order_btn = document.getElementById('chat21-start-upload-doc'); + // send_order_btn.disabled = true; + that.logger.debug('[IMAGE-UPLOAD] AppComponent::uploadSingle::', file); + // const file = this.selectedFiles.item(0); + const currentUpload = new UploadModel(file); + + this.uploadService.uploadAsset(this.user.uid, currentUpload).then(data => { + that.logger.debug(`[IMAGE-UPLOAD] Successfully uploaded file and got download link - ${data}`); + + this.fileUploadedName = file.name; + if (this.header_params[0].image) { + this.header_params[0].image.link = data.downloadURL; + } + if (this.header_params[0].document) { + this.header_params[0].document.link = data.downloadURL; + this.sanitizeUrl(data.downloadURL); + } + this.isFilePendingToUpload = false + // return downloadURL; + }).catch(error => { + // Use to signal error if something goes wrong. + that.logger.error(`[IMAGE-UPLOAD] uploadSingle:: Failed to upload file and get link - ${error}`); + that.isFilePendingToUpload = false; + }); + that.logger.debug('[IMAGE-UPLOAD] reader-result: ', file); + } + + getHeaderParamLink(index: number): string { + const param = this.header_params[index]; + if (!param) return null; + if (param.image && param.image.link) { + return param.image.link; + } + if (param.document && param.document.link) { + return param.document.link; + } + return null; + } + + removeHeaderFile(index) { + this.isFilePendingToUpload = true; + const linkToDelete = this.getHeaderParamLink(0); + + if (!linkToDelete) { + this.isFilePendingToUpload = false; + return; + } + + this.uploadService.deleteAsset(this.user.uid, linkToDelete).then((result)=>{ + + this.isFilePendingToUpload = false; + this.fileUploadedName = null; + + if (this.header_params[0].image) { + this.header_params[0].image.link = ""; + } + if (this.header_params[0].document) { + this.header_params[0].document.link = ""; + } + this.checkParameters() + }).catch((error)=> { + this.logger.error('[WHATSAPP-RECEIVER] delete header media file ERORR:', error) + + if (this.header_params[0].image) { + this.header_params[0].image.link = ""; + } + if (this.header_params[0].document) { + this.header_params[0].document.link = ""; + } + this.checkParameters() + this.isFilePendingToUpload = false; + }) + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.spec.ts new file mode 100644 index 000000000..85d608388 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsWhatsappReceiverComponent } from './whatsapp-receiver.component'; + +describe('WhatsappReceiverComponent', () => { + let component: CdsWhatsappReceiverComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsWhatsappReceiverComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsWhatsappReceiverComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.html new file mode 100644 index 000000000..fcdcbe0bf --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.html @@ -0,0 +1,56 @@ + +
+ +
+ timelapse +
+{{action.millis/1000}}s {{'CDSCanvas.delay' | translate }}
+
+ +
+ + + + +
+ +
+ +
+ + +
+
0.5s
+ + + +
15s
+
+ +
+ timelapse + + + + s + + +
+
+
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss new file mode 100644 index 000000000..03ee4a9be --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss @@ -0,0 +1,208 @@ +:host { + --background-color: #{var(--blu-light-01)}; + --text-color: #{var(--blu)}; +} + +.title-label { + font-size: 16px; +} + +.action-wait-content{ + margin-top: 30px; +} +.action-wait-slider { + align-items: center; + background: var(--background-color); + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 3px; + width: 100%; + text-align: center; + transition: width 0.3s ease-in; + font-size: var(--font-size-base); +} + +.action-wait-slider > mat-slider { + width: 100%; + margin-left: 6px; +} + +.action-wait-range { + color: var(--text-color); + font-size: 11px; + font-weight: 400; + padding-left: 6px; +} + +.wait-action-title { + font-family: var(--font-family-poppins); + color: #e8eaed; +} + + +.action-wait-slider ::ng-deep{ + .mat-accent .mat-slider-track-fill { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label { + background-color: var(--text-color) !important; + } + .mat-slider-thumb-label-text{ + color: var(--background-color) !important; + font-size: 8px!important; + } + .mat-slider-thumb { + background-color: var(--text-color) !important; + } +} + +/* Action delay preview +/* ------------------------ */ +.action-delay-preview { + align-items: center; + background: var(--blu-light-01);; + border-radius: 13px; + display: inline-flex; + position: relative; + height: 26px; + padding: 0 9px 0 3px; + text-align: center; + transition: width 0.3s ease-in; + font-size: var(--font-size-base); + // top: 3px; +} +.action-delay-preview .delay--icon { + padding-right: 4px; + color: var(--blu); +} + +.action-delay-preview .delay--time { + color: var(--blu); + cursor: pointer; + font-size: 11px; + font-weight: 400; + white-space: nowrap; +} + +.material-icons{ + line-height: unset; +} + +/** INPUT **/ +.box-input { + // width: calc(100% - 40px); + // margin-left: 20px; + width: 100%; + input { + // border-radius: var(--input-border-radius-base); + // background: var(--color-white-hex); + outline: 0px solid transparent; + outline-offset: -1px; + overflow-x: hidden; + overflow-y: auto; + // width: calc(100% - 2.5em); + width: 100%; + color: var(--text-color); + caret-color: var(--text-color); + font-size: 1.15em; + text-align: end; + // line-height: 25px; + resize: vertical; + + padding: 10px; + padding-top: 4px; + padding-bottom: 4px; + margin: 0px; + + &.customPrefix{ + padding-left: 20px; + width: calc(100% - 20px); + } + + &.autocompleteOpen{ + border-radius: var(--input-border-radius-base) 0 0 0; + } + + } + + .input-prefix { + position: absolute; + top: 14px; + left: 8px; + color: #7d7d7d; + font-weight: 800; + } + + .input-suffix { + position: absolute; + top: 14px; + right: 8px; + color: #7d7d7d; + font-weight: 800; + } +} + +/** TEXT **/ +mat-form-field.mat-form-field ::ng-deep { + .mat-form-field-infix{ + border-top: 0px !important; + input{ + &:hover{ + // border: 1px solid var(--blu) !important; + outline: 0px solid var(--blu) !important; + outline-offset: -1px; + } + } + } +} + +mat-form-field.mat-focused ::ng-deep { + .mat-form-field-wrapper { + .mat-form-field-flex { + .mat-form-field-infix { + display: flex; + input { + // border: 1px solid var(--blu)!important; + outline: 0px solid var(--blu)!important; + outline-offset: -1px; + // transition: border .3s; + &.invalid{ + // border: 1px solid red !important; + outline: 1px solid red !important; + outline-offset: -1px; + // transition: border 0.3s; + } + + } + + + } + } + } +} +mat-form-field.box-input ::ng-deep { + .mat-form-field-wrapper { + padding-bottom:0; + .mat-form-field-flex { + border-radius: 4px 4px 0 0; + // padding: 0 0.75em 0 0.75em; + padding: 0px; + margin: 0px; + background: transparent; + } + } + .mat-form-field-underline { + display: none; + } + .mat-form-field-infix { + display: flex; + width: 100%; + padding: 0px; + + .mat-form-field-label-wrapper{ + display: none; + } + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.ts new file mode 100644 index 000000000..2e5eb9695 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.ts @@ -0,0 +1,57 @@ +import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core'; +import { ActionWait } from 'src/app/models/action-model'; + +@Component({ + selector: ' selector: 'cds-action-wait-new',-new', + templateUrl: './cds-action-wait-new.component.html', + styleUrls: ['./cds-action-wait-new.component.scss'] +}) +export class CdsActionWaitNewComponent implements OnInit, OnChanges { + + @ViewChild('input_text') inputEl: ElementRef; + + @Input() action: ActionWait; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + delayTime: number; + + constructor() { } + + ngOnInit(): void { + } + + ngOnChanges() { + const waitInSec = this.action.millis / 1000 + this.delayTime = waitInSec; + } + + formatLabel(value: number) { + return value + 's'; + } + + updateWaitValue(event) { + const msvalue = event.value * 1000 + + this.action.millis = msvalue + this.updateAndSaveAction.emit() + // this.delayTime = msvalue + } + + onFocusInput(){ + setTimeout(() => { + this.inputEl.nativeElement.focus(); + }, 500); + } + + onFocusOut(){ + this.updateAndSaveAction.emit() + } + + onChangeText(event){ + const msvalue = event * 1000 + this.action.millis = msvalue + } + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait.component.spec.ts new file mode 100644 index 000000000..67a96cddd --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWaitComponent } from './cds-action-wait.component'; + +describe('CdsActionWaitComponent', () => { + let component: CdsActionWaitComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWaitComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWaitComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.html new file mode 100644 index 000000000..ee4c1eadd --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.html @@ -0,0 +1,279 @@ +
+
+ + + {{action.method}} + + +
+ +
+ {{action.url}} +
+
+ {{'CDSCanvas.EnterRequestURL' | translate}} +
+ +
+
+ + {{ 'CDSCanvas.AssignResultTo' | translate }}: + {{ action.assignResultTo }} + + + {{ 'CDSCanvas.AssignStatusTo' | translate }}: + {{ action.assignStatusTo }} + + + {{ 'CDSCanvas.AssignErrorTo' | translate }}: + {{ action.assignErrorTo }} + + +
+
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss new file mode 100644 index 000000000..5e19259fd --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss @@ -0,0 +1,308 @@ +::-webkit-scrollbar { + width: 0px; +} + + +.content { + // max-height: calc(100vh - 220px); + padding: 20px 0px; + margin-left: 30px; + margin-right: 30px; + overflow: auto; +} + + +.cds-web-request-options { + margin: 10px 0px; + display: flex; + gap: 10px; + position: relative; + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + .cds-rigth{ + // position: absolute; + // right: 18px; + // top: -6px; + .btn{ + padding: 8px 12px; + margin: 2px 10px; + } + } +} + +.cds-web-request-row{ + display: flex; + flex-direction: column; + gap: 10px; +} + + +.input-group .input-group-addon { + border: 0; + background: transparent; + padding: 6px 0; + display: flex; + align-items: center; +} +.cds-input-group { + // margin: 10px 10px; + display: flex; + flex-wrap: nowrap; + input { + border: 0; + background: #fff; + margin: 6px 0px 0; + height: 36px; + width: 100%; + padding: 0 10px; + border-radius: 0px 4px 4px 0px; + } + +} + +// .form-control-select { +// width: 120px!important; +// } +// .form-control-select ::ng-deep .ng-select-container { +// cursor: default; +// display: flex; +// outline: none; +// overflow: hidden; +// position: relative; +// width: 100%; +// border-radius: 4px 0px 0px 4px; +// background: #f2f2f2; +// font-weight: bold; +// } +// .form-control-select.ng-select-focused ::ng-deep .ng-select-container { +// border-color: transparent; +// border: 1; +// box-shadow: none; +// } +// .ng-select { +// position: relative; +// display: block; +// box-sizing: border-box; +// width: 120px; +// } + +.cds-web-request-row-body { + display: flex; + font-size: 0.8em; + line-height: normal; + padding: 0px; + margin: 0px; + span{ + line-height: normal; + min-height: 30px; + align-items: center; + display: flex; + justify-content: center; + } + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + &.json-error-yes { + transition-delay: 0s; + transition: all 0.3s; + padding: 10px; + margin: 10px 0px; + color: rgb(209, 47, 25); + background: rgb(251, 227, 228); + border-color: rgb(251, 194, 196); + } +} + + +.cds-web-request-row-setting{ + display: flex; + align-items: flex-end; + .setting-left{ + display: flex; + flex-direction: column; + width: 70%; + } + .setting-right{ + width: 30%; + } + +} + + +/** CSS textarea */ +.text-editor-wrapper { + font-size: var(--font-size-base); + position: relative; + width: 100%; + //height: auto; + margin: 0; + padding: 0; + margin-bottom: 20px; +} + +.field-box { + display: flex; + flex-direction: column; + // width: 70%; + // min-width: 90px; + // gap: 10px; +} + +.material-icons { + color: var(--icon-color); + font-size: 18px; +} + +cds-select#method ::ng-deep{ + // padding: 6px 0; + min-width:120px; + .ng-select-container{ + height: 37px; + border-radius: var(--input-border-radius-base) 0px 0px var(--input-border-radius-base); + } +} + +// cds-textarea#assignTo ::ng-deep { +// display: flex; +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } + +cds-textarea#url ::ng-deep { + display: flex; + width: calc(100% - 120px); + // .focus-out { + // position: relative; + // } + // .focus-in { + // position: absolute; + // z-index: 2; + // width: 100%; + // } + .div-textarea { + width: 100%; + } + textarea { + border-radius: 0px var(--input-border-radius-base) var(--input-border-radius-base) 0px; + min-height: 27px; + } +} + +cds-textarea#body.jsonError ::ng-deep, +cds-textarea#timeout.jsonError ::ng-deep { + // textarea { + // border: 1px solid red !important; + // } +} + +/** button TOOGLE */ +mat-button-toggle-group ::ng-deep{ + border: unset; + border-radius: 0px; +} + +mat-button-toggle{ + background-color: transparent; + border: none; + color: var(--blu-light-02); + border-bottom: 2px solid transparent; + + &.mat-button-toggle-checked{ + border-color: var(--blu); + color: var(--blu); + font-weight: 400; + + } + + &.mat-button-toggle+mat-button-toggle.mat-button-toggle{ + border-left: none; + } + + &::ng-deep .mat-button-toggle-label-content { + line-height: 36px; + } +} + + +.action-row-left { + width: auto; + justify-content: flex-start; +} +.action-row-left { + width: auto; + justify-content: flex-start; +} + + +.action-row-right { + display: block; +} + +.output-assignments { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; + font-size: 11px; + line-height: 16px; + flex-wrap: wrap; + .tag { + display: flex; + width: fit-content; + border-radius: 4px; + font-size: 10px; + margin: 3px; + height: fit-content; + padding: 0px 6px; + background-color: var(--blu); + color: var(--color-white-hex); + flex-wrap: nowrap; + text-align: end; + } +} + +.output-item { + display: inline-flex; + align-items: center; + gap: 4px; + min-width: 0; +} + +.output-key { + opacity: 0.75; + white-space: nowrap; +} + +.output-val { + min-width: 0; + max-width: 140px; + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.output-empty { + opacity: 0.6; +} + +.cds-attributes ::ng-deep{ + .liquidjs-menu { + width: calc(100% - 15px); + .liquidjs-button { + margin-top: 16px!important; + margin-right: -25px !important; + z-index: 1; + } + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.ts new file mode 100644 index 000000000..bbbb152be --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.ts @@ -0,0 +1,391 @@ +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs/internal/Subscription'; + +//SERVICES +import { IntentService } from '../../../../../services/intent.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +//MODELS +import { Intent } from 'src/app/models/intent-model'; +import { ActionWebRequestV2 } from 'src/app/models/action-model'; + +//UTILS +import { TYPE_UPDATE_ACTION, TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from 'src/app/chatbot-design-studio/utils'; +import { variableList } from 'src/app/chatbot-design-studio/utils-variables'; +import { checkConnectionStatusOfAction, updateConnector } from 'src/app/chatbot-design-studio/utils-connectors'; +import { HEADER_TYPE, TYPE_METHOD_REQUEST } from 'src/app/chatbot-design-studio/utils-request'; +// import { CDSTextareaComponent } from '../../../base-elements/textarea/textarea.component'; + +@Component({ + selector: 'cds-action-web-request-v2-new', + templateUrl: './cds-action-web-request-v2-new.component.html', + styleUrls: ['./cds-action-web-request-v2-new.component.scss'] +}) +export class CdsActionWebRequestV2Component implements OnInit { + // @ViewChild('cdsTextareaBody', { static: false }) cdsTextareaBody!: CDSTextareaComponent; + + @Input() intentSelected: Intent; + @Input() action: ActionWebRequestV2; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + methods: Array<{label: string, value: string}>; + optionSelected: 'header' | 'body' = 'header' + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonHeader: any; + jsonSettings: any; + body: string = null + jsonIsValid = true; + errorMessage: string; + methodSelectedHeader = true; + methodSelectedBody = false; + headerAttributes: any; + autocompleteHeaderOptions: Array<{label: string, value: string}> = []; + + valueIsInvalid: boolean = false; + + // hasSelectedVariable: boolean = false; + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + bodyOptions: Array<{name: string, value: string, disabled: boolean, checked: boolean}>= [ + {name: 'none', value: 'none', disabled: false, checked: true }, + {name: 'Json', value: 'json', disabled: false, checked: false }, + {name: 'form-data', value: 'form-data', disabled: false, checked: false } + ] + bodyType: 'none' | 'json' | 'form-data' = 'none'; + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private readonly intentService: IntentService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-WEB-REQUEST-v2] action detail: ", this.action); + this.subscriptionChangedConnector = this.intentService.isChangedConnector$.subscribe((connector: any) => { + this.logger.debug('[ACTION-WEB-REQUEST-v2] isChangedConnector -->', connector); + let connectorId = this.idIntentSelected+"/"+this.action._tdActionId; + if(connector.fromId.startsWith(connectorId)){ + this.connector = connector; + this.updateConnector(); + } + }); + this.initialize(); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + ngOnChanges(changes: SimpleChanges) { + // on change + this.initialize(); + if(this.intentSelected){ + this.initializeConnector(); + } + this.logger.log('[ACTION-WEB-REQUEST-v2] onChanges' , this.action, this.intentSelected ) + // if (this.action && this.action.assignStatusTo) { + // this.hasSelectedVariable = true + // } + } + + initializeConnector() { + this.idIntentSelected = this.intentSelected.intent_id; + this.idConnectorTrue = this.idIntentSelected+'/'+this.action._tdActionId + '/true'; + this.idConnectorFalse = this.idIntentSelected+'/'+this.action._tdActionId + '/false'; + this.listOfIntents = this.intentService.getListOfIntents(); + this.checkConnectionStatus(); + } + + private checkConnectionStatus(){ + const resp = checkConnectionStatusOfAction(this.action, this.idConnectorTrue, this.idConnectorFalse); + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + } + + /** */ + private updateConnector(){ + this.logger.log('[ACTION WEB-REQUEST-v2] updateConnector:'); + const resp = updateConnector(this.connector, this.action, this.isConnectedTrue, this.isConnectedFalse, this.idConnectionTrue, this.idConnectionFalse); + if(resp){ + this.isConnectedTrue = resp.isConnectedTrue; + this.isConnectedFalse = resp.isConnectedFalse; + this.idConnectionTrue = resp.idConnectionTrue; + this.idConnectionFalse = resp.idConnectionFalse; + this.logger.log('[ACTION WEB-REQUEST-v2] updateConnector:', resp); + if (resp.emit) { + this.updateAndSaveAction.emit({ type: TYPE_UPDATE_ACTION.CONNECTOR, element: this.connector }); + } + } + } + + + // CUSTOM FUNCTIONS // + private initialize(){ + this.initializeAttributes(); + this.methods = Object.keys(TYPE_METHOD_REQUEST).map((key, index) => { + return { label: key, value: key } + }) + this.jsonHeader = this.action.headersString + this.bodyOptions.forEach(el => { el.value ===this.action.bodyType? el.checked= true: el.checked = false }) + // this.jsonIsValid = this.isValidJson(this.action.jsonBody); + + if(this.action.jsonBody){ + //this.body = this.checkAndSetJsonBody(this.action.jsonBody); + this.body = this.action.jsonBody; + this.body = this.formatJSON(this.body, "\t"); + } + this.jsonSettings = { timeout: 20000} + if(this.action.settings){ + this.jsonSettings = this.action.settings + } + if(!this.action.formData){ + this.action.formData = [] + } + this.assignments = this.action.assignments + if(this.intentSelected){ + this.initializeConnector(); + } + this.autocompleteHeaderOptions = []; + HEADER_TYPE.forEach(el => this.autocompleteHeaderOptions.push({label: el.label, value: el.value})) + + } + + private initializeAttributes() { + let new_attributes = []; + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'result')) { + new_attributes.push({ name: "result", value: "result" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'status')) { + new_attributes.push({ name: "status", value: "status" }); + } + if (!variableList.find(el => el.key ==='userDefined').elements.some(v => v.name === 'error')) { + new_attributes.push({ name: "error", value: "error" }); + } + variableList.find(el => el.key ==='userDefined').elements = [ ...variableList.find(el => el.key ==='userDefined').elements, ...new_attributes]; + this.logger.debug("[ACTION-WEB-REQUEST-v2] Initialized variableList.userDefined: ", variableList.find(el => el.key ==='userDefined')); + } + + + private formatJSON(input, indent) { + if (input.length == 0) { + return ''; + } + else { + try { + var parsedData = JSON.parse(input); + return JSON.stringify(parsedData, null, indent); + } catch (e) { + return input; + } + } + } + + private isValidJson(json) { + try { + JSON.parse(json); + this.errorMessage = null; + return true; + } catch (e) { + this.errorMessage = e; + return false; + } + } + + + // EVENT FUNCTIONS // + onChangeMethodButton(e: {label: string, value: string}){ + this.action.method = e.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeButtonSelect(event: {name: string, value: string, disabled: boolean, checked: boolean}){ + this.bodyOptions.forEach(el => { el.value ===event.value? el.checked = true: el.checked = false }) + this.bodyOptions.forEach(el => { el.value ===event.value? el.checked = true: el.checked = false }) + this.action.bodyType= event.value + switch (event.value){ + case 'none': + this.bodyType = 'none'; + this.bodyType = 'none'; + this.body = JSON.stringify({}) + delete this.jsonHeader['Content-Type'] + break; + case 'json': + this.bodyType = 'json'; + this.body = this.action.jsonBody; + this.jsonHeader['Content-Type'] = 'application/json'; + // this.body = this.checkAndSetJsonBody(this.action.jsonBody); + break; + case 'form-data': + this.bodyType = 'form-data'; + this.bodyType = 'form-data'; + this.jsonHeader['Content-Type'] = 'multipart/form-data' + break; + } + this.action.headersString = this.jsonHeader + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeTextarea(e, type: 'url' | 'body' | 'setting'){ + switch(type){ + case 'body': { + this.body = e; + // // setTimeout(() => { + // this.jsonIsValid = this.isValidJson(this.body); + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + // }, 0); + break; + } + case 'url' : { + this.action.url = e; + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + break; + } + case 'setting': { + if(isNaN(+e)){ + this.valueIsInvalid = true; + break; + } + this.valueIsInvalid = false; + this.jsonSettings.timeout = +e; + this.action['settings'] = this.jsonSettings; + break; + } + } + } + + onBlur(event){ + // this.action.jsonBody = this.checkAndSetJsonBody(this.body); + // this.body = this.action.jsonBody; + this.action.jsonBody = this.body; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeOption(event: 'header'|'body'){ + switch(event){ + case 'header': + this.jsonHeader = this.action.headersString; + break; + case 'body': + break; + } + } + + onChangeAttributes(attributes:any){ + this.logger.log('onChangeAttributes'); + this.action.headersString = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributesResponse(attributes:{[key: string]: string }){ + this.action.assignments = attributes ; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onFormDataChanged(event){ + this.logger.log('[ACTION-WEB-REQUEST-v2] onFormDataChanged --> ', event) + this.action.formData= event + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-WEB-REQUEST-v2] onEditableDivTextChange event", event) + this.logger.log("[ACTION-WEB-REQUEST-v2] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + // onSelectedAttribute2(event, property) { + // if (this.cdsTextareaBody) { + // // const cursorPosition = this.cdsTextareaBody.getCursorPosition(); + // this.logger.log("[ACTION-WEB-REQUEST-v2] onSelectedAttribute2 textarea",event); + // const textarea: HTMLTextAreaElement = this.cdsTextareaBody.textAreaElement.nativeElement; + + // const cursorPosition = textarea.selectionStart; + // this.logger.log("[ACTION-WEB-REQUEST-v2] onSelectedAttribute2 cursorPosition", textarea); + // const textBeforeCursor = this.body.slice(0, cursorPosition); // Testo fino al cursore + // this.logger.log("[ACTION-WEB-REQUEST-v2] onSelectedAttribute2 textBeforeCursor", textBeforeCursor); + // // Regex per individuare solo l'ultima istanza di {{...}} immediatamente prima del cursore + // const regex = new RegExp(`{{\\s*${event.value}\\s*}}`, 'g'); // Cerca tutte le istanze + // const matches = textBeforeCursor.match(regex); + // const match = matches?matches[matches.length - 1] : null; + // //const match = textBeforeCursor.match(regex); + // this.logger.log("[ACTION-WEB-REQUEST-v2] onSelectedAttribute2", match); + + // if (match) { + // const extractedText = match;//[0]; + // this.logger.log("[ACTION-WEB-REQUEST-v2] extractedText", extractedText); + // // Modifica il testo estratto (ad esempio, aggiunge '-modificato') + // const modifiedText = this.checkAndSetJsonBody(extractedText); + // // Sostituisce solo il testo trovato immediatamente prima del cursore + // const updatedTextBeforeCursor = textBeforeCursor.replace(extractedText, modifiedText); + // this.body = updatedTextBeforeCursor + this.body.slice(cursorPosition); // Combina il testo aggiornato con il resto + // // Aggiorna la textarea con il nuovo contenuto + // textarea.value = this.body; + // } + // } + // } + + // checkAndSetJsonBody(jsonBody){ + // this.logger.log('[ACTION-WEB-REQUEST-v2] jsonBody:: ', jsonBody); + // return jsonBody.replace(/{{(.*?)}}/g, (match, content) => { + // if (match.includes('| json') || match.includes('|json')) { + // return match; + // } else { + // return `{{ ${content.trim()} | json }}`; + // } + // }); + // } + + + onChangeBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + if(event){ + this.action[type]=event.value + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'create', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + } + + onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') { + switch(type){ + case 'trueIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorTrue, toId: this.action.trueIntent}) + break; + case 'falseIntent': + this.onConnectorChange.emit({ type: 'delete', fromId: this.idConnectorFalse, toId: this.action.falseIntent}) + break; + } + this.action[type] = null; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2.component.spec.ts new file mode 100644 index 000000000..1e92adc40 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWebRequestV2Component } from './cds-action-web-request-v2.component'; + +describe('CdsActionWebRequestV2Component', () => { + let component: CdsActionWebRequestV2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWebRequestV2Component ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWebRequestV2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.html new file mode 100644 index 000000000..f2e7a1b0b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.html @@ -0,0 +1,60 @@ +
+ +
+
+
Key
+
Value
+
+ +
+ +
+ + +
+ + +
+ + + + +
+ + + + + +
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss new file mode 100644 index 000000000..6785123e3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss @@ -0,0 +1,115 @@ +:host { + --background-color: var(--blu-light-01); + --column-color: var(--blu-02); + --text-color: var(--blu); + + --content-background: rgb(244, 246, 251, 0.4); + --base-radius: 8px +} + +.form-data-wrp{ + background: var(--background-color); + padding: 10px; +} + +.form-data-row-header{ + display: grid; + width: 100%; + grid-template-columns: 0.05fr 0.5fr 0.45fr; + font-size: 14px; +} +.form-data-row{ + display: flex; + align-items: center; + justify-content: center; +} + +.input-group{ + justify-content: flex-end; +} + +cds-textarea#key ::ng-deep, +cds-textarea#value ::ng-deep { + // width: calc(50% - 2px); + .editor-utils { + display: flex; + align-items: center; + gap: 5px; + position: absolute; + bottom: -8px; + right: 4px; + z-index: 1; + } + textarea { + max-height: 41px; + cursor: default; + display: flex; + position: relative; + border-radius: var(--base-radius) 0 0 var(--base-radius); + font-weight: 500; + font-size: 12px; + margin: 3px 0px 3px 0; + padding: 0 10px 0 10px !important; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + resize: none!important; + } +} + +cds-textarea{ + display: flex; + + &#key{ + width: 68%; + } +} + +cds-textarea#key ::ng-deep { + textarea{ + border-right: 0; + } +} + +cds-textarea#value ::ng-deep { + + textarea{ + border-radius: 0 var(--base-radius) var(--base-radius) 0; + border-left: 0; + } +} + +cds-select#method{ + display: flex; + align-items: center; + width: 30%; + margin: 0; + + ::ng-deep{ + + .select-bot-box{ + width: 100% + } + + .ng-select .ng-select-container { + height: 28px; + min-height: 28px; + border-radius: 0; + } + .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{ + top: unset; + } + + .ng-select .ng-select-container .ng-value span.label-select{ + font-size: 12px; + } + + + } +} + +::ng-deep { + .ng-dropdown-panel .ng-dropdown-panel-items .ng-option span.label-select{ + font-size: 12px; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.ts new file mode 100644 index 000000000..499f04d30 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.ts @@ -0,0 +1,87 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormData } from 'src/app/models/action-model'; + +@Component({ + selector: 'cds-form-data-new', + templateUrl: './form-data-new.component.html', + styleUrls: ['./form-data-new.component.scss'] +}) + + + +export class FormDataComponent implements OnInit { + + @Input() dataRows: Array + @Output() onDataRowChanged = new EventEmitter>() + + methods: Array<{label: string, value: string}> = [ + { label: 'Text', value: 'Text'}, + { label: 'URL', value: 'URL'} + ] + constructor() { } + + ngOnInit(): void { + + } + + ngOnChanges(){ + this.initialize() + } + + + initialize(){ + if(!this.dataRows || this.dataRows.length === 0){ + this.dataRows.push(new FormData()) + } + } + + onCheckboxChanged(event, index: number){ + this.dataRows[index].enabled = event.checked + this.onDataRowChanged.emit(this.dataRows) + } + + onChangeMethodButton(e: {label: string, value: 'Text' | 'URL'}, index: number){ + this.dataRows[index].type = e.value; + this.onDataRowChanged.emit(this.dataRows) + } + + onChangeTextarea(e, type: 'name' | 'value', index: number){ + switch(type){ + case 'name': { + this.dataRows[index]['name'] = e + break; + } + case 'value' : { + this.dataRows[index]['value'] = e + break; + } + } + this.onChangeDataRow(index) + } + + onBlur(event){ + this.onDataRowChanged.emit(this.dataRows); + } + + + onChangeDataRow(index: number){ + let row = this.dataRows[index] + let that = this; + if(row.name.length>0 || row.value.length>0){ + if (index == this.dataRows.length-1){ + this.dataRows.push(new FormData()); + } + } else { + this.dataRows.forEach(function(item, index, object) { + if(!item.name && !item.value){ + if (index < that.dataRows.length-1){ + object.splice(index, 1); + } + } + }); + } + + // this.setChangedAttributes(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data.component.spec.ts new file mode 100644 index 000000000..4e712f3cd --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormDataComponent } from './form-data.component'; + +describe('FormDataComponent', () => { + let component: FormDataComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FormDataComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FormDataComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.html new file mode 100644 index 000000000..79854b814 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.html @@ -0,0 +1,103 @@ +
+ +
+ + + {{ action.method}} + + +
+
+ {{action.url}} +
+
+ {{' CDSCanvas.EnterRequestURL' | translate}} +
+ + +
+ + + +
+ +
+ + + + +
+ +
+
+ Header +
+
+ Body +
+
+ +
+
+ +
+ + + + + + +
+ +
+ + {{errorMessage}} +
+ + +
+
+ + + +
+
+ + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss new file mode 100644 index 000000000..090d529ae --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss @@ -0,0 +1,274 @@ +::-webkit-scrollbar { + width: 0px; +} + + +.content { + //padding: 10px 30px; + padding: 20px 0px; + margin-left: 30px; + margin-right: 30px; + max-height: calc(100vh - 223px); + overflow: auto; +} + + + +.cds-web-request-row { + margin: 10px 0px; + padding: 0px 2px; + display: flex; + gap: 10px; + position: relative; + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + .cds-rigth{ + // position: absolute; + // right: 18px; + // top: -6px; + .btn{ + padding: 8px 12px; + margin: 2px 10px; + } + } +} +.label-assign-to { + cursor: default; + display: flex; + outline: none; + overflow: hidden; + position: relative; + width: 150px; + height: 36px; + border-radius: 4px 0 0 4px; + background: #f2f2f2; + font-weight: 700; + margin: 6px 0; + padding: 8px 0 0 10px; +} +.input-group .input-group-addon { + border: 0; + background: transparent; + padding: 6px 0; + display: flex; + align-items: center; +} +.cds-input-group { + // margin: 10px 10px; + display: flex; + flex-wrap: nowrap; + input { + border: 0; + background: #fff; + margin: 6px 0px 0; + height: 36px; + width: 100%; + padding: 0 10px; + border-radius: 0px 4px 4px 0px; + } + +} + +.form-control-select { + width: 120px!important; +} +.form-control-select ::ng-deep .ng-select-container { + cursor: default; + display: flex; + outline: none; + overflow: hidden; + position: relative; + width: 100%; + border-radius: 4px 0px 0px 4px; + background: #f2f2f2; + font-weight: bold; +} +.form-control-select.ng-select-focused ::ng-deep .ng-select-container { + border-color: transparent; + border: 1; + box-shadow: none; +} +.ng-select { + position: relative; + display: block; + box-sizing: border-box; + width: 120px; +} + +.add-response { + text-align: center; + cursor: pointer; + box-sizing: border-box; + outline: none; + padding: 0; + span { + align-items: center; + display: flex; + width: 80px; + padding: 8px; + justify-content: center; + background: var(--blu-light-01); + color: var(--blu); + border-radius: 6px; + height: 40px; + font-size: 0.8em; + border: 1px solid #0F172A; + font-weight: 400; + &:hover { + outline: 2px solid rgba(236,182,6,.6901960784)!important; + } + &.cds-action-active { + outline: 2px solid rgba(236,182,6,.6901960784)!important; + } + } +} + +.cds-web-request-row-error { + display: flex; + font-size: 0.8em; + line-height: normal; + border-radius: 4px; + color: rgb(209, 47, 25); + background: rgb(251, 227, 228); + border-color: rgb(251, 194, 196); + opacity: 1; + height: 0px; + padding: 0px; + margin: 0px; + span{ + line-height: normal; + min-height: 30px; + align-items: center; + display: flex; + justify-content: center; + } + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + &.json-error-yes { + transition-delay: 0s; + transition: all 0.3s; + height: auto; + padding: 10px; + margin: 10px 0px; + } +} + +.cds-attributes { + display: block; + width: 100%; + // margin: 6px 15px; +} + + + + +/** CSS textarea */ + +.material-icons { + color: var(--icon-color); + font-size: 18px; +} + +cds-select#method ::ng-deep{ + // padding: 6px 0; + min-width:120px; + .ng-select-container{ + height: 37px; + border-radius: var(--input-border-radius-base) 0px 0px var(--input-border-radius-base); + border: 1px solid rgb(118, 118, 118) !important; + } +} + +// cds-textarea#assignTo ::ng-deep { +// display: flex; +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } + +cds-textarea#url ::ng-deep { + display: flex; + width: 100%; + // padding: 6px 0px 0px 0; + textarea { + border: 1px solid rgb(118, 118, 118) !important; + border-radius: 0px var(--input-border-radius-base) var(--input-border-radius-base) 0px; + resize: none !important; + padding: 6px 16px !important; + height: 23px !important; + min-height: 23px !important; + } +} + +cds-textarea#body.jsonError ::ng-deep { + textarea { + border: 1px solid red !important; + } +} + +div.value-wrp { + min-height: 50px; +} +/* +div.value-wrp { + position: relative; + min-height: 40px; + .flex{ + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + .close{ + position: absolute; + display: flex; + top: -7px; + right: -7px; + width: 18px; + height: 18px; + font-size: 14px; + border-radius: 50%; + background: #fff; + border: 1px solid #ecb607; + color: #ecb606; + cursor: pointer; + opacity: 1; + justify-content: center; + align-items: center; + padding: 2px; + margin: 0; + &:hover{ + background: #ecb606; + color: white; + } + } + } + + div.tag { + position: absolute; + top: 0; + bottom: 0; + left: 0px; + right: unset; + border-radius: 7px; + margin: 5px 0; + padding: 5px 10px; + background-color: #ecb606; + color: #fff; + min-height: 30px; + height: fit-content; + } +} +*/ \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.ts new file mode 100644 index 000000000..9e30f2b1f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.ts @@ -0,0 +1,170 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { ActionWebRequest } from 'src/app/models/action-model'; +import { TYPE_METHOD_ATTRIBUTE, TEXT_CHARS_LIMIT } from '../../../../../utils'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +import { TYPE_METHOD_REQUEST } from 'src/app/chatbot-design-studio/utils-request'; + +@Component({ + selector: 'cds-action-web-request-new', + templateUrl: './cds-action-web-request-new.component.html', + styleUrls: ['./cds-action-web-request-new.component.scss'] +}) +export class CdsActionWebRequestNewComponent implements OnInit { + + @Input() action: ActionWebRequest; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + methods: Array<{label: string, value: string}>; + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonHeader: any; + jsonBody: string; + jsonIsValid = true; + errorMessage: string; + methodSelectedHeader = true; + methodSelectedBody = false; + headerAttributes: any; + + hasSelectedVariable: boolean = false; + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + assignments: {} = {} + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + // on init + } + + ngOnChanges() { + // on change + this.initialize(); + if (this.action && this.action.assignTo) { + this.hasSelectedVariable = true + } + } + + + // CUSTOM FUNCTIONS // + private initialize(){ + this.methods = Object.keys(TYPE_METHOD_REQUEST).map((key, index) => { + return { label: key, value: key } + }) + this.jsonHeader = this.action.headersString; + this.jsonIsValid = this.isValidJson(this.action.jsonBody); + if(this.jsonIsValid){ + this.jsonBody = this.action.jsonBody; + this.jsonBody = this.formatJSON(this.jsonBody, "\t"); + } + this.assignments = this.action.assignments + } + + private setActionWebRequest(){ + this.action.jsonBody = this.jsonBody; + this.updateAndSaveAction.emit() + } + + private formatJSON(input, indent) { + if (input.length == 0) { + return ''; + } + else { + try { + var parsedData = JSON.parse(input); + return JSON.stringify(parsedData, null, indent); + } catch (e) { + return input; + } + } + } + + private isValidJson(json) { + try { + JSON.parse(json); + this.errorMessage = null; + return true; + } catch (e) { + this.errorMessage = e; + return false; + } + } + + + // EVENT FUNCTIONS // + onChangeMethodButton(e: {label: string, value: string}){ + this.action.method = e.value; + this.updateAndSaveAction.emit() + } + + onChangeTextarea(e, type: 'url' | 'jsonBody'){ + this.logger.debug('onChangeTextarea:', e, type ); + switch(type){ + case 'jsonBody': { + this.jsonBody = e; + this.setActionWebRequest(); + setTimeout(() => { + this.jsonIsValid = this.isValidJson(this.jsonBody); + this.updateAndSaveAction.emit() + }, 500); + break; + } + case 'url' : { + this.action.url = e + this.updateAndSaveAction.emit() + } + } + + } + + onChangeParamsButton(){ + if(this.methodSelectedHeader){ + this.methodSelectedHeader = false; + this.methodSelectedBody = true; + this.jsonHeader = this.action.headersString; + } else if(this.methodSelectedBody){ + this.methodSelectedHeader = true; + this.methodSelectedBody = false; + } + this.jsonIsValid = this.isValidJson(this.jsonBody); + this.setActionWebRequest(); + } + + onJsonFormatter(){ + try { + this.jsonBody = this.formatJSON(this.jsonBody, "\t"); + } + catch (err) { + this.logger.error('error:', err); + } + } + + onChangeAttributes(attributes:any){ + this.action.headersString = attributes; + this.updateAndSaveAction.emit() + // this.jsonHeader = attributes; + } + + onClearSelectedAttribute(){ + this.action.assignTo = ''; + this.hasSelectedVariable = false; + this.updateAndSaveAction.emit() + } + + onSelectedAttribute(variableSelected: {name: string, value: string}, step: number){ + this.hasSelectedVariable = true; + this.action.assignTo = variableSelected.value; + this.updateAndSaveAction.emit() + } + + + onChangeAttributesResponse(attributes:{[key: string]: string }){ + this.action.assignments = attributes ; + this.updateAndSaveAction.emit() + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request.component.spec.ts new file mode 100644 index 000000000..7fd6ffe58 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWebRequestComponent } from './cds-action-web-request.component'; + +describe('CdsActionWebRequestComponent', () => { + let component: CdsActionWebRequestComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWebRequestComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWebRequestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.html new file mode 100644 index 000000000..19996cfbb --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.html @@ -0,0 +1,94 @@ +
+ +
+
+ + + +
+
+ {{'CDSCanvas.Status' | translate }}: {{action?.status}} +
+ +
+ {{'CDSCanvas.StatusNotSelected' | translate}} +
+
+ +
+ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss new file mode 100644 index 000000000..b0eb5e640 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss @@ -0,0 +1,246 @@ +::-webkit-scrollbar { + width: 0px; +} + + +.content { + // max-height: calc(100vh - 220px); + padding: 20px 0px; + margin-left: 30px; + margin-right: 30px; + overflow: auto; +} + + +.cds-web-request-options { + margin: 10px 0px; + display: flex; + gap: 10px; + position: relative; + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + .cds-rigth{ + // position: absolute; + // right: 18px; + // top: -6px; + .btn{ + padding: 8px 12px; + margin: 2px 10px; + } + } +} + +.cds-web-request-row{ + display: flex; + flex-direction: column; + gap: 10px; +} + + +.input-group .input-group-addon { + border: 0; + background: transparent; + padding: 6px 0; + display: flex; + align-items: center; +} +.cds-input-group { + // margin: 10px 10px; + display: flex; + flex-wrap: nowrap; + input { + border: 0; + background: #fff; + margin: 6px 0px 0; + height: 36px; + width: 100%; + padding: 0 10px; + border-radius: 0px 4px 4px 0px; + } + +} + +// .form-control-select { +// width: 120px!important; +// } +// .form-control-select ::ng-deep .ng-select-container { +// cursor: default; +// display: flex; +// outline: none; +// overflow: hidden; +// position: relative; +// width: 100%; +// border-radius: 4px 0px 0px 4px; +// background: #f2f2f2; +// font-weight: bold; +// } +// .form-control-select.ng-select-focused ::ng-deep .ng-select-container { +// border-color: transparent; +// border: 1; +// box-shadow: none; +// } +// .ng-select { +// position: relative; +// display: block; +// box-sizing: border-box; +// width: 120px; +// } + +.cds-web-request-row-body { + display: flex; + font-size: 0.8em; + line-height: normal; + padding: 0px; + margin: 0px; + span{ + line-height: normal; + min-height: 30px; + align-items: center; + display: flex; + justify-content: center; + } + &.center{ + display: flex; + align-items: center; + justify-content: center; + } + &.json-error-yes { + transition-delay: 0s; + transition: all 0.3s; + padding: 10px; + margin: 10px 0px; + color: rgb(209, 47, 25); + background: rgb(251, 227, 228); + border-color: rgb(251, 194, 196); + } +} + + +.cds-web-request-row-setting{ + display: flex; + align-items: flex-end; + .setting-left{ + display: flex; + flex-direction: column; + width: 70%; + } + .setting-right{ + width: 30%; + } + +} + + +/** CSS textarea */ +.text-editor-wrapper { + font-size: var(--font-size-base); + position: relative; + width: 100%; + //height: auto; + margin: 0; + padding: 0; + margin-bottom: 20px; +} + +.field-box { + display: flex; + flex-direction: column; + // width: 70%; + // min-width: 90px; + // gap: 10px; +} + +.material-icons { + color: var(--icon-color); + font-size: 18px; +} + +cds-select#method ::ng-deep{ + // padding: 6px 0; + min-width:120px; + .ng-select-container{ + height: 37px; + border-radius: var(--input-border-radius-base) 0px 0px var(--input-border-radius-base); + } +} + +// cds-textarea#assignTo ::ng-deep { +// display: flex; +// textarea { +// border: 1px solid rgb(118, 118, 118) !important; +// resize: none !important; +// padding: 8px 20px !important; +// height: 25px !important; +// min-height: 25px !important; +// } +// } + +cds-textarea#url ::ng-deep { + display: flex; + width: 100%; + // padding: 6px 0px 0px 0; + .focus-out { + position: relative; + textarea{ + height: 23px !important; + } + } + .focus-in { + position: absolute; + z-index: 2; + width: 100%; + textarea{ + min-height: 23px !important; + } + } + + textarea { + border-radius: 0px var(--input-border-radius-base) var(--input-border-radius-base) 0px; + resize: none !important; + padding: 6px 16px !important; + + // height: 23px !important; + min-height: 23px !important; + } +} + +cds-textarea#body.jsonError ::ng-deep, +cds-textarea#timeout.jsonError ::ng-deep { + textarea { + border: 1px solid red !important; + } +} + +/** button TOOGLE */ +mat-button-toggle-group ::ng-deep{ + border: unset; + border-radius: 0px; +} + +mat-button-toggle{ + background-color: transparent; + border: none; + color: var(--blu-light-02); + border-bottom: 2px solid transparent; + + &.mat-button-toggle-checked{ + border-color: var(--blu); + color: var(--blu); + font-weight: 400; + + } + + &.mat-button-toggle+mat-button-toggle.mat-button-toggle{ + border-left: none; + } + + &::ng-deep .mat-button-toggle-label-content { + line-height: 36px; + } + + +} + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.ts new file mode 100644 index 000000000..4749d49a3 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.ts @@ -0,0 +1,221 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { IntentService } from 'src/app/chatbot-design-studio/services/intent.service'; +import { TEXT_CHARS_LIMIT, TYPE_METHOD_ATTRIBUTE, TYPE_UPDATE_ACTION } from 'src/app/chatbot-design-studio/utils'; +import { TYPE_METHOD_REQUEST, HEADER_TYPE, RESPONSE_STATUS_TYPE } from 'src/app/chatbot-design-studio/utils-request'; +import { ActionWebRespose } from 'src/app/models/action-model'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: ' selector: 'cds-action-web-response-new',-new', + templateUrl: './cds-action-web-response-new.component.html', + styleUrls: ['./cds-action-web-response-new.component.scss'] +}) +export class CdsActionWebResponseNewComponent implements OnInit { + + @Input() intentSelected: Intent; + @Input() action: ActionWebRespose; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() + + listOfIntents: Array<{name: string, value: string, icon?:string}>; + + // Connectors + idIntentSelected: string; + idConnectorTrue: string; + idConnectorFalse: string; + idConnectionTrue: string; + idConnectionFalse: string; + isConnectedTrue: boolean = false; + isConnectedFalse: boolean = false; + connector: any; + private subscriptionChangedConnector: Subscription; + + methods: Array<{label: string, value: string}>; + optionSelected: 'header' | 'body' = 'body' + pattern = "^[a-zA-Z_]*[a-zA-Z_]+[a-zA-Z0-9_]*$"; + + limitCharsText = TEXT_CHARS_LIMIT; + jsonHeader: any; + jsonSettings: any; + body: string = null + jsonIsValid = true; + errorMessage: string; + methodSelectedHeader = true; + methodSelectedBody = false; + headerAttributes: any; + autocompleteHeaderOptions: Array<{label: string, value: string}> = []; + autocompleteStatusOptions: Array<{label: string, value: string}> = []; + + valueIsInvalid: boolean = false; + // hasSelectedVariable: boolean = false; + typeMethodAttribute = TYPE_METHOD_ATTRIBUTE; + type + assignments: {} = {} + + bodyOptions: Array<{name: string, value: string, disabled: boolean, checked: boolean}>= [ + {name: 'none', value: 'none', disabled: false, checked: true }, + {name: 'json', value: 'json', disabled: false, checked: false } + ] + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor( + private intentService: IntentService + ) { } + + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.debug("[ACTION-WEB-RESPONSE] action detail: ", this.action); + } + + /** */ + ngOnDestroy() { + if (this.subscriptionChangedConnector) { + this.subscriptionChangedConnector.unsubscribe(); + } + } + + ngOnChanges(changes: SimpleChanges) { + this.logger.log('[ACTION-WEB-RESPONSE] onChanges' , this.action, this.intentSelected ) + this.initialize(); + // if (this.action && this.action.assignStatusTo) { + // this.hasSelectedVariable = true + // } + } + + // private checkConnectionStatus(){ + // if(this.action.trueIntent){ + // this.isConnectedTrue = true; + // } else { + // this.isConnectedTrue = false; + // } + // if(this.action.falseIntent){ + // this.isConnectedFalse = true; + // } else { + // this.isConnectedFalse = false; + // } + // } + + + + + + // CUSTOM FUNCTIONS // + private initialize(){ + this.methods = Object.keys(TYPE_METHOD_REQUEST).map((key, index) => { + return { label: key, value: key } + }) + this.jsonHeader = this.action.headersString + this.bodyOptions.forEach(el => { el.value ===this.action.bodyType? el.checked= true: el.checked = false }) + // this.jsonIsValid = this.isValidJson(this.action.jsonBody); + if(this.action.payload){ + this.body = this.action.payload; + this.body = this.formatJSON(this.body, "\t"); + } + this.jsonSettings = { timeout: 20000} + + this.assignments = this.action.assignments + this.autocompleteHeaderOptions = []; + HEADER_TYPE.forEach(el => this.autocompleteHeaderOptions.push({label: el.label, value: el.value})) + RESPONSE_STATUS_TYPE.forEach(el => this.autocompleteStatusOptions.push({label: el.label, value: el.value})) + } + + + private formatJSON(input, indent) { + if (input.length == 0) { + return ''; + } + else { + try { + var parsedData = JSON.parse(input); + return JSON.stringify(parsedData, null, indent); + } catch (e) { + return input; + } + } + } + + private isValidJson(json) { + try { + JSON.parse(json); + this.errorMessage = null; + return true; + } catch (e) { + this.errorMessage = e; + return false; + } + } + + + // EVENT FUNCTIONS // + onChangeButtonSelect(event: {name: string, value: string, disabled: boolean, checked: boolean}){ + this.bodyOptions.forEach(el => { el.value ===event.value? el.checked= true: el.checked = false }) + this.action.bodyType= event.value + switch (event.value){ + case 'none': + this.body = JSON.stringify({}) + delete this.jsonHeader['Content-Type'] + break; + case 'json': + this.body = this.action.payload + this.jsonHeader['Content-Type'] = 'application/json' + break; + } + this.action.headersString = this.jsonHeader + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeTextarea(e, type: string){ + switch(type){ + case 'body': { + this.body = e; + this.action.payload = this.body; + + // setTimeout(() => { + // this.jsonIsValid = this.isValidJson(this.body); + // this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + // }, 0); + break; + } + default: { + this.action[type]=e + } + } + } + + onBlur(event){ + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeOption(event: 'header'|'body'){ + switch(event){ + case 'header': + this.jsonHeader = this.action.headersString; + break; + case 'body': + break; + } + } + + onChangeAttributes(attributes:any){ + this.logger.log('onChangeAttributes'); + this.action.headersString = attributes; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onChangeAttributesResponse(attributes:{[key: string]: string }){ + this.action.assignments = attributes ; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + + onSelectedAttribute(event, property) { + this.logger.log("[ACTION-WEB-RESPONSE] onEditableDivTextChange event", event) + this.logger.log("[ACTION-WEB-RESPONSE] onEditableDivTextChange property", property) + this.action[property] = event.value; + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response.component.spec.ts new file mode 100644 index 000000000..17ee2f8bb --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWebResponseComponent } from './cds-action-web-response.component'; + +describe('CdsActionWebResponseComponent', () => { + let component: CdsActionWebResponseComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWebResponseComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWebResponseComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.html new file mode 100644 index 000000000..2458be7ce --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.html @@ -0,0 +1,35 @@ +
+ +
+
+ {{'CDSCanvas.AssignTo' | translate }}: +
+ +
+
+ {{action?.attributeName}} +
+
+ {{'CDSCanvas.SelectAttribute' | translate}} +
+
+
+
+ + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.scss new file mode 100644 index 000000000..8eacade6d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.scss @@ -0,0 +1,75 @@ +div{ + .flex{ + position: absolute; + top: 0px; + bottom: 0px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + + .close{ + // height: 16px; + width: 17px; + top: -7px; + right: -7px; + font-size: 15px; + border-radius: 50%; + background: white; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + &:hover{ + background: #ecb606; + color: white; + } + } + } + + div.tag{ + position: absolute; + top: 0; + bottom: 0; + left: 8px; + right: unset; + border-radius: 7px; + margin: 5px; + padding: 5px 10px; + background-color: #ecb606; + color: white; + + } +} + + +.cds-action-preview{ + .action-row-left{ + width: unset; + } + + .set-attribute-label { + color: #6c6859d9; + font-size: 12px; + margin-bottom: 0; + font-weight: 400; + // background: #e8e6dd; + padding: 0px 3px; + height: inherit; + } + + .set-attribute-value { + font-size: 10px; + font-weight: 400; + background: #ecb606; + width: fit-content; + padding: 0px 6px; + border-radius: 4px; + color: #fff; + // height: 18px; + line-height: 1.5; + + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.ts new file mode 100644 index 000000000..2c3998d8a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute-new.component.ts @@ -0,0 +1,31 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ActionWhatsappAttribute } from 'src/app/models/action-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-whatsapp-attribute-new', + templateUrl: './cds-action-whatsapp-attribute-new.component.html', + styleUrls: ['./cds-action-whatsapp-attribute-new.component.scss'] +}) +export class CdsActionWhatsappAttributeNewComponent implements OnInit { + + @Input() action: ActionWhatsappAttribute; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + private logger: LoggerService = LoggerInstance.getInstance(); + constructor() { } + + ngOnInit(): void { + this.logger.log("action: ", this.action); + this.logger.debug("action.attribute: ", this.action.attributeName); + } + + onSelectedAttribute(event) { + this.action.attributeName = event.value; + this.logger.debug("onSelectedAttribute event: ", this.action); + this.updateAndSaveAction.emit() + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute.component.spec.ts new file mode 100644 index 000000000..2c0cfd04e --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-attribute/cds-action-whatsapp-attribute.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWhatsappAttributeComponent } from './cds-action-whatsapp-attribute.component'; + +describe('ActionWhatsappAttributeComponent', () => { + let component: CdsActionWhatsappAttributeComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWhatsappAttributeComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWhatsappAttributeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.html new file mode 100644 index 000000000..03e15c6ba --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.html @@ -0,0 +1,157 @@ +
+ +
+
+ + + +
+ +
+ {{action.payload.receiver_list.length}} {{'CDSCanvas.ContactSelected' | translate }} +
+ +
+ {{action.payload.receiver_list.length}} {{'CDSCanvas.ContactSelected' | translate }} +
+ +
+
+
+ + + +
+ +
+ {{'CDSCanvas.AddContacts' | translate }} +
+ +
+ +
+ + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss new file mode 100644 index 000000000..1e5755c7d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss @@ -0,0 +1,183 @@ +.loader-container { + display: flex; + justify-content: center; + align-items: center; + height: 100px; + + #opt-train-wrp { + display: flex; + align-items: center; + + label { + font-weight: 500; + font-family: var(--font-family-poppins); + text-transform: capitalize; + font-size: 14px; + animation: blinker 1s linear infinite; + } + @keyframes blinker { + 50% { + opacity: 0; + } + } + } +} + + +cds-textarea#phone-number-id.is-invalid ::ng-deep { + display: flex; + textarea { + border-color: red; + color: red; + } +} + + + + +.select-template-box { + margin-right: 30px; + margin-left: 30px; +} + +.receiver-list { + //max-height: calc(100vh - 380px); + overflow-y: scroll; + padding: 10px 0px 0px 0px; + margin-top: 10px; +} + +.add-block-btn-container { + text-align: center; + margin-top: -10px; + //margin-top: 4px; + + .add-block-btn { + margin: 0px; + padding: 4px; + border-radius: 50%; + box-shadow: unset; + background-color: var(--blu-light-02); + color: white; + cursor: pointer; + } + + .add-block-btn > span { + font-size: 24px; + position: relative; + top: 0px; + } + + + .add-btn-text { + cursor: pointer; + color: var(--blu-light-02); + position: relative; + width: 130px; + top: -27px; + left: 225px; + } + .add-block-btn:hover, + .action--text:hover{ + opacity: 0.5; + } +} + + +.json-preview-container { + //margin-top: -20px; + //padding: 0 20px; + display: none; + background-color: var(--blu); + border-radius: 4px; + // animation: fadein 1s; + // animation-delay: 1s; +} + +@keyframes fadein { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.preview-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + //padding: 2px 10px; + padding: 4px 10px 0px 10px; + + span.title { + color: var(--color-white-hex); + font-size: 14px; + } +} + +.icon-only { + background-color: transparent; + border: none; + color: #bababa; + padding: 0; + //position: relative; + // top: 36px; + // left: 400px; + + span { + font-size: 14px; + } +} + +.icon-only:hover { + color: var(--color-white-hex); +} + + +pre ::ng-deep{ + color: var(--color-white-hex); + line-height: 16px; + margin-bottom: 0px; + padding: 10px; + overflow-x: auto; + border-radius: 4px; + font-size: 13px; + //margin: 10px; + + span { + display: inline; + } + + span::before { + display: none; + } + span.key { + color: red; + } + span.number { + color: #6eb4bc; + } + span.boolean { + color: #a693e0; + } + span.null { + color: #e09393; + } + span.key { + color: #a9d18f; + } + + .json { + margin-top: -10px; + } + + .headers { + span { + margin-left: -36px; + } + } +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.ts new file mode 100644 index 000000000..9a4a97367 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.ts @@ -0,0 +1,237 @@ +import { v4 as uuidv4 } from 'uuid'; +import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { ActionWhatsappStatic } from 'src/app/models/action-model'; +import { WhatsappService } from 'src/app/services/whatsapp.service'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +@Component({ + selector: 'cds-action-whatsapp-static-new', + templateUrl: './cds-action-whatsapp-static-new.component.html', + styleUrls: ['./cds-action-whatsapp-static-new.component.scss'] +}) +export class CdsActionWhatsappStaticNewComponent implements OnInit { + + @Input() action: ActionWhatsappStatic; + @Input() project_id: string; + @Input() intentName: string; + @Input() previewMode: boolean = true; + @Output() updateAndSaveAction = new EventEmitter(); + + // project_id: "123457"; + templates_list = []; + // receiver_list = []; + + phone_number_id: string; + showLoader: Boolean = false; + selected_template: any; + payload: any; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private whatsapp: WhatsappService, + public el: ElementRef + ) { } + + ngOnInit(): void { + // this.logger.log("[ACTION WHATSAPP STATIC] action: ", this.action); + // this.getTemplates(); + //this.initialize(); + if (this.previewMode == false) { + this.logger.log("Whatsapp static project_id: ", this.project_id); + this.showLoader = true; + this.getTemplates(); + } + } + + + + getTemplates() { + this.whatsapp.getAllTemplates().subscribe((templates: any[]) => { + + this.templates_list = templates.map(t => { + if (t.category === 'MARKETING') { + t.icon = "campaign" + } + else { + t.icon = "notifications_active" + } + t.description = t.components.find(c => c.type === 'BODY').text; + return t; + }) + + }, (error) => { + this.showLoader = false; + this.logger.log("[ACTION WHATSAPP STATIC] error get templates: ", error); + }, () => { + this.logger.log("[ACTION WHATSAPP STATIC] get templates completed: "); + this.updateJsonPreview(); + if (this.action.templateName) { + this.selected_template = this.templates_list.find(t => t.name === this.action.templateName); + } + this.showLoader = false; + let preview = document.getElementById('json-preview-container'); + if(preview){ + preview.style.display = 'block'; + } + this.initialize(); + }) + } + + initialize() { + if (this.action.payload) { + this.logger.debug("[ACTION WHATSAPP STATIC] initialize with payload: ", this.action.payload); + if (this.action.payload.phone_number_id) { + this.phone_number_id = this.action.payload.phone_number_id; + } + //this.updateJsonPreview(); + // if (this.action.payload.receiver_list) { + // this.receiver_list = this.action.payload.receiver_list; + // } + // this.logger.log("[ACTION WHATSAPP STATIC] payload: ", this.action.payload); + } else { + this.logger.log("action payload non esiste: ", this.action.payload); + this.logger.debug("[ACTION WHATSAPP STATIC] Payload empty --> create payload") + this.action.payload = { + id_project: this.project_id, + phone_number_id: null, + template: { + name: null, + language: null + }, + receiver_list: [] + } + this.updateJsonPreview(); + this.logger.log("[ACTION WHATSAPP STATIC] payload: ", this.action.payload) + } + } + + onChangeSelect(event) { + this.logger.debug("[ACTION WHATSAPP STATIC] onChangeSelect event", event); + this.selected_template = event; + this.action.templateName = this.selected_template.name; + this.action.payload.template.name = this.selected_template.name; + this.action.payload.template.language = this.selected_template.language; + this.action.payload.receiver_list = []; + this.updateJsonPreview(); + this.addReceiver(); + this.updateAndSaveAction.emit() + } + + addReceiver() { + this.action.payload.receiver_list.push({ phone_number: null }); + } + + onReceiverEmitted(event, index) { + // update receiver + this.action.payload.receiver_list[index] = event; + this.logger.log("[ACTION WHATSAPP] Action updated ", this.action.payload); + this.updateAndSaveAction.emit() + this.updateJsonPreview(); + + // if (this.action.payload.receiver_list.find(r => r.phone_number === event.phone_number)) { + // this.logger.log("[ACTION WHATSAPP STATIC] Receiver already exists with number: onReceiverEmitted event: ", event.phone_number); + // } else { + + // // this.message.receiver_list.push(event); + // // this.logger.log("payload.receiver_list (before) ", this.action.payload.receiver_list); + // this.action.payload.receiver_list[index] = event; + // // this.action.payload = this.message; + // // this.logger.log("[ACTION WHATSAPP] Action updated ", this.action.payload); + // this.logger.log("[ACTION WHATSAPP] Action updated ", this.action.payload); + // } + } + + onReceiverDeleteEmitted(event, index) { + this.logger.debug("delete event: ", event); + this.action.payload.receiver_list.splice(index, 1); + this.updateAndSaveAction.emit() + this.updateJsonPreview(); + } + + + onChangeTextarea(event){ + if(event){ + this.phone_number_id = event + let element = document.getElementById('phone-number-id'); + element.classList.remove('is-invalid'); + var reg = new RegExp('^[0-9]+$'); + if (!reg.test(this.phone_number_id)) { + element.classList.add('is-invalid'); + } else { + this.action.payload.phone_number_id = this.phone_number_id; + this.updateAndSaveAction.emit(); + } + + this.logger.debug("[ACTION WHATSAPP] Action updated ", this.action.payload); + this.updateJsonPreview(); + } + } + + updateJsonPreview() { + // var str = JSON.stringify(this.action.payload, undefined, 4); + + let json = { + payload: { + text: "/" + this.intentName, + id_project: this.project_id, + request: { + request_id: uuidv4() + }, + attributes: { + payload: { + whatsapp_attribute: this.action.payload + } + } + }, + token: "YOUR_CHATBOT_TOKEN_HERE" + } + var str = JSON.stringify(json, undefined, 2); + let element = document.getElementById('json'); + if (element) { + element.innerHTML = this.syntaxHighlight(str); + //element.innerHTML = str; + } + } + + syntaxHighlight(json) { + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + return '' + match + ''; + }); + } + + copyToClipboard() { + let json = { + payload: { + text: "/" + this.intentName, + id_project: this.project_id, + request: { + request_id: uuidv4() + }, + attributes: { + payload: { + whatsapp_attribute: this.action.payload + } + } + }, + token: "YOUR_CHATBOT_TOKEN_HERE" + } + var str = JSON.stringify(json, undefined, 2); + navigator.clipboard.writeText(str); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static.component.spec.ts new file mode 100644 index 000000000..3d969c7d7 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsActionWhatsappStaticComponent } from './cds-action-whatsapp-static.component'; + +describe('ActionWhatsappStaticComponent', () => { + let component: CdsActionWhatsappStaticComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsActionWhatsappStaticComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsActionWhatsappStaticComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-actions-new.module.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-actions-new.module.ts new file mode 100644 index 000000000..0a826d2e1 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-actions-new.module.ts @@ -0,0 +1,309 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { MaterialModule } from 'src/app/shared/material.module'; +import { HttpClient } from '@angular/common/http'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { RouterModule, Routes } from '@angular/router'; +import { SharedModule } from 'src/app/shared/shared.module'; +import { CdsBaseElementModule } from 'src/app/shared/cds-base-element.module'; +import { CdsAnswerComponent } from './answer/answer.component'; +import { CdsActionAgentHandoffNewComponent } from './cds-action-agent-handoff/cds-action-agent-handoff.component'; +import { CdsActionAskgptV2Component } from './cds-action-askgpt-v2/cds-action-askgpt-v2.component'; +import { AddkbDialogComponent } from './cds-action-askgpt/addkb-dialog/addkb-dialog.component'; +import { CdsActionAskgptNewComponent } from './cds-action-askgpt/cds-action-askgpt.component'; +import { CdsActionAssignVariableV2Component } from './cds-action-assign-variable-v2/cds-action-assign-variable-v2.component'; +import { OperandV2Component } from './cds-action-assign-variable-v2/operand/operand.component'; +import { OperationV2Component } from './cds-action-assign-variable-v2/operation/operation.component'; +import { OperatorV2Component } from './cds-action-assign-variable-v2/operator/operator.component'; +import { CdsActionAssignVariableNewComponent } from './cds-action-assign-variable/cds-action-assign-variable.component'; +import { OperandComponent } from './cds-action-assign-variable/operand/operand.component'; +import { OperationComponent } from './cds-action-assign-variable/operation/operation.component'; +import { OperatorComponent } from './cds-action-assign-variable/operator/operator.component'; +import { CdsActionCaptureUserReplyNewComponent } from './cds-action-capture-user-reply/cds-action-capture-user-reply.component'; +import { CdsActionIterationNewComponent } from './cds-action-iteration/cds-action-iteration.component'; +import { CdsActionChangeDepartmentNewComponent } from './cds-action-change-department/cds-action-change-department.component'; +import { CdsActionCloseNewComponent } from './cds-action-close/cds-action-close.component'; +import { CdsActionCodeNewComponent } from './cds-action-code/cds-action-code.component'; +import { CdsActionCustomerioNewComponent } from './cds-action-customerio/cds-action-customerio.component'; +import { CdsActionDeleteVariableNewComponent } from './cds-action-delete-variable/cds-action-delete-variable.component'; +import { CdsActionDescriptionNewComponent } from './cds-action-description/cds-action-description.component'; +import { CdsActionEmailNewComponent } from './cds-action-email/cds-action-email.component'; +import { AttributesDialogComponent } from './cds-action-gpt-task/attributes-dialog/attributes-dialog.component'; +import { CdsActionGPTTaskNewComponent } from './cds-action-gpt-task/cds-action-gpt-task.component'; +import { CdsActionHideMessageNewComponent } from './cds-action-hide-message/cds-action-hide-message.component'; +import { CdsActionHubspotNewComponent } from './cds-action-hubspot/cds-action-hubspot.component'; +import { CdsActionIntentNewComponent } from './cds-action-intent/cds-action-intent.component'; +import { BaseConditionRowComponent } from './cds-action-json-condition/base-condition-row/base-condition-row.component'; +import { BaseFilterComponent } from './cds-action-json-condition/base-filter/base-filter.component'; +import { CdsActionJsonConditionNewComponent } from './cds-action-json-condition/cds-action-json-condition.component'; +import { CdsActionMakeNewComponent } from './cds-action-make/cds-action-make.component'; +import { CdsActionOnlineAgentsNewComponent } from './cds-action-online-agents/cds-action-online-agents.component'; +import { CdsActionOpenHoursNewComponent } from './cds-action-open-hours/cds-action-open-hours.component'; +import { CdsActionQaplaNewComponent } from './cds-action-qapla/cds-action-qapla.component'; +import { CdsActionReplaceBotV2Component } from './cds-action-replace-bot/cds-action-replace-bot-v2/cds-action-replace-bot-v2.component'; +import { CdsActionReplaceBotV3Component } from './cds-action-replace-bot/cds-action-replace-bot-v3/cds-action-replace-bot-v3.component'; +import { CdsActionReplaceBotNewComponent } from './cds-action-replace-bot/cds-action-replace-bot-v1/cds-action-replace-bot.component'; +import { CdsActionReplyNewComponent } from './cds-action-reply/cds-action-reply-v1/cds-action-reply.component'; +import { CdsActionReplyButtonNewComponent } from './cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component'; +import { CdsActionReplyFrameNewComponent } from './cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component'; +import { CdsActionReplyGalleryNewComponent } from './cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component'; +import { CdsActionReplyImageNewComponent } from './cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component'; +import { CdsActionReplyRedirectNewComponent } from './cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component'; +import { CdsActionReplyTextNewComponent } from './cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component'; +import { CdsActionReplyToolsNewComponent } from './cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools.component'; +import { CdsActionWaitNewComponent } from './cds-action-wait/cds-action-wait.component'; +import { CdsActionWebRequestNewComponent } from './cds-action-web-request/cds-action-web-request.component'; +import { CdsActionWhatsappAttributeNewComponent } from './cds-action-whatsapp-attribute/cds-action-whatsapp-attribute.component'; +import { CdsActionWhatsappStaticNewComponent } from './cds-action-whatsapp-static/cds-action-whatsapp-static.component'; +import { CdsWhatsappReceiverComponent } from './cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component'; +import { FormEditAddComponent } from './form/form-edit-add/form-edit-add.component'; +import { FormFieldComponent } from './form/form-field/form-field.component'; +import { CdsFormComponent } from './form/form.component'; +import { ModalWindowComponent } from './form/modal-window/modal-window.component'; +import { CdsQuestionComponent } from './question/question.component'; +import { BaseElementModule } from 'src/app/shared/base-element.module'; +import { CdsActionBrevoNewComponent } from './cds-action-brevo/cds-action-brevo.component'; +import { CdsActionN8nComponent } from './cds-action-n8n/cds-action-n8n.component'; +import { CdsActionReplySettingsNewComponent } from './cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component'; +import { CdsActionGptAssistantNewComponent } from './cds-action-gpt-assistant/cds-action-gpt-assistant.component'; +import { FormDataComponent } from './cds-action-web-request-v2/form-data/form-data.component'; +import { CdsActionWebRequestV2Component } from './cds-action-web-request-v2/cds-action-web-request-v2.component'; +import { CdsActionReplyV2Component } from './cds-action-reply/cds-action-reply-v2/cds-action-reply.component'; +import { CdsActionOnlineAgentsV2Component } from './cds-action-online-agents-v2/cds-action-online-agents.component'; +import { CdsActionAddTagNewComponent } from './cds-action-add-tag/cds-action-add-tag.component'; +import { CdsActionLeadUpdateNewComponent } from './cds-action-lead-update/cds-action-lead-update.component'; +import { CdsActionClearTranscriptNewComponent } from './cds-action-clear-transcript/cds-action-clear-transcript.component'; +import { CdsActionMoveUnassignedNewComponent } from './cds-action-move-unassigned/cds-action-move-unassigned.component'; +import { CdsActionConnectBlockNewComponent } from './cds-action-connect-block/cds-action-connect-block.component'; +import { CdsActionSendWhatsappNewComponent } from './cds-action-send-whatsapp/cds-action-send-whatsapp.component'; +import { VariableCssClassPipe } from 'src/app/pipe/variablecssClass.pipe'; +import { GetVariableNamePipe } from 'src/app/pipe/get-variable-name.pipe'; +import { CdsActionAiPromptNewComponent } from './cds-action-ai-prompt/cds-action-ai-prompt.component'; +import { AttributesDialogAiPromptComponent } from './cds-action-ai-prompt/attributes-dialog/attributes-dialog.component'; +import { McpServersDialogComponent } from './cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component'; +import { McpServerEditDialogComponent } from './cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component'; +import { CdsActionWebResponseNewComponent } from './cds-action-web-response/cds-action-web-response.component'; +import { CdsActionReplyJsonbuttonsNewComponent } from './cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component'; +import { CdsActionAddKbContentNewComponent } from './cds-action-add-kb-content/cds-action-add-kb-content.component'; +import { CdsActionFlowLogNewComponent } from './cds-action-flow-log/cds-action-flow-log.component'; +import { CdsActionAiConditionNewComponent } from './cds-action-ai-condition/cds-action-ai-condition.component'; +import { AttributesDialogAiConditionComponent } from './cds-action-ai-condition/attributes-dialog/attributes-dialog.component'; +import { AiConditionComponent } from './cds-action-ai-condition/ai-condition/ai-condition.component'; +import { FindPipe } from 'src/app/pipe/find.pipe'; + +@NgModule({ + declarations: [ + //ACTIONS LIST + CdsFormComponent, + //FORM components + FormFieldComponent, + FormEditAddComponent, + ModalWindowComponent, + CdsQuestionComponent, + CdsAnswerComponent, + CdsActionDescriptionNewComponent, + CdsActionReplyNewComponent, + CdsActionReplyV2Component, + CdsActionWaitNewComponent, + CdsActionAgentHandoffNewComponent, + CdsActionOnlineAgentsNewComponent, + CdsActionOnlineAgentsV2Component, + CdsActionEmailNewComponent, + CdsActionIntentNewComponent, + CdsActionChangeDepartmentNewComponent, + CdsActionCloseNewComponent, + CdsActionOpenHoursNewComponent, + CdsActionJsonConditionNewComponent, + CdsActionDeleteVariableNewComponent, + CdsActionReplaceBotNewComponent, + CdsActionReplaceBotV2Component, + CdsActionReplaceBotV3Component, + CdsActionAssignVariableNewComponent, + CdsActionAssignVariableV2Component, + CdsActionHideMessageNewComponent, + CdsActionWebRequestNewComponent, + CdsActionWebRequestV2Component, + FormDataComponent, + CdsActionMakeNewComponent, + CdsActionHubspotNewComponent, + CdsActionWhatsappAttributeNewComponent, + CdsActionWhatsappStaticNewComponent, + CdsWhatsappReceiverComponent, + CdsActionAskgptNewComponent, + CdsActionGPTTaskNewComponent, + CdsActionCaptureUserReplyNewComponent, + CdsActionIterationNewComponent, + CdsActionGptAssistantNewComponent, + CdsActionQaplaNewComponent, + CdsActionCodeNewComponent, + CdsActionAskgptV2Component, + CdsActionCustomerioNewComponent, + CdsActionBrevoNewComponent, + CdsActionN8nComponent, + CdsActionAddTagNewComponent, + CdsActionLeadUpdateNewComponent, + // action REPLY elements: start // + CdsActionReplyToolsNewComponent, + CdsActionReplyTextNewComponent, + CdsActionReplyImageNewComponent, + CdsActionReplyFrameNewComponent, + CdsActionReplyRedirectNewComponent, + CdsActionReplyGalleryNewComponent, + CdsActionReplyButtonNewComponent, + CdsActionReplySettingsNewComponent, + // action REPLY elements: end // + // action ASSIGN-VARIABLE elements: start // + OperationComponent, + OperatorComponent, + OperandComponent, + // action ASSIGN-VARIABLE elements: end // + // action ASSIGN-VARIABLE-V2 elements: start // + OperationV2Component, + OperatorV2Component, + OperandV2Component, + // action ASSIGN-VARIABLE-V2 elements: end // + // action JSON-CONDITION elements: start // + // BaseConditionRowComponent, + BaseFilterComponent, + // VariableListComponent, + // action JSON-CONDITION elements: end // + // action ASKGPT elements: start // + AddkbDialogComponent, + // action ASKGPT elements: end // + // action GptTask elements: start // + AttributesDialogComponent, + FormDataComponent, + // action GptTask elements: end // + CdsActionClearTranscriptNewComponent, + CdsActionMoveUnassignedNewComponent, + CdsActionConnectBlockNewComponent, + CdsActionSendWhatsappNewComponent, + CdsActionAiPromptNewComponent, + AttributesDialogAiPromptComponent, + McpServersDialogComponent, + McpServerEditDialogComponent, + CdsActionAiConditionNewComponent, + AttributesDialogAiConditionComponent, + AiConditionComponent, + // action Ai Prompt elements: end // + CdsActionWebResponseNewComponent, + + //PIPES + GetVariableNamePipe, + VariableCssClassPipe, + CdsActionReplyJsonbuttonsNewComponent, + CdsActionAddKbContentNewComponent, + CdsActionFlowLogNewComponent + + ], + imports: [ + CommonModule, + TranslateModule, + MaterialModule, + SharedModule, + CdsBaseElementModule, + BaseElementModule + ], + exports:[ + //ACTIONS LIST + CdsFormComponent, + //FORM components + FormFieldComponent, + FormEditAddComponent, + ModalWindowComponent, + CdsQuestionComponent, + CdsAnswerComponent, + CdsActionDescriptionNewComponent, + CdsActionReplyNewComponent, + CdsActionReplyV2Component, + CdsActionWaitNewComponent, + CdsActionAgentHandoffNewComponent, + CdsActionOnlineAgentsNewComponent, + CdsActionOnlineAgentsV2Component, + CdsActionEmailNewComponent, + CdsActionIntentNewComponent, + CdsActionChangeDepartmentNewComponent, + CdsActionCloseNewComponent, + CdsActionOpenHoursNewComponent, + CdsActionJsonConditionNewComponent, + CdsActionDeleteVariableNewComponent, + CdsActionReplaceBotNewComponent, + CdsActionReplaceBotV2Component, + CdsActionReplaceBotV3Component, + CdsActionAssignVariableNewComponent, + CdsActionAssignVariableV2Component, + CdsActionHideMessageNewComponent, + CdsActionWebRequestNewComponent, + CdsActionWebRequestV2Component, + CdsActionMakeNewComponent, + CdsActionHubspotNewComponent, + CdsActionWhatsappAttributeNewComponent, + CdsActionWhatsappStaticNewComponent, + CdsWhatsappReceiverComponent, + CdsActionAskgptNewComponent, + CdsActionGPTTaskNewComponent, + CdsActionGptAssistantNewComponent, + CdsActionCaptureUserReplyNewComponent, + CdsActionIterationNewComponent, + CdsActionQaplaNewComponent, + CdsActionCodeNewComponent, + CdsActionAskgptV2Component, + CdsActionCustomerioNewComponent, + CdsActionBrevoNewComponent, + CdsActionN8nComponent, + CdsActionAddTagNewComponent, + CdsActionLeadUpdateNewComponent, + // action REPLY elements: start // + CdsActionReplyToolsNewComponent, + CdsActionReplyTextNewComponent, + CdsActionReplyImageNewComponent, + CdsActionReplyFrameNewComponent, + CdsActionReplyRedirectNewComponent, + CdsActionReplyGalleryNewComponent, + CdsActionReplyButtonNewComponent, + // action REPLY elements: end // + // action ASSIGN-VARIABLE elements: start // + OperationComponent, + OperatorComponent, + OperandComponent, + // action ASSIGN-VARIABLE elements: end // + // action ASSIGN-VARIABLE-V2 elements: start // + OperationV2Component, + OperatorV2Component, + OperandV2Component, + // action ASSIGN-VARIABLE-V2 elements: end // + // action JSON-CONDITION elements: start // + BaseConditionRowComponent, + BaseFilterComponent, + // VariableListComponent, + // action JSON-CONDITION elements: end // + // action ASKGPT elements: start // + AddkbDialogComponent, + // action ASKGPT elements: end // + // action GptTask elements: start // + AttributesDialogComponent, + // action GptTask elements: end // + CdsActionClearTranscriptNewComponent, + CdsActionMoveUnassignedNewComponent, + CdsActionConnectBlockNewComponent, + CdsActionSendWhatsappNewComponent, + CdsActionAiPromptNewComponent, + AttributesDialogAiPromptComponent, + McpServersDialogComponent, + McpServerEditDialogComponent, + CdsActionAiConditionNewComponent, + AttributesDialogAiConditionComponent, + AiConditionComponent, + // action Ai Prompt elements: end // + CdsActionWebResponseNewComponent, + + //PIPES + GetVariableNamePipe, + VariableCssClassPipe, + CdsActionAddKbContentNewComponent, + CdsActionFlowLogNewComponent + ] +}) +export class CdsActionsNewModule { } + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.html new file mode 100644 index 000000000..44b76b71d --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.html @@ -0,0 +1,129 @@ +
+ +
+ + + +
+ +
+ + + +
+ + +
+ + + + +

+ {{ 'CDSForm.ValidationField' | translate }} +

+
+
+ + +
+
+ + + +
+
+ + + +
+ +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss new file mode 100644 index 000000000..c0e4f8d33 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss @@ -0,0 +1,171 @@ +:host { + --background-color: #{var(--ds-canvas, #f7f6f3)}; + --text-color: #{var(--blu)}; + --icon-color: #{var(--blu-light-02)}; + --selected-row-background: #{var(--blu-light-02)}; + --selected-row-color: #{var(--blu-light-03)}; + + --content-background: rgb(244, 246, 251, 0.4); +} + + +.tilebot-add-edit-form { + background-color: var(--content-background); + border: 1px solid var(--gray-light-02); + border-radius: 4px; + height: auto; + max-height: 0; + overflow: hidden; + box-shadow: none; + transition: max-height 0.3s ease-in; + padding: 20px 20px 30px; + &.active { + max-height: 38vh; + } + + button { + text-align: right; + margin: 0px; + } + button.edit-form { + border-radius: 20px; + padding-right: 20px; + padding-top: 10px; + color: #fff; + min-height: 30px; + background-color: transparent; + box-shadow: none; + float: right; + } + button.edit-form .icon-label { + vertical-align: text-top; + display: inline-block; + overflow: hidden; + margin-right: 10px; + width: auto; + } + + + + ::ng-deep .mat-expansion-indicator:after { + color: var(--text-color); + margin-top: -4px; + } + + mat-expansion-panel { + box-shadow: none; + background: var(--background-color); + border: 0px solid #5f6368; + overflow: visible; + &.open-block { + pointer-events: none; + } + mat-expansion-panel-header { + height: 40px; + padding: 0 12px; + } + &.mat-expanded { + ::ng-deep .mat-expansion-panel-body { + opacity: 1; + } + } + ::ng-deep .mat-expansion-panel-body { + opacity: 0; + margin-top: 20px; + padding: 0px 20px 0px + } + + .validation-field-title { + margin: 0; + font-weight: 500; + color: var(--text-color); + } + } + + .input-wrapper { + margin: 10px 0 0 0; + } +} + + + +// ****** TYPE REGEX + INPUT REGEX CUSTOM : end ********* +.input-group .input-group-addon { + border: 0; + background: transparent; + padding: 6px 0; + display: flex; + align-items: center; +} +.cds-input-group { + // margin: 10px 10px; + display: flex; + flex-wrap: nowrap; + +} + +.field-box:last-child{ + width: 100%; +} +cds-select#method ::ng-deep{ + // padding: 6px 0; + min-width:120px; + .ng-select-container{ + height: 37px; + border-radius: var(--input-border-radius-base) 0px 0px var(--input-border-radius-base); + } +} +cds-select#method.no-regex ::ng-deep{ + + .ng-select-container{ + height: 37px; + border-radius: var(--input-border-radius-base); + } +} + +cds-textarea#regex ::ng-deep { + display: flex; + width: 100%; + // padding: 6px 0px 0px 0; + textarea { + border-radius: 0px var(--input-border-radius-base) var(--input-border-radius-base) 0px; + resize: none !important; + padding: 6px 16px !important; + + height: 23px !important; + min-height: 23px !important; + } +} +// ****** TYPE REGEX + INPUT REGEX CUSTOM : end ********* + + + +.form-footer { + text-align: right; + display: flex; + flex-direction: row-reverse; + gap: 10px; + + button#add-button{ + background-color: #45c351; + } +} + + + + +.input-prefix { + position: absolute; + top: 8px; + left: 8px; + color: #7d7d7d; + font-weight: 800; +} + +.input-suffix { + position: absolute; + top: 8px; + right: 8px; + color: #7d7d7d; + font-weight: 800; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.ts new file mode 100644 index 000000000..a141221da --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.ts @@ -0,0 +1,324 @@ +import { Component, OnInit, Output, Input, EventEmitter, OnChanges } from '@angular/core'; +import { HttpClient } from "@angular/common/http"; +import { TranslateService } from '@ngx-translate/core'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; + +export enum TYPE_FIELD { + CUSTOM = 'CUSTOM', + TEXT = 'TEXT', + EMAIL = 'EMAIL', + PHONE = 'PHONE' +} + +export enum TYPE_REGEX { + nameRGEX = '/^[a-zA-Z0-9_]{1,}$/', + + customRGEX = '^.{1,}$', + textRGEX = '^.{1,}$', + // phoneRGEX = "/^((?:\\+|00)[17](?: |\\-)?|(?:\\+|00)[1-9]\\d{0,2}(?: |\\-)?|(?:\\+|00)1\\-\\d{3}(?: |\\-)?)?(0\\d|\\([0-9]{3}\\)|[1-9]{0,3})(?:((?: |\\-)[0-9]{2}){4}|((?:[0-9]{2}){4})|((?: |\\-)[0-9]{3}(?: |\\-)[0-9]{4})|([0-9]{7}))$/", + phoneRGEX = '^.{1,}$', + emailRGEX = "^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$" +} + +@Component({ + selector: ' selector: 'appdashboard-form-edit-add-new',-new', + templateUrl: './form-edit-add-new.component.html', + styleUrls: ['./form-edit-add-new.component.scss'] +}) +export class FormEditAddComponent implements OnInit, OnChanges { + @Output() closeAddEditForm = new EventEmitter(); + @Output() saveAddEditForm = new EventEmitter(); + // @Output() editFormFields = new EventEmitter(); + + @Output() scrollToBottom = new EventEmitter(); + @Output() changedFormFields = new EventEmitter(); + + @Input() displayAddForm: boolean; + @Input() displayEditForm: boolean; + @Input() field: any; + + + typeField = TYPE_FIELD; + langDashboard = 'En'; + showForm = false; + nameResult = true; + typeResult = true; + labelResult = true; + regexResult = true; + errorLabelResult = true; + showRegexField = true; + // displayInfoMessage = false; + // inputTypePlaceholderClass = true; + panelOpenState = false; + hasSelectedVariable: boolean = false; + + + // customRGEX = /^.{1,}$/; + // textRGEX = /^.{1,}$/; + // phoneRGEX = /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/; + // nameRGEX = /^[a-zA-Z0-9_]{1,}$/; + // emailRGEX = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/ + // /^[(]{0,1}[0-9]{3}[)]{0,1}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/; + modelsOfType = [{ "label": "Text", "value": TYPE_FIELD.TEXT }, { "label": "Email", "value": TYPE_FIELD.EMAIL }, { "label": "Phone number", "value": TYPE_FIELD.PHONE }, { "label": "Custom", "value": TYPE_FIELD.CUSTOM }]; + infoMessages = {} + infoMessage: string; + markbotLabel: string; + + fieldName: string = ''; + fieldType: string = null; + fieldRegex: string = ''; + fieldLabel: string = ''; + fieldErrorLabel: string = ''; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + private translate: TranslateService, + private httpClient: HttpClient, + ) { } + + ngOnInit(): void { + this.hasSelectedVariable = false; + this.showRegexField = true; + if (this.displayAddForm) { + this.field = { + "name": "", + "type": "", + "regex": "", + "label": "", + "errorLabel": "" + } + } else if (this.displayEditForm) { + this.field.type = this.field.type.toUpperCase(); + // if(this.field.regex && this.field.type === TYPE_FIELD.CUSTOM){ + // this.fieldRegex = this.field.regex; + // } + this.fieldName = this.field.name; + if(this.fieldName && this.fieldName !== ''){ + this.hasSelectedVariable = true; + } + this.fieldType = this.field.type; + this.fieldRegex = this.field.regex?this.field.regex:TYPE_REGEX.customRGEX; + this.fieldLabel = this.field.label; + this.fieldErrorLabel = this.field.errorLabel; + // this.inputTypePlaceholderClass = false; + } + // this.setRegex(); + this.getCurrentTranslation(); + this.infoMessage = this.infoMessages['field_name']; + + } + + ngOnChanges() { + this.fieldType = "TEXT"; + this.fieldRegex = '^.{1,}$' + // this.logger.log('[FORM-EDIT-ADD] fieldType ', this.fieldType) + } + + ngAfterViewInit() { + this.showForm = false; + if (this.displayAddForm || this.displayEditForm) { + setTimeout(() => { + this.showForm = true; + }, 100); + } + } + + getCurrentTranslation() { + if (this.translate.currentLang) { + this.langDashboard = this.translate.currentLang; + } + this.translate.get(['CDSForm.InfoMessages', 'CDSForm.MarkbotLabel']).subscribe(data => { + this.infoMessages = data['CDSForm.InfoMessages']; + this.markbotLabel = data['CDSForm.MarkbotLabel']; + }) + } + + checkFields() { + this.nameResult = true; + this.typeResult = true; + this.labelResult = true; + this.errorLabelResult = true; + let status = true; + if (this.fieldType == null) { + this.typeResult = false; + status = false; + } + let REGEX = new RegExp(TYPE_REGEX.nameRGEX.replace(/\//gi, '')); + // this.logger.log('[TILEBOT-EDIT-ADD] checkFields nameRGEX REGEX ', REGEX) + this.nameResult = REGEX.test(this.fieldName); + // this.logger.log('[TILEBOT-EDIT-ADD] nameResult',this.nameResult,' REGEX.test - field.name', this.field.name ) + if (this.nameResult === false) { + status = false; + } + if (this.fieldName.length == 0) { + this.nameResult = false; + status = false; + } + if (this.fieldLabel.length == 0) { + //this.labelResult = false; + //status = false; + + } + if (this.fieldRegex.length == 0 && this.fieldType === TYPE_FIELD.CUSTOM) { + //this.regexResult = false; + //status = false; + } + // this.field.regex = this.field.regex.replace(/\//gi, ''); + // this.logger.log('[TILEBOT-EDIT-ADD] checkFields this.field.regex 1 ', this.field.regex) + // this.fieldRegex = this.field.regex.toString(); + // this.logger.log('[TILEBOT-EDIT-ADD] checkFields this.field.regex 2 ', this.field.regex) + return status; + + } + + private setRegex() { + switch (this.field.type) { + case TYPE_FIELD.TEXT: + this.field.regex = TYPE_REGEX.textRGEX; + break; + case TYPE_FIELD.EMAIL: + this.field.regex = TYPE_REGEX.emailRGEX; + break; + case TYPE_FIELD.PHONE: + this.field.regex = TYPE_REGEX.phoneRGEX; + break; + case TYPE_FIELD.CUSTOM: + this.field.regex = TYPE_REGEX.customRGEX; + break; + default: + this.field.regex = TYPE_REGEX.textRGEX; + } + this.fieldRegex = this.field.regex; + } + + // ON EVENT // + /** */ + onChangeParameterName(parameterName) { + parameterName.toString(); + this.fieldName = parameterName.replace(/[^A-Z0-9_]+/ig, ""); + } + + // displayPlaceholder(event) { + // if (event === true && this.fieldType) { + // this.inputTypePlaceholderClass = false; + // } else if (event === false) { + // this.inputTypePlaceholderClass = false; + // } else { + // this.inputTypePlaceholderClass = true; + // } + // } + + + save() { + // this.logger.log('[TILEBOT-EDIT-ADD] save ') + if (this.checkFields()) { + // this.displayInfoMessage = false; + this.showForm = false; + this.field.name = this.fieldName ? this.fieldName : ''; + this.field.type = this.fieldType ? this.fieldType.toUpperCase() : null; + this.field.regex = this.fieldRegex ? this.fieldRegex : TYPE_REGEX.customRGEX; + if(!this.fieldLabel || this.fieldLabel.trim().length === 0){ + delete this.field.label + } else { + this.field.label = this.fieldLabel.trim(); + } + if(!this.fieldErrorLabel || this.fieldErrorLabel.trim().length === 0){ + delete this.field.errorLabel; + } else { + this.field.errorLabel = this.fieldErrorLabel.trim(); + } + // this.fieldRegex = this.field.regex.toString(); + this.logger.log('[TILEBOT-EDIT-ADD] checkFields field ', this.field); + this.saveAddEditForm.emit(this.field); + } + } + + close() { + this.displayAddForm = false; + this.displayEditForm = false; + this.showForm = false; + // this.displayInfoMessage = false; + this.closeAddEditForm.emit(); + } + + onScrollToBottom(){ + this.scrollToBottom.emit(); + } + + + + + + + + + + + /** START EVENTS */ + onSelectedAttributeParam(variableSelected: {name: string, value: string}){ + this.hasSelectedVariable = true; + this.fieldName = variableSelected.value; + this.field.name = variableSelected.value; + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + this.logger.log('onSelectedAttributeParam:: ', this.field); + } + } + onClearSelectedAttributeParam() { + this.hasSelectedVariable = false; + this.fieldName = ''; + this.field.name = ''; + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + this.logger.log('clearSelectedAttributeParam:: ', this.field); + } + } + onChangeTextAreaLabel(text: string){ + this.field.label = text; + this.fieldLabel = text; + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + this.logger.log('onChangeTextAreaLabel:: ', this.field); + } + } + onChangeValidationErrorMessage(errorLabel){ + this.field.errorLabel = this.fieldErrorLabel = errorLabel.trim(); + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + this.logger.log('onChangeValidationErrorMessage:: ', errorLabel.data, this.fieldErrorLabel); + } + } + onChangeValidationRegex(regex){ + this.field.regex = this.fieldRegex = regex.trim(); + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + this.logger.log('onChangeValidationRegex:: ', regex.data, this.fieldRegex); + } + } + /** */ + onChangeValidationType(event: {label: string, value: string}) { + this.field.type = event.value; + this.setRegex(); + if(this.displayAddForm === false){ + this.changedFormFields.emit(this.field); + } + } + + // displayMessage(field?) { + // this.displayInfoMessage = false; + // if(field){ + // if (this.infoMessages[field]) { + // this.infoMessage = this.infoMessages[field]; + // this.displayInfoMessage = true; + // } + // if (field === 'field_label') { + // this.infoMessage += " " + this.markbotLabel; + // } + // } + // this.onScrollToBottom(); + // } + /** END ACTIONS CDS-TEXTAREA */ + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add.component.spec.ts new file mode 100644 index 000000000..b4ad0b4f6 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormEditAddComponent } from './form-edit-add.component'; + +describe('FormEditAddComponent', () => { + let component: FormEditAddComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FormEditAddComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FormEditAddComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.html new file mode 100644 index 000000000..6722c03db --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.html @@ -0,0 +1,58 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{ "Name" | translate }} + + {{ "Label" | translate }} + + {{ "Actions" | translate }} +
+ + {{ field.name }} + + + + {{ field?.label }} + + + + + + + + +
+
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss new file mode 100644 index 000000000..71256132f --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss @@ -0,0 +1,118 @@ +:host { + --background-color: #{var(--blu-light-01)}; + --text-color: #{var(--blu)}; + --icon-color: #{var(--blu-light-02)}; + --selected-row-background: #{var(--blu-light-02)}; + --selected-row-color: #{var(--blu-light-03)}; +} + +.card-content{ + max-height: 40vh; +} + +.form-fields-table { + display: block; + .col-30 { + width:150px; + max-width:150px; + } + .label-field { + font-weight: 400; + font-size: 13px; + white-space: normal; + word-wrap: break-word; + color: var(--text-color); + } + .td-actions { + text-align: right; + padding: 0px; + width:85px; + display: table-cell; + > :last-child , >:first-child{ + color: var(--icon-color); + } + } +} + +.form-fields-table > thead { + width: 100%; + display: block; + tr { + width: 100%; + display: inline-table; + border-bottom: 1px solid var(--icon-color); + th { + color: var(--icon-color); + font-weight: 400; + border-bottom: 0px solid var(--icon-color) !important; + } + } +} + +.form-fields-table td { + padding: 5px 8px; +} + + +.form-fields-table > tbody > tr { + cursor:pointer; + width: 100%; + display: inline-table; +} + +.form-fields-table > tbody > tr:hover { + // background-color: rgba(30, 41, 59, 0.5); +} + +.form-fields-table tr.selected > * { + background-color: var(--selected-row-background); + .label-field{ + color: var(--selected-row-color); + } + border: 0px; +} + + +/** DRAG **/ +.cdk-drag-preview { + border-radius: 6px; + display: flex; + flex-direction: row; + align-items: center; + box-sizing: border-box; + padding: 0 16px; + position: relative; + height: inherit; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); + tr > * { + background-color: var(--selected-row-background); + } + .label-field { + font-weight: 400; + font-size: 13px; + white-space: normal; + word-wrap: break-word; + color: var(--text-color); + } + .col-30 { + width:150px; + max-width:150px; + } + + .td-actions { + // display: none; + width: 85px; + button{ + display: none; + } + } +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.ts new file mode 100644 index 000000000..66b2ceff2 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.ts @@ -0,0 +1,54 @@ +import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'; +import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop'; + +@Component({ + selector: ' selector: 'appdashboard-form-field-new',-new', + templateUrl: './form-field-new.component.html', + styleUrls: ['./form-field-new.component.scss'] +}) +export class FormFieldComponent implements OnInit, OnChanges { + + @Output() eventEditField = new EventEmitter(); + @Output() openDeleteFieldModal = new EventEmitter(); + @Output() eventDropField = new EventEmitter(); + + @Input() fields: [any]; + + // modal + displayMODAL = false; + selectedObjectId: number; + + // add edit form + selectedField: any; + + + constructor() { + // void + } + + ngOnInit(): void { + this.selectedObjectId = null; + } + + ngOnChanges() { + } + + drop(event: CdkDragDrop) { + moveItemInArray(this.fields, event.previousIndex, event.currentIndex); + this.selectedField = null; + this.eventDropField.emit(this.fields); + } + + // EVENTS // + /** Event modal open delete field */ + deleteFieldModal(index:number) { + this.openDeleteFieldModal.emit(index); + } + + /** Event edit field */ + editField(index:number){ + this.selectedObjectId = index; + this.eventEditField.emit(index); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field.component.spec.ts new file mode 100644 index 000000000..ae005ae55 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormFieldComponent } from './form-field.component'; + +describe('FormFieldComponent', () => { + let component: FormFieldComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FormFieldComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FormFieldComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-models-factory.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-models-factory.ts new file mode 100644 index 000000000..dbbd93856 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-models-factory.ts @@ -0,0 +1,142 @@ + +import { Field, Form } from 'src/app/models/intent-model'; + +export class FormModelsFactory { + + getModels() { + let models: Form[] = new Array() as Form[]; + // ------------------------------------- + // @ Base form + // ------------------------------------- + let form_base = new Form(); + form_base.name = 'Base' + form_base.id = 1 + form_base.cancelCommands = []; + form_base.cancelReply = ""; + form_base.description = '"Base" model contains the following fields: user fullname, user email'; + form_base.fields = new Array() as Field[]; + // first nested JSON + let field0 = new Field() + field0.name = 'userFullname'; + field0.type = 'text'; + field0.label = 'What is your name?'; + // second nested JSON + let field1 = new Field() + field1.name = 'userEmail'; + field1.type = 'text'; + field1.regex = '^.{1,}$' + //field1.regex = "/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/"; + field1.label = "Hi ${userFullname}\n\nJust one last question\n\nYour email " + field1.errorLabel = "${userFullname} this email address is invalid\n\nCan you insert a correct email address?" + form_base.fields.push(field0) + form_base.fields.push(field1) + + // ------------------------------------- + // @ Advanced form + // ------------------------------------- + let form_advanced = new Form(); + form_advanced.name = 'Advanced' + form_advanced.id = 2 + form_advanced.cancelCommands = []; + form_advanced.cancelReply = ""; + form_advanced.description = '"Advanced" model contains the following fields: user fullname, company name, user phone, user email'; + form_advanced.fields = new Array() as Field[]; + let field2 = new Field() + field2.name = 'userFullname'; + field2.type = 'text'; + field2.label = 'What is your name?'; + let field3 = new Field() + field3.name = 'companyName'; + field3.type = 'text'; + field3.label = 'Thank you ${userFullname}! What is your Company name?'; + let field4 = new Field() + field4.name = 'userPhone'; + field4.type = 'text'; + field4.label = 'Thank you ${userFullname}! What is your phone number?'; + let field5 = new Field() + field5.name = 'userEmail'; + field5.type = 'text'; + field5.label = "Hi ${userFullname} \n\nJust one last question\n\nYour email 🙂"; + field5.regex = '^.{1,}$' + //field5.regex = "/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/" + field5.errorLabel = "${userFullname} this email address is invalid\n\nCan you insert a correct email address?"; + form_advanced.fields.push(field2) + form_advanced.fields.push(field3) + form_advanced.fields.push(field4) + form_advanced.fields.push(field5) + + + let form_custom = new Form(); + form_custom.name = 'Custom' + form_custom.id = 3 + form_custom.cancelCommands = []; + form_custom.cancelReply = ""; + form_custom.description = '"Custom" model is empty'; + form_custom.fields = new Array() as Field[]; + + + //let item = { "id": "custom-model", "name": "Custom", "description_key": "", "fields": "" }; + + + + models.push(form_base); + models.push(form_advanced); + models.push(form_custom); + + return models; + } + + // modelsOfForm: Form[] = [ + // { + // "name": "Base", + // "id": 1, + + // "cancelCommands": [], + // "cancelReply": "", + // "fields": [ + // { + // "name": "userFullname", + // "type": "text", + // "label": "What is your name?" + // }, { + // "name": "userEmail", + // "type": "text", + // "regex": "/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/", + // "label": "Hi ${userFullname}\n\nJust one last question\n\nYour email 🙂", + // "errorLabel": "${userFullname} this email address is invalid\n\nCan you insert a correct email address?" + // } + // ] + // }, + // { + // "name": "Advanced", + // "id": 2, + + // "cancelCommands": [], + // "cancelReply": "", + // "fields": [ + // { + // "name": "userFullname", + // "type": "text", + // "label": "What is your name?" + // }, { + // "name": "companyName", + // "type": "text", + // "label": "Thank you ${userFullname}! What is your Company name?" + // }, { + // "name": "userPhone", + // "type": "text", + // "label": "Thank you ${userFullname}! What is your phone number?" + // }, { + // "name": "userEmail", + // "type": "text", + // "regex": "/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/", + // "label": "Hi ${userFullname} \n\nJust one last question\n\nYour email 🙂", + // "errorLabel": "${userFullname} this email address is invalid\n\nCan you insert a correct email address?" + // } + // ] + // } + // ] + + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.html new file mode 100644 index 000000000..c166ec2b5 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.html @@ -0,0 +1,115 @@ + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss new file mode 100644 index 000000000..9975aee76 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss @@ -0,0 +1,134 @@ +:host { + --background-color: #{var(--blu-light-01)}; + --text-color: #{var(--blu)}; + --icon-color: #{var(--blu-light-02)}; +} + +.content-panel-intent-detail { + .content-buttons--form { + position: relative; + display: block; + height: auto; + width: 100%; + margin-top: 0; + overflow: visible; + max-height: calc(100% - 35px); + .box-settings-form{ + background: #425575; + } + } + + //*** SPLASH SCREEN : start **** // + .splash-screen--form { + text-align: center; + + .tpl-info-text { + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; + a { + color: var(--icon-color); + text-decoration: underline; + } + span.material-icons, + span.material-icons-outlined { + color: var(--icon-color); + } + } + + } + //*** SPLASH SCREEN : start **** // + + .more-info { + cursor: pointer; + position: absolute; + top: -60px; + left: 60px; + z-index: 2; + em.material-icons { + vertical-align: middle; + display: inline-flex; + color: #3ea9f5; + margin-right: 3px; + } + } + + .header-buttons--form { + align-items: center; + justify-content: space-between; + display: flex; + margin: auto; + width: 100%; + margin-bottom: 20px; + } + + button { + span.material-icons, + span.material-icons-outlined{ + top: 0px; + } + } + + button#delete-form-btn{ + &:hover{ + background-color: red; + } + } + + button#open-setting-btn, + button#close-general-btn, + button#delete-form-btn{ + display: flex; + align-items: center; + justify-content: center; + padding: 6px; + margin: 0; + + } + + .field-box { + line-height: 20px; + font-size: 14px; + text-align: left; + .bold { + font-weight: 300; + } + .form-description{ + font-size: 12px; + color: var(--icon-color); + } + } + + .add-form { + flex-direction: row; + justify-content: center; + } +} + + +.header-list-form { + text-align: center; + .hide { + display: none; + } +} + +.btn-only-string { + background: transparent !important; + color: #fff !important; + border: unset !important; + box-shadow: unset !important; + // background-color: #dce9ff !important; + // border-color: #dce9ff !important; + padding-left: 0px !important; + padding-right: 0px !important; +} +.btn-only-string:hover { + // color: rgba(138, 180, 248, .8) !important; + color: #8ab4f8cc!important; + // background-color: #9ac1ff !important; + // border-color: #9ac1ff !important; +} + + diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.ts new file mode 100644 index 000000000..5856809ca --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.ts @@ -0,0 +1,512 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild, ElementRef } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { TranslateService } from '@ngx-translate/core'; +import { Field, Form, Intent } from 'src/app/models/intent-model'; +import { FormModelsFactory } from './form-models-factory'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +const swal = require('sweetalert'); +// import { URL_more_info_chatbot_forms } from 'app/utils/util'; + +export interface ModalDeleteModel { + deleteField?: string; + nameField?: string; + confirmDeleteField?: string; + cancel?: string; +} + +@Component({ + selector: ' selector: 'cds-form-new',-new', + templateUrl: './form-new.component.html', + styleUrls: ['./form-new.component.scss'] +}) +export class CdsFormComponent implements OnInit, OnChanges { + @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + + // @Output() passJsonIntentForm = new EventEmitter(); + @Input() intentForm: Form; + @Input() intentSelected: Intent; + @Output() updateIntentForm = new EventEmitter(); + + langBot: string; + fields = new Array() as Field[];; + URL_to_form_more_info = "https://gethelp.tiledesk.com/articles/tiledesk-chatbot-forms/"; + + // modal + displayMODAL = false; + translateMap: ModalDeleteModel; + translations: any; + + selectedObjectId: string; + + // add edit form + selectedField: Field; + displayTilebotAddEditForm = true; + displayAddForm = false; + displayEditForm = false + displayBoxNewForm = false; + displaySettingForm = false; + displayNewFormButton = true; + displayCancelButton = false; + displaySettingsButton = false; + + idForm: string = "id-form-000"; + selectedForm: Form; + selectedFormId: number; + modelsOfForm: Form[] = []; + cancelCommands: string[] = []; + cancelCommandsString: string; + cancelReply: string; + intentFormSize: number; + + translateparam = { selectedFormName: "", description_key: "" }; + + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor( + public translate: TranslateService, + private route: ActivatedRoute, + ) { + this.langBot = this.route.snapshot.params['botlang']; + if (!this.langBot || this.langBot === undefined) { + this.langBot = 'en'; + } + } + + ngOnInit(): void { + } + + ngOnChanges() { + this.logger.log('[FORM-COMP] (OnChanges) intentForm ', this.intentForm); + this.initialize(); + } + + + private initialize(){ + this.logger.log('[FORM-COMP] (OnInit) intentSelected ', this.intentSelected) + this.logger.log('[FORM-COMP] (OnInit) intentForm ', this.intentForm) + this.displayTilebotAddEditForm = true; + this.displayAddForm = false; + this.displayEditForm = false + this.displayBoxNewForm = false; + this.displaySettingForm = false; + this.displayNewFormButton = true; + this.displayCancelButton = false; + this.displaySettingsButton = false; + this.idForm = "id-form-000"; + this.modelsOfForm = []; + this.cancelCommands = []; + + let modelsFactory = new FormModelsFactory() + this.modelsOfForm = modelsFactory.getModels(); + this.selectedForm = this.modelsOfForm[0]; + this.selectedFormId = this.modelsOfForm[0].id ? this.modelsOfForm[0].id : null; + this.logger.log('[FORM-COMP] (OnInit) selectedForm ', this.selectedForm) + this.logger.log('[FORM-COMP] (OnInit) modelsOfForm ', this.modelsOfForm) + this.logger.log('[FORM-COMP] (OnInit) selectedFormId ', this.selectedFormId) + this.translateMap = {}; + this.translations = {}; + this.getCurrentTranslation(); + this.intentFormSize = Object.keys(this.intentForm).length; + if (this.intentFormSize > 0) { + this.displayNewFormButton = false; + this.displaySettingsButton = true; + if (this.intentForm && this.intentForm.fields) { + // this.fields = this.intentForm.fields; + this.fields = JSON.parse(JSON.stringify(this.intentForm.fields)); + } + this.cancelCommands = this.intentForm.cancelCommands; + this.cancelReply = this.intentForm.cancelReply; + this.cancelCommandsString = this.cancelCommands.toString(); + this.logger.log('[FORM-COMP] (OnInit) intentFormSize ', this.intentFormSize) + this.logger.log('[FORM-COMP] OnInit intentForm.fields ', this.fields) + this.logger.log('[FORM-COMP] cancelCommands ', this.cancelCommands) + this.logger.log('[FORM-COMP] cancelReply ', this.cancelReply) + this.logger.log('[FORM-COMP] cancelCommandsString ', this.cancelCommandsString) + } + } + + scrollToTop(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = 0; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.log('scrollToTop ERROR: ', error); + } + }, 500); + } + + scrollToBottom(): void { + setTimeout(() => { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); + } catch (error) { + this.logger.error('scrollToBottom ERROR: ', error); + } + }, 500); + } + + onChangeBlockSelect(event:{name: string, id: number}){ + this.getFieldFromId(event.id) + } + + getFieldFromId(idForm: number) { + this.logger.log('[FORM-COMP] getFieldFromId idForm ', idForm) + // this.selectedForm = new FormModelsFactory().getModels()[0] + this.selectedForm = new FormModelsFactory().getModels().find(({ id }) => id === idForm); + this.logger.log('[FORM-COMP] getFieldFromId selectedForm ', this.selectedForm) + // this.translateparam = { selectedFormName: this.selectedForm.name, description_key: this.selectedForm.description_key }; + } + + /** CREATE NEW FORM */ + generateJsonIntentForm() { + this.logger.log('[FORM-COMP] generateJsonIntentForm') + if (this.selectedFormId && !this.selectedForm) { + this.getFieldFromId(this.selectedFormId); + } + this.logger.log('[FORM-COMP] selectedForm ', this.selectedForm) + if (this.selectedForm) { + this.selectedForm.to_JSON(); + this.intentForm = this.selectedForm; + this.intentForm.cancelCommands = this.cancelCommands; + this.intentForm.cancelReply = this.cancelReply; + this.intentForm.to_JSON(); + // this.fields = JSON.parse(JSON.stringify(this.selectedForm.fields)); + this.fields = this.selectedForm.fields; + this.intentFormSize = Object.keys(this.intentForm).length; + this.logger.log('[FORM-COMP] generateJsonIntentForm ', this.intentForm) + } + this.displayCancelButton = false; + this.displaySettingsButton = true; + this.logger.log('[FORM-COMP] generateJsonIntentForm displaySettingsButton:', this.displaySettingsButton, ' displayCancelButton', this.displayCancelButton) + // se sto creando un form custom che non ha campi + if (this.fields.length === 0) { + this.displayEditForm = false; + this.displayAddForm = true; + this.openAddEditForm(); + } + this.jsonGenerator(); + } + + + getCurrentTranslation() { + let keys = [ + 'Cancel', + 'CDSForm.CancelReply', + 'CDSForm.DeleteField', + 'CDSForm.ConfirmDeleteField', + 'CDSForm.DeleteForm', + 'CDSForm.ConfirmDeleteForm' + ] + this.translate.get(keys).subscribe(data => { + this.translations = data + let cancel = this.translations['Cancel'] ? this.translations['Cancel'] : 'cancel'; + this.logger.log('[FORM-COMP] getCurrentTranslation intentForm 1', this.intentForm); + this.intentFormSize = Object.keys(this.intentForm).length; + if (this.intentFormSize === 0) { + this.logger.log('[FORM-COMP] getCurrentTranslation intentForm 2', this.intentForm) + this.cancelCommands.push(cancel); + this.cancelReply = this.translations['CDSForm.CancelReply'] ? this.translations['CDSForm.CancelReply'] : ''; + } + this.logger.log('[FORM-COMP] getCurrentTranslation this.cancelReply::', this.cancelReply); + this.logger.log('[FORM-COMP] getCurrentTranslation cancel::', cancel); + this.logger.log('[FORM-COMP] getCurrentTranslation cancelCommands::', this.cancelCommands); + }) + } + + + setCancelCommands() { + //this.cancelCommandsString.split(","); + this.intentForm.cancelCommands = this.cancelCommandsString + .split(',') + .map(element => element.trim()) + .filter(element => element !== ''); + this.jsonGenerator(); + } + + setCancelReplay() { + this.intentForm.cancelReply = this.cancelReply; + this.logger.log('[FORM-COMP] setCancelReplay this.intentForm.cancelReply', this.intentForm.cancelReply) + this.jsonGenerator(); + } + + jsonGenerator() { + this.logger.log('[FORM-COMP] jsonGenerator this.intentForm:: ', this.intentForm); + // this.intentSelected.form = this.intentForm; + this.updateIntentForm.emit(this.intentForm); + // this.logger.log('[FORM-COMP] jsonGenerator this.intentSelected:: ', this.intentSelected); + } + + openSettingsForm() { + this.displaySettingsButton = false; + this.displayCancelButton = true; + this.displaySettingForm = true; + this.cancelCommands = this.intentForm.cancelCommands; + this.cancelReply = this.intentForm.cancelReply; + this.cancelCommandsString = this.cancelCommands.toString(); + this.scrollToTop(); + this.logger.log('[FORM-COMP] cancelCommands ', this.cancelCommands) + this.logger.log('[FORM-COMP] cancelReply ', this.cancelReply) + this.logger.log('[FORM-COMP] cancelCommandsString ', this.cancelCommandsString) + + // this.cancelCommandsString = this.cancelCommands.toString(); // this was commented - not commented in v 3.2.8 + this.logger.log('[FORM-COM] openSettingsForm displaySettingsButton', this.displaySettingsButton) + this.logger.log('[FORM-COM] openSettingsForm displayCancelButton', this.displayCancelButton) + this.logger.log('[FORM-COM] openSettingsForm displaySettingForm', this.displaySettingForm) + this.logger.log('[FORM-COM] openSettingsForm cancelCommandsString', this.cancelCommandsString) + } + + closeSettingsForm() { + this.displaySettingsButton = true; + this.displayCancelButton = false; + this.displaySettingForm = false; + this.cancelCommandsString = this.cancelCommands.toString(); // this was commented - not commented in v 3.2.8 + this.logger.log('[FORM-COM] closeSettingsForm displaySettingsButton', this.displaySettingsButton) + this.logger.log('[FORM-COM] closeSettingsForm displayCancelButton', this.displayCancelButton) + this.logger.log('[FORM-COM] closeSettingsForm displaySettingForm', this.displaySettingForm) + this.logger.log('[FORM-COM] closeSettingsForm cancelCommandsString', this.cancelCommandsString) + + } + + closeGeneral() { + // if (this.intentForm) { + if (this.intentFormSize > 0) { + this.displaySettingForm = false; + this.displaySettingsButton = true; + } else { + this.displayBoxNewForm = false; + this.displayNewFormButton = true; + } + this.displayCancelButton = false; + } + + openDeleteFieldModal(index: string) { + // this.logger.log('this.translations:::: ', this.translations); + let i: number = +index; + this.displayMODAL = true; + this.translateMap.deleteField = this.translations['CDSForm.DeleteField'] ? this.translations['CDSForm.DeleteField'] : ''; + this.translateMap.confirmDeleteField = this.translations['CDSForm.ConfirmDeleteField'] ? this.translations['CDSForm.ConfirmDeleteField'] : ''; + this.translateMap.nameField = this.fields[i].name; + this.selectedObjectId = index; + } + + + + // presenModalDeleteForm() { + // swal({ + // title: "Are you sure", + // text: "this.youAreAboutToJoinMsg + ': ' + chatAgent", + + // icon: "info", + // buttons: { + // cancel: "this.cancelMs"g, + // catch: { + // text: this.joinToChatMsg, + // value: "catch", + // }, + // }, + + // // `"Cancel", ${this.goToMultilanguagePageMsg}`], + // dangerMode: false, + // }) + // .then((value) => { + // this.logger.log('[WS-REQUESTS-LIST][SERVED] ARE YOU SURE TO JOIN THIS CHAT ... value', value) + + // if (value === 'catch') { + // this.onJoinHandled(request_id, this.currentUserID); + // } + // }) + // } + + + /** Event modal confirm delete field */ + confirmDeleteModal(index: string) { + this.logger.log('[FORM-COMP] confirmDeleteModal index ', index) + this.logger.log('[FORM-COMP] confirmDeleteModal this.idForm ', this.idForm) + if (index === this.idForm) { + // if (index === this.selectedFormId) { + + this.deleteForm(); + } else { + this.displayAddForm = false; + this.displayEditForm = false; + let i: number = +index; + this.fields.splice(i, 1); + if (this.fields.length === 0) { + this.deleteForm(); + } + this.intentForm.fields = this.fields; + this.logger.log('confirmDeleteModal::: ', this.intentForm, this.fields); + } + this.jsonGenerator(); + this.displayMODAL = false; + } + + + openBoxNewFormForm() { + // this.intentForm = null; + // this.intentForm = new Form(); + this.fields = []; + this.displayBoxNewForm = true; + this.displayTilebotAddEditForm = true; + this.displayCancelButton = true; + this.displayNewFormButton = false; + this.displaySettingsButton = false; + this.displayAddForm = false; + this.displayEditForm = false; + this.displaySettingForm = false; + this.intentFormSize = 0 + this.logger.log('[FORM-COM] openBoxNewFormForm - displayBoxNewForm ', this.displayBoxNewForm, 'intentForm', this.intentForm); + } + + private deleteForm() { + this.displayTilebotAddEditForm = false; + this.displayNewFormButton = true; + this.displayBoxNewForm = false; + this.displaySettingForm = false; + this.displayAddForm = false; + this.displayEditForm = false + this.displayCancelButton = false; + this.displaySettingsButton = false; + this.intentForm = new Form(); + // this.intentForm = null; + this.fields = []; + this.intentFormSize = 0; + this.logger.log('[FORM-COM] deleteForm - displayBoxNewForm ', this.displayBoxNewForm, 'intentForm', this.intentForm); + } + + + private resetForm() { + this.intentForm = new Form(); + this.fields = []; + this.displayNewFormButton = false; + this.displaySettingsButton = true; + this.displayAddForm = false; + this.displayEditForm = false; + this.displayTilebotAddEditForm = false; + } + + // ------------------------------------- + // Form Field + // ------------------------------------- + /** Event modal close delete field */ + closeDeleteModal(i: number) { + this.displayMODAL = false; + } + + /** Event add field */ + eventAddField() { + this.displayEditForm = false; + this.selectedField = null; + this.displayAddForm = true; + this.openAddEditForm(); + this.logger.log('[FORM-COMP] eventAddField displayEditForm ', this.displayEditForm) + this.logger.log('[FORM-COMP] eventAddField selectedField ', this.selectedField) + this.logger.log('[FORM-COMP] eventAddField displayAddForm ', this.displayAddForm) + } + + /** Event edit field */ + eventEditField(i: number) { + this.closeAddEditForm(); + setTimeout(() => { + this.selectedField = this.fields[i]; + this.displayAddForm = false; + this.displayEditForm = true; + this.openAddEditForm(); + }, 300); + this.logger.log('[FORM-COMP] eventEditField selectedField ', this.selectedField) + this.logger.log('[FORM-COMP] eventEditField displayAddForm ', this.displayAddForm) + this.logger.log('[FORM-COMP] eventEditField displayEditForm ', this.displayEditForm) + } + + eventDropField(fields) { + this.intentForm.fields = fields; + this.fields = fields; + this.updateIntentForm.emit(this.intentForm); + //this.updateIntentForm.emit(this.intentForm); + this.closeAddEditForm(); + this.selectedField = null; + } + + + /** Event close add/edit form accordion */ + closeAddEditForm() { + this.displayAddForm = false; + this.displayEditForm = false; + this.displayTilebotAddEditForm = true; + this.scrollToTop(); + this.logger.log('[FORM-COMP] closeAddEditForm displayAddForm ', this.displayAddForm) + this.logger.log('[FORM-COMP] closeAddEditForm displayEditForm ', this.displayEditForm) + this.logger.log('[FORM-COMP] closeAddEditForm displayEditForm ', this.displayTilebotAddEditForm) + } + + /** Event SAVE field */ + saveAddEditForm(event: any) { + const objIndex = this.fields.findIndex(obj => obj.name === event.name); + if (objIndex === -1) { + this.fields.push(event); + } else { + this.fields.splice(objIndex, 1, event); + } + if (this.intentForm) { + this.intentForm.fields = this.fields; + this.logger.log('[FORM-COMP] saveAddEditForm intentForm ', this.intentForm) + } + this.displayAddForm = false; + this.displayEditForm = false; + this.displayTilebotAddEditForm = true; + this.jsonGenerator(); + } + + openAddEditForm() { + this.displayTilebotAddEditForm = false; + this.displayTilebotAddEditForm = true; + this.scrollToBottom(); + } + + openDeleteForm() { + this.logger.log('[FORM-COMP] openDeleteForm this.translations:::: ', this.translations); + this.translateMap.deleteField = this.translations['CDSForm.DeleteForm'] ? this.translations['CDSForm.DeleteForm'] : ''; + this.translateMap.confirmDeleteField = this.translations['CDSForm.ConfirmDeleteForm'] ? this.translations['CDSForm.ConfirmDeleteForm'] : ''; + this.displayMODAL = true; + this.selectedObjectId = this.idForm; + this.logger.log('[FORM-COMP] openDeleteForm displayMODAL', this.displayMODAL) + this.logger.log('[FORM-COMP openDeleteForm selectedObjectId', this.selectedObjectId) + } + + goToFormMoreInfo() { + const url = this.URL_to_form_more_info; + window.open(url, '_blank'); + } + + + + + + /** START EVENTS */ + /** Events of FORM EDIT ADD */ + onChangedFormFields(event:any){ + try { + const objIndex = this.fields.findIndex(obj => obj.name === event.name); + if (objIndex === -1) { + this.fields.push(event); + } else { + this.fields.splice(objIndex, 1, event); + } + if (this.intentForm) { + this.intentForm.fields = this.fields; + } + // this.intentSelected.form = this.intentForm; + // this.updateIntentForm.emit(this.intentForm); + this.logger.log('[FORM-COMP] saveAddEditForm intentForm ', this.intentForm); + this.jsonGenerator(); + } catch (error) { + this.logger.log('[FORM-COMP] error ', error); + } + } + + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form.component.spec.ts new file mode 100644 index 000000000..83ddf2a54 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsFormComponent } from './form.component'; + +describe('FormComponent', () => { + let component: CdsFormComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsFormComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.html new file mode 100644 index 000000000..9fe0a8c06 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.html @@ -0,0 +1,41 @@ + + + \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.scss new file mode 100644 index 000000000..01e4f3201 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.scss @@ -0,0 +1,42 @@ +.modal { + display: block; + background-color: rgba(90,90,90,0.5); +} + +.modal-header { + background-color:#ff5252; + padding: 15px; + border-bottom: 1px solid #e5e5e5; + button.close { + background: unset; + border: unset; + span { + color: #fff; + } + } +} + +.modal-title { + color: #fff; + .material-icons { + vertical-align: middle; + span { + vertical-align: middle; + padding-left:8px; + } + } +} + +.modal-body { + color:rgba(0,0,0,0.87); + margin-top: 10px; +} + +.modal-footer{ + padding: 7px !important; + background-color: #eeeeee; + gap: 10px; + .btn-close-delete { + padding:12px 16px; + } +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.ts new file mode 100644 index 000000000..17fd47d7a --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window-new.component.ts @@ -0,0 +1,27 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +@Component({ + selector: ' selector: 'appdashboard-modal-window-new',-new', + templateUrl: './modal-window-new.component.html', + styleUrls: ['./modal-window-new.component.scss'] +}) +export class ModalWindowComponent implements OnInit { + @Output() confirmDeleteModal = new EventEmitter(); + @Output() closeDeleteModal = new EventEmitter(); + @Input() translateMap: any; + @Input() objectId: string; + + constructor() { } + + ngOnInit(): void { + } + + confirmDelete() { + this.confirmDeleteModal.emit(this.objectId); + } + + closeDelete() { + this.closeDeleteModal.emit(); + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window.component.spec.ts new file mode 100644 index 000000000..d3c206c99 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/modal-window/modal-window.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ModalWindowComponent } from './modal-window.component'; + +describe('ModalWindowComponent', () => { + let component: ModalWindowComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ModalWindowComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ModalWindowComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.html new file mode 100644 index 000000000..e27bf6aa5 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.html @@ -0,0 +1,42 @@ +
+ +
+

{{'CDSCanvas.QuestionDescription' | translate:BRAND_BASE_INFO}}

+
+ + + format_quote + + + + + + + add + + +
+ +
+ +
+
+ + + format_quote + + + + + + delete + + +
+
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss new file mode 100644 index 000000000..dcd24b3e4 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss @@ -0,0 +1,135 @@ +h4 { + font-size: 16px; + color: var(--blu); +} + + +.cds-questions-main-content { + padding: 25px; + width: 100%; +} + +.cds-questions-container { + width: 100%; +} + +.cds-add-question-container { + margin-bottom: 18px; +} + +.cds-input-group { + margin-bottom: 8px; + flex-wrap: nowrap; + border: 1px solid var(--gray-light-02); + border-radius: 4px; +} + +// .cds-add-question-input { +// border: none; +// height: 47px; +// width: 100%; +// color: var(--blu); +// // border-top-right-radius: 4px; +// // border-bottom-right-radius: 4px; +// } + +.cds-question-input { + border: none; + // height: 47px; + width: 100%; + font-weight: 400; + color: var(--blu); + font-size: 12px; + padding: 4px 0px; +} + +.cds-group-addon-left { + // height: 47px; + border-radius: 0; + padding-left: 6px; + padding-right: 6px; + padding-top: 0px; + display: flex; + align-items: center; +} + +.cds-group-addon-question-right { + background: var(--blu); + // height: 47px; + border-radius: 0; + // padding-left: 6px; + // padding-right: 6px; + padding-top: 0px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + cursor: pointer; + max-width: 47px; + display: flex; + align-items: center; +} + +.cds-group-addon-question-right:hover { + opacity: 0.8 !important; +} + +.cds-group-addon-question-right-btn-text { + vertical-align: middle; + position: relative; + top: -7px; + color: #fff; +} + +.cds-group-addon-question-right-btn-icon { + color: #fff; + position: relative; + right: 3px; +} + +.cds-group-addon-right { + background: #fff; + border-radius: 0; + padding-left: 6px; + padding-right: 6px; + padding-top: 0px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; +} + +// .cds-group-addon-right-icon:hover { +// color: #ff4000 +// } + +.cds-group-addon-right:hover>.cds-group-addon-right-icon { + color: #ff4000; +} + +.add-question-btn-disabled { + pointer-events: none; + background: #aaa; +} + +// .cds-question-input:hover ~ .cds-group-addon-right ~ span { +// opacity: 1; +// } + +.cds-add-question-input::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + font-size: 14px; +} + +.cds-add-question-input:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-size: 14px; +} + +.cds-add-question-input::-ms-input-placeholder { + /* Microsoft Edge */ + font-size: 14px; +} + +.cds-add-question-input::-webkit-input-placeholder { + font-size: 14px; +} \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.ts new file mode 100644 index 000000000..33b55850b --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.ts @@ -0,0 +1,84 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { BRAND_BASE_INFO } from 'src/app/chatbot-design-studio/utils-resources'; +import { Intent } from 'src/app/models/intent-model'; +import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service'; +import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'; +// import { Question } from 'app/models/intent-model'; + +@Component({ + selector: 'cds-question-new', + templateUrl: './question-new.component.html', + styleUrls: ['./question-new.component.scss'] +}) +export class CdsQuestionComponent implements OnInit { + + @Input() intentSelected: Intent; + @Output() updateIntentSelected = new EventEmitter(); + + question: string; + questions_array: string[]; + newQuestion: string; + + BRAND_BASE_INFO = BRAND_BASE_INFO + private logger: LoggerService = LoggerInstance.getInstance(); + + constructor() { } + + ngOnInit(): void { + } + + ngOnChanges(changes: SimpleChanges){ + this.initialize(); + } + + private initialize(){ + this.question = ""; + this.questions_array = []; + this.newQuestion = ""; + try { + this.question = this.intentSelected.question; + this.questions_array = this.intentSelected.question.split(/\r?\n/).filter(element => element); + } catch (error) { + // error + this.logger.log('[INTENT-QUESTION] error initialize::', error) + } + } + + onAddQuestion() { + this.questions_array.push(this.newQuestion); + this.logger.log('[INTENT-QUESTION] ADD QUESTION questions_array ', this.questions_array); + const questionArrayJoinedWithNewLine = this.questions_array.join('\n'); + this.question = questionArrayJoinedWithNewLine.toString(); + this.newQuestion = ''; + this.updateIntentSelected.emit(this.question); + } + + onRemoveQuestion(questionindex: number) { + this.questions_array.splice(questionindex, 1); + this.logger.log('[INTENT-QUESTION] REMOVE QUESTION questions_array ', this.questions_array); + const questionArrayJoinedWithNewLine = this.questions_array.join('\n'); + this.question = questionArrayJoinedWithNewLine.toString(); + this.updateIntentSelected.emit(this.question); + } + + onChangeText(_question: string, index: number) { + this.logger.log('[INTENT-QUESTION] onChangeText _question', _question) + this.logger.log('[INTENT-QUESTION] onChangeText index', index) + this.logger.log('[INTENT-QUESTION] onChangeText > question ', _question) + this.logger.log('[INTENT-QUESTION] onChangeText questions_array ', this.questions_array) + this.logger.log('[INTENT-QUESTION] onChangeText questions_array - question at index ', index, ': ', this.questions_array[index]) + this.questions_array[index] = _question; + const questionArrayJoinedWithNewLine = this.questions_array.join('\n'); + this.logger.log('[INTENT-QUESTION] onChangeText EDITED questions_array ', this.questions_array) + this.logger.log('[INTENT-QUESTION] onChangeText EDITED questions_array questionArrayJoinedWithNewLine', questionArrayJoinedWithNewLine) + this.logger.log('[INTENT-QUESTION] onChangeText EDITED questions_array questionArrayJoinedWithNewLine TO STRING', questionArrayJoinedWithNewLine.toString()) + this.question = questionArrayJoinedWithNewLine.toString(); + this.updateIntentSelected.emit(this.question); + } + + // serve per mantenere il focus nel campo input mentre si edita un valore + trackByIndex(index: number, obj: any): any { + return index; + } + +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question.component.spec.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question.component.spec.ts new file mode 100644 index 000000000..e5dc65891 --- /dev/null +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CdsQuestionComponent } from './question.component'; + +describe('QuestionComponent', () => { + let component: CdsQuestionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ CdsQuestionComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CdsQuestionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 259c5c13e..46810d32c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -113,13 +113,13 @@
- - + - - + - - + - - + - - + - - + mixin` + +--- + +## References + +- Design System Tokens: See `_variables.scss` +- Material Component Styles: [Angular Material](https://material.angular.io/) +- SCSS Best Practices: [SASS Guidelines](https://sass-guidelin.es/) diff --git a/src/assets/sass/cds/_mixins.scss b/src/assets/sass/cds/_mixins.scss new file mode 100644 index 000000000..8e5d5216c --- /dev/null +++ b/src/assets/sass/cds/_mixins.scss @@ -0,0 +1,288 @@ +// ============================================================================ +// Design System SCSS Mixins +// Centralized reusable patterns for consistent styling across components +// ============================================================================ + +// ============ Layout Mixins ============ + +// Flex row container with gap +@mixin flex-row($gap: 8px, $align: center, $justify: flex-start) { + display: flex; + flex-direction: row; + align-items: $align; + justify-content: $justify; + gap: $gap; +} + +// Flex column container with gap +@mixin flex-column($gap: 8px, $align: center, $justify: flex-start) { + display: flex; + flex-direction: column; + align-items: $align; + justify-content: $justify; + gap: $gap; +} + +// Grid layout for 2-column response (icon + content) +@mixin response-grid($icon-width: 32px, $gap: 8px) { + display: grid; + grid-template-columns: $icon-width 1fr; + gap: $gap; + align-items: start; +} + +// ============ Panel Styling ============ + +// Toolbar/header pattern +@mixin panel-toolbar($padding: 10px 14px, $border-color: var(--ds-border), $bg-color: var(--ds-canvas)) { + display: flex; + align-items: center; + padding: $padding; + gap: 4px; + overflow-x: auto; + border-bottom: 1px solid $border-color; + background: $bg-color; + width: 100%; +} + +// Content area pattern +@mixin panel-content($padding: 18px 14px, $gap: 22px) { + @include flex-column($gap); + width: 100%; + padding: $padding; + min-height: auto; + overflow: auto; +} + +// Footer panel pattern +@mixin panel-footer($padding: 14px 18px, $border-color: var(--ds-border), $bg-color: var(--ds-canvas)) { + padding: $padding; + border-top: 1px solid $border-color; + @include flex-row(10px); + background: $bg-color; +} + +// ============ Empty State ============ + +// Empty state placeholder +@mixin empty-state($min-height: 80px, $padding: 20px, $gap: 8px) { + position: relative; + @include flex-column($gap, center, center); + min-height: $min-height; + padding: $padding; + border: 1px dashed var(--ds-border-strong, #d8d6d2); + border-radius: 10px; + background: var(--ds-canvas, #f7f6f3); + text-align: center; + + > * { + color: var(--ds-muted, #8a8884); + font-size: 13px; + line-height: 1.4; + } +} + +// ============ Borders & Spacing ============ + +// Border utility +@mixin border-solid($color: var(--ds-border), $width: 1px) { + border: $width solid $color; +} + +// Border with DS token +@mixin border-ds($side: 'all', $color: var(--ds-border), $width: 1px) { + @if $side == 'top' { + border-top: $width solid $color; + } @else if $side == 'bottom' { + border-bottom: $width solid $color; + } @else if $side == 'left' { + border-left: $width solid $color; + } @else if $side == 'right' { + border-right: $width solid $color; + } @else { + border: $width solid $color; + } +} + +// ============ Typography ============ + +// Mono text (for char counts, codes) +@mixin mono-text($size: 11px) { + font-family: "Geist Mono", monospace; + font-size: $size; +} + +// ============ Buttons & Controls ============ + +// Base button/control styling +@mixin control-button($size: 20px, $bg: var(--ds-surface), $color: var(--ds-muted), $hover-bg: var(--ds-canvas)) { + width: $size; + height: $size; + border-radius: 50%; + border: 1px solid var(--ds-border, #ececea); + background: $bg; + color: $color; + cursor: pointer; + @include flex-row(0, center, center); + transition: background 0.15s ease, color 0.15s ease; + + &:hover { + background: $hover-bg; + color: var(--ds-ink-2, #4a4a47); + } +} + +// Pill button (rounded end-to-end) +@mixin pill-button($height: 32px, $padding: 0 16px, $bg: var(--ds-surface), $color: var(--ds-ink)) { + height: $height; + padding: $padding; + border-radius: 999px; + border: 1px solid var(--ds-border, #ececea); + background: $bg; + color: $color; + font-size: 13px; + font-weight: 500; + cursor: pointer; + @include flex-row(0, center, center); + transition: background 0.12s, border-color 0.12s; + + &:hover { + border-color: var(--ds-border-strong, #d8d6d2); + background: var(--ds-canvas, #f7f6f3); + } +} + +// Chip/badge pattern +@mixin chip($bg: var(--ds-surface), $color: var(--ds-ink-2)) { + height: 28px; + padding: 0 10px; + border-radius: 999px; + border: 1px solid var(--ds-border, #ececea); + background: $bg; + color: $color; + font-size: 12.5px; + font-weight: 500; + @include flex-row(0, center, center); + transition: background 0.12s, border-color 0.12s; + + &:hover { + border-color: var(--ds-border-strong); + background: var(--ds-canvas, #f7f6f3); + } +} + +// ============ Shadow & Elevation ============ + +// Drop shadow for dragged elements +@mixin shadow-drag() { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); +} + +// Subtle shadow +@mixin shadow-subtle() { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +// ============ Material Overrides ============ + +// Material checkbox override with DS tokens +@mixin checkbox-override($color: var(--ds-ink, #1a1a19), $surface: var(--ds-surface, #fff)) { + ::ng-deep .mat-checkbox.mat-accent { + .mat-checkbox-frame { + border-color: $color !important; + } + } + + ::ng-deep .mat-checkbox-checked { + .mat-checkbox-background { + background-color: $color !important; + } + + .mat-checkbox-checkmark { + background: $color !important; + + .mat-checkbox-checkmark-path { + stroke: $surface !important; + stroke-width: 2px !important; + } + } + } +} + +// ============ Drag & Drop ============ + +// CDK drag preview styling +@mixin cdk-drag-preview() { + box-sizing: border-box; + border-radius: 10px; + @include shadow-drag(); + background: var(--ds-surface, #fff); +} + +// CDK drag placeholder +@mixin cdk-placeholder() { + opacity: 0.4; + background: var(--ds-border, #ececea); + border: 1px dashed var(--ds-border-strong, #d8d6d2); + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +// ============ Scrollbar ============ + +// Custom scrollbar styling +@mixin scrollbar-custom($width: 6px, $thumb-color: var(--ds-border-strong, #d8d6d2), $hover-color: var(--ds-ink-2, #4a4a47)) { + ::-webkit-scrollbar { + width: $width; + height: $width; + } + + ::-webkit-scrollbar-track { + background: transparent; + } + + ::-webkit-scrollbar-thumb { + background: $thumb-color; + border-radius: $width / 2; + + &:hover { + background: $hover-color; + } + } +} + +// ============ Focus & Interaction ============ + +// Focus ring for accessibility +@mixin focus-ring($color: var(--ds-focus-ring, oklch(0.85 0.05 240 / 0.55))) { + box-shadow: 0 0 0 3px $color; + transition: box-shadow 0.15s ease; +} + +// Transition utility +@mixin transition($property: all, $duration: 0.15s, $easing: ease) { + transition: $property $duration $easing; +} + +// ============ Responsive ============ + +// Mobile-first responsive mixin +@mixin respond-to($breakpoint) { + @if $breakpoint == 'sm' { + @media (min-width: 576px) { + @content; + } + } @else if $breakpoint == 'md' { + @media (min-width: 768px) { + @content; + } + } @else if $breakpoint == 'lg' { + @media (min-width: 992px) { + @content; + } + } @else if $breakpoint == 'xl' { + @media (min-width: 1200px) { + @content; + } + } +} diff --git a/src/assets/sass/cds/_variables.scss b/src/assets/sass/cds/_variables.scss index c51d3602a..ca95b2721 100644 --- a/src/assets/sass/cds/_variables.scss +++ b/src/assets/sass/cds/_variables.scss @@ -107,37 +107,49 @@ --header-height: 60px; --sidebar-base-width: 60px; - /** DESIGN STUDIO v2 — token palette (Design Studio.html) **/ + /** DESIGN STUDIO v3 — token palette (Reply Inspector.html - Design System V3) **/ + // Color palette --ds-bg: #fbfbfa; --ds-canvas: #f7f6f3; --ds-surface: #ffffff; - --ds-border: #ececea; - --ds-border-strong: #d8d6d2; - --ds-ink: #1a1a19; - --ds-ink-2: #4a4a47; + --ds-border: #e8e6e0; + --ds-border-strong: #d8d6d0; + --ds-ink: #14140e; + --ds-ink-2: #3a3935; --ds-muted: #8a8884; --ds-muted-2: #b3b1ac; + // Semantic colors --ds-accent: oklch(0.66 0.15 50); --ds-accent-soft: oklch(0.95 0.04 60); --ds-accent-ink: oklch(0.45 0.15 45); - --ds-green: oklch(0.68 0.13 155); + --ds-green: oklch(0.68 0.14 155); --ds-green-soft: oklch(0.95 0.04 155); --ds-blue: oklch(0.62 0.13 245); --ds-blue-soft: oklch(0.95 0.03 245); - --ds-red: oklch(0.62 0.16 28); - --ds-red-soft: oklch(0.95 0.03 28); + --ds-red: oklch(0.55 0.2 25); + --ds-red-soft: oklch(0.98 0.02 25); --ds-purple: oklch(0.6 0.14 290); - --ds-shadow-card: 0 1px 2px rgba(20,20,18,.04), 0 0 0 1px rgba(20,20,18,.05); - --ds-shadow-pop: 0 8px 24px -8px rgba(20,20,18,.12), 0 2px 6px rgba(20,20,18,.05), 0 0 0 1px rgba(20,20,18,.06); + // Shadows + --ds-shadow-card: 0 1px 2px rgba(20,20,18,0.04); + --ds-shadow-pop: 0 8px 24px -8px rgba(20,20,18,0.12), 0 2px 6px rgba(20,20,18,0.05); + // Focus ring + --ds-focus-ring: oklch(0.85 0.05 240 / 0.55); + + // Spacing & Radius --ds-radius: 10px; --ds-radius-sm: 6px; + --ds-radius-lg: 14px; + + // Typography + --ds-font-family: 'Geist', system-ui, sans-serif; + --ds-font-mono: 'Geist Mono', monospace; /** CONNECTOR **/ --success-connector: rgb(44, 191, 35); diff --git a/src/assets/sass/cds/action-styles.scss b/src/assets/sass/cds/action-styles.scss index 900eb0d5d..ab65c119b 100644 --- a/src/assets/sass/cds/action-styles.scss +++ b/src/assets/sass/cds/action-styles.scss @@ -374,3 +374,152 @@ appdashboard-filter{ line-height: 22px; } +// ============================================================================ +// SHARED ACTION REPLY STYLES (DS V3) +// ============================================================================ + +// Panel containers +.ds-action-panel { + display: flex; + flex-direction: column; + height: 100%; +} + +.ds-panel-toolbar { + display: flex; + align-items: center; + padding: 10px 14px; + gap: 4px; + overflow-x: auto; + border-bottom: 1px solid var(--ds-border, #ececea); + background: var(--ds-canvas, #f7f6f3); + width: 100%; + flex-wrap: nowrap; +} + +.ds-panel-content { + display: flex; + flex-direction: column; + width: 100%; + padding: 18px 14px; + gap: 22px; + min-height: auto; + max-height: calc(100vh - 180px); + overflow: auto; + margin-top: 0; + flex: 1; +} + +.ds-panel-footer { + padding: 14px 18px; + border-top: 1px solid var(--ds-border, #ececea); + display: flex; + align-items: center; + gap: 10px; + background: var(--ds-canvas, #f7f6f3); +} + +// Response grid (icon + content) +.ds-response-grid { + display: grid; + grid-template-columns: 32px 1fr; + gap: 8px; + align-items: start; + position: relative; + height: auto; + width: 100%; + margin: 0; +} + +.ds-response-drop { + position: absolute; + display: flex; + align-content: space-around; + width: 24px; + height: 26px; + left: 0; + top: 27px; + margin: 0; + color: var(--ds-muted, #8a8884); + cursor: grab; + background-color: transparent; + z-index: 1; + transition: color 0.15s ease; + + &:hover { + color: var(--ds-ink-2, #4a4a47); + } + + &.grabbing { + cursor: grabbing; + color: var(--ds-ink-2, #4a4a47); + } +} + +// Empty state +.ds-empty-state { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 80px; + padding: 20px; + margin: 18px 14px; + border: 1px dashed var(--ds-border-strong, #d8d6d2); + border-radius: 10px; + background: var(--ds-canvas, #f7f6f3); + text-align: center; + gap: 8px; + + .ds-empty-state-text { + font-weight: 400; + color: var(--ds-muted, #8a8884); + font-size: 13px; + line-height: 1.4; + } +} + +// Drag & drop +.ds-drag-preview { + box-sizing: border-box; + border-radius: 10px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); + background: var(--ds-surface, #fff); +} + +.ds-drag-placeholder { + opacity: 0.4; + background: var(--ds-border, #ececea); + border: 1px dashed var(--ds-border-strong, #d8d6d2); + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.ds-draggable-list { + &.cdk-drop-list-dragging .ds-draggable-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } +} + +// Custom scrollbar +.ds-scrollable { + ::-webkit-scrollbar { + width: 6px; + height: 6px; + } + + ::-webkit-scrollbar-track { + background: transparent; + } + + ::-webkit-scrollbar-thumb { + background: var(--ds-border-strong, #d8d6d2); + border-radius: 3px; + + &:hover { + background: var(--ds-ink-2, #4a4a47); + } + } +} + diff --git a/src/assets/sass/cds/styles.scss b/src/assets/sass/cds/styles.scss index 06436fe0a..d95c73d02 100644 --- a/src/assets/sass/cds/styles.scss +++ b/src/assets/sass/cds/styles.scss @@ -1,4 +1,5 @@ @import "./src/assets/sass/cds/_variables.scss"; +@import "./src/assets/sass/cds/_mixins.scss"; @import "./src/assets/sass/md/_variables.scss"; /** GENERIC **/ diff --git a/src/chat21-core/providers/abstract/upload.service.ts b/src/chat21-core/providers/abstract/upload.service.ts index fb72c83b8..c60399ff0 100644 --- a/src/chat21-core/providers/abstract/upload.service.ts +++ b/src/chat21-core/providers/abstract/upload.service.ts @@ -13,7 +13,7 @@ import { UploadModel } from '../../models/upload'; export abstract class UploadService { //params - private DEFAULT_URL: string = environment.apiUrl; + private DEFAULT_URL: string = environment.apiUrl || ''; private baseUrl: string = ''; public setBaseUrl(baseUrl: string): void { diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 2fedc1a3b..c1f9d4bd9 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,27 +1,36 @@ export const environment = { - production: false, - t2y12PruGU9wUtEGzBJfolMIgK: 'tokenKey', - VERSION: require('../../package.json').version, - DS_VERSION: '3', - remoteConfig: true, - remoteConfigUrl: './real_data/cds-config-local.json', - apiUrl: 'http://localhost:3000/', - widgetBaseUrl: 'http://localhost:4200/', - dashboardBaseUrl: 'http://localhost:4200/', - wsUrl: 'ws://localhost:3000/', - uploadEngine: 'native', - baseImageUrl: 'http://localhost:3000/', - logLevel: 'debug', - storage_prefix: 'tiledesk_', - firebaseConfig: { - apiKey: '', - authDomain: '', - databaseURL: '', - projectId: '', - storageBucket: '', - messagingSenderId: '', - appId: '', - vapidKey: '' - } + production: true, + t2y12PruGU9wUtEGzBJfolMIgK: 'CHANGEIT', + VERSION: require('../../package.json').version, + DS_VERSION: '3', + remoteConfig: true, + // remoteConfigUrl: './design-studio-config.json', + remoteConfigUrl: '/real_data/cds-config-local.json', + apiUrl: 'CHANGEIT', + widgetBaseUrl: 'CHANGEIT', + dashboardBaseUrl: 'CHANGEIT', + whatsappTemplatesBaseUrl: 'CHANGEIT', + wsUrl: 'ws://localhost:3000/', + uploadEngine: 'native', + baseImageUrl: 'CHANGEIT', + fileUploadAccept: "*/*", + logLevel: 'error', + aiModels: 'CHANGEIT', + storage_prefix: "CHANGEIT", + pineconeReranking: "CHANGEIT", + firebaseConfig: { + apiKey: 'CHANGEIT', + authDomain: 'CHANGEIT', + databaseURL: 'CHANGEIT', + projectId: 'CHANGEIT', + storageBucket: 'CHANGEIT', + messagingSenderId: 'CHANGEIT', + appId: 'CHANGEIT', + vapidKey: 'CHANGEIT' + }, + chat21Config: { + appId: 'tilechat', + MQTTendpoint: 'mqtt://localhost:15675/ws', // MQTT endpoint + APIendpoint: 'http://localhost:8004/api' + } }; - From fdf9d96f79019db861dd01123a9e69129930dfe4 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Tue, 5 May 2026 18:01:22 +0200 Subject: [PATCH 16/30] Fix cds-action-reply-new initialization to load data on ngOnInit Initialize arrayResponses from action.attributes.commands in ngOnInit, not just in ngOnChanges. This ensures data loads when component inputs are already set at creation time. Prevents empty reply state. Co-Authored-By: Claude Haiku 4.5 --- .../cds-action-reply-v1/cds-action-reply-new.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts index e8b8d70a0..413bcc58d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -80,6 +80,11 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { this.action._tdActionId = generateShortUID(); } this.idAction = `${this.intentSelected.intent_id}/${this.action._tdActionId}`; + + if (this.action && this.intentSelected) { + this.initialize(); + } + this.changeDetectorRef.detectChanges(); } From 7af4a8dc5f2c56ac13445a8fdae6b9a3a1a64487 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Tue, 5 May 2026 18:04:59 +0200 Subject: [PATCH 17/30] Revert to cds-action-reply component Switch back from cds-action-reply-new to cds-action-reply in all templates: - cds-intent.component.html - cds-panel-action-detail.component.html - cds-panel-detail.component.html Co-Authored-By: Claude Haiku 4.5 --- .../cds-canvas/cds-intent/cds-intent.component.html | 8 ++++---- .../cds-panel-action-detail.component.html | 8 ++++---- .../cds-panel-detail/cds-panel-detail.component.html | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 46810d32c..259c5c13e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -113,13 +113,13 @@
- - + - - + - - + - - + - - + - - + Date: Tue, 5 May 2026 20:02:07 +0200 Subject: [PATCH 18/30] Activate cds-action-reply-new with full compatibility - Add debug comment to verify new component loads - Add missing @Input() connector to new component for compatibility - Activate new component in all three templates: * cds-intent.component.html (REPLY + RANDOM_REPLY cases) * cds-panel-action-detail.component.html (REPLY + RANDOM_REPLY cases) * cds-panel-detail.component.html (REPLY + RANDOM_REPLY cases) Build verified: successfully compiled with zero errors. Co-Authored-By: Claude Haiku 4.5 --- .../cds-action-reply-new.component.html | 1 + .../cds-action-reply-v1/cds-action-reply-new.component.ts | 1 + .../cds-canvas/cds-intent/cds-intent.component.html | 8 ++++---- .../cds-panel-action-detail.component.html | 8 ++++---- .../cds-panel-detail/cds-panel-detail.component.html | 8 ++++---- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html index e8a2a1081..75cc2891b 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html @@ -1,4 +1,5 @@ +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts index 413bcc58d..d2491c292 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -27,6 +27,7 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { // ============ Inputs & Outputs ============ @Input() action: ActionReply; @Input() intentSelected: Intent; + @Input() connector: any; @Input() previewMode: boolean = true; @Output() updateAndSaveAction = new EventEmitter(); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 259c5c13e..46810d32c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -113,13 +113,13 @@
- - + - - + - - + - - + - - + - - + Date: Tue, 5 May 2026 20:10:40 +0200 Subject: [PATCH 19/30] Revert cds-action-reply-new activation - incomplete module The cds-actions-new.module.ts has missing imports (clone script incomplete). Reverted to old cds-action-reply component while the new module is being completed. New component remains in place with debug logging for testing when module is ready. Co-Authored-By: Claude Haiku 4.5 --- .../cds-action-reply-new.component.ts | 15 +++++++++++++++ .../cds-intent/cds-intent.component.html | 8 ++++---- .../cds-panel-action-detail.component.html | 8 ++++---- .../cds-panel-detail.component.html | 8 ++++---- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts index d2491c292..db0014aa0 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -66,7 +66,17 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { // ============ Lifecycle Hooks ============ ngOnInit(): void { + console.log('[CdsActionReplyNew] ngOnInit called'); + console.log('[CdsActionReplyNew] this.action:', this.action); + console.log('[CdsActionReplyNew] this.intentSelected:', this.intentSelected); + this.logger.log('CdsActionReplyNewComponent ngOnInit', this.action, this.intentSelected); + + if (!this.action) { + console.warn('[CdsActionReplyNew] Action is undefined in ngOnInit!'); + return; + } + this.typeAction = this.action._tdActionType === TYPE_ACTION.RANDOM_REPLY ? TYPE_ACTION.RANDOM_REPLY : TYPE_ACTION.REPLY; @@ -104,8 +114,13 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { this.intentNameResult = true; this.textGrabbing = false; + console.log('[CdsActionReplyNew] initialize() called with action:', this.action); + console.log('[CdsActionReplyNew] action.attributes:', this.action?.attributes); + console.log('[CdsActionReplyNew] action.attributes.commands:', this.action?.attributes?.commands); + try { this.arrayResponses = this.action?.attributes?.commands ?? []; + console.log('[CdsActionReplyNew] arrayResponses set to:', this.arrayResponses); } catch (error) { this.logger.error('Failed to initialize arrayResponses', error); this.arrayResponses = []; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 46810d32c..259c5c13e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -113,13 +113,13 @@
- - + - - + - - + - - + - - + - - + Date: Wed, 6 May 2026 09:17:00 +0200 Subject: [PATCH 20/30] Add V3 badge to Reply and Random Reply actions - Add badge: 'V3' to REPLY and RANDOM_REPLY in utils-actions.ts - Add .badge-V3 styling with green gradient in cds-action-description.component.scss - Badge appears in action detail panel for visual identification of V3 components Co-Authored-By: Claude Haiku 4.5 --- .../cds-action-description.component.scss | 3 +++ src/app/chatbot-design-studio/utils-actions.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss index dffc89d52..f5d69a22f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss @@ -94,6 +94,9 @@ background: linear-gradient(45deg, #e23131, #ff8736); } +.badge-V3 { + background: linear-gradient(45deg, #10b981, #059669); +} .deprecation-badge, .badge-DEP { diff --git a/src/app/chatbot-design-studio/utils-actions.ts b/src/app/chatbot-design-studio/utils-actions.ts index 398c05e48..8a13c2ca6 100644 --- a/src/app/chatbot-design-studio/utils-actions.ts +++ b/src/app/chatbot-design-studio/utils-actions.ts @@ -129,9 +129,9 @@ export const ACTIONS_LIST: { disabled?: boolean } } = { - REPLY : { name: 'CDSActionList.NAME.Reply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLY, src: "assets/images/actions/reply.svg", status: "active" , doc: "CDSActionList.DOC.Reply", }, + REPLY : { name: 'CDSActionList.NAME.Reply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLY, src: "assets/images/actions/reply.svg", status: "active" , doc: "CDSActionList.DOC.Reply", badge: 'V3' }, REPLYV2 : { name: 'CDSActionList.NAME.ReplyV2', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLYV2, src: "assets/images/actions/reply_v2.svg", status: "active" , doc: "CDSActionList.DOC.ReplyV2", }, - RANDOM_REPLY : { name: 'CDSActionList.NAME.RandomReply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.RANDOM_REPLY, src: "assets/images/actions/random_reply.svg", status: "active", doc: "CDSActionList.DOC.RandomReply" }, + RANDOM_REPLY : { name: 'CDSActionList.NAME.RandomReply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.RANDOM_REPLY, src: "assets/images/actions/random_reply.svg", status: "active", doc: "CDSActionList.DOC.RandomReply", badge: 'V3' }, AGENT : { name: 'CDSActionList.NAME.AgentHandoff', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.AGENT, src: "assets/images/actions/agent_handoff.svg", status: "active", doc: "CDSActionList.DOC.AgentHandoff" }, CLOSE : { name: 'CDSActionList.NAME.Close', chatbot_types: [TYPE_CHATBOT.CHATBOT, TYPE_CHATBOT.VOICE, TYPE_CHATBOT.VOICE_TWILIO], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.CLOSE, src: "assets/images/actions/close.svg", status: "active", doc: "CDSActionList.DOC.Close" }, OPEN_HOURS: { name: 'CDSActionList.NAME.IfOperatingHours', chatbot_types: [TYPE_CHATBOT.CHATBOT, TYPE_CHATBOT.VOICE, TYPE_CHATBOT.VOICE_TWILIO], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.OPEN_HOURS, src: "assets/images/actions/open_hours.svg", status: "active", doc: "CDSActionList.DOC.IfOperatingHours" }, From 1932cc040c9e892c14387fefcca28a8fff24c182 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Wed, 6 May 2026 12:08:27 +0200 Subject: [PATCH 21/30] rifattorizzazione actions e colori step 1 --- .../attributes/attributes.component.scss | 8 +- .../filter/filter.component.scss | 23 +- .../cds-base-element/menu/menu.component.scss | 8 +- .../preload-bar/preload-bar.component.scss | 2 +- .../radio-button/radio-button.component.scss | 4 +- .../select/select.component.scss | 16 +- .../text-editable-div.component.scss | 4 +- .../toogle/toogle.component.scss | 2 +- .../cds-chatbot-details.component.scss | 12 +- .../community/community.component.scss | 14 +- .../detail/detail.component.scss | 12 +- .../developer/developer.component.scss | 8 +- .../import-export.component.scss | 4 +- .../list-new/answer/answer-new.component.scss | 4 +- ...s-action-add-kb-content-new.component.scss | 8 +- .../cds-action-add-tag-new.component.scss | 2 +- .../ai-condition-new.component.scss | 2 +- .../attributes-dialog-new.component.scss | 2 +- ...cds-action-ai-condition-new.component.scss | 28 +- .../attributes-dialog-new.component.scss | 2 +- .../cds-action-ai-prompt-new.component.scss | 20 +- .../mcp-server-edit-dialog-new.component.scss | 6 +- .../mcp-servers-dialog-new.component.scss | 8 +- .../cds-action-askgpt-v2-new.component.scss | 26 +- .../cds-action-askgpt-new.component.scss | 2 +- .../operand/operand-new.component.scss | 4 +- .../operation/operation-new.component.scss | 10 +- ...-action-assign-variable-new.component.scss | 2 +- .../operand/operand-new.component.scss | 4 +- .../operation/operation-new.component.scss | 10 +- .../cds-action-brevo-new.component.scss | 10 +- .../cds-action-customerio-new.component.scss | 10 +- .../cds-action-description-new.component.scss | 8 +- .../cds-action-flow-log-new.component.scss | 4 +- .../attributes-dialog-new.component.scss | 2 +- .../cds-action-gpt-task-new.component.scss | 12 +- .../cds-action-hubspot-new.component.scss | 4 +- .../base-condition-row-new.component.scss | 10 +- .../base-filter-new.component.scss | 20 +- ...s-action-json-condition-new.component.scss | 12 +- .../variable-list-new.component.scss | 12 +- .../cds-action-lead-update-new.component.scss | 6 +- .../cds-action-make-new.component.scss | 4 +- .../cds-action-n8n-new.component.scss | 10 +- .../cds-action-reply-new.component.html | 468 ++++++----- .../cds-action-reply-new.component.scss | 730 ++++++++++++------ .../cds-action-reply-new.component.ts | 489 ++++++------ .../cds-action-reply-new.component.scss | 8 +- ...cds-action-reply-button-new.component.scss | 12 +- .../cds-action-reply-frame-new.component.scss | 2 +- ...ds-action-reply-gallery-new.component.scss | 22 +- .../cds-action-reply-image-new.component.scss | 22 +- ...ction-reply-jsonbuttons-new.component.scss | 4 +- ...s-action-reply-redirect-new.component.scss | 8 +- ...s-action-reply-settings-new.component.scss | 4 +- .../cds-action-reply-text-new.component.scss | 8 +- .../cds-action-reply-tools-new.component.scss | 58 +- .../whatsapp-receiver-new.component.scss | 18 +- .../cds-action-wait-new.component.scss | 18 +- ...s-action-web-request-v2-new.component.scss | 8 +- .../form-data/form-data-new.component.scss | 4 +- .../cds-action-web-request-new.component.scss | 4 +- ...cds-action-web-response-new.component.scss | 6 +- ...-action-whatsapp-static-new.component.scss | 6 +- .../form-edit-add-new.component.scss | 6 +- .../form-field/form-field-new.component.scss | 8 +- .../list-new/form/form-new.component.scss | 6 +- .../question/question-new.component.scss | 8 +- .../cds-action-audio-record.component.scss | 8 +- .../cds-action-blind-transfer.component.scss | 8 +- .../cds-action-dtmf-form.component.scss | 8 +- .../cds-action-dtmf-menu.component.scss | 8 +- .../cds-action-play-prompt.component.scss | 8 +- .../cds-action-speech-form.component.scss | 8 +- .../cds-action-voice.component.scss | 8 +- .../cds-action-reply-button.component.scss | 12 +- .../cds-action-reply-settings.component.scss | 4 +- ...cds-action-reply-voice-text.component.scss | 8 +- .../actions/list/answer/answer.component.scss | 4 +- .../cds-action-add-kb-content.component.scss | 8 +- .../cds-action-add-tag.component.scss | 2 +- .../ai-condition/ai-condition.component.scss | 2 +- .../attributes-dialog.component.scss | 2 +- .../cds-action-ai-condition.component.scss | 28 +- .../attributes-dialog.component.scss | 2 +- .../cds-action-ai-prompt.component.scss | 20 +- .../mcp-server-edit-dialog.component.scss | 6 +- .../mcp-servers-dialog.component.scss | 8 +- .../cds-action-askgpt-v2.component.scss | 26 +- .../cds-action-askgpt.component.scss | 2 +- .../operand/operand.component.scss | 4 +- .../operation/operation.component.scss | 10 +- .../cds-action-assign-variable.component.scss | 2 +- .../operand/operand.component.scss | 4 +- .../operation/operation.component.scss | 10 +- .../cds-action-brevo.component.scss | 10 +- .../cds-action-customerio.component.scss | 10 +- .../cds-action-description.component.scss | 8 +- .../cds-action-flow-log.component.scss | 4 +- .../attributes-dialog.component.scss | 2 +- .../cds-action-gpt-task.component.scss | 12 +- .../cds-action-hubspot.component.scss | 4 +- .../base-condition-row.component.scss | 10 +- .../base-filter/base-filter.component.scss | 20 +- .../cds-action-json-condition.component.scss | 12 +- .../variable-list.component.scss | 12 +- .../cds-action-lead-update.component.scss | 6 +- .../cds-action-make.component.scss | 4 +- .../cds-action-n8n.component.scss | 10 +- .../cds-action-reply.component.scss | 8 +- .../cds-action-reply.component.scss | 8 +- .../cds-action-reply-button.component.scss | 12 +- .../cds-action-reply-frame.component.scss | 2 +- .../cds-action-reply-gallery.component.scss | 22 +- .../cds-action-reply-image.component.scss | 22 +- ...ds-action-reply-jsonbuttons.component.scss | 4 +- .../cds-action-reply-redirect.component.scss | 8 +- .../cds-action-reply-settings.component.scss | 4 +- .../cds-action-reply-text.component.scss | 8 +- .../whatsapp-receiver.component.scss | 18 +- .../cds-action-wait.component.scss | 18 +- .../cds-action-web-request-v2.component.scss | 8 +- .../form-data/form-data.component.scss | 4 +- .../cds-action-web-request.component.scss | 4 +- .../cds-action-web-response.component.scss | 6 +- .../cds-action-whatsapp-static.component.scss | 6 +- .../form-edit-add.component.scss | 6 +- .../form/form-field/form-field.component.scss | 8 +- .../actions/list/form/form.component.scss | 6 +- .../list/question/question.component.scss | 8 +- .../cds-action-arrow.component.scss | 4 +- .../cds-action-controls.component.scss | 2 +- .../audio-upload/audio-upload.component.scss | 22 +- .../cds-color-menu.component.scss | 2 +- .../cds-connector-in.component.scss | 2 +- .../cds-connector.component.scss | 4 +- .../cds-widget-logs.component.scss | 18 +- .../context-menu/context-menu.component.scss | 4 +- .../delay-slider/delay-slider.component.scss | 55 +- .../delay-text/delay-text.component.scss | 12 +- .../element-from-url.component.scss | 6 +- .../height-slider.component.scss | 6 +- .../image-upload/image-upload.component.scss | 22 +- .../base-elements/text/text.component.scss | 28 +- .../textarea/textarea.component.scss | 30 +- .../cds-canvas/cds-canvas.component.scss | 2 +- .../cds-canvas/cds-canvas.module.ts | 6 + .../cds-intent/cds-intent.component.html | 8 +- .../cds-intent/cds-intent.component.scss | 4 +- .../cds-notes/cds-notes.component.scss | 2 +- .../cds-panel-action-detail.component.html | 8 +- ...-panel-button-configuration.component.scss | 8 +- .../cds-panel-connector-menu.component.scss | 2 +- .../cds-panel-detail.component.html | 8 +- .../cds-panel-actions.component.scss | 10 +- .../cds-panel-elements.component.scss | 2 +- .../cds-panel-intent-detail.component.scss | 34 +- .../cds-panel-note-detail.component.scss | 42 +- .../cds-panel-publish.component.scss | 18 +- .../cds-dashboard.component.scss | 2 +- .../cds-splash-screen.component.scss | 2 +- .../cds-fulfillment.component.scss | 8 +- .../cds-global-panel-detail.component.scss | 4 +- .../cds-globals/cds-globals.component.scss | 24 +- .../condition/condition.component.scss | 4 +- .../rules-add/rules-add.component.scss | 4 +- .../cds-support/cds-support.component.scss | 2 +- .../chatbot-design-studio/utils-actions.ts | 6 +- .../cds-modal-activate-bot.component.scss | 6 +- .../change-alpha-color.component.scss | 12 +- .../modals/changelog/changelog.component.scss | 2 +- .../mouse-tips/mouse-tips.component.scss | 8 +- src/assets/sass/cds/_variables.scss | 13 +- src/assets/sass/cds/action-styles.scss | 28 +- src/assets/sass/cds/settings-section.scss | 6 +- src/assets/sass/cds/styles.scss | 21 +- 176 files changed, 1824 insertions(+), 1541 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-base-element/attributes/attributes.component.scss b/src/app/chatbot-design-studio/cds-base-element/attributes/attributes.component.scss index b4ca68262..7dbdce903 100644 --- a/src/app/chatbot-design-studio/cds-base-element/attributes/attributes.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/attributes/attributes.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: var(--blu-light-01); + --background-color: var(--ds-bg); --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px @@ -113,7 +113,7 @@ padding: 0 10px; border-radius: 0 var(--base-radius) var(--base-radius) 0; color: var(--gray); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); width: calc(50% - 2px); text-overflow: ellipsis; overflow: hidden; @@ -122,7 +122,7 @@ } .dx-input:focus, .sx-input:focus { - border-color: var(--blu); + border-color: var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss index 5c8f64bf4..949ac77b2 100644 --- a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss @@ -1,5 +1,5 @@ :host{ - --textColor: #{var(--blu)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; --border-radius-base: 8px; @@ -72,13 +72,13 @@ span.material-icons{ font-size: 20px; - color: var(--backGroundColor); + color: var(--ds-bg); } &:hover{ background-color: var(--textColor); span.material-icons{ - color: var(--backGroundColor); + color: var(--ds-bg); } } } @@ -102,9 +102,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -122,6 +122,7 @@ } &:hover{ + background: var(--ds-bg); border-color: var(--textColor); color: var(--textColor); cursor: pointer; @@ -146,9 +147,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -221,14 +222,14 @@ padding: 6px 15px; transition: background-color 0.3s ease 0s, border 0.3s ease 0s, opacity 0.3s ease 0s; cursor: pointer; - background: var(--backGroundColor); + background: var(--ds-bg); border-width: 1px; border-style: solid; - border-color: var(--backGroundColor); + border-color: var(--ds-bg); border-image: initial; font-size: 12px; &:hover{ - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); border-color: var(--textColor); div.remove{ opacity: 1; @@ -260,7 +261,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } diff --git a/src/app/chatbot-design-studio/cds-base-element/menu/menu.component.scss b/src/app/chatbot-design-studio/cds-base-element/menu/menu.component.scss index b1d79db7d..662f78702 100644 --- a/src/app/chatbot-design-studio/cds-base-element/menu/menu.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/menu/menu.component.scss @@ -1,8 +1,8 @@ :host { - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; --icon-color-menu: #{var(--gray-light-01)}; - --text-hover-color: #{var(--blu)}; - --icon-hover-color: #{var(--blu)}; + --text-hover-color: #{var(--ds-ink)}; + --icon-hover-color: #{var(--ds-ink)}; --base-padding: 6px; } @@ -85,7 +85,7 @@ .custom-divider { margin-top: 5px; margin-bottom: 5px; - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } .current-user{ diff --git a/src/app/chatbot-design-studio/cds-base-element/preload-bar/preload-bar.component.scss b/src/app/chatbot-design-studio/cds-base-element/preload-bar/preload-bar.component.scss index 08f2b5b80..68bdf4859 100644 --- a/src/app/chatbot-design-studio/cds-base-element/preload-bar/preload-bar.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/preload-bar/preload-bar.component.scss @@ -13,6 +13,6 @@ z-index: 2; height: 4px; border-radius: 2px; - background-color: var(--blu); + background-color: var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-base-element/radio-button/radio-button.component.scss b/src/app/chatbot-design-studio/cds-base-element/radio-button/radio-button.component.scss index 8ea389cc9..1c7c9ffef 100644 --- a/src/app/chatbot-design-studio/cds-base-element/radio-button/radio-button.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/radio-button/radio-button.component.scss @@ -1,6 +1,6 @@ :host{ - --selectedColor: #{var(--blu)}; - --text-color : #{var(--blu-light-02)}; + --selectedColor: #{var(--ds-ink)}; + --text-color : #{var(--border)}; --rows: 1; --columns: 1 diff --git a/src/app/chatbot-design-studio/cds-base-element/select/select.component.scss b/src/app/chatbot-design-studio/cds-base-element/select/select.component.scss index 71418e547..4146ec02f 100644 --- a/src/app/chatbot-design-studio/cds-base-element/select/select.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/select/select.component.scss @@ -27,7 +27,7 @@ span.material-icons{ font-size: 20px; padding: 0px 4px; - color: var(--blu-light-02); + color: var(--border); &.intent-start{ color: var(--color-green-hex); @@ -40,7 +40,7 @@ span.label-select { margin-right: 4px; - color: var(--blu); + color: var(--ds-ink); line-height: 17px; } @@ -52,7 +52,7 @@ span.label-select-option.right-badge { margin-left: auto; background-color: var(--gray-light-02); - color: var(--blu); + color: var(--ds-ink); padding: 1px 6px; border-radius: 999px; font-size: 11px; @@ -85,11 +85,11 @@ } // &.ng-option-marked { - // // background-color: rgba(var(--blu-light-02), .23) !important; + // // background-color: rgba(var(--border), .23) !important; // } // &.ng-option-selected{ - // // background-color: rgba(var(--blu-light-02), .43) !important; + // // background-color: rgba(var(--border), .43) !important; // // span.label-select-option { // // color: #848484; @@ -112,7 +112,7 @@ .ng-select .ng-select-container { height: 43px; border-radius: var(--input-border-radius-base); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); .ng-value { display: flex; align-items: center; @@ -146,7 +146,7 @@ span.label-select-option.right-badge { margin-left: auto; background-color: var(--gray-light-02); - color: var(--blu); + color: var(--ds-ink); padding: 1px 6px; border-radius: 999px; font-size: 11px; @@ -179,7 +179,7 @@ .ng-dropdown-panel, .ng-select.ng-select-opened>.ng-select-container{ - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); } .ng-dropdown-panel .ng-dropdown-footer { border-top: 1px solid #ededed; diff --git a/src/app/chatbot-design-studio/cds-base-element/text-editable-div/text-editable-div.component.scss b/src/app/chatbot-design-studio/cds-base-element/text-editable-div/text-editable-div.component.scss index ba1c62476..6c79de4a9 100644 --- a/src/app/chatbot-design-studio/cds-base-element/text-editable-div/text-editable-div.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/text-editable-div/text-editable-div.component.scss @@ -87,12 +87,12 @@ transition: background-color 0.3s, color 0.3s; min-width: 45px; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-base-element/toogle/toogle.component.scss b/src/app/chatbot-design-studio/cds-base-element/toogle/toogle.component.scss index 892d5bb7d..533128db1 100644 --- a/src/app/chatbot-design-studio/cds-base-element/toogle/toogle.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/toogle/toogle.component.scss @@ -7,7 +7,7 @@ //CASE: checked &.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar { - background-color: var(--blu-light-02); + background-color: var(--border); } &.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb { background-color: var(--blu-02); diff --git a/src/app/chatbot-design-studio/cds-chatbot-details/cds-chatbot-details.component.scss b/src/app/chatbot-design-studio/cds-chatbot-details/cds-chatbot-details.component.scss index eff4b8a8d..d2b0a4b8a 100644 --- a/src/app/chatbot-design-studio/cds-chatbot-details/cds-chatbot-details.component.scss +++ b/src/app/chatbot-design-studio/cds-chatbot-details/cds-chatbot-details.component.scss @@ -47,7 +47,7 @@ .border-from-center { &:hover { - color: var(--blu); + color: var(--ds-ink); } // Set up base styles, we're going to scale instead of animating width/height @@ -64,7 +64,7 @@ // scale3d(, , ); &::before { // border-top: 2px solid $purple; - border-bottom: 3px solid var(--blu); + border-bottom: 3px solid var(--ds-ink); transform: scale3d(0, 1, 1); // Shrink only width } @@ -95,13 +95,13 @@ position: relative; display: block; height: 52px; - border-bottom: 3px solid var(--blu-light-02); + border-bottom: 3px solid var(--border); cursor: pointer; } .cds-bottom-nav li a { padding: 0px 15px; - color: var(--blu-light-02); + color: var(--border); line-height: 20px; } @@ -111,11 +111,11 @@ } .li-active { - border-bottom: 3px solid var(--blu) !important; + border-bottom: 3px solid var(--ds-ink) !important; pointer-events: none; } .li-active a { - color: var(--blu) !important; + color: var(--ds-ink) !important; } .disabled-li { pointer-events: none; diff --git a/src/app/chatbot-design-studio/cds-chatbot-details/community/community.component.scss b/src/app/chatbot-design-studio/cds-chatbot-details/community/community.component.scss index 72f9907de..2a490a684 100644 --- a/src/app/chatbot-design-studio/cds-chatbot-details/community/community.component.scss +++ b/src/app/chatbot-design-studio/cds-chatbot-details/community/community.component.scss @@ -7,13 +7,13 @@ position: relative; display: block; height: 53px; - border-bottom: 2px solid var(--blu-light-02); + border-bottom: 2px solid var(--border); cursor: pointer; } .cds-bottom-nav div a { padding: 0px 15px; - color: var(--blu-light-02); + color: var(--border); line-height: 20px; } @@ -23,11 +23,11 @@ } .li-active { - border-bottom: 2px solid var(--blu) !important; + border-bottom: 2px solid var(--ds-ink) !important; pointer-events: none; } .li-active a { - color: var(--blu) !important; + color: var(--ds-ink) !important; } .disabled-li { pointer-events: none; @@ -69,7 +69,7 @@ ng-select { ::ng-deep { .ng-select .ng-select-container { border-radius: var(--input-border-radius-base); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); } } @@ -210,7 +210,7 @@ ng-select { .border-from-center { &:hover { - color: var(--blu); + color: var(--ds-ink); } // Set up base styles, we're going to scale instead of animating width/height @@ -227,7 +227,7 @@ ng-select { // scale3d(, , ); &::before { // border-top: 2px solid $purple; - border-bottom: 3px solid var(--blu); + border-bottom: 3px solid var(--ds-ink); transform: scale3d(0, 1, 1); // Shrink only width } diff --git a/src/app/chatbot-design-studio/cds-chatbot-details/detail/detail.component.scss b/src/app/chatbot-design-studio/cds-chatbot-details/detail/detail.component.scss index bec815875..99a61e35c 100644 --- a/src/app/chatbot-design-studio/cds-chatbot-details/detail/detail.component.scss +++ b/src/app/chatbot-design-studio/cds-chatbot-details/detail/detail.component.scss @@ -12,7 +12,7 @@ input[type="text"] { -moz-box-sizing: border-box; border-radius: var(--input-border-radius-base); background-color: var(--color-white-hex); - border: solid 1px var(--blu-light-02); + border: solid 1px var(--border); } textarea[type="text"] { // min-width: 307px !important; @@ -31,7 +31,7 @@ textarea[type="text"] { -moz-box-sizing: border-box; border-radius: var(--input-border-radius-base); background-color: var(--color-white-hex); - border: solid 1px var(--blu-light-02); + border: solid 1px var(--border); } input[type="text"]:disabled { @@ -135,11 +135,11 @@ input[type="file"] { } .custom-file-upload { - border: 1px solid var(--blu); + border: 1px solid var(--ds-ink); display: inline-block; padding: 11px 12px; cursor: pointer; - background: var(--blu) !important; + background: var(--ds-ink) !important; color: var(--color-white-hex); border-radius: var(--button-border-radius-base); border-top-right-radius: 0; @@ -293,11 +293,11 @@ input[type="file"] { transition: all 0.3s ease-in 0s; } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label { - background-color: var(--blu); + background-color: var(--ds-ink); } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label, .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label:before { - border-color: var(--blu); + border-color: var(--ds-ink); } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label:before { right: 0px; diff --git a/src/app/chatbot-design-studio/cds-chatbot-details/developer/developer.component.scss b/src/app/chatbot-design-studio/cds-chatbot-details/developer/developer.component.scss index eaae66416..c79fb9051 100644 --- a/src/app/chatbot-design-studio/cds-chatbot-details/developer/developer.component.scss +++ b/src/app/chatbot-design-studio/cds-chatbot-details/developer/developer.component.scss @@ -29,7 +29,7 @@ position: absolute; top: 0; bottom: 0; - color: var(--blu); + color: var(--ds-ink); right: 0px; display: flex; align-items: center; @@ -76,7 +76,7 @@ color: var(--gray); &.active{ - color: var(--blu) + color: var(--ds-ink) } } } @@ -124,11 +124,11 @@ transition: all 0.3s ease-in 0s; } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label { - background-color: var(--blu); + background-color: var(--ds-ink); } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label, .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label:before { - border-color: var(--blu); + border-color: var(--ds-ink); } .nw-onoffswitch-checkbox:checked + .nw-onoffswitch-label:before { right: 0px; diff --git a/src/app/chatbot-design-studio/cds-chatbot-details/import-export/import-export.component.scss b/src/app/chatbot-design-studio/cds-chatbot-details/import-export/import-export.component.scss index 643f922f2..de35e9581 100644 --- a/src/app/chatbot-design-studio/cds-chatbot-details/import-export/import-export.component.scss +++ b/src/app/chatbot-design-studio/cds-chatbot-details/import-export/import-export.component.scss @@ -124,8 +124,8 @@ input[type="file"] { .cds-dwnld-example-csv { text-align: center; - border: 1px solid var(--blu-light-02); - background-color: var(--blu-light-02); + border: 1px solid var(--border); + background-color: var(--border); color: #202124; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss index 7d4e33f16..3401605ae 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/answer/answer-new.component.scss @@ -46,8 +46,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-flex { .mat-form-field-infix { textarea { - border: 1px solid var(--blu) !important; - outline: 1px solid var(--blu) !important; + border: 1px solid var(--ds-ink) !important; + outline: 1px solid var(--ds-ink) !important; transition: border .3s; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss index 35902d8d0..80f306155 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-kb-content/cds-action-add-kb-content-new.component.scss @@ -31,7 +31,7 @@ padding: 3px 7px; border: none; border-radius: 6px; - background: var(--blu); + background: var(--ds-ink); color: #fff; font-size: 12px; line-height: 12px; @@ -58,7 +58,7 @@ gap: 4px; padding: 0px; border-radius: 4px; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border: 0px solid #d2d4d6; font-size: 12px; } @@ -66,7 +66,7 @@ .model-name { margin: 0; font-weight: 300; - color: var(--blu); + color: var(--ds-ink); padding-left: 6px; } @@ -86,7 +86,7 @@ border-radius: 0px 4px 4px 0px; &:hover { - background: var(--blu); + background: var(--ds-ink); .remove-tag-icon { fill: var(--color-white-hex); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss index 583b15c3e..fbe282178 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-add-tag/cds-action-add-tag-new.component.scss @@ -19,7 +19,7 @@ cds-text#text.sx-input ::ng-deep { } .cds-group-addon-question-right { - background: var(--blu); + background: var(--ds-ink); // height: 47px; border-radius: 0; // padding-left: 6px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss index 2dadd07a5..f0a8672fa 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/ai-condition/ai-condition-new.component.scss @@ -31,7 +31,7 @@ .condition-number { font-size: 14px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); } .delete-condition-btn { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss index c758611f4..8e646cf1e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/attributes-dialog/attributes-dialog-new.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss index d22530235..a51d5bbf3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -71,7 +71,7 @@ div { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -204,7 +204,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -386,7 +386,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -408,7 +408,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -504,11 +504,11 @@ loading-spinner.custom-spinner ::ng-deep { .condition-number { font-size: 14px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); } // .condition-number2 { -// background-color: var(--blu); +// background-color: var(--ds-ink); // color: white; // padding: 4px 12px; // border-radius: 16px; @@ -530,9 +530,9 @@ loading-spinner.custom-spinner ::ng-deep { user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -547,9 +547,9 @@ loading-spinner.custom-spinner ::ng-deep { text-transform: none; box-shadow:none; &:hover { - border-color: var(--blu-light-02); + border-color: var(--border); color: var(--color-white-hex); - background-color: var(--blu); + background-color: var(--ds-ink); } .material-icons { @@ -576,7 +576,7 @@ loading-spinner.custom-spinner ::ng-deep { .prompt-label { font-size: 11px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); text-transform: uppercase; letter-spacing: 0.5px; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss index fd606cd44..384046778 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/attributes-dialog/attributes-dialog-new.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss index 5b5394601..b3d88d0d1 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -72,7 +72,7 @@ div { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -178,7 +178,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -388,7 +388,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -410,7 +410,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -496,7 +496,7 @@ loading-spinner.custom-spinner ::ng-deep { .configure-model-button { - color: var(--blu); + color: var(--ds-ink); text-align: right; padding: 0 5px; text-decoration: underline; @@ -636,8 +636,8 @@ cds-select#model-condition.not-configured ::ng-deep { &:hover { background-color: #e8f4ff; - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); } &.selected { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss index 7a0044449..2a92fce5d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss @@ -123,9 +123,9 @@ .tools-select-btn { padding: 6px 10px; font-size: 12px; - background: var(--blu) !important; + background: var(--ds-ink) !important; color: #fff !important; - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; &:hover:enabled { opacity: 0.9; @@ -205,7 +205,7 @@ border-radius: 4px; &:hover { - background: var(--blu); + background: var(--ds-ink); } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss index 314d196fd..784fc0504 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss @@ -91,7 +91,7 @@ border-radius: 4px; &:hover { - background: var(--blu); + background: var(--ds-ink); } } } @@ -190,7 +190,7 @@ .mcp-server-item { background-color: #ffffff; - border: 2px solid var(--blu-light-01); + border: 2px solid var(--ds-bg); border-radius: 8px; padding: 8px 12px; font-size: 14px; @@ -207,7 +207,7 @@ min-height: 50px; &:hover { - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border-color: #b0b0b0; } @@ -275,7 +275,7 @@ margin-top: 4px; .material-icons { font-size: 20px; - color: var(--blu); + color: var(--ds-ink); } &:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss index 38cb79185..565ce19c0 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss @@ -3,9 +3,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; --text-color-gray: #{var(--gray)}; } @@ -42,7 +42,7 @@ padding: 3px 7px; border: none; border-radius: 6px; - background: var(--blu); + background: var(--ds-ink); color: #fff; font-size: 12px; line-height: 12px; @@ -69,7 +69,7 @@ gap: 4px; padding: 0px; border-radius: 4px; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border: 0px solid #d2d4d6; font-size: 12px; } @@ -77,7 +77,7 @@ .model-name { margin: 0; font-weight: 300; - color: var(--blu); + color: var(--ds-ink); padding-left: 6px; } @@ -97,7 +97,7 @@ border-radius: 0px 4px 4px 0px; &:hover { - background: var(--blu); + background: var(--ds-ink); .remove-tag-icon { fill: var(--color-white-hex); } @@ -219,7 +219,7 @@ mat-expansion-panel ::ng-deep { position: absolute; left: 0; top: 0; - color: var(--blu); + color: var(--ds-ink); font-weight: 700; font-size: 10px; line-height: 1; @@ -251,7 +251,7 @@ cds-select#model-condition ::ng-deep{ .ng-dropdown-panel-items.scroll-host .ng-optgroup { padding: 0 10px; - color: var(--blu); + color: var(--ds-ink); font-weight: 500; font-size: 14px; background: var(--blu-light-03); @@ -381,7 +381,7 @@ cds-select#model-condition ::ng-deep{ background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -403,7 +403,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -510,7 +510,7 @@ mat-checkbox ::ng-deep { flex-direction: row; justify-content: space-between; align-items: center; - color: var(--blu); + color: var(--ds-ink); font-weight: 400; font-size: 12px; } @@ -621,7 +621,7 @@ cds-select#model-condition.not-configured ::ng-deep { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -642,7 +642,7 @@ cds-select#model-condition.not-configured ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss index 78820ca24..c592cc2e5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt/cds-action-askgpt-new.component.scss @@ -1,5 +1,5 @@ .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss index 4e7cd68aa..a8a03d5f3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operand/operand-new.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --text-color: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --text-color: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss index d5f15dc85..ce0bce062 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/operation/operation-new.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -29,9 +29,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -99,7 +99,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss index 1cad14757..87a30490e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss @@ -5,7 +5,7 @@ .material-icons { - color: var(--blu); + color: var(--ds-ink); font-size: 16px; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss index 7de469476..0d81e0d4a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operand/operand-new.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss index d5f15dc85..ce0bce062 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/operation/operation-new.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -29,9 +29,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -99,7 +99,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss index e4c355de6..dbfba6b23 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss index a753caa1c..b635b291c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss @@ -3,9 +3,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } /** button TOOGLE */ @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss index dffc89d52..c144ffeca 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-description/cds-action-description-new.component.scss @@ -13,7 +13,7 @@ .label-action { font-size: 12px !important; - color: var(--blu) !important; + color: var(--ds-ink) !important; width: 100%; } @@ -161,7 +161,7 @@ border-radius: 4px; // margin-right: 6px; // align-self: start; - color: var(--blu); + color: var(--ds-ink); background: none; display: flex; @@ -182,7 +182,7 @@ font-size: 14px; font-weight: 500; margin: 0; - color: var(--blu); + color: var(--ds-ink); } } @@ -192,7 +192,7 @@ align-items: center; justify-content: flex-start; font-size: 11px; - color: var(--blu-light-02); + color: var(--border); line-height: 1.5; span { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss index 3a65431a4..9d521f3d3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-flow-log/cds-action-flow-log-new.component.scss @@ -1,9 +1,9 @@ /** NG-SELECT **/ // .ng-select ::ng-deep .ng-select-container { // border-radius: var(--input-border-radius-base); -// border: 1px solid var(--blu-light-02); +// border: 1px solid var(--border); // } // .ng-select.ng-select-focused ::ng-deep .ng-select-container { -// border: 1px solid var(--blu-light-02); +// border: 1px solid var(--border); // box-shadow: none; // } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss index a7d4eec7d..1dc0e63b7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/attributes-dialog/attributes-dialog-new.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss index 3ac44e8dc..b17c07337 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -189,7 +189,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -350,7 +350,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -372,7 +372,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss index 1729d508f..63f17d379 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: var(--blu-light-01); + --background-color: var(--ds-bg); //--slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } .custom-expansion-panel { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss index 629f31991..bb85962d3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss @@ -151,13 +151,13 @@ section.header{ font-size: 16px; line-height: 20px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); margin: 0; } span.material-icons{ font-size: 25px; cursor: pointer; - color: var(--blu); + color: var(--ds-ink); } } @@ -235,13 +235,13 @@ section.condition{ margin: 5px; padding: 10px 15px; transition: all 0.3s ease 0s; - background-color: var(--blu-light-01); - color: var(--blu); + background-color: var(--ds-bg); + color: var(--ds-ink); cursor: pointer; &.active, &:hover{ - background: var(--blu); + background: var(--ds-ink); color: var(--blu-light-03); img{ filter: brightness(0) saturate(100%) invert(100%) sepia(20%) saturate(7023%) hue-rotate(179deg) brightness(106%) contrast(89%); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss index be6fe8a12..23ea9b3ed 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-filter/base-filter-new.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -58,14 +58,14 @@ span.material-icons, span.material-icons-outlined{ font-size: 20px; - color: var(--backGroundColor); + color: var(--ds-bg); } &:hover{ background-color: var(--textColor); span.material-icons, span.material-icons-outlined{ - color: var(--backGroundColor); + color: var(--ds-bg); } } } @@ -89,9 +89,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -159,13 +159,13 @@ padding: 4px 15px; transition: background-color 0.3s ease 0s, border 0.3s ease 0s, opacity 0.3s ease 0s; cursor: pointer; - background: var(--backGroundColor); + background: var(--ds-bg); border-width: 1px; border-style: solid; - border-color: var(--backGroundColor); + border-color: var(--ds-bg); border-image: initial; &:hover{ - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); border-color: var(--textColor); div.remove{ opacity: 1; @@ -196,7 +196,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss index d0cc53f8d..ad482dc06 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--blu-light-03)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -164,7 +164,7 @@ cds-select.operator ::ng-deep{ } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } @@ -183,15 +183,15 @@ cds-select.operator ::ng-deep{ } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss index 16c78ad65..09de8d689 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/variable-list/variable-list-new.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px @@ -29,7 +29,7 @@ .material-icons, .material-icons-outlined{ - color: var(--blu-light-02); + color: var(--border); font-size: 18px; &:hover.delete{ @@ -76,7 +76,7 @@ } .material-icons, .material-icons-outlined { - color: var(--blu); + color: var(--ds-ink); } } } @@ -147,12 +147,12 @@ justify-content: center; .material-icons{ margin-right: 15px; - color: var(--blu); + color: var(--ds-ink); font-size: 24px; font-weight: 500; } div { - color: var(--blu); + color: var(--ds-ink); font-size: 16px; font-weight: 600; line-height: 20px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss index 24ddcf0d1..f6a06af06 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-lead-update/cds-action-lead-update-new.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -133,7 +133,7 @@ } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss index 247412e0c..e1a245e00 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } .custom-expansion-panel { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss index bcd706cd1..3e1233f2e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html index 75cc2891b..6f425d09d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html @@ -1,255 +1,235 @@ - - -
- - -
-
- comment -
-
{{ action._tdActionTitle || 'Reply' }}
- -
- - -
- - -
- - -
-
- {{ 'CDSCanvas.AddContentsToReply' | translate }} -
-
- - -
- -
- - -
- - - - -
- -
- - - - - -
- - -
- - -
-
- - -
-
- - - - - -
- -
- - -
-
- - -
-
- - - - - -
+
+ star +
-
- - -
-
- - -
-
- - - - - -
+
+
-
- - -
-
- - -
-
- - - - - -
+ + -
- - -
-
+
- -
+ + + +
+
+ {{'CDSCanvas.AddContentsToReply' | translate }} +
+
- +
+ +
{{actionList.RANDOM_REPLY.doc+'.DESCRIPTION' | translate }}
+ +
+ +
+ +
+ + +
+ +
+ +
+
+ + + + +
+ +
+ + +
+ + +
+
+
+ + +
+
+ + +
+ + +
+
+
+ + +
+
+ + +
+ + +
+
+
+ + +
+
+ + + +
+ + +
+
+
+ + +
+
+ +
+ +
-
+
+ +
-
- -
-
+ - {{ 'DisableUserInput' | translate }} -
- -
+ +
\ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss index 7fc8bec90..ebabb063f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss @@ -1,338 +1,582 @@ @import "./src/assets/sass/cds/_variables.scss"; -@import "./src/assets/sass/cds/_mixins.scss"; -// ============================================================================ -// cds-action-reply-v1-new Component -// Reply Inspector Layout (DS V3) -// ============================================================================ +$min-height-content: 376px; +$margin-left: 10px; +$padding: 10px; +$action-description-height: 100px; +$margin-bottom: 15px; -:host { - display: block; - font-family: var(--ds-font-family); +.cds-action-content-new { + display: flex; + flex-direction: column; + height: 100%; + padding: 0; } -.cds-action-content-new { - display: flex; - flex-direction: column; - height: 100%; - background: var(--ds-surface, #ffffff); - border: 1px solid var(--ds-border, #e8e6e0); - border-radius: var(--ds-radius-lg, 14px); - box-shadow: var(--ds-shadow-card, 0 1px 2px rgba(20, 20, 18, 0.04)); - overflow: hidden; + +/**header**/ +.action_welcome { + margin-bottom: 5px; } -// ============ Header ============ +.action_welcome .action-description { + display:flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + font-size: 11px; + // color: #d2e3fc; + line-height: 1.5; +} -.insp-head { - @include flex-row(10px); - padding: 14px 18px; - border-bottom: 1px solid var(--ds-border, #e8e6e0); - background: var(--ds-surface, #ffffff); - flex-shrink: 0; - - .insp-icon { - width: 26px; - height: 26px; - border-radius: 7px; +.action_welcome em{ + font-size: 20px; + display: block; + margin: auto 4px auto 0; +} + + +.action_welcome input.action-input { + width: 100%; + border-radius: 4px; + border: 0; + padding: 5px 10px; + color: #22272d; + font-size: 1.15em; + line-height: 16px; +} + + + + + + +/**header**/ + + + + + + +/* customize scrollbar */ +::-webkit-scrollbar { + width: 0px; +} + +// .disable-input-message { +// position: absolute; +// bottom: 10px; +// left: 10px; +// color: white; +// } + +::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { + border-color: var(--ds-ink) !important; +} + +// overwrite the checkbox background +::ng-deep .mat-checkbox-checked .mat-checkbox-background, +.mat-checkbox-indeterminate .mat-checkbox-background { + background-color: var(--ds-ink) !important; + .mat-checkbox-checkmark { + background: var(--ds-ink) !important;; + .mat-checkbox-checkmark-path { + stroke: white; + stroke-width: 5px; + } + } + +} + +// // overwrite the ripple overlay on hover and click +// ::ng-deep .mat-checkbox:not(.mat-checkbox-disabled) .mat-checkbox-ripple .mat-ripple-element { +// background-color: black !important; +// } + +.__box-up { + display: flex; + padding: 5px 10px; background: var(--ds-canvas, #f7f6f3); - @include flex-row(0, center, center); - color: var(--ds-ink, #14140e); - flex-shrink: 0; + position: relative; + /* top: 0; */ + width: 100%; + flex-direction: column; + align-content: flex-end; + align-items: flex-end; + flex-wrap: nowrap; + justify-content: flex-start; +} - mat-icon { - font-size: 14px; - width: 14px; - height: 14px; +.box-dw { + // display: flex; + margin: 0px 5px; + .reply-info{ + color: var(--ds-ink); + padding: 10px; + font-size: 14px; + text-align: center; + border: 1px solid var(--gray-light-01); + border-radius: 10px; + margin: 10px; + background: var(--blu-light-03); } - } +} - .insp-title { - flex: 1; - font-size: 15px; - font-weight: 600; - letter-spacing: -0.01em; - color: var(--ds-ink, #14140e); - } +.cds-action-preview{ + padding: 10px 0px; +} - .icon-btn { - width: 30px; - height: 30px; - @include flex-row(0, center, center); - border: 1px solid transparent; - border-radius: 7px; - background: transparent; - color: var(--ds-ink-2, #3a3935); - cursor: pointer; - @include transition(); +.previewMode{ + &.box-dw{ + margin: 0px; + } + #scrollMe{ + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + overflow: unset; + // gap: 5px; + } + .content{ + min-height: unset; + max-height: unset; + overflow: unset; + } + // .draggable-box{ + // padding-top: $padding-base-preview; + // padding-bottom: $padding-base-preview; + // border-bottom: 3px solid #ebe2c6 + // } + .reply-info{ + max-width: calc(100% - 20px); + margin: 5px auto; + padding: 5px; + font-size: .7em; + line-height: 16px; + } - &:hover:not(:disabled) { - background: var(--ds-canvas, #f7f6f3); - color: var(--ds-ink, #14140e); + .preview-divider { + margin: 10px 0px; } +} - &:disabled { - cursor: not-allowed; - opacity: 0.5; +.content { + position: relative; + display: block; + // display: flex; + // flex-direction: column; + // gap: 10px; + width: 100%; + min-height: $min-height-content; + margin-top: 0px; + overflow: auto; + max-height: calc(100vh - 180px); + .response { + display: block; + position: relative; + height: auto; + width: 100%; + min-height: auto; + margin: 0px; + .response-drop { + position: absolute; + display: flex; + align-content: space-around; + width: 24px; + height: 26px; + left: 0px; + top: 27px; + margin: 0; + color: var(--blu-04); + cursor: grab; + background-color: transparent; + z-index: 1; + } + .response-drop:hover { + color: var(--color-white-hex); + cursor: grab; + } + } + + + + /** START DRAG AND DROP **/ + // &.draggable-list { + // width: 500px; + // max-width: 100%; + // // border: solid 1px $color-txt-3-hex; + // min-height: 60px; + // display: block; + // background: var(--color-white-hex); + // border-radius: 4px; + // overflow: hidden; + // } + + .cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); + } + + .draggable-box:last-child { + border: none; + } + + .draggable-list.cdk-drop-list-dragging .draggable-box:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); } + + .custom-placeholder { + opacity: 0.4; + background: #CCCCCC; + border: dotted 2px #858585; + min-height: 60px; + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); + } + /** END DRAG AND DROP **/ +} - mat-icon { - font-size: 16px; - width: 16px; - height: 16px; + + +.card-buttons { + position: absolute; + display: none; + top: 0; + right: 0; + margin: 0; + outline: none; + width: 380px; + height: 100%; + color: #fff; + justify-content: center; + align-items: center; + text-align: center; + background: transparent; + overflow: visible; + z-index: 14; + border-radius: 1em; + box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), + 0 2px 2px 0 rgba(0, 0, 0, 0.14), + 0 1px 5px 0 rgba(0, 0, 0, 0.12); + &.active{ + display: block; } - } } -// ============ Toolbar ============ -.insp-toolbar { - @include flex-row(4px); - padding: 10px 14px; - border-bottom: 1px solid var(--ds-border, #e8e6e0); - background: var(--ds-surface, #ffffff); - overflow-x: auto; - flex-shrink: 0; - - // Toolbar buttons inherited from cds-action-reply-tools-new - ::ng-deep { - .tool-btn { - width: 32px; - height: 32px; - @include flex-row(0, center, center); - border-radius: var(--ds-radius-sm, 6px); - border: 1px solid transparent; - background: transparent; - color: var(--ds-ink-2, #3a3935); - cursor: pointer; - flex-shrink: 0; - @include transition(); - - &:hover { - background: var(--ds-canvas, #f7f6f3); - color: var(--ds-ink, #14140e); - } +.reply--action-placeholder { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + min-height: 30px; + border-radius: var(--input-border-radius-base); + border: 1px dashed var(--brown); + padding: 6px 12px; + background: rgba(255,255,255,.8); + margin: 12px auto; + width: calc(100% - 5px); + .reply--action-placeholder-text { + font-weight: 400; + color: var(--brown); + font-size: 14px; + } +} - &.active { - background: var(--ds-canvas, #f7f6f3); - color: var(--ds-ink, #14140e); - } +// cds-action-description { +// padding: 10px 0; +// margin-left: 10px; +// // margin-right: 30px; +// & ::ng-deep .action_welcome{ +// margin-bottom: 0px; +// } +// } + +/* ===== INSPECTOR HEADER ===== */ +.insp-head { + display: flex; + align-items: center; + gap: 8px; + padding: 14px 16px 14px 18px; + border-bottom: 1px solid var(--border, #e8e6e0); + flex-shrink: 0; +} - svg, mat-icon { +.insp-icon { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + flex-shrink: 0; + color: var(--ink-2, #3a3935); + font-size: 18px; +} + +.insp-title { + flex: 1; + display: flex; + align-items: center; + gap: 6px; + font-size: 15px; + font-weight: 700; + color: var(--ink, #14140e); + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + .version-icon { + color: #f59e0b; + font-size: 16px; width: 16px; height: 16px; - } + flex-shrink: 0; + display: block; } - - .tool-divider { - width: 1px; - height: 18px; - background: var(--ds-border, #e8e6e0); - margin: 0 4px; - flex-shrink: 0; - } - } } -// ============ Body (Content Area) ============ +.icon-btn { + width: 30px; + height: 30px; + flex-shrink: 0; + border: none; + background: none; + cursor: pointer; + border-radius: 7px; + display: grid; + place-items: center; + color: var(--muted, #8a8884); + transition: background 0.12s, color 0.12s; + padding: 0; + + &:hover:not(:disabled) { + background: var(--canvas, #f7f6f3); + color: var(--ink, #14140e); + } -.insp-body { - flex: 1; - padding: 18px 14px 20px; - @include flex-column(28px); - background: var(--ds-surface, #ffffff); - overflow: auto; + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } - &.previewMode { - padding: 12px 14px; - } + mat-icon { + display: block; + width: 16px; + height: 16px; + font-size: 16px; + } } -// ============ Empty State ============ +/* ===== INSPECTOR TOOLBAR ===== */ +.insp-toolbar { + border-bottom: 1px solid var(--border, #e8e6e0); + flex-shrink: 0; +} +/* ===== INSPECTOR EMPTY STATE ===== */ .insp-empty-state { - @include empty-state(80px, 20px, 8px); - margin: 18px 14px; - - .insp-empty-text { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 12px; + padding: 32px 24px; + text-align: center; + color: var(--ink-2, #3a3935); font-size: 13px; - color: var(--ds-muted, #8a8884); - } + flex: 1; +} + +.insp-empty-text { + line-height: 1.5; } -// ============ Message Block ============ +/* ===== INSPECTOR BODY ===== */ +.insp-body { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-direction: column; + + &.previewMode { + overflow: unset; + padding: 0; + margin: 0; + } +} +/* ===== MESSAGE CONTENT ===== */ .content { - @include flex-column(0); - width: 100%; - @include scrollbar-custom(); - - .msg { - @include response-grid(32px, 8px); position: relative; + display: block; width: 100%; - } - - .msg-content { - @include flex-column(22px); - min-width: 0; - } + min-height: $min-height-content; + margin-top: 0; + overflow: auto; + max-height: calc(100vh - 180px); + + &.previewMode { + min-height: unset; + max-height: unset; + overflow: unset; + } } -// ============ Move Stack ============ +.msg { + position: relative; + display: flex; + gap: 12px; + padding: 12px 16px; + align-items: flex-start; +} .move-stack { - @include flex-column(2px); - margin-top: 4px; - flex-shrink: 0; + display: flex; + flex-direction: column; + gap: 4px; + flex-shrink: 0; +} - .move-btn { - width: 24px; - height: 22px; - @include flex-row(0, center, center); - border: 1px solid transparent; - border-radius: 5px; - background: transparent; - color: var(--ds-muted-2, #b3b1ac); +.move-btn { + width: 28px; + height: 28px; + padding: 0; + border: none; + background: var(--canvas, #f7f6f3); cursor: pointer; - @include transition(); + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + color: var(--ink-2, #3a3935); + transition: background 0.12s, color 0.12s; flex-shrink: 0; - svg { - width: 12px; - height: 12px; - stroke: currentColor; - stroke-width: 1.8; - fill: none; - } - &:hover:not(:disabled) { - color: var(--ds-ink, #14140e); - background: var(--ds-canvas, #f7f6f3); - border-color: var(--ds-border, #e8e6e0); + background: var(--border-strong, #d8d6d0); + color: var(--ink, #14140e); } &:disabled { - opacity: 0.5; - cursor: not-allowed; + opacity: 0.4; + cursor: not-allowed; } &.trash-btn { - margin-bottom: 4px; - padding-bottom: 4px; - border-bottom: 1px solid var(--ds-border, #e8e6e0); - border-radius: 5px 5px 0 0; - color: var(--ds-muted-2, #b3b1ac); - - &:hover { - color: var(--ds-red, oklch(0.55 0.2 25)); - background: var(--ds-red-soft, oklch(0.98 0.02 25)); - border-color: oklch(0.88 0.06 25); - } + background: transparent; + color: #ef4444; - mat-icon { - font-size: 14px; - width: 14px; - height: 14px; - } + &:hover { + background: rgba(239, 68, 68, 0.1); + } + } + + .i { + width: 16px; + height: 16px; + display: block; } - } } -// ============ Message Separator ============ +.msg-content { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; +} .msg-sep { - height: 1px; - background: var(--ds-border, #e8e6e0); - margin: 4px 0 4px 30px; - width: calc(100% - 30px); + height: 1px; + background: var(--border, #e8e6e0); + margin: 8px 16px; } -// ============ Footer ============ - +/* ===== INSPECTOR FOOTER ===== */ .insp-foot { - @include panel-footer(); - padding: 14px 18px; - border-top: 1px solid var(--ds-border, #e8e6e0); - background: var(--ds-surface, #ffffff); - flex-shrink: 0; + display: flex; + align-items: center; + gap: 8px; + padding: 12px 18px; + border-top: 1px solid var(--border, #e8e6e0); + flex-shrink: 0; +} - .switch { +.switch { width: 32px; height: 18px; border-radius: 999px; - background: var(--ds-border, #e8e6e0); - position: relative; + border: none; + background: var(--border, #e8e6e0); cursor: pointer; + position: relative; + transition: background 0.18s; flex-shrink: 0; - @include transition(); + padding: 0; &::after { - content: ""; - position: absolute; - top: 2px; - left: 2px; - width: 14px; - height: 14px; - border-radius: 50%; - background: var(--ds-surface, #ffffff); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18); - @include transition(left); + content: ''; + position: absolute; + width: 14px; + height: 14px; + border-radius: 50%; + background: white; + top: 2px; + left: 2px; + transition: left 0.18s; + box-shadow: 0 1px 2px rgba(20, 20, 18, 0.15); } &.on { - background: var(--ds-green, oklch(0.68 0.14 155)); + background: oklch(0.68 0.14 155); + } - &::after { + &.on::after { left: 16px; - } } - } - - .foot-label { - font-size: 13.5px; - color: var(--ds-ink-2, #3a3935); - } } -// ============ Sub-component Selectors ============ +.foot-label { + font-size: 13px; + color: var(--ink-2, #3a3935); + flex: 1; +} +cds-action-reply-text, +cds-action-reply-image, +cds-action-reply-frame, +cds-action-reply-redirect, +cds-action-reply-gallery, cds-action-reply-text-new, cds-action-reply-image-new, cds-action-reply-frame-new, cds-action-reply-redirect-new, -cds-action-reply-gallery-new { - display: flex; - flex-direction: column; - gap: 10px; -} - -// ============ Preview Mode ============ - -.previewMode { - .insp-body { - gap: 0; - } - - .msg-sep { - margin-top: 10px; - margin-bottom: 10px; - } +cds-action-reply-gallery-new{ + display: flex; + flex-direction: column; + gap: 10px; } -// ============ Remove Controls for RANDOM_REPLY ============ +/* REMOVE DROP AND MOVE_UP/MOVE_DOWN INDICATORS for RANDOM_REPLY type only */ +cds-action-reply-text.no-controls ::ng-deep, +cds-action-reply-image.no-controls ::ng-deep, +cds-action-reply-frame.no-controls ::ng-deep, +cds-action-reply-redirect.no-controls ::ng-deep, +cds-action-reply-gallery.no-controls ::ng-deep, cds-action-reply-text-new.no-controls ::ng-deep, cds-action-reply-image-new.no-controls ::ng-deep, cds-action-reply-frame-new.no-controls ::ng-deep, cds-action-reply-redirect-new.no-controls ::ng-deep, -cds-action-reply-gallery-new.no-controls ::ng-deep { - .text-editor-drop, - .move-stack { - display: none; - } - - .control-button:not(.delete) { - display: none; - } +cds-action-reply-gallery-new.no-controls ::ng-deep{ + .text-editor-drop{ + display: none; + } + .control-button:not(.delete){ + display: none; + } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts index db0014aa0..a0d291177 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -9,7 +9,8 @@ import { TYPE_MESSAGE, TYPE_BUTTON, TYPE_URL, - generateShortUID + generateShortUID, + TYPE_RESPONSE } from '../../../../../../utils'; import { ControllerService } from '../../../../../../services/controller.service'; import { IntentService } from '../../../../../../services/intent.service'; @@ -24,36 +25,39 @@ import { TYPE_ACTION, ACTIONS_LIST } from 'src/app/chatbot-design-studio/utils-a styleUrls: ['./cds-action-reply-new.component.scss'] }) export class CdsActionReplyNewComponent implements OnInit, OnChanges { - // ============ Inputs & Outputs ============ - @Input() action: ActionReply; - @Input() intentSelected: Intent; - @Input() connector: any; - @Input() previewMode: boolean = true; - @Output() updateAndSaveAction = new EventEmitter(); - @Output() onConnectorChange = new EventEmitter<{ type: 'create' | 'delete'; fromId: string; toId: string }>(); @ViewChild('scrollMe', { static: false }) scrollContainer: ElementRef; + translateY: string; + + @Input() action: ActionReply; + @Input() intentSelected: Intent; + @Input() previewMode: boolean = true + @Output() updateAndSaveAction = new EventEmitter(); + @Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>() - // ============ State ============ - arrayResponses: Command[] = []; - typeAction: string; idAction: string; openCardButton: boolean = false; - textGrabbing: boolean = false; - intentName: string = ''; - intentNameResult: boolean = true; - - // ============ Constants (Type Enums) ============ - readonly typeCommand = TYPE_COMMAND; - readonly typeMessage = TYPE_MESSAGE; - readonly typeActions = TYPE_ACTION; - readonly actionList = ACTIONS_LIST; + typeCommand = TYPE_COMMAND; + typeResponse = TYPE_RESPONSE; + typeMessage = TYPE_MESSAGE; + typeActions = TYPE_ACTION; + actionList = ACTIONS_LIST; + + intentName: string; + intentNameResult: boolean; + textGrabbing: boolean; + arrayResponses: Array; + typeAction: string; - // ============ View Model ============ element: any; + showTip: boolean = true; + descriptionTooltip: string = ""; + dataInput: string; + tipText: string; + titlePlaceholder: string; + - // ============ Services ============ private readonly logger: LoggerService = LoggerInstance.getInstance(); constructor( @@ -61,314 +65,365 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { private readonly controllerService: ControllerService, private readonly connectorService: ConnectorService, private readonly changeDetectorRef: ChangeDetectorRef - ) {} - - // ============ Lifecycle Hooks ============ + ) { } - ngOnInit(): void { - console.log('[CdsActionReplyNew] ngOnInit called'); - console.log('[CdsActionReplyNew] this.action:', this.action); - console.log('[CdsActionReplyNew] this.intentSelected:', this.intentSelected); + // manageTooltip(){} + // onChangeText(event){} + // addElement(event){} - this.logger.log('CdsActionReplyNewComponent ngOnInit', this.action, this.intentSelected); - - if (!this.action) { - console.warn('[CdsActionReplyNew] Action is undefined in ngOnInit!'); - return; - } - - this.typeAction = this.action._tdActionType === TYPE_ACTION.RANDOM_REPLY - ? TYPE_ACTION.RANDOM_REPLY - : TYPE_ACTION.REPLY; + // SYSTEM FUNCTIONS // + ngOnInit(): void { + this.logger.log('ActionReplyComponent ngOnInit', this.action, this.intentSelected); + // // this.logger.log('ngOnInit panel-response::: ', this.typeAction); + this.typeAction = (this.action._tdActionType === TYPE_ACTION.RANDOM_REPLY ? TYPE_ACTION.RANDOM_REPLY : TYPE_ACTION.REPLY); try { this.element = Object.values(ACTIONS_LIST).find(item => item.type === this.action._tdActionType); + if(this.action._tdActionTitle && this.action._tdActionTitle != ""){ + this.dataInput = this.action._tdActionTitle; + } + // this.settings = { no_input: null, timeout: 20 } + // if(this.action.noInput){ + // this.settings = { no_input: this.action.noInput} + // } + this.logger.log('ActionDescriptionComponent action:: ', this.element); } catch (error) { - this.logger.error('Failed to find action element', error); - } - - if (!this.action._tdActionId) { - this.action._tdActionId = generateShortUID(); + this.logger.log("error ", error); } - this.idAction = `${this.intentSelected.intent_id}/${this.action._tdActionId}`; - - if (this.action && this.intentSelected) { - this.initialize(); - } - + this.action._tdActionId = this.action._tdActionId?this.action._tdActionId:generateShortUID(); + this.idAction = this.intentSelected.intent_id+'/'+this.action._tdActionId; + // this.initialize(); this.changeDetectorRef.detectChanges(); } + + + /** + * + * @param changes + * IMPORTANT! serve per aggiornare il dettaglio della action nel pannello + */ ngOnChanges(changes: SimpleChanges): void { - if (this.action && this.intentSelected) { - this.initialize(); - } + if(this.action && this.intentSelected) this.initialize(); } - // ============ Initialization ============ - private initialize(): void { + + + + + // CUSTOM FUNCTIONS // + /** */ + private initialize() { this.openCardButton = false; this.arrayResponses = []; this.intentName = ''; this.intentNameResult = true; this.textGrabbing = false; - - console.log('[CdsActionReplyNew] initialize() called with action:', this.action); - console.log('[CdsActionReplyNew] action.attributes:', this.action?.attributes); - console.log('[CdsActionReplyNew] action.attributes.commands:', this.action?.attributes?.commands); - - try { - this.arrayResponses = this.action?.attributes?.commands ?? []; - console.log('[CdsActionReplyNew] arrayResponses set to:', this.arrayResponses); - } catch (error) { - this.logger.error('Failed to initialize arrayResponses', error); - this.arrayResponses = []; + if (this.action) { + try { + this.arrayResponses = this.action.attributes.commands; + } catch (error) { + this.logger.log('error:::', error); + } } - this.scrollToBottom(); } - private scrollToBottom(): void { + + /** */ + scrollToBottom(): void { setTimeout(() => { try { - const scrollElement = this.scrollContainer?.nativeElement; - if (scrollElement) { - scrollElement.scrollTop = scrollElement.scrollHeight; - } + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + this.scrollContainer.nativeElement.animate({ scrollTop: 0 }, '500'); } catch (error) { - this.logger.error('Failed to scroll to bottom', error); + this.logger.log('scrollToBottom ERROR: ', error); } }, 300); } - // ============ Drag & Drop Handlers ============ - onMouseDown(): void { + // EVENT FUNCTIONS // + + + // on drag // + /** */ + mouseDown() { this.textGrabbing = true; } - onMouseUp(): void { + /** */ + mouseUp() { this.textGrabbing = false; } - async drop(event: CdkDragDrop): Promise { + /** */ + async drop(event: CdkDragDrop) { + // //this.logger.log( 'DROP REPLY ---> ',event, this.arrayResponses); this.textGrabbing = false; - try { - const currentPos = event.currentIndex * 2 + 1; - const previousPos = event.previousIndex * 2 + 1; - - // Swap wait + message pairs - const [waitCur, msgCur] = [this.arrayResponses[currentPos - 1], this.arrayResponses[currentPos]]; - const [waitPre, msgPre] = [this.arrayResponses[previousPos - 1], this.arrayResponses[previousPos]]; - - this.arrayResponses[currentPos - 1] = waitPre; + let currentPos = event.currentIndex*2+1; + let previousPos = event.previousIndex*2+1; + const waitCur = this.arrayResponses[currentPos-1]; + const msgCur = this.arrayResponses[currentPos]; + const waitPre = this.arrayResponses[previousPos-1]; + const msgPre = this.arrayResponses[previousPos]; + this.arrayResponses[currentPos-1] = waitPre; this.arrayResponses[currentPos] = msgPre; - this.arrayResponses[previousPos - 1] = waitCur; + this.arrayResponses[previousPos-1] = waitCur; this.arrayResponses[previousPos] = msgCur; - + // // this.logger.log( 'DROP REPLY ---> ', this.arrayResponses); this.connectorService.updateConnector(this.intentSelected.intent_id); - await this.onUpdateAndSaveAction(this.action); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.intentSelected}; + await this.onUpdateAndSaveAction(element); } catch (error) { - this.logger.error('Drop operation failed', error); + this.logger.log('drop ERROR', error); } } - // ============ Response Handlers ============ - - onMoveUpResponse(index: number): void { - if (index < 2) return; + // on action // + /** */ + onMoveUpResponse(index: number) { + if(index<2)return; try { - this.swapResponsePair(index - 2, index); + let from = index - 1; + let to = from - 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + from = index; + to = from - 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + // // this.logger.log( 'onMoveUpResponse ---> ', this.arrayResponses); this.connectorService.updateConnector(this.intentSelected.intent_id); - this.onUpdateAndSaveAction(this.action); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); } catch (error) { - this.logger.error('Failed to move response up', error); + this.logger.log('onAddNewResponse ERROR', error); } } - onMoveDownResponse(index: number): void { - if (index >= this.arrayResponses.length - 1) return; - + /** */ + onMoveDownResponse(index: number) { + if(index === this.arrayResponses.length-1)return; try { - this.swapResponsePair(index, index + 2); + let from = index; + let to = from + 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + from = index - 1; + to = from + 2; + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + // this.logger.log( 'onMoveUpResponse ---> ', this.arrayResponses); this.connectorService.updateConnector(this.intentSelected.intent_id); - this.onUpdateAndSaveAction(this.action); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); } catch (error) { - this.logger.error('Failed to move response down', error); + this.logger.log('onAddNewResponse ERROR', error); } } - private swapResponsePair(fromIndex: number, toIndex: number): void { - this.arrayResponses.splice(toIndex, 0, ...this.arrayResponses.splice(fromIndex, 2)); - } - - onAddNewActionReply(event: any): void { - this.logger.log('Adding new action reply', event); + /** onAddNewActionReply */ + onAddNewActionReply(ele) { + this.logger.log('onAddNewActionReply: ', ele); try { - const message = new Message(event.message.type, event.message.text); - if (event.message.attributes) { - message.attributes = event.message.attributes; + let message = new Message(ele.message.type, ele.message.text); + if (ele.message.attributes) { + message.attributes = ele.message.attributes; } - if (event.message.metadata) { - message.metadata = event.message.metadata; + if (ele.message.metadata) { + message.metadata = ele.message.metadata; } - - const command = new Command(event.type); + const wait = new Wait(); + let command = new Command(ele.type); command.message = message; - - this.arrayResponses.push(new Wait()); + this.arrayResponses.push(wait); this.arrayResponses.push(command); this.scrollToBottom(); - this.onUpdateAndSaveAction(this.action); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); } catch (error) { - this.logger.error('Failed to add new action reply', error); + this.logger.log('onAddNewResponse ERROR', error); } } - onDeleteActionReply(index: number): void { - this.logger.log('Deleting action reply at index', index); + /** onDeleteActionReply */ + onDeleteActionReply(index: number) { + this.logger.log('onDeleteActionReply: ', this.arrayResponses[index]); + // !!! cancello tutti i connettori di una action + var intentId = this.idAction.substring(0, this.idAction.indexOf('/')); try { - // Delete all connectors from buttons in this action - const intentId = this.idAction.substring(0, this.idAction.indexOf('/')); - const buttons = this.arrayResponses[index]?.message?.attributes?.attachment?.buttons; - - if (buttons && Array.isArray(buttons)) { - buttons.forEach(button => { - if (button.__isConnected) { - this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); - } - }); - } - - // Delete the wait + message pair - const waitElement = this.arrayResponses[index - 1]; - if (waitElement?.type === this.typeCommand.WAIT) { - this.arrayResponses.splice(index - 1, 2); - } else { - this.arrayResponses.splice(index, 1); - } - - this.onUpdateAndSaveAction(this.action); + let buttons = this.arrayResponses[index].message.attributes.attachment.buttons; + buttons.forEach(button => { + this.logger.log('button: ', button); + if(button.__isConnected){ + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + // this.connectorService.deleteConnector(button.__idConnector); + } + }); } catch (error) { - this.logger.error('Failed to delete action reply', error); + this.logger.log('onAddNewResponse ERROR', error); } + // cancello l'elemento wait precedente + this.logger.log('**** arrayResponses: ', this.arrayResponses, 'index-1: ', (index-1)); + const wait = this.arrayResponses[index-1]; + this.logger.log('wait: ', wait); + if( wait && wait.type === this.typeCommand.WAIT){ + this.logger.log('CANCELLO WAIT E MESSAGE'); + this.arrayResponses.splice(index-1, 2); + } else { + this.logger.log('CANCELLO SOLO MESSAGE'); + this.arrayResponses.splice(index, 1); + } + this.logger.log('onDeleteActionReply', this.arrayResponses); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); } - onChangeActionReply(event: any): void { - this.onUpdateAndSaveAction(this.action); - } - - onChangeJsonButtons(event: any, index: number): void { - this.logger.log('JSON buttons changed', event, index); - this.onChangeActionReply(event); + /** onChangingReplyAction */ + onChangeActionReply(event) { + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.logger.log('onChangeActionReply ************', element); + this.onUpdateAndSaveAction(element); } - // ============ Button Handlers ============ - - onCreateNewButton(index: number): void { - this.logger.log('Creating new button at index', index); + // on button action // + /** onCreateNewButton */ + onCreateNewButton(index){ + this.logger.log('[cds-action-reply] onCreateNewButton: ', index); try { - const response = this.arrayResponses[index]; - if (!response?.message?.attributes || !response.message.attributes.attachment) { - response.message.attributes = new MessageAttributes(); - } - - const newButton = this.createNewButton(); - if (newButton) { - response.message.attributes.attachment.buttons.push(newButton); - this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); - this.onUpdateAndSaveAction(this.action); + if(!this.arrayResponses[index].message.attributes || !this.arrayResponses[index].message.attributes.attachment){ + this.arrayResponses[index].message.attributes = new MessageAttributes(); } } catch (error) { - this.logger.error('Failed to create new button', error); + this.logger.error('error: ', error); + } + let buttonSelected = this.createNewButton(); + if(buttonSelected){ + this.arrayResponses[index].message.attributes.attachment.buttons.push(buttonSelected); + this.logger.log('[cds-action-reply] onCreateNewButton: ', this.action, this.arrayResponses); + // this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); } } - onDeleteButton(event: { buttons: Button[]; index: number }): void { - try { - const button = event.buttons[event.index]; - event.buttons.splice(event.index, 1); - - const intentId = this.idAction.substring(0, this.idAction.indexOf('/')); - this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); - this.updateAndSaveAction.emit(this.action); - } catch (error) { - this.logger.error('Failed to delete button', error); + private createNewButton() { + const idButton = generateShortUID(); + if(this.intentSelected.intent_id){ + this.idAction = this.intentSelected.intent_id+'/'+this.action._tdActionId; + const idActionConnector = this.idAction+'/'+idButton; + let buttonSelected = new Button( + idButton, + idActionConnector, + false, + TYPE_BUTTON.TEXT, + 'Button', + '', + TYPE_URL.BLANK, + '', + '', + true + ); + this.logger.log('[cds-action-reply] createNewButton: ', buttonSelected); + return buttonSelected; } + return null; } - onOpenButtonPanel(buttonSelected: Button): void { - this.logger.log('Opening button panel', buttonSelected); - this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); - this.controllerService.openButtonPanel(buttonSelected); + /** onDeleteButton */ + onDeleteButton(event){ + let button = event.buttons[event.index]; + event.buttons.splice(event.index, 1); + let intentId = this.idAction.substring(0, this.idAction.indexOf('/')); + this.connectorService.deleteConnectorFromAction(intentId, button.__idConnector); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); } - onOpenPanelActionDetail(command: Command): void { - if (!this.controllerService.isOpenActionDetailPanel$) { - this.intentService.setIntentSelected(this.intentSelected.intent_id); - this.controllerService.openActionDetailPanel(TYPE_INTENT_ELEMENT.ACTION, this.action); - } + + /** onUpdateAndSaveAction: + * function called by all actions in @output whenever they are modified! + * 1 - update connectors + * 2 - update intent + * */ + public async onUpdateAndSaveAction(element) { + this.logger.log('[cds-action-reply] onUpdateAndSaveAction:::: ', this.action, element); + // //this.connectorService.updateConnector(this.intentSelected.intent_id); + this.updateAndSaveAction.emit(this.action); } - // ============ Settings Handlers ============ + // on intent name // - onChangeIntentName(name: string): void { + /** onChangeIntentName */ + onChangeIntentName(name: string) { + name.toString(); try { - this.intentName = name.replace(/[^A-Z0-9_]+/gi, ''); + this.intentName = name.replace(/[^A-Z0-9_]+/ig, ""); } catch (error) { - this.logger.error('Failed to change intent name', error); + this.logger.log('name is not a string', error) } } - onBlurIntentName(): void { + /** onBlurIntentName */ + onBlurIntentName(name: string) { this.intentNameResult = true; } - onDisableInputMessage(): void { + /** onDisableInputMessage */ + onDisableInputMessage() { try { this.action.attributes.disableInputMessage = !this.action.attributes.disableInputMessage; - this.updateAndSaveAction.emit(this.action); + this.updateAndSaveAction.emit({type: TYPE_UPDATE_ACTION.ACTION, element: this.action}); } catch (error) { - this.logger.error('Failed to toggle disable input message', error); + this.logger.log("Error: ", error); } } - // ============ Internal Helpers ============ - private createNewButton(): Button | null { - const idButton = generateShortUID(); - - if (this.intentSelected?.intent_id) { - this.idAction = `${this.intentSelected.intent_id}/${this.action._tdActionId}`; - const idActionConnector = `${this.idAction}/${idButton}`; + /** appdashboard-button-configuration-panel: onOpenButtonPanel */ + onOpenButtonPanel(buttonSelected) { + this.logger.log('onOpenButtonPanel 2 :: ', buttonSelected); + // this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.intentService.selectAction(this.intentSelected.intent_id, this.action._tdActionId); + this.controllerService.openButtonPanel(buttonSelected); + } - return new Button( - idButton, - idActionConnector, - false, - TYPE_BUTTON.TEXT, - 'Button', - '', - TYPE_URL.BLANK, - '', - '', - true - ); + onOpenPanelActionDetail(event){ + this.logger.log('onOpenPanelActionDetail :: ',this.controllerService.isOpenActionDetailPanel$, event, this.action); + if(!this.controllerService.isOpenActionDetailPanel$){ + this.intentService.setIntentSelected(this.intentSelected.intent_id); + this.controllerService.openActionDetailPanel(TYPE_INTENT_ELEMENT.ACTION, this.action); } + } - return null; + + + /** appdashboard-button-configuration-panel: Save button */ + onSaveButton(button) { + // this.logger.log('onSaveButton :: ', button, this.response); + // this.generateCommandsWithWaitOfElements(); } - // ============ Public Event Emitter ============ + + + /** appdashboard-button-configuration-panel: Close button panel */ + onCloseButtonPanel() { + this.logger.log('onCloseButtonPanel :: '); + this.openCardButton = false; + } - async onUpdateAndSaveAction(element: ActionReply): Promise { - this.logger.log('Saving action', element); - this.updateAndSaveAction.emit(element); + onFocusOutEvent(event) { + // this.logger.log('onFocusOutEvent ::::::: ', event); + // this.onCloseButtonPanel() + } + + onChangeJsonButtons(event: any, i: number){ + this.logger.log('[cds-action-reply] onChangeJsonButtons ::::::: ', event, i); + // // this.arrayResponses[i].message = event; + this.onChangeActionReply(event); } + } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss index 227639009..09d4beaa4 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss @@ -69,15 +69,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -109,7 +109,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss index 0da19eb5c..25da2e980 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button-new.component.scss @@ -3,8 +3,8 @@ :host{ --backgroundColor: var(--color-white-hex); - --textColor: #{var(--blu)}; - --hoverBackgroundColor: #{var(--blu)}; + --textColor: #{var(--ds-ink)}; + --hoverBackgroundColor: #{var(--ds-ink)}; --hoverTextColor: var(--color-white-hex); --buttonFontSize: 0.7em; --max-width: #{var(--button-max-width-base)}; @@ -70,7 +70,7 @@ &:focus, &:hover { color: var(--hoverTextColor); - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); .icon-button-action, .icon-button-action-self { svg { fill: var(--hoverTextColor); @@ -127,8 +127,8 @@ } .control-button { cursor: pointer; - background: var(--blu-light-02); - color: var(--blu); + background: var(--border); + color: var(--ds-ink); transition: color .3s; height: 20px; width: 20px; @@ -138,7 +138,7 @@ justify-content: center; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss index 5c9a3a757..621516c05 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss @@ -38,7 +38,7 @@ $max-height: 230px; align-items: center; justify-content: center; mat-icon { - color: var(--blu); + color: var(--ds-ink); } img { max-height: 90%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss index f0b731201..0d5c4e45f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.scss @@ -3,8 +3,8 @@ :host{ --cardImageHeight: 150px; --cardWidth: 220px; - --border-color: #{var(--blu-light-01)}; - --base-color: #{var(--blu-light-02)}; + --border-color: #{var(--ds-bg)}; + --base-color: #{var(--border)}; } .previewMode{ @@ -468,7 +468,7 @@ cds-image-upload ::ng-deep { position: absolute; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } @@ -519,8 +519,8 @@ cds-image-upload ::ng-deep { } .control-button { cursor: pointer; - background: var(--blu-light-02); - color: var(--blu); + background: var(--border); + color: var(--ds-ink); transition: color .3s; height: 24px; width: 24px; @@ -531,7 +531,7 @@ cds-image-upload ::ng-deep { margin: 0 2px; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } @@ -724,7 +724,7 @@ cds-textarea#description.noButtons ::ng-deep{ .image-from-url { margin: 0px 10px 10px; - border: 2px dashed var(--blu-light-02); + border: 2px dashed var(--border); border-radius: 6px; padding: 2px 10px 10px; text-align: center; @@ -737,7 +737,7 @@ cds-textarea#description.noButtons ::ng-deep{ .box-textarea textarea { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); outline: none; overflow-x: hidden; overflow-y: hidden; @@ -769,7 +769,7 @@ cds-textarea#description.noButtons ::ng-deep{ } .image-load-or { - color: var(--blu-light-02); + color: var(--border); font-size: 10px; line-height: 12px; } @@ -792,7 +792,7 @@ cds-textarea#description.noButtons ::ng-deep{ ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { font-size: 12px; display:block!important; - color: var(--blu); + color: var(--ds-ink); } ::ng-deep .ng-select .ng-select-container .ng-value-container { // justify-content: flex-end; @@ -801,7 +801,7 @@ cds-textarea#description.noButtons ::ng-deep{ } ::ng-deep .ng-select .ng-select-container { // justify-content: flex-end; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); box-shadow: none; } ::ng-deep .ng-select .ng-select-container:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss index 2fa3d6fef..8de0a27ef 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image-new.component.scss @@ -65,8 +65,8 @@ flex-wrap: nowrap; align-items: center; .button-reply-add{ - color: var(--blu-light-02); - border-color: var(--blu-light-02); + color: var(--border); + border-color: var(--border); } } @@ -143,7 +143,7 @@ } .control-button { &.delete { - color: var(--blu); + color: var(--ds-ink); position: absolute; top: 0px; right: 0px; @@ -189,11 +189,11 @@ cds-textarea.text-editable-div ::ng-deep{ margin-right: var(--base-margin); justify-content: center; align-items: center; - background: var(--blu-light-01); + background: var(--ds-bg); border-radius: 8px; padding: 3px; box-shadow: none; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); width: calc(100% - 2 * var(--base-margin)); min-width: 0; } @@ -201,9 +201,9 @@ cds-textarea.text-editable-div ::ng-deep{ .cds-toggle-btn { flex: 1 1 0%; width: 50%; - background: var(--blu-light-01); - color: var(--blu); - border: 0px solid var(--blu-light-02); + background: var(--ds-bg); + color: var(--ds-ink); + border: 0px solid var(--border); border-radius: 8px; font-family: var(--font-family-poppins); font-size: 12px; @@ -226,11 +226,11 @@ cds-textarea.text-editable-div ::ng-deep{ .cds-toggle-btn.selected, .cds-toggle-btn:active { background: #fff; - color: var(--blu); + color: var(--ds-ink); font-weight: 500; z-index: 2; box-shadow: 0 1px 4px 0 rgba(80,100,147,0.04); - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); } .cds-toggle-btn:first-child { @@ -243,7 +243,7 @@ cds-textarea.text-editable-div ::ng-deep{ } .cds-toggle-btn:hover:not(.selected) { - color: var(--blu); + color: var(--ds-ink); } .cds-toggle-label { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss index f770bb9b9..1da192c76 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons-new.component.scss @@ -50,7 +50,7 @@ cds-textarea.text-editable-div { ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { font-size: 12px; display:block!important; - color: var(--blu); + color: var(--ds-ink); } ::ng-deep .ng-select .ng-select-container .ng-value-container { // justify-content: flex-end; @@ -59,7 +59,7 @@ cds-textarea.text-editable-div { } ::ng-deep .ng-select .ng-select-container { // justify-content: flex-end; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); box-shadow: none; } ::ng-deep .ng-select .ng-select-container:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss index 09cd9854c..f30e6cf37 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect-new.component.scss @@ -66,7 +66,7 @@ .control-label{ font-family: var(--font-family-poppins); - color: var(--blu); + color: var(--ds-ink); text-align: left; line-height: 20px; font-size: 14px; @@ -104,10 +104,10 @@ mat-button-toggle-group { border-radius: var(--input-border-radius-base); } mat-button-toggle.mat-button-toggle-checked{ - background-color: var(--blu); - color: var(--blu-light-02); + background-color: var(--ds-ink); + color: var(--border); } mat-button-toggle.mat-button-toggle{ - color: var(--blu-light-02); + color: var(--border); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss index c2445b34c..bf93b96d7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings-new.component.scss @@ -51,12 +51,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss index 21bbfa7c7..993a6392d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text-new.component.scss @@ -9,8 +9,8 @@ flex-wrap: nowrap; align-items: center; .button-reply-add { - color: var(--blu-light-02); - border-color: var(--blu-light-02); + color: var(--border); + border-color: var(--border); } } @@ -25,12 +25,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss index 3797e024c..8ec7e9460 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component.scss @@ -1,29 +1,35 @@ -@import "./src/assets/sass/cds/_variables.scss"; - .add-responses { - // grid-gap: 5px; - // display: grid;+ display: flex; - float: right; - .add-response { - text-align: center; - cursor: pointer; - box-sizing: border-box; - outline: none; - margin: 0; - padding: 3px 6px; - display: flex; - - &:not(:first-child){ - border-left: 1px solid white; - } - - img{ - width: 16px; - &:hover{ - filter: brightness(0) saturate(100%) invert(83%) sepia(87%) saturate(3891%) hue-rotate(177deg) brightness(92%) contrast(89%); - } - } - + align-items: center; + justify-content: flex-start; + gap: 2px; + padding: 6px 10px; + border-bottom: 1px solid var(--border, #e8e6e0); +} + +.add-response { + display: flex; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + border-radius: 6px; + cursor: pointer; + transition: background 0.12s; + + &:hover { + background: var(--border, #e8e6e0); + } + + img { + width: 16px; + height: 16px; + display: block; + filter: brightness(0) saturate(100%) invert(40%); + transition: filter 0.12s; + } + + &:hover img { + filter: brightness(0) saturate(100%) invert(15%); } -} \ No newline at end of file +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss index 5c64b8cd6..e0125572a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver-new.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -69,14 +69,14 @@ } } .control-button:hover { - color: var(--blu-light-02); + color: var(--border); &.delete{ em { color: var(--color-red-hex); } } &.copy { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } @@ -91,7 +91,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -144,7 +144,7 @@ loading-spinner.custom-spinner ::ng-deep { height: 36px; width: 36px; //background-color: var(--textColor); - color: var(--backGroundColor); + color: var(--ds-bg); display: flex; align-items: center; margin-right: 10px; @@ -165,7 +165,7 @@ loading-spinner.custom-spinner ::ng-deep { height: 36px; border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02) !important; + border: 1px solid var(--border) !important; color: var(--gray); padding: 4px 8px; font-size: 14px; @@ -319,8 +319,8 @@ button.icon-only { width: 40px; margin-left: 4px; border-radius: 8px; - background: var(--blu-light-02); - border: 1px solid var(--blu-light-02) !important; + background: var(--border); + border: 1px solid var(--border) !important; color: var(--color-white-hex); display: flex; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss index 03ee4a9be..103ffdec7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-wait/cds-action-wait-new.component.scss @@ -1,6 +1,6 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; } .title-label { @@ -62,7 +62,7 @@ /* ------------------------ */ .action-delay-preview { align-items: center; - background: var(--blu-light-01);; + background: var(--ds-bg);; border-radius: 13px; display: inline-flex; position: relative; @@ -75,11 +75,11 @@ } .action-delay-preview .delay--icon { padding-right: 4px; - color: var(--blu); + color: var(--ds-ink); } .action-delay-preview .delay--time { - color: var(--blu); + color: var(--ds-ink); cursor: pointer; font-size: 11px; font-weight: 400; @@ -150,8 +150,8 @@ mat-form-field.mat-form-field ::ng-deep { border-top: 0px !important; input{ &:hover{ - // border: 1px solid var(--blu) !important; - outline: 0px solid var(--blu) !important; + // border: 1px solid var(--ds-ink) !important; + outline: 0px solid var(--ds-ink) !important; outline-offset: -1px; } } @@ -164,8 +164,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-infix { display: flex; input { - // border: 1px solid var(--blu)!important; - outline: 0px solid var(--blu)!important; + // border: 1px solid var(--ds-ink)!important; + outline: 0px solid var(--ds-ink)!important; outline-offset: -1px; // transition: border .3s; &.invalid{ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss index 5e19259fd..6a87e9ac3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/cds-action-web-request-v2-new.component.scss @@ -214,12 +214,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } @@ -264,7 +264,7 @@ mat-button-toggle{ margin: 3px; height: fit-content; padding: 0px 6px; - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss index 6785123e3..6e9d1b1f4 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request-v2/form-data/form-data-new.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: var(--blu-light-01); + --background-color: var(--ds-bg); --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss index 090d529ae..893537f75 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-request/cds-action-web-request-new.component.scss @@ -110,8 +110,8 @@ width: 80px; padding: 8px; justify-content: center; - background: var(--blu-light-01); - color: var(--blu); + background: var(--ds-bg); + color: var(--ds-ink); border-radius: 6px; height: 40px; font-size: 0.8em; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss index b0eb5e640..68cf4ff72 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-web-response/cds-action-web-response-new.component.scss @@ -223,12 +223,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss index 1e5755c7d..1ae22bfdb 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-whatsapp-static/cds-action-whatsapp-static-new.component.scss @@ -57,7 +57,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { padding: 4px; border-radius: 50%; box-shadow: unset; - background-color: var(--blu-light-02); + background-color: var(--border); color: white; cursor: pointer; } @@ -71,7 +71,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { .add-btn-text { cursor: pointer; - color: var(--blu-light-02); + color: var(--border); position: relative; width: 130px; top: -27px; @@ -88,7 +88,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { //margin-top: -20px; //padding: 0 20px; display: none; - background-color: var(--blu); + background-color: var(--ds-ink); border-radius: 4px; // animation: fadein 1s; // animation-delay: 1s; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss index c0e4f8d33..1a9b12759 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-edit-add/form-edit-add-new.component.scss @@ -1,8 +1,8 @@ :host { --background-color: #{var(--ds-canvas, #f7f6f3)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; - --selected-row-background: #{var(--blu-light-02)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; + --selected-row-background: #{var(--border)}; --selected-row-color: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss index 71256132f..c160514dc 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-field/form-field-new.component.scss @@ -1,8 +1,8 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; - --selected-row-background: #{var(--blu-light-02)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; + --selected-row-background: #{var(--border)}; --selected-row-color: #{var(--blu-light-03)}; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss index 9975aee76..030d5d40d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/form/form-new.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; } .content-panel-intent-detail { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss index dcd24b3e4..661370ccf 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/question/question-new.component.scss @@ -1,6 +1,6 @@ h4 { font-size: 16px; - color: var(--blu); + color: var(--ds-ink); } @@ -28,7 +28,7 @@ h4 { // border: none; // height: 47px; // width: 100%; -// color: var(--blu); +// color: var(--ds-ink); // // border-top-right-radius: 4px; // // border-bottom-right-radius: 4px; // } @@ -38,7 +38,7 @@ h4 { // height: 47px; width: 100%; font-weight: 400; - color: var(--blu); + color: var(--ds-ink); font-size: 12px; padding: 4px 0px; } @@ -54,7 +54,7 @@ h4 { } .cds-group-addon-question-right { - background: var(--blu); + background: var(--ds-ink); // height: 47px; border-radius: 0; // padding-left: 6px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss index 6ac7973c7..b514d73fc 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-audio-record/cds-action-audio-record.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-blind-transfer/cds-action-blind-transfer.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-form/cds-action-dtmf-form.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-dtmf-menu/cds-action-dtmf-menu.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-play-prompt/cds-action-play-prompt.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-speech-form/cds-action-speech-form.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss index 9bbfcaed5..a0988ffe5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/cds-action-voice-base/cds-action-voice.component.scss @@ -67,15 +67,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -107,7 +107,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-button/cds-action-reply-button.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-button/cds-action-reply-button.component.scss index 05590b90a..5b8793cef 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-button/cds-action-reply-button.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-button/cds-action-reply-button.component.scss @@ -1,7 +1,7 @@ :host{ --backgroundColor: var(--color-white-hex); - --textColor: #{var(--blu)}; - --hoverBackgroundColor: #{var(--blu)}; + --textColor: #{var(--ds-ink)}; + --hoverBackgroundColor: #{var(--ds-ink)}; --hoverTextColor: var(--color-white-hex); --buttonFontSize: 0.7em; --max-width: #{var(--button-max-width-base)}; @@ -62,7 +62,7 @@ &:focus, &:hover { color: var(--hoverTextColor); - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); .icon-button-action, .icon-button-action-self { svg { fill: var(--hoverTextColor); @@ -121,8 +121,8 @@ } .control-button { cursor: pointer; - background: var(--blu-light-02); - color: var(--blu); + background: var(--border); + color: var(--ds-ink); transition: color .3s; height: 20px; width: 20px; @@ -132,7 +132,7 @@ justify-content: center; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss index ec9700571..e28cca9c0 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss @@ -50,12 +50,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-voice-text/cds-action-reply-voice-text.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-voice-text/cds-action-reply-voice-text.component.scss index 719395c46..56314a8d0 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-voice-text/cds-action-reply-voice-text.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-voice/elements/cds-action-reply-voice-text/cds-action-reply-voice-text.component.scss @@ -14,8 +14,8 @@ flex-wrap: nowrap; align-items: end; .button-reply-add{ - color: var(--blu-light-02); - border-color: var(--blu-light-02); + color: var(--border); + border-color: var(--border); margin: 0 15px; } } @@ -31,12 +31,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/answer/answer.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/answer/answer.component.scss index 7d4e33f16..3401605ae 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/answer/answer.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/answer/answer.component.scss @@ -46,8 +46,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-flex { .mat-form-field-infix { textarea { - border: 1px solid var(--blu) !important; - outline: 1px solid var(--blu) !important; + border: 1px solid var(--ds-ink) !important; + outline: 1px solid var(--ds-ink) !important; transition: border .3s; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-kb-content/cds-action-add-kb-content.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-kb-content/cds-action-add-kb-content.component.scss index 35902d8d0..80f306155 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-kb-content/cds-action-add-kb-content.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-kb-content/cds-action-add-kb-content.component.scss @@ -31,7 +31,7 @@ padding: 3px 7px; border: none; border-radius: 6px; - background: var(--blu); + background: var(--ds-ink); color: #fff; font-size: 12px; line-height: 12px; @@ -58,7 +58,7 @@ gap: 4px; padding: 0px; border-radius: 4px; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border: 0px solid #d2d4d6; font-size: 12px; } @@ -66,7 +66,7 @@ .model-name { margin: 0; font-weight: 300; - color: var(--blu); + color: var(--ds-ink); padding-left: 6px; } @@ -86,7 +86,7 @@ border-radius: 0px 4px 4px 0px; &:hover { - background: var(--blu); + background: var(--ds-ink); .remove-tag-icon { fill: var(--color-white-hex); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-tag/cds-action-add-tag.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-tag/cds-action-add-tag.component.scss index 583b15c3e..fbe282178 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-tag/cds-action-add-tag.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-add-tag/cds-action-add-tag.component.scss @@ -19,7 +19,7 @@ cds-text#text.sx-input ::ng-deep { } .cds-group-addon-question-right { - background: var(--blu); + background: var(--ds-ink); // height: 47px; border-radius: 0; // padding-left: 6px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/ai-condition/ai-condition.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/ai-condition/ai-condition.component.scss index 2dadd07a5..f0a8672fa 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/ai-condition/ai-condition.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/ai-condition/ai-condition.component.scss @@ -31,7 +31,7 @@ .condition-number { font-size: 14px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); } .delete-condition-btn { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.scss index c758611f4..8e646cf1e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/attributes-dialog/attributes-dialog.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/cds-action-ai-condition.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/cds-action-ai-condition.component.scss index d22530235..a51d5bbf3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/cds-action-ai-condition.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-condition/cds-action-ai-condition.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -71,7 +71,7 @@ div { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -204,7 +204,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -386,7 +386,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -408,7 +408,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -504,11 +504,11 @@ loading-spinner.custom-spinner ::ng-deep { .condition-number { font-size: 14px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); } // .condition-number2 { -// background-color: var(--blu); +// background-color: var(--ds-ink); // color: white; // padding: 4px 12px; // border-radius: 16px; @@ -530,9 +530,9 @@ loading-spinner.custom-spinner ::ng-deep { user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -547,9 +547,9 @@ loading-spinner.custom-spinner ::ng-deep { text-transform: none; box-shadow:none; &:hover { - border-color: var(--blu-light-02); + border-color: var(--border); color: var(--color-white-hex); - background-color: var(--blu); + background-color: var(--ds-ink); } .material-icons { @@ -576,7 +576,7 @@ loading-spinner.custom-spinner ::ng-deep { .prompt-label { font-size: 11px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); text-transform: uppercase; letter-spacing: 0.5px; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.scss index fd606cd44..384046778 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/attributes-dialog/attributes-dialog.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/cds-action-ai-prompt.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/cds-action-ai-prompt.component.scss index 5b5394601..b3d88d0d1 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/cds-action-ai-prompt.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/cds-action-ai-prompt.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -72,7 +72,7 @@ div { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -178,7 +178,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -388,7 +388,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -410,7 +410,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -496,7 +496,7 @@ loading-spinner.custom-spinner ::ng-deep { .configure-model-button { - color: var(--blu); + color: var(--ds-ink); text-align: right; padding: 0 5px; text-decoration: underline; @@ -636,8 +636,8 @@ cds-select#model-condition.not-configured ::ng-deep { &:hover { background-color: #e8f4ff; - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); } &.selected { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.scss index 7a0044449..2a92fce5d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog.component.scss @@ -123,9 +123,9 @@ .tools-select-btn { padding: 6px 10px; font-size: 12px; - background: var(--blu) !important; + background: var(--ds-ink) !important; color: #fff !important; - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; &:hover:enabled { opacity: 0.9; @@ -205,7 +205,7 @@ border-radius: 4px; &:hover { - background: var(--blu); + background: var(--ds-ink); } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.scss index 314d196fd..784fc0504 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog.component.scss @@ -91,7 +91,7 @@ border-radius: 4px; &:hover { - background: var(--blu); + background: var(--ds-ink); } } } @@ -190,7 +190,7 @@ .mcp-server-item { background-color: #ffffff; - border: 2px solid var(--blu-light-01); + border: 2px solid var(--ds-bg); border-radius: 8px; padding: 8px 12px; font-size: 14px; @@ -207,7 +207,7 @@ min-height: 50px; &:hover { - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border-color: #b0b0b0; } @@ -275,7 +275,7 @@ margin-top: 4px; .material-icons { font-size: 20px; - color: var(--blu); + color: var(--ds-ink); } &:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt-v2/cds-action-askgpt-v2.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt-v2/cds-action-askgpt-v2.component.scss index 38cb79185..565ce19c0 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt-v2/cds-action-askgpt-v2.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt-v2/cds-action-askgpt-v2.component.scss @@ -3,9 +3,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; --text-color-gray: #{var(--gray)}; } @@ -42,7 +42,7 @@ padding: 3px 7px; border: none; border-radius: 6px; - background: var(--blu); + background: var(--ds-ink); color: #fff; font-size: 12px; line-height: 12px; @@ -69,7 +69,7 @@ gap: 4px; padding: 0px; border-radius: 4px; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border: 0px solid #d2d4d6; font-size: 12px; } @@ -77,7 +77,7 @@ .model-name { margin: 0; font-weight: 300; - color: var(--blu); + color: var(--ds-ink); padding-left: 6px; } @@ -97,7 +97,7 @@ border-radius: 0px 4px 4px 0px; &:hover { - background: var(--blu); + background: var(--ds-ink); .remove-tag-icon { fill: var(--color-white-hex); } @@ -219,7 +219,7 @@ mat-expansion-panel ::ng-deep { position: absolute; left: 0; top: 0; - color: var(--blu); + color: var(--ds-ink); font-weight: 700; font-size: 10px; line-height: 1; @@ -251,7 +251,7 @@ cds-select#model-condition ::ng-deep{ .ng-dropdown-panel-items.scroll-host .ng-optgroup { padding: 0 10px; - color: var(--blu); + color: var(--ds-ink); font-weight: 500; font-size: 14px; background: var(--blu-light-03); @@ -381,7 +381,7 @@ cds-select#model-condition ::ng-deep{ background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -403,7 +403,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -510,7 +510,7 @@ mat-checkbox ::ng-deep { flex-direction: row; justify-content: space-between; align-items: center; - color: var(--blu); + color: var(--ds-ink); font-weight: 400; font-size: 12px; } @@ -621,7 +621,7 @@ cds-select#model-condition.not-configured ::ng-deep { height: fit-content; padding: 0px 6px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; @@ -642,7 +642,7 @@ cds-select#model-condition.not-configured ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt/cds-action-askgpt.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt/cds-action-askgpt.component.scss index 78820ca24..c592cc2e5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt/cds-action-askgpt.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-askgpt/cds-action-askgpt.component.scss @@ -1,5 +1,5 @@ .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss index 4e7cd68aa..a8a03d5f3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operand/operand.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --text-color: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --text-color: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss index d5f15dc85..ce0bce062 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable-v2/operation/operation.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -29,9 +29,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -99,7 +99,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/cds-action-assign-variable.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/cds-action-assign-variable.component.scss index 1cad14757..87a30490e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/cds-action-assign-variable.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/cds-action-assign-variable.component.scss @@ -5,7 +5,7 @@ .material-icons { - color: var(--blu); + color: var(--ds-ink); font-size: 16px; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss index 7de469476..0d81e0d4a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operand/operand.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss index d5f15dc85..ce0bce062 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-assign-variable/operation/operation.component.scss @@ -1,8 +1,8 @@ @import "./src/assets/sass/cds/_variables.scss"; :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -29,9 +29,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -99,7 +99,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-brevo/cds-action-brevo.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-brevo/cds-action-brevo.component.scss index e4c355de6..dbfba6b23 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-brevo/cds-action-brevo.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-brevo/cds-action-brevo.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-customerio/cds-action-customerio.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-customerio/cds-action-customerio.component.scss index a753caa1c..b635b291c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-customerio/cds-action-customerio.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-customerio/cds-action-customerio.component.scss @@ -3,9 +3,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } /** button TOOGLE */ @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss index f5d69a22f..125e61f5e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-description/cds-action-description.component.scss @@ -13,7 +13,7 @@ .label-action { font-size: 12px !important; - color: var(--blu) !important; + color: var(--ds-ink) !important; width: 100%; } @@ -164,7 +164,7 @@ border-radius: 4px; // margin-right: 6px; // align-self: start; - color: var(--blu); + color: var(--ds-ink); background: none; display: flex; @@ -185,7 +185,7 @@ font-size: 14px; font-weight: 500; margin: 0; - color: var(--blu); + color: var(--ds-ink); } } @@ -195,7 +195,7 @@ align-items: center; justify-content: flex-start; font-size: 11px; - color: var(--blu-light-02); + color: var(--border); line-height: 1.5; span { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-flow-log/cds-action-flow-log.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-flow-log/cds-action-flow-log.component.scss index 3a65431a4..9d521f3d3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-flow-log/cds-action-flow-log.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-flow-log/cds-action-flow-log.component.scss @@ -1,9 +1,9 @@ /** NG-SELECT **/ // .ng-select ::ng-deep .ng-select-container { // border-radius: var(--input-border-radius-base); -// border: 1px solid var(--blu-light-02); +// border: 1px solid var(--border); // } // .ng-select.ng-select-focused ::ng-deep .ng-select-container { -// border: 1px solid var(--blu-light-02); +// border: 1px solid var(--border); // box-shadow: none; // } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.scss index a7d4eec7d..1dc0e63b7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/attributes-dialog/attributes-dialog.component.scss @@ -76,7 +76,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); font-size: 1.15em; line-height: 25px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/cds-action-gpt-task.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/cds-action-gpt-task.component.scss index 3ac44e8dc..b17c07337 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/cds-action-gpt-task.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-gpt-task/cds-action-gpt-task.component.scss @@ -2,9 +2,9 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } ::-webkit-scrollbar { @@ -12,7 +12,7 @@ } .custom-divider { - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } @@ -189,7 +189,7 @@ mat-expansion-panel ::ng-deep { } .preview-badge { color: #fff; - background-color: var(--blu); + background-color: var(--ds-ink); display: inline-block; padding: 1px 5px; border-radius: 4px; @@ -350,7 +350,7 @@ mat-checkbox ::ng-deep { background-color: var(--color-white-hex); padding: 6px 12px; font-size: 14px; - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); color: var(--gray); } @@ -372,7 +372,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-hubspot/cds-action-hubspot.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-hubspot/cds-action-hubspot.component.scss index 1729d508f..63f17d379 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-hubspot/cds-action-hubspot.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-hubspot/cds-action-hubspot.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: var(--blu-light-01); + --background-color: var(--ds-bg); //--slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } .custom-expansion-panel { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-condition-row/base-condition-row.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-condition-row/base-condition-row.component.scss index 629f31991..bb85962d3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-condition-row/base-condition-row.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-condition-row/base-condition-row.component.scss @@ -151,13 +151,13 @@ section.header{ font-size: 16px; line-height: 20px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); margin: 0; } span.material-icons{ font-size: 25px; cursor: pointer; - color: var(--blu); + color: var(--ds-ink); } } @@ -235,13 +235,13 @@ section.condition{ margin: 5px; padding: 10px 15px; transition: all 0.3s ease 0s; - background-color: var(--blu-light-01); - color: var(--blu); + background-color: var(--ds-bg); + color: var(--ds-ink); cursor: pointer; &.active, &:hover{ - background: var(--blu); + background: var(--ds-ink); color: var(--blu-light-03); img{ filter: brightness(0) saturate(100%) invert(100%) sepia(20%) saturate(7023%) hue-rotate(179deg) brightness(106%) contrast(89%); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss index be6fe8a12..23ea9b3ed 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/base-filter/base-filter.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -58,14 +58,14 @@ span.material-icons, span.material-icons-outlined{ font-size: 20px; - color: var(--backGroundColor); + color: var(--ds-bg); } &:hover{ background-color: var(--textColor); span.material-icons, span.material-icons-outlined{ - color: var(--backGroundColor); + color: var(--ds-bg); } } } @@ -89,9 +89,9 @@ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -159,13 +159,13 @@ padding: 4px 15px; transition: background-color 0.3s ease 0s, border 0.3s ease 0s, opacity 0.3s ease 0s; cursor: pointer; - background: var(--backGroundColor); + background: var(--ds-bg); border-width: 1px; border-style: solid; - border-color: var(--backGroundColor); + border-color: var(--ds-bg); border-image: initial; &:hover{ - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); border-color: var(--textColor); div.remove{ opacity: 1; @@ -196,7 +196,7 @@ color: var(--textColor); } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/cds-action-json-condition.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/cds-action-json-condition.component.scss index d0cc53f8d..ad482dc06 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/cds-action-json-condition.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/cds-action-json-condition.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--blu-light-03)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -164,7 +164,7 @@ cds-select.operator ::ng-deep{ } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } @@ -183,15 +183,15 @@ cds-select.operator ::ng-deep{ } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/variable-list/variable-list.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/variable-list/variable-list.component.scss index 16c78ad65..09de8d689 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/variable-list/variable-list.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-json-condition/variable-list/variable-list.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px @@ -29,7 +29,7 @@ .material-icons, .material-icons-outlined{ - color: var(--blu-light-02); + color: var(--border); font-size: 18px; &:hover.delete{ @@ -76,7 +76,7 @@ } .material-icons, .material-icons-outlined { - color: var(--blu); + color: var(--ds-ink); } } } @@ -147,12 +147,12 @@ justify-content: center; .material-icons{ margin-right: 15px; - color: var(--blu); + color: var(--ds-ink); font-size: 24px; font-weight: 500; } div { - color: var(--blu); + color: var(--ds-ink); font-size: 16px; font-weight: 600; line-height: 20px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss index 24ddcf0d1..f6a06af06 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-lead-update/cds-action-lead-update.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -133,7 +133,7 @@ } &:hover { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-make/cds-action-make.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-make/cds-action-make.component.scss index 247412e0c..e1a245e00 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-make/cds-action-make.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-make/cds-action-make.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{var(--blu-light-03)}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } .custom-expansion-panel { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-n8n/cds-action-n8n.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-n8n/cds-action-n8n.component.scss index bcd706cd1..3e1233f2e 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-n8n/cds-action-n8n.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-n8n/cds-action-n8n.component.scss @@ -2,9 +2,9 @@ width: 0px; } :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; - --text-color: #{var(--blu)}; + --text-color: #{var(--ds-ink)}; } @@ -17,12 +17,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss index ea9c9b378..bbb092e7f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v1/cds-action-reply.component.scss @@ -69,15 +69,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -109,7 +109,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss index 227639009..09d4beaa4 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/cds-action-reply-v2/cds-action-reply.component.scss @@ -69,15 +69,15 @@ $margin-bottom: 15px; // } ::ng-deep .mat-checkbox.mat-accent .mat-checkbox-frame { - border-color: var(--blu) !important; + border-color: var(--ds-ink) !important; } // overwrite the checkbox background ::ng-deep .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background { - background-color: var(--blu) !important; + background-color: var(--ds-ink) !important; .mat-checkbox-checkmark { - background: var(--blu) !important;; + background: var(--ds-ink) !important;; .mat-checkbox-checkmark-path { stroke: white; stroke-width: 5px; @@ -109,7 +109,7 @@ $margin-bottom: 15px; // display: flex; margin: 0px 5px; .reply-info{ - color: var(--blu); + color: var(--ds-ink); padding: 10px; font-size: 14px; text-align: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.scss index 0da19eb5c..25da2e980 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-button/cds-action-reply-button.component.scss @@ -3,8 +3,8 @@ :host{ --backgroundColor: var(--color-white-hex); - --textColor: #{var(--blu)}; - --hoverBackgroundColor: #{var(--blu)}; + --textColor: #{var(--ds-ink)}; + --hoverBackgroundColor: #{var(--ds-ink)}; --hoverTextColor: var(--color-white-hex); --buttonFontSize: 0.7em; --max-width: #{var(--button-max-width-base)}; @@ -70,7 +70,7 @@ &:focus, &:hover { color: var(--hoverTextColor); - background: var(--hoverBackgroundColor); + background: var(--cds-canvas); .icon-button-action, .icon-button-action-self { svg { fill: var(--hoverTextColor); @@ -127,8 +127,8 @@ } .control-button { cursor: pointer; - background: var(--blu-light-02); - color: var(--blu); + background: var(--border); + color: var(--ds-ink); transition: color .3s; height: 20px; width: 20px; @@ -138,7 +138,7 @@ justify-content: center; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.scss index 5c9a3a757..621516c05 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame.component.scss @@ -38,7 +38,7 @@ $max-height: 230px; align-items: center; justify-content: center; mat-icon { - color: var(--blu); + color: var(--ds-ink); } img { max-height: 90%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component.scss index f0b731201..0d5c4e45f 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery.component.scss @@ -3,8 +3,8 @@ :host{ --cardImageHeight: 150px; --cardWidth: 220px; - --border-color: #{var(--blu-light-01)}; - --base-color: #{var(--blu-light-02)}; + --border-color: #{var(--ds-bg)}; + --base-color: #{var(--border)}; } .previewMode{ @@ -468,7 +468,7 @@ cds-image-upload ::ng-deep { position: absolute; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } @@ -519,8 +519,8 @@ cds-image-upload ::ng-deep { } .control-button { cursor: pointer; - background: var(--blu-light-02); - color: var(--blu); + background: var(--border); + color: var(--ds-ink); transition: color .3s; height: 24px; width: 24px; @@ -531,7 +531,7 @@ cds-image-upload ::ng-deep { margin: 0 2px; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } @@ -724,7 +724,7 @@ cds-textarea#description.noButtons ::ng-deep{ .image-from-url { margin: 0px 10px 10px; - border: 2px dashed var(--blu-light-02); + border: 2px dashed var(--border); border-radius: 6px; padding: 2px 10px 10px; text-align: center; @@ -737,7 +737,7 @@ cds-textarea#description.noButtons ::ng-deep{ .box-textarea textarea { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); outline: none; overflow-x: hidden; overflow-y: hidden; @@ -769,7 +769,7 @@ cds-textarea#description.noButtons ::ng-deep{ } .image-load-or { - color: var(--blu-light-02); + color: var(--border); font-size: 10px; line-height: 12px; } @@ -792,7 +792,7 @@ cds-textarea#description.noButtons ::ng-deep{ ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { font-size: 12px; display:block!important; - color: var(--blu); + color: var(--ds-ink); } ::ng-deep .ng-select .ng-select-container .ng-value-container { // justify-content: flex-end; @@ -801,7 +801,7 @@ cds-textarea#description.noButtons ::ng-deep{ } ::ng-deep .ng-select .ng-select-container { // justify-content: flex-end; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); box-shadow: none; } ::ng-deep .ng-select .ng-select-container:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.scss index 2fa3d6fef..8de0a27ef 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-image/cds-action-reply-image.component.scss @@ -65,8 +65,8 @@ flex-wrap: nowrap; align-items: center; .button-reply-add{ - color: var(--blu-light-02); - border-color: var(--blu-light-02); + color: var(--border); + border-color: var(--border); } } @@ -143,7 +143,7 @@ } .control-button { &.delete { - color: var(--blu); + color: var(--ds-ink); position: absolute; top: 0px; right: 0px; @@ -189,11 +189,11 @@ cds-textarea.text-editable-div ::ng-deep{ margin-right: var(--base-margin); justify-content: center; align-items: center; - background: var(--blu-light-01); + background: var(--ds-bg); border-radius: 8px; padding: 3px; box-shadow: none; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); width: calc(100% - 2 * var(--base-margin)); min-width: 0; } @@ -201,9 +201,9 @@ cds-textarea.text-editable-div ::ng-deep{ .cds-toggle-btn { flex: 1 1 0%; width: 50%; - background: var(--blu-light-01); - color: var(--blu); - border: 0px solid var(--blu-light-02); + background: var(--ds-bg); + color: var(--ds-ink); + border: 0px solid var(--border); border-radius: 8px; font-family: var(--font-family-poppins); font-size: 12px; @@ -226,11 +226,11 @@ cds-textarea.text-editable-div ::ng-deep{ .cds-toggle-btn.selected, .cds-toggle-btn:active { background: #fff; - color: var(--blu); + color: var(--ds-ink); font-weight: 500; z-index: 2; box-shadow: 0 1px 4px 0 rgba(80,100,147,0.04); - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); } .cds-toggle-btn:first-child { @@ -243,7 +243,7 @@ cds-textarea.text-editable-div ::ng-deep{ } .cds-toggle-btn:hover:not(.selected) { - color: var(--blu); + color: var(--ds-ink); } .cds-toggle-label { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.scss index f770bb9b9..1da192c76 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-jsonbuttons/cds-action-reply-jsonbuttons.component.scss @@ -50,7 +50,7 @@ cds-textarea.text-editable-div { ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-placeholder { font-size: 12px; display:block!important; - color: var(--blu); + color: var(--ds-ink); } ::ng-deep .ng-select .ng-select-container .ng-value-container { // justify-content: flex-end; @@ -59,7 +59,7 @@ cds-textarea.text-editable-div { } ::ng-deep .ng-select .ng-select-container { // justify-content: flex-end; - border: 0px solid var(--blu-light-02); + border: 0px solid var(--border); box-shadow: none; } ::ng-deep .ng-select .ng-select-container:hover { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.scss index 09cd9854c..f30e6cf37 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-redirect/cds-action-reply-redirect.component.scss @@ -66,7 +66,7 @@ .control-label{ font-family: var(--font-family-poppins); - color: var(--blu); + color: var(--ds-ink); text-align: left; line-height: 20px; font-size: 14px; @@ -104,10 +104,10 @@ mat-button-toggle-group { border-radius: var(--input-border-radius-base); } mat-button-toggle.mat-button-toggle-checked{ - background-color: var(--blu); - color: var(--blu-light-02); + background-color: var(--ds-ink); + color: var(--border); } mat-button-toggle.mat-button-toggle{ - color: var(--blu-light-02); + color: var(--border); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss index c2445b34c..bf93b96d7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-settings/cds-action-reply-settings.component.scss @@ -51,12 +51,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.scss index 21bbfa7c7..993a6392d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-reply/elements/cds-action-reply-text/cds-action-reply-text.component.scss @@ -9,8 +9,8 @@ flex-wrap: nowrap; align-items: center; .button-reply-add { - color: var(--blu-light-02); - border-color: var(--blu-light-02); + color: var(--border); + border-color: var(--border); } } @@ -25,12 +25,12 @@ margin: -20px 50px 0px 0px; float: right; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss index 5c64b8cd6..e0125572a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-send-whatsapp/whatsapp-receiver/whatsapp-receiver.component.scss @@ -1,6 +1,6 @@ :host{ - --icon-color: #{var(--blu)}; - --textColor: #{var(--blu)}; + --icon-color: #{var(--ds-ink)}; + --textColor: #{var(--ds-ink)}; --backGroundColor: #{var(--ds-canvas, #f7f6f3)}; --hoverBackgroundColor: #{var(--blu-light-03)}; @@ -69,14 +69,14 @@ } } .control-button:hover { - color: var(--blu-light-02); + color: var(--border); &.delete{ em { color: var(--color-red-hex); } } &.copy { - background-color: var(--hoverBackgroundColor); + background-color: var(--cds-canvas); } } } @@ -91,7 +91,7 @@ loading-spinner.custom-spinner ::ng-deep { } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -144,7 +144,7 @@ loading-spinner.custom-spinner ::ng-deep { height: 36px; width: 36px; //background-color: var(--textColor); - color: var(--backGroundColor); + color: var(--ds-bg); display: flex; align-items: center; margin-right: 10px; @@ -165,7 +165,7 @@ loading-spinner.custom-spinner ::ng-deep { height: 36px; border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02) !important; + border: 1px solid var(--border) !important; color: var(--gray); padding: 4px 8px; font-size: 14px; @@ -319,8 +319,8 @@ button.icon-only { width: 40px; margin-left: 4px; border-radius: 8px; - background: var(--blu-light-02); - border: 1px solid var(--blu-light-02) !important; + background: var(--border); + border: 1px solid var(--border) !important; color: var(--color-white-hex); display: flex; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-wait/cds-action-wait.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-wait/cds-action-wait.component.scss index 03ee4a9be..103ffdec7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-wait/cds-action-wait.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-wait/cds-action-wait.component.scss @@ -1,6 +1,6 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; } .title-label { @@ -62,7 +62,7 @@ /* ------------------------ */ .action-delay-preview { align-items: center; - background: var(--blu-light-01);; + background: var(--ds-bg);; border-radius: 13px; display: inline-flex; position: relative; @@ -75,11 +75,11 @@ } .action-delay-preview .delay--icon { padding-right: 4px; - color: var(--blu); + color: var(--ds-ink); } .action-delay-preview .delay--time { - color: var(--blu); + color: var(--ds-ink); cursor: pointer; font-size: 11px; font-weight: 400; @@ -150,8 +150,8 @@ mat-form-field.mat-form-field ::ng-deep { border-top: 0px !important; input{ &:hover{ - // border: 1px solid var(--blu) !important; - outline: 0px solid var(--blu) !important; + // border: 1px solid var(--ds-ink) !important; + outline: 0px solid var(--ds-ink) !important; outline-offset: -1px; } } @@ -164,8 +164,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-infix { display: flex; input { - // border: 1px solid var(--blu)!important; - outline: 0px solid var(--blu)!important; + // border: 1px solid var(--ds-ink)!important; + outline: 0px solid var(--ds-ink)!important; outline-offset: -1px; // transition: border .3s; &.invalid{ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/cds-action-web-request-v2.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/cds-action-web-request-v2.component.scss index 5e19259fd..6a87e9ac3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/cds-action-web-request-v2.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/cds-action-web-request-v2.component.scss @@ -214,12 +214,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } @@ -264,7 +264,7 @@ mat-button-toggle{ margin: 3px; height: fit-content; padding: 0px 6px; - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); flex-wrap: nowrap; text-align: end; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/form-data/form-data.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/form-data/form-data.component.scss index 6785123e3..6e9d1b1f4 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/form-data/form-data.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request-v2/form-data/form-data.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: var(--blu-light-01); + --background-color: var(--ds-bg); --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request/cds-action-web-request.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request/cds-action-web-request.component.scss index 090d529ae..893537f75 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request/cds-action-web-request.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-request/cds-action-web-request.component.scss @@ -110,8 +110,8 @@ width: 80px; padding: 8px; justify-content: center; - background: var(--blu-light-01); - color: var(--blu); + background: var(--ds-bg); + color: var(--ds-ink); border-radius: 6px; height: 40px; font-size: 0.8em; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-response/cds-action-web-response.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-response/cds-action-web-response.component.scss index b0eb5e640..68cf4ff72 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-response/cds-action-web-response.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-web-response/cds-action-web-response.component.scss @@ -223,12 +223,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-whatsapp-static/cds-action-whatsapp-static.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-whatsapp-static/cds-action-whatsapp-static.component.scss index 1e5755c7d..1ae22bfdb 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-whatsapp-static/cds-action-whatsapp-static.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/cds-action-whatsapp-static/cds-action-whatsapp-static.component.scss @@ -57,7 +57,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { padding: 4px; border-radius: 50%; box-shadow: unset; - background-color: var(--blu-light-02); + background-color: var(--border); color: white; cursor: pointer; } @@ -71,7 +71,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { .add-btn-text { cursor: pointer; - color: var(--blu-light-02); + color: var(--border); position: relative; width: 130px; top: -27px; @@ -88,7 +88,7 @@ cds-textarea#phone-number-id.is-invalid ::ng-deep { //margin-top: -20px; //padding: 0 20px; display: none; - background-color: var(--blu); + background-color: var(--ds-ink); border-radius: 4px; // animation: fadein 1s; // animation-delay: 1s; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss index c0e4f8d33..1a9b12759 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-edit-add/form-edit-add.component.scss @@ -1,8 +1,8 @@ :host { --background-color: #{var(--ds-canvas, #f7f6f3)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; - --selected-row-background: #{var(--blu-light-02)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; + --selected-row-background: #{var(--border)}; --selected-row-color: #{var(--blu-light-03)}; --content-background: rgb(244, 246, 251, 0.4); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-field/form-field.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-field/form-field.component.scss index 71256132f..c160514dc 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-field/form-field.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form-field/form-field.component.scss @@ -1,8 +1,8 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; - --selected-row-background: #{var(--blu-light-02)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; + --selected-row-background: #{var(--border)}; --selected-row-color: #{var(--blu-light-03)}; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form.component.scss index 9975aee76..030d5d40d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/form/form.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: #{var(--blu-light-01)}; - --text-color: #{var(--blu)}; - --icon-color: #{var(--blu-light-02)}; + --background-color: #{var(--ds-bg)}; + --text-color: #{var(--ds-ink)}; + --icon-color: #{var(--border)}; } .content-panel-intent-detail { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/question/question.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/question/question.component.scss index dcd24b3e4..661370ccf 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/question/question.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list/question/question.component.scss @@ -1,6 +1,6 @@ h4 { font-size: 16px; - color: var(--blu); + color: var(--ds-ink); } @@ -28,7 +28,7 @@ h4 { // border: none; // height: 47px; // width: 100%; -// color: var(--blu); +// color: var(--ds-ink); // // border-top-right-radius: 4px; // // border-bottom-right-radius: 4px; // } @@ -38,7 +38,7 @@ h4 { // height: 47px; width: 100%; font-weight: 400; - color: var(--blu); + color: var(--ds-ink); font-size: 12px; padding: 4px 0px; } @@ -54,7 +54,7 @@ h4 { } .cds-group-addon-question-right { - background: var(--blu); + background: var(--ds-ink); // height: 47px; border-radius: 0; // padding-left: 6px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-arrow/cds-action-arrow.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-arrow/cds-action-arrow.component.scss index 08e3a3b7e..99f877159 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-arrow/cds-action-arrow.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-arrow/cds-action-arrow.component.scss @@ -13,7 +13,7 @@ height: 6px; position: relative; overflow: hidden; - color: var(--blu); + color: var(--ds-ink); transform: rotate(90deg); top: 15px; } @@ -51,5 +51,5 @@ .cds-action-arrow-icon{ font-size: 25px; - color: var(--blu); + color: var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-controls/cds-action-controls.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-controls/cds-action-controls.component.scss index fb9825028..82ccd4974 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-controls/cds-action-controls.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/shared/cds-action-controls/cds-action-controls/cds-action-controls.component.scss @@ -37,7 +37,7 @@ .action-control-btn:hover { mat-icon { ::ng-deep svg { - fill: var(--blu); + fill: var(--ds-ink); } } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/audio-upload/audio-upload.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/audio-upload/audio-upload.component.scss index 7f2f2c214..f0176d098 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/audio-upload/audio-upload.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/audio-upload/audio-upload.component.scss @@ -9,7 +9,7 @@ } .inputUploadAudio { - color: var(--blu-light-02);; + color: var(--border);; cursor: pointer; div.image{ width: 40px; @@ -25,7 +25,7 @@ display: block; width: 100%; height: 100%; - color: var(--blu-light-02);; + color: var(--border);; text-wrap: wrap; font-weight: 300; span { @@ -34,7 +34,7 @@ } .dropUploadAudio { - border: 2px dashed var(--blu-light-02); + border: 2px dashed var(--border); border-radius: 6px; display: flex; flex-direction: column; @@ -97,7 +97,7 @@ .control-button { &.delete { - color: var(--blu); + color: var(--ds-ink); position: absolute; top: 0px; right: 0px; @@ -133,7 +133,7 @@ height: fit-content; padding: 2px 10px; max-width: calc(100% - 40px); - background-color: var(--blu); + background-color: var(--ds-ink); color: #fff; .close{ position: absolute; @@ -145,8 +145,8 @@ font-size: 13px; border-radius: 50%; background: #fff; - border: 1px solid var(--blu); - color: var(--blu); + border: 1px solid var(--ds-ink); + color: var(--ds-ink); cursor: pointer; opacity: 1; justify-content: center; @@ -169,7 +169,7 @@ loading-spinner.custom-spinner ::ng-deep{ } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -190,12 +190,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-color-menu/cds-color-menu.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-color-menu/cds-color-menu.component.scss index 381c814ea..55fd78851 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-color-menu/cds-color-menu.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-color-menu/cds-color-menu.component.scss @@ -11,7 +11,7 @@ top: 0; left: 0; z-index: 1; - color: var(--blu); + color: var(--ds-ink); font-size: 15px; line-height: 18px; list-style: none; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector-in/cds-connector-in.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector-in/cds-connector-in.component.scss index b4bb520cb..99d9dc742 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector-in/cds-connector-in.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector-in/cds-connector-in.component.scss @@ -53,7 +53,7 @@ .menu-item { padding: 4px 16px; font-size: 10px; - color: var(--blu); + color: var(--ds-ink); cursor: pointer; transition: background-color 0.2s ease; border-bottom: 1px solid rgb(240, 240, 240); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss index 984727daa..1c3bec9fe 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-connector/cds-connector.component.scss @@ -163,7 +163,7 @@ .menu-item { padding: 4px 6px; font-size: 10px; - color: var(--blu); + color: var(--ds-ink); cursor: pointer; transition: background-color 0.2s ease; border-bottom: 1px solid rgb(240, 240, 240); @@ -191,7 +191,7 @@ font-size: 16px; width: 16px; height: 16px; - color: var(--blu); + color: var(--ds-ink); } &:hover { padding: 2px; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss index d87dd9d50..a2f6c458d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/cds-widget-logs/cds-widget-logs.component.scss @@ -136,7 +136,7 @@ color: var(--grey); } &.debug{ - color: var(--blu); + color: var(--ds-ink); } &.info{ color: #1b6ef3; @@ -174,7 +174,7 @@ .mat-icon{ width: 18px; height: 18px; - fill:var(--blu); + fill:var(--ds-ink); } } @@ -191,7 +191,7 @@ align-items: center; height: 25px; padding: 2px 5px; - background: var(--blu-light-01); + background: var(--ds-bg); margin-bottom: 20px; .loading-loader { margin-left: 10px; @@ -199,7 +199,7 @@ position: relative; width: 16px; height: 16px; - border: 2px solid var(--blu); //#3498db; + border: 2px solid var(--ds-ink); //#3498db; border-top: 2px solid var(--gray-light-02); border-radius: 50%; animation: spin 1s linear infinite; @@ -208,7 +208,7 @@ font-size: 11px; margin: 0 10px; font-weight: 500; - color: var(--blu); + color: var(--ds-ink); } } @@ -248,7 +248,7 @@ top: 3px; label { font-family: var(--font-family-poppins); - color: var(--blu); + color: var(--ds-ink); font-size: 12px; padding-right: 10px; } @@ -256,7 +256,7 @@ padding: 0px; font-size: 12px; border: none; - color: var(--blu); + color: var(--ds-ink); background-color: #fafafa; } } @@ -331,8 +331,8 @@ } @keyframes fadeBackground { - 0% { background-color: var(--blu-light-01); } - 20% { background-color: var(--blu-light-01); } + 0% { background-color: var(--ds-bg); } + 20% { background-color: var(--ds-bg); } 100% { background-color: #ffffff; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/context-menu/context-menu.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/context-menu/context-menu.component.scss index cf9e90b08..15d14c85b 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/context-menu/context-menu.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/context-menu/context-menu.component.scss @@ -12,7 +12,7 @@ min-width: 100px; max-width: 400px; width: 185px; - color: var(--blu); + color: var(--ds-ink); font-size: 15px; line-height: 18px; list-style: none; @@ -94,7 +94,7 @@ svg { min-width: 100px; max-width: 400px; width: 190px; - color: var(--blu); + color: var(--ds-ink); font-size: 15px; line-height: 18px; list-style: none; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-slider/delay-slider.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-slider/delay-slider.component.scss index 24cd92912..7b4dd8a72 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-slider/delay-slider.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-slider/delay-slider.component.scss @@ -1,54 +1,51 @@ -$background-color: var(--blu-light-01); -$text-color: var(--blu); - .delay { align-items: center; - background: $background-color; + background: var(--ds-bg); border-radius: 13px; display: inline-flex; position: relative; height: 26px; padding: 0 9px 0 3px; - // width: 100px; text-align: center; transition: width .3s ease-in; font-size: var(--font-size-base); - &:hover{ + &:hover { opacity: 0.8; cursor: pointer; } - // margin-top: 30px; - .delay-current{ + + .delay-current { display: contents; width: auto; - color: $text-color; + color: var(--ds-ink, #14140e); cursor: pointer; font-size: 0.8em; font-weight: 400; white-space: nowrap; } - .delay-slider{ + + .delay-slider { display: inline-block; - // opacity: 0; visibility: hidden; width: 0; transition: opacity .2s; } + .delay-range { display: inline-flex; - color: $text-color; + color: var(--ds-ink, #14140e); font-size: 0.8em; font-weight: 600; } + &.open { width: 100%; - .delay-current{ + .delay-current { display: none; } - .delay-slider{ + .delay-slider { width: 100%; - // opacity: 1; visibility: visible; } } @@ -56,22 +53,18 @@ $text-color: var(--blu); .delay-button { padding-right: 4px; - color: $text-color; + color: var(--ds-ink, #14140e); cursor: pointer; } - - .delay-icon { - color: $text-color; + color: var(--ds-ink, #14140e); font-size: 1em; font-weight: 700; margin-right: 9px; } - - -/** SLIDER **/ +/** SLIDER **/ .vue-slider { margin: 0 5px; position: relative; @@ -87,20 +80,18 @@ mat-slider { top: -14px; } -.vue-slider ::ng-deep{ +.vue-slider ::ng-deep { .mat-accent .mat-slider-track-fill { - background-color: $text-color !important; + background-color: var(--ds-ink, #14140e) !important; } .mat-slider-thumb-label { - background-color: $text-color !important; - + background-color: var(--ds-ink, #14140e) !important; } - .mat-slider-thumb-label-text{ - color: $background-color !important; - font-size: 8px!important; + .mat-slider-thumb-label-text { + color: var(--ds-border, #e8e6e0) !important; + font-size: 8px !important; } .mat-slider-thumb { - background-color: $text-color !important; + background-color: var(--ds-ink, #14140e) !important; } - -} \ No newline at end of file +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-text/delay-text.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-text/delay-text.component.scss index 54e416cb4..29df07a18 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-text/delay-text.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/delay-text/delay-text.component.scss @@ -1,5 +1,5 @@ -$background-color: var(--blu-light-01); -$text-color: var(--blu); +$background-color: var(--ds-bg); +$text-color: var(--ds-ink); .delay { align-items: center; @@ -134,8 +134,8 @@ mat-form-field.mat-form-field ::ng-deep { border-top: 0px !important; input{ &:hover{ - // border: 1px solid var(--blu) !important; - outline: 0px solid var(--blu) !important; + // border: 1px solid var(--ds-ink) !important; + outline: 0px solid var(--ds-ink) !important; outline-offset: -1px; } } @@ -148,8 +148,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-infix { display: flex; input { - // border: 1px solid var(--blu)!important; - outline: 0px solid var(--blu)!important; + // border: 1px solid var(--ds-ink)!important; + outline: 0px solid var(--ds-ink)!important; outline-offset: -1px; // transition: border .3s; &.invalid{ diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/element-from-url/element-from-url.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/element-from-url/element-from-url.component.scss index 6c460e9e7..70f7f077a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/element-from-url/element-from-url.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/element-from-url/element-from-url.component.scss @@ -42,7 +42,7 @@ } .response-frame-panel { - // border: 2px dashed var(--blu-light-02); + // border: 2px dashed var(--border); border-radius: 6px; display: flex; justify-content: center; @@ -55,7 +55,7 @@ display: flex; width: auto; border-radius: 6px; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); height: calc(100vh - 450px); min-height: 200px; max-height: 400px; @@ -69,7 +69,7 @@ right: 0px; margin-right: 0px; opacity: 0; - color: var(--blu); + color: var(--ds-ink); cursor: pointer; transition: all .3s ease-in-out; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/height-slider/height-slider.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/height-slider/height-slider.component.scss index 4044150f4..bb9eccdf8 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/height-slider/height-slider.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/height-slider/height-slider.component.scss @@ -1,5 +1,5 @@ -$background-color: var(--blu-light-01); -$text-color: var(--blu); +$background-color: var(--ds-bg); +$text-color: var(--ds-ink); .delay { align-items: center; @@ -38,7 +38,7 @@ $text-color: var(--blu); text-align: right; display: block; max-width: 26px; - background: var(--blu-light-01); + background: var(--ds-bg); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/image-upload/image-upload.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/image-upload/image-upload.component.scss index 0a2352ab7..558eed61b 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/image-upload/image-upload.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/image-upload/image-upload.component.scss @@ -9,7 +9,7 @@ } .inputUploadImage { - color: var(--blu-light-02);; + color: var(--border);; cursor: pointer; div.image{ width: 40px; @@ -25,7 +25,7 @@ display: block; width: 100%; height: 100%; - color: var(--blu-light-02);; + color: var(--border);; text-wrap: wrap; font-weight: 300; span { @@ -34,7 +34,7 @@ } .dropUploadImage { - border: 2px dashed var(--blu-light-02); + border: 2px dashed var(--border); border-radius: 6px; display: flex; flex-direction: column; @@ -77,7 +77,7 @@ .image-wrp{ .control-button { &.delete { - color: var(--blu); + color: var(--ds-ink); position: absolute; top: 0px; right: 0px; @@ -113,7 +113,7 @@ height: fit-content; padding: 2px 10px; max-width: calc(100% - 40px); - background-color: var(--blu); + background-color: var(--ds-ink); color: #fff; .close{ position: absolute; @@ -125,8 +125,8 @@ font-size: 13px; border-radius: 50%; background: #fff; - border: 1px solid var(--blu); - color: var(--blu); + border: 1px solid var(--ds-ink); + color: var(--ds-ink); cursor: pointer; opacity: 1; justify-content: center; @@ -149,7 +149,7 @@ loading-spinner.custom-spinner ::ng-deep{ } .sk-fading-circle .sk-circle:before { - background-color: var(--blu) ; + background-color: var(--ds-ink) ; } } @@ -170,12 +170,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/text/text.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/text/text.component.scss index d275984b8..ec0038b37 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/text/text.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/text/text.component.scss @@ -26,7 +26,7 @@ input { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); overflow-x: hidden; overflow-y: auto; // width: calc(100% - 2.5em); @@ -80,8 +80,8 @@ mat-form-field.mat-form-field ::ng-deep { border-top: 0px !important; input{ &:hover{ - border: 1px solid var(--blu) !important; - outline: 0px solid var(--blu) !important; + border: 1px solid var(--ds-ink) !important; + outline: 0px solid var(--ds-ink) !important; } } } @@ -93,8 +93,8 @@ mat-form-field.mat-focused ::ng-deep { .mat-form-field-infix { display: flex; input { - border: 1px solid var(--blu)!important; - outline: 0px solid var(--blu)!important; + border: 1px solid var(--ds-ink)!important; + outline: 0px solid var(--ds-ink)!important; transition: border .3s; &.invalid{ border: 1px solid red !important; @@ -151,7 +151,7 @@ input[type=number] { textarea { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); overflow-x: hidden; overflow-y: auto; color: var(--gray); @@ -187,12 +187,12 @@ input[type=number] { transition: background-color 0.3s, color 0.3s; min-width: 45px; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; @@ -222,10 +222,10 @@ input[type=number] { height: 24px; width: 24px; justify-content: center; - color: var(--blu); - border: 1px solid var(--blu-light-02); + color: var(--ds-ink); + border: 1px solid var(--border); &:hover { - background: var(--blu); + background: var(--ds-ink); color:var(--color-white-hex) ; } } @@ -240,10 +240,10 @@ input[type=number] { height: 24px; width: 24px; justify-content: center; - color: var(--blu); - border: 1px solid var(--blu-light-02); + color: var(--ds-ink); + border: 1px solid var(--border); &:hover { - background: var(--blu); + background: var(--ds-ink); color:var(--color-white-hex) ; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/textarea/textarea.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/textarea/textarea.component.scss index e6f616e55..771e4afe9 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/textarea/textarea.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/base-elements/textarea/textarea.component.scss @@ -20,8 +20,8 @@ mat-form-field.mat-focused ::ng-deep { padding: 0px; .mat-form-field-infix { textarea { - border: 1px solid var(--blu) ; - // outline: 0px solid var(--blu); + border: 1px solid var(--ds-ink) ; + // outline: 0px solid var(--ds-ink); transition: border 0.3s; &.invalid{ border: 1px solid red !important; @@ -62,7 +62,7 @@ mat-form-field.box-textarea ::ng-deep { textarea { border-radius: var(--input-border-radius-base); background: var(--color-white-hex); - border: 1px solid var(--blu-light-02); + border: 1px solid var(--border); overflow-x: hidden; overflow-y: auto; color: var(--gray); @@ -97,12 +97,12 @@ mat-form-field.box-textarea ::ng-deep { pointer-events: none; transition: background-color 0.3s, color 0.3s; .num-chars { - background: var(--blu-light-01); + background: var(--ds-bg); flex-shrink: 0; padding: 0px 8px; border-radius: 10px; font-size: 0.8em; - color: var(--blu); + color: var(--ds-ink); float: right; line-height: 24px; font-weight: 700; @@ -132,10 +132,10 @@ mat-form-field.box-textarea ::ng-deep { height: 24px; width: 24px; justify-content: center; - color: var(--blu); - border: 1px solid var(--blu-light-02); + color: var(--ds-ink); + border: 1px solid var(--border); &:hover { - background: var(--blu); + background: var(--ds-ink); color:var(--color-white-hex) ; } } @@ -150,10 +150,10 @@ mat-form-field.box-textarea ::ng-deep { height: 24px; width: 24px; justify-content: center; - color: var(--blu); - border: 1px solid var(--blu-light-02); + color: var(--ds-ink); + border: 1px solid var(--border); &:hover { - background: var(--blu); + background: var(--ds-ink); color:var(--color-white-hex) ; } } @@ -190,7 +190,7 @@ mat-form-field.box-textarea ::ng-deep { height: fit-content; padding: 2px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); .close{ position: absolute; @@ -202,8 +202,8 @@ mat-form-field.box-textarea ::ng-deep { font-size: 13px; border-radius: 50%; background: var(--color-white-hex); - border: 1px solid var(--blu); - color: var(--blu); + border: 1px solid var(--ds-ink); + color: var(--ds-ink); cursor: pointer; opacity: 1; justify-content: center; @@ -221,7 +221,7 @@ mat-form-field.box-textarea ::ng-deep { .liquidjs-menu { position: absolute; display: flex; - color: var(--blu); + color: var(--ds-ink); cursor: pointer; font-size: 0.8em; font-weight: 400; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss index 82963f5bf..a0bbe1453 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.component.scss @@ -145,7 +145,7 @@ cds-fulfillment { width: $box-left-width; max-width: $box-left-width; min-width: $box-left-width; - background-color: var(--blu-light-01); + background-color: var(--ds-bg); border-right: 1px solid var(--gray-light-02); z-index: 10; position: relative; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.module.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.module.ts index bc36f24bc..40c9ff500 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.module.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-canvas.module.ts @@ -44,6 +44,8 @@ import { CdsPanelNoteDetailComponent } from './cds-panel-note-detail/cds-panel-n import { NoteControlsComponent } from './cds-notes/note-controls/note-controls.component'; import { CdsPanelDetailComponent } from './cds-panel-detail/cds-panel-detail.component'; import { NoteResizeStateService } from './note-resize-state.service'; +import { CdsActionReplyNewComponent } from './actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component'; +import { CdsActionReplyToolsNewComponent } from './actions/list-new/cds-action-reply/elements/cds-action-reply-tools/cds-action-reply-tools-new.component'; import { FormsModule } from '@angular/forms'; import { QuillModule } from "ngx-quill"; @@ -111,6 +113,10 @@ const routes: Routes = [ CdsActionArrowComponent, CdsAddActionMenuComponent, + //ACTIONS NEW (V3) + CdsActionReplyNewComponent, + CdsActionReplyToolsNewComponent, + //MODALS MouseTipsComponent, ChangeAlphaColorComponent, diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html index 259c5c13e..46810d32c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/cds-intent/cds-intent.component.html @@ -113,13 +113,13 @@
- - + - - + - - + - - + - - + - - + , , ); &::before { // border-top: 2px solid $purple; - border-bottom: 3px solid var(--blu); + border-bottom: 3px solid var(--ds-ink); transform: scale3d(0, 1, 1); // Shrink only width } @@ -150,7 +150,7 @@ label:first-child{ font-weight: 300; font-size: 16px; - color: var(--blu) + color: var(--ds-ink) } label{ font-size: 12px; @@ -191,7 +191,7 @@ min-width: 100px; max-width: 400px; width: 185px; - color: var(--blu); + color: var(--ds-ink); font-size: 15px; line-height: 18px; list-style: none; @@ -304,7 +304,7 @@ justify-content: center; background-color: var(--color-white-hex); - color: var(--blu); + color: var(--ds-ink); .material-icons{ font-size: 22px; } diff --git a/src/app/chatbot-design-studio/cds-rules/rules-add/condition/condition.component.scss b/src/app/chatbot-design-studio/cds-rules/rules-add/condition/condition.component.scss index 0fdcec33c..579d2c73e 100644 --- a/src/app/chatbot-design-studio/cds-rules/rules-add/condition/condition.component.scss +++ b/src/app/chatbot-design-studio/cds-rules/rules-add/condition/condition.component.scss @@ -1,6 +1,6 @@ :host{ - --selectedColor: #{var(--blu)}; - --text-color : #{var(--blu-light-02)}; + --selectedColor: #{var(--ds-ink)}; + --text-color : #{var(--border)}; } .section{ diff --git a/src/app/chatbot-design-studio/cds-rules/rules-add/rules-add.component.scss b/src/app/chatbot-design-studio/cds-rules/rules-add/rules-add.component.scss index 5ba4431b7..eaf52a23f 100644 --- a/src/app/chatbot-design-studio/cds-rules/rules-add/rules-add.component.scss +++ b/src/app/chatbot-design-studio/cds-rules/rules-add/rules-add.component.scss @@ -1,7 +1,7 @@ :host { - --background-color: #{var(--blu-light-01)}; + --background-color: #{var(--ds-bg)}; --column-color: var(--blu-02); - --text-color: var(--blu); + --text-color: var(--ds-ink); --content-background: rgb(244, 246, 251, 0.4); --base-radius: 8px diff --git a/src/app/chatbot-design-studio/cds-support/cds-support.component.scss b/src/app/chatbot-design-studio/cds-support/cds-support.component.scss index 8bc902ba9..65e2084c1 100644 --- a/src/app/chatbot-design-studio/cds-support/cds-support.component.scss +++ b/src/app/chatbot-design-studio/cds-support/cds-support.component.scss @@ -1,6 +1,6 @@ :host { --content-background: rgb(244, 246, 251, 0.4); - --content-hover-background: #{var(--blu)}; + --content-hover-background: #{var(--ds-ink)}; --base-radius: 8px; width: 100%; diff --git a/src/app/chatbot-design-studio/utils-actions.ts b/src/app/chatbot-design-studio/utils-actions.ts index 8a13c2ca6..1afbfecc0 100644 --- a/src/app/chatbot-design-studio/utils-actions.ts +++ b/src/app/chatbot-design-studio/utils-actions.ts @@ -129,9 +129,9 @@ export const ACTIONS_LIST: { disabled?: boolean } } = { - REPLY : { name: 'CDSActionList.NAME.Reply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLY, src: "assets/images/actions/reply.svg", status: "active" , doc: "CDSActionList.DOC.Reply", badge: 'V3' }, - REPLYV2 : { name: 'CDSActionList.NAME.ReplyV2', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLYV2, src: "assets/images/actions/reply_v2.svg", status: "active" , doc: "CDSActionList.DOC.ReplyV2", }, - RANDOM_REPLY : { name: 'CDSActionList.NAME.RandomReply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.RANDOM_REPLY, src: "assets/images/actions/random_reply.svg", status: "active", doc: "CDSActionList.DOC.RandomReply", badge: 'V3' }, + REPLY : { name: 'CDSActionList.NAME.Reply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLY, src: "assets/images/actions/reply.svg", status: "active" , doc: "CDSActionList.DOC.Reply", }, + REPLYV2 : { name: 'CDSActionList.NAME.ReplyV2', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLYV2, src: "assets/images/actions/reply_v2.svg", status: "active" , doc: "CDSActionList.DOC.ReplyV2", }, + RANDOM_REPLY : { name: 'CDSActionList.NAME.RandomReply', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.RANDOM_REPLY, src: "assets/images/actions/random_reply.svg", status: "active", doc: "CDSActionList.DOC.RandomReply", }, AGENT : { name: 'CDSActionList.NAME.AgentHandoff', chatbot_types: [TYPE_CHATBOT.CHATBOT], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.AGENT, src: "assets/images/actions/agent_handoff.svg", status: "active", doc: "CDSActionList.DOC.AgentHandoff" }, CLOSE : { name: 'CDSActionList.NAME.Close', chatbot_types: [TYPE_CHATBOT.CHATBOT, TYPE_CHATBOT.VOICE, TYPE_CHATBOT.VOICE_TWILIO], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.CLOSE, src: "assets/images/actions/close.svg", status: "active", doc: "CDSActionList.DOC.Close" }, OPEN_HOURS: { name: 'CDSActionList.NAME.IfOperatingHours', chatbot_types: [TYPE_CHATBOT.CHATBOT, TYPE_CHATBOT.VOICE, TYPE_CHATBOT.VOICE_TWILIO], category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.OPEN_HOURS, src: "assets/images/actions/open_hours.svg", status: "active", doc: "CDSActionList.DOC.IfOperatingHours" }, diff --git a/src/app/modals/cds-modal-activate-bot/cds-modal-activate-bot.component.scss b/src/app/modals/cds-modal-activate-bot/cds-modal-activate-bot.component.scss index 70504e1b3..aa4a759fa 100644 --- a/src/app/modals/cds-modal-activate-bot/cds-modal-activate-bot.component.scss +++ b/src/app/modals/cds-modal-activate-bot/cds-modal-activate-bot.component.scss @@ -76,14 +76,14 @@ font-size: 17px; line-height: 17px; font-weight: 500; - color: var(--blu); + color: var(--ds-ink); } .subtitle{ font-size: 13px; color: var(--gray); } span.material-icons-outlined{ - color: var(--blu); + color: var(--ds-ink); } &:hover{ cursor: pointer; @@ -101,7 +101,7 @@ gap: 10px; // #ignoreBtn{ - // background-color: var(--blu-light-02); + // background-color: var(--border); // } } diff --git a/src/app/modals/change-alpha-color/change-alpha-color.component.scss b/src/app/modals/change-alpha-color/change-alpha-color.component.scss index 7a55849ea..99d80e12d 100644 --- a/src/app/modals/change-alpha-color/change-alpha-color.component.scss +++ b/src/app/modals/change-alpha-color/change-alpha-color.component.scss @@ -33,7 +33,7 @@ .header-subtitle { font-size: 12px; - color: var(--blu); + color: var(--ds-ink); } .title-label{ @@ -89,12 +89,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } @@ -121,7 +121,7 @@ mat-button-toggle{ justify-content: space-between; padding: 20px 0 10px 0; .numbers{ - color: var(--blu-light-02); + color: var(--border); font-size: 11px; font-weight: 600; width: 20px; @@ -181,7 +181,7 @@ mat-button-toggle{ margin-left:8px; width: 20px; font-size: 11px; - color: var(--blu); + color: var(--ds-ink); top: -30px; left: calc((100% - 60px)/2); transform: translateX(-50%); diff --git a/src/app/modals/changelog/changelog.component.scss b/src/app/modals/changelog/changelog.component.scss index 6b24f93f1..872b68d29 100644 --- a/src/app/modals/changelog/changelog.component.scss +++ b/src/app/modals/changelog/changelog.component.scss @@ -3,7 +3,7 @@ align-items: center; justify-content: center; gap: 15px; - background-color: var(--blu); + background-color: var(--ds-ink); padding: 5px 15px; border-radius: 8px; diff --git a/src/app/modals/mouse-tips/mouse-tips.component.scss b/src/app/modals/mouse-tips/mouse-tips.component.scss index fbfc58ab5..e5060bd9f 100644 --- a/src/app/modals/mouse-tips/mouse-tips.component.scss +++ b/src/app/modals/mouse-tips/mouse-tips.component.scss @@ -30,7 +30,7 @@ } mat-icon { ::ng-deep svg { - fill: var(--blu); + fill: var(--ds-ink); } } } @@ -90,12 +90,12 @@ mat-button-toggle-group ::ng-deep{ mat-button-toggle{ background-color: transparent; border: none; - color: var(--blu-light-02); + color: var(--border); border-bottom: 2px solid transparent; &.mat-button-toggle-checked{ - border-color: var(--blu); - color: var(--blu); + border-color: var(--ds-ink); + color: var(--ds-ink); font-weight: 400; } diff --git a/src/assets/sass/cds/_variables.scss b/src/assets/sass/cds/_variables.scss index ca95b2721..b619d5f58 100644 --- a/src/assets/sass/cds/_variables.scss +++ b/src/assets/sass/cds/_variables.scss @@ -24,7 +24,7 @@ // $action-item-color: #d2e3fc; // $action-item-background:rgba(255,255,255, 0.7); //rgba(66,85,117,1); // $action-no-featured-item-background:rgba(255,255,255, 1); //rgba(66,85,117,1); -// $action-color-selected: var(--blu); // rgba(179,141,38,1); +// $action-color-selected: var(--ds-ink); // rgba(179,141,38,1); // $intent-preview-background: var(--blu-light-03); //rgb(235, 226, 198); // $intent-preview-borderColor: var(--gray-light-02); // $empty-element-property:rgb(191, 35, 35); @@ -118,6 +118,7 @@ --ds-ink-2: #3a3935; --ds-muted: #8a8884; --ds-muted-2: #b3b1ac; + --ds-white: #ffffff; // Semantic colors --ds-accent: oklch(0.66 0.15 50); @@ -161,8 +162,8 @@ --drag-preview-background: var(--color-white-hex); /** SCROLL-BAR **/ - --scrollbar-track-background: #{var(--blu-light-01)}; - --scrollbar-thumb-background: var(--blu); + --scrollbar-track-background: #{var(--ds-bg)}; + --scrollbar-thumb-background: var(--ds-ink); --scrollbar-thumb-border-radius: 3px; /** CANVAS CONTAINER COLORS — Design Studio v3 */ @@ -188,16 +189,16 @@ /** INTENT PREVIEW **/ --action-item-background:rgba(255,255,255, 0.7); //rgba(66,85,117,1); --action-no-featured-item-background:rgba(255,255,255, 1); //rgba(66,85,117,1); - --action-color-selected: var(--blu); // rgba(179,141,38,1); + --action-color-selected: var(--ds-ink); // rgba(179,141,38,1); --intent-preview-background: var(--blu-light-03); //rgb(235, 226, 198); --intent-preview-borderColor: var(--gray-light-02); - --intent-header-icon-color: var(--blu); + --intent-header-icon-color: var(--ds-ink); --padding-base-preview: 0 10px 10px; --base-element-gap: 5px; --border-radius-base-preview: 8px; --add-action-btn-background-preview: var(--color-white-hex); --add-action-btn-color-preview: var(--gray); - --add-action-btn-hover-color-preview: var(--blu); + --add-action-btn-hover-color-preview: var(--ds-ink); /** SETTINGS section **/ --input-placeholder: #a0a0a0; diff --git a/src/assets/sass/cds/action-styles.scss b/src/assets/sass/cds/action-styles.scss index ab65c119b..1a9352638 100644 --- a/src/assets/sass/cds/action-styles.scss +++ b/src/assets/sass/cds/action-styles.scss @@ -44,12 +44,12 @@ font-weight: 400; border-radius: 13px; transition: all 0.3s ease 0s; - background: var(--blu); - color: var(--blu-light-01); + background: var(--ds-bg); + color: var(--ds-link); span.material-icons-outlined{ font-size: 20px; - color: var(--color-white-hex); + color: var(--ds-link); } &:hover{ @@ -132,8 +132,8 @@ appdashboard-filter{ } &.json-shown { .button-json { - border: 1px solid var(--blu); - color: var(--blu); + border: 1px solid var(--ds-ink); + color: var(--ds-ink); } } .more-info { @@ -155,18 +155,18 @@ appdashboard-filter{ top: 0; .control-button { cursor: pointer; - color: var(--blu); + color: var(--ds-ink); transition: color 0.3s; height: 24px; width: 24px; - background: var(--blu-light-02); + background: var(--border); border-radius: 50%; display: flex; align-items: center; justify-content: center; em { font-size: 16px; - color: var(--blu); + color: var(--ds-ink); transition: color 0.3s; } } @@ -191,9 +191,9 @@ appdashboard-filter{ user-select: none; box-sizing: border-box; outline: none; - border: 1px dashed var(--blu-light-02); + border: 1px dashed var(--border); border-radius: var(--button-border-radius-base); - color: var(--blu-light-02); + color: var(--border); cursor: pointer; font-size: 0.7em; font-weight: 400; @@ -219,20 +219,20 @@ appdashboard-filter{ &.delete{ height: 24px; width: 24px; - background: var(--blu-light-02); + background: var(--border); border-radius: 50%; display: flex; align-items: center; justify-content: center; em { font-size: 1.15em; - color: var(--blu); + color: var(--ds-ink); transition: color .3s; } } } .control-button:hover{ - color: var(--blu-light-02); + color: var(--border); &.delete{ box-shadow: 0 2px 6px 0 rgb(255 255 255 / 15%); em { @@ -360,7 +360,7 @@ appdashboard-filter{ height: fit-content; padding: 2px; max-width: calc(100% - 25px); - background-color: var(--blu); + background-color: var(--ds-ink); color: var(--color-white-hex); display: inline-flex; align-items: center; diff --git a/src/assets/sass/cds/settings-section.scss b/src/assets/sass/cds/settings-section.scss index 281e61c95..cbf524525 100644 --- a/src/assets/sass/cds/settings-section.scss +++ b/src/assets/sass/cds/settings-section.scss @@ -13,7 +13,7 @@ input[type="text"] { -moz-box-sizing: border-box; border-radius: var(--input-border-radius-base); background-color: var(--color-white-hex); - border: solid 1px var(--blu-light-02); + border: solid 1px var(--border); color:#808080; } textarea[type="text"] { @@ -33,7 +33,7 @@ textarea[type="text"] { -moz-box-sizing: border-box; border-radius: var(--input-border-radius-base); background-color: var(--color-white-hex); - border: solid 1px var(--blu-light-02); + border: solid 1px var(--border); color:#808080; } @@ -75,6 +75,6 @@ input[type="text"]:disabled::placeholder { .cds--custom-label { - color: var(--blu); + color: var(--ds-ink); margin-bottom: 2px; } \ No newline at end of file diff --git a/src/assets/sass/cds/styles.scss b/src/assets/sass/cds/styles.scss index d95c73d02..143c10f35 100644 --- a/src/assets/sass/cds/styles.scss +++ b/src/assets/sass/cds/styles.scss @@ -79,7 +79,7 @@ button.close { /* Bottom Underline of the titles of the sections */ .card_title__underlined { text-transform: none; - color: var(--blu); + color: var(--ds-ink); margin-bottom: 0px; height: 40px !important; position: relative; @@ -95,8 +95,8 @@ button.close { top: 0; left: 0; bottom: -1px; - border-bottom: 2px solid var(--blu); - color: var(--blu); + border-bottom: 2px solid var(--ds-ink); + color: var(--ds-ink); z-index: 1; } @@ -126,12 +126,12 @@ button.close { } .title-label { - color: var(--blu); + color: var(--ds-ink); font-size: 14px; } .subtitle-label { - color: var(--blu); + color: var(--ds-ink); font-size: 11px; font-style: italic; } @@ -139,7 +139,7 @@ button.close { .condition-text { font-size: 14px; font-weight: 600; - color: var(--blu); + color: var(--ds-ink); } .condition-container { @@ -300,7 +300,7 @@ cds-intent:hover > cds-panel-intent-controls > .intent-header-actions-container .preview-divider { margin: 5px 0px; - border-top: 2px solid color-mix(in srgb, var(--blu) 70%, transparent); + border-top: 2px solid color-mix(in srgb, var(--ds-ink) 70%, transparent); } @@ -308,7 +308,7 @@ cds-intent:hover > cds-panel-intent-controls > .intent-header-actions-container margin-top: 40px; margin-bottom: 20px; border: 0; - border-top: 1px solid var(--blu); + border-top: 1px solid var(--ds-ink); } .btn.btn-primary.cds-blue-button { @@ -341,7 +341,7 @@ appdashboard-cds-dashboard a { .cds-title { font-size: 18px; position: relative; - color: var(--blu); + color: var(--ds-ink); font-weight: 600; } @@ -349,13 +349,12 @@ appdashboard-cds-dashboard a { width: 100%; position: absolute; bottom: 0; - // left: 0; - // right: 0; z-index: 2; height: var(--footer-panel-action-detail-height); margin: auto 0; padding: 7px 20px; border-top: 1px solid var(--gray-light-02); + background-color: var(--ds-white); } img.active-icon { From e6f7cfd53f9fe100b3a57c922aaa378c23c4c7c3 Mon Sep 17 00:00:00 2001 From: Dario De Pascalis Date: Thu, 7 May 2026 08:48:44 +0200 Subject: [PATCH 22/30] refactoring action reply step1 --- .../filter/filter.component.html | 6 +- .../filter/filter.component.scss | 105 ++++++----- ...cds-action-ai-condition-new.component.scss | 4 - .../cds-action-ai-prompt-new.component.scss | 4 - .../mcp-server-edit-dialog-new.component.scss | 20 +- .../mcp-servers-dialog-new.component.scss | 15 -- .../cds-action-askgpt-v2-new.component.scss | 5 +- ...tion-assign-variable-v2-new.component.scss | 3 - ...-action-assign-variable-new.component.scss | 3 - .../cds-action-brevo-new.component.scss | 3 - .../cds-action-customerio-new.component.scss | 4 - .../cds-action-gpt-task-new.component.scss | 4 - .../cds-action-hubspot-new.component.scss | 3 - .../base-condition-row-new.component.scss | 6 +- ...s-action-json-condition-new.component.scss | 4 - .../cds-action-make-new.component.scss | 3 - .../cds-action-n8n-new.component.scss | 3 - .../cds-action-reply-new.component.html | 145 ++++---------- .../cds-action-reply-new.component.scss | 28 +-- .../cds-action-reply-new.component.ts | 74 ++++---- .../cds-action-reply-new.component.html | 136 +++---------- .../cds-action-reply-new.component.scss | 32 ++-- .../cds-action-reply-new.component.ts | 72 ++++--- .../cds-action-reply-frame-new.component.html | 18 +- .../cds-action-reply-frame-new.component.scss | 16 -- .../cds-action-reply-frame-new.component.ts | 18 -- ...ds-action-reply-gallery-new.component.html | 43 +---- ...ds-action-reply-gallery-new.component.scss | 11 +- .../cds-action-reply-gallery-new.component.ts | 18 -- .../cds-action-reply-image-new.component.html | 18 +- .../cds-action-reply-image-new.component.scss | 10 - .../cds-action-reply-image-new.component.ts | 18 -- ...ction-reply-jsonbuttons-new.component.scss | 17 +- ...s-action-reply-redirect-new.component.html | 18 +- ...s-action-reply-redirect-new.component.scss | 10 - ...cds-action-reply-redirect-new.component.ts | 18 -- ...s-action-reply-settings-new.component.html | 4 +- ...s-action-reply-settings-new.component.scss | 8 - .../cds-action-reply-text-new.component.html | 28 +-- .../cds-action-reply-text-new.component.scss | 10 - .../cds-action-reply-text-new.component.ts | 18 -- .../cds-action-reply-tools-new.component.html | 47 +++-- .../cds-action-reply-tools-new.component.scss | 42 +++-- ...s-action-web-request-v2-new.component.scss | 14 +- .../cds-action-web-request-new.component.scss | 3 - ...cds-action-web-response-new.component.scss | 3 - .../form-field/form-field-new.component.html | 89 ++++----- .../form-field/form-field-new.component.scss | 178 +++++++++--------- .../form-field/form-field-new.component.ts | 33 ++-- .../cds-action-audio-record.component.scss | 25 +-- .../cds-action-blind-transfer.component.scss | 25 +-- .../cds-action-dtmf-form.component.scss | 25 +-- .../cds-action-dtmf-menu.component.scss | 25 +-- .../cds-action-play-prompt.component.scss | 25 +-- .../cds-action-speech-form.component.scss | 25 +-- .../cds-action-voice.component.scss | 25 +-- .../cds-action-reply-audio.component.scss | 18 -- .../cds-action-reply-settings.component.scss | 9 - ...ds-action-reply-tools-voice.component.scss | 4 - ...cds-action-reply-voice-text.component.scss | 11 -- .../cds-action-ai-condition.component.scss | 4 - .../cds-action-ai-prompt.component.scss | 4 - .../mcp-server-edit-dialog.component.scss | 20 +- .../mcp-servers-dialog.component.scss | 15 -- .../cds-action-askgpt-v2.component.scss | 5 +- ...s-action-assign-variable-v2.component.scss | 3 - .../cds-action-assign-variable.component.scss | 3 - .../cds-action-brevo.component.scss | 3 - .../cds-action-customerio.component.scss | 4 - .../cds-action-gpt-task.component.scss | 4 - .../cds-action-hubspot.component.scss | 3 - .../base-condition-row.component.scss | 6 +- .../cds-action-json-condition.component.scss | 4 - .../cds-action-make.component.scss | 3 - .../cds-action-n8n.component.scss | 3 - .../cds-action-reply.component.scss | 4 - .../cds-action-reply.component.scss | 25 +-- .../cds-action-reply-frame.component.scss | 17 -- .../cds-action-reply-gallery.component.scss | 11 +- .../cds-action-reply-image.component.scss | 12 +- ...ds-action-reply-jsonbuttons.component.scss | 19 +- .../cds-action-reply-redirect.component.scss | 11 -- .../cds-action-reply-settings.component.scss | 9 - .../cds-action-reply-text.component.scss | 10 - .../cds-action-web-request-v2.component.scss | 14 +- .../cds-action-web-request.component.scss | 3 - .../cds-action-web-response.component.scss | 3 - .../cds-add-action-menu.component.scss | 5 +- .../delay-slider/delay-slider.component.scss | 44 +++-- .../delay-slider/delay-slider.component.ts | 2 +- .../height-slider.component.scss | 2 +- .../base-elements/text/text.component.scss | 5 - .../textarea/textarea.component.scss | 45 +---- .../cds-canvas/cds-canvas.component.scss | 10 - .../cds-canvas/cds-canvas.module.ts | 4 + .../cds-panel-action-detail.component.scss | 41 +++- ...-panel-button-configuration.component.scss | 6 - .../cds-panel-connector-menu.component.scss | 2 - .../cds-panel-detail.component.html | 23 ++- .../cds-panel-detail.component.scss | 27 ++- .../cds-panel-intent-list.component.scss | 5 +- .../cds-panel-library.component.scss | 5 +- .../cds-panel-note-detail.component.scss | 19 +- src/assets/sass/cds/_variables.scss | 1 + src/assets/sass/cds/action-styles.scss | 141 ++++++++++++-- src/assets/sass/cds/styles.scss | 3 +- src/styles.scss | 21 +++ 107 files changed, 710 insertions(+), 1532 deletions(-) diff --git a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.html b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.html index 5a3b91d0c..5fbafa23f 100644 --- a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.html +++ b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.html @@ -1,11 +1,11 @@
-
filter_alt - {{ 'CDSCanvas.Filter' | translate }} + {{ 'CDSCanvas.Filter' | translate }}
diff --git a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss index 949ac77b2..7524c4e39 100644 --- a/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss +++ b/src/app/chatbot-design-studio/cds-base-element/filter/filter.component.scss @@ -85,47 +85,51 @@ } -.add-filter-btn { - display: flex; +.chip { + display: inline-flex; align-items: center; - justify-content: center; - gap: 5px; - height: 26px; - // padding: 0px 9px; - // font-size: .9em; - // font-weight: 400; - // border-radius: 13px; - transition: all 0.3s ease 0s; - // background: $background-color; - // color: $text-color; - - user-select: none; - box-sizing: border-box; - outline: none; - border: 1px dashed var(--border); - border-radius: var(--button-border-radius); - color: var(--border); + gap: 2px; + height: 27px; + padding: 0 10px 0 4px; + border-radius: 999px; + border: 1px solid var(--ds-muted, #8a8884); + background: var(--surface, #ffffff); + color: var(--ink-2, #3a3935); + font-size: 12.5px; + font-weight: 500; cursor: pointer; - font-size: 0.7em; - font-weight: 400; - line-height: var(--button-height); - // margin: 0px 5px 0; - order: 1; - padding: 0 10px; - transition: all .3s; - min-width: 100px; - text-align: center; - width: fit-content; + transition: background 0.12s, border-color 0.12s, color 0.12s; - span.material-icons-outlined{ - font-size: 20px; + &:hover { + background: var(--canvas, #f7f6f3); + border-color: var(--border-strong, #d8d6d2); + color: var(--ink, #14140e); + .filter-label { + color: var(--ink-2, #3a3935); + } } +} - &:hover{ - background: var(--ds-bg); - border-color: var(--textColor); - color: var(--textColor); +.add-filter-btn { + @extend .chip; + border-style: dashed; + color: var(--muted, #8a8884); + + &:hover { + color: var(--ink-2, #3a3935); + border-color: var(--ds-muted, #8a8884); + } + + .filter-label { + display: flex; + width: auto; + color: var(--ds-muted, #8a8884); cursor: pointer; + font-size: 0.8em; + font-weight: 400; + white-space: nowrap; + align-items: center; + justify-content: flex-start; } } @@ -230,7 +234,7 @@ font-size: 12px; &:hover{ background: var(--cds-canvas); - border-color: var(--textColor); + border: 1px solid var(--border, #e8e6e0); div.remove{ opacity: 1; } @@ -240,28 +244,29 @@ position: absolute; right: -8px; top: -14px; - transition: opacity 0.3s ease 0s; opacity: 0; - height: 28px; - width: 28px; - -webkit-box-align: center; - -webkit-box-pack: center; - align-items: center; - box-shadow: rgba(0, 0, 0, 0.19) 0px 1px 4px 0px; + transition: opacity 0.3s ease 0s; + + width: 24px; + height: 24px; + padding: 0; + border: none; + background: #ffffff; cursor: pointer; + border-radius: 4px; display: flex; + align-items: center; justify-content: center; - background: white; - border-radius: 100%; - transition: background-color 0.3s ease 0s; - font-size: 12px; + color: var(--ds-muted, #8a8884); + span.material-icons, span.material-icons-outlined { - font-size: 20px; - color: var(--textColor); + font-size: 16px; } + &:hover { - background-color: var(--cds-canvas); + background: #fde8e8; + color: #ef4444; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss index a51d5bbf3..2e11577a7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-condition/cds-action-ai-condition-new.component.scss @@ -7,10 +7,6 @@ --text-color: #{var(--ds-ink)}; } -::-webkit-scrollbar { - width: 0px; -} - .custom-divider { border-top: 1px solid var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss index b3d88d0d1..85e7c2fa8 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/cds-action-ai-prompt-new.component.scss @@ -7,10 +7,6 @@ --text-color: #{var(--ds-ink)}; } -::-webkit-scrollbar { - width: 0px; -} - .custom-divider { border-top: 1px solid var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss index 2a92fce5d..616591136 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-server-edit-dialog/mcp-server-edit-dialog-new.component.scss @@ -191,28 +191,10 @@ overflow-x: hidden; /* Custom scrollbar styles (aligned with .custom-mcp-dialog-container .tpl-modal-content) */ - &::-webkit-scrollbar { - width: 8px; - } - &::-webkit-scrollbar-track { - background: transparent; - border-radius: 4px; - } - &::-webkit-scrollbar-thumb { - background: var(--blu-02); - border-radius: 4px; - &:hover { - background: var(--ds-ink); - } - } - - /* Firefox */ - scrollbar-width: thin; - scrollbar-color: var(--blu-02) transparent; -} + /* Firefox */} ::ng-deep .custom-mcp-edit-dialog-container .tools-modal__item { display: block; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss index 784fc0504..9553016e4 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-ai-prompt/mcp-servers-dialog/mcp-servers-dialog-new.component.scss @@ -77,23 +77,8 @@ border: none; // Custom scrollbar styles - &::-webkit-scrollbar { - width: 8px; - } - &::-webkit-scrollbar-track { - background: transparent; - border-radius: 4px; - } - &::-webkit-scrollbar-thumb { - background: var(--blu-02); - border-radius: 4px; - - &:hover { - background: var(--ds-ink); - } - } } .tpl-modal-buttons { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss index 565ce19c0..0cc208433 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-askgpt-v2/cds-action-askgpt-v2-new.component.scss @@ -9,10 +9,7 @@ --text-color-gray: #{var(--gray)}; } -// ::-webkit-scrollbar { -// width: 0px; -// } - +// .tags-input-row { display: flex; align-items: center; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss index 96e291066..d5606ba5d 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable-v2/cds-action-assign-variable-v2-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} div { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss index 87a30490e..3f58b41f8 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-assign-variable/cds-action-assign-variable-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss index dbfba6b23..188853ffe 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-brevo/cds-action-brevo-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} :host { --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss index b635b291c..75a0b85d9 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-customerio/cds-action-customerio-new.component.scss @@ -1,7 +1,3 @@ - -::-webkit-scrollbar { - width: 0px; -} :host { --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss index b17c07337..56de68f8c 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-gpt-task/cds-action-gpt-task-new.component.scss @@ -7,10 +7,6 @@ --text-color: #{var(--ds-ink)}; } -::-webkit-scrollbar { - width: 0px; -} - .custom-divider { border-top: 1px solid var(--ds-ink); } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss index 63f17d379..25122441a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-hubspot/cds-action-hubspot-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} :host { --background-color: var(--ds-bg); //--slider-background-color: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss index bb85962d3..ca42dd9c5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/base-condition-row/base-condition-row-new.component.scss @@ -350,11 +350,7 @@ section.submit{ cds-textarea#operand2 ::ng-deep { display: flex; textarea { - // border: 1px solid rgb(118, 118, 118) !important; + background-color: var(--ds-bg, #fbfbfa); resize: none !important; - // padding: 8px 20px !important; - - // height: 25px !important; - // min-height: 25px !important; } } diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss index ad482dc06..0efe05909 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-json-condition/cds-action-json-condition-new.component.scss @@ -8,10 +8,6 @@ } /* customize scrollbar */ -::-webkit-scrollbar { - width: 0px; -} - .flex-element{ display: flex; width: 100%; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss index e1a245e00..0100e603a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-make/cds-action-make-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} :host { --background-color: #{var(--ds-bg)}; //--slider-background-color: #{var(--blu-light-03)}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss index 3e1233f2e..ce4776930 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-n8n/cds-action-n8n-new.component.scss @@ -1,6 +1,3 @@ -::-webkit-scrollbar { - width: 0px; -} :host { --background-color: #{var(--ds-bg)}; //--slider-background-color: #{$blu-light-03}; diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html index 6f425d09d..1eeb193c9 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.html @@ -1,14 +1,13 @@ -
+
- +
@@ -22,87 +21,65 @@
-
+
{{actionList.RANDOM_REPLY.doc+'.DESCRIPTION' | translate }}
-
- +
+
-
- -
+
+ + + +
+ + +
- -
-
- - - - +
-
- -
-
-
@@ -112,31 +89,13 @@
- -
-
-
@@ -144,86 +103,52 @@
- -
-
-
- - +
- -
-
-
+ (updateAndSaveAction) = onUpdateAndSaveAction($event)>
+
+
+
- +
- \ No newline at end of file + +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss index ebabb063f..21ab127f5 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.scss @@ -6,7 +6,8 @@ $padding: 10px; $action-description-height: 100px; $margin-bottom: 15px; -.cds-action-content-new { +.cds-action-content-new, +.cds-action-content { display: flex; flex-direction: column; height: 100%; @@ -59,10 +60,6 @@ $margin-bottom: 15px; /* customize scrollbar */ -::-webkit-scrollbar { - width: 0px; -} - // .disable-input-message { // position: absolute; // bottom: 10px; @@ -107,9 +104,7 @@ $margin-bottom: 15px; justify-content: flex-start; } -.box-dw { - // display: flex; - margin: 0px 5px; +.box-content { .reply-info{ color: var(--ds-ink); padding: 10px; @@ -127,7 +122,7 @@ $margin-bottom: 15px; } .previewMode{ - &.box-dw{ + &.box-content { margin: 0px; } #scrollMe{ @@ -171,8 +166,7 @@ $margin-bottom: 15px; min-height: $min-height-content; margin-top: 0px; overflow: auto; - max-height: calc(100vh - 180px); - .response { + max-height: calc(100vh - 180px); .response { display: block; position: relative; height: auto; @@ -558,7 +552,7 @@ cds-action-reply-redirect-new, cds-action-reply-gallery-new{ display: flex; flex-direction: column; - gap: 10px; + gap: 5px; } @@ -580,3 +574,13 @@ cds-action-reply-gallery-new.no-controls ::ng-deep{ display: none; } } + +.content.reply-scroll-list { + min-height: 0; + max-height: none; + flex: 1; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-direction: column; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts index a0d291177..4cf3120ff 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v1/cds-action-reply-new.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, OnChanges, Input, ViewChild, ElementRef, Output, EventEmitter, SimpleChanges, ChangeDetectorRef } from '@angular/core'; -import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { Intent } from 'src/app/models/intent-model'; import { Wait, Button, Message, Command, ActionReply, MessageAttributes } from 'src/app/models/action-model'; import { @@ -46,7 +45,6 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { intentName: string; intentNameResult: boolean; - textGrabbing: boolean; arrayResponses: Array; typeAction: string; @@ -119,7 +117,6 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { this.arrayResponses = []; this.intentName = ''; this.intentNameResult = true; - this.textGrabbing = false; if (this.action) { try { this.arrayResponses = this.action.attributes.commands; @@ -146,43 +143,6 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { // EVENT FUNCTIONS // - - // on drag // - /** */ - mouseDown() { - this.textGrabbing = true; - } - - /** */ - mouseUp() { - this.textGrabbing = false; - } - - /** */ - async drop(event: CdkDragDrop) { - // //this.logger.log( 'DROP REPLY ---> ',event, this.arrayResponses); - this.textGrabbing = false; - try { - let currentPos = event.currentIndex*2+1; - let previousPos = event.previousIndex*2+1; - const waitCur = this.arrayResponses[currentPos-1]; - const msgCur = this.arrayResponses[currentPos]; - const waitPre = this.arrayResponses[previousPos-1]; - const msgPre = this.arrayResponses[previousPos]; - this.arrayResponses[currentPos-1] = waitPre; - this.arrayResponses[currentPos] = msgPre; - this.arrayResponses[previousPos-1] = waitCur; - this.arrayResponses[previousPos] = msgCur; - // // this.logger.log( 'DROP REPLY ---> ', this.arrayResponses); - this.connectorService.updateConnector(this.intentSelected.intent_id); - const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.intentSelected}; - await this.onUpdateAndSaveAction(element); - } catch (error) { - this.logger.log('drop ERROR', error); - } - } - - // on action // /** */ onMoveUpResponse(index: number) { @@ -209,7 +169,7 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { try { let from = index; let to = from + 2; - this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); + this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); from = index - 1; to = from + 2; this.arrayResponses.splice(to, 0, this.arrayResponses.splice(from, 1)[0]); @@ -222,6 +182,38 @@ export class CdsActionReplyNewComponent implements OnInit, OnChanges { } } + /** */ + onMoveToTopResponse(index: number) { + if(index < 2) return; + try { + const wait = this.arrayResponses.splice(index - 1, 1)[0]; + const cmd = this.arrayResponses.splice(index - 1, 1)[0]; + this.arrayResponses.unshift(cmd); + this.arrayResponses.unshift(wait); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onMoveToTopResponse ERROR', error); + } + } + + /** */ + onMoveToBottomResponse(index: number) { + if(index === this.arrayResponses.length - 1) return; + try { + const wait = this.arrayResponses.splice(index - 1, 1)[0]; + const cmd = this.arrayResponses.splice(index - 1, 1)[0]; + this.arrayResponses.push(wait); + this.arrayResponses.push(cmd); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onMoveToBottomResponse ERROR', error); + } + } + /** onAddNewActionReply */ onAddNewActionReply(ele) { diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html index d1492a830..65f43e5f3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.html @@ -5,7 +5,7 @@ - +
@@ -19,88 +19,66 @@
-
+
{{actionList.RANDOM_REPLY.doc+'.DESCRIPTION' | translate }}
-
- +
+
-
- -
+
-
+ + - -
-
+
- +
+
+ -
-
- -
-
-
@@ -110,31 +88,13 @@
- -
-
-
@@ -142,72 +102,38 @@
- -
-
-
- - +
- -
-
-
+ (updateAndSaveAction) = onUpdateAndSaveAction($event)>
+
+
+
@@ -227,16 +153,16 @@ (onConnectorChange)= onConnectorChangeReply($event)>
- +
- \ No newline at end of file + +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss index 09d4beaa4..2098864f6 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.scss @@ -6,9 +6,12 @@ $padding: 10px; $action-description-height: 100px; $margin-bottom: 15px; -.cds-action-content{ - // position: relative; - padding: 0px; +.cds-action-content-new, +.cds-action-content { + display: flex; + flex-direction: column; + height: 100%; + padding: 0; } @@ -57,10 +60,6 @@ $margin-bottom: 15px; /* customize scrollbar */ -::-webkit-scrollbar { - width: 0px; -} - // .disable-input-message { // position: absolute; // bottom: 10px; @@ -105,9 +104,7 @@ $margin-bottom: 15px; justify-content: flex-start; } -.box-dw { - // display: flex; - margin: 0px 5px; +.box-content { .reply-info{ color: var(--ds-ink); padding: 10px; @@ -125,7 +122,7 @@ $margin-bottom: 15px; } .previewMode{ - &.box-dw{ + &.box-content { margin: 0px; } #scrollMe{ @@ -169,8 +166,7 @@ $margin-bottom: 15px; min-height: $min-height-content; margin-top: 0px; overflow: auto; - max-height: calc(100vh - 180px); - .response { + max-height: calc(100vh - 180px); .response { display: block; position: relative; height: auto; @@ -321,3 +317,13 @@ cds-action-reply-gallery.no-controls ::ng-deep{ display: none; } } + +.content.reply-scroll-list { + min-height: 0; + max-height: none; + flex: 1; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-direction: column; +} diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts index f12be4dc8..b37084e6a 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/cds-action-reply-v2/cds-action-reply-new.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, Input, ViewChild, ElementRef, Output, EventEmitter, SimpleChanges, ChangeDetectorRef } from '@angular/core'; -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { Intent } from 'src/app/models/intent-model'; import { Wait, Button, Message, Command, ActionReply, MessageAttributes, Setting, ActionReplyV2 } from 'src/app/models/action-model'; import { TYPE_UPDATE_ACTION, TYPE_INTENT_ELEMENT, TYPE_COMMAND, TYPE_RESPONSE, TYPE_BUTTON, TYPE_URL, TYPE_MESSAGE, generateShortUID } from '../../../../../../utils'; @@ -48,7 +47,6 @@ export class CdsActionReplyV2Component implements OnInit { intentName: string; intentNameResult: boolean; - textGrabbing: boolean; arrayResponses: Array; typeAction: string; @@ -156,7 +154,6 @@ export class CdsActionReplyV2Component implements OnInit { this.arrayResponses = []; this.intentName = ''; this.intentNameResult = true; - this.textGrabbing = false; if (this.action) { try { this.arrayResponses = this.action.attributes.commands; @@ -183,43 +180,6 @@ export class CdsActionReplyV2Component implements OnInit { // EVENT FUNCTIONS // - - // on drag // - /** */ - mouseDown() { - this.textGrabbing = true; - } - - /** */ - mouseUp() { - this.textGrabbing = false; - } - - /** */ - drop(event: CdkDragDrop) { - // this.logger.log( 'DROP REPLY ---> ',event, this.arrayResponses); - this.textGrabbing = false; - try { - let currentPos = event.currentIndex*2+1; - let previousPos = event.previousIndex*2+1; - const waitCur = this.arrayResponses[currentPos-1]; - const msgCur = this.arrayResponses[currentPos]; - const waitPre = this.arrayResponses[previousPos-1]; - const msgPre = this.arrayResponses[previousPos]; - this.arrayResponses[currentPos-1] = waitPre; - this.arrayResponses[currentPos] = msgPre; - this.arrayResponses[previousPos-1] = waitCur; - this.arrayResponses[previousPos] = msgCur; - // // this.logger.log( 'DROP REPLY ---> ', this.arrayResponses); - this.connectorService.updateConnector(this.intentSelected.intent_id); - const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.intentSelected}; - this.onUpdateAndSaveAction(element); - } catch (error) { - this.logger.log('drop ERROR', error); - } - } - - // on action // /** */ onMoveUpResponse(index: number) { @@ -260,6 +220,38 @@ export class CdsActionReplyV2Component implements OnInit { } + /** */ + onMoveToTopResponse(index: number) { + if(index < 2) return; + try { + const wait = this.arrayResponses.splice(index - 1, 1)[0]; + const cmd = this.arrayResponses.splice(index - 1, 1)[0]; + this.arrayResponses.unshift(cmd); + this.arrayResponses.unshift(wait); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onMoveToTopResponse ERROR', error); + } + } + + /** */ + onMoveToBottomResponse(index: number) { + if(index === this.arrayResponses.length - 1) return; + try { + const wait = this.arrayResponses.splice(index - 1, 1)[0]; + const cmd = this.arrayResponses.splice(index - 1, 1)[0]; + this.arrayResponses.push(wait); + this.arrayResponses.push(cmd); + this.connectorService.updateConnector(this.intentSelected.intent_id); + const element = {type: TYPE_UPDATE_ACTION.ACTION, element: this.action}; + this.onUpdateAndSaveAction(element); + } catch (error) { + this.logger.log('onMoveToBottomResponse ERROR', error); + } + } + /** onAddNewActionReply */ onAddNewActionReply(ele) { this.logger.log('onAddNewActionReply: ', ele); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html index 735c634f7..1d7f94dec 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.html @@ -1,27 +1,11 @@
- -
- drag_indicator -
- -
-
- delete -
-
- expand_less -
-
- expand_more -
-
- +
diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss index 621516c05..62e0e3db7 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.scss @@ -1,12 +1,6 @@ @import "./src/assets/sass/cds/_variables.scss"; $max-height: 230px; -.extensions-response{ - display: flex; - flex-direction: row; - justify-content: flex-start; -} - .delay-wrapper, .height-wrapper { height: 32px; } @@ -91,14 +85,4 @@ $max-height: 230px; /** box-textarea **/ -cds-textarea.text-editable-div ::ng-deep{ - display: block; - margin-left: var(--base-margin); - margin-right: var(--base-margin); - // width: calc(100% - 66px); - textarea { - line-height: 20px !important; - width: calc(100% - 20px) !important; - font-size: 0.9em !important; - } } \ No newline at end of file diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts index 1ec8e8508..7a9b835c3 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-frame/cds-action-reply-frame-new.component.ts @@ -14,9 +14,6 @@ import { TYPE_ACTION } from 'src/app/chatbot-design-studio/utils-actions'; export class CdsActionReplyFrameNewComponent implements OnInit { @Output() changeActionReply = new EventEmitter(); - @Output() deleteActionReply = new EventEmitter(); - @Output() moveUpResponse = new EventEmitter(); - @Output() moveDownResponse = new EventEmitter(); @Input() idAction: string; @Input() response: Message; @@ -99,21 +96,6 @@ export class CdsActionReplyFrameNewComponent implements OnInit { this.changeActionReply.emit(); } - /** onDeleteActionReply */ - onDeleteActionReply(){ - this.deleteActionReply.emit(this.index); - } - - /** onMoveUpResponse */ - onMoveUpResponse(){ - this.moveUpResponse.emit(this.index); - } - - /** onMoveDownResponse */ - onMoveDownResponse(){ - this.moveDownResponse.emit(this.index); - } - /** onChangeTextarea */ onChangeTextarea(text:string) { this.logger.log("[ActionReplyFrameComponent] onChangeTextarea: ", text); diff --git a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html index 2c94b1be9..c177fd275 100644 --- a/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html +++ b/src/app/chatbot-design-studio/cds-dashboard/cds-canvas/actions/list-new/cds-action-reply/elements/cds-action-reply-gallery/cds-action-reply-gallery-new.component.html @@ -1,27 +1,11 @@
- -
- drag_indicator -
- -
-
- delete -
-
- expand_less -
-
- expand_more -
-
- +
@@ -104,10 +88,7 @@ (changeTextarea)="onChangeJsonTextarea($event)">
-
- delete -
-
+
@@ -218,30 +199,14 @@ expand_more
-->
- -
- delete -
-
+
-
- chevron_left -
-
- chevron_right -
-
- -
- delete -
- -
+