synapse-react-client 4.0.45 → 4.0.46

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 (319) hide show
  1. package/dist/SWC.index.js +1 -1
  2. package/dist/aridhia-queries/AridhiaKeyFactory.d.ts +1 -0
  3. package/dist/aridhia-queries/AridhiaKeyFactory.d.ts.map +1 -1
  4. package/dist/aridhia-queries/AridhiaKeyFactory.js +3 -0
  5. package/dist/aridhia-queries/AridhiaKeyFactory.js.map +1 -1
  6. package/dist/aridhia-queries/aridhiaTokenExchange.js +6 -6
  7. package/dist/aridhia-queries/index.d.ts +1 -0
  8. package/dist/aridhia-queries/index.d.ts.map +1 -1
  9. package/dist/aridhia-queries/index.js +11 -10
  10. package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.d.ts +19 -0
  11. package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.d.ts.map +1 -0
  12. package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.js +14 -0
  13. package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.js.map +1 -0
  14. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.d.ts.map +1 -1
  15. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js +6 -4
  16. package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js.map +1 -1
  17. package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
  18. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/AccessorRequirementHelpText.js +1 -1
  19. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/AccessorRequirementHelpText.js.map +1 -1
  20. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js +1 -1
  21. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js.map +1 -1
  22. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewCollaboratorsAndSigningOfficialAccordion.js +1 -1
  23. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewCollaboratorsAndSigningOfficialAccordion.js.map +1 -1
  24. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.d.ts.map +1 -1
  25. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js +11 -8
  26. package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js.map +1 -1
  27. package/dist/components/AccessTokenPage/AccessTokenPage.js +1 -1
  28. package/dist/components/AccessTokenPage/AccessTokenPage.js.map +1 -1
  29. package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js +1 -1
  30. package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js.map +1 -1
  31. package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts.map +1 -1
  32. package/dist/components/Aridhia/DarWizard/DarSectionForm.js +17 -13
  33. package/dist/components/Aridhia/DarWizard/DarSectionForm.js.map +1 -1
  34. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts +3 -3
  35. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts.map +1 -1
  36. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +33 -34
  37. package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -1
  38. package/dist/components/Aridhia/fairFormToRjsf.js +1 -1
  39. package/dist/components/Aridhia/fairFormToRjsf.js.map +1 -1
  40. package/dist/components/Authentication/LastLoginInfo.js +1 -1
  41. package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
  42. package/dist/components/CertificationQuiz/CertificationQuiz.js +1 -1
  43. package/dist/components/CertificationQuiz/CertificationQuiz.js.map +1 -1
  44. package/dist/components/ChallengeSubmission/AvailableEvaluationQueueList.js +1 -1
  45. package/dist/components/ChallengeSubmission/AvailableEvaluationQueueList.js.map +1 -1
  46. package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js +1 -1
  47. package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js.map +1 -1
  48. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +6 -6
  49. package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
  50. package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.d.ts.map +1 -1
  51. package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.js +4 -4
  52. package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.js.map +1 -1
  53. package/dist/components/ChallengeTeamWizard/SelectChallengeTeam.js +4 -4
  54. package/dist/components/CitationPopover/CitationPopoverContent.js +4 -4
  55. package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
  56. package/dist/components/ComponentCollapse.d.ts.map +1 -1
  57. package/dist/components/ComponentCollapse.js +2 -1
  58. package/dist/components/ComponentCollapse.js.map +1 -1
  59. package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
  60. package/dist/components/DataGrid/SynapseGrid.js +231 -219
  61. package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
  62. package/dist/components/DataGrid/SyncGridWithSourceButton.d.ts.map +1 -1
  63. package/dist/components/DataGrid/SyncGridWithSourceButton.js +5 -4
  64. package/dist/components/DataGrid/SyncGridWithSourceButton.js.map +1 -1
  65. package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts.map +1 -1
  66. package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js +7 -5
  67. package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js.map +1 -1
  68. package/dist/components/DataGrid/components/ExportCsvFromGridButton.js +4 -4
  69. package/dist/components/DataGrid/components/ExportCsvFromGridButton.js.map +1 -1
  70. package/dist/components/DataGrid/components/ReorderColumnsButton.js +4 -4
  71. package/dist/components/DataGrid/components/ReorderColumnsButton.js.map +1 -1
  72. package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts.map +1 -1
  73. package/dist/components/DataGrid/components/ReorderColumnsDialog.js +12 -8
  74. package/dist/components/DataGrid/components/ReorderColumnsDialog.js.map +1 -1
  75. package/dist/components/DataGrid/components/UploadCsvToGridButton.js +1 -1
  76. package/dist/components/DataGrid/components/UploadCsvToGridButton.js.map +1 -1
  77. package/dist/components/DataGrid/hooks/useGridUndoRedo.js +5 -5
  78. package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
  79. package/dist/components/DataGrid/utils/applyModelChange.js +14 -14
  80. package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
  81. package/dist/components/DataGrid/utils/columnFactory.js +1 -1
  82. package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
  83. package/dist/components/DataGrid/utils/splitPatch.d.ts.map +1 -1
  84. package/dist/components/DataGrid/utils/splitPatch.js +22 -13
  85. package/dist/components/DataGrid/utils/splitPatch.js.map +1 -1
  86. package/dist/components/DownloadCart/DownloadCartPage.js +1 -1
  87. package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
  88. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
  89. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +2 -1
  90. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
  91. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -1
  92. package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +1 -3
  93. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.d.ts.map +1 -1
  94. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js +16 -10
  95. package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
  96. package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -1
  97. package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
  98. package/dist/components/EntityFinder/EntityFinder.js +4 -4
  99. package/dist/components/EntityFinder/EntityIdTextField.js +1 -1
  100. package/dist/components/EntityFinder/EntityIdTextField.js.map +1 -1
  101. package/dist/components/EntityFinder/tree/VirtualizedTree.d.ts.map +1 -1
  102. package/dist/components/EntityFinder/tree/VirtualizedTree.js +5 -4
  103. package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
  104. package/dist/components/EntityHeaderTable/EntityHeaderTable.js +1 -1
  105. package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
  106. package/dist/components/EntityTreeTable/components/EntityNameCell.d.ts.map +1 -1
  107. package/dist/components/EntityTreeTable/components/EntityNameCell.js +2 -1
  108. package/dist/components/EntityTreeTable/components/EntityNameCell.js.map +1 -1
  109. package/dist/components/EntityUpload/FileUploadProgress.d.ts.map +1 -1
  110. package/dist/components/EntityUpload/FileUploadProgress.js +11 -7
  111. package/dist/components/EntityUpload/FileUploadProgress.js.map +1 -1
  112. package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.d.ts.map +1 -1
  113. package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.js +4 -3
  114. package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.js.map +1 -1
  115. package/dist/components/ExperimentalMode/ExperimentalMode.js +1 -1
  116. package/dist/components/ExperimentalMode/ExperimentalMode.js.map +1 -1
  117. package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js +1 -1
  118. package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js.map +1 -1
  119. package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.d.ts.map +1 -1
  120. package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.js +2 -1
  121. package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.js.map +1 -1
  122. package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.d.ts.map +1 -1
  123. package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.js +2 -1
  124. package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.js.map +1 -1
  125. package/dist/components/FormTemplateEditor/FieldLibrary.d.ts.map +1 -1
  126. package/dist/components/FormTemplateEditor/FieldLibrary.js +2 -1
  127. package/dist/components/FormTemplateEditor/FieldLibrary.js.map +1 -1
  128. package/dist/components/FormTemplateEditor/FieldLibraryRow.js +4 -4
  129. package/dist/components/FormTemplateEditor/FieldLibraryRow.js.map +1 -1
  130. package/dist/components/FormTemplateEditor/FormStructurePanel.js +1 -1
  131. package/dist/components/FormTemplateEditor/FormStructurePanel.js.map +1 -1
  132. package/dist/components/FormTemplateEditor/FormTemplateEditorForm.js +1 -1
  133. package/dist/components/FormTemplateEditor/FormTemplateEditorForm.js.map +1 -1
  134. package/dist/components/FormTemplateEditor/StepCard.d.ts.map +1 -1
  135. package/dist/components/FormTemplateEditor/StepCard.js +15 -10
  136. package/dist/components/FormTemplateEditor/StepCard.js.map +1 -1
  137. package/dist/components/FormTemplateEditor/StepFieldRow.d.ts.map +1 -1
  138. package/dist/components/FormTemplateEditor/StepFieldRow.js +11 -6
  139. package/dist/components/FormTemplateEditor/StepFieldRow.js.map +1 -1
  140. package/dist/components/FormTemplateEditor/TemplateFileHandleField.d.ts.map +1 -1
  141. package/dist/components/FormTemplateEditor/TemplateFileHandleField.js +2 -1
  142. package/dist/components/FormTemplateEditor/TemplateFileHandleField.js.map +1 -1
  143. package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js +45 -45
  144. package/dist/components/GenericCard/PortalDOI/PortalDOI.js +5 -5
  145. package/dist/components/GenericCard/PortalDOI/PortalDOI.js.map +1 -1
  146. package/dist/components/GenericCard/TableRowGenericCard.js +1 -1
  147. package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
  148. package/dist/components/HelpPopover/HelpPopover.js +1 -1
  149. package/dist/components/HelpPopover/HelpPopover.js.map +1 -1
  150. package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
  151. package/dist/components/IconSvg/IconSvg.js +154 -47
  152. package/dist/components/IconSvg/IconSvg.js.map +1 -1
  153. package/dist/components/JsonSchemaForm/templates/ButtonTemplate.d.ts.map +1 -1
  154. package/dist/components/JsonSchemaForm/templates/ButtonTemplate.js +19 -16
  155. package/dist/components/JsonSchemaForm/templates/ButtonTemplate.js.map +1 -1
  156. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.d.ts.map +1 -1
  157. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js +2 -1
  158. package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js.map +1 -1
  159. package/dist/components/JsonSchemaForm/widgets/PhoneWidget.d.ts +9 -0
  160. package/dist/components/JsonSchemaForm/widgets/PhoneWidget.d.ts.map +1 -0
  161. package/dist/components/JsonSchemaForm/widgets/PhoneWidget.js +21 -0
  162. package/dist/components/JsonSchemaForm/widgets/PhoneWidget.js.map +1 -0
  163. package/dist/components/Markdown/MarkdownCollapse.d.ts.map +1 -1
  164. package/dist/components/Markdown/MarkdownCollapse.js +3 -1
  165. package/dist/components/Markdown/MarkdownCollapse.js.map +1 -1
  166. package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js +1 -1
  167. package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
  168. package/dist/components/OAuthClientManagement/OAuthManagement.js +14 -13
  169. package/dist/components/OAuthClientManagement/OAuthManagement.js.map +1 -1
  170. package/dist/components/PortalList/PortalCard.d.ts.map +1 -1
  171. package/dist/components/PortalList/PortalCard.js +6 -5
  172. package/dist/components/PortalList/PortalCard.js.map +1 -1
  173. package/dist/components/PortalList/PortalList.js +4 -4
  174. package/dist/components/PortalList/PortalList.js.map +1 -1
  175. package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js +6 -6
  176. package/dist/components/QueryBuilder/FilterConditionRow.js +4 -4
  177. package/dist/components/QueryCountButton/QueryCountButton.js +5 -5
  178. package/dist/components/QueryCountButton/QueryCountButton.js.map +1 -1
  179. package/dist/components/ReleaseCard/ReleaseCardLarge.js +5 -5
  180. package/dist/components/ReleaseCard/ReleaseCardLarge.js.map +1 -1
  181. package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js +1 -1
  182. package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
  183. package/dist/components/ShareThisPage/ShareThisPage.js +4 -4
  184. package/dist/components/ShareThisPage/ShareThisPage.js.map +1 -1
  185. package/dist/components/SustainabilityScorecard/DialLayout.js +1 -1
  186. package/dist/components/SustainabilityScorecard/DialLayout.js.map +1 -1
  187. package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js +1 -1
  188. package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js.map +1 -1
  189. package/dist/components/SynapseChat/SynapseChat.js +1 -1
  190. package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
  191. package/dist/components/SynapseChat/SynapseChatInteraction.d.ts.map +1 -1
  192. package/dist/components/SynapseChat/SynapseChatInteraction.js +2 -1
  193. package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
  194. package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js +1 -1
  195. package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js.map +1 -1
  196. package/dist/components/SynapseFooter/SynapseFooter.js +1 -1
  197. package/dist/components/SynapseFooter/SynapseFooter.js.map +1 -1
  198. package/dist/components/SynapseHomepageV2/SynapseFeaturedDatasetItem.js +1 -1
  199. package/dist/components/SynapseHomepageV2/SynapseFeaturedDatasetItem.js.map +1 -1
  200. package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.d.ts.map +1 -1
  201. package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.js +2 -1
  202. package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.js.map +1 -1
  203. package/dist/components/SynapseHomepageV2/SynapseInActionItem.js +4 -4
  204. package/dist/components/SynapseHomepageV2/SynapseInActionItem.js.map +1 -1
  205. package/dist/components/SynapseHomepageV2/SynapseTrendingProjectsItem.js +1 -1
  206. package/dist/components/SynapseHomepageV2/SynapseTrendingProjectsItem.js.map +1 -1
  207. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts.map +1 -1
  208. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js +4 -1
  209. package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js.map +1 -1
  210. package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js +1 -1
  211. package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
  212. package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js +1 -1
  213. package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js.map +1 -1
  214. package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.d.ts.map +1 -1
  215. package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.js +12 -9
  216. package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.js.map +1 -1
  217. package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js +4 -4
  218. package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
  219. package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +140 -140
  220. package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
  221. package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js +1 -1
  222. package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
  223. package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js +1 -1
  224. package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js.map +1 -1
  225. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
  226. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
  227. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js +9 -9
  228. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
  229. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.d.ts.map +1 -1
  230. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.js +6 -4
  231. package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.js.map +1 -1
  232. package/dist/components/TanStackTable/ColumnHeader.js +1 -1
  233. package/dist/components/TanStackTable/ColumnHeader.js.map +1 -1
  234. package/dist/components/TeamSubjectsSelector/TeamBadgeOrError.js +1 -1
  235. package/dist/components/TeamSubjectsSelector/TeamBadgeOrError.js.map +1 -1
  236. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.d.ts.map +1 -1
  237. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js +4 -3
  238. package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js.map +1 -1
  239. package/dist/components/Webhook/WebhookDashboard.js +1 -1
  240. package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
  241. package/dist/components/dataaccess/AccessRequirementDashboard.js +4 -4
  242. package/dist/components/dataaccess/AccessRequirementDashboard.js.map +1 -1
  243. package/dist/components/dataaccess/AccessRequirementTable.js +1 -1
  244. package/dist/components/dataaccess/AccessRequirementTable.js.map +1 -1
  245. package/dist/components/dataaccess/EDucTemplateTable.d.ts.map +1 -1
  246. package/dist/components/dataaccess/EDucTemplateTable.js +13 -11
  247. package/dist/components/dataaccess/EDucTemplateTable.js.map +1 -1
  248. package/dist/components/dataaccess/FormTemplateTable.js +6 -6
  249. package/dist/components/dataaccess/FormTemplateTable.js.map +1 -1
  250. package/dist/components/dataaccess/ReviewerDashboard.js +17 -17
  251. package/dist/components/dataaccess/ReviewerDashboard.js.map +1 -1
  252. package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +4 -4
  253. package/dist/components/doi/CreateOrUpdateDoiModal.js +1 -1
  254. package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
  255. package/dist/components/download_list/DownloadDetails.d.ts.map +1 -1
  256. package/dist/components/download_list/DownloadDetails.js +12 -10
  257. package/dist/components/download_list/DownloadDetails.js.map +1 -1
  258. package/dist/components/entity/metadata/AnnotationsTable.js +1 -1
  259. package/dist/components/entity/metadata/AnnotationsTable.js.map +1 -1
  260. package/dist/components/entity/page/CreatedByModifiedBy.js +1 -1
  261. package/dist/components/entity/page/CreatedByModifiedBy.js.map +1 -1
  262. package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
  263. package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
  264. package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js +1 -1
  265. package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js.map +1 -1
  266. package/dist/components/error/ErrorChip.d.ts.map +1 -1
  267. package/dist/components/error/ErrorChip.js +2 -1
  268. package/dist/components/error/ErrorChip.js.map +1 -1
  269. package/dist/components/table/CsvPreview/CreateTableFromCsvDialog.js +14 -14
  270. package/dist/components/table/CsvPreview/CsvPreviewWithOptions.js +4 -4
  271. package/dist/components/table/CsvPreview/CsvPreviewWithOptions.js.map +1 -1
  272. package/dist/components/widgets/facet-nav/FacetNavPanel.js +1 -1
  273. package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
  274. package/dist/features/curator/dashboard/components/NextStepButton.d.ts.map +1 -1
  275. package/dist/features/curator/dashboard/components/NextStepButton.js +7 -6
  276. package/dist/features/curator/dashboard/components/NextStepButton.js.map +1 -1
  277. package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +8 -8
  278. package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
  279. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +4 -4
  280. package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
  281. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +4 -4
  282. package/dist/features/entity/metadata-task/components/MetadataTasksPage.js.map +1 -1
  283. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
  284. package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
  285. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js +4 -4
  286. package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js.map +1 -1
  287. package/dist/features/entity/metadata-task/create-task/TaskCategoryCard.js +1 -1
  288. package/dist/features/entity/metadata-task/create-task/TaskCategoryCard.js.map +1 -1
  289. package/dist/features/entity/metadata-task/create-task/TaskFormHeader.js +1 -1
  290. package/dist/features/entity/metadata-task/create-task/TaskFormHeader.js.map +1 -1
  291. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js +10 -10
  292. package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js.map +1 -1
  293. package/dist/features/team/invitation/components/OpenInvitationsToUserCard.js +1 -1
  294. package/dist/features/team/invitation/components/OpenInvitationsToUserCard.js.map +1 -1
  295. package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +8 -0
  296. package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -1
  297. package/dist/mocks/msw/handlers/aridhiaHandlers.js +52 -41
  298. package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -1
  299. package/dist/mocks/msw/handlers/entityHandlers.d.ts.map +1 -1
  300. package/dist/mocks/msw/handlers/entityHandlers.js +70 -67
  301. package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
  302. package/dist/mocks/msw/handlers/gridHandlers.js +2 -2
  303. package/dist/mocks/msw/handlers/gridHandlers.js.map +1 -1
  304. package/dist/mocks/msw/server.d.ts.map +1 -1
  305. package/dist/mocks/msw/server.js +4 -2
  306. package/dist/mocks/msw/server.js.map +1 -1
  307. package/dist/synapse-queries/user/useGetUserChallenges.d.ts.map +1 -1
  308. package/dist/synapse-queries/user/useGetUserChallenges.js.map +1 -1
  309. package/dist/theme/DefaultTheme.d.ts.map +1 -1
  310. package/dist/theme/DefaultTheme.js +4 -1
  311. package/dist/theme/DefaultTheme.js.map +1 -1
  312. package/dist/tsconfig.build.tsbuildinfo +1 -1
  313. package/dist/utils/APIConstants.d.ts.map +1 -1
  314. package/dist/utils/APIConstants.js.map +1 -1
  315. package/dist/utils/AppUtils/AppUtils.js +1 -1
  316. package/dist/utils/AppUtils/AppUtils.js.map +1 -1
  317. package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
  318. package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
  319. package/package.json +7 -6
@@ -1 +1 @@
1
- {"version":3,"file":"DatasetItemsEditor.js","names":[],"sources":["../../../../src/components/SynapseTable/datasets/DatasetItemsEditor.tsx"],"sourcesContent":["import React from 'react'\nimport WideButton from '@/components/styled/WideButton'\nimport { datasetItemToReference } from '@/components/SynapseTable/datasets/DatasetEditorUtils'\nimport {\n useGetEntity,\n useGetEntityPath,\n useUpdateEntity,\n} from '@/synapse-queries'\nimport { RequiredProperties } from '@/utils'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isDatasetCollection,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSet } from '@/utils/hooks'\nimport AddCircleTwoToneIcon from '@mui/icons-material/AddCircleTwoTone'\nimport {\n Alert,\n Button,\n Checkbox,\n Skeleton,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityRef,\n EntityRefCollectionView,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n createColumnHelper,\n getCoreRowModel,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { isEqual, upperFirst } from 'lodash-es'\nimport pluralize from 'pluralize'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { CreatedOnCell } from '../../EntityFinder/details/view/table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from '../../EntityFinder/details/view/table/EntityBadgeIconsCell'\nimport { EntityNameCell } from '../../EntityFinder/details/view/table/EntityNameCell'\nimport { ModifiedByCell } from '../../EntityFinder/details/view/table/ModifiedByCell'\nimport { ModifiedOnCell } from '../../EntityFinder/details/view/table/ModifiedOnCell'\nimport { ParentProjectCell } from '../../EntityFinder/details/view/table/ParentProjectCell'\nimport { EntityFinderModal } from '../../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../../EntityFinder/VersionSelectionType'\nimport { BlockingLoader } from '../../LoadingScreen/LoadingScreen'\nimport { SkeletonTable } from '../../Skeleton'\nimport WarningDialog from '../../SynapseForm/WarningDialog'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../TanStackTable/StyledVirtualTanStackTable'\nimport { displayToast } from '../../ToastMessage'\nimport { DatasetEditorCheckboxCell } from './DatasetEditorCheckboxCell'\nimport { DatasetEditorVersionCell } from './DatasetEditorVersionCell'\nimport { EntityFetchErrorCell } from './EntityFetchErrorCell'\n\nexport type DatasetItemsEditorTableData = EntityRef & {\n isSelected: boolean\n setSelected: (value: boolean) => void\n}\n\nenum DatasetItemsEditorColumn {\n ERROR_STATE = 'errorState',\n SELECTED = 'isSelected',\n NAME = 'name',\n ENTITY_ID = 'entityId',\n BADGES = 'badges',\n VERSION = 'version',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifieddOn',\n MODIFIED_BY = 'modifiedBy',\n PROJECT = 'project',\n}\n\nconst columnHelper = createColumnHelper<DatasetItemsEditorTableData>()\nfunction getColumns(\n opts: SelectAllCheckboxRendererProps & {\n changeVersionOnItem: (entityId: string, newVersion: number) => void\n },\n) {\n const {\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n } = opts\n return [\n columnHelper.display({\n id: DatasetItemsEditorColumn.ERROR_STATE,\n minSize: 35,\n maxSize: 35,\n size: 35,\n enableResizing: false,\n header: () => null,\n cell: EntityFetchErrorCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.SELECTED,\n minSize: 40,\n maxSize: 40,\n size: 40,\n enableResizing: false,\n header: () => (\n <SelectAllCheckboxRenderer\n datasetToUpdate={datasetToUpdate}\n selectedIds={selectedIds}\n clearSelectedIds={clearSelectedIds}\n addSelectedId={addSelectedId}\n allItemsAreSelected={allItemsAreSelected}\n />\n ),\n cell: DatasetEditorCheckboxCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.NAME,\n minSize: 50,\n size: 300,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: EntityNameCell,\n }),\n columnHelper.accessor(DatasetItemsEditorColumn.ENTITY_ID, {\n minSize: 50,\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.BADGES,\n minSize: 80,\n size: 80,\n enableResizing: true,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.VERSION,\n minSize: 150,\n size: 150,\n header: props => <ColumnHeader {...props} title={'Version'} />,\n cell: props => (\n <DatasetEditorVersionCell\n {...props}\n toggleSelection={datasetItem => {\n changeVersionOnItem(datasetItem.entityId, datasetItem.versionNumber)\n }}\n />\n ),\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.CREATED_ON,\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_ON,\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n cell: ModifiedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_BY,\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.PROJECT,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 300,\n cell: ParentProjectCell,\n }),\n ]\n}\n\nfunction getSelectableTypes(entity: EntityRefCollectionView) {\n if (isDataset(entity)) {\n return [EntityType.file]\n } else if (isDatasetCollection(entity)) {\n return [EntityType.dataset]\n } else {\n console.error(\n 'Cannot determine selectable types for entity type: ' +\n entity.concreteType,\n )\n return []\n }\n}\n\nexport function getCopy(entity?: EntityRefCollectionView) {\n const displayName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : 'Collection'\n let itemName = 'Item'\n let currentVersionName = 'Current Version'\n if (entity && isDataset(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.file)\n currentVersionName = 'Draft'\n } else if (entity && isDatasetCollection(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.dataset)\n }\n\n const entityFinderPopover =\n entity && isDataset(entity)\n ? `Use the left pane to browse projects and folders. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple folders. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n : `Use the left pane to browse projects. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple projects. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n\n return {\n ADD_ITEMS: `Add ${pluralize(itemName)}`,\n ADD_ITEMS_TO: `Add ${pluralize(itemName)} to ${displayName}`,\n REMOVE_ITEMS: `Remove ${pluralize(itemName)}`,\n NO_ITEMS_IN_THIS_DATASET: `No ${pluralize(\n itemName,\n )} in this ${displayName}`,\n SAVE_TO_CONTINUE: `Save the ${displayName} to continue`,\n CREATE_VERSION_TO_FREEZE: `Create a Version of this ${displayName} to freeze it in its current state`,\n ENTITY_SAVED: `${displayName} Saved`,\n SAVE_CHANGES: `Save changes to ${currentVersionName}`,\n ENTITY_FINDER_POPOVER: entityFinderPopover,\n ENTITY_FINDER_PROMPT: `Find ${pluralize(\n itemName,\n )} to add to the ${displayName}.`,\n PRECONDITION_FAILED_MESSAGE: `Re-retrieve the ${displayName} to get the latest changes. Your current changes will be lost.`,\n PRECONDITION_FAILED_TITLE: `${displayName} updated since last fetched`,\n PRECONDITION_FAILED_ACTION: `Retrieve ${displayName}`,\n NO_CHANGES_MADE: `You have not made any changes to the ${displayName}.`,\n }\n}\n\nfunction getDataSetDifference(\n oldDataSet: EntityRef[],\n changedItems: EntityRef[],\n) {\n const unchangedItems = oldDataSet.filter(\n oldItem =>\n !changedItems.find(newItem => newItem.entityId === oldItem.entityId),\n )\n const deletedItems = [...unchangedItems]\n const { updatedItems, newItems } = changedItems.reduce(\n (results, result) => {\n const oldItem = oldDataSet.find(old => old.entityId === result.entityId)\n if (oldItem) {\n if (result.versionNumber !== oldItem.versionNumber) {\n results['updatedItems'].push(result)\n } else {\n unchangedItems.push(result)\n }\n } else {\n results['newItems'].push(result)\n }\n return results\n },\n { updatedItems: [], newItems: [] } as {\n updatedItems: EntityRef[]\n newItems: EntityRef[]\n },\n )\n\n return { unchangedItems, updatedItems, newItems, deletedItems }\n}\n\nfunction getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate?: RequiredProperties<\n EntityRefCollectionView,\n 'items'\n >,\n datasetToUpdate?: RequiredProperties<EntityRefCollectionView, 'items'>,\n) {\n const { updatedItems, newItems, deletedItems } = getDataSetDifference(\n previousDatasetToUpdate?.items ?? [],\n datasetToUpdate?.items!,\n )\n let toastTitle = ''\n\n // \"X items(s) deleted\"\n if (deletedItems.length > 0) {\n toastTitle += `${deletedItems.length} Item${\n deletedItems.length === 1 ? '' : 's'\n } removed`\n } else {\n // \"Y item(s) added\"\n toastTitle += `${newItems.length} Item${\n newItems.length === 1 ? '' : 's'\n } added`\n\n // \"and Z item(s) updated\", only shown if there are updated items\n if (updatedItems.length > 0) {\n toastTitle += ` and ${updatedItems.length} Item${\n updatedItems.length === 1 ? '' : 's'\n } updated`\n }\n }\n return toastTitle\n}\n\nexport type DatasetItemsEditorProps = {\n /* The synId of the EntityRefCollectionView to modify */\n entityId: string\n /** Callback invoked when the editor changes state to contain un/saved changes. */\n onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void\n onSave?: () => void\n onClose?: () => void\n}\n\nconst ROW_HEIGHT = 48\n\ntype SelectAllCheckboxRendererProps = {\n datasetToUpdate: RequiredProperties<EntityRefCollectionView, 'items'>\n selectedIds: Omit<Set<string>, 'add' | 'delete' | 'clear'>\n addSelectedId: (...items: string[]) => void\n clearSelectedIds: () => void\n allItemsAreSelected: boolean\n}\n\nconst SelectAllCheckboxRenderer = (\n props: SelectAllCheckboxRendererProps,\n): React.ReactNode => {\n const {\n datasetToUpdate,\n clearSelectedIds,\n allItemsAreSelected,\n addSelectedId,\n } = props\n const isChecked = allItemsAreSelected\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={isChecked}\n disabled={datasetToUpdate.items.length === 0}\n onChange={() => {\n if (isChecked) {\n clearSelectedIds()\n } else {\n addSelectedId(...datasetToUpdate.items.map(item => item.entityId))\n }\n }}\n />\n )\n}\n\nfunction NoItemsPlaceholder(props: {\n titleCopy: string\n buttonCopy: string\n onButtonClick: () => void\n}) {\n const { titleCopy, buttonCopy, onButtonClick } = props\n return (\n <div className=\"NoItemsPlaceholder\">\n <Typography variant={'headline3'}>{titleCopy}</Typography>\n <WideButton\n variant=\"contained\"\n color=\"primary\"\n onClick={onButtonClick}\n startIcon={<AddCircleTwoToneIcon />}\n sx={{ mt: 2 }}\n >\n {buttonCopy}\n </WideButton>\n </div>\n )\n}\n\nexport function DatasetItemsEditor(props: DatasetItemsEditorProps) {\n const { entityId, onSave, onClose, onUnsavedChangesChange } = props\n const [showEntityFinder, setShowEntityFinder] = useState<boolean>(false)\n const [showWarningDialog, setShowWarningDialog] = useState<boolean>(false)\n\n // The current 'client state' of dataset that the user is currently editing. Updates to this state are not saved until the user clicks 'Save'.\n const [datasetToUpdate, setDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // The previous value of the datasetToUpdate variable. This is used to calculate a summary of bulk actions since the last update to the unsaved dataset state.\n const [previousDatasetToUpdate, setPreviousDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // Stores the `close` function that will be used to hide the last toast that prompted the user to save\n const [onCloseLastSavePromptToast, setOnCloseLastSavePromptToast] = useState<\n { close: () => void } | undefined\n >()\n\n const { data: datasetOnServer, refetch: refetchDataset } = useGetEntity<\n RequiredProperties<EntityRefCollectionView, 'items'>\n >(entityId, undefined, {\n staleTime: Infinity,\n })\n\n const hasChangedSinceLastSave = Boolean(\n datasetOnServer &&\n datasetToUpdate &&\n !isEqual(datasetOnServer, datasetToUpdate),\n )\n\n const {\n ADD_ITEMS,\n ADD_ITEMS_TO,\n REMOVE_ITEMS,\n NO_ITEMS_IN_THIS_DATASET,\n SAVE_TO_CONTINUE,\n CREATE_VERSION_TO_FREEZE,\n ENTITY_SAVED,\n SAVE_CHANGES,\n PRECONDITION_FAILED_TITLE,\n PRECONDITION_FAILED_MESSAGE,\n PRECONDITION_FAILED_ACTION,\n ENTITY_FINDER_POPOVER,\n ENTITY_FINDER_PROMPT,\n NO_CHANGES_MADE,\n } = useMemo(() => getCopy(datasetOnServer), [datasetOnServer])\n\n useEffect(() => {\n if (datasetOnServer) {\n // SWC-5876: Dataset Items may be undefined. This has the same inherent meaning as the empty list, so we'll just change it to save us some null checks.\n if (datasetOnServer.items == null) {\n datasetOnServer.items = []\n }\n setDatasetToUpdate(datasetOnServer)\n }\n }, [datasetOnServer])\n\n const {\n set: selectedIds,\n add: addSelectedId,\n remove: removeSelectedId,\n clear: clearSelectedIds,\n } = useSet<string>()\n const allItemsAreSelected = Boolean(\n datasetToUpdate && datasetToUpdate.items.length === selectedIds.size,\n )\n\n useEffect(() => {\n if (datasetToUpdate && datasetOnServer && onUnsavedChangesChange) {\n onUnsavedChangesChange(hasChangedSinceLastSave)\n }\n }, [\n datasetOnServer,\n datasetToUpdate,\n hasChangedSinceLastSave,\n onUnsavedChangesChange,\n ])\n\n // We get the project ID to show the \"Current Project\" context in the Entity Finder.\n const { data: path } = useGetEntityPath(entityId)\n const projectId = path?.path[1]?.id\n\n const { mutate, isPending: updateIsPending } =\n useUpdateEntity<EntityRefCollectionView>({\n onMutate: () => {\n // Close existing toast that prompted the user to save\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n setOnCloseLastSavePromptToast(undefined)\n }\n },\n onSuccess: () => {\n // The query should automatically be invalidated, but just in case\n void refetchDataset()\n\n if (onSave) {\n onSave()\n } else {\n // If onSave isn't specified, push a generic toast message.\n displayToast(CREATE_VERSION_TO_FREEZE, 'success', {\n title: ENTITY_SAVED,\n })\n }\n },\n onError: error => {\n if (error.status === 412) {\n displayToast(PRECONDITION_FAILED_MESSAGE, 'warning', {\n title: PRECONDITION_FAILED_TITLE,\n primaryButtonConfig: {\n text: PRECONDITION_FAILED_ACTION,\n onClick: () => {\n void refetchDataset()\n },\n },\n })\n } else {\n displayToast(error.reason, 'danger', {\n title: 'An Error Occurred',\n })\n }\n },\n })\n\n useEffect(() => {\n // When changes are made (but not saved) to the datasetToUpdate, show a notification that summarizes the change and prompts the user to save\n if (\n previousDatasetToUpdate &&\n datasetToUpdate &&\n !isEqual(previousDatasetToUpdate.items, datasetToUpdate.items) &&\n !updateIsPending\n ) {\n const toastMessageTitle = getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate,\n datasetToUpdate,\n )\n // Replace existing toast that prompts the user to save before showing the new one\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n }\n const onCloseToast = displayToast(SAVE_TO_CONTINUE, 'info', {\n title: toastMessageTitle,\n primaryButtonConfig: {\n text: SAVE_CHANGES,\n onClick: () => mutate(datasetToUpdate),\n },\n })\n setOnCloseLastSavePromptToast({ close: onCloseToast })\n }\n setPreviousDatasetToUpdate(datasetToUpdate)\n // Only run when datasetToUpdate changes\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [datasetToUpdate])\n\n const tableData = useMemo(\n () =>\n datasetToUpdate?.items.map(\n (item: EntityRef): DatasetItemsEditorTableData => {\n return {\n ...item,\n isSelected: selectedIds.has(item.entityId),\n setSelected: (value: boolean) => {\n return value\n ? addSelectedId(item.entityId)\n : removeSelectedId(item.entityId)\n },\n }\n },\n ) ?? [],\n [addSelectedId, datasetToUpdate?.items, removeSelectedId, selectedIds],\n )\n\n function addItemsToDataset(itemsToAdd: Reference[]) {\n setDatasetToUpdate(datasetToUpdate => {\n if (datasetToUpdate) {\n const refToDatasetItem = itemsToAdd.map(item => ({\n entityId: item.targetId,\n versionNumber: item.targetVersionNumber!,\n }))\n const { unchangedItems, updatedItems, newItems } = getDataSetDifference(\n datasetToUpdate.items,\n refToDatasetItem,\n )\n\n if (updatedItems.length == 0 && newItems.length == 0) {\n // No items were added or updated, so don't update the state variable.\n return datasetToUpdate\n }\n\n const items = [...unchangedItems, ...updatedItems, ...newItems]\n\n return {\n ...datasetToUpdate,\n items: items,\n }\n } else {\n console.warn(\n 'Cannot add items to the Collection because it is undefined. The Collection may not have been fetched yet.',\n )\n return datasetToUpdate\n }\n })\n clearSelectedIds()\n }\n\n function removeSelectedItemsFromDataset() {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.filter(\n datasetItem => !selectedIds.has(datasetItem.entityId),\n ),\n }))\n clearSelectedIds()\n }\n\n function changeVersionOnItem(entityId: string, newVersion: number) {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.map(datasetItem =>\n datasetItem.entityId === entityId\n ? { entityId: entityId, versionNumber: newVersion }\n : datasetItem,\n ),\n }))\n }\n\n const selectableTypes: EntityType[] | undefined = useMemo(() => {\n if (datasetOnServer) {\n return getSelectableTypes(datasetOnServer)\n } else {\n return undefined\n }\n }, [datasetOnServer])\n\n const columns = useMemo(() => {\n if (!datasetToUpdate) {\n return []\n }\n return getColumns({\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n })\n }, [\n addSelectedId,\n allItemsAreSelected,\n clearSelectedIds,\n datasetToUpdate,\n selectedIds,\n ])\n\n const table: Table<DatasetItemsEditorTableData> =\n useReactTable<DatasetItemsEditorTableData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n // There are no backend sort controls. The server only provides ID/version, and a dataset could be up to 10k items,\n // so client side sorting is non-trivial. We may consider fetching all entity headers upon user request.\n enableSorting: false,\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: tableData?.length ?? 0,\n estimateSize: () => ROW_HEIGHT, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const datasetItemsAsEntityFinderRef = useMemo(\n () => datasetToUpdate?.items.map(datasetItemToReference),\n [datasetToUpdate],\n )\n\n return (\n <div className=\"DatasetEditor\">\n <EntityFinderModal\n initialSelected={datasetItemsAsEntityFinderRef}\n configuration={{\n projectId: projectId,\n selectMultiple: true,\n initialScope: FinderScope.CURRENT_PROJECT,\n initialContainer: projectId ?? null,\n selectableTypes: selectableTypes,\n versionSelection: VersionSelectionType.REQUIRED,\n }}\n titleHelpPopoverProps={{\n markdownText: ENTITY_FINDER_POPOVER,\n helpUrl: 'https://help.synapse.org/docs/Datasets.2611281979.html',\n placement: 'right',\n }}\n promptCopy={ENTITY_FINDER_PROMPT}\n show={showEntityFinder}\n title={ADD_ITEMS_TO}\n confirmButtonCopy={'Apply changes'}\n onConfirm={items => {\n addItemsToDataset(items)\n setShowEntityFinder(false)\n }}\n onCancel={() => setShowEntityFinder(false)}\n />\n <WarningDialog\n title=\"Unsaved Changes\"\n content=\"Any unsaved changes will be lost. Are you sure you want to close the editor?\"\n confirmButtonText=\"Close Editor\"\n onConfirm={() => {\n if (onClose) {\n setShowWarningDialog(false)\n if (onUnsavedChangesChange) {\n onUnsavedChangesChange(false)\n }\n onClose()\n }\n }}\n open={showWarningDialog}\n onConfirmCallbackArgs={[]}\n onCancel={() => setShowWarningDialog(false)}\n />\n\n <div className=\"DatasetEditorTopBottomPanel\">\n <BlockingLoader show={updateIsPending} />\n <div className=\"ItemCount\">\n {datasetToUpdate ? (\n <Typography variant=\"headline3\">\n {datasetToUpdate.items.length === 0\n ? 'No'\n : datasetToUpdate.items.length.toLocaleString()}{' '}\n File\n {datasetToUpdate.items.length !== 1 && 's'}\n </Typography>\n ) : (\n <Skeleton variant=\"rectangular\" width={200} />\n )}\n </div>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={datasetToUpdate == null}\n onClick={() => setShowEntityFinder(true)}\n >\n {ADD_ITEMS}\n </Button>\n <Button\n disabled={selectedIds.size === 0}\n variant=\"outlined\"\n color=\"primary\"\n onClick={removeSelectedItemsFromDataset}\n >\n {REMOVE_ITEMS}\n </Button>\n </div>\n <div className=\"DatasetEditorTableContainer\">\n {datasetToUpdate && datasetToUpdate.items.length === 0 && (\n <NoItemsPlaceholder\n titleCopy={NO_ITEMS_IN_THIS_DATASET}\n buttonCopy={ADD_ITEMS}\n onButtonClick={() => setShowEntityFinder(true)}\n />\n )}\n {datasetToUpdate && datasetToUpdate.items.length > 0 && (\n <StyledVirtualTanStackTable<DatasetItemsEditorTableData>\n styledTableContainerProps={{\n className: 'DatasetEditorTable',\n ref: tableContainerRef,\n height: '350px',\n }}\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: {\n className: `DatasetEditorRow`,\n style: {\n height: `${ROW_HEIGHT}px`,\n maxHeight: `${ROW_HEIGHT}px`,\n },\n },\n }}\n />\n )}\n {!datasetToUpdate && (\n <SkeletonTable\n className=\"DatasetItemsEditorSkeleton\"\n numRows={8}\n numCols={6}\n rowHeight={`${ROW_HEIGHT}px`}\n />\n )}\n </div>\n <div className=\"DatasetEditorTopBottomPanel\">\n {hasChangedSinceLastSave && (\n <Alert severity=\"warning\">You have unsaved changes</Alert>\n )}\n <Button\n variant=\"outlined\"\n color=\"primary\"\n onClick={() => {\n if (hasChangedSinceLastSave) {\n setShowWarningDialog(true)\n } else if (onClose) {\n onClose()\n }\n }}\n >\n Cancel\n </Button>\n\n <Tooltip title={!hasChangedSinceLastSave && NO_CHANGES_MADE}>\n <div>\n <Button\n disabled={!datasetToUpdate || !hasChangedSinceLastSave}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => mutate(datasetToUpdate!)}\n >\n Save\n </Button>\n </div>\n </Tooltip>\n </div>\n </div>\n )\n}\n\nexport default DatasetItemsEditor\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatasetItemsEditor.js","names":[],"sources":["../../../../src/components/SynapseTable/datasets/DatasetItemsEditor.tsx"],"sourcesContent":["import React from 'react'\nimport WideButton from '@/components/styled/WideButton'\nimport { datasetItemToReference } from '@/components/SynapseTable/datasets/DatasetEditorUtils'\nimport {\n useGetEntity,\n useGetEntityPath,\n useUpdateEntity,\n} from '@/synapse-queries'\nimport { RequiredProperties } from '@/utils'\nimport {\n convertToEntityType,\n entityTypeToFriendlyName,\n isDataset,\n isDatasetCollection,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSet } from '@/utils/hooks'\nimport AddCircleTwoToneIcon from '@mui/icons-material/AddCircleTwoTone'\nimport {\n Alert,\n Button,\n Checkbox,\n Skeleton,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityRef,\n EntityRefCollectionView,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport {\n createColumnHelper,\n getCoreRowModel,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { isEqual, upperFirst } from 'lodash-es'\nimport pluralize from 'pluralize'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { CreatedOnCell } from '../../EntityFinder/details/view/table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from '../../EntityFinder/details/view/table/EntityBadgeIconsCell'\nimport { EntityNameCell } from '../../EntityFinder/details/view/table/EntityNameCell'\nimport { ModifiedByCell } from '../../EntityFinder/details/view/table/ModifiedByCell'\nimport { ModifiedOnCell } from '../../EntityFinder/details/view/table/ModifiedOnCell'\nimport { ParentProjectCell } from '../../EntityFinder/details/view/table/ParentProjectCell'\nimport { EntityFinderModal } from '../../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../../EntityFinder/VersionSelectionType'\nimport { BlockingLoader } from '../../LoadingScreen/LoadingScreen'\nimport { SkeletonTable } from '../../Skeleton'\nimport WarningDialog from '../../SynapseForm/WarningDialog'\nimport ColumnHeader from '../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../TanStackTable/StyledVirtualTanStackTable'\nimport { displayToast } from '../../ToastMessage'\nimport { DatasetEditorCheckboxCell } from './DatasetEditorCheckboxCell'\nimport { DatasetEditorVersionCell } from './DatasetEditorVersionCell'\nimport { EntityFetchErrorCell } from './EntityFetchErrorCell'\n\nexport type DatasetItemsEditorTableData = EntityRef & {\n isSelected: boolean\n setSelected: (value: boolean) => void\n}\n\nenum DatasetItemsEditorColumn {\n ERROR_STATE = 'errorState',\n SELECTED = 'isSelected',\n NAME = 'name',\n ENTITY_ID = 'entityId',\n BADGES = 'badges',\n VERSION = 'version',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifieddOn',\n MODIFIED_BY = 'modifiedBy',\n PROJECT = 'project',\n}\n\nconst columnHelper = createColumnHelper<DatasetItemsEditorTableData>()\nfunction getColumns(\n opts: SelectAllCheckboxRendererProps & {\n changeVersionOnItem: (entityId: string, newVersion: number) => void\n },\n) {\n const {\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n } = opts\n return [\n columnHelper.display({\n id: DatasetItemsEditorColumn.ERROR_STATE,\n minSize: 35,\n maxSize: 35,\n size: 35,\n enableResizing: false,\n header: () => null,\n cell: EntityFetchErrorCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.SELECTED,\n minSize: 40,\n maxSize: 40,\n size: 40,\n enableResizing: false,\n header: () => (\n <SelectAllCheckboxRenderer\n datasetToUpdate={datasetToUpdate}\n selectedIds={selectedIds}\n clearSelectedIds={clearSelectedIds}\n addSelectedId={addSelectedId}\n allItemsAreSelected={allItemsAreSelected}\n />\n ),\n cell: DatasetEditorCheckboxCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.NAME,\n minSize: 50,\n size: 300,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: EntityNameCell,\n }),\n columnHelper.accessor(DatasetItemsEditorColumn.ENTITY_ID, {\n minSize: 50,\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.BADGES,\n minSize: 80,\n size: 80,\n enableResizing: true,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.VERSION,\n minSize: 150,\n size: 150,\n header: props => <ColumnHeader {...props} title={'Version'} />,\n cell: props => (\n <DatasetEditorVersionCell\n {...props}\n toggleSelection={datasetItem => {\n changeVersionOnItem(datasetItem.entityId, datasetItem.versionNumber)\n }}\n />\n ),\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.CREATED_ON,\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_ON,\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n cell: ModifiedOnCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.MODIFIED_BY,\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n }),\n columnHelper.display({\n id: DatasetItemsEditorColumn.PROJECT,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 300,\n cell: ParentProjectCell,\n }),\n ]\n}\n\nfunction getSelectableTypes(entity: EntityRefCollectionView) {\n if (isDataset(entity)) {\n return [EntityType.file]\n } else if (isDatasetCollection(entity)) {\n return [EntityType.dataset]\n } else {\n console.error(\n 'Cannot determine selectable types for entity type: ' +\n entity.concreteType,\n )\n return []\n }\n}\n\nexport function getCopy(entity?: EntityRefCollectionView) {\n const displayName = entity\n ? entityTypeToFriendlyName(convertToEntityType(entity.concreteType))\n : 'Collection'\n let itemName = 'Item'\n let currentVersionName = 'Current Version'\n if (entity && isDataset(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.file)\n currentVersionName = 'Draft'\n } else if (entity && isDatasetCollection(entity)) {\n itemName = entityTypeToFriendlyName(EntityType.dataset)\n }\n\n const entityFinderPopover =\n entity && isDataset(entity)\n ? `Use the left pane to browse projects and folders. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple folders. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n : `Use the left pane to browse projects. Select ${pluralize(\n itemName,\n )} from the right pane to add to this ${displayName}. ${upperFirst(\n pluralize(itemName),\n )} in a ${displayName} can be added from multiple projects. You can also use Search to find and select ${pluralize(\n itemName,\n )}.`\n\n return {\n ADD_ITEMS: `Add ${pluralize(itemName)}`,\n ADD_ITEMS_TO: `Add ${pluralize(itemName)} to ${displayName}`,\n REMOVE_ITEMS: `Remove ${pluralize(itemName)}`,\n NO_ITEMS_IN_THIS_DATASET: `No ${pluralize(\n itemName,\n )} in this ${displayName}`,\n SAVE_TO_CONTINUE: `Save the ${displayName} to continue`,\n CREATE_VERSION_TO_FREEZE: `Create a Version of this ${displayName} to freeze it in its current state`,\n ENTITY_SAVED: `${displayName} Saved`,\n SAVE_CHANGES: `Save changes to ${currentVersionName}`,\n ENTITY_FINDER_POPOVER: entityFinderPopover,\n ENTITY_FINDER_PROMPT: `Find ${pluralize(\n itemName,\n )} to add to the ${displayName}.`,\n PRECONDITION_FAILED_MESSAGE: `Re-retrieve the ${displayName} to get the latest changes. Your current changes will be lost.`,\n PRECONDITION_FAILED_TITLE: `${displayName} updated since last fetched`,\n PRECONDITION_FAILED_ACTION: `Retrieve ${displayName}`,\n NO_CHANGES_MADE: `You have not made any changes to the ${displayName}.`,\n }\n}\n\nfunction getDataSetDifference(\n oldDataSet: EntityRef[],\n changedItems: EntityRef[],\n) {\n const unchangedItems = oldDataSet.filter(\n oldItem =>\n !changedItems.find(newItem => newItem.entityId === oldItem.entityId),\n )\n const deletedItems = [...unchangedItems]\n const { updatedItems, newItems } = changedItems.reduce(\n (results, result) => {\n const oldItem = oldDataSet.find(old => old.entityId === result.entityId)\n if (oldItem) {\n if (result.versionNumber !== oldItem.versionNumber) {\n results['updatedItems'].push(result)\n } else {\n unchangedItems.push(result)\n }\n } else {\n results['newItems'].push(result)\n }\n return results\n },\n { updatedItems: [], newItems: [] } as {\n updatedItems: EntityRef[]\n newItems: EntityRef[]\n },\n )\n\n return { unchangedItems, updatedItems, newItems, deletedItems }\n}\n\nfunction getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate?: RequiredProperties<\n EntityRefCollectionView,\n 'items'\n >,\n datasetToUpdate?: RequiredProperties<EntityRefCollectionView, 'items'>,\n) {\n const { updatedItems, newItems, deletedItems } = getDataSetDifference(\n previousDatasetToUpdate?.items ?? [],\n datasetToUpdate?.items!,\n )\n let toastTitle = ''\n\n // \"X items(s) deleted\"\n if (deletedItems.length > 0) {\n toastTitle += `${deletedItems.length} Item${\n deletedItems.length === 1 ? '' : 's'\n } removed`\n } else {\n // \"Y item(s) added\"\n toastTitle += `${newItems.length} Item${\n newItems.length === 1 ? '' : 's'\n } added`\n\n // \"and Z item(s) updated\", only shown if there are updated items\n if (updatedItems.length > 0) {\n toastTitle += ` and ${updatedItems.length} Item${\n updatedItems.length === 1 ? '' : 's'\n } updated`\n }\n }\n return toastTitle\n}\n\nexport type DatasetItemsEditorProps = {\n /* The synId of the EntityRefCollectionView to modify */\n entityId: string\n /** Callback invoked when the editor changes state to contain un/saved changes. */\n onUnsavedChangesChange?: (hasUnsavedChanges: boolean) => void\n onSave?: () => void\n onClose?: () => void\n}\n\nconst ROW_HEIGHT = 48\n\ntype SelectAllCheckboxRendererProps = {\n datasetToUpdate: RequiredProperties<EntityRefCollectionView, 'items'>\n selectedIds: Omit<Set<string>, 'add' | 'delete' | 'clear'>\n addSelectedId: (...items: string[]) => void\n clearSelectedIds: () => void\n allItemsAreSelected: boolean\n}\n\nconst SelectAllCheckboxRenderer = (\n props: SelectAllCheckboxRendererProps,\n): React.ReactNode => {\n const {\n datasetToUpdate,\n clearSelectedIds,\n allItemsAreSelected,\n addSelectedId,\n } = props\n const isChecked = allItemsAreSelected\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={isChecked}\n disabled={datasetToUpdate.items.length === 0}\n onChange={() => {\n if (isChecked) {\n clearSelectedIds()\n } else {\n addSelectedId(...datasetToUpdate.items.map(item => item.entityId))\n }\n }}\n />\n )\n}\n\nfunction NoItemsPlaceholder(props: {\n titleCopy: string\n buttonCopy: string\n onButtonClick: () => void\n}) {\n const { titleCopy, buttonCopy, onButtonClick } = props\n return (\n <div className=\"NoItemsPlaceholder\">\n <Typography variant={'headline3'}>{titleCopy}</Typography>\n <WideButton\n variant=\"contained\"\n color=\"primary\"\n onClick={onButtonClick}\n startIcon={<AddCircleTwoToneIcon />}\n sx={{ mt: 2 }}\n >\n {buttonCopy}\n </WideButton>\n </div>\n )\n}\n\nexport function DatasetItemsEditor(props: DatasetItemsEditorProps) {\n const { entityId, onSave, onClose, onUnsavedChangesChange } = props\n const [showEntityFinder, setShowEntityFinder] = useState<boolean>(false)\n const [showWarningDialog, setShowWarningDialog] = useState<boolean>(false)\n\n // The current 'client state' of dataset that the user is currently editing. Updates to this state are not saved until the user clicks 'Save'.\n const [datasetToUpdate, setDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // The previous value of the datasetToUpdate variable. This is used to calculate a summary of bulk actions since the last update to the unsaved dataset state.\n const [previousDatasetToUpdate, setPreviousDatasetToUpdate] =\n useState<RequiredProperties<EntityRefCollectionView, 'items'>>()\n\n // Stores the `close` function that will be used to hide the last toast that prompted the user to save\n const [onCloseLastSavePromptToast, setOnCloseLastSavePromptToast] = useState<\n { close: () => void } | undefined\n >()\n\n const { data: datasetOnServer, refetch: refetchDataset } = useGetEntity<\n RequiredProperties<EntityRefCollectionView, 'items'>\n >(entityId, undefined, {\n staleTime: Infinity,\n })\n\n const hasChangedSinceLastSave = Boolean(\n datasetOnServer &&\n datasetToUpdate &&\n !isEqual(datasetOnServer, datasetToUpdate),\n )\n\n const {\n ADD_ITEMS,\n ADD_ITEMS_TO,\n REMOVE_ITEMS,\n NO_ITEMS_IN_THIS_DATASET,\n SAVE_TO_CONTINUE,\n CREATE_VERSION_TO_FREEZE,\n ENTITY_SAVED,\n SAVE_CHANGES,\n PRECONDITION_FAILED_TITLE,\n PRECONDITION_FAILED_MESSAGE,\n PRECONDITION_FAILED_ACTION,\n ENTITY_FINDER_POPOVER,\n ENTITY_FINDER_PROMPT,\n NO_CHANGES_MADE,\n } = useMemo(() => getCopy(datasetOnServer), [datasetOnServer])\n\n useEffect(() => {\n if (datasetOnServer) {\n // SWC-5876: Dataset Items may be undefined. This has the same inherent meaning as the empty list, so we'll just change it to save us some null checks.\n if (datasetOnServer.items == null) {\n datasetOnServer.items = []\n }\n setDatasetToUpdate(datasetOnServer)\n }\n }, [datasetOnServer])\n\n const {\n set: selectedIds,\n add: addSelectedId,\n remove: removeSelectedId,\n clear: clearSelectedIds,\n } = useSet<string>()\n const allItemsAreSelected = Boolean(\n datasetToUpdate && datasetToUpdate.items.length === selectedIds.size,\n )\n\n useEffect(() => {\n if (datasetToUpdate && datasetOnServer && onUnsavedChangesChange) {\n onUnsavedChangesChange(hasChangedSinceLastSave)\n }\n }, [\n datasetOnServer,\n datasetToUpdate,\n hasChangedSinceLastSave,\n onUnsavedChangesChange,\n ])\n\n // We get the project ID to show the \"Current Project\" context in the Entity Finder.\n const { data: path } = useGetEntityPath(entityId)\n const projectId = path?.path[1]?.id\n\n const { mutate, isPending: updateIsPending } =\n useUpdateEntity<EntityRefCollectionView>({\n onMutate: () => {\n // Close existing toast that prompted the user to save\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n setOnCloseLastSavePromptToast(undefined)\n }\n },\n onSuccess: () => {\n // The query should automatically be invalidated, but just in case\n void refetchDataset()\n\n if (onSave) {\n onSave()\n } else {\n // If onSave isn't specified, push a generic toast message.\n displayToast(CREATE_VERSION_TO_FREEZE, 'success', {\n title: ENTITY_SAVED,\n })\n }\n },\n onError: error => {\n if (error.status === 412) {\n displayToast(PRECONDITION_FAILED_MESSAGE, 'warning', {\n title: PRECONDITION_FAILED_TITLE,\n primaryButtonConfig: {\n text: PRECONDITION_FAILED_ACTION,\n onClick: () => {\n void refetchDataset()\n },\n },\n })\n } else {\n displayToast(error.reason, 'danger', {\n title: 'An Error Occurred',\n })\n }\n },\n })\n\n useEffect(() => {\n // When changes are made (but not saved) to the datasetToUpdate, show a notification that summarizes the change and prompts the user to save\n if (\n previousDatasetToUpdate &&\n datasetToUpdate &&\n !isEqual(previousDatasetToUpdate.items, datasetToUpdate.items) &&\n !updateIsPending\n ) {\n const toastMessageTitle = getDatasetChangedToastMessageTitle(\n previousDatasetToUpdate,\n datasetToUpdate,\n )\n // Replace existing toast that prompts the user to save before showing the new one\n if (onCloseLastSavePromptToast) {\n onCloseLastSavePromptToast.close()\n }\n const onCloseToast = displayToast(SAVE_TO_CONTINUE, 'info', {\n title: toastMessageTitle,\n primaryButtonConfig: {\n text: SAVE_CHANGES,\n onClick: () => mutate(datasetToUpdate),\n },\n })\n setOnCloseLastSavePromptToast({ close: onCloseToast })\n }\n setPreviousDatasetToUpdate(datasetToUpdate)\n // Only run when datasetToUpdate changes\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [datasetToUpdate])\n\n const tableData = useMemo(\n () =>\n datasetToUpdate?.items.map(\n (item: EntityRef): DatasetItemsEditorTableData => {\n return {\n ...item,\n isSelected: selectedIds.has(item.entityId),\n setSelected: (value: boolean) => {\n return value\n ? addSelectedId(item.entityId)\n : removeSelectedId(item.entityId)\n },\n }\n },\n ) ?? [],\n [addSelectedId, datasetToUpdate?.items, removeSelectedId, selectedIds],\n )\n\n function addItemsToDataset(itemsToAdd: Reference[]) {\n setDatasetToUpdate(datasetToUpdate => {\n if (datasetToUpdate) {\n const refToDatasetItem = itemsToAdd.map(item => ({\n entityId: item.targetId,\n versionNumber: item.targetVersionNumber!,\n }))\n const { unchangedItems, updatedItems, newItems } = getDataSetDifference(\n datasetToUpdate.items,\n refToDatasetItem,\n )\n\n if (updatedItems.length == 0 && newItems.length == 0) {\n // No items were added or updated, so don't update the state variable.\n return datasetToUpdate\n }\n\n const items = [...unchangedItems, ...updatedItems, ...newItems]\n\n return {\n ...datasetToUpdate,\n items: items,\n }\n } else {\n console.warn(\n 'Cannot add items to the Collection because it is undefined. The Collection may not have been fetched yet.',\n )\n return datasetToUpdate\n }\n })\n clearSelectedIds()\n }\n\n function removeSelectedItemsFromDataset() {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.filter(\n datasetItem => !selectedIds.has(datasetItem.entityId),\n ),\n }))\n clearSelectedIds()\n }\n\n function changeVersionOnItem(entityId: string, newVersion: number) {\n setDatasetToUpdate(dataset => ({\n ...dataset!,\n items: dataset!.items.map(datasetItem =>\n datasetItem.entityId === entityId\n ? { entityId: entityId, versionNumber: newVersion }\n : datasetItem,\n ),\n }))\n }\n\n const selectableTypes: EntityType[] | undefined = useMemo(() => {\n if (datasetOnServer) {\n return getSelectableTypes(datasetOnServer)\n } else {\n return undefined\n }\n }, [datasetOnServer])\n\n const columns = useMemo(() => {\n if (!datasetToUpdate) {\n return []\n }\n return getColumns({\n datasetToUpdate,\n selectedIds,\n clearSelectedIds,\n addSelectedId,\n allItemsAreSelected,\n changeVersionOnItem,\n })\n }, [\n addSelectedId,\n allItemsAreSelected,\n clearSelectedIds,\n datasetToUpdate,\n selectedIds,\n ])\n\n const table: Table<DatasetItemsEditorTableData> =\n useReactTable<DatasetItemsEditorTableData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n // There are no backend sort controls. The server only provides ID/version, and a dataset could be up to 10k items,\n // so client side sorting is non-trivial. We may consider fetching all entity headers upon user request.\n enableSorting: false,\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: tableData?.length ?? 0,\n estimateSize: () => ROW_HEIGHT, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const datasetItemsAsEntityFinderRef = useMemo(\n () => datasetToUpdate?.items.map(datasetItemToReference),\n [datasetToUpdate],\n )\n\n return (\n <div className=\"DatasetEditor\">\n <EntityFinderModal\n initialSelected={datasetItemsAsEntityFinderRef}\n configuration={{\n projectId: projectId,\n selectMultiple: true,\n initialScope: FinderScope.CURRENT_PROJECT,\n initialContainer: projectId ?? null,\n selectableTypes: selectableTypes,\n versionSelection: VersionSelectionType.REQUIRED,\n }}\n titleHelpPopoverProps={{\n markdownText: ENTITY_FINDER_POPOVER,\n helpUrl: 'https://help.synapse.org/docs/Datasets.2611281979.html',\n placement: 'right',\n }}\n promptCopy={ENTITY_FINDER_PROMPT}\n show={showEntityFinder}\n title={ADD_ITEMS_TO}\n confirmButtonCopy={'Apply changes'}\n onConfirm={items => {\n addItemsToDataset(items)\n setShowEntityFinder(false)\n }}\n onCancel={() => setShowEntityFinder(false)}\n />\n <WarningDialog\n title=\"Unsaved Changes\"\n content=\"Any unsaved changes will be lost. Are you sure you want to close the editor?\"\n confirmButtonText=\"Close Editor\"\n onConfirm={() => {\n if (onClose) {\n setShowWarningDialog(false)\n if (onUnsavedChangesChange) {\n onUnsavedChangesChange(false)\n }\n onClose()\n }\n }}\n open={showWarningDialog}\n onConfirmCallbackArgs={[]}\n onCancel={() => setShowWarningDialog(false)}\n />\n\n <div className=\"DatasetEditorTopBottomPanel\">\n <BlockingLoader show={updateIsPending} />\n <div className=\"ItemCount\">\n {datasetToUpdate ? (\n <Typography variant=\"headline3\">\n {datasetToUpdate.items.length === 0\n ? 'No'\n : datasetToUpdate.items.length.toLocaleString()}{' '}\n File\n {datasetToUpdate.items.length !== 1 && 's'}\n </Typography>\n ) : (\n <Skeleton variant=\"rectangular\" width={200} />\n )}\n </div>\n\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={datasetToUpdate == null}\n onClick={() => setShowEntityFinder(true)}\n >\n {ADD_ITEMS}\n </Button>\n <Button\n disabled={selectedIds.size === 0}\n variant=\"outlined\"\n color=\"primary\"\n onClick={removeSelectedItemsFromDataset}\n >\n {REMOVE_ITEMS}\n </Button>\n </div>\n <div className=\"DatasetEditorTableContainer\">\n {datasetToUpdate && datasetToUpdate.items.length === 0 && (\n <NoItemsPlaceholder\n titleCopy={NO_ITEMS_IN_THIS_DATASET}\n buttonCopy={ADD_ITEMS}\n onButtonClick={() => setShowEntityFinder(true)}\n />\n )}\n {datasetToUpdate && datasetToUpdate.items.length > 0 && (\n <StyledVirtualTanStackTable<DatasetItemsEditorTableData>\n styledTableContainerProps={{\n className: 'DatasetEditorTable',\n ref: tableContainerRef,\n height: '350px',\n }}\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: {\n className: `DatasetEditorRow`,\n style: {\n height: `${ROW_HEIGHT}px`,\n maxHeight: `${ROW_HEIGHT}px`,\n },\n },\n }}\n />\n )}\n {!datasetToUpdate && (\n <SkeletonTable\n className=\"DatasetItemsEditorSkeleton\"\n numRows={8}\n numCols={6}\n rowHeight={`${ROW_HEIGHT}px`}\n />\n )}\n </div>\n <div className=\"DatasetEditorTopBottomPanel\">\n {hasChangedSinceLastSave && (\n <Alert severity=\"warning\">You have unsaved changes</Alert>\n )}\n <Button\n variant=\"outlined\"\n color=\"primary\"\n onClick={() => {\n if (hasChangedSinceLastSave) {\n setShowWarningDialog(true)\n } else if (onClose) {\n onClose()\n }\n }}\n >\n Cancel\n </Button>\n\n <Tooltip title={!hasChangedSinceLastSave && NO_CHANGES_MADE}>\n <div>\n <Button\n disabled={!datasetToUpdate || !hasChangedSinceLastSave}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => mutate(datasetToUpdate!)}\n >\n Save\n </Button>\n </div>\n </Tooltip>\n </div>\n </div>\n )\n}\n\nexport default DatasetItemsEditor\n"],"mappings":"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"}
@@ -10,7 +10,7 @@ import { isArray as h, isEmpty as g, isEqual as _ } from "lodash-es";
10
10
  import { Box as v, Checkbox as re, FormControl as y, Link as ie, MenuItem as b, Select as x, TextField as S, Tooltip as C } from "@mui/material";
11
11
  import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
12
12
  import { VIEW_CONCRETE_TYPE_VALUES as D } from "@sage-bionetworks/synapse-types";
13
- import { InfoTwoTone as O } from "@mui/icons-material";
13
+ import O from "@mui/icons-material/InfoTwoTone";
14
14
  import { useAtomValue as k, useSetAtom as ae } from "jotai";
15
15
  import A from "@mui/material/FormHelperText";
16
16
  import { selectAtom as j } from "jotai/utils";
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnModelForm.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/ColumnModelForm.tsx"],"sourcesContent":["import { convertToConcreteEntityType } from '@/utils/functions/EntityTypeUtils'\nimport { InfoTwoTone } from '@mui/icons-material'\nimport {\n Box,\n Checkbox,\n FormControl,\n Link,\n MenuItem,\n Select,\n SxProps,\n TextField,\n Tooltip,\n} from '@mui/material'\nimport FormHelperText from '@mui/material/FormHelperText'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ColumnModel,\n ColumnTypeEnum,\n FacetType,\n VIEW_CONCRETE_TYPE_VALUES,\n FacetColumnSortConfig,\n} from '@sage-bionetworks/synapse-types'\nimport { useAtomValue, useSetAtom } from 'jotai'\nimport { selectAtom } from 'jotai/utils'\nimport { isArray, isEmpty, isEqual } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { ZodIssue } from 'zod'\nimport DefaultValueField from './ColumnModelFormFields/DefaultValueField'\nimport { FieldWithRecommendedMinimum } from './ColumnModelFormFields/FieldWithRecommendedMinimum'\nimport MultiValueField from './ColumnModelFormFields/MultiValueField'\nimport {\n canHaveDefault,\n canHaveMaxListLength,\n canHaveRestrictedValues,\n canHaveSize,\n configureFacetsForType,\n getAllowedColumnTypes,\n getColumnTypeFriendlyName,\n getFacetTypeFriendlyName,\n getFormDataValueAsNumber,\n getMaxListLengthForType,\n getMaxSizeForType,\n} from './TableColumnSchemaEditorUtils'\nimport { HIERARCHY_VERTICAL_LINE_COMPONENT } from './TableColumnSchemaForm'\nimport { tableColumnSchemaFormDataAtom } from './TableColumnSchemaFormReducer'\nimport {\n ColumnModelFormData,\n JsonSubColumnModelFormData,\n} from './Validators/ColumnModelValidator'\n\ntype ColumnModelFormProps = {\n entityType: EntityType\n columnModelIndex: number\n jsonSubColumnIndex?: number\n /* Default Columns are read-only, except for the facetType */\n isDefaultColumn: boolean\n disabled?: boolean\n /* Can be used to override the schema used for validating ColumnModels */\n validationErrors?: ZodIssue[] | null\n defaultAnnotationModel?: ColumnModel | null\n originalColumnModel?: ColumnModel | null\n}\nconst jsonSubColumnFieldSx: SxProps = {\n height: '28px',\n fontSize: '12px',\n}\nconst topLevelColumnModelFieldSx: SxProps = {\n height: '38px',\n fontSize: '14px',\n}\n\nfunction renderDefaultValue(\n defaultValue: string | unknown[] | undefined,\n _columnType: ColumnTypeEnum,\n): string {\n if (defaultValue == null) {\n return ''\n }\n\n if (isArray(defaultValue)) {\n return defaultValue.map(String).join(', ')\n }\n return defaultValue\n}\n\n// Helper type for the combined sort configuration value\ntype FacetSortValue =\n | 'FREQUENCY_DESC'\n | 'FREQUENCY_ASC'\n | 'VALUE_DESC'\n | 'VALUE_ASC'\n | ''\n\n/**\n * Converts a FacetColumnSortConfig object to a single string value for the select dropdown\n */\nfunction facetSortConfigToValue(\n config: FacetColumnSortConfig | undefined,\n): FacetSortValue {\n if (!config || (!config.property && !config.direction)) {\n return ''\n }\n const property = config.property || 'FREQUENCY'\n const direction = config.direction || 'DESC'\n return `${property}_${direction}` as FacetSortValue\n}\n\n/**\n * Converts a select dropdown value to a FacetColumnSortConfig object\n */\nfunction valueToFacetSortConfig(\n value: FacetSortValue,\n): FacetColumnSortConfig | undefined {\n if (!value) {\n return undefined\n }\n const [property, direction] = value.split('_') as [\n 'FREQUENCY' | 'VALUE',\n 'DESC' | 'ASC',\n ]\n return { property, direction }\n}\n\n/*\n * Disable immediate MUI/Emotion style injection because it causes performance issues when adding many columns at once.\n * This can be a common occurence when adding annotation columns\n */\nconst DISABLE_INJECTING_GLOBAL_STYLES_VALUE = true\n\nexport default function ColumnModelForm(props: ColumnModelFormProps) {\n const {\n columnModelIndex,\n jsonSubColumnIndex,\n entityType,\n isDefaultColumn,\n disabled = false,\n validationErrors = null,\n defaultAnnotationModel,\n originalColumnModel,\n } = props\n const isJsonSubColumn = jsonSubColumnIndex != undefined\n const dispatch = useSetAtom(tableColumnSchemaFormDataAtom)\n const isView = (VIEW_CONCRETE_TYPE_VALUES as readonly string[]).includes(\n convertToConcreteEntityType(entityType),\n )\n\n const columnModelAtom = useMemo(\n () =>\n selectAtom(\n tableColumnSchemaFormDataAtom,\n v =>\n isJsonSubColumn\n ? v[columnModelIndex].jsonSubColumns![jsonSubColumnIndex]\n : v[columnModelIndex],\n isEqual,\n ),\n [columnModelIndex, isJsonSubColumn, jsonSubColumnIndex],\n )\n\n const columnModel = useAtomValue(columnModelAtom)\n\n const allowedColumnTypes = useMemo(\n () => getAllowedColumnTypes(isView, isJsonSubColumn),\n [isView, isJsonSubColumn],\n )\n\n const allowedFacetTypes = useMemo(\n () => configureFacetsForType(columnModel.columnType, isJsonSubColumn),\n [columnModel.columnType, isJsonSubColumn],\n )\n const fieldSx: SxProps = useMemo(\n () => (isJsonSubColumn ? jsonSubColumnFieldSx : topLevelColumnModelFieldSx),\n [isJsonSubColumn],\n )\n\n const errorsByField = useMemo(() => {\n if (validationErrors && isArray(validationErrors)) {\n const errorsByField: Record<string, string> = {}\n validationErrors.forEach(e => {\n if (e.path) {\n errorsByField[String(e.path[e.path.length - 1])] = e.message\n }\n })\n return errorsByField\n }\n return {}\n }, [validationErrors])\n\n return (\n <>\n <Box\n sx={{\n display: 'grid',\n gridColumn: '1 / span 11',\n gridTemplateColumns: 'subgrid',\n }}\n >\n {isJsonSubColumn && (\n <Box sx={{ gridColumn: '1 / span 1' }}>\n {HIERARCHY_VERTICAL_LINE_COMPONENT}\n </Box>\n )}\n <Box\n data-testid={`ColumnModelForm`}\n sx={{\n display: 'flex',\n alignItems: 'start',\n gridColumn: isJsonSubColumn ? '2 / span 1' : ' 1 / span 1',\n // Checkbox is offset from top; vertical centering causes issues when validation errors are displayed\n mt: isJsonSubColumn ? '0px' : '5px',\n }}\n >\n <Checkbox\n checked={columnModel.isSelected}\n inputProps={{ 'aria-label': 'Select' }}\n disabled={disabled}\n onChange={() => {\n dispatch({\n type: 'toggleSelect',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n })\n }}\n />\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n gridColumn: isJsonSubColumn\n ? /* If this is a JSON Subcolumn, we reduce the width of this grid column to create space to render the visual hierarchical line */\n '3 / span 1'\n : /* Otherwise, span across both grid columns */\n '2 / span 2',\n }}\n >\n {isDefaultColumn ? (\n columnModel.name\n ) : (\n <TextField\n value={columnModel.name}\n placeholder={isJsonSubColumn ? 'Facet name' : 'Column name'}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n name: e.target.value,\n },\n })\n }}\n disabled={disabled}\n fullWidth\n error={!!errorsByField['name']}\n helperText={errorsByField['name']}\n slotProps={{\n input: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Name',\n },\n },\n },\n }}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n getColumnTypeFriendlyName(columnModel.columnType)\n ) : (\n <FormControl fullWidth>\n <Select\n label=\"Column Type\"\n value={columnModel.columnType}\n onChange={e => {\n dispatch({\n type: 'changeColumnModelType',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n newColumnType: e.target.value as ColumnTypeEnum,\n })\n }}\n slotProps={{\n input: {\n 'aria-label': 'Column Type',\n },\n }}\n sx={fieldSx}\n disabled={disabled}\n error={!!errorsByField['columnType']}\n >\n {allowedColumnTypes.map(value => {\n return (\n <MenuItem value={value} key={value}>\n {getColumnTypeFriendlyName(value)}\n </MenuItem>\n )\n })}\n </Select>\n {errorsByField['columnType'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['columnType']}\n </FormHelperText>\n )}\n </FormControl>\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n ((columnModel as ColumnModelFormData).maximumSize ?? '')\n ) : (\n <FieldWithRecommendedMinimum\n value={(columnModel as ColumnModelFormData).maximumSize ?? ''}\n originalValue={originalColumnModel?.maximumSize}\n recommendedValue={defaultAnnotationModel?.maximumSize}\n columnType={columnModel.columnType as ColumnTypeEnum}\n disabled={disabled || !canHaveSize(columnModel.columnType)}\n InputProps={{\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n\n slotProps: {\n input: {\n 'aria-label': 'Maximum Size',\n min: 1,\n max: canHaveSize(columnModel.columnType)\n ? getMaxSizeForType(columnModel.columnType)\n : undefined,\n },\n },\n sx: fieldSx,\n }}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n maximumSize: e.target.value,\n },\n })\n }}\n fullWidth\n error={!!errorsByField['maximumSize']}\n helperText={errorsByField['maximumSize']}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n ((columnModel as ColumnModelFormData).maximumListLength ?? '')\n ) : (\n <FieldWithRecommendedMinimum\n value={\n (columnModel as ColumnModelFormData).maximumListLength ?? ''\n }\n originalValue={originalColumnModel?.maximumListLength}\n recommendedValue={defaultAnnotationModel?.maximumListLength}\n columnType={columnModel.columnType as ColumnTypeEnum}\n disabled={\n disabled || !canHaveMaxListLength(columnModel.columnType)\n }\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n maximumListLength: e.target.value,\n },\n })\n }}\n InputProps={{\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n slotProps: {\n input: {\n 'aria-label': 'Maximum List Length',\n min: 1,\n max: canHaveMaxListLength(columnModel.columnType)\n ? getMaxListLengthForType(\n columnModel.columnType,\n getFormDataValueAsNumber(\n (columnModel as ColumnModelFormData).maximumSize,\n ) ?? undefined,\n )\n : undefined,\n },\n },\n sx: fieldSx,\n }}\n fullWidth\n error={!!errorsByField['maximumListLength']}\n helperText={errorsByField['maximumListLength']}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n renderDefaultValue(\n (columnModel as ColumnModelFormData)?.defaultValue,\n columnModel.columnType as ColumnTypeEnum,\n )\n ) : (\n <DefaultValueField\n TextFieldProps={{\n InputProps: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n slotProps: {\n input: {\n 'aria-label': 'Default Value',\n },\n },\n sx: fieldSx,\n },\n fullWidth: true,\n error: !!errorsByField['defaultValue'],\n helperText: errorsByField['defaultValue'],\n }}\n SelectProps={{\n label: 'Default Value',\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Default Value',\n },\n },\n error: !!errorsByField['defaultValue'],\n }}\n selectFormHelperText={errorsByField['defaultValue']}\n columnModel={columnModel as ColumnModelFormData}\n value={(columnModel as ColumnModelFormData)?.defaultValue || null}\n onChange={value => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n defaultValue: value || undefined,\n },\n })\n }}\n disabled={\n disabled ||\n !canHaveDefault(columnModel.columnType, isView, isJsonSubColumn)\n }\n />\n )}\n </Box>\n <Box>\n <MultiValueField\n value={(columnModel as ColumnModelFormData)?.enumValues}\n onChange={newValue => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n enumValues:\n newValue == null || isEmpty(newValue)\n ? undefined\n : newValue,\n },\n })\n }}\n columnType={columnModel.columnType as ColumnTypeEnum}\n TextFieldProps={{\n fullWidth: true,\n disabled:\n disabled ||\n !canHaveRestrictedValues(\n columnModel.columnType,\n isJsonSubColumn,\n ),\n InputProps: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n // Is readOnly because edits are made with the JSONArrayEditorModal\n readOnly: true,\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Restrict Values',\n },\n },\n },\n error: !!errorsByField['enumValues'],\n helperText: errorsByField['enumValues'],\n }}\n />\n </Box>\n <Box>\n <FormControl fullWidth>\n <Select\n label=\"Facet Type\"\n value={columnModel.facetType || ''}\n disabled={disabled || allowedFacetTypes === null}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n facetType: e.target.value as FacetType,\n },\n })\n }}\n sx={fieldSx}\n slotProps={{\n input: {\n 'aria-label': 'Facet Type',\n },\n }}\n error={!!errorsByField['facetType']}\n >\n {(allowedFacetTypes ?? []).map((value, index) => {\n return (\n <MenuItem value={value} key={index}>\n {value === undefined ? '' : getFacetTypeFriendlyName(value)}\n </MenuItem>\n )\n })}\n </Select>\n {errorsByField['facetType'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['facetType']}\n </FormHelperText>\n )}\n </FormControl>\n </Box>\n <Box>\n <FormControl fullWidth>\n <Select\n label=\"Sort Facet Values\"\n value={facetSortConfigToValue(\n 'facetSortConfig' in columnModel\n ? columnModel.facetSortConfig\n : undefined,\n )}\n disabled={disabled || columnModel.facetType !== 'enumeration'}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n facetSortConfig: valueToFacetSortConfig(\n e.target.value as FacetSortValue,\n ),\n },\n })\n }}\n sx={fieldSx}\n slotProps={{\n input: {\n 'aria-label': 'Sort Facet Values',\n },\n }}\n error={!!errorsByField['facetSortConfig']}\n >\n <MenuItem value=\"FREQUENCY_DESC\">Frequency Descending</MenuItem>\n <MenuItem value=\"FREQUENCY_ASC\">Frequency Ascending</MenuItem>\n <MenuItem value=\"VALUE_DESC\">Value Descending</MenuItem>\n <MenuItem value=\"VALUE_ASC\">Value Ascending</MenuItem>\n </Select>\n {errorsByField['facetSortConfig'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['facetSortConfig']}\n </FormHelperText>\n )}\n </FormControl>\n </Box>\n </Box>\n {isJsonSubColumn && (\n <Box\n sx={{\n display: 'grid',\n gridColumn: '1 / span 11',\n gridTemplateColumns: 'subgrid',\n }}\n >\n <Box\n sx={{\n gridColumn: '1 / span 1',\n }}\n >\n {HIERARCHY_VERTICAL_LINE_COMPONENT}\n </Box>\n <Box></Box>\n <Box\n sx={{\n gridColumn: '3 / span 7',\n }}\n >\n <TextField\n placeholder={'JSON Path'}\n value={(columnModel as JsonSubColumnModelFormData).jsonPath}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...(columnModel as JsonSubColumnModelFormData),\n jsonPath: e.target.value,\n },\n })\n }}\n disabled={disabled}\n fullWidth\n slotProps={{\n input: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n sx: fieldSx,\n endAdornment: (\n <Tooltip\n title={\n <>\n <p>\n <Link\n href={\n 'https://dev.mysql.com/doc/refman/8.0/en/json.html#json-path-syntax'\n }\n >\n Please use a valid JSON Path selector, following\n this format.\n </Link>\n </p>\n <p>\n This field is for linking the sub-column facet to\n the corresponding location in the JSON data, so that\n it can be used as facet filter. The correct selector\n will point to the key referenced in the sub-column\n JSON Path.\n </p>\n </>\n }\n >\n <InfoTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n ),\n slotProps: {\n input: { 'aria-label': 'JSON Path' },\n },\n },\n }}\n error={!!errorsByField['jsonPath']}\n helperText={errorsByField['jsonPath']}\n />\n </Box>\n </Box>\n )}\n </>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ColumnModelForm.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/ColumnModelForm.tsx"],"sourcesContent":["import { convertToConcreteEntityType } from '@/utils/functions/EntityTypeUtils'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport {\n Box,\n Checkbox,\n FormControl,\n Link,\n MenuItem,\n Select,\n SxProps,\n TextField,\n Tooltip,\n} from '@mui/material'\nimport FormHelperText from '@mui/material/FormHelperText'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ColumnModel,\n ColumnTypeEnum,\n FacetType,\n VIEW_CONCRETE_TYPE_VALUES,\n FacetColumnSortConfig,\n} from '@sage-bionetworks/synapse-types'\nimport { useAtomValue, useSetAtom } from 'jotai'\nimport { selectAtom } from 'jotai/utils'\nimport { isArray, isEmpty, isEqual } from 'lodash-es'\nimport { useMemo } from 'react'\nimport { ZodIssue } from 'zod'\nimport DefaultValueField from './ColumnModelFormFields/DefaultValueField'\nimport { FieldWithRecommendedMinimum } from './ColumnModelFormFields/FieldWithRecommendedMinimum'\nimport MultiValueField from './ColumnModelFormFields/MultiValueField'\nimport {\n canHaveDefault,\n canHaveMaxListLength,\n canHaveRestrictedValues,\n canHaveSize,\n configureFacetsForType,\n getAllowedColumnTypes,\n getColumnTypeFriendlyName,\n getFacetTypeFriendlyName,\n getFormDataValueAsNumber,\n getMaxListLengthForType,\n getMaxSizeForType,\n} from './TableColumnSchemaEditorUtils'\nimport { HIERARCHY_VERTICAL_LINE_COMPONENT } from './TableColumnSchemaForm'\nimport { tableColumnSchemaFormDataAtom } from './TableColumnSchemaFormReducer'\nimport {\n ColumnModelFormData,\n JsonSubColumnModelFormData,\n} from './Validators/ColumnModelValidator'\n\ntype ColumnModelFormProps = {\n entityType: EntityType\n columnModelIndex: number\n jsonSubColumnIndex?: number\n /* Default Columns are read-only, except for the facetType */\n isDefaultColumn: boolean\n disabled?: boolean\n /* Can be used to override the schema used for validating ColumnModels */\n validationErrors?: ZodIssue[] | null\n defaultAnnotationModel?: ColumnModel | null\n originalColumnModel?: ColumnModel | null\n}\nconst jsonSubColumnFieldSx: SxProps = {\n height: '28px',\n fontSize: '12px',\n}\nconst topLevelColumnModelFieldSx: SxProps = {\n height: '38px',\n fontSize: '14px',\n}\n\nfunction renderDefaultValue(\n defaultValue: string | unknown[] | undefined,\n _columnType: ColumnTypeEnum,\n): string {\n if (defaultValue == null) {\n return ''\n }\n\n if (isArray(defaultValue)) {\n return defaultValue.map(String).join(', ')\n }\n return defaultValue\n}\n\n// Helper type for the combined sort configuration value\ntype FacetSortValue =\n | 'FREQUENCY_DESC'\n | 'FREQUENCY_ASC'\n | 'VALUE_DESC'\n | 'VALUE_ASC'\n | ''\n\n/**\n * Converts a FacetColumnSortConfig object to a single string value for the select dropdown\n */\nfunction facetSortConfigToValue(\n config: FacetColumnSortConfig | undefined,\n): FacetSortValue {\n if (!config || (!config.property && !config.direction)) {\n return ''\n }\n const property = config.property || 'FREQUENCY'\n const direction = config.direction || 'DESC'\n return `${property}_${direction}` as FacetSortValue\n}\n\n/**\n * Converts a select dropdown value to a FacetColumnSortConfig object\n */\nfunction valueToFacetSortConfig(\n value: FacetSortValue,\n): FacetColumnSortConfig | undefined {\n if (!value) {\n return undefined\n }\n const [property, direction] = value.split('_') as [\n 'FREQUENCY' | 'VALUE',\n 'DESC' | 'ASC',\n ]\n return { property, direction }\n}\n\n/*\n * Disable immediate MUI/Emotion style injection because it causes performance issues when adding many columns at once.\n * This can be a common occurence when adding annotation columns\n */\nconst DISABLE_INJECTING_GLOBAL_STYLES_VALUE = true\n\nexport default function ColumnModelForm(props: ColumnModelFormProps) {\n const {\n columnModelIndex,\n jsonSubColumnIndex,\n entityType,\n isDefaultColumn,\n disabled = false,\n validationErrors = null,\n defaultAnnotationModel,\n originalColumnModel,\n } = props\n const isJsonSubColumn = jsonSubColumnIndex != undefined\n const dispatch = useSetAtom(tableColumnSchemaFormDataAtom)\n const isView = (VIEW_CONCRETE_TYPE_VALUES as readonly string[]).includes(\n convertToConcreteEntityType(entityType),\n )\n\n const columnModelAtom = useMemo(\n () =>\n selectAtom(\n tableColumnSchemaFormDataAtom,\n v =>\n isJsonSubColumn\n ? v[columnModelIndex].jsonSubColumns![jsonSubColumnIndex]\n : v[columnModelIndex],\n isEqual,\n ),\n [columnModelIndex, isJsonSubColumn, jsonSubColumnIndex],\n )\n\n const columnModel = useAtomValue(columnModelAtom)\n\n const allowedColumnTypes = useMemo(\n () => getAllowedColumnTypes(isView, isJsonSubColumn),\n [isView, isJsonSubColumn],\n )\n\n const allowedFacetTypes = useMemo(\n () => configureFacetsForType(columnModel.columnType, isJsonSubColumn),\n [columnModel.columnType, isJsonSubColumn],\n )\n const fieldSx: SxProps = useMemo(\n () => (isJsonSubColumn ? jsonSubColumnFieldSx : topLevelColumnModelFieldSx),\n [isJsonSubColumn],\n )\n\n const errorsByField = useMemo(() => {\n if (validationErrors && isArray(validationErrors)) {\n const errorsByField: Record<string, string> = {}\n validationErrors.forEach(e => {\n if (e.path) {\n errorsByField[String(e.path[e.path.length - 1])] = e.message\n }\n })\n return errorsByField\n }\n return {}\n }, [validationErrors])\n\n return (\n <>\n <Box\n sx={{\n display: 'grid',\n gridColumn: '1 / span 11',\n gridTemplateColumns: 'subgrid',\n }}\n >\n {isJsonSubColumn && (\n <Box sx={{ gridColumn: '1 / span 1' }}>\n {HIERARCHY_VERTICAL_LINE_COMPONENT}\n </Box>\n )}\n <Box\n data-testid={`ColumnModelForm`}\n sx={{\n display: 'flex',\n alignItems: 'start',\n gridColumn: isJsonSubColumn ? '2 / span 1' : ' 1 / span 1',\n // Checkbox is offset from top; vertical centering causes issues when validation errors are displayed\n mt: isJsonSubColumn ? '0px' : '5px',\n }}\n >\n <Checkbox\n checked={columnModel.isSelected}\n inputProps={{ 'aria-label': 'Select' }}\n disabled={disabled}\n onChange={() => {\n dispatch({\n type: 'toggleSelect',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n })\n }}\n />\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n gridColumn: isJsonSubColumn\n ? /* If this is a JSON Subcolumn, we reduce the width of this grid column to create space to render the visual hierarchical line */\n '3 / span 1'\n : /* Otherwise, span across both grid columns */\n '2 / span 2',\n }}\n >\n {isDefaultColumn ? (\n columnModel.name\n ) : (\n <TextField\n value={columnModel.name}\n placeholder={isJsonSubColumn ? 'Facet name' : 'Column name'}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n name: e.target.value,\n },\n })\n }}\n disabled={disabled}\n fullWidth\n error={!!errorsByField['name']}\n helperText={errorsByField['name']}\n slotProps={{\n input: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Name',\n },\n },\n },\n }}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n getColumnTypeFriendlyName(columnModel.columnType)\n ) : (\n <FormControl fullWidth>\n <Select\n label=\"Column Type\"\n value={columnModel.columnType}\n onChange={e => {\n dispatch({\n type: 'changeColumnModelType',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n newColumnType: e.target.value as ColumnTypeEnum,\n })\n }}\n slotProps={{\n input: {\n 'aria-label': 'Column Type',\n },\n }}\n sx={fieldSx}\n disabled={disabled}\n error={!!errorsByField['columnType']}\n >\n {allowedColumnTypes.map(value => {\n return (\n <MenuItem value={value} key={value}>\n {getColumnTypeFriendlyName(value)}\n </MenuItem>\n )\n })}\n </Select>\n {errorsByField['columnType'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['columnType']}\n </FormHelperText>\n )}\n </FormControl>\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n ((columnModel as ColumnModelFormData).maximumSize ?? '')\n ) : (\n <FieldWithRecommendedMinimum\n value={(columnModel as ColumnModelFormData).maximumSize ?? ''}\n originalValue={originalColumnModel?.maximumSize}\n recommendedValue={defaultAnnotationModel?.maximumSize}\n columnType={columnModel.columnType as ColumnTypeEnum}\n disabled={disabled || !canHaveSize(columnModel.columnType)}\n InputProps={{\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n\n slotProps: {\n input: {\n 'aria-label': 'Maximum Size',\n min: 1,\n max: canHaveSize(columnModel.columnType)\n ? getMaxSizeForType(columnModel.columnType)\n : undefined,\n },\n },\n sx: fieldSx,\n }}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n maximumSize: e.target.value,\n },\n })\n }}\n fullWidth\n error={!!errorsByField['maximumSize']}\n helperText={errorsByField['maximumSize']}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n ((columnModel as ColumnModelFormData).maximumListLength ?? '')\n ) : (\n <FieldWithRecommendedMinimum\n value={\n (columnModel as ColumnModelFormData).maximumListLength ?? ''\n }\n originalValue={originalColumnModel?.maximumListLength}\n recommendedValue={defaultAnnotationModel?.maximumListLength}\n columnType={columnModel.columnType as ColumnTypeEnum}\n disabled={\n disabled || !canHaveMaxListLength(columnModel.columnType)\n }\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n maximumListLength: e.target.value,\n },\n })\n }}\n InputProps={{\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n slotProps: {\n input: {\n 'aria-label': 'Maximum List Length',\n min: 1,\n max: canHaveMaxListLength(columnModel.columnType)\n ? getMaxListLengthForType(\n columnModel.columnType,\n getFormDataValueAsNumber(\n (columnModel as ColumnModelFormData).maximumSize,\n ) ?? undefined,\n )\n : undefined,\n },\n },\n sx: fieldSx,\n }}\n fullWidth\n error={!!errorsByField['maximumListLength']}\n helperText={errorsByField['maximumListLength']}\n />\n )}\n </Box>\n <Box\n sx={{\n my: isDefaultColumn ? 'auto' : undefined,\n }}\n >\n {isDefaultColumn ? (\n renderDefaultValue(\n (columnModel as ColumnModelFormData)?.defaultValue,\n columnModel.columnType as ColumnTypeEnum,\n )\n ) : (\n <DefaultValueField\n TextFieldProps={{\n InputProps: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n slotProps: {\n input: {\n 'aria-label': 'Default Value',\n },\n },\n sx: fieldSx,\n },\n fullWidth: true,\n error: !!errorsByField['defaultValue'],\n helperText: errorsByField['defaultValue'],\n }}\n SelectProps={{\n label: 'Default Value',\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Default Value',\n },\n },\n error: !!errorsByField['defaultValue'],\n }}\n selectFormHelperText={errorsByField['defaultValue']}\n columnModel={columnModel as ColumnModelFormData}\n value={(columnModel as ColumnModelFormData)?.defaultValue || null}\n onChange={value => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n defaultValue: value || undefined,\n },\n })\n }}\n disabled={\n disabled ||\n !canHaveDefault(columnModel.columnType, isView, isJsonSubColumn)\n }\n />\n )}\n </Box>\n <Box>\n <MultiValueField\n value={(columnModel as ColumnModelFormData)?.enumValues}\n onChange={newValue => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n enumValues:\n newValue == null || isEmpty(newValue)\n ? undefined\n : newValue,\n },\n })\n }}\n columnType={columnModel.columnType as ColumnTypeEnum}\n TextFieldProps={{\n fullWidth: true,\n disabled:\n disabled ||\n !canHaveRestrictedValues(\n columnModel.columnType,\n isJsonSubColumn,\n ),\n InputProps: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n // Is readOnly because edits are made with the JSONArrayEditorModal\n readOnly: true,\n sx: fieldSx,\n slotProps: {\n input: {\n 'aria-label': 'Restrict Values',\n },\n },\n },\n error: !!errorsByField['enumValues'],\n helperText: errorsByField['enumValues'],\n }}\n />\n </Box>\n <Box>\n <FormControl fullWidth>\n <Select\n label=\"Facet Type\"\n value={columnModel.facetType || ''}\n disabled={disabled || allowedFacetTypes === null}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n facetType: e.target.value as FacetType,\n },\n })\n }}\n sx={fieldSx}\n slotProps={{\n input: {\n 'aria-label': 'Facet Type',\n },\n }}\n error={!!errorsByField['facetType']}\n >\n {(allowedFacetTypes ?? []).map((value, index) => {\n return (\n <MenuItem value={value} key={index}>\n {value === undefined ? '' : getFacetTypeFriendlyName(value)}\n </MenuItem>\n )\n })}\n </Select>\n {errorsByField['facetType'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['facetType']}\n </FormHelperText>\n )}\n </FormControl>\n </Box>\n <Box>\n <FormControl fullWidth>\n <Select\n label=\"Sort Facet Values\"\n value={facetSortConfigToValue(\n 'facetSortConfig' in columnModel\n ? columnModel.facetSortConfig\n : undefined,\n )}\n disabled={disabled || columnModel.facetType !== 'enumeration'}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...columnModel,\n facetSortConfig: valueToFacetSortConfig(\n e.target.value as FacetSortValue,\n ),\n },\n })\n }}\n sx={fieldSx}\n slotProps={{\n input: {\n 'aria-label': 'Sort Facet Values',\n },\n }}\n error={!!errorsByField['facetSortConfig']}\n >\n <MenuItem value=\"FREQUENCY_DESC\">Frequency Descending</MenuItem>\n <MenuItem value=\"FREQUENCY_ASC\">Frequency Ascending</MenuItem>\n <MenuItem value=\"VALUE_DESC\">Value Descending</MenuItem>\n <MenuItem value=\"VALUE_ASC\">Value Ascending</MenuItem>\n </Select>\n {errorsByField['facetSortConfig'] && (\n <FormHelperText color={'error.main'}>\n {errorsByField['facetSortConfig']}\n </FormHelperText>\n )}\n </FormControl>\n </Box>\n </Box>\n {isJsonSubColumn && (\n <Box\n sx={{\n display: 'grid',\n gridColumn: '1 / span 11',\n gridTemplateColumns: 'subgrid',\n }}\n >\n <Box\n sx={{\n gridColumn: '1 / span 1',\n }}\n >\n {HIERARCHY_VERTICAL_LINE_COMPONENT}\n </Box>\n <Box></Box>\n <Box\n sx={{\n gridColumn: '3 / span 7',\n }}\n >\n <TextField\n placeholder={'JSON Path'}\n value={(columnModel as JsonSubColumnModelFormData).jsonPath}\n onChange={e => {\n dispatch({\n type: 'setColumnModelValue',\n columnModelIndex,\n jsonSubColumnModelIndex: jsonSubColumnIndex,\n value: {\n ...(columnModel as JsonSubColumnModelFormData),\n jsonPath: e.target.value,\n },\n })\n }}\n disabled={disabled}\n fullWidth\n slotProps={{\n input: {\n disableInjectingGlobalStyles:\n DISABLE_INJECTING_GLOBAL_STYLES_VALUE,\n sx: fieldSx,\n endAdornment: (\n <Tooltip\n title={\n <>\n <p>\n <Link\n href={\n 'https://dev.mysql.com/doc/refman/8.0/en/json.html#json-path-syntax'\n }\n >\n Please use a valid JSON Path selector, following\n this format.\n </Link>\n </p>\n <p>\n This field is for linking the sub-column facet to\n the corresponding location in the JSON data, so that\n it can be used as facet filter. The correct selector\n will point to the key referenced in the sub-column\n JSON Path.\n </p>\n </>\n }\n >\n <InfoTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n ),\n slotProps: {\n input: { 'aria-label': 'JSON Path' },\n },\n },\n }}\n error={!!errorsByField['jsonPath']}\n helperText={errorsByField['jsonPath']}\n />\n </Box>\n </Box>\n )}\n </>\n )\n}\n"],"mappings":"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"}
@@ -11,7 +11,7 @@ import { useCallback as s, useState as c } from "react";
11
11
  import { Button as l } from "@mui/material";
12
12
  import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
13
13
  import { EntityType as p } from "@sage-bionetworks/synapse-client";
14
- import { DownloadTwoTone as m } from "@mui/icons-material";
14
+ import m from "@mui/icons-material/DownloadTwoTone";
15
15
  //#region src/components/TableColumnSchemaEditor/ImportTableColumnsButton.tsx
16
16
  function h(h) {
17
17
  let { initialFinderProjectId: g, onAddColumns: _, ...v } = h, [y, b] = c(!1), { accessToken: x } = r(), S = s(async (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"ImportTableColumnsButton.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/ImportTableColumnsButton.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport { useSynapseContext } from '@/utils'\nimport { EntityTypeGroup } from '@/utils/functions/EntityTypeUtils'\nimport { DownloadTwoTone } from '@mui/icons-material'\nimport { Button, ButtonProps } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { ColumnModel, Reference } from '@sage-bionetworks/synapse-types'\nimport { useCallback, useState } from 'react'\nimport { SetOptional } from 'type-fest'\nimport { EntityFinderModal } from '../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../EntityFinder/VersionSelectionType'\nimport { displayToast } from '../ToastMessage'\n\nexport type ImportTableColumnsButtonProps = Omit<ButtonProps, 'onClick'> & {\n initialFinderProjectId?: string\n onAddColumns: (columnModels: SetOptional<ColumnModel, 'id'>[]) => void\n}\n\nexport default function ImportTableColumnsButton(\n props: ImportTableColumnsButtonProps,\n) {\n const { initialFinderProjectId, onAddColumns, ...buttonProps } = props\n const [showFinder, setShowFinder] = useState(false)\n const { accessToken } = useSynapseContext()\n\n const fetchColumnModels = useCallback(\n async (reference: Reference): Promise<SetOptional<ColumnModel, 'id'>[]> => {\n const { tableBundle } = await SynapseClient.getEntityBundleV2(\n reference.targetId,\n { includeTableBundle: true },\n reference.targetVersionNumber,\n accessToken,\n )\n return tableBundle!.columnModels.map(columnModel => ({\n ...columnModel,\n id: undefined,\n }))\n },\n [accessToken],\n )\n\n const onConfirmEntityFinder = useCallback(\n async (selected: Reference[]) => {\n try {\n const selectedEntity = selected[0]\n\n if (selectedEntity) {\n // Get the column models from the selected table\n const columnModels = await fetchColumnModels(selectedEntity)\n onAddColumns(columnModels)\n }\n } catch (err) {\n console.error(err)\n displayToast(err.message, 'danger')\n } finally {\n setShowFinder(false)\n }\n },\n [fetchColumnModels, onAddColumns],\n )\n\n return (\n <>\n <EntityFinderModal\n configuration={{\n initialScope: initialFinderProjectId\n ? FinderScope.CURRENT_PROJECT\n : FinderScope.ALL_PROJECTS,\n initialContainer: initialFinderProjectId ?? 'root',\n selectMultiple: false,\n selectableTypes: EntityTypeGroup.ALL_TABLES,\n visibleTypesInTree: [EntityType.project],\n versionSelection: VersionSelectionType.UNTRACKED,\n }}\n show={showFinder}\n title={'Import Columns from Table'}\n promptCopy={'Find Tables to import columns'}\n titleHelpPopoverProps={{\n markdownText:\n 'Search or Browse Synapse to find an existing Table in order to import columns into this Table',\n }}\n onConfirm={selected => {\n onConfirmEntityFinder(selected)\n }}\n confirmButtonCopy={'Import Columns'}\n onCancel={() => {\n setShowFinder(false)\n }}\n />\n <Button\n variant={'outlined'}\n onClick={() => {\n setShowFinder(true)\n }}\n startIcon={<DownloadTwoTone />}\n {...buttonProps}\n >\n Import Columns\n </Button>\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,2BAAwB,iBAAc,GAAG,MAAgB,GAC3D,CAAC,GAAY,KAAiB,EAAS,EAAK,GAC5C,EAAE,mBAAgB,EAAkB,GAEpC,IAAoB,EACxB,OAAO,MAAoE;EACzE,IAAM,EAAE,mBAAgB,MAAM,EAAc,kBAC1C,EAAU,UACV,EAAE,oBAAoB,GAAK,GAC3B,EAAU,qBACV,CACF;EACA,OAAO,EAAa,aAAa,KAAI,OAAgB;GACnD,GAAG;GACH,IAAI,KAAA;EACN,EAAE;CACJ,GACA,CAAC,CAAW,CACd,GAEM,IAAwB,EAC5B,OAAO,MAA0B;EAC/B,IAAI;GACF,IAAM,IAAiB,EAAS;GAEhC,AAAI,KAGF,EAAa,MADc,EAAkB,CAAc,CAClC;EAE7B,SAAS,GAAK;GAEZ,AADA,QAAQ,MAAM,CAAG,GACjB,EAAa,EAAI,SAAS,QAAQ;EACpC,UAAU;GACR,EAAc,EAAK;EACrB;CACF,GACA,CAAC,GAAmB,CAAY,CAClC;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,eAAe;GACb,cAAc,IACV,EAAY,kBACZ,EAAY;GAChB,kBAAkB,KAA0B;GAC5C,gBAAgB;GAChB,iBAAiB,EAAgB;GACjC,oBAAoB,CAAC,EAAW,OAAO;GACvC,kBAAkB,EAAqB;EACzC;EACA,MAAM;EACN,OAAO;EACP,YAAY;EACZ,uBAAuB,EACrB,cACE,gGACJ;EACA,YAAW,MAAY;GACrB,EAAsB,CAAQ;EAChC;EACA,mBAAmB;EACnB,gBAAgB;GACd,EAAc,EAAK;EACrB;CACD,CAAA,GACD,kBAAC,GAAD;EACE,SAAS;EACT,eAAe;GACb,EAAc,EAAI;EACpB;EACA,WAAW,kBAAC,GAAD,CAAkB,CAAA;EAC7B,GAAI;YACL;CAEO,CAAA,CACR,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"ImportTableColumnsButton.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/ImportTableColumnsButton.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport { useSynapseContext } from '@/utils'\nimport { EntityTypeGroup } from '@/utils/functions/EntityTypeUtils'\nimport DownloadTwoTone from '@mui/icons-material/DownloadTwoTone'\nimport { Button, ButtonProps } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { ColumnModel, Reference } from '@sage-bionetworks/synapse-types'\nimport { useCallback, useState } from 'react'\nimport { SetOptional } from 'type-fest'\nimport { EntityFinderModal } from '../EntityFinder/EntityFinderModal'\nimport { FinderScope } from '../EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '../EntityFinder/VersionSelectionType'\nimport { displayToast } from '../ToastMessage'\n\nexport type ImportTableColumnsButtonProps = Omit<ButtonProps, 'onClick'> & {\n initialFinderProjectId?: string\n onAddColumns: (columnModels: SetOptional<ColumnModel, 'id'>[]) => void\n}\n\nexport default function ImportTableColumnsButton(\n props: ImportTableColumnsButtonProps,\n) {\n const { initialFinderProjectId, onAddColumns, ...buttonProps } = props\n const [showFinder, setShowFinder] = useState(false)\n const { accessToken } = useSynapseContext()\n\n const fetchColumnModels = useCallback(\n async (reference: Reference): Promise<SetOptional<ColumnModel, 'id'>[]> => {\n const { tableBundle } = await SynapseClient.getEntityBundleV2(\n reference.targetId,\n { includeTableBundle: true },\n reference.targetVersionNumber,\n accessToken,\n )\n return tableBundle!.columnModels.map(columnModel => ({\n ...columnModel,\n id: undefined,\n }))\n },\n [accessToken],\n )\n\n const onConfirmEntityFinder = useCallback(\n async (selected: Reference[]) => {\n try {\n const selectedEntity = selected[0]\n\n if (selectedEntity) {\n // Get the column models from the selected table\n const columnModels = await fetchColumnModels(selectedEntity)\n onAddColumns(columnModels)\n }\n } catch (err) {\n console.error(err)\n displayToast(err.message, 'danger')\n } finally {\n setShowFinder(false)\n }\n },\n [fetchColumnModels, onAddColumns],\n )\n\n return (\n <>\n <EntityFinderModal\n configuration={{\n initialScope: initialFinderProjectId\n ? FinderScope.CURRENT_PROJECT\n : FinderScope.ALL_PROJECTS,\n initialContainer: initialFinderProjectId ?? 'root',\n selectMultiple: false,\n selectableTypes: EntityTypeGroup.ALL_TABLES,\n visibleTypesInTree: [EntityType.project],\n versionSelection: VersionSelectionType.UNTRACKED,\n }}\n show={showFinder}\n title={'Import Columns from Table'}\n promptCopy={'Find Tables to import columns'}\n titleHelpPopoverProps={{\n markdownText:\n 'Search or Browse Synapse to find an existing Table in order to import columns into this Table',\n }}\n onConfirm={selected => {\n onConfirmEntityFinder(selected)\n }}\n confirmButtonCopy={'Import Columns'}\n onCancel={() => {\n setShowFinder(false)\n }}\n />\n <Button\n variant={'outlined'}\n onClick={() => {\n setShowFinder(true)\n }}\n startIcon={<DownloadTwoTone />}\n {...buttonProps}\n >\n Import Columns\n </Button>\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,2BAAwB,iBAAc,GAAG,MAAgB,GAC3D,CAAC,GAAY,KAAiB,EAAS,EAAK,GAC5C,EAAE,mBAAgB,EAAkB,GAEpC,IAAoB,EACxB,OAAO,MAAoE;EACzE,IAAM,EAAE,mBAAgB,MAAM,EAAc,kBAC1C,EAAU,UACV,EAAE,oBAAoB,GAAK,GAC3B,EAAU,qBACV,CACF;EACA,OAAO,EAAa,aAAa,KAAI,OAAgB;GACnD,GAAG;GACH,IAAI,KAAA;EACN,EAAE;CACJ,GACA,CAAC,CAAW,CACd,GAEM,IAAwB,EAC5B,OAAO,MAA0B;EAC/B,IAAI;GACF,IAAM,IAAiB,EAAS;GAEhC,AAAI,KAGF,EAAa,MADc,EAAkB,CAAc,CAClC;EAE7B,SAAS,GAAK;GAEZ,AADA,QAAQ,MAAM,CAAG,GACjB,EAAa,EAAI,SAAS,QAAQ;EACpC,UAAU;GACR,EAAc,EAAK;EACrB;CACF,GACA,CAAC,GAAmB,CAAY,CAClC;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,eAAe;GACb,cAAc,IACV,EAAY,kBACZ,EAAY;GAChB,kBAAkB,KAA0B;GAC5C,gBAAgB;GAChB,iBAAiB,EAAgB;GACjC,oBAAoB,CAAC,EAAW,OAAO;GACvC,kBAAkB,EAAqB;EACzC;EACA,MAAM;EACN,OAAO;EACP,YAAY;EACZ,uBAAuB,EACrB,cACE,gGACJ;EACA,YAAW,MAAY;GACrB,EAAsB,CAAQ;EAChC;EACA,mBAAmB;EACnB,gBAAgB;GACd,EAAc,EAAK;EACrB;CACD,CAAA,GACD,kBAAC,GAAD;EACE,SAAS;EACT,eAAe;GACb,EAAc,EAAI;EACpB;EACA,WAAW,kBAAC,GAAD,CAAkB,CAAA;EAC7B,GAAI;YACL;CAEO,CAAA,CACR,EAAA,CAAA;AAEN"}
@@ -1 +1 @@
1
- {"version":3,"file":"TableColumnSchemaEditorUtils.d.ts","sourceRoot":"","sources":["../../../src/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TableColumnSchemaEditorUtils.d.ts","sourceRoot":"","sources":["../../../src/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TableColumnSchemaEditorUtils.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.ts"],"sourcesContent":["import {\n convertToEntityType,\n isDataset,\n isDatasetCollection,\n isEntityView,\n isSubmissionView,\n} from '@/utils/functions/EntityTypeUtils'\nimport { ViewEntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ColumnModel,\n ColumnType,\n ColumnTypeEnum,\n Entity,\n ENTITY_VIEW_TYPE_MASK_DATASET,\n ENTITY_VIEW_TYPE_MASK_FILE,\n FacetType,\n ViewScope,\n} from '@sage-bionetworks/synapse-types'\nimport { JSONSchema7Definition } from 'json-schema'\nimport { SetOptional } from 'type-fest'\nimport {\n ColumnModelFormData,\n JsonSubColumnModelFormData,\n} from './Validators/ColumnModelValidator'\n\n/**\n * These column types can only be used in Tables. They can not be used in views.\n * See SWC-6333 - for views, only allow column types that are mapped to annotation types.\n */\nconst unsupportedTypesForViews = [ColumnTypeEnum.JSON]\n\n/**\n * Get the allowed column types for a column model based on the table type.\n * @param isView - whether the base table is a view\n * @param isJsonSubColumnFacet - whether the proposed column is a JSON subcolumn facet\n */\nexport function getAllowedColumnTypes(\n isView: boolean,\n isJsonSubColumnFacet: boolean,\n): ColumnTypeEnum[] {\n return Object.values(ColumnTypeEnum)\n .filter(columnType =>\n isView ? !unsupportedTypesForViews.includes(columnType) : true,\n )\n .filter(columnType => {\n if (isJsonSubColumnFacet) {\n switch (columnType) {\n // JSON Subcolumns cannot be JSON or LIST types\n case ColumnTypeEnum.JSON:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.INTEGER_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.DATE_LIST:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n return false\n default:\n return true\n }\n }\n return true\n })\n}\n\nexport function getFacetTypeFriendlyName(facetType: FacetType) {\n switch (facetType) {\n case 'enumeration':\n return 'Values'\n case 'range':\n return 'Range'\n default:\n return facetType\n }\n}\nexport function getColumnTypeFriendlyName(type: ColumnType | ColumnTypeEnum) {\n switch (type) {\n case ColumnTypeEnum.STRING:\n return 'String'\n case ColumnTypeEnum.DOUBLE:\n return 'Double'\n case ColumnTypeEnum.BOOLEAN:\n return 'Boolean'\n case ColumnTypeEnum.INTEGER:\n return 'Integer'\n case ColumnTypeEnum.DATE:\n return 'Date'\n case ColumnTypeEnum.FILEHANDLEID:\n return 'File'\n case ColumnTypeEnum.ENTITYID:\n return 'Entity'\n case ColumnTypeEnum.LINK:\n return 'Link'\n case ColumnTypeEnum.MEDIUMTEXT:\n return 'MediumText'\n case ColumnTypeEnum.LARGETEXT:\n return 'LargeText'\n case ColumnTypeEnum.USERID:\n return 'User'\n case ColumnTypeEnum.STRING_LIST:\n return 'String List'\n case ColumnTypeEnum.INTEGER_LIST:\n return 'Integer List'\n case ColumnTypeEnum.BOOLEAN_LIST:\n return 'Boolean List'\n case ColumnTypeEnum.DATE_LIST:\n return 'Date List'\n case ColumnTypeEnum.USERID_LIST:\n return 'User ID List'\n case ColumnTypeEnum.ENTITYID_LIST:\n return 'Entity ID List'\n case ColumnTypeEnum.EVALUATIONID:\n return 'Evaluation'\n case ColumnTypeEnum.SUBMISSIONID:\n return 'Submission'\n case ColumnTypeEnum.JSON:\n return 'JSON'\n default:\n return type\n }\n}\n\n/**\n * Can the given type have a size?\n *\n * @param type\n * @return\n */\nexport function canHaveSize(type: ColumnType | ColumnTypeEnum): boolean {\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.LINK:\n return true\n default:\n // all others are false\n return false\n }\n}\n\nexport function canHaveMaxListLength(\n type: ColumnType | ColumnTypeEnum,\n): boolean {\n switch (type) {\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.DATE_LIST:\n case ColumnTypeEnum.INTEGER_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.USERID_LIST:\n return true\n default:\n // all others are false\n return false\n }\n}\n\n/**\n * Configure the facet selection based on the column type\n *\n * @param type a ColumnType for which to get the facet selection\n * @param isJsonSubColumnFacet is this a facet for a json subcolumn?\n * @return the allowed facetTypes, or null if faceting is not allowed\n */\nexport function configureFacetsForType(\n type: ColumnType | ColumnTypeEnum,\n isJsonSubColumnFacet: boolean,\n): (FacetType | undefined)[] | null {\n let allowedFacetTypes: (FacetType | undefined)[] | null\n switch (type) {\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.INTEGER_LIST:\n allowedFacetTypes = ['enumeration', 'range']\n break\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.USERID:\n case ColumnTypeEnum.ENTITYID:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.EVALUATIONID:\n allowedFacetTypes = ['enumeration']\n break\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.DATE_LIST:\n allowedFacetTypes = ['range']\n break\n default:\n allowedFacetTypes = null\n }\n\n if (allowedFacetTypes && !isJsonSubColumnFacet) {\n // jsonSubColumn facets MUST have a facet definition, but regular column models do not need one\n // So allow `undefined` for regular columnModels.\n allowedFacetTypes = [undefined, ...allowedFacetTypes]\n }\n return allowedFacetTypes\n}\n\n/**\n * Column types that are not allowed to have a default value.\n * @see the `defaultValue` property description on the ColumnModel schema in the Synapse OpenAPI specification.\n */\nexport const DISALLOWED_DEFAULT_VALUE_COLUMN_TYPES: ColumnTypeEnum[] = [\n ColumnTypeEnum.ENTITYID,\n ColumnTypeEnum.ENTITYID_LIST,\n ColumnTypeEnum.EVALUATIONID,\n ColumnTypeEnum.FILEHANDLEID,\n ColumnTypeEnum.LARGETEXT,\n ColumnTypeEnum.MEDIUMTEXT,\n ColumnTypeEnum.SUBMISSIONID,\n ColumnTypeEnum.USERID,\n ColumnTypeEnum.USERID_LIST,\n]\n\nexport function canHaveDefault(\n type: ColumnType | ColumnTypeEnum,\n isView: boolean,\n isJsonSubColumnFacet: boolean,\n) {\n // SWC-6333: default types are not allowed in views\n if (isView) {\n return false\n } else if (isJsonSubColumnFacet) {\n return false\n } else {\n return !DISALLOWED_DEFAULT_VALUE_COLUMN_TYPES.includes(\n type as ColumnTypeEnum,\n )\n }\n}\n\nexport const DEFAULT_STRING_SIZE = 50\nexport const MAX_STRING_SIZE = 1000\nexport const DEFAULT_LIST_LENGTH = 100\n\n/** The maximum number of characters allowed in a column name. */\nexport const MAX_COLUMN_NAME_LENGTH = 256\n\n/** The maximum number of enumeration values allowed for a single column. */\nexport const MAX_ENUM_VALUES = 100\n\n/**\n * The maximum total character budget for a list column. The server enforces that\n * `maximumListLength * <per-element character size>` does not exceed this value.\n */\nexport const LIST_LENGTH_CHARACTER_BUDGET = 100_000\n\n/**\n * The fixed per-element character size (in the list-length budget) for list column types\n * whose element size is not configurable. STRING_LIST is excluded because its per-element\n * size is the configurable `maximumSize`.\n */\nconst FIXED_LIST_ELEMENT_CHARACTER_SIZE: Partial<\n Record<ColumnTypeEnum, number>\n> = {\n [ColumnTypeEnum.INTEGER_LIST]: 20,\n [ColumnTypeEnum.DATE_LIST]: 20,\n [ColumnTypeEnum.USERID_LIST]: 20,\n [ColumnTypeEnum.BOOLEAN_LIST]: 5,\n [ColumnTypeEnum.ENTITYID_LIST]: 44,\n}\n\n/**\n * Get the default max size for a given type.\n *\n * @param type\n * @return\n */\nexport function getMaxSizeForType(type: ColumnType | ColumnTypeEnum): number {\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.LINK:\n return MAX_STRING_SIZE\n default:\n throw new Error(`Type is not known to have a max size: ${type}`)\n }\n}\n\n/**\n * Get the maximum allowed `maximumListLength` for a list column type.\n *\n * The server enforces a total character budget of {@link LIST_LENGTH_CHARACTER_BUDGET}.\n * For STRING_LIST the per-element size is the configurable `maximumSize` (defaulting to\n * {@link DEFAULT_STRING_SIZE}); for all other list types the per-element size is fixed.\n *\n * @param type the list column type\n * @param maximumSize the configured element size, used only for STRING_LIST\n * @return the maximum allowed list length\n */\nexport function getMaxListLengthForType(\n type: ColumnType | ColumnTypeEnum,\n maximumSize?: number,\n): number {\n if (type === ColumnTypeEnum.STRING_LIST) {\n const elementSize = maximumSize ?? DEFAULT_STRING_SIZE\n return Math.floor(LIST_LENGTH_CHARACTER_BUDGET / elementSize)\n }\n const elementSize = FIXED_LIST_ELEMENT_CHARACTER_SIZE[type as ColumnTypeEnum]\n if (elementSize == null) {\n throw new Error(`Type is not known to have a max list length: ${type}`)\n }\n return Math.floor(LIST_LENGTH_CHARACTER_BUDGET / elementSize)\n}\n\nexport function canHaveRestrictedValues(\n type: ColumnType | ColumnTypeEnum,\n isJsonSubColumnFacet: boolean,\n): boolean {\n if (isJsonSubColumnFacet) {\n return false\n }\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.ENTITYID:\n return true\n default:\n // all other are false\n return false\n }\n}\n\nfunction transformEnumValues(\n enumValues: string[],\n columnType: ColumnType | ColumnTypeEnum,\n): (string | number)[] {\n // SWC-6622 - Special case: if these are INTEGER, convert to numbers before inserting data into form components\n // The editor validates that these are integers, so inserting the strings returned by the API causes an\n // unexpected validation error\n if (columnType === ColumnTypeEnum.INTEGER) {\n return enumValues.map(value => parseInt(value))\n }\n return enumValues\n}\n\n/**\n * Transform ColumnModels returned by Synapse into the form data for the TableColumnSchemaForm.\n * Default column models, if available, are used to determine which columns should not be editable in the form.\n * @param columnModels\n * @param defaultColumns\n */\nexport function transformColumnModelsToFormData(\n columnModels: SetOptional<ColumnModel, 'id'>[],\n defaultColumns: ColumnModel[] = [],\n): ColumnModelFormData[] {\n return columnModels.map((cm): ColumnModelFormData => {\n return {\n ...cm,\n columnType: cm.columnType as ColumnTypeEnum,\n maximumSize:\n cm.maximumSize == null ? undefined : cm.maximumSize.toString(),\n maximumListLength:\n cm.maximumListLength == null\n ? undefined\n : cm.maximumListLength.toString(),\n isSelected: false,\n // If the name matches a known default column model, then we consider it to be a default column model itself\n isOriginallyDefaultColumn: defaultColumns.some(\n dcm => dcm.name === cm.name,\n ),\n jsonSubColumns: cm.jsonSubColumns\n ? cm.jsonSubColumns.map(\n (jsc): JsonSubColumnModelFormData => ({\n ...jsc,\n columnType: jsc.columnType as ColumnTypeEnum,\n isSelected: false,\n }),\n )\n : undefined,\n // If this is defaultValue for a LIST column, the value is a serialized string\n defaultValue:\n cm.defaultValue && cm.columnType.endsWith('_LIST')\n ? JSON.parse(cm.defaultValue)\n : cm.defaultValue,\n enumValues:\n cm.enumValues != null\n ? transformEnumValues(cm.enumValues, cm.columnType)\n : undefined,\n }\n })\n}\n\nexport function getViewScopeForEntity(entity: Entity): ViewScope | undefined {\n if (isEntityView(entity)) {\n return {\n scope: entity.scopeIds,\n viewTypeMask: entity.viewTypeMask,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n } else if (isDataset(entity) || isDatasetCollection(entity)) {\n const mask = isDataset(entity)\n ? ENTITY_VIEW_TYPE_MASK_FILE\n : ENTITY_VIEW_TYPE_MASK_DATASET\n return {\n scope: (entity.items ?? []).map(\n item => `${item.entityId}.${item.versionNumber}`,\n ),\n viewTypeMask: mask,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n } else if (isSubmissionView(entity)) {\n return {\n scope: entity.scopeIds,\n viewTypeMask: undefined,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n }\n return undefined\n}\n\nexport function getJsonSchemaItemDefinitionForColumnType(\n columnType: ColumnTypeEnum,\n): JSONSchema7Definition {\n switch (columnType) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n return { type: 'string', minLength: 1 }\n case ColumnTypeEnum.DOUBLE:\n return { type: 'number' }\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.BOOLEAN_LIST:\n return { type: 'boolean' }\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.INTEGER_LIST:\n return { type: 'integer' }\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.DATE_LIST:\n return { type: 'string', format: 'datetime' }\n case ColumnTypeEnum.FILEHANDLEID:\n case ColumnTypeEnum.ENTITYID:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.LINK:\n case ColumnTypeEnum.MEDIUMTEXT:\n case ColumnTypeEnum.LARGETEXT:\n case ColumnTypeEnum.USERID:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.SUBMISSIONID:\n case ColumnTypeEnum.JSON:\n case ColumnTypeEnum.EVALUATIONID:\n default:\n return { type: 'string', minLength: 1 }\n }\n}\n\nconst columnModelMatchesFormData = (\n model: ColumnModel,\n target: ColumnModelFormData,\n): boolean => {\n return model.name === target.name && model.columnType === target.columnType\n}\n\nexport const findMatchingColumnModel = (\n columnModels: ColumnModel[],\n target: ColumnModelFormData,\n): ColumnModel | undefined => {\n let closestMatch: ColumnModel | undefined\n\n for (const model of columnModels) {\n if (columnModelMatchesFormData(model, target)) {\n closestMatch = model\n break\n }\n }\n\n return closestMatch\n}\n\nexport function getFormDataValueAsNumber(\n formDataValue: string | number | undefined,\n): number | null {\n const maxSize =\n formDataValue !== null ? parseFloat(String(formDataValue)) : null\n const isInteger = Number.isInteger(maxSize)\n return isInteger ? maxSize : null\n}\n\nexport const isFormDataValueSmallerThanRecommendedValue = (\n formDataValue: string | number | undefined,\n recommendedValue: number | undefined,\n): boolean => {\n const currentValue = getFormDataValueAsNumber(formDataValue)\n return recommendedValue != null && currentValue != null && currentValue > 0\n ? currentValue < recommendedValue\n : false\n}\n\nexport function doesColumnModelSatisfyAnnotationMinimums(\n columnModel: ColumnModelFormData,\n annotationColumnModel?: ColumnModel,\n): boolean {\n if (!annotationColumnModel) {\n return true\n }\n\n if (\n isFormDataValueSmallerThanRecommendedValue(\n columnModel.maximumSize,\n annotationColumnModel.maximumSize,\n ) ||\n isFormDataValueSmallerThanRecommendedValue(\n columnModel.maximumListLength,\n annotationColumnModel.maximumListLength,\n )\n ) {\n return false\n }\n\n return true\n}\n\nexport function getNumberOfColumnModelsWithValuesBelowMinimumRecommendedSizes(\n columnModels: ColumnModelFormData[],\n annotationColumnModels: ColumnModel[],\n): number {\n return columnModels.filter(cm => {\n const matchingAnnotationColumnModel = findMatchingColumnModel(\n annotationColumnModels,\n cm,\n )\n\n return !doesColumnModelSatisfyAnnotationMinimums(\n cm,\n matchingAnnotationColumnModel,\n )\n }).length\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TableColumnSchemaEditorUtils.js","names":[],"sources":["../../../src/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.ts"],"sourcesContent":["import {\n convertToEntityType,\n isDataset,\n isDatasetCollection,\n isEntityView,\n isSubmissionView,\n} from '@/utils/functions/EntityTypeUtils'\nimport { ViewEntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ColumnModel,\n ColumnType,\n ColumnTypeEnum,\n Entity,\n ENTITY_VIEW_TYPE_MASK_DATASET,\n ENTITY_VIEW_TYPE_MASK_FILE,\n FacetType,\n ViewScope,\n} from '@sage-bionetworks/synapse-types'\nimport { JSONSchema7Definition } from 'json-schema'\nimport { SetOptional } from 'type-fest'\nimport {\n ColumnModelFormData,\n JsonSubColumnModelFormData,\n} from './Validators/ColumnModelValidator'\n\n/**\n * These column types can only be used in Tables. They can not be used in views.\n * See SWC-6333 - for views, only allow column types that are mapped to annotation types.\n */\nconst unsupportedTypesForViews = [ColumnTypeEnum.JSON]\n\n/**\n * Get the allowed column types for a column model based on the table type.\n * @param isView - whether the base table is a view\n * @param isJsonSubColumnFacet - whether the proposed column is a JSON subcolumn facet\n */\nexport function getAllowedColumnTypes(\n isView: boolean,\n isJsonSubColumnFacet: boolean,\n): ColumnTypeEnum[] {\n return Object.values(ColumnTypeEnum)\n .filter(columnType =>\n isView ? !unsupportedTypesForViews.includes(columnType) : true,\n )\n .filter(columnType => {\n if (isJsonSubColumnFacet) {\n switch (columnType) {\n // JSON Subcolumns cannot be JSON or LIST types\n case ColumnTypeEnum.JSON:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.INTEGER_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.DATE_LIST:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n return false\n default:\n return true\n }\n }\n return true\n })\n}\n\nexport function getFacetTypeFriendlyName(facetType: FacetType) {\n switch (facetType) {\n case 'enumeration':\n return 'Values'\n case 'range':\n return 'Range'\n default:\n return facetType\n }\n}\nexport function getColumnTypeFriendlyName(type: ColumnType | ColumnTypeEnum) {\n switch (type) {\n case ColumnTypeEnum.STRING:\n return 'String'\n case ColumnTypeEnum.DOUBLE:\n return 'Double'\n case ColumnTypeEnum.BOOLEAN:\n return 'Boolean'\n case ColumnTypeEnum.INTEGER:\n return 'Integer'\n case ColumnTypeEnum.DATE:\n return 'Date'\n case ColumnTypeEnum.FILEHANDLEID:\n return 'File'\n case ColumnTypeEnum.ENTITYID:\n return 'Entity'\n case ColumnTypeEnum.LINK:\n return 'Link'\n case ColumnTypeEnum.MEDIUMTEXT:\n return 'MediumText'\n case ColumnTypeEnum.LARGETEXT:\n return 'LargeText'\n case ColumnTypeEnum.USERID:\n return 'User'\n case ColumnTypeEnum.STRING_LIST:\n return 'String List'\n case ColumnTypeEnum.INTEGER_LIST:\n return 'Integer List'\n case ColumnTypeEnum.BOOLEAN_LIST:\n return 'Boolean List'\n case ColumnTypeEnum.DATE_LIST:\n return 'Date List'\n case ColumnTypeEnum.USERID_LIST:\n return 'User ID List'\n case ColumnTypeEnum.ENTITYID_LIST:\n return 'Entity ID List'\n case ColumnTypeEnum.EVALUATIONID:\n return 'Evaluation'\n case ColumnTypeEnum.SUBMISSIONID:\n return 'Submission'\n case ColumnTypeEnum.JSON:\n return 'JSON'\n default:\n return type\n }\n}\n\n/**\n * Can the given type have a size?\n *\n * @param type\n * @return\n */\nexport function canHaveSize(type: ColumnType | ColumnTypeEnum): boolean {\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.LINK:\n return true\n default:\n // all others are false\n return false\n }\n}\n\nexport function canHaveMaxListLength(\n type: ColumnType | ColumnTypeEnum,\n): boolean {\n switch (type) {\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.DATE_LIST:\n case ColumnTypeEnum.INTEGER_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.USERID_LIST:\n return true\n default:\n // all others are false\n return false\n }\n}\n\n/**\n * Configure the facet selection based on the column type\n *\n * @param type a ColumnType for which to get the facet selection\n * @param isJsonSubColumnFacet is this a facet for a json subcolumn?\n * @return the allowed facetTypes, or null if faceting is not allowed\n */\nexport function configureFacetsForType(\n type: ColumnType | ColumnTypeEnum,\n isJsonSubColumnFacet: boolean,\n): (FacetType | undefined)[] | null {\n let allowedFacetTypes: (FacetType | undefined)[] | null\n switch (type) {\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.INTEGER_LIST:\n allowedFacetTypes = ['enumeration', 'range']\n break\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.USERID:\n case ColumnTypeEnum.ENTITYID:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.BOOLEAN_LIST:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.EVALUATIONID:\n allowedFacetTypes = ['enumeration']\n break\n case ColumnTypeEnum.DOUBLE:\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.DATE_LIST:\n allowedFacetTypes = ['range']\n break\n default:\n allowedFacetTypes = null\n }\n\n if (allowedFacetTypes && !isJsonSubColumnFacet) {\n // jsonSubColumn facets MUST have a facet definition, but regular column models do not need one\n // So allow `undefined` for regular columnModels.\n allowedFacetTypes = [undefined, ...allowedFacetTypes]\n }\n return allowedFacetTypes\n}\n\n/**\n * Column types that are not allowed to have a default value.\n * @see the `defaultValue` property description on the ColumnModel schema in the Synapse OpenAPI specification.\n */\nexport const DISALLOWED_DEFAULT_VALUE_COLUMN_TYPES: ColumnTypeEnum[] = [\n ColumnTypeEnum.ENTITYID,\n ColumnTypeEnum.ENTITYID_LIST,\n ColumnTypeEnum.EVALUATIONID,\n ColumnTypeEnum.FILEHANDLEID,\n ColumnTypeEnum.LARGETEXT,\n ColumnTypeEnum.MEDIUMTEXT,\n ColumnTypeEnum.SUBMISSIONID,\n ColumnTypeEnum.USERID,\n ColumnTypeEnum.USERID_LIST,\n]\n\nexport function canHaveDefault(\n type: ColumnType | ColumnTypeEnum,\n isView: boolean,\n isJsonSubColumnFacet: boolean,\n) {\n // SWC-6333: default types are not allowed in views\n if (isView) {\n return false\n } else if (isJsonSubColumnFacet) {\n return false\n } else {\n return !DISALLOWED_DEFAULT_VALUE_COLUMN_TYPES.includes(\n type as ColumnTypeEnum,\n )\n }\n}\n\nexport const DEFAULT_STRING_SIZE = 50\nexport const MAX_STRING_SIZE = 1000\nexport const DEFAULT_LIST_LENGTH = 100\n\n/** The maximum number of characters allowed in a column name. */\nexport const MAX_COLUMN_NAME_LENGTH = 256\n\n/** The maximum number of enumeration values allowed for a single column. */\nexport const MAX_ENUM_VALUES = 100\n\n/**\n * The maximum total character budget for a list column. The server enforces that\n * `maximumListLength * <per-element character size>` does not exceed this value.\n */\nexport const LIST_LENGTH_CHARACTER_BUDGET = 100_000\n\n/**\n * The fixed per-element character size (in the list-length budget) for list column types\n * whose element size is not configurable. STRING_LIST is excluded because its per-element\n * size is the configurable `maximumSize`.\n */\nconst FIXED_LIST_ELEMENT_CHARACTER_SIZE: Partial<\n Record<ColumnTypeEnum, number>\n> = {\n [ColumnTypeEnum.INTEGER_LIST]: 20,\n [ColumnTypeEnum.DATE_LIST]: 20,\n [ColumnTypeEnum.USERID_LIST]: 20,\n [ColumnTypeEnum.BOOLEAN_LIST]: 5,\n [ColumnTypeEnum.ENTITYID_LIST]: 44,\n}\n\n/**\n * Get the default max size for a given type.\n *\n * @param type\n * @return\n */\nexport function getMaxSizeForType(type: ColumnType | ColumnTypeEnum): number {\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n case ColumnTypeEnum.LINK:\n return MAX_STRING_SIZE\n default:\n throw new Error(`Type is not known to have a max size: ${type}`)\n }\n}\n\n/**\n * Get the maximum allowed `maximumListLength` for a list column type.\n *\n * The server enforces a total character budget of {@link LIST_LENGTH_CHARACTER_BUDGET}.\n * For STRING_LIST the per-element size is the configurable `maximumSize` (defaulting to\n * {@link DEFAULT_STRING_SIZE}); for all other list types the per-element size is fixed.\n *\n * @param type the list column type\n * @param maximumSize the configured element size, used only for STRING_LIST\n * @return the maximum allowed list length\n */\nexport function getMaxListLengthForType(\n type: ColumnType | ColumnTypeEnum,\n maximumSize?: number,\n): number {\n if (type === ColumnTypeEnum.STRING_LIST) {\n const elementSize = maximumSize ?? DEFAULT_STRING_SIZE\n return Math.floor(LIST_LENGTH_CHARACTER_BUDGET / elementSize)\n }\n const elementSize = FIXED_LIST_ELEMENT_CHARACTER_SIZE[type as ColumnTypeEnum]\n if (elementSize == null) {\n throw new Error(`Type is not known to have a max list length: ${type}`)\n }\n return Math.floor(LIST_LENGTH_CHARACTER_BUDGET / elementSize)\n}\n\nexport function canHaveRestrictedValues(\n type: ColumnType | ColumnTypeEnum,\n isJsonSubColumnFacet: boolean,\n): boolean {\n if (isJsonSubColumnFacet) {\n return false\n }\n switch (type) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.ENTITYID:\n return true\n default:\n // all other are false\n return false\n }\n}\n\nfunction transformEnumValues(\n enumValues: string[],\n columnType: ColumnType | ColumnTypeEnum,\n): (string | number)[] {\n // SWC-6622 - Special case: if these are INTEGER, convert to numbers before inserting data into form components\n // The editor validates that these are integers, so inserting the strings returned by the API causes an\n // unexpected validation error\n if (columnType === ColumnTypeEnum.INTEGER) {\n return enumValues.map(value => parseInt(value))\n }\n return enumValues\n}\n\n/**\n * Transform ColumnModels returned by Synapse into the form data for the TableColumnSchemaForm.\n * Default column models, if available, are used to determine which columns should not be editable in the form.\n * @param columnModels\n * @param defaultColumns\n */\nexport function transformColumnModelsToFormData(\n columnModels: SetOptional<ColumnModel, 'id'>[],\n defaultColumns: ColumnModel[] = [],\n): ColumnModelFormData[] {\n return columnModels.map((cm): ColumnModelFormData => {\n return {\n ...cm,\n columnType: cm.columnType as ColumnTypeEnum,\n maximumSize:\n cm.maximumSize == null ? undefined : cm.maximumSize.toString(),\n maximumListLength:\n cm.maximumListLength == null\n ? undefined\n : cm.maximumListLength.toString(),\n isSelected: false,\n // If the name matches a known default column model, then we consider it to be a default column model itself\n isOriginallyDefaultColumn: defaultColumns.some(\n dcm => dcm.name === cm.name,\n ),\n jsonSubColumns: cm.jsonSubColumns\n ? cm.jsonSubColumns.map((jsc): JsonSubColumnModelFormData => ({\n ...jsc,\n columnType: jsc.columnType as ColumnTypeEnum,\n isSelected: false,\n }))\n : undefined,\n // If this is defaultValue for a LIST column, the value is a serialized string\n defaultValue:\n cm.defaultValue && cm.columnType.endsWith('_LIST')\n ? JSON.parse(cm.defaultValue)\n : cm.defaultValue,\n enumValues:\n cm.enumValues != null\n ? transformEnumValues(cm.enumValues, cm.columnType)\n : undefined,\n }\n })\n}\n\nexport function getViewScopeForEntity(entity: Entity): ViewScope | undefined {\n if (isEntityView(entity)) {\n return {\n scope: entity.scopeIds,\n viewTypeMask: entity.viewTypeMask,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n } else if (isDataset(entity) || isDatasetCollection(entity)) {\n const mask = isDataset(entity)\n ? ENTITY_VIEW_TYPE_MASK_FILE\n : ENTITY_VIEW_TYPE_MASK_DATASET\n return {\n scope: (entity.items ?? []).map(\n item => `${item.entityId}.${item.versionNumber}`,\n ),\n viewTypeMask: mask,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n } else if (isSubmissionView(entity)) {\n return {\n scope: entity.scopeIds,\n viewTypeMask: undefined,\n viewEntityType: convertToEntityType(\n entity.concreteType,\n ) as ViewEntityType,\n }\n }\n return undefined\n}\n\nexport function getJsonSchemaItemDefinitionForColumnType(\n columnType: ColumnTypeEnum,\n): JSONSchema7Definition {\n switch (columnType) {\n case ColumnTypeEnum.STRING:\n case ColumnTypeEnum.STRING_LIST:\n return { type: 'string', minLength: 1 }\n case ColumnTypeEnum.DOUBLE:\n return { type: 'number' }\n case ColumnTypeEnum.BOOLEAN:\n case ColumnTypeEnum.BOOLEAN_LIST:\n return { type: 'boolean' }\n case ColumnTypeEnum.INTEGER:\n case ColumnTypeEnum.INTEGER_LIST:\n return { type: 'integer' }\n case ColumnTypeEnum.DATE:\n case ColumnTypeEnum.DATE_LIST:\n return { type: 'string', format: 'datetime' }\n case ColumnTypeEnum.FILEHANDLEID:\n case ColumnTypeEnum.ENTITYID:\n case ColumnTypeEnum.ENTITYID_LIST:\n case ColumnTypeEnum.LINK:\n case ColumnTypeEnum.MEDIUMTEXT:\n case ColumnTypeEnum.LARGETEXT:\n case ColumnTypeEnum.USERID:\n case ColumnTypeEnum.USERID_LIST:\n case ColumnTypeEnum.SUBMISSIONID:\n case ColumnTypeEnum.JSON:\n case ColumnTypeEnum.EVALUATIONID:\n default:\n return { type: 'string', minLength: 1 }\n }\n}\n\nconst columnModelMatchesFormData = (\n model: ColumnModel,\n target: ColumnModelFormData,\n): boolean => {\n return model.name === target.name && model.columnType === target.columnType\n}\n\nexport const findMatchingColumnModel = (\n columnModels: ColumnModel[],\n target: ColumnModelFormData,\n): ColumnModel | undefined => {\n let closestMatch: ColumnModel | undefined\n\n for (const model of columnModels) {\n if (columnModelMatchesFormData(model, target)) {\n closestMatch = model\n break\n }\n }\n\n return closestMatch\n}\n\nexport function getFormDataValueAsNumber(\n formDataValue: string | number | undefined,\n): number | null {\n const maxSize =\n formDataValue !== null ? parseFloat(String(formDataValue)) : null\n const isInteger = Number.isInteger(maxSize)\n return isInteger ? maxSize : null\n}\n\nexport const isFormDataValueSmallerThanRecommendedValue = (\n formDataValue: string | number | undefined,\n recommendedValue: number | undefined,\n): boolean => {\n const currentValue = getFormDataValueAsNumber(formDataValue)\n return recommendedValue != null && currentValue != null && currentValue > 0\n ? currentValue < recommendedValue\n : false\n}\n\nexport function doesColumnModelSatisfyAnnotationMinimums(\n columnModel: ColumnModelFormData,\n annotationColumnModel?: ColumnModel,\n): boolean {\n if (!annotationColumnModel) {\n return true\n }\n\n if (\n isFormDataValueSmallerThanRecommendedValue(\n columnModel.maximumSize,\n annotationColumnModel.maximumSize,\n ) ||\n isFormDataValueSmallerThanRecommendedValue(\n columnModel.maximumListLength,\n annotationColumnModel.maximumListLength,\n )\n ) {\n return false\n }\n\n return true\n}\n\nexport function getNumberOfColumnModelsWithValuesBelowMinimumRecommendedSizes(\n columnModels: ColumnModelFormData[],\n annotationColumnModels: ColumnModel[],\n): number {\n return columnModels.filter(cm => {\n const matchingAnnotationColumnModel = findMatchingColumnModel(\n annotationColumnModels,\n cm,\n )\n\n return !doesColumnModelSatisfyAnnotationMinimums(\n cm,\n matchingAnnotationColumnModel,\n )\n }).length\n}\n"],"mappings":"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"}
@@ -15,8 +15,8 @@ import { groupBy as b, isEqual as x, noop as S, omit as C, times as te } from "l
15
15
  import { Box as w, Button as T, styled as E } from "@mui/material";
16
16
  import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
17
17
  import { ColumnTypeEnum as A, VIEW_CONCRETE_TYPE_VALUES as ne } from "@sage-bionetworks/synapse-types";
18
- import { AddCircleTwoTone as j } from "@mui/icons-material";
19
- import { Provider as M, atom as re, useAtomValue as N, useSetAtom as P } from "jotai";
18
+ import { Provider as j, atom as re, useAtomValue as M, useSetAtom as N } from "jotai";
19
+ import P from "@mui/icons-material/AddCircleTwoTone";
20
20
  import F from "pluralize";
21
21
  import { selectAtom as I, useAtomCallback as L } from "jotai/utils";
22
22
  //#region src/components/TableColumnSchemaEditor/TableColumnSchemaForm.tsx
@@ -36,7 +36,7 @@ var R = "18px 18px 1.75fr 1.75fr 0.75fr 1fr 1.25fr 1.25fr 1fr 1.25fr", z = /* @_
36
36
  borderBottomLeftRadius: "5px"
37
37
  }) }), V = E(w, { label: "ColumnHeader" })({ fontWeight: 700 }), H = "Add All Annotations";
38
38
  function U(i, s) {
39
- let { initialData: d, entityType: h, viewScope: x, onSubmit: E = S, isSubmitting: D = !1, originalColumnModels: A } = i, M = N(v(() => re((e) => e(u).length), [])), I = P(u), [z, B] = y(null), H = L(g((e) => e(u), [])), U = t(h), W = ne.includes(U), G = W, K = W, { data: q, isLoading: J } = o(x?.viewEntityType, x?.viewTypeMask, {
39
+ let { initialData: d, entityType: h, viewScope: x, onSubmit: E = S, isSubmitting: D = !1, originalColumnModels: A } = i, j = M(v(() => re((e) => e(u).length), [])), I = N(u), [z, B] = y(null), H = L(g((e) => e(u), [])), U = t(h), W = ne.includes(U), G = W, K = W, { data: q, isLoading: J } = o(x?.viewEntityType, x?.viewTypeMask, {
40
40
  enabled: K,
41
41
  staleTime: Infinity
42
42
  }), Y = a({
@@ -117,7 +117,7 @@ function U(i, s) {
117
117
  backgroundColor: "grey.300",
118
118
  height: "2px"
119
119
  } }),
120
- te(M, (e) => /* @__PURE__ */ O(ie, {
120
+ te(j, (e) => /* @__PURE__ */ O(ie, {
121
121
  entityType: h,
122
122
  columnModelIndex: e,
123
123
  disabled: D,
@@ -138,13 +138,13 @@ function U(i, s) {
138
138
  onClick: () => {
139
139
  I({ type: "appendColumn" });
140
140
  },
141
- startIcon: /* @__PURE__ */ O(j, {}),
141
+ startIcon: /* @__PURE__ */ O(P, {}),
142
142
  disabled: D,
143
143
  children: "Add Column"
144
144
  }),
145
145
  K && /* @__PURE__ */ k(T, {
146
146
  variant: "outlined",
147
- startIcon: O(J ? r : j, {}),
147
+ startIcon: O(J ? r : P, {}),
148
148
  onClick: () => {
149
149
  ae();
150
150
  },
@@ -157,7 +157,7 @@ function U(i, s) {
157
157
  }),
158
158
  G && /* @__PURE__ */ O(T, {
159
159
  variant: "outlined",
160
- startIcon: O(Z ? r : j, {}),
160
+ startIcon: O(Z ? r : P, {}),
161
161
  disabled: Z || D,
162
162
  onClick: () => {
163
163
  oe();
@@ -176,7 +176,7 @@ function U(i, s) {
176
176
  });
177
177
  }
178
178
  function ie(e) {
179
- let { columnModelIndex: t, entityType: n, disabled: r, columnModelValidationErrors: a = null, annotationColumnModels: o, originalColumnModels: c } = e, l = P(u), f = N(v(() => I(u, (e) => e[t], x), [t])), p = c ? s(c, f) : void 0, m = o ? s(o, f) : void 0, h = v(() => a ? b(a.filter((e) => e.path[0] === t && e.path[1] == "jsonSubColumns"), (e) => e.path[2]) : {}, [t, a]);
179
+ let { columnModelIndex: t, entityType: n, disabled: r, columnModelValidationErrors: a = null, annotationColumnModels: o, originalColumnModels: c } = e, l = N(u), f = M(v(() => I(u, (e) => e[t], x), [t])), p = c ? s(c, f) : void 0, m = o ? s(o, f) : void 0, h = v(() => a ? b(a.filter((e) => e.path[0] === t && e.path[1] == "jsonSubColumns"), (e) => e.path[2]) : {}, [t, a]);
180
180
  if (!f) return /* @__PURE__ */ O(D, {});
181
181
  let g = f.isOriginallyDefaultColumn;
182
182
  return /* @__PURE__ */ k(D, { children: [
@@ -216,7 +216,7 @@ function ie(e) {
216
216
  ] });
217
217
  }
218
218
  var W = h(U), G = h(function(e, t) {
219
- return /* @__PURE__ */ O(M, { children: /* @__PURE__ */ O(W, {
219
+ return /* @__PURE__ */ O(j, { children: /* @__PURE__ */ O(W, {
220
220
  ...e,
221
221
  ref: t
222
222
  }) });