@tencentcloud/ai-desk-customer-vue 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +23 -4
  2. package/assets/customer_avatar.png +0 -0
  3. package/assets/face.svg +10 -0
  4. package/assets/feedback_dialog_close.svg +3 -0
  5. package/assets/feedback_dislike_after.svg +3 -0
  6. package/assets/feedback_dislike_before.svg +10 -0
  7. package/assets/feedback_dislike_hover.svg +10 -0
  8. package/assets/feedback_like_after.svg +14 -0
  9. package/assets/feedback_like_before.svg +10 -0
  10. package/assets/feedback_like_hover.svg +10 -0
  11. package/assets/files.svg +5 -0
  12. package/assets/green_check.svg +4 -0
  13. package/assets/image.svg +8 -0
  14. package/assets/rating_tool_icon.svg +5 -0
  15. package/assets/rating_tool_icon_h5.svg +1 -0
  16. package/assets/video.svg +8 -0
  17. package/assets/video_h5.svg +1 -0
  18. package/components/CustomerServiceChat/chat-header/index-web.vue +16 -14
  19. package/components/CustomerServiceChat/index-web.vue +87 -13
  20. package/components/CustomerServiceChat/message-input/index-web.vue +31 -5
  21. package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +25 -0
  22. package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +29 -20
  23. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/emoji-picker-dialog.vue +36 -36
  24. package/components/CustomerServiceChat/message-input-toolbar/emoji-picker/index.vue +1 -1
  25. package/components/CustomerServiceChat/message-input-toolbar/file-upload/index.vue +6 -8
  26. package/components/CustomerServiceChat/message-input-toolbar/image-upload/index.vue +11 -16
  27. package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +61 -18
  28. package/components/CustomerServiceChat/message-input-toolbar/rating-tool/index.vue +72 -0
  29. package/components/CustomerServiceChat/message-input-toolbar/toolbar-item-container/style/h5.scss +10 -1
  30. package/components/CustomerServiceChat/message-input-toolbar/user-define-input-tool.vue +80 -0
  31. package/components/CustomerServiceChat/message-input-toolbar/video-upload/index.vue +9 -14
  32. package/components/CustomerServiceChat/message-list/index-web.vue +38 -6
  33. package/components/CustomerServiceChat/message-list/message-elements/feedback-button.vue +369 -0
  34. package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +81 -15
  35. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/marked.ts +17 -10
  36. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-branch.vue +18 -10
  37. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +1 -1
  38. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-desk.vue +13 -6
  39. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-ivr-form/form-branch.vue +117 -0
  40. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/{message-single-form → message-ivr-form}/form-input.vue +65 -111
  41. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/{message-single-form → message-ivr-form}/index.vue +7 -2
  42. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +25 -9
  43. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/index.vue +5 -3
  44. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/input-mobile.vue +1 -0
  45. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-mobile/label-mobile.vue +4 -2
  46. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/component-pc/label-pc.vue +5 -3
  47. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +17 -5
  48. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +21 -1
  49. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +3 -3
  50. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-product-card.vue +2 -1
  51. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-number.vue +9 -13
  52. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +11 -18
  53. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-robot-welcome.vue +1 -0
  54. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +14 -10
  55. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-timeout-warning.vue +29 -0
  56. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/styles/common.scss +1 -0
  57. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-web.vue +22 -2
  58. package/components/CustomerServiceChat/message-list/message-elements/message-file.vue +1 -1
  59. package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +6 -24
  60. package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +0 -9
  61. package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +31 -20
  62. package/components/CustomerServiceChat/message-list/message-elements/simple-message-list/index.vue +2 -1
  63. package/components/CustomerServiceChat/message-list/scroll-button/index.vue +3 -3
  64. package/components/CustomerServiceChat/message-list/style/web.scss +2 -1
  65. package/components/CustomerServiceChat/message-toolbar-button/index.vue +111 -42
  66. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-end-human-service.vue +59 -0
  67. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-human-service.vue +55 -0
  68. package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-service-rating.vue +59 -0
  69. package/components/common/Toast/index-web.vue +4 -2
  70. package/constant.ts +25 -0
  71. package/interface.ts +35 -5
  72. package/locales/en/aidesk.ts +28 -15
  73. package/locales/fil/aidesk.ts +28 -15
  74. package/locales/id/aidesk.ts +28 -15
  75. package/locales/ja/aidesk.ts +28 -15
  76. package/locales/ms/aidesk.ts +28 -15
  77. package/locales/ru/aidesk.ts +28 -15
  78. package/locales/th/aidesk.ts +28 -15
  79. package/locales/vi/aidesk.ts +28 -15
  80. package/locales/zh_cn/aidesk.ts +28 -15
  81. package/locales/zh_tw/aidesk.ts +28 -15
  82. package/package.json +1 -1
  83. package/server.ts +5 -1
  84. package/utils/state.js +30 -0
  85. package/utils/utils.ts +48 -1
  86. package/assets/face.png +0 -0
  87. package/assets/files.png +0 -0
  88. package/assets/image.png +0 -0
  89. package/assets/video.png +0 -0
  90. package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-single-form/form-branch.vue +0 -68
@@ -12,21 +12,19 @@
12
12
  :class="[message.flow === 'in' ? '' : 'reverse']"
13
13
  >
14
14
  <Avatar
15
- v-if="isPC"
15
+ v-if="showAvatar === 1"
16
16
  useSkeletonAnimation
17
- :url="message.flow=== 'in'? (message.avatar || customerAvatar) : (message.avatar || '')"
17
+ :url="avatarUrl"
18
18
  />
19
19
  <main
20
20
  :class="['message-body',message.flow==='out' && 'message-body-reverse']"
21
21
  @click.stop
22
22
  >
23
23
  <div
24
- v-if="
25
- isPC
26
- "
24
+ v-if="showNickName === 1"
27
25
  class="message-body-nick-name"
28
26
  >
29
- {{ props.content.showName }}
27
+ {{ nickName }}
30
28
  </div>
31
29
  <div
32
30
  :class="[
@@ -109,8 +107,13 @@
109
107
  <ReadStatus
110
108
  class="message-label align-self-bottom"
111
109
  :message="shallowCopyMessage(message)"
110
+ @setStatus="setStatus"
111
+ :prevStatus="prevStatus"
112
112
  />
113
113
  </div>
114
+ <!-- <div class="message-bubble-feedback-button">
115
+ <FeedbackButton v-if="isFromRobot(message.cloudCustomData)"/>
116
+ </div> -->
114
117
  </main>
115
118
  </div>
116
119
  <!-- message extra area -->
@@ -142,7 +145,11 @@ import loadingIcon from '../../../../assets/loading.png';
142
145
  import customerAvatar from '../../../../assets/customer_avatar.png';
143
146
  import { shallowCopyMessage } from '../../../../utils/utils';
144
147
  import { isPC,isH5 } from '../../../../utils/env';
148
+ import { JSONToObject } from '../../../../utils/index';
149
+ import state from '../../../../utils/state.js';
145
150
  import { CUSTOM_MESSAGE_SRC } from '../../../../constant';
151
+ import FeedbackButton from './feedback-button.vue';
152
+ import { ReadState } from '../../../../constant';
146
153
  const { computed, toRefs } = vue;
147
154
 
148
155
  interface IProps {
@@ -182,7 +189,17 @@ const needLoadingIconMessageType = [
182
189
  ];
183
190
 
184
191
  const { blinkMessageIDList, messageItem: message } = toRefs(props);
185
-
192
+ const {
193
+ showAvatar,
194
+ showNickName,
195
+ robotAvatar,
196
+ staffAvatar,
197
+ userAvatar,
198
+ robotNickName,
199
+ staffNickName,
200
+ userNickName,
201
+ } = state.get('avatarNickName');
202
+ let prevStatus = ReadState.Unread;
186
203
  const isDisplayUnplayMark = computed<boolean>(() => {
187
204
  return (
188
205
  message.value.flow === 'in'
@@ -213,6 +230,43 @@ const isMultiBranchMsg = computed(()=>{
213
230
  return false;
214
231
  });
215
232
 
233
+ function isFromRobot(cloudCustomData: string) {
234
+ try {
235
+ const jsonObj = JSONToObject(cloudCustomData);
236
+ return jsonObj.hasOwnProperty("role") && jsonObj.role === "robot";
237
+ } catch (e) {
238
+ return false;
239
+ }
240
+ }
241
+
242
+ const avatarUrl = computed(() => {
243
+ let url = '';
244
+ if (message.value?.flow === 'in') {
245
+ if (isFromRobot(message.value?.cloudCustomData)) {
246
+ url = robotAvatar || customerAvatar;
247
+ } else {
248
+ url = staffAvatar || message.value?.avatar;
249
+ }
250
+ } else {
251
+ url = userAvatar || message.value?.avatar || '';
252
+ }
253
+ return url;
254
+ });
255
+
256
+ const nickName = computed(() => {
257
+ let nick = '';
258
+ if (message.value?.flow === 'in') {
259
+ if (isFromRobot(message.value?.cloudCustomData)) {
260
+ nick = robotNickName || props.content.showName;
261
+ } else {
262
+ nick = staffNickName || props.content.showName;
263
+ }
264
+ } else {
265
+ nick = userNickName || props.content.showName;
266
+ }
267
+ return nick;
268
+ });
269
+
216
270
  const isProductCardOrOrderMessage = computed(() => {
217
271
  if (message.value?.type == "TIMCustomElem") {
218
272
  const src = JSON.parse(message.value.payload.data).src;
@@ -266,6 +320,10 @@ function blinkMessage(messageID: string) {
266
320
  function scrollTo(scrollHeight: number) {
267
321
  emits('scrollTo', scrollHeight);
268
322
  }
323
+
324
+ function setStatus(status: ReadState) {
325
+ prevStatus = status;
326
+ }
269
327
  </script>
270
328
 
271
329
  <style lang="scss" scoped>
@@ -277,7 +335,7 @@ function scrollTo(scrollHeight: number) {
277
335
  }
278
336
 
279
337
  .message-bubble {
280
- padding: 10px 15px;
338
+ padding: 10px 5px;
281
339
  display: flex;
282
340
  flex-direction: row;
283
341
  user-select: none;
@@ -360,12 +418,12 @@ function scrollTo(scrollHeight: number) {
360
418
  flex-direction: column;
361
419
  min-width: 0;
362
420
  box-sizing: border-box;
363
- padding: 16px;
421
+ padding: 8px 16px;
364
422
  font-size: 14px;
365
423
  color: #000;
366
424
  letter-spacing: 0;
367
- word-wrap: break-word;
368
- word-break: break-all;
425
+ overflow-wrap: break-word;
426
+ word-break: normal;
369
427
  position: relative;
370
428
 
371
429
  .content-main {
@@ -398,7 +456,7 @@ function scrollTo(scrollHeight: number) {
398
456
 
399
457
  .content-in {
400
458
  background: #f3f4f7;
401
- border-radius: 0 10px 10px;
459
+ border-radius: 0 8px 8px;
402
460
  }
403
461
 
404
462
  .body-mobile {
@@ -407,7 +465,7 @@ function scrollTo(scrollHeight: number) {
407
465
 
408
466
  .multi-branch-message {
409
467
  background-color: transparent;
410
- border-radius: 0 10px 10px;
468
+ border-radius: 0 8px 8px;
411
469
  padding: 0px;
412
470
  }
413
471
 
@@ -422,7 +480,7 @@ function scrollTo(scrollHeight: number) {
422
480
  .content-out {
423
481
  background: linear-gradient(26deg, #1C66E5 2.07%, #03C8FD 152.75%);
424
482
  color:#fff;
425
- border-radius: 10px 0 10px 10px;
483
+ border-radius: 8px 0 8px 8px;
426
484
  }
427
485
 
428
486
  .content-no-padding {
@@ -454,7 +512,10 @@ function scrollTo(scrollHeight: number) {
454
512
  .blink-content {
455
513
  @keyframes reference-blink {
456
514
  50% {
457
- background-color: #ff9c19;
515
+ // 消息气泡的底色是渐变色,实际是 background-image,background-image 优先级高于 background-color
516
+ // 所以这里如果设置 background-color,动画将不会生效
517
+ // 闪烁时背景不渐变
518
+ background: linear-gradient(90deg, #ff9c19, #ff9c19);
458
519
  }
459
520
  }
460
521
 
@@ -504,6 +565,11 @@ function scrollTo(scrollHeight: number) {
504
565
  align-self: flex-end;
505
566
  }
506
567
  }
568
+ .message-bubble-feedback-button {
569
+ display: flex;
570
+ flex-direction: row;
571
+ margin-top: 8px;
572
+ }
507
573
  }
508
574
  }
509
575
 
@@ -1,4 +1,5 @@
1
1
  import {Marked} from 'marked';
2
+ import Log from '../../../../../../utils/logger';
2
3
 
3
4
  export const marked = new Marked(
4
5
  {mangle: false, headerIds: false},
@@ -7,19 +8,25 @@ export const marked = new Marked(
7
8
  image(this: any, href: string | null, title: string | null, text: string) {
8
9
  const safeHref = encodeURIComponent(href || '');
9
10
  return `<div
10
- class="image-container"
11
- onclick="onMarkdownImageClicked('${safeHref}')"
12
- style="cursor:pointer;" >
13
- <img src="${href}" alt="${text}" onload="onMarkdownImageLoad()"/>
14
- </div>
15
- `;
11
+ class="image-container"
12
+ onclick="onMarkdownImageClicked('${safeHref}')"
13
+ style="cursor:pointer;" >
14
+ <img src="${href}" alt="${text}" onload="onMarkdownImageLoad()"/>
15
+ </div>
16
+ `;
16
17
  },
17
18
  link(this: any, href: string | null, title: string | null, text: string) {
18
- // a 标签 href 如果异常(包含非 ASCII 字符),则当成普通文本处理
19
- if (href && /[^\x00-\x7F]/g.test(href)) {
20
- return text;
19
+ if (href) {
20
+ // 匹配以 http:// https:// 开头,所有 URL 主体字符,遇到第一个非主体字符(如中文括号、空格、表情符号等)时停止
21
+ let ret = href.replace(/https?:\/\/[\w\-./?=&:#]+(?=[^\w\-./?=&:#]|$)/g, (matchedUrl) => {
22
+ return `<a target="_blank" rel="noreferrer noopenner" class="message-marked_link" href="${matchedUrl || ''}" title="${title}">${matchedUrl}</a>`;
23
+ });
24
+ if (ret === href) {
25
+ Log.w(`Unable to extract url, href:${href}`);
26
+ }
27
+ return ret;
21
28
  }
22
- return `<a target="_blank" rel="noreferrer noopenner" class="message-marked_link" href="${href || ''}" title="${title}">${text}</a>`;
29
+ return text;
23
30
  },
24
31
  },
25
32
  },
@@ -5,7 +5,9 @@
5
5
  :class="['branch-body',isPC ? 'branch-bubble':'branch-bubble-h5']"
6
6
  >
7
7
  <Icon :src="iconQuestion" class="branch-title-icon"/>
8
- {{ content.header || content.title }}
8
+ <div class="branch-title-text">
9
+ {{ content.header || content.title }}
10
+ </div>
9
11
  </div>
10
12
  <div
11
13
  v-for="(item, index) in content.items"
@@ -91,14 +93,15 @@ export default {
91
93
  display: flex;
92
94
  min-width: 0;
93
95
  box-sizing: border-box;
94
- padding: 12px 14px;
96
+ padding: 8px 16px;
95
97
  font-size: 14px;
96
98
  color: #000;
97
99
  letter-spacing: 0;
98
- word-wrap: break-word;
99
- word-break: break-all;
100
+ overflow-wrap: break-word;
101
+ word-break: normal;
100
102
  position: relative;
101
-
103
+ width: 100%;
104
+ max-width: fit-content;
102
105
  .branch-main {
103
106
  box-sizing: border-box;
104
107
  display: flex;
@@ -122,8 +125,9 @@ export default {
122
125
  margin-bottom: 8px;
123
126
  }
124
127
  .branch-item {
125
- color:#1c66e5;
128
+ color: #1c66e5;
126
129
  cursor: pointer;
130
+ display: inline-block;
127
131
  }
128
132
  .warning-item {
129
133
  color: #ff9800;
@@ -131,18 +135,22 @@ export default {
131
135
  .branch-card {
132
136
  min-width: 250px;
133
137
  max-width: 350px;
134
- display:flex;
135
- flex-direction:column;
138
+ display: flex;
139
+ flex-direction: column;
136
140
  align-items: flex-start;
137
141
  }
138
142
  .branch-item-selected {
139
- cursor:none;
143
+ cursor: default;
140
144
  color: #a0a7b8;
141
- opacity:0.6;
145
+ opacity: 0.6;
142
146
  }
143
147
  .branch-title-icon {
144
148
  margin-right: 5px;
145
149
  align-items: flex-start !important;
146
150
  margin-top: 2px;
147
151
  }
152
+ .branch-title-text {
153
+ display: inline-block;
154
+ min-width: 0;
155
+ }
148
156
  </style>
@@ -26,7 +26,7 @@ import {TUITranslateService} from "@tencentcloud/chat-uikit-engine";
26
26
  text-size-adjust: none;
27
27
  font-family: PingFangSC-Regular;
28
28
  overflow-wrap: break-word;
29
- word-break: break-all;
29
+ word-break: normal;
30
30
  }
31
31
 
32
32
  .text:lang(en) {
@@ -79,9 +79,10 @@ import { CustomMessagePayload, TextMessagePayload, customerServicePayloadType }
79
79
  import MessageRating from './message-rating/index.vue';
80
80
  import vue from '../../../../../../adapter-vue';
81
81
  import { JSONToObject } from '../../../../../../utils/index';
82
+ import { isEnabledMessageReadReceiptGlobal } from '../../../../../../utils/utils';
82
83
  import { CUSTOM_MESSAGE_SRC } from '../../../../../../constant';
83
84
  import MessageBranch from './message-branch.vue';
84
- import MessageForm from './message-single-form/index.vue';
85
+ import MessageForm from './message-ivr-form/index.vue';
85
86
  import MessageIMRobotWelcome from './message-robot-welcome.vue';
86
87
  import MessageProductCard from './message-product-card.vue';
87
88
  import MessageRichText from './message-rich-text.vue';
@@ -118,16 +119,22 @@ export default {
118
119
  default: () => ({}),
119
120
  },
120
121
  },
121
- emits: ['showFormPopup', 'heightChanged'],
122
+ emits: ['showFormPopup', 'heightChanged', 'messageSent'],
122
123
  setup(props: Props, { emit }) {
123
124
  const payload = computed<customerServicePayloadType>(() => {
124
125
  return props.message && JSONToObject(props.message?.payload?.data);
125
126
  });
126
- const sendTextMessage = (payload: TextMessagePayload) => {
127
- TUIChatService.sendTextMessage({payload});
127
+ const sendTextMessage = async (payload: TextMessagePayload, cloudCustomData?: string) => {
128
+ await TUIChatService.sendTextMessage({
129
+ payload,
130
+ cloudCustomData: cloudCustomData || '',
131
+ needReadReceipt: isEnabledMessageReadReceiptGlobal()
132
+ });
133
+ emit('messageSent');
128
134
  };
129
- const sendCustomMessage = (payload: CustomMessagePayload) => {
130
- TUIChatService.sendCustomMessage({payload});
135
+ const sendCustomMessage = async (payload: CustomMessagePayload) => {
136
+ await TUIChatService.sendCustomMessage({ payload });
137
+ emit('messageSent');
131
138
  };
132
139
  const handleShowFormPopup = (data: boolean) => {
133
140
  emit('showFormPopup', data);
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <div class="form-branch-container">
3
+ <p
4
+ v-if="props.title"
5
+ class="form-card-title"
6
+ >
7
+ {{ props.title }}
8
+ </p>
9
+ <div
10
+ v-for="(item, index) in props.list"
11
+ :key="index"
12
+ :class="getItemClass(item)"
13
+ @click="listItemClick(item)"
14
+ >
15
+ {{ item.content }}
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script lang="ts">
21
+ import vue from '../../../../../../../adapter-vue';
22
+ const { computed, ref } = vue;
23
+
24
+ interface branchItem {
25
+ content: string;
26
+ desc: string;
27
+ }
28
+
29
+ interface Props {
30
+ title: string;
31
+ list: branchItem[];
32
+ selectedContent: string;
33
+ }
34
+
35
+ export default {
36
+ props: {
37
+ title: {
38
+ type: String,
39
+ default: '',
40
+ },
41
+ list: {
42
+ type: Array,
43
+ default: () => [],
44
+ },
45
+ selectedContent: {
46
+ type: String,
47
+ default: '',
48
+ },
49
+ },
50
+ emits: ['input-click'],
51
+ setup(props: Props, { emit }) {
52
+ const disabled = ref<boolean>(false);
53
+ const selectedItem = ref<string>('');
54
+ const listItemClick = (branch: branchItem): void => {
55
+ if (disabled.value || props.selectedContent) {
56
+ return;
57
+ }
58
+ emit('input-click', branch);
59
+ disabled.value = true;
60
+ selectedItem.value = branch.content;
61
+ };
62
+ const getItemClass = (item: branchItem) => {
63
+ const classes:string[] = [];
64
+ if (props.selectedContent) {
65
+ classes.push(item.content === props.selectedContent ? 'item-selected' : 'item-disabled');
66
+ } else if (disabled.value) {
67
+ classes.push(item.content === selectedItem.value ? 'item-selected' : 'item-disabled');
68
+ }
69
+ classes.push('ivr-form-branch-item');
70
+ return classes;
71
+ };
72
+ return {
73
+ props,
74
+ listItemClick,
75
+ disabled,
76
+ selectedItem,
77
+ getItemClass
78
+ };
79
+ },
80
+ };
81
+ </script>
82
+ <style lang="scss">
83
+ .form-branch-container {
84
+ .form-card-title {
85
+ margin-bottom: 8px;
86
+ }
87
+
88
+ .ivr-form-branch-item {
89
+ cursor: pointer;
90
+ color: #1C66E5;
91
+ background-color: #fff;
92
+ border: 1px solid rgba(0, 110, 255, 0.3);
93
+ padding: 12px;
94
+ border-radius: 20px;
95
+ margin-top: 8px;
96
+ line-height: 16px;
97
+ width: -moz-fit-content;
98
+ max-width: fit-content;
99
+ font-family: PingFangSC-Regular;
100
+ min-width: 50px;
101
+ text-align: center;
102
+ word-wrap: break-word;
103
+ }
104
+ .item-disabled {
105
+ cursor: default !important;
106
+ opacity: 0.6;
107
+ color: #94BFFF;
108
+ background-color: #F5F9FF;
109
+ border: 1px solid rgba(0, 110, 255, 0.15);
110
+ }
111
+ .item-selected {
112
+ background-color: rgba(54, 141, 255, 0.15) !important;
113
+ position: relative;
114
+ cursor: default !important;
115
+ }
116
+ }
117
+ </style>