Skip to content

Commit

Permalink
Merge branch 'features/action-operating-hours' into features/master-pre
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriele Panico committed Jul 23, 2024
2 parents 8141535 + ef7507d commit 024d69f
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 32 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
*Giovanni Troisi*
### **Copyrigth**: *Tiledesk SRL*


### 1.18.0-rc.2
👉 **added**: implement time slots on cds-action-operating-hours
👉 **added**: ignoreOperatingHours property added on cds-action-online-agents-v2

### 1.18.0-rc.1
👉 **added**: cds-action-lead-update component
👉 **added**: gpt-4o-mini support

### 1.17.4 in PROD
👉 **added**: gpt-4o-mini support

Expand All @@ -17,6 +26,12 @@

### 1.17.1 in PROD

### 1.17.1-rc.2
👉 **added**: check to hide/show actionCategory

### 1.17.1-rc.1
👉 **bug-fixed**: if two or more cds-action-reply-v2 is in the same intent, when user select one of them, also the first action is selected

### 1.17.0-rc.1
👉 **added**: check to project profile object to dynamically hide/show action

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@tiledesk/cds",
"author": "Tiledesk SRL",
"version": "1.17.4",
"version": "1.18.0-rc.2",
"license": "MIT",
"homepage": "https://www.tiledesk.com",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ export class CdsActionChangeDepartmentComponent implements OnInit {
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@
</div>
</div>

<div class="field-box">
<section class="disable-input-message-section">
<mat-checkbox
[checked]="action?.ignoreOperatingHours"
(change)="onChangeCheckbox('ignoreOperatingHours')">
{{"CDSCanvas.IgnoreOperatingHours" | translate}}
</mat-checkbox>
</section>
<label class="field-description" [innerHTML]='"CDSCanvas.IgnoreOperatingHoursDescription" | translate'></label>
</div>


<hr class="custom-divider">

<!-- trueIntent -->
Expand Down Expand Up @@ -146,4 +158,4 @@
</section>
</div>
</div> -->
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ export class CdsActionOnlineAgentsV2Component implements OnInit {
}
}

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 })
Expand Down Expand Up @@ -271,4 +280,4 @@ export class CdsActionOnlineAgentsV2Component implements OnInit {
}


}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
<div *ngIf="previewMode" class="cds-action-preview">

<div class="action-row">
<div class="action-row-left">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="none">
<path d="M10,0.4c-5.3,0-9.6,4.3-9.6,9.6s4.3,9.6,9.6,9.6c5.3,0,9.6-4.3,9.6-9.6C19.6,4.7,15.3,0.4,10,0.4z M10,17.6c-4.2,0-7.6-3.4-7.6-7.6c0-4.2,3.4-7.6,7.6-7.6l0,0V10l6.8-3.4c0.5,1,0.8,2.2,0.8,3.4C17.6,14.2,14.2,17.6,10,17.6z"/>
</svg>
</div>

<div *ngIf="action?.slotId" class="action-row-right">
<span *ngIf="action.slotId === ''">
{{ (radioOptions | filter:{key: 'category', value: 'general'}).name | translate }}
</span>
<span *ngIf="action.slotId !== ''">
<b>{{ (timeSlots | filter:{key: 'value', value: action.slotId}).name }}</b>
</span>
</div>
<div *ngIf="!action?.slotId" class="action-row-right">
{{ (radioOptions | filter:{key: 'category', value: 'general'}).name | translate }}
</div>
</div>

<div class="previewContent">

<div class="icon-action">
Expand Down Expand Up @@ -34,6 +54,34 @@
<div *ngIf="!previewMode">
<div class="content-panel-intent-detail">

<div class="field-box">
<label class="title-label">{{'CDSCanvas.CheckOperatingHours' | translate }}</label>
<cds-radio-buttons
[items]="radioOptions"
[itemSelected]="radioOptionSelected"
[bindLabelButton]="'name'"
[bindValueButton]="'category'"
[rows]="3" [columns]="1"
(changeButtonSelect)="onChangeButtonSelect($event)">
</cds-radio-buttons>


<div *ngIf="radioOptionSelected !== null" class="deps-wrp">
<cds-select id="list-deps"
[items]="timeSlots"
[bindLabelSelect]="'name'"
[bindValueSelect]="'value'"
[itemSelected]="action?.slotId"
[placeholder]="'CDSCanvas.SelectTimeSlot' | translate "
[clearable]="true"
(onSelected)="onChangeSelect($event, 'slotId')"
(onReset)="onResetBlockSelect($event, 'slotId')">
</cds-select>
</div>
</div>

<hr class="custom-divider">

<!-- trueIntent -->
<div class="field-box">
<div class="condition-container">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.deps-wrp{
display: flex;
justify-content: center;
}

cds-select#list-deps{
width: 80%;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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';

@Component({
selector: 'cds-action-open-hours',
Expand All @@ -21,7 +22,6 @@ export class CdsActionOpenHoursComponent implements OnInit {
@Output() updateAndSaveAction = new EventEmitter();
@Output() onConnectorChange = new EventEmitter<{type: 'create' | 'delete', fromId: string, toId: string}>()

actionOpenHoursFormGroup: FormGroup
trueIntentAttributes: any = "";
falseIntentAttributes: any = "";

Expand All @@ -36,13 +36,21 @@ export class CdsActionOpenHoursComponent implements OnInit {
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 {
Expand Down Expand Up @@ -74,21 +82,26 @@ export class CdsActionOpenHoursComponent implements OnInit {
// }

private initialize() {
this.actionOpenHoursFormGroup = this.buildForm();
this.actionOpenHoursFormGroup.valueChanges.subscribe(form => {
this.logger.log('[ACTION-OPEN-HOURS] form valueChanges-->', form)
if (form && (form.trueIntent !== ''))
this.action = Object.assign(this.action, this.actionOpenHoursFormGroup.value);
})
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();
}
if (this.action && this.action.trueIntent) {
this.setFormValue()

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 checkConnectionStatus(){
Expand Down Expand Up @@ -168,21 +181,23 @@ export class CdsActionOpenHoursComponent implements OnInit {
}


buildForm(): FormGroup {
return this.formBuilder.group({
trueIntent: ['', Validators.required],
falseIntent: ['', Validators.required]
})
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});
}

setFormValue() {
this.actionOpenHoursFormGroup.patchValue({
trueIntent: this.action.trueIntent,
falseIntent: this.action.falseIntent
})
}

onChangeSelect(event:{name: string, value: string}, type : 'trueIntent' | 'falseIntent'){
onChangeSelect(event:{name: string, value: string}, type : 'trueIntent' | 'falseIntent' | 'slotId'){
if(event){
this.action[type]=event.value
switch(type){
Expand All @@ -197,7 +212,7 @@ export class CdsActionOpenHoursComponent implements OnInit {
}
}

onResetBlockSelect(event:{name: string, value: string}, type: 'trueIntent' | 'falseIntent') {
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})
Expand Down
8 changes: 4 additions & 4 deletions src/app/chatbot-design-studio/utils-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ export function getKeyByValue(value, keys) {

export const ACTIONS_LIST: {[key: string]: {name: string, category: TYPE_ACTION_CATEGORY, type: TYPE_ACTION | TYPE_ACTION_VXML, src: string, status: 'active' | 'inactive' | 'beta', plan?: PLAN_NAME, badge?: string, description?: string, doc?: string, disabled?: boolean}}= {
REPLY : { name: 'CDSActionList.NAME.Reply', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLY, src:"assets/images/actions/reply.svg", status: "active" , description: "CDSActionList.DESCRIPTION.Reply", doc: "CDSActionList.DOCS.Reply" },
REPLYV2 : { name: 'CDSActionList.NAME.ReplyV2', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLYV2, src:"assets/images/actions/reply_v2.svg", status: "beta" , badge: 'NEW', description: "CDSActionList.DESCRIPTION.ReplyV2", doc: "CDSActionList.DOCS.ReplyV2" },
REPLYV2 : { name: 'CDSActionList.NAME.ReplyV2', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.REPLYV2, src:"assets/images/actions/reply_v2.svg", status: "active" , badge: 'NEW', description: "CDSActionList.DESCRIPTION.ReplyV2", doc: "CDSActionList.DOCS.ReplyV2" },
RANDOM_REPLY : { name: 'CDSActionList.NAME.RandomReply', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.RANDOM_REPLY, src:"assets/images/actions/random_reply.svg", status: "active", description: "CDSActionList.DESCRIPTION.RandomReply" },
AGENT : { name: 'CDSActionList.NAME.AgentHandoff', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.AGENT, src:"assets/images/actions/agent_handoff.svg", status: "active", description: "CDSActionList.DESCRIPTION.AgentHandoff" },
CLOSE : { name: 'CDSActionList.NAME.Close', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.CLOSE, src:"assets/images/actions/close.svg", status: "active", description: "CDSActionList.DESCRIPTION.Close" },
OPEN_HOURS: { name: 'CDSActionList.NAME.IfOperatingHours', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.OPEN_HOURS, src: "assets/images/actions/open_hours.svg", status: "active", description: "CDSActionList.DESCRIPTION.IfOperatingHours" },
OPEN_HOURS: { name: 'CDSActionList.NAME.IfOperatingHours', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.OPEN_HOURS, src: "assets/images/actions/open_hours.svg", status: "active", badge: 'NEW', description: "CDSActionList.DESCRIPTION.IfOperatingHours" },
ONLINE_AGENTS: { name: 'CDSActionList.NAME.IfOnlineAgent', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.ONLINE_AGENTS, src: "assets/images/actions/online_agents.svg", status: "inactive", description: "CDSActionList.DESCRIPTION.IfOnlineAgent" },
ONLINE_AGENTSV2: { name: 'CDSActionList.NAME.IfOnlineAgent', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.ONLINE_AGENTSV2, src: "assets/images/actions/online_agents.svg", status: "active", badge: 'NEW', description: "CDSActionList.DESCRIPTION.IfOnlineAgent" },
ONLINE_AGENTSV2: { name: 'CDSActionList.NAME.IfOnlineAgent', category: TYPE_ACTION_CATEGORY.MOST_USED, type: TYPE_ACTION.ONLINE_AGENTSV2, src: "assets/images/actions/online_agents.svg", status: "active", description: "CDSActionList.DESCRIPTION.IfOnlineAgent" },
CONDITION: { name: 'CDSActionList.NAME.Condition', category: TYPE_ACTION_CATEGORY.FLOW, type: TYPE_ACTION.CONDITION, src: "assets/images/actions/condition.svg", status: "active" },
JSON_CONDITION: { name: 'CDSActionList.NAME.ConditionElse', category: TYPE_ACTION_CATEGORY.FLOW, type: TYPE_ACTION.JSON_CONDITION, src: "assets/images/actions/condition.svg", status: "active" },
INTENT : { name: 'CDSActionList.NAME.ConnectBlock', category: TYPE_ACTION_CATEGORY.FLOW, type: TYPE_ACTION.INTENT, src:"assets/images/actions/connect_intent.svg", status: "inactive", description: "CDSActionList.DESCRIPTION.ConnectBlock" },
Expand All @@ -97,7 +97,7 @@ export const ACTIONS_LIST: {[key: string]: {name: string, category: TYPE_ACTION_
WAIT : { name: 'CDSActionList.NAME.Wait', category: TYPE_ACTION_CATEGORY.FLOW, type: TYPE_ACTION.WAIT, src:"assets/images/actions/wait.svg", status: "active", description: "CDSActionList.DESCRIPTION.Wait" },
LEAD_UPDATE : { name: 'CDSActionList.NAME.LeadUpdate', category: TYPE_ACTION_CATEGORY.FLOW, type: TYPE_ACTION.LEAD_UPDATE, src:"assets/images/actions/lead_update.svg", status: "active", description: "CDSActionList.DESCRIPTION.LeadUpdate" },
// WEB_REQUEST : { name: 'CDSActionList.NAME.WebRequest',category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.WEB_REQUEST, src:"assets/images/actions/web_request.svg", status: "active", description: ''},
WEB_REQUESTV2 : { name: 'CDSActionList.NAME.WebRequest', category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.WEB_REQUESTV2, src:"assets/images/actions/web_request.svg", status: "beta", description: '' },
WEB_REQUESTV2 : { name: 'CDSActionList.NAME.WebRequest', category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.WEB_REQUESTV2, src:"assets/images/actions/web_request.svg", status: "active", description: '' },
EMAIL : { name: 'CDSActionList.NAME.SendEmail', category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.EMAIL, src:"assets/images/actions/send_email.svg", status: "active", description: "CDSActionList.DESCRIPTION.SendEmail" },
WHATSAPP_STATIC: { name: 'CDSActionList.NAME.WhatsAppStatic', category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.WHATSAPP_STATIC, src: "assets/images/actions/whatsapp.svg", status: "active", description: "CDSActionList.DESCRIPTION.WhatsAppStatic" },
WHATSAPP_ATTRIBUTE: { name: 'CDSActionList.NAME.WhatsAppByAttribute', category: TYPE_ACTION_CATEGORY.INTEGRATIONS, type: TYPE_ACTION.WHATSAPP_ATTRIBUTE, src: "assets/images/actions/whatsapp.svg", status: "active", description: "CDSActionList.DESCRIPTION.WhatsAppByAttribute" },
Expand Down
4 changes: 4 additions & 0 deletions src/app/models/action-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,18 @@ export class ActionOnlineAgentV2 extends Action {
stopOnConditionMet: boolean;
selectedOption: string;
selectedDepartmentId?: string;
ignoreOperatingHours?: boolean;
constructor() {
super();
this.stopOnConditionMet = true;
this._tdActionType = TYPE_ACTION.ONLINE_AGENTSV2;
this.selectedOption = 'all'
this.ignoreOperatingHours = false;
}
}

export class ActionOpenHours extends Action {
slotId?: string;
trueIntent: string;
falseIntent: string;
trueIntentAttributes?: string;
Expand All @@ -99,6 +102,7 @@ export class ActionOpenHours extends Action {
constructor() {
super();
this.stopOnConditionMet = true;
// this.slotId = null;
this._tdActionType = TYPE_ACTION.OPEN_HOURS;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/app/models/project-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export interface Project {
name?: string;
activeOperatingHours?: boolean;
operatingHours?: any
timeSlots?: {
[key: string]: { name: string, hours: string, active: boolean}
}
createdBy?: string;
id_project?: any;
widget?: any;
Expand Down
Loading

0 comments on commit 024d69f

Please sign in to comment.