@gen3/frontend 0.10.50 → 0.10.51

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 (315) hide show
  1. package/dist/cjs/index.js +2225 -240
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.d.ts +11 -0
  4. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.d.ts.map +1 -0
  5. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.js +75 -0
  6. package/dist/dts/components/Buttons/DownloadButtons/JSONObjectDownloadButton.js.map +1 -0
  7. package/dist/dts/components/Buttons/UploadJSONButton.d.ts +9 -0
  8. package/dist/dts/components/Buttons/UploadJSONButton.d.ts.map +1 -0
  9. package/dist/dts/components/Buttons/UploadJSONButton.js +65 -0
  10. package/dist/dts/components/Buttons/UploadJSONButton.js.map +1 -0
  11. package/dist/dts/components/Login/CredentialsLogin.d.ts.map +1 -1
  12. package/dist/dts/components/Login/CredentialsLogin.js +11 -6
  13. package/dist/dts/components/Login/CredentialsLogin.js.map +1 -1
  14. package/dist/dts/components/Login/LoginPanel.d.ts.map +1 -1
  15. package/dist/dts/components/Login/LoginPanel.js +10 -6
  16. package/dist/dts/components/Login/LoginPanel.js.map +1 -1
  17. package/dist/dts/components/Login/LoginProvidersPanel.d.ts.map +1 -1
  18. package/dist/dts/components/Login/LoginProvidersPanel.js +5 -1
  19. package/dist/dts/components/Login/LoginProvidersPanel.js.map +1 -1
  20. package/dist/dts/components/MessageCards/CardContainer.d.ts +7 -0
  21. package/dist/dts/components/MessageCards/CardContainer.d.ts.map +1 -0
  22. package/dist/dts/components/MessageCards/CardContainer.js +8 -0
  23. package/dist/dts/components/MessageCards/CardContainer.js.map +1 -0
  24. package/dist/dts/components/MessageCards/ErrorCard.d.ts +5 -0
  25. package/dist/dts/components/MessageCards/ErrorCard.d.ts.map +1 -0
  26. package/dist/dts/components/MessageCards/ErrorCard.js +9 -0
  27. package/dist/dts/components/MessageCards/ErrorCard.js.map +1 -0
  28. package/dist/dts/components/MessageCards/MessageCard.d.ts +13 -0
  29. package/dist/dts/components/MessageCards/MessageCard.d.ts.map +1 -0
  30. package/dist/dts/components/MessageCards/MessageCard.js +13 -0
  31. package/dist/dts/components/MessageCards/MessageCard.js.map +1 -0
  32. package/dist/dts/components/MessageCards/WarningCard.d.ts +5 -0
  33. package/dist/dts/components/MessageCards/WarningCard.d.ts.map +1 -0
  34. package/dist/dts/components/MessageCards/WarningCard.js +9 -0
  35. package/dist/dts/components/MessageCards/WarningCard.js.map +1 -0
  36. package/dist/dts/components/MessageCards/index.d.ts +6 -0
  37. package/dist/dts/components/MessageCards/index.d.ts.map +1 -0
  38. package/dist/dts/components/MessageCards/index.js +6 -0
  39. package/dist/dts/components/MessageCards/index.js.map +1 -0
  40. package/dist/dts/components/Profile/ResourcesTable.d.ts.map +1 -1
  41. package/dist/dts/components/Profile/ResourcesTable.js.map +1 -1
  42. package/dist/dts/components/Protected/ProtectedContent.d.ts.map +1 -1
  43. package/dist/dts/components/Protected/ProtectedContent.js +4 -4
  44. package/dist/dts/components/Protected/ProtectedContent.js.map +1 -1
  45. package/dist/dts/components/Providers/Gen3Provider.d.ts +1 -1
  46. package/dist/dts/components/Providers/Gen3Provider.d.ts.map +1 -1
  47. package/dist/dts/components/Providers/Gen3Provider.js +1 -1
  48. package/dist/dts/components/Providers/Gen3Provider.js.map +1 -1
  49. package/dist/dts/components/Providers/ResourceMonitor.d.ts +6 -0
  50. package/dist/dts/components/Providers/ResourceMonitor.d.ts.map +1 -0
  51. package/dist/dts/components/Providers/ResourceMonitor.js +105 -0
  52. package/dist/dts/components/Providers/ResourceMonitor.js.map +1 -0
  53. package/dist/dts/components/StyledComponents/DarkFunctionButton.d.ts +7 -0
  54. package/dist/dts/components/StyledComponents/DarkFunctionButton.d.ts.map +1 -0
  55. package/dist/dts/components/StyledComponents/DarkFunctionButton.js +9 -0
  56. package/dist/dts/components/StyledComponents/DarkFunctionButton.js.map +1 -0
  57. package/dist/dts/components/charts/BarChart.d.ts.map +1 -1
  58. package/dist/dts/components/charts/BarChart.js.map +1 -1
  59. package/dist/dts/features/Analysis/AnalysisCardEditor.d.ts +3 -0
  60. package/dist/dts/features/Analysis/AnalysisCardEditor.d.ts.map +1 -0
  61. package/dist/dts/features/Analysis/AnalysisCardEditor.js +275 -0
  62. package/dist/dts/features/Analysis/AnalysisCardEditor.js.map +1 -0
  63. package/dist/dts/features/Analysis/AnalysisCenter.d.ts +5 -0
  64. package/dist/dts/features/Analysis/AnalysisCenter.d.ts.map +1 -0
  65. package/dist/dts/features/Analysis/AnalysisCenter.js +68 -0
  66. package/dist/dts/features/Analysis/AnalysisCenter.js.map +1 -0
  67. package/dist/dts/features/Analysis/AnalysisPanel.d.ts +4 -0
  68. package/dist/dts/features/Analysis/AnalysisPanel.d.ts.map +1 -0
  69. package/dist/dts/features/Analysis/AnalysisPanel.js +8 -0
  70. package/dist/dts/features/Analysis/AnalysisPanel.js.map +1 -0
  71. package/dist/dts/features/Analysis/TextDescription.d.ts +7 -0
  72. package/dist/dts/features/Analysis/TextDescription.d.ts.map +1 -0
  73. package/dist/dts/features/Analysis/TextDescription.js +11 -0
  74. package/dist/dts/features/Analysis/TextDescription.js.map +1 -0
  75. package/dist/dts/features/Analysis/index.d.ts +3 -0
  76. package/dist/dts/features/Analysis/index.d.ts.map +1 -0
  77. package/dist/dts/features/Analysis/index.js +3 -0
  78. package/dist/dts/features/Analysis/index.js.map +1 -0
  79. package/dist/dts/features/Analysis/types.d.ts +16 -0
  80. package/dist/dts/features/Analysis/types.d.ts.map +1 -0
  81. package/dist/dts/features/Analysis/types.js +2 -0
  82. package/dist/dts/features/Analysis/types.js.map +1 -0
  83. package/dist/dts/features/CohortBuilder/CohortManager.d.ts.map +1 -1
  84. package/dist/dts/features/CohortBuilder/CohortManager.js +1 -1
  85. package/dist/dts/features/CohortBuilder/CohortManager.js.map +1 -1
  86. package/dist/dts/features/CohortBuilder/CohortPanel.js +1 -1
  87. package/dist/dts/features/CohortBuilder/CohortPanel.js.map +1 -1
  88. package/dist/dts/features/CohortBuilder/CohortSelector.d.ts +10 -0
  89. package/dist/dts/features/CohortBuilder/CohortSelector.d.ts.map +1 -0
  90. package/dist/dts/features/CohortBuilder/CohortSelector.js +20 -0
  91. package/dist/dts/features/CohortBuilder/CohortSelector.js.map +1 -0
  92. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.d.ts +1 -6
  93. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.d.ts.map +1 -1
  94. package/dist/dts/features/CohortBuilder/ExplorerTable/CellRenderers.js.map +1 -1
  95. package/dist/dts/features/CohortBuilder/ExplorerTable/ExploreTableDetails/QueryRowDetailsPanel.js +1 -1
  96. package/dist/dts/features/CohortBuilder/ExplorerTable/ExploreTableDetails/QueryRowDetailsPanel.js.map +1 -1
  97. package/dist/dts/features/CohortBuilder/ExplorerTable/types.d.ts +9 -3
  98. package/dist/dts/features/CohortBuilder/ExplorerTable/types.d.ts.map +1 -1
  99. package/dist/dts/features/CohortBuilder/QueryExpressionSection.d.ts.map +1 -1
  100. package/dist/dts/features/CohortBuilder/QueryExpressionSection.js +8 -6
  101. package/dist/dts/features/CohortBuilder/QueryExpressionSection.js.map +1 -1
  102. package/dist/dts/features/CohortBuilder/style.d.ts.map +1 -1
  103. package/dist/dts/features/CohortBuilder/style.js +2 -2
  104. package/dist/dts/features/CohortBuilder/style.js.map +1 -1
  105. package/dist/dts/features/CohortDiscovery/IndexPanel.js +1 -1
  106. package/dist/dts/features/CohortDiscovery/IndexPanel.js.map +1 -1
  107. package/dist/dts/features/CohortDiversity/CohortDiversityApp.js +1 -1
  108. package/dist/dts/features/CohortDiversity/CohortDiversityApp.js.map +1 -1
  109. package/dist/dts/features/Dictionary/Cell.d.ts.map +1 -1
  110. package/dist/dts/features/Dictionary/Cell.js.map +1 -1
  111. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.d.ts.map +1 -1
  112. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js +2 -2
  113. package/dist/dts/features/Discovery/TableRenderers/CellRendererFactory.js.map +1 -1
  114. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js +2 -2
  115. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js.map +1 -1
  116. package/dist/dts/features/Discovery/TableRenderers/RowRendererFactory.js +2 -2
  117. package/dist/dts/features/Discovery/TableRenderers/RowRendererFactory.js.map +1 -1
  118. package/dist/dts/features/Navigation/TopBar.js +1 -1
  119. package/dist/dts/features/Navigation/TopBar.js.map +1 -1
  120. package/dist/dts/features/Navigation/Vertical/VerticalTopBar.d.ts.map +1 -1
  121. package/dist/dts/features/Navigation/Vertical/VerticalTopBar.js.map +1 -1
  122. package/dist/dts/features/Navigation/types.d.ts +8 -0
  123. package/dist/dts/features/Navigation/types.d.ts.map +1 -1
  124. package/dist/dts/features/Theme/ColorTheme.js.map +1 -1
  125. package/dist/dts/features/Workspace/ExternalLogins/ExternalLoginsStatus.d.ts +3 -0
  126. package/dist/dts/features/Workspace/ExternalLogins/ExternalLoginsStatus.d.ts.map +1 -0
  127. package/dist/dts/features/Workspace/ExternalLogins/ExternalLoginsStatus.js +21 -0
  128. package/dist/dts/features/Workspace/ExternalLogins/ExternalLoginsStatus.js.map +1 -0
  129. package/dist/dts/features/Workspace/NotebookCard.d.ts +7 -0
  130. package/dist/dts/features/Workspace/NotebookCard.d.ts.map +1 -0
  131. package/dist/dts/features/Workspace/NotebookCard.js +22 -0
  132. package/dist/dts/features/Workspace/NotebookCard.js.map +1 -0
  133. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.d.ts +3 -0
  134. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.d.ts.map +1 -0
  135. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.js +76 -0
  136. package/dist/dts/features/Workspace/PaymentPanel/PaymentPanel.js.map +1 -0
  137. package/dist/dts/features/Workspace/StatusAndControls.d.ts +3 -0
  138. package/dist/dts/features/Workspace/StatusAndControls.d.ts.map +1 -0
  139. package/dist/dts/features/Workspace/StatusAndControls.js +28 -0
  140. package/dist/dts/features/Workspace/StatusAndControls.js.map +1 -0
  141. package/dist/dts/features/Workspace/Workspace.d.ts +7 -0
  142. package/dist/dts/features/Workspace/Workspace.d.ts.map +1 -0
  143. package/dist/dts/features/Workspace/Workspace.js +12 -0
  144. package/dist/dts/features/Workspace/Workspace.js.map +1 -0
  145. package/dist/dts/features/Workspace/WorkspaceLaunchProgress.d.ts +3 -0
  146. package/dist/dts/features/Workspace/WorkspaceLaunchProgress.d.ts.map +1 -0
  147. package/dist/dts/features/Workspace/WorkspaceLaunchProgress.js +19 -0
  148. package/dist/dts/features/Workspace/WorkspaceLaunchProgress.js.map +1 -0
  149. package/dist/dts/features/Workspace/WorkspaceNotebook.d.ts +3 -0
  150. package/dist/dts/features/Workspace/WorkspaceNotebook.d.ts.map +1 -0
  151. package/dist/dts/features/Workspace/WorkspaceNotebook.js +11 -0
  152. package/dist/dts/features/Workspace/WorkspaceNotebook.js.map +1 -0
  153. package/dist/dts/features/Workspace/WorkspaceNotebookPanelWithControls.d.ts +3 -0
  154. package/dist/dts/features/Workspace/WorkspaceNotebookPanelWithControls.d.ts.map +1 -0
  155. package/dist/dts/features/Workspace/WorkspaceNotebookPanelWithControls.js +16 -0
  156. package/dist/dts/features/Workspace/WorkspaceNotebookPanelWithControls.js.map +1 -0
  157. package/dist/dts/features/Workspace/WorkspacePanel.d.ts +3 -0
  158. package/dist/dts/features/Workspace/WorkspacePanel.d.ts.map +1 -0
  159. package/dist/dts/features/Workspace/WorkspacePanel.js +18 -0
  160. package/dist/dts/features/Workspace/WorkspacePanel.js.map +1 -0
  161. package/dist/dts/features/Workspace/WorkspaceProvider.d.ts +9 -0
  162. package/dist/dts/features/Workspace/WorkspaceProvider.d.ts.map +1 -0
  163. package/dist/dts/features/Workspace/WorkspaceProvider.js +46 -0
  164. package/dist/dts/features/Workspace/WorkspaceProvider.js.map +1 -0
  165. package/dist/dts/features/Workspace/WorkspaceStatusProvider.d.ts +17 -0
  166. package/dist/dts/features/Workspace/WorkspaceStatusProvider.d.ts.map +1 -0
  167. package/dist/dts/features/Workspace/WorkspaceStatusProvider.js +103 -0
  168. package/dist/dts/features/Workspace/WorkspaceStatusProvider.js.map +1 -0
  169. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.d.ts +20 -0
  170. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.d.ts.map +1 -0
  171. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js +78 -0
  172. package/dist/dts/features/Workspace/admin/WorkspaceEditorContext.js.map +1 -0
  173. package/dist/dts/features/Workspace/admin/WorkspacePanelForm.d.ts +4 -0
  174. package/dist/dts/features/Workspace/admin/WorkspacePanelForm.d.ts.map +1 -0
  175. package/dist/dts/features/Workspace/admin/WorkspacePanelForm.js +46 -0
  176. package/dist/dts/features/Workspace/admin/WorkspacePanelForm.js.map +1 -0
  177. package/dist/dts/features/Workspace/admin/WorkspacePanelsEditor.d.ts +3 -0
  178. package/dist/dts/features/Workspace/admin/WorkspacePanelsEditor.d.ts.map +1 -0
  179. package/dist/dts/features/Workspace/admin/WorkspacePanelsEditor.js +7 -0
  180. package/dist/dts/features/Workspace/admin/WorkspacePanelsEditor.js.map +1 -0
  181. package/dist/dts/features/Workspace/calculateLaunchSteps.d.ts +6 -0
  182. package/dist/dts/features/Workspace/calculateLaunchSteps.d.ts.map +1 -0
  183. package/dist/dts/features/Workspace/calculateLaunchSteps.js +101 -0
  184. package/dist/dts/features/Workspace/calculateLaunchSteps.js.map +1 -0
  185. package/dist/dts/features/Workspace/constants.d.ts +8 -0
  186. package/dist/dts/features/Workspace/constants.d.ts.map +1 -0
  187. package/dist/dts/features/Workspace/constants.js +24 -0
  188. package/dist/dts/features/Workspace/constants.js.map +1 -0
  189. package/dist/dts/features/Workspace/index.d.ts +3 -3
  190. package/dist/dts/features/Workspace/index.d.ts.map +1 -1
  191. package/dist/dts/features/Workspace/index.js +2 -2
  192. package/dist/dts/features/Workspace/index.js.map +1 -1
  193. package/dist/dts/features/Workspace/test/calculateLaunchSteps.unit.test.d.ts +2 -0
  194. package/dist/dts/features/Workspace/test/calculateLaunchSteps.unit.test.d.ts.map +1 -0
  195. package/dist/dts/features/Workspace/test/calculateLaunchSteps.unit.test.js +105 -0
  196. package/dist/dts/features/Workspace/test/calculateLaunchSteps.unit.test.js.map +1 -0
  197. package/dist/dts/features/Workspace/types.d.ts +26 -1
  198. package/dist/dts/features/Workspace/types.d.ts.map +1 -1
  199. package/dist/dts/features/Workspace/utils.d.ts +2 -0
  200. package/dist/dts/features/Workspace/utils.d.ts.map +1 -0
  201. package/dist/dts/features/Workspace/utils.js +8 -0
  202. package/dist/dts/features/Workspace/utils.js.map +1 -0
  203. package/dist/dts/index.d.ts +13 -4
  204. package/dist/dts/index.d.ts.map +1 -1
  205. package/dist/dts/index.js +12 -4
  206. package/dist/dts/index.js.map +1 -1
  207. package/dist/dts/lib/content/ContentDatabase.d.ts +1 -0
  208. package/dist/dts/lib/content/ContentDatabase.d.ts.map +1 -1
  209. package/dist/dts/lib/content/ContentDatabase.js +8 -0
  210. package/dist/dts/lib/content/ContentDatabase.js.map +1 -1
  211. package/dist/dts/lib/content/filesystem.d.ts +2 -1
  212. package/dist/dts/lib/content/filesystem.d.ts.map +1 -1
  213. package/dist/dts/lib/content/filesystem.js +28 -0
  214. package/dist/dts/lib/content/filesystem.js.map +1 -1
  215. package/dist/dts/lib/content/types.d.ts +1 -0
  216. package/dist/dts/lib/content/types.d.ts.map +1 -1
  217. package/dist/dts/lib/session/session.d.ts.map +1 -1
  218. package/dist/dts/lib/session/session.js +4 -2
  219. package/dist/dts/lib/session/session.js.map +1 -1
  220. package/dist/dts/pages/Analysis/Analysis.d.ts +4 -0
  221. package/dist/dts/pages/Analysis/Analysis.d.ts.map +1 -0
  222. package/dist/dts/pages/Analysis/Analysis.js +13 -0
  223. package/dist/dts/pages/Analysis/Analysis.js.map +1 -0
  224. package/dist/dts/pages/Analysis/data.d.ts +4 -0
  225. package/dist/dts/pages/Analysis/data.d.ts.map +1 -0
  226. package/dist/dts/pages/Analysis/data.js +78 -0
  227. package/dist/dts/pages/Analysis/data.js.map +1 -0
  228. package/dist/dts/pages/Analysis/index.d.ts +3 -0
  229. package/dist/dts/pages/Analysis/index.d.ts.map +1 -0
  230. package/dist/dts/pages/Analysis/index.js +3 -0
  231. package/dist/dts/pages/Analysis/index.js.map +1 -0
  232. package/dist/dts/pages/Analysis/types.d.ts +6 -0
  233. package/dist/dts/pages/Analysis/types.d.ts.map +1 -0
  234. package/dist/dts/pages/Analysis/types.js +2 -0
  235. package/dist/dts/pages/Analysis/types.js.map +1 -0
  236. package/dist/dts/pages/Explorer/Explorer.d.ts.map +1 -1
  237. package/dist/dts/pages/Explorer/Explorer.js.map +1 -1
  238. package/dist/dts/pages/Explorer/index.d.ts +1 -0
  239. package/dist/dts/pages/Explorer/index.d.ts.map +1 -1
  240. package/dist/dts/pages/Explorer/index.js +1 -0
  241. package/dist/dts/pages/Explorer/index.js.map +1 -1
  242. package/dist/dts/pages/NotebookLite/NotebookLite.d.ts +4 -0
  243. package/dist/dts/pages/NotebookLite/NotebookLite.d.ts.map +1 -0
  244. package/dist/dts/pages/NotebookLite/NotebookLite.js +12 -0
  245. package/dist/dts/pages/NotebookLite/NotebookLite.js.map +1 -0
  246. package/dist/dts/pages/NotebookLite/data.d.ts +3 -0
  247. package/dist/dts/pages/NotebookLite/data.d.ts.map +1 -0
  248. package/dist/dts/pages/NotebookLite/data.js +62 -0
  249. package/dist/dts/pages/NotebookLite/data.js.map +1 -0
  250. package/dist/dts/pages/NotebookLite/index.d.ts +3 -0
  251. package/dist/dts/pages/NotebookLite/index.d.ts.map +1 -0
  252. package/dist/dts/pages/NotebookLite/index.js +3 -0
  253. package/dist/dts/pages/NotebookLite/index.js.map +1 -0
  254. package/dist/dts/pages/Workspace/Workspace.d.ts +4 -0
  255. package/dist/dts/pages/Workspace/Workspace.d.ts.map +1 -0
  256. package/dist/dts/pages/Workspace/Workspace.js +13 -0
  257. package/dist/dts/pages/Workspace/Workspace.js.map +1 -0
  258. package/dist/dts/pages/Workspace/WorkspaceNoAccess.d.ts +4 -0
  259. package/dist/dts/pages/Workspace/WorkspaceNoAccess.d.ts.map +1 -0
  260. package/dist/dts/pages/Workspace/WorkspaceNoAccess.js +15 -0
  261. package/dist/dts/pages/Workspace/WorkspaceNoAccess.js.map +1 -0
  262. package/dist/dts/pages/Workspace/data.d.ts +4 -2
  263. package/dist/dts/pages/Workspace/data.d.ts.map +1 -1
  264. package/dist/dts/pages/Workspace/data.js +33 -6
  265. package/dist/dts/pages/Workspace/data.js.map +1 -1
  266. package/dist/dts/pages/Workspace/index.d.ts +4 -2
  267. package/dist/dts/pages/Workspace/index.d.ts.map +1 -1
  268. package/dist/dts/pages/Workspace/index.js +4 -2
  269. package/dist/dts/pages/Workspace/index.js.map +1 -1
  270. package/dist/dts/pages/Workspace/types.d.ts +3 -3
  271. package/dist/dts/pages/Workspace/types.d.ts.map +1 -1
  272. package/dist/dts/pages/admin/Workspace/WorkspaceNotebooks.d.ts +7 -0
  273. package/dist/dts/pages/admin/Workspace/WorkspaceNotebooks.d.ts.map +1 -0
  274. package/dist/dts/pages/admin/Workspace/WorkspaceNotebooks.js +13 -0
  275. package/dist/dts/pages/admin/Workspace/WorkspaceNotebooks.js.map +1 -0
  276. package/dist/dts/pages/admin/Workspace/data.d.ts +2 -0
  277. package/dist/dts/pages/admin/Workspace/data.d.ts.map +1 -0
  278. package/dist/dts/pages/admin/Workspace/data.js +45 -0
  279. package/dist/dts/pages/admin/Workspace/data.js.map +1 -0
  280. package/dist/dts/pages/admin/Workspace/index.d.ts +3 -0
  281. package/dist/dts/pages/admin/Workspace/index.d.ts.map +1 -0
  282. package/dist/dts/pages/admin/Workspace/index.js +3 -0
  283. package/dist/dts/pages/admin/Workspace/index.js.map +1 -0
  284. package/dist/dts/pages/admin/analysis/Analysis.d.ts +7 -0
  285. package/dist/dts/pages/admin/analysis/Analysis.d.ts.map +1 -0
  286. package/dist/dts/pages/admin/analysis/Analysis.js +13 -0
  287. package/dist/dts/pages/admin/analysis/Analysis.js.map +1 -0
  288. package/dist/dts/pages/admin/analysis/data.d.ts +9 -0
  289. package/dist/dts/pages/admin/analysis/data.d.ts.map +1 -0
  290. package/dist/dts/pages/admin/analysis/data.js +76 -0
  291. package/dist/dts/pages/admin/analysis/data.js.map +1 -0
  292. package/dist/dts/pages/admin/authz/index.d.ts.map +1 -1
  293. package/dist/dts/pages/admin/authz/index.js.map +1 -1
  294. package/dist/dts/utils/RendererFactory.d.ts.map +1 -1
  295. package/dist/dts/utils/RendererFactory.js +1 -0
  296. package/dist/dts/utils/RendererFactory.js.map +1 -1
  297. package/dist/dts/utils/download.d.ts.map +1 -1
  298. package/dist/dts/utils/download.js.map +1 -1
  299. package/dist/esm/index.js +2224 -248
  300. package/dist/esm/index.js.map +1 -1
  301. package/dist/index.d.ts +108 -26
  302. package/dist/tsconfig.tsbuildinfo +1 -1
  303. package/package.json +2 -1
  304. package/dist/dts/components/FilterPanel.d.ts +0 -1
  305. package/dist/dts/components/FilterPanel.d.ts.map +0 -1
  306. package/dist/dts/components/FilterPanel.js +0 -2
  307. package/dist/dts/components/FilterPanel.js.map +0 -1
  308. package/dist/dts/components/Login/utils.d.ts +0 -1
  309. package/dist/dts/components/Login/utils.d.ts.map +0 -1
  310. package/dist/dts/components/Login/utils.js +0 -2
  311. package/dist/dts/components/Login/utils.js.map +0 -1
  312. package/dist/dts/features/Submission/Tables/hooks.d.ts +0 -1
  313. package/dist/dts/features/Submission/Tables/hooks.d.ts.map +0 -1
  314. package/dist/dts/features/Submission/Tables/hooks.js +0 -2
  315. package/dist/dts/features/Submission/Tables/hooks.js.map +0 -1
package/dist/esm/index.js CHANGED
@@ -5,18 +5,18 @@ import { twMerge } from 'tailwind-merge';
5
5
  import Image from 'next/image';
6
6
  import { toString, capitalize as capitalize$1, isArray, get, partial, omit } from 'lodash';
7
7
  import Link from 'next/link';
8
- import { FaExternalLinkAlt, FaQuestion, FaExclamation, FaExclamationTriangle, FaUndo, FaPlus, FaChartPie, FaGraduationCap, FaRegQuestionCircle, FaVideo, FaCircle } from 'react-icons/fa';
8
+ import { FaExternalLinkAlt, FaQuestion, FaExclamation, FaExclamationTriangle, FaUndo, FaPlus, FaRegStopCircle, FaUser, FaExclamationCircle, FaChartPie, FaGraduationCap, FaRegQuestionCircle, FaVideo, FaCircle, FaRedo, FaUpload, FaDownload } from 'react-icons/fa';
9
9
  import { Icon, addCollection } from '@iconify/react';
10
- import { Tooltip, UnstyledButton, Menu, Text, Button, Box, Badge, Alert, Tabs, Accordion, Stack, Group, Drawer, CopyButton, LoadingOverlay, factory, useProps, useMantineTheme, getStyleObject, Paper, Checkbox, SegmentedControl, Loader, Grid, Card, Table, ColorSwatch, Modal, Switch, Divider, Autocomplete, TextInput, Title, Avatar, Select, Textarea, FileButton, Anchor, ThemeIcon, ActionIcon, NumberInput, RangeSlider, MultiSelect, Center, Flex, ScrollArea, rem, MantineProvider, createTheme, Highlight, List } from '@mantine/core';
10
+ import { Tooltip, UnstyledButton, Menu, Text, Button, Box, Badge, Alert, Tabs, Accordion, Stack, Group, Drawer, CopyButton, LoadingOverlay, factory, useProps, useMantineTheme, getStyleObject, Paper, Checkbox, SegmentedControl, Loader, Grid, Card, Table, ColorSwatch, Modal, Switch, Divider, Autocomplete, TextInput, Title, Avatar, ThemeIcon, Select, Textarea, FileButton, Anchor, ActionIcon, NumberInput, RangeSlider, MultiSelect, Center, Transition, rem, Stepper, Image as Image$1, NavLink, Flex, ScrollArea, MantineProvider, createTheme, Highlight, List, FileInput } from '@mantine/core';
11
11
  import { useRouter } from 'next/router';
12
12
  import { usePathname } from 'next/navigation';
13
- import { MdLogin, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdClose, MdInfo, MdExpandLess, MdExpandMore, MdFlip, MdAddCircle, MdRemoveCircle, MdOutlineArrowBack, MdOutlineArrowForward, MdOutlineArrowBackIos, MdOutlineArrowForwardIos, MdKeyboardArrowDown, MdKeyboardArrowUp, MdDownload, MdFormatQuote, MdOutlineSearch, MdOutlineBarChart, MdGroup, MdDelete } from 'react-icons/md';
14
- import { useCoreDispatch, useLazyFetchUserDetailsQuery, useCoreSelector, selectUserAuthStatus, GEN3_REDIRECT_URL, showModal, Modals, GEN3_FENCE_API, isAuthenticated, selectUserDetails, useIsUserLoggedIn, fieldNameToTitle, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, useUserAuth, useGetAuthzMappingsQuery, useGetLoginProvidersQuery, hideModal, useGetCSRFQuery, selectCurrentModal, updateCohortFilter, selectIndexedFilterByName, isOperationWithField, removeCohortFilter, trimFirstFieldNameToTitle, selectCohortFilters, handleOperation, selectCurrentCohortId, clearCohortFilters, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, useGetAggsQuery, extractEnumFilterValue, useGetCountsQuery, selectHeadersWithCSRFToken, GEN3_GUPPY_API, GEN3_COMMONS_NAME, createAppStore, createGen3AppWithOwnStore, createAppApiForRTKQ, getGen3AppId, CoreProvider, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetExternalLoginsQuery, useGetDictionaryQuery, useGetProjectsDetailsQuery, useGetSubmissionsQuery, useLazyGetCrosswalkDataQuery } from '@gen3/core';
13
+ import { MdLogin, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdClose, MdInfo, MdExpandLess, MdExpandMore, MdFlip, MdAddCircle, MdRemoveCircle, MdOutlineArrowBack, MdOutlineArrowForward, MdKeyboardArrowDown, MdKeyboardArrowUp, MdDownload, MdFormatQuote, MdOutlineSearch, MdOutlineBarChart, MdGroup, MdDelete } from 'react-icons/md';
14
+ import { useGetWorkspaceStatusQuery, useTerminateWorkspaceMutation, useCoreSelector, selectRequestedWorkspaceStatus, useCoreDispatch, WorkspaceStatus, setActiveWorkspaceStatus, setRequestedWorkspaceStatus, useLazyFetchUserDetailsQuery, selectUserAuthStatus, GEN3_REDIRECT_URL, showModal, Modals, GEN3_FENCE_API, isAuthenticated, selectUserDetails, useIsUserLoggedIn, fieldNameToTitle, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, useUserAuth, useGetAuthzMappingsQuery, useGetLoginProvidersQuery, hideModal, useGetCSRFQuery, selectCurrentModal, updateCohortFilter, selectIndexedFilterByName, isOperationWithField, removeCohortFilter, trimFirstFieldNameToTitle, selectCohortFilters, handleOperation, selectCurrentCohortId, setCohortFilter, clearCohortFilters, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, useGetAggsQuery, extractEnumFilterValue, useGetCountsQuery, selectHeadersWithCSRFToken, GEN3_GUPPY_API, useLaunchWorkspaceMutation, useGetWorkspacePayModelsQuery, selectActiveWorkspaceStatus, isFetchBaseQueryError, setActiveWorkspace, selectWorkspaceStatusFromService, selectActiveWorkspaceId, useGetWorkspaceOptionsQuery, GEN3_WORKSPACE_API, useGetExternalLoginsQuery, isWorkspaceRunningOrStopping, useSetCurrentPayModelMutation, PodStatus, PodConditionType, GEN3_COMMONS_NAME, createAppStore, createGen3AppWithOwnStore, createAppApiForRTKQ, getGen3AppId, CoreProvider, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetDictionaryQuery, useGetProjectsDetailsQuery, useGetSubmissionsQuery, useLazyGetCrosswalkDataQuery } from '@gen3/core';
15
15
  import { useDeepCompareEffect, useDeepCompareMemo, useDeepCompareCallback } from 'use-deep-compare';
16
16
  import 'swr';
17
17
  import { getCookie, deleteCookie, setCookie } from 'cookies-next';
18
18
  import { decodeJwt } from 'jose';
19
- import { showNotification, notifications, cleanNotifications, Notifications } from '@mantine/notifications';
19
+ import { notifications, showNotification, cleanNotifications, Notifications } from '@mantine/notifications';
20
20
  import Markdown from 'react-markdown';
21
21
  import { AiOutlineLogin } from 'react-icons/ai';
22
22
  import { PiDotsThreeCircleThin, PiTrash, PiSparkleFill, PiCaretUpFill, PiCaretDownFill, PiCaretUpDownFill, PiCaretCircleDownFill } from 'react-icons/pi';
@@ -25,7 +25,7 @@ import { useMantineReactTable, MantineReactTable } from 'mantine-react-table';
25
25
  import { JSONPath } from 'jsonpath-plus';
26
26
  import { LuClock, LuCircleSlash, LuUnlock, LuLock, LuRefreshCw } from 'react-icons/lu';
27
27
  import tinycolor from 'tinycolor2';
28
- import { useDisclosure, useDidUpdate, mergeRefs, useReducedMotion, useResizeObserver, useElementSize, useClipboard, useMediaQuery, useLocalStorage, useScrollIntoView } from '@mantine/hooks';
28
+ import { useDisclosure, useDidUpdate, mergeRefs, useReducedMotion, useResizeObserver, useElementSize, useClipboard, useMediaQuery, useFullscreen, useLocalStorage, useScrollIntoView } from '@mantine/hooks';
29
29
  import { FiDownload, FiMoreVertical } from 'react-icons/fi';
30
30
  import { TiArrowUnsorted, TiArrowSortedUp, TiArrowSortedDown } from 'react-icons/ti';
31
31
  import { flushSync } from 'react-dom';
@@ -36,15 +36,17 @@ import MiniSearch from 'minisearch';
36
36
  import uniq from 'lodash/uniq';
37
37
  import sum from 'lodash/sum';
38
38
  import remarkGfm from 'remark-gfm';
39
+ import { IconAlertTriangle } from '@tabler/icons-react';
39
40
  import { useCookies } from 'react-cookie';
40
41
  import FileSaver from 'file-saver';
41
42
  import { defaultComposer } from 'default-composer';
42
- import { BsExclamationTriangle } from 'react-icons/bs';
43
43
  import tw from 'tailwind-styled-components';
44
44
  import 'universal-cookie';
45
45
  import { RiCloseCircleLine } from 'react-icons/ri';
46
46
  import { IoMdArrowDropdown, IoMdRefresh, IoMdLogIn } from 'react-icons/io';
47
47
  import GraphiQL from 'graphiql';
48
+ import { modals, ModalsProvider } from '@mantine/modals';
49
+ import { BsArrowsFullscreen } from 'react-icons/bs';
48
50
  import fs from 'fs';
49
51
  import path from 'path';
50
52
  import { PersistGate } from 'redux-persist/integration/react';
@@ -52,11 +54,11 @@ import { persistReducer, persistStore } from 'redux-persist';
52
54
  import { combineReducers } from 'redux';
53
55
  import storage from 'redux-persist/lib/storage';
54
56
  import { createSlice } from '@reduxjs/toolkit';
55
- import { ModalsProvider } from '@mantine/modals';
56
57
  import dynamic from 'next/dynamic';
57
58
  import { useForm } from '@mantine/form';
58
59
  import YAML from 'yaml';
59
60
  import { filesize } from 'filesize';
61
+ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
60
62
  import plugin from 'tailwindcss/plugin';
61
63
  import cookie from 'cookie';
62
64
 
@@ -358,6 +360,107 @@ const useManageSession = (userStatus)=>{
358
360
  return session;
359
361
  };
360
362
 
363
+ const WorkspacePollingInterval = {
364
+ 'Not Found': 0,
365
+ Launching: 5000,
366
+ Terminating: 5000,
367
+ Running: 300000,
368
+ Stopped: 5000,
369
+ Errored: 10000,
370
+ 'Status Error': 0
371
+ };
372
+ const workspaceShutdownAlertLimit = 30000; // 5 minutes: 5 * 60 * 1000 TODO Figure how to configure this
373
+ /**
374
+ * Monitors resource usage.
375
+ * Currently, handles workspace, payment and idle status
376
+ */ const useResourceMonitor = ()=>{
377
+ const [pollingInterval, setPollingInterval] = useState(0);
378
+ const { data: workspaceStatusData, isError: isWorkspaceStatusError, isSuccess: isWorkspaceStatusSuccess, refetch } = useGetWorkspaceStatusQuery(undefined, {
379
+ pollingInterval: pollingInterval,
380
+ refetchOnMountOrArgChange: 1800,
381
+ refetchOnFocus: true
382
+ });
383
+ const [terminateWorkspace] = useTerminateWorkspaceMutation();
384
+ const requestedStatus = useCoreSelector(selectRequestedWorkspaceStatus);
385
+ const dispatch = useCoreDispatch();
386
+ useDeepCompareEffect(()=>{
387
+ if (requestedStatus === 'Launching') {
388
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.Launching]);
389
+ refetch();
390
+ }
391
+ if (requestedStatus === 'Terminating') {
392
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.Terminating]);
393
+ }
394
+ }, [
395
+ requestedStatus
396
+ ]);
397
+ useDeepCompareEffect(()=>{
398
+ if (!workspaceStatusData) return;
399
+ if (isWorkspaceStatusError) {
400
+ dispatch(setActiveWorkspaceStatus(WorkspaceStatus.StatusError));
401
+ setPollingInterval(0); // stop polling
402
+ }
403
+ if (workspaceStatusData.status === WorkspaceStatus.Running) {
404
+ // in some state other than idle
405
+ if (!workspaceStatusData.idleTimeLimit || workspaceStatusData.idleTimeLimit < 0) {
406
+ // Do not need to poll
407
+ dispatch(setActiveWorkspaceStatus(workspaceStatusData.status));
408
+ setPollingInterval(0);
409
+ return;
410
+ }
411
+ if (workspaceStatusData?.idleTimeLimit && workspaceStatusData.idleTimeLimit > 0 && workspaceStatusData.lastActivityTime > 0) {
412
+ const remainingWorkspaceKernelLife = workspaceStatusData.idleTimeLimit - (Date.now() - workspaceStatusData.lastActivityTime);
413
+ if (remainingWorkspaceKernelLife <= 0) {
414
+ // kernel has died due to inactivity
415
+ terminateWorkspace();
416
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.Terminating]);
417
+ dispatch(setActiveWorkspaceStatus(WorkspaceStatus.Terminating));
418
+ notifications.show({
419
+ title: 'Workspace Shutdown',
420
+ message: 'Workspace has been idle for too long. Shutting workspace down',
421
+ position: 'top-center'
422
+ });
423
+ return;
424
+ }
425
+ if (remainingWorkspaceKernelLife <= workspaceShutdownAlertLimit) {
426
+ // TODO change running refresh to handle this
427
+ notifications.show({
428
+ title: 'Workspace Warning',
429
+ message: 'Workspace has been idle for too long. Will shutdown soon',
430
+ position: 'top-center'
431
+ });
432
+ }
433
+ }
434
+ if (requestedStatus === 'Launching') {
435
+ dispatch(setRequestedWorkspaceStatus('NotSet'));
436
+ }
437
+ if (requestedStatus === 'Terminating') {
438
+ refetch();
439
+ return;
440
+ }
441
+ dispatch(setActiveWorkspaceStatus(workspaceStatusData.status));
442
+ setPollingInterval(WorkspacePollingInterval[workspaceStatusData.status]);
443
+ return;
444
+ }
445
+ if (workspaceStatusData.status === WorkspaceStatus.NotFound) {
446
+ if (requestedStatus !== 'Launching') {
447
+ // need to consider that if in launchState might get a number of NotFound status before Launching
448
+ setPollingInterval(WorkspacePollingInterval[WorkspaceStatus.NotFound]);
449
+ dispatch(setActiveWorkspaceStatus(WorkspaceStatus.NotFound));
450
+ }
451
+ if (requestedStatus === 'Terminating') dispatch(setRequestedWorkspaceStatus('NotSet'));
452
+ return;
453
+ }
454
+ dispatch(setActiveWorkspaceStatus(workspaceStatusData.status));
455
+ setPollingInterval(WorkspacePollingInterval[workspaceStatusData.status]);
456
+ }, [
457
+ dispatch,
458
+ workspaceStatusData,
459
+ isWorkspaceStatusError,
460
+ requestedStatus
461
+ ]);
462
+ };
463
+
361
464
  const MinutesToMilliseconds = (minutes)=>minutes * 60 * 1000;
362
465
  const logoutSession = async ()=>{
363
466
  await fetch(`${GEN3_FENCE_API}/user/logout?next=${GEN3_REDIRECT_URL}/`, {
@@ -432,6 +535,7 @@ const UPDATE_SESSION_LIMIT = MinutesToMilliseconds(5);
432
535
  */ const SessionProvider = ({ children, session, updateSessionTime = 5, inactiveTimeLimit = 20, workspaceInactivityTimeLimit = 0, logoutInactiveUsers = true })=>{
433
536
  const router = useRouter();
434
537
  const coreDispatch = useCoreDispatch();
538
+ useResourceMonitor();
435
539
  const [getUserDetails] = useLazyFetchUserDetailsQuery(); // Fetch user details
436
540
  const userStatus = useCoreSelector((state)=>selectUserAuthStatus(state));
437
541
  const [mostRecentActivityTimestamp, setMostRecentActivityTimestamp] = useState(Date.now());
@@ -480,14 +584,14 @@ const UPDATE_SESSION_LIMIT = MinutesToMilliseconds(5);
480
584
  if (isUserOnPage('Login')) return;
481
585
  const timeSinceLastActivity = Date.now() - mostRecentActivityTimestamp;
482
586
  if (logoutInactiveUsers) {
483
- if (timeSinceLastActivity >= inactiveTimeLimitMilliseconds && !isUserOnPage('workspace')) {
587
+ if (timeSinceLastActivity >= inactiveTimeLimitMilliseconds && !isUserOnPage('Workspace')) {
484
588
  coreDispatch(showModal({
485
589
  modal: Modals.SessionExpireModal
486
590
  }));
487
591
  endSession();
488
592
  return;
489
593
  }
490
- if (workspaceInactivityTimeLimitMilliseconds > 0 && timeSinceLastActivity >= workspaceInactivityTimeLimitMilliseconds && isUserOnPage('workspace')) {
594
+ if (workspaceInactivityTimeLimitMilliseconds > 0 && timeSinceLastActivity >= workspaceInactivityTimeLimitMilliseconds && isUserOnPage('Workspace')) {
491
595
  coreDispatch(showModal({
492
596
  modal: Modals.SessionExpireModal
493
597
  }));
@@ -658,7 +762,7 @@ const TopBar = ({ items, loginButtonVisibility = LoginButtonVisibility.Hidden, c
658
762
  className: "flex items-center align-middle",
659
763
  children: [
660
764
  processTopBarItems(items, loginButtonVisibility === LoginButtonVisibility.Visible),
661
- loginButtonVisibility != LoginButtonVisibility.Visible ? /*#__PURE__*/ jsx(LoginAccountButton, {}) : null,
765
+ loginButtonVisibility != LoginButtonVisibility.Hidden ? /*#__PURE__*/ jsx(LoginAccountButton, {}) : null,
662
766
  loginButtonVisibility != LoginButtonVisibility.Hidden ? /*#__PURE__*/ jsx(LoginButton, {
663
767
  visibility: loginButtonVisibility
664
768
  }) : null
@@ -1196,8 +1300,8 @@ class DiscoveryCellRendererFactory {
1196
1300
  DiscoveryCellRendererFactory.getInstance().cellRendererCatalog[type][functionName] = func;
1197
1301
  }
1198
1302
  static registerCellRendererCatalog(catalog) {
1199
- Object.keys(catalog).map((type)=>{
1200
- Object.entries(catalog[type]).map(([name, func])=>{
1303
+ Object.keys(catalog).forEach((type)=>{
1304
+ Object.entries(catalog[type]).forEach(([name, func])=>{
1201
1305
  DiscoveryCellRendererFactory.registerCellRenderer(type, name, func);
1202
1306
  });
1203
1307
  });
@@ -1269,8 +1373,8 @@ class DiscoveryRowRendererFactory {
1269
1373
  DiscoveryRowRendererFactory.getInstance().RowRendererCatalog[type][functionName] = func;
1270
1374
  }
1271
1375
  static registerRowRendererCatalog(catalog) {
1272
- Object.keys(catalog).map((type)=>{
1273
- Object.entries(catalog[type]).map(([name, func])=>{
1376
+ Object.keys(catalog).forEach((type)=>{
1377
+ Object.entries(catalog[type]).forEach(([name, func])=>{
1274
1378
  DiscoveryRowRendererFactory.registerRowRenderer(type, name, func);
1275
1379
  });
1276
1380
  });
@@ -1635,11 +1739,11 @@ const RenderYearOfBirthRestricted = ({ value }, params)=>{
1635
1739
  }
1636
1740
  // Check if the content is a string and represents a year less than 1935
1637
1741
  let displayContent;
1638
- if (typeof content === 'string' && !isNaN(Number(content)) && Number(content) < 1935) {
1742
+ if (typeof content === 'string' && !Number.isNaN(Number(content)) && Number(content) < 1935) {
1639
1743
  displayContent = '1935';
1640
1744
  } else if (isArray(content)) {
1641
1745
  displayContent = content.map((item)=>{
1642
- if (typeof item === 'string' && !isNaN(Number(item)) && Number(item) < 1935) {
1746
+ if (typeof item === 'string' && !Number.isNaN(Number(item)) && Number(item) < 1935) {
1643
1747
  return '1935';
1644
1748
  }
1645
1749
  return item;
@@ -3015,6 +3119,7 @@ class RenderFactoryTypedInstance {
3015
3119
  }
3016
3120
  getRenderer(type, functionName) {
3017
3121
  if (!this.rendererExists(type, functionName)) {
3122
+ console.warn('[RenderFactory] Renderer function not found for type: ', type, ' and function name: ', functionName, '. Using default renderer instead.');
3018
3123
  return DefaultItemRenderer;
3019
3124
  }
3020
3125
  return this.catalog[type][functionName];
@@ -5608,6 +5713,51 @@ const useResourcesContext = ()=>{
5608
5713
  });
5609
5714
  };
5610
5715
 
5716
+ const CardContainer = ({ children })=>/*#__PURE__*/ jsx("div", {
5717
+ className: "flex justify-center pt-2 items-center",
5718
+ children: /*#__PURE__*/ jsx(Card, {
5719
+ shadow: "sm",
5720
+ p: "md",
5721
+ className: "bg-base-lightest border-2 border-base-lighter",
5722
+ children: /*#__PURE__*/ jsx(Group, {
5723
+ align: "center",
5724
+ wrap: "nowrap",
5725
+ children: children
5726
+ })
5727
+ })
5728
+ });
5729
+
5730
+ const MessageText = ({ message, color })=>/*#__PURE__*/ jsx(Text, {
5731
+ c: color,
5732
+ size: "md",
5733
+ fw: 500,
5734
+ children: message
5735
+ });
5736
+ const MessageCard = ({ message, icon, size = 'lg', color = 'utility.5' })=>/*#__PURE__*/ jsxs(CardContainer, {
5737
+ children: [
5738
+ /*#__PURE__*/ jsx(ThemeIcon, {
5739
+ color: color,
5740
+ variant: "outline",
5741
+ radius: "xl",
5742
+ size: size,
5743
+ children: icon
5744
+ }),
5745
+ /*#__PURE__*/ jsx(MessageText, {
5746
+ message: message,
5747
+ color: color
5748
+ }),
5749
+ ' '
5750
+ ]
5751
+ });
5752
+
5753
+ const ErrorCard = ({ message })=>/*#__PURE__*/ jsx(MessageCard, {
5754
+ message: message,
5755
+ icon: /*#__PURE__*/ jsx(IconAlertTriangle, {
5756
+ size: 24
5757
+ }),
5758
+ color: "utility.3"
5759
+ });
5760
+
5611
5761
  const LoginProviderMultipleItems = ({ provider, handleLoginSelected })=>{
5612
5762
  const [value, setValue] = useState(null);
5613
5763
  return /*#__PURE__*/ jsxs("div", {
@@ -5650,7 +5800,12 @@ const LoginProviderSingleItem = ({ provider, handleLoginSelected })=>{
5650
5800
  }, provider.name);
5651
5801
  };
5652
5802
  const LoginProvidersPanel = ({ handleLoginSelected })=>{
5653
- const { data, isSuccess } = useGetLoginProvidersQuery();
5803
+ const { data, isSuccess, isError } = useGetLoginProvidersQuery();
5804
+ if (isError) {
5805
+ return /*#__PURE__*/ jsx(ErrorCard, {
5806
+ message: 'request to authentication service failed'
5807
+ });
5808
+ }
5654
5809
  if (!isSuccess) {
5655
5810
  return /*#__PURE__*/ jsx(LoadingOverlay, {
5656
5811
  visible: !isSuccess
@@ -5695,6 +5850,7 @@ const CredentialsLogin = ({ handleLogin })=>{
5695
5850
  const sessionContext = useContext(SessionContext);
5696
5851
  const [credentials, setCredentials] = useState(null);
5697
5852
  const [file, setFile] = useState(null);
5853
+ const [isCredentialsPending, setIsCredentialsPending] = useState(false);
5698
5854
  useEffect(()=>{
5699
5855
  if (file) {
5700
5856
  const reader = new FileReader();
@@ -5707,8 +5863,10 @@ const CredentialsLogin = ({ handleLogin })=>{
5707
5863
  file
5708
5864
  ]);
5709
5865
  const handleCredentialsLogin = useCallback(async (credentials)=>{
5866
+ setIsCredentialsPending(true);
5710
5867
  const updateSession = sessionContext?.updateSession ?? (()=>null);
5711
5868
  try {
5869
+ // setIsCredentialsPending(true);
5712
5870
  const json = await JSON.parse(credentials);
5713
5871
  await fetch('/api/auth/credentialsLogin', {
5714
5872
  method: 'POST',
@@ -5724,6 +5882,8 @@ const CredentialsLogin = ({ handleLogin })=>{
5724
5882
  title: 'Format Error',
5725
5883
  message: 'JSON is not valid'
5726
5884
  });
5885
+ } finally{
5886
+ setIsCredentialsPending(false); // Set loading to false once fetch is done (success or fail)
5727
5887
  }
5728
5888
  }, [
5729
5889
  handleLogin,
@@ -5771,6 +5931,7 @@ const CredentialsLogin = ({ handleLogin })=>{
5771
5931
  }),
5772
5932
  /*#__PURE__*/ jsx(Button, {
5773
5933
  color: "blue",
5934
+ loading: isCredentialsPending,
5774
5935
  onClick: async ()=>{
5775
5936
  await handleCredentialsLogin(credentials ?? '');
5776
5937
  },
@@ -5926,7 +6087,13 @@ const LoginPanel = (loginConfig)=>{
5926
6087
  router
5927
6088
  ]);
5928
6089
  const handleCredentialsLogin = useCallback(async ()=>{
5929
- await router.push(filterRedirect(referer));
6090
+ const redirect = !referer ? '/' : isArray(referer) ? referer[0] : referer;
6091
+ router.push(redirect).catch((e)=>{
6092
+ showNotification({
6093
+ title: 'Login Error',
6094
+ message: `error logging in ${e.message}`
6095
+ });
6096
+ });
5930
6097
  }, [
5931
6098
  referer,
5932
6099
  router
@@ -6354,44 +6521,6 @@ const Gen3ModalsProvider = ({ config, children })=>{
6354
6521
  });
6355
6522
  };
6356
6523
 
6357
- const ErrorMessage = ({ message })=>/*#__PURE__*/ jsx(Text, {
6358
- color: "utility.4",
6359
- size: "md",
6360
- fw: "md",
6361
- children: message
6362
- });
6363
- const CardContainer = ({ children })=>/*#__PURE__*/ jsx("div", {
6364
- className: "flex justify-center pt-10 items-center",
6365
- children: /*#__PURE__*/ jsx(Card, {
6366
- shadow: "sm",
6367
- p: "lg",
6368
- className: "bg-base-lightest border-2 border-base-lighter",
6369
- children: /*#__PURE__*/ jsxs(Group, {
6370
- align: "center",
6371
- children: [
6372
- /*#__PURE__*/ jsx(ThemeIcon, {
6373
- color: "utility.4",
6374
- variant: "outline",
6375
- radius: "xl",
6376
- size: "lg",
6377
- children: /*#__PURE__*/ jsx(BsExclamationTriangle, {
6378
- size: 24
6379
- })
6380
- }),
6381
- children
6382
- ]
6383
- })
6384
- })
6385
- });
6386
- const ErrorCard = ({ message })=>/*#__PURE__*/ jsxs(CardContainer, {
6387
- children: [
6388
- /*#__PURE__*/ jsx(ErrorMessage, {
6389
- message: message
6390
- }),
6391
- ' '
6392
- ]
6393
- });
6394
-
6395
6524
  const getAllFieldsFromFilterConfigs = (filterTabConfigs)=>filterTabConfigs.reduce((acc, cur)=>acc.concat(cur.fields), []);
6396
6525
  const processBucketData = (data)=>{
6397
6526
  if (!data) return {};
@@ -8211,20 +8340,133 @@ const convertFilterToComponent = (filter, index, path = '.')=>{
8211
8340
  };
8212
8341
 
8213
8342
  const getCombinedClassesExpandCollapseQuery = (allQueryExpressionsCollapsed)=>{
8214
- const baseClasses = 'flex gap-0 items-center border-1 border-base-max rounded-md w-7 h-7';
8343
+ const baseClasses = 'flex gap-0 items-center border-1 border-base-max rounded-md';
8215
8344
  const dynamicClasses = allQueryExpressionsCollapsed ? 'text-primary bg-base-max' : 'text-base-max bg-transparent';
8216
8345
  const disabledClasses = 'disabled:opacity-50';
8217
8346
  const enabledHoverClasses = 'enabled:hover:bg-primary-darkest enabled:hover:text-primary-content-lightest enabled:hover:border-primary-darkest';
8218
8347
  return `${dynamicClasses} ${disabledClasses} ${enabledHoverClasses} ${baseClasses}`;
8219
8348
  };
8220
8349
  const getCombinedClassesForRowCollapse = (filtersSectionCollapsed)=>{
8221
- const baseClasses = 'border-1 border-white rounded-md w-7 h-7 flex items-center';
8350
+ const baseClasses = 'border-1 border-white rounded-md flex items-center';
8222
8351
  const dynamicClasses = !filtersSectionCollapsed ? 'text-primary bg-base-max' : 'text-base-max bg-transparent';
8223
8352
  const disabledClasses = 'disabled:opacity-50 disabled:bg-base-max disabled:text-primary';
8224
8353
  const enabledHoverClasses = 'enabled:hover:bg-primary-darkest enabled:hover:text-primary-content-lightest enabled:hover:border-primary-darkest';
8225
8354
  return `${disabledClasses} ${enabledHoverClasses} ${baseClasses} ${dynamicClasses}`;
8226
8355
  };
8227
8356
 
8357
+ const JSONObjectDownloadButton = ({ getData, filename = 'data.json', icon = 'gen3:download', tooltip })=>{
8358
+ const [isDownloading, setIsDownloading] = useState(false);
8359
+ const saveToJSONFile = async ()=>{
8360
+ setIsDownloading(true);
8361
+ try {
8362
+ const data = getData();
8363
+ // Create blob from JSON data
8364
+ const blob = new Blob([
8365
+ JSON.stringify(data, null, 2)
8366
+ ], {
8367
+ type: 'application/json'
8368
+ });
8369
+ // Create URL for the blob
8370
+ const url = URL.createObjectURL(blob);
8371
+ // Create temporary link element
8372
+ const link = document.createElement('a');
8373
+ link.href = url;
8374
+ link.download = filename;
8375
+ // Append to document, click, and cleanup
8376
+ document.body.appendChild(link);
8377
+ link.click();
8378
+ document.body.removeChild(link);
8379
+ URL.revokeObjectURL(url);
8380
+ } catch (error) {
8381
+ console.error('Error saving file:', error);
8382
+ } finally{
8383
+ setIsDownloading(false);
8384
+ }
8385
+ };
8386
+ return /*#__PURE__*/ jsx(Tooltip, {
8387
+ label: tooltip,
8388
+ disabled: !tooltip,
8389
+ children: /*#__PURE__*/ jsx(Button, {
8390
+ variant: "outline",
8391
+ onClick: saveToJSONFile,
8392
+ disabled: isDownloading,
8393
+ loading: isDownloading,
8394
+ classNames: {
8395
+ root: 'bg-base-max'
8396
+ },
8397
+ className: "flex items-center gap-2",
8398
+ children: /*#__PURE__*/ jsx(Icon, {
8399
+ icon: icon,
8400
+ height: "1.5rem"
8401
+ })
8402
+ })
8403
+ });
8404
+ };
8405
+
8406
+ const UploadJSONButton = ({ handleFileChange, tooltip, icon = 'gen3:upload' })=>{
8407
+ const [file, setFile] = useState(null);
8408
+ const [processingFile, setProcessingFile] = useState(false);
8409
+ return /*#__PURE__*/ jsx(FileButton, {
8410
+ onChange: async (file)=>{
8411
+ if (file !== null) {
8412
+ setProcessingFile(true);
8413
+ setFile(file);
8414
+ const contents = await file.text();
8415
+ handleFileChange(contents);
8416
+ setProcessingFile(false);
8417
+ }
8418
+ },
8419
+ accept: "application/json",
8420
+ children: ()=>/*#__PURE__*/ jsx(Tooltip, {
8421
+ label: tooltip,
8422
+ disabled: !tooltip,
8423
+ children: /*#__PURE__*/ jsx(Button, {
8424
+ loading: processingFile,
8425
+ variant: "outline",
8426
+ classNames: {
8427
+ root: 'bg-base-max'
8428
+ },
8429
+ children: /*#__PURE__*/ jsx(Icon, {
8430
+ icon: icon,
8431
+ height: "1.5rem"
8432
+ })
8433
+ })
8434
+ })
8435
+ });
8436
+ };
8437
+
8438
+ const CohortSelector = ({ index, filters })=>{
8439
+ const dispatch = useCoreDispatch();
8440
+ const getData = useDeepCompareCallback(()=>{
8441
+ return filters;
8442
+ }, [
8443
+ filters
8444
+ ]);
8445
+ const setCohort = useDeepCompareCallback((data)=>{
8446
+ const jsonForm = JSON.parse(data);
8447
+ dispatch(setCohortFilter({
8448
+ index,
8449
+ filters: jsonForm
8450
+ }));
8451
+ }, [
8452
+ index,
8453
+ dispatch
8454
+ ]);
8455
+ return /*#__PURE__*/ jsxs(Group, {
8456
+ children: [
8457
+ /*#__PURE__*/ jsx(JSONObjectDownloadButton, {
8458
+ getData: getData,
8459
+ filename: "cohort.json",
8460
+ tooltip: "Export Cohort"
8461
+ }),
8462
+ /*#__PURE__*/ jsx(UploadJSONButton, {
8463
+ handleFileChange: setCohort,
8464
+ tooltip: "Import Cohort"
8465
+ })
8466
+ ]
8467
+ });
8468
+ };
8469
+
8228
8470
  const QueryExpressionContainer = tw.div`
8229
8471
  flex
8230
8472
  items-center
@@ -8377,9 +8619,13 @@ const QueryExpressionSection = ({ index, filters, currentCohortName, currentCoho
8377
8619
  /*#__PURE__*/ jsxs("div", {
8378
8620
  className: "display flex gap-2 ml-auto mr-3",
8379
8621
  children: [
8622
+ /*#__PURE__*/ jsx(CohortSelector, {
8623
+ index: index,
8624
+ filters: filters
8625
+ }),
8380
8626
  /*#__PURE__*/ jsx(Tooltip, {
8381
8627
  label: noFilters ? 'No values to expand/collapse' : allQueryExpressionsCollapsed ? 'Expand all values' : 'Collapse all values',
8382
- children: /*#__PURE__*/ jsx("button", {
8628
+ children: /*#__PURE__*/ jsx(Button, {
8383
8629
  "data-testid": "button-expand-collapse-cohort-queries",
8384
8630
  color: "white",
8385
8631
  onClick: ()=>allQueryExpressionsCollapsed ? setExpandedState({
@@ -8393,34 +8639,22 @@ const QueryExpressionSection = ({ index, filters, currentCohortName, currentCoho
8393
8639
  "aria-expanded": !allQueryExpressionsCollapsed,
8394
8640
  className: getCombinedClassesExpandCollapseQuery(allQueryExpressionsCollapsed),
8395
8641
  disabled: noFilters,
8396
- children: allQueryExpressionsCollapsed ? /*#__PURE__*/ jsxs(React__default.Fragment, {
8397
- children: [
8398
- /*#__PURE__*/ jsx(MdOutlineArrowBackIos, {
8399
- size: 16,
8400
- "aria-hidden": "true"
8401
- }),
8402
- /*#__PURE__*/ jsx(MdOutlineArrowForwardIos, {
8403
- size: 16,
8404
- "aria-hidden": "true"
8405
- })
8406
- ]
8407
- }) : /*#__PURE__*/ jsxs(React__default.Fragment, {
8408
- children: [
8409
- /*#__PURE__*/ jsx(MdOutlineArrowForwardIos, {
8410
- size: 16,
8411
- "aria-hidden": "true"
8412
- }),
8413
- /*#__PURE__*/ jsx(MdOutlineArrowBackIos, {
8414
- size: 16,
8415
- "aria-hidden": "true"
8416
- })
8417
- ]
8642
+ children: allQueryExpressionsCollapsed ? /*#__PURE__*/ jsx(Icon, {
8643
+ icon: "gen3:chevron-expand",
8644
+ "aria-hidden": "true",
8645
+ height: "1.5rem",
8646
+ children: ' '
8647
+ }) : /*#__PURE__*/ jsx(Icon, {
8648
+ icon: "gen3:chevron-contract",
8649
+ "aria-hidden": "true",
8650
+ height: "1.5rem",
8651
+ children: ' '
8418
8652
  })
8419
8653
  })
8420
8654
  }),
8421
8655
  /*#__PURE__*/ jsx(Tooltip, {
8422
8656
  label: noFilters || filtersRef.current != null && filtersRef?.current?.scrollHeight <= MAX_HEIGHT_QE_SECTION ? 'All rows are already displayed' : filtersSectionCollapsed ? 'Display all rows' : 'Display fewer rows',
8423
- children: /*#__PURE__*/ jsx("button", {
8657
+ children: /*#__PURE__*/ jsx(Button, {
8424
8658
  "data-testid": "button-expand-collapse-cohort-filters-section",
8425
8659
  color: "white",
8426
8660
  onClick: ()=>setFiltersSectionCollapsed(!filtersSectionCollapsed),
@@ -9932,78 +10166,1102 @@ var GqlQueryEditor$2 = /*#__PURE__*/Object.freeze({
9932
10166
  default: GqlQueryEditor$1
9933
10167
  });
9934
10168
 
9935
- const WorkspacesPanel = ()=>{
9936
- return /*#__PURE__*/ jsx(Center, {
9937
- className: "m-20 w-full",
9938
- children: /*#__PURE__*/ jsx(Text, {
9939
- size: "2rem",
9940
- children: "Coming soon."
9941
- })
9942
- });
9943
- };
9944
-
9945
- class FilesystemContent {
9946
- constructor({ rootPath }){
9947
- this.rootPath = rootPath || '';
10169
+ const ProtectedContent = ({ children, referer })=>{
10170
+ const router = useRouter();
10171
+ let redirect = referer;
10172
+ if (!referer && typeof window !== 'undefined') {
10173
+ // route not available on SSR
10174
+ redirect = router.asPath;
9948
10175
  }
9949
- async get(filepath) {
9950
- try {
9951
- return await JSON.parse(fs.readFileSync(path.join(this.rootPath, filepath)).toString('utf-8'));
9952
- } catch (err) {
9953
- throw new Error(`Cannot process ${filepath}`);
9954
- }
10176
+ const onUnauthenticated = ()=>{
10177
+ if (typeof window !== 'undefined') // route not available on SSR
10178
+ router.push({
10179
+ pathname: '/Login',
10180
+ query: {
10181
+ referer: redirect
10182
+ }
10183
+ });
10184
+ };
10185
+ const { status, pending } = useSession(true, onUnauthenticated);
10186
+ if (status !== 'issued') {
10187
+ // not logged in
10188
+ if (pending) return /*#__PURE__*/ jsx("div", {
10189
+ className: "flex justify-center w-full mt-10",
10190
+ children: /*#__PURE__*/ jsx(Loader, {})
10191
+ });
10192
+ else return /*#__PURE__*/ jsx("div", {
10193
+ className: "w-full h-full relative",
10194
+ children: /*#__PURE__*/ jsx(Center, {
10195
+ children: /*#__PURE__*/ jsx(Paper, {
10196
+ shadow: "md",
10197
+ p: "md",
10198
+ children: /*#__PURE__*/ jsx(Text, {
10199
+ children: "You are not signed in and cannot access this protected content. Please login in."
10200
+ })
10201
+ })
10202
+ })
10203
+ });
9955
10204
  }
9956
- }
10205
+ return /*#__PURE__*/ jsx(React__default.Fragment, {
10206
+ children: children
10207
+ });
10208
+ };
9957
10209
 
9958
- class ContentDatabase {
9959
- constructor(config){
9960
- this.config = config;
9961
- this.store = config.store;
10210
+ const WorkspaceConfigDefaults = {
10211
+ launchStepIndicatorConfig: {
10212
+ steps: [
10213
+ {
10214
+ label: 'Requesting',
10215
+ description: 'requesting workspace resources'
10216
+ },
10217
+ {
10218
+ label: 'Initializing',
10219
+ description: 'starting workspace resources'
10220
+ },
10221
+ {
10222
+ label: 'Configuring',
10223
+ description: 'starting services'
10224
+ },
10225
+ {
10226
+ label: 'Starting',
10227
+ description: 'waiting for services'
10228
+ },
10229
+ {
10230
+ label: 'Connecting',
10231
+ description: 'waiting for connecting to workspace'
10232
+ },
10233
+ {
10234
+ label: 'Ready',
10235
+ description: 'workspace is ready'
10236
+ }
10237
+ ]
9962
10238
  }
9963
- async get(filepath) {
9964
- return this.store.get(filepath);
10239
+ };
10240
+ const WorkspaceContext = /*#__PURE__*/ createContext(WorkspaceConfigDefaults);
10241
+ const useWorkspaceContext = ()=>{
10242
+ const context = React__default.useContext(WorkspaceContext);
10243
+ if (context === undefined) {
10244
+ throw Error('Workspace must be used inside of a useWorkspaceContext');
9965
10245
  }
9966
- }
9967
-
9968
- const GEN3_FRONTEND_CONFIGURATION_ROOT = process.env.GEN3_FRONTEND_CONFIGURATION_ROOT || './';
9969
-
9970
- const ContentRoot = GEN3_FRONTEND_CONFIGURATION_ROOT;
9971
- const setup = ()=>{
9972
- const config = {
9973
- store: new FilesystemContent({
9974
- rootPath: ContentRoot
9975
- })
10246
+ return context;
10247
+ };
10248
+ const WorkspaceProvider = ({ children, config })=>{
10249
+ const mergedConfig = {
10250
+ ...WorkspaceConfigDefaults,
10251
+ ...config
9976
10252
  };
9977
- return new ContentDatabase(config);
10253
+ return /*#__PURE__*/ jsx(WorkspaceContext.Provider, {
10254
+ value: mergedConfig,
10255
+ children: children
10256
+ });
9978
10257
  };
9979
- const ContentSource = setup();
9980
10258
 
9981
- /**
9982
- * Retrieves navigation page layout properties from configuration.
9983
- * Note: GEN3_COMMONS_NAME depends on siteConfig.json value in the data commons package
9984
- * @returns A Promise resolving to an object containing header and footer props.
9985
- */ const getNavPageLayoutPropsFromConfig = async ()=>{
9986
- const navigationConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/navigation.json`);
9987
- let bannerConfigJSON = [];
9988
- try {
9989
- bannerConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/banner.json`);
9990
- } catch (e) {
9991
- console.warn('No banner config found at: ', `config/${GEN3_COMMONS_NAME}/banner.json`);
10259
+ const getWorkspaceErrorMessage = (error, defaultMessage)=>{
10260
+ if (isFetchBaseQueryError(error)) {
10261
+ return error.data;
9992
10262
  }
9993
- const { topBar, navigation, type = 'original' } = navigationConfigJSON;
9994
- const headerProps = {
9995
- top: topBar,
9996
- navigation: navigation,
9997
- banners: bannerConfigJSON,
9998
- type
9999
- };
10000
- const footerProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/footer.json`);
10001
- return {
10002
- headerProps,
10003
- footerProps,
10004
- headerData: {
10005
- title: 'Gen3 Frontend Framework Page',
10006
- content: 'Gen3 Frontend Framework Page',
10263
+ return defaultMessage;
10264
+ };
10265
+ const WorkspaceStatusContext = /*#__PURE__*/ createContext({
10266
+ isFullscreen: false,
10267
+ startWorkspace: ()=>null,
10268
+ stopWorkspace: ()=>null,
10269
+ toggleFullscreen: ()=>null,
10270
+ workspaceLaunchIsLoading: false,
10271
+ terminateIsLoading: false,
10272
+ isPayModelNeededToLaunch: undefined
10273
+ });
10274
+ const useWorkspaceStatusContext = ()=>{
10275
+ const context = React__default.useContext(WorkspaceStatusContext);
10276
+ if (context === undefined) {
10277
+ throw Error('Any workspace status component must be used inside of a useWorkspaceStatusContext');
10278
+ }
10279
+ return context;
10280
+ };
10281
+ const WorkspaceStatusProvider = ({ children })=>{
10282
+ const { toggle: switchScreenMode, fullscreen: isFullscreen } = useFullscreen();
10283
+ const [isPayModelNeededToLaunch, setIsPayModelNeededToLaunch] = useState(undefined);
10284
+ const [launchTrigger, { isError: isWorkspaceLaunchError, error: workspaceLaunchError }] = useLaunchWorkspaceMutation();
10285
+ const [terminateWorkspace, { isLoading: terminateIsLoading, isError: isTerminateError, error: workspaceTerminateError }] = useTerminateWorkspaceMutation();
10286
+ const { data: payModels, isLoading: isPayModelLoading, isError: isPayModelError } = useGetWorkspacePayModelsQuery();
10287
+ useDeepCompareEffect(()=>{
10288
+ if (isPayModelError) {
10289
+ notifications.show({
10290
+ title: 'Pay Model Error',
10291
+ message: 'Unable to get Pay Model.'
10292
+ });
10293
+ }
10294
+ if (isPayModelLoading) {
10295
+ setIsPayModelNeededToLaunch(true);
10296
+ }
10297
+ if (payModels) {
10298
+ setIsPayModelNeededToLaunch(Object.keys(payModels).length > 0 && payModels.currentPayModel != null);
10299
+ }
10300
+ }, [
10301
+ payModels
10302
+ ]);
10303
+ const dispatch = useCoreDispatch();
10304
+ const currentWorkspaceStatus = useCoreSelector(selectActiveWorkspaceStatus);
10305
+ // handle errors in launching, getting status, or terminating
10306
+ useDeepCompareEffect(()=>{
10307
+ if (isWorkspaceLaunchError || isTerminateError) {
10308
+ notifications.show({
10309
+ title: 'Workspace Error',
10310
+ message: getWorkspaceErrorMessage(isWorkspaceLaunchError ? workspaceLaunchError : workspaceTerminateError, isWorkspaceLaunchError ? 'Error launching workspace' : 'Error stopping workspace'),
10311
+ position: 'top-center',
10312
+ containerWidth: '50%'
10313
+ });
10314
+ dispatch(setRequestedWorkspaceStatus('NotSet'));
10315
+ dispatch(setActiveWorkspaceStatus(WorkspaceStatus.NotFound));
10316
+ }
10317
+ }, [
10318
+ isWorkspaceLaunchError,
10319
+ isTerminateError
10320
+ ]);
10321
+ const status = useMemo(()=>{
10322
+ const startWorkspace = (id)=>{
10323
+ launchTrigger(id);
10324
+ dispatch(setActiveWorkspace({
10325
+ id: id,
10326
+ status: WorkspaceStatus.Launching,
10327
+ requestedStatus: 'Launching'
10328
+ }));
10329
+ };
10330
+ const toggleFullscreen = ()=>switchScreenMode();
10331
+ const stopWorkspace = ()=>{
10332
+ terminateWorkspace();
10333
+ dispatch(setRequestedWorkspaceStatus('Terminating'));
10334
+ dispatch(setActiveWorkspaceStatus(WorkspaceStatus.Terminating));
10335
+ };
10336
+ return {
10337
+ isFullscreen,
10338
+ startWorkspace,
10339
+ stopWorkspace,
10340
+ toggleFullscreen,
10341
+ workspaceLaunchIsLoading: currentWorkspaceStatus === WorkspaceStatus.Launching,
10342
+ terminateIsLoading,
10343
+ isPayModelNeededToLaunch
10344
+ };
10345
+ }, [
10346
+ dispatch,
10347
+ isFullscreen,
10348
+ launchTrigger,
10349
+ terminateIsLoading,
10350
+ terminateWorkspace
10351
+ ]);
10352
+ return /*#__PURE__*/ jsx(WorkspaceStatusContext.Provider, {
10353
+ value: status,
10354
+ children: children
10355
+ });
10356
+ };
10357
+
10358
+ const COMPUTE_PROPS_LABEL_STYLE = 'text-base-lighter font-medium text-sm opacity-90';
10359
+ const NotebookCard = ({ info })=>{
10360
+ const { startWorkspace, stopWorkspace, isPayModelNeededToLaunch } = useWorkspaceStatusContext();
10361
+ const { status } = useCoreSelector(selectWorkspaceStatusFromService);
10362
+ const requestedStatus = useCoreSelector(selectRequestedWorkspaceStatus);
10363
+ const workspaceId = useCoreSelector(selectActiveWorkspaceId);
10364
+ console.log('NotebookCard: ', requestedStatus, workspaceId, status);
10365
+ return /*#__PURE__*/ jsxs(Card, {
10366
+ withBorder: true,
10367
+ radius: "xs",
10368
+ className: "w-64",
10369
+ children: [
10370
+ /*#__PURE__*/ jsx(Card.Section, {
10371
+ inheritPadding: true,
10372
+ py: "xs",
10373
+ children: /*#__PURE__*/ jsxs(Stack, {
10374
+ align: "center",
10375
+ children: [
10376
+ /*#__PURE__*/ jsx(Icon, {
10377
+ height: '48px',
10378
+ icon: 'workspace:jupyter'
10379
+ }),
10380
+ /*#__PURE__*/ jsx(Text, {
10381
+ ta: "center",
10382
+ className: "font-header",
10383
+ size: "md",
10384
+ fw: 500,
10385
+ children: info.name
10386
+ })
10387
+ ]
10388
+ })
10389
+ }),
10390
+ /*#__PURE__*/ jsx(Card.Section, {
10391
+ inheritPadding: true,
10392
+ py: "xs",
10393
+ children: /*#__PURE__*/ jsxs(Group, {
10394
+ justify: "center",
10395
+ children: [
10396
+ /*#__PURE__*/ jsxs(Text, {
10397
+ c: "base-contrast.4",
10398
+ className: COMPUTE_PROPS_LABEL_STYLE,
10399
+ children: [
10400
+ "CPU Limit: ",
10401
+ info.cpuLimit
10402
+ ]
10403
+ }),
10404
+ /*#__PURE__*/ jsxs(Text, {
10405
+ c: "base-contrast.4",
10406
+ className: COMPUTE_PROPS_LABEL_STYLE,
10407
+ size: "xs",
10408
+ children: [
10409
+ "Memory: ",
10410
+ info.memoryLimit
10411
+ ]
10412
+ })
10413
+ ]
10414
+ })
10415
+ }),
10416
+ /*#__PURE__*/ jsx("div", {
10417
+ className: "flex mx-8 justify-center border-1 border-base"
10418
+ }),
10419
+ /*#__PURE__*/ jsxs(Group, {
10420
+ className: "mt-2 p-2",
10421
+ justify: "center",
10422
+ children: [
10423
+ /*#__PURE__*/ jsx(Button, {
10424
+ loading: info.id === workspaceId && requestedStatus === 'Launching',
10425
+ disabled: status !== WorkspaceStatus.NotFound || isPayModelNeededToLaunch,
10426
+ onClick: ()=>{
10427
+ startWorkspace(info.id);
10428
+ },
10429
+ children: "Launch"
10430
+ }),
10431
+ /*#__PURE__*/ jsx(Transition, {
10432
+ mounted: info.id === workspaceId && requestedStatus === 'Launching' || status === 'Launching',
10433
+ transition: "fade",
10434
+ duration: 400,
10435
+ timingFunction: "ease",
10436
+ children: ()=>/*#__PURE__*/ jsx(Button, {
10437
+ onClick: ()=>{
10438
+ stopWorkspace();
10439
+ },
10440
+ children: "Shutdown"
10441
+ })
10442
+ })
10443
+ ]
10444
+ })
10445
+ ]
10446
+ });
10447
+ };
10448
+
10449
+ const WorkspacePanel = ()=>{
10450
+ const { data, isLoading, isError, isSuccess } = useGetWorkspaceOptionsQuery();
10451
+ const workspaceStatus = useCoreSelector(selectActiveWorkspaceStatus);
10452
+ if (isError) {
10453
+ return /*#__PURE__*/ jsx(ErrorCard, {
10454
+ message: "Error loading workspace definitions"
10455
+ });
10456
+ }
10457
+ return /*#__PURE__*/ jsx(Fragment, {
10458
+ children: /*#__PURE__*/ jsx(Transition, {
10459
+ mounted: workspaceStatus === WorkspaceStatus.NotFound || workspaceStatus === WorkspaceStatus.Launching,
10460
+ transition: "scale-y",
10461
+ duration: 600,
10462
+ exitDuration: 600,
10463
+ timingFunction: "ease",
10464
+ children: (styles)=>/*#__PURE__*/ jsx("div", {
10465
+ className: "px-2 mt-4",
10466
+ style: styles,
10467
+ children: /*#__PURE__*/ jsx(Grid, {
10468
+ justify: "center",
10469
+ align: "stretch",
10470
+ gutter: "md",
10471
+ children: data?.map((card)=>{
10472
+ return /*#__PURE__*/ jsx(Grid.Col, {
10473
+ span: "content",
10474
+ style: {
10475
+ minHeight: rem(120)
10476
+ },
10477
+ children: /*#__PURE__*/ jsx(NotebookCard, {
10478
+ info: card
10479
+ })
10480
+ }, card.id);
10481
+ })
10482
+ })
10483
+ })
10484
+ })
10485
+ });
10486
+ };
10487
+
10488
+ const WorkspaceNotebook = ()=>{
10489
+ const currentWorkspaceStatus = useCoreSelector(selectActiveWorkspaceStatus);
10490
+ if (currentWorkspaceStatus !== WorkspaceStatus.Running) return null;
10491
+ return /*#__PURE__*/ jsx(React__default.Fragment, {
10492
+ children: /*#__PURE__*/ jsx("div", {
10493
+ className: "flex flex-col w-full flex-grow content-center items-center",
10494
+ children: /*#__PURE__*/ jsx("iframe", {
10495
+ className: "w-full h-full border-8",
10496
+ title: "Workspace",
10497
+ src: `${GEN3_WORKSPACE_API}/proxy/`
10498
+ })
10499
+ })
10500
+ });
10501
+ };
10502
+
10503
+ const ExternalLoginsStatus = ()=>{
10504
+ const { data: externalProviders, isLoading, isError, isSuccess } = useGetExternalLoginsQuery();
10505
+ if (isLoading) {
10506
+ return /*#__PURE__*/ jsx("div", {
10507
+ className: "bg-primary h-24 flex justify-center",
10508
+ children: /*#__PURE__*/ jsx(Loader, {})
10509
+ });
10510
+ }
10511
+ if (isError) {
10512
+ return /*#__PURE__*/ jsx("div", {
10513
+ children: "Error occurred while fetching external logins"
10514
+ });
10515
+ }
10516
+ if (isSuccess) {
10517
+ const providersNeedToken = externalProviders.providers.filter((option)=>!option.refresh_token_expiration);
10518
+ if (providersNeedToken.length > 0) {
10519
+ return /*#__PURE__*/ jsx("div", {
10520
+ className: "p-2 border border-base-lighter pb-4",
10521
+ children: /*#__PURE__*/ jsxs(Stack, {
10522
+ children: [
10523
+ /*#__PURE__*/ jsxs(Text, {
10524
+ children: [
10525
+ "To analyze all data to which you have access, please authorize these external data resources in the Profile page:",
10526
+ ' '
10527
+ ]
10528
+ }),
10529
+ /*#__PURE__*/ jsx(Group, {
10530
+ gap: "xs",
10531
+ children: providersNeedToken.map((provider)=>/*#__PURE__*/ jsx(Badge, {
10532
+ size: "lg",
10533
+ variant: "outline",
10534
+ radius: "sm",
10535
+ children: provider.name
10536
+ }, provider.name))
10537
+ })
10538
+ ]
10539
+ })
10540
+ });
10541
+ }
10542
+ return null;
10543
+ }
10544
+ };
10545
+
10546
+ const PaymentNumberToString = (x, undefinedValue = 'N/A', precision = 2)=>{
10547
+ if (!x || Number.isNaN(x)) return undefinedValue;
10548
+ return x.toFixed(precision);
10549
+ };
10550
+
10551
+ const StatusAndControls = ()=>{
10552
+ const { stopWorkspace, toggleFullscreen, isFullscreen } = useWorkspaceStatusContext();
10553
+ const openModal = ()=>modals.openConfirmModal({
10554
+ title: 'Workspace',
10555
+ children: /*#__PURE__*/ jsx(Text, {
10556
+ size: "sm",
10557
+ children: "Please confirm workspace shutdown"
10558
+ }),
10559
+ labels: {
10560
+ confirm: 'Confirm',
10561
+ cancel: 'Cancel'
10562
+ },
10563
+ onConfirm: ()=>stopWorkspace()
10564
+ });
10565
+ const workspaceStatus = useCoreSelector(selectActiveWorkspaceStatus);
10566
+ const requestedStatus = useCoreSelector(selectRequestedWorkspaceStatus);
10567
+ return /*#__PURE__*/ jsx(Transition, {
10568
+ mounted: isWorkspaceRunningOrStopping(workspaceStatus),
10569
+ transition: "fade",
10570
+ duration: 1200,
10571
+ timingFunction: "ease",
10572
+ children: (styles)=>/*#__PURE__*/ jsx("div", {
10573
+ style: styles,
10574
+ children: /*#__PURE__*/ jsxs(Group, {
10575
+ children: [
10576
+ /*#__PURE__*/ jsx(Icon, {
10577
+ height: '2.0rem',
10578
+ icon: 'workspace:jupyter'
10579
+ }),
10580
+ /*#__PURE__*/ jsx(Tooltip, {
10581
+ label: "Stop Workspace",
10582
+ children: /*#__PURE__*/ jsx(Button, {
10583
+ loading: requestedStatus === 'Terminating',
10584
+ size: "md",
10585
+ color: "accent.5",
10586
+ variant: "default",
10587
+ onClick: ()=>{
10588
+ openModal();
10589
+ },
10590
+ "aria-label": "Stop Workspace",
10591
+ leftSection: /*#__PURE__*/ jsx(FaRegStopCircle, {
10592
+ color: "utility.2",
10593
+ size: "1rem",
10594
+ className: "text-accent-warm"
10595
+ }),
10596
+ children: "Stop Workspace"
10597
+ })
10598
+ }),
10599
+ /*#__PURE__*/ jsx(Tooltip, {
10600
+ label: "Toggle fullscreen mode",
10601
+ children: /*#__PURE__*/ jsx(Button, {
10602
+ color: "utility.2",
10603
+ size: "md",
10604
+ variant: "default",
10605
+ onClick: ()=>{
10606
+ toggleFullscreen();
10607
+ },
10608
+ "aria-label": isFullscreen ? 'Exit Fullscreen' : 'Make Fullscreen',
10609
+ leftSection: /*#__PURE__*/ jsx(BsArrowsFullscreen, {
10610
+ className: "text-accent-warm"
10611
+ }),
10612
+ children: isFullscreen ? 'Exit Fullscreen' : 'Make Fullscreen'
10613
+ })
10614
+ })
10615
+ ]
10616
+ })
10617
+ })
10618
+ });
10619
+ };
10620
+
10621
+ const isNoPayModelError = (error)=>{
10622
+ return 'status' in error && error.status === 'PARSING_ERROR' && error.originalStatus === 404;
10623
+ };
10624
+ const NoPayModel = ()=>{
10625
+ return /*#__PURE__*/ jsxs(Group, {
10626
+ className: "p-2 border-1 border-l-0 border-r-0 border-base-lighter w-full h-16",
10627
+ justify: "space-between",
10628
+ children: [
10629
+ /*#__PURE__*/ jsx(Text, {
10630
+ className: "pl-4",
10631
+ size: "md",
10632
+ classNames: {
10633
+ root: 'font-heading'
10634
+ },
10635
+ children: "No pay model defined"
10636
+ }),
10637
+ /*#__PURE__*/ jsx(StatusAndControls, {})
10638
+ ]
10639
+ });
10640
+ };
10641
+ const PaymentPanel = ()=>{
10642
+ const { data, isLoading, isFetching, isError, error } = useGetWorkspacePayModelsQuery();
10643
+ const [setWorkspacePayModel] = useSetCurrentPayModelMutation();
10644
+ const [selectedPayModel, setSelectedPayModel] = useState(null);
10645
+ const setPayModel = useDeepCompareCallback((id)=>{
10646
+ setWorkspacePayModel(id); // triggers the call to the service to select the pay model
10647
+ setSelectedPayModel(id); // set the paymodel value for the select component
10648
+ }, [
10649
+ setWorkspacePayModel,
10650
+ selectedPayModel
10651
+ ]);
10652
+ const { usersPayModels, workspaceName, hardLimit, totalUsage } = useDeepCompareMemo(()=>{
10653
+ if (!data) return {
10654
+ usersPayModels: [],
10655
+ selectedPayModel: [],
10656
+ workspaceName: 'Not Set',
10657
+ totalUsage: undefined,
10658
+ hardLimit: undefined
10659
+ };
10660
+ const usersPayModels = data.allPayModels.map((payModel)=>{
10661
+ return {
10662
+ value: payModel.bmh_workspace_id ?? payModel.workspace_type,
10663
+ label: payModel.workspace_type,
10664
+ totalUsage: payModel['total-usage'].toFixed(2),
10665
+ icon: payModel.request_status === 'active' ? /*#__PURE__*/ jsx(FaUser, {}) : /*#__PURE__*/ jsx(FaExclamationCircle, {})
10666
+ };
10667
+ });
10668
+ setSelectedPayModel(data.currentPayModel.bmh_workspace_id ?? data.currentPayModel.workspace_type);
10669
+ return {
10670
+ usersPayModels,
10671
+ workspaceName: data.currentPayModel.bmh_workspace_id.length > 0 ? data.currentPayModel.bmh_workspace_id.length : data.currentPayModel.workspace_type,
10672
+ totalUsage: data.currentPayModel['total-usage'],
10673
+ hardLimit: data.currentPayModel['hard-limit']
10674
+ };
10675
+ }, [
10676
+ data
10677
+ ]);
10678
+ const PayModelSelectItem = ({ option })=>{
10679
+ const menuItem = usersPayModels[Number(option.value)];
10680
+ return /*#__PURE__*/ jsx("div", {
10681
+ children: /*#__PURE__*/ jsxs(Group, {
10682
+ wrap: "nowrap",
10683
+ children: [
10684
+ /*#__PURE__*/ jsx(Text, {
10685
+ size: "sm",
10686
+ children: menuItem.label
10687
+ }),
10688
+ /*#__PURE__*/ jsx(Text, {
10689
+ size: "sm",
10690
+ children: menuItem.totalUsage
10691
+ }),
10692
+ menuItem.icon
10693
+ ]
10694
+ })
10695
+ });
10696
+ };
10697
+ if (isLoading && isFetching) return /*#__PURE__*/ jsx("div", {
10698
+ className: "flex justify-center p-2 border-1 border-l-0 border-r-0 border-base-lighter w-full h-14",
10699
+ children: /*#__PURE__*/ jsx(Loader, {})
10700
+ });
10701
+ if (isError) {
10702
+ if (isNoPayModelError(error)) {
10703
+ return /*#__PURE__*/ jsx(NoPayModel, {});
10704
+ } else return /*#__PURE__*/ jsx(ErrorCard, {
10705
+ message: "Unable to get Payment information"
10706
+ });
10707
+ }
10708
+ return /*#__PURE__*/ jsx("div", {
10709
+ children: /*#__PURE__*/ jsx(Accordion, {
10710
+ chevronPosition: "left",
10711
+ children: /*#__PURE__*/ jsxs(Accordion.Item, {
10712
+ value: "accountInformation",
10713
+ children: [
10714
+ /*#__PURE__*/ jsx(Accordion.Control, {
10715
+ children: /*#__PURE__*/ jsxs(Group, {
10716
+ justify: "space-between",
10717
+ children: [
10718
+ "Account Information",
10719
+ /*#__PURE__*/ jsxs(Group, {
10720
+ className: "font-heading text-base-contrast",
10721
+ children: [
10722
+ /*#__PURE__*/ jsx(Text, {
10723
+ fw: 600,
10724
+ children: workspaceName
10725
+ }),
10726
+ /*#__PURE__*/ jsxs("div", {
10727
+ className: "flex items-center",
10728
+ children: [
10729
+ /*#__PURE__*/ jsx(Text, {
10730
+ fw: 500,
10731
+ size: "sm",
10732
+ className: "mr-1",
10733
+ children: "Total Usage:"
10734
+ }),
10735
+ /*#__PURE__*/ jsx(Text, {
10736
+ fw: 500,
10737
+ size: "sm",
10738
+ children: PaymentNumberToString(totalUsage)
10739
+ })
10740
+ ]
10741
+ }),
10742
+ /*#__PURE__*/ jsxs("div", {
10743
+ className: "flex items-center pr-1",
10744
+ children: [
10745
+ /*#__PURE__*/ jsx(Text, {
10746
+ fw: 500,
10747
+ size: "sm",
10748
+ className: "mr-1",
10749
+ children: "Hard Limit:"
10750
+ }),
10751
+ /*#__PURE__*/ jsx(Text, {
10752
+ fw: 500,
10753
+ size: "sm",
10754
+ children: PaymentNumberToString(hardLimit)
10755
+ })
10756
+ ]
10757
+ })
10758
+ ]
10759
+ })
10760
+ ]
10761
+ })
10762
+ }),
10763
+ /*#__PURE__*/ jsx(Accordion.Panel, {
10764
+ children: /*#__PURE__*/ jsxs("div", {
10765
+ className: "grid grid-cols-3 p-4",
10766
+ children: [
10767
+ /*#__PURE__*/ jsxs("div", {
10768
+ className: "flex flex-col border-1 border-gray p-2 mr-4",
10769
+ children: [
10770
+ /*#__PURE__*/ jsxs("div", {
10771
+ className: "flex justify-between border-b-1 border-gray mb-2 w-full py-2",
10772
+ children: [
10773
+ /*#__PURE__*/ jsx("div", {
10774
+ className: "ml-2 text-xs",
10775
+ children: "Account"
10776
+ }),
10777
+ /*#__PURE__*/ jsx("div", {
10778
+ className: "mr-2 text-xs",
10779
+ children: "Workspace Account Manager"
10780
+ })
10781
+ ]
10782
+ }),
10783
+ /*#__PURE__*/ jsx("div", {
10784
+ className: "text-center",
10785
+ children: /*#__PURE__*/ jsx("div", {
10786
+ children: /*#__PURE__*/ jsx(Select, {
10787
+ placeholder: "Select Workspace",
10788
+ renderOption: PayModelSelectItem,
10789
+ data: usersPayModels,
10790
+ onChange: (id)=>{
10791
+ if (id) setPayModel(id);
10792
+ },
10793
+ value: selectedPayModel
10794
+ })
10795
+ })
10796
+ })
10797
+ ]
10798
+ }),
10799
+ /*#__PURE__*/ jsxs("div", {
10800
+ className: "flex flex-col text-center border-1 border-gray p-2 mr-4",
10801
+ children: [
10802
+ /*#__PURE__*/ jsx("div", {
10803
+ className: "text-md border-b-1 border-gray mb-2 w-full py-2 text-xs",
10804
+ children: "Total Charges (USD)"
10805
+ }),
10806
+ /*#__PURE__*/ jsx(Text, {
10807
+ children: PaymentNumberToString(totalUsage)
10808
+ })
10809
+ ]
10810
+ }),
10811
+ /*#__PURE__*/ jsxs("div", {
10812
+ className: "flex flex-col text-center border-1 border-gray p-2",
10813
+ children: [
10814
+ /*#__PURE__*/ jsx("div", {
10815
+ className: "text-md border-b-1 border-gray mb-2 w-full py-2 text-xs",
10816
+ children: "Spending Limit (USD)"
10817
+ }),
10818
+ /*#__PURE__*/ jsx(Text, {
10819
+ children: PaymentNumberToString(hardLimit)
10820
+ })
10821
+ ]
10822
+ })
10823
+ ]
10824
+ })
10825
+ })
10826
+ ]
10827
+ })
10828
+ })
10829
+ });
10830
+ };
10831
+
10832
+ const isTerminated = (state)=>{
10833
+ return state !== undefined && 'terminated' in state.state;
10834
+ };
10835
+ const PodConditionIndex = {
10836
+ PodScheduled: 0,
10837
+ Initialized: 1,
10838
+ PodReadyToStartContainers: 2,
10839
+ ContainersReady: 3,
10840
+ ProxyConnected: 4,
10841
+ Ready: 5
10842
+ };
10843
+ const retrievePodConditionStatus = (conditionType, conditions)=>{
10844
+ const matchingCondition = conditions.find((condition)=>condition.type === conditionType);
10845
+ if (!matchingCondition) return PodStatus.Unknown;
10846
+ return matchingCondition.status;
10847
+ };
10848
+ const calculateCurrentStep = (conditions)=>{
10849
+ let currentStep = 0;
10850
+ conditions.forEach((condition)=>{
10851
+ const idx = PodConditionIndex[condition.type];
10852
+ if (condition.status === PodStatus.True) currentStep = Math.max(idx + 1, currentStep); // Add +1 since if True this
10853
+ });
10854
+ return currentStep;
10855
+ };
10856
+ const calculateLaunchSteps = ({ status, conditions, containerStates, workspaceType })=>{
10857
+ // if status is not 'Launching', or 'Stopped',
10858
+ // or we don't have conditions array, don't display steps bar
10859
+ if (!conditions || conditions.length === 0 || status !== 'Launching' && status !== 'Stopped') {
10860
+ return undefined;
10861
+ }
10862
+ // the return steps state
10863
+ const workspaceLaunchStatus = {
10864
+ step: 0,
10865
+ status: 'not ready'
10866
+ };
10867
+ const currentStep = calculateCurrentStep(conditions);
10868
+ workspaceLaunchStatus.step = currentStep;
10869
+ workspaceLaunchStatus.status = status === 'Stopped' ? 'error' : 'processing';
10870
+ if (currentStep == 2) {
10871
+ // PodReadyToStartContainers == False
10872
+ const cs = containerStates ?? [];
10873
+ // handle container stats
10874
+ if (cs.some((element)=>isTerminated(element))) {
10875
+ workspaceLaunchStatus.status = 'error';
10876
+ workspaceLaunchStatus.message = 'Service is terminated';
10877
+ }
10878
+ workspaceLaunchStatus.message = 'Starting notebook services';
10879
+ }
10880
+ if (currentStep == 3) {
10881
+ // ContainersReady == False
10882
+ // get container status
10883
+ if (workspaceType === 'ECS') {
10884
+ if (status === 'Launching') {
10885
+ workspaceLaunchStatus.status = 'processing';
10886
+ } else if (status !== 'Stopped') {
10887
+ workspaceLaunchStatus.status = 'error';
10888
+ }
10889
+ } else {
10890
+ const cs = containerStates ?? [];
10891
+ // handle container stats
10892
+ if (cs.some((element)=>isTerminated(element))) {
10893
+ workspaceLaunchStatus.status = 'error';
10894
+ workspaceLaunchStatus.message = 'Service is terminated';
10895
+ } else {
10896
+ // If container states are available, display detailed pod statuses
10897
+ workspaceLaunchStatus.subSteps = cs.map((c)=>({
10898
+ title: c.name,
10899
+ description: `${c.ready ? 'ready' : 'pending'}`
10900
+ }));
10901
+ }
10902
+ }
10903
+ const podStatus = retrievePodConditionStatus(PodConditionType.ProxyConnected, conditions);
10904
+ if (podStatus === PodStatus.False) workspaceLaunchStatus.message = 'In progress. If you are stuck here for more than a few minutes, cancel launch and try again or contact user support.';
10905
+ }
10906
+ // wait for proxy
10907
+ if (currentStep == 4) {
10908
+ // ProxyConnect == False
10909
+ const podStatus = retrievePodConditionStatus(PodConditionType.ProxyConnected, conditions);
10910
+ if (podStatus === PodStatus.True) workspaceLaunchStatus.message = 'Proxy is ready';
10911
+ else workspaceLaunchStatus.status = 'error';
10912
+ }
10913
+ if (currentStep == 5) {
10914
+ workspaceLaunchStatus.message = 'Proxy is ready';
10915
+ workspaceLaunchStatus.status = 'complete';
10916
+ }
10917
+ return workspaceLaunchStatus;
10918
+ };
10919
+
10920
+ const WorkspaceStepper = ({ stepsConfig, step })=>{
10921
+ return /*#__PURE__*/ jsx(Transition, {
10922
+ mounted: step !== undefined,
10923
+ transition: "fade",
10924
+ duration: 1200,
10925
+ exitDuration: 1200,
10926
+ timingFunction: "ease",
10927
+ children: (styles)=>/*#__PURE__*/ jsx("div", {
10928
+ className: "p-2 mt-2 w-3/4 mx-4",
10929
+ style: styles,
10930
+ children: !step ? null : /*#__PURE__*/ jsx(Stepper, {
10931
+ size: "xs",
10932
+ active: step?.step,
10933
+ allowNextStepsSelect: false,
10934
+ wrap: false,
10935
+ children: stepsConfig.steps.map((x)=>{
10936
+ return /*#__PURE__*/ jsx(Stepper.Step, {
10937
+ label: x.label,
10938
+ description: x.description,
10939
+ color: step.status === 'error' ? 'red' : 'accent.4',
10940
+ children: step.message ? /*#__PURE__*/ jsx(Center, {
10941
+ children: /*#__PURE__*/ jsx(Text, {
10942
+ children: step.message
10943
+ })
10944
+ }) : null
10945
+ }, x.label);
10946
+ })
10947
+ })
10948
+ })
10949
+ });
10950
+ };
10951
+ const WorkspaceLaunchProgress = ()=>{
10952
+ const config = useWorkspaceContext();
10953
+ const workspaceStatus = useCoreSelector(selectWorkspaceStatusFromService);
10954
+ const step = calculateLaunchSteps(workspaceStatus);
10955
+ return /*#__PURE__*/ jsx("div", {
10956
+ className: "px-2 py-1 mx-8",
10957
+ children: /*#__PURE__*/ jsx(WorkspaceStepper, {
10958
+ stepsConfig: config.launchStepIndicatorConfig,
10959
+ step: step
10960
+ })
10961
+ });
10962
+ };
10963
+
10964
+ const FULLSCREEN_STYLE = 'fixed top-0 left-0 w-full h-full flex flex-col flex-grow content-center items-center bg-base-lightest';
10965
+ const WorkspaceNotebookPanelWithControls = ()=>{
10966
+ const { isFullscreen } = useWorkspaceStatusContext();
10967
+ return /*#__PURE__*/ jsxs("div", {
10968
+ className: isFullscreen ? FULLSCREEN_STYLE : 'flex flex-col grow w-full h-full relative',
10969
+ children: [
10970
+ /*#__PURE__*/ jsx(ExternalLoginsStatus, {}),
10971
+ /*#__PURE__*/ jsx(PaymentPanel, {}),
10972
+ /*#__PURE__*/ jsx(WorkspaceLaunchProgress, {}),
10973
+ /*#__PURE__*/ jsx(WorkspacePanel, {}),
10974
+ /*#__PURE__*/ jsx(WorkspaceNotebook, {})
10975
+ ]
10976
+ });
10977
+ };
10978
+
10979
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
10980
+ const Workspace = ({ config })=>{
10981
+ return /*#__PURE__*/ jsx(ProtectedContent, {
10982
+ children: /*#__PURE__*/ jsx(WorkspaceProvider, {
10983
+ config: config,
10984
+ children: /*#__PURE__*/ jsx(WorkspaceStatusProvider, {
10985
+ children: /*#__PURE__*/ jsx("div", {
10986
+ className: "flex flex-col grow w-full relative",
10987
+ children: /*#__PURE__*/ jsx(WorkspaceNotebookPanelWithControls, {})
10988
+ })
10989
+ })
10990
+ })
10991
+ });
10992
+ };
10993
+
10994
+ const TextDescription = ({ description })=>{
10995
+ const [extend, setExtend] = useState(false);
10996
+ return /*#__PURE__*/ jsxs(Fragment, {
10997
+ children: [
10998
+ !extend ? /*#__PURE__*/ jsx(Text, {
10999
+ lineClamp: 4,
11000
+ children: description
11001
+ }) : /*#__PURE__*/ jsx(Text, {
11002
+ children: description
11003
+ }),
11004
+ /*#__PURE__*/ jsx("button", {
11005
+ onClick: ()=>setExtend((extend)=>!extend),
11006
+ children: /*#__PURE__*/ jsxs("div", {
11007
+ className: "flex text-xs font-semibold text-gray-400",
11008
+ children: [
11009
+ !extend ? 'Extend Text' : 'Collapse Text',
11010
+ ' ',
11011
+ /*#__PURE__*/ jsx("div", {
11012
+ className: "my-auto",
11013
+ children: !extend ? /*#__PURE__*/ jsx(MdKeyboardArrowDown, {}) : /*#__PURE__*/ jsx(MdKeyboardArrowUp, {})
11014
+ })
11015
+ ]
11016
+ })
11017
+ })
11018
+ ]
11019
+ });
11020
+ };
11021
+
11022
+ const AnalysisCenter = ({ tools, showFilterAndSort = false })=>{
11023
+ const [cards, setCards] = useState({
11024
+ type: '',
11025
+ access: '',
11026
+ search: ''
11027
+ });
11028
+ const handleCardsFilter = (filterType, selected)=>{
11029
+ if (!selected?.length) return;
11030
+ setCards((c)=>({
11031
+ ...c,
11032
+ [filterType]: selected
11033
+ }));
11034
+ };
11035
+ const handleCardsSearch = (keyword)=>{
11036
+ if (!keyword.length) return;
11037
+ };
11038
+ return /*#__PURE__*/ jsxs("div", {
11039
+ className: "w-full bg-base-lighter",
11040
+ children: [
11041
+ showFilterAndSort ? /*#__PURE__*/ jsxs("div", {
11042
+ className: "flex justify-between items-center w-7/8 mt-2 mx-2",
11043
+ children: [
11044
+ /*#__PURE__*/ jsxs("div", {
11045
+ className: "flex space-x-4",
11046
+ children: [
11047
+ /*#__PURE__*/ jsx(Select, {
11048
+ // todo: data opts
11049
+ data: [],
11050
+ value: cards.type,
11051
+ comboboxProps: {
11052
+ transitionProps: {
11053
+ transition: 'pop-top-left',
11054
+ duration: 50,
11055
+ timingFunction: 'ease'
11056
+ }
11057
+ },
11058
+ placeholder: "Filter by type",
11059
+ onChange: (value)=>handleCardsFilter('type', value)
11060
+ }),
11061
+ /*#__PURE__*/ jsx(Select, {
11062
+ // todo: data opts
11063
+ data: [],
11064
+ value: cards.access,
11065
+ comboboxProps: {
11066
+ transitionProps: {
11067
+ transition: 'pop-top-left',
11068
+ duration: 50,
11069
+ timingFunction: 'ease'
11070
+ }
11071
+ },
11072
+ placeholder: "Filter by access",
11073
+ onChange: (value)=>handleCardsFilter('access', value)
11074
+ })
11075
+ ]
11076
+ }),
11077
+ /*#__PURE__*/ jsx("div", {
11078
+ children: /*#__PURE__*/ jsx(TextInput, {
11079
+ placeholder: "Search in Analysis Center",
11080
+ value: cards.search,
11081
+ size: "md",
11082
+ onChange: (event)=>handleCardsSearch(event.currentTarget.value)
11083
+ })
11084
+ })
11085
+ ]
11086
+ }) : null,
11087
+ /*#__PURE__*/ jsx("div", {
11088
+ children: /*#__PURE__*/ jsx("div", {
11089
+ className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 p-1 mx-4 overflow-y-scroll",
11090
+ children: tools.map(({ title, description, type, icon, image, hasDemo, loginRequired, href }, key)=>{
11091
+ return /*#__PURE__*/ jsx(Stack, {
11092
+ children: /*#__PURE__*/ jsxs("div", {
11093
+ className: "rounded-sm bg-base-max",
11094
+ children: [
11095
+ /*#__PURE__*/ jsx("div", {
11096
+ className: "p-0 rounded-sm",
11097
+ children: /*#__PURE__*/ jsx(Image$1, {
11098
+ component: Image,
11099
+ src: `/images/apps/${image}`,
11100
+ alt: `${title} image`,
11101
+ height: 1000,
11102
+ width: 1000,
11103
+ radius: "md"
11104
+ })
11105
+ }),
11106
+ /*#__PURE__*/ jsxs("div", {
11107
+ className: "flex -mt-5 relative z-10",
11108
+ children: [
11109
+ /*#__PURE__*/ jsx("div", {
11110
+ className: "p-0.5 rounded-sm bg-base-lightest ml-5 border-2 border-base",
11111
+ children: /*#__PURE__*/ jsx(Image$1, {
11112
+ component: Image,
11113
+ src: `/icons/apps/${icon}`,
11114
+ alt: `${title} logo`,
11115
+ width: 40,
11116
+ height: 40,
11117
+ radius: "lg"
11118
+ })
11119
+ }),
11120
+ /*#__PURE__*/ jsx("div", {
11121
+ className: "relative mb-0 ml-2",
11122
+ children: /*#__PURE__*/ jsx("span", {
11123
+ className: "absolute bottom-0 left-0 text-xs text-gray-700 w-max",
11124
+ children: type === 'application' ? 'Application' : 'Jupyter Notebook'
11125
+ })
11126
+ })
11127
+ ]
11128
+ }),
11129
+ /*#__PURE__*/ jsxs("div", {
11130
+ className: "flex flex-col mt-2 ml-2",
11131
+ children: [
11132
+ /*#__PURE__*/ jsx("div", {
11133
+ className: "text-sm font-black h-6",
11134
+ children: title
11135
+ }),
11136
+ /*#__PURE__*/ jsx("div", {
11137
+ className: "text-xs text-gray-400 h-6",
11138
+ children: loginRequired ? 'Login Required' : ' '
11139
+ }),
11140
+ /*#__PURE__*/ jsx("div", {
11141
+ className: "text-sm p-2 h-fit",
11142
+ children: /*#__PURE__*/ jsx(TextDescription, {
11143
+ description: description
11144
+ })
11145
+ }),
11146
+ /*#__PURE__*/ jsx("div", {
11147
+ className: "flex mb-4 rounded-b-md",
11148
+ children: type === 'application' ? /*#__PURE__*/ jsxs("div", {
11149
+ className: "m-auto",
11150
+ children: [
11151
+ /*#__PURE__*/ jsx(NavLink, {
11152
+ component: Link,
11153
+ href: href ?? '_blank',
11154
+ classNames: {
11155
+ root: 'bg-accent text-accent-contrast hover:bg-accent-darker p-2 rounded-sm',
11156
+ label: 'text-sm font-semibold'
11157
+ },
11158
+ label: "Run App"
11159
+ }),
11160
+ hasDemo && /*#__PURE__*/ jsx("button", {
11161
+ className: "ml-2 p-1.5 rounded-sm text-sm font-semibold",
11162
+ children: "Demo"
11163
+ })
11164
+ ]
11165
+ }) : /*#__PURE__*/ jsx("button", {
11166
+ className: "m-auto bg-accent text-accent-contrast p-1.5 rounded-sm text-sm font-semibold",
11167
+ children: "View Notebook"
11168
+ })
11169
+ })
11170
+ ]
11171
+ })
11172
+ ]
11173
+ })
11174
+ }, key);
11175
+ })
11176
+ })
11177
+ })
11178
+ ]
11179
+ });
11180
+ };
11181
+
11182
+ const myGlob = (dir, filter)=>{
11183
+ try {
11184
+ const files = fs.readdirSync(dir);
11185
+ return files.filter((file)=>file.search(filter) !== -1);
11186
+ } catch (error) {
11187
+ console.log('myGlow error', error, dir);
11188
+ }
11189
+ return [];
11190
+ };
11191
+ class FilesystemContent {
11192
+ constructor({ rootPath }){
11193
+ this.rootPath = rootPath || '';
11194
+ }
11195
+ async get(filepath) {
11196
+ try {
11197
+ return await JSON.parse(fs.readFileSync(path.join(this.rootPath, filepath)).toString('utf-8'));
11198
+ } catch (err) {
11199
+ throw new Error(`Cannot process ${filepath}`);
11200
+ }
11201
+ }
11202
+ async getAll(filepath, filter) {
11203
+ try {
11204
+ const files = myGlob(path.join(this.rootPath, filepath), filter);
11205
+ return Promise.all(files.map((file)=>this.get(path.join(this.rootPath, filepath, file))));
11206
+ } catch (err) {
11207
+ throw new Error(`getAllCannot process ${filepath}/${filter}`);
11208
+ }
11209
+ }
11210
+ }
11211
+
11212
+ class ContentDatabase {
11213
+ constructor(config){
11214
+ this.config = config;
11215
+ this.store = config.store;
11216
+ }
11217
+ async get(filepath) {
11218
+ return this.store.get(filepath);
11219
+ }
11220
+ async getAll(filepath, filter) {
11221
+ // Array<Promise<T>>
11222
+ return this.store.getAll(filepath, filter);
11223
+ }
11224
+ }
11225
+
11226
+ const GEN3_FRONTEND_CONFIGURATION_ROOT = process.env.GEN3_FRONTEND_CONFIGURATION_ROOT || './';
11227
+
11228
+ const ContentRoot = GEN3_FRONTEND_CONFIGURATION_ROOT;
11229
+ const setup = ()=>{
11230
+ const config = {
11231
+ store: new FilesystemContent({
11232
+ rootPath: ContentRoot
11233
+ })
11234
+ };
11235
+ return new ContentDatabase(config);
11236
+ };
11237
+ const ContentSource = setup();
11238
+
11239
+ /**
11240
+ * Retrieves navigation page layout properties from configuration.
11241
+ * Note: GEN3_COMMONS_NAME depends on siteConfig.json value in the data commons package
11242
+ * @returns A Promise resolving to an object containing header and footer props.
11243
+ */ const getNavPageLayoutPropsFromConfig = async ()=>{
11244
+ const navigationConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/navigation.json`);
11245
+ let bannerConfigJSON = [];
11246
+ try {
11247
+ bannerConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/banner.json`);
11248
+ } catch (e) {
11249
+ console.warn('No banner config found at: ', `config/${GEN3_COMMONS_NAME}/banner.json`);
11250
+ }
11251
+ const { topBar, navigation, type = 'original' } = navigationConfigJSON;
11252
+ const headerProps = {
11253
+ top: topBar,
11254
+ navigation: navigation,
11255
+ banners: bannerConfigJSON,
11256
+ type
11257
+ };
11258
+ const footerProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/footer.json`);
11259
+ return {
11260
+ headerProps,
11261
+ footerProps,
11262
+ headerData: {
11263
+ title: 'Gen3 Frontend Framework Page',
11264
+ content: 'Gen3 Frontend Framework Page',
10007
11265
  key: 'gen3-common-page'
10008
11266
  }
10009
11267
  };
@@ -11681,7 +12939,7 @@ const createMantineTheme = (fonts, colors)=>{
11681
12939
  * inactivity limits for session timeouts.
11682
12940
  */ const Gen3Provider = ({ colors, icons, fonts, sessionConfig, modalsConfig, children })=>{
11683
12941
  useEffect(()=>{
11684
- addCollection(icons);
12942
+ icons.forEach((i)=>addCollection(i));
11685
12943
  }, [
11686
12944
  icons
11687
12945
  ]);
@@ -12486,51 +13744,6 @@ const ColorThemePageGetServerSideProps = async ()=>{
12486
13744
  };
12487
13745
  };
12488
13746
 
12489
- const ProtectedContent = ({ children, referer })=>{
12490
- const router = useRouter();
12491
- let redirect = referer;
12492
- if (!referer && typeof window !== 'undefined') {
12493
- // route not available on SSR
12494
- redirect = router.asPath;
12495
- }
12496
- const onUnauthenticated = ()=>{
12497
- if (typeof window !== 'undefined') // route not available on SSR
12498
- router.push({
12499
- pathname: '/Login',
12500
- query: {
12501
- referer: redirect
12502
- }
12503
- });
12504
- };
12505
- const { status, pending } = useSession(true, onUnauthenticated);
12506
- if (status !== 'issued') {
12507
- // not logged in
12508
- if (pending) return /*#__PURE__*/ jsx(LoadingOverlay, {
12509
- visible: pending
12510
- });
12511
- else return /*#__PURE__*/ jsxs("div", {
12512
- className: "w-full h-full relative",
12513
- children: [
12514
- /*#__PURE__*/ jsx(LoadingOverlay, {
12515
- visible: pending
12516
- }),
12517
- /*#__PURE__*/ jsx(Center, {
12518
- children: /*#__PURE__*/ jsx(Paper, {
12519
- shadow: "md",
12520
- p: "md",
12521
- children: /*#__PURE__*/ jsx(Text, {
12522
- children: "You are not signed in and cannot access this protected content. Please login in."
12523
- })
12524
- })
12525
- })
12526
- ]
12527
- });
12528
- }
12529
- return /*#__PURE__*/ jsx(React__default.Fragment, {
12530
- children: children
12531
- });
12532
- };
12533
-
12534
13747
  const SOON_IN_DAYS = 86400 * 5;
12535
13748
  const getStatus = (expiration, now)=>{
12536
13749
  if (expiration < now) return 'Expired';
@@ -15066,67 +16279,182 @@ const SubmissionsTable = ()=>{
15066
16279
  }),
15067
16280
  ' '
15068
16281
  ]
15069
- });
15070
- }
15071
- if (isError) {
15072
- return /*#__PURE__*/ jsx("div", {
15073
- className: "flex w-full py-24 h-100 relative justify-center",
15074
- children: /*#__PURE__*/ jsx(Text, {
15075
- size: 'xl',
15076
- children: "Error loading project data"
15077
- })
15078
- });
15079
- }
15080
- return /*#__PURE__*/ jsx("div", {
15081
- className: "flex w-full bg-base-max p-4 rounded-lg",
15082
- children: /*#__PURE__*/ jsx("div", {
15083
- className: "grow w-auto inline-block overflow-x-scroll",
15084
- children: /*#__PURE__*/ jsx(MantineReactTable, {
15085
- table: table
15086
- })
16282
+ });
16283
+ }
16284
+ if (isError) {
16285
+ return /*#__PURE__*/ jsx("div", {
16286
+ className: "flex w-full py-24 h-100 relative justify-center",
16287
+ children: /*#__PURE__*/ jsx(Text, {
16288
+ size: 'xl',
16289
+ children: "Error loading project data"
16290
+ })
16291
+ });
16292
+ }
16293
+ return /*#__PURE__*/ jsx("div", {
16294
+ className: "flex w-full bg-base-max p-4 rounded-lg",
16295
+ children: /*#__PURE__*/ jsx("div", {
16296
+ className: "grow w-auto inline-block overflow-x-scroll",
16297
+ children: /*#__PURE__*/ jsx(MantineReactTable, {
16298
+ table: table
16299
+ })
16300
+ })
16301
+ });
16302
+ };
16303
+
16304
+ const SubmissionPanel = ({ config })=>{
16305
+ if (!config) {
16306
+ return /*#__PURE__*/ jsx(MessagePanel, {
16307
+ message: "Submission config is not defined. Page disabled"
16308
+ });
16309
+ }
16310
+ return /*#__PURE__*/ jsxs("div", {
16311
+ className: "flex flex-col items-center p-4 w-full bg-base-lightest",
16312
+ children: [
16313
+ /*#__PURE__*/ jsx(ProjectTable, {
16314
+ columns: config.projectTable.columns
16315
+ }),
16316
+ /*#__PURE__*/ jsx(SubmissionsTable, {})
16317
+ ]
16318
+ });
16319
+ };
16320
+
16321
+ const SubmissionPage = ({ submissionConfig, headerProps, footerProps })=>{
16322
+ return /*#__PURE__*/ jsx(NavPageLayout, {
16323
+ footerProps: footerProps,
16324
+ headerProps: headerProps,
16325
+ headerData: {
16326
+ title: 'Gen3 Submission Page',
16327
+ content: 'Submission page',
16328
+ key: 'gen3-submission-page'
16329
+ },
16330
+ children: /*#__PURE__*/ jsx(SubmissionPanel, {
16331
+ config: submissionConfig
16332
+ })
16333
+ });
16334
+ };
16335
+
16336
+ const SubmissionPageGetServerSideProps = async ()=>{
16337
+ try {
16338
+ const submissionConfig = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/submission.json`);
16339
+ return {
16340
+ props: {
16341
+ ...await getNavPageLayoutPropsFromConfig(),
16342
+ submissionConfig: submissionConfig
16343
+ }
16344
+ };
16345
+ } catch (err) {
16346
+ console.error(err);
16347
+ return {
16348
+ props: {
16349
+ ...await getNavPageLayoutPropsFromConfig(),
16350
+ submissionConfig: undefined
16351
+ }
16352
+ };
16353
+ }
16354
+ };
16355
+
16356
+ const WorkspacePage = ({ headerProps, footerProps, workspaceProps })=>{
16357
+ return /*#__PURE__*/ jsx(NavPageLayout, {
16358
+ headerProps,
16359
+ footerProps,
16360
+ headerData: {
16361
+ title: 'Gen3 Workspace Page',
16362
+ content: 'Workspace page',
16363
+ key: 'gen3-workspace-page'
16364
+ },
16365
+ children: /*#__PURE__*/ jsx(Workspace, {
16366
+ config: workspaceProps
16367
+ })
16368
+ });
16369
+ };
16370
+
16371
+ const WorkspaceNoAccessPage = ({ headerProps, footerProps })=>{
16372
+ const supportEmail = headerProps?.siteProps?.contactEmail || 'support@datacommons.io';
16373
+ return /*#__PURE__*/ jsx(NavPageLayout, {
16374
+ headerProps,
16375
+ footerProps,
16376
+ headerData: {
16377
+ title: 'Gen3 Workspace No Access Page',
16378
+ content: 'Workspace no access page',
16379
+ key: 'gen3-workspace-no-access-page'
16380
+ },
16381
+ children: /*#__PURE__*/ jsxs(CardContainer, {
16382
+ children: [
16383
+ /*#__PURE__*/ jsx("h1", {
16384
+ children: "Error opening workspace..."
16385
+ }),
16386
+ /*#__PURE__*/ jsxs("p", {
16387
+ children: [
16388
+ "Workspace access requires authorization. Please contact",
16389
+ ' ',
16390
+ /*#__PURE__*/ jsx("a", {
16391
+ href: `mailto:${supportEmail}`,
16392
+ children: supportEmail
16393
+ }),
16394
+ " for more information."
16395
+ ]
16396
+ })
16397
+ ]
15087
16398
  })
15088
16399
  });
15089
16400
  };
15090
16401
 
15091
- const SubmissionPanel = ({ config })=>{
15092
- if (!config) {
15093
- return /*#__PURE__*/ jsx(MessagePanel, {
15094
- message: "Submission config is not defined. Page disabled"
15095
- });
16402
+ const WorkspacePageGetServerSideProps = async (_context)=>{
16403
+ const workspaceProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/workspace.json`);
16404
+ try {
16405
+ return {
16406
+ props: {
16407
+ ...await getNavPageLayoutPropsFromConfig(),
16408
+ workspaceProps
16409
+ }
16410
+ };
16411
+ } catch (err) {
16412
+ return {
16413
+ props: {
16414
+ ...await getNavPageLayoutPropsFromConfig(),
16415
+ workspaceProps: {
16416
+ launchStepIndicatorConfig: {}
16417
+ }
16418
+ }
16419
+ };
15096
16420
  }
15097
- return /*#__PURE__*/ jsxs("div", {
15098
- className: "flex flex-col items-center p-4 w-full bg-base-lightest",
15099
- children: [
15100
- /*#__PURE__*/ jsx(ProjectTable, {
15101
- columns: config.projectTable.columns
15102
- }),
15103
- /*#__PURE__*/ jsx(SubmissionsTable, {})
15104
- ]
16421
+ };
16422
+ const WorkspaceNoAccessPageServerSideProps = async ()=>{
16423
+ return {
16424
+ props: {
16425
+ ...await getNavPageLayoutPropsFromConfig()
16426
+ }
16427
+ };
16428
+ };
16429
+
16430
+ const AnalysisPanel = ({ tools })=>{
16431
+ return /*#__PURE__*/ jsx(AnalysisCenter, {
16432
+ tools: tools
15105
16433
  });
15106
16434
  };
15107
16435
 
15108
- const SubmissionPage = ({ submissionConfig, headerProps, footerProps })=>{
16436
+ const AnalysisPage = ({ headerProps, footerProps, tools })=>{
15109
16437
  return /*#__PURE__*/ jsx(NavPageLayout, {
15110
- footerProps: footerProps,
15111
- headerProps: headerProps,
16438
+ headerProps,
16439
+ footerProps,
15112
16440
  headerData: {
15113
- title: 'Gen3 Submission Page',
15114
- content: 'Submission page',
15115
- key: 'gen3-submission-page'
16441
+ title: 'Gen3 Analysis Center',
16442
+ content: 'Analysis Center',
16443
+ key: 'gen3-analysis-center'
15116
16444
  },
15117
- children: /*#__PURE__*/ jsx(SubmissionPanel, {
15118
- config: submissionConfig
16445
+ children: /*#__PURE__*/ jsx(AnalysisPanel, {
16446
+ tools: tools
15119
16447
  })
15120
16448
  });
15121
16449
  };
15122
16450
 
15123
- const SubmissionPageGetServerSideProps = async ()=>{
16451
+ const AnalysisPageGetServerSideProps = async ()=>{
15124
16452
  try {
15125
- const submissionConfig = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/submission.json`);
16453
+ const analysisConfig = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/analysisTools.json`);
15126
16454
  return {
15127
16455
  props: {
15128
16456
  ...await getNavPageLayoutPropsFromConfig(),
15129
- submissionConfig: submissionConfig
16457
+ ...analysisConfig
15130
16458
  }
15131
16459
  };
15132
16460
  } catch (err) {
@@ -15134,31 +16462,647 @@ const SubmissionPageGetServerSideProps = async ()=>{
15134
16462
  return {
15135
16463
  props: {
15136
16464
  ...await getNavPageLayoutPropsFromConfig(),
15137
- submissionConfig: undefined
16465
+ tools: []
15138
16466
  }
15139
16467
  };
15140
16468
  }
15141
16469
  };
15142
16470
 
15143
- const WorkspacesPage = ({ headerProps, footerProps, workspaceProps })=>{
16471
+ // File validation
16472
+ const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
16473
+ const ALLOWED_IMAGE_TYPES = [
16474
+ 'image/jpeg',
16475
+ 'image/png',
16476
+ 'image/svg+xml'
16477
+ ];
16478
+ const MAX_HISTORY = 50;
16479
+ const AnalysisCardEditor = ()=>{
16480
+ // Enhanced state management with history
16481
+ const [history, setHistory] = useState({
16482
+ past: [],
16483
+ present: [],
16484
+ future: []
16485
+ });
16486
+ const [editingIndex, setEditingIndex] = useState(null);
16487
+ const [selectedCards, setSelectedCards] = useState([]);
16488
+ const [errors, setErrors] = useState({});
16489
+ const [searchTerm, setSearchTerm] = useState('');
16490
+ const [filters, setFilters] = useState({
16491
+ type: [],
16492
+ loginRequired: null
16493
+ });
16494
+ const [currentCard, setCurrentCard] = useState({
16495
+ title: '',
16496
+ type: '',
16497
+ icon: '',
16498
+ image: '',
16499
+ description: '',
16500
+ loginRequired: false,
16501
+ href: '/'
16502
+ });
16503
+ // Helper function to update history
16504
+ const updateHistory = useCallback((newPresent)=>{
16505
+ setHistory((prev)=>({
16506
+ past: [
16507
+ ...prev.past,
16508
+ prev.present
16509
+ ].slice(-MAX_HISTORY),
16510
+ present: newPresent,
16511
+ future: []
16512
+ }));
16513
+ }, []);
16514
+ // Undo/Redo functions
16515
+ const undo = useCallback(()=>{
16516
+ setHistory((prev)=>{
16517
+ if (prev.past.length === 0) return prev;
16518
+ const newPast = prev.past.slice(0, -1);
16519
+ const newPresent = prev.past[prev.past.length - 1];
16520
+ return {
16521
+ past: newPast,
16522
+ present: newPresent,
16523
+ future: [
16524
+ prev.present,
16525
+ ...prev.future
16526
+ ]
16527
+ };
16528
+ });
16529
+ }, []);
16530
+ const redo = useCallback(()=>{
16531
+ setHistory((prev)=>{
16532
+ if (prev.future.length === 0) return prev;
16533
+ const [newPresent, ...newFuture] = prev.future;
16534
+ return {
16535
+ past: [
16536
+ ...prev.past,
16537
+ prev.present
16538
+ ],
16539
+ present: newPresent,
16540
+ future: newFuture
16541
+ };
16542
+ });
16543
+ }, []);
16544
+ const validateFile = (file, type)=>{
16545
+ if (!file) return null;
16546
+ if (!ALLOWED_IMAGE_TYPES.includes(file.type)) {
16547
+ return 'Invalid file type. Please upload a JPEG, PNG, or SVG file.';
16548
+ }
16549
+ if (file.size > MAX_FILE_SIZE) {
16550
+ return 'File size exceeds 5MB limit.';
16551
+ }
16552
+ return null;
16553
+ };
16554
+ const handleFileChange = (file, field)=>{
16555
+ const error = validateFile(file);
16556
+ if (error) {
16557
+ setErrors({
16558
+ ...errors,
16559
+ [field]: error
16560
+ });
16561
+ return;
16562
+ }
16563
+ setErrors({
16564
+ ...errors,
16565
+ [field]: ''
16566
+ });
16567
+ if (file) {
16568
+ const fileWithPreview = file;
16569
+ fileWithPreview.preview = URL.createObjectURL(file);
16570
+ setCurrentCard((prev)=>({
16571
+ ...prev,
16572
+ [`${field}File`]: fileWithPreview,
16573
+ [field]: file.name
16574
+ }));
16575
+ }
16576
+ };
16577
+ const validateForm = ()=>{
16578
+ const newErrors = {};
16579
+ if (!currentCard.title.trim()) {
16580
+ newErrors.title = 'Title is required';
16581
+ }
16582
+ if (!currentCard.type) {
16583
+ newErrors.type = 'Type is required';
16584
+ }
16585
+ if (!currentCard.description.trim()) {
16586
+ newErrors.description = 'Description is required';
16587
+ }
16588
+ if (!currentCard.href.trim()) {
16589
+ newErrors.description = 'href is required';
16590
+ }
16591
+ setErrors(newErrors);
16592
+ return Object.keys(newErrors).length === 0;
16593
+ };
16594
+ const handleDelete = (indices)=>{
16595
+ const newCards = history.present.filter((_, index)=>!indices.includes(index));
16596
+ updateHistory(newCards);
16597
+ setSelectedCards([]);
16598
+ };
16599
+ // Import/Export
16600
+ const handleImport = (file)=>{
16601
+ if (!file) return;
16602
+ const reader = new FileReader();
16603
+ reader.onload = (e)=>{
16604
+ try {
16605
+ const content = e.target?.result;
16606
+ const imported = JSON.parse(content);
16607
+ const withImages = imported.map((card)=>{
16608
+ return {
16609
+ ...card,
16610
+ iconFile: {
16611
+ preview: card.icon
16612
+ },
16613
+ imageFile: {
16614
+ preview: card.image
16615
+ }
16616
+ };
16617
+ });
16618
+ if (Array.isArray(withImages)) {
16619
+ updateHistory(withImages);
16620
+ console.log('Imported cards:', withImages);
16621
+ }
16622
+ } catch (error) {
16623
+ alert('Invalid file format');
16624
+ }
16625
+ };
16626
+ reader.readAsText(file);
16627
+ };
16628
+ const handleExport = ()=>{
16629
+ const dataStr = JSON.stringify(history.present, null, 2);
16630
+ const blob = new Blob([
16631
+ dataStr
16632
+ ], {
16633
+ type: 'application/json'
16634
+ });
16635
+ const url = URL.createObjectURL(blob);
16636
+ const link = document.createElement('a');
16637
+ link.download = 'analysis-cards.json';
16638
+ link.href = url;
16639
+ link.click();
16640
+ };
16641
+ // Filter cards
16642
+ history.present.filter((card)=>{
16643
+ const matchesSearch = card.title.toLowerCase().includes(searchTerm.toLowerCase()) || card.description.toLowerCase().includes(searchTerm.toLowerCase());
16644
+ const matchesType = filters.type.length === 0 || filters.type.includes(card.type);
16645
+ const matchesLogin = filters.loginRequired === null || card.loginRequired === filters.loginRequired;
16646
+ return matchesSearch && matchesType && matchesLogin;
16647
+ });
16648
+ // Enhanced drag and drop handling with history
16649
+ const handleDragEnd = (result)=>{
16650
+ if (!result.destination) return;
16651
+ const items = Array.from(history.present);
16652
+ const [reorderedItem] = items.splice(result.source.index, 1);
16653
+ items.splice(result.destination.index, 0, reorderedItem);
16654
+ updateHistory(items);
16655
+ };
16656
+ // Enhanced edit handling with history
16657
+ const handleEdit = (index)=>{
16658
+ setEditingIndex(index);
16659
+ setCurrentCard({
16660
+ ...history.present[index],
16661
+ // Reset file previews when editing
16662
+ iconFile: undefined,
16663
+ imageFile: undefined
16664
+ });
16665
+ };
16666
+ // Enhanced save handling
16667
+ const handleSave = ()=>{
16668
+ if (!validateForm()) return;
16669
+ let newCards;
16670
+ if (editingIndex !== null) {
16671
+ newCards = history.present.map((card, index)=>index === editingIndex ? {
16672
+ ...currentCard,
16673
+ // Remove the file preview properties before saving
16674
+ iconFile: undefined,
16675
+ imageFile: undefined
16676
+ } : card);
16677
+ } else {
16678
+ newCards = [
16679
+ ...history.present,
16680
+ {
16681
+ ...currentCard,
16682
+ // Remove the file preview properties before saving
16683
+ iconFile: undefined,
16684
+ imageFile: undefined
16685
+ }
16686
+ ];
16687
+ }
16688
+ updateHistory(newCards);
16689
+ resetForm();
16690
+ };
16691
+ // Enhanced reset form
16692
+ const resetForm = ()=>{
16693
+ setCurrentCard({
16694
+ title: '',
16695
+ type: '',
16696
+ icon: '',
16697
+ image: '',
16698
+ description: '',
16699
+ loginRequired: false,
16700
+ href: '/'
16701
+ });
16702
+ setEditingIndex(null);
16703
+ setErrors({});
16704
+ };
16705
+ const CardPreview = ({ card })=>/*#__PURE__*/ jsx("div", {
16706
+ className: "flex flex-col items-center w-full max-w-sm",
16707
+ children: /*#__PURE__*/ jsxs("div", {
16708
+ className: "rounded-sm bg-white w-full",
16709
+ children: [
16710
+ /*#__PURE__*/ jsx("div", {
16711
+ className: "p-0 rounded-sm relative h-48 bg-gray-200",
16712
+ children: card.imageFile?.preview ? /*#__PURE__*/ jsx(Image, {
16713
+ src: `/images/apps/${card.imageFile.preview}`,
16714
+ alt: "Preview",
16715
+ className: "w-full h-full object-cover"
16716
+ }) : /*#__PURE__*/ jsx("div", {
16717
+ className: "w-full h-full flex items-center justify-center text-gray-400",
16718
+ children: "Preview Image"
16719
+ })
16720
+ }),
16721
+ /*#__PURE__*/ jsxs("div", {
16722
+ className: "flex -mt-5 relative z-10",
16723
+ children: [
16724
+ /*#__PURE__*/ jsx("div", {
16725
+ className: "p-0.5 rounded-sm bg-gray-100 ml-5 w-10 h-10",
16726
+ children: card.iconFile?.preview ? /*#__PURE__*/ jsx(Image, {
16727
+ src: `/icons/apps/${card.iconFile.preview}`,
16728
+ alt: "Icon",
16729
+ className: "w-full h-full object-contain"
16730
+ }) : /*#__PURE__*/ jsx("div", {
16731
+ className: "w-full h-full flex items-center justify-center bg-gray-200"
16732
+ })
16733
+ }),
16734
+ /*#__PURE__*/ jsx("div", {
16735
+ className: "relative mb-0 ml-2",
16736
+ children: /*#__PURE__*/ jsx("span", {
16737
+ className: "absolute bottom-0 left-0 text-xs text-gray-400 w-max",
16738
+ children: card.type === 'application' ? 'Application' : 'Jupyter Notebook'
16739
+ })
16740
+ })
16741
+ ]
16742
+ }),
16743
+ /*#__PURE__*/ jsxs("div", {
16744
+ className: "flex flex-col mt-2 ml-2",
16745
+ children: [
16746
+ /*#__PURE__*/ jsx("div", {
16747
+ className: "text-sm font-black h-6",
16748
+ children: card.title
16749
+ }),
16750
+ /*#__PURE__*/ jsx("div", {
16751
+ className: "text-xs text-gray-400 h-6",
16752
+ children: card.loginRequired ? 'Login Required' : ' '
16753
+ }),
16754
+ /*#__PURE__*/ jsx("div", {
16755
+ className: "text-sm p-2 h-fit",
16756
+ children: /*#__PURE__*/ jsx(TextDescription, {
16757
+ description: card.description
16758
+ })
16759
+ }),
16760
+ /*#__PURE__*/ jsx("div", {
16761
+ className: "flex mb-4 rounded-b-md h-6",
16762
+ children: card.type === 'application' ? /*#__PURE__*/ jsxs("div", {
16763
+ className: "m-auto",
16764
+ children: [
16765
+ /*#__PURE__*/ jsx("button", {
16766
+ className: "bg-blue-500 mr-2 text-white p-1.5 rounded-sm text-sm font-semibold",
16767
+ children: "Run App"
16768
+ }),
16769
+ /*#__PURE__*/ jsx("button", {
16770
+ className: "bg-blue-500 ml-2 text-white p-1.5 rounded-sm text-sm font-semibold",
16771
+ children: "Demo"
16772
+ })
16773
+ ]
16774
+ }) : /*#__PURE__*/ jsx("button", {
16775
+ className: "m-auto bg-blue-500 text-white p-1.5 rounded-sm text-sm font-semibold",
16776
+ children: "View Notebook"
16777
+ })
16778
+ })
16779
+ ]
16780
+ })
16781
+ ]
16782
+ })
16783
+ });
16784
+ return /*#__PURE__*/ jsx("div", {
16785
+ className: "p-8 max-w-6xl mx-auto",
16786
+ children: /*#__PURE__*/ jsxs(Stack, {
16787
+ gap: "xl",
16788
+ children: [
16789
+ /*#__PURE__*/ jsx(Title, {
16790
+ order: 2,
16791
+ children: "Analysis Card Editor"
16792
+ }),
16793
+ /*#__PURE__*/ jsxs(Group, {
16794
+ children: [
16795
+ /*#__PURE__*/ jsxs(Tabs, {
16796
+ defaultValue: "edit",
16797
+ children: [
16798
+ /*#__PURE__*/ jsxs(Tabs.List, {
16799
+ children: [
16800
+ /*#__PURE__*/ jsx(Tabs.Tab, {
16801
+ value: "edit",
16802
+ children: "Edit"
16803
+ }),
16804
+ /*#__PURE__*/ jsx(Tabs.Tab, {
16805
+ value: "preview",
16806
+ children: "Preview"
16807
+ })
16808
+ ]
16809
+ }),
16810
+ /*#__PURE__*/ jsx(Tabs.Panel, {
16811
+ value: "edit",
16812
+ pt: "xs",
16813
+ children: /*#__PURE__*/ jsx(Card, {
16814
+ shadow: "sm",
16815
+ p: "lg",
16816
+ radius: "md",
16817
+ withBorder: true,
16818
+ children: /*#__PURE__*/ jsxs(Stack, {
16819
+ gap: "md",
16820
+ children: [
16821
+ /*#__PURE__*/ jsx(TextInput, {
16822
+ required: true,
16823
+ label: "Title",
16824
+ placeholder: "Enter tool title",
16825
+ value: currentCard.title,
16826
+ onChange: (e)=>setCurrentCard((prev)=>({
16827
+ ...prev,
16828
+ title: e.target.value
16829
+ })),
16830
+ error: errors.title
16831
+ }),
16832
+ /*#__PURE__*/ jsx(Select, {
16833
+ required: true,
16834
+ label: "Type",
16835
+ placeholder: "Select tool type",
16836
+ value: currentCard.type,
16837
+ onChange: (value)=>setCurrentCard((prev)=>({
16838
+ ...prev,
16839
+ type: value || ''
16840
+ })),
16841
+ data: [
16842
+ {
16843
+ value: 'application',
16844
+ label: 'Application'
16845
+ },
16846
+ {
16847
+ value: 'notebook',
16848
+ label: 'Jupyter Notebook'
16849
+ }
16850
+ ],
16851
+ error: errors.type
16852
+ }),
16853
+ /*#__PURE__*/ jsxs(Group, {
16854
+ grow: true,
16855
+ children: [
16856
+ /*#__PURE__*/ jsx(FileInput, {
16857
+ label: "Icon",
16858
+ placeholder: "Upload icon",
16859
+ accept: ALLOWED_IMAGE_TYPES.join(','),
16860
+ onChange: (file)=>handleFileChange(file, 'icon'),
16861
+ error: errors.icon
16862
+ }),
16863
+ /*#__PURE__*/ jsx(FileInput, {
16864
+ label: "Preview Image",
16865
+ placeholder: "Upload preview image",
16866
+ accept: ALLOWED_IMAGE_TYPES.join(','),
16867
+ onChange: (file)=>handleFileChange(file, 'image'),
16868
+ error: errors.image
16869
+ })
16870
+ ]
16871
+ }),
16872
+ /*#__PURE__*/ jsx(Textarea, {
16873
+ required: true,
16874
+ label: "Description",
16875
+ placeholder: "Enter tool description",
16876
+ minRows: 4,
16877
+ value: currentCard.description,
16878
+ onChange: (e)=>setCurrentCard((prev)=>({
16879
+ ...prev,
16880
+ description: e.target.value
16881
+ })),
16882
+ error: errors.description
16883
+ }),
16884
+ /*#__PURE__*/ jsx(TextInput, {
16885
+ required: true,
16886
+ label: "href",
16887
+ placeholder: "Enter application path",
16888
+ value: currentCard.href,
16889
+ onChange: (e)=>setCurrentCard((prev)=>({
16890
+ ...prev,
16891
+ href: e.target.value
16892
+ })),
16893
+ error: errors.href
16894
+ }),
16895
+ /*#__PURE__*/ jsx(Switch, {
16896
+ label: "Login Required",
16897
+ checked: currentCard.loginRequired,
16898
+ onChange: (e)=>setCurrentCard((prev)=>({
16899
+ ...prev,
16900
+ loginRequired: e.currentTarget.checked
16901
+ }))
16902
+ }),
16903
+ /*#__PURE__*/ jsxs(Group, {
16904
+ children: [
16905
+ /*#__PURE__*/ jsx(Button, {
16906
+ onClick: handleSave,
16907
+ color: "blue",
16908
+ children: editingIndex !== null ? 'Update Card' : 'Add Card'
16909
+ }),
16910
+ editingIndex !== null && /*#__PURE__*/ jsx(Button, {
16911
+ onClick: resetForm,
16912
+ color: "gray",
16913
+ children: "Cancel Edit"
16914
+ })
16915
+ ]
16916
+ })
16917
+ ]
16918
+ })
16919
+ })
16920
+ }),
16921
+ /*#__PURE__*/ jsx(Tabs.Panel, {
16922
+ value: "preview",
16923
+ pt: "xs",
16924
+ children: /*#__PURE__*/ jsx(CardPreview, {
16925
+ card: currentCard
16926
+ })
16927
+ })
16928
+ ]
16929
+ }),
16930
+ history.present.length > 0 && /*#__PURE__*/ jsx(Card, {
16931
+ shadow: "sm",
16932
+ p: "lg",
16933
+ radius: "md",
16934
+ withBorder: true,
16935
+ children: /*#__PURE__*/ jsxs(Stack, {
16936
+ gap: "md",
16937
+ children: [
16938
+ /*#__PURE__*/ jsxs(Title, {
16939
+ order: 3,
16940
+ children: [
16941
+ "Added Cards (",
16942
+ history.present.length,
16943
+ ")"
16944
+ ]
16945
+ }),
16946
+ /*#__PURE__*/ jsx(DragDropContext, {
16947
+ onDragEnd: handleDragEnd,
16948
+ children: /*#__PURE__*/ jsx(Droppable, {
16949
+ droppableId: "cards",
16950
+ children: (provided)=>/*#__PURE__*/ jsxs("div", {
16951
+ ...provided.droppableProps,
16952
+ ref: provided.innerRef,
16953
+ children: [
16954
+ history.present.map((card, index)=>/*#__PURE__*/ jsx(Draggable, {
16955
+ draggableId: `card-${index}`,
16956
+ index: index,
16957
+ children: (provided)=>/*#__PURE__*/ jsx("div", {
16958
+ ref: provided.innerRef,
16959
+ ...provided.draggableProps,
16960
+ ...provided.dragHandleProps,
16961
+ className: "mb-2",
16962
+ children: /*#__PURE__*/ jsx(Card, {
16963
+ withBorder: true,
16964
+ children: /*#__PURE__*/ jsxs(Group, {
16965
+ justify: "space-between",
16966
+ children: [
16967
+ /*#__PURE__*/ jsxs("div", {
16968
+ children: [
16969
+ /*#__PURE__*/ jsx(Text, {
16970
+ fw: 500,
16971
+ children: card.title
16972
+ }),
16973
+ /*#__PURE__*/ jsxs(Text, {
16974
+ size: "sm",
16975
+ color: "dimmed",
16976
+ children: [
16977
+ "Type: ",
16978
+ card.type
16979
+ ]
16980
+ }),
16981
+ /*#__PURE__*/ jsxs(Text, {
16982
+ size: "sm",
16983
+ color: "dimmed",
16984
+ children: [
16985
+ "Login Required:",
16986
+ ' ',
16987
+ card.loginRequired ? 'Yes' : 'No'
16988
+ ]
16989
+ })
16990
+ ]
16991
+ }),
16992
+ /*#__PURE__*/ jsxs(Group, {
16993
+ children: [
16994
+ /*#__PURE__*/ jsx(Button, {
16995
+ variant: "light",
16996
+ size: "xs",
16997
+ onClick: ()=>handleEdit(index),
16998
+ children: "Edit"
16999
+ }),
17000
+ /*#__PURE__*/ jsx(Button, {
17001
+ variant: "light",
17002
+ color: "red",
17003
+ size: "xs",
17004
+ onClick: ()=>handleDelete([
17005
+ index
17006
+ ]),
17007
+ children: "Delete"
17008
+ })
17009
+ ]
17010
+ })
17011
+ ]
17012
+ })
17013
+ })
17014
+ })
17015
+ }, index)),
17016
+ provided.placeholder
17017
+ ]
17018
+ })
17019
+ })
17020
+ })
17021
+ ]
17022
+ })
17023
+ })
17024
+ ]
17025
+ }),
17026
+ /*#__PURE__*/ jsxs(Group, {
17027
+ gap: "xs",
17028
+ children: [
17029
+ /*#__PURE__*/ jsx(ActionIcon, {
17030
+ onClick: undo,
17031
+ disabled: history.past.length === 0,
17032
+ title: "Undo",
17033
+ children: /*#__PURE__*/ jsx(FaUndo, {
17034
+ size: 20
17035
+ })
17036
+ }),
17037
+ /*#__PURE__*/ jsx(ActionIcon, {
17038
+ onClick: redo,
17039
+ disabled: history.future.length === 0,
17040
+ title: "Redo",
17041
+ children: /*#__PURE__*/ jsx(FaRedo, {
17042
+ size: 20
17043
+ })
17044
+ }),
17045
+ /*#__PURE__*/ jsx(FileInput, {
17046
+ accept: ".json",
17047
+ onChange: handleImport,
17048
+ style: {
17049
+ display: 'none'
17050
+ },
17051
+ id: "import-file"
17052
+ }),
17053
+ /*#__PURE__*/ jsx(Button, {
17054
+ variant: "light",
17055
+ leftSection: /*#__PURE__*/ jsx(FaUpload, {
17056
+ size: 16
17057
+ }),
17058
+ onClick: ()=>document.getElementById('import-file')?.click(),
17059
+ children: "Import"
17060
+ }),
17061
+ /*#__PURE__*/ jsx(Button, {
17062
+ variant: "light",
17063
+ leftSection: /*#__PURE__*/ jsx(FaDownload, {
17064
+ size: 16
17065
+ }),
17066
+ onClick: handleExport,
17067
+ children: "Export"
17068
+ })
17069
+ ]
17070
+ })
17071
+ ]
17072
+ })
17073
+ });
17074
+ };
17075
+
17076
+ const AnalysisEditorPage = ({ headerProps, footerProps, analysisFile })=>{
15144
17077
  return /*#__PURE__*/ jsx(NavPageLayout, {
15145
17078
  headerProps,
15146
17079
  footerProps,
17080
+ headerProps: headerProps,
15147
17081
  headerData: {
15148
- title: 'Gen3 Workspace Page',
15149
- content: 'Workspace page',
15150
- key: 'gen3-workspace-page'
17082
+ title: 'Gen3 Analysis Editor Page',
17083
+ content: 'Analysis Editor page',
17084
+ key: 'gen3-analysis-editor-page'
15151
17085
  },
15152
- children: /*#__PURE__*/ jsx(WorkspacesPanel, {})
15153
- });
15154
- };
15155
-
15156
- const WorkspacesPageGetServerSideProps = async (_context)=>{
15157
- const workspaceProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/workspaces.json`);
17086
+ children: /*#__PURE__*/ jsx(AnalysisCardEditor, {})
17087
+ });
17088
+ };
17089
+
17090
+ const AnalysisEditorPageGetServerSideProps = async ()=>{
17091
+ // const rootPath = `config/${GEN3_COMMONS_NAME}/`;
17092
+ // const filepath = 'user.yaml';
17093
+ // let data: Record<string, any> = {};
17094
+ // try {
17095
+ // // const contents = fs.readFileSync(path.join(rootPath, filepath), 'utf8');
17096
+ // // data = await YAML.parse(contents);
17097
+ // } catch (error: unknown) {
17098
+ // if (error instanceof Error) {
17099
+ // console.error(error.message);
17100
+ // }
17101
+ // throw new Error(`Cannot process ${rootPath}${filepath}`);
17102
+ // }
15158
17103
  return {
15159
17104
  props: {
15160
- ...await getNavPageLayoutPropsFromConfig(),
15161
- workspaceProps
17105
+ ...await getNavPageLayoutPropsFromConfig()
15162
17106
  }
15163
17107
  };
15164
17108
  };
@@ -15207,6 +17151,38 @@ const AISearchPageGetServerSideProps = async ()=>{
15207
17151
  }
15208
17152
  };
15209
17153
 
17154
+ const NotebookLitePage = ({ headerProps, footerProps })=>{
17155
+ return /*#__PURE__*/ jsx(NavPageLayout, {
17156
+ footerProps,
17157
+ headerProps,
17158
+ headerData: {
17159
+ title: 'Gen3 Notebooks Lite Page',
17160
+ content: 'Notebooks Lite',
17161
+ key: 'gen3-notebooks-lite-page'
17162
+ },
17163
+ children: /*#__PURE__*/ jsx("div", {
17164
+ className: "flex justify-items-center w-full",
17165
+ children: /*#__PURE__*/ jsx("iframe", {
17166
+ allow: "cross-origin",
17167
+ src: "https://localhost:3010/jupyter/index.html",
17168
+ width: "100%",
17169
+ height: "100%",
17170
+ title: "client notebook"
17171
+ })
17172
+ })
17173
+ });
17174
+ };
17175
+
17176
+ // should move this thing into _app.tsx and make a dedicated layout component after https://github.com/vercel/next.js/discussions/10949 is addressed
17177
+ const NotebookLitePageGetStaticProps = async ()=>{
17178
+ const navPageLayoutProps = await getNavPageLayoutPropsFromConfig();
17179
+ return {
17180
+ props: {
17181
+ ...navPageLayoutProps
17182
+ }
17183
+ };
17184
+ };
17185
+
15210
17186
  const CrosswalkTable = ({ mapping, data, isFetching, isError, tableMessage, showSubmittedIdInTable })=>{
15211
17187
  const cols = useMemo(()=>{
15212
17188
  return [
@@ -15779,5 +17755,5 @@ async function credentialsLogout(req, res) {
15779
17755
  res.redirect(307, '/');
15780
17756
  }
15781
17757
 
15782
- export { AISearchPageGetServerSideProps, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AuthzPage, BaseModal, Charts, CohortBuilder, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetStaticProps, LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, User, WorkspacesPage, WorkspacesPageGetServerSideProps, WorkspacesPanel, capitalize, computeRowSpan, create10ColorAccessibleContrast, create10ColorPallet, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortDiversityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, toDisplayName, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
17758
+ export { AISearchPageGetServerSideProps, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AnalysisCenter, AnalysisEditorPage, AnalysisEditorPageGetServerSideProps, AnalysisPage, AnalysisPageGetServerSideProps, AuthzPage, BaseModal, Charts, CohortBuilder, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetStaticProps, LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, NotebookLitePage, NotebookLitePageGetStaticProps, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, User, Workspace, WorkspaceNoAccessPage, WorkspaceNoAccessPageServerSideProps, WorkspacePage, WorkspacePageGetServerSideProps, capitalize, computeRowSpan, create10ColorAccessibleContrast, create10ColorPallet, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortDiversityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, toDisplayName, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
15783
17759
  //# sourceMappingURL=index.js.map