nexus-shared 1.1.20 → 2.0.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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +903 -0
  3. package/dist/Client.Index.d.ts +44 -0
  4. package/dist/Client.Index.js +49 -0
  5. package/dist/Components/Documents/Button.d.ts +29 -0
  6. package/dist/Components/Documents/Button.js +11 -0
  7. package/dist/Components/Documents/Menu.d.ts +102 -0
  8. package/dist/Components/Documents/Menu.js +238 -0
  9. package/dist/Components/Documents/SplitButton.d.ts +64 -0
  10. package/dist/Components/Documents/SplitButton.js +127 -0
  11. package/dist/Components/Documents/TabButtons.d.ts +62 -0
  12. package/dist/Components/Documents/TabButtons.js +19 -0
  13. package/dist/Components/Forms/ApiForm.d.ts +21 -0
  14. package/dist/Components/Forms/ApiForm.js +99 -0
  15. package/dist/Components/Forms/Crud.d.ts +17 -0
  16. package/dist/Components/Forms/Crud.js +556 -0
  17. package/dist/Components/Forms/CrudParts.d.ts +15 -0
  18. package/dist/Components/Forms/CrudParts.js +36 -0
  19. package/dist/Components/Forms/Form.d.ts +52 -0
  20. package/dist/Components/Forms/Form.js +319 -0
  21. package/dist/Components/Forms/SubmitForm.d.ts +65 -0
  22. package/dist/Components/Forms/SubmitForm.js +198 -0
  23. package/dist/Components/Inputs/Calendar.d.ts +69 -0
  24. package/dist/Components/Inputs/Calendar.js +258 -0
  25. package/dist/Components/Inputs/CheckBox.d.ts +53 -0
  26. package/dist/Components/Inputs/CheckBox.js +87 -0
  27. package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
  28. package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
  29. package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
  30. package/dist/Components/Inputs/ChoiceField.js +169 -0
  31. package/dist/Components/Inputs/DatePicker.d.ts +54 -0
  32. package/dist/Components/Inputs/DatePicker.js +246 -0
  33. package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
  34. package/dist/Components/Inputs/DateRangePicker.js +283 -0
  35. package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
  36. package/dist/Components/Inputs/DateTimePicker.js +399 -0
  37. package/dist/Components/Inputs/Dropdown.d.ts +117 -0
  38. package/dist/Components/Inputs/Dropdown.js +839 -0
  39. package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
  40. package/dist/Components/Inputs/DropdownParts.js +102 -0
  41. package/dist/Components/Inputs/EditorShell.d.ts +45 -0
  42. package/dist/Components/Inputs/EditorShell.js +214 -0
  43. package/dist/Components/Inputs/Field.d.ts +53 -0
  44. package/dist/Components/Inputs/Field.js +16 -0
  45. package/dist/Components/Inputs/GroupForm.d.ts +20 -0
  46. package/dist/Components/Inputs/GroupForm.js +170 -0
  47. package/dist/Components/Inputs/InputField.d.ts +59 -0
  48. package/dist/Components/Inputs/InputField.js +169 -0
  49. package/dist/Components/Inputs/InputRenderer.d.ts +35 -0
  50. package/dist/Components/Inputs/InputRenderer.js +99 -0
  51. package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
  52. package/dist/Components/Inputs/MarkdownEditor.js +289 -0
  53. package/dist/Components/Inputs/NumberBox.d.ts +53 -0
  54. package/dist/Components/Inputs/NumberBox.js +228 -0
  55. package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
  56. package/dist/Components/Inputs/RadioGroup.js +43 -0
  57. package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
  58. package/dist/Components/Inputs/ReadOnlyNotice.js +116 -0
  59. package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
  60. package/dist/Components/Inputs/RichTextEditor.js +1170 -0
  61. package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
  62. package/dist/Components/Inputs/RichTextParts.js +157 -0
  63. package/dist/Components/Inputs/RowsInput.d.ts +104 -0
  64. package/dist/Components/Inputs/RowsInput.js +259 -0
  65. package/dist/Components/Inputs/Slider.d.ts +87 -0
  66. package/dist/Components/Inputs/Slider.js +216 -0
  67. package/dist/Components/Inputs/TabularForm.d.ts +23 -0
  68. package/dist/Components/Inputs/TabularForm.js +283 -0
  69. package/dist/Components/Inputs/TextArea.d.ts +43 -0
  70. package/dist/Components/Inputs/TextArea.js +31 -0
  71. package/dist/Components/Inputs/TextBox.d.ts +52 -0
  72. package/dist/Components/Inputs/TextBox.js +58 -0
  73. package/dist/Components/Inputs/TextField.d.ts +31 -0
  74. package/dist/Components/Inputs/TextField.js +35 -0
  75. package/dist/Components/Inputs/TimePanel.d.ts +34 -0
  76. package/dist/Components/Inputs/TimePanel.js +288 -0
  77. package/dist/Components/Inputs/TimePicker.d.ts +54 -0
  78. package/dist/Components/Inputs/TimePicker.js +239 -0
  79. package/dist/Components/Inputs/TreeView.d.ts +160 -0
  80. package/dist/Components/Inputs/TreeView.js +947 -0
  81. package/dist/Components/Layouts/MessageBox.d.ts +71 -0
  82. package/dist/Components/Layouts/MessageBox.js +104 -0
  83. package/dist/Components/Layouts/Popup.d.ts +92 -0
  84. package/dist/Components/Layouts/Popup.js +376 -0
  85. package/dist/Components/Layouts/PopupContext.d.ts +2 -0
  86. package/dist/Components/Layouts/PopupContext.js +4 -0
  87. package/dist/Components/Layouts/PopupDock.d.ts +22 -0
  88. package/dist/Components/Layouts/PopupDock.js +121 -0
  89. package/dist/Components/Layouts/PopupHost.d.ts +56 -0
  90. package/dist/Components/Layouts/PopupHost.js +163 -0
  91. package/dist/Components/Layouts/PopupRules.d.ts +30 -0
  92. package/dist/Components/Layouts/PopupRules.js +63 -0
  93. package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
  94. package/dist/Components/Layouts/ThemePicker.js +22 -0
  95. package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
  96. package/dist/Components/Layouts/ThemeScript.js +13 -0
  97. package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
  98. package/dist/Components/Layouts/ThemeSwitcher.js +29 -0
  99. package/dist/Components/Layouts/Toaster.d.ts +76 -0
  100. package/dist/Components/Layouts/Toaster.js +172 -0
  101. package/dist/Components/Viewers/DataTable.d.ts +25 -0
  102. package/dist/Components/Viewers/DataTable.js +542 -0
  103. package/dist/Components/Viewers/DataTableParts.d.ts +134 -0
  104. package/dist/Components/Viewers/DataTableParts.js +145 -0
  105. package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
  106. package/dist/Components/Viewers/MarkdownView.js +79 -0
  107. package/dist/Components/Viewers/RichTextView.d.ts +18 -0
  108. package/dist/Components/Viewers/RichTextView.js +17 -0
  109. package/dist/Helpers/AnimationHelpers.d.ts +6 -0
  110. package/dist/Helpers/AnimationHelpers.js +35 -0
  111. package/dist/Helpers/ApiClient.d.ts +74 -0
  112. package/dist/Helpers/ApiClient.js +197 -0
  113. package/dist/Helpers/ApiFormHelpers.d.ts +26 -0
  114. package/dist/Helpers/ApiFormHelpers.js +56 -0
  115. package/dist/Helpers/ApiModules.d.ts +135 -0
  116. package/dist/Helpers/ApiModules.js +194 -0
  117. package/dist/Helpers/ApiResponses.d.ts +41 -0
  118. package/dist/Helpers/ApiResponses.js +159 -0
  119. package/dist/Helpers/ApiRoutes.d.ts +150 -0
  120. package/dist/Helpers/ApiRoutes.js +191 -0
  121. package/dist/Helpers/ApiToasts.d.ts +21 -0
  122. package/dist/Helpers/ApiToasts.js +22 -0
  123. package/dist/Helpers/ClassHelpers.d.ts +3 -0
  124. package/dist/Helpers/ClassHelpers.js +4 -0
  125. package/dist/Helpers/CrudBackend.d.ts +56 -0
  126. package/dist/Helpers/CrudBackend.js +119 -0
  127. package/dist/Helpers/CrudHelpers.d.ts +76 -0
  128. package/dist/Helpers/CrudHelpers.js +202 -0
  129. package/dist/Helpers/DateHelpers.d.ts +88 -0
  130. package/dist/Helpers/DateHelpers.js +363 -0
  131. package/dist/Helpers/DatePreferences.d.ts +14 -0
  132. package/dist/Helpers/DatePreferences.js +94 -0
  133. package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
  134. package/dist/Helpers/DateTimeHelpers.js +286 -0
  135. package/dist/Helpers/DragHelpers.d.ts +129 -0
  136. package/dist/Helpers/DragHelpers.js +281 -0
  137. package/dist/Helpers/DropdownHelpers.d.ts +56 -0
  138. package/dist/Helpers/DropdownHelpers.js +180 -0
  139. package/dist/Helpers/FormDrafts.d.ts +18 -0
  140. package/dist/Helpers/FormDrafts.js +76 -0
  141. package/dist/Helpers/FormStore.d.ts +231 -0
  142. package/dist/Helpers/FormStore.js +734 -0
  143. package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
  144. package/dist/Helpers/InputParamsHelpers.js +388 -0
  145. package/dist/Helpers/MarkdownEditing.d.ts +27 -0
  146. package/dist/Helpers/MarkdownEditing.js +250 -0
  147. package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
  148. package/dist/Helpers/MarkdownHelpers.js +775 -0
  149. package/dist/Helpers/MessageBuilder.d.ts +74 -0
  150. package/dist/Helpers/MessageBuilder.js +254 -0
  151. package/dist/Helpers/NepaliCalendar.d.ts +25 -0
  152. package/dist/Helpers/NepaliCalendar.js +107 -0
  153. package/dist/Helpers/NumberHelpers.d.ts +71 -0
  154. package/dist/Helpers/NumberHelpers.js +202 -0
  155. package/dist/Helpers/Permissions.d.ts +62 -0
  156. package/dist/Helpers/Permissions.js +133 -0
  157. package/dist/Helpers/PopoverHelpers.d.ts +43 -0
  158. package/dist/Helpers/PopoverHelpers.js +91 -0
  159. package/dist/Helpers/RichTextHelpers.d.ts +77 -0
  160. package/dist/Helpers/RichTextHelpers.js +1072 -0
  161. package/dist/Helpers/RowsStore.d.ts +160 -0
  162. package/dist/Helpers/RowsStore.js +584 -0
  163. package/dist/Helpers/TableColumns.d.ts +40 -0
  164. package/dist/Helpers/TableColumns.js +254 -0
  165. package/dist/Helpers/TableExport.d.ts +30 -0
  166. package/dist/Helpers/TableExport.js +97 -0
  167. package/dist/Helpers/TableHelpers.d.ts +102 -0
  168. package/dist/Helpers/TableHelpers.js +281 -0
  169. package/dist/Helpers/TableStore.d.ts +142 -0
  170. package/dist/Helpers/TableStore.js +530 -0
  171. package/dist/Helpers/ThemeHelpers.d.ts +15 -0
  172. package/dist/Helpers/ThemeHelpers.js +16 -0
  173. package/dist/Helpers/TimeHelpers.d.ts +73 -0
  174. package/dist/Helpers/TimeHelpers.js +253 -0
  175. package/dist/Helpers/TreeStore.d.ts +188 -0
  176. package/dist/Helpers/TreeStore.js +577 -0
  177. package/dist/Helpers/ValidationHelpers.d.ts +124 -0
  178. package/dist/Helpers/ValidationHelpers.js +301 -0
  179. package/dist/Interfaces/ApiInterfaces.d.ts +149 -0
  180. package/dist/Interfaces/ApiInterfaces.js +24 -0
  181. package/dist/Interfaces/CrudInterfaces.d.ts +171 -0
  182. package/{src/sso-client.tsx → dist/Interfaces/CrudInterfaces.js} +1 -1
  183. package/dist/Interfaces/DateInterfaces.d.ts +154 -0
  184. package/dist/Interfaces/DateInterfaces.js +29 -0
  185. package/dist/Interfaces/FormInterfaces.d.ts +352 -0
  186. package/dist/Interfaces/FormInterfaces.js +1 -0
  187. package/dist/Interfaces/InputInterfaces.d.ts +141 -0
  188. package/dist/Interfaces/InputInterfaces.js +1 -0
  189. package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
  190. package/dist/Interfaces/MessageInterfaces.js +5 -0
  191. package/dist/Interfaces/TableInterfaces.d.ts +291 -0
  192. package/dist/Interfaces/TableInterfaces.js +1 -0
  193. package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
  194. package/dist/Interfaces/ThemeInterfaces.js +17 -0
  195. package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
  196. package/dist/Interfaces/TypeInterfaces.js +1 -0
  197. package/dist/Server.Index.d.ts +2 -0
  198. package/dist/Server.Index.js +5 -0
  199. package/dist/Services/ApiProxy.d.ts +32 -0
  200. package/dist/Services/ApiProxy.js +111 -0
  201. package/dist/Services/BrowserApi.d.ts +78 -0
  202. package/dist/Services/BrowserApi.js +111 -0
  203. package/dist/Services/ServerApi.d.ts +49 -0
  204. package/dist/Services/ServerApi.js +75 -0
  205. package/dist/Services/ThemeService.d.ts +17 -0
  206. package/dist/Services/ThemeService.js +83 -0
  207. package/dist/Shared.Index.d.ts +43 -0
  208. package/dist/Shared.Index.js +47 -0
  209. package/package.json +82 -33
  210. package/src/Styles/Nexus.Base.css +70 -0
  211. package/src/Styles/Nexus.Button.css +151 -0
  212. package/src/Styles/Nexus.Calendar.css +275 -0
  213. package/src/Styles/Nexus.Choice.css +345 -0
  214. package/src/Styles/Nexus.Crud.css +84 -0
  215. package/src/Styles/Nexus.DateTime.css +81 -0
  216. package/src/Styles/Nexus.Dropdown.css +774 -0
  217. package/src/Styles/Nexus.Editor.css +297 -0
  218. package/src/Styles/Nexus.Form.css +298 -0
  219. package/src/Styles/Nexus.Index.css +34 -0
  220. package/src/Styles/Nexus.Input.css +637 -0
  221. package/src/Styles/Nexus.Markdown.css +265 -0
  222. package/src/Styles/Nexus.Menu.css +249 -0
  223. package/src/Styles/Nexus.Popup.css +731 -0
  224. package/src/Styles/Nexus.RichText.css +463 -0
  225. package/src/Styles/Nexus.Rows.css +566 -0
  226. package/src/Styles/Nexus.Slider.css +278 -0
  227. package/src/Styles/Nexus.Tab.Buttons.css +364 -0
  228. package/src/Styles/Nexus.Table.css +1014 -0
  229. package/src/Styles/Nexus.Theme.Picker.css +159 -0
  230. package/src/Styles/Nexus.Themes.css +194 -0
  231. package/src/Styles/Nexus.Time.css +147 -0
  232. package/src/Styles/Nexus.Toast.css +265 -0
  233. package/src/Styles/Nexus.Tokens.css +72 -0
  234. package/src/Styles/Nexus.Tree.css +435 -0
  235. package/src/api-services/authentication-service.tsx +0 -23
  236. package/src/api-services/preference-service.tsx +0 -5
  237. package/src/api-services/system-service.tsx +0 -34
  238. package/src/client.ts +0 -31
  239. package/src/components/documents/button.tsx +0 -142
  240. package/src/components/documents/icon-box.tsx +0 -93
  241. package/src/components/documents/page-title.tsx +0 -7
  242. package/src/components/documents/tab-button.tsx +0 -172
  243. package/src/components/documents/tag.tsx +0 -30
  244. package/src/components/index.js +0 -0
  245. package/src/components/inputs/checkbox-input.tsx +0 -66
  246. package/src/components/inputs/input-box.tsx +0 -48
  247. package/src/components/inputs/input-element.tsx +0 -65
  248. package/src/components/inputs/input-form.tsx +0 -164
  249. package/src/components/inputs/input.tsx +0 -181
  250. package/src/components/inputs/number-input.tsx +0 -108
  251. package/src/components/inputs/radiobox-input.tsx +0 -53
  252. package/src/components/inputs/textarea-input.tsx +0 -47
  253. package/src/components/inputs/textbox-input.tsx +0 -45
  254. package/src/components/layouts/global-dialogbox.tsx +0 -431
  255. package/src/components/layouts/global-layout.tsx +0 -59
  256. package/src/components/layouts/layout-helpers.tsx +0 -20
  257. package/src/components/layouts/panels/user-panel.tsx +0 -112
  258. package/src/components/layouts/utility-menu.tsx +0 -49
  259. package/src/components/panels/theme-panel.tsx +0 -46
  260. package/src/helpers/bitwise-helpers.tsx +0 -11
  261. package/src/helpers/browser-helpers.tsx +0 -156
  262. package/src/helpers/datasource-helpers.tsx +0 -99
  263. package/src/helpers/element-helpers.tsx +0 -57
  264. package/src/helpers/input-helpers.tsx +0 -74
  265. package/src/helpers/string-helpers.tsx +0 -28
  266. package/src/helpers/utility-helpers.tsx +0 -45
  267. package/src/helpers/validation-helpers.tsx +0 -302
  268. package/src/index.ts +0 -26
  269. package/src/interface.ts +0 -19
  270. package/src/interfaces/auth-token-interfaces.tsx +0 -6
  271. package/src/interfaces/browser-interfaces.tsx +0 -36
  272. package/src/interfaces/button-interfaces.tsx +0 -63
  273. package/src/interfaces/datasource-interfaces.tsx +0 -22
  274. package/src/interfaces/datatable-interfaces.tsx +0 -25
  275. package/src/interfaces/dialogbox-interfaces.tsx +0 -5
  276. package/src/interfaces/exception-interfaces.tsx +0 -99
  277. package/src/interfaces/http-interfaces.tsx +0 -129
  278. package/src/interfaces/icon-interfaces.tsx +0 -129
  279. package/src/interfaces/input-interfaces.tsx +0 -410
  280. package/src/interfaces/layout-interfaces.tsx +0 -191
  281. package/src/interfaces/menu-interfaces.tsx +0 -49
  282. package/src/interfaces/message-interfaces.tsx +0 -32
  283. package/src/interfaces/permission-interfaces.tsx +0 -9
  284. package/src/interfaces/storage-interfaces.tsx +0 -5
  285. package/src/interfaces/system-interfaces.tsx +0 -22
  286. package/src/interfaces/theme-interfaces.tsx +0 -123
  287. package/src/interfaces/type-interfaces.tsx +0 -28
  288. package/src/interfaces/user-interfaces.tsx +0 -47
  289. package/src/nexus-client.tsx +0 -21
  290. package/src/nexus.environments.tsx +0 -66
  291. package/src/proxy-api/proxy-backend.tsx +0 -60
  292. package/src/proxy-api/proxy-constants.tsx +0 -28
  293. package/src/proxy-api/proxy-helpers.tsx +0 -91
  294. package/src/proxy-api-client.tsx +0 -1
  295. package/src/proxy-api-server.tsx +0 -2
  296. package/src/services/http-client-services.tsx +0 -75
  297. package/src/services/http-services.tsx +0 -158
  298. package/src/services/loader-service.tsx +0 -185
  299. package/src/services/localstorage-service.tsx +0 -119
  300. package/src/services/message-services.tsx +0 -383
  301. package/src/services/theme-service.tsx +0 -161
  302. package/src/services/user-services.tsx +0 -10
  303. package/src/sso-config/auth-token-validation.ts +0 -16
  304. package/src/sso-config/callback-route.tsx +0 -35
  305. package/src/sso-config/cookie-encryption.ts +0 -51
  306. package/src/sso-config/cookie-helpers.tsx +0 -102
  307. package/src/sso-config/forgot-password-route.tsx +0 -36
  308. package/src/sso-config/oauth-callback-state.ts +0 -61
  309. package/src/sso-config/pkce-helpers.ts +0 -9
  310. package/src/sso-config/provider-complete-route.tsx +0 -18
  311. package/src/sso-config/redirect-context-actions.tsx +0 -45
  312. package/src/sso-config/redirect-context-helpers.tsx +0 -159
  313. package/src/sso-config/redirect-context-persist.tsx +0 -18
  314. package/src/sso-config/redirect-context-route.tsx +0 -45
  315. package/src/sso-config/refresh-route.tsx +0 -23
  316. package/src/sso-config/sign-in-route.tsx +0 -74
  317. package/src/sso-config/sign-out-route.tsx +0 -57
  318. package/src/sso-config/sign-up-route.tsx +0 -57
  319. package/src/sso-config/sso-backend-flow.ts +0 -38
  320. package/src/sso-config/sso-complete-route.tsx +0 -50
  321. package/src/sso-config/sso-config.ts +0 -59
  322. package/src/sso-config/sso-interfaces.tsx +0 -99
  323. package/src/sso-config/sso-response-helpers.tsx +0 -20
  324. package/src/sso-server.tsx +0 -21
  325. package/src/styles/nexus.animation.css +0 -269
  326. package/src/styles/nexus.core.css +0 -119
  327. package/src/styles/nexus.dialog.css +0 -144
  328. package/src/styles/nexus.icon.css +0 -51
  329. package/src/styles/nexus.input.css +0 -207
  330. package/src/styles/nexus.loader.css +0 -11
  331. package/src/styles/nexus.logic.css +0 -47
  332. package/src/styles/nexus.utility.css +0 -347
@@ -1,431 +0,0 @@
1
- "use client";
2
-
3
- import React, { useEffect } from "react";
4
- import { ConvertRemToPixels, IsKeyPressed } from "../../helpers/browser-helpers";
5
- import { Debounce, DebouncedFunction } from "../../helpers/utility-helpers";
6
- import { EKeys } from "../../interfaces/browser-interfaces";
7
- import { IDialogboxResults } from "../../interfaces/dialogbox-interfaces";
8
- import { DEFAULT_ANIMATION_DURATION, EPositions } from "../../interfaces/layout-interfaces";
9
- import { EBackgrounds } from "../../interfaces/theme-interfaces";
10
- import { UN } from "../../interfaces/type-interfaces";
11
- import { NEXUS_CONFIG } from "../../nexus.environments";
12
-
13
- const GetDialogId = (buttonIdentity: string) => `dialog-${buttonIdentity}`;
14
- const VISIBILITY_KEY = "data-dialog-visibility";
15
- export const DEFAULT_DIALOGBOX_HOVER_EFFECT_DELAY = 500;
16
-
17
- interface IDialogRegistryEntry {
18
- triggerElement: HTMLElement;
19
- affectedElement: HTMLElement;
20
- iggnoreChildClick?: boolean | UN;
21
- close: (isInitial: boolean) => void;
22
- }
23
-
24
- /** All initialized dialogs — O(1) lookup by trigger. */
25
- const dialogRegistry = new Map<HTMLElement, IDialogRegistryEntry>();
26
- /** Only open dialogs — hot paths iterate this (usually 1–2), not all 100+ instances. */
27
- const openDialogs = new Set<HTMLElement>();
28
-
29
- let globalDocumentClickAttached = false;
30
- let globalDocumentClickTimeout: ReturnType<typeof setTimeout>;
31
-
32
- const shouldKeepDialogOpen = (entry: IDialogRegistryEntry, path: EventTarget[], target: HTMLElement) => {
33
- if (entry.iggnoreChildClick === false) return target === entry.triggerElement;
34
-
35
- return path.includes(entry.triggerElement) || path.includes(entry.affectedElement) || isClickInsideOpenNestedDialog(entry.triggerElement, path) || entry.triggerElement.contains(target);
36
- };
37
-
38
- const isClickInsideOpenNestedDialog = (parentTrigger: HTMLElement, path: EventTarget[]) => {
39
- for (const trigger of openDialogs) {
40
- if (trigger === parentTrigger) continue;
41
- const nested = dialogRegistry.get(trigger);
42
- if (!nested || !parentTrigger.contains(nested.triggerElement)) continue;
43
- if (path.includes(nested.triggerElement) || path.includes(nested.affectedElement)) return true;
44
- }
45
- return false;
46
- };
47
-
48
- const onGlobalDocumentClick = (e: MouseEvent) => {
49
- if (openDialogs.size === 0) return;
50
-
51
- const path = e.composedPath();
52
- const target = e.target as HTMLElement;
53
-
54
- for (const trigger of [...openDialogs]) {
55
- const entry = dialogRegistry.get(trigger);
56
- if (!entry || shouldKeepDialogOpen(entry, path, target)) continue;
57
- entry.close(false);
58
- }
59
- };
60
-
61
- const scheduleGlobalDocumentClick = () => {
62
- clearTimeout(globalDocumentClickTimeout);
63
- globalDocumentClickTimeout = setTimeout(() => {
64
- if (openDialogs.size === 0) return;
65
- if (!globalDocumentClickAttached) {
66
- document.addEventListener("click", onGlobalDocumentClick);
67
- globalDocumentClickAttached = true;
68
- }
69
- }, 0);
70
- };
71
-
72
- const teardownGlobalDocumentClick = () => {
73
- if (openDialogs.size > 0) return;
74
- clearTimeout(globalDocumentClickTimeout);
75
- document.removeEventListener("click", onGlobalDocumentClick);
76
- globalDocumentClickAttached = false;
77
- };
78
-
79
- /** Keep parent panels open when opening a nested dialog (e.g. theme overflow ellipsis inside utility menu). */
80
- const closeOtherDialogs = (currentTrigger: HTMLElement, isInitial: boolean) => {
81
- for (const trigger of openDialogs) {
82
- if (trigger === currentTrigger) continue;
83
- const entry = dialogRegistry.get(trigger);
84
- if (!entry) continue;
85
- if (entry.triggerElement.contains(currentTrigger)) continue;
86
- entry.close(isInitial);
87
- }
88
- };
89
-
90
- const closeNestedDialogs = (parentTrigger: HTMLElement, isInitial: boolean) => {
91
- for (const trigger of openDialogs) {
92
- if (trigger === parentTrigger) continue;
93
- const entry = dialogRegistry.get(trigger);
94
- if (!entry || !parentTrigger.contains(entry.triggerElement)) continue;
95
- entry.close(isInitial);
96
- }
97
- };
98
-
99
- const registerDialog = (entry: IDialogRegistryEntry) => {
100
- dialogRegistry.set(entry.triggerElement, entry);
101
- };
102
-
103
- const unregisterDialog = (triggerElement: HTMLElement) => {
104
- openDialogs.delete(triggerElement);
105
- dialogRegistry.delete(triggerElement);
106
- teardownGlobalDocumentClick();
107
- };
108
-
109
- /**
110
- *
111
- * @param children
112
- * @param position
113
- * @param buttonIdentity
114
- * @param background
115
- * @param defaultWidth The default width of the dialog box (in REM units).
116
- * @param defaultPadding
117
- * @param iggnoreChildClick
118
- * @param isFixedHeight
119
- * @param defaultClass
120
- * @param preferTopWhenEnoughSpace
121
- *
122
- * @returns
123
- */
124
- interface IDialogboxProps {
125
- children: React.ReactNode;
126
- hoverEffectDelay?: number | boolean;
127
- position?: EPositions;
128
- buttonIdentity: string;
129
- background?: EBackgrounds;
130
- defaultWidth?: number;
131
- defaultPadding?: number;
132
- autoAdjuctPosition?: boolean;
133
- iggnoreChildClick?: boolean;
134
- isFixedHeight?: boolean;
135
- preferTopWhenEnoughSpace?: boolean;
136
- defaultClass?: string;
137
- }
138
-
139
- export const GlobalDialogbox = ({ children, hoverEffectDelay, position, buttonIdentity, background, defaultWidth, defaultPadding, iggnoreChildClick, isFixedHeight, defaultClass, preferTopWhenEnoughSpace }: Readonly<IDialogboxProps>) => {
140
- const [isVisible, setIsVisible] = React.useState<boolean>(false);
141
-
142
- const onVisibilityChanged = (visible: boolean) => {
143
- setIsVisible(visible);
144
- };
145
- const onDisposed = () => {};
146
-
147
- useEffect(() => {
148
- let dialogResults: IDialogboxResults | null = null;
149
- const timeout = setTimeout(() => {
150
- clearTimeout(timeout);
151
- const button = document.getElementById(buttonIdentity);
152
- const dialog = document.getElementById(GetDialogId(buttonIdentity));
153
- if (!button || !dialog) return;
154
-
155
- const defaultHeight = isFixedHeight ? "80vh" : undefined;
156
- dialogResults = InitializeDialogbox(button, dialog, hoverEffectDelay, defaultHeight, defaultPadding, defaultWidth, background, onVisibilityChanged, onDisposed, iggnoreChildClick, position, defaultClass, preferTopWhenEnoughSpace, null);
157
- }, 0);
158
- return () => {
159
- dialogResults?.destroy();
160
- clearTimeout(timeout);
161
- };
162
- }, []);
163
-
164
- return <ul id={GetDialogId(buttonIdentity)}>{isVisible && children}</ul>;
165
- };
166
-
167
- export const InitializeDialogbox = (triggerElement: HTMLElement, affectedElement: HTMLElement, hoverEffectDelay?: number | boolean | UN, defaultHeight?: string | UN, defaultPadding?: number | UN, defaultWidth?: number | UN, background?: EBackgrounds | UN, onVisibilityChanged?: (isVisible: boolean) => void | UN, onDisposed?: () => void | UN, iggnoreChildClick?: boolean | UN, position?: EPositions | UN, defaultClass?: string | UN, preferTopWhenEnoughSpace?: boolean | UN, targetInput?: HTMLTextAreaElement | HTMLInputElement | UN, isAutoHideInInitialization?: boolean | UN): IDialogboxResults | null => {
168
- if (!triggerElement || !affectedElement) return null;
169
- defaultHeight = defaultHeight ?? "auto";
170
- defaultPadding = defaultPadding ?? 5;
171
- defaultWidth = defaultWidth ?? 34;
172
-
173
- const isTargetForInput: boolean = targetInput ? true : false;
174
-
175
- const forceUpdate = (index: number) => {
176
- if (index === 0) {
177
- affectedElement.classList.remove("anim", "dn");
178
- } else if (index === 1) {
179
- affectedElement.classList.add("dn");
180
- affectedElement.classList.remove("anim");
181
- }
182
- };
183
- const forceUpdateDebounced = Debounce(forceUpdate, 300);
184
- const refreshDialog = () => {
185
- const dialog = affectedElement;
186
- const parentElement = triggerElement;
187
-
188
- if (!parentElement) return;
189
-
190
- const inputRec = parentElement.getBoundingClientRect();
191
- const boxRec = dialog.getBoundingClientRect();
192
- const style = window.getComputedStyle(parentElement);
193
- const inputHeight = inputRec.height + parseFloat(style.borderBottomWidth) + parseFloat(style.borderTopWidth);
194
- const top = inputRec.top + inputHeight;
195
- const windowHeight = window.innerHeight;
196
- const bottomOverflow = top + boxRec.height;
197
- dialog.classList.remove("T");
198
-
199
- const topSpace = inputRec.top - boxRec.height;
200
- const bottomSpace = windowHeight - (inputRec.top + inputHeight + boxRec.height);
201
-
202
- if (!isTargetForInput) {
203
- if (preferTopWhenEnoughSpace && topSpace > 0 && bottomSpace > 0) {
204
- // Both sides have space, prefer top
205
- dialog.classList.add("T");
206
- dialog.style.top = `${top - inputHeight - boxRec.height}px`;
207
- } else if (bottomOverflow > windowHeight) {
208
- // Bottom overflow
209
- if (top - inputHeight - boxRec.height > 0) {
210
- dialog.classList.add("T");
211
- dialog.style.top = `${top - inputHeight - boxRec.height}px`;
212
- } else {
213
- // If no space on top either, push to bottom of screen
214
- dialog.style.top = `${windowHeight - boxRec.height}px`;
215
- }
216
- } else {
217
- // Default to bottom
218
- dialog.style.top = `${top}px`;
219
- }
220
- }
221
-
222
- // REM to PX conversion
223
-
224
- const DEFAULT_PADDING = ConvertRemToPixels(1);
225
-
226
- if (position === EPositions.Right) dialog.style.left = `${inputRec.right - boxRec.width}px`;
227
- else if (position === EPositions.Left) dialog.style.left = `${inputRec.left}px`;
228
- else if (position === EPositions.Center) dialog.style.left = `${inputRec.left + inputRec.width / 2 - boxRec.width / 2}px`;
229
-
230
- // Handle viewport overflow for dialogs without explicit position
231
- if (!position) {
232
- if (inputRec.left + boxRec.width > window.innerWidth) dialog.style.left = `${window.innerWidth - boxRec.width - DEFAULT_PADDING}px`;
233
- else dialog.style.left = `${inputRec.left}px`;
234
- } else {
235
- // For positioned dialogs, just check if they overflow and adjust if needed
236
- const currentLeft = parseFloat(dialog.style.left);
237
- if (!isNaN(currentLeft) && currentLeft + boxRec.width > window.innerWidth) {
238
- dialog.style.left = `${window.innerWidth - boxRec.width - DEFAULT_PADDING}px`;
239
- }
240
- }
241
-
242
- if (parseFloat(dialog.style.left) < DEFAULT_PADDING) dialog.style.left = `${DEFAULT_PADDING}px`;
243
-
244
- // ----- Arrow positioning (works for Left / Center / Right) -----
245
- const dialogRect = dialog.getBoundingClientRect();
246
- const inputCenterX = inputRec.left + inputRec.width / 2;
247
-
248
- // Arrow position relative to dialog
249
- let arrowLeft = inputCenterX - dialogRect.left + ConvertRemToPixels(0.15);
250
-
251
- // Clamp arrow to dialog bounds (optional but recommended)
252
- const ARROW_MARGIN = ConvertRemToPixels(1);
253
- arrowLeft = Math.max(ARROW_MARGIN, Math.min(arrowLeft, boxRec.width - ARROW_MARGIN));
254
-
255
- dialog.style.setProperty("--arrow-left", `${arrowLeft}px`);
256
-
257
- const pxWidth = inputRec.width;
258
- const DEFAULT_WIDTH = ConvertRemToPixels(defaultWidth);
259
- dialog.style.width = `${Math.max(pxWidth, DEFAULT_WIDTH)}px`;
260
- };
261
- const _onMouseEnter = (e: MouseEvent) => {
262
- if (!triggerElement.matches(":hover")) return;
263
- if (e.target !== triggerElement) return;
264
-
265
- const isVisible = triggerElement.getAttribute(VISIBILITY_KEY) === "true";
266
- if (!isVisible) visibility(true, false);
267
- };
268
- let hoverListenersAttached = false;
269
- let onMouseEnterDebounced: DebouncedFunction<typeof _onMouseEnter> | null = null;
270
- const getHoverDebounce = () => {
271
- if (!onMouseEnterDebounced) {
272
- onMouseEnterDebounced = Debounce(_onMouseEnter, (hoverEffectDelay === true ? DEFAULT_DIALOGBOX_HOVER_EFFECT_DELAY : (hoverEffectDelay as number)) ?? DEFAULT_DIALOGBOX_HOVER_EFFECT_DELAY);
273
- }
274
- return onMouseEnterDebounced;
275
- };
276
- const onMouseLeaveCancelHover = () => {
277
- onMouseEnterDebounced?.cancel();
278
- };
279
- const attachHoverListeners = () => {
280
- if (!hoverEffectDelay || hoverListenersAttached) return;
281
- triggerElement.addEventListener("mouseenter", getHoverDebounce());
282
- triggerElement.addEventListener("mouseleave", onMouseLeaveCancelHover);
283
- hoverListenersAttached = true;
284
- };
285
- const onHoverProxy = (e: MouseEvent) => {
286
- attachHoverListeners();
287
- triggerElement.removeEventListener("mouseenter", onHoverProxy);
288
- getHoverDebounce()(e);
289
- };
290
-
291
- const setupDialog = () => {
292
- triggerElement.addEventListener("click", onClick);
293
- if (hoverEffectDelay) triggerElement.addEventListener("mouseenter", onHoverProxy);
294
- if (isTargetForInput) {
295
- triggerElement.addEventListener("focusin", onFocus);
296
- triggerElement.addEventListener("focusout", onFocusOut);
297
- document.addEventListener("keydown", onKeyDown, true);
298
- }
299
-
300
- const timeout = setTimeout(() => {
301
- clearTimeout(timeout);
302
- refreshDialog();
303
- isAutoHideInInitialization = isAutoHideInInitialization ?? true;
304
- visibility(!isAutoHideInInitialization, true);
305
- }, 0);
306
- };
307
- const cleanupDialog = () => {
308
- triggerElement.setAttribute(VISIBILITY_KEY, "false");
309
- triggerElement.removeEventListener("click", onClick);
310
- if (hoverEffectDelay) {
311
- triggerElement.removeEventListener("mouseenter", onHoverProxy);
312
- if (hoverListenersAttached) {
313
- triggerElement.removeEventListener("mouseenter", getHoverDebounce());
314
- triggerElement.removeEventListener("mouseleave", onMouseLeaveCancelHover);
315
- onMouseEnterDebounced?.cancel();
316
- }
317
- }
318
- clearTimeout(visibilityTimeout);
319
- teardownGlobalDocumentClick();
320
- if (isTargetForInput) {
321
- triggerElement.removeEventListener("focusin", onFocus);
322
- triggerElement.removeEventListener("focusout", onFocusOut);
323
- document.removeEventListener("keydown", onKeyDown);
324
- document.removeEventListener("scroll", onDocumentScroll);
325
- }
326
- unregisterDialog(triggerElement);
327
- onDisposed?.();
328
- };
329
- // @ts-ignore
330
- let visibilityTimeout: NodeJS.Timeout;
331
- const visibility = (visible: boolean, isInitial: boolean) => {
332
- const isVisible = visible;
333
- if (!triggerElement) return;
334
- if (isVisible) {
335
- if (!isInitial) closeOtherDialogs(triggerElement, false);
336
-
337
- openDialogs.add(triggerElement);
338
- scheduleGlobalDocumentClick();
339
-
340
- clearTimeout(visibilityTimeout);
341
- forceUpdateDebounced.cancel();
342
- onMouseEnterDebounced?.cancel();
343
-
344
- onVisibilityChanged?.(isVisible);
345
- refreshDialog();
346
- const timeout2 = setTimeout(() => {
347
- clearTimeout(timeout2);
348
- refreshDialog();
349
- }, 0);
350
-
351
- affectedElement.classList.remove("dn");
352
- affectedElement.style.pointerEvents = "";
353
- const timeout = setTimeout(() => {
354
- clearTimeout(timeout);
355
- affectedElement.classList.remove("o0");
356
- affectedElement.classList.add("anim");
357
- triggerElement.setAttribute(VISIBILITY_KEY, "true");
358
- }, 10);
359
- forceUpdateDebounced(0);
360
-
361
- if (isTargetForInput) document.addEventListener("scroll", onDocumentScroll);
362
- } else {
363
- if (!isInitial) closeNestedDialogs(triggerElement, false);
364
-
365
- openDialogs.delete(triggerElement);
366
- teardownGlobalDocumentClick();
367
-
368
- if (isTargetForInput) document.removeEventListener("scroll", onDocumentScroll);
369
-
370
- affectedElement.classList.add("o0", "anim");
371
- affectedElement.style.pointerEvents = "none";
372
- if (isInitial) forceUpdate(1);
373
- forceUpdateDebounced(1);
374
- visibilityTimeout = setTimeout(() => {
375
- if (!isInitial) onVisibilityChanged?.(false);
376
- clearTimeout(visibilityTimeout);
377
- triggerElement.setAttribute(VISIBILITY_KEY, "false");
378
- }, DEFAULT_ANIMATION_DURATION);
379
- }
380
- };
381
- const onKeyDown = (e: KeyboardEvent) => {
382
- if (IsKeyPressed(e, EKeys.TAB)) if (document.activeElement !== triggerElement) visibility(false, false);
383
- };
384
- const onClick = (e: MouseEvent) => {
385
- const isOpen = triggerElement.getAttribute(VISIBILITY_KEY) === "true";
386
- const target = e.target as HTMLElement;
387
- if (isOpen && target.id !== triggerElement.id && target !== triggerElement) return;
388
-
389
- if (isOpen && isTargetForInput) return;
390
-
391
- visibility(!isOpen, false);
392
- e.stopPropagation();
393
- };
394
- const onFocus = (e: FocusEvent) => {
395
- if (isTargetForInput) visibility(true, false);
396
- };
397
-
398
- const onFocusOut = (e: FocusEvent) => {
399
- if (!isTargetForInput) return;
400
-
401
- if (!triggerElement) return;
402
- if (!e.relatedTarget || triggerElement.contains(e.relatedTarget as Node | null)) return;
403
-
404
- visibility(false, false);
405
- };
406
- const onDocumentScroll = (e: Event) => {};
407
-
408
- registerDialog({
409
- triggerElement,
410
- affectedElement,
411
- iggnoreChildClick,
412
- close: (isInitial) => visibility(false, isInitial),
413
- });
414
-
415
- if (!affectedElement.classList.contains("dialog")) {
416
- affectedElement.className = defaultClass ?? "dialog";
417
- affectedElement.classList.add("pf", "r", "bs2", "b1", "df", "ddc", `p${defaultPadding}`, background ?? NEXUS_CONFIG.DEFAULT_BACKGROUND, position ?? EPositions.Left);
418
- setupDialog();
419
- affectedElement.style.maxWidth = `calc(100vw - ${ConvertRemToPixels(2)}px)`;
420
- affectedElement.style.maxHeight = `calc(80vh)`;
421
- }
422
-
423
- // Add input-dialog class if it's a target for input to handle specific styling
424
- if (isTargetForInput && !affectedElement.classList.contains("input-dialog")) affectedElement.classList.add("input-dialog");
425
-
426
- return {
427
- destroy: cleanupDialog,
428
- visibility: visibility,
429
- isValid: () => !!affectedElement?.parentElement,
430
- } as IDialogboxResults;
431
- };
@@ -1,59 +0,0 @@
1
- "use server";
2
- import { Inter } from "next/font/google";
3
- import Script from "next/script";
4
- import React from "react";
5
- import { IGlobalLayout, ROOT_LOADER_IDENTITY } from "../../interfaces/layout-interfaces";
6
- import { FILES } from "../../nexus.environments";
7
- import { LayoutHelpers } from "./layout-helpers";
8
-
9
- import { GetSystemThemesAsync } from "../../api-services/system-service";
10
- import "./../../styles/nexus.animation.css";
11
- import "./../../styles/nexus.core.css";
12
- import "./../../styles/nexus.dialog.css";
13
- import "./../../styles/nexus.icon.css";
14
- import "./../../styles/nexus.input.css";
15
- import "./../../styles/nexus.loader.css";
16
- import "./../../styles/nexus.logic.css";
17
- import "./../../styles/nexus.utility.css";
18
-
19
- const inter = Inter({ weight: ["300", "400", "500", "600", "700", "800"], subsets: ["latin"] });
20
-
21
- export const GlobalLayout = async ({ children, globalLayout }: Readonly<{ children: React.ReactNode; globalLayout: IGlobalLayout }>) => {
22
- const systemThemes = await GetSystemThemesAsync();
23
- globalLayout.systemThemes = systemThemes;
24
- return (
25
- <html lang="en">
26
- <head>
27
- <title>{globalLayout.defaultDocumentTitle}</title>
28
- <meta name="description" content={globalLayout.defaultDocumentDescription} />
29
- <meta name="keywords" content={globalLayout.defaultDocumentKeywords.join(", ")} />
30
- <link rel="icon" href="/favicon.ico" />
31
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
32
- <style id="nexus-styles"></style>
33
- </head>
34
- <body className={inter.className}>
35
- <LayoutHelpers globalLayout={globalLayout} />
36
- <div
37
- style={{
38
- zIndex: "1000",
39
- width: "100vw",
40
- height: "100vh",
41
- position: "fixed",
42
- display: "flex",
43
- justifyContent: "center",
44
- alignItems: "center",
45
- backgroundColor: "rgb(60, 60, 60)",
46
- }}
47
- id={ROOT_LOADER_IDENTITY}
48
- >
49
- <a href={"/"} className="p5 h r bg52" style={{ marginTop: "8rem" }} title="Visit Home Page">
50
- <img src={FILES.LOGO.ICON} alt={"logo"} style={{ minHeight: "3rem", minWidth: "3rem", width: "3rem", height: "3rem" }} />
51
- </a>
52
- </div>
53
- {children}
54
- <Script type="module" src="https://cdn.jsdelivr.net/npm/ionicons@5.5.2/dist/ionicons/ionicons.esm.js" strategy="lazyOnload"></Script>
55
- <Script noModule src="https://cdn.jsdelivr.net/npm/ionicons@5.5.2/dist/ionicons/ionicons.js" strategy="lazyOnload"></Script>
56
- </body>
57
- </html>
58
- );
59
- };
@@ -1,20 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect } from "react";
4
- import { RemoveElement } from "../../helpers/browser-helpers";
5
- import { IGlobalLayout, ROOT_LOADER_IDENTITY } from "../../interfaces/layout-interfaces";
6
- import { O } from "../../nexus-client";
7
- import { InitializeStyles } from "../../services/theme-service";
8
-
9
- export const LayoutHelpers = ({ globalLayout }: Readonly<{ globalLayout: IGlobalLayout }>) => {
10
- useEffect(() => {
11
- O.systemThemes = globalLayout.systemThemes;
12
- const timeout = setTimeout(() => {
13
- clearTimeout(timeout);
14
- RemoveElement(ROOT_LOADER_IDENTITY, 500);
15
- InitializeStyles();
16
- }, 50);
17
- }, [globalLayout]);
18
-
19
- return <div className="nexus-popup-container"></div>;
20
- };
@@ -1,112 +0,0 @@
1
- import Image from "next/image";
2
- import React, { JSX, useEffect, useMemo, useState } from "react";
3
- import { GetProfileDetails } from "../../../api-services/authentication-service";
4
- import { BuildImageUrl, GetAuthPageURL, GetSignOutPageURL } from "../../../helpers/browser-helpers";
5
- import { BUTTON_IDENTITY, ClickHandler, EBackgrounds, EButtonTypes, EFileSizes, EIcons, EMenuVisibility, EOpacity, EPositions, ESizes, GetButton, GetUtilityMenuCode, IButton, ICurrentUser, IGlobalLayout, IPanelMenu, IsAdmin_SuperAdmin, UN } from "../../../interface";
6
- import { FILES } from "../../../nexus.environments";
7
- import { InputLoader, ShowLoader } from "../../../services/loader-service";
8
- import { SetCurrentUser } from "../../../services/user-services";
9
- import { Buttons } from "../../documents/button";
10
- import { Iconbox } from "../../documents/icon-box";
11
- import { GetUserRoleTag } from "../../documents/tag";
12
- import { GlobalDialogbox } from "../global-dialogbox";
13
-
14
- const USER_PROFILE_ID = GetUtilityMenuCode("user-profile");
15
- export const DEFAULT_USER_PROFILE_PICTURE_CLASS = "profile-user";
16
- const USER_PROFILE_BUTTON_ID = "user-profile-menu-tab";
17
-
18
- export const ProfilePanel = ({ globalLayout, userPanels, boxBackground, hasAccessToken }: Readonly<{ globalLayout: IGlobalLayout; userPanels: IPanelMenu[]; boxBackground?: EBackgrounds; hasAccessToken?: boolean | UN }>): JSX.Element => {
19
- const [isLoading, setIsLoading] = useState(hasAccessToken === true);
20
- const [currentUser, setCurrentUser] = useState<ICurrentUser | null>(null);
21
- const groupPanels = useMemo(() => {
22
- // TODO: Implement menu visibility logic
23
- const isAuthenticated = currentUser && currentUser.username && hasAccessToken === true;
24
- const visibilityFlag = isAuthenticated ? EMenuVisibility.AuthenticatedOnly : EMenuVisibility.GuestOnly;
25
- const visibleMenus = userPanels.filter((x) => (x.menuVisibilities & visibilityFlag) !== 0);
26
- return groupByGroupOrder(visibleMenus);
27
- }, [userPanels, currentUser]);
28
- const fetchProfileDetails = async () => {
29
- setIsLoading(true);
30
- InputLoader(USER_PROFILE_ID, true);
31
- const response = await GetProfileDetails(true);
32
- setCurrentUser(response);
33
- SetCurrentUser(response);
34
- setIsLoading(false);
35
- InputLoader(USER_PROFILE_ID, false);
36
- };
37
- useEffect(() => {
38
- if (hasAccessToken) fetchProfileDetails();
39
- }, [hasAccessToken]);
40
- return (
41
- <div id={USER_PROFILE_ID} className={`pr ${ESizes.Small} ib ${boxBackground} h p2 r`}>
42
- <Image src={FILES.ICONS.USER} alt="logo" width={74} height={74} className="img" />
43
- {!isLoading && (
44
- <GlobalDialogbox hoverEffectDelay={false} defaultPadding={0} position={EPositions.Left} buttonIdentity={USER_PROFILE_ID} iggnoreChildClick={false} defaultWidth={25}>
45
- <React.Fragment>
46
- <div className="bb h100 oh df ddc pl5">
47
- <div style={{ display: currentUser ? "flex" : "none" }} className="df ac pr5 pt5">
48
- <div className="ib xl oh item pr">
49
- {currentUser && <Iconbox onClicked={() => onEditProfileClicked(currentUser)} iconOpacity={EOpacity.NONE} iconDefaultClass="xl" defaultClass="xl pa ho1 bg950 rr" background={EBackgrounds.None} icon={EIcons.CAMERA} />}
50
- <img src={BuildImageUrl(currentUser?.profilePicture, EFileSizes.SIZE_128, FILES.ICONS.USER)} alt="profile-picture" className={`${DEFAULT_USER_PROFILE_PICTURE_CLASS} img ba2 rr`} />
51
- </div>
52
- <div className="ml5 w100">
53
- <div className="df ac">
54
- <h5 className="fw500 bg1 o09">{currentUser?.fullname}</h5>
55
- </div>
56
- <div className="df ac mt2">
57
- <p className="bg1 mr5 o06">{currentUser?.emailAddress ?? `@${currentUser?.username}`}</p>
58
- {IsAdmin_SuperAdmin(currentUser?.roleName) && GetUserRoleTag(currentUser?.roleName, true, "")}
59
- </div>
60
- </div>
61
- </div>
62
-
63
- <div className="sb sm h100 mt5 mb5 pr5">
64
- {groupPanels.map((group, index) => (
65
- <Buttons key={index} padding={0} pt={index !== 0 ? 5 : 0} buttons={group} />
66
- ))}
67
- </div>
68
- </div>
69
- </React.Fragment>
70
- </GlobalDialogbox>
71
- )}
72
- </div>
73
- );
74
- };
75
-
76
- const onEditProfileClicked = (currentUser: ICurrentUser) => {
77
- // TODO: Implement edit profile functionality
78
- };
79
-
80
- function groupByGroupOrder(menuArray: IPanelMenu[]): IButton[][] {
81
- const grouped: Record<number, IButton[]> = {};
82
- menuArray.forEach((menu) => {
83
- if (!grouped[menu.groupOrder]) {
84
- grouped[menu.groupOrder] = [];
85
- }
86
- grouped[menu.groupOrder].push(GetButton(menu.menuName, menu.menuCode, menu.menuUrl, menu.menuIcon, onClickedPanelMenu, menu, null, null, menu.displayOrder, null, null, 12, 0, EButtonTypes.BUTTON));
87
- });
88
-
89
- const groupedArray = Object.keys(grouped)
90
- .sort((a, b) => Number(a) - Number(b)) // Sort groups by groupOrder
91
- .map((groupKey) => grouped[Number(groupKey)].sort((a, b) => (a.displayOrder ?? 0) - (b.displayOrder ?? 0)));
92
-
93
- return groupedArray;
94
- }
95
-
96
- const onClickedPanelMenu: ClickHandler = async (event, element, data: IPanelMenu) => {
97
- switch (data.menuCode) {
98
- case BUTTON_IDENTITY(false).SIGN_IN_BUTTON: {
99
- ShowLoader();
100
- const url = GetAuthPageURL();
101
- return (window.location.href = url);
102
- }
103
- case BUTTON_IDENTITY(false).SIGN_OUT_BUTTON: {
104
- ShowLoader();
105
- SetCurrentUser(null);
106
- return (window.location.href = GetSignOutPageURL());
107
- }
108
- default: {
109
- break;
110
- }
111
- }
112
- };
@@ -1,49 +0,0 @@
1
- import { UN } from "nexus-shared";
2
- import { EIconTypes } from "../../interfaces/icon-interfaces";
3
- import { EOpacity, EPositions, ESizes, IGlobalLayout } from "../../interfaces/layout-interfaces";
4
- import { BUTTON_IDENTITY, GetUtilityMenuCode, IPanelMenu, IUtilityMenu } from "../../interfaces/menu-interfaces";
5
- import { EBackgrounds } from "../../interfaces/theme-interfaces";
6
- import { Iconbox } from "../documents/icon-box";
7
- import { PageTitle } from "../documents/page-title";
8
- import { ThemePanel } from "../panels/theme-panel";
9
- import { GlobalDialogbox } from "./global-dialogbox";
10
- import { ProfilePanel } from "./panels/user-panel";
11
-
12
- export const UtilityMenu = ({ utilityMenus, userPanels, column, paddingRight, globalLayout, iconBoxBackground, hasAccessToken }: Readonly<{ utilityMenus: IUtilityMenu[]; userPanels: IPanelMenu[]; column?: number; paddingRight?: number; globalLayout: IGlobalLayout; iconBoxBackground: EBackgrounds; hasAccessToken?: boolean | UN }>) => {
13
- return (
14
- <div style={{ paddingRight: paddingRight ?? 0 }} className={`utilities df fr ac jr h100p col-${column ?? 12}`}>
15
- {utilityMenus.map((utilityMenu, index) => (
16
- <UtilityIcon key={index} utilityMenu={utilityMenu} boxBackground={iconBoxBackground} globalLayout={globalLayout} />
17
- ))}
18
- <ProfilePanel globalLayout={globalLayout} boxBackground={iconBoxBackground} userPanels={userPanels} hasAccessToken={hasAccessToken} />
19
- </div>
20
- );
21
- };
22
-
23
- const UtilityIcon = ({ utilityMenu, globalLayout, boxBackground }: Readonly<{ utilityMenu: IUtilityMenu; globalLayout: IGlobalLayout; boxBackground?: EBackgrounds }>) => {
24
- return (
25
- <Iconbox id={GetUtilityMenuCode(utilityMenu.menuCode)} icon={utilityMenu.menuIcon} iconType={EIconTypes.FILLED} iconSize={ESizes.Small} boxSize={ESizes.Small} background={boxBackground} iconOpacity={EOpacity.O07} defaultClass="ml2">
26
- <UtilityDialogBox utilityMenu={utilityMenu} globalLayout={globalLayout} />
27
- </Iconbox>
28
- );
29
- };
30
-
31
- const UtilityDialogBox = ({ utilityMenu, globalLayout }: Readonly<{ utilityMenu: IUtilityMenu; globalLayout: IGlobalLayout }>) => {
32
- return (
33
- <GlobalDialogbox hoverEffectDelay={false} defaultPadding={5} position={EPositions.Left} buttonIdentity={GetUtilityMenuCode(utilityMenu.menuCode)} defaultWidth={30}>
34
- <div>
35
- <PageTitle marginBottom={5} borderBottom={1} title={utilityMenu.menuName} />
36
- <UtilityPanel utilityMenu={utilityMenu} globalLayout={globalLayout} />
37
- </div>
38
- </GlobalDialogbox>
39
- );
40
- };
41
-
42
- const UtilityPanel = ({ utilityMenu, globalLayout }: Readonly<{ utilityMenu: IUtilityMenu; globalLayout: IGlobalLayout }>) => {
43
- switch (utilityMenu.menuCode) {
44
- case BUTTON_IDENTITY(false).THEME_BOX:
45
- return <ThemePanel />;
46
- default:
47
- return <div>Unknown Panel: {utilityMenu.menuName}</div>;
48
- }
49
- };