@seamly/web-ui 22.2.0 → 22.3.0-beta.2

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 (61) hide show
  1. package/build/dist/lib/components.js +449 -291
  2. package/build/dist/lib/components.js.map +1 -1
  3. package/build/dist/lib/components.min.js +1 -1
  4. package/build/dist/lib/components.min.js.map +1 -1
  5. package/build/dist/lib/hooks.js +367 -177
  6. package/build/dist/lib/hooks.js.map +1 -1
  7. package/build/dist/lib/hooks.min.js +1 -1
  8. package/build/dist/lib/hooks.min.js.map +1 -1
  9. package/build/dist/lib/index.debug.js +76 -54
  10. package/build/dist/lib/index.debug.js.map +1 -1
  11. package/build/dist/lib/index.debug.min.js +1 -1
  12. package/build/dist/lib/index.debug.min.js.LICENSE.txt +16 -8
  13. package/build/dist/lib/index.debug.min.js.map +1 -1
  14. package/build/dist/lib/index.js +342 -193
  15. package/build/dist/lib/index.js.map +1 -1
  16. package/build/dist/lib/index.min.js +1 -1
  17. package/build/dist/lib/index.min.js.map +1 -1
  18. package/build/dist/lib/standalone.js +350 -194
  19. package/build/dist/lib/standalone.js.map +1 -1
  20. package/build/dist/lib/standalone.min.js +1 -1
  21. package/build/dist/lib/standalone.min.js.map +1 -1
  22. package/build/dist/lib/style-guide.js +365 -194
  23. package/build/dist/lib/style-guide.js.map +1 -1
  24. package/build/dist/lib/style-guide.min.js +1 -1
  25. package/build/dist/lib/style-guide.min.js.map +1 -1
  26. package/build/dist/lib/styles.css +1 -1
  27. package/build/dist/lib/utils.js +504 -324
  28. package/build/dist/lib/utils.js.map +1 -1
  29. package/build/dist/lib/utils.min.js +1 -1
  30. package/build/dist/lib/utils.min.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/javascripts/api/errors/seamly-api-error.ts +0 -1
  33. package/src/javascripts/api/index.ts +16 -8
  34. package/src/javascripts/domains/app/actions.ts +8 -3
  35. package/src/javascripts/domains/interrupt/selectors.ts +3 -2
  36. package/src/javascripts/domains/interrupt/slice.ts +2 -0
  37. package/src/javascripts/domains/redux/create-debounced-async-thunk.ts +109 -0
  38. package/src/javascripts/domains/redux/redux.types.ts +2 -1
  39. package/src/javascripts/domains/store/actions.ts +38 -0
  40. package/src/javascripts/domains/translations/components/options-dialog/translation-option.tsx +1 -1
  41. package/src/javascripts/domains/visibility/actions.ts +4 -1
  42. package/src/javascripts/style-guide/states.js +26 -1
  43. package/src/javascripts/ui/components/chat-status/chat-status-action.tsx +2 -2
  44. package/src/javascripts/ui/components/conversation/event/{card-component.js → card-component.tsx} +6 -4
  45. package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +2 -2
  46. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +1 -1
  47. package/src/javascripts/ui/components/conversation/event/event-participant.js +1 -1
  48. package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
  49. package/src/javascripts/ui/components/conversation/event-divider.js +6 -1
  50. package/src/javascripts/ui/components/core/seamly-event-subscriber.ts +14 -30
  51. package/src/javascripts/ui/components/form-controls/error.js +1 -1
  52. package/src/javascripts/ui/components/form-controls/file-input.js +1 -1
  53. package/src/javascripts/ui/components/layout/agent-info.js +1 -1
  54. package/src/javascripts/ui/components/layout/{icon.js → icon.tsx} +74 -37
  55. package/src/javascripts/ui/components/options/options-button.js +1 -1
  56. package/src/javascripts/ui/components/suggestions/suggestions-item.js +1 -1
  57. package/src/javascripts/ui/components/view/window-view/window-open-button.js +9 -4
  58. package/src/javascripts/ui/components/widgets/lightbox.js +1 -1
  59. package/src/javascripts/ui/hooks/use-session-expired-command.ts +31 -2
  60. package/src/stylesheets/5-components/_message-card.scss +4 -3
  61. package/src/stylesheets/5-components/_message-count.scss +11 -9
@@ -3927,7 +3927,8 @@ class API {
3927
3927
  });
3928
3928
  }
3929
3929
  getConversationUrl() {
3930
- return this.store.get('conversationUrl');
3930
+ const conversationUrl = this.store.get('conversationUrl');
3931
+ return conversationUrl;
3931
3932
  }
3932
3933
  hasConversation() {
3933
3934
  return !!this.getConversationUrl();
@@ -4035,7 +4036,7 @@ class API {
4035
4036
  if (error.status >= 500) {
4036
4037
  throw new SeamlyGeneralError(error);
4037
4038
  }
4038
- throw error;
4039
+ throw new ApiError(error);
4039
4040
  }
4040
4041
  });
4041
4042
  }
@@ -4144,7 +4145,7 @@ class API {
4144
4145
  if (error.status >= 500) {
4145
4146
  throw new SeamlyGeneralError(error);
4146
4147
  }
4147
- throw error;
4148
+ throw new ApiError(error);
4148
4149
  }
4149
4150
  });
4150
4151
  }
@@ -4204,15 +4205,17 @@ class API {
4204
4205
  }
4205
4206
  }
4206
4207
  _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAuthToken = new WeakMap(), _API_layoutMode = new WeakMap(), _API_config = new WeakMap(), _API_getLocale = new WeakMap(), _API_instances = new WeakSet(), _API_getAccessToken = function _API_getAccessToken() {
4207
- return this.store.get('accessToken');
4208
+ const accessToken = this.store.get('accessToken');
4209
+ return accessToken;
4208
4210
  }, _API_setAccessToken = function _API_setAccessToken(accessToken) {
4209
4211
  this.store.set('accessToken', accessToken);
4210
4212
  }, _API_setConversationUrl = function _API_setConversationUrl(url) {
4211
4213
  this.store.set('conversationUrl', url);
4212
4214
  }, _API_getChannelTopic = function _API_getChannelTopic() {
4215
+ const channelTopic = this.store.get('channelTopic') || this.store.get('channelName');
4213
4216
  // The `channelName` fallback is needed for seamless client upgrades.
4214
4217
  // TODO: Remove when all clients have been upgraded past v20.
4215
- return this.store.get('channelTopic') || this.store.get('channelName');
4218
+ return channelTopic;
4216
4219
  }, _API_setChannelTopic = function _API_setChannelTopic(topic) {
4217
4220
  this.store.set('channelTopic', topic);
4218
4221
  }, _API_getUrlPrefix = function _API_getUrlPrefix(protocol) {
@@ -4277,7 +4280,7 @@ _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAu
4277
4280
  return {
4278
4281
  clientName: "@seamly/web-ui",
4279
4282
  clientVariant: api_classPrivateFieldGet(this, _API_layoutMode, "f"),
4280
- clientVersion: "22.2.0",
4283
+ clientVersion: "22.3.0-beta.2",
4281
4284
  currentUrl: window.location.toString(),
4282
4285
  screenResolution: `${window.screen.width}x${window.screen.height}`,
4283
4286
  timezone: getTimeZone(),
@@ -8111,6 +8114,62 @@ const setLocale = createAsyncThunk('setLocale', (locale, {
8111
8114
  return true;
8112
8115
  }
8113
8116
  });
8117
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/redux/create-debounced-async-thunk.ts
8118
+
8119
+ /**
8120
+ * A debounced analogue of the `createAsyncThunk` from `@reduxjs/toolkit`
8121
+ * @param typePrefix - a string action type value
8122
+ * @param payloadCreator - a callback function that should return a promise containing the result of some asynchronous logic
8123
+ * @param debounceOptions - the debounce options object
8124
+ */
8125
+ const createDebouncedAsyncThunk = (typePrefix, payloadCreator, debounceOptions) => {
8126
+ const {
8127
+ wait = 300,
8128
+ maxWait = 0,
8129
+ leading = false
8130
+ } = debounceOptions !== null && debounceOptions !== void 0 ? debounceOptions : {};
8131
+ let debounceTimer = null;
8132
+ let maxWaitTimer = null;
8133
+ let resolve;
8134
+ const cancel = () => {
8135
+ if (resolve) {
8136
+ resolve(false);
8137
+ resolve = undefined;
8138
+ }
8139
+ };
8140
+ const invoke = () => {
8141
+ clearTimeout(maxWaitTimer);
8142
+ maxWaitTimer = undefined;
8143
+ if (resolve) {
8144
+ resolve(true);
8145
+ resolve = undefined;
8146
+ }
8147
+ };
8148
+ const debounceExecutionCondition = () => {
8149
+ const immediate = leading && !debounceTimer;
8150
+ // Start debounced condition resolution
8151
+ clearTimeout(debounceTimer);
8152
+ debounceTimer = setTimeout(() => {
8153
+ invoke();
8154
+ debounceTimer = null;
8155
+ }, wait);
8156
+ if (immediate) {
8157
+ return true;
8158
+ }
8159
+ cancel();
8160
+ // Start max wait condition resolution
8161
+ if (maxWait && !maxWaitTimer) {
8162
+ maxWaitTimer = setTimeout(invoke, maxWait);
8163
+ }
8164
+ return new Promise(res => {
8165
+ resolve = res;
8166
+ });
8167
+ };
8168
+ return createAsyncThunk(typePrefix, payloadCreator, {
8169
+ condition: debounceExecutionCondition
8170
+ });
8171
+ };
8172
+ /* harmony default export */ const create_debounced_async_thunk = (createDebouncedAsyncThunk);
8114
8173
  ;// CONCATENATED MODULE: ./node_modules/reselect/es/defaultMemoize.js
8115
8174
  // Cache implementation based on Erik Rasmussen's `lru-memoize`:
8116
8175
  // https://github.com/erikras/lru-memoize
@@ -8667,8 +8726,9 @@ const setVisibility = createAsyncThunk('setVisibility', (requestedVisibility, {
8667
8726
  if (previousVisibility === calculatedVisibility) {
8668
8727
  return undefined;
8669
8728
  }
8729
+ const visibility = api.store.get(StoreKey);
8670
8730
  // Store the user-requested visibility in order to reinitialize after refresh
8671
- api.store.set(StoreKey, Object.assign(Object.assign({}, api.store.get(StoreKey) || {}), {
8731
+ api.store.set(StoreKey, Object.assign(Object.assign({}, visibility || {}), {
8672
8732
  [layoutMode]: requestedVisibility
8673
8733
  }));
8674
8734
  if (requestedVisibility) {
@@ -8732,6 +8792,7 @@ var app_actions_awaiter = undefined && undefined.__awaiter || function (thisArg,
8732
8792
 
8733
8793
 
8734
8794
 
8795
+
8735
8796
  const initializeApp = createAsyncThunk('initializeApp', (_, {
8736
8797
  extra: {
8737
8798
  api,
@@ -8797,14 +8858,14 @@ const initializeApp = createAsyncThunk('initializeApp', (_, {
8797
8858
  });
8798
8859
  }
8799
8860
  }));
8800
- const resetApp = createAsyncThunk('resetApp', (_, {
8861
+ const resetApp = create_debounced_async_thunk('resetApp', (_, {
8801
8862
  dispatch,
8802
8863
  extra: {
8803
8864
  api
8804
8865
  }
8805
8866
  }) => app_actions_awaiter(void 0, void 0, void 0, function* () {
8806
8867
  yield api.disconnect();
8807
- yield api.clearStore();
8868
+ api.clearStore();
8808
8869
  dispatch(resetConfig());
8809
8870
  yield dispatch(initializeConfig());
8810
8871
  try {
@@ -8812,11 +8873,14 @@ const resetApp = createAsyncThunk('resetApp', (_, {
8812
8873
  locale
8813
8874
  } = yield dispatch(initializeApp()).unwrap();
8814
8875
  yield dispatch(setLocale(locale));
8815
- } catch (rejectedValueOrSerializedError) {
8876
+ } catch (e) {
8816
8877
  // nothing to do
8817
8878
  }
8818
8879
  dispatch(initializeVisibility());
8819
- }));
8880
+ }), {
8881
+ wait: 2000,
8882
+ leading: true
8883
+ });
8820
8884
  ;// CONCATENATED MODULE: ./src/javascripts/domains/app/hooks.js
8821
8885
 
8822
8886
 
@@ -8852,12 +8916,75 @@ const {
8852
8916
  setHasResponded
8853
8917
  } = appSlice.actions;
8854
8918
  /* harmony default export */ const slice = (appSlice.reducer);
8919
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/store/actions.ts
8920
+ var store_actions_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
8921
+ function adopt(value) {
8922
+ return value instanceof P ? value : new P(function (resolve) {
8923
+ resolve(value);
8924
+ });
8925
+ }
8926
+ return new (P || (P = Promise))(function (resolve, reject) {
8927
+ function fulfilled(value) {
8928
+ try {
8929
+ step(generator.next(value));
8930
+ } catch (e) {
8931
+ reject(e);
8932
+ }
8933
+ }
8934
+ function rejected(value) {
8935
+ try {
8936
+ step(generator["throw"](value));
8937
+ } catch (e) {
8938
+ reject(e);
8939
+ }
8940
+ }
8941
+ function step(result) {
8942
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
8943
+ }
8944
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8945
+ });
8946
+ };
8947
+
8948
+ const getConversation = createAsyncThunk('getConversation', (_, {
8949
+ extra: {
8950
+ api
8951
+ },
8952
+ rejectWithValue
8953
+ }) => store_actions_awaiter(void 0, void 0, void 0, function* () {
8954
+ try {
8955
+ return api.getConversation();
8956
+ } catch (error) {
8957
+ return rejectWithValue({
8958
+ name: error === null || error === void 0 ? void 0 : error.name,
8959
+ message: error === null || error === void 0 ? void 0 : error.message,
8960
+ langKey: error === null || error === void 0 ? void 0 : error.langKey,
8961
+ action: error === null || error === void 0 ? void 0 : error.action,
8962
+ originalEvent: error === null || error === void 0 ? void 0 : error.originalEvent,
8963
+ originalError: error === null || error === void 0 ? void 0 : error.originalError
8964
+ });
8965
+ }
8966
+ }), {
8967
+ condition(payload, {
8968
+ getState
8969
+ }) {
8970
+ var _a;
8971
+ const {
8972
+ state: {
8973
+ events
8974
+ }
8975
+ } = getState();
8976
+ const lastEvent = events[events.length - 1];
8977
+ const payloadLastEventId = (_a = payload === null || payload === void 0 ? void 0 : payload.lastEvent) === null || _a === void 0 ? void 0 : _a.id;
8978
+ return lastEvent && payloadLastEventId !== lastEvent.payload.id;
8979
+ }
8980
+ });
8855
8981
  ;// CONCATENATED MODULE: ./src/javascripts/domains/interrupt/slice.ts
8856
8982
 
8857
8983
 
8858
8984
 
8859
8985
 
8860
8986
 
8987
+
8861
8988
  const slice_initialState = {
8862
8989
  error: undefined
8863
8990
  };
@@ -8871,7 +8998,7 @@ const interruptSlice = createSlice({
8871
8998
  clearInterrupt: () => slice_initialState
8872
8999
  },
8873
9000
  extraReducers: builder => {
8874
- builder.addCase(initializeConfig.pending, () => slice_initialState).addMatcher(isAnyOf(initializeApp.rejected, initializeConfig.rejected, setLocale.rejected, setVisibility.rejected, initializeVisibility.rejected), (state, {
9001
+ builder.addCase(initializeConfig.pending, () => slice_initialState).addMatcher(isAnyOf(initializeApp.rejected, initializeConfig.rejected, setLocale.rejected, setVisibility.rejected, initializeVisibility.rejected, getConversation.rejected), (state, {
8875
9002
  payload
8876
9003
  }) => {
8877
9004
  state.error = payload;
@@ -11277,6 +11404,9 @@ function useInterrupt() {
11277
11404
 
11278
11405
 
11279
11406
 
11407
+
11408
+
11409
+
11280
11410
  function useSessionExpiredCommand() {
11281
11411
  const {
11282
11412
  meta: {
@@ -11284,13 +11414,35 @@ function useSessionExpiredCommand() {
11284
11414
  action
11285
11415
  }
11286
11416
  } = useInterrupt();
11417
+ const dispatch = useAppDispatch();
11287
11418
  const seamlyCommands = use_seamly_commands();
11288
11419
  const isExpiredError = (originalError === null || originalError === void 0 ? void 0 : originalError.name) === 'SeamlySessionExpiredError';
11420
+ const limit = (0,hooks_.useRef)(0);
11421
+ const limitTimer = (0,hooks_.useRef)(null);
11289
11422
  (0,hooks_.useEffect)(() => {
11290
11423
  if (isExpiredError && seamlyCommands[action]) {
11424
+ if (limit.current >= 10) {
11425
+ limitTimer.current = setTimeout(() => {
11426
+ limit.current = 0;
11427
+ }, 10000);
11428
+ const error = new SeamlyGeneralError();
11429
+ dispatch(setInterrupt({
11430
+ name: error.name,
11431
+ message: error.message,
11432
+ langKey: error.langKey,
11433
+ originalEvent: error.originalEvent,
11434
+ originalError: error.originalError,
11435
+ action: error.action
11436
+ }));
11437
+ return () => {};
11438
+ }
11439
+ limit.current += 1;
11291
11440
  seamlyCommands[action]();
11292
11441
  }
11293
- }, [action, seamlyCommands, isExpiredError]);
11442
+ return () => {
11443
+ if (limitTimer.current) clearTimeout(limitTimer.current);
11444
+ };
11445
+ }, [action, seamlyCommands, isExpiredError, dispatch]);
11294
11446
  }
11295
11447
  ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-chat.ts
11296
11448
  var use_seamly_chat_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
@@ -12118,7 +12270,7 @@ const EventParticipant = ({
12118
12270
  })
12119
12271
  }));
12120
12272
  }
12121
- if (showName) {
12273
+ if (showName && participantName) {
12122
12274
  authorInfo.push((0,jsx_runtime_namespaceObject.jsx)("span", {
12123
12275
  className: css_className('message__author-name'),
12124
12276
  children: participantName
@@ -12198,108 +12350,61 @@ function MessageContainer({
12198
12350
  });
12199
12351
  }
12200
12352
  /* harmony default export */ const message_container = (MessageContainer);
12201
- ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-component.js
12353
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-component.tsx
12202
12354
 
12203
12355
 
12204
12356
 
12205
12357
 
12206
12358
 
12207
-
12208
- const CardComponent = ({
12209
- id,
12210
- action,
12211
- buttonText,
12212
- description,
12213
- hasFocus,
12214
- image,
12215
- title,
12216
- isCarouselItem
12217
- }) => {
12218
- const cardRef = (0,hooks_.useRef)(null);
12219
- const {
12220
- sendMessage,
12221
- sendAction,
12222
- emitEvent
12223
- } = use_seamly_commands();
12224
- const descriptionId = useGeneratedId();
12225
- const isMounted = (0,hooks_.useRef)();
12226
- const CardActionComponent = action.type === cardTypes.navigate ? 'a' : 'button';
12227
- const emitCardEvent = (0,hooks_.useCallback)(() => emitEvent(`action.${actionTypes.clickCard}`, {
12228
- type: actionTypes.clickCta,
12229
- originMessage: id,
12230
- action
12231
- }), [emitEvent, id, action]);
12232
- const handleClick = (0,hooks_.useCallback)(() => {
12233
- emitCardEvent();
12234
- if (action.type === cardTypes.ask) {
12235
- sendMessage({
12236
- body: action.ask
12237
- });
12238
- } else if (action.type === cardTypes.topic) {
12239
- const {
12240
- topic: name,
12241
- fallbackMessage
12242
- } = action;
12243
- sendAction({
12244
- type: actionTypes.setTopic,
12245
- body: {
12246
- name,
12247
- fallbackMessage
12359
+ const CardComponent = ({ id, action, buttonText, description, hasFocus, image, title, isCarouselItem, }) => {
12360
+ const cardRef = (0,hooks_.useRef)(null);
12361
+ const { sendMessage, sendAction, emitEvent } = use_seamly_commands();
12362
+ const descriptionId = useGeneratedId();
12363
+ const isMounted = (0,hooks_.useRef)(false);
12364
+ const CardActionComponent = action.type === cardTypes.navigate ? 'a' : 'button';
12365
+ const emitCardEvent = (0,hooks_.useCallback)(() => emitEvent(`action.${actionTypes.clickCard}`, {
12366
+ type: actionTypes.clickCta,
12367
+ originMessage: id,
12368
+ action,
12369
+ }), [emitEvent, id, action]);
12370
+ const handleClick = (0,hooks_.useCallback)(() => {
12371
+ emitCardEvent();
12372
+ if (action.type === cardTypes.ask) {
12373
+ sendMessage({ body: action.ask });
12248
12374
  }
12249
- });
12250
- }
12251
- }, [sendMessage, action, sendAction, emitCardEvent]);
12252
- const actionProps = (0,hooks_.useMemo)(() => action.type === cardTypes.navigate ? {
12253
- href: action.link,
12254
- rel: 'noopener noreferrer',
12255
- target: action.newTab ? '_blank' : '_self',
12256
- onClick: emitCardEvent
12257
- } : {
12258
- onClick: handleClick
12259
- }, [action, handleClick, emitCardEvent]);
12260
- (0,hooks_.useEffect)(() => {
12261
- if (isCarouselItem) {
12262
- if (hasFocus && isMounted.current) {
12263
- window.requestAnimationFrame(() => cardRef.current.focus());
12264
- } else {
12265
- cardRef.current.blur();
12266
- }
12267
- }
12268
- isMounted.current = true;
12269
- }, [hasFocus, isCarouselItem]);
12270
- return (0,jsx_runtime_namespaceObject.jsxs)("div", {
12271
- className: css_className('card__wrapper'),
12272
- id: id,
12273
- tabIndex: "-1" // set tabIndex of -1 so card can be focussed
12274
- ,
12275
- ref: cardRef,
12276
- children: [(0,jsx_runtime_namespaceObject.jsx)("img", {
12277
- className: css_className('card__image'),
12278
- src: image,
12279
- alt: ""
12280
- }), (0,jsx_runtime_namespaceObject.jsxs)("div", {
12281
- className: css_className('card__content'),
12282
- id: id,
12283
- children: [title && (0,jsx_runtime_namespaceObject.jsx)("h2", {
12284
- className: css_className('card__title'),
12285
- children: title
12286
- }), description && (0,jsx_runtime_namespaceObject.jsx)("div", {
12287
- className: css_className('card__description'),
12288
- dangerouslySetInnerHTML: {
12289
- __html: description
12375
+ else if (action.type === cardTypes.topic) {
12376
+ const { topic: name, fallbackMessage } = action;
12377
+ sendAction({
12378
+ type: actionTypes.setTopic,
12379
+ body: { name, fallbackMessage },
12380
+ });
12290
12381
  }
12291
- }), (0,jsx_runtime_namespaceObject.jsx)(CardActionComponent, {
12292
- tabIndex: isCarouselItem && !hasFocus ? '-1' : undefined // disable to prevent tabbing through cards
12293
- ,
12294
- className: css_className('button', 'button--primary'),
12295
- "aria-describedby": descriptionId,
12296
- ...actionProps,
12297
- children: buttonText
12298
- })]
12299
- })]
12300
- });
12382
+ }, [sendMessage, action, sendAction, emitCardEvent]);
12383
+ const actionProps = (0,hooks_.useMemo)(() => action.type === cardTypes.navigate
12384
+ ? {
12385
+ href: action.link,
12386
+ rel: 'noopener noreferrer',
12387
+ target: action.newTab ? '_blank' : '_self',
12388
+ onClick: emitCardEvent,
12389
+ }
12390
+ : {
12391
+ onClick: handleClick,
12392
+ }, [action, handleClick, emitCardEvent]);
12393
+ (0,hooks_.useEffect)(() => {
12394
+ if (isCarouselItem) {
12395
+ if (hasFocus && isMounted.current) {
12396
+ window.requestAnimationFrame(() => cardRef.current.focus());
12397
+ }
12398
+ else {
12399
+ cardRef.current.blur();
12400
+ }
12401
+ }
12402
+ isMounted.current = true;
12403
+ }, [hasFocus, isCarouselItem]);
12404
+ return ((0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('card__wrapper'), id: id, tabIndex: -1, ref: cardRef, children: [image ? ((0,jsx_runtime_namespaceObject.jsx)("img", { className: css_className('card__image'), src: image, alt: "" })) : null, (0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('card__content'), id: id, children: [title && (0,jsx_runtime_namespaceObject.jsx)("h2", { className: css_className('card__title'), children: title }), description && ((0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('card__description'), dangerouslySetInnerHTML: { __html: description } })), (0,jsx_runtime_namespaceObject.jsx)(CardActionComponent, Object.assign({ tabIndex: isCarouselItem && !hasFocus ? -1 : undefined, className: css_className('button', 'button--primary'), "aria-describedby": descriptionId }, actionProps, { children: buttonText }))] })] }));
12301
12405
  };
12302
12406
  /* harmony default export */ const card_component = (CardComponent);
12407
+
12303
12408
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-message.js
12304
12409
 
12305
12410
 
@@ -12396,7 +12501,8 @@ function CarouselMessageSlide({
12396
12501
  /* harmony default export */ const icon_send_32 = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32px\" height=\"32px\" x=\"0px\" y=\"0px\" viewBox=\"0 0 32 32\"><defs/><path fill=\"#4A48C1\" d=\"M6.714,14.985l17.837-7.906c0.681-0.302,1.414,0.301,1.25,1.027L22.273,23.59\tc-0.13,0.566-0.751,0.865-1.275,0.613l-3.623-1.752l-2.334,2.287c-0.572,0.562-1.538,0.156-1.538-0.645V21.01\tc0-0.217,0.078-0.43,0.222-0.594l7.676-8.841l-10.414,7.472l-4.351-2.445C5.987,16.236,6.033,15.287,6.714,14.985L6.714,14.985z\"/></svg>");
12397
12502
  ;// CONCATENATED MODULE: ./node_modules/raw-loader/dist/cjs.js!./src/icons/icon_upload-32.svg
12398
12503
  /* harmony default export */ const icon_upload_32 = ("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32px\" height=\"32px\" x=\"0px\" y=\"0px\" viewBox=\"0 0 32 32\"><defs/><path fill=\"#4A48C1\" d=\"M9.488,13.481c-0.391-0.391-0.391-1.023,0-1.414l5.805-5.805c0.026-0.026,0.06-0.036,0.088-0.058\tc0.073-0.06,0.146-0.119,0.235-0.156c0.246-0.103,0.522-0.103,0.769,0c0.093,0.039,0.171,0.101,0.249,0.165\tc0.023,0.02,0.053,0.027,0.074,0.049l5.805,5.805c0.391,0.391,0.391,1.023,0,1.414c-0.195,0.195-0.451,0.293-0.707,0.293\ts-0.512-0.098-0.707-0.293L17,9.383V20.33c0,0.553-0.447,1-1,1c-0.552,0-1-0.447-1-1V9.383l-4.098,4.098\tC10.512,13.872,9.879,13.872,9.488,13.481z M22.819,24.031H9.181c-0.552,0-1,0.447-1,1s0.448,1,1,1h13.639c0.553,0,1-0.447,1-1\tS23.372,24.031,22.819,24.031z\"/></svg>");
12399
- ;// CONCATENATED MODULE: ./src/javascripts/ui/components/layout/icon.js
12504
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/components/layout/icon.tsx
12505
+
12400
12506
  /* eslint-disable import/no-webpack-loader-syntax */
12401
12507
  // The eslint rules are disabled for this as otherwsise we'd need to include the loader rule in all implementations
12402
12508
  // this can again be changed when we can import pre-built packages in implementations
@@ -12421,58 +12527,70 @@ function CarouselMessageSlide({
12421
12527
 
12422
12528
 
12423
12529
 
12424
-
12425
12530
 
12426
12531
 
12427
12532
  /* eslint-enable import/no-webpack-loader-syntax */
12428
-
12429
-
12430
-
12431
12533
  const ICONS = {
12432
- send32: icon_send_32,
12433
- balloon32: icon_balloon_32,
12434
- newTopic32: icon_newtopic_32,
12435
- newTranslation16: icon_newtranslation_16,
12436
- newTranslation32: icon_newtranslation_32,
12437
- avatar32: avatar_bot_32,
12438
- chevronDown8: icon_chevron_down_8,
12439
- chevronDown32: icon_chevron_down_32,
12440
- chevronRight8: icon_chevron_right_8,
12441
- chevronRight16: icon_chevron_right_16,
12442
- close8: icon_close_8,
12443
- close16: icon_close_16,
12444
- enlarge32: icon_enlarge_32,
12445
- options32: icon_options_32,
12446
- file32: icon_file_32,
12447
- upload32: icon_upload_32,
12448
- download16: icon_download_16,
12449
- error16: icon_error_16,
12450
- arrowLeft16: icon_arrow_left_16,
12451
- arrowRight16: icon_arrow_right_16,
12452
- check32: icon_check_32,
12453
- check16: icon_check_16
12454
- };
12455
- const Icon = ({
12456
- name,
12457
- size = '32',
12458
- className = undefined,
12459
- alt
12460
- }) => {
12461
- const iconName = `${name}${size}`;
12462
- return (0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
12463
- children: [(0,jsx_runtime_namespaceObject.jsx)("div", {
12464
- "aria-hidden": "true",
12465
- className: className || css_className('icon'),
12466
- dangerouslySetInnerHTML: {
12467
- __html: ICONS[iconName]
12468
- }
12469
- }), alt && (0,jsx_runtime_namespaceObject.jsx)("span", {
12470
- className: css_className('visually-hidden'),
12471
- children: alt
12472
- })]
12473
- });
12534
+ send: {
12535
+ 32: icon_send_32,
12536
+ },
12537
+ balloon: {
12538
+ 32: icon_balloon_32,
12539
+ },
12540
+ newTopic: {
12541
+ 32: icon_newtopic_32,
12542
+ },
12543
+ newTranslation: {
12544
+ 16: icon_newtranslation_16,
12545
+ 32: icon_newtranslation_32,
12546
+ },
12547
+ avatar: {
12548
+ 32: avatar_bot_32,
12549
+ },
12550
+ chevronDown: {
12551
+ 8: icon_chevron_down_8,
12552
+ 32: icon_chevron_down_32,
12553
+ },
12554
+ chevronRight: {
12555
+ 8: icon_chevron_right_8,
12556
+ 16: icon_chevron_right_16,
12557
+ },
12558
+ close: {
12559
+ 8: icon_close_8,
12560
+ 16: icon_close_16,
12561
+ },
12562
+ enlarge: {
12563
+ 32: icon_enlarge_32,
12564
+ },
12565
+ options: {
12566
+ 32: icon_options_32,
12567
+ },
12568
+ file: {
12569
+ 32: icon_file_32,
12570
+ },
12571
+ upload: {
12572
+ 32: icon_upload_32,
12573
+ },
12574
+ download: {
12575
+ 16: icon_download_16,
12576
+ },
12577
+ error: {
12578
+ 16: icon_error_16,
12579
+ },
12580
+ arrowLeft: {
12581
+ 16: icon_arrow_left_16,
12582
+ },
12583
+ arrowRight: {
12584
+ 16: icon_arrow_right_16,
12585
+ },
12586
+ check: {
12587
+ 16: icon_check_16,
12588
+ 32: icon_check_32,
12589
+ },
12474
12590
  };
12591
+ const Icon = ({ name, size = '32', className, alt }) => ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [(0,jsx_runtime_namespaceObject.jsx)("div", { "aria-hidden": "true", className: className || css_className('icon'), dangerouslySetInnerHTML: { __html: ICONS[name][size] } }), alt && (0,jsx_runtime_namespaceObject.jsx)("span", { className: css_className('visually-hidden'), children: alt })] }));
12475
12592
  /* harmony default export */ const layout_icon = (Icon);
12593
+
12476
12594
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js
12477
12595
 
12478
12596
 
@@ -12503,7 +12621,8 @@ function CarouselControls({
12503
12621
  onClick: handlePrevious,
12504
12622
  children: (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
12505
12623
  name: "arrowLeft",
12506
- size: "16"
12624
+ size: "16",
12625
+ alt: ""
12507
12626
  })
12508
12627
  }), children, (0,jsx_runtime_namespaceObject.jsx)("button", {
12509
12628
  className: css_className('button', 'button--next'),
@@ -12511,7 +12630,8 @@ function CarouselControls({
12511
12630
  onClick: handleNext,
12512
12631
  children: (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
12513
12632
  name: "arrowRight",
12514
- size: "16"
12633
+ size: "16",
12634
+ alt: ""
12515
12635
  })
12516
12636
  })]
12517
12637
  });
@@ -12798,7 +12918,8 @@ const ChoicePrompt = ({
12798
12918
  "aria-describedby": descriptorId,
12799
12919
  children: [showOptions ? t('message.choicePrompts.cancelChooseAgain') : t('message.choicePrompts.chooseAgain'), (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
12800
12920
  name: "chevronDown",
12801
- size: "8"
12921
+ size: "8",
12922
+ alt: ""
12802
12923
  })]
12803
12924
  }), showOptions && (0,jsx_runtime_namespaceObject.jsx)(message_container, {
12804
12925
  type: "choice-prompt",
@@ -12858,7 +12979,8 @@ const SuggestionsItem = ({
12858
12979
  className: css_className('button', 'button--primary'),
12859
12980
  children: [hasIcon && (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
12860
12981
  name: "chevronRight",
12861
- size: "8"
12982
+ size: "8",
12983
+ alt: ""
12862
12984
  }), question]
12863
12985
  })
12864
12986
  });
@@ -13088,7 +13210,8 @@ function EventDivider({
13088
13210
  children: iconName ? (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
13089
13211
  name: iconName,
13090
13212
  size: iconSize,
13091
- className: iconClassName
13213
+ className: iconClassName,
13214
+ alt: ""
13092
13215
  }) : (0,jsx_runtime_namespaceObject.jsx)("img", {
13093
13216
  src: graphicSrc,
13094
13217
  className: css_className({
@@ -14976,7 +15099,8 @@ const Lightbox = ({
14976
15099
  onClick: onClose,
14977
15100
  children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
14978
15101
  name: "close",
14979
- size: "16"
15102
+ size: "16",
15103
+ alt: ""
14980
15104
  }), t('lightbox.closeLabel')]
14981
15105
  })]
14982
15106
  })
@@ -15024,7 +15148,8 @@ const ImageLightbox = ({
15024
15148
  description
15025
15149
  }), (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
15026
15150
  name: "enlarge",
15027
- size: "32"
15151
+ size: "32",
15152
+ alt: ""
15028
15153
  })]
15029
15154
  }), showLightBox && (0,jsx_runtime_namespaceObject.jsx)(lightbox, {
15030
15155
  url: url,
@@ -15455,6 +15580,33 @@ const SeamlyActivityMonitor = ({ children }) => {
15455
15580
  /* harmony default export */ const seamly_activity_monitor = (SeamlyActivityMonitor);
15456
15581
 
15457
15582
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/core/seamly-event-subscriber.ts
15583
+ var seamly_event_subscriber_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
15584
+ function adopt(value) {
15585
+ return value instanceof P ? value : new P(function (resolve) {
15586
+ resolve(value);
15587
+ });
15588
+ }
15589
+ return new (P || (P = Promise))(function (resolve, reject) {
15590
+ function fulfilled(value) {
15591
+ try {
15592
+ step(generator.next(value));
15593
+ } catch (e) {
15594
+ reject(e);
15595
+ }
15596
+ }
15597
+ function rejected(value) {
15598
+ try {
15599
+ step(generator["throw"](value));
15600
+ } catch (e) {
15601
+ reject(e);
15602
+ }
15603
+ }
15604
+ function step(result) {
15605
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
15606
+ }
15607
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15608
+ });
15609
+ };
15458
15610
  var seamly_event_subscriber_rest = undefined && undefined.__rest || function (s, e) {
15459
15611
  var t = {};
15460
15612
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
@@ -15475,13 +15627,13 @@ var seamly_event_subscriber_rest = undefined && undefined.__rest || function (s,
15475
15627
 
15476
15628
 
15477
15629
 
15630
+
15478
15631
  const EMITTABLE_MESSAGE_TYPES = ['text', 'choice_prompt', 'image', 'video'];
15479
15632
  const SeamlyEventSubscriber = () => {
15480
15633
  const api = useSeamlyApiContext();
15481
15634
  const syncChannelRef = (0,hooks_.useRef)();
15482
15635
  const messageChannelRef = (0,hooks_.useRef)();
15483
- const dispatch = useDispatch();
15484
- const events = useEvents();
15636
+ const dispatch = useAppDispatch();
15485
15637
  const eventBus = (0,hooks_.useContext)(SeamlyEventBusContext);
15486
15638
  const prevEmittedEventId = (0,hooks_.useRef)(null);
15487
15639
  const {
@@ -15726,31 +15878,19 @@ const SeamlyEventSubscriber = () => {
15726
15878
  if (syncChannelRef.current) {
15727
15879
  (_a = api.conversation.channel) === null || _a === void 0 ? void 0 : _a.off('sync', syncChannelRef.current);
15728
15880
  }
15729
- syncChannelRef.current = api.conversation.channel.on('sync', payload => {
15730
- var _a;
15731
- const lastEvent = events[events.length - 1];
15732
- const payloadLastEventId = (_a = payload === null || payload === void 0 ? void 0 : payload.lastEvent) === null || _a === void 0 ? void 0 : _a.id;
15733
- if (lastEvent && payloadLastEventId === lastEvent.payload.id) {
15734
- return payload;
15735
- }
15736
- return api.getConversation().then(history => {
15881
+ syncChannelRef.current = api.conversation.channel.on('sync', payload => seamly_event_subscriber_awaiter(void 0, void 0, void 0, function* () {
15882
+ try {
15883
+ const history = yield dispatch(getConversation(payload)).unwrap();
15737
15884
  if (!history) return;
15738
15885
  dispatch(setHistory(history));
15739
- }).catch(error => {
15740
- dispatch(setInterrupt({
15741
- name: error === null || error === void 0 ? void 0 : error.name,
15742
- message: error === null || error === void 0 ? void 0 : error.message,
15743
- langKey: error === null || error === void 0 ? void 0 : error.langKey,
15744
- action: error === null || error === void 0 ? void 0 : error.action,
15745
- originalEvent: error === null || error === void 0 ? void 0 : error.originalEvent,
15746
- originalError: error === null || error === void 0 ? void 0 : error.originalError
15747
- }));
15748
- });
15749
- });
15886
+ } catch (_e) {
15887
+ // nothing to do, the error is handled in the thunk
15888
+ }
15889
+ }));
15750
15890
  return true;
15751
15891
  });
15752
15892
  }
15753
- }, [api, api.connectionInfo, api.conversation.channel, events, dispatch]);
15893
+ }, [api, api.connectionInfo, api.conversation.channel, dispatch]);
15754
15894
  return null;
15755
15895
  };
15756
15896
  /* harmony default export */ const seamly_event_subscriber = (SeamlyEventSubscriber);
@@ -17335,7 +17475,8 @@ function error_Error({
17335
17475
  className: css_className('error__message'),
17336
17476
  children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
17337
17477
  name: "error",
17338
- size: "16"
17478
+ size: "16",
17479
+ alt: ""
17339
17480
  }), error]
17340
17481
  })
17341
17482
  });
@@ -17712,7 +17853,8 @@ const OptionsButton = () => {
17712
17853
  "aria-disabled": !multiMenu && !firstOption.available ? 'true' : null,
17713
17854
  children: [multiMenu && (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
17714
17855
  name: "options",
17715
- size: "32"
17856
+ size: "32",
17857
+ alt: ""
17716
17858
  }), (0,jsx_runtime_namespaceObject.jsx)("span", {
17717
17859
  className: css_className('button__text'),
17718
17860
  children: multiMenu ? t('options.openButtonText') : `${firstOption.title}${!firstOption.available ? ' ' : ''}`
@@ -17735,7 +17877,7 @@ const TranslationOption = ({ label, checked, description, onChange, id, itemClas
17735
17877
  onChange();
17736
17878
  }
17737
17879
  };
17738
- return ((0,jsx_runtime_namespaceObject.jsxs)("li", { className: css_className([itemClassName, 'translation-options__item']), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id, children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { alt: "", name: "check", size: "16" }), label, " ", description && (0,jsx_runtime_namespaceObject.jsxs)("span", { children: ["(", description, ")"] })] }));
17880
+ return ((0,jsx_runtime_namespaceObject.jsxs)("li", { className: css_className([itemClassName, 'translation-options__item']), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id, children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "check", size: "16", alt: "" }), label, " ", description && (0,jsx_runtime_namespaceObject.jsxs)("span", { children: ["(", description, ")"] })] }));
17739
17881
  };
17740
17882
  /* harmony default export */ const translation_option = (TranslationOption);
17741
17883
 
@@ -18562,7 +18704,8 @@ function FileInput({
18562
18704
  className: css_className('upload__label'),
18563
18705
  children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
18564
18706
  name: "upload",
18565
- size: "32"
18707
+ size: "32",
18708
+ alt: ""
18566
18709
  }), (0,jsx_runtime_namespaceObject.jsxs)("div", {
18567
18710
  children: [(0,jsx_runtime_namespaceObject.jsx)("span", {
18568
18711
  className: css_className(['upload__label--text']),
@@ -19305,7 +19448,8 @@ const ButtonIcon = () => {
19305
19448
  alt: ""
19306
19449
  }) : (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
19307
19450
  name: "avatar",
19308
- size: "32"
19451
+ size: "32",
19452
+ alt: ""
19309
19453
  });
19310
19454
  };
19311
19455
  const WindowOpenButton = ({
@@ -19333,10 +19477,14 @@ const WindowOpenButton = ({
19333
19477
  "aria-label": ariaLabel,
19334
19478
  "aria-hidden": isOpen,
19335
19479
  onClick: handleClick,
19336
- children: [(0,jsx_runtime_namespaceObject.jsx)("span", {
19337
- className: css_className('message-count'),
19338
- "aria-hidden": "true",
19339
- children: !!count && count
19480
+ children: [(0,jsx_runtime_namespaceObject.jsx)(in_out_transition, {
19481
+ isActive: !!count,
19482
+ transitionStartState: transitionStartStates.notRendered,
19483
+ children: (0,jsx_runtime_namespaceObject.jsx)("span", {
19484
+ className: css_className('message-count'),
19485
+ "aria-hidden": "true",
19486
+ children: count
19487
+ })
19340
19488
  }), (0,jsx_runtime_namespaceObject.jsx)(ButtonIcon, {})]
19341
19489
  })
19342
19490
  });
@@ -19980,7 +20128,8 @@ const AgentInfo = () => {
19980
20128
  alt: ""
19981
20129
  }) : (0,jsx_runtime_namespaceObject.jsx)(layout_icon, {
19982
20130
  name: "avatar",
19983
- size: "32"
20131
+ size: "32",
20132
+ alt: ""
19984
20133
  }), (0,jsx_runtime_namespaceObject.jsx)("span", {
19985
20134
  className: css_className(classNames),
19986
20135
  "aria-hidden": "true",