@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
@@ -3,8 +3,8 @@
3
3
  :iconFile="handleIcon()"
4
4
  :title="handleTitle()"
5
5
  :needDialog="false"
6
- iconWidth='21px'
7
- iconHeight='18px'
6
+ iconWidth='20px'
7
+ iconHeight='20px'
8
8
  @onIconClick="onIconClick"
9
9
  >
10
10
  <div :class="['video-upload', !isPC && 'video-upload-h5']">
@@ -32,8 +32,9 @@ import {
32
32
  import vue from '../../../../adapter-vue';
33
33
  import { isPC } from '../../../../utils/env';
34
34
  import ToolbarItemContainer from '../toolbar-item-container/index.vue';
35
- import videoIcon from '../../../../assets/video.png';
36
- import { isEnabledMessageReadReceiptGlobal } from '../../../../utils/utils';
35
+ import videoIcon from '../../../../assets/video.svg';
36
+ import videoIconH5 from '../../../../assets/video_h5.svg'
37
+ import { isEnabledMessageReadReceiptGlobal, getTo } from '../../../../utils/utils';
37
38
  const { ref } = vue;
38
39
 
39
40
  const props = defineProps({
@@ -56,19 +57,15 @@ TUIStore.watch(StoreName.CONV, {
56
57
  });
57
58
 
58
59
  const handleIcon = (): string => {
59
- return videoIcon;
60
-
60
+ return isPC ? videoIcon : videoIconH5;
61
61
  };
62
62
 
63
63
  const handleTitle = (): string => {
64
-
65
- return '视频';
66
-
64
+ return TUITranslateService.t('视频');
67
65
  };
68
66
 
69
67
  const onIconClick = () => {
70
- inputRef?.value?.click && inputRef?.value?.click();
71
-
68
+ inputRef?.value?.click && inputRef?.value?.click();
72
69
  };
73
70
 
74
71
  const sendVideoInWeb = (e: any) => {
@@ -84,9 +81,7 @@ const sendVideoMessage = (file: any) => {
84
81
  return;
85
82
  }
86
83
  const options = {
87
- to:
88
- currentConversation?.value?.groupProfile?.groupID
89
- || currentConversation?.value?.userProfile?.userID,
84
+ to: getTo(currentConversation?.value),
90
85
  conversationType: currentConversation?.value?.type,
91
86
  payload: {
92
87
  file,
@@ -48,6 +48,7 @@
48
48
  @handleToggleMessageItem="handleToggleMessageItem"
49
49
  @handleH5LongPress="handleH5LongPress"
50
50
  @heightChanged="onHeightChanged"
51
+ @messageSent="onMessageSent"
51
52
  />
52
53
  <div
53
54
  v-else
@@ -217,8 +218,9 @@ import {
217
218
  isEnabledMessageReadReceiptGlobal,
218
219
  deepCopy,
219
220
  } from '../../../utils/utils';
220
- import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime } from '../../../utils/index';
221
+ import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime, JSONToObject } from '../../../utils/index';
221
222
  import { isCustomerConversation } from '../../../index';
223
+ import { CUSTOM_MESSAGE_SRC } from '../../../constant';
222
224
 
223
225
  interface ScrollConfig {
224
226
  scrollToMessage?: IMessageModel;
@@ -290,9 +292,9 @@ onMounted(() => {
290
292
  messageList: onMessageListUpdated,
291
293
  messageSource: onMessageSourceUpdated,
292
294
  isCompleted: isCompletedUpdated,
295
+ newMessageList: onNewMessageList,
293
296
  });
294
297
 
295
-
296
298
  TUIStore.watch(StoreName.CUSTOM, {
297
299
  isShowMessagePopMenu: isShowMessagePopMenuUpdated,
298
300
  });
@@ -329,6 +331,29 @@ onUnmounted(() => {
329
331
  observer = null;
330
332
  });
331
333
 
334
+ function onNewMessageList(list: IMessageModel[]) {
335
+ list.forEach((message:IMessageModel) => {
336
+ if (message?.type === TUIChatEngine.TYPES.MSG_CUSTOM) {
337
+ const data = JSONToObject(message?.payload?.data);
338
+ if (data?.src === CUSTOM_MESSAGE_SRC.SEAT_STATUS) {
339
+ if (data?.content.command === "updateSeatStatus") {
340
+ if (data.content.content === 'inSeat') {
341
+ TUIStore.update(StoreName.CUSTOM, "isInHumanService", true);
342
+ } else if (data.content.content === 'outSeat') {
343
+ TUIStore.update(StoreName.CUSTOM, "isInHumanService", false);
344
+ }
345
+ }
346
+ } else if (data?.src === CUSTOM_MESSAGE_SRC.TYPING_STATE) {
347
+ if (data?.typingStatus === 1) {
348
+ TUIStore.update(StoreName.CUSTOM, 'isTyping', true);
349
+ } else {
350
+ TUIStore.update(StoreName.CUSTOM, 'isTyping', false);
351
+ }
352
+ }
353
+ }
354
+ });
355
+ }
356
+
332
357
  async function onMessageListUpdated(list: IMessageModel[]) {
333
358
  if (!isCustomerConversation(currentConversationID.value)) {
334
359
  return;
@@ -370,7 +395,6 @@ async function onMessageListUpdated(list: IMessageModel[]) {
370
395
  await scrollToPosition({
371
396
  scrollToOffset: { bottom: beforeHistoryGetScrollHeight.value },
372
397
  });
373
- beforeHistoryGetScrollHeight.value = 0;
374
398
  } else if (
375
399
  scrollButtonInstanceRef.value?.isScrollButtonVisible
376
400
  && newLastMessage?.flow === 'in'
@@ -425,8 +449,7 @@ async function scrollToPosition(config: ScrollConfig = {}): Promise<void> {
425
449
  if (config.scrollToOffset?.top) {
426
450
  container!.scrollTop = config.scrollToOffset.top;
427
451
  } else if (config.scrollToOffset?.bottom) {
428
- container!.scrollTop
429
- = container!.scrollHeight - config.scrollToOffset.bottom;
452
+ container!.scrollTop = container!.scrollHeight - config.scrollToOffset.bottom;
430
453
  }
431
454
  }
432
455
  resolve();
@@ -574,6 +597,15 @@ const handleH5LongPress = (e: any, message: IMessageModel, type: string) => {
574
597
  };
575
598
 
576
599
  function onHeightChanged() {
600
+ // 如果 view more 导致了子组件派发了 heightChanged 事件,不滚动到最底部,保留原来的滚动位置
601
+ if (beforeHistoryGetScrollHeight.value > 0) {
602
+ return;
603
+ }
604
+
605
+ scrollToLatestMessage();
606
+ }
607
+
608
+ function onMessageSent() {
577
609
  scrollToLatestMessage();
578
610
  }
579
611
 
@@ -617,6 +649,7 @@ async function scrollToLatestMessage() {
617
649
  messageListRef.value.scrollTop = scrollHeight - height;
618
650
  }
619
651
  scrollButtonInstanceRef.value?.hideScrollButton();
652
+ beforeHistoryGetScrollHeight.value = 0;
620
653
  }
621
654
 
622
655
  const handelScrollListScroll = throttle(
@@ -709,7 +742,6 @@ function setAudioPlayed(messageID: string) {
709
742
  };
710
743
  }
711
744
 
712
-
713
745
  defineExpose({
714
746
  scrollToLatestMessage,
715
747
  });
@@ -0,0 +1,369 @@
1
+ <template>
2
+ <div>
3
+ <div class="feedback-container">
4
+ <div
5
+ class="feedback-like"
6
+ @mouseenter="isFeedbackLikeHover = true"
7
+ @mouseleave="isFeedbackLikeHover = false"
8
+ @click="feedbackLikeClick"
9
+ >
10
+ <Icon :file="feedbackLikeIcon" width="16px" height="16px"/>
11
+ <div
12
+ class="tooltip"
13
+ >
14
+ {{ TUITranslateService.t("AIDesk.满意") }}
15
+ <div class="tooltip-arrow"></div>
16
+ </div>
17
+ </div>
18
+ <span class="divider"></span>
19
+ <div
20
+ class="feedback-dislike"
21
+ @mouseenter="isFeedbackDislikeHover = true"
22
+ @mouseleave="isFeedbackDislikeHover = false"
23
+ @click="feedbackDislikeClick"
24
+ >
25
+ <Icon :file="feedbackDislikeIcon" width="16px" height="16px" @click="dislickClick"/>
26
+ <div
27
+ class="tooltip"
28
+ >
29
+ {{ TUITranslateService.t("AIDesk.不满意") }}
30
+ <div class="tooltip-arrow"></div>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div v-if="showDialog" class="feedback-dialog">
35
+ <div class="feedback-dialog-main">
36
+ <div class="feedback-dialog-header">
37
+ <div class="dialog-header-content">
38
+ <Icon :file="GreenCheck" width="24px" height="24px"/>
39
+ <span class="dialog-header-title">
40
+ {{ TUITranslateService.t("AIDesk.感谢您的反馈,我们会持续优化改进") }}
41
+ </span>
42
+ </div>
43
+ <Icon :file="DialogCloseIcon" width="24px" height="24px" @click="closeDialog"/>
44
+ </div>
45
+
46
+ <div class="dialog-select">
47
+ <span class="dialog-session-title">
48
+ {{ TUITranslateService.t("AIDesk.您遇到了哪方面的问题") }}
49
+ </span>
50
+ <div class="dialog-button-list">
51
+ <div class="dialog-button-row" v-for="(item) in feedbackButton">
52
+ <div :class="['dialog-button',item.isSelected ? 'dialog-button-selected': '']" @click="dialogButtonClick(item)">
53
+ {{ TUITranslateService.t(`AIDesk.${item.text}`) }}
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
58
+
59
+ <div class="dialog-other">
60
+ <span class="dialog-session-title">
61
+ {{ TUITranslateService.t("AIDesk.其他反馈内容") }}
62
+ </span>
63
+ <textarea type="text" :placeholder="TUITranslateService.t('AIDesk.请输入内容')" v-model="feedbackText" class="dialog-other-input"/>
64
+ </div>
65
+ <div class="dialog-foot">
66
+ <div class="dialog-submit" @click="submitBadFeeback">
67
+ {{ TUITranslateService.t("AIDesk.提交") }}
68
+ </div>
69
+ <div class="dialog-cancel" @click="closeDialog">
70
+ {{ TUITranslateService.t("AIDesk.取消") }}
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </template>
77
+ <script lang="ts">
78
+ import vue from '../../../../adapter-vue';
79
+ import Icon from '../../../common/Icon.vue';
80
+ import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
81
+ import FeedbackLikeBefore from '../../../../assets/feedback_like_before.svg';
82
+ import FeedbackLikeAfter from '../../../../assets/feedback_like_after.svg';
83
+ import FeedbackLikeHover from '../../../../assets/feedback_like_hover.svg';
84
+ import FeedbackDislikeBefore from '../../../../assets/feedback_dislike_before.svg';
85
+ import FeedbackDislikeAfter from '../../../../assets/feedback_dislike_after.svg';
86
+ import FeedbackDislikeHover from '../../../../assets/feedback_dislike_hover.svg';
87
+ import GreenCheck from '../../../../assets/green_check.svg';
88
+ import DialogCloseIcon from '../../../../assets/feedback_dialog_close.svg';
89
+ const { ref,computed } = vue;
90
+
91
+ export default {
92
+ components:{
93
+ Icon
94
+ },
95
+ setup(){
96
+ const isFeedbackLikeHover = ref(false);
97
+ const isFeedbackLikeClick = ref(false);
98
+ const isFeedbackDislikeHover = ref(false);
99
+ const isFeedbackDislikeClick = ref(false);
100
+ const showDialog = ref(false);
101
+ const feedbackText = ref('');
102
+ const feedbackButton = ref([
103
+ { id:'nonResponsiveAnswer', text: '答非所问', isSelected: false },
104
+ { id:'unmatchedContentRetrieval', text: '未匹配相关内容', isSelected: false },
105
+ { id:'incorrectInfoAnswer', text: '信息错误', isSelected: false },
106
+ { id:'contextMisunderstandingQuery', text: '上下文理解错误', isSelected: false },
107
+ { id:'nonStandardFormatAnswer', text: '格式不规范', isSelected: false },
108
+ { id:'incompleteContentRetrieval', text: '内容不完整', isSelected: false },
109
+ ]);
110
+ const feedbackReply = {
111
+ isSupport:1, //1:点赞。0:点踩
112
+ nonResponsiveAnswer:0, // 是否答非所问
113
+ incorrectInfoAnswer:0, // 是否信息错误
114
+ nonStandardFormatAnswer:0, // 是否信息不规范
115
+ incompleteContentRetrieval:0, // 是否回答不完整
116
+ unmatchedContentRetrieval:0, // 是否信息不匹配
117
+ contextMisunderstandingQuery:0, //是否上下文理解错误
118
+ feedbackText:"" //文字反馈
119
+ };
120
+ const feedbackLikeIcon = computed(() => {
121
+ if (isFeedbackLikeClick.value) {
122
+ return FeedbackLikeAfter;
123
+ } else if (isFeedbackLikeHover.value) {
124
+ return FeedbackLikeHover;
125
+ } else {
126
+ return FeedbackLikeBefore;
127
+ }
128
+ });
129
+ const feedbackLikeClick = () => {
130
+ isFeedbackLikeClick.value = !isFeedbackLikeClick.value;
131
+ if(isFeedbackLikeClick.value){
132
+ isFeedbackDislikeClick.value = false;
133
+ feedbackReply.isSupport = 1;
134
+ }
135
+ resetFeedback();
136
+ }
137
+ const feedbackDislikeIcon = computed(() => {
138
+ if (isFeedbackDislikeClick.value) {
139
+ return FeedbackDislikeAfter;
140
+ } else if (isFeedbackDislikeHover.value) {
141
+ return FeedbackDislikeHover;
142
+ } else {
143
+ return FeedbackDislikeBefore;
144
+ }
145
+ });
146
+ const dialogButtonClick = (item) => {
147
+ item.isSelected = !item.isSelected;
148
+ }
149
+ const feedbackDislikeClick = () => {
150
+ isFeedbackDislikeClick.value = true;
151
+ if(isFeedbackDislikeClick.value){
152
+ isFeedbackLikeClick.value = false;
153
+ }
154
+ }
155
+ const dislickClick = () => {
156
+ showDialog.value = true;
157
+ }
158
+ const closeDialog = () => {
159
+ isFeedbackDislikeClick.value = false;
160
+ showDialog.value = false;
161
+ resetFeedback();
162
+ }
163
+ const resetFeedback = () => {
164
+ feedbackButton.value.forEach(item => {
165
+ item.isSelected = false;
166
+ });
167
+ feedbackText.value = "";
168
+ }
169
+ const submitBadFeeback = () => {
170
+ feedbackReply.isSupport = 0;
171
+ feedbackButton.value.forEach(item => {
172
+ feedbackReply[item.id] = item.isSelected ? 1 : 0;
173
+ feedbackReply.feedbackText = feedbackText.value;
174
+ });
175
+ }
176
+
177
+ return {
178
+ feedbackLikeIcon,
179
+ isFeedbackLikeHover,
180
+ feedbackLikeClick,
181
+ isFeedbackDislikeHover,
182
+ feedbackDislikeIcon,
183
+ feedbackDislikeClick,
184
+ GreenCheck,
185
+ DialogCloseIcon,
186
+ feedbackButton,
187
+ showDialog,
188
+ closeDialog,
189
+ dislickClick,
190
+ feedbackText,
191
+ dialogButtonClick,
192
+ TUITranslateService,
193
+ submitBadFeeback
194
+ };
195
+ }
196
+ }
197
+ </script>
198
+ <style lang="scss">
199
+ .feedback-container {
200
+ display: flex;
201
+ flex-direction: row !important;
202
+ padding: 4px 10px;
203
+ align-items: center;
204
+ gap: 10px;
205
+ border-radius: 8px;
206
+ border: 1px solid var(---G61, #DBE1EB);
207
+ .feedback-like, .feedback-dislike {
208
+ position: relative;
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ cursor: pointer;
213
+ &:hover .tooltip {
214
+ display: block;
215
+ }
216
+ }
217
+ .divider {
218
+ width: 1px;
219
+ height: 14px;
220
+ background-color: rgba(0,0,0,0.05);
221
+ }
222
+ }
223
+ .feedback-dialog {
224
+ position: fixed;
225
+ top: 0;
226
+ left: 0;
227
+ right: 0;
228
+ bottom: 0;
229
+ background: rgba(13, 17, 26, 0.4);
230
+ z-index: 1000;
231
+ display: flex;
232
+ justify-content: center;
233
+ align-items: center;
234
+ font-family: PingFangSC-Regular;
235
+ &-main {
236
+ width: 418px;
237
+ min-height: 442px;
238
+ background: white;
239
+ border-radius: 16px;
240
+ padding: 30px;
241
+ overflow: hidden;
242
+
243
+ .feedback-dialog-header {
244
+ display: flex;
245
+ justify-content: space-between;
246
+ .dialog-header-content {
247
+ display: flex;
248
+ gap: 8px;
249
+ align-items: center;
250
+ .dialog-header-title {
251
+ font-weight: 600;
252
+
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+ .dialog-session-title {
259
+ color: #4F586B;
260
+ font-size: 14px;
261
+ }
262
+ .dialog-select {
263
+ margin-top: 30px;
264
+ .dialog-button-list {
265
+ display: flex;
266
+ flex-wrap: wrap;
267
+ justify-content: center;
268
+ align-items: center;
269
+ gap: 8px;
270
+ margin-top: 10px;
271
+ .dialog-button-row {
272
+ flex: 0 0 49%;
273
+ .dialog-button {
274
+ border-radius: 8px;
275
+ border: 1px solid #E4E8EE;
276
+ background: #F9FAFC;
277
+ padding: 10px 16px;
278
+ display: flex;
279
+ justify-content: center;
280
+ font-size: 12px;
281
+ color: #0f1014;
282
+ cursor: pointer;
283
+ text-align: center;
284
+ align-items: center;
285
+ &-selected {
286
+ border-radius: 8px;
287
+ border: 1px solid #1C66E5;
288
+ background: rgba(28, 102, 229, 0.10);
289
+ color: #0052d9;
290
+ }
291
+ }
292
+ }
293
+
294
+ }
295
+ }
296
+ .dialog-other {
297
+ margin: 20px 0 10px 0;
298
+ display: flex;
299
+ flex-direction: column;
300
+ gap: 10px;
301
+ .dialog-other-input {
302
+ border-radius: 12px;
303
+ border: 1px solid #E4E8EE;
304
+ background: #F9FAFC;
305
+ height: 102px;
306
+ padding: 10px 16px;
307
+ display: flex;
308
+ align-items: flex-start;
309
+ align-self: stretch;
310
+ resize: none;
311
+ &::placeholder {
312
+ color: #929CB2;
313
+ font-size: 14px;
314
+ }
315
+ }
316
+ }
317
+ .dialog-foot {
318
+ width: 100%;
319
+ display: flex;
320
+ margin-top: 30px;
321
+ gap: 10px;
322
+ justify-content: center;
323
+ .dialog-submit {
324
+ padding: 9px 33px;
325
+ border-radius: 20px;
326
+ background: #1C66E5;
327
+ font-weight: 600;
328
+ color: #fff;
329
+ cursor: pointer;
330
+ }
331
+ .dialog-cancel {
332
+ padding: 9px 33px;
333
+ border-radius: 20px;
334
+ border: 1px solid #1C66E5;
335
+ font-weight: 600;
336
+ color: #1C66E5;
337
+ cursor: pointer;
338
+ }
339
+ }
340
+
341
+ .tooltip {
342
+ position: absolute;
343
+ z-index: 100;
344
+ font-size: 14px;
345
+ bottom: calc(100% + 13px);
346
+ left: 50%;
347
+ transform: translateX(-50%);
348
+ background: #fff;
349
+ color: #000;
350
+ padding: 8px 16px;
351
+ border-radius: 6px;
352
+ box-shadow: var(--shadow-md-offsetx-1, 0px) var(--shadow-md-offsety-1, 8px) var(--shadow-md-blur-1, 12px) var(--shadow-md-spread-1, -8px) var(--shadow-md-color-1, rgba(0, 0, 0, 0.05)), var(--shadow-md-offsetx-2, 0px) var(--shadow-md-offsety-2, 8px) var(--shadow-md-blur-2, 24px) var(--shadow-md-spread-2, -4px) var(--shadow-md-color-2, rgba(0, 0, 0, 0.10));
353
+ text-align: center;
354
+ display: none;
355
+ white-space: nowrap;
356
+
357
+ &-arrow {
358
+ position: absolute;
359
+ bottom: -8px;
360
+ left: 50%;
361
+ transform: translateX(-50%);
362
+ width: 0;
363
+ height: 0;
364
+ border-left: 8px solid transparent;
365
+ border-right: 8px solid transparent;
366
+ border-top: 8px solid #fff;
367
+ }
368
+ }
369
+ </style>