@webitel/ui-sdk 26.4.29 → 26.4.31

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 (89) hide show
  1. package/dist/{index-oh1_UWqX.js → index-BDiSa4-m.js} +1 -1
  2. package/dist/{index-VLBQPnjY.js → index-BgvQJ55B.js} +1 -1
  3. package/dist/{install-CEGf7rvJ.js → install-CmnYn4Q5.js} +35 -35
  4. package/dist/{isObject-C2EnTSY7.js → isObject-KF_Ebg5z.js} +1 -1
  5. package/dist/ui-sdk.css +1 -1
  6. package/dist/ui-sdk.js +1 -1
  7. package/dist/ui-sdk.umd.cjs +1 -1
  8. package/dist/{useVidstackSrc-BoI6qQaE.js → useVidstackSrc-B0xwIfTb.js} +1 -1
  9. package/dist/{vidstack-Bq6c3Bam-BcVukUvQ.js → vidstack-Bq6c3Bam-DhvXCxPV.js} +3 -3
  10. package/dist/{vidstack-D2pY00kU-DU8R3ze4.js → vidstack-D2pY00kU-sPoBbX0L.js} +3 -3
  11. package/dist/{vidstack-DDXt6fpN-CnS79_M3.js → vidstack-DDXt6fpN-BM2BGxFz.js} +2 -2
  12. package/dist/{vidstack-D_-9AA6_-BeYN7WwU.js → vidstack-D_-9AA6_-C2DgO-os.js} +2 -2
  13. package/dist/{vidstack-DqAw8m9J-bTd-oi6c.js → vidstack-DqAw8m9J-Ysy5Vb6Y.js} +1 -1
  14. package/dist/{vidstack-audio-DfV6NzrV.js → vidstack-audio-B37XwcY8.js} +2 -2
  15. package/dist/{vidstack-dash-28gycFPs.js → vidstack-dash-BXHoBGdo.js} +4 -4
  16. package/dist/{vidstack-google-cast-ORpxxhri.js → vidstack-google-cast-D9nG4uOf.js} +4 -4
  17. package/dist/{vidstack-hls-DwdoDEgJ.js → vidstack-hls-BcaqlMdk.js} +4 -4
  18. package/dist/{vidstack-video-CF8ySFTF.js → vidstack-video-DhvV6yuT.js} +3 -3
  19. package/dist/{vidstack-vimeo-DZoGSBhY.js → vidstack-vimeo-BIOQ72l9.js} +4 -4
  20. package/dist/{vidstack-youtube-Lgxw1He5.js → vidstack-youtube-LPvkuIr0.js} +3 -3
  21. package/dist/{wt-action-bar-Cbuh1LrW.js → wt-action-bar-5Y74_D0e.js} +1 -1
  22. package/dist/{wt-button-select-BFHPdkQh.js → wt-button-select-DZslcZ1V.js} +1 -1
  23. package/dist/{wt-chat-emoji-Dw7NSkjE.js → wt-chat-emoji-D3g6pOHE.js} +2 -2
  24. package/dist/{wt-confirm-dialog-B_3VrcV2.js → wt-confirm-dialog-ZFQkFkvI.js} +1 -1
  25. package/dist/{wt-context-menu-7oTcVjwZ.js → wt-context-menu-C4yrbjs6.js} +1 -1
  26. package/dist/{wt-copy-action-CI6MwBCQ.js → wt-copy-action-B4_vhvMK.js} +1 -1
  27. package/dist/{wt-datepicker-dBUNe0vY.js → wt-datepicker-B7l8plHH.js} +1 -1
  28. package/dist/{wt-display-chip-items-BdnVUJum.js → wt-display-chip-items-CfngGHWP.js} +1 -1
  29. package/dist/{wt-dual-panel-DdOQkiSq.js → wt-dual-panel-YwIAy-CK.js} +1 -1
  30. package/dist/{wt-dummy-hnpAJg3I.js → wt-dummy-CvpMQfG2.js} +1 -1
  31. package/dist/{wt-error-page-CT3Zc7Jy.js → wt-error-page-D-Y9PhH1.js} +1 -1
  32. package/dist/{wt-expansion-card-DZFDwtkW.js → wt-expansion-card-tqRrluyb.js} +1 -1
  33. package/dist/{wt-expansion-panel-C1ZTuiOS.js → wt-expansion-panel-30caNqys.js} +1 -1
  34. package/dist/{wt-filters-panel-wrapper-CsbMmdCS.js → wt-filters-panel-wrapper-D76zEG78.js} +1 -1
  35. package/dist/{wt-galleria-B6qsjlpN.js → wt-galleria-cwy7Tvf-.js} +1 -1
  36. package/dist/{wt-navigation-menu-BqFNRt-w.js → wt-navigation-menu-BYbM07l8.js} +1 -1
  37. package/dist/{wt-notifications-bar-r8RcgN82.js → wt-notifications-bar-DezuiAAo.js} +2 -2
  38. package/dist/{wt-pagination-NEieH0GI.js → wt-pagination-BGmYgSMp.js} +1 -1
  39. package/dist/{wt-player-CwNmEqGK.js → wt-player-DQ8YcvKj.js} +2 -2
  40. package/dist/{wt-screen-recordings-action-DMl4osh9.js → wt-screen-recordings-action-iak2FA0l.js} +1 -1
  41. package/dist/{wt-search-bar-Bv1WjSik.js → wt-search-bar-B_a0nLqc.js} +1 -1
  42. package/dist/{wt-selection-popup-zztv110P.js → wt-selection-popup-Bs5eyX7a.js} +1 -1
  43. package/dist/{wt-start-page-DzHHDSfC.js → wt-start-page-DfMKqk3M.js} +1 -1
  44. package/dist/{wt-status-select-Ckt-Q0nH.js → wt-status-select-zfarytHm.js} +1 -1
  45. package/dist/{wt-stepper-B1iloeAL.js → wt-stepper-DUG3Xaez.js} +1 -1
  46. package/dist/{wt-table-actions-onq158M0.js → wt-table-actions-u2XOfySQ.js} +1 -1
  47. package/dist/{wt-table-column-select-fwbVAsCI.js → wt-table-column-select-DbZqK3Qm.js} +2 -2
  48. package/dist/{wt-table-Cq8VWrhY.js → wt-table-hMzPySzt.js} +1 -1
  49. package/dist/{wt-tabs-CphZpRpb.js → wt-tabs-DTvCfvL6.js} +1 -1
  50. package/dist/{wt-tags-input-B4yiqhez.js → wt-tags-input-D3aSj0H_.js} +2 -2
  51. package/dist/{wt-timepicker-DA4j12NZ.js → wt-timepicker-CtEEP15t.js} +1 -1
  52. package/dist/{wt-tree-DkPvJwqe.js → wt-tree-DKIlJ5Lj.js} +2 -2
  53. package/dist/{wt-tree-table-CS4HF1cH.js → wt-tree-table-DBI1YzTG.js} +1 -1
  54. package/dist/{wt-type-extension-value-input-kpRyXv0R.js → wt-type-extension-value-input-D2-w-B9U.js} +2 -2
  55. package/dist/{wt-vidstack-player-CnzT-5zn.js → wt-vidstack-player-71xF8aro.js} +13 -13
  56. package/package.json +1 -1
  57. package/src/components/wt-vidstack-player/components/panels/video-display-panel/video-display-panel.vue +2 -2
  58. package/src/locale/en/en.js +1 -1
  59. package/src/locale/es/es.js +1 -1
  60. package/src/locale/kz/kz.js +1 -1
  61. package/src/locale/pl/pl.js +1 -1
  62. package/src/locale/ro/ro.js +1 -1
  63. package/src/locale/ru/ru.js +1 -1
  64. package/src/locale/uk/uk.js +1 -1
  65. package/src/locale/uz/uz.js +1 -1
  66. package/src/locale/vi/vi.js +1 -1
  67. package/src/modules/UserNotifications/api/UserNotifications.ts +18 -0
  68. package/src/modules/UserNotifications/maps/userNotificationConfigsMap.ts +16 -0
  69. package/src/modules/UserNotifications/stores/__tests__/userNotificationsStore.spec.ts +118 -0
  70. package/src/modules/UserNotifications/stores/userNotificationsStore.ts +76 -0
  71. package/src/modules/UserNotifications/types/UserNotifications.ts +15 -0
  72. package/src/modules/Userinfo/stores/__tests__/UserinfoAccessControl.spec.ts +19 -11
  73. package/src/modules/Userinfo/stores/userinfoStore.ts +10 -1
  74. package/types/locale/en/en.d.ts +1 -1
  75. package/types/locale/es/es.d.ts +1 -1
  76. package/types/locale/i18n.d.ts +9 -9
  77. package/types/locale/index.d.ts +9 -9
  78. package/types/locale/kz/kz.d.ts +1 -1
  79. package/types/locale/pl/pl.d.ts +1 -1
  80. package/types/locale/ro/ro.d.ts +1 -1
  81. package/types/locale/ru/ru.d.ts +1 -1
  82. package/types/locale/uk/uk.d.ts +1 -1
  83. package/types/locale/uz/uz.d.ts +1 -1
  84. package/types/locale/vi/vi.d.ts +1 -1
  85. package/types/modules/UserNotifications/api/UserNotifications.d.ts +2 -0
  86. package/types/modules/UserNotifications/maps/userNotificationConfigsMap.d.ts +1 -0
  87. package/types/modules/UserNotifications/stores/userNotificationsStore.d.ts +105 -0
  88. package/types/modules/UserNotifications/types/UserNotifications.d.ts +13 -0
  89. package/types/modules/Userinfo/stores/userinfoStore.d.ts +4 -1
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as lt, inject as ye, createElementBlock as ft, openBlock as G, normalizeClass as be, unref as ot, createElementVNode as at, renderSlot as pt, createVNode as U, useTemplateRef as _i, onMounted as Ii, onBeforeUnmount as Vi, createBlock as Ut, createCommentVNode as Kt, toDisplayString as Di, createSlots as Ds, withCtx as Qt, resolveComponent as Ri, ref as us, provide as Oi, toRefs as Ni } from "vue";
2
- import { a as q, c as gt, i as B, b as Ie, d as S, e as nt, f as Ve, l as O, s as te, g as Rs, E as Os, D as L, h as Q, o as P, j as Hi, k as f, m as l, n as M, p as Ns, q as Fi, r as he, t as W, V as J, v as w, C as b, S as yt, w as Vt, x as p, y as rt, z, I as Hs, A as Bi, B as Gi, F as tt, G as Ge, H as Fs, J as ps, K as Ue, L as Bs, M as kt, N as Ke, O as ce, P as Ui, Q as xt, R as Ki, U as Qi, W as Wi, X as zi, Y as ji, Z as Yi, _ as Xi, $ as Ji, a0 as Zi, a1 as Gs, a2 as T, a3 as _, a4 as ue, a5 as ta, a6 as Dt, a7 as K, a8 as ea, a9 as sa, aa as ia, ab as aa, ac as ms, ad as na, ae as ra, af as v, ag as y, ah as oa, ai as ha, T as la, u as da } from "./useVidstackSrc-BoI6qQaE.js";
3
- import { T as ca, U as ua, V as pa, X as ma, _ as dt, Q as jt, Y as fa, C as Y } from "./install-CEGf7rvJ.js";
2
+ import { a as q, c as gt, i as B, b as Ie, d as S, e as nt, f as Ve, l as O, s as te, g as Rs, E as Os, D as L, h as Q, o as P, j as Hi, k as f, m as l, n as M, p as Ns, q as Fi, r as he, t as W, V as J, v as w, C as b, S as yt, w as Vt, x as p, y as rt, z, I as Hs, A as Bi, B as Gi, F as tt, G as Ge, H as Fs, J as ps, K as Ue, L as Bs, M as kt, N as Ke, O as ce, P as Ui, Q as xt, R as Ki, U as Qi, W as Wi, X as zi, Y as ji, Z as Yi, _ as Xi, $ as Ji, a0 as Zi, a1 as Gs, a2 as T, a3 as _, a4 as ue, a5 as ta, a6 as Dt, a7 as K, a8 as ea, a9 as sa, aa as ia, ab as aa, ac as ms, ad as na, ae as ra, af as v, ag as y, ah as oa, ai as ha, T as la, u as da } from "./useVidstackSrc-B0xwIfTb.js";
3
+ import { T as ca, U as ua, V as pa, X as ma, _ as dt, Q as jt, Y as fa, C as Y } from "./install-CmnYn4Q5.js";
4
4
  import { _ as ga } from "./wt-slider.vue_vue_type_script_setup_true_lang-DlaRDHxo.js";
5
5
  const Us = gt();
6
6
  function $() {
@@ -2070,7 +2070,7 @@ class un {
2070
2070
  return "audio";
2071
2071
  }
2072
2072
  async load(t) {
2073
- return new (await import("./vidstack-audio-DfV6NzrV.js")).AudioProvider(this.target, t);
2073
+ return new (await import("./vidstack-audio-B37XwcY8.js")).AudioProvider(this.target, t);
2074
2074
  }
2075
2075
  }
2076
2076
  class je {
@@ -2083,7 +2083,7 @@ class je {
2083
2083
  return "video";
2084
2084
  }
2085
2085
  async load(t) {
2086
- return new (await import("./vidstack-video-CF8ySFTF.js")).VideoProvider(this.target, t);
2086
+ return new (await import("./vidstack-video-DhvV6yuT.js")).VideoProvider(this.target, t);
2087
2087
  }
2088
2088
  }
2089
2089
  class Ye extends je {
@@ -2093,7 +2093,7 @@ class Ye extends je {
2093
2093
  return Ye.supported && Ge(t);
2094
2094
  }
2095
2095
  async load(t) {
2096
- return new (await import("./vidstack-hls-DwdoDEgJ.js")).HLSProvider(this.target, t);
2096
+ return new (await import("./vidstack-hls-BcaqlMdk.js")).HLSProvider(this.target, t);
2097
2097
  }
2098
2098
  }
2099
2099
  class Xe extends je {
@@ -2103,7 +2103,7 @@ class Xe extends je {
2103
2103
  return Xe.supported && Ue(t);
2104
2104
  }
2105
2105
  async load(t) {
2106
- return new (await import("./vidstack-dash-28gycFPs.js")).DASHProvider(this.target, t);
2106
+ return new (await import("./vidstack-dash-BXHoBGdo.js")).DASHProvider(this.target, t);
2107
2107
  }
2108
2108
  }
2109
2109
  class pn {
@@ -2125,7 +2125,7 @@ class pn {
2125
2125
  return "video";
2126
2126
  }
2127
2127
  async load(t) {
2128
- return new (await import("./vidstack-vimeo-DZoGSBhY.js")).VimeoProvider(this.target, t);
2128
+ return new (await import("./vidstack-vimeo-BIOQ72l9.js")).VimeoProvider(this.target, t);
2129
2129
  }
2130
2130
  async loadPoster(t, e, s) {
2131
2131
  const { resolveVimeoVideoId: i, getVimeoVideoInfo: n } = await import("./vidstack-krOAtKMi-C50BTxmn.js");
@@ -2157,7 +2157,7 @@ class mn {
2157
2157
  return "video";
2158
2158
  }
2159
2159
  async load(t) {
2160
- return new (await import("./vidstack-youtube-Lgxw1He5.js")).YouTubeProvider(this.target, t);
2160
+ return new (await import("./vidstack-youtube-LPvkuIr0.js")).YouTubeProvider(this.target, t);
2161
2161
  }
2162
2162
  async loadPoster(t, e, s) {
2163
2163
  const { findYouTubePoster: i, resolveYouTubeVideoId: n } = await import("./vidstack-Dm1xEU9Q-CXHNvShT.js"), r = S(t.src) && n(t.src);
@@ -2625,7 +2625,7 @@ class vn extends Ct {
2625
2625
  throw i.code = "CAST_NOT_AVAILABLE", i;
2626
2626
  }
2627
2627
  if (ee("https://www.gstatic.com"), !this.#v) {
2628
- const i = await import("./vidstack-D2pY00kU-DU8R3ze4.js").then((n) => n.v);
2628
+ const i = await import("./vidstack-D2pY00kU-sPoBbX0L.js").then((n) => n.v);
2629
2629
  this.#v = new i.GoogleCastLoader();
2630
2630
  }
2631
2631
  await this.#v.prompt(this.#s), t && this.#e.queue.enqueue("media-google-cast-request", t);
@@ -8022,7 +8022,7 @@ class Lr extends v(HTMLElement, ai) {
8022
8022
  if (this.#e?.classList.contains("vds-google-cast"))
8023
8023
  return this.#e;
8024
8024
  const t = document.createElement("div");
8025
- return t.classList.add("vds-google-cast"), import("./vidstack-D_-9AA6_-BeYN7WwU.js").then(({ insertContent: e }) => {
8025
+ return t.classList.add("vds-google-cast"), import("./vidstack-D_-9AA6_-C2DgO-os.js").then(({ insertContent: e }) => {
8026
8026
  e(t, this.#t.$state);
8027
8027
  }), t;
8028
8028
  }
@@ -8850,8 +8850,8 @@ const zo = { class: "controls-group__actions" }, jo = /* @__PURE__ */ lt({
8850
8850
  U(Jo, { onToggle: o }),
8851
8851
  n.hideExpand ? Kt("", !0) : (G(), Ut(eh, {
8852
8852
  key: 0,
8853
- "primary-icon": "collapse",
8854
- "secondary-icon": "expand",
8853
+ "primary-icon": "expand",
8854
+ "secondary-icon": "collapse",
8855
8855
  color: "on-dark",
8856
8856
  onToggle: h
8857
8857
  })),
@@ -8864,7 +8864,7 @@ const zo = { class: "controls-group__actions" }, jo = /* @__PURE__ */ lt({
8864
8864
  ])
8865
8865
  ], 2));
8866
8866
  }
8867
- }), rh = /* @__PURE__ */ dt(nh, [["__scopeId", "data-v-3e22e98c"]]), oh = { class: "video-display-panel-wrapper" }, hh = { class: "video-layout-content" }, lh = { class: "video-layout-controls" }, dh = /* @__PURE__ */ lt({
8867
+ }), rh = /* @__PURE__ */ dt(nh, [["__scopeId", "data-v-bb1a9cc4"]]), oh = { class: "video-display-panel-wrapper" }, hh = { class: "video-layout-content" }, lh = { class: "video-layout-controls" }, dh = /* @__PURE__ */ lt({
8868
8868
  __name: "video-layout",
8869
8869
  props: {
8870
8870
  title: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "26.4.29",
3
+ "version": "26.4.31",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "make-all": "npm version patch --git-tag-version false && npm run build && (npm run build:types || true) && (npm run biome:format:all || true) && npm run publish-lib",
@@ -24,8 +24,8 @@
24
24
  />
25
25
  <toggle-button
26
26
  v-if="!props.hideExpand"
27
- primary-icon="collapse"
28
- secondary-icon="expand"
27
+ primary-icon="expand"
28
+ secondary-icon="collapse"
29
29
  color="on-dark"
30
30
  @toggle="handlePlayerSize"
31
31
  />
@@ -851,7 +851,7 @@ export default deepmerge(
851
851
  delete: ({ named }) =>
852
852
  `The ${named('entity').toLowerCase()} was deleted`,
853
853
  },
854
- info: {
854
+ warnings: {
855
855
  passwordExpirationMessage: 'Your password will expire in { days } days',
856
856
  },
857
857
  },
@@ -837,7 +837,7 @@ export default {
837
837
  delete: ({ named }) =>
838
838
  `El ${named('entity').toLowerCase()} fue eliminado`,
839
839
  },
840
- info: {
840
+ warnings: {
841
841
  passwordExpirationMessage: 'Tu contraseña expirará en { days } días',
842
842
  },
843
843
  },
@@ -838,7 +838,7 @@ export default {
838
838
  create: ({ named }) => `${named('entity').toLowerCase()} сақталды`,
839
839
  delete: ({ named }) => `${named('entity').toLowerCase()} жойылды`,
840
840
  },
841
- info: {
841
+ warnings: {
842
842
  passwordExpirationMessage:
843
843
  'Сіздің құпия сөзіңіз { days } күннен кейін мерзімі аяқталады',
844
844
  },
@@ -838,7 +838,7 @@ export default {
838
838
  create: ({ named }) => `${named('entity').toLowerCase()} został zapisany`,
839
839
  delete: ({ named }) => `${named('entity').toLowerCase()} został usunięty`,
840
840
  },
841
- info: {
841
+ warnings: {
842
842
  passwordExpirationMessage: 'Twoje hasło wygaśnie za { days } dni',
843
843
  },
844
844
  },
@@ -843,7 +843,7 @@ export default {
843
843
  create: ({ named }) => `${named('entity').toLowerCase()} a fost salvat`,
844
844
  delete: ({ named }) => `${named('entity').toLowerCase()} a fost șters`,
845
845
  },
846
- info: {
846
+ warnings: {
847
847
  passwordExpirationMessage: 'Parola ta va expira în { days } zile',
848
848
  },
849
849
  },
@@ -833,7 +833,7 @@ export default {
833
833
  create: ({ named }) => `${named('entity')} был сохранён`,
834
834
  delete: ({ named }) => `${named('entity')} был удалён`,
835
835
  },
836
- info: {
836
+ warnings: {
837
837
  passwordExpirationMessage: 'Ваш пароль истечёт через { days } дн(я/ей)',
838
838
  },
839
839
  },
@@ -832,7 +832,7 @@ export default {
832
832
  create: ({ named }) => `${named('entity')} було збережено`,
833
833
  delete: ({ named }) => `${named('entity')} було видалено`,
834
834
  },
835
- info: {
835
+ warnings: {
836
836
  passwordExpirationMessage: 'Пароль спливе через { days } дн(і/ів)',
837
837
  },
838
838
  },
@@ -841,7 +841,7 @@ export default {
841
841
  create: ({ named }) => `${named('entity').toLowerCase()} saqlandi`,
842
842
  delete: ({ named }) => `${named('entity').toLowerCase()} o'chirildi`,
843
843
  },
844
- info: {
844
+ warnings: {
845
845
  passwordExpirationMessage:
846
846
  'Parolingiz { days } kundan keyin amal qilishdan chiqadi',
847
847
  },
@@ -841,7 +841,7 @@ export default {
841
841
  create: ({ named }) => `${named('entity').toLowerCase()} đã được lưu`,
842
842
  delete: ({ named }) => `${named('entity').toLowerCase()} đã bị xóa`,
843
843
  },
844
- info: {
844
+ warnings: {
845
845
  passwordExpirationMessage:
846
846
  'Mật khẩu của bạn sẽ hết hạn sau { days } ngày',
847
847
  },
@@ -0,0 +1,18 @@
1
+ import {
2
+ applyTransform,
3
+ snakeToCamel,
4
+ } from '@webitel/api-services/api/transformers';
5
+ import { getUsers } from '@webitel/api-services/gen';
6
+
7
+ const getUserWarnings = async () => {
8
+ try {
9
+ const response = await getUsers().getUserWarnings();
10
+ return applyTransform(response.data, [
11
+ snakeToCamel(),
12
+ ]);
13
+ } catch (err) {
14
+ throw applyTransform(err, []);
15
+ }
16
+ };
17
+
18
+ export { getUserWarnings };
@@ -0,0 +1,16 @@
1
+ import { ApiUserWarningId } from '@webitel/api-services/gen/models';
2
+ import type { UserNotificationsConfigsMap } from '../types/UserWarnings';
3
+
4
+ export const USER_NOTIFICATION_CONFIGS_MAP = new Map<
5
+ string,
6
+ UserNotificationsConfigsMap
7
+ >([
8
+ [
9
+ ApiUserWarningId.PasswordExpiresSoon,
10
+ {
11
+ type: 'info',
12
+ localeKey: 'passwordExpirationMessage',
13
+ getDays: (warningData) => warningData.passwordExpiry.daysRemaining || 0,
14
+ },
15
+ ],
16
+ ]);
@@ -0,0 +1,118 @@
1
+ import { ApiUserWarningId } from '@webitel/api-services/gen/models';
2
+ import { createPinia, setActivePinia } from 'pinia';
3
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
4
+ import { createApp } from 'vue';
5
+
6
+ type ViMock = ReturnType<typeof vi.fn>;
7
+
8
+ // Mocks for modules used by the store
9
+ vi.mock('../../api/UserNotifications', () => {
10
+ return {
11
+ getUserWarnings: vi.fn(),
12
+ };
13
+ });
14
+
15
+ vi.mock('../../../../locale/i18n', () => {
16
+ return {
17
+ default: {
18
+ global: {
19
+ t: (key: string, payload?: number) =>
20
+ `${key}:${JSON.stringify(payload)}`,
21
+ },
22
+ },
23
+ };
24
+ });
25
+
26
+ vi.mock('../../../../scripts/eventBus', () => {
27
+ const emitMock = vi.fn();
28
+ return {
29
+ default: {
30
+ $on: vi.fn(),
31
+ $off: vi.fn(),
32
+ $emit: emitMock,
33
+ },
34
+ };
35
+ });
36
+
37
+ import eventBus from '../../../../scripts/eventBus';
38
+ import { getUserWarnings } from '../../api/UserNotifications';
39
+ import { USER_NOTIFICATION_CONFIGS_MAP } from '../../maps/userNotificationConfigsMap';
40
+ import { createUserNotificationsStore } from '../userNotificationsStore';
41
+
42
+ describe('createUserNotificationsStore', () => {
43
+ let useStore: ReturnType<typeof createUserNotificationsStore>;
44
+ let pinia: ReturnType<typeof createPinia>;
45
+
46
+ beforeEach(() => {
47
+ vi.clearAllMocks();
48
+
49
+ pinia = createPinia();
50
+ const app = createApp({});
51
+ app.use(pinia);
52
+ setActivePinia(pinia);
53
+
54
+ useStore = createUserNotificationsStore();
55
+ });
56
+
57
+ it('fetch should call API and populate notifications', async () => {
58
+ // Arrange: mock API to return warnings
59
+ const notificationsResponse = {
60
+ warnings: [
61
+ {
62
+ id: ApiUserWarningId.PasswordExpiresSoon,
63
+ warningData: {
64
+ passwordExpiry: {
65
+ daysRemaining: 5,
66
+ },
67
+ },
68
+ },
69
+ ],
70
+ };
71
+
72
+ (getUserWarnings as ViMock).mockResolvedValue(notificationsResponse);
73
+
74
+ const store = useStore();
75
+
76
+ // Act
77
+ await store.initialize();
78
+
79
+ // Assert
80
+ expect(store.notifications.length).toBe(1);
81
+ expect(store.notifications[0].days).toBe(5);
82
+ expect(store.notifications[0].localeKey).toBe(
83
+ USER_NOTIFICATION_CONFIGS_MAP.get(ApiUserWarningId.PasswordExpiresSoon)
84
+ ?.localeKey,
85
+ );
86
+ expect(getUserWarnings).toHaveBeenCalledOnce();
87
+ });
88
+
89
+ it('show should emit notification for mapped warnings', async () => {
90
+ const notificationsResponse = {
91
+ warnings: [
92
+ {
93
+ id: ApiUserWarningId.PasswordExpiresSoon,
94
+ warningData: {
95
+ passwordExpiry: {
96
+ daysRemaining: 3,
97
+ },
98
+ },
99
+ },
100
+ ],
101
+ };
102
+
103
+ (getUserWarnings as ViMock).mockResolvedValue(notificationsResponse);
104
+
105
+ const store = useStore();
106
+ await store.initialize();
107
+
108
+ // Act: show should emit once
109
+ store.show();
110
+ expect(eventBus.$emit).toHaveBeenCalledOnce();
111
+ const [[eventName, payload]] = (eventBus.$emit as ViMock).mock.calls;
112
+ expect(eventName).toBe('notification');
113
+ expect(payload.type).toBe('info');
114
+ expect(payload.text).toContain(
115
+ 'systemNotifications.warnings.passwordExpirationMessage',
116
+ );
117
+ });
118
+ });
@@ -0,0 +1,76 @@
1
+ import type { ApiUserWarning } from '@webitel/api-services/gen/models';
2
+ import { defineStore } from 'pinia';
3
+ import { computed, ref } from 'vue';
4
+ import i18n from '../../../locale/i18n';
5
+ import eventBus from '../../../scripts/eventBus';
6
+ import { getUserWarnings } from '../api/UserNotifications';
7
+ import { USER_NOTIFICATION_CONFIGS_MAP } from '../maps/userNotificationConfigsMap';
8
+ import type {
9
+ NotificationsType,
10
+ UserNotificationsConfigsMap,
11
+ } from '../types/UserNotifications';
12
+
13
+ export const createUserNotificationsStore = () => {
14
+ const namespace = 'userNotifications';
15
+
16
+ const store = defineStore(namespace, () => {
17
+ const rawNotifications = ref<ApiUserWarning[]>([]);
18
+
19
+ const initialize = async () => {
20
+ await fetch();
21
+ };
22
+
23
+ const fetch = async () => {
24
+ const response = await getUserWarnings();
25
+ rawNotifications.value =
26
+ (response && (response.warnings as ApiUserWarning[])) ?? [];
27
+ };
28
+
29
+ const notifications = computed<NotificationsType[]>(() => {
30
+ return rawNotifications.value
31
+ .map((notification) => {
32
+ const config: UserNotificationsConfigsMap =
33
+ USER_NOTIFICATION_CONFIGS_MAP.get(notification.id);
34
+ if (!config) return null;
35
+
36
+ return {
37
+ type: config.type,
38
+ localeKey: config.localeKey,
39
+ days: config.getDays(notification.warningData),
40
+ shown: false,
41
+ };
42
+ })
43
+ .filter(Boolean) as NotificationsType[];
44
+ });
45
+
46
+ const show = () => {
47
+ notifications.value.forEach((notification) => {
48
+ // @author @Lera24
49
+ //notification should only be displayed the first time you visit the page
50
+ if (notification.shown) return;
51
+
52
+ eventBus.$emit('notification', {
53
+ type: notification.type,
54
+ text: i18n.global.t(
55
+ `systemNotifications.warnings.${notification.localeKey}`,
56
+ {
57
+ days: notification.days,
58
+ },
59
+ ),
60
+ });
61
+ notification.shown = true;
62
+ });
63
+ };
64
+
65
+ return {
66
+ initialize,
67
+ show,
68
+
69
+ /** internal for devtools/debug */
70
+ rawNotifications,
71
+ notifications,
72
+ };
73
+ });
74
+
75
+ return store;
76
+ };
@@ -0,0 +1,15 @@
1
+ interface UserNotificationsConfigsMap {
2
+ id: string;
3
+ type: 'info' | 'warning' | 'error';
4
+ localeKey: string;
5
+ getDays: (warningData: number) => number;
6
+ }
7
+
8
+ interface NotificationsType {
9
+ type: 'info' | 'warning' | 'error';
10
+ localeKey: string;
11
+ days: number;
12
+ shown?: boolean;
13
+ }
14
+
15
+ export type { NotificationsType, UserNotificationsConfigsMap };
@@ -3,6 +3,25 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
4
  import { createUserinfoStore } from '../userinfoStore';
5
5
 
6
+ // Mock modules at top-level so vitest hoists them before imports
7
+ vi.mock('../../api/UserinfoAPI', () => ({
8
+ getSession: vi.fn().mockResolvedValue({
9
+ userId: 1,
10
+ username: 'test',
11
+ permissions: [],
12
+ scope: [],
13
+ access: {},
14
+ license: [],
15
+ }),
16
+ getUiVisibilityAccess: vi.fn().mockResolvedValue({}),
17
+ }));
18
+
19
+ vi.mock('../../../UserWarnings/api/UserWarnings', () => ({
20
+ getUserWarnings: vi.fn().mockResolvedValue({
21
+ warnings: [],
22
+ }),
23
+ }));
24
+
6
25
  describe('UserinfoAccessControl', () => {
7
26
  let useUserinfoStore: ReturnType<typeof createUserinfoStore>;
8
27
 
@@ -13,17 +32,6 @@ describe('UserinfoAccessControl', () => {
13
32
  });
14
33
 
15
34
  it('should be defined', async () => {
16
- vi.mock(import('../../api/UserinfoAPI'), () => ({
17
- getSession: vi.fn().mockResolvedValue({
18
- userId: 1,
19
- username: 'test',
20
- permissions: [],
21
- scope: [],
22
- access: {},
23
- license: [],
24
- }),
25
- getUiVisibilityAccess: vi.fn().mockResolvedValue({}),
26
- }));
27
35
  const userinfoStore = useUserinfoStore();
28
36
  const { initialize } = userinfoStore;
29
37
  const { userId } = storeToRefs(userinfoStore);
@@ -1,7 +1,7 @@
1
1
  import pick from 'lodash/pick';
2
2
  import { defineStore, storeToRefs } from 'pinia';
3
3
  import { ref } from 'vue';
4
-
4
+ import { createUserNotificationsStore } from '../../UserNotifications/stores/userNotificationsStore';
5
5
  import { getSession, getUiVisibilityAccess, logout } from '../api/UserinfoAPI';
6
6
  import { createUserAccessStore } from './accessStore';
7
7
  import { createSettingsStore } from './settingsStore';
@@ -15,6 +15,8 @@ export const createUserinfoStore = () => {
15
15
  namespace,
16
16
  });
17
17
 
18
+ const useUserNotificationsStore = createUserNotificationsStore();
19
+
18
20
  const store = defineStore(namespace, () => {
19
21
  const accessStore = useAccessStore();
20
22
  const {
@@ -34,6 +36,11 @@ export const createUserinfoStore = () => {
34
36
  const settingsStore = useSettingsStore();
35
37
  const { initialize: initializeSettingsStore } = settingsStore;
36
38
  const { timezone } = storeToRefs(settingsStore);
39
+ const userNotificationsStore = useUserNotificationsStore();
40
+ const {
41
+ initialize: initializeUserNotificationsStore,
42
+ show: showUserNotifications,
43
+ } = userNotificationsStore;
37
44
 
38
45
  const userId = ref();
39
46
  const userInfo = ref();
@@ -41,6 +48,7 @@ export const createUserinfoStore = () => {
41
48
  const initialize = async () => {
42
49
  const session = await getSession();
43
50
  const access = await getUiVisibilityAccess();
51
+ await initializeUserNotificationsStore();
44
52
 
45
53
  userId.value = session.userId;
46
54
  userInfo.value = pick(session, [
@@ -89,6 +97,7 @@ export const createUserinfoStore = () => {
89
97
  hasSpecialGlobalActionAccess,
90
98
  hasApplicationVisibility,
91
99
  logoutUser,
100
+ showUserNotifications,
92
101
  };
93
102
  });
94
103
 
@@ -798,7 +798,7 @@ declare const _default: {
798
798
  named: any;
799
799
  }) => string;
800
800
  };
801
- info: {
801
+ warnings: {
802
802
  passwordExpirationMessage: string;
803
803
  };
804
804
  };
@@ -915,7 +915,7 @@ declare namespace _default {
915
915
  export { _delete_2 as delete };
916
916
  }
917
917
  export { success_1 as success };
918
- export namespace info {
918
+ export namespace warnings {
919
919
  let passwordExpirationMessage: string;
920
920
  }
921
921
  }
@@ -799,7 +799,7 @@ declare const _default: import("vue-i18n").I18n<{
799
799
  named: any;
800
800
  }) => string;
801
801
  };
802
- info: {
802
+ warnings: {
803
803
  passwordExpirationMessage: string;
804
804
  };
805
805
  };
@@ -1623,7 +1623,7 @@ declare const _default: import("vue-i18n").I18n<{
1623
1623
  named: any;
1624
1624
  }) => string;
1625
1625
  };
1626
- info: {
1626
+ warnings: {
1627
1627
  passwordExpirationMessage: string;
1628
1628
  };
1629
1629
  };
@@ -2431,7 +2431,7 @@ declare const _default: import("vue-i18n").I18n<{
2431
2431
  named: any;
2432
2432
  }) => string;
2433
2433
  };
2434
- info: {
2434
+ warnings: {
2435
2435
  passwordExpirationMessage: string;
2436
2436
  };
2437
2437
  };
@@ -3241,7 +3241,7 @@ declare const _default: import("vue-i18n").I18n<{
3241
3241
  named: any;
3242
3242
  }) => string;
3243
3243
  };
3244
- info: {
3244
+ warnings: {
3245
3245
  passwordExpirationMessage: string;
3246
3246
  };
3247
3247
  };
@@ -4049,7 +4049,7 @@ declare const _default: import("vue-i18n").I18n<{
4049
4049
  named: any;
4050
4050
  }) => string;
4051
4051
  };
4052
- info: {
4052
+ warnings: {
4053
4053
  passwordExpirationMessage: string;
4054
4054
  };
4055
4055
  };
@@ -4859,7 +4859,7 @@ declare const _default: import("vue-i18n").I18n<{
4859
4859
  named: any;
4860
4860
  }) => string;
4861
4861
  };
4862
- info: {
4862
+ warnings: {
4863
4863
  passwordExpirationMessage: string;
4864
4864
  };
4865
4865
  };
@@ -5669,7 +5669,7 @@ declare const _default: import("vue-i18n").I18n<{
5669
5669
  named: any;
5670
5670
  }) => string;
5671
5671
  };
5672
- info: {
5672
+ warnings: {
5673
5673
  passwordExpirationMessage: string;
5674
5674
  };
5675
5675
  };
@@ -6480,7 +6480,7 @@ declare const _default: import("vue-i18n").I18n<{
6480
6480
  named: any;
6481
6481
  }) => string;
6482
6482
  };
6483
- info: {
6483
+ warnings: {
6484
6484
  passwordExpirationMessage: string;
6485
6485
  };
6486
6486
  };
@@ -7290,7 +7290,7 @@ declare const _default: import("vue-i18n").I18n<{
7290
7290
  named: any;
7291
7291
  }) => string;
7292
7292
  };
7293
- info: {
7293
+ warnings: {
7294
7294
  passwordExpirationMessage: string;
7295
7295
  };
7296
7296
  };