Skip to content

Commit c347ab1

Browse files
authored
Merge pull request #94 from iceljc/features/refine-chat-window
add generic elements
2 parents ab9b979 + cfc33f4 commit c347ab1

File tree

5 files changed

+185
-48
lines changed

5 files changed

+185
-48
lines changed

src/lib/scss/custom/pages/_chat.scss

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,40 @@
188188
min-width: 50px;
189189
}
190190
}
191+
192+
.card-group-container {
193+
display: flex;
194+
flex-wrap: wrap;
195+
gap: 5px;
196+
margin-top: 10px;
197+
198+
.card-element {
199+
flex: 1 1 fit-content;
200+
border-radius: 10px;
201+
border-width: 2px;
202+
max-width: 100%;
203+
margin-bottom: 0px;
204+
205+
.card-element-title {
206+
font-size: 1.1rem;
207+
font-weight: 700;
208+
}
209+
210+
.card-element-subtitle {
211+
font-size: 0.8rem;
212+
font-weight: 500;
213+
}
214+
215+
.card-option-group {
216+
margin-top: 5px;
217+
218+
.btn {
219+
display: block;
220+
margin-left: 0px !important;
221+
}
222+
}
223+
}
224+
}
191225
}
192226

193227
.ctext-wrap {

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,11 @@
362362
await sentTextMessage();
363363
}
364364
365-
/** @param {string} payload */
366-
async function confirmSelectedOption(payload) {
365+
/** @param {string} answer */
366+
async function confirmSelectedOption(answer) {
367367
if (isSendingMsg || isThinking) return;
368368
369-
await sendChatMessage(payload);
369+
await sendChatMessage(answer);
370370
}
371371
372372
async function sentTextMessage() {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<script>
2+
import { Card, CardBody } from "@sveltestrap/sveltestrap";
3+
import { onMount } from "svelte";
4+
5+
6+
/** @type {boolean} */
7+
export let disableOption = false;
8+
9+
/** @type {boolean} */
10+
export let fillPostback = false;
11+
12+
/** @type {any[]} */
13+
export let options = [];
14+
15+
/** @type {(args0: string) => any} */
16+
export let onConfirm;
17+
18+
/** @type {any[]} */
19+
let cards = [];
20+
21+
onMount(() => {
22+
cards = collectOptions(options);
23+
});
24+
25+
/** @param {any[]} options */
26+
function collectOptions(options) {
27+
const res = options?.map(op => {
28+
// @ts-ignore
29+
const options = op.buttons?.map(x => {
30+
return {
31+
title: x.title,
32+
payload: x.payload
33+
};
34+
}) || [];
35+
36+
return {
37+
title: op.title,
38+
subtitle: op.subtitle,
39+
options: options
40+
};
41+
}) || [];
42+
43+
return res;
44+
}
45+
46+
/**
47+
* @param {any} e
48+
* @param {any} option
49+
*/
50+
function handleClickOption(e, option) {
51+
e.preventDefault();
52+
innerConfirm(fillPostback ? option?.payload : option?.title);
53+
}
54+
55+
/**
56+
* @param {string} answer
57+
*/
58+
function innerConfirm(answer) {
59+
onConfirm && onConfirm(answer);
60+
reset();
61+
}
62+
63+
function reset() {
64+
cards = [];
65+
}
66+
</script>
67+
68+
{#if cards.length > 0}
69+
<div class="card-group-container">
70+
{#each cards as card, idx (idx)}
71+
<Card class="card-element">
72+
<CardBody>
73+
{#if !!card.title}
74+
<div class="card-element-title">{card.title}</div>
75+
{/if}
76+
{#if !!card.subtitle}
77+
<div class="card-element-subtitle">{card.subtitle}</div>
78+
{/if}
79+
{#if card.options?.length > 0}
80+
<div class="card-option-group">
81+
{#each card.options as option, i (i)}
82+
<button
83+
class="btn btn-outline-primary btn-rounded btn-sm m-1"
84+
disabled={disableOption}
85+
on:click={(e) => handleClickOption(e, option)}
86+
>
87+
{option.title}
88+
</button>
89+
{/each}
90+
</div>
91+
{/if}
92+
</CardBody>
93+
</Card>
94+
{/each}
95+
</div>
96+
{/if}

src/routes/chat/[agentId]/[conversationId]/richContent/rc-options.svelte

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/** @type {boolean} */
88
export let disableOption = false;
99
10+
/** @type {boolean} */
11+
export let fillPostback = false;
12+
1013
/** @type {any[]} */
1114
export let options = [];
1215
@@ -30,54 +33,43 @@
3033
3134
/** @param {any[]} options */
3235
function collectOptions(options) {
33-
/** @type {any[]} */
34-
let res = [];
35-
options?.map(op => {
36-
if (!!!op.title || !!!op.payload) {
37-
return;
38-
}
39-
40-
if (op.buttons?.length > 0) {
41-
// @ts-ignore
42-
op.buttons?.map(x => {
43-
if (!!x.title && !!x.payload) {
44-
res.push({
45-
title: x.title,
46-
payload: x.payload,
47-
isClicked: false
48-
});
49-
}
50-
});
51-
} else {
52-
res.push({
53-
title: op.title,
54-
payload: op.payload,
55-
isClicked: false
56-
});
57-
}
58-
});
36+
const res = options?.map(op => {
37+
return {
38+
title: op.title,
39+
payload: op.payload,
40+
isClicked: false
41+
};
42+
}) || [];
5943
6044
return res;
6145
}
6246
6347
/**
6448
* @param {any} e
65-
* @param {string} payload
49+
* @param {any} option
6650
* @param {number} index
6751
*/
68-
function handleClickOption(e, payload, index) {
52+
function handleClickOption(e, option, index) {
6953
e.preventDefault();
7054
7155
if (!isMultiSelect) {
72-
innerConfirm(payload);
56+
innerConfirm(fillPostback ? option?.payload : option?.title);
7357
} else {
7458
localOptions = localOptions.map((op, idx) => {
7559
if (idx === index) {
7660
op.isClicked = !op.isClicked;
7761
if (op.isClicked) {
78-
answers = [...answers, op.payload];
62+
if (fillPostback) {
63+
answers = [...answers, op.payload];
64+
} else {
65+
answers = [...answers, op.title];
66+
}
7967
} else {
80-
answers = answers.filter(a => a != op.payload);
68+
if (fillPostback) {
69+
answers = answers.filter(a => a != op.payload);
70+
} else {
71+
answers = answers.filter(a => a != op.title);
72+
}
8173
}
8274
}
8375
return op;
@@ -90,15 +82,15 @@
9082
*/
9183
function handleConfirm(e) {
9284
e.preventDefault();
93-
const payload = answers.join(separator);
94-
innerConfirm(payload);
85+
const answer = answers.join(separator);
86+
innerConfirm(answer);
9587
}
9688
9789
/**
98-
* @param {string} payload
90+
* @param {string} answer
9991
*/
100-
function innerConfirm(payload) {
101-
onConfirm && onConfirm(payload);
92+
function innerConfirm(answer) {
93+
onConfirm && onConfirm(answer);
10294
reset();
10395
}
10496
@@ -112,10 +104,24 @@
112104
{#if localOptions.length > 0}
113105
<div class="button-group">
114106
{#each localOptions as option, index}
115-
<button class="btn btn-outline-primary btn-rounded btn-sm m-1" class:active={!!option.isClicked} disabled={disableOption} on:click={(e) => handleClickOption(e, option.payload, index)}>{option.title}</button>
107+
<button
108+
class="btn btn-outline-primary btn-rounded btn-sm m-1"
109+
class:active={!!option.isClicked}
110+
disabled={disableOption}
111+
on:click={(e) => handleClickOption(e, option, index)}
112+
>
113+
{option.title}
114+
</button>
116115
{/each}
117116
{#if isMultiSelect}
118-
<button class="btn btn-outline-success btn-rounded btn-sm m-1" name="confirm" disabled={disableOption || localOptions.every(x => !!!x.isClicked)} on:click={(e) => handleConfirm(e)}>{confirmBtnText}</button>
117+
<button
118+
class="btn btn-outline-success btn-rounded btn-sm m-1"
119+
name="confirm"
120+
disabled={disableOption || localOptions.every(x => !!!x.isClicked)}
121+
on:click={(e) => handleConfirm(e)}
122+
>
123+
{confirmBtnText || 'Continue'}
124+
</button>
119125
{/if}
120126
</div>
121127
{/if}

src/routes/chat/[agentId]/[conversationId]/richContent/rich-content.svelte

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { RichType } from "$lib/helpers/enums";
33
import Markdown from "$lib/common/Markdown.svelte";
44
import RcOptions from "./rc-options.svelte";
5+
import RcGenericOptions from "./rc-generic-options.svelte";
56
67
/** @type {any} */
78
export let message;
@@ -16,10 +17,10 @@
1617
export let onConfirm = () => {};
1718
1819
/**
19-
* @param {string} payload
20+
* @param {string} answer
2021
*/
21-
function handleConfirm(payload) {
22-
onConfirm && onConfirm(payload);
22+
function handleConfirm(answer) {
23+
onConfirm && onConfirm(answer);
2324
}
2425
</script>
2526

@@ -31,12 +32,12 @@
3132

3233
{#if displayExtraElements}
3334
{#if message?.rich_content?.message?.rich_type === RichType.QuickReply}
34-
<RcOptions options={message?.rich_content?.message?.quick_replies} disableOption={disableOption} onConfirm={handleConfirm} />
35+
<RcOptions options={message?.rich_content?.message?.quick_replies} fillPostback={message?.rich_content?.fill_postback} disableOption={disableOption} onConfirm={handleConfirm} />
3536
{:else if message?.rich_content?.message?.rich_type === RichType.Button}
36-
<RcOptions options={message?.rich_content?.message?.buttons} disableOption={disableOption} onConfirm={handleConfirm} />
37+
<RcOptions options={message?.rich_content?.message?.buttons} fillPostback={message?.rich_content?.fill_postback} disableOption={disableOption} onConfirm={handleConfirm} />
3738
{:else if message?.rich_content?.message?.rich_type === RichType.MultiSelect}
38-
<RcOptions options={message?.rich_content?.message?.options} isMultiSelect disableOption={disableOption} onConfirm={handleConfirm} />
39+
<RcOptions options={message?.rich_content?.message?.options} isMultiSelect fillPostback={message?.rich_content?.fill_postback} disableOption={disableOption} onConfirm={handleConfirm} />
3940
{:else if message?.rich_content?.message?.rich_type === RichType.Generic}
40-
<RcOptions options={message?.rich_content?.message?.elements} disableOption={disableOption} onConfirm={handleConfirm} />
41+
<RcGenericOptions options={message?.rich_content?.message?.elements} disableOption={disableOption} onConfirm={handleConfirm} />
4142
{/if}
4243
{/if}

0 commit comments

Comments
 (0)