@peers-app/peers-ui 0.14.0 → 0.15.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 (438) hide show
  1. package/.github/workflows/publish.yml +8 -5
  2. package/babel.config.js +4 -4
  3. package/biome.json +191 -0
  4. package/dist/command-palette/command-palette-ui.d.ts +1 -2
  5. package/dist/command-palette/command-palette-ui.js +175 -244
  6. package/dist/command-palette/command-palette.js +65 -64
  7. package/dist/components/chat-overlay.d.ts +2 -2
  8. package/dist/components/chat-overlay.js +160 -217
  9. package/dist/components/checkbox.d.ts +5 -4
  10. package/dist/components/checkbox.js +4 -7
  11. package/dist/components/group-switcher.d.ts +1 -2
  12. package/dist/components/group-switcher.js +119 -159
  13. package/dist/components/input-date.d.ts +3 -3
  14. package/dist/components/input-date.js +6 -6
  15. package/dist/components/input-number.d.ts +7 -6
  16. package/dist/components/input-number.js +25 -20
  17. package/dist/components/input.d.ts +5 -4
  18. package/dist/components/input.js +4 -7
  19. package/dist/components/inverse-lazy-list.d.ts +3 -3
  20. package/dist/components/inverse-lazy-list.js +13 -47
  21. package/dist/components/io-schema-values.d.ts +5 -6
  22. package/dist/components/io-schema-values.js +28 -65
  23. package/dist/components/io-schema.d.ts +4 -5
  24. package/dist/components/io-schema.js +42 -79
  25. package/dist/components/lazy-list.d.ts +3 -3
  26. package/dist/components/lazy-list.js +38 -58
  27. package/dist/components/list-screen.d.ts +3 -8
  28. package/dist/components/list-screen.js +28 -23
  29. package/dist/components/loading-indicator.d.ts +1 -2
  30. package/dist/components/loading-indicator.js +2 -6
  31. package/dist/components/markdown-editor/autolink-plugin.js +5 -8
  32. package/dist/components/markdown-editor/editor-inline.d.ts +2 -3
  33. package/dist/components/markdown-editor/editor-inline.js +2 -6
  34. package/dist/components/markdown-editor/editor.d.ts +6 -6
  35. package/dist/components/markdown-editor/editor.js +9 -19
  36. package/dist/components/markdown-editor/markdown-plugin.d.ts +1 -1
  37. package/dist/components/markdown-editor/markdown-plugin.js +20 -21
  38. package/dist/components/markdown-editor/mention-node.d.ts +2 -2
  39. package/dist/components/markdown-editor/mention-node.js +24 -24
  40. package/dist/components/markdown-editor/mentions-plugin.d.ts +2 -2
  41. package/dist/components/markdown-editor/mentions-plugin.js +61 -62
  42. package/dist/components/markdown-editor/theme.js +28 -28
  43. package/dist/components/markdown-editor/toolbar.d.ts +2 -3
  44. package/dist/components/markdown-editor/toolbar.js +32 -49
  45. package/dist/components/markdown-with-mentions.d.ts +1 -1
  46. package/dist/components/markdown-with-mentions.js +43 -43
  47. package/dist/components/message-logs/message-logs.d.ts +1 -2
  48. package/dist/components/message-logs/message-logs.js +91 -116
  49. package/dist/components/messages/avatar.d.ts +3 -4
  50. package/dist/components/messages/avatar.js +37 -46
  51. package/dist/components/messages/channel-message-list.d.ts +5 -6
  52. package/dist/components/messages/channel-message-list.js +34 -34
  53. package/dist/components/messages/channel-view.d.ts +1 -2
  54. package/dist/components/messages/channel-view.js +23 -57
  55. package/dist/components/messages/message-compose.d.ts +3 -4
  56. package/dist/components/messages/message-compose.js +27 -38
  57. package/dist/components/messages/message-display.d.ts +2 -3
  58. package/dist/components/messages/message-display.js +42 -95
  59. package/dist/components/messages/thread-message-list.d.ts +4 -5
  60. package/dist/components/messages/thread-message-list.js +29 -29
  61. package/dist/components/router.d.ts +1 -2
  62. package/dist/components/router.js +58 -66
  63. package/dist/components/save-button.d.ts +3 -3
  64. package/dist/components/save-button.js +23 -33
  65. package/dist/components/sortable-list.d.ts +11 -12
  66. package/dist/components/sortable-list.js +42 -22
  67. package/dist/components/tabs.d.ts +3 -3
  68. package/dist/components/tabs.js +16 -47
  69. package/dist/components/tooltip.d.ts +4 -4
  70. package/dist/components/tooltip.js +4 -9
  71. package/dist/components/trust-level-badge.d.ts +2 -3
  72. package/dist/components/trust-level-badge.js +16 -16
  73. package/dist/components/trust-level-dropdown.d.ts +3 -4
  74. package/dist/components/trust-level-dropdown.js +32 -55
  75. package/dist/components/typeahead.d.ts +3 -3
  76. package/dist/components/typeahead.js +48 -89
  77. package/dist/components/voice-indicator.d.ts +2 -2
  78. package/dist/components/voice-indicator.js +93 -106
  79. package/dist/components/voice-subscribe-events.d.ts +32 -0
  80. package/dist/components/voice-subscribe-events.js +2 -0
  81. package/dist/globals.d.ts +3 -5
  82. package/dist/globals.js +22 -33
  83. package/dist/hooks.d.ts +5 -5
  84. package/dist/hooks.js +22 -12
  85. package/dist/hooks.test.js +129 -145
  86. package/dist/index.d.ts +9 -8
  87. package/dist/index.js +13 -12
  88. package/dist/mention-configs.d.ts +2 -2
  89. package/dist/mention-configs.js +55 -42
  90. package/dist/screens/assistants/assistant-config.d.ts +2 -3
  91. package/dist/screens/assistants/assistant-config.js +9 -22
  92. package/dist/screens/assistants/assistant-details.d.ts +1 -2
  93. package/dist/screens/assistants/assistant-details.js +13 -28
  94. package/dist/screens/assistants/assistant-info.d.ts +2 -3
  95. package/dist/screens/assistants/assistant-info.js +3 -17
  96. package/dist/screens/assistants/assistant-list.d.ts +1 -2
  97. package/dist/screens/assistants/assistant-list.js +15 -56
  98. package/dist/screens/assistants/assistant-tools.d.ts +2 -3
  99. package/dist/screens/assistants/assistant-tools.js +10 -24
  100. package/dist/screens/console-logs/console-logs-list.d.ts +1 -2
  101. package/dist/screens/console-logs/console-logs-list.js +130 -134
  102. package/dist/screens/console-logs/log-display.d.ts +2 -3
  103. package/dist/screens/console-logs/log-display.js +40 -42
  104. package/dist/screens/console-logs/log-filters.d.ts +1 -2
  105. package/dist/screens/console-logs/log-filters.js +2 -24
  106. package/dist/screens/console-logs/mobile-log-card.d.ts +2 -3
  107. package/dist/screens/console-logs/mobile-log-card.js +64 -67
  108. package/dist/screens/console-logs/resizable-table-header.d.ts +1 -2
  109. package/dist/screens/console-logs/resizable-table-header.js +31 -67
  110. package/dist/screens/contacts/contact-details.d.ts +1 -2
  111. package/dist/screens/contacts/contact-details.js +16 -46
  112. package/dist/screens/contacts/contact-list.d.ts +1 -2
  113. package/dist/screens/contacts/contact-list.js +44 -103
  114. package/dist/screens/contacts/index.d.ts +4 -4
  115. package/dist/screens/contacts/index.js +1 -1
  116. package/dist/screens/contacts/user-connect.d.ts +1 -2
  117. package/dist/screens/contacts/user-connect.js +85 -186
  118. package/dist/screens/data-explorer/data-explorer.d.ts +1 -2
  119. package/dist/screens/data-explorer/data-explorer.js +61 -181
  120. package/dist/screens/data-explorer/index.d.ts +2 -2
  121. package/dist/screens/data-explorer/query-executor.d.ts +1 -2
  122. package/dist/screens/data-explorer/query-executor.js +56 -166
  123. package/dist/screens/groups/group-details.d.ts +1 -2
  124. package/dist/screens/groups/group-details.js +27 -122
  125. package/dist/screens/groups/group-invite-listener.d.ts +2 -3
  126. package/dist/screens/groups/group-invite-listener.js +8 -104
  127. package/dist/screens/groups/group-list.d.ts +1 -2
  128. package/dist/screens/groups/group-list.js +56 -133
  129. package/dist/screens/groups/group-members.d.ts +2 -3
  130. package/dist/screens/groups/group-members.js +62 -132
  131. package/dist/screens/groups/index.d.ts +4 -4
  132. package/dist/screens/groups/index.js +1 -1
  133. package/dist/screens/join-group/index.d.ts +2 -2
  134. package/dist/screens/join-group/join-group.d.ts +1 -2
  135. package/dist/screens/join-group/join-group.js +9 -109
  136. package/dist/screens/network-viewer/connection-troubleshooter.d.ts +2 -3
  137. package/dist/screens/network-viewer/connection-troubleshooter.js +89 -193
  138. package/dist/screens/network-viewer/cpu-usage-graph.d.ts +1 -2
  139. package/dist/screens/network-viewer/cpu-usage-graph.js +60 -99
  140. package/dist/screens/network-viewer/device-details-modal.d.ts +1 -2
  141. package/dist/screens/network-viewer/device-details-modal.js +25 -177
  142. package/dist/screens/network-viewer/group-details-modal.d.ts +1 -2
  143. package/dist/screens/network-viewer/group-details-modal.js +31 -142
  144. package/dist/screens/network-viewer/index.d.ts +4 -4
  145. package/dist/screens/network-viewer/index.js +3 -3
  146. package/dist/screens/network-viewer/network-viewer-ipc.d.ts +22 -0
  147. package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
  148. package/dist/screens/network-viewer/network-viewer.d.ts +1 -2
  149. package/dist/screens/network-viewer/network-viewer.js +91 -296
  150. package/dist/screens/network-viewer/usage-graph.d.ts +1 -2
  151. package/dist/screens/network-viewer/usage-graph.js +78 -110
  152. package/dist/screens/packages/package-details.d.ts +1 -2
  153. package/dist/screens/packages/package-details.js +35 -41
  154. package/dist/screens/packages/package-info.d.ts +2 -2
  155. package/dist/screens/packages/package-info.js +33 -86
  156. package/dist/screens/packages/package-list.d.ts +1 -2
  157. package/dist/screens/packages/package-list.js +42 -106
  158. package/dist/screens/packages/package-new-local.d.ts +1 -2
  159. package/dist/screens/packages/package-new-local.js +13 -19
  160. package/dist/screens/packages/package-versions.d.ts +2 -3
  161. package/dist/screens/packages/package-versions.js +29 -96
  162. package/dist/screens/peer-types/peer-type-details.d.ts +3 -4
  163. package/dist/screens/peer-types/peer-type-details.js +26 -78
  164. package/dist/screens/peer-types/peer-type-list.d.ts +1 -2
  165. package/dist/screens/peer-types/peer-type-list.js +13 -24
  166. package/dist/screens/search/global-search.d.ts +1 -2
  167. package/dist/screens/search/global-search.js +104 -182
  168. package/dist/screens/settings/color-mode-dropdown.d.ts +3 -4
  169. package/dist/screens/settings/color-mode-dropdown.js +18 -37
  170. package/dist/screens/settings/settings-page.d.ts +1 -1
  171. package/dist/screens/settings/settings-page.js +86 -213
  172. package/dist/screens/settings/voice-settings-agent.d.ts +1 -1
  173. package/dist/screens/settings/voice-settings-agent.js +7 -44
  174. package/dist/screens/settings/voice-settings-api-keys.d.ts +2 -2
  175. package/dist/screens/settings/voice-settings-api-keys.js +2 -29
  176. package/dist/screens/settings/voice-settings-output.d.ts +2 -2
  177. package/dist/screens/settings/voice-settings-output.js +2 -40
  178. package/dist/screens/settings/voice-settings-providers.d.ts +2 -2
  179. package/dist/screens/settings/voice-settings-providers.js +2 -19
  180. package/dist/screens/settings/voice-settings-types.d.ts +4 -4
  181. package/dist/screens/settings/voice-settings-types.js +31 -31
  182. package/dist/screens/settings/voice-settings-wake-word.d.ts +2 -2
  183. package/dist/screens/settings/voice-settings-wake-word.js +2 -33
  184. package/dist/screens/settings/voice-settings.d.ts +1 -1
  185. package/dist/screens/settings/voice-settings.js +35 -112
  186. package/dist/screens/setup-user.d.ts +1 -2
  187. package/dist/screens/setup-user.js +38 -116
  188. package/dist/screens/tools/tool-code.d.ts +2 -3
  189. package/dist/screens/tools/tool-code.js +9 -13
  190. package/dist/screens/tools/tool-details.d.ts +1 -2
  191. package/dist/screens/tools/tool-details.js +26 -39
  192. package/dist/screens/tools/tool-info.d.ts +2 -3
  193. package/dist/screens/tools/tool-info.js +9 -48
  194. package/dist/screens/tools/tool-list.d.ts +1 -2
  195. package/dist/screens/tools/tool-list.js +33 -65
  196. package/dist/screens/tools/tool-schema.d.ts +2 -3
  197. package/dist/screens/tools/tool-schema.js +2 -13
  198. package/dist/screens/tools/tool-test-details.d.ts +1 -2
  199. package/dist/screens/tools/tool-test-details.js +12 -28
  200. package/dist/screens/tools/tool-test-list.d.ts +1 -2
  201. package/dist/screens/tools/tool-test-list.js +17 -56
  202. package/dist/screens/variables/variable-details.d.ts +1 -2
  203. package/dist/screens/variables/variable-details.js +19 -86
  204. package/dist/screens/variables/variable-list.d.ts +1 -2
  205. package/dist/screens/variables/variable-list.js +16 -27
  206. package/dist/screens/welcome-modal.d.ts +1 -2
  207. package/dist/screens/welcome-modal.js +44 -111
  208. package/dist/screens/workflows/workflow-details.d.ts +1 -2
  209. package/dist/screens/workflows/workflow-details.js +17 -31
  210. package/dist/screens/workflows/workflow-info.d.ts +2 -3
  211. package/dist/screens/workflows/workflow-info.js +2 -9
  212. package/dist/screens/workflows/workflow-instructions.d.ts +2 -3
  213. package/dist/screens/workflows/workflow-instructions.js +23 -55
  214. package/dist/screens/workflows/workflow-list.d.ts +1 -2
  215. package/dist/screens/workflows/workflow-list.js +23 -62
  216. package/dist/setupTests.d.ts +1 -1
  217. package/dist/setupTests.js +10 -11
  218. package/dist/system-apps/assistants.app.d.ts +1 -1
  219. package/dist/system-apps/assistants.app.js +3 -3
  220. package/dist/system-apps/console-logs.app.d.ts +1 -1
  221. package/dist/system-apps/console-logs.app.js +3 -3
  222. package/dist/system-apps/contacts.app.d.ts +1 -1
  223. package/dist/system-apps/contacts.app.js +4 -4
  224. package/dist/system-apps/data-explorer.app.d.ts +1 -1
  225. package/dist/system-apps/data-explorer.app.js +4 -4
  226. package/dist/system-apps/groups.app.d.ts +1 -1
  227. package/dist/system-apps/groups.app.js +4 -4
  228. package/dist/system-apps/index.d.ts +17 -17
  229. package/dist/system-apps/index.js +52 -52
  230. package/dist/system-apps/join-group.app.d.ts +1 -1
  231. package/dist/system-apps/join-group.app.js +4 -4
  232. package/dist/system-apps/mobile-settings.app.d.ts +1 -1
  233. package/dist/system-apps/mobile-settings.app.js +3 -3
  234. package/dist/system-apps/network-viewer.app.d.ts +1 -1
  235. package/dist/system-apps/network-viewer.app.js +4 -4
  236. package/dist/system-apps/packages.app.d.ts +1 -1
  237. package/dist/system-apps/packages.app.js +3 -3
  238. package/dist/system-apps/search.app.d.ts +1 -1
  239. package/dist/system-apps/search.app.js +4 -4
  240. package/dist/system-apps/settings.app.d.ts +1 -1
  241. package/dist/system-apps/settings.app.js +3 -3
  242. package/dist/system-apps/threads.app.d.ts +1 -1
  243. package/dist/system-apps/threads.app.js +3 -3
  244. package/dist/system-apps/tools.app.d.ts +1 -1
  245. package/dist/system-apps/tools.app.js +3 -3
  246. package/dist/system-apps/types.app.d.ts +1 -1
  247. package/dist/system-apps/types.app.js +3 -3
  248. package/dist/system-apps/variables.app.d.ts +1 -1
  249. package/dist/system-apps/variables.app.js +3 -3
  250. package/dist/system-apps/workflows.app.d.ts +1 -1
  251. package/dist/system-apps/workflows.app.js +3 -3
  252. package/dist/tabs-layout/tabs-layout.d.ts +2 -3
  253. package/dist/tabs-layout/tabs-layout.js +215 -246
  254. package/dist/tabs-layout/tabs-state.d.ts +2 -2
  255. package/dist/tabs-layout/tabs-state.js +73 -61
  256. package/dist/ui-defaults/index.d.ts +2 -2
  257. package/dist/ui-defaults/list-screen.d.ts +2 -3
  258. package/dist/ui-defaults/list-screen.js +33 -37
  259. package/dist/ui-defaults/markdown-field.js +24 -56
  260. package/dist/ui-router/routes-loader.d.ts +1 -1
  261. package/dist/ui-router/routes-loader.js +17 -13
  262. package/dist/ui-router/ui-loader.d.ts +6 -6
  263. package/dist/ui-router/ui-loader.js +172 -268
  264. package/dist/utils.js +49 -39
  265. package/jest.config.js +16 -16
  266. package/package.json +16 -14
  267. package/src/command-palette/command-palette-ui.tsx +261 -237
  268. package/src/command-palette/command-palette.ts +81 -78
  269. package/src/components/chat-overlay.tsx +366 -261
  270. package/src/components/checkbox.tsx +15 -12
  271. package/src/components/group-switcher.tsx +150 -105
  272. package/src/components/input-date.tsx +17 -16
  273. package/src/components/input-number.tsx +47 -31
  274. package/src/components/input.tsx +15 -12
  275. package/src/components/inverse-lazy-list.tsx +14 -13
  276. package/src/components/io-schema-values.tsx +51 -69
  277. package/src/components/io-schema.tsx +94 -69
  278. package/src/components/lazy-list.tsx +51 -34
  279. package/src/components/list-screen.tsx +51 -35
  280. package/src/components/loading-indicator.tsx +2 -4
  281. package/src/components/markdown-editor/autolink-plugin.tsx +4 -11
  282. package/src/components/markdown-editor/editor-inline.tsx +3 -4
  283. package/src/components/markdown-editor/editor.tsx +53 -51
  284. package/src/components/markdown-editor/markdown-plugin.tsx +48 -40
  285. package/src/components/markdown-editor/mention-node.ts +39 -38
  286. package/src/components/markdown-editor/mentions-plugin.tsx +99 -101
  287. package/src/components/markdown-editor/theme.ts +28 -29
  288. package/src/components/markdown-editor/toolbar.tsx +53 -47
  289. package/src/components/markdown-with-mentions.tsx +56 -46
  290. package/src/components/message-logs/message-logs.tsx +225 -165
  291. package/src/components/messages/avatar.tsx +70 -52
  292. package/src/components/messages/channel-message-list.tsx +80 -68
  293. package/src/components/messages/channel-view.tsx +34 -33
  294. package/src/components/messages/message-compose.tsx +84 -67
  295. package/src/components/messages/message-display.tsx +103 -89
  296. package/src/components/messages/thread-message-list.tsx +53 -44
  297. package/src/components/router.tsx +42 -43
  298. package/src/components/save-button.tsx +43 -39
  299. package/src/components/sortable-list.tsx +77 -49
  300. package/src/components/tabs.tsx +31 -31
  301. package/src/components/tooltip.tsx +21 -28
  302. package/src/components/trust-level-badge.tsx +15 -11
  303. package/src/components/trust-level-dropdown.tsx +49 -19
  304. package/src/components/typeahead.tsx +57 -59
  305. package/src/components/voice-indicator.tsx +158 -141
  306. package/src/components/voice-subscribe-events.ts +20 -0
  307. package/src/globals.tsx +42 -40
  308. package/src/hooks.test.tsx +141 -134
  309. package/src/hooks.ts +80 -48
  310. package/src/index.tsx +17 -10
  311. package/src/mention-configs.ts +122 -68
  312. package/src/screens/assistants/assistant-config.tsx +28 -18
  313. package/src/screens/assistants/assistant-details.tsx +35 -36
  314. package/src/screens/assistants/assistant-info.tsx +16 -11
  315. package/src/screens/assistants/assistant-list.tsx +37 -34
  316. package/src/screens/assistants/assistant-tools.tsx +41 -20
  317. package/src/screens/console-logs/console-logs-list.tsx +173 -140
  318. package/src/screens/console-logs/log-display.tsx +65 -38
  319. package/src/screens/console-logs/log-filters.tsx +4 -3
  320. package/src/screens/console-logs/mobile-log-card.tsx +78 -71
  321. package/src/screens/console-logs/resizable-table-header.tsx +29 -21
  322. package/src/screens/contacts/contact-details.tsx +29 -30
  323. package/src/screens/contacts/contact-list.tsx +71 -60
  324. package/src/screens/contacts/index.ts +5 -5
  325. package/src/screens/contacts/user-connect.tsx +177 -171
  326. package/src/screens/data-explorer/data-explorer.tsx +134 -98
  327. package/src/screens/data-explorer/index.ts +2 -3
  328. package/src/screens/data-explorer/query-executor.tsx +90 -80
  329. package/src/screens/groups/group-details.tsx +120 -101
  330. package/src/screens/groups/group-invite-listener.tsx +34 -37
  331. package/src/screens/groups/group-list.tsx +119 -103
  332. package/src/screens/groups/group-members.tsx +225 -164
  333. package/src/screens/groups/index.ts +5 -6
  334. package/src/screens/join-group/index.ts +2 -2
  335. package/src/screens/join-group/join-group.tsx +41 -39
  336. package/src/screens/network-viewer/connection-troubleshooter.tsx +145 -104
  337. package/src/screens/network-viewer/cpu-usage-graph.tsx +39 -43
  338. package/src/screens/network-viewer/device-details-modal.tsx +46 -59
  339. package/src/screens/network-viewer/group-details-modal.tsx +68 -49
  340. package/src/screens/network-viewer/index.ts +4 -5
  341. package/src/screens/network-viewer/network-viewer-ipc.ts +23 -0
  342. package/src/screens/network-viewer/network-viewer.tsx +261 -236
  343. package/src/screens/network-viewer/usage-graph.tsx +57 -49
  344. package/src/screens/packages/package-details.tsx +43 -35
  345. package/src/screens/packages/package-info.tsx +107 -66
  346. package/src/screens/packages/package-list.tsx +175 -98
  347. package/src/screens/packages/package-new-local.tsx +28 -26
  348. package/src/screens/packages/package-versions.tsx +102 -77
  349. package/src/screens/peer-types/peer-type-details.tsx +60 -50
  350. package/src/screens/peer-types/peer-type-list.tsx +20 -30
  351. package/src/screens/search/global-search.tsx +153 -137
  352. package/src/screens/settings/color-mode-dropdown.tsx +52 -35
  353. package/src/screens/settings/settings-page.tsx +215 -141
  354. package/src/screens/settings/voice-settings-agent.tsx +13 -12
  355. package/src/screens/settings/voice-settings-api-keys.tsx +14 -12
  356. package/src/screens/settings/voice-settings-output.tsx +12 -11
  357. package/src/screens/settings/voice-settings-providers.tsx +7 -3
  358. package/src/screens/settings/voice-settings-types.ts +52 -49
  359. package/src/screens/settings/voice-settings-wake-word.tsx +25 -9
  360. package/src/screens/settings/voice-settings.tsx +66 -43
  361. package/src/screens/setup-user.tsx +88 -41
  362. package/src/screens/tools/tool-code.tsx +12 -17
  363. package/src/screens/tools/tool-details.tsx +28 -28
  364. package/src/screens/tools/tool-info.tsx +14 -19
  365. package/src/screens/tools/tool-list.tsx +58 -40
  366. package/src/screens/tools/tool-schema.tsx +16 -9
  367. package/src/screens/tools/tool-test-details.tsx +11 -22
  368. package/src/screens/tools/tool-test-list.tsx +29 -30
  369. package/src/screens/variables/variable-details.tsx +63 -51
  370. package/src/screens/variables/variable-list.tsx +29 -30
  371. package/src/screens/welcome-modal.tsx +68 -48
  372. package/src/screens/workflows/workflow-details.tsx +40 -30
  373. package/src/screens/workflows/workflow-info.tsx +4 -11
  374. package/src/screens/workflows/workflow-instructions.tsx +35 -28
  375. package/src/screens/workflows/workflow-list.tsx +50 -40
  376. package/src/setupTests.ts +14 -13
  377. package/src/system-apps/assistants.app.ts +5 -5
  378. package/src/system-apps/console-logs.app.ts +4 -4
  379. package/src/system-apps/contacts.app.ts +6 -6
  380. package/src/system-apps/data-explorer.app.ts +5 -5
  381. package/src/system-apps/groups.app.ts +6 -6
  382. package/src/system-apps/index.ts +49 -49
  383. package/src/system-apps/join-group.app.ts +5 -5
  384. package/src/system-apps/mobile-settings.app.ts +4 -5
  385. package/src/system-apps/network-viewer.app.ts +5 -5
  386. package/src/system-apps/packages.app.ts +5 -5
  387. package/src/system-apps/search.app.ts +6 -6
  388. package/src/system-apps/settings.app.ts +5 -5
  389. package/src/system-apps/threads.app.ts +5 -5
  390. package/src/system-apps/tools.app.ts +5 -5
  391. package/src/system-apps/types.app.ts +5 -5
  392. package/src/system-apps/variables.app.ts +5 -5
  393. package/src/system-apps/workflows.app.ts +5 -5
  394. package/src/tabs-layout/tabs-layout.tsx +345 -254
  395. package/src/tabs-layout/tabs-state.ts +100 -81
  396. package/src/ui-defaults/index.ts +2 -3
  397. package/src/ui-defaults/list-screen.tsx +45 -40
  398. package/src/ui-defaults/markdown-field.tsx +22 -26
  399. package/src/ui-router/routes-loader.ts +40 -24
  400. package/src/ui-router/ui-loader.tsx +312 -214
  401. package/src/utils.ts +68 -81
  402. package/tsconfig.json +5 -10
  403. package/dist/components/input-datetime.d.ts +0 -7
  404. package/dist/components/input-datetime.js +0 -35
  405. package/dist/components/lazy-sortable-list.d.ts +0 -29
  406. package/dist/components/lazy-sortable-list.js +0 -12
  407. package/dist/components/left-bar.d.ts +0 -5
  408. package/dist/components/left-bar.js +0 -207
  409. package/dist/components/main-content-container.d.ts +0 -2
  410. package/dist/components/main-content-container.js +0 -92
  411. package/dist/components/messages/thread-view.d.ts +0 -6
  412. package/dist/components/messages/thread-view.js +0 -174
  413. package/dist/components/off-canvas.d.ts +0 -13
  414. package/dist/components/off-canvas.js +0 -89
  415. package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +0 -6
  416. package/dist/components/text-list-editor.tsx/text-list-editor.js +0 -13
  417. package/dist/components/top-bar.d.ts +0 -2
  418. package/dist/components/top-bar.js +0 -51
  419. package/dist/components/typeahead/mentions-plugin.d.ts +0 -7
  420. package/dist/components/typeahead/mentions-plugin.js +0 -203
  421. package/dist/components/typeahead/typeahead-editor.d.ts +0 -15
  422. package/dist/components/typeahead/typeahead-editor.js +0 -134
  423. package/dist/components/typeahead/typeahead.d.ts +0 -12
  424. package/dist/components/typeahead/typeahead.js +0 -94
  425. package/dist/screens/profile.d.ts +0 -2
  426. package/dist/screens/profile.js +0 -76
  427. package/src/components/input-datetime.tsx +0 -41
  428. package/src/components/lazy-sortable-list.tsx +0 -51
  429. package/src/components/left-bar.tsx +0 -322
  430. package/src/components/main-content-container.tsx +0 -79
  431. package/src/components/messages/thread-view.tsx +0 -214
  432. package/src/components/off-canvas.tsx +0 -83
  433. package/src/components/text-list-editor.tsx/text-list-editor.tsx +0 -13
  434. package/src/components/top-bar.tsx +0 -119
  435. package/src/components/typeahead/mentions-plugin.tsx +0 -265
  436. package/src/components/typeahead/typeahead-editor.tsx +0 -140
  437. package/src/components/typeahead/typeahead.tsx +0 -77
  438. package/src/screens/profile.tsx +0 -75
@@ -1,17 +1,17 @@
1
- import { sortBy } from 'lodash';
2
- import React, { useEffect, useState } from 'react';
3
- import { IMessage, Messages } from "@peers-app/peers-sdk";
4
- import { me } from '../../globals';
5
- import { MessageCompose } from './message-compose';
6
- import { MessageDisplay } from './message-display';
7
- import { usePromise } from '../../hooks';
1
+ import { type IMessage, Messages } from "@peers-app/peers-sdk";
2
+ import { sortBy } from "lodash";
3
+ import React, { useCallback, useEffect, useState } from "react";
4
+ import { me } from "../../globals";
5
+ import { usePromise } from "../../hooks";
6
+ import { MessageCompose } from "./message-compose";
7
+ import { MessageDisplay } from "./message-display";
8
8
 
9
9
  interface IProps {
10
- threadId: string
10
+ threadId: string;
11
11
  effects?: {
12
- pushMessage: (message: IMessage) => any,
13
- }
14
- scrollChanged?: (isBottomInView: boolean) => any,
12
+ pushMessage: (message: IMessage) => void;
13
+ };
14
+ scrollChanged?: (isBottomInView: boolean) => void;
15
15
  }
16
16
 
17
17
  export const ThreadMessageList = (props: IProps) => {
@@ -19,50 +19,54 @@ export const ThreadMessageList = (props: IProps) => {
19
19
 
20
20
  const [messages, setMessages] = useState<IMessage[]>([]);
21
21
  const messagesEndRef = React.useRef<HTMLDivElement>(null);
22
- const messageParent = usePromise(() => Messages().get(messageParentId), undefined, [messageParentId]);
22
+ const messageParent = usePromise(() => Messages().get(messageParentId), undefined, [
23
+ messageParentId,
24
+ ]);
23
25
 
24
- function scrollToBottom(behavior: 'instant' | 'smooth', delay = 100) {
26
+ const scrollToBottom = useCallback((behavior: "instant" | "smooth", delay = 100) => {
25
27
  setTimeout(() => {
26
28
  messagesEndRef.current?.scrollIntoView({ behavior });
27
29
  }, delay);
28
- }
30
+ }, []);
29
31
 
30
- async function loadMessages() {
31
- const messages = await Messages().list(
32
+ const loadMessages = useCallback(async () => {
33
+ const loaded = await Messages().list(
32
34
  { messageParentId },
33
35
  {
34
- sortBy: ['createdAt', 'messageId'],
35
- }
36
+ sortBy: ["createdAt", "messageId"],
37
+ },
36
38
  );
37
- setMessages(messages);
38
- scrollToBottom('instant', 1);
39
- }
39
+ setMessages(loaded);
40
+ scrollToBottom("instant", 1);
41
+ }, [messageParentId, scrollToBottom]);
40
42
 
41
43
  // first load
42
44
  useEffect(() => {
43
45
  loadMessages();
44
- }, [messageParentId]);
46
+ }, [loadMessages]);
45
47
 
46
48
  // reload when messages change
47
49
  useEffect(() => {
48
50
  // subscribe to message changes
49
51
  const sub = Messages().dataChanged.subscribe((evt) => {
50
- if (evt.dataObject.messageParentId == messageParentId || evt.dataObject.messageId === messageParentId) {
52
+ if (
53
+ evt.dataObject.messageParentId === messageParentId ||
54
+ evt.dataObject.messageId === messageParentId
55
+ ) {
51
56
  loadMessages();
52
57
  }
53
58
  });
54
59
  return () => {
55
60
  sub.unsubscribe();
56
- }
57
- }, [messageParentId]);
58
-
61
+ };
62
+ }, [messageParentId, loadMessages]);
59
63
 
60
64
  useEffect(() => {
61
65
  const observer = new IntersectionObserver(
62
66
  ([entry]) => {
63
67
  props?.scrollChanged?.(entry.isIntersecting);
64
68
  },
65
- { threshold: 1.0 }
69
+ { threshold: 1.0 },
66
70
  );
67
71
 
68
72
  if (messagesEndRef.current) {
@@ -74,23 +78,24 @@ export const ThreadMessageList = (props: IProps) => {
74
78
  observer.unobserve(messagesEndRef.current);
75
79
  }
76
80
  };
77
- }, []);
81
+ }, [props?.scrollChanged]);
78
82
 
79
-
80
- const [effects] = useState(() => props.effects || ({} as IProps['effects'])!);
83
+ // Shared-ref pattern: if a parent passes `effects`, we mutate `pushMessage` on that SAME
84
+ // reference so the parent can invoke it. Do NOT spread/clone (`{...props.effects}`).
85
+ // biome-ignore lint/style/noNonNullAssertion: initial `{}` is populated on this same render; the `!` placates TS for the optional `IProps["effects"]` shape.
86
+ const [effects] = useState(() => props.effects || ({} as IProps["effects"])!);
81
87
  effects.pushMessage = (newMessage: IMessage) => {
82
- if (messages.find(m => m.messageId === newMessage.messageId)) {
88
+ if (messages.find((m) => m.messageId === newMessage.messageId)) {
83
89
  return;
84
90
  }
85
- let _messages = sortBy([newMessage, ...messages], 'createdAt');
91
+ const _messages = sortBy([newMessage, ...messages], "createdAt");
86
92
  setMessages(_messages);
87
93
  if (newMessage.userId === me.userId && !newMessage.assistantId) {
88
- scrollToBottom('instant', 1);
94
+ scrollToBottom("instant", 1);
89
95
  } else {
90
- scrollToBottom('smooth');
96
+ scrollToBottom("smooth");
91
97
  }
92
- }
93
-
98
+ };
94
99
 
95
100
  const sendMessage = (userMessage: IMessage) => {
96
101
  effects.pushMessage(userMessage);
@@ -103,18 +108,22 @@ export const ThreadMessageList = (props: IProps) => {
103
108
 
104
109
  return (
105
110
  <>
106
- {messageParent &&
107
- <MessageDisplay message={messageParent} isThreadParent={true} />
108
- }
111
+ {messageParent && <MessageDisplay message={messageParent} isThreadParent={true} />}
109
112
  <hr />
110
113
 
111
114
  {messages.map((message, index) => {
112
- return <MessageDisplay key={message.messageId} message={message} messageAbove={messages[index - 1]} />
115
+ return (
116
+ <MessageDisplay
117
+ key={message.messageId}
118
+ message={message}
119
+ messageAbove={messages[index - 1]}
120
+ />
121
+ );
113
122
  })}
114
123
 
115
- <div className='p-2'>
124
+ <div className="p-2">
116
125
  <MessageCompose
117
- channelId={messageParent.channelId!}
126
+ channelId={messageParent.channelId ?? ""}
118
127
  threadId={messageParentId}
119
128
  onMessageSubmit={sendMessage}
120
129
  />
@@ -122,5 +131,5 @@ export const ThreadMessageList = (props: IProps) => {
122
131
 
123
132
  <div ref={messagesEndRef} />
124
133
  </>
125
- )
126
- }
134
+ );
135
+ };
@@ -1,27 +1,26 @@
1
- import React from "react";
2
1
  import * as globals from "../globals";
2
+ import { useObservable } from "../hooks";
3
3
  import { AssistantDetails } from "../screens/assistants/assistant-details";
4
4
  import { AssistantList } from "../screens/assistants/assistant-list";
5
+ import { PackageDetails } from "../screens/packages/package-details";
6
+ import { PackageList } from "../screens/packages/package-list";
7
+ import { PackageNewLocal } from "../screens/packages/package-new-local";
8
+ import { PeerTypeDetails } from "../screens/peer-types/peer-type-details";
9
+ import { PeerTypeLists } from "../screens/peer-types/peer-type-list";
10
+ import { GlobalSearch } from "../screens/search/global-search";
11
+ import { SettingsPage } from "../screens/settings/settings-page";
5
12
  // import { TaskDetails } from "../screens/tasks/task-details";
6
13
  // import { TaskList } from "../screens/tasks/task-list";
7
14
  import { ToolDetails } from "../screens/tools/tool-details";
8
15
  import { ToolList } from "../screens/tools/tool-list";
9
16
  import { ToolTestDetails } from "../screens/tools/tool-test-details";
17
+ import { VariableDetails } from "../screens/variables/variable-details";
18
+ import { VariableList } from "../screens/variables/variable-list";
10
19
  import { WorkflowDetails } from "../screens/workflows/workflow-details";
11
20
  import { WorkflowList } from "../screens/workflows/workflow-list";
12
- import { ChannelMessages } from "./messages/channel-view";
13
- import { SettingsPage } from "../screens/settings/settings-page";
14
- import { PackageDetails } from "../screens/packages/package-details";
15
- import { PackageList } from "../screens/packages/package-list";
16
- import { PackageNewLocal } from "../screens/packages/package-new-local";
17
- import { VariableList } from "../screens/variables/variable-list";
18
- import { VariableDetails } from "../screens/variables/variable-details";
19
- import { PeerTypeLists } from "../screens/peer-types/peer-type-list";
20
- import { PeerTypeDetails } from "../screens/peer-types/peer-type-details";
21
21
  import { UIRouter } from "../ui-router/ui-loader";
22
- import { useObservable } from "../hooks";
22
+ import { ChannelMessages } from "./messages/channel-view";
23
23
  import { ThreadMessageList } from "./messages/thread-message-list";
24
- import { GlobalSearch } from "../screens/search/global-search";
25
24
  import "../screens/console-logs/console-logs-list";
26
25
  import "../screens/groups";
27
26
  import "../screens/contacts";
@@ -29,53 +28,54 @@ import "../screens/join-group";
29
28
  import "../screens/network-viewer";
30
29
  import "../screens/data-explorer";
31
30
 
32
-
33
31
  export function Router({ path: providedPath }: { path?: string } = {}) {
32
+ // Hooks must run unconditionally (same order every render)
33
+ const [globalPath] = useObservable(globals.mainContentPath);
34
+
34
35
  try {
35
36
  // Use provided path or fall back to global mainContentPath
36
- const [globalPath] = useObservable(globals.mainContentPath);
37
37
  let path = providedPath ?? globalPath;
38
38
  const originalPath = path;
39
39
  path = path.toLowerCase().trim();
40
- path = path.split('?')[0]; // remove query string
40
+ path = path.split("?")[0]; // remove query string
41
41
 
42
42
  // remove leading '/'
43
- if (path.startsWith('/')) {
43
+ if (path.startsWith("/")) {
44
44
  path = path.substring(1);
45
45
  }
46
46
  // remove trailing '/'
47
- if (path.endsWith('/')) {
47
+ if (path.endsWith("/")) {
48
48
  path = path.substring(0, path.length - 1);
49
49
  }
50
50
 
51
- if (path === 'search') {
51
+ if (path === "search") {
52
52
  return <GlobalSearch />;
53
53
  }
54
- if (path === 'settings' || path === 'profile') {
54
+ if (path === "settings" || path === "profile") {
55
55
  return <SettingsPage />;
56
56
  }
57
- if (path === 'threads' || path === '') {
57
+ if (path === "threads" || path === "") {
58
58
  return <ChannelMessages />;
59
59
  }
60
60
 
61
- const ui = UIRouter({ path, props: {}, uiCategory: 'screen' });
61
+ const ui = UIRouter({ path, props: {}, uiCategory: "screen" });
62
62
  if (ui) {
63
63
  return ui;
64
64
  }
65
65
 
66
66
  if (path.match(/^channel\//)) {
67
- const parts = path.split('/');
67
+ const parts = path.split("/");
68
68
  parts.shift();
69
69
  const channelId = parts[0];
70
70
  // todo add additional params as props if they exist
71
71
  return <ChannelMessages channelId={channelId} />;
72
72
  }
73
73
 
74
- if (path === 'assistants') {
74
+ if (path === "assistants") {
75
75
  return <AssistantList />;
76
76
  }
77
77
  if (path.match(/^assistants\//)) {
78
- const parts = path.split('/');
78
+ const parts = path.split("/");
79
79
  parts.shift();
80
80
  const id = parts[0];
81
81
  return <AssistantDetails assistantId={id} />;
@@ -91,85 +91,84 @@ export function Router({ path: providedPath }: { path?: string } = {}) {
91
91
  // return <TaskDetails taskId={taskId} />;
92
92
  // }
93
93
 
94
- if (path === 'workflows') {
94
+ if (path === "workflows") {
95
95
  return <WorkflowList />;
96
96
  }
97
97
  if (path.match(/^workflows\//)) {
98
- const parts = path.split('/');
98
+ const parts = path.split("/");
99
99
  parts.shift();
100
100
  const workflowId = parts[0];
101
101
  return <WorkflowDetails workflowId={workflowId} />;
102
102
  }
103
103
 
104
- if (path === 'tools') {
104
+ if (path === "tools") {
105
105
  return <ToolList />;
106
106
  }
107
107
  if (path.match(/^tools\/tests\//)) {
108
- const parts = path.split('/');
108
+ const parts = path.split("/");
109
109
  parts.shift();
110
110
  parts.shift();
111
111
  const toolTestId = parts[0];
112
112
  return <ToolTestDetails toolTestId={toolTestId} />;
113
113
  }
114
114
  if (path.match(/^tools\//)) {
115
- const parts = path.split('/');
115
+ const parts = path.split("/");
116
116
  parts.shift();
117
117
  const toolId = parts[0];
118
118
  return <ToolDetails toolId={toolId} />;
119
119
  }
120
120
 
121
- if (path === 'packages') {
121
+ if (path === "packages") {
122
122
  return <PackageList />;
123
123
  }
124
124
  if (path.match(/^packages\//)) {
125
- const parts = path.split('/');
125
+ const parts = path.split("/");
126
126
  parts.shift();
127
127
  const id = parts[0];
128
- if (id.toLowerCase() === 'newlocal') {
128
+ if (id.toLowerCase() === "newlocal") {
129
129
  return <PackageNewLocal />;
130
130
  }
131
131
  return <PackageDetails packageId={id} />;
132
132
  }
133
133
 
134
- if (path === 'variables') {
134
+ if (path === "variables") {
135
135
  return <VariableList />;
136
136
  }
137
137
  if (path.match(/^variables\//)) {
138
- const parts = path.split('/');
138
+ const parts = path.split("/");
139
139
  parts.shift();
140
140
  const id = parts[0];
141
141
  return <VariableDetails persistentVarId={id} />;
142
142
  }
143
143
 
144
- if (path === 'peer-types') {
144
+ if (path === "peer-types") {
145
145
  return <PeerTypeLists />;
146
146
  }
147
147
  if (path.match(/^peer-types\//)) {
148
- const parts = path.split('/');
148
+ const parts = path.split("/");
149
149
  parts.shift();
150
150
  const id = parts[0];
151
151
  return <PeerTypeDetails peerTypeId={id} />;
152
152
  }
153
153
 
154
154
  if (path.match(/^threads\//)) {
155
- const parts = path.split('/');
155
+ const parts = path.split("/");
156
156
  parts.shift();
157
157
  const threadId = parts[0];
158
158
  return <ThreadMessageList threadId={threadId} />;
159
159
  }
160
160
 
161
- throw new Error('Unrecognized route: ' + originalPath);
162
-
161
+ throw new Error(`Unrecognized route: ${originalPath}`);
163
162
  } catch (err) {
164
163
  return (
165
164
  <div className="p-3">
166
- <a href='#threads'>Home</a>
165
+ <a href="#threads">Home</a>
167
166
  <h3>Error loading route</h3>
168
167
  <pre>
169
- route: {globals.mainContentPath() + '\n'}
168
+ route: {`${globals.mainContentPath()}\n`}
170
169
  {String(err)}
171
170
  </pre>
172
171
  </div>
173
- )
172
+ );
174
173
  }
175
- }
174
+ }
@@ -1,19 +1,20 @@
1
- import React from "react";
2
- import { IDoc } from "@peers-app/peers-sdk";
1
+ import type { IDoc } from "@peers-app/peers-sdk";
2
+ import type React from "react";
3
3
  import { isDesktop, mainContentPath } from "../globals";
4
4
  import { useObservable } from "../hooks";
5
5
 
6
6
  export interface ISaveButtonProps {
7
- doc: IDoc<any>
7
+ // biome-ignore lint/suspicious/noExplicitAny: SaveButton is used with many concrete table row shapes; IDoc stays generic at call sites.
8
+ doc: IDoc<any>;
8
9
  onClick?: () => void | Promise<void>;
9
10
  addActions?: (
10
- {
11
- label: string;
12
- onClick: () => void;
13
- className?: string;
14
- }
11
+ | {
12
+ label: string;
13
+ onClick: () => void;
14
+ className?: string;
15
+ }
15
16
  | React.ReactNode
16
- )[]
17
+ )[];
17
18
  noBuiltInActions?: boolean;
18
19
  }
19
20
 
@@ -25,85 +26,88 @@ export const SaveButton = (props: ISaveButtonProps) => {
25
26
  if (!addActions) {
26
27
  addActions = [];
27
28
  }
28
- const allActions: ISaveButtonProps['addActions'] = props.addActions ? [...addActions] : [];
29
+ const allActions: ISaveButtonProps["addActions"] = props.addActions ? [...addActions] : [];
29
30
 
30
31
  if (!props.noBuiltInActions) {
31
32
  if (q()) {
32
33
  allActions.unshift({
33
- label: 'Discard Changes',
34
- className: 'text-bg-warning',
34
+ label: "Discard Changes",
35
+ className: "text-bg-warning",
35
36
  onClick: () => {
36
- if (confirm('Are you sure you want to discard your changes?')) {
37
- doc.load()
38
- .then(() => {
39
- setTimeout(() => doc.q(0), 100);
40
- });
37
+ if (confirm("Are you sure you want to discard your changes?")) {
38
+ doc.load().then(() => {
39
+ setTimeout(() => doc.q(0), 100);
40
+ });
41
41
  }
42
- }
42
+ },
43
43
  });
44
44
  }
45
45
  if (allActions.length) {
46
46
  allActions.push(<hr className="dropdown-divider mt-3" />);
47
47
  }
48
48
  allActions.push({
49
- label: 'Delete',
49
+ label: "Delete",
50
50
  className: `text-bg-danger`,
51
51
  onClick: async () => {
52
- if (confirm('Are you sure you want to delete this?')) {
52
+ if (confirm("Are you sure you want to delete this?")) {
53
53
  await doc.delete();
54
- const pathParts = mainContentPath().split('/');
54
+ const pathParts = mainContentPath().split("/");
55
55
  pathParts.pop();
56
- const path = pathParts.join('/') ?? '';
56
+ const path = pathParts.join("/") ?? "";
57
57
  mainContentPath(path);
58
58
  }
59
- }
59
+ },
60
60
  });
61
61
  }
62
62
 
63
-
64
-
65
63
  let className = `btn `;
66
64
  if (q()) {
67
- className += 'btn-primary';
65
+ className += "btn-primary";
68
66
  } else {
69
- className += 'disabled';
67
+ className += "disabled";
70
68
  }
71
69
 
72
70
  if (!addActions?.length && props.noBuiltInActions) {
73
71
  return (
74
72
  <button className={className} onClick={props.onClick ?? doc.save} disabled={!q()}>
75
- {isDesktop() ? 'Save Changes' : 'Save'}
73
+ {isDesktop() ? "Save Changes" : "Save"}
76
74
  </button>
77
- )
75
+ );
78
76
  }
79
77
 
80
78
  return (
81
- <div style={{ display: 'inline-block' }}>
82
- <div className="input-group" >
79
+ <div style={{ display: "inline-block" }}>
80
+ <div className="input-group">
83
81
  <button className={className} onClick={props.onClick ?? doc.save} disabled={!q()}>
84
- {isDesktop() ? 'Save Changes' : 'Save'}
82
+ {isDesktop() ? "Save Changes" : "Save"}
85
83
  </button>
86
- <button type="button" data-bs-toggle="dropdown" aria-expanded="false"
84
+ <button
85
+ type="button"
86
+ data-bs-toggle="dropdown"
87
+ aria-expanded="false"
87
88
  // className={`btn dropdown-toggle dropdown-toggle-split ${q() ? 'btn-primary' : 'btn-secondary'}`}
88
89
  className={`btn dropdown-toggle dropdown-toggle-split btn-secondary`}
89
90
  >
90
91
  <span className="visually-hidden">Toggle Dropdown</span>
91
92
  </button>
92
93
  <ul className="dropdown-menu dropdown-menu-end">
93
- {allActions.map(action => {
94
- if (typeof action !== 'object' || action === null || !('label' in action)) {
95
- return (<li key={Math.random()}>{action}</li>);
94
+ {allActions.map((action) => {
95
+ if (typeof action !== "object" || action === null || !("label" in action)) {
96
+ return <li key={Math.random()}>{action}</li>;
96
97
  }
97
98
  return (
98
99
  <li key={action.label}>
99
- <button className={`dropdown-item rounded mt-2 ${action.className || ''}`} onClick={action.onClick}>
100
+ <button
101
+ className={`dropdown-item rounded mt-2 ${action.className || ""}`}
102
+ onClick={action.onClick}
103
+ >
100
104
  {action.label}
101
105
  </button>
102
106
  </li>
103
- )
107
+ );
104
108
  })}
105
109
  </ul>
106
110
  </div>
107
111
  </div>
108
112
  );
109
- }
113
+ };