nexus-shared 1.1.21 → 3.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 (376) hide show
  1. package/CHANGELOG.md +262 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1000 -0
  4. package/dist/Client.Index.d.ts +55 -0
  5. package/dist/Client.Index.js +60 -0
  6. package/dist/Components/Chats/Chat.d.ts +28 -0
  7. package/dist/Components/Chats/Chat.js +19 -0
  8. package/dist/Components/Chats/ChatButton.d.ts +26 -0
  9. package/dist/Components/Chats/ChatButton.js +41 -0
  10. package/dist/Components/Chats/ChatComposer.d.ts +41 -0
  11. package/dist/Components/Chats/ChatComposer.js +177 -0
  12. package/dist/Components/Chats/ChatConversations.d.ts +35 -0
  13. package/dist/Components/Chats/ChatConversations.js +38 -0
  14. package/dist/Components/Chats/ChatPanel.d.ts +66 -0
  15. package/dist/Components/Chats/ChatPanel.js +94 -0
  16. package/dist/Components/Chats/ChatParts.d.ts +87 -0
  17. package/dist/Components/Chats/ChatParts.js +100 -0
  18. package/dist/Components/Chats/ChatThread.d.ts +22 -0
  19. package/dist/Components/Chats/ChatThread.js +96 -0
  20. package/dist/Components/Documents/Button.d.ts +29 -0
  21. package/dist/Components/Documents/Button.js +11 -0
  22. package/dist/Components/Documents/Menu.d.ts +102 -0
  23. package/dist/Components/Documents/Menu.js +242 -0
  24. package/dist/Components/Documents/SplitButton.d.ts +64 -0
  25. package/dist/Components/Documents/SplitButton.js +129 -0
  26. package/dist/Components/Documents/TabButtons.d.ts +80 -0
  27. package/dist/Components/Documents/TabButtons.js +38 -0
  28. package/dist/Components/Forms/ApiForm.d.ts +23 -0
  29. package/dist/Components/Forms/ApiForm.js +100 -0
  30. package/dist/Components/Forms/Crud.d.ts +17 -0
  31. package/dist/Components/Forms/Crud.js +708 -0
  32. package/dist/Components/Forms/CrudParts.d.ts +15 -0
  33. package/dist/Components/Forms/CrudParts.js +36 -0
  34. package/dist/Components/Forms/ExcelImport.d.ts +42 -0
  35. package/dist/Components/Forms/ExcelImport.js +190 -0
  36. package/dist/Components/Forms/Form.d.ts +52 -0
  37. package/dist/Components/Forms/Form.js +323 -0
  38. package/dist/Components/Forms/SubmitForm.d.ts +65 -0
  39. package/dist/Components/Forms/SubmitForm.js +198 -0
  40. package/dist/Components/Inputs/Calendar.d.ts +69 -0
  41. package/dist/Components/Inputs/Calendar.js +258 -0
  42. package/dist/Components/Inputs/CheckBox.d.ts +53 -0
  43. package/dist/Components/Inputs/CheckBox.js +87 -0
  44. package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
  45. package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
  46. package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
  47. package/dist/Components/Inputs/ChoiceField.js +169 -0
  48. package/dist/Components/Inputs/DatePicker.d.ts +54 -0
  49. package/dist/Components/Inputs/DatePicker.js +246 -0
  50. package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
  51. package/dist/Components/Inputs/DateRangePicker.js +283 -0
  52. package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
  53. package/dist/Components/Inputs/DateTimePicker.js +400 -0
  54. package/dist/Components/Inputs/Dropdown.d.ts +117 -0
  55. package/dist/Components/Inputs/Dropdown.js +839 -0
  56. package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
  57. package/dist/Components/Inputs/DropdownParts.js +102 -0
  58. package/dist/Components/Inputs/EditorShell.d.ts +45 -0
  59. package/dist/Components/Inputs/EditorShell.js +214 -0
  60. package/dist/Components/Inputs/Field.d.ts +53 -0
  61. package/dist/Components/Inputs/Field.js +16 -0
  62. package/dist/Components/Inputs/GroupForm.d.ts +20 -0
  63. package/dist/Components/Inputs/GroupForm.js +172 -0
  64. package/dist/Components/Inputs/InputField.d.ts +59 -0
  65. package/dist/Components/Inputs/InputField.js +169 -0
  66. package/dist/Components/Inputs/InputRenderer.d.ts +37 -0
  67. package/dist/Components/Inputs/InputRenderer.js +99 -0
  68. package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
  69. package/dist/Components/Inputs/MarkdownEditor.js +289 -0
  70. package/dist/Components/Inputs/NumberBox.d.ts +53 -0
  71. package/dist/Components/Inputs/NumberBox.js +228 -0
  72. package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
  73. package/dist/Components/Inputs/RadioGroup.js +43 -0
  74. package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
  75. package/dist/Components/Inputs/ReadOnlyNotice.js +117 -0
  76. package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
  77. package/dist/Components/Inputs/RichTextEditor.js +1170 -0
  78. package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
  79. package/dist/Components/Inputs/RichTextParts.js +157 -0
  80. package/dist/Components/Inputs/RowsInput.d.ts +115 -0
  81. package/dist/Components/Inputs/RowsInput.js +308 -0
  82. package/dist/Components/Inputs/Slider.d.ts +87 -0
  83. package/dist/Components/Inputs/Slider.js +216 -0
  84. package/dist/Components/Inputs/TabularForm.d.ts +27 -0
  85. package/dist/Components/Inputs/TabularForm.js +348 -0
  86. package/dist/Components/Inputs/TextArea.d.ts +43 -0
  87. package/dist/Components/Inputs/TextArea.js +31 -0
  88. package/dist/Components/Inputs/TextBox.d.ts +52 -0
  89. package/dist/Components/Inputs/TextBox.js +58 -0
  90. package/dist/Components/Inputs/TextField.d.ts +31 -0
  91. package/dist/Components/Inputs/TextField.js +35 -0
  92. package/dist/Components/Inputs/TimePanel.d.ts +34 -0
  93. package/dist/Components/Inputs/TimePanel.js +288 -0
  94. package/dist/Components/Inputs/TimePicker.d.ts +54 -0
  95. package/dist/Components/Inputs/TimePicker.js +240 -0
  96. package/dist/Components/Inputs/TreeView.d.ts +160 -0
  97. package/dist/Components/Inputs/TreeView.js +947 -0
  98. package/dist/Components/Layouts/MessageBox.d.ts +71 -0
  99. package/dist/Components/Layouts/MessageBox.js +104 -0
  100. package/dist/Components/Layouts/Popup.d.ts +92 -0
  101. package/dist/Components/Layouts/Popup.js +376 -0
  102. package/dist/Components/Layouts/PopupContext.d.ts +2 -0
  103. package/dist/Components/Layouts/PopupContext.js +4 -0
  104. package/dist/Components/Layouts/PopupDock.d.ts +22 -0
  105. package/dist/Components/Layouts/PopupDock.js +121 -0
  106. package/dist/Components/Layouts/PopupHost.d.ts +56 -0
  107. package/dist/Components/Layouts/PopupHost.js +163 -0
  108. package/dist/Components/Layouts/PopupRules.d.ts +30 -0
  109. package/dist/Components/Layouts/PopupRules.js +63 -0
  110. package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
  111. package/dist/Components/Layouts/ThemePicker.js +22 -0
  112. package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
  113. package/dist/Components/Layouts/ThemeScript.js +13 -0
  114. package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
  115. package/dist/Components/Layouts/ThemeSwitcher.js +49 -0
  116. package/dist/Components/Layouts/Toaster.d.ts +76 -0
  117. package/dist/Components/Layouts/Toaster.js +172 -0
  118. package/dist/Components/Viewers/DataTable.d.ts +25 -0
  119. package/dist/Components/Viewers/DataTable.js +596 -0
  120. package/dist/Components/Viewers/DataTableColumns.d.ts +28 -0
  121. package/dist/Components/Viewers/DataTableColumns.js +243 -0
  122. package/dist/Components/Viewers/DataTableParts.d.ts +138 -0
  123. package/dist/Components/Viewers/DataTableParts.js +157 -0
  124. package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
  125. package/dist/Components/Viewers/MarkdownView.js +79 -0
  126. package/dist/Components/Viewers/RichTextView.d.ts +18 -0
  127. package/dist/Components/Viewers/RichTextView.js +17 -0
  128. package/dist/Helpers/AnimationHelpers.d.ts +6 -0
  129. package/dist/Helpers/AnimationHelpers.js +35 -0
  130. package/dist/Helpers/ApiClient.d.ts +96 -0
  131. package/dist/Helpers/ApiClient.js +200 -0
  132. package/dist/Helpers/ApiFormHelpers.d.ts +49 -0
  133. package/dist/Helpers/ApiFormHelpers.js +120 -0
  134. package/dist/Helpers/ApiModules.d.ts +131 -0
  135. package/dist/Helpers/ApiModules.js +195 -0
  136. package/dist/Helpers/ApiResponses.d.ts +51 -0
  137. package/dist/Helpers/ApiResponses.js +250 -0
  138. package/dist/Helpers/ApiRoutes.d.ts +140 -0
  139. package/dist/Helpers/ApiRoutes.js +183 -0
  140. package/dist/Helpers/ApiToasts.d.ts +21 -0
  141. package/dist/Helpers/ApiToasts.js +22 -0
  142. package/dist/Helpers/ChatBackend.d.ts +134 -0
  143. package/dist/Helpers/ChatBackend.js +332 -0
  144. package/dist/Helpers/ChatHelpers.d.ts +189 -0
  145. package/dist/Helpers/ChatHelpers.js +486 -0
  146. package/dist/Helpers/ChatHooks.d.ts +81 -0
  147. package/dist/Helpers/ChatHooks.js +175 -0
  148. package/dist/Helpers/ChatStore.d.ts +132 -0
  149. package/dist/Helpers/ChatStore.js +394 -0
  150. package/dist/Helpers/ChatSummaries.d.ts +39 -0
  151. package/dist/Helpers/ChatSummaries.js +118 -0
  152. package/dist/Helpers/ClassHelpers.d.ts +3 -0
  153. package/dist/Helpers/ClassHelpers.js +4 -0
  154. package/dist/Helpers/CrudBackend.d.ts +98 -0
  155. package/dist/Helpers/CrudBackend.js +214 -0
  156. package/dist/Helpers/CrudHelpers.d.ts +111 -0
  157. package/dist/Helpers/CrudHelpers.js +267 -0
  158. package/dist/Helpers/DateHelpers.d.ts +88 -0
  159. package/dist/Helpers/DateHelpers.js +363 -0
  160. package/dist/Helpers/DatePreferences.d.ts +14 -0
  161. package/dist/Helpers/DatePreferences.js +94 -0
  162. package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
  163. package/dist/Helpers/DateTimeHelpers.js +286 -0
  164. package/dist/Helpers/DragHelpers.d.ts +129 -0
  165. package/dist/Helpers/DragHelpers.js +281 -0
  166. package/dist/Helpers/DropdownHelpers.d.ts +56 -0
  167. package/dist/Helpers/DropdownHelpers.js +180 -0
  168. package/dist/Helpers/ExcelBackend.d.ts +106 -0
  169. package/dist/Helpers/ExcelBackend.js +290 -0
  170. package/dist/Helpers/ExcelHelpers.d.ts +98 -0
  171. package/dist/Helpers/ExcelHelpers.js +302 -0
  172. package/dist/Helpers/FormDrafts.d.ts +18 -0
  173. package/dist/Helpers/FormDrafts.js +76 -0
  174. package/dist/Helpers/FormStore.d.ts +233 -0
  175. package/dist/Helpers/FormStore.js +752 -0
  176. package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
  177. package/dist/Helpers/InputParamsHelpers.js +388 -0
  178. package/dist/Helpers/MarkdownEditing.d.ts +27 -0
  179. package/dist/Helpers/MarkdownEditing.js +250 -0
  180. package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
  181. package/dist/Helpers/MarkdownHelpers.js +775 -0
  182. package/dist/Helpers/MessageBuilder.d.ts +74 -0
  183. package/dist/Helpers/MessageBuilder.js +252 -0
  184. package/dist/Helpers/NepaliCalendar.d.ts +25 -0
  185. package/dist/Helpers/NepaliCalendar.js +107 -0
  186. package/dist/Helpers/NumberHelpers.d.ts +71 -0
  187. package/dist/Helpers/NumberHelpers.js +202 -0
  188. package/dist/Helpers/Permissions.d.ts +62 -0
  189. package/dist/Helpers/Permissions.js +133 -0
  190. package/dist/Helpers/PopoverHelpers.d.ts +68 -0
  191. package/dist/Helpers/PopoverHelpers.js +195 -0
  192. package/dist/Helpers/RichTextHelpers.d.ts +77 -0
  193. package/dist/Helpers/RichTextHelpers.js +1072 -0
  194. package/dist/Helpers/RowsStore.d.ts +166 -0
  195. package/dist/Helpers/RowsStore.js +606 -0
  196. package/dist/Helpers/TableColumns.d.ts +47 -0
  197. package/dist/Helpers/TableColumns.js +282 -0
  198. package/dist/Helpers/TableExport.d.ts +30 -0
  199. package/dist/Helpers/TableExport.js +97 -0
  200. package/dist/Helpers/TableHelpers.d.ts +110 -0
  201. package/dist/Helpers/TableHelpers.js +301 -0
  202. package/dist/Helpers/TableStore.d.ts +142 -0
  203. package/dist/Helpers/TableStore.js +530 -0
  204. package/dist/Helpers/ThemeHelpers.d.ts +15 -0
  205. package/dist/Helpers/ThemeHelpers.js +16 -0
  206. package/dist/Helpers/TimeHelpers.d.ts +73 -0
  207. package/dist/Helpers/TimeHelpers.js +253 -0
  208. package/dist/Helpers/TreeStore.d.ts +188 -0
  209. package/dist/Helpers/TreeStore.js +577 -0
  210. package/dist/Helpers/ValidationHelpers.d.ts +124 -0
  211. package/dist/Helpers/ValidationHelpers.js +301 -0
  212. package/dist/Interfaces/ApiInterfaces.d.ts +174 -0
  213. package/dist/Interfaces/ApiInterfaces.js +30 -0
  214. package/dist/Interfaces/ChatInterfaces.d.ts +240 -0
  215. package/{src/sso-client.tsx → dist/Interfaces/ChatInterfaces.js} +1 -1
  216. package/dist/Interfaces/CrudInterfaces.d.ts +232 -0
  217. package/dist/Interfaces/CrudInterfaces.js +1 -0
  218. package/dist/Interfaces/DateInterfaces.d.ts +154 -0
  219. package/dist/Interfaces/DateInterfaces.js +29 -0
  220. package/dist/Interfaces/ExcelInterfaces.d.ts +215 -0
  221. package/dist/Interfaces/ExcelInterfaces.js +45 -0
  222. package/dist/Interfaces/FormInterfaces.d.ts +402 -0
  223. package/dist/Interfaces/FormInterfaces.js +1 -0
  224. package/dist/Interfaces/InputInterfaces.d.ts +141 -0
  225. package/dist/Interfaces/InputInterfaces.js +1 -0
  226. package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
  227. package/dist/Interfaces/MessageInterfaces.js +5 -0
  228. package/dist/Interfaces/TableInterfaces.d.ts +351 -0
  229. package/dist/Interfaces/TableInterfaces.js +1 -0
  230. package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
  231. package/dist/Interfaces/ThemeInterfaces.js +17 -0
  232. package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
  233. package/dist/Interfaces/TypeInterfaces.js +1 -0
  234. package/dist/Server.Index.d.ts +2 -0
  235. package/dist/Server.Index.js +5 -0
  236. package/dist/Services/ApiProxy.d.ts +32 -0
  237. package/dist/Services/ApiProxy.js +111 -0
  238. package/dist/Services/BrowserApi.d.ts +95 -0
  239. package/dist/Services/BrowserApi.js +129 -0
  240. package/dist/Services/ChatApi.d.ts +37 -0
  241. package/dist/Services/ChatApi.js +98 -0
  242. package/dist/Services/ExcelApi.d.ts +46 -0
  243. package/dist/Services/ExcelApi.js +196 -0
  244. package/dist/Services/ServerApi.d.ts +54 -0
  245. package/dist/Services/ServerApi.js +78 -0
  246. package/dist/Services/ThemeService.d.ts +17 -0
  247. package/dist/Services/ThemeService.js +83 -0
  248. package/dist/Shared.Index.d.ts +51 -0
  249. package/dist/Shared.Index.js +55 -0
  250. package/package.json +85 -33
  251. package/src/Styles/Nexus.Base.css +70 -0
  252. package/src/Styles/Nexus.Button.css +153 -0
  253. package/src/Styles/Nexus.Calendar.css +275 -0
  254. package/src/Styles/Nexus.Chat.css +1489 -0
  255. package/src/Styles/Nexus.Choice.css +345 -0
  256. package/src/Styles/Nexus.Crud.css +161 -0
  257. package/src/Styles/Nexus.DateTime.css +81 -0
  258. package/src/Styles/Nexus.Dropdown.css +774 -0
  259. package/src/Styles/Nexus.Editor.css +297 -0
  260. package/src/Styles/Nexus.Excel.css +370 -0
  261. package/src/Styles/Nexus.Form.css +321 -0
  262. package/src/Styles/Nexus.Index.css +36 -0
  263. package/src/Styles/Nexus.Input.css +637 -0
  264. package/src/Styles/Nexus.Markdown.css +265 -0
  265. package/src/Styles/Nexus.Menu.css +259 -0
  266. package/src/Styles/Nexus.Popup.css +731 -0
  267. package/src/Styles/Nexus.RichText.css +463 -0
  268. package/src/Styles/Nexus.Rows.css +596 -0
  269. package/src/Styles/Nexus.Slider.css +278 -0
  270. package/src/Styles/Nexus.Tab.Buttons.css +419 -0
  271. package/src/Styles/Nexus.Table.css +1296 -0
  272. package/src/Styles/Nexus.Theme.Picker.css +232 -0
  273. package/src/Styles/Nexus.Themes.css +194 -0
  274. package/src/Styles/Nexus.Time.css +147 -0
  275. package/src/Styles/Nexus.Toast.css +265 -0
  276. package/src/Styles/Nexus.Tokens.css +72 -0
  277. package/src/Styles/Nexus.Tree.css +435 -0
  278. package/src/api-services/authentication-service.tsx +0 -23
  279. package/src/api-services/preference-service.tsx +0 -5
  280. package/src/api-services/system-service.tsx +0 -29
  281. package/src/client.ts +0 -31
  282. package/src/components/documents/button.tsx +0 -133
  283. package/src/components/documents/icon-box.tsx +0 -93
  284. package/src/components/documents/page-title.tsx +0 -7
  285. package/src/components/documents/tab-button.tsx +0 -172
  286. package/src/components/documents/tag.tsx +0 -30
  287. package/src/components/index.js +0 -0
  288. package/src/components/inputs/checkbox-input.tsx +0 -66
  289. package/src/components/inputs/input-box.tsx +0 -48
  290. package/src/components/inputs/input-element.tsx +0 -65
  291. package/src/components/inputs/input-form.tsx +0 -164
  292. package/src/components/inputs/input.tsx +0 -181
  293. package/src/components/inputs/number-input.tsx +0 -108
  294. package/src/components/inputs/radiobox-input.tsx +0 -53
  295. package/src/components/inputs/textarea-input.tsx +0 -47
  296. package/src/components/inputs/textbox-input.tsx +0 -45
  297. package/src/components/layouts/global-dialogbox.tsx +0 -431
  298. package/src/components/layouts/global-layout.tsx +0 -64
  299. package/src/components/layouts/layout-helpers.tsx +0 -20
  300. package/src/components/layouts/panels/user-panel.tsx +0 -112
  301. package/src/components/layouts/utility-menu.tsx +0 -49
  302. package/src/components/panels/theme-panel.tsx +0 -46
  303. package/src/helpers/bitwise-helpers.tsx +0 -11
  304. package/src/helpers/browser-helpers.tsx +0 -156
  305. package/src/helpers/datasource-helpers.tsx +0 -99
  306. package/src/helpers/element-helpers.tsx +0 -123
  307. package/src/helpers/input-helpers.tsx +0 -74
  308. package/src/helpers/string-helpers.tsx +0 -28
  309. package/src/helpers/utility-helpers.tsx +0 -45
  310. package/src/helpers/validation-helpers.tsx +0 -302
  311. package/src/index.ts +0 -26
  312. package/src/interface.ts +0 -19
  313. package/src/interfaces/auth-token-interfaces.tsx +0 -6
  314. package/src/interfaces/browser-interfaces.tsx +0 -36
  315. package/src/interfaces/button-interfaces.tsx +0 -63
  316. package/src/interfaces/datasource-interfaces.tsx +0 -22
  317. package/src/interfaces/datatable-interfaces.tsx +0 -25
  318. package/src/interfaces/dialogbox-interfaces.tsx +0 -5
  319. package/src/interfaces/exception-interfaces.tsx +0 -99
  320. package/src/interfaces/http-interfaces.tsx +0 -129
  321. package/src/interfaces/icon-interfaces.tsx +0 -129
  322. package/src/interfaces/input-interfaces.tsx +0 -410
  323. package/src/interfaces/layout-interfaces.tsx +0 -191
  324. package/src/interfaces/menu-interfaces.tsx +0 -53
  325. package/src/interfaces/message-interfaces.tsx +0 -32
  326. package/src/interfaces/permission-interfaces.tsx +0 -9
  327. package/src/interfaces/storage-interfaces.tsx +0 -5
  328. package/src/interfaces/system-interfaces.tsx +0 -22
  329. package/src/interfaces/theme-interfaces.tsx +0 -123
  330. package/src/interfaces/type-interfaces.tsx +0 -28
  331. package/src/interfaces/user-interfaces.tsx +0 -47
  332. package/src/nexus-client.tsx +0 -21
  333. package/src/nexus.environments.tsx +0 -66
  334. package/src/proxy-api/proxy-backend.tsx +0 -60
  335. package/src/proxy-api/proxy-constants.tsx +0 -28
  336. package/src/proxy-api/proxy-helpers.tsx +0 -91
  337. package/src/proxy-api-client.tsx +0 -1
  338. package/src/proxy-api-server.tsx +0 -2
  339. package/src/services/http-client-services.tsx +0 -75
  340. package/src/services/http-services.tsx +0 -158
  341. package/src/services/loader-service.tsx +0 -185
  342. package/src/services/localstorage-service.tsx +0 -119
  343. package/src/services/message-services.tsx +0 -383
  344. package/src/services/theme-service.tsx +0 -163
  345. package/src/services/user-services.tsx +0 -10
  346. package/src/sso-config/auth-token-validation.ts +0 -16
  347. package/src/sso-config/callback-route.tsx +0 -35
  348. package/src/sso-config/cookie-encryption.ts +0 -51
  349. package/src/sso-config/cookie-helpers.tsx +0 -102
  350. package/src/sso-config/forgot-password-route.tsx +0 -36
  351. package/src/sso-config/oauth-callback-state.ts +0 -61
  352. package/src/sso-config/pkce-helpers.ts +0 -9
  353. package/src/sso-config/provider-complete-route.tsx +0 -18
  354. package/src/sso-config/redirect-context-actions.tsx +0 -45
  355. package/src/sso-config/redirect-context-helpers.tsx +0 -159
  356. package/src/sso-config/redirect-context-persist.tsx +0 -18
  357. package/src/sso-config/redirect-context-route.tsx +0 -45
  358. package/src/sso-config/refresh-route.tsx +0 -23
  359. package/src/sso-config/sign-in-route.tsx +0 -74
  360. package/src/sso-config/sign-out-route.tsx +0 -57
  361. package/src/sso-config/sign-up-route.tsx +0 -57
  362. package/src/sso-config/sso-backend-flow.ts +0 -38
  363. package/src/sso-config/sso-complete-route.tsx +0 -50
  364. package/src/sso-config/sso-config.ts +0 -59
  365. package/src/sso-config/sso-interfaces.tsx +0 -99
  366. package/src/sso-config/sso-response-helpers.tsx +0 -20
  367. package/src/sso-server.tsx +0 -21
  368. package/src/styles/nexus.animation.css +0 -269
  369. package/src/styles/nexus.core.css +0 -119
  370. package/src/styles/nexus.dialog.css +0 -144
  371. package/src/styles/nexus.grid-view.css +0 -42
  372. package/src/styles/nexus.icon.css +0 -51
  373. package/src/styles/nexus.input.css +0 -207
  374. package/src/styles/nexus.loader.css +0 -11
  375. package/src/styles/nexus.logic.css +0 -47
  376. package/src/styles/nexus.utility.css +0 -347
@@ -0,0 +1,281 @@
1
+ "use client";
2
+ import { useEffect, useLayoutEffect, useRef } from "react";
3
+ /** Controls inside a handle keep their own clicks and text selection. */
4
+ export const DRAG_CANCEL_SELECTOR = 'button, a[href], input, select, textarea, label, summary, [contenteditable]:not([contenteditable="false"]), [data-nx-no-drag]';
5
+ /** The browser window, without its scrollbars. */
6
+ export function viewportBounds() {
7
+ const root = document.documentElement;
8
+ return { left: 0, top: 0, width: root.clientWidth || window.innerWidth, height: root.clientHeight || window.innerHeight };
9
+ }
10
+ /** The inside of an element's borders (its padding box), without a scrollbar, in viewport pixels. */
11
+ export function elementBounds(element) {
12
+ const rect = element.getBoundingClientRect();
13
+ const html = element;
14
+ // An inline element has no client box; its outer box stands in.
15
+ if (!html.clientWidth && !html.clientHeight)
16
+ return { left: rect.left, top: rect.top, width: rect.width, height: rect.height };
17
+ return { left: rect.left + html.clientLeft, top: rect.top + html.clientTop, width: html.clientWidth, height: html.clientHeight };
18
+ }
19
+ /** Turns a `DragBounds` into a box, for an element being moved. */
20
+ export function resolveBounds(bounds, element) {
21
+ if (bounds === undefined || bounds === "viewport")
22
+ return viewportBounds();
23
+ if (bounds === null)
24
+ return null;
25
+ if (bounds === "parent") {
26
+ const parent = element.offsetParent ?? element.parentElement;
27
+ return parent ? elementBounds(parent) : viewportBounds();
28
+ }
29
+ if (typeof bounds === "function")
30
+ return bounds();
31
+ if (bounds instanceof Element)
32
+ return elementBounds(bounds);
33
+ return bounds;
34
+ }
35
+ function clampAxis(start, size, min, room, keepVisible) {
36
+ if (keepVisible === undefined)
37
+ return Math.max(min, Math.min(start, min + room - size));
38
+ const keep = Math.min(Math.max(keepVisible, 0), size);
39
+ return Math.max(min - size + keep, Math.min(start, min + room - keep));
40
+ }
41
+ /**
42
+ * The top-left corner a box must move to, the least distance, to stay inside bounds.
43
+ *
44
+ * @example clampToBounds({ left: -20, top: 40, width: 300, height: 200 }, viewportBounds()) // { x: 0, y: 40 }
45
+ */
46
+ export function clampToBounds(box, bounds, options = {}) {
47
+ const margin = options.margin ?? 0;
48
+ return {
49
+ x: clampAxis(box.left, box.width, bounds.left + margin, bounds.width - 2 * margin, options.keepVisible),
50
+ y: clampAxis(box.top, box.height, bounds.top + margin, bounds.height - 2 * margin, options.keepVisible),
51
+ };
52
+ }
53
+ function readPixels(value) {
54
+ const [x = 0, y = 0] = value.split(/\s+/).map(part => Number.parseFloat(part));
55
+ return { x: Number.isFinite(x) ? x : 0, y: Number.isFinite(y) ? y : 0 };
56
+ }
57
+ /** The default position: the element's inline CSS `translate`, in pixels. */
58
+ export function translatePosition(element) {
59
+ return {
60
+ get: () => readPixels(element.style.translate),
61
+ set: ({ x, y }) => {
62
+ element.style.translate = `${x}px ${y}px`;
63
+ },
64
+ };
65
+ }
66
+ /** A position kept in two CSS variables on the element, for a stylesheet that places it with them (and can ignore them, e.g. when maximized). */
67
+ export function cssVariablePosition(element, xVariable, yVariable) {
68
+ return {
69
+ get: () => ({ x: Number.parseFloat(element.style.getPropertyValue(xVariable)) || 0, y: Number.parseFloat(element.style.getPropertyValue(yVariable)) || 0 }),
70
+ set: ({ x, y }) => {
71
+ element.style.setProperty(xVariable, `${x}px`);
72
+ element.style.setProperty(yVariable, `${y}px`);
73
+ },
74
+ };
75
+ }
76
+ /**
77
+ * Moves an element by an offset, kept inside bounds, and returns its new position. With no offset it pulls an element
78
+ * back inside, e.g. after the window got smaller or the element grew. Also the way to move an element from the keyboard.
79
+ */
80
+ export function moveWithin(element, by, options = {}) {
81
+ const position = options.position ?? translatePosition(element);
82
+ const from = position.get();
83
+ let dx = options.axis === "y" ? 0 : by.x;
84
+ let dy = options.axis === "x" ? 0 : by.y;
85
+ const bounds = resolveBounds(options.bounds, element);
86
+ if (bounds) {
87
+ const rect = element.getBoundingClientRect();
88
+ const corner = clampToBounds({ left: rect.left + dx, top: rect.top + dy, width: rect.width, height: rect.height }, bounds, options);
89
+ if (options.axis !== "y")
90
+ dx = corner.x - rect.left;
91
+ if (options.axis !== "x")
92
+ dy = corner.y - rect.top;
93
+ }
94
+ const to = { x: from.x + dx, y: from.y + dy };
95
+ if (to.x !== from.x || to.y !== from.y)
96
+ position.set(to);
97
+ return to;
98
+ }
99
+ /**
100
+ * Starts dragging `target` from a `pointerdown` event, e.g. in a React `onPointerDown` on a title bar. The target
101
+ * follows the pointer once it has moved past the threshold, stays inside the bounds, and goes back where it started on
102
+ * Esc. The handle needs `touch-action: none` in its CSS, or a touch pans the page instead. Returns a function that ends
103
+ * the drag early.
104
+ */
105
+ export function startDrag(event, options) {
106
+ const { target, threshold = 3, axis = "both" } = options;
107
+ const position = options.position ?? translatePosition(target);
108
+ const handle = options.handle ?? (event.currentTarget instanceof Element ? event.currentTarget : target);
109
+ const pointerId = event.pointerId;
110
+ const start = { x: event.clientX, y: event.clientY };
111
+ let pointer = start;
112
+ let moving = false;
113
+ let done = false;
114
+ let base = { x: 0, y: 0 };
115
+ let baseRect = { left: 0, top: 0, width: 0, height: 0 };
116
+ let bounds = null;
117
+ let current = { x: 0, y: 0 };
118
+ const state = () => ({ target, start, pointer, position: current, delta: { x: current.x - base.x, y: current.y - base.y } });
119
+ function place() {
120
+ let dx = axis === "y" ? 0 : pointer.x - start.x;
121
+ let dy = axis === "x" ? 0 : pointer.y - start.y;
122
+ if (bounds) {
123
+ const corner = clampToBounds({ left: baseRect.left + dx, top: baseRect.top + dy, width: baseRect.width, height: baseRect.height }, bounds, options);
124
+ if (axis !== "y")
125
+ dx = corner.x - baseRect.left;
126
+ if (axis !== "x")
127
+ dy = corner.y - baseRect.top;
128
+ }
129
+ current = { x: base.x + dx, y: base.y + dy };
130
+ position.set(current);
131
+ options.onMove?.(state());
132
+ }
133
+ function begin() {
134
+ current = position.get();
135
+ base = current;
136
+ if (options.onStart?.(state()) === false)
137
+ return false;
138
+ base = position.get();
139
+ current = base;
140
+ const rect = target.getBoundingClientRect();
141
+ baseRect = { left: rect.left, top: rect.top, width: rect.width, height: rect.height };
142
+ bounds = resolveBounds(options.bounds, target);
143
+ moving = true;
144
+ target.setAttribute("data-nx-dragging", "");
145
+ window.getSelection()?.removeAllRanges();
146
+ try {
147
+ handle.setPointerCapture(pointerId);
148
+ }
149
+ catch {
150
+ // The pointer is already gone; the next pointerup ends the drag.
151
+ }
152
+ return true;
153
+ }
154
+ function onPointerMove(move) {
155
+ if (move.pointerId !== pointerId)
156
+ return;
157
+ pointer = { x: move.clientX, y: move.clientY };
158
+ if (!moving) {
159
+ if (Math.hypot(pointer.x - start.x, pointer.y - start.y) < threshold)
160
+ return;
161
+ if (!begin())
162
+ return finish(false);
163
+ }
164
+ move.preventDefault();
165
+ place();
166
+ }
167
+ function onPointerEnd(end) {
168
+ if (end.pointerId === pointerId)
169
+ finish(false);
170
+ }
171
+ function onKeyDown(key) {
172
+ if (key.key !== "Escape" || !moving)
173
+ return;
174
+ // Esc cancels the drag only: it must not also close the popup or menu around the target.
175
+ key.preventDefault();
176
+ key.stopPropagation();
177
+ current = base;
178
+ position.set(base);
179
+ finish(true);
180
+ }
181
+ // A drag selects no text on its way.
182
+ function onSelectStart(select) {
183
+ select.preventDefault();
184
+ }
185
+ // The click that ends a drag is not a click on what lies under the pointer.
186
+ function swallowClick(click) {
187
+ click.stopPropagation();
188
+ click.preventDefault();
189
+ }
190
+ function finish(cancelled) {
191
+ if (done)
192
+ return;
193
+ done = true;
194
+ window.removeEventListener("pointermove", onPointerMove, true);
195
+ window.removeEventListener("pointerup", onPointerEnd, true);
196
+ window.removeEventListener("pointercancel", onPointerEnd, true);
197
+ window.removeEventListener("keydown", onKeyDown, true);
198
+ window.removeEventListener("blur", onBlur);
199
+ document.removeEventListener("selectstart", onSelectStart, true);
200
+ if (!moving)
201
+ return;
202
+ target.removeAttribute("data-nx-dragging");
203
+ if (handle.hasPointerCapture?.(pointerId))
204
+ handle.releasePointerCapture(pointerId);
205
+ window.addEventListener("click", swallowClick, { capture: true, once: true });
206
+ window.setTimeout(() => window.removeEventListener("click", swallowClick, true), 0);
207
+ options.onEnd?.(state(), cancelled);
208
+ }
209
+ const onBlur = () => finish(false);
210
+ window.addEventListener("pointermove", onPointerMove, true);
211
+ window.addEventListener("pointerup", onPointerEnd, true);
212
+ window.addEventListener("pointercancel", onPointerEnd, true);
213
+ window.addEventListener("keydown", onKeyDown, true);
214
+ window.addEventListener("blur", onBlur);
215
+ document.addEventListener("selectstart", onSelectStart, true);
216
+ return () => finish(false);
217
+ }
218
+ /**
219
+ * Makes `handle` drag `options.target` (or itself), and returns a function that stops it. Options can be a function,
220
+ * read at every press, so a component can pass its latest props.
221
+ *
222
+ * @example
223
+ * const stop = makeDraggable(card.querySelector(".title"), { target: card, bounds: "parent" });
224
+ */
225
+ export function makeDraggable(handle, options = {}) {
226
+ const read = typeof options === "function" ? options : () => options;
227
+ let stopDrag = null;
228
+ const touchAction = handle.style.touchAction;
229
+ handle.style.touchAction = "none";
230
+ function onPointerDown(event) {
231
+ if (event.button !== 0 || !event.isPrimary)
232
+ return;
233
+ const current = read();
234
+ if (current.enabled && !current.enabled())
235
+ return;
236
+ const origin = event.target instanceof Element ? event.target.closest(current.cancel ?? DRAG_CANCEL_SELECTOR) : null;
237
+ if (origin && origin !== handle && handle.contains(origin))
238
+ return;
239
+ const target = current.target === undefined ? handle : typeof current.target === "function" ? current.target() : current.target;
240
+ if (!target)
241
+ return;
242
+ stopDrag?.();
243
+ stopDrag = startDrag(event, {
244
+ ...current,
245
+ target,
246
+ handle,
247
+ onEnd: (state, cancelled) => {
248
+ stopDrag = null;
249
+ current.onEnd?.(state, cancelled);
250
+ },
251
+ });
252
+ }
253
+ handle.addEventListener("pointerdown", onPointerDown);
254
+ return () => {
255
+ handle.removeEventListener("pointerdown", onPointerDown);
256
+ handle.style.touchAction = touchAction;
257
+ stopDrag?.();
258
+ };
259
+ }
260
+ /**
261
+ * React: the element in `handleRef` drags the target (or itself). The options may change on every render; the latest
262
+ * are used at each press.
263
+ *
264
+ * @example
265
+ * const card = useRef<HTMLDivElement>(null);
266
+ * const title = useRef<HTMLDivElement>(null);
267
+ * useDraggable(title, { target: () => card.current, bounds: "parent" });
268
+ */
269
+ export function useDraggable(handleRef, options = {}) {
270
+ const latest = useRef(options);
271
+ useLayoutEffect(() => {
272
+ latest.current = options;
273
+ });
274
+ const disabled = options.disabled ?? false;
275
+ useEffect(() => {
276
+ const handle = handleRef.current;
277
+ if (!handle || disabled)
278
+ return;
279
+ return makeDraggable(handle, () => latest.current);
280
+ }, [handleRef, disabled]);
281
+ }
@@ -0,0 +1,56 @@
1
+ import type { DropdownColumn, DropdownItem, OptionValue } from "../Interfaces/InputInterfaces.ts";
2
+ /** Tones an avatar without a photo takes, picked from its name. Each is a soft theme color under the text color. */
3
+ export declare const AVATAR_TONES: readonly ["primary", "info", "success", "warning", "neutral"];
4
+ export type AvatarTone = (typeof AVATAR_TONES)[number];
5
+ /** Reads an item's field; `undefined` for a missing item or field. */
6
+ export declare function readField(item: DropdownItem | null | undefined, key: string): unknown;
7
+ /**
8
+ * The key a value is compared by. A number and its text are the same value, so id 7 from an API matches "7" from a
9
+ * form or a URL. `null` and `undefined` give "".
10
+ */
11
+ export declare function optionKey(value: unknown): string;
12
+ /** An item's value under `valueKey`, when it is a string or a number. */
13
+ export declare function itemValue(item: DropdownItem, valueKey: string): OptionValue | undefined;
14
+ /** An item's label as text: the field under `labelKey`, or its value when the label is empty. */
15
+ export declare function itemLabel(item: DropdownItem, labelKey: string, valueKey: string): string;
16
+ /** Whether an item is inactive: `inactive: true`, or `isActive: false` as many APIs mark a deactivated record. */
17
+ export declare function isInactiveItem(item: DropdownItem): boolean;
18
+ /** Whether an item is disabled: `disabled: true`, as on a `ChoiceOption`. */
19
+ export declare function isDisabledItem(item: DropdownItem): boolean;
20
+ /**
21
+ * Values as a list: `null` or `undefined` → `[]`, one value → `[value]`, a list → a copy without repeated keys.
22
+ * A single choice keeps only the first value.
23
+ */
24
+ export declare function toValueList<T extends OptionValue>(value: T | readonly T[] | null | undefined, multiple: boolean): T[];
25
+ /** Whether two lists hold the same values, by key, in the same order. */
26
+ export declare function sameValues(a: readonly OptionValue[], b: readonly OptionValue[]): boolean;
27
+ /** A list with the value removed when it is there, or added at the end when it is not. */
28
+ export declare function toggleValue<T extends OptionValue>(values: readonly T[], value: T): T[];
29
+ /** A map from each item's value key to the item; the first item wins when two share a value. Cached per array. */
30
+ export declare function indexItems<TItem extends DropdownItem>(items: readonly TItem[], valueKey: string): Map<string, TItem>;
31
+ /**
32
+ * Text folded for matching what people type: lower case, and Latin, Greek, and Cyrillic letters without their accents
33
+ * ("José" → "jose"). Other scripts keep their marks, so Devanagari vowel signs still count.
34
+ */
35
+ export declare function foldSearchText(text: string): string;
36
+ /** The words of a search. An item matches when it contains every word, in any order. */
37
+ export declare function searchWords(search: string): string[];
38
+ /** An item's fields under `keys`, folded and joined, for matching a search. */
39
+ export declare function itemSearchText(item: DropdownItem, keys: readonly string[]): string;
40
+ /** Whether an item's fields under `keys` contain every word. */
41
+ export declare function matchesSearch(item: DropdownItem, words: readonly string[], keys: readonly string[]): boolean;
42
+ /** The items whose fields under `keys` contain every word of the search, in their order. All items for an empty search. */
43
+ export declare function filterItems<TItem extends DropdownItem>(items: readonly TItem[], search: string, keys: readonly string[]): TItem[];
44
+ /** The fields searched by default: the label, the description, the value, and every text, muted, or code column. */
45
+ export declare function defaultSearchKeys(labelKey: string, descriptionKey: string, valueKey: string, columns?: readonly DropdownColumn<never>[]): string[];
46
+ /** Whether a column draws a picture: an avatar, an image, or an icon. The first one also leads the value in the box. */
47
+ export declare function isMediaColumn(column: Pick<DropdownColumn<never>, "type">): boolean;
48
+ /** A column's grid track: its `width`, or `auto` for pictures and codes and `minmax(0, 1fr)` for text. */
49
+ export declare function columnTrack(column: Pick<DropdownColumn<never>, "type" | "width">): string;
50
+ /**
51
+ * Up to two initials of a name, from its first and last words: "Ram Bahadur Sharma" → "RS", "admin" → "A",
52
+ * "sita.rai" → "SR". Letters keep their script, so "राम शर्मा" → "रश".
53
+ */
54
+ export declare function initials(name: string): string;
55
+ /** The tone of an avatar without a photo: the same name always gets the same tone. */
56
+ export declare function avatarTone(name: string): AvatarTone;
@@ -0,0 +1,180 @@
1
+ /*
2
+ * Pure helpers behind the dropdown: reading items by key, comparing values, searching, and the look of avatars.
3
+ * No DOM and no React, so a form or a data table can use them on data alone.
4
+ */
5
+ /** Tones an avatar without a photo takes, picked from its name. Each is a soft theme color under the text color. */
6
+ export const AVATAR_TONES = ["primary", "info", "success", "warning", "neutral"];
7
+ /** Reads an item's field; `undefined` for a missing item or field. */
8
+ export function readField(item, key) {
9
+ return item ? item[key] : undefined;
10
+ }
11
+ /**
12
+ * The key a value is compared by. A number and its text are the same value, so id 7 from an API matches "7" from a
13
+ * form or a URL. `null` and `undefined` give "".
14
+ */
15
+ export function optionKey(value) {
16
+ return value === null || value === undefined ? "" : String(value);
17
+ }
18
+ /** An item's value under `valueKey`, when it is a string or a number. */
19
+ export function itemValue(item, valueKey) {
20
+ const value = readField(item, valueKey);
21
+ return typeof value === "string" || typeof value === "number" ? value : undefined;
22
+ }
23
+ /** An item's label as text: the field under `labelKey`, or its value when the label is empty. */
24
+ export function itemLabel(item, labelKey, valueKey) {
25
+ const label = readField(item, labelKey);
26
+ if (label !== null && label !== undefined && label !== "")
27
+ return String(label);
28
+ return optionKey(readField(item, valueKey));
29
+ }
30
+ /** Whether an item is inactive: `inactive: true`, or `isActive: false` as many APIs mark a deactivated record. */
31
+ export function isInactiveItem(item) {
32
+ const record = item;
33
+ return record.inactive === true || record.isActive === false;
34
+ }
35
+ /** Whether an item is disabled: `disabled: true`, as on a `ChoiceOption`. */
36
+ export function isDisabledItem(item) {
37
+ return item.disabled === true;
38
+ }
39
+ /**
40
+ * Values as a list: `null` or `undefined` → `[]`, one value → `[value]`, a list → a copy without repeated keys.
41
+ * A single choice keeps only the first value.
42
+ */
43
+ export function toValueList(value, multiple) {
44
+ if (value === null || value === undefined)
45
+ return [];
46
+ const list = Array.isArray(value) ? value : [value];
47
+ const seen = new Set();
48
+ const result = [];
49
+ for (const item of list) {
50
+ if (item === null || item === undefined)
51
+ continue;
52
+ const key = optionKey(item);
53
+ if (seen.has(key))
54
+ continue;
55
+ seen.add(key);
56
+ result.push(item);
57
+ if (!multiple)
58
+ break;
59
+ }
60
+ return result;
61
+ }
62
+ /** Whether two lists hold the same values, by key, in the same order. */
63
+ export function sameValues(a, b) {
64
+ return a.length === b.length && a.every((value, index) => optionKey(value) === optionKey(b[index]));
65
+ }
66
+ /** A list with the value removed when it is there, or added at the end when it is not. */
67
+ export function toggleValue(values, value) {
68
+ const key = optionKey(value);
69
+ return values.some(item => optionKey(item) === key) ? values.filter(item => optionKey(item) !== key) : [...values, value];
70
+ }
71
+ // One index per items array and value key, so a thousand dropdowns sharing one list of countries build it once.
72
+ const indexes = new WeakMap();
73
+ /** A map from each item's value key to the item; the first item wins when two share a value. Cached per array. */
74
+ export function indexItems(items, valueKey) {
75
+ let byKey = indexes.get(items);
76
+ if (!byKey) {
77
+ byKey = new Map();
78
+ indexes.set(items, byKey);
79
+ }
80
+ let index = byKey.get(valueKey);
81
+ if (!index) {
82
+ index = new Map();
83
+ for (const item of items) {
84
+ const key = optionKey(itemValue(item, valueKey));
85
+ if (key && !index.has(key))
86
+ index.set(key, item);
87
+ }
88
+ byKey.set(valueKey, index);
89
+ }
90
+ return index;
91
+ }
92
+ /**
93
+ * Text folded for matching what people type: lower case, and Latin, Greek, and Cyrillic letters without their accents
94
+ * ("José" → "jose"). Other scripts keep their marks, so Devanagari vowel signs still count.
95
+ */
96
+ export function foldSearchText(text) {
97
+ return text
98
+ .normalize("NFD")
99
+ .replace(/(?<=[\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}])\p{M}+/gu, "")
100
+ .normalize("NFC")
101
+ .toLocaleLowerCase();
102
+ }
103
+ /** The words of a search. An item matches when it contains every word, in any order. */
104
+ export function searchWords(search) {
105
+ return foldSearchText(search).split(/\s+/).filter(Boolean);
106
+ }
107
+ // The folded text of an item, kept per item object and set of keys, so each keystroke only compares strings.
108
+ const searchTexts = new WeakMap();
109
+ /** An item's fields under `keys`, folded and joined, for matching a search. */
110
+ export function itemSearchText(item, keys) {
111
+ const joinedKeys = keys.join("\n");
112
+ const cached = searchTexts.get(item);
113
+ if (cached && cached.keys === joinedKeys)
114
+ return cached.text;
115
+ const parts = [];
116
+ for (const key of keys) {
117
+ const value = readField(item, key);
118
+ if (typeof value === "string" || typeof value === "number")
119
+ parts.push(String(value));
120
+ }
121
+ const text = foldSearchText(parts.join("\n"));
122
+ searchTexts.set(item, { keys: joinedKeys, text });
123
+ return text;
124
+ }
125
+ /** Whether an item's fields under `keys` contain every word. */
126
+ export function matchesSearch(item, words, keys) {
127
+ if (words.length === 0)
128
+ return true;
129
+ const text = itemSearchText(item, keys);
130
+ return words.every(word => text.includes(word));
131
+ }
132
+ /** The items whose fields under `keys` contain every word of the search, in their order. All items for an empty search. */
133
+ export function filterItems(items, search, keys) {
134
+ const words = searchWords(search);
135
+ if (words.length === 0)
136
+ return items.slice();
137
+ return items.filter(item => matchesSearch(item, words, keys));
138
+ }
139
+ /** Column types that draw text, and so are searched by default. */
140
+ const TEXT_TYPES = new Set(["text", "muted", "code"]);
141
+ /** The fields searched by default: the label, the description, the value, and every text, muted, or code column. */
142
+ export function defaultSearchKeys(labelKey, descriptionKey, valueKey, columns) {
143
+ const keys = [labelKey, descriptionKey, valueKey];
144
+ for (const column of columns ?? [])
145
+ if (TEXT_TYPES.has(column.type ?? "text") && !keys.includes(column.key))
146
+ keys.push(column.key);
147
+ return keys;
148
+ }
149
+ /** Whether a column draws a picture: an avatar, an image, or an icon. The first one also leads the value in the box. */
150
+ export function isMediaColumn(column) {
151
+ return column.type === "avatar" || column.type === "image" || column.type === "icon";
152
+ }
153
+ /** A column's grid track: its `width`, or `auto` for pictures and codes and `minmax(0, 1fr)` for text. */
154
+ export function columnTrack(column) {
155
+ if (column.width)
156
+ return column.width;
157
+ return isMediaColumn(column) || column.type === "code" ? "auto" : "minmax(0, 1fr)";
158
+ }
159
+ /**
160
+ * Up to two initials of a name, from its first and last words: "Ram Bahadur Sharma" → "RS", "admin" → "A",
161
+ * "sita.rai" → "SR". Letters keep their script, so "राम शर्मा" → "रश".
162
+ */
163
+ export function initials(name) {
164
+ const words = name
165
+ .trim()
166
+ .split(/[\s._\-@]+/)
167
+ .filter(word => /[\p{L}\p{N}]/u.test(word));
168
+ if (words.length === 0)
169
+ return "";
170
+ const first = (word) => Array.from(word.replace(/^[^\p{L}\p{N}]+/u, ""))[0] ?? "";
171
+ const letters = words.length === 1 ? first(words[0]) : first(words[0]) + first(words[words.length - 1]);
172
+ return letters.toLocaleUpperCase();
173
+ }
174
+ /** The tone of an avatar without a photo: the same name always gets the same tone. */
175
+ export function avatarTone(name) {
176
+ let hash = 0;
177
+ for (let index = 0; index < name.length; index++)
178
+ hash = (hash * 31 + name.charCodeAt(index)) | 0;
179
+ return AVATAR_TONES[Math.abs(hash) % AVATAR_TONES.length];
180
+ }
@@ -0,0 +1,106 @@
1
+ import type { ApiModuleValue, ApiResult, HttpMethod } from "../Interfaces/ApiInterfaces.ts";
2
+ import type { ExcelDownload, ExcelEndpoints, ExcelExportQuery, ExcelImportAnswer, ExcelSettings, ExcelSheetRow, ExcelVerifyAnswer } from "../Interfaces/ExcelInterfaces.ts";
3
+ /** The actions of a Nexus Excel controller, as the backend names them (`NexusExcelController`). */
4
+ export declare const EXCEL_ACTIONS: {
5
+ readonly settings: "Excel/Settings";
6
+ readonly template: "Excel/Template";
7
+ readonly verify: "Excel/Verify";
8
+ readonly import: "Excel/Import";
9
+ /** The model's own action, which the two controller bases leave to it. */
10
+ readonly export: "Excel/Export";
11
+ };
12
+ /** Which controller a model's spreadsheets sit on. An `apiController(...)` fits as it is. */
13
+ export interface ExcelController<TModule extends ApiModuleValue = ApiModuleValue> {
14
+ module: TModule;
15
+ /** The controller's name: "City". */
16
+ controller: string;
17
+ }
18
+ /** Changes to the endpoints a Nexus controller gets. */
19
+ export interface ExcelEndpointOptions {
20
+ /** What one row is, for the messages: "city". */
21
+ subject?: string;
22
+ /** No export is offered. Default: `Excel/Export` as a POST. */
23
+ exportable?: false;
24
+ /** The export action, when the controller named it something else: `"Export"`, or `["GET", "Download"]`. */
25
+ exportAction?: string | [HttpMethod, string];
26
+ }
27
+ /**
28
+ * The spreadsheet endpoints of a Nexus controller, named as the backend names them: `Excel/Settings`,
29
+ * `Excel/Template`, `Excel/Verify`, `Excel/Import`, and the model's own `Excel/Export`.
30
+ *
31
+ * @example
32
+ * export const CITIES = MODULES.controller(NexusModule.Configuration, "City", "city");
33
+ * export const CITY_SHEET = excelEndpoints(CITIES, { subject: "city" });
34
+ */
35
+ export declare function excelEndpoints<TModule extends ApiModuleValue>(controller: ExcelController<TModule>, options?: ExcelEndpointOptions): ExcelEndpoints<TModule>;
36
+ /** What a download's own headers are called, so a backend that names them differently still reads. */
37
+ export interface ExcelDownloadHeaders {
38
+ rows: string;
39
+ skipped: string;
40
+ limit: string;
41
+ note: string;
42
+ }
43
+ export declare abstract class ExcelBackend {
44
+ /** The form field an upload is sent under. */
45
+ abstract get uploadField(): string;
46
+ /** What an import sends: the rows the verify answered with, as the person left them. */
47
+ abstract importRequest(rows: readonly ExcelSheetRow[]): unknown;
48
+ /** What an export sends: the search, the sort and the filters the person has on screen. */
49
+ abstract exportRequest(query: ExcelExportQuery): unknown;
50
+ /** Reads what the settings endpoint answered. */
51
+ abstract readSettings(result: unknown): ExcelSettings;
52
+ /** Reads what a verify answered. */
53
+ abstract readVerify(result: unknown): ExcelVerifyAnswer;
54
+ /** Reads what an import answered. */
55
+ abstract readImport(result: unknown): ExcelImportAnswer;
56
+ /**
57
+ * What a download says about itself in its headers. Every one of them has to be named in the backend's CORS policy:
58
+ * a browser can read only the headers it is told it may, `Content-Disposition` included, so a frontend on another
59
+ * origin otherwise receives a file it cannot even name.
60
+ */
61
+ abstract get downloadHeaders(): ExcelDownloadHeaders;
62
+ }
63
+ /**
64
+ * The Nexus backend. The four calls sit under one controller; an import sends `{ rows }`; an export sends the list
65
+ * request a Nexus pagination takes, without its paging, because an export is not a page; a download says what it came
66
+ * to in `X-Nexus-Export-*` headers.
67
+ */
68
+ export declare class NexusExcelBackend extends ExcelBackend {
69
+ get uploadField(): string;
70
+ importRequest(rows: readonly ExcelSheetRow[]): unknown;
71
+ /**
72
+ * The same request a Nexus listing takes, minus `skipCount` and `maxCount`: an export writes every row the search
73
+ * leaves, up to the backend's own limit, not the page the person happens to be on. With nothing sorted it follows
74
+ * the list's own order, newest first.
75
+ */
76
+ exportRequest(query: ExcelExportQuery): unknown;
77
+ readSettings(result: unknown): ExcelSettings;
78
+ readVerify(result: unknown): ExcelVerifyAnswer;
79
+ readImport(result: unknown): ExcelImportAnswer;
80
+ get downloadHeaders(): ExcelDownloadHeaders;
81
+ }
82
+ /** The most rows one export writes when the backend does not say (`Nexus:Excel:MaxExportRows`). */
83
+ export declare const DEFAULT_MAX_EXPORT_ROWS = 5000;
84
+ /** The most rows one import takes when the backend does not say (`Nexus:Excel:MaxImportRows`). */
85
+ export declare const DEFAULT_MAX_IMPORT_ROWS = 2000;
86
+ /** What a Nexus download says about itself (`Excels/ExcelHeaders.cs`), all of them exposed by the CORS policy. */
87
+ export declare const NEXUS_DOWNLOAD_HEADERS: ExcelDownloadHeaders;
88
+ /**
89
+ * Reads an answer whose problems are in `errorMessages`, which is how the backend answers a refusal now: nothing at the
90
+ * top level, and one entry per wrong field (`{ message, messageCode, errorCode, inputName }`) so every one of them is
91
+ * told at once. The first entry words the answer, and each entry that names an input lands on that input.
92
+ *
93
+ * Anything else - a success, a backend of another shape, problem details, a proxy answering while the service is down -
94
+ * goes to `readApiResponse`, which is also the default for every call that does not name a reader. It is used here
95
+ * because a spreadsheet's refusals are the whole point of the review: "no row could be written" has to reach the person
96
+ * in the backend's own words, not as a generic sentence.
97
+ */
98
+ export declare function readExcelResponse(body: unknown, status?: number): ApiResult;
99
+ /** Registers the app's spreadsheet conventions, once, beside its API modules. */
100
+ export declare function defineExcelBackend<T extends ExcelBackend>(backend: T): T;
101
+ /** The registered spreadsheet conventions, or the Nexus ones. */
102
+ export declare function getExcelBackend(): ExcelBackend;
103
+ /** The file name out of a `Content-Disposition`, `filename*` first (it carries the encoding) and `filename` after. */
104
+ export declare function readFileName(disposition: string | null | undefined): string | undefined;
105
+ /** What a download answered, as its own headers tell it. */
106
+ export declare function readDownloadHeaders(headers: Headers, blob: Blob, fallbackName: string): ExcelDownload;