@subiz/widget-v4 4.1.120 → 4.1.122

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 (44) hide show
  1. package/assets/less/avatar.less +0 -29
  2. package/assets/less/chatbox.less +7 -10
  3. package/assets/less/form.less +26 -9
  4. package/assets/less/message.less +7 -7
  5. package/assets/less/message_input.less +2 -3
  6. package/assets/less/widget.less +5 -11
  7. package/assets/less/widget_header.less +18 -16
  8. package/compiled_src/chatbox/AgentsAvatar.js +2 -2
  9. package/compiled_src/chatbox/Event.js +1 -1
  10. package/compiled_src/chatbox/Events.js +5 -2
  11. package/compiled_src/chatbox/Header.js +2 -7
  12. package/compiled_src/chatbox/TextMessage.js +1 -0
  13. package/compiled_src/chatbox/Widget.js +55 -42
  14. package/compiled_src/lib.js +0 -5
  15. package/compiled_src/util/common.js +2 -2
  16. package/dist/{19641cfa41e.278.js → 19643345ab6.278.js} +1 -1
  17. package/dist/{19641cfa41e.app.js → 19643345ab6.app.js} +1 -1
  18. package/dist/{19641cfa41e.index.html → 19643345ab6.index.html} +1 -1
  19. package/dist/{19641cfa41e.library.html → 19643345ab6.library.html} +1 -1
  20. package/dist/{19641cfa41e.library.js → 19643345ab6.library.js} +1 -1
  21. package/dist/{19641cfa41e.preview.html → 19643345ab6.preview.html} +1 -1
  22. package/dist/{19641cfa41e.preview.js → 19643345ab6.preview.js} +1 -1
  23. package/dist/{19641cfa41e.webview.js → 19643345ab6.webview.js} +1 -1
  24. package/dist/278.js +1 -1
  25. package/dist/HASH +1 -1
  26. package/dist/screenshoot.js +55 -33
  27. package/package.json +2 -2
  28. package/src/chatbox/AgentsAvatar.js +3 -2
  29. package/src/chatbox/Event.js +1 -1
  30. package/src/chatbox/Events.js +5 -2
  31. package/src/chatbox/Header.js +2 -3
  32. package/src/chatbox/TextMessage.js +1 -0
  33. package/src/chatbox/Widget.js +52 -43
  34. package/src/lib.js +2 -0
  35. package/src/util/common.js +2 -2
  36. package/up +3 -6
  37. /package/dist/{19641cfa41e.127.js → 19643345ab6.127.js} +0 -0
  38. /package/dist/{19641cfa41e.132.js → 19643345ab6.132.js} +0 -0
  39. /package/dist/{19641cfa41e.185.js → 19643345ab6.185.js} +0 -0
  40. /package/dist/{19641cfa41e.27.js → 19643345ab6.27.js} +0 -0
  41. /package/dist/{19641cfa41e.459.js → 19643345ab6.459.js} +0 -0
  42. /package/dist/{19641cfa41e.490.js → 19643345ab6.490.js} +0 -0
  43. /package/dist/{19641cfa41e.74.js → 19643345ab6.74.js} +0 -0
  44. /package/dist/{19641cfa41e.997.js → 19643345ab6.997.js} +0 -0
@@ -24,18 +24,6 @@
24
24
  border-radius: 35px;
25
25
  }
26
26
 
27
- .group-avatar--member {
28
- align-self: center;
29
- width: 65px;
30
- }
31
-
32
- .group-avatar--member .avatar {
33
- position: relative;
34
- width: 35px;
35
- height: 35px;
36
- border-radius: 35px;
37
- }
38
-
39
27
  .group-avatar--primary .group-avatar--agent-middle {
40
28
  width: 50px;
41
29
  height: 50px;
@@ -70,20 +58,3 @@
70
58
  z-index: 1;
71
59
  margin-left: -15px;
72
60
  }
73
-
74
- .group-avatar--member .group-avatar--agent-left {
75
- border: 2px solid @white;
76
- z-index: 3;
77
- }
78
-
79
- .group-avatar--member .group-avatar--agent-middle {
80
- border: 2px solid @white;
81
- z-index: 2;
82
- margin-left: -20px;
83
- }
84
-
85
- .group-avatar--member .group-avatar--agent-right {
86
- border: 2px solid @white;
87
- z-index: 1;
88
- margin-left: -20px;
89
- }
@@ -31,13 +31,13 @@
31
31
  @widget-position: '@widget_position';
32
32
 
33
33
  @spacer: 15px;
34
- @spacer1: @spacer * 0.25; // 3.75px
35
- @spacer2: @spacer * 0.5; // 7.5px
36
- @spacer3: @spacer; // 15px;
37
- @spacer4: @spacer * 1.5; // 22.5px
34
+ @spacer1: @spacer * 0.5; // 3.75px
35
+ @spacer2: @spacer * 1; // 7.5px
36
+ @spacer3: @spacer * 1.5; // 15px;
37
+ @spacer4: @spacer * 2; // 22.5px
38
38
 
39
- @font-family-sans-serif: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial,
40
- sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
39
+ @font-family-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif,
40
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
41
41
 
42
42
  @font-size-base: 16px; // Assumes the browser default, typically `16px`
43
43
 
@@ -155,7 +155,6 @@ body div#sbz92 {
155
155
  .ml-1 {
156
156
  margin-left: @spacer1;
157
157
  }
158
-
159
158
  .pl-2 {
160
159
  padding-left: @spacer2;
161
160
  }
@@ -168,7 +167,6 @@ body div#sbz92 {
168
167
  .mt-1 {
169
168
  margin-top: @spacer1;
170
169
  }
171
-
172
170
  .mt-2 {
173
171
  margin-top: @spacer2;
174
172
  }
@@ -178,7 +176,6 @@ body div#sbz92 {
178
176
  .mr-2 {
179
177
  margin-right: @spacer2;
180
178
  }
181
-
182
179
  .pt-3 {
183
180
  padding-top: @spacer3;
184
181
  }
@@ -245,7 +242,7 @@ body div#sbz92 {
245
242
  justify-content: center;
246
243
  display: flex;
247
244
  flex-direction: column;
248
- background: white
245
+ background: white;
249
246
  }
250
247
 
251
248
  @import 'avatar.less';
@@ -38,6 +38,8 @@ input.form-control[disabled] {
38
38
 
39
39
  .form-control--valid-input--error {
40
40
  .color(@red);
41
+ font-size: 14px;
42
+ padding-top: 5px;
41
43
  }
42
44
 
43
45
  input[type='text'].form-control.input--error,
@@ -45,7 +47,8 @@ input[type='number'].form-control.input--error,
45
47
  input[type='date'].form-control.input--error,
46
48
  textarea.form-control.input--error,
47
49
  select.form-control.input--error {
48
- border: 1px solid red;
50
+ border: 1px solid @red;
51
+ background: #dd41500f;
49
52
  }
50
53
 
51
54
  input[type='text'].form-control,
@@ -55,12 +58,16 @@ textarea.form-control,
55
58
  select.form-control {
56
59
  width: 100%;
57
60
 
58
- border: 1px solid #d8d8d8;
59
- border-radius: 5px;
60
-
61
- padding: 8px;
61
+ border: 1px solid @gray-400;
62
+ border-radius: 8px;
63
+ transition: all 100ms ease;
64
+ padding: 10px 12px;
62
65
  &:hover {
63
- border: 1px solid #888;
66
+ border: 1px solid @gray-600;
67
+ }
68
+
69
+ &.input--error:hover {
70
+ border: 1px solid @red;
64
71
  }
65
72
  }
66
73
 
@@ -76,11 +83,21 @@ select.form-control:focus {
76
83
  border: 1px solid @primary-color;
77
84
  }
78
85
 
86
+ input[type='text'].form-control.input--error:focus,
87
+ input[type='number'].form-control.input--error:focus,
88
+ input[type='date'].form-control.input--error:focus,
89
+ textarea.form-control.input--error:focus,
90
+ select.form-control.input--error:focus {
91
+ border: 1px solid @red;
92
+ }
93
+
79
94
  .label {
80
95
  display: block;
81
- margin-bottom: 3px;
82
- margin-top: 10px;
83
- opacity: 0.7;
96
+ padding-bottom: 6px;
97
+ margin-top: 14px;
98
+ .color(@gray-600);
99
+ font-size: 14px;
100
+ font-weight: 500;
84
101
  }
85
102
 
86
103
  .form--btn-submit {
@@ -4,8 +4,8 @@
4
4
  display: flex;
5
5
  flex-direction: column;
6
6
  flex: 1;
7
- padding-left: 15px;
8
- padding-right: 15px;
7
+ padding-left: @spacer3;
8
+ padding-right: @spacer3;
9
9
  }
10
10
 
11
11
  .widget-body--events {
@@ -99,6 +99,7 @@
99
99
  }
100
100
 
101
101
  .message-text--user {
102
+ line-height: 1.5;
102
103
  margin: 5px 0 0;
103
104
  display: inline-block;
104
105
  font-weight: 500;
@@ -111,6 +112,7 @@
111
112
  }
112
113
 
113
114
  .message-text--agent {
115
+ line-height: 1.5;
114
116
  white-space: pre-wrap;
115
117
  display: inline-block;
116
118
  background: @primary-color-faded;
@@ -246,7 +248,6 @@ a.message_error {
246
248
  width: 25px;
247
249
  height: 25px;
248
250
  margin-right: 10px;
249
- border: 1px solid @gray-300;
250
251
  }
251
252
 
252
253
  .message-sender-name {
@@ -401,7 +402,7 @@ a.message_error {
401
402
  .agent-message {
402
403
  .url-button-attachment {
403
404
  text-decoration: none;
404
- padding: 10px;
405
+ padding: 10px 18px;
405
406
  display: block;
406
407
  text-align: center;
407
408
  .color(@black);
@@ -415,6 +416,7 @@ a.message_error {
415
416
  .color(@primary-color);
416
417
  border-color: @primary-color;
417
418
  }
419
+ white-space: nowrap;
418
420
  }
419
421
  }
420
422
 
@@ -434,12 +436,9 @@ a.message_error {
434
436
  user-select: none;
435
437
  overflow: hidden;
436
438
  white-space: nowrap;
437
- text-overflow: ellipsis;
438
439
  width: fit-content;
439
- overflow: hidden;
440
440
  font-weight: 500;
441
441
  max-width: 100%;
442
- overflow: hidden;
443
442
  text-overflow: ellipsis;
444
443
  border: 1px solid @black;
445
444
  &:hover {
@@ -447,6 +446,7 @@ a.message_error {
447
446
  .color(@text-color);
448
447
  border-color: @primary-color;
449
448
  }
449
+ transition: all 100ms ease;
450
450
  }
451
451
 
452
452
  .generic-attachment-container {
@@ -3,7 +3,7 @@
3
3
  border-top: 1px solid #e3e3e3;
4
4
  display: flex;
5
5
  flex-direction: row;
6
- padding: 15px;
6
+ padding: @spacer2 @spacer3;
7
7
  }
8
8
 
9
9
  .message-input--disabled {
@@ -83,8 +83,7 @@ textarea[disabled=disabled] {
83
83
 
84
84
  .message-input--preform {
85
85
  justify-content: center;
86
- padding-top: 10px;
87
- padding-bottom: 10px;
86
+ padding: @spacer2 @spacer3;
88
87
  }
89
88
 
90
89
  .btn--preform {
@@ -19,12 +19,11 @@
19
19
  }
20
20
 
21
21
  .convo-list--title {
22
- font-size: 18px;
23
- line-height: 20px;
22
+ font-weight: 500;
24
23
  .color(@black);
25
24
  background: @white;
26
25
  border-bottom: 1px solid #f0f0f0;
27
- padding: @spacer3;
26
+ padding: @spacer2;
28
27
  }
29
28
 
30
29
  .convo-list--container {
@@ -44,8 +43,6 @@
44
43
  }
45
44
 
46
45
  .convo-list--convo-last-info {
47
- font-size: 15px;
48
- line-height: 20px;
49
46
  overflow: hidden;
50
47
  white-space: nowrap;
51
48
  justify-content: center;
@@ -88,19 +85,15 @@
88
85
  text-overflow: ellipsis;
89
86
  white-space: nowrap;
90
87
  overflow: hidden;
91
- font-weight: 500;
92
88
  flex: 1;
93
- margin-right: 20px;
89
+ margin-right: 16px;
94
90
  cursor: pointer;
95
91
  }
96
92
 
97
93
  .convo-list--item {
98
94
  cursor: pointer;
99
95
  border-bottom: 1px solid @primary-color-faded;
100
- padding-left: 10px;
101
- padding-right: 10px;
102
- padding-bottom: 15px;
103
- padding-top: 15px;
96
+ padding: @spacer2;
104
97
  display: flex;
105
98
  flex-direction: row;
106
99
  transition: background 0.15s ease;
@@ -248,6 +241,7 @@
248
241
 
249
242
  .btn--start-convo {
250
243
  border-radius: 7px;
244
+ flex-shrink: 0;
251
245
  display: flex;
252
246
  align-items: center;
253
247
  justify-content: center;
@@ -1,25 +1,26 @@
1
1
  .widget-header {
2
2
  z-index: -1;
3
3
  position: relative;
4
- transition: height 0.2s;
4
+ transition: height 0.2s;
5
5
  border-radius: 15px 15px 0px 0px;
6
6
  background: @background;
7
7
  .color(@text-color);
8
8
  width: 100%;
9
9
 
10
10
  .widget-header--total-unread-convo {
11
- display: none;
12
- margin: 0 10px 10px 0;
11
+ font-size: 13px;
12
+ font-weight: 500;
13
13
  background: #ef000d;
14
- font-weight: 400;
15
14
  display: flex;
16
- border-radius: 5px;
15
+ border-radius: 50%;
17
16
  justify-content: center;
17
+ align-items: center;
18
18
  width: 20px;
19
19
  height: 20px;
20
+ position: absolute;
20
21
  cursor: pointer;
21
- position: relative;
22
- top: 5px;
22
+ right: -8px;
23
+ top: -4px;
23
24
  }
24
25
  }
25
26
 
@@ -29,7 +30,7 @@
29
30
 
30
31
  .widget-header--inner.widget-header--inner--collapsed {
31
32
  height: auto;
32
- padding: 15px;
33
+ padding: @spacer2 @spacer3;
33
34
  position: relative;
34
35
 
35
36
  .widget-header--title {
@@ -58,7 +59,7 @@
58
59
 
59
60
  .widget-header--inner.widget-header--inner--expanded {
60
61
  height: 224px;
61
- padding: 15px;
62
+ padding: @spacer2 @spacer3;
62
63
 
63
64
  .widget-header--top-wrapper {
64
65
  display: flex;
@@ -122,7 +123,7 @@
122
123
  flex: 1;
123
124
  display: flex;
124
125
  flex-direction: column;
125
- margin-left: 10px;
126
+ margin-left: @spacer2;
126
127
  z-index: 1;
127
128
  }
128
129
 
@@ -132,7 +133,9 @@
132
133
  align-items: center;
133
134
  align-self: flex-start;
134
135
 
135
- transition: scale 0.15s ease, filter 0.15s ease;
136
+ transition:
137
+ scale 0.15s ease,
138
+ filter 0.15s ease;
136
139
  filter: brightness(0.95);
137
140
  &:hover {
138
141
  filter: brightness(1.1);
@@ -166,7 +169,9 @@
166
169
 
167
170
  cursor: pointer;
168
171
  scale: 1;
169
- transition: scale 0.15s ease, filter 0.15s ease;
172
+ transition:
173
+ scale 0.15s ease,
174
+ filter 0.15s ease;
170
175
  filter: brightness(0.95);
171
176
  &:hover {
172
177
  filter: brightness(1.1);
@@ -174,12 +179,9 @@
174
179
  }
175
180
  }
176
181
 
177
- .widget-header--has-convo-unred .widget-header--button-back {
178
- width: 20px;
179
- }
180
-
181
182
  .widget-header--wrap-button-back {
182
183
  display: flex;
184
+ position: relative;
183
185
  }
184
186
 
185
187
  .fade-enter-active,
@@ -30,7 +30,7 @@ function AgentsAvatar(props) {
30
30
  }
31
31
  let agentM = props.store.matchAgent('*');
32
32
  var agents = _index.default.map(props.agent_ids, id => agentM[id]);
33
- if (props.agent_ids === undefined || _index.default.size(props.agent_ids) === 0) {
33
+ if (props.agent_ids !== undefined && _index.default.size(props.agent_ids) == 0) {
34
34
  var agids = _index.default.get(accountSetting, 'header.agent_ids', []);
35
35
  agids = _index.default.filter(agids, id => !!agentM[id]);
36
36
  if (agids.length !== 0) {
@@ -40,7 +40,7 @@ function AgentsAvatar(props) {
40
40
  }
41
41
  }
42
42
  agents = _index.default.filter(agents, ag => !!ag);
43
- if (agents.length === 0 || props.agent_ids === undefined || _index.default.size(props.agent_ids) === 0) {
43
+ if (_index.default.size(agents) === 0) {
44
44
  return (0, _preact.h)("div", {
45
45
  class: `group-avatar group-avatar--${mode}`
46
46
  }, (0, _preact.h)("div", {
@@ -315,7 +315,7 @@ class Event extends _common.Com {
315
315
  }
316
316
  let $sender = null;
317
317
  if (this.props.event.mode === 'lead') $sender = (0, _preact.h)("div", {
318
- class: "pt-2"
318
+ class: "pt-3"
319
319
  });
320
320
  let $error = null;
321
321
  if (ev._error && ev.type === 'message_sent') {
@@ -301,7 +301,7 @@ function processEvents(convo, events) {
301
301
  }
302
302
  if (visibleEvent(curEvent.ev)) {
303
303
  let elapsedSec = _index.default.unixSec(curEvent.ev.created) - _index.default.unixSec(lastEvent.ev.created);
304
- if (elapsedSec > 120) curEvent.show_time = true;
304
+ if (elapsedSec > 300) curEvent.show_time = true;
305
305
  }
306
306
  }
307
307
  if (lastAgentEvent) lastAgentEvent.show_time = true;
@@ -326,7 +326,10 @@ function processEvents(convo, events) {
326
326
  }
327
327
  function visibleEvent(ev) {
328
328
  let type = _index.default.get(ev, 'type');
329
- return type === 'message_sent' || type === 'conversation_state_updated';
329
+ if (type === 'message_sent') return true;
330
+ if (type === 'conversation_state_updated') {
331
+ return _index.default.get(ev, 'data.conversation.state') == 'ended';
332
+ }
330
333
  }
331
334
  function isSummited(form) {
332
335
  let fields = _index.default.get(form, 'fields') || [];
@@ -50,12 +50,6 @@ class Header extends _common.Com {
50
50
  class: cls,
51
51
  style: style
52
52
  }, $back, (0, _preact.h)("div", {
53
- class: "mr-2"
54
- }), (0, _preact.h)(_AgentsAvatar.default, {
55
- plugin: this.props.plugin,
56
- store: this.props.store,
57
- mode: "secondary"
58
- }), (0, _preact.h)("div", {
59
53
  class: "widget-header--title-container"
60
54
  }, (0, _preact.h)("div", {
61
55
  class: "widget-header--title"
@@ -147,7 +141,8 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
147
141
  }, (0, _preact.h)(_AgentsAvatar.default, {
148
142
  plugin: this.props.plugin,
149
143
  store: this.props.store,
150
- mode: "primary"
144
+ mode: "primary",
145
+ agent_ids: []
151
146
  })), (0, _preact.h)("div", {
152
147
  class: "widget-header--title-container"
153
148
  }, (0, _preact.h)("div", {
@@ -13,6 +13,7 @@ var _time = _interopRequireDefault(require("./time.js"));
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  class TextMessage extends _common.Com {
15
15
  renderTime() {
16
+ return null;
16
17
  if (!this.props.showTime && !this.props.isLast && !this.props.isFirst) return null;
17
18
  return (0, _preact.h)("div", null, (0, _preact.h)(_time.default, {
18
19
  class: "inline-time",
@@ -228,26 +228,25 @@ class Widget extends _common.Com {
228
228
  class: cls
229
229
  }, $header, $body);
230
230
  }
231
- async submitPrechatForm(form, formName) {
232
- if (this.state.submiting) return;
233
- var hasError = false;
234
- _index.default.map(this.state.formData, (field, key) => {
231
+ validateForm(formData) {
232
+ let newformdata = {};
233
+ _index.default.map(formData, (field, key) => {
234
+ field = Object.assign({}, field);
235
+ field.is_empty_error = false;
235
236
  if (field.is_required && (field.value === undefined || field.value === '' || _index.default.size(field.value) === 0 && Array.isArray(field.value))) {
237
+ field.is_empty_error = true;
236
238
  field.error = this.props.t('error_empty');
237
- hasError = true;
238
239
  } else field.error = '';
239
240
  if (key.substr(5) === 'emails') {
240
241
  if (field.is_required) {
241
242
  if (!_index.default.isEmail(field.value)) {
242
243
  field.error = this.props.t('error_email_invalid');
243
- hasError = true;
244
244
  }
245
245
  } else {
246
246
  let value = field.value || '';
247
247
  if (typeof value !== 'string') value = value + '';
248
248
  if (value.trim() && !_index.default.isEmail(field.value)) {
249
249
  field.error = this.props.t('error_email_invalid');
250
- hasError = true;
251
250
  }
252
251
  }
253
252
  }
@@ -255,19 +254,30 @@ class Widget extends _common.Com {
255
254
  if (field.is_required) {
256
255
  if (!_index.default.isPhone(field.value)) {
257
256
  field.error = this.props.t('error_phone_invalid');
258
- hasError = true;
259
257
  }
260
258
  } else {
261
259
  let value = field.value || '';
262
260
  if (typeof value !== 'string') value = value + '';
263
261
  if (value.trim() && !_index.default.isPhone(field.value)) {
264
262
  field.error = this.props.t('error_phone_invalid');
265
- hasError = true;
266
263
  }
267
264
  }
268
265
  }
266
+ newformdata[key] = field;
269
267
  });
270
- if (hasError) return this.forceUpdate();
268
+ return newformdata;
269
+ }
270
+ async submitPrechatForm(form, formName) {
271
+ if (this.state.submiting) return;
272
+ let newData = this.validateForm(this.state.formData);
273
+ let hasError = _index.default.find(newData, field => !!field.error);
274
+ if (hasError) {
275
+ this.setState({
276
+ formData: newData
277
+ });
278
+ this.focusInput();
279
+ return;
280
+ }
271
281
  let data = _index.default.cloneDeep(this.state.formData);
272
282
  let user = _index.default.cloneDeep(this.props.store.matchUser());
273
283
  let is_lead = false;
@@ -391,6 +401,7 @@ class Widget extends _common.Com {
391
401
  let field = _index.default.find(formData, (_, fkkey) => fkkey === key);
392
402
  if (!field) return;
393
403
  field.value = val;
404
+ field.error = undefined;
394
405
  this.setState({
395
406
  formData
396
407
  });
@@ -517,7 +528,7 @@ class Widget extends _common.Com {
517
528
  if (field.type === 'text') {
518
529
  if (key == 'question' || _index.default.get(field, 'def.multiple_line')) {
519
530
  $field = (0, _preact.h)("textarea", {
520
- class: "form-control",
531
+ class: `form-control ${errclass}`,
521
532
  ref: ref => {
522
533
  this['form_' + encode(key)] = ref;
523
534
  },
@@ -525,8 +536,7 @@ class Widget extends _common.Com {
525
536
  value: field.value || '',
526
537
  onInput: e => this.onInputChange(key, e.target.value),
527
538
  onChange: e => this.onInputChange(key, e.target.value),
528
- row: "4",
529
- class: "form-control"
539
+ row: "4"
530
540
  });
531
541
  } else if (_index.default.get(field, 'def.select') === 'checkbox') {
532
542
  $field = this.renderCheckboxField(field);
@@ -628,9 +638,9 @@ class Widget extends _common.Com {
628
638
  for: 'form_' + encode(key)
629
639
  }, label, field.is_required ? (0, _preact.h)("span", {
630
640
  class: "ml-1 red"
631
- }, "*") : ''), field.error ? (0, _preact.h)("div", {
641
+ }, "*") : ''), $field, field.error ? (0, _preact.h)("div", {
632
642
  class: "form-control--valid-input--error"
633
- }, field.error) : '', $field);
643
+ }, field.error) : '');
634
644
  });
635
645
  return (0, _preact.h)("div", {
636
646
  class: "pt-2"
@@ -640,6 +650,10 @@ class Widget extends _common.Com {
640
650
  let title = this.props.t.i18n(_index.default.get(form, `i18n_title`, {}));
641
651
  if (!title) title = _index.default.get(form, 'title', this.props.t('capture_lead_title'));
642
652
  title = title.replace('↵', '');
653
+ let btncls = 'btn--start-convo ';
654
+ let hasError = _index.default.find(this.state.formData, field => !!field.error);
655
+ let newData = this.validateForm(this.state.formData);
656
+ let hasEmptyError = _index.default.find(newData, field => !!field.is_empty_error);
643
657
  return (0, _preact.h)("div", {
644
658
  class: "widget-body"
645
659
  }, (0, _preact.h)(FormMounter, {
@@ -649,21 +663,16 @@ class Widget extends _common.Com {
649
663
  }), (0, _preact.h)("div", {
650
664
  class: "widget-body--content flex-grow-1 pl-3 pr-3 d-flex flex-column"
651
665
  }, (0, _preact.h)("div", {
652
- class: "flex-grow-1"
653
- }, (0, _preact.h)("div", {
654
- class: "form mt-3 pl-3 pr-3 pt-3 pb-3 d-flex flex-column"
655
- }, (0, _preact.h)("div", null, title), this.renderFields(form, formName))), (0, _preact.h)("div", {
656
- class: "mt-2"
657
- }), (0, _preact.h)(_PoweredBy.default, {
658
- store: this.props.store,
659
- t: this.props.t
660
- })), (0, _preact.h)("div", {
661
- class: "message-input message-input--preform"
662
- }, (0, _preact.h)("button", {
663
- class: "btn--start-convo",
666
+ class: "mt-3 d-flex flex-column"
667
+ }, (0, _preact.h)("div", null, title), this.renderFields(form, formName)), (0, _preact.h)("div", {
668
+ style: "min-height: 15px !important; flex: 1 !important; flex-shrink: 0 !important"
669
+ }), (0, _preact.h)("button", {
670
+ class: btncls,
664
671
  onClick: _ => this.submitPrechatForm(form, formName),
665
- disabled: this.state.creating
666
- }, submitLabel)));
672
+ disabled: !!hasEmptyError || !!hasError || this.state.creating
673
+ }, submitLabel)), (0, _preact.h)("div", {
674
+ class: "mt-2"
675
+ }));
667
676
  }
668
677
  goToConvo(cid) {
669
678
  this.props.onGo({
@@ -689,10 +698,10 @@ class Widget extends _common.Com {
689
698
  }, (0, _preact.h)(_AgentsAvatar.default, {
690
699
  plugin: this.props.plugin,
691
700
  store: this.props.store,
692
- mode: "member",
701
+ mode: "secondary",
693
702
  class: "d-flex flex-row",
694
703
  tooltipPos: "right",
695
- agent_ids: agentids
704
+ agent_ids: [agentids[0]]
696
705
  }), this.renderConvoSummary(convo));
697
706
  });
698
707
  let $body = (0, _preact.h)("div", {
@@ -718,7 +727,9 @@ class Widget extends _common.Com {
718
727
  class: "convo-list--title"
719
728
  }, this.props.t('conversations')), $body), (0, _preact.h)("div", {
720
729
  class: "convo-list--footer"
721
- }, (0, _preact.h)("button", {
730
+ }, (0, _preact.h)(_PoweredBy.default, {
731
+ store: this.props.store
732
+ }), (0, _preact.h)("button", {
722
733
  class: "btn--start-convo",
723
734
  onClick: _ => this.goToConvo('')
724
735
  }, (0, _preact.h)("span", null, this.props.t('start_conversation')), (0, _preact.h)("img", {
@@ -728,8 +739,6 @@ class Widget extends _common.Com {
728
739
  height: "26"
729
740
  })), (0, _preact.h)("div", {
730
741
  class: "mt-2"
731
- }), (0, _preact.h)(_PoweredBy.default, {
732
- store: this.props.store
733
742
  })));
734
743
  }
735
744
  blur() {
@@ -742,17 +751,21 @@ class Widget extends _common.Com {
742
751
  focusInput(text) {
743
752
  if (this.props.store.isPreview) return;
744
753
  if (this.shouldShowForm()) {
745
- let firstemptykey = '';
754
+ let focusfieldkey = '';
746
755
  _index.default.map(this.state.formData, (field, key) => {
747
- if (field.type !== 'text') return;
748
- if (firstemptykey) return;
749
- if (!field.value) firstemptykey = key;
756
+ if (focusfieldkey || field.type !== 'text') return;
757
+ if (!field.value || field.error) focusfieldkey = key;
750
758
  });
759
+ var $input = this['form_' + encode(focusfieldkey)];
760
+ if ($input) $input.focus();
751
761
  _index.default.setTimeout(() => {
752
- var $input = this['form_' + encode(firstemptykey)];
753
- if (!$input) return;
754
- $input.focus();
755
- }, 300);
762
+ _index.default.map(this.state.formData, (field, key) => {
763
+ if (focusfieldkey || field.type !== 'text') return;
764
+ if (!field.value || field.error) focusfieldkey = key;
765
+ });
766
+ var $input = this['form_' + encode(focusfieldkey)];
767
+ if ($input) $input.focus();
768
+ }, 200);
756
769
  return;
757
770
  }
758
771
  var $input = this.msgInput.current;