synapse-react-client 4.0.36 → 4.0.37
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.
- package/dist/SWC.index.js +1 -1
- package/dist/aridhia-queries/index.js +11 -11
- package/dist/aridhia-queries/useAridhiaQuery.d.ts +1 -0
- package/dist/aridhia-queries/useAridhiaQuery.d.ts.map +1 -1
- package/dist/aridhia-queries/useAridhiaQuery.js +24 -17
- package/dist/aridhia-queries/useAridhiaQuery.js.map +1 -1
- package/dist/assets/icons/emailWithNotification.js +15 -15
- package/dist/assets/icons/emailWithNotification.js.map +1 -1
- package/dist/assets/icons/emailWithNotification.svg +13 -13
- package/dist/components/AccessRequirementList/AccessRequirementList.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js +124 -117
- package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js +33 -32
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.js +39 -18
- package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts +32 -0
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js +285 -0
- package/dist/components/Aridhia/DarWizard/AridhiaDarWizard.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarAboutStep.d.ts +4 -0
- package/dist/components/Aridhia/DarWizard/DarAboutStep.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarAboutStep.js +17 -0
- package/dist/components/Aridhia/DarWizard/DarAboutStep.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarCompleteStep.d.ts +27 -0
- package/dist/components/Aridhia/DarWizard/DarCompleteStep.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarCompleteStep.js +96 -0
- package/dist/components/Aridhia/DarWizard/DarCompleteStep.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarDestinationStep.d.ts +28 -0
- package/dist/components/Aridhia/DarWizard/DarDestinationStep.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarDestinationStep.js +128 -0
- package/dist/components/Aridhia/DarWizard/DarDestinationStep.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarProjectStep.d.ts +4 -0
- package/dist/components/Aridhia/DarWizard/DarProjectStep.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarProjectStep.js +17 -0
- package/dist/components/Aridhia/DarWizard/DarProjectStep.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts +13 -0
- package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarSectionForm.js +23 -0
- package/dist/components/Aridhia/DarWizard/DarSectionForm.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts +11 -0
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +47 -0
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.d.ts +16 -0
- package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.js +33 -0
- package/dist/components/Aridhia/DarWizard/DarWorkspaceStep.js.map +1 -0
- package/dist/components/Aridhia/DarWizard/useDarDraft.d.ts +32 -0
- package/dist/components/Aridhia/DarWizard/useDarDraft.d.ts.map +1 -0
- package/dist/components/Aridhia/DarWizard/useDarDraft.js +44 -0
- package/dist/components/Aridhia/DarWizard/useDarDraft.js.map +1 -0
- package/dist/components/Aridhia/FairLabelField.d.ts +8 -0
- package/dist/components/Aridhia/FairLabelField.d.ts.map +1 -0
- package/dist/components/Aridhia/FairLabelField.js +13 -0
- package/dist/components/Aridhia/FairLabelField.js.map +1 -0
- package/dist/components/Aridhia/fairFormToRjsf.d.ts +36 -0
- package/dist/components/Aridhia/fairFormToRjsf.d.ts.map +1 -0
- package/dist/components/Aridhia/fairFormToRjsf.js +137 -0
- package/dist/components/Aridhia/fairFormToRjsf.js.map +1 -0
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.d.ts.map +1 -1
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js +2 -2
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js.map +1 -1
- package/dist/components/CardContainer/CardContainer.d.ts.map +1 -1
- package/dist/components/CardContainer/CardContainer.js +1 -1
- package/dist/components/CardContainer/CardContainer.js.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmission.d.ts.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmission.js +2 -2
- package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
- package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.d.ts.map +1 -1
- package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js +3 -3
- package/dist/components/ChallengeTeamWizard/ChallengeTeamWizard.js.map +1 -1
- package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js +1 -1
- package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
- package/dist/components/CreateTableViewWizard/CreateTableViewWizard.js +2 -2
- package/dist/components/CreateTableViewWizard/CreateTableViewWizard.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +121 -117
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts +21 -1
- package/dist/components/DataGrid/columns/DateTimeColumn.d.ts.map +1 -1
- package/dist/components/DataGrid/columns/DateTimeColumn.js +73 -29
- package/dist/components/DataGrid/columns/DateTimeColumn.js.map +1 -1
- package/dist/components/DataGrid/columns/NumberColumn.d.ts +31 -0
- package/dist/components/DataGrid/columns/NumberColumn.d.ts.map +1 -0
- package/dist/components/DataGrid/columns/NumberColumn.js +27 -0
- package/dist/components/DataGrid/columns/NumberColumn.js.map +1 -0
- package/dist/components/DataGrid/components/ReorderColumnsButton.d.ts +1 -0
- package/dist/components/DataGrid/components/ReorderColumnsButton.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsButton.js +17 -16
- package/dist/components/DataGrid/components/ReorderColumnsButton.js.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts +2 -0
- package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsDialog.js +104 -65
- package/dist/components/DataGrid/components/ReorderColumnsDialog.js.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.js +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +55 -51
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DataGrid/utils/computeDefaultColumnOrder.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/computeDefaultColumnOrder.js +9 -8
- package/dist/components/DataGrid/utils/computeDefaultColumnOrder.js.map +1 -1
- package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts +10 -5
- package/dist/components/DatasetHosting/DatasetDownloadButton.d.ts.map +1 -1
- package/dist/components/DatasetHosting/DatasetDownloadButton.js +66 -74
- package/dist/components/DatasetHosting/DatasetDownloadButton.js.map +1 -1
- package/dist/components/DatasetHosting/DatasetHosting.d.ts +6 -0
- package/dist/components/DatasetHosting/DatasetHosting.d.ts.map +1 -1
- package/dist/components/DatasetHosting/DatasetHosting.js +6 -0
- package/dist/components/DatasetHosting/DatasetHosting.js.map +1 -1
- package/dist/components/DatasetHosting/DatasetHostingAdornment.d.ts +15 -0
- package/dist/components/DatasetHosting/DatasetHostingAdornment.d.ts.map +1 -0
- package/dist/components/DatasetHosting/DatasetHostingAdornment.js +23 -0
- package/dist/components/DatasetHosting/DatasetHostingAdornment.js.map +1 -0
- package/dist/components/DatasetHosting/index.d.ts +2 -0
- package/dist/components/DatasetHosting/index.d.ts.map +1 -1
- package/dist/components/DatasetHosting/index.js +2 -1
- package/dist/components/DownloadCart/DownloadCartPage.d.ts.map +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.js +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
- package/dist/components/DropdownSelect/DropdownSelect.d.ts.map +1 -1
- package/dist/components/DropdownSelect/DropdownSelect.js +1 -1
- package/dist/components/DropdownSelect/DropdownSelect.js.map +1 -1
- package/dist/components/EntityFinder/tree/EntityTree.d.ts.map +1 -1
- package/dist/components/EntityFinder/tree/EntityTree.js +1 -1
- package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
- package/dist/components/EntityFinder/tree/VirtualizedTree.js +1 -1
- package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
- package/dist/components/FeaturedDataTabs/FacetPlotsCard.js +1 -1
- package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +176 -170
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/JsonSchemaForm/CustomFormContext.d.ts +9 -0
- package/dist/components/JsonSchemaForm/CustomFormContext.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.js +2 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.js.map +1 -1
- package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.js +1 -1
- package/dist/components/JsonSchemaForm/templates/ArrayFieldTemplate.js.map +1 -1
- package/dist/components/JsonSchemaForm/templates/FieldTemplate.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/templates/FieldTemplate.js +6 -6
- package/dist/components/JsonSchemaForm/templates/FieldTemplate.js.map +1 -1
- package/dist/components/JsonSchemaForm/widgets/DateWidget.d.ts +9 -0
- package/dist/components/JsonSchemaForm/widgets/DateWidget.d.ts.map +1 -0
- package/dist/components/JsonSchemaForm/widgets/DateWidget.js +23 -0
- package/dist/components/JsonSchemaForm/widgets/DateWidget.js.map +1 -0
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.css +1 -1
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts +3 -2
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.d.ts.map +1 -1
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js +10 -12
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.js.map +1 -1
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.js +8 -7
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.js.map +1 -1
- package/dist/components/MailchimpSubscribeSection/MailchimpSubscribeSection.module.scss +12 -2
- package/dist/components/Markdown/MarkdownEditor.js +1 -1
- package/dist/components/Markdown/MarkdownEditor.js.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.d.ts.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js +46 -46
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.js +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/LastUpdatedOn.js +1 -1
- package/dist/components/QueryWrapperPlotNav/LastUpdatedOn.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +27 -25
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.d.ts +0 -9
- package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.d.ts.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js +23 -31
- package/dist/components/SchemaDrivenAnnotationEditor/AnnotationEditorUtils.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.d.ts.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js +5 -4
- package/dist/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationEditor.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.d.ts.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.js +6 -5
- package/dist/components/SchemaDrivenAnnotationEditor/field/SynapseAnnotationsRJSFObjectField.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +2 -0
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +18 -13
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
- package/dist/components/StatisticsPlot.d.ts.map +1 -1
- package/dist/components/StatisticsPlot.js +1 -1
- package/dist/components/StatisticsPlot.js.map +1 -1
- package/dist/components/SynapseForm/SynapseFormWrapper.js +1 -1
- package/dist/components/SynapseForm/SynapseFormWrapper.js.map +1 -1
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.css +1 -1
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js +9 -9
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.js.map +1 -1
- package/dist/components/SynapseHomepageV2/HotdropsAndNews.module.scss +14 -0
- package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js +1 -1
- package/dist/components/SynapseHomepageV2/SynapseHomepageChatSearch.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchPage.js +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchPage.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTableRenderers.d.ts.map +1 -1
- package/dist/components/SynapseTable/SynapseTableRenderers.js +1 -1
- package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts +4 -0
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +71 -69
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
- package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts +4 -0
- package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts.map +1 -1
- package/dist/components/SynapseTable/table-top/DownloadOptions.js +14 -13
- package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
- package/dist/components/SynapseTable/usePrefetchTableData.js +1 -1
- package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js +4 -4
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormReducer.js.map +1 -1
- package/dist/components/TanStackTable/TableCellRenderer.d.ts.map +1 -1
- package/dist/components/TanStackTable/TableCellRenderer.js +1 -1
- package/dist/components/TanStackTable/TableCellRenderer.js.map +1 -1
- package/dist/components/TermsAndConditions/TermsAndConditions.js +1 -1
- package/dist/components/TermsAndConditions/TermsAndConditions.js.map +1 -1
- package/dist/components/Webhook/CreateWebhookModal.d.ts.map +1 -1
- package/dist/components/Webhook/CreateWebhookModal.js +1 -1
- package/dist/components/Webhook/CreateWebhookModal.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +172 -63
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.d.ts +3 -0
- package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.js +2 -2
- package/dist/components/dataaccess/UserAccessRequestHistory/RouteConstants.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js +10 -8
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPage.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js +74 -43
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js +2 -2
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryTable.js.map +1 -1
- package/dist/components/doi/CreateOrUpdateDoiModal.js +5 -5
- package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
- package/dist/components/entity/metadata/EntityModal.js +1 -1
- package/dist/components/entity/metadata/EntityModal.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +2 -2
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/index.js +113 -112
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +1 -1
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/components/row_renderers/Dataset.js +1 -1
- package/dist/components/row_renderers/Dataset.js.map +1 -1
- package/dist/components/styled/LeftRightPanel.d.ts +8 -0
- package/dist/components/styled/LeftRightPanel.d.ts.map +1 -1
- package/dist/components/styled/LeftRightPanel.js +10 -1
- package/dist/components/styled/LeftRightPanel.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
- package/dist/components/widgets/query-filter/FacetFilterControls.js +1 -1
- package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
- package/dist/index.js +174 -173
- package/dist/index.js.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +73 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.js +119 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -0
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js +1 -1
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/entityHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/entityHandlers.js +4 -4
- package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/userProfileHandlers.js +2 -2
- package/dist/mocks/msw/handlers/userProfileHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers.js +72 -69
- package/dist/mocks/msw/handlers.js.map +1 -1
- package/dist/style/components/_terms-and-conditions.scss +25 -3
- package/dist/style/main.css +1 -1
- package/dist/testutils/RjsfFormTestUtils.js +12 -0
- package/dist/testutils/RjsfFormTestUtils.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +1 -0
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/functions/QueryFilterUtils.js +1 -1
- package/dist/utils/functions/QueryFilterUtils.js.map +1 -1
- package/dist/utils/functions/SqlFunctions.js +1 -1
- package/dist/utils/functions/SqlFunctions.js.map +1 -1
- package/dist/utils/functions/queryUtils.js +1 -1
- package/dist/utils/functions/queryUtils.js.map +1 -1
- package/dist/utils/hooks/useDetectSSOCode.d.ts.map +1 -1
- package/dist/utils/hooks/useDetectSSOCode.js +1 -1
- package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
- package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js +1 -1
- package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
- package/dist/utils/jsonschema/SchemaAnnotationUtils.js +1 -1
- package/dist/utils/jsonschema/SchemaAnnotationUtils.js.map +1 -1
- package/dist/utils/jsonschema/collectTopLevelProperties.d.ts +22 -0
- package/dist/utils/jsonschema/collectTopLevelProperties.d.ts.map +1 -0
- package/dist/utils/jsonschema/collectTopLevelProperties.js +31 -0
- package/dist/utils/jsonschema/collectTopLevelProperties.js.map +1 -0
- package/dist/utils/jsonschema/getSchemaPropertyInfo.d.ts.map +1 -1
- package/dist/utils/jsonschema/getSchemaPropertyInfo.js +1 -1
- package/dist/utils/jsonschema/getSchemaPropertyInfo.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import e from "dayjs";
|
|
2
|
+
//#region src/components/Aridhia/fairFormToRjsf.ts
|
|
3
|
+
var t = new Set([
|
|
4
|
+
"string",
|
|
5
|
+
"text",
|
|
6
|
+
"markdown",
|
|
7
|
+
"boolean",
|
|
8
|
+
"date",
|
|
9
|
+
"list",
|
|
10
|
+
"phone",
|
|
11
|
+
"label"
|
|
12
|
+
]);
|
|
13
|
+
function n(e) {
|
|
14
|
+
if (!e || typeof e != "object") return [];
|
|
15
|
+
let { sections: t } = e;
|
|
16
|
+
if (t && typeof t == "object") return Object.entries(t).map(([e, t]) => {
|
|
17
|
+
let { label: n, fields: r } = t ?? {};
|
|
18
|
+
return {
|
|
19
|
+
key: e,
|
|
20
|
+
label: n,
|
|
21
|
+
fields: r ?? []
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
let n = e.fields;
|
|
25
|
+
return n && typeof n == "object" ? Object.entries(n).map(([e, t]) => ({
|
|
26
|
+
key: e,
|
|
27
|
+
fields: t ?? []
|
|
28
|
+
})) : [];
|
|
29
|
+
}
|
|
30
|
+
function r(e) {
|
|
31
|
+
return e == null ? void 0 : Number(e);
|
|
32
|
+
}
|
|
33
|
+
function i(e) {
|
|
34
|
+
let n = {}, i = { "ui:order": e.fields.map((e) => e.name) }, a = [], o = [];
|
|
35
|
+
for (let s of e.fields) {
|
|
36
|
+
let e = s.name;
|
|
37
|
+
if (!e) continue;
|
|
38
|
+
let c = s.validation ?? {};
|
|
39
|
+
if (!s.type || !t.has(s.type)) {
|
|
40
|
+
o.push(s);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
switch (c.required === !0 && s.type !== "label" && a.push(e), s.type) {
|
|
44
|
+
case "string":
|
|
45
|
+
n[e] = {
|
|
46
|
+
type: "string",
|
|
47
|
+
maxLength: r(c.maximum),
|
|
48
|
+
minLength: r(c.minimum)
|
|
49
|
+
}, i[e] = { "ui:placeholder": s.placeholder };
|
|
50
|
+
break;
|
|
51
|
+
case "text":
|
|
52
|
+
case "markdown":
|
|
53
|
+
n[e] = {
|
|
54
|
+
type: "string",
|
|
55
|
+
maxLength: r(c.maximum),
|
|
56
|
+
minLength: r(c.minimum)
|
|
57
|
+
}, i[e] = {
|
|
58
|
+
"ui:widget": "textarea",
|
|
59
|
+
"ui:placeholder": s.placeholder
|
|
60
|
+
};
|
|
61
|
+
break;
|
|
62
|
+
case "boolean":
|
|
63
|
+
n[e] = { type: "boolean" };
|
|
64
|
+
break;
|
|
65
|
+
case "date":
|
|
66
|
+
n[e] = {
|
|
67
|
+
type: "string",
|
|
68
|
+
format: "date-time"
|
|
69
|
+
}, i[e] = { "ui:widget": "DateWidget" };
|
|
70
|
+
break;
|
|
71
|
+
case "list":
|
|
72
|
+
n[e] = {
|
|
73
|
+
type: "string",
|
|
74
|
+
oneOf: (s.options ?? []).map((e) => ({
|
|
75
|
+
const: e.value,
|
|
76
|
+
title: e.text,
|
|
77
|
+
...e.description ? { description: e.description } : {}
|
|
78
|
+
}))
|
|
79
|
+
}, s.default_options && (n[e].default = s.default_options), i[e] = {
|
|
80
|
+
"ui:widget": "SelectWidget",
|
|
81
|
+
"ui:placeholder": s.placeholder
|
|
82
|
+
};
|
|
83
|
+
break;
|
|
84
|
+
case "phone":
|
|
85
|
+
n[e] = {
|
|
86
|
+
type: "string",
|
|
87
|
+
maxLength: r(c.maximum)
|
|
88
|
+
}, i[e] = { "ui:options": { inputType: "tel" } };
|
|
89
|
+
break;
|
|
90
|
+
case "label":
|
|
91
|
+
n[e] = {
|
|
92
|
+
type: "null",
|
|
93
|
+
title: s.label
|
|
94
|
+
}, i[e] = {
|
|
95
|
+
"ui:field": "fairLabel",
|
|
96
|
+
"ui:label": !1
|
|
97
|
+
};
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
s.type !== "label" && s.label && (n[e].title = s.label), s.defaultValue && (n[e].default = s.defaultValue);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
schema: {
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: n,
|
|
106
|
+
required: a
|
|
107
|
+
},
|
|
108
|
+
uiSchema: i,
|
|
109
|
+
unsupported: o
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function a(t, n) {
|
|
113
|
+
if (Array.isArray(n)) return n.map((e) => a(t, e)).join(", ");
|
|
114
|
+
if (typeof n == "boolean") return n ? "Yes" : "No";
|
|
115
|
+
let r = t.oneOf?.find((e) => e.const === n);
|
|
116
|
+
if (r) return r.title ?? String(n);
|
|
117
|
+
if (t.format === "date-time" && typeof n == "string") {
|
|
118
|
+
let t = e(n.slice(0, 10));
|
|
119
|
+
return t.isValid() ? t.format("MMM D, YYYY") : n;
|
|
120
|
+
}
|
|
121
|
+
return String(n);
|
|
122
|
+
}
|
|
123
|
+
function o(e, t) {
|
|
124
|
+
return Object.keys(e.properties ?? {}).flatMap((n) => {
|
|
125
|
+
let r = t[n];
|
|
126
|
+
if (r == null || r === "") return [];
|
|
127
|
+
let i = e.properties[n];
|
|
128
|
+
return [{
|
|
129
|
+
label: i.title ?? n,
|
|
130
|
+
value: a(i, r)
|
|
131
|
+
}];
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { i as fairSectionToRjsf, n as parseFairFormSections, o as summarizeFormAnswers };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=fairFormToRjsf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fairFormToRjsf.js","names":[],"sources":["../../../src/components/Aridhia/fairFormToRjsf.ts"],"sourcesContent":["import { RJSFSchema, UiSchema } from '@rjsf/utils'\nimport dayjs from 'dayjs'\nimport { FairField, FairFormPayload } from '@/aridhia-queries/FairFormPayload'\n\nexport type { FairField, FairFormPayload }\n\nexport type FairFormSection = {\n key: string\n label?: string\n fields: FairField[]\n}\n\nexport type FairRjsfSection = {\n schema: RJSFSchema\n uiSchema: UiSchema\n /** Fields whose `type` cannot be rendered; the wizard blocks submit and names them. */\n unsupported: FairField[]\n}\n\nconst RENDERABLE_TYPES = new Set([\n 'string',\n 'text',\n 'markdown',\n 'boolean',\n 'date',\n 'list',\n 'phone',\n 'label',\n])\n\n/**\n * Accepts both FAIR form-definition payload shapes seen in practice and normalizes them to\n * ordered sections:\n * - `{ sections: { about: { label, fields: [...] }, ... } }` — the shape returned by\n * `GET /workspaces-forms/{code}` (via `WorkspaceForm.sections`).\n * - `{ fields: { about: [...], project: [...] } }` — the shape declared for\n * `GET /workflows/{code}` (via `WorkflowNoControlsRequests.fields`).\n */\nexport function parseFairFormSections(\n payload: FairFormPayload | null | undefined,\n): FairFormSection[] {\n if (!payload || typeof payload !== 'object') {\n return []\n }\n\n const { sections } = payload\n if (sections && typeof sections === 'object') {\n return Object.entries(sections).map(([key, section]) => {\n const { label, fields } = section ?? {}\n return { key, label, fields: fields ?? [] }\n })\n }\n\n const fieldsBySection = payload.fields\n if (fieldsBySection && typeof fieldsBySection === 'object') {\n return Object.entries(fieldsBySection).map(([key, fields]) => ({\n key,\n fields: fields ?? [],\n }))\n }\n\n return []\n}\n\n/** FAIR sends `minimum`/`maximum` as strings; `undefined` in, `undefined` out. */\nfunction num(value: string | undefined): number | undefined {\n return value == null ? undefined : Number(value)\n}\n\n/** Translates one FAIR form section into an RJSF schema/uiSchema pair. */\nexport function fairSectionToRjsf(section: FairFormSection): FairRjsfSection {\n const properties: Record<string, RJSFSchema> = {}\n const uiSchema: UiSchema = {\n 'ui:order': section.fields.map(field => field.name!),\n }\n const required: string[] = []\n const unsupported: FairField[] = []\n\n for (const field of section.fields) {\n const name = field.name\n if (!name) {\n continue\n }\n const v = field.validation ?? {}\n\n if (!field.type || !RENDERABLE_TYPES.has(field.type)) {\n unsupported.push(field)\n continue\n }\n\n if (v.required === true && field.type !== 'label') {\n required.push(name)\n }\n\n switch (field.type) {\n case 'string': {\n properties[name] = {\n type: 'string',\n maxLength: num(v.maximum),\n minLength: num(v.minimum),\n }\n uiSchema[name] = { 'ui:placeholder': field.placeholder }\n break\n }\n case 'text':\n case 'markdown': {\n properties[name] = {\n type: 'string',\n maxLength: num(v.maximum),\n minLength: num(v.minimum),\n }\n uiSchema[name] = {\n 'ui:widget': 'textarea',\n 'ui:placeholder': field.placeholder,\n }\n break\n }\n case 'boolean': {\n properties[name] = { type: 'boolean' }\n break\n }\n case 'date': {\n // The FAIR API expects a `date-time`; the only date field is project_end_date\n // so a simple date picker (DateWidget) is ideal.\n properties[name] = { type: 'string', format: 'date-time' }\n uiSchema[name] = { 'ui:widget': 'DateWidget' }\n break\n }\n case 'list': {\n properties[name] = {\n type: 'string',\n oneOf: (field.options ?? []).map(option => ({\n const: option.value,\n title: option.text,\n ...(option.description ? { description: option.description } : {}),\n })),\n }\n if (field.default_options) {\n properties[name].default = field.default_options\n }\n uiSchema[name] = {\n 'ui:widget': 'SelectWidget',\n 'ui:placeholder': field.placeholder,\n }\n break\n }\n case 'phone': {\n properties[name] = { type: 'string', maxLength: num(v.maximum) }\n uiSchema[name] = { 'ui:options': { inputType: 'tel' } }\n break\n }\n case 'label': {\n properties[name] = { type: 'null', title: field.label }\n uiSchema[name] = { 'ui:field': 'fairLabel', 'ui:label': false }\n break\n }\n }\n\n if (field.type !== 'label' && field.label) {\n properties[name].title = field.label\n }\n\n if (field.defaultValue) {\n properties[name].default = field.defaultValue\n }\n }\n\n return {\n schema: {\n type: 'object',\n properties,\n required,\n },\n uiSchema,\n unsupported,\n }\n}\n\nexport type AnsweredField = { label: string; value: string }\n\nfunction formatAnswerValue(propertySchema: RJSFSchema, value: unknown): string {\n if (Array.isArray(value)) {\n return value.map(v => formatAnswerValue(propertySchema, v)).join(', ')\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n const oneOf = propertySchema.oneOf as\n | { const: unknown; title?: string }[]\n | undefined\n const matchedOption = oneOf?.find(option => option.const === value)\n if (matchedOption) {\n return matchedOption.title ?? String(value)\n }\n if (propertySchema.format === 'date-time' && typeof value === 'string') {\n // `DateWidget`-produced values are always UTC midnight for the picked calendar date;\n // format the date portion directly to avoid a local-timezone parse shifting it onto\n // the adjacent day.\n const parsed = dayjs(value.slice(0, 10))\n return parsed.isValid() ? parsed.format('MMM D, YYYY') : value\n }\n return String(value)\n}\n\n/**\n * Renders a `fairSectionToRjsf` schema's answered fields as `{ label, value }` pairs, in the\n * form's own field order, for read-only review UI (the DAR wizard's Review & submit step).\n * Unanswered fields (including `label`-type fields, which never carry a value) are omitted.\n */\nexport function summarizeFormAnswers(\n schema: RJSFSchema,\n values: Record<string, unknown>,\n): AnsweredField[] {\n const propertyNames = Object.keys(schema.properties ?? {})\n return propertyNames.flatMap(name => {\n const value = values[name]\n if (value === undefined || value === null || value === '') {\n return []\n }\n const propertySchema = (schema.properties as Record<string, RJSFSchema>)[\n name\n ]\n const label = propertySchema.title ?? name\n return [{ label, value: formatAnswerValue(propertySchema, value) }]\n })\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CannedRejectionDialog.d.ts","sourceRoot":"","sources":["../../../src/components/CannedRejectionDialog/CannedRejectionDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAA;AAI7F,OAAO,EAAY,SAAS,EAAuC,MAAM,OAAO,CAAA;AAYhF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAA;IAEb,OAAO,EAAE,MAAM,CAAA;IAEf,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,6DAA6D;IAC7D,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,yDAAyD;IACzD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,2EAA2E;IAC3E,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;
|
|
1
|
+
{"version":3,"file":"CannedRejectionDialog.d.ts","sourceRoot":"","sources":["../../../src/components/CannedRejectionDialog/CannedRejectionDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAA;AAI7F,OAAO,EAAY,SAAS,EAAuC,MAAM,OAAO,CAAA;AAYhF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAA;IAEb,OAAO,EAAE,MAAM,CAAA;IAEf,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,6DAA6D;IAC7D,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,yDAAyD;IACzD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,2EAA2E;IAC3E,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AA8LD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CA6JtE"}
|
|
@@ -48,7 +48,7 @@ function C(e) {
|
|
|
48
48
|
})] });
|
|
49
49
|
}
|
|
50
50
|
function w(e) {
|
|
51
|
-
let { tableQuery: r, selectedRowIds: i, setSelectedRowIds: a, rejectionFormPromptCopy: o } = e, { data: s, isLoading: c, error: l } = r, d = s?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === y), p = s?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === x), v = s
|
|
51
|
+
let { tableQuery: r, selectedRowIds: i, setSelectedRowIds: a, rejectionFormPromptCopy: o } = e, { data: s, isLoading: c, error: l } = r, d = s?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === y), p = s?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === x), v = s?.queryResult?.queryResults.rows.reduce((e, t) => {
|
|
52
52
|
let n = t.values[d];
|
|
53
53
|
return e[n] = [...e[n] || [], t], e;
|
|
54
54
|
}, {});
|
|
@@ -119,7 +119,7 @@ function E(t) {
|
|
|
119
119
|
query: { sql: `SELECT * FROM ${a}` },
|
|
120
120
|
partMask: 1,
|
|
121
121
|
concreteType: "org.sagebionetworks.repo.model.table.QueryBundleRequest"
|
|
122
|
-
}), { data: j } = A, M = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === y), N = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === b), P = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === S), F = j
|
|
122
|
+
}), { data: j } = A, M = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === y), N = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === b), P = j?.queryResult?.queryResults.headers.findIndex((e) => e.name.toLowerCase() === S), F = j?.queryResult && O.reduce((e, t) => {
|
|
123
123
|
let n = j.queryResult.queryResults.rows.find((e) => e.rowId === t), r = n.values[M], i = n.values[N], a = n.values[P];
|
|
124
124
|
return e[r] ? e[r].reasons = [...e[r].reasons, a] : e[r] = {
|
|
125
125
|
sectionText: i,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CannedRejectionDialog.js","names":[],"sources":["../../../src/components/CannedRejectionDialog/CannedRejectionDialog.tsx"],"sourcesContent":["import { useGetFullTableQueryResults } from '@/synapse-queries'\nimport { BUNDLE_MASK_QUERY_RESULTS } from '@/utils/SynapseConstants'\nimport {\n Checkbox,\n Collapse,\n FormControl,\n FormControlLabel,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport { QueryResultBundle, Row } from '@sage-bionetworks/synapse-types'\nimport { UseQueryResult } from '@tanstack/react-query'\nimport { Set } from 'immutable'\nimport { Dispatch, ReactNode, SetStateAction, useEffect, useState } from 'react'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FullWidthAlert from '../FullWidthAlert/FullWidthAlert'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\nconst CATEGORY_COLUMN_NAME = 'category'\nconst CATEGORY_SECTION_EMAIL_TEXT_COLUMN_NAME = 'category email prompt'\nconst REJECTION_REASON_FORM_TEXT_COLUMN_NAME = 'rejection reason'\nconst REJECTION_REASON_EMAIL_TEXT_COLUMN_NAME = 'email text'\n\nexport type CannedRejectionDialogProps = {\n open: boolean\n /* SynID of the table which contains the email responses which should populate this modal */\n tableId: string\n /* Callback invoked when the rejection is confirmed */\n onConfirm: (message: string) => void\n onClose: () => void\n /** Text injected into the beginning of the email template */\n defaultMessagePrefix?: string\n /** Text appended onto the end of the email template */\n defaultMessageAppend?: string\n /** Text to display above the canned rejection reasons */\n rejectionFormPromptCopy?: string\n /** Error to display, in case one occurred in the callback to `onReject` */\n error: SynapseClientError | null\n /** Optional children, can be used to extend the form as needed on step 2 */\n children?: ReactNode\n}\n\ntype RejectionCategoryProps = {\n category: string\n rows: Row[]\n rejectionReasonFormTextIndex: number\n selectedRowIds: Set<number>\n setSelectedRowIds: Dispatch<SetStateAction<Set<number>>>\n initialIsExpanded?: boolean\n}\n\ntype SelectRejectionReasonsFormProps = {\n tableQuery: UseQueryResult<QueryResultBundle, SynapseClientError>\n selectedRowIds: Set<number>\n setSelectedRowIds: Dispatch<SetStateAction<Set<number>>>\n rejectionFormPromptCopy?: string\n}\n\n/**\n * Renders a rejection reason category and checkboxes for each reason in the category\n */\nfunction RejectionCategory(props: RejectionCategoryProps) {\n const {\n category,\n rows,\n selectedRowIds,\n setSelectedRowIds,\n rejectionReasonFormTextIndex,\n initialIsExpanded = false,\n } = props\n const [isExpanded, setIsExpanded] = useState(initialIsExpanded)\n\n return (\n <>\n <Typography\n variant=\"body1\"\n onClick={() => setIsExpanded(!isExpanded)}\n sx={{ fontWeight: 700, cursor: 'pointer', my: 1 }}\n >\n <IconSvg\n icon={isExpanded ? 'expandMore' : 'chevronRight'}\n sx={{ color: 'grey.700' }}\n wrap={false}\n />\n {category}\n </Typography>\n <Collapse in={isExpanded}>\n <Stack sx={{ ml: 3 }}>\n {(rows ?? []).map(row => (\n <FormControlLabel\n key={row.rowId}\n control={\n <Checkbox\n checked={selectedRowIds.has(row.rowId!)}\n size={'small'}\n onChange={event => {\n if (event.target.checked) {\n setSelectedRowIds(selectedRowIds.add(row.rowId!))\n } else {\n setSelectedRowIds(selectedRowIds.remove(row.rowId!))\n }\n }}\n />\n }\n label={\n <Typography variant={'smallText1'}>\n {row.values[rejectionReasonFormTextIndex]}\n </Typography>\n }\n />\n ))}\n </Stack>\n </Collapse>\n </>\n )\n}\n\n/**\n * Renders a form for selecting individual rejection reasons grouped by category.\n * The rejection reason data comes from the table whose data is fetched in the tableQuery prop.\n */\nfunction SelectRejectionReasonsForm(props: SelectRejectionReasonsFormProps) {\n const {\n tableQuery,\n selectedRowIds,\n setSelectedRowIds,\n rejectionFormPromptCopy,\n } = props\n const { data: tableData, isLoading, error } = tableQuery\n const categoryIndex = tableData?.queryResult?.queryResults.headers.findIndex(\n header => header.name.toLowerCase() === CATEGORY_COLUMN_NAME,\n )\n const rejectionReasonFormTextIndex =\n tableData?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === REJECTION_REASON_FORM_TEXT_COLUMN_NAME,\n )\n\n const rowsGroupedByCategory =\n tableData &&\n tableData.queryResult &&\n tableData.queryResult.queryResults.rows.reduce(\n (acc: Record<string, Row[]>, row) => {\n const category: string = row.values[categoryIndex!]!\n acc[category] = [...(acc[category] || []), row]\n return acc\n },\n {},\n )\n return (\n <>\n <Typography variant=\"headline3\" gutterBottom>\n Reasons for rejecting\n </Typography>\n {rejectionFormPromptCopy && (\n <Typography variant=\"body1\" gutterBottom>\n {rejectionFormPromptCopy}\n </Typography>\n )}\n {isLoading && (\n <Stack sx={{ my: 2 }}>\n <SynapseSpinner size={30} />\n </Stack>\n )}\n {error && <ErrorBanner error={error} />}\n {rowsGroupedByCategory && (\n <FormControl>\n {Object.keys(rowsGroupedByCategory).map(category => (\n <RejectionCategory\n key={category}\n category={category}\n rows={rowsGroupedByCategory[category]}\n selectedRowIds={selectedRowIds}\n setSelectedRowIds={setSelectedRowIds}\n rejectionReasonFormTextIndex={rejectionReasonFormTextIndex!}\n initialIsExpanded={\n Object.keys(rowsGroupedByCategory).length === 1\n }\n />\n ))}\n </FormControl>\n )}\n <Typography variant=\"headline3\" sx={{ mt: 1 }} gutterBottom>\n We’ll generate a response email message based on your selections.\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n If your reasons for rejecting are not shown here, that’s okay! You can\n edit the complete text of the message on the next screen before sending\n it.\n </Typography>\n </>\n )\n}\n\ntype DraftRejectionMessageProps = {\n emailText: string\n setEmailText: Dispatch<SetStateAction<string>>\n}\n\n/**\n * Presents a text field form that can be used to directly modify the rejection message.\n */\nfunction DraftRejectionMessage(props: DraftRejectionMessageProps) {\n const { emailText, setEmailText } = props\n return (\n <>\n <Typography variant=\"headline3\" gutterBottom>\n Edit the text of the rejection message\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n This message will be sent to the requester. You may edit it, or add\n custom text to the message.\n </Typography>\n <TextField\n multiline\n fullWidth\n rows={15}\n value={emailText}\n onChange={event => {\n setEmailText(event.target.value)\n }}\n />\n </>\n )\n}\ntype RejectionMessageObject = {\n [category: string]: {\n sectionText: string\n reasons: string[]\n }\n}\n\n/**\n * Modal component presented to a data access submission reviewer when they decide to reject a request.\n * The modal contains a form for selecting rejection reasons and a text field for editing the rejection message.\n * After crafting a message, the user can reject the submission and send the message to the requester.\n */\nexport function CannedRejectionDialog(props: CannedRejectionDialogProps) {\n const {\n open,\n tableId,\n onClose,\n onConfirm: onReject,\n defaultMessagePrefix = '',\n defaultMessageAppend = '',\n rejectionFormPromptCopy,\n children,\n error,\n } = props\n\n const [step, setStep] = useState<1 | 2>(1)\n // selectedRowIds are the row IDs of the canned responses the user selected:\n const [emailText, setEmailText] = useState('')\n const [selectedRowIds, setSelectedRowIds] = useState(Set<number>())\n\n // Fetch the table data\n const tableQuery = useGetFullTableQueryResults({\n entityId: tableId,\n query: {\n sql: `SELECT * FROM ${tableId}`,\n },\n partMask: BUNDLE_MASK_QUERY_RESULTS,\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n })\n\n const { data } = tableQuery\n\n const categoryIndex = data?.queryResult?.queryResults.headers.findIndex(\n header => header.name.toLowerCase() === CATEGORY_COLUMN_NAME,\n )\n const categorySectionEmailTextIndex =\n data?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === CATEGORY_SECTION_EMAIL_TEXT_COLUMN_NAME,\n )\n\n const reasonEmailTextIndex =\n data?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === REJECTION_REASON_EMAIL_TEXT_COLUMN_NAME,\n )\n\n // Transform the selected rejection reasons into an object that can be easily transformed into an email\n const defaultEmailMessageObject: RejectionMessageObject | undefined =\n data &&\n data.queryResult &&\n selectedRowIds.reduce((messageObject: RejectionMessageObject, rowId) => {\n const row = data.queryResult!.queryResults.rows.find(\n row => row.rowId === rowId,\n )!\n const category = row.values[categoryIndex!]!\n const sectionText = row.values[categorySectionEmailTextIndex!]!\n const reasonText = row.values[reasonEmailTextIndex!]!\n if (messageObject[category]) {\n messageObject[category].reasons = [\n ...messageObject[category].reasons,\n reasonText,\n ]\n } else {\n messageObject[category] = {\n sectionText: sectionText,\n reasons: [reasonText],\n }\n }\n return messageObject\n }, {})\n\n // Using the rejection message object, create the email template.\n const defaultEmailMessage =\n defaultEmailMessageObject &&\n defaultMessagePrefix +\n Object.keys(defaultEmailMessageObject).reduce((message, key) => {\n message += '\\n'\n const sectionText = defaultEmailMessageObject[key].sectionText\n if (sectionText) {\n message += sectionText + '\\n'\n }\n\n for (const reason of defaultEmailMessageObject[key].reasons) {\n if (reason != null) {\n message += '\\n* ' + reason.replaceAll('\\\\n', '\\n') + '\\n'\n }\n }\n return message\n }, '') +\n defaultMessageAppend\n\n /* If the selected rows change, then reset the email text. */\n useEffect(() => {\n if (defaultEmailMessage) {\n setEmailText(defaultEmailMessage)\n }\n // Specifically fire on update to just selectedRowIds\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedRowIds])\n\n // If fetching/processing the table fails, gracefully fall back to just show the email template\n return (\n <ConfirmationDialog\n open={open}\n onCancel={() => {\n if (step === 1) {\n onClose()\n }\n if (step === 2) {\n setStep(1)\n }\n }}\n maxWidth={'md'}\n fullWidth\n title=\"Reject Request?\"\n content={\n <>\n {step === 1 && (\n <SelectRejectionReasonsForm\n tableQuery={tableQuery}\n selectedRowIds={selectedRowIds}\n setSelectedRowIds={setSelectedRowIds}\n rejectionFormPromptCopy={rejectionFormPromptCopy}\n />\n )}\n {step === 2 && (\n <>\n <DraftRejectionMessage\n emailText={emailText}\n setEmailText={setEmailText}\n />\n {children}\n </>\n )}\n {error && (\n <FullWidthAlert\n variant={'danger'}\n description={error.reason}\n isGlobal={false}\n />\n )}\n </>\n }\n onConfirm={() => {\n if (step === 1) {\n setStep(2)\n }\n if (step === 2) {\n onReject(emailText)\n }\n }}\n confirmButtonProps={{\n children: step === 1 ? 'Generate Email' : 'Reject and Notify Requester',\n }}\n cancelButtonProps={{\n children: step === 1 ? 'Cancel' : 'Back',\n }}\n />\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CannedRejectionDialog.js","names":[],"sources":["../../../src/components/CannedRejectionDialog/CannedRejectionDialog.tsx"],"sourcesContent":["import { useGetFullTableQueryResults } from '@/synapse-queries'\nimport { BUNDLE_MASK_QUERY_RESULTS } from '@/utils/SynapseConstants'\nimport {\n Checkbox,\n Collapse,\n FormControl,\n FormControlLabel,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport { QueryResultBundle, Row } from '@sage-bionetworks/synapse-types'\nimport { UseQueryResult } from '@tanstack/react-query'\nimport { Set } from 'immutable'\nimport { Dispatch, ReactNode, SetStateAction, useEffect, useState } from 'react'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FullWidthAlert from '../FullWidthAlert/FullWidthAlert'\nimport IconSvg from '../IconSvg/IconSvg'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\nconst CATEGORY_COLUMN_NAME = 'category'\nconst CATEGORY_SECTION_EMAIL_TEXT_COLUMN_NAME = 'category email prompt'\nconst REJECTION_REASON_FORM_TEXT_COLUMN_NAME = 'rejection reason'\nconst REJECTION_REASON_EMAIL_TEXT_COLUMN_NAME = 'email text'\n\nexport type CannedRejectionDialogProps = {\n open: boolean\n /* SynID of the table which contains the email responses which should populate this modal */\n tableId: string\n /* Callback invoked when the rejection is confirmed */\n onConfirm: (message: string) => void\n onClose: () => void\n /** Text injected into the beginning of the email template */\n defaultMessagePrefix?: string\n /** Text appended onto the end of the email template */\n defaultMessageAppend?: string\n /** Text to display above the canned rejection reasons */\n rejectionFormPromptCopy?: string\n /** Error to display, in case one occurred in the callback to `onReject` */\n error: SynapseClientError | null\n /** Optional children, can be used to extend the form as needed on step 2 */\n children?: ReactNode\n}\n\ntype RejectionCategoryProps = {\n category: string\n rows: Row[]\n rejectionReasonFormTextIndex: number\n selectedRowIds: Set<number>\n setSelectedRowIds: Dispatch<SetStateAction<Set<number>>>\n initialIsExpanded?: boolean\n}\n\ntype SelectRejectionReasonsFormProps = {\n tableQuery: UseQueryResult<QueryResultBundle, SynapseClientError>\n selectedRowIds: Set<number>\n setSelectedRowIds: Dispatch<SetStateAction<Set<number>>>\n rejectionFormPromptCopy?: string\n}\n\n/**\n * Renders a rejection reason category and checkboxes for each reason in the category\n */\nfunction RejectionCategory(props: RejectionCategoryProps) {\n const {\n category,\n rows,\n selectedRowIds,\n setSelectedRowIds,\n rejectionReasonFormTextIndex,\n initialIsExpanded = false,\n } = props\n const [isExpanded, setIsExpanded] = useState(initialIsExpanded)\n\n return (\n <>\n <Typography\n variant=\"body1\"\n onClick={() => setIsExpanded(!isExpanded)}\n sx={{ fontWeight: 700, cursor: 'pointer', my: 1 }}\n >\n <IconSvg\n icon={isExpanded ? 'expandMore' : 'chevronRight'}\n sx={{ color: 'grey.700' }}\n wrap={false}\n />\n {category}\n </Typography>\n <Collapse in={isExpanded}>\n <Stack sx={{ ml: 3 }}>\n {(rows ?? []).map(row => (\n <FormControlLabel\n key={row.rowId}\n control={\n <Checkbox\n checked={selectedRowIds.has(row.rowId!)}\n size={'small'}\n onChange={event => {\n if (event.target.checked) {\n setSelectedRowIds(selectedRowIds.add(row.rowId!))\n } else {\n setSelectedRowIds(selectedRowIds.remove(row.rowId!))\n }\n }}\n />\n }\n label={\n <Typography variant={'smallText1'}>\n {row.values[rejectionReasonFormTextIndex]}\n </Typography>\n }\n />\n ))}\n </Stack>\n </Collapse>\n </>\n )\n}\n\n/**\n * Renders a form for selecting individual rejection reasons grouped by category.\n * The rejection reason data comes from the table whose data is fetched in the tableQuery prop.\n */\nfunction SelectRejectionReasonsForm(props: SelectRejectionReasonsFormProps) {\n const {\n tableQuery,\n selectedRowIds,\n setSelectedRowIds,\n rejectionFormPromptCopy,\n } = props\n const { data: tableData, isLoading, error } = tableQuery\n const categoryIndex = tableData?.queryResult?.queryResults.headers.findIndex(\n header => header.name.toLowerCase() === CATEGORY_COLUMN_NAME,\n )\n const rejectionReasonFormTextIndex =\n tableData?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === REJECTION_REASON_FORM_TEXT_COLUMN_NAME,\n )\n\n const rowsGroupedByCategory =\n tableData?.queryResult?.queryResults.rows.reduce(\n (acc: Record<string, Row[]>, row) => {\n const category: string = row.values[categoryIndex!]!\n acc[category] = [...(acc[category] || []), row]\n return acc\n },\n {},\n )\n return (\n <>\n <Typography variant=\"headline3\" gutterBottom>\n Reasons for rejecting\n </Typography>\n {rejectionFormPromptCopy && (\n <Typography variant=\"body1\" gutterBottom>\n {rejectionFormPromptCopy}\n </Typography>\n )}\n {isLoading && (\n <Stack sx={{ my: 2 }}>\n <SynapseSpinner size={30} />\n </Stack>\n )}\n {error && <ErrorBanner error={error} />}\n {rowsGroupedByCategory && (\n <FormControl>\n {Object.keys(rowsGroupedByCategory).map(category => (\n <RejectionCategory\n key={category}\n category={category}\n rows={rowsGroupedByCategory[category]}\n selectedRowIds={selectedRowIds}\n setSelectedRowIds={setSelectedRowIds}\n rejectionReasonFormTextIndex={rejectionReasonFormTextIndex!}\n initialIsExpanded={\n Object.keys(rowsGroupedByCategory).length === 1\n }\n />\n ))}\n </FormControl>\n )}\n <Typography variant=\"headline3\" sx={{ mt: 1 }} gutterBottom>\n We’ll generate a response email message based on your selections.\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n If your reasons for rejecting are not shown here, that’s okay! You can\n edit the complete text of the message on the next screen before sending\n it.\n </Typography>\n </>\n )\n}\n\ntype DraftRejectionMessageProps = {\n emailText: string\n setEmailText: Dispatch<SetStateAction<string>>\n}\n\n/**\n * Presents a text field form that can be used to directly modify the rejection message.\n */\nfunction DraftRejectionMessage(props: DraftRejectionMessageProps) {\n const { emailText, setEmailText } = props\n return (\n <>\n <Typography variant=\"headline3\" gutterBottom>\n Edit the text of the rejection message\n </Typography>\n <Typography variant=\"body1\" gutterBottom>\n This message will be sent to the requester. You may edit it, or add\n custom text to the message.\n </Typography>\n <TextField\n multiline\n fullWidth\n rows={15}\n value={emailText}\n onChange={event => {\n setEmailText(event.target.value)\n }}\n />\n </>\n )\n}\ntype RejectionMessageObject = {\n [category: string]: {\n sectionText: string\n reasons: string[]\n }\n}\n\n/**\n * Modal component presented to a data access submission reviewer when they decide to reject a request.\n * The modal contains a form for selecting rejection reasons and a text field for editing the rejection message.\n * After crafting a message, the user can reject the submission and send the message to the requester.\n */\nexport function CannedRejectionDialog(props: CannedRejectionDialogProps) {\n const {\n open,\n tableId,\n onClose,\n onConfirm: onReject,\n defaultMessagePrefix = '',\n defaultMessageAppend = '',\n rejectionFormPromptCopy,\n children,\n error,\n } = props\n\n const [step, setStep] = useState<1 | 2>(1)\n // selectedRowIds are the row IDs of the canned responses the user selected:\n const [emailText, setEmailText] = useState('')\n const [selectedRowIds, setSelectedRowIds] = useState(Set<number>())\n\n // Fetch the table data\n const tableQuery = useGetFullTableQueryResults({\n entityId: tableId,\n query: {\n sql: `SELECT * FROM ${tableId}`,\n },\n partMask: BUNDLE_MASK_QUERY_RESULTS,\n concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',\n })\n\n const { data } = tableQuery\n\n const categoryIndex = data?.queryResult?.queryResults.headers.findIndex(\n header => header.name.toLowerCase() === CATEGORY_COLUMN_NAME,\n )\n const categorySectionEmailTextIndex =\n data?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === CATEGORY_SECTION_EMAIL_TEXT_COLUMN_NAME,\n )\n\n const reasonEmailTextIndex =\n data?.queryResult?.queryResults.headers.findIndex(\n header =>\n header.name.toLowerCase() === REJECTION_REASON_EMAIL_TEXT_COLUMN_NAME,\n )\n\n // Transform the selected rejection reasons into an object that can be easily transformed into an email\n const defaultEmailMessageObject: RejectionMessageObject | undefined =\n data?.queryResult &&\n selectedRowIds.reduce((messageObject: RejectionMessageObject, rowId) => {\n const row = data.queryResult!.queryResults.rows.find(\n row => row.rowId === rowId,\n )!\n const category = row.values[categoryIndex!]!\n const sectionText = row.values[categorySectionEmailTextIndex!]!\n const reasonText = row.values[reasonEmailTextIndex!]!\n if (messageObject[category]) {\n messageObject[category].reasons = [\n ...messageObject[category].reasons,\n reasonText,\n ]\n } else {\n messageObject[category] = {\n sectionText: sectionText,\n reasons: [reasonText],\n }\n }\n return messageObject\n }, {})\n\n // Using the rejection message object, create the email template.\n const defaultEmailMessage =\n defaultEmailMessageObject &&\n defaultMessagePrefix +\n Object.keys(defaultEmailMessageObject).reduce((message, key) => {\n message += '\\n'\n const sectionText = defaultEmailMessageObject[key].sectionText\n if (sectionText) {\n message += sectionText + '\\n'\n }\n\n for (const reason of defaultEmailMessageObject[key].reasons) {\n if (reason != null) {\n message += '\\n* ' + reason.replaceAll('\\\\n', '\\n') + '\\n'\n }\n }\n return message\n }, '') +\n defaultMessageAppend\n\n /* If the selected rows change, then reset the email text. */\n useEffect(() => {\n if (defaultEmailMessage) {\n setEmailText(defaultEmailMessage)\n }\n // Specifically fire on update to just selectedRowIds\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedRowIds])\n\n // If fetching/processing the table fails, gracefully fall back to just show the email template\n return (\n <ConfirmationDialog\n open={open}\n onCancel={() => {\n if (step === 1) {\n onClose()\n }\n if (step === 2) {\n setStep(1)\n }\n }}\n maxWidth={'md'}\n fullWidth\n title=\"Reject Request?\"\n content={\n <>\n {step === 1 && (\n <SelectRejectionReasonsForm\n tableQuery={tableQuery}\n selectedRowIds={selectedRowIds}\n setSelectedRowIds={setSelectedRowIds}\n rejectionFormPromptCopy={rejectionFormPromptCopy}\n />\n )}\n {step === 2 && (\n <>\n <DraftRejectionMessage\n emailText={emailText}\n setEmailText={setEmailText}\n />\n {children}\n </>\n )}\n {error && (\n <FullWidthAlert\n variant={'danger'}\n description={error.reason}\n isGlobal={false}\n />\n )}\n </>\n }\n onConfirm={() => {\n if (step === 1) {\n setStep(2)\n }\n if (step === 2) {\n onReject(emailText)\n }\n }}\n confirmButtonProps={{\n children: step === 1 ? 'Generate Email' : 'Reject and Notify Requester',\n }}\n cancelButtonProps={{\n children: step === 1 ? 'Cancel' : 'Back',\n }}\n />\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardContainer.d.ts","sourceRoot":"","sources":["../../../src/components/CardContainer/CardContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAA;AAYhF,OAAO,EAIL,MAAM,EACP,MAAM,iCAAiC,CAAA;AAaxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;AAuBzE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uBAAuB,CAAC,EAAE,4BAA4B,CAAA;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,iBAAiB,CAAA;AAoBrB,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"CardContainer.d.ts","sourceRoot":"","sources":["../../../src/components/CardContainer/CardContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAA;AAYhF,OAAO,EAIL,MAAM,EACP,MAAM,iCAAiC,CAAA;AAaxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;AAuBzE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uBAAuB,CAAC,EAAE,4BAA4B,CAAA;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,iBAAiB,CAAA;AAoBrB,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAyHtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardContainer.js","names":[],"sources":["../../../src/components/CardContainer/CardContainer.tsx"],"sourcesContent":["import { CardConfiguration } from '@/components/CardContainer/CardConfiguration'\nimport TableRowGenericCard from '@/components/GenericCard/TableRowGenericCard'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n DATASET,\n FUNDER,\n GENERIC_CARD,\n MEDIUM_USER_CARD,\n OBSERVATION_CARD,\n RELEASE_CARD,\n} from '@/utils/SynapseConstants'\nimport { Box } from '@mui/material'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Row,\n RowSet,\n} from '@sage-bionetworks/synapse-types'\nimport loadingScreen from '../LoadingScreen/LoadingScreen'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { ReleaseCard } from '../ReleaseCard'\nimport { Dataset, Funder } from '../row_renderers'\nimport {\n LoadingObservationCard,\n ObservationCard,\n} from '../row_renderers/ObservationCard'\nimport TotalQueryResults from '../TotalQueryResults'\nimport UserCardList from '../UserCardList/UserCardList'\nimport { SustainabilityScorecardProps } from '../SustainabilityScorecard'\n\nconst defaultListSx = { display: 'block' }\nconst releaseCardMediumListSx = {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, 272px)',\n gridAutoRows: 'auto',\n gridAutoFlow: 'row',\n gap: '10px',\n mb: '30px',\n}\nconst multiCardListSx = {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',\n gridColumnGap: '20px',\n marginBottom: '20px',\n marginTop: '20px',\n\n '& .SRC-portalCard': {\n margin: '10px 0px',\n },\n}\n\nexport type CardContainerProps = {\n rowSet: RowSet\n isHeader?: boolean\n sustainabilityScorecard?: SustainabilityScorecardProps\n isAlignToLeftNav?: boolean\n title?: string\n isLoading?: boolean\n unitDescription?: string\n multiCardList?: boolean\n} & CardConfiguration\n\nfunction Card(props: { propsToPass: any; type: string }) {\n const { propsToPass, type } = props\n switch (type) {\n case DATASET:\n return <Dataset {...propsToPass} />\n case FUNDER:\n return <Funder {...propsToPass} />\n case GENERIC_CARD:\n return <TableRowGenericCard {...propsToPass} />\n case OBSERVATION_CARD:\n return <ObservationCard {...propsToPass} />\n case RELEASE_CARD:\n return <ReleaseCard {...propsToPass} />\n default:\n return <div /> // this should never happen\n }\n}\n\nexport function CardContainer(props: CardContainerProps) {\n const {\n unitDescription,\n type,\n secondaryLabelLimit = 3,\n title,\n rowSet,\n multiCardList,\n ...rest\n } = props\n const { NoContentPlaceholder } = useQueryVisualizationContext()\n const queryContext = useQueryContext()\n const { data: queryMetadata, isLoading: queryMetadataIsLoading } =\n useGetQueryMetadata({ throwOnError: true })\n const queryVisualizationContext = useQueryVisualizationContext()\n\n const dataRows: Row[] = rowSet.rows\n const isMultipleCards = dataRows.length > 1\n\n const ids = [rowSet.tableId]\n const tableEntityConcreteType = useGetInfoFromIds<EntityHeader>({\n ids,\n type: 'ENTITY_HEADER',\n })\n\n // Render a loading placeholder while waiting for query metadata. Using a\n // non-suspense query (with conditional rendering) instead of Suspense keeps\n // the cards inline in the prerendered HTML when data is already cached,\n // rather than forcing React 19 streaming to stash them in a hidden div.\n if (queryMetadataIsLoading) {\n return (\n <div>\n {type === OBSERVATION_CARD && <LoadingObservationCard />}\n {type !== OBSERVATION_CARD && loadingScreen}\n </div>\n )\n }\n\n // the cards only show the loading screen on initial load, this occurs when data is undefined\n if (dataRows.length === 0) {\n // Show \"no results\" UI (see PORTALS-1497)\n return <NoContentPlaceholder />\n }\n\n const schema: Record<string, number> = {}\n rowSet.headers.forEach((element, index) => {\n schema[element.name] = index\n })\n\n let cards\n if (type === MEDIUM_USER_CARD) {\n // Hard coding ownerId as a column name containing the user profile ownerId\n // for each row, grab the column with the ownerId\n const userIdColumnName = queryMetadata?.columnModels?.find(\n cm => cm.columnType === ColumnTypeEnum.USERID,\n )?.name\n const userIdColumnIndex = userIdColumnName\n ? rowSet.headers.findIndex(el => el.name === userIdColumnName)\n : -1\n if (userIdColumnIndex === -1) {\n throw Error(\n 'Type MEDIUM_USER_CARD specified but no columnType USERID found',\n )\n }\n const listIds = dataRows.map(el => el.values[userIdColumnIndex])\n cards = (\n <UserCardList rowSet={rowSet} list={listIds} size={MEDIUM_USER_CARD} />\n )\n } else {\n // render the cards\n cards = dataRows.length ? (\n dataRows.map((rowData: Row, index) => {\n const propsForCard = {\n type,\n schema,\n secondaryLabelLimit,\n rowId: rowData.rowId,\n versionNumber: rowData.versionNumber,\n data: rowData.values,\n selectColumns: rowSet.headers,\n columnModels: queryMetadata!.columnModels,\n tableEntityConcreteType
|
|
1
|
+
{"version":3,"file":"CardContainer.js","names":[],"sources":["../../../src/components/CardContainer/CardContainer.tsx"],"sourcesContent":["import { CardConfiguration } from '@/components/CardContainer/CardConfiguration'\nimport TableRowGenericCard from '@/components/GenericCard/TableRowGenericCard'\nimport useGetInfoFromIds from '@/utils/hooks/useGetInfoFromIds'\nimport {\n DATASET,\n FUNDER,\n GENERIC_CARD,\n MEDIUM_USER_CARD,\n OBSERVATION_CARD,\n RELEASE_CARD,\n} from '@/utils/SynapseConstants'\nimport { Box } from '@mui/material'\nimport {\n ColumnTypeEnum,\n EntityHeader,\n Row,\n RowSet,\n} from '@sage-bionetworks/synapse-types'\nimport loadingScreen from '../LoadingScreen/LoadingScreen'\nimport { useQueryContext } from '../QueryContext'\nimport { useQueryVisualizationContext } from '../QueryVisualizationWrapper'\nimport { useGetQueryMetadata } from '../QueryWrapper/useGetQueryMetadata'\nimport { ReleaseCard } from '../ReleaseCard'\nimport { Dataset, Funder } from '../row_renderers'\nimport {\n LoadingObservationCard,\n ObservationCard,\n} from '../row_renderers/ObservationCard'\nimport TotalQueryResults from '../TotalQueryResults'\nimport UserCardList from '../UserCardList/UserCardList'\nimport { SustainabilityScorecardProps } from '../SustainabilityScorecard'\n\nconst defaultListSx = { display: 'block' }\nconst releaseCardMediumListSx = {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, 272px)',\n gridAutoRows: 'auto',\n gridAutoFlow: 'row',\n gap: '10px',\n mb: '30px',\n}\nconst multiCardListSx = {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',\n gridColumnGap: '20px',\n marginBottom: '20px',\n marginTop: '20px',\n\n '& .SRC-portalCard': {\n margin: '10px 0px',\n },\n}\n\nexport type CardContainerProps = {\n rowSet: RowSet\n isHeader?: boolean\n sustainabilityScorecard?: SustainabilityScorecardProps\n isAlignToLeftNav?: boolean\n title?: string\n isLoading?: boolean\n unitDescription?: string\n multiCardList?: boolean\n} & CardConfiguration\n\nfunction Card(props: { propsToPass: any; type: string }) {\n const { propsToPass, type } = props\n switch (type) {\n case DATASET:\n return <Dataset {...propsToPass} />\n case FUNDER:\n return <Funder {...propsToPass} />\n case GENERIC_CARD:\n return <TableRowGenericCard {...propsToPass} />\n case OBSERVATION_CARD:\n return <ObservationCard {...propsToPass} />\n case RELEASE_CARD:\n return <ReleaseCard {...propsToPass} />\n default:\n return <div /> // this should never happen\n }\n}\n\nexport function CardContainer(props: CardContainerProps) {\n const {\n unitDescription,\n type,\n secondaryLabelLimit = 3,\n title,\n rowSet,\n multiCardList,\n ...rest\n } = props\n const { NoContentPlaceholder } = useQueryVisualizationContext()\n const queryContext = useQueryContext()\n const { data: queryMetadata, isLoading: queryMetadataIsLoading } =\n useGetQueryMetadata({ throwOnError: true })\n const queryVisualizationContext = useQueryVisualizationContext()\n\n const dataRows: Row[] = rowSet.rows\n const isMultipleCards = dataRows.length > 1\n\n const ids = [rowSet.tableId]\n const tableEntityConcreteType = useGetInfoFromIds<EntityHeader>({\n ids,\n type: 'ENTITY_HEADER',\n })\n\n // Render a loading placeholder while waiting for query metadata. Using a\n // non-suspense query (with conditional rendering) instead of Suspense keeps\n // the cards inline in the prerendered HTML when data is already cached,\n // rather than forcing React 19 streaming to stash them in a hidden div.\n if (queryMetadataIsLoading) {\n return (\n <div>\n {type === OBSERVATION_CARD && <LoadingObservationCard />}\n {type !== OBSERVATION_CARD && loadingScreen}\n </div>\n )\n }\n\n // the cards only show the loading screen on initial load, this occurs when data is undefined\n if (dataRows.length === 0) {\n // Show \"no results\" UI (see PORTALS-1497)\n return <NoContentPlaceholder />\n }\n\n const schema: Record<string, number> = {}\n rowSet.headers.forEach((element, index) => {\n schema[element.name] = index\n })\n\n let cards\n if (type === MEDIUM_USER_CARD) {\n // Hard coding ownerId as a column name containing the user profile ownerId\n // for each row, grab the column with the ownerId\n const userIdColumnName = queryMetadata?.columnModels?.find(\n cm => cm.columnType === ColumnTypeEnum.USERID,\n )?.name\n const userIdColumnIndex = userIdColumnName\n ? rowSet.headers.findIndex(el => el.name === userIdColumnName)\n : -1\n if (userIdColumnIndex === -1) {\n throw Error(\n 'Type MEDIUM_USER_CARD specified but no columnType USERID found',\n )\n }\n const listIds = dataRows.map(el => el.values[userIdColumnIndex])\n cards = (\n <UserCardList rowSet={rowSet} list={listIds} size={MEDIUM_USER_CARD} />\n )\n } else {\n // render the cards\n cards = dataRows.length ? (\n dataRows.map((rowData: Row, index) => {\n const propsForCard = {\n type,\n schema,\n secondaryLabelLimit,\n rowId: rowData.rowId,\n versionNumber: rowData.versionNumber,\n data: rowData.values,\n selectColumns: rowSet.headers,\n columnModels: queryMetadata!.columnModels,\n tableEntityConcreteType: tableEntityConcreteType[0]?.type,\n tableId: rowSet.tableId,\n queryContext: queryContext,\n queryVisualizationContext,\n ...rest,\n }\n return (\n <Card\n key={rowData.rowId ?? index}\n propsToPass={propsForCard}\n type={type}\n />\n )\n })\n ) : (\n <></>\n )\n }\n\n const isReleaseCardMediumList =\n props.type === RELEASE_CARD &&\n props.releaseCardConfig?.cardSize === 'medium'\n\n let cardListSx = defaultListSx\n if (isReleaseCardMediumList) {\n cardListSx = releaseCardMediumListSx\n } else if (multiCardList && isMultipleCards) {\n cardListSx = multiCardListSx\n }\n\n return (\n <Box role=\"list\" sx={cardListSx}>\n {title && <h2 className=\"SRC-card-overview-title\">{title}</h2>}\n {!title && unitDescription && (\n <TotalQueryResults frontText={'Displaying'} />\n )}\n {/* ReactCSSTransitionGroup adds css fade in property for cards that come into view */}\n {cards}\n </Box>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,IAAgB,EAAE,SAAS,QAAQ,GACnC,IAA0B;CAC9B,SAAS;CACT,qBAAqB;CACrB,cAAc;CACd,cAAc;CACd,KAAK;CACL,IAAI;AACN,GACM,IAAkB;CACtB,SAAS;CACT,qBAAqB;CACrB,eAAe;CACf,cAAc;CACd,WAAW;CAEX,qBAAqB,EACnB,QAAQ,WACV;AACF;AAaA,SAAS,EAAK,GAA2C;CACvD,IAAM,EAAE,gBAAa,YAAS;CAC9B,QAAQ,GAAR;EACE,KAAK,GACH,OAAO,kBAAC,GAAD,EAAS,GAAI,EAAc,CAAA;EACpC,KAAK,GACH,OAAO,kBAAC,GAAD,EAAQ,GAAI,EAAc,CAAA;EACnC,KAAK,GACH,OAAO,kBAAC,GAAD,EAAqB,GAAI,EAAc,CAAA;EAChD,KAAK,GACH,OAAO,kBAAC,GAAD,EAAiB,GAAI,EAAc,CAAA;EAC5C,KAAK,GACH,OAAO,kBAAC,GAAD,EAAa,GAAI,EAAc,CAAA;EACxC,SACE,OAAO,kBAAC,OAAD,CAAM,CAAA;CACjB;AACF;AAEA,SAAgB,EAAc,GAA2B;CACvD,IAAM,EACJ,oBACA,SACA,yBAAsB,GACtB,UACA,WACA,kBACA,GAAG,MACD,GACE,EAAE,4BAAyB,EAA6B,GACxD,IAAe,EAAgB,GAC/B,EAAE,MAAM,GAAe,WAAW,MACtC,EAAoB,EAAE,cAAc,GAAK,CAAC,GACtC,IAA4B,EAA6B,GAEzD,IAAkB,EAAO,MACzB,IAAkB,EAAS,SAAS,GAGpC,IAA0B,EAAgC;EAC9D,KAAA,CAFW,EAAO,OAElB;EACA,MAAM;CACR,CAAC;CAMD,IAAI,GACF,OACE,kBAAC,OAAD,EAAA,UAAA,CACG,MAAA,sBAA6B,kBAAC,GAAD,CAAyB,CAAA,GACtD,MAAA,sBAA6B,CAC3B,EAAA,CAAA;CAKT,IAAI,EAAS,WAAW,GAEtB,OAAO,kBAAC,GAAD,CAAuB,CAAA;CAGhC,IAAM,IAAiC,CAAC;CACxC,EAAO,QAAQ,SAAS,GAAS,MAAU;EACzC,EAAO,EAAQ,QAAQ;CACzB,CAAC;CAED,IAAI;CACJ,IAAI,MAAA,oBAA2B;EAG7B,IAAM,IAAmB,GAAe,cAAc,MACpD,MAAM,EAAG,eAAe,EAAe,MACzC,GAAG,MACG,IAAoB,IACtB,EAAO,QAAQ,WAAU,MAAM,EAAG,SAAS,CAAgB,IAC3D;EACJ,IAAI,MAAsB,IACxB,MAAM,MACJ,gEACF;EAGF,IACE,kBAAC,GAAD;GAAsB;GAAQ,MAFhB,EAAS,KAAI,MAAM,EAAG,OAAO,EAEP;GAAS,MAAM;EAAmB,CAAA;CAE1E,OAEE,IAAQ,EAAS,SACf,EAAS,KAAK,GAAc,MAiBxB,kBAAC,GAAD;EAEE,aAAa;GAjBf;GACA;GACA;GACA,OAAO,EAAQ;GACf,eAAe,EAAQ;GACvB,MAAM,EAAQ;GACd,eAAe,EAAO;GACtB,cAAc,EAAe;GAC7B,yBAAyB,EAAwB,IAAI;GACrD,SAAS,EAAO;GACF;GACd;GACA,GAAG;EAKY;EACP;CACP,GAHM,EAAQ,SAAS,CAGvB,CAEJ,IAED,kBAAA,GAAA,CAAI,CAAA;CAIR,IAAM,IACJ,EAAM,SAAA,kBACN,EAAM,mBAAmB,aAAa,UAEpC,IAAa;CAOjB,OANI,IACF,IAAa,IACJ,KAAiB,MAC1B,IAAa,IAIb,kBAAC,GAAD;EAAK,MAAK;EAAO,IAAI;YAArB;GACG,KAAS,kBAAC,MAAD;IAAI,WAAU;cAA2B;GAAU,CAAA;GAC5D,CAAC,KAAS,KACT,kBAAC,GAAD,EAAmB,WAAW,aAAe,CAAA;GAG9C;EACE;;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeSubmission.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeSubmission/ChallengeSubmission.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EAGL,MAAM,EAKP,MAAM,iCAAiC,CAAA;AAMxC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,OAAO,UAAU,CAAC,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;IACjE,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,SAAS,EACT,QAAa,GACd,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"ChallengeSubmission.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeSubmission/ChallengeSubmission.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EAGL,MAAM,EAKP,MAAM,iCAAiC,CAAA;AAMxC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,EAAE,OAAO,UAAU,CAAC,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;IACjE,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,SAAS,EACT,QAAa,GACd,EAAE,wBAAwB,2CA0N1B;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -86,7 +86,7 @@ function y({ entityType: y, projectId: b, pageSize: x = 10 }) {
|
|
|
86
86
|
throwOnError: !0
|
|
87
87
|
});
|
|
88
88
|
return f(() => {
|
|
89
|
-
|
|
89
|
+
$?.canView && $.canAddChild && B(!0), T(!1);
|
|
90
90
|
}, [$]), f(() => {
|
|
91
91
|
!S && (K || !q) && (T(!1), D("Please login to continue."));
|
|
92
92
|
}, [
|
|
@@ -103,7 +103,7 @@ function y({ entityType: y, projectId: b, pageSize: x = 10 }) {
|
|
|
103
103
|
]), f(() => {
|
|
104
104
|
async function t() {
|
|
105
105
|
let t = await e(G(J, X), C);
|
|
106
|
-
t
|
|
106
|
+
t?.id && (j(t.id), F(!0));
|
|
107
107
|
}
|
|
108
108
|
S && X && J && M && I === !1 && t();
|
|
109
109
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeSubmission.js","names":[],"sources":["../../../src/components/ChallengeSubmission/ChallengeSubmission.tsx"],"sourcesContent":["import { createEntity } from '@/synapse-client'\nimport {\n useGetCurrentUserProfile,\n useGetEntityACL,\n useGetEntityAlias,\n useGetEntityChallenge,\n useGetEntityPermissions,\n useGetUserSubmissionTeams,\n useUpdateEntityACL,\n} from '@/synapse-queries'\nimport { useGetTeam } from '@/synapse-queries/team/useTeam'\nimport { useSynapseContext } from '@/utils'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ACCESS_TYPE,\n Challenge,\n Entity,\n Project,\n PROJECT_CONCRETE_TYPE_VALUE,\n ResourceAccess,\n Team,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect, useState } from 'react'\nimport { ErrorBanner, SynapseErrorBoundary } from '../error/ErrorBanner'\nimport ChallengeSubmissionStepper from './ChallengeSubmissionStepper'\nimport SubmissionDirectoryList from './SubmissionDirectoryList'\n\nexport type EntityItem = Entity & {\n repositoryName?: string\n versionNumber?: number\n}\n\nexport type ChallengeSubmissionProps = {\n entityType: typeof EntityType.dockerrepo | typeof EntityType.file\n pageSize: number\n projectId: string\n}\n\nexport function ChallengeSubmission({\n entityType,\n projectId,\n pageSize = 10,\n}: ChallengeSubmissionProps) {\n const { isAuthenticated, accessToken } = useSynapseContext()\n\n const [loading, setLoading] = useState<boolean>(true)\n const [errorMessage, setErrorMessage] = useState<string>()\n const [submissionTeamId, setSubmissionTeamId] = useState<string>()\n const [challengeProjectId, setChallengeProjectId] = useState<string>()\n const [newProject, setNewProject] = useState<Project>()\n const [isProjectNewlyCreated, setIsProjectNewlyCreated] = useState<boolean>()\n const [projectAliasFound, setProjectAliasFound] = useState<boolean>()\n const { mutate: updateACL } = useUpdateEntityACL()\n const [canSubmit, setCanSubmit] = useState<boolean>(false)\n const [selectedEntity, setSelectedEntity] = useState<EntityItem>()\n const [isShowingModal, setIsShowingModal] = useState<boolean>(false)\n\n const EMPTY_ID = ''\n\n const getProject = (c: Challenge, t: Team): Project => {\n const name = `Challenge Submission Project-${c.projectId}-${t.id}`\n const alias = name.replace(/\\s+/g, '_').replace(/-+/g, '_').toLowerCase()\n return {\n name,\n alias,\n concreteType: PROJECT_CONCRETE_TYPE_VALUE,\n description: `This Project was automatically created for Team \"${t.name}\" for Challenge \"${c.id}\"`,\n }\n }\n\n // Use the existing accessToken if present to get the current user's profile / userId\n const { data: userProfile, isLoading: isProfileLoading } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n throwOnError: true,\n })\n\n // Retrieve the challenge associated with the projectId passed through props\n const { data: challenge } = useGetEntityChallenge(projectId, {\n enabled: isAuthenticated && !!projectId,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n // Determine whether or not the given user belongs to any submission teams\n const { data: userSubmissionTeams } = useGetUserSubmissionTeams(\n challenge?.id ?? EMPTY_ID,\n 2,\n )\n\n useEffect(() => {\n if (isAuthenticated && !!challenge && userSubmissionTeams) {\n const isReg = userSubmissionTeams.results.length > 0\n if (!isReg) {\n setErrorMessage(\n 'Error: Please join a Submission Team before continuing.',\n )\n return setLoading(false)\n }\n if (userSubmissionTeams.results.length > 1) {\n setErrorMessage(\n 'Error: You are a member of more than one Submission Team. You may only belong to one Submission Team per Challenge.',\n )\n return setLoading(false)\n }\n setSubmissionTeamId(userSubmissionTeams.results[0])\n }\n }, [challenge, isAuthenticated, userSubmissionTeams])\n\n const { data: submissionTeam } = useGetTeam(submissionTeamId!, {\n enabled: !!submissionTeamId,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n const { data: entityAlias } = useGetEntityAlias(\n newProject?.alias ?? EMPTY_ID,\n {\n enabled: newProject !== undefined && !!challenge && !!submissionTeam,\n throwOnError: true,\n },\n )\n useEffect(() => {\n if (entityAlias) {\n setProjectAliasFound(true)\n setChallengeProjectId(entityAlias.id)\n } else {\n setProjectAliasFound(false)\n }\n }, [entityAlias])\n\n /**\n * If the challenge project was just created, retrieve its ACL\n * and add the submission team to it\n */\n const { data: entityACL } = useGetEntityACL(challengeProjectId ?? EMPTY_ID, {\n enabled: !!challengeProjectId && isProjectNewlyCreated === true,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n useEffect(() => {\n if (entityACL && isProjectNewlyCreated === true) {\n // Give submission team admin access to challenge project\n const teamResourceAccess: ResourceAccess = {\n principalId: Number(submissionTeam!.id),\n accessType: [\n ACCESS_TYPE.CHANGE_PERMISSIONS,\n ACCESS_TYPE.CHANGE_SETTINGS,\n ACCESS_TYPE.CREATE,\n ACCESS_TYPE.DELETE,\n ACCESS_TYPE.DOWNLOAD,\n ACCESS_TYPE.MODERATE,\n ACCESS_TYPE.READ,\n ACCESS_TYPE.UPDATE,\n ],\n }\n updateACL({\n ...entityACL,\n resourceAccess: [...entityACL.resourceAccess, teamResourceAccess],\n })\n setIsProjectNewlyCreated(false)\n }\n }, [entityACL])\n\n const { data: entityPermissions } = useGetEntityPermissions(\n challengeProjectId!,\n {\n enabled: !!challengeProjectId,\n refetchInterval: Infinity,\n throwOnError: true,\n },\n )\n\n useEffect(() => {\n if (\n entityPermissions &&\n entityPermissions.canView &&\n entityPermissions.canAddChild\n ) {\n setCanSubmit(true)\n }\n setLoading(false)\n }, [entityPermissions])\n\n useEffect(() => {\n if (!isAuthenticated && (!!userProfile || !isProfileLoading)) {\n setLoading(false)\n setErrorMessage('Please login to continue.')\n }\n }, [isAuthenticated, userProfile, isProfileLoading])\n\n useEffect(() => {\n if (isAuthenticated && submissionTeam && challenge && !newProject) {\n const project = getProject(challenge, submissionTeam)\n setNewProject(project)\n }\n }, [isAuthenticated, submissionTeam, challenge, newProject])\n\n useEffect(() => {\n async function createChallengeProject() {\n const project: Project = getProject(challenge!, submissionTeam!)\n const challengeProject = await createEntity(project, accessToken)\n if (challengeProject && challengeProject.id) {\n setChallengeProjectId(challengeProject.id)\n setIsProjectNewlyCreated(true)\n }\n }\n if (\n isAuthenticated &&\n submissionTeam &&\n challenge &&\n newProject &&\n projectAliasFound === false\n ) {\n createChallengeProject()\n }\n }, [\n isAuthenticated,\n submissionTeam,\n challenge,\n newProject,\n projectAliasFound,\n accessToken,\n ])\n\n const itemSelectedHandler = (entity: EntityItem) => {\n setSelectedEntity(entity)\n setIsShowingModal(true)\n }\n\n const onModalClose = () => {\n setIsShowingModal(false)\n }\n\n return (\n <SynapseErrorBoundary>\n {loading && (\n <span data-testid=\"SpinnerButton-spinner\" className=\"spinner\" />\n )}\n {canSubmit && (\n <>\n <SubmissionDirectoryList\n entityType={entityType}\n pageSize={pageSize}\n challengeProjectId={challengeProjectId!}\n onItemSelected={itemSelectedHandler}\n />\n {userProfile && selectedEntity && (\n <ChallengeSubmissionStepper\n projectId={projectId}\n userId={userProfile?.ownerId}\n teamId={submissionTeamId!}\n entity={selectedEntity}\n entityType={entityType}\n isShowingModal={isShowingModal}\n onClose={onModalClose}\n />\n )}\n </>\n )}\n {errorMessage && <ErrorBanner error={errorMessage}></ErrorBanner>}\n </SynapseErrorBoundary>\n )\n}\n\nexport default ChallengeSubmission\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChallengeSubmission.js","names":[],"sources":["../../../src/components/ChallengeSubmission/ChallengeSubmission.tsx"],"sourcesContent":["import { createEntity } from '@/synapse-client'\nimport {\n useGetCurrentUserProfile,\n useGetEntityACL,\n useGetEntityAlias,\n useGetEntityChallenge,\n useGetEntityPermissions,\n useGetUserSubmissionTeams,\n useUpdateEntityACL,\n} from '@/synapse-queries'\nimport { useGetTeam } from '@/synapse-queries/team/useTeam'\nimport { useSynapseContext } from '@/utils'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n ACCESS_TYPE,\n Challenge,\n Entity,\n Project,\n PROJECT_CONCRETE_TYPE_VALUE,\n ResourceAccess,\n Team,\n} from '@sage-bionetworks/synapse-types'\nimport { useEffect, useState } from 'react'\nimport { ErrorBanner, SynapseErrorBoundary } from '../error/ErrorBanner'\nimport ChallengeSubmissionStepper from './ChallengeSubmissionStepper'\nimport SubmissionDirectoryList from './SubmissionDirectoryList'\n\nexport type EntityItem = Entity & {\n repositoryName?: string\n versionNumber?: number\n}\n\nexport type ChallengeSubmissionProps = {\n entityType: typeof EntityType.dockerrepo | typeof EntityType.file\n pageSize: number\n projectId: string\n}\n\nexport function ChallengeSubmission({\n entityType,\n projectId,\n pageSize = 10,\n}: ChallengeSubmissionProps) {\n const { isAuthenticated, accessToken } = useSynapseContext()\n\n const [loading, setLoading] = useState<boolean>(true)\n const [errorMessage, setErrorMessage] = useState<string>()\n const [submissionTeamId, setSubmissionTeamId] = useState<string>()\n const [challengeProjectId, setChallengeProjectId] = useState<string>()\n const [newProject, setNewProject] = useState<Project>()\n const [isProjectNewlyCreated, setIsProjectNewlyCreated] = useState<boolean>()\n const [projectAliasFound, setProjectAliasFound] = useState<boolean>()\n const { mutate: updateACL } = useUpdateEntityACL()\n const [canSubmit, setCanSubmit] = useState<boolean>(false)\n const [selectedEntity, setSelectedEntity] = useState<EntityItem>()\n const [isShowingModal, setIsShowingModal] = useState<boolean>(false)\n\n const EMPTY_ID = ''\n\n const getProject = (c: Challenge, t: Team): Project => {\n const name = `Challenge Submission Project-${c.projectId}-${t.id}`\n const alias = name.replace(/\\s+/g, '_').replace(/-+/g, '_').toLowerCase()\n return {\n name,\n alias,\n concreteType: PROJECT_CONCRETE_TYPE_VALUE,\n description: `This Project was automatically created for Team \"${t.name}\" for Challenge \"${c.id}\"`,\n }\n }\n\n // Use the existing accessToken if present to get the current user's profile / userId\n const { data: userProfile, isLoading: isProfileLoading } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n throwOnError: true,\n })\n\n // Retrieve the challenge associated with the projectId passed through props\n const { data: challenge } = useGetEntityChallenge(projectId, {\n enabled: isAuthenticated && !!projectId,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n // Determine whether or not the given user belongs to any submission teams\n const { data: userSubmissionTeams } = useGetUserSubmissionTeams(\n challenge?.id ?? EMPTY_ID,\n 2,\n )\n\n useEffect(() => {\n if (isAuthenticated && !!challenge && userSubmissionTeams) {\n const isReg = userSubmissionTeams.results.length > 0\n if (!isReg) {\n setErrorMessage(\n 'Error: Please join a Submission Team before continuing.',\n )\n return setLoading(false)\n }\n if (userSubmissionTeams.results.length > 1) {\n setErrorMessage(\n 'Error: You are a member of more than one Submission Team. You may only belong to one Submission Team per Challenge.',\n )\n return setLoading(false)\n }\n setSubmissionTeamId(userSubmissionTeams.results[0])\n }\n }, [challenge, isAuthenticated, userSubmissionTeams])\n\n const { data: submissionTeam } = useGetTeam(submissionTeamId!, {\n enabled: !!submissionTeamId,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n const { data: entityAlias } = useGetEntityAlias(\n newProject?.alias ?? EMPTY_ID,\n {\n enabled: newProject !== undefined && !!challenge && !!submissionTeam,\n throwOnError: true,\n },\n )\n useEffect(() => {\n if (entityAlias) {\n setProjectAliasFound(true)\n setChallengeProjectId(entityAlias.id)\n } else {\n setProjectAliasFound(false)\n }\n }, [entityAlias])\n\n /**\n * If the challenge project was just created, retrieve its ACL\n * and add the submission team to it\n */\n const { data: entityACL } = useGetEntityACL(challengeProjectId ?? EMPTY_ID, {\n enabled: !!challengeProjectId && isProjectNewlyCreated === true,\n refetchInterval: Infinity,\n throwOnError: true,\n })\n\n useEffect(() => {\n if (entityACL && isProjectNewlyCreated === true) {\n // Give submission team admin access to challenge project\n const teamResourceAccess: ResourceAccess = {\n principalId: Number(submissionTeam!.id),\n accessType: [\n ACCESS_TYPE.CHANGE_PERMISSIONS,\n ACCESS_TYPE.CHANGE_SETTINGS,\n ACCESS_TYPE.CREATE,\n ACCESS_TYPE.DELETE,\n ACCESS_TYPE.DOWNLOAD,\n ACCESS_TYPE.MODERATE,\n ACCESS_TYPE.READ,\n ACCESS_TYPE.UPDATE,\n ],\n }\n updateACL({\n ...entityACL,\n resourceAccess: [...entityACL.resourceAccess, teamResourceAccess],\n })\n setIsProjectNewlyCreated(false)\n }\n }, [entityACL])\n\n const { data: entityPermissions } = useGetEntityPermissions(\n challengeProjectId!,\n {\n enabled: !!challengeProjectId,\n refetchInterval: Infinity,\n throwOnError: true,\n },\n )\n\n useEffect(() => {\n if (entityPermissions?.canView && entityPermissions.canAddChild) {\n setCanSubmit(true)\n }\n setLoading(false)\n }, [entityPermissions])\n\n useEffect(() => {\n if (!isAuthenticated && (!!userProfile || !isProfileLoading)) {\n setLoading(false)\n setErrorMessage('Please login to continue.')\n }\n }, [isAuthenticated, userProfile, isProfileLoading])\n\n useEffect(() => {\n if (isAuthenticated && submissionTeam && challenge && !newProject) {\n const project = getProject(challenge, submissionTeam)\n setNewProject(project)\n }\n }, [isAuthenticated, submissionTeam, challenge, newProject])\n\n useEffect(() => {\n async function createChallengeProject() {\n const project: Project = getProject(challenge!, submissionTeam!)\n const challengeProject = await createEntity(project, accessToken)\n if (challengeProject?.id) {\n setChallengeProjectId(challengeProject.id)\n setIsProjectNewlyCreated(true)\n }\n }\n if (\n isAuthenticated &&\n submissionTeam &&\n challenge &&\n newProject &&\n projectAliasFound === false\n ) {\n createChallengeProject()\n }\n }, [\n isAuthenticated,\n submissionTeam,\n challenge,\n newProject,\n projectAliasFound,\n accessToken,\n ])\n\n const itemSelectedHandler = (entity: EntityItem) => {\n setSelectedEntity(entity)\n setIsShowingModal(true)\n }\n\n const onModalClose = () => {\n setIsShowingModal(false)\n }\n\n return (\n <SynapseErrorBoundary>\n {loading && (\n <span data-testid=\"SpinnerButton-spinner\" className=\"spinner\" />\n )}\n {canSubmit && (\n <>\n <SubmissionDirectoryList\n entityType={entityType}\n pageSize={pageSize}\n challengeProjectId={challengeProjectId!}\n onItemSelected={itemSelectedHandler}\n />\n {userProfile && selectedEntity && (\n <ChallengeSubmissionStepper\n projectId={projectId}\n userId={userProfile?.ownerId}\n teamId={submissionTeamId!}\n entity={selectedEntity}\n entityType={entityType}\n isShowingModal={isShowingModal}\n onClose={onModalClose}\n />\n )}\n </>\n )}\n {errorMessage && <ErrorBanner error={errorMessage}></ErrorBanner>}\n </SynapseErrorBoundary>\n )\n}\n\nexport default ChallengeSubmission\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeTeamWizard.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamWizard.tsx"],"names":[],"mappings":"AAuDA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,iBAAS,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"ChallengeTeamWizard.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamWizard.tsx"],"names":[],"mappings":"AAuDA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,iBAAS,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,2CAkW3D;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -72,11 +72,11 @@ function C(C) {
|
|
|
72
72
|
switch (O) {
|
|
73
73
|
case "SELECT_YOUR_CHALLENGE_TEAM": {
|
|
74
74
|
let e = "Join Team", t = !1, n = g, i = "";
|
|
75
|
-
return J
|
|
75
|
+
return J?.hasOpenInvitation ? (e = "View Invitation to Join Team", n = () => {
|
|
76
76
|
k("ACCEPT_INVITATION");
|
|
77
|
-
}) : J
|
|
77
|
+
}) : J?.hasOpenRequest ? (e = "Join Request Pending", t = !0, i = "You have already submitted a request to join this team.") : J?.membershipApprovalRequired ? (e = "Request to Join Team", n = () => {
|
|
78
78
|
k("JOIN_REQUEST_FORM");
|
|
79
|
-
}) : J
|
|
79
|
+
}) : J?.canJoin && (e = "Join Team", n = () => {
|
|
80
80
|
X();
|
|
81
81
|
}), {
|
|
82
82
|
content: B && !q && /* @__PURE__ */ x(re, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeTeamWizard.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamWizard.tsx"],"sourcesContent":["import {\n useAddMemberToTeam,\n useGetCurrentUserProfile,\n useGetEntityChallenge,\n useGetMembershipStatus,\n useGetUserSubmissionTeams,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { Alert, Box, Button, Tooltip, Typography } from '@mui/material'\nimport { noop } from 'lodash-es'\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { DialogBase } from '../DialogBase'\nimport { SignInPrompt, SynapseErrorBoundary } from '../error/ErrorBanner'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport {\n CreateChallengeTeam,\n CreateChallengeTeamHandle,\n} from './CreateChallengeTeam'\nimport {\n MembershipRequestForm,\n MembershipRequestFormHandle,\n} from './MembershipRequestForm'\nimport {\n AcceptMembershipInvitationButton,\n OpenMembershipInvitation,\n} from './OpenMembershipInvitation'\nimport { RegistrationSuccessful } from './RegistrationSuccessful'\nimport { SelectChallengeTeam } from './SelectChallengeTeam'\n\nenum ChallengeTeamWizardStep {\n SELECT_YOUR_CHALLENGE_TEAM = 'SELECT_YOUR_CHALLENGE_TEAM',\n ACCEPT_INVITATION = 'ACCEPT_INVITATION',\n JOIN_REQUEST_FORM = 'JOIN_REQUEST_FORM',\n JOIN_REQUEST_SENT = 'JOIN_REQUEST_SENT',\n CREATE_NEW_TEAM = 'CREATE_NEW_TEAM',\n REGISTRATION_SUCCESSFUL = 'REGISTRATION_SUCCESSFUL',\n}\n\nfunction getStepDialogTitle(step: ChallengeTeamWizardStep) {\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM:\n return 'Select Your Submission Team'\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n return 'Invitation to Join Team'\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n return 'Request Team Membership'\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n return 'Request Sent'\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM:\n return 'Create Team'\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n return 'Registration Successful!'\n }\n}\n\nexport type ChallengeTeamWizardProps = {\n projectId: string\n isShowingModal?: boolean\n onClose: () => void\n}\n\n/**\n * The ChallengeTeamWizard is used to guide a user through the process of joining or creating a team for a challenge.\n *\n * A required precondition is that the user is NOT on any registered submission team for the challenge.\n */\nfunction ChallengeTeamWizard(props: ChallengeTeamWizardProps) {\n const { projectId, isShowingModal = false, onClose } = props\n const { isAuthenticated } = useSynapseContext()\n\n const [step, setStep] = useState<ChallengeTeamWizardStep>(\n ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM,\n )\n const [selectedTeamId, setSelectedTeamId] = useState<string | undefined>()\n\n // Tracks if the form to create a new team is valid, so the wizard can control the `disabled` status of the confirm button\n const [canCreateNewTeam, setCanCreateNewTeam] = useState(false)\n // true if the user has created a new team to register for the challenge\n const [hasCreatedNewTeam, setHasCreatedNewTeam] = useState<boolean>(false)\n\n const membershipRequestFormRef = useRef<MembershipRequestFormHandle>(null)\n const createTeamRef = useRef<CreateChallengeTeamHandle>(null)\n\n const { data: userProfile, isLoading: isLoadingUserProfile } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n })\n\n // Retrieve the challenge associated with the projectId passed through props\n const { data: challenge, isLoading: isLoadingChallenge } =\n useGetEntityChallenge(projectId)\n\n const {\n mutateAsync: addTeamMember,\n isPending: addMemberToTeamIsPending,\n error: addUserToTeamError,\n } = useAddMemberToTeam()\n\n // Determine whether the given user belongs to any submission teams\n const { data: userSubmissionTeams, error: userSubmissionTeamError } =\n useGetUserSubmissionTeams(challenge?.id!, 1, 0, {\n enabled: Boolean(isAuthenticated && challenge),\n })\n\n const isMemberOfSubmissionTeam =\n userSubmissionTeams && userSubmissionTeams.results.length > 0\n\n const {\n data: selectedTeamMembershipStatus,\n isLoading: selectedTeamMembershipStatusIsLoading,\n error: selectedTeamMembershipStatusError,\n } = useGetMembershipStatus(selectedTeamId!, String(userProfile?.ownerId), {\n enabled: isAuthenticated && !!selectedTeamId && !!userProfile,\n })\n\n const addUserToTeam = useCallback(async () => {\n if (!selectedTeamId || !userProfile) return\n await addTeamMember({\n teamId: selectedTeamId,\n userId: userProfile.ownerId,\n })\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }, [addTeamMember, setStep, selectedTeamId, userProfile])\n\n const hide = useCallback(() => {\n setHasCreatedNewTeam(false)\n setSelectedTeamId(undefined)\n onClose()\n }, [onClose])\n\n const isLoading = isLoadingUserProfile || isLoadingChallenge\n\n const backButton = useMemo(() => {\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM:\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n // Cannot go back from these steps\n return <></>\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM:\n default:\n // All the other steps go back to team selection\n return (\n <Button\n variant={'outlined'}\n onClick={() => {\n setStep(ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM)\n setSelectedTeamId(undefined)\n }}\n >\n Back\n </Button>\n )\n }\n }, [step])\n\n const closeButton = useMemo(() => {\n return (\n <Button\n variant={'contained'}\n onClick={() => {\n onClose()\n }}\n >\n Close\n </Button>\n )\n }, [onClose])\n\n // Determine modal content based on step.id\n const { actions = <></>, content = <></> } = useMemo(() => {\n if (!isAuthenticated) {\n return {\n content: (\n <Alert severity={'error'}>\n <SignInPrompt />\n </Alert>\n ),\n }\n }\n\n if (isMemberOfSubmissionTeam) {\n return {\n content: (\n <Alert severity={'error'}>\n <Typography>\n You are already a member of a registered submission team for this\n Challenge.\n </Typography>\n </Alert>\n ),\n }\n }\n\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM: {\n let buttonText = 'Join Team'\n let disableJoiningSelectedTeam = false\n let buttonOnClickBehavior: () => void = noop\n let buttonTooltip = ''\n if (\n selectedTeamMembershipStatus &&\n selectedTeamMembershipStatus.hasOpenInvitation\n ) {\n // The user has been invited to join the selected team\n buttonText = 'View Invitation to Join Team'\n buttonOnClickBehavior = () => {\n setStep(ChallengeTeamWizardStep.ACCEPT_INVITATION)\n }\n } else if (\n selectedTeamMembershipStatus &&\n selectedTeamMembershipStatus.hasOpenRequest\n ) {\n // User already has an open request to join the selected team, disable button to avoid request spamming\n buttonText = 'Join Request Pending'\n disableJoiningSelectedTeam = true\n buttonTooltip =\n 'You have already submitted a request to join this team.'\n } else if (\n selectedTeamMembershipStatus &&\n selectedTeamMembershipStatus.membershipApprovalRequired\n ) {\n // The user has to send a request to join the selected team\n buttonText = 'Request to Join Team'\n buttonOnClickBehavior = () => {\n setStep(ChallengeTeamWizardStep.JOIN_REQUEST_FORM)\n }\n } else if (\n selectedTeamMembershipStatus &&\n selectedTeamMembershipStatus.canJoin\n ) {\n // The user can freely join the selected team\n buttonText = 'Join Team'\n buttonOnClickBehavior = () => {\n void addUserToTeam()\n }\n }\n return {\n content: challenge && !isMemberOfSubmissionTeam && (\n <SelectChallengeTeam\n challengeId={challenge.id}\n onCreateTeam={() =>\n setStep(ChallengeTeamWizardStep.CREATE_NEW_TEAM)\n }\n selectedTeamId={selectedTeamId}\n onSelectTeam={teamId => setSelectedTeamId(teamId)}\n />\n ),\n actions: (\n <>\n {backButton}\n <Tooltip title={buttonTooltip}>\n {/* Wrap button in span to show tooltip when button is disabled */}\n <span>\n <Button\n onClick={buttonOnClickBehavior}\n startIcon={\n addMemberToTeamIsPending ? <SynapseSpinner /> : undefined\n }\n disabled={\n !selectedTeamId ||\n selectedTeamMembershipStatusIsLoading ||\n addMemberToTeamIsPending ||\n disableJoiningSelectedTeam\n }\n variant={'contained'}\n >\n {buttonText}\n </Button>\n </span>\n </Tooltip>\n </>\n ),\n }\n }\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n return {\n content: <OpenMembershipInvitation teamId={selectedTeamId!} />,\n actions: (\n <>\n {backButton}\n <AcceptMembershipInvitationButton\n teamId={selectedTeamId!}\n onSuccess={() => {\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }}\n />\n </>\n ),\n }\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n return {\n content: (\n <MembershipRequestForm\n ref={membershipRequestFormRef}\n teamId={selectedTeamId!}\n onRequestSubmitted={() => {\n setStep(ChallengeTeamWizardStep.JOIN_REQUEST_SENT)\n }}\n />\n ),\n actions: (\n <>\n {backButton}\n <Button\n variant={'contained'}\n onClick={() => {\n membershipRequestFormRef?.current?.submit()\n }}\n >\n Send Request\n </Button>\n </>\n ),\n }\n\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n return {\n content: (\n <Typography variant=\"body1\" sx={{ lineHeight: '20px' }}>\n Team Manager(s) have received your request. Check your Synapse\n email address for status of your request.\n </Typography>\n ),\n actions: (\n <>\n {backButton}\n {closeButton}\n </>\n ),\n }\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n return {\n content: (\n <RegistrationSuccessful\n createdNewTeam={hasCreatedNewTeam}\n teamId={selectedTeamId}\n />\n ),\n actions: (\n <>\n {backButton}\n {closeButton}\n </>\n ),\n }\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM: {\n return {\n content: (\n <CreateChallengeTeam\n ref={createTeamRef}\n challengeId={challenge?.id!}\n onCanSubmitChange={canSubmit => setCanCreateNewTeam(canSubmit)}\n onFinished={teamId => {\n setHasCreatedNewTeam(true)\n setSelectedTeamId(teamId)\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }}\n />\n ),\n actions: (\n <>\n {backButton}\n <Button\n variant={'contained'}\n disabled={!canCreateNewTeam}\n onClick={() => {\n createTeamRef?.current?.submit()\n }}\n >\n Create Team\n </Button>\n </>\n ),\n }\n }\n }\n }, [\n isAuthenticated,\n isMemberOfSubmissionTeam,\n step,\n selectedTeamId,\n backButton,\n closeButton,\n hasCreatedNewTeam,\n selectedTeamMembershipStatus,\n challenge,\n addMemberToTeamIsPending,\n selectedTeamMembershipStatusIsLoading,\n addUserToTeam,\n canCreateNewTeam,\n ])\n\n const errorMessage =\n addUserToTeamError?.message ||\n selectedTeamMembershipStatusError?.message ||\n userSubmissionTeamError?.message\n\n return (\n <DialogBase\n onCancel={hide}\n open={isShowingModal}\n actions={actions}\n title={`Challenge Registration (Step 2 of 2): ${getStepDialogTitle(\n step,\n )}`}\n content={\n <SynapseErrorBoundary>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n }}\n >\n {isLoading ? (\n <SynapseSpinner size={40} />\n ) : (\n <>\n {content}\n {errorMessage && (\n <Alert severity={'error'}>{errorMessage}</Alert>\n )}\n </>\n )}\n </Box>\n </SynapseErrorBoundary>\n }\n />\n )\n}\n\nexport default ChallengeTeamWizard\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChallengeTeamWizard.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamWizard.tsx"],"sourcesContent":["import {\n useAddMemberToTeam,\n useGetCurrentUserProfile,\n useGetEntityChallenge,\n useGetMembershipStatus,\n useGetUserSubmissionTeams,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { Alert, Box, Button, Tooltip, Typography } from '@mui/material'\nimport { noop } from 'lodash-es'\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { DialogBase } from '../DialogBase'\nimport { SignInPrompt, SynapseErrorBoundary } from '../error/ErrorBanner'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport {\n CreateChallengeTeam,\n CreateChallengeTeamHandle,\n} from './CreateChallengeTeam'\nimport {\n MembershipRequestForm,\n MembershipRequestFormHandle,\n} from './MembershipRequestForm'\nimport {\n AcceptMembershipInvitationButton,\n OpenMembershipInvitation,\n} from './OpenMembershipInvitation'\nimport { RegistrationSuccessful } from './RegistrationSuccessful'\nimport { SelectChallengeTeam } from './SelectChallengeTeam'\n\nenum ChallengeTeamWizardStep {\n SELECT_YOUR_CHALLENGE_TEAM = 'SELECT_YOUR_CHALLENGE_TEAM',\n ACCEPT_INVITATION = 'ACCEPT_INVITATION',\n JOIN_REQUEST_FORM = 'JOIN_REQUEST_FORM',\n JOIN_REQUEST_SENT = 'JOIN_REQUEST_SENT',\n CREATE_NEW_TEAM = 'CREATE_NEW_TEAM',\n REGISTRATION_SUCCESSFUL = 'REGISTRATION_SUCCESSFUL',\n}\n\nfunction getStepDialogTitle(step: ChallengeTeamWizardStep) {\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM:\n return 'Select Your Submission Team'\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n return 'Invitation to Join Team'\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n return 'Request Team Membership'\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n return 'Request Sent'\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM:\n return 'Create Team'\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n return 'Registration Successful!'\n }\n}\n\nexport type ChallengeTeamWizardProps = {\n projectId: string\n isShowingModal?: boolean\n onClose: () => void\n}\n\n/**\n * The ChallengeTeamWizard is used to guide a user through the process of joining or creating a team for a challenge.\n *\n * A required precondition is that the user is NOT on any registered submission team for the challenge.\n */\nfunction ChallengeTeamWizard(props: ChallengeTeamWizardProps) {\n const { projectId, isShowingModal = false, onClose } = props\n const { isAuthenticated } = useSynapseContext()\n\n const [step, setStep] = useState<ChallengeTeamWizardStep>(\n ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM,\n )\n const [selectedTeamId, setSelectedTeamId] = useState<string | undefined>()\n\n // Tracks if the form to create a new team is valid, so the wizard can control the `disabled` status of the confirm button\n const [canCreateNewTeam, setCanCreateNewTeam] = useState(false)\n // true if the user has created a new team to register for the challenge\n const [hasCreatedNewTeam, setHasCreatedNewTeam] = useState<boolean>(false)\n\n const membershipRequestFormRef = useRef<MembershipRequestFormHandle>(null)\n const createTeamRef = useRef<CreateChallengeTeamHandle>(null)\n\n const { data: userProfile, isLoading: isLoadingUserProfile } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n })\n\n // Retrieve the challenge associated with the projectId passed through props\n const { data: challenge, isLoading: isLoadingChallenge } =\n useGetEntityChallenge(projectId)\n\n const {\n mutateAsync: addTeamMember,\n isPending: addMemberToTeamIsPending,\n error: addUserToTeamError,\n } = useAddMemberToTeam()\n\n // Determine whether the given user belongs to any submission teams\n const { data: userSubmissionTeams, error: userSubmissionTeamError } =\n useGetUserSubmissionTeams(challenge?.id!, 1, 0, {\n enabled: Boolean(isAuthenticated && challenge),\n })\n\n const isMemberOfSubmissionTeam =\n userSubmissionTeams && userSubmissionTeams.results.length > 0\n\n const {\n data: selectedTeamMembershipStatus,\n isLoading: selectedTeamMembershipStatusIsLoading,\n error: selectedTeamMembershipStatusError,\n } = useGetMembershipStatus(selectedTeamId!, String(userProfile?.ownerId), {\n enabled: isAuthenticated && !!selectedTeamId && !!userProfile,\n })\n\n const addUserToTeam = useCallback(async () => {\n if (!selectedTeamId || !userProfile) return\n await addTeamMember({\n teamId: selectedTeamId,\n userId: userProfile.ownerId,\n })\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }, [addTeamMember, setStep, selectedTeamId, userProfile])\n\n const hide = useCallback(() => {\n setHasCreatedNewTeam(false)\n setSelectedTeamId(undefined)\n onClose()\n }, [onClose])\n\n const isLoading = isLoadingUserProfile || isLoadingChallenge\n\n const backButton = useMemo(() => {\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM:\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n // Cannot go back from these steps\n return <></>\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM:\n default:\n // All the other steps go back to team selection\n return (\n <Button\n variant={'outlined'}\n onClick={() => {\n setStep(ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM)\n setSelectedTeamId(undefined)\n }}\n >\n Back\n </Button>\n )\n }\n }, [step])\n\n const closeButton = useMemo(() => {\n return (\n <Button\n variant={'contained'}\n onClick={() => {\n onClose()\n }}\n >\n Close\n </Button>\n )\n }, [onClose])\n\n // Determine modal content based on step.id\n const { actions = <></>, content = <></> } = useMemo(() => {\n if (!isAuthenticated) {\n return {\n content: (\n <Alert severity={'error'}>\n <SignInPrompt />\n </Alert>\n ),\n }\n }\n\n if (isMemberOfSubmissionTeam) {\n return {\n content: (\n <Alert severity={'error'}>\n <Typography>\n You are already a member of a registered submission team for this\n Challenge.\n </Typography>\n </Alert>\n ),\n }\n }\n\n switch (step) {\n case ChallengeTeamWizardStep.SELECT_YOUR_CHALLENGE_TEAM: {\n let buttonText = 'Join Team'\n let disableJoiningSelectedTeam = false\n let buttonOnClickBehavior: () => void = noop\n let buttonTooltip = ''\n if (selectedTeamMembershipStatus?.hasOpenInvitation) {\n // The user has been invited to join the selected team\n buttonText = 'View Invitation to Join Team'\n buttonOnClickBehavior = () => {\n setStep(ChallengeTeamWizardStep.ACCEPT_INVITATION)\n }\n } else if (selectedTeamMembershipStatus?.hasOpenRequest) {\n // User already has an open request to join the selected team, disable button to avoid request spamming\n buttonText = 'Join Request Pending'\n disableJoiningSelectedTeam = true\n buttonTooltip =\n 'You have already submitted a request to join this team.'\n } else if (selectedTeamMembershipStatus?.membershipApprovalRequired) {\n // The user has to send a request to join the selected team\n buttonText = 'Request to Join Team'\n buttonOnClickBehavior = () => {\n setStep(ChallengeTeamWizardStep.JOIN_REQUEST_FORM)\n }\n } else if (selectedTeamMembershipStatus?.canJoin) {\n // The user can freely join the selected team\n buttonText = 'Join Team'\n buttonOnClickBehavior = () => {\n void addUserToTeam()\n }\n }\n return {\n content: challenge && !isMemberOfSubmissionTeam && (\n <SelectChallengeTeam\n challengeId={challenge.id}\n onCreateTeam={() =>\n setStep(ChallengeTeamWizardStep.CREATE_NEW_TEAM)\n }\n selectedTeamId={selectedTeamId}\n onSelectTeam={teamId => setSelectedTeamId(teamId)}\n />\n ),\n actions: (\n <>\n {backButton}\n <Tooltip title={buttonTooltip}>\n {/* Wrap button in span to show tooltip when button is disabled */}\n <span>\n <Button\n onClick={buttonOnClickBehavior}\n startIcon={\n addMemberToTeamIsPending ? <SynapseSpinner /> : undefined\n }\n disabled={\n !selectedTeamId ||\n selectedTeamMembershipStatusIsLoading ||\n addMemberToTeamIsPending ||\n disableJoiningSelectedTeam\n }\n variant={'contained'}\n >\n {buttonText}\n </Button>\n </span>\n </Tooltip>\n </>\n ),\n }\n }\n case ChallengeTeamWizardStep.ACCEPT_INVITATION:\n return {\n content: <OpenMembershipInvitation teamId={selectedTeamId!} />,\n actions: (\n <>\n {backButton}\n <AcceptMembershipInvitationButton\n teamId={selectedTeamId!}\n onSuccess={() => {\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }}\n />\n </>\n ),\n }\n case ChallengeTeamWizardStep.JOIN_REQUEST_FORM:\n return {\n content: (\n <MembershipRequestForm\n ref={membershipRequestFormRef}\n teamId={selectedTeamId!}\n onRequestSubmitted={() => {\n setStep(ChallengeTeamWizardStep.JOIN_REQUEST_SENT)\n }}\n />\n ),\n actions: (\n <>\n {backButton}\n <Button\n variant={'contained'}\n onClick={() => {\n membershipRequestFormRef?.current?.submit()\n }}\n >\n Send Request\n </Button>\n </>\n ),\n }\n\n case ChallengeTeamWizardStep.JOIN_REQUEST_SENT:\n return {\n content: (\n <Typography variant=\"body1\" sx={{ lineHeight: '20px' }}>\n Team Manager(s) have received your request. Check your Synapse\n email address for status of your request.\n </Typography>\n ),\n actions: (\n <>\n {backButton}\n {closeButton}\n </>\n ),\n }\n case ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL:\n return {\n content: (\n <RegistrationSuccessful\n createdNewTeam={hasCreatedNewTeam}\n teamId={selectedTeamId}\n />\n ),\n actions: (\n <>\n {backButton}\n {closeButton}\n </>\n ),\n }\n case ChallengeTeamWizardStep.CREATE_NEW_TEAM: {\n return {\n content: (\n <CreateChallengeTeam\n ref={createTeamRef}\n challengeId={challenge?.id!}\n onCanSubmitChange={canSubmit => setCanCreateNewTeam(canSubmit)}\n onFinished={teamId => {\n setHasCreatedNewTeam(true)\n setSelectedTeamId(teamId)\n setStep(ChallengeTeamWizardStep.REGISTRATION_SUCCESSFUL)\n }}\n />\n ),\n actions: (\n <>\n {backButton}\n <Button\n variant={'contained'}\n disabled={!canCreateNewTeam}\n onClick={() => {\n createTeamRef?.current?.submit()\n }}\n >\n Create Team\n </Button>\n </>\n ),\n }\n }\n }\n }, [\n isAuthenticated,\n isMemberOfSubmissionTeam,\n step,\n selectedTeamId,\n backButton,\n closeButton,\n hasCreatedNewTeam,\n selectedTeamMembershipStatus,\n challenge,\n addMemberToTeamIsPending,\n selectedTeamMembershipStatusIsLoading,\n addUserToTeam,\n canCreateNewTeam,\n ])\n\n const errorMessage =\n addUserToTeamError?.message ||\n selectedTeamMembershipStatusError?.message ||\n userSubmissionTeamError?.message\n\n return (\n <DialogBase\n onCancel={hide}\n open={isShowingModal}\n actions={actions}\n title={`Challenge Registration (Step 2 of 2): ${getStepDialogTitle(\n step,\n )}`}\n content={\n <SynapseErrorBoundary>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n }}\n >\n {isLoading ? (\n <SynapseSpinner size={40} />\n ) : (\n <>\n {content}\n {errorMessage && (\n <Alert severity={'error'}>{errorMessage}</Alert>\n )}\n </>\n )}\n </Box>\n </SynapseErrorBoundary>\n }\n />\n )\n}\n\nexport default ChallengeTeamWizard\n"],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ var { parse: g } = h, _ = 3, v = "Please limit the initial number of invited mem
|
|
|
26
26
|
inviteesParseResult: e,
|
|
27
27
|
parsedInvitees: e.data[0] || []
|
|
28
28
|
};
|
|
29
|
-
}, [T]), A = k.length > _, j = !!(x
|
|
29
|
+
}, [T]), A = k.length > _, j = !!(x?.name && x.name.length > 1 && !A);
|
|
30
30
|
r(() => {
|
|
31
31
|
y(j);
|
|
32
32
|
}, [j, y]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateChallengeTeam.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/CreateChallengeTeam.tsx"],"sourcesContent":["import {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react'\nimport { Alert, Box, Stack, Typography } from '@mui/material'\nimport TextField from '../TextField'\nimport { CreateTeamRequest, Team } from '@sage-bionetworks/synapse-types'\nimport useCreateAndRegisterChallengeTeam from './useCreateAndRegisterChallengeTeam'\nimport { isEmpty, noop } from 'lodash-es'\nimport papaparseLib from 'papaparse'\n// papaparse is CJS-only; pull named values from the default export.\nconst { parse } = papaparseLib\n\nexport type CreateChallengeTeamProps = {\n challengeId: string\n onCanSubmitChange?: (canSubmit: boolean) => void\n onFinished?: (teamId: string) => void\n}\n\nconst INVITEE_LIMIT = 3\nexport const TOO_MANY_INVITEES_ERROR =\n 'Please limit the initial number of invited members to three. You may add additional members after the team has been created.'\n\nexport type CreateChallengeTeamHandle = {\n // Allow the parent component to trigger a submit of the form, so this may be embedded in an arbitrary modal.\n submit: () => void\n}\n\nexport const CreateChallengeTeam = forwardRef(function CreateChallengeTeam(\n props: CreateChallengeTeamProps,\n ref: ForwardedRef<CreateChallengeTeamHandle>,\n) {\n const { challengeId, onCanSubmitChange = noop, onFinished = noop } = props\n const [team, setTeam] = useState<CreateTeamRequest>({\n name: '',\n description: '',\n })\n const [invitationMessage, setInvitationMessage] = useState('')\n const [rawInvitees, setRawInvitees] = useState('')\n\n const handleTeamUpdate = (update: Partial<Team>) => {\n const updatedTeam: CreateTeamRequest = { ...team, ...update }\n setTeam(updatedTeam)\n }\n\n const { inviteesParseResult, parsedInvitees } = useMemo(() => {\n const inviteesParseResult = parse<string[]>(rawInvitees, {\n delimiter: ',',\n transform(value) {\n return value.trim()\n },\n })\n const parsedInvitees: string[] = inviteesParseResult.data[0] || []\n\n return { inviteesParseResult, parsedInvitees }\n }, [rawInvitees])\n\n const numberOfInvitees = parsedInvitees.length\n const tooManyInvitees = numberOfInvitees > INVITEE_LIMIT\n\n const formDataIsValid = Boolean(\n team
|
|
1
|
+
{"version":3,"file":"CreateChallengeTeam.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/CreateChallengeTeam.tsx"],"sourcesContent":["import {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react'\nimport { Alert, Box, Stack, Typography } from '@mui/material'\nimport TextField from '../TextField'\nimport { CreateTeamRequest, Team } from '@sage-bionetworks/synapse-types'\nimport useCreateAndRegisterChallengeTeam from './useCreateAndRegisterChallengeTeam'\nimport { isEmpty, noop } from 'lodash-es'\nimport papaparseLib from 'papaparse'\n// papaparse is CJS-only; pull named values from the default export.\nconst { parse } = papaparseLib\n\nexport type CreateChallengeTeamProps = {\n challengeId: string\n onCanSubmitChange?: (canSubmit: boolean) => void\n onFinished?: (teamId: string) => void\n}\n\nconst INVITEE_LIMIT = 3\nexport const TOO_MANY_INVITEES_ERROR =\n 'Please limit the initial number of invited members to three. You may add additional members after the team has been created.'\n\nexport type CreateChallengeTeamHandle = {\n // Allow the parent component to trigger a submit of the form, so this may be embedded in an arbitrary modal.\n submit: () => void\n}\n\nexport const CreateChallengeTeam = forwardRef(function CreateChallengeTeam(\n props: CreateChallengeTeamProps,\n ref: ForwardedRef<CreateChallengeTeamHandle>,\n) {\n const { challengeId, onCanSubmitChange = noop, onFinished = noop } = props\n const [team, setTeam] = useState<CreateTeamRequest>({\n name: '',\n description: '',\n })\n const [invitationMessage, setInvitationMessage] = useState('')\n const [rawInvitees, setRawInvitees] = useState('')\n\n const handleTeamUpdate = (update: Partial<Team>) => {\n const updatedTeam: CreateTeamRequest = { ...team, ...update }\n setTeam(updatedTeam)\n }\n\n const { inviteesParseResult, parsedInvitees } = useMemo(() => {\n const inviteesParseResult = parse<string[]>(rawInvitees, {\n delimiter: ',',\n transform(value) {\n return value.trim()\n },\n })\n const parsedInvitees: string[] = inviteesParseResult.data[0] || []\n\n return { inviteesParseResult, parsedInvitees }\n }, [rawInvitees])\n\n const numberOfInvitees = parsedInvitees.length\n const tooManyInvitees = numberOfInvitees > INVITEE_LIMIT\n\n const formDataIsValid = Boolean(\n team?.name && team.name.length > 1 && !tooManyInvitees,\n )\n\n useEffect(() => {\n onCanSubmitChange(formDataIsValid)\n }, [formDataIsValid, onCanSubmitChange])\n\n const {\n createAndRegisterTeam,\n isPending: mutationIsPending,\n errors,\n } = useCreateAndRegisterChallengeTeam()\n\n useImperativeHandle(ref, () => {\n return {\n submit() {\n if (!formDataIsValid) {\n console.warn(\n 'Attempted to submit when form data was not valid. Nothing will happen.',\n )\n return\n }\n createAndRegisterTeam(\n team,\n challengeId,\n parsedInvitees,\n invitationMessage,\n )\n .then(([newTeam]) => {\n onFinished(newTeam.id)\n })\n .catch(() => {\n // The hook will return errors, so no need to handle them here\n })\n },\n }\n }, [\n formDataIsValid,\n parsedInvitees,\n createAndRegisterTeam,\n team,\n challengeId,\n invitationMessage,\n onFinished,\n ])\n\n return (\n <Stack gap={2}>\n <Typography variant=\"body1\" sx={{ lineHeight: '20px' }}>\n Create a new team for this Challenge!\n </Typography>\n <TextField\n id=\"name\"\n label=\"Team Name\"\n value={team.name}\n fullWidth\n autoFocus\n required\n onChange={event => handleTeamUpdate({ name: event.target.value })}\n disabled={mutationIsPending}\n />\n <Box\n sx={{\n display: 'flex',\n }}\n >\n <TextField\n id=\"description\"\n label={\n <Box\n sx={{\n display: 'flex',\n gap: 2,\n }}\n >\n <Box>Team Description</Box>\n </Box>\n }\n value={team.description}\n fullWidth\n multiline\n rows={4}\n onChange={event =>\n handleTeamUpdate({ description: event.target.value })\n }\n disabled={mutationIsPending}\n />\n </Box>\n <Box\n sx={{\n display: 'flex',\n }}\n >\n <TextField\n id=\"message\"\n label={\n <Box\n sx={{\n display: 'flex',\n gap: 2,\n }}\n >\n <Box>Recruitment Message</Box>\n </Box>\n }\n value={invitationMessage}\n fullWidth\n multiline\n rows={4}\n onChange={event => setInvitationMessage(event.target.value)}\n disabled={mutationIsPending}\n />\n </Box>\n <TextField\n id=\"invitees\"\n label=\"Emails of Additional Members to Invite (max 3)\"\n placeholder=\"Enter emails separated by comma\"\n value={rawInvitees}\n fullWidth\n onChange={event => setRawInvitees(event.target.value)}\n disabled={mutationIsPending}\n />\n {(tooManyInvitees || !isEmpty(inviteesParseResult.errors) || errors) && (\n <Alert severity=\"error\">\n {tooManyInvitees && (\n <Typography variant={'body1'}>{TOO_MANY_INVITEES_ERROR}</Typography>\n )}\n {inviteesParseResult.errors.map((error, index) => (\n <Typography key={index} variant={'body1'}>\n {error.message}\n </Typography>\n ))}\n {errors &&\n errors.map(error => (\n <Typography key={error.reason} variant={'body1'}>\n {error.reason}\n </Typography>\n ))}\n </Alert>\n )}\n </Stack>\n )\n})\n"],"mappings":"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"}
|
|
@@ -42,8 +42,8 @@ function g(g) {
|
|
|
42
42
|
}), { mutateAsync: B, error: V } = t({ onSuccess: (e) => {
|
|
43
43
|
Se(e.id);
|
|
44
44
|
} }), { mutate: H, data: U, error: W } = ne({ onSuccess: (e) => {
|
|
45
|
-
e
|
|
46
|
-
} }), G = o(() => W ? W.reason : U
|
|
45
|
+
e?.isValid && b("TABLE_NAME");
|
|
46
|
+
} }), G = o(() => W ? W.reason : U?.invalidReason ? U.invalidReason : null, [W, U]), { mutateAsync: K, error: q } = ee(), J = a((e, t) => {
|
|
47
47
|
we(e), t != null && A(t), b(le(e));
|
|
48
48
|
}, []), Y = a(() => {
|
|
49
49
|
b("CHOOSE_VIEW_TYPE");
|