synapse-react-client 4.0.46 → 4.0.48
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/useSubmitAridhiaDar.js +2 -2
- package/dist/aridhia-queries/useSubmitAridhiaDar.js.map +1 -1
- package/dist/components/AccessTokenPage/CreateAccessTokenModal.js +1 -1
- package/dist/components/AccessTokenPage/CreateAccessTokenModal.js.map +1 -1
- package/dist/components/AccountLevelBadges/AccountLevelBadges.js +1 -1
- package/dist/components/AccountLevelBadges/AccountLevelBadges.js.map +1 -1
- package/dist/components/AclEditor/AclEditor.test-utils.js +3 -5
- package/dist/components/AclEditor/AclEditor.test-utils.js.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.d.ts.map +1 -1
- package/dist/components/Aridhia/AridhiaAccessStatus.js +43 -30
- package/dist/components/Aridhia/AridhiaAccessStatus.js.map +1 -1
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts +6 -2
- package/dist/components/Aridhia/AridhiaDarStatusPopover.d.ts.map +1 -1
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js +101 -31
- package/dist/components/Aridhia/AridhiaDarStatusPopover.js.map +1 -1
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.d.ts +11 -9
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.d.ts.map +1 -1
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js +24 -13
- package/dist/components/Aridhia/aridhiaAccessStatusUtils.js.map +1 -1
- package/dist/components/Authentication/LastLoginInfo.js +2 -2
- package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
- package/dist/components/Authentication/RecoveryCodeForm.js +1 -1
- package/dist/components/Authentication/RecoveryCodeForm.js.map +1 -1
- package/dist/components/Authentication/RecoveryCodeGrid.js.map +1 -1
- package/dist/components/Authentication/TOTPForm.d.ts.map +1 -1
- package/dist/components/Authentication/TOTPForm.js +3 -3
- package/dist/components/Authentication/TOTPForm.js.map +1 -1
- package/dist/components/Authentication/index.d.ts +6 -6
- package/dist/components/Authentication/index.d.ts.map +1 -1
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js +1 -1
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js.map +1 -1
- package/dist/components/CardContainer/CardContainer.js +7 -7
- package/dist/components/CardContainer/CardContainer.js.map +1 -1
- package/dist/components/ChallengeRequirementsModal/ChallengeRequirementsModal.js +1 -1
- package/dist/components/ChallengeRequirementsModal/ChallengeRequirementsModal.js.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmission.d.ts.map +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmission.js +1 -1
- package/dist/components/ChallengeSubmission/ChallengeSubmission.js.map +1 -1
- package/dist/components/ChallengeTeamWizard/SelectChallengeTeam.js +1 -1
- package/dist/components/ChallengeTeamWizard/SelectChallengeTeam.js.map +1 -1
- package/dist/components/CitationPopover/CitationPopoverUtils.js +2 -2
- package/dist/components/CitationPopover/CitationPopoverUtils.js.map +1 -1
- package/dist/components/CohortBuilder/CohortBuilder.css +1 -0
- package/dist/components/CohortBuilder/CohortBuilder.d.ts +35 -0
- package/dist/components/CohortBuilder/CohortBuilder.d.ts.map +1 -0
- package/dist/components/CohortBuilder/CohortBuilder.js +108 -0
- package/dist/components/CohortBuilder/CohortBuilder.js.map +1 -0
- package/dist/components/CohortBuilder/CohortBuilder.module.js +10 -0
- package/dist/components/CohortBuilder/CohortBuilder.module.js.map +1 -0
- package/dist/components/CohortBuilder/CohortBuilder.module.scss +20 -0
- package/dist/components/CohortBuilder/CohortFilesPanel.d.ts +16 -0
- package/dist/components/CohortBuilder/CohortFilesPanel.d.ts.map +1 -0
- package/dist/components/CohortBuilder/CohortFilesPanel.js +124 -0
- package/dist/components/CohortBuilder/CohortFilesPanel.js.map +1 -0
- package/dist/components/CohortBuilder/cohortHandOff.d.ts +25 -0
- package/dist/components/CohortBuilder/cohortHandOff.d.ts.map +1 -0
- package/dist/components/CohortBuilder/cohortHandOff.js +26 -0
- package/dist/components/CohortBuilder/cohortHandOff.js.map +1 -0
- package/dist/components/ColumnFilter/ColumnFilter.d.ts.map +1 -1
- package/dist/components/ColumnFilter/ColumnFilter.js +14 -13
- package/dist/components/ColumnFilter/ColumnFilter.js.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.d.ts.map +1 -1
- package/dist/components/DataExplorer/DataExplorer.js.map +1 -1
- package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts +11 -2
- package/dist/components/DataGrid/columns/AutocompleteColumn.d.ts.map +1 -1
- package/dist/components/DataGrid/columns/AutocompleteColumn.js +115 -109
- package/dist/components/DataGrid/columns/AutocompleteColumn.js.map +1 -1
- package/dist/components/DataGrid/columns/NumberColumn.js +1 -1
- package/dist/components/DataGrid/columns/NumberColumn.js.map +1 -1
- package/dist/components/DataGrid/columns/NumberOrEnumColumn.d.ts +20 -0
- package/dist/components/DataGrid/columns/NumberOrEnumColumn.d.ts.map +1 -0
- package/dist/components/DataGrid/columns/NumberOrEnumColumn.js +18 -0
- package/dist/components/DataGrid/columns/NumberOrEnumColumn.js.map +1 -0
- package/dist/components/DataGrid/components/contextMenu.js +3 -3
- package/dist/components/DataGrid/components/contextMenu.js.map +1 -1
- package/dist/components/DataGrid/hooks/useGridUndoRedo.d.ts.map +1 -1
- package/dist/components/DataGrid/hooks/useGridUndoRedo.js +9 -7
- package/dist/components/DataGrid/hooks/useGridUndoRedo.js.map +1 -1
- package/dist/components/DataGrid/hooks/useStack.d.ts +1 -1
- package/dist/components/DataGrid/hooks/useStack.js +2 -2
- package/dist/components/DataGrid/hooks/useStack.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +47 -42
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DataGrid/utils/extractColumnValidationMessages.js +7 -7
- package/dist/components/DataGrid/utils/extractColumnValidationMessages.js.map +1 -1
- package/dist/components/DataGrid/utils/json-rx/JsonRx.js +2 -2
- package/dist/components/DataGrid/utils/json-rx/JsonRx.js.map +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
- package/dist/components/DownloadCart/MeetAccessRequirementCard.js +1 -1
- package/dist/components/DownloadCart/MeetAccessRequirementCard.js.map +1 -1
- package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js +5 -5
- package/dist/components/EntityDownloadConfirmation/EntityDownloadConfirmation.js.map +1 -1
- package/dist/components/EntityFinder/details/view/DetailsView.d.ts.map +1 -1
- package/dist/components/EntityFinder/details/view/DetailsView.js +4 -4
- package/dist/components/EntityFinder/details/view/DetailsView.js.map +1 -1
- package/dist/components/EntityHeaderTable/EntityHeaderTable.js +4 -4
- package/dist/components/EntityHeaderTable/Filter.d.ts.map +1 -1
- package/dist/components/EntityHeaderTable/Filter.js +1 -1
- package/dist/components/EntityHeaderTable/Filter.js.map +1 -1
- package/dist/components/Evaluation/EvaluationRoundEditor.js.map +1 -1
- package/dist/components/FeaturedDataTabs/FacetPlotsCard.d.ts.map +1 -1
- package/dist/components/FeaturedDataTabs/FacetPlotsCard.js +80 -84
- package/dist/components/FeaturedDataTabs/FacetPlotsCard.js.map +1 -1
- package/dist/components/FormTemplateEditor/FormStructurePanel.js +7 -7
- package/dist/components/FormTemplateEditor/StepCard.js +9 -9
- package/dist/components/FormTemplateEditor/schemaFieldUtils.js +2 -2
- package/dist/components/FormTemplateEditor/schemaFieldUtils.js.map +1 -1
- package/dist/components/FullTextSearch/FullTextSearch.js +8 -8
- package/dist/components/GenericCard/CardUtils.js.map +1 -1
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js +1 -1
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js.map +1 -1
- package/dist/components/GenericCard/DuoTermTags/duoTerms.js +1 -1
- package/dist/components/GenericCard/DuoTermTags/duoTerms.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +37 -37
- package/dist/components/GoalsV3/GoalsV3.js +1 -1
- package/dist/components/GoalsV3/GoalsV3.js.map +1 -1
- package/dist/components/HexGrid/HexGrid.d.ts +3 -1
- package/dist/components/HexGrid/HexGrid.d.ts.map +1 -1
- package/dist/components/HexGrid/HexGrid.js +14 -13
- package/dist/components/HexGrid/HexGrid.js.map +1 -1
- package/dist/components/IconSvg/index.d.ts +1 -1
- package/dist/components/IconSvg/index.d.ts.map +1 -1
- package/dist/components/IconSvg/index.js.map +1 -1
- package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.js +3 -3
- package/dist/components/JsonSchemaForm/templates/BaseInputTemplate.js.map +1 -1
- package/dist/components/Markdown/MarkdownEditor.js +1 -1
- package/dist/components/Markdown/MarkdownEditor.js.map +1 -1
- package/dist/components/Markdown/widget/index.d.ts +1 -1
- package/dist/components/Markdown/widget/index.d.ts.map +1 -1
- package/dist/components/ModalDownload/ModalDownload.d.ts.map +1 -1
- package/dist/components/ModalDownload/ModalDownload.js +2 -1
- package/dist/components/ModalDownload/ModalDownload.js.map +1 -1
- package/dist/components/Plot/BarPlot.js +1 -1
- package/dist/components/Plot/BarPlot.js.map +1 -1
- package/dist/components/Plot/PlotPanelHeader.d.ts +3 -2
- package/dist/components/Plot/PlotPanelHeader.d.ts.map +1 -1
- package/dist/components/Plot/PlotPanelHeader.js.map +1 -1
- package/dist/components/ProgrammaticTableDownload/ProgrammaticTableDownload.js +1 -1
- package/dist/components/ProgrammaticTableDownload/ProgrammaticTableDownload.js.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceExternalIcon.js +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceExternalIcon.js.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.d.ts.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js +3 -3
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
- package/dist/components/QueryBuilder/FilterConditionRow.d.ts.map +1 -1
- package/dist/components/QueryBuilder/FilterConditionRow.js +28 -27
- package/dist/components/QueryBuilder/FilterConditionRow.js.map +1 -1
- package/dist/components/QueryBuilder/FilterGroupNode.d.ts.map +1 -1
- package/dist/components/QueryBuilder/FilterGroupNode.js +91 -75
- package/dist/components/QueryBuilder/FilterGroupNode.js.map +1 -1
- package/dist/components/QueryBuilder/QueryBuilderControls.css +1 -1
- package/dist/components/QueryBuilder/QueryBuilderControls.d.ts.map +1 -1
- package/dist/components/QueryBuilder/QueryBuilderControls.js +91 -79
- package/dist/components/QueryBuilder/QueryBuilderControls.js.map +1 -1
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js +11 -11
- package/dist/components/QueryBuilder/QueryBuilderControls.module.js.map +1 -1
- package/dist/components/QueryBuilder/QueryBuilderControls.module.scss +2 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts +2 -0
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.d.ts.map +1 -1
- package/dist/components/QueryBuilder/QueryBuilderInternalContext.js.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderLimits.d.ts +18 -0
- package/dist/components/QueryBuilder/queryBuilderLimits.d.ts.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderLimits.js +38 -0
- package/dist/components/QueryBuilder/queryBuilderLimits.js.map +1 -0
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts +0 -8
- package/dist/components/QueryBuilder/queryBuilderMetadata.d.ts.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderMetadata.js +6 -9
- package/dist/components/QueryBuilder/queryBuilderMetadata.js.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts +5 -4
- package/dist/components/QueryBuilder/queryBuilderTranslation.d.ts.map +1 -1
- package/dist/components/QueryBuilder/queryBuilderTranslation.js +58 -33
- package/dist/components/QueryBuilder/queryBuilderTranslation.js.map +1 -1
- package/dist/components/QueryBuilder/useQBCombinedSql.d.ts.map +1 -1
- package/dist/components/QueryBuilder/useQBCombinedSql.js +4 -4
- package/dist/components/QueryBuilder/useQBCombinedSql.js.map +1 -1
- package/dist/components/QueryBuilder/useQBValueDisplayName.d.ts.map +1 -1
- package/dist/components/QueryBuilder/useQBValueDisplayName.js +5 -5
- package/dist/components/QueryBuilder/useQBValueDisplayName.js.map +1 -1
- package/dist/components/QuerySortSelector.js +5 -5
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +21 -21
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js.map +1 -1
- package/dist/components/QueryWrapper/AggregateQueryErrorNotice.d.ts +20 -0
- package/dist/components/QueryWrapper/AggregateQueryErrorNotice.d.ts.map +1 -0
- package/dist/components/QueryWrapper/AggregateQueryErrorNotice.js +50 -0
- package/dist/components/QueryWrapper/AggregateQueryErrorNotice.js.map +1 -0
- package/dist/components/QueryWrapper/TableQueryUseQueryOptions.d.ts +5 -3
- package/dist/components/QueryWrapper/TableQueryUseQueryOptions.d.ts.map +1 -1
- package/dist/components/QueryWrapper/TableQueryUseQueryOptions.js +7 -3
- package/dist/components/QueryWrapper/TableQueryUseQueryOptions.js.map +1 -1
- package/dist/components/QueryWrapper/downloadListFiles.d.ts +25 -0
- package/dist/components/QueryWrapper/downloadListFiles.d.ts.map +1 -0
- package/dist/components/QueryWrapper/downloadListFiles.js +39 -0
- package/dist/components/QueryWrapper/downloadListFiles.js.map +1 -0
- package/dist/components/QueryWrapper/useAddSelectedRowsToDownloadList.d.ts +16 -0
- package/dist/components/QueryWrapper/useAddSelectedRowsToDownloadList.d.ts.map +1 -0
- package/dist/components/QueryWrapper/useAddSelectedRowsToDownloadList.js +50 -0
- package/dist/components/QueryWrapper/useAddSelectedRowsToDownloadList.js.map +1 -0
- package/dist/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery.d.ts +4 -1
- package/dist/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery.d.ts.map +1 -1
- package/dist/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery.js +15 -28
- package/dist/components/QueryWrapper/useGetAddToDownloadListRequestForCurrentQuery.js.map +1 -1
- package/dist/components/QueryWrapper/useOnQueryDataChange.d.ts.map +1 -1
- package/dist/components/QueryWrapper/useOnQueryDataChange.js +7 -6
- package/dist/components/QueryWrapper/useOnQueryDataChange.js.map +1 -1
- package/dist/components/QueryWrapperErrorBoundary.d.ts +3 -1
- package/dist/components/QueryWrapperErrorBoundary.d.ts.map +1 -1
- package/dist/components/QueryWrapperErrorBoundary.js +26 -21
- package/dist/components/QueryWrapperErrorBoundary.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/LastUpdatedOn.js +7 -7
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts +2 -2
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +34 -32
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.js +7 -7
- package/dist/components/QueryWrapperPlotNav/UseRowSet.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/UseRowSet.js +12 -12
- package/dist/components/QueryWrapperPlotNav/UseRowSet.js.map +1 -1
- package/dist/components/RowDataTable/CategorizedRowDataTable.css +1 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.d.ts +33 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.d.ts.map +1 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.js +64 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.js.map +1 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.module.js +8 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.module.js.map +1 -0
- package/dist/components/RowDataTable/CategorizedRowDataTable.module.scss +18 -0
- package/dist/components/RowDataTable/RowDataTable.d.ts +13 -0
- package/dist/components/RowDataTable/RowDataTable.d.ts.map +1 -1
- package/dist/components/RowDataTable/RowDataTable.js +25 -8
- package/dist/components/RowDataTable/RowDataTable.js.map +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js +1 -1
- package/dist/components/RssFeedCards/RssFeedCards.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/field/AdditionalPropertiesSchemaField.d.ts.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/field/AdditionalPropertiesSchemaField.js +2 -2
- package/dist/components/SchemaDrivenAnnotationEditor/field/AdditionalPropertiesSchemaField.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/template/ObjectFieldTemplate.js +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/template/ObjectFieldTemplate.js.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts +17 -9
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js +39 -30
- package/dist/components/SearchQueryWrapper/SearchQueryUseQueryOptions.js.map +1 -1
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js +24 -24
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
- package/dist/components/StandaloneQueryWrapper/StandaloneQueryWrapper.js +8 -8
- package/dist/components/SynapseChat/SynapseChatMessage.js +1 -1
- package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
- package/dist/components/SynapseForm/NavButtons.js.map +1 -1
- package/dist/components/SynapseForm/StepsSideNav.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/HighlightedTypography.js +1 -1
- package/dist/components/SynapseSearchPageResults/HighlightedTypography.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.d.ts.map +1 -1
- package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.js +3 -3
- package/dist/components/SynapseSearchPageResults/SearchFacetPanel/SearchFacetPanelUtils.js.map +1 -1
- package/dist/components/SynapseTable/RowSelection/RowSelectionControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js +38 -44
- package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
- package/dist/components/SynapseTable/RowSelection/RowSelectionUI.js +4 -4
- package/dist/components/SynapseTable/SqlEditor.js +7 -7
- package/dist/components/SynapseTable/SynapseTable.js +8 -8
- package/dist/components/SynapseTable/SynapseTable.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTableRenderers.d.ts.map +1 -1
- package/dist/components/SynapseTable/SynapseTableRenderers.js +73 -72
- package/dist/components/SynapseTable/SynapseTableRenderers.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTableUtils.js +1 -1
- package/dist/components/SynapseTable/SynapseTableUtils.js.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.d.ts.map +1 -1
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js +44 -45
- package/dist/components/SynapseTable/TopLevelControls/TopLevelControls.js.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetEditorVersionCell.js +1 -1
- package/dist/components/SynapseTable/datasets/DatasetEditorVersionCell.js.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.d.ts.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +142 -142
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
- package/dist/components/SynapseTable/export/ExportToAnalysisPlatformDialog.js +4 -4
- package/dist/components/SynapseTable/export/ExternalPlatformActionsRequiredPrecheck.js +12 -12
- package/dist/components/SynapseTable/export/ExternalPlatformActionsRequiredPrecheck.js.map +1 -1
- package/dist/components/SynapseTable/table-top/ColumnSelection.js +6 -6
- package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts +0 -1
- package/dist/components/SynapseTable/table-top/DownloadOptions.d.ts.map +1 -1
- package/dist/components/SynapseTable/table-top/DownloadOptions.js +64 -57
- package/dist/components/SynapseTable/table-top/DownloadOptions.js.map +1 -1
- package/dist/components/SynapseTable/usePrefetchTableData.d.ts.map +1 -1
- package/dist/components/SynapseTable/usePrefetchTableData.js +3 -3
- package/dist/components/SynapseTable/usePrefetchTableData.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js +1 -1
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorTestUtils.js +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorTestUtils.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js +2 -2
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js +60 -60
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.js +1 -1
- package/dist/components/TableColumnSchemaEditor/Validators/DatetimeSchema.js.map +1 -1
- package/dist/components/TanStackTable/ColumnHeaderEnumFilter.js +1 -1
- package/dist/components/TanStackTable/ColumnHeaderEnumFilter.js.map +1 -1
- package/dist/components/TanStackTable/StyledTanStackTable.d.ts.map +1 -1
- package/dist/components/TanStackTable/StyledTanStackTable.js +1 -4
- package/dist/components/TanStackTable/StyledTanStackTable.js.map +1 -1
- package/dist/components/TermsAndConditions/TermsAndConditions.js.map +1 -1
- package/dist/components/TotalQueryResults.js +14 -14
- package/dist/components/Webhook/WebhookDashboard.d.ts.map +1 -1
- package/dist/components/Webhook/WebhookDashboard.js +2 -2
- package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
- package/dist/components/download_list/DownloadConfirmationUtils.d.ts +5 -1
- package/dist/components/download_list/DownloadConfirmationUtils.d.ts.map +1 -1
- package/dist/components/download_list/DownloadConfirmationUtils.js +2 -2
- package/dist/components/download_list/DownloadConfirmationUtils.js.map +1 -1
- package/dist/components/error/ErrorBanner.d.ts.map +1 -1
- package/dist/components/error/ErrorBanner.js +49 -46
- package/dist/components/error/ErrorBanner.js.map +1 -1
- package/dist/components/file/upload/MultiFileUploadProgress.js +5 -5
- package/dist/components/row_renderers/Dataset.d.ts.map +1 -1
- package/dist/components/row_renderers/Dataset.js +6 -6
- package/dist/components/row_renderers/Dataset.js.map +1 -1
- package/dist/components/row_renderers/Funder.js +1 -1
- package/dist/components/row_renderers/Funder.js.map +1 -1
- package/dist/components/widgets/ElementWithTooltip.d.ts +6 -1
- package/dist/components/widgets/ElementWithTooltip.d.ts.map +1 -1
- package/dist/components/widgets/ElementWithTooltip.js +22 -14
- package/dist/components/widgets/ElementWithTooltip.js.map +1 -1
- package/dist/components/widgets/RangeSlider/RangeSlider.d.ts.map +1 -1
- package/dist/components/widgets/RangeSlider/RangeSlider.js +1 -1
- package/dist/components/widgets/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/widgets/SynapseImage.js +1 -1
- package/dist/components/widgets/SynapseImage.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.d.ts +16 -5
- package/dist/components/widgets/facet-nav/FacetNavPanel.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js +115 -102
- package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendList.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendList.js +4 -2
- package/dist/components/widgets/facet-nav/FacetPlotLegendList.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendTable.js +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendTable.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendUtils.d.ts +2 -0
- package/dist/components/widgets/facet-nav/FacetPlotLegendUtils.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/FacetPlotLegendUtils.js.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.d.ts +7 -0
- package/dist/components/widgets/facet-nav/PlotsContainer.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.js +47 -45
- package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
- package/dist/components/widgets/facet-nav/SelectionCriteriaPills.js +4 -4
- package/dist/components/widgets/facet-nav/useFacetPlots.d.ts +3 -2
- package/dist/components/widgets/facet-nav/useFacetPlots.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/useFacetPlots.js +16 -15
- package/dist/components/widgets/facet-nav/useFacetPlots.js.map +1 -1
- package/dist/components/widgets/query-filter/CombinedRangeFacetFilter.js +4 -4
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.d.ts +2 -2
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js +62 -60
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilter.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.d.ts +2 -0
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.js +10 -10
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterOption.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.d.ts +1 -0
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.js +2 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUI.js.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUtils.d.ts +3 -2
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUtils.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/EnumFacetFilter/EnumFacetFilterUtils.js.map +1 -1
- package/dist/components/widgets/query-filter/FacetFilterControls.d.ts +3 -2
- package/dist/components/widgets/query-filter/FacetFilterControls.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/FacetFilterControls.js +63 -62
- package/dist/components/widgets/query-filter/FacetFilterControls.js.map +1 -1
- package/dist/components/widgets/query-filter/JsonColumnFacetFilters.d.ts.map +1 -1
- package/dist/components/widgets/query-filter/JsonColumnFacetFilters.js +30 -29
- package/dist/components/widgets/query-filter/JsonColumnFacetFilters.js.map +1 -1
- package/dist/components/widgets/query-filter/RangeFacetFilter.js +5 -5
- package/dist/mocks/cohortBuilder/cohortBuilderMockProfiles.d.ts +53 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockProfiles.d.ts.map +1 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockProfiles.js +391 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockProfiles.js.map +1 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockQueryEngine.d.ts +41 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockQueryEngine.d.ts.map +1 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockQueryEngine.js +379 -0
- package/dist/mocks/cohortBuilder/cohortBuilderMockQueryEngine.js.map +1 -0
- package/dist/mocks/cohortBuilder/cohortBuilderSyntheticData.d.ts +26 -0
- package/dist/mocks/cohortBuilder/cohortBuilderSyntheticData.d.ts.map +1 -0
- package/dist/mocks/cohortBuilder/cohortBuilderSyntheticData.js +112 -0
- package/dist/mocks/cohortBuilder/cohortBuilderSyntheticData.js.map +1 -0
- package/dist/mocks/mockAnnotationColumns.d.ts.map +1 -1
- package/dist/mocks/mockAnnotationColumns.js +1 -1
- package/dist/mocks/mockAnnotationColumns.js.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +9 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.js +24 -15
- package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/asyncJobHandlers.d.ts +21 -2
- package/dist/mocks/msw/handlers/asyncJobHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/asyncJobHandlers.js +30 -22
- package/dist/mocks/msw/handlers/asyncJobHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/cohortBuilderHandlers.d.ts +27 -0
- package/dist/mocks/msw/handlers/cohortBuilderHandlers.d.ts.map +1 -0
- package/dist/mocks/msw/handlers/cohortBuilderHandlers.js +158 -0
- package/dist/mocks/msw/handlers/cohortBuilderHandlers.js.map +1 -0
- package/dist/mocks/msw/handlers/subscriptionHandlers.js +1 -1
- package/dist/mocks/msw/handlers/subscriptionHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/userProfileHandlers.d.ts.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/query/mockColumnCategoryTable.d.ts +19 -0
- package/dist/mocks/query/mockColumnCategoryTable.d.ts.map +1 -0
- package/dist/mocks/query/mockColumnCategoryTable.js +188 -0
- package/dist/mocks/query/mockColumnCategoryTable.js.map +1 -0
- package/dist/stories/ColorPaletteInspector.d.ts.map +1 -1
- package/dist/stories/ColorPaletteInspector.js +2 -2
- package/dist/stories/ColorPaletteInspector.js.map +1 -1
- package/dist/style/components/facet_nav/_facet-nav-panel.scss +8 -0
- package/dist/style/main.css +1 -1
- package/dist/synapse-queries/auth/useOIDC.js +2 -2
- package/dist/synapse-queries/auth/useOIDC.js.map +1 -1
- package/dist/synapse-queries/auth/useUnbindOAuthProviderIdentity.js +2 -2
- package/dist/synapse-queries/auth/useUnbindOAuthProviderIdentity.js.map +1 -1
- package/dist/synapse-queries/challenge/useChallenge.js +2 -2
- package/dist/synapse-queries/challenge/useChallenge.js.map +1 -1
- package/dist/synapse-queries/chat/useChat.js +8 -8
- package/dist/synapse-queries/chat/useChat.js.map +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.js +10 -10
- package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useAccessRequirements.js +24 -24
- package/dist/synapse-queries/dataaccess/useAccessRequirements.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useDataAccessSubmission.js +4 -4
- package/dist/synapse-queries/dataaccess/useDataAccessSubmission.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useEDuc.js +6 -6
- package/dist/synapse-queries/dataaccess/useEDuc.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useFormTemplate.js +4 -4
- package/dist/synapse-queries/dataaccess/useFormTemplate.js.map +1 -1
- package/dist/synapse-queries/download/index.js +2 -2
- package/dist/synapse-queries/download/useDownloadList.d.ts +5 -0
- package/dist/synapse-queries/download/useDownloadList.d.ts.map +1 -1
- package/dist/synapse-queries/download/useDownloadList.js +14 -13
- package/dist/synapse-queries/download/useDownloadList.js.map +1 -1
- package/dist/synapse-queries/entity/useEntity.d.ts.map +1 -1
- package/dist/synapse-queries/entity/useEntity.js +20 -20
- package/dist/synapse-queries/entity/useEntity.js.map +1 -1
- package/dist/synapse-queries/entity/useExportToADWorkbench.d.ts.map +1 -1
- package/dist/synapse-queries/entity/useExportToADWorkbench.js +2 -1
- package/dist/synapse-queries/entity/useExportToADWorkbench.js.map +1 -1
- package/dist/synapse-queries/entity/useExportToCavatica.d.ts.map +1 -1
- package/dist/synapse-queries/entity/useExportToCavatica.js +3 -2
- package/dist/synapse-queries/entity/useExportToCavatica.js.map +1 -1
- package/dist/synapse-queries/entity/useExportToPluto.d.ts.map +1 -1
- package/dist/synapse-queries/entity/useExportToPluto.js +2 -1
- package/dist/synapse-queries/entity/useExportToPluto.js.map +1 -1
- package/dist/synapse-queries/entity/useGetQueryResultBundle.d.ts.map +1 -1
- package/dist/synapse-queries/entity/useGetQueryResultBundle.js +4 -7
- package/dist/synapse-queries/entity/useGetQueryResultBundle.js.map +1 -1
- package/dist/synapse-queries/forum/useReply.js +6 -6
- package/dist/synapse-queries/forum/useReply.js.map +1 -1
- package/dist/synapse-queries/forum/useThread.js +14 -14
- package/dist/synapse-queries/forum/useThread.js.map +1 -1
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js +1 -1
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
- package/dist/synapse-queries/grid/useGridSession.js +4 -4
- package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
- package/dist/synapse-queries/index.js +177 -176
- package/dist/synapse-queries/oauth/useOAuthClient.js +9 -9
- package/dist/synapse-queries/oauth/useOAuthClient.js.map +1 -1
- package/dist/synapse-queries/portal/usePortal.js +7 -7
- package/dist/synapse-queries/portal/usePortal.js.map +1 -1
- package/dist/synapse-queries/subscription/useSubscription.js +4 -4
- package/dist/synapse-queries/subscription/useSubscription.js.map +1 -1
- package/dist/synapse-queries/table/useTableUpdateTransaction.js +2 -2
- package/dist/synapse-queries/table/useTableUpdateTransaction.js.map +1 -1
- package/dist/synapse-queries/team/useTeam.js +2 -2
- package/dist/synapse-queries/team/useTeam.js.map +1 -1
- package/dist/synapse-queries/team/useTeamList.d.ts.map +1 -1
- package/dist/synapse-queries/team/useTeamList.js +3 -3
- package/dist/synapse-queries/team/useTeamList.js.map +1 -1
- package/dist/synapse-queries/team/useTeamMembers.js +8 -8
- package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
- package/dist/synapse-queries/termsOfService/useTermsOfService.js +2 -2
- package/dist/synapse-queries/termsOfService/useTermsOfService.js.map +1 -1
- package/dist/synapse-queries/trash/useTrashCan.js +4 -4
- package/dist/synapse-queries/trash/useTrashCan.js.map +1 -1
- package/dist/synapse-queries/user/useCertificationQuiz.js +2 -2
- package/dist/synapse-queries/user/useCertificationQuiz.js.map +1 -1
- package/dist/synapse-queries/user/useFavorites.js +4 -4
- package/dist/synapse-queries/user/useFavorites.js.map +1 -1
- package/dist/synapse-queries/user/useRevokeCertification.js +2 -2
- package/dist/synapse-queries/user/useRevokeCertification.js.map +1 -1
- package/dist/synapse-queries/wiki/useWiki.js +10 -10
- package/dist/synapse-queries/wiki/useWiki.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/ContentTypeUtils.js +4 -4
- package/dist/utils/ContentTypeUtils.js.map +1 -1
- package/dist/utils/PermissionLevelToAccessType.js +1 -1
- package/dist/utils/PermissionLevelToAccessType.js.map +1 -1
- package/dist/utils/analytics/useGoogleAnalytics.js +1 -1
- package/dist/utils/analytics/useGoogleAnalytics.js.map +1 -1
- package/dist/utils/context/DocumentMetadataContext.js +1 -1
- package/dist/utils/context/DocumentMetadataContext.js.map +1 -1
- package/dist/utils/functions/AccessControlListUtils.d.ts.map +1 -1
- package/dist/utils/functions/AccessControlListUtils.js +3 -3
- package/dist/utils/functions/AccessControlListUtils.js.map +1 -1
- package/dist/utils/functions/ArrayUtils.js +2 -2
- package/dist/utils/functions/ArrayUtils.js.map +1 -1
- package/dist/utils/functions/FileHandleUtils.js +1 -1
- package/dist/utils/functions/FileHandleUtils.js.map +1 -1
- package/dist/utils/functions/RegularExpressions.js +1 -1
- package/dist/utils/functions/RegularExpressions.js.map +1 -1
- package/dist/utils/functions/StringUtils.d.ts.map +1 -1
- package/dist/utils/functions/StringUtils.js +1 -2
- package/dist/utils/functions/StringUtils.js.map +1 -1
- package/dist/utils/functions/deepLinkingUtils.js +2 -2
- package/dist/utils/functions/deepLinkingUtils.js.map +1 -1
- package/dist/utils/functions/enumerationFacet.d.ts +26 -0
- package/dist/utils/functions/enumerationFacet.d.ts.map +1 -0
- package/dist/utils/functions/enumerationFacet.js +27 -0
- package/dist/utils/functions/enumerationFacet.js.map +1 -0
- package/dist/utils/functions/facetCountUtils.d.ts +12 -0
- package/dist/utils/functions/facetCountUtils.d.ts.map +1 -0
- package/dist/utils/functions/facetCountUtils.js +9 -0
- package/dist/utils/functions/facetCountUtils.js.map +1 -0
- package/dist/utils/functions/getEndpoint.js.map +1 -1
- package/dist/utils/functions/getUserData.js +1 -1
- package/dist/utils/functions/getUserData.js.map +1 -1
- package/dist/utils/functions/queryUtils.d.ts +1 -1
- package/dist/utils/functions/queryUtils.d.ts.map +1 -1
- package/dist/utils/functions/queryUtils.js +26 -22
- package/dist/utils/functions/queryUtils.js.map +1 -1
- package/dist/utils/functions/testDownloadSpeed.d.ts.map +1 -1
- package/dist/utils/functions/testDownloadSpeed.js +17 -26
- package/dist/utils/functions/testDownloadSpeed.js.map +1 -1
- package/dist/utils/functions/unCamelCase.js +1 -1
- package/dist/utils/functions/unCamelCase.js.map +1 -1
- package/dist/utils/hooks/useGetInfoFromIds.js +5 -5
- package/dist/utils/hooks/useGetInfoFromIds.js.map +1 -1
- package/dist/utils/hooks/useImmutableTableQuery/TableQueryReducerActions.js +1 -1
- package/dist/utils/hooks/useImmutableTableQuery/TableQueryReducerActions.js.map +1 -1
- package/dist/utils/hooks/useLogin.d.ts.map +1 -1
- package/dist/utils/hooks/useLogin.js +5 -5
- package/dist/utils/hooks/useLogin.js.map +1 -1
- package/dist/utils/hooks/useUploadFileEntity/useCreateFolderPath.js.map +1 -1
- package/dist/utils/jsonschema/collectTopLevelProperties.d.ts +6 -0
- package/dist/utils/jsonschema/collectTopLevelProperties.d.ts.map +1 -1
- package/dist/utils/jsonschema/collectTopLevelProperties.js +1 -1
- package/dist/utils/jsonschema/collectTopLevelProperties.js.map +1 -1
- package/dist/utils/jsonschema/getNumberOrEnumInfo.d.ts +22 -0
- package/dist/utils/jsonschema/getNumberOrEnumInfo.d.ts.map +1 -0
- package/dist/utils/jsonschema/getNumberOrEnumInfo.js +39 -0
- package/dist/utils/jsonschema/getNumberOrEnumInfo.js.map +1 -0
- package/dist/utils/jsonschema/getOnlyNonNullOneOfOption.d.ts +1 -0
- package/dist/utils/jsonschema/getOnlyNonNullOneOfOption.d.ts.map +1 -1
- package/dist/utils/jsonschema/getOnlyNonNullOneOfOption.js +1 -1
- package/dist/utils/jsonschema/getOnlyNonNullOneOfOption.js.map +1 -1
- package/dist/utils/jsonschema/getSchemaPropertyInfo.d.ts +5 -0
- package/dist/utils/jsonschema/getSchemaPropertyInfo.d.ts.map +1 -1
- package/dist/utils/jsonschema/getSchemaPropertyInfo.js +30 -15
- package/dist/utils/jsonschema/getSchemaPropertyInfo.js.map +1 -1
- package/dist/utils/jsonschema/submissionContext.js +2 -2
- package/dist/utils/jsonschema/submissionContext.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aridhiaAccessStatusUtils.d.ts","sourceRoot":"","sources":["../../../src/components/Aridhia/aridhiaAccessStatusUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AAEnF
|
|
1
|
+
{"version":3,"file":"aridhiaAccessStatusUtils.d.ts","sourceRoot":"","sources":["../../../src/components/Aridhia/aridhiaAccessStatusUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AAEnF,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAA;AAwBlE;;;;;;GAMG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,SAAS,eAAe,EAAE,GACnC,iBAAiB,CAMnB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,WAAW,EAAE,MAAM,GAClB,eAAe,EAAE,CAUnB"}
|
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
import { RestrictionUiType as e } from "../HasAccess/AccessIcon.js";
|
|
2
2
|
//#region src/components/Aridhia/aridhiaAccessStatusUtils.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
var t = [
|
|
4
|
+
"approved",
|
|
5
|
+
"pending",
|
|
6
|
+
"denied",
|
|
7
|
+
"error"
|
|
8
|
+
], n = {
|
|
9
|
+
approved: e.AccessibleOnRDCADAP,
|
|
10
|
+
pending: e.AccessBlockedByRestrictionWithPendingRDCADAPRequest,
|
|
11
|
+
denied: e.AccessBlockedByRestrictionWithRejectedRDCADAPRequest,
|
|
12
|
+
error: e.AccessBlockedByACL
|
|
13
|
+
};
|
|
14
|
+
function r(r) {
|
|
15
|
+
let i = new Set(r.map((e) => e.status)), a = t.find((e) => i.has(e));
|
|
16
|
+
return a ? n[a] : e.AccessBlockedByRestriction;
|
|
12
17
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
function i(e, t) {
|
|
19
|
+
return e.filter((e) => e.datasets?.some((e) => e.code === t)).sort((e, t) => {
|
|
20
|
+
let n = a(e), r = a(t);
|
|
21
|
+
return n === r ? 0 : r - n;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function a(e) {
|
|
25
|
+
let t = Date.parse(e.updated_at ?? "");
|
|
26
|
+
return Number.isNaN(t) ? -Infinity : t;
|
|
16
27
|
}
|
|
17
28
|
//#endregion
|
|
18
|
-
export {
|
|
29
|
+
export { i as findRequestsForDataset, r as getRestrictionUiTypeFromAridhiaRequests };
|
|
19
30
|
|
|
20
31
|
//# sourceMappingURL=aridhiaAccessStatusUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aridhiaAccessStatusUtils.js","names":[],"sources":["../../../src/components/Aridhia/aridhiaAccessStatusUtils.ts"],"sourcesContent":["import { RestrictionUiType } from '../HasAccess/AccessIcon'\nimport { RequestListItem } from '@sage-bionetworks/aridhia-client/generated/models'\n\n/**\n * Maps
|
|
1
|
+
{"version":3,"file":"aridhiaAccessStatusUtils.js","names":[],"sources":["../../../src/components/Aridhia/aridhiaAccessStatusUtils.ts"],"sourcesContent":["import { RestrictionUiType } from '../HasAccess/AccessIcon'\nimport { RequestListItem } from '@sage-bionetworks/aridhia-client/generated/models'\n\nexport type RequestStatus = NonNullable<RequestListItem['status']>\n\n/**\n * A user may hold several DARs for one dataset (e.g. different tables, or a resubmission after\n * a denial). The icon reflects the most favorable one: any approval grants access to some of\n * the data, and any pending request means a decision is still outstanding.\n */\nconst STATUS_PRECEDENCE: readonly RequestStatus[] = [\n 'approved',\n 'pending',\n 'denied',\n 'error',\n]\n\nconst RESTRICTION_UI_TYPE_BY_STATUS: Record<RequestStatus, RestrictionUiType> =\n {\n approved: RestrictionUiType.AccessibleOnRDCADAP,\n pending:\n RestrictionUiType.AccessBlockedByRestrictionWithPendingRDCADAPRequest,\n denied:\n RestrictionUiType.AccessBlockedByRestrictionWithRejectedRDCADAPRequest,\n error: RestrictionUiType.AccessBlockedByACL,\n }\n\n/**\n * Maps a user's Aridhia requests for one dataset to the RestrictionUiType for display.\n *\n * @param requests - Every request the user holds for the dataset (may be empty)\n * @returns The RestrictionUiType of the highest-precedence status present, or\n * `AccessBlockedByRestriction` when no request has a recognized status\n */\nexport function getRestrictionUiTypeFromAridhiaRequests(\n requests: readonly RequestListItem[],\n): RestrictionUiType {\n const statuses = new Set(requests.map(request => request.status))\n const status = STATUS_PRECEDENCE.find(candidate => statuses.has(candidate))\n return status\n ? RESTRICTION_UI_TYPE_BY_STATUS[status]\n : RestrictionUiType.AccessBlockedByRestriction\n}\n\n/**\n * Finds every Aridhia request that includes a specific dataset.\n *\n * @param requests - Array of Aridhia requests\n * @param datasetCode - The dataset code to search for (case-sensitive)\n * @returns The matching requests, most recently updated first; requests whose `updated_at` is\n * missing or unparseable sort last\n */\nexport function findRequestsForDataset(\n requests: readonly RequestListItem[],\n datasetCode: string,\n): RequestListItem[] {\n return requests\n .filter(request =>\n request.datasets?.some(dataset => dataset.code === datasetCode),\n )\n .sort((a, b) => {\n const aMillis = updatedAtMillis(a)\n const bMillis = updatedAtMillis(b)\n return aMillis === bMillis ? 0 : bMillis - aMillis\n })\n}\n\n/** Undated and unparseable timestamps map to -Infinity so they sort after every real date. */\nfunction updatedAtMillis(request: RequestListItem): number {\n const millis = Date.parse(request.updated_at ?? '')\n return Number.isNaN(millis) ? -Infinity : millis\n}\n"],"mappings":";;AAUA,IAAM,IAA8C;CAClD;CACA;CACA;CACA;AACF,GAEM,IACJ;CACE,UAAU,EAAkB;CAC5B,SACE,EAAkB;CACpB,QACE,EAAkB;CACpB,OAAO,EAAkB;AAC3B;AASF,SAAgB,EACd,GACmB;CACnB,IAAM,IAAW,IAAI,IAAI,EAAS,KAAI,MAAW,EAAQ,MAAM,CAAC,GAC1D,IAAS,EAAkB,MAAK,MAAa,EAAS,IAAI,CAAS,CAAC;CAC1E,OAAO,IACH,EAA8B,KAC9B,EAAkB;AACxB;AAUA,SAAgB,EACd,GACA,GACmB;CACnB,OAAO,EACJ,QAAO,MACN,EAAQ,UAAU,MAAK,MAAW,EAAQ,SAAS,CAAW,CAChE,EACC,MAAM,GAAG,MAAM;EACd,IAAM,IAAU,EAAgB,CAAC,GAC3B,IAAU,EAAgB,CAAC;EACjC,OAAO,MAAY,IAAU,IAAI,IAAU;CAC7C,CAAC;AACL;AAGA,SAAS,EAAgB,GAAkC;CACzD,IAAM,IAAS,KAAK,MAAM,EAAQ,cAAc,EAAE;CAClD,OAAO,OAAO,MAAM,CAAM,IAAI,YAAY;AAC5C"}
|
|
@@ -36,10 +36,10 @@ function y() {
|
|
|
36
36
|
].forEach((e) => localStorage.removeItem(e));
|
|
37
37
|
}
|
|
38
38
|
function b(e) {
|
|
39
|
-
return
|
|
39
|
+
return /^[aeiou]/i.exec(e) ? "an" : "a";
|
|
40
40
|
}
|
|
41
41
|
function x(e) {
|
|
42
|
-
return
|
|
42
|
+
return / Portal$/.exec(e) ? "the " : "";
|
|
43
43
|
}
|
|
44
44
|
function S(e) {
|
|
45
45
|
let { currentSourceAppName: t, lastLoginMethod: n, lastLoginSourceAppName: r, lastLoginSourceAppURL: i, lastLoginDate: g, display: _ } = e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LastLoginInfo.js","names":[],"sources":["../../../src/components/Authentication/LastLoginInfo.tsx"],"sourcesContent":["import { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n} from '@/utils/SynapseConstants'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport { Box, Link, Tooltip, Typography } from '@mui/material'\nimport { useLocalStorageValue } from '@react-hookz/web'\nimport dayjs from 'dayjs'\nimport { getLoginMethodFriendlyName, LoginMethod } from './LoginMethod'\n\nexport type LastLoginInfoProps = {\n currentSourceAppName: string | undefined\n lastLoginMethod: LoginMethod | undefined\n lastLoginSourceAppName: string | undefined\n lastLoginSourceAppURL: string | undefined\n lastLoginDate: string | undefined\n display: 'sentence' | 'box'\n}\n\nexport function useLastLoginInfoState() {\n return {\n currentSourceAppNameState: useLocalStorageValue<string>(\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n ),\n lastLoginMethodState: useLocalStorageValue<LoginMethod>(\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n ),\n lastLoginSourceAppNameState: useLocalStorageValue<string>(\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n ),\n lastLoginSourceAppURLState: useLocalStorageValue<string>(\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n ),\n lastLoginDateState: useLocalStorageValue<string>(\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n ),\n }\n}\n\nexport function useLastLoginInfo() {\n const states = useLastLoginInfoState()\n return {\n currentSourceAppName: states.currentSourceAppNameState.value,\n lastLoginMethod: states.lastLoginMethodState.value,\n lastLoginSourceAppName: states.lastLoginSourceAppNameState.value,\n lastLoginSourceAppURL: states.lastLoginSourceAppURLState.value,\n lastLoginDate: states.lastLoginDateState.value,\n }\n}\n\nexport function clearLastLoginInfo() {\n const keys = [\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n ]\n keys.forEach(key => localStorage.removeItem(key))\n}\n\nfunction getSourceAppIndefiniteArticle(val: string) {\n return
|
|
1
|
+
{"version":3,"file":"LastLoginInfo.js","names":[],"sources":["../../../src/components/Authentication/LastLoginInfo.tsx"],"sourcesContent":["import { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n} from '@/utils/SynapseConstants'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport { Box, Link, Tooltip, Typography } from '@mui/material'\nimport { useLocalStorageValue } from '@react-hookz/web'\nimport dayjs from 'dayjs'\nimport { getLoginMethodFriendlyName, LoginMethod } from './LoginMethod'\n\nexport type LastLoginInfoProps = {\n currentSourceAppName: string | undefined\n lastLoginMethod: LoginMethod | undefined\n lastLoginSourceAppName: string | undefined\n lastLoginSourceAppURL: string | undefined\n lastLoginDate: string | undefined\n display: 'sentence' | 'box'\n}\n\nexport function useLastLoginInfoState() {\n return {\n currentSourceAppNameState: useLocalStorageValue<string>(\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n ),\n lastLoginMethodState: useLocalStorageValue<LoginMethod>(\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n ),\n lastLoginSourceAppNameState: useLocalStorageValue<string>(\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n ),\n lastLoginSourceAppURLState: useLocalStorageValue<string>(\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n ),\n lastLoginDateState: useLocalStorageValue<string>(\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n ),\n }\n}\n\nexport function useLastLoginInfo() {\n const states = useLastLoginInfoState()\n return {\n currentSourceAppName: states.currentSourceAppNameState.value,\n lastLoginMethod: states.lastLoginMethodState.value,\n lastLoginSourceAppName: states.lastLoginSourceAppNameState.value,\n lastLoginSourceAppURL: states.lastLoginSourceAppURLState.value,\n lastLoginDate: states.lastLoginDateState.value,\n }\n}\n\nexport function clearLastLoginInfo() {\n const keys = [\n CURRENT_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_METHOD_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_NAME_LOCALSTORAGE_KEY,\n LAST_LOGIN_SOURCEAPP_URL_LOCALSTORAGE_KEY,\n LAST_LOGIN_DATE_LOCALSTORAGE_KEY,\n ]\n keys.forEach(key => localStorage.removeItem(key))\n}\n\nfunction getSourceAppIndefiniteArticle(val: string) {\n return /^[aeiou]/i.exec(val) ? 'an' : 'a'\n}\n\nfunction getSourceAppDefiniteArticle(val: string) {\n return / Portal$/.exec(val) ? 'the ' : ''\n}\n\nexport default function LastLoginInfo(props: LastLoginInfoProps) {\n const {\n currentSourceAppName,\n lastLoginMethod,\n lastLoginSourceAppName,\n lastLoginSourceAppURL,\n lastLoginDate,\n display,\n } = props\n\n const showLastLoginInfo =\n currentSourceAppName &&\n lastLoginMethod &&\n lastLoginSourceAppName &&\n lastLoginSourceAppURL &&\n lastLoginDate &&\n currentSourceAppName !== lastLoginSourceAppName\n\n if (!showLastLoginInfo) {\n return null\n }\n\n const currentSourceAppIndefiniteArticle =\n getSourceAppIndefiniteArticle(currentSourceAppName)\n const currentSourceAppDefiniteArticle =\n getSourceAppDefiniteArticle(currentSourceAppName)\n const lastLoginSourceAppDefiniteArticle = getSourceAppDefiniteArticle(\n lastLoginSourceAppName,\n )\n\n const title = `You may already have ${currentSourceAppIndefiniteArticle} ${currentSourceAppName} account`\n const accountLastUsed = `Account last used on ${formatDate(\n dayjs(lastLoginDate),\n 'MMMM D, YYYY',\n )}`\n\n const tooltipText = (\n <>\n <Typography\n variant=\"smallText2\"\n sx={{\n mb: 1,\n }}\n >\n {title}\n </Typography>\n <Typography\n variant=\"smallText1\"\n color=\"white\"\n sx={{\n mb: 1,\n }}\n >\n {`This computer was used to sign in to an account on ${lastLoginSourceAppDefiniteArticle}${lastLoginSourceAppName}. \n You can use the same account to sign in to ${currentSourceAppDefiniteArticle}${currentSourceAppName}.`}\n </Typography>\n <Typography variant=\"smallText1\" color=\"white\">\n {accountLastUsed}\n </Typography>\n </>\n )\n\n const boxText = (\n <>\n <Typography\n variant=\"smallText2\"\n sx={{\n mb: 1,\n color: 'grey.900',\n fontSize: '12px',\n }}\n >\n {title}\n </Typography>\n <Typography\n variant=\"smallText1\"\n sx={{\n mb: 1,\n color: 'grey.900',\n fontSize: '12px',\n }}\n >\n It looks like you already have an account, last used on{' '}\n {lastLoginSourceAppDefiniteArticle}\n <Link href={lastLoginSourceAppURL}>{lastLoginSourceAppName}</Link>.{' '}\n {`You can use this account to sign in via ${getLoginMethodFriendlyName(\n lastLoginMethod,\n )}.`}\n </Typography>\n <Typography\n variant=\"smallText1\"\n sx={{ color: 'grey.700', fontSize: '10px' }}\n >\n {accountLastUsed}\n </Typography>\n </>\n )\n\n return (\n <>\n {display === 'sentence' ? (\n <Typography\n variant=\"smallText1\"\n sx={{ color: 'grey.700', textTransform: 'none' }}\n >\n You may be able to use an existing account\n <Tooltip\n title={tooltipText}\n placement={'top'}\n slotProps={{\n tooltip: {\n sx: {\n bgcolor: '#63676C',\n '& .MuiTooltip-arrow': {\n color: '#63676C',\n },\n },\n },\n }}\n >\n <InfoTwoTone\n sx={{\n color: 'grey.700',\n width: '12px',\n height: '12px',\n ml: '4px',\n verticalAlign: 'middle',\n }}\n />\n </Tooltip>\n </Typography>\n ) : (\n <Box sx={{ backgroundColor: 'grey.100', p: '10px' }}>{boxText}</Box>\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;;;AAuBA,SAAgB,IAAwB;CACtC,OAAO;EACL,2BAA2B,EACzB,CACF;EACA,sBAAsB,EACpB,CACF;EACA,6BAA6B,EAC3B,CACF;EACA,4BAA4B,EAC1B,CACF;EACA,oBAAoB,EAClB,CACF;CACF;AACF;AAEA,SAAgB,IAAmB;CACjC,IAAM,IAAS,EAAsB;CACrC,OAAO;EACL,sBAAsB,EAAO,0BAA0B;EACvD,iBAAiB,EAAO,qBAAqB;EAC7C,wBAAwB,EAAO,4BAA4B;EAC3D,uBAAuB,EAAO,2BAA2B;EACzD,eAAe,EAAO,mBAAmB;CAC3C;AACF;AAEA,SAAgB,IAAqB;CAQnC;EANE;EACA;EACA;EACA;EACA;CAEF,EAAK,SAAQ,MAAO,aAAa,WAAW,CAAG,CAAC;AAClD;AAEA,SAAS,EAA8B,GAAa;CAClD,OAAO,YAAY,KAAK,CAAG,IAAI,OAAO;AACxC;AAEA,SAAS,EAA4B,GAAa;CAChD,OAAO,WAAW,KAAK,CAAG,IAAI,SAAS;AACzC;AAEA,SAAwB,EAAc,GAA2B;CAC/D,IAAM,EACJ,yBACA,oBACA,2BACA,0BACA,kBACA,eACE;CAUJ,IAAI,EAPF,KACA,KACA,KACA,KACA,KACA,MAAyB,IAGzB,OAAO;CAGT,IAAM,IACJ,EAA8B,CAAoB,GAC9C,IACJ,EAA4B,CAAoB,GAC5C,IAAoC,EACxC,CACF,GAEM,IAAQ,wBAAwB,EAAkC,GAAG,EAAqB,WAC1F,IAAkB,wBAAwB,EAC9C,EAAM,CAAa,GACnB,cACF,KAEM,IACJ,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI,EACF,IAAI,EACN;aAEC;EACS,CAAA;EACZ,kBAAC,GAAD;GACE,SAAQ;GACR,OAAM;GACN,IAAI,EACF,IAAI,EACN;aAEC,sDAAsD,IAAoC,EAAuB;uDACnE,IAAkC,EAAqB;EAC5F,CAAA;EACZ,kBAAC,GAAD;GAAY,SAAQ;GAAa,OAAM;aACpC;EACS,CAAA;CACZ,EAAA,CAAA,GAGE,IACJ,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI;IACF,IAAI;IACJ,OAAO;IACP,UAAU;GACZ;aAEC;EACS,CAAA;EACZ,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI;IACF,IAAI;IACJ,OAAO;IACP,UAAU;GACZ;aANF;IAOC;IACyD;IACvD;IACD,kBAAC,GAAD;KAAM,MAAM;eAAwB;IAA6B,CAAA;IAAC;IAAE;IACnE,2CAA2C,EAC1C,CACF,EAAE;GACQ;;EACZ,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI;IAAE,OAAO;IAAY,UAAU;GAAO;aAEzC;EACS,CAAA;CACZ,EAAA,CAAA;CAGJ,OACE,kBAAA,GAAA,EAAA,UACG,MAAY,aACX,kBAAC,GAAD;EACE,SAAQ;EACR,IAAI;GAAE,OAAO;GAAY,eAAe;EAAO;YAFjD,CAGC,8CAEC,kBAAC,GAAD;GACE,OAAO;GACP,WAAW;GACX,WAAW,EACT,SAAS,EACP,IAAI;IACF,SAAS;IACT,uBAAuB,EACrB,OAAO,UACT;GACF,EACF,EACF;aAEA,kBAAC,GAAD,EACE,IAAI;IACF,OAAO;IACP,OAAO;IACP,QAAQ;IACR,IAAI;IACJ,eAAe;GACjB,EACD,CAAA;EACM,CAAA,CACC;MAEZ,kBAAC,GAAD;EAAK,IAAI;GAAE,iBAAiB;GAAY,GAAG;EAAO;YAAI;CAAa,CAAA,EAErE,CAAA;AAEN"}
|
|
@@ -10,7 +10,7 @@ function s(s) {
|
|
|
10
10
|
placeholder: "Enter backup code",
|
|
11
11
|
value: u,
|
|
12
12
|
onChange: (e) => {
|
|
13
|
-
d(e.target.value.toLowerCase().
|
|
13
|
+
d(e.target.value.toLowerCase().replaceAll(/[^a-z0-9-]/gi, ""));
|
|
14
14
|
}
|
|
15
15
|
}), /* @__PURE__ */ i(r, {
|
|
16
16
|
fullWidth: !0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecoveryCodeForm.js","names":[],"sources":["../../../src/components/Authentication/RecoveryCodeForm.tsx"],"sourcesContent":["import { UseLoginReturn } from '@/utils/hooks'\nimport { Box, Button } from '@mui/material'\nimport { useState } from 'react'\nimport TextField from '../TextField/TextField'\n\n// 16 characters separated into chunks of 4 by 3 hyphens\nconst RECOVERY_CODE_LENGTH = 19\n\ntype RecoveryCodeFormProps = {\n onSubmit: (value: string) => void\n loginIsPending: UseLoginReturn['loginIsPending']\n}\n\nexport default function RecoveryCodeForm(props: RecoveryCodeFormProps) {\n const { onSubmit, loginIsPending } = props\n const [recoveryCode, setRecoveryCode] = useState('')\n return (\n <Box>\n <TextField\n placeholder=\"Enter backup code\"\n value={recoveryCode}\n onChange={e => {\n // coerce the input to lowercase and remove any nonalphanumeric or hyphen characters\n const valueWithAllowedChars = e.target.value\n .toLowerCase()\n .
|
|
1
|
+
{"version":3,"file":"RecoveryCodeForm.js","names":[],"sources":["../../../src/components/Authentication/RecoveryCodeForm.tsx"],"sourcesContent":["import { UseLoginReturn } from '@/utils/hooks'\nimport { Box, Button } from '@mui/material'\nimport { useState } from 'react'\nimport TextField from '../TextField/TextField'\n\n// 16 characters separated into chunks of 4 by 3 hyphens\nconst RECOVERY_CODE_LENGTH = 19\n\ntype RecoveryCodeFormProps = {\n onSubmit: (value: string) => void\n loginIsPending: UseLoginReturn['loginIsPending']\n}\n\nexport default function RecoveryCodeForm(props: RecoveryCodeFormProps) {\n const { onSubmit, loginIsPending } = props\n const [recoveryCode, setRecoveryCode] = useState('')\n return (\n <Box>\n <TextField\n placeholder=\"Enter backup code\"\n value={recoveryCode}\n onChange={e => {\n // coerce the input to lowercase and remove any nonalphanumeric or hyphen characters\n const valueWithAllowedChars = e.target.value\n .toLowerCase()\n .replaceAll(/[^a-z0-9-]/gi, '')\n setRecoveryCode(valueWithAllowedChars)\n }}\n />\n\n <Button\n fullWidth\n type=\"submit\"\n color=\"primary\"\n variant=\"contained\"\n sx={{\n height: '50px',\n mt: 4,\n mb: 2,\n }}\n disabled={\n recoveryCode.length !== RECOVERY_CODE_LENGTH || loginIsPending\n }\n onClick={e => {\n e.preventDefault()\n onSubmit(recoveryCode)\n }}\n >\n {loginIsPending ? 'Verifying...' : 'Submit'}\n </Button>\n </Box>\n )\n}\n"],"mappings":";;;;;AAMA,IAAM,IAAuB;AAO7B,SAAwB,EAAiB,GAA8B;CACrE,IAAM,EAAE,aAAU,sBAAmB,GAC/B,CAAC,GAAc,KAAmB,EAAS,EAAE;CACnD,OACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,aAAY;EACZ,OAAO;EACP,WAAU,MAAK;GAKb,EAH8B,EAAE,OAAO,MACpC,YAAY,EACZ,WAAW,gBAAgB,EACd,CAAqB;EACvC;CACD,CAAA,GAED,kBAAC,GAAD;EACE,WAAA;EACA,MAAK;EACL,OAAM;EACN,SAAQ;EACR,IAAI;GACF,QAAQ;GACR,IAAI;GACJ,IAAI;EACN;EACA,UACE,EAAa,WAAW,KAAwB;EAElD,UAAS,MAAK;GAEZ,AADA,EAAE,eAAe,GACjB,EAAS,CAAY;EACvB;YAEC,IAAiB,iBAAiB;CAC7B,CAAA,CACL,EAAA,CAAA;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecoveryCodeGrid.js","names":[],"sources":["../../../src/components/Authentication/RecoveryCodeGrid.tsx"],"sourcesContent":["import ConditionalWrapper from '@/components/utils/ConditionalWrapper'\nimport { Box } from '@mui/material'\nimport Skeleton from '@mui/material/Skeleton'\nimport { TwoFactorAuthRecoveryCodes } from '@sage-bionetworks/synapse-types'\n\nconst DEFAULT_RECOVERY_CODE_COUNT = 10\n\n// Placeholder codes used to render skeletons while loading\nconst PLACEHOLDER_RECOVERY_CODE = '1234-5678-9012-3456'\nconst PLACEHOLDER_RECOVERY_CODES = Array(DEFAULT_RECOVERY_CODE_COUNT).fill(\n PLACEHOLDER_RECOVERY_CODE,\n)\n\ntype RecoveryCodeGridProps = {\n recoveryCodes?: TwoFactorAuthRecoveryCodes\n}\n\nexport function RecoveryCodeGrid(props: RecoveryCodeGridProps) {\n const { recoveryCodes } = props\n return (\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: { xs: 'max-content', md: '47.5% 47.5%' },\n justifyContent: { xs: 'center', md: 'stretch' },\n columnGap: '5%',\n gridTemplateRows: 'repeat(5, 1fr)',\n fontFamily: 'Menlo, Courier New, Courier, monospace',\n my: 2,\n }}\n >\n {(recoveryCodes?.codes ?? PLACEHOLDER_RECOVERY_CODES).map(\n (code, index) => {\n return (\n <ConditionalWrapper\n key={index}\n condition={!recoveryCodes}\n wrapper={Skeleton}\n wrapperProps={{ width: '100%', height: '100%' }}\n >\n <Box\n sx={{\n my: 1,\n fontSize: '13px',\n }}\n >\n {code}\n </Box>\n </ConditionalWrapper>\n )\n },\n )}\n </Box>\n )\n}\n"],"mappings":";;;;;AASA,IAAM,
|
|
1
|
+
{"version":3,"file":"RecoveryCodeGrid.js","names":[],"sources":["../../../src/components/Authentication/RecoveryCodeGrid.tsx"],"sourcesContent":["import ConditionalWrapper from '@/components/utils/ConditionalWrapper'\nimport { Box } from '@mui/material'\nimport Skeleton from '@mui/material/Skeleton'\nimport { TwoFactorAuthRecoveryCodes } from '@sage-bionetworks/synapse-types'\n\nconst DEFAULT_RECOVERY_CODE_COUNT = 10\n\n// Placeholder codes used to render skeletons while loading\nconst PLACEHOLDER_RECOVERY_CODE = '1234-5678-9012-3456'\nconst PLACEHOLDER_RECOVERY_CODES = new Array(DEFAULT_RECOVERY_CODE_COUNT).fill(\n PLACEHOLDER_RECOVERY_CODE,\n)\n\ntype RecoveryCodeGridProps = {\n recoveryCodes?: TwoFactorAuthRecoveryCodes\n}\n\nexport function RecoveryCodeGrid(props: RecoveryCodeGridProps) {\n const { recoveryCodes } = props\n return (\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: { xs: 'max-content', md: '47.5% 47.5%' },\n justifyContent: { xs: 'center', md: 'stretch' },\n columnGap: '5%',\n gridTemplateRows: 'repeat(5, 1fr)',\n fontFamily: 'Menlo, Courier New, Courier, monospace',\n my: 2,\n }}\n >\n {(recoveryCodes?.codes ?? PLACEHOLDER_RECOVERY_CODES).map(\n (code, index) => {\n return (\n <ConditionalWrapper\n key={index}\n condition={!recoveryCodes}\n wrapper={Skeleton}\n wrapperProps={{ width: '100%', height: '100%' }}\n >\n <Box\n sx={{\n my: 1,\n fontSize: '13px',\n }}\n >\n {code}\n </Box>\n </ConditionalWrapper>\n )\n },\n )}\n </Box>\n )\n}\n"],"mappings":";;;;;AASA,IAAM,IAAiC,MAAM,EAA2B,EAAE,KACxE,qBACF;AAMA,SAAgB,EAAiB,GAA8B;CAC7D,IAAM,EAAE,qBAAkB;CAC1B,OACE,kBAAC,GAAD;EACE,IAAI;GACF,SAAS;GACT,qBAAqB;IAAE,IAAI;IAAe,IAAI;GAAc;GAC5D,gBAAgB;IAAE,IAAI;IAAU,IAAI;GAAU;GAC9C,WAAW;GACX,kBAAkB;GAClB,YAAY;GACZ,IAAI;EACN;aAEE,GAAe,SAAS,GAA4B,KACnD,GAAM,MAEH,kBAAC,GAAD;GAEE,WAAW,CAAC;GACZ,SAAS;GACT,cAAc;IAAE,OAAO;IAAQ,QAAQ;GAAO;aAE9C,kBAAC,GAAD;IACE,IAAI;KACF,IAAI;KACJ,UAAU;IACZ;cAEC;GACE,CAAA;EACa,GAbb,CAaa,CAG1B;CACG,CAAA;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TOTPForm.d.ts","sourceRoot":"","sources":["../../../src/components/Authentication/TOTPForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"TOTPForm.d.ts","sourceRoot":"","sources":["../../../src/components/Authentication/TOTPForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAoB9C,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAA;CACjD,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,2CA6DpD"}
|
|
@@ -4,7 +4,7 @@ import { Box as n, Button as r } from "@mui/material";
|
|
|
4
4
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
5
|
import { MuiOtpInput as o } from "mui-one-time-password-input";
|
|
6
6
|
//#region src/components/Authentication/TOTPForm.tsx
|
|
7
|
-
var s = 6, c = [
|
|
7
|
+
var s = 6, c = new Set([
|
|
8
8
|
"0",
|
|
9
9
|
"1",
|
|
10
10
|
"2",
|
|
@@ -15,7 +15,7 @@ var s = 6, c = [
|
|
|
15
15
|
"7",
|
|
16
16
|
"8",
|
|
17
17
|
"9"
|
|
18
|
-
];
|
|
18
|
+
]);
|
|
19
19
|
function l(l) {
|
|
20
20
|
let { onSubmit: u, loginIsPending: d } = l, [f, p] = t("");
|
|
21
21
|
return /* @__PURE__ */ a(n, { children: [/* @__PURE__ */ i(o, {
|
|
@@ -25,7 +25,7 @@ function l(l) {
|
|
|
25
25
|
value: f,
|
|
26
26
|
onChange: p,
|
|
27
27
|
onComplete: u,
|
|
28
|
-
validateChar: (e) => c.
|
|
28
|
+
validateChar: (e) => c.has(e) || e === "",
|
|
29
29
|
gap: "2px",
|
|
30
30
|
sx: {
|
|
31
31
|
mx: "auto",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TOTPForm.js","names":[],"sources":["../../../src/components/Authentication/TOTPForm.tsx"],"sourcesContent":["import { UseLoginReturn } from '@/utils/hooks'\nimport { Box, Button } from '@mui/material'\nimport { MuiOtpInput } from 'mui-one-time-password-input'\nimport { useState } from 'react'\nimport { NUMERIC_CODE_HTML_INPUT_PROPS } from './Constants'\n\nconst TOTP_LENGTH = 6\nconst DIGIT_CHARACTERS = ['0'
|
|
1
|
+
{"version":3,"file":"TOTPForm.js","names":[],"sources":["../../../src/components/Authentication/TOTPForm.tsx"],"sourcesContent":["import { UseLoginReturn } from '@/utils/hooks'\nimport { Box, Button } from '@mui/material'\nimport { MuiOtpInput } from 'mui-one-time-password-input'\nimport { useState } from 'react'\nimport { NUMERIC_CODE_HTML_INPUT_PROPS } from './Constants'\n\nconst TOTP_LENGTH = 6\nconst DIGIT_CHARACTERS = new Set([\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n])\n\ntype TOTPFormProps = {\n onSubmit: (value: string) => void\n loginIsPending: UseLoginReturn['loginIsPending']\n}\n\nexport default function TOTPForm(props: TOTPFormProps) {\n const { onSubmit, loginIsPending } = props\n const [verificationCode, setVerificationCode] = useState('')\n return (\n <Box>\n <MuiOtpInput\n autoFocus\n length={TOTP_LENGTH}\n TextFieldsProps={{\n slotProps: {\n htmlInput: NUMERIC_CODE_HTML_INPUT_PROPS,\n },\n }}\n value={verificationCode}\n onChange={setVerificationCode}\n onComplete={onSubmit}\n validateChar={(character: string) => {\n return DIGIT_CHARACTERS.has(character) || character === ''\n }}\n gap={'2px'}\n sx={{\n mx: 'auto',\n maxWidth: '350px',\n '.MuiInputBase-root': {\n paddingLeft: '5px',\n paddingRight: '5px',\n },\n '.MuiFormControl-root:first-of-type > .MuiInputBase-root': {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n },\n '.MuiFormControl-root:last-of-type > .MuiInputBase-root': {\n borderTopLeftRadius: 0,\n borderBottomLeftRadius: 0,\n },\n '.MuiFormControl-root:not(:first-of-type):not(:last-of-type) > .MuiInputBase-root':\n {\n borderRadius: 0,\n },\n }}\n />\n <Button\n fullWidth\n type=\"submit\"\n color=\"primary\"\n variant=\"contained\"\n sx={{\n height: '50px',\n mt: 4,\n mb: 2,\n }}\n disabled={verificationCode.length !== TOTP_LENGTH || loginIsPending}\n onClick={e => {\n e.preventDefault()\n onSubmit(verificationCode)\n }}\n >\n {loginIsPending ? 'Verifying...' : 'Submit'}\n </Button>\n </Box>\n )\n}\n"],"mappings":";;;;;;AAMA,IAAM,IAAc,GACd,IAAmB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAOD,SAAwB,EAAS,GAAsB;CACrD,IAAM,EAAE,aAAU,sBAAmB,GAC/B,CAAC,GAAkB,KAAuB,EAAS,EAAE;CAC3D,OACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EACE,WAAA;EACA,QAAQ;EACR,iBAAiB,EACf,WAAW,EACT,WAAW,EACb,EACF;EACA,OAAO;EACP,UAAU;EACV,YAAY;EACZ,eAAe,MACN,EAAiB,IAAI,CAAS,KAAK,MAAc;EAE1D,KAAK;EACL,IAAI;GACF,IAAI;GACJ,UAAU;GACV,sBAAsB;IACpB,aAAa;IACb,cAAc;GAChB;GACA,2DAA2D;IACzD,sBAAsB;IACtB,yBAAyB;GAC3B;GACA,0DAA0D;IACxD,qBAAqB;IACrB,wBAAwB;GAC1B;GACA,oFACE,EACE,cAAc,EAChB;EACJ;CACD,CAAA,GACD,kBAAC,GAAD;EACE,WAAA;EACA,MAAK;EACL,OAAM;EACN,SAAQ;EACR,IAAI;GACF,QAAQ;GACR,IAAI;GACJ,IAAI;EACN;EACA,UAAU,EAAiB,WAAW,KAAe;EACrD,UAAS,MAAK;GAEZ,AADA,EAAE,eAAe,GACjB,EAAS,CAAgB;EAC3B;YAEC,IAAiB,iBAAiB;CAC7B,CAAA,CACL,EAAA,CAAA;AAET"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { LastLoginInfoProps } from './LastLoginInfo';
|
|
2
|
-
import
|
|
2
|
+
import LastLoginInfo, { useLastLoginInfo, useLastLoginInfoState } from './LastLoginInfo';
|
|
3
3
|
import type { LoginMethod } from './LoginMethod';
|
|
4
|
-
import
|
|
4
|
+
import PasswordField from './PasswordField';
|
|
5
5
|
import type { StandaloneLoginFormProps } from './StandaloneLoginForm';
|
|
6
|
-
import
|
|
6
|
+
import StandaloneLoginForm from './StandaloneLoginForm';
|
|
7
7
|
import type { TwoFactorAuthSettingsPanelProps } from './TwoFactorAuthSettingsPanel';
|
|
8
|
-
import
|
|
8
|
+
import TwoFactorAuthSettingsPanel from './TwoFactorAuthSettingsPanel';
|
|
9
9
|
import type { TwoFactorEnrollmentFormProps } from './TwoFactorEnrollmentForm';
|
|
10
|
-
import
|
|
10
|
+
import TwoFactorEnrollmentForm from './TwoFactorEnrollmentForm';
|
|
11
11
|
import type { TwoFactorBackupCodesProps } from './TwoFactorBackupCodes';
|
|
12
|
-
import
|
|
12
|
+
import TwoFactorBackupCodes from './TwoFactorBackupCodes';
|
|
13
13
|
import OneTimePasswordForm, { type OneTimePasswordFormProps, type ONE_TIME_PASSWORD_STEP } from './OneTimePasswordForm';
|
|
14
14
|
export { useLastLoginInfoState, useLastLoginInfo, LastLoginInfo, LastLoginInfoProps, LoginMethod, PasswordField, StandaloneLoginForm, StandaloneLoginFormProps, TwoFactorAuthSettingsPanel, TwoFactorAuthSettingsPanelProps, TwoFactorEnrollmentForm, TwoFactorEnrollmentFormProps, TwoFactorBackupCodes, TwoFactorBackupCodesProps, OneTimePasswordForm, OneTimePasswordFormProps, ONE_TIME_PASSWORD_STEP, };
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Authentication/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Authentication/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,aAAa,EAAE,EACpB,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AACvD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAA;AACnF,OAAO,0BAA0B,MAAM,8BAA8B,CAAA;AACrE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,uBAAuB,MAAM,2BAA2B,CAAA;AAC/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,oBAAoB,MAAM,wBAAwB,CAAA;AACzD,OAAO,mBAAmB,EAAE,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,GACvB,CAAA"}
|
|
@@ -129,7 +129,7 @@ function E(t) {
|
|
|
129
129
|
e += "\n";
|
|
130
130
|
let n = F[t].sectionText;
|
|
131
131
|
n && (e += n + "\n");
|
|
132
|
-
for (let n of F[t].reasons) n != null && (e += "\n* " + n.replaceAll(
|
|
132
|
+
for (let n of F[t].reasons) n != null && (e += "\n* " + n.replaceAll(String.raw`\n`, "\n") + "\n");
|
|
133
133
|
return e;
|
|
134
134
|
}, "") + d;
|
|
135
135
|
return o(() => {
|
|
@@ -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?.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
|
+
{"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(String.raw`\\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,10 +1,10 @@
|
|
|
1
1
|
import { DATASET as e, FUNDER as t, GENERIC_CARD as n, MEDIUM_USER_CARD as r, OBSERVATION_CARD as i, RELEASE_CARD as a } from "../../utils/SynapseConstants.js";
|
|
2
|
-
import o from "
|
|
3
|
-
import s from "
|
|
4
|
-
import
|
|
2
|
+
import { useQueryVisualizationContext as o } from "../QueryVisualizationWrapper/QueryVisualizationContext.js";
|
|
3
|
+
import s from "../../utils/hooks/useGetInfoFromIds.js";
|
|
4
|
+
import c from "../LoadingScreen/LoadingScreen.js";
|
|
5
|
+
import { useQueryContext as l } from "../QueryContext/QueryContext.js";
|
|
5
6
|
import "../QueryContext/index.js";
|
|
6
|
-
import { useGetQueryMetadata as
|
|
7
|
-
import { useQueryVisualizationContext as u } from "../QueryVisualizationWrapper/QueryVisualizationContext.js";
|
|
7
|
+
import { useGetQueryMetadata as u } from "../QueryWrapper/useGetQueryMetadata.js";
|
|
8
8
|
import "../QueryVisualizationWrapper/index.js";
|
|
9
9
|
import { TableRowGenericCard as d } from "../GenericCard/TableRowGenericCard.js";
|
|
10
10
|
import { ReleaseCard as f } from "../ReleaseCard/ReleaseCard.js";
|
|
@@ -46,11 +46,11 @@ function D(r) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
function O(e) {
|
|
49
|
-
let { unitDescription: t, type: n, secondaryLabelLimit: i = 3, title: a, rowSet: d, multiCardList: f, ...p } = e, { NoContentPlaceholder: m } =
|
|
49
|
+
let { unitDescription: t, type: n, secondaryLabelLimit: i = 3, title: a, rowSet: d, multiCardList: f, ...p } = e, { NoContentPlaceholder: m } = o(), g = l(), { data: O, isLoading: k } = u({ throwOnError: !0 }), A = o(), j = d.rows, M = j.length > 1, N = s({
|
|
50
50
|
ids: [d.tableId],
|
|
51
51
|
type: "ENTITY_HEADER"
|
|
52
52
|
});
|
|
53
|
-
if (k) return /* @__PURE__ */ S("div", { children: [n === "observation_card" && /* @__PURE__ */ x(h, {}), n !== "observation_card" &&
|
|
53
|
+
if (k) return /* @__PURE__ */ S("div", { children: [n === "observation_card" && /* @__PURE__ */ x(h, {}), n !== "observation_card" && c] });
|
|
54
54
|
if (j.length === 0) return /* @__PURE__ */ x(m, {});
|
|
55
55
|
let P = {};
|
|
56
56
|
d.headers.forEach((e, t) => {
|
|
@@ -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: 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,
|
|
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 new 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,MAAU,MACR,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"}
|
|
@@ -33,7 +33,7 @@ function y(y) {
|
|
|
33
33
|
P,
|
|
34
34
|
B,
|
|
35
35
|
L
|
|
36
|
-
].filter((e) =>
|
|
36
|
+
].filter((e) => e != null), G = "Next Step";
|
|
37
37
|
return I && (G = "Registering..."), d(W) ? !j || !b ? /* @__PURE__ */ g(h, {}) : /* @__PURE__ */ g(l, {
|
|
38
38
|
dialogTitle: "Challenge Registration (Step 1 of 2): Terms and Conditions",
|
|
39
39
|
subjectId: j,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeRequirementsModal.js","names":[],"sources":["../../../src/components/ChallengeRequirementsModal/ChallengeRequirementsModal.tsx"],"sourcesContent":["import {\n useGetAccessRequirementsForTeam,\n useGetAccessRequirementStatuses,\n useGetCurrentUserProfile,\n useGetEntity,\n useGetEntityChallenge,\n} from '@/synapse-queries'\nimport {\n useAddMemberToTeam,\n useGetMembershipStatus,\n} from '@/synapse-queries/team/useTeamMembers'\nimport { SynapseClientError, useSynapseContext } from '@/utils'\nimport { Alert, Button, Typography } from '@mui/material'\nimport { RestrictableObjectType } from '@sage-bionetworks/synapse-types'\nimport { isEmpty } from 'lodash-es'\nimport { useCallback } from 'react'\nimport AccessRequirementList from '../AccessRequirementList/AccessRequirementList'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\nexport type ChallengeRequirementsModalProps = {\n open: boolean\n projectId: string\n onCancel: () => void\n onRegisterComplete: () => void\n}\n\n/**\n * The challenge requirements modal will\n * 1. Display the access requirements that must be accepted to join a participant team. The component will guide the user through meeting the requirements.\n * 2. If the user has accepted the requirements, the user can click 'Register' to join the team\n * If the user has not accepted the requirements, the user cannot register for the challenge.\n */\nexport default function ChallengeRequirementsModal(\n props: ChallengeRequirementsModalProps,\n) {\n const { open, projectId, onRegisterComplete, onCancel } = props\n const { data: project, error: getEntityError } = useGetEntity(projectId)\n\n const { isAuthenticated } = useSynapseContext()\n\n const { data: challenge, error: getChallengeError } =\n useGetEntityChallenge(projectId)\n const { data: userProfile, error: getProfileError } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n })\n\n const participantTeamId = challenge?.participantTeamId\n const userId = userProfile?.ownerId\n\n const { data: teamMembershipStatus, error: getMembershipStatusError } =\n useGetMembershipStatus(participantTeamId!, userId!, {\n enabled: Boolean(participantTeamId && userId),\n })\n\n const {\n mutateAsync: addTeamMember,\n isPending: registrationIsPending,\n error: registrationError,\n } = useAddMemberToTeam()\n\n const {\n data: fetchedRequirementsForTeam,\n isSuccess: hasFetchedRequirements,\n error: getAccessRequirementsError,\n } = useGetAccessRequirementsForTeam(challenge?.participantTeamId!, {\n enabled: Boolean(challenge?.participantTeamId),\n })\n\n const requirementStatusesQueryResults = useGetAccessRequirementStatuses(\n fetchedRequirementsForTeam?.map(ar => String(ar.id)) ?? [],\n )\n\n const meetsAllRequirements =\n hasFetchedRequirements &&\n requirementStatusesQueryResults.every(queryResult => {\n return queryResult.status === 'success' && queryResult.data.isApproved\n })\n\n const registerForChallenge = useCallback(async () => {\n if (participantTeamId && userId && !teamMembershipStatus?.isMember) {\n await addTeamMember({\n teamId: participantTeamId,\n userId,\n })\n }\n onRegisterComplete()\n }, [\n addTeamMember,\n onRegisterComplete,\n participantTeamId,\n teamMembershipStatus?.isMember,\n userId,\n ])\n\n const errors = [\n getEntityError,\n getChallengeError,\n getProfileError,\n getMembershipStatusError,\n getAccessRequirementsError,\n registrationError,\n ].filter((e): e is SynapseClientError =>
|
|
1
|
+
{"version":3,"file":"ChallengeRequirementsModal.js","names":[],"sources":["../../../src/components/ChallengeRequirementsModal/ChallengeRequirementsModal.tsx"],"sourcesContent":["import {\n useGetAccessRequirementsForTeam,\n useGetAccessRequirementStatuses,\n useGetCurrentUserProfile,\n useGetEntity,\n useGetEntityChallenge,\n} from '@/synapse-queries'\nimport {\n useAddMemberToTeam,\n useGetMembershipStatus,\n} from '@/synapse-queries/team/useTeamMembers'\nimport { SynapseClientError, useSynapseContext } from '@/utils'\nimport { Alert, Button, Typography } from '@mui/material'\nimport { RestrictableObjectType } from '@sage-bionetworks/synapse-types'\nimport { isEmpty } from 'lodash-es'\nimport { useCallback } from 'react'\nimport AccessRequirementList from '../AccessRequirementList/AccessRequirementList'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\n\nexport type ChallengeRequirementsModalProps = {\n open: boolean\n projectId: string\n onCancel: () => void\n onRegisterComplete: () => void\n}\n\n/**\n * The challenge requirements modal will\n * 1. Display the access requirements that must be accepted to join a participant team. The component will guide the user through meeting the requirements.\n * 2. If the user has accepted the requirements, the user can click 'Register' to join the team\n * If the user has not accepted the requirements, the user cannot register for the challenge.\n */\nexport default function ChallengeRequirementsModal(\n props: ChallengeRequirementsModalProps,\n) {\n const { open, projectId, onRegisterComplete, onCancel } = props\n const { data: project, error: getEntityError } = useGetEntity(projectId)\n\n const { isAuthenticated } = useSynapseContext()\n\n const { data: challenge, error: getChallengeError } =\n useGetEntityChallenge(projectId)\n const { data: userProfile, error: getProfileError } =\n useGetCurrentUserProfile({\n enabled: isAuthenticated,\n })\n\n const participantTeamId = challenge?.participantTeamId\n const userId = userProfile?.ownerId\n\n const { data: teamMembershipStatus, error: getMembershipStatusError } =\n useGetMembershipStatus(participantTeamId!, userId!, {\n enabled: Boolean(participantTeamId && userId),\n })\n\n const {\n mutateAsync: addTeamMember,\n isPending: registrationIsPending,\n error: registrationError,\n } = useAddMemberToTeam()\n\n const {\n data: fetchedRequirementsForTeam,\n isSuccess: hasFetchedRequirements,\n error: getAccessRequirementsError,\n } = useGetAccessRequirementsForTeam(challenge?.participantTeamId!, {\n enabled: Boolean(challenge?.participantTeamId),\n })\n\n const requirementStatusesQueryResults = useGetAccessRequirementStatuses(\n fetchedRequirementsForTeam?.map(ar => String(ar.id)) ?? [],\n )\n\n const meetsAllRequirements =\n hasFetchedRequirements &&\n requirementStatusesQueryResults.every(queryResult => {\n return queryResult.status === 'success' && queryResult.data.isApproved\n })\n\n const registerForChallenge = useCallback(async () => {\n if (participantTeamId && userId && !teamMembershipStatus?.isMember) {\n await addTeamMember({\n teamId: participantTeamId,\n userId,\n })\n }\n onRegisterComplete()\n }, [\n addTeamMember,\n onRegisterComplete,\n participantTeamId,\n teamMembershipStatus?.isMember,\n userId,\n ])\n\n const errors = [\n getEntityError,\n getChallengeError,\n getProfileError,\n getMembershipStatusError,\n getAccessRequirementsError,\n registrationError,\n ].filter((e): e is SynapseClientError => e != null)\n\n // It's possible that the user joined the team, but requirements on the team changed since they became a member\n // They do not need to re-join the team, but they should still be prompted to accept the requirements\n let registerButtonText = 'Next Step'\n if (registrationIsPending) {\n registerButtonText = 'Registering...'\n }\n\n if (!isEmpty(errors)) {\n return (\n <Alert severity=\"error\">\n {errors.map((e, index) => (\n <Typography variant={'body1'} key={index}>\n {e.reason}\n </Typography>\n ))}\n </Alert>\n )\n }\n\n if (!participantTeamId || !open) {\n return <></>\n }\n\n return (\n <AccessRequirementList\n dialogTitle={`Challenge Registration (Step 1 of 2): Terms and Conditions`}\n subjectId={participantTeamId}\n subjectType={RestrictableObjectType.TEAM}\n teamId={challenge?.participantTeamId}\n renderAsModal={true}\n requestObjectName={project?.name}\n onHide={() => {\n onCancel()\n }}\n customDialogActions={\n <>\n <Button variant={'outlined'} onClick={onCancel}>\n Cancel\n </Button>\n <Button\n variant={'contained'}\n onClick={() => {\n registerForChallenge()\n }}\n startIcon={registrationIsPending ? <SynapseSpinner /> : undefined}\n disabled={!meetsAllRequirements || registrationIsPending}\n >\n {registerButtonText}\n </Button>\n </>\n }\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgCA,SAAwB,EACtB,GACA;CACA,IAAM,EAAE,SAAM,cAAW,uBAAoB,gBAAa,GACpD,EAAE,MAAM,GAAS,OAAO,MAAmB,EAAa,CAAS,GAEjE,EAAE,uBAAoB,EAAkB,GAExC,EAAE,MAAM,GAAW,OAAO,MAC9B,EAAsB,CAAS,GAC3B,EAAE,MAAM,GAAa,OAAO,MAChC,EAAyB,EACvB,SAAS,EACX,CAAC,GAEG,IAAoB,GAAW,mBAC/B,IAAS,GAAa,SAEtB,EAAE,MAAM,GAAsB,OAAO,MACzC,EAAuB,GAAoB,GAAS,EAClD,SAAS,GAAQ,KAAqB,GACxC,CAAC,GAEG,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAmB,GAEjB,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAgC,GAAW,mBAAoB,EACjE,SAAS,EAAQ,GAAW,kBAC9B,CAAC,GAEK,IAAkC,EACtC,GAA4B,KAAI,MAAM,OAAO,EAAG,EAAE,CAAC,KAAK,CAAC,CAC3D,GAEM,IACJ,KACA,EAAgC,OAAM,MAC7B,EAAY,WAAW,aAAa,EAAY,KAAK,UAC7D,GAEG,IAAuB,EAAY,YAAY;EAOnD,AANI,KAAqB,KAAU,CAAC,GAAsB,YACxD,MAAM,EAAc;GAClB,QAAQ;GACR;EACF,CAAC,GAEH,EAAmB;CACrB,GAAG;EACD;EACA;EACA;EACA,GAAsB;EACtB;CACF,CAAC,GAEK,IAAS;EACb;EACA;EACA;EACA;EACA;EACA;CACF,EAAE,QAAQ,MAA+B,KAAK,IAAI,GAI9C,IAAqB;CAqBzB,OApBI,MACF,IAAqB,mBAGlB,EAAQ,CAAM,IAYf,CAAC,KAAqB,CAAC,IAClB,kBAAA,GAAA,CAAI,CAAA,IAIX,kBAAC,GAAD;EACE,aAAa;EACb,WAAW;EACX,aAAa,EAAuB;EACpC,QAAQ,GAAW;EACnB,eAAe;EACf,mBAAmB,GAAS;EAC5B,cAAc;GACZ,EAAS;EACX;EACA,qBACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GAAQ,SAAS;GAAY,SAAS;aAAU;EAExC,CAAA,GACR,kBAAC,GAAD;GACE,SAAS;GACT,eAAe;IACb,EAAqB;GACvB;GACA,WAAW,IAAwB,kBAAC,GAAD,CAAiB,CAAA,IAAI,KAAA;GACxD,UAAU,CAAC,KAAwB;aAElC;EACK,CAAA,CACR,EAAA,CAAA;CAEL,CAAA,IA1CC,kBAAC,GAAD;EAAO,UAAS;YACb,EAAO,KAAK,GAAG,MACd,kBAAC,GAAD;GAAY,SAAS;aAClB,EAAE;EACO,GAFuB,CAEvB,CACb;CACI,CAAA;AAsCb"}
|
|
@@ -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,2CA6N1B;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -20,7 +20,7 @@ function y({ entityType: y, projectId: b, pageSize: x = 10 }) {
|
|
|
20
20
|
let n = `Challenge Submission Project-${e.projectId}-${t.id}`;
|
|
21
21
|
return {
|
|
22
22
|
name: n,
|
|
23
|
-
alias: n.
|
|
23
|
+
alias: n.replaceAll(/\s+/g, "_").replaceAll(/-+/g, "_").toLowerCase(),
|
|
24
24
|
concreteType: v,
|
|
25
25
|
description: `This Project was automatically created for Team "${t.name}" for Challenge "${e.id}"`
|
|
26
26
|
};
|
|
@@ -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 (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
|
+
{"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\n .replaceAll(/\\s+/g, '_')\n .replaceAll(/-+/g, '_')\n .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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"}
|
|
@@ -5,7 +5,7 @@ import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
|
5
5
|
import o from "@mui/icons-material/AddCircleTwoTone";
|
|
6
6
|
import { Stack as s } from "@mui/system";
|
|
7
7
|
//#region src/components/ChallengeTeamWizard/SelectChallengeTeam.tsx
|
|
8
|
-
var c = "To participate in a challenge, you need to create a new Team or join an existing one.
|
|
8
|
+
var c = "To participate in a challenge, you need to create a new Team or join an existing one. By default, the participant who creates a team is the \"Team Captain\" and has the ability to invite and remove members. All team members will need a Synapse account so that they can login and accept the team invitation.", l = ({ challengeId: l, onCreateTeam: u, selectedTeamId: d, onSelectTeam: f }) => /* @__PURE__ */ a(s, {
|
|
9
9
|
spacing: 2,
|
|
10
10
|
children: [
|
|
11
11
|
/* @__PURE__ */ i(r, {
|