@peassoft/mnr-web-topline 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +44 -0
  2. package/dist/css/index.css +192 -0
  3. package/dist/en/hooks/use-topline/index.d.ts +11 -0
  4. package/dist/en/hooks/use-topline/index.js +14 -0
  5. package/dist/en/index.d.ts +8 -0
  6. package/dist/en/index.js +5 -0
  7. package/dist/en/modules/env/index.d.ts +12 -0
  8. package/dist/en/modules/env/index.js +27 -0
  9. package/dist/en/modules/focus-marshal/index.d.ts +6 -0
  10. package/dist/en/modules/focus-marshal/index.js +6 -0
  11. package/dist/en/modules/keyboard-navigation/key-codes.d.ts +18 -0
  12. package/dist/en/modules/keyboard-navigation/key-codes.js +18 -0
  13. package/dist/en/modules/keyboard-navigation/vertical-menu.d.ts +14 -0
  14. package/dist/en/modules/keyboard-navigation/vertical-menu.js +45 -0
  15. package/dist/en/modules/local-db/actions/delete-all-data/index.d.ts +4 -0
  16. package/dist/en/modules/local-db/actions/delete-all-data/index.js +21 -0
  17. package/dist/en/modules/local-db/actions/get-all-data/index.d.ts +11 -0
  18. package/dist/en/modules/local-db/actions/get-all-data/index.js +51 -0
  19. package/dist/en/modules/local-db/actions/update-grant-token/index.d.ts +4 -0
  20. package/dist/en/modules/local-db/actions/update-grant-token/index.js +26 -0
  21. package/dist/en/modules/local-db/actions/update-refresh-token/index.d.ts +4 -0
  22. package/dist/en/modules/local-db/actions/update-refresh-token/index.js +26 -0
  23. package/dist/en/modules/local-db/actions/update-user/index.d.ts +5 -0
  24. package/dist/en/modules/local-db/actions/update-user/index.js +26 -0
  25. package/dist/en/modules/local-db/create-request-error.d.ts +5 -0
  26. package/dist/en/modules/local-db/create-request-error.js +9 -0
  27. package/dist/en/modules/local-db/index.d.ts +6 -0
  28. package/dist/en/modules/local-db/index.js +6 -0
  29. package/dist/en/modules/local-db/init-db.d.ts +17 -0
  30. package/dist/en/modules/local-db/init-db.js +52 -0
  31. package/dist/en/modules/logger/index.d.ts +1 -0
  32. package/dist/en/modules/logger/index.js +3 -0
  33. package/dist/en/modules/request/index.d.ts +20 -0
  34. package/dist/en/modules/request/index.js +78 -0
  35. package/dist/en/modules/request/normalize-request-opts.d.ts +5 -0
  36. package/dist/en/modules/request/normalize-request-opts.js +11 -0
  37. package/dist/en/modules/request/should-retry.d.ts +6 -0
  38. package/dist/en/modules/request/should-retry.js +16 -0
  39. package/dist/en/modules/request/types.d.ts +20 -0
  40. package/dist/en/modules/request/types.js +1 -0
  41. package/dist/en/modules/tokens/index.d.ts +4 -0
  42. package/dist/en/modules/tokens/index.js +14 -0
  43. package/dist/en/modules/topline-service/index.d.ts +24 -0
  44. package/dist/en/modules/topline-service/index.js +46 -0
  45. package/dist/en/modules/topline-service/inner-service.d.ts +45 -0
  46. package/dist/en/modules/topline-service/inner-service.js +219 -0
  47. package/dist/en/modules/topline-service/types.d.ts +32 -0
  48. package/dist/en/modules/topline-service/types.js +19 -0
  49. package/dist/en/modules/validators/email.d.ts +4 -0
  50. package/dist/en/modules/validators/email.js +7 -0
  51. package/dist/en/modules/validators/password-recovery-code.d.ts +4 -0
  52. package/dist/en/modules/validators/password-recovery-code.js +6 -0
  53. package/dist/en/modules/validators/password.d.ts +4 -0
  54. package/dist/en/modules/validators/password.js +6 -0
  55. package/dist/en/modules/websocket/index.d.ts +4 -0
  56. package/dist/en/modules/websocket/index.js +92 -0
  57. package/dist/en/parts/login/actions/perform-login/index.d.ts +27 -0
  58. package/dist/en/parts/login/actions/perform-login/index.js +60 -0
  59. package/dist/en/parts/login/index.d.ts +1 -0
  60. package/dist/en/parts/login/index.js +1 -0
  61. package/dist/en/parts/login/ui/login/index.d.ts +8 -0
  62. package/dist/en/parts/login/ui/login/index.js +138 -0
  63. package/dist/en/parts/logout/actions/perform-logout/index.d.ts +23 -0
  64. package/dist/en/parts/logout/actions/perform-logout/index.js +54 -0
  65. package/dist/en/parts/logout/actions/perform-logout/make-second-attempt.d.ts +1 -0
  66. package/dist/en/parts/logout/actions/perform-logout/make-second-attempt.js +3 -0
  67. package/dist/en/parts/logout/index.d.ts +1 -0
  68. package/dist/en/parts/logout/index.js +1 -0
  69. package/dist/en/parts/password-recovery/actions/create-claim/index.d.ts +22 -0
  70. package/dist/en/parts/password-recovery/actions/create-claim/index.js +41 -0
  71. package/dist/en/parts/password-recovery/actions/save-password/index.d.ts +27 -0
  72. package/dist/en/parts/password-recovery/actions/save-password/index.js +61 -0
  73. package/dist/en/parts/password-recovery/index.d.ts +1 -0
  74. package/dist/en/parts/password-recovery/index.js +1 -0
  75. package/dist/en/parts/password-recovery/ui/password-recovery/index.d.ts +6 -0
  76. package/dist/en/parts/password-recovery/ui/password-recovery/index.js +33 -0
  77. package/dist/en/parts/password-recovery/ui/step-one/index.d.ts +7 -0
  78. package/dist/en/parts/password-recovery/ui/step-one/index.js +82 -0
  79. package/dist/en/parts/password-recovery/ui/step-two/index.d.ts +7 -0
  80. package/dist/en/parts/password-recovery/ui/step-two/index.js +134 -0
  81. package/dist/en/parts/shell/actions/refresh-user/has-user-been-changed.d.ts +5 -0
  82. package/dist/en/parts/shell/actions/refresh-user/has-user-been-changed.js +6 -0
  83. package/dist/en/parts/shell/actions/refresh-user/index.d.ts +28 -0
  84. package/dist/en/parts/shell/actions/refresh-user/index.js +79 -0
  85. package/dist/en/parts/shell/actions/refresh-user/make-second-attempt.d.ts +2 -0
  86. package/dist/en/parts/shell/actions/refresh-user/make-second-attempt.js +3 -0
  87. package/dist/en/parts/shell/context.d.ts +12 -0
  88. package/dist/en/parts/shell/context.js +8 -0
  89. package/dist/en/parts/shell/index.d.ts +2 -0
  90. package/dist/en/parts/shell/index.js +2 -0
  91. package/dist/en/parts/shell/ui/logged-out-user-menu/index.d.ts +8 -0
  92. package/dist/en/parts/shell/ui/logged-out-user-menu/index.js +42 -0
  93. package/dist/en/parts/shell/ui/loggeg-in-user-menu/index.d.ts +8 -0
  94. package/dist/en/parts/shell/ui/loggeg-in-user-menu/index.js +42 -0
  95. package/dist/en/parts/shell/ui/logo/index.d.ts +1 -0
  96. package/dist/en/parts/shell/ui/logo/index.js +8 -0
  97. package/dist/en/parts/shell/ui/logo/logo-full.d.ts +2 -0
  98. package/dist/en/parts/shell/ui/logo/logo-full.js +26 -0
  99. package/dist/en/parts/shell/ui/logo/logo-short.d.ts +2 -0
  100. package/dist/en/parts/shell/ui/logo/logo-short.js +26 -0
  101. package/dist/en/parts/shell/ui/shell/index.d.ts +2 -0
  102. package/dist/en/parts/shell/ui/shell/index.js +187 -0
  103. package/dist/en/parts/shell/ui/user-avatar/index.d.ts +7 -0
  104. package/dist/en/parts/shell/ui/user-avatar/index.js +48 -0
  105. package/dist/en/parts/shell/ui/user-menu/index.d.ts +8 -0
  106. package/dist/en/parts/shell/ui/user-menu/index.js +37 -0
  107. package/dist/en/parts/shell/ui/user-menu-item/index.d.ts +10 -0
  108. package/dist/en/parts/shell/ui/user-menu-item/index.js +19 -0
  109. package/dist/en/parts/signup/actions/perform-signup/index.d.ts +33 -0
  110. package/dist/en/parts/signup/actions/perform-signup/index.js +58 -0
  111. package/dist/en/parts/signup/index.d.ts +1 -0
  112. package/dist/en/parts/signup/index.js +1 -0
  113. package/dist/en/parts/signup/ui/signup/index.d.ts +8 -0
  114. package/dist/en/parts/signup/ui/signup/index.js +163 -0
  115. package/dist/en/shared/components/alternative/index.d.ts +7 -0
  116. package/dist/en/shared/components/alternative/index.js +3 -0
  117. package/dist/en/shared/components/modal/index.d.ts +8 -0
  118. package/dist/en/shared/components/modal/index.js +32 -0
  119. package/dist/en/shared/procedures/process-successful-response/index.d.ts +30 -0
  120. package/dist/en/shared/procedures/process-successful-response/index.js +66 -0
  121. package/dist/en/topline.d.ts +24 -0
  122. package/dist/en/topline.js +33 -0
  123. package/dist/en/types/app.d.ts +1 -0
  124. package/dist/en/types/app.js +1 -0
  125. package/dist/en/types/data.d.ts +10 -0
  126. package/dist/en/types/data.js +4 -0
  127. package/dist/en/types/helpers.d.ts +2 -0
  128. package/dist/en/types/helpers.js +3 -0
  129. package/dist/ru/hooks/use-topline/index.d.ts +11 -0
  130. package/dist/ru/hooks/use-topline/index.js +14 -0
  131. package/dist/ru/index.d.ts +8 -0
  132. package/dist/ru/index.js +5 -0
  133. package/dist/ru/modules/env/index.d.ts +12 -0
  134. package/dist/ru/modules/env/index.js +27 -0
  135. package/dist/ru/modules/focus-marshal/index.d.ts +6 -0
  136. package/dist/ru/modules/focus-marshal/index.js +6 -0
  137. package/dist/ru/modules/keyboard-navigation/key-codes.d.ts +18 -0
  138. package/dist/ru/modules/keyboard-navigation/key-codes.js +18 -0
  139. package/dist/ru/modules/keyboard-navigation/vertical-menu.d.ts +14 -0
  140. package/dist/ru/modules/keyboard-navigation/vertical-menu.js +45 -0
  141. package/dist/ru/modules/local-db/actions/delete-all-data/index.d.ts +4 -0
  142. package/dist/ru/modules/local-db/actions/delete-all-data/index.js +21 -0
  143. package/dist/ru/modules/local-db/actions/get-all-data/index.d.ts +11 -0
  144. package/dist/ru/modules/local-db/actions/get-all-data/index.js +51 -0
  145. package/dist/ru/modules/local-db/actions/update-grant-token/index.d.ts +4 -0
  146. package/dist/ru/modules/local-db/actions/update-grant-token/index.js +26 -0
  147. package/dist/ru/modules/local-db/actions/update-refresh-token/index.d.ts +4 -0
  148. package/dist/ru/modules/local-db/actions/update-refresh-token/index.js +26 -0
  149. package/dist/ru/modules/local-db/actions/update-user/index.d.ts +5 -0
  150. package/dist/ru/modules/local-db/actions/update-user/index.js +26 -0
  151. package/dist/ru/modules/local-db/create-request-error.d.ts +5 -0
  152. package/dist/ru/modules/local-db/create-request-error.js +9 -0
  153. package/dist/ru/modules/local-db/index.d.ts +6 -0
  154. package/dist/ru/modules/local-db/index.js +6 -0
  155. package/dist/ru/modules/local-db/init-db.d.ts +17 -0
  156. package/dist/ru/modules/local-db/init-db.js +52 -0
  157. package/dist/ru/modules/logger/index.d.ts +1 -0
  158. package/dist/ru/modules/logger/index.js +3 -0
  159. package/dist/ru/modules/request/index.d.ts +20 -0
  160. package/dist/ru/modules/request/index.js +78 -0
  161. package/dist/ru/modules/request/normalize-request-opts.d.ts +5 -0
  162. package/dist/ru/modules/request/normalize-request-opts.js +11 -0
  163. package/dist/ru/modules/request/should-retry.d.ts +6 -0
  164. package/dist/ru/modules/request/should-retry.js +16 -0
  165. package/dist/ru/modules/request/types.d.ts +20 -0
  166. package/dist/ru/modules/request/types.js +1 -0
  167. package/dist/ru/modules/tokens/index.d.ts +4 -0
  168. package/dist/ru/modules/tokens/index.js +14 -0
  169. package/dist/ru/modules/topline-service/index.d.ts +24 -0
  170. package/dist/ru/modules/topline-service/index.js +46 -0
  171. package/dist/ru/modules/topline-service/inner-service.d.ts +45 -0
  172. package/dist/ru/modules/topline-service/inner-service.js +219 -0
  173. package/dist/ru/modules/topline-service/types.d.ts +32 -0
  174. package/dist/ru/modules/topline-service/types.js +19 -0
  175. package/dist/ru/modules/validators/email.d.ts +4 -0
  176. package/dist/ru/modules/validators/email.js +7 -0
  177. package/dist/ru/modules/validators/password-recovery-code.d.ts +4 -0
  178. package/dist/ru/modules/validators/password-recovery-code.js +6 -0
  179. package/dist/ru/modules/validators/password.d.ts +4 -0
  180. package/dist/ru/modules/validators/password.js +6 -0
  181. package/dist/ru/modules/websocket/index.d.ts +4 -0
  182. package/dist/ru/modules/websocket/index.js +92 -0
  183. package/dist/ru/parts/login/actions/perform-login/index.d.ts +27 -0
  184. package/dist/ru/parts/login/actions/perform-login/index.js +60 -0
  185. package/dist/ru/parts/login/index.d.ts +1 -0
  186. package/dist/ru/parts/login/index.js +1 -0
  187. package/dist/ru/parts/login/ui/login/index.d.ts +8 -0
  188. package/dist/ru/parts/login/ui/login/index.js +138 -0
  189. package/dist/ru/parts/logout/actions/perform-logout/index.d.ts +23 -0
  190. package/dist/ru/parts/logout/actions/perform-logout/index.js +54 -0
  191. package/dist/ru/parts/logout/actions/perform-logout/make-second-attempt.d.ts +1 -0
  192. package/dist/ru/parts/logout/actions/perform-logout/make-second-attempt.js +3 -0
  193. package/dist/ru/parts/logout/index.d.ts +1 -0
  194. package/dist/ru/parts/logout/index.js +1 -0
  195. package/dist/ru/parts/password-recovery/actions/create-claim/index.d.ts +22 -0
  196. package/dist/ru/parts/password-recovery/actions/create-claim/index.js +41 -0
  197. package/dist/ru/parts/password-recovery/actions/save-password/index.d.ts +27 -0
  198. package/dist/ru/parts/password-recovery/actions/save-password/index.js +61 -0
  199. package/dist/ru/parts/password-recovery/index.d.ts +1 -0
  200. package/dist/ru/parts/password-recovery/index.js +1 -0
  201. package/dist/ru/parts/password-recovery/ui/password-recovery/index.d.ts +6 -0
  202. package/dist/ru/parts/password-recovery/ui/password-recovery/index.js +33 -0
  203. package/dist/ru/parts/password-recovery/ui/step-one/index.d.ts +7 -0
  204. package/dist/ru/parts/password-recovery/ui/step-one/index.js +82 -0
  205. package/dist/ru/parts/password-recovery/ui/step-two/index.d.ts +7 -0
  206. package/dist/ru/parts/password-recovery/ui/step-two/index.js +134 -0
  207. package/dist/ru/parts/shell/actions/refresh-user/has-user-been-changed.d.ts +5 -0
  208. package/dist/ru/parts/shell/actions/refresh-user/has-user-been-changed.js +6 -0
  209. package/dist/ru/parts/shell/actions/refresh-user/index.d.ts +28 -0
  210. package/dist/ru/parts/shell/actions/refresh-user/index.js +79 -0
  211. package/dist/ru/parts/shell/actions/refresh-user/make-second-attempt.d.ts +2 -0
  212. package/dist/ru/parts/shell/actions/refresh-user/make-second-attempt.js +3 -0
  213. package/dist/ru/parts/shell/context.d.ts +12 -0
  214. package/dist/ru/parts/shell/context.js +8 -0
  215. package/dist/ru/parts/shell/index.d.ts +2 -0
  216. package/dist/ru/parts/shell/index.js +2 -0
  217. package/dist/ru/parts/shell/ui/logged-out-user-menu/index.d.ts +8 -0
  218. package/dist/ru/parts/shell/ui/logged-out-user-menu/index.js +42 -0
  219. package/dist/ru/parts/shell/ui/loggeg-in-user-menu/index.d.ts +8 -0
  220. package/dist/ru/parts/shell/ui/loggeg-in-user-menu/index.js +42 -0
  221. package/dist/ru/parts/shell/ui/logo/index.d.ts +1 -0
  222. package/dist/ru/parts/shell/ui/logo/index.js +8 -0
  223. package/dist/ru/parts/shell/ui/logo/logo-full.d.ts +2 -0
  224. package/dist/ru/parts/shell/ui/logo/logo-full.js +26 -0
  225. package/dist/ru/parts/shell/ui/logo/logo-short.d.ts +2 -0
  226. package/dist/ru/parts/shell/ui/logo/logo-short.js +26 -0
  227. package/dist/ru/parts/shell/ui/shell/index.d.ts +2 -0
  228. package/dist/ru/parts/shell/ui/shell/index.js +187 -0
  229. package/dist/ru/parts/shell/ui/user-avatar/index.d.ts +7 -0
  230. package/dist/ru/parts/shell/ui/user-avatar/index.js +48 -0
  231. package/dist/ru/parts/shell/ui/user-menu/index.d.ts +8 -0
  232. package/dist/ru/parts/shell/ui/user-menu/index.js +37 -0
  233. package/dist/ru/parts/shell/ui/user-menu-item/index.d.ts +10 -0
  234. package/dist/ru/parts/shell/ui/user-menu-item/index.js +19 -0
  235. package/dist/ru/parts/signup/actions/perform-signup/index.d.ts +33 -0
  236. package/dist/ru/parts/signup/actions/perform-signup/index.js +58 -0
  237. package/dist/ru/parts/signup/index.d.ts +1 -0
  238. package/dist/ru/parts/signup/index.js +1 -0
  239. package/dist/ru/parts/signup/ui/signup/index.d.ts +8 -0
  240. package/dist/ru/parts/signup/ui/signup/index.js +163 -0
  241. package/dist/ru/shared/components/alternative/index.d.ts +7 -0
  242. package/dist/ru/shared/components/alternative/index.js +3 -0
  243. package/dist/ru/shared/components/modal/index.d.ts +8 -0
  244. package/dist/ru/shared/components/modal/index.js +32 -0
  245. package/dist/ru/shared/procedures/process-successful-response/index.d.ts +30 -0
  246. package/dist/ru/shared/procedures/process-successful-response/index.js +66 -0
  247. package/dist/ru/topline.d.ts +24 -0
  248. package/dist/ru/topline.js +33 -0
  249. package/dist/ru/types/app.d.ts +1 -0
  250. package/dist/ru/types/app.js +1 -0
  251. package/dist/ru/types/data.d.ts +10 -0
  252. package/dist/ru/types/data.js +4 -0
  253. package/dist/ru/types/helpers.d.ts +2 -0
  254. package/dist/ru/types/helpers.js +3 -0
  255. package/package.json +75 -0
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @peassoft/mnr-web-topline
2
+
3
+ Topline widget for mem'n'rev web applications.
4
+
5
+ ## Usage Example
6
+
7
+ ```jsx
8
+ import { useCallback } from 'react';
9
+ import WebTopline, {
10
+ ToplineService,
11
+ ToplineUser,
12
+ } from '@peassoft/mnr-web-topline';
13
+
14
+ export default function Topline(): JSX.Element {
15
+ const handleReady = useCallback(
16
+ async(toplineService: ToplineService, toplineUser: ToplineUser | null) => {
17
+ toplineService
18
+ .on('userChange', user => {
19
+ //
20
+ })
21
+ .on('logout', () => {
22
+ //
23
+ })
24
+ .on('syncNotification', syncId => {
25
+ //
26
+ });
27
+
28
+ // Use toplineService and toplineUser somehow else
29
+ },
30
+ [],
31
+ );
32
+
33
+ return (
34
+ <WebTopline
35
+ onReady={handleReady}
36
+ onError={(err: Error) => {/* Handle the error */}}
37
+ />
38
+ );
39
+ }
40
+ ```
41
+
42
+ ## API Reference
43
+
44
+ Refer to the file `index.d.ts`.
@@ -0,0 +1,192 @@
1
+ .topline_root {
2
+ --color-palette-brightest: #f9f7f7;
3
+ --color-palette-bright: #dbe2ef;
4
+ --color-palette-dark: #3f72af;
5
+ --color-palette-darkest: #112d4e;
6
+ --color-background-main: #fff;
7
+ --color-text-main: #242629;
8
+ --color-border: var(--color-palette-dark);
9
+ --color-menu-bkg: var(--color-palette-brightest);
10
+ --color-menu-text: var(--color-palette-darkest);
11
+ --color-modal-overlay: rgba(0, 0, 0, 0.7);
12
+ --color-modal-heading-fg: var(--color-palette-darkest);
13
+ }
14
+ .topline_root {
15
+ box-sizing: border-box;
16
+ background-color: var(--color-background-main);
17
+ }
18
+
19
+ .topline_root *,
20
+ .topline_root *::before,
21
+ .topline_root *::after {
22
+ box-sizing: inherit;
23
+ }
24
+
25
+ .topline_root {
26
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
27
+ color: var(--color-text-main);
28
+ }
29
+
30
+ .topline_shell_cont {
31
+ display: flex;
32
+ justify-content: space-between;
33
+ align-items: center;
34
+ height: 48px;
35
+ border-bottom: 1px solid var(--color-border);
36
+ background-color: var(--color-background-main);
37
+ padding-right: 0.5em;
38
+ position: relative;
39
+ }
40
+
41
+ .topline_shell_fullLogo {
42
+ width: 300px;
43
+ height: 40px;
44
+ display: none;
45
+ }
46
+ @media (min-width: 600px) {
47
+ .topline_shell_fullLogo {
48
+ display: block;
49
+ }
50
+ }
51
+
52
+ .topline_shell_shortLogo {
53
+ display: block;
54
+ width: 180px;
55
+ height: 40px;
56
+ }
57
+ @media (min-width: 600px) {
58
+ .topline_shell_shortLogo {
59
+ display: none;
60
+ }
61
+ }
62
+
63
+ .topline_shell_userAvatar {
64
+ display: block;
65
+ appearance: none;
66
+ border: 0;
67
+ background-color: transparent;
68
+ border-radius: 0;
69
+ font-size: 1em;
70
+ margin: 0;
71
+ padding: 0;
72
+ width: 40px;
73
+ height: 40px;
74
+ color: var(--color-border);
75
+ cursor: pointer;
76
+ position: relative;
77
+ }
78
+ .topline_shell_userAvatar::after {
79
+ content: "";
80
+ position: absolute;
81
+ width: 100%;
82
+ height: 100%;
83
+ top: 0;
84
+ left: 0;
85
+ border: 1px solid var(--color-border);
86
+ border-radius: 50%;
87
+ }
88
+ .topline_shell_userAvatar svg {
89
+ width: 32px;
90
+ height: 32px;
91
+ fill: currentColor;
92
+ }
93
+ .topline_shell_userAvatar img {
94
+ width: 40px;
95
+ height: 40px;
96
+ object-fit: contain;
97
+ border-radius: 50%;
98
+ }
99
+
100
+ .topline_shell_userMenu {
101
+ position: absolute;
102
+ z-index: 1;
103
+ bottom: 0;
104
+ right: 0;
105
+ width: 300px;
106
+ border: 1px solid var(--color-border);
107
+ color: var(--color-menu-text);
108
+ background-color: var(--color-menu-bkg);
109
+ transform: translateY(100%);
110
+ }
111
+
112
+ .topline_shell_userMenuItem {
113
+ cursor: pointer;
114
+ padding: 1em;
115
+ outline-offset: -0.5em;
116
+ }
117
+ .topline_shell_userMenuItem:not(:last-child) {
118
+ border-bottom: 1px solid var(--color-border);
119
+ }
120
+
121
+ .topline_login_btnsCont {
122
+ margin-top: 2em;
123
+ }
124
+
125
+ .topline_login_extraBlock {
126
+ margin-top: 2em;
127
+ display: flex;
128
+ justify-content: space-between;
129
+ align-items: center;
130
+ }
131
+
132
+ .topline_login_extraBlockLabel {
133
+ margin: 0;
134
+ }
135
+
136
+ .topline_signup_btnsCont {
137
+ margin-top: 2em;
138
+ }
139
+
140
+ .topline_signup_extraBlockPrompt {
141
+ margin-top: 2em;
142
+ margin-bottom: 0;
143
+ }
144
+
145
+ .topline_signup_extraBlockBtnsCont {
146
+ margin-top: 1em;
147
+ display: flex;
148
+ }
149
+
150
+ .topline_passwordRecovery_btnsCont {
151
+ margin-top: 2em;
152
+ }
153
+
154
+ .topline_passwordRecovery_email {
155
+ font-weight: bolder;
156
+ }
157
+
158
+ .topline_c_modal_overlay {
159
+ position: fixed;
160
+ z-index: 1;
161
+ top: 0;
162
+ bottom: 0;
163
+ left: 0;
164
+ right: 0;
165
+ display: flex;
166
+ justify-content: center;
167
+ align-items: center;
168
+ background-color: var(--color-modal-overlay);
169
+ color: var(--color-text-main);
170
+ }
171
+
172
+ .topline_c_modal_window {
173
+ position: absolute;
174
+ width: calc(100% - 16px);
175
+ max-width: 500px;
176
+ height: calc(100% - 16px);
177
+ max-height: 600px;
178
+ background-color: var(--color-background-main);
179
+ border-radius: 8px;
180
+ overflow-y: auto;
181
+ padding: 1em 1.5em 2em;
182
+ font-size: 1em;
183
+ }
184
+
185
+ .topline_c_modal_heading {
186
+ margin: 0 0 1.6em;
187
+ font-size: 1.4em;
188
+ text-align: center;
189
+ color: var(--color-modal-heading-fg);
190
+ border-bottom: 1px solid currentColor;
191
+ padding-bottom: 0.5em;
192
+ }
@@ -0,0 +1,11 @@
1
+ import { type ToplineService } from '../../modules/topline-service/index.js';
2
+ /**
3
+ * @public
4
+ */
5
+ export type UseTopline = Pick<ToplineService, 'grantToken' | 'upgradeGrantToken' | 'logIn' | 'createAccount'>;
6
+ /**
7
+ * React hook to get access for Topline features
8
+ *
9
+ * @public
10
+ */
11
+ export default function useTopline(): UseTopline;
@@ -0,0 +1,14 @@
1
+ import { toplineService } from '../../modules/topline-service/index.js';
2
+ /**
3
+ * React hook to get access for Topline features
4
+ *
5
+ * @public
6
+ */
7
+ export default function useTopline() {
8
+ return {
9
+ grantToken: () => toplineService.grantToken(),
10
+ upgradeGrantToken: () => toplineService.upgradeGrantToken(),
11
+ logIn: () => toplineService.logIn(),
12
+ createAccount: () => toplineService.createAccount()
13
+ };
14
+ }
@@ -0,0 +1,8 @@
1
+ import Topline from './topline.js';
2
+ import '../css/index.css';
3
+ export default Topline;
4
+ export type { ToplineProps } from './topline.js';
5
+ export type { ToplineUser } from './types/data.js';
6
+ export { type ToplineService, ToplineEventName, } from './modules/topline-service/index.js';
7
+ export { default as useTopline } from './hooks/use-topline/index.js';
8
+ export type { UseTopline } from './hooks/use-topline/index.js';
@@ -0,0 +1,5 @@
1
+ import Topline from './topline.js';
2
+ import '../css/index.css';
3
+ export default Topline;
4
+ export { ToplineEventName } from './modules/topline-service/index.js';
5
+ export { default as useTopline } from './hooks/use-topline/index.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Return base URL for requests to backend API
3
+ */
4
+ export declare function getApiBaseUrl(): string;
5
+ /**
6
+ * Return URL for websocket connection
7
+ */
8
+ export declare function getWebsocketUrl(): string;
9
+ /**
10
+ * Return value of `credentials` setting for fetch requests
11
+ */
12
+ export declare function getRequestCredentialsMode(): RequestCredentials;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Return base URL for requests to backend API
3
+ */
4
+ export function getApiBaseUrl() {
5
+ if (window.location.hostname === 'localhost') {
6
+ return 'http://localhost:5000';
7
+ }
8
+ return '/api';
9
+ }
10
+ /**
11
+ * Return URL for websocket connection
12
+ */
13
+ export function getWebsocketUrl() {
14
+ if (window.location.hostname === 'localhost') {
15
+ return 'ws://localhost:5003';
16
+ }
17
+ return `wss://${window.location.hostname}/ws`;
18
+ }
19
+ /**
20
+ * Return value of `credentials` setting for fetch requests
21
+ */
22
+ export function getRequestCredentialsMode() {
23
+ if (window.location.hostname === 'localhost') {
24
+ return 'include';
25
+ }
26
+ return 'same-origin';
27
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const globalRefs: {
3
+ userAvatar: React.RefObject<HTMLButtonElement | null>;
4
+ userMenuFirstItem: React.RefObject<HTMLDivElement | null>;
5
+ modalFirstItem: React.RefObject<HTMLInputElement | null>;
6
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export const globalRefs = {
3
+ userAvatar: React.createRef(),
4
+ userMenuFirstItem: React.createRef(),
5
+ modalFirstItem: React.createRef()
6
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Keyboard key codes
3
+ */
4
+ declare const keyCodes: Readonly<{
5
+ TAB: 9;
6
+ RETURN: 13;
7
+ ESC: 27;
8
+ SPACE: 32;
9
+ PAGEUP: 33;
10
+ PAGEDOWN: 34;
11
+ END: 35;
12
+ HOME: 36;
13
+ LEFT: 37;
14
+ UP: 38;
15
+ RIGHT: 39;
16
+ DOWN: 40;
17
+ }>;
18
+ export default keyCodes;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Keyboard key codes
3
+ */
4
+ const keyCodes = Object.freeze({
5
+ TAB: 9,
6
+ RETURN: 13,
7
+ ESC: 27,
8
+ SPACE: 32,
9
+ PAGEUP: 33,
10
+ PAGEDOWN: 34,
11
+ END: 35,
12
+ HOME: 36,
13
+ LEFT: 37,
14
+ UP: 38,
15
+ RIGHT: 39,
16
+ DOWN: 40
17
+ });
18
+ export default keyCodes;
@@ -0,0 +1,14 @@
1
+ import type { ToplineAction } from '../../types/app.js';
2
+ export type ProcessKeyDownParams = {
3
+ currIndex: number;
4
+ e: Pick<React.KeyboardEvent, 'which' | 'preventDefault' | 'stopPropagation'>;
5
+ setCurrItemIdx: (idx: number) => unknown;
6
+ menuItemRefs: React.RefObject<HTMLDivElement | null>[];
7
+ actionName: ToplineAction;
8
+ onSelect: (actionName: ToplineAction) => unknown;
9
+ onClose: () => unknown;
10
+ };
11
+ /**
12
+ * Process pressed key for vertical menu
13
+ */
14
+ export declare function processKeyDown(params: ProcessKeyDownParams): void;
@@ -0,0 +1,45 @@
1
+ import keyCodes from './key-codes.js';
2
+ /**
3
+ * Process pressed key for vertical menu
4
+ */
5
+ export function processKeyDown(params) {
6
+ const {
7
+ currIndex,
8
+ e,
9
+ setCurrItemIdx,
10
+ menuItemRefs,
11
+ actionName,
12
+ onSelect,
13
+ onClose
14
+ } = params;
15
+ const itemsNum = menuItemRefs.length;
16
+ let nextIndex = -Infinity;
17
+ switch (e.which) {
18
+ case keyCodes.DOWN:
19
+ nextIndex = currIndex === itemsNum - 1 ? 0 : currIndex + 1;
20
+ break;
21
+ case keyCodes.UP:
22
+ nextIndex = currIndex === 0 ? itemsNum - 1 : currIndex - 1;
23
+ break;
24
+ case keyCodes.HOME:
25
+ nextIndex = 0;
26
+ break;
27
+ case keyCodes.END:
28
+ nextIndex = itemsNum - 1;
29
+ }
30
+ if (nextIndex > -Infinity) {
31
+ e.preventDefault();
32
+ e.stopPropagation();
33
+ setCurrItemIdx(nextIndex);
34
+ menuItemRefs[nextIndex]?.current?.focus();
35
+ return;
36
+ }
37
+ if (e.which === keyCodes.RETURN) {
38
+ onSelect(actionName);
39
+ return;
40
+ }
41
+ if (e.which === keyCodes.ESC) {
42
+ onClose();
43
+ return;
44
+ }
45
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Delete all data from local database
3
+ */
4
+ export default function deleteAllData(): Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { getDb, STORE_NAME } from '../../init-db.js';
2
+ import createRequestError from '../../create-request-error.js';
3
+ import { logError } from '../../../logger/index.js';
4
+ /**
5
+ * Delete all data from local database
6
+ */
7
+ export default function deleteAllData() {
8
+ return new Promise(resolve => {
9
+ const db = getDb();
10
+ if (!db) {
11
+ resolve();
12
+ return;
13
+ }
14
+ const req = db.transaction(STORE_NAME, 'readwrite').objectStore(STORE_NAME).clear();
15
+ req.onsuccess = () => resolve();
16
+ req.onerror = () => {
17
+ logError(createRequestError('deleteAllData'));
18
+ resolve();
19
+ };
20
+ });
21
+ }
@@ -0,0 +1,11 @@
1
+ import type { ToplineUser } from '../../../../types/data.js';
2
+ type ReturnData = {
3
+ user: ToplineUser | null;
4
+ grantToken: string | null;
5
+ refreshToken: string | null;
6
+ };
7
+ /**
8
+ * Fetch all data from local database
9
+ */
10
+ export default function getAllData(): Promise<ReturnData>;
11
+ export {};
@@ -0,0 +1,51 @@
1
+ import { getDb, STORE_NAME } from '../../init-db.js';
2
+ import createRequestError from '../../create-request-error.js';
3
+ import { logError } from '../../../logger/index.js';
4
+ /**
5
+ * Fetch all data from local database
6
+ */
7
+ export default function getAllData() {
8
+ return new Promise(resolve => {
9
+ const db = getDb();
10
+ if (!db) {
11
+ resolve({
12
+ user: null,
13
+ grantToken: null,
14
+ refreshToken: null
15
+ });
16
+ return;
17
+ }
18
+ const req = db.transaction(STORE_NAME).objectStore(STORE_NAME).getAll();
19
+ req.onsuccess = function () {
20
+ const recordset = this.result;
21
+ let user = null;
22
+ let grantToken = null;
23
+ let refreshToken = null;
24
+ for (const record of recordset) {
25
+ switch (record.entityType) {
26
+ case 'user':
27
+ user = record.user;
28
+ break;
29
+ case 'grantToken':
30
+ grantToken = record.grantToken;
31
+ break;
32
+ case 'refreshToken':
33
+ refreshToken = record.refreshToken;
34
+ }
35
+ }
36
+ resolve({
37
+ user,
38
+ grantToken,
39
+ refreshToken
40
+ });
41
+ };
42
+ req.onerror = () => {
43
+ logError(createRequestError('getAllData'));
44
+ resolve({
45
+ user: null,
46
+ grantToken: null,
47
+ refreshToken: null
48
+ });
49
+ };
50
+ });
51
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Update grant token
3
+ */
4
+ export default function updateGrantToken(grantToken: string): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { getDb, STORE_NAME } from '../../init-db.js';
2
+ import createRequestError from '../../create-request-error.js';
3
+ import { logError } from '../../../logger/index.js';
4
+ /**
5
+ * Update grant token
6
+ */
7
+ export default function updateGrantToken(grantToken) {
8
+ return new Promise(resolve => {
9
+ const db = getDb();
10
+ if (!db) {
11
+ resolve();
12
+ return;
13
+ }
14
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
15
+ transaction.oncomplete = () => resolve();
16
+ transaction.onerror = () => {
17
+ logError(createRequestError('updateGrantToken'));
18
+ resolve();
19
+ };
20
+ const objectStore = transaction.objectStore(STORE_NAME);
21
+ objectStore.put({
22
+ entityType: 'grantToken',
23
+ grantToken
24
+ });
25
+ });
26
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Update refresh token
3
+ */
4
+ export default function updateRefreshToken(refreshToken: string): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { getDb, STORE_NAME } from '../../init-db.js';
2
+ import createRequestError from '../../create-request-error.js';
3
+ import { logError } from '../../../logger/index.js';
4
+ /**
5
+ * Update refresh token
6
+ */
7
+ export default function updateRefreshToken(refreshToken) {
8
+ return new Promise(resolve => {
9
+ const db = getDb();
10
+ if (!db) {
11
+ resolve();
12
+ return;
13
+ }
14
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
15
+ transaction.oncomplete = () => resolve();
16
+ transaction.onerror = () => {
17
+ logError(createRequestError('updateRefreshToken'));
18
+ resolve();
19
+ };
20
+ const objectStore = transaction.objectStore(STORE_NAME);
21
+ objectStore.put({
22
+ entityType: 'refreshToken',
23
+ refreshToken
24
+ });
25
+ });
26
+ }
@@ -0,0 +1,5 @@
1
+ import type { ToplineUser } from '../../../../types/data.js';
2
+ /**
3
+ * Update user data
4
+ */
5
+ export default function updateUser(user: ToplineUser): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { getDb, STORE_NAME } from '../../init-db.js';
2
+ import createRequestError from '../../create-request-error.js';
3
+ import { logError } from '../../../logger/index.js';
4
+ /**
5
+ * Update user data
6
+ */
7
+ export default function updateUser(user) {
8
+ return new Promise(resolve => {
9
+ const db = getDb();
10
+ if (!db) {
11
+ resolve();
12
+ return;
13
+ }
14
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
15
+ transaction.oncomplete = () => resolve();
16
+ transaction.onerror = () => {
17
+ logError(createRequestError('updateUser'));
18
+ resolve();
19
+ };
20
+ const objectStore = transaction.objectStore(STORE_NAME);
21
+ objectStore.put({
22
+ entityType: 'user',
23
+ user
24
+ });
25
+ });
26
+ }
@@ -0,0 +1,5 @@
1
+ import WebError from '@memnrev/web-error';
2
+ /**
3
+ * Create error for failed request to local database
4
+ */
5
+ export default function createRequestError(reason: string): WebError;
@@ -0,0 +1,9 @@
1
+ import WebError from '@memnrev/web-error';
2
+ /**
3
+ * Create error for failed request to local database
4
+ */
5
+ export default function createRequestError(reason) {
6
+ return new WebError({
7
+ name: 'LocalDbRequestError'
8
+ }, `request to local database failed (${reason})`);
9
+ }
@@ -0,0 +1,6 @@
1
+ export { initDb } from './init-db.js';
2
+ export { default as getAllData } from './actions/get-all-data/index.js';
3
+ export { default as deleteAllData } from './actions/delete-all-data/index.js';
4
+ export { default as updateUser } from './actions/update-user/index.js';
5
+ export { default as updateGrantToken } from './actions/update-grant-token/index.js';
6
+ export { default as updateRefreshToken } from './actions/update-refresh-token/index.js';
@@ -0,0 +1,6 @@
1
+ export { initDb } from './init-db.js';
2
+ export { default as getAllData } from './actions/get-all-data/index.js';
3
+ export { default as deleteAllData } from './actions/delete-all-data/index.js';
4
+ export { default as updateUser } from './actions/update-user/index.js';
5
+ export { default as updateGrantToken } from './actions/update-grant-token/index.js';
6
+ export { default as updateRefreshToken } from './actions/update-refresh-token/index.js';
@@ -0,0 +1,17 @@
1
+ export declare const STORE_NAME = "main";
2
+ /**
3
+ * Get IndexedDb database object
4
+ *
5
+ * Returns null if database initialization has failed.
6
+ *
7
+ * @public
8
+ */
9
+ export declare function getDb(): IDBDatabase | null;
10
+ /**
11
+ * Initialize local database
12
+ *
13
+ * @throws {LocalDbInitializationError}
14
+ *
15
+ * @public
16
+ */
17
+ export declare function initDb(): Promise<void>;