synapse-react-client 4.0.46 → 4.0.47
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 +6 -6
package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DownloadIneligibleForPackagingFilesFromListButton.js","names":[],"sources":["../../../src/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.tsx"],"sourcesContent":["import { useSynapseContext } from '@/utils'\nimport { implementsExternalFileHandleInterface } from '@/utils/types/IsType'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport {\n Box,\n Button,\n IconButton,\n LinearProgress,\n Paper,\n Typography,\n} from '@mui/material'\nimport Close from '@mui/icons-material/Close'\nimport Download from '@mui/icons-material/Download'\nimport CloudWarning from '@/assets/icons/CloudWarning'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport dayjs from 'dayjs'\nimport duration from 'dayjs/plugin/duration'\nimport relativeTime from 'dayjs/plugin/relativeTime'\nimport {\n BatchFileRequest,\n BatchFileResult,\n ExternalFileHandle,\n FileEntity,\n FileHandleAssociation,\n FileHandleAssociateType,\n} from '@sage-bionetworks/synapse-types'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport {\n useGetAvailableFilesToDownloadInfinite,\n useGetDownloadListStatistics,\n useRemoveFilesFromDownloadList,\n} from '@/synapse-queries/download/useDownloadList'\nimport { getFiles } from '@/synapse-client/SynapseClient'\nimport { useGetEntityQueryOptions } from '@/synapse-queries/entity/useEntity'\n\nimport { deduplicateFileName, getFileName } from './fileNameUtils'\nimport styles from './DownloadIneligibleForPackagingFilesFromListButton.module.scss'\n\n// showDirectoryPicker is not yet available on the Window interface.\ninterface FileSystemAccessWindow extends Window {\n showDirectoryPicker(options?: {\n mode?: 'read' | 'readwrite'\n startIn?:\n | 'desktop'\n | 'documents'\n | 'downloads'\n | 'music'\n | 'pictures'\n | 'videos'\n }): Promise<FileSystemDirectoryHandle>\n}\n\n/**\n * Type guard to check if File System Access API is available\n */\nfunction supportsFileSystemAccess(\n window: Window,\n): window is FileSystemAccessWindow {\n return 'showDirectoryPicker' in window\n}\n\nconst FILE_BATCH_SIZE = 50 // Maximum batch size for fetching presigned URLs\nconst ETA_DELAY_MS = 3000 // Wait this long before showing ETA\n\ndayjs.extend(duration)\ndayjs.extend(relativeTime)\n\nexport type DownloadIneligibleForPackagingFilesFromListButtonProps = {\n buttonText?: string\n variant?: 'text' | 'outlined' | 'contained'\n}\n\n/**\n * Button component that downloads files from the user's download list that are ineligible for packaging.\n * Uses the infinite query hook to fetch all pages of download list items,\n * batches requests to get presigned URLs, and triggers browser downloads.\n */\nexport function DownloadIneligibleForPackagingFilesFromListButton(\n props: DownloadIneligibleForPackagingFilesFromListButtonProps,\n) {\n const { buttonText = 'Start Multi-file Download', variant = 'contained' } =\n props\n const { accessToken, isAuthenticated } = useSynapseContext()\n const queryClient = useQueryClient()\n const getEntityQueryOptions = useGetEntityQueryOptions<FileEntity>()\n const [isDownloading, setIsDownloading] = useState(false)\n const isDownloadingRef = useRef(false)\n const [showExternalFileWarning, setShowExternalFileWarning] = useState(false)\n const isCancelledRef = useRef(false)\n const abortControllerRef = useRef<AbortController | null>(null)\n const [downloadProgress, setDownloadProgress] = useState<{\n currentFile: string\n fileIndex: number\n totalFiles: number\n bytesDownloaded: number\n totalBytes: number\n estimatedSecondsRemaining: number | null\n } | null>(null)\n const fileDownloadStartRef = useRef<number | null>(null)\n\n // Accessibility: tracks the last announced file index and progress bucket so\n // the aria-live region only updates on meaningful changes (not every chunk).\n const [announceText, setAnnounceText] = useState('')\n const lastAnnouncedFileIndexRef = useRef<number>(-1)\n const lastAnnouncedPercentBucketRef = useRef<number>(-1)\n\n useEffect(() => {\n if (!downloadProgress) {\n lastAnnouncedFileIndexRef.current = -1\n lastAnnouncedPercentBucketRef.current = -1\n setAnnounceText('')\n return\n }\n\n const { fileIndex, totalFiles, currentFile, bytesDownloaded, totalBytes } =\n downloadProgress\n\n // Announce when a new file starts downloading\n if (fileIndex !== lastAnnouncedFileIndexRef.current) {\n lastAnnouncedFileIndexRef.current = fileIndex\n lastAnnouncedPercentBucketRef.current = -1\n setAnnounceText(\n `Downloading file ${fileIndex} of ${totalFiles}: ${currentFile}`,\n )\n return\n }\n\n // Announce at each 25% milestone (25, 50, 75, 100) once per file\n if (totalBytes > 0) {\n const percent = Math.floor((bytesDownloaded / totalBytes) * 100)\n const bucket = Math.floor(percent / 25) * 25\n if (bucket > 0 && bucket !== lastAnnouncedPercentBucketRef.current) {\n lastAnnouncedPercentBucketRef.current = bucket\n setAnnounceText(`${bucket}% of ${currentFile} downloaded`)\n }\n }\n }, [downloadProgress])\n\n const { data, status, hasNextPage, fetchNextPage, error } =\n useGetAvailableFilesToDownloadInfinite()\n\n const { mutateAsync: removeFilesFromDownloadList } =\n useRemoveFilesFromDownloadList()\n\n const { refetch: refetchDownloadListStatistics } =\n useGetDownloadListStatistics()\n\n /**\n * Downloads all files from the download list.\n */\n const downloadAllFiles = useCallback(\n async (downloadListItems: typeof data) => {\n // Prevent re-entry if already downloading\n if (isDownloadingRef.current) {\n return\n }\n\n if (!downloadListItems || !isAuthenticated) {\n setIsDownloading(false)\n return\n }\n\n try {\n isDownloadingRef.current = true\n isCancelledRef.current = false\n setShowExternalFileWarning(false)\n const allItems = downloadListItems.pages.flatMap(page => page.page)\n\n // Filter to only include files that are NOT eligible for packaging\n const nonPackageableFiles = allItems.filter(\n item => !item.isEligibleForPackaging,\n )\n\n if (nonPackageableFiles.length === 0) {\n displayToast('No non-packageable files available to download', 'info')\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n\n // Determine if File System Access API is available\n const useFileSystemAccess = supportsFileSystemAccess(window)\n\n // Prompt user to select a directory for downloads BEFORE async operations\n // (must be called during user gesture to avoid SecurityError)\n let directoryHandle: FileSystemDirectoryHandle | undefined\n\n if (useFileSystemAccess) {\n // TypeScript narrowing: we know window has showDirectoryPicker at this point\n const fileSystemWindow = window as unknown as FileSystemAccessWindow\n\n try {\n directoryHandle = await fileSystemWindow.showDirectoryPicker({\n mode: 'readwrite',\n })\n } catch (error) {\n // User cancelled directory picker\n console.error('Failed to select directory:', error)\n displayToast(\n 'Directory selection is required to directly download files from the website.',\n 'warning',\n )\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n } else {\n // Show info message for browsers without File System Access API\n displayToast(\n 'Your browser will download files individually to your default downloads folder. Each file may trigger a separate download prompt.',\n 'info',\n )\n }\n\n // Initialize progress tracking\n fileDownloadStartRef.current = null\n setDownloadProgress({\n currentFile: '',\n fileIndex: 0,\n totalFiles: nonPackageableFiles.length,\n bytesDownloaded: 0,\n totalBytes: 0,\n estimatedSecondsRemaining: null,\n })\n\n // Fetch entities to get dataFileHandleId for each file\n // Use React Query's ensureQueryData to leverage cache and built-in retry logic (handles 429s with exponential backoff)\n // Map key combines entity ID and version to handle multiple versions of the same entity\n const entityIdToFileHandleId = new Map<string, string>()\n\n // Fetch all entities in parallel - React Query handles concurrency and retries\n const entityPromises = nonPackageableFiles.map(async item => {\n if (isCancelledRef.current) {\n return\n }\n\n try {\n const entity = await queryClient.ensureQueryData(\n getEntityQueryOptions(\n item.fileEntityId,\n item.versionNumber?.toString(),\n ),\n )\n // Use composite key: entityId-version (or entityId if no version)\n const mapKey = `${entity.id!}-${item.versionNumber ?? 'latest'}`\n entityIdToFileHandleId.set(mapKey, entity.dataFileHandleId)\n } catch (error) {\n console.error(`Failed to fetch entity ${item.fileEntityId}:`, error)\n // Continue even if one entity fails\n }\n })\n\n await Promise.all(entityPromises)\n\n // Convert download list items to file handle associations using the fetched dataFileHandleIds\n const fileHandleAssociations: FileHandleAssociation[] =\n nonPackageableFiles\n .filter(item => {\n const mapKey = `${item.fileEntityId}-${\n item.versionNumber ?? 'latest'\n }`\n return entityIdToFileHandleId.has(mapKey)\n })\n .map(item => {\n const mapKey = `${item.fileEntityId}-${\n item.versionNumber ?? 'latest'\n }`\n return {\n fileHandleId: entityIdToFileHandleId.get(mapKey)!,\n associateObjectId: item.fileEntityId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }\n })\n\n if (fileHandleAssociations.length === 0) {\n displayToast(\n 'Failed to fetch file information for download',\n 'danger',\n )\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n\n // Split into batches to avoid overwhelming the API\n const batches: FileHandleAssociation[][] = []\n for (\n let i = 0;\n i < fileHandleAssociations.length;\n i += FILE_BATCH_SIZE\n ) {\n batches.push(fileHandleAssociations.slice(i, i + FILE_BATCH_SIZE))\n }\n\n let downloadedCount = 0\n let failedCount = 0\n const successfullyDownloadedItems: typeof nonPackageableFiles = []\n\n // Track used filenames to prevent collisions\n const usedFilenames = new Map<string, number>()\n\n /**\n * Helper function to download file using traditional anchor tag method\n * @returns boolean indicating if the download was successful\n */\n const downloadFileTraditional = async (\n downloadUrl: string,\n fileName: string,\n ): Promise<boolean> => {\n try {\n const response = await fetch(downloadUrl)\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n\n const blob = await response.blob()\n const blobUrl = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = blobUrl\n anchor.download = fileName\n anchor.style.display = 'none'\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n\n // Clean up blob URL after a delay to ensure download initiation\n setTimeout(() => URL.revokeObjectURL(blobUrl), 1000)\n\n return true\n } catch (error) {\n console.error(`Failed to download file ${fileName}:`, error)\n // Fallback to window.open method\n try {\n window.open(downloadUrl, '_blank', 'noopener,noreferrer')\n return true\n } catch (fallbackError) {\n console.error(`Fallback window.open also failed:`, fallbackError)\n return false\n }\n }\n }\n\n /**\n * Helper function to process a single file download\n * @returns boolean indicating if download is successful\n */\n const processFileDownload = async (\n fileResult: BatchFileResult['requestedFiles'][0],\n originalItem: (typeof nonPackageableFiles)[0] | undefined,\n ): Promise<boolean> => {\n try {\n let downloadUrl: string | undefined\n\n // Check if this is an external file handle\n if (\n fileResult.fileHandle &&\n implementsExternalFileHandleInterface(fileResult.fileHandle)\n ) {\n // For external file handles, use the externalURL\n downloadUrl = (fileResult.fileHandle as ExternalFileHandle)\n .externalURL\n setShowExternalFileWarning(true)\n } else if (fileResult.preSignedURL) {\n // For other file types, use the presigned URL\n downloadUrl = fileResult.preSignedURL\n }\n\n if (!downloadUrl) {\n return false\n }\n\n // Get filename from file result or create a default name\n const baseFileName = getFileName(fileResult, originalItem)\n\n // Handle filename collisions by adding a counter suffix\n const fileName = deduplicateFileName(baseFileName, usedFilenames)\n\n // Update progress with current file info\n const currentFileIndex = downloadedCount + 1\n fileDownloadStartRef.current = null\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n currentFile: fileName,\n fileIndex: currentFileIndex,\n bytesDownloaded: 0,\n totalBytes: 0,\n estimatedSecondsRemaining: null,\n }\n : null,\n )\n\n // Use traditional download method for unsupported browsers\n if (!useFileSystemAccess) {\n const success = await downloadFileTraditional(\n downloadUrl,\n fileName,\n )\n if (success) {\n downloadedCount = currentFileIndex\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n }\n return success\n }\n\n // Use File System Access API for supported browsers\n if (!directoryHandle) {\n return false\n }\n\n try {\n // Fetch the file\n abortControllerRef.current = new AbortController()\n const response = await fetch(downloadUrl, {\n signal: abortControllerRef.current.signal,\n })\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n\n // Get total file size from headers\n const contentLength = response.headers.get('content-length')\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0\n\n // Update progress with file size\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n bytesDownloaded: 0,\n totalBytes,\n }\n : null,\n )\n\n // Create file handle in selected directory\n const fileHandle = await directoryHandle.getFileHandle(fileName, {\n create: true,\n })\n const writableStream = await fileHandle.createWritable()\n\n // Stream the response body to the file with progress tracking\n if (response.body) {\n const reader = response.body.getReader()\n let bytesReceived = 0\n let streamAborted = false\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n bytesReceived += value.length\n await writableStream.write(value)\n\n // Check for cancellation on every chunk\n if (isCancelledRef.current) {\n streamAborted = true\n reader.cancel()\n await writableStream.abort()\n break\n }\n\n if (fileDownloadStartRef.current === null) {\n fileDownloadStartRef.current = Date.now()\n }\n const elapsedMs = Date.now() - fileDownloadStartRef.current\n let estimatedSecondsRemaining: number | null = null\n if (\n elapsedMs > ETA_DELAY_MS &&\n bytesReceived > 0 &&\n totalBytes > 0\n ) {\n const rate = bytesReceived / elapsedMs\n estimatedSecondsRemaining = Math.max(\n 0,\n (totalBytes - bytesReceived) / rate / 1000,\n )\n }\n\n // Update progress\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n bytesDownloaded: bytesReceived,\n ...(elapsedMs > ETA_DELAY_MS && {\n estimatedSecondsRemaining,\n }),\n }\n : null,\n )\n }\n } catch (streamError) {\n if (!streamAborted) {\n await writableStream.abort()\n streamAborted = true\n }\n throw streamError\n } finally {\n if (!streamAborted) {\n await writableStream.close()\n }\n }\n\n // If cancelled mid-stream, return false without falling through to success path\n if (isCancelledRef.current) {\n return false\n }\n } else {\n // Fallback if streaming not supported\n try {\n const blob = await response.blob()\n await writableStream.write(blob)\n } finally {\n await writableStream.close()\n }\n }\n\n downloadedCount = currentFileIndex\n\n // Track successfully downloaded item for batch removal\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n return true\n } catch (fetchError) {\n // If the fetch was aborted due to cancellation, do not fall back\n if (\n isCancelledRef.current ||\n (fetchError instanceof DOMException &&\n fetchError.name === 'AbortError')\n ) {\n return false\n }\n console.error(\n `Failed to fetch/write file ${fileResult.fileHandleId}:`,\n fetchError,\n )\n // Fallback to window.open if File System Access API fails\n try {\n downloadFileTraditional(downloadUrl, fileName)\n downloadedCount = currentFileIndex\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n return true\n } catch (fallbackError) {\n console.error(\n `Fallback downloadFileTraditional also failed for ${fileResult.fileHandleId}:`,\n fallbackError,\n )\n return false\n }\n }\n } catch (error) {\n console.error(\n `Failed to download file ${fileResult.fileHandleId}:`,\n error,\n )\n return false\n }\n }\n\n /**\n * Fallback function to fetch files individually when batch fails\n */\n const fetchIndividually = async (\n batch: FileHandleAssociation[],\n ): Promise<void> => {\n console.info(\n `Attempting to fetch ${batch.length} files individually after batch failure`,\n )\n\n for (const fileHandleAssociation of batch) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info('Individual file fetch cancelled by user')\n break\n }\n\n const singleBatch = [fileHandleAssociation]\n try {\n const batchRequest: BatchFileRequest = {\n requestedFiles: singleBatch,\n includeFileHandles: true,\n includePreSignedURLs: true,\n includePreviewPreSignedURLs: false,\n }\n\n const batchResult = await getFiles(batchRequest, accessToken)\n\n if (batchResult.requestedFiles.length > 0) {\n const fileResult = batchResult.requestedFiles[0]\n const originalItem = nonPackageableFiles.find(\n item =>\n item.fileEntityId ===\n fileHandleAssociation.associateObjectId,\n )\n\n const success = await processFileDownload(\n fileResult,\n originalItem,\n )\n if (!success) {\n failedCount++\n }\n } else {\n failedCount++\n }\n } catch (error) {\n console.error(\n `Failed to fetch individual file ${fileHandleAssociation.fileHandleId}:`,\n error,\n )\n failedCount++\n }\n }\n }\n\n // Process each batch\n for (const batch of batches) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info('Download cancelled by user')\n break\n }\n\n // Try to fetch the entire batch (getFiles has built-in retry logic)\n let batchResult: BatchFileResult | null = null\n try {\n const batchRequest: BatchFileRequest = {\n requestedFiles: batch,\n includeFileHandles: true,\n includePreSignedURLs: true,\n includePreviewPreSignedURLs: false,\n }\n batchResult = await getFiles(batchRequest, accessToken)\n } catch (error) {\n console.error('Failed to fetch batch:', error)\n }\n\n if (batchResult) {\n // Batch fetch succeeded, process all files\n for (let i = 0; i < batchResult.requestedFiles.length; i++) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info(\n 'Download cancelled by user during batch processing',\n )\n break\n }\n\n const fileResult = batchResult.requestedFiles[i]\n const originalItem = nonPackageableFiles.find(\n item => item.fileEntityId === batch[i].associateObjectId,\n )\n\n const success = await processFileDownload(\n fileResult,\n originalItem,\n )\n if (!success) {\n failedCount++\n }\n }\n } else {\n // Batch fetch failed after retries, try fetching files individually\n await fetchIndividually(batch)\n }\n }\n\n // Remove all successfully downloaded files from the download list in one batch\n if (successfullyDownloadedItems.length > 0) {\n await removeFilesFromDownloadList({\n batchToRemove: successfullyDownloadedItems.map(\n (item: (typeof nonPackageableFiles)[0]) => ({\n fileEntityId: item.fileEntityId,\n versionNumber: item.versionNumber,\n }),\n ),\n })\n // Refetch statistics after removing files\n await refetchDownloadListStatistics()\n // Scroll to top of page to show updated statistics\n window.scrollTo({ top: 0, behavior: 'smooth' })\n }\n\n // Show completion message\n if (isCancelledRef.current) {\n displayToast(\n `Download cancelled. ${downloadedCount} file${\n downloadedCount !== 1 ? 's were' : ' was'\n } downloaded before cancellation.`,\n 'info',\n )\n } else if (downloadedCount > 0) {\n displayToast(\n `Download started for ${downloadedCount} file${\n downloadedCount !== 1 ? 's' : ''\n }${\n failedCount > 0\n ? `. ${failedCount} file${failedCount !== 1 ? 's' : ''} failed.`\n : '.'\n }`,\n failedCount > 0 ? 'warning' : 'success',\n )\n } else {\n displayToast('No files could be downloaded', 'warning')\n }\n } catch (error) {\n console.error('Error downloading files:', error)\n const message =\n (error as SynapseClientError | undefined)?.reason ??\n (error instanceof Error ? error.message : undefined) ??\n 'An error occurred while downloading files'\n displayToast(message, 'danger')\n } finally {\n setDownloadProgress(null)\n setIsDownloading(false)\n isDownloadingRef.current = false\n }\n },\n [\n accessToken,\n isAuthenticated,\n queryClient,\n getEntityQueryOptions,\n removeFilesFromDownloadList,\n refetchDownloadListStatistics,\n ],\n )\n\n const handleClick = useCallback(async () => {\n if (isDownloading) {\n return\n }\n setIsDownloading(true)\n\n // Fetch all remaining pages imperatively, then download\n try {\n let stillHasNextPage = hasNextPage\n let latestData = data\n while (stillHasNextPage && fetchNextPage) {\n const result = await fetchNextPage()\n stillHasNextPage = result.hasNextPage\n if (result.data) {\n latestData = result.data\n }\n }\n\n // All pages loaded, now download\n if (status === 'success' && latestData) {\n void downloadAllFiles(latestData)\n } else {\n // Failed to load data\n setIsDownloading(false)\n isDownloadingRef.current = false\n displayToast(\n 'Failed to load download list. Please try again.',\n 'danger',\n )\n }\n } catch (error) {\n console.error('Error downloading files:', error)\n setIsDownloading(false)\n isDownloadingRef.current = false\n const message =\n (error as SynapseClientError | undefined)?.reason ??\n (error instanceof Error ? error.message : undefined) ??\n 'An error occurred while preparing files for download'\n displayToast(message, 'danger')\n }\n }, [\n isDownloading,\n hasNextPage,\n fetchNextPage,\n status,\n data,\n downloadAllFiles,\n ])\n\n const handleCancel = useCallback(() => {\n isCancelledRef.current = true\n abortControllerRef.current?.abort()\n setDownloadProgress(null)\n setIsDownloading(false)\n isDownloadingRef.current = false\n }, [])\n\n if (error) {\n return null\n }\n\n return (\n <>\n {/* Visually-hidden live region — announces file start and progress milestones to screen readers */}\n <span\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={styles.visuallyHidden}\n >\n {announceText}\n </span>\n {!!downloadProgress && showExternalFileWarning && (\n <Paper\n elevation={8}\n className={styles.externalWarningPanel}\n sx={{ zIndex: theme => theme.zIndex.modal }}\n role=\"region\"\n aria-label=\"External file warning\"\n >\n <CloudWarning className={styles.warningIcon} />\n <Box className={styles.warningTextContainer}>\n <Typography className={styles.warningTitleText}>\n Some of your files are hosted externally.\n </Typography>\n <Typography className={styles.progressFileNameText}>\n Downloads may be slower than expected\n </Typography>\n </Box>\n <IconButton\n onClick={() => setShowExternalFileWarning(false)}\n size=\"small\"\n className={styles.warningCloseButton}\n aria-label=\"Dismiss external file warning\"\n >\n <Close />\n </IconButton>\n </Paper>\n )}\n {!!downloadProgress && (\n <Paper\n elevation={8}\n className={styles.progressPanel}\n sx={{ zIndex: theme => theme.zIndex.modal }}\n role=\"region\"\n aria-label=\"Download progress\"\n >\n <Typography className={styles.progressTitleText}>\n Downloading file {downloadProgress.fileIndex} of{' '}\n {downloadProgress.totalFiles}\n </Typography>\n <Typography className={styles.progressFileNameText}>\n {downloadProgress.currentFile}\n </Typography>\n <Box className={styles.progressFooter}>\n <Box className={styles.progressBarContainer}>\n <Box className={styles.progressStats}>\n <Typography className={styles.progressStatsText}>\n {downloadProgress.totalBytes > 0\n ? `${Math.round(\n (downloadProgress.bytesDownloaded /\n downloadProgress.totalBytes) *\n 100,\n )}% ( ${calculateFriendlyFileSize(\n downloadProgress.bytesDownloaded,\n )} / ${calculateFriendlyFileSize(\n downloadProgress.totalBytes,\n )} )`\n : ''}\n </Typography>\n <Typography className={styles.progressStatsText}>\n {downloadProgress.estimatedSecondsRemaining !== null\n ? `About ${dayjs\n .duration({\n seconds: downloadProgress.estimatedSecondsRemaining,\n })\n .humanize()} remaining`\n : ''}\n </Typography>\n </Box>\n <LinearProgress\n variant={\n downloadProgress.totalBytes > 0\n ? 'determinate'\n : 'indeterminate'\n }\n value={\n downloadProgress.totalBytes > 0\n ? (downloadProgress.bytesDownloaded /\n downloadProgress.totalBytes) *\n 100\n : undefined\n }\n aria-label=\"Download progress\"\n className={styles.progressBar}\n />\n </Box>\n <Box className={styles.cancelButtonContainer}>\n <Button\n variant=\"outlined\"\n onClick={handleCancel}\n className={styles.cancelButton}\n >\n Cancel\n </Button>\n </Box>\n </Box>\n </Paper>\n )}\n <Button\n variant={variant}\n onClick={() => {\n void handleClick()\n }}\n loading={isDownloading}\n startIcon={<Download />}\n >\n {buttonText}\n </Button>\n </>\n )\n}\n\nexport default DownloadIneligibleForPackagingFilesFromListButton\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DownloadIneligibleForPackagingFilesFromListButton.js","names":[],"sources":["../../../src/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.tsx"],"sourcesContent":["import { useSynapseContext } from '@/utils'\nimport { implementsExternalFileHandleInterface } from '@/utils/types/IsType'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport {\n Box,\n Button,\n IconButton,\n LinearProgress,\n Paper,\n Typography,\n} from '@mui/material'\nimport Close from '@mui/icons-material/Close'\nimport Download from '@mui/icons-material/Download'\nimport CloudWarning from '@/assets/icons/CloudWarning'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport dayjs from 'dayjs'\nimport duration from 'dayjs/plugin/duration'\nimport relativeTime from 'dayjs/plugin/relativeTime'\nimport {\n BatchFileRequest,\n BatchFileResult,\n ExternalFileHandle,\n FileEntity,\n FileHandleAssociation,\n FileHandleAssociateType,\n} from '@sage-bionetworks/synapse-types'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport {\n useGetAvailableFilesToDownloadInfinite,\n useGetDownloadListStatistics,\n useRemoveFilesFromDownloadList,\n} from '@/synapse-queries/download/useDownloadList'\nimport { getFiles } from '@/synapse-client/SynapseClient'\nimport { useGetEntityQueryOptions } from '@/synapse-queries/entity/useEntity'\n\nimport { deduplicateFileName, getFileName } from './fileNameUtils'\nimport styles from './DownloadIneligibleForPackagingFilesFromListButton.module.scss'\n\n// showDirectoryPicker is not yet available on the Window interface.\ninterface FileSystemAccessWindow extends Window {\n showDirectoryPicker(options?: {\n mode?: 'read' | 'readwrite'\n startIn?:\n | 'desktop'\n | 'documents'\n | 'downloads'\n | 'music'\n | 'pictures'\n | 'videos'\n }): Promise<FileSystemDirectoryHandle>\n}\n\n/**\n * Type guard to check if File System Access API is available\n */\nfunction supportsFileSystemAccess(\n window: Window,\n): window is FileSystemAccessWindow {\n return 'showDirectoryPicker' in window\n}\n\nconst FILE_BATCH_SIZE = 50 // Maximum batch size for fetching presigned URLs\nconst ETA_DELAY_MS = 3000 // Wait this long before showing ETA\n\ndayjs.extend(duration)\ndayjs.extend(relativeTime)\n\nexport type DownloadIneligibleForPackagingFilesFromListButtonProps = {\n buttonText?: string\n variant?: 'text' | 'outlined' | 'contained'\n}\n\n/**\n * Button component that downloads files from the user's download list that are ineligible for packaging.\n * Uses the infinite query hook to fetch all pages of download list items,\n * batches requests to get presigned URLs, and triggers browser downloads.\n */\nexport function DownloadIneligibleForPackagingFilesFromListButton(\n props: DownloadIneligibleForPackagingFilesFromListButtonProps,\n) {\n const { buttonText = 'Start Multi-file Download', variant = 'contained' } =\n props\n const { accessToken, isAuthenticated } = useSynapseContext()\n const queryClient = useQueryClient()\n const getEntityQueryOptions = useGetEntityQueryOptions<FileEntity>()\n const [isDownloading, setIsDownloading] = useState(false)\n const isDownloadingRef = useRef(false)\n const [showExternalFileWarning, setShowExternalFileWarning] = useState(false)\n const isCancelledRef = useRef(false)\n const abortControllerRef = useRef<AbortController | null>(null)\n const [downloadProgress, setDownloadProgress] = useState<{\n currentFile: string\n fileIndex: number\n totalFiles: number\n bytesDownloaded: number\n totalBytes: number\n estimatedSecondsRemaining: number | null\n } | null>(null)\n const fileDownloadStartRef = useRef<number | null>(null)\n\n // Accessibility: tracks the last announced file index and progress bucket so\n // the aria-live region only updates on meaningful changes (not every chunk).\n const [announceText, setAnnounceText] = useState('')\n const lastAnnouncedFileIndexRef = useRef<number>(-1)\n const lastAnnouncedPercentBucketRef = useRef<number>(-1)\n\n useEffect(() => {\n if (!downloadProgress) {\n lastAnnouncedFileIndexRef.current = -1\n lastAnnouncedPercentBucketRef.current = -1\n setAnnounceText('')\n return\n }\n\n const { fileIndex, totalFiles, currentFile, bytesDownloaded, totalBytes } =\n downloadProgress\n\n // Announce when a new file starts downloading\n if (fileIndex !== lastAnnouncedFileIndexRef.current) {\n lastAnnouncedFileIndexRef.current = fileIndex\n lastAnnouncedPercentBucketRef.current = -1\n setAnnounceText(\n `Downloading file ${fileIndex} of ${totalFiles}: ${currentFile}`,\n )\n return\n }\n\n // Announce at each 25% milestone (25, 50, 75, 100) once per file\n if (totalBytes > 0) {\n const percent = Math.floor((bytesDownloaded / totalBytes) * 100)\n const bucket = Math.floor(percent / 25) * 25\n if (bucket > 0 && bucket !== lastAnnouncedPercentBucketRef.current) {\n lastAnnouncedPercentBucketRef.current = bucket\n setAnnounceText(`${bucket}% of ${currentFile} downloaded`)\n }\n }\n }, [downloadProgress])\n\n const { data, status, hasNextPage, fetchNextPage, error } =\n useGetAvailableFilesToDownloadInfinite()\n\n const { mutateAsync: removeFilesFromDownloadList } =\n useRemoveFilesFromDownloadList()\n\n const { refetch: refetchDownloadListStatistics } =\n useGetDownloadListStatistics()\n\n /**\n * Downloads all files from the download list.\n */\n const downloadAllFiles = useCallback(\n async (downloadListItems: typeof data) => {\n // Prevent re-entry if already downloading\n if (isDownloadingRef.current) {\n return\n }\n\n if (!downloadListItems || !isAuthenticated) {\n setIsDownloading(false)\n return\n }\n\n try {\n isDownloadingRef.current = true\n isCancelledRef.current = false\n setShowExternalFileWarning(false)\n const allItems = downloadListItems.pages.flatMap(page => page.page)\n\n // Filter to only include files that are NOT eligible for packaging\n const nonPackageableFiles = allItems.filter(\n item => !item.isEligibleForPackaging,\n )\n\n if (nonPackageableFiles.length === 0) {\n displayToast('No non-packageable files available to download', 'info')\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n\n // Determine if File System Access API is available\n const useFileSystemAccess = supportsFileSystemAccess(window)\n\n // Prompt user to select a directory for downloads BEFORE async operations\n // (must be called during user gesture to avoid SecurityError)\n let directoryHandle: FileSystemDirectoryHandle | undefined\n\n if (useFileSystemAccess) {\n // TypeScript narrowing: we know window has showDirectoryPicker at this point\n const fileSystemWindow = window as unknown as FileSystemAccessWindow\n\n try {\n directoryHandle = await fileSystemWindow.showDirectoryPicker({\n mode: 'readwrite',\n })\n } catch (error) {\n // User cancelled directory picker\n console.error('Failed to select directory:', error)\n displayToast(\n 'Directory selection is required to directly download files from the website.',\n 'warning',\n )\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n } else {\n // Show info message for browsers without File System Access API\n displayToast(\n 'Your browser will download files individually to your default downloads folder. Each file may trigger a separate download prompt.',\n 'info',\n )\n }\n\n // Initialize progress tracking\n fileDownloadStartRef.current = null\n setDownloadProgress({\n currentFile: '',\n fileIndex: 0,\n totalFiles: nonPackageableFiles.length,\n bytesDownloaded: 0,\n totalBytes: 0,\n estimatedSecondsRemaining: null,\n })\n\n // Fetch entities to get dataFileHandleId for each file\n // Use React Query's ensureQueryData to leverage cache and built-in retry logic (handles 429s with exponential backoff)\n // Map key combines entity ID and version to handle multiple versions of the same entity\n const entityIdToFileHandleId = new Map<string, string>()\n\n // Fetch all entities in parallel - React Query handles concurrency and retries\n const entityPromises = nonPackageableFiles.map(async item => {\n if (isCancelledRef.current) {\n return\n }\n\n try {\n const entity = await queryClient.ensureQueryData(\n getEntityQueryOptions(\n item.fileEntityId,\n item.versionNumber?.toString(),\n ),\n )\n // Use composite key: entityId-version (or entityId if no version)\n const mapKey = `${entity.id!}-${item.versionNumber ?? 'latest'}`\n entityIdToFileHandleId.set(mapKey, entity.dataFileHandleId)\n } catch (error) {\n console.error(`Failed to fetch entity ${item.fileEntityId}:`, error)\n // Continue even if one entity fails\n }\n })\n\n await Promise.all(entityPromises)\n\n // Convert download list items to file handle associations using the fetched dataFileHandleIds\n const fileHandleAssociations: FileHandleAssociation[] =\n nonPackageableFiles\n .filter(item => {\n const mapKey = `${item.fileEntityId}-${\n item.versionNumber ?? 'latest'\n }`\n return entityIdToFileHandleId.has(mapKey)\n })\n .map(item => {\n const mapKey = `${item.fileEntityId}-${\n item.versionNumber ?? 'latest'\n }`\n return {\n fileHandleId: entityIdToFileHandleId.get(mapKey)!,\n associateObjectId: item.fileEntityId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }\n })\n\n if (fileHandleAssociations.length === 0) {\n displayToast(\n 'Failed to fetch file information for download',\n 'danger',\n )\n setIsDownloading(false)\n isDownloadingRef.current = false\n return\n }\n\n // Split into batches to avoid overwhelming the API\n const batches: FileHandleAssociation[][] = []\n for (\n let i = 0;\n i < fileHandleAssociations.length;\n i += FILE_BATCH_SIZE\n ) {\n batches.push(fileHandleAssociations.slice(i, i + FILE_BATCH_SIZE))\n }\n\n let downloadedCount = 0\n let failedCount = 0\n const successfullyDownloadedItems: typeof nonPackageableFiles = []\n\n // Track used filenames to prevent collisions\n const usedFilenames = new Map<string, number>()\n\n /**\n * Helper function to download file using traditional anchor tag method\n * @returns boolean indicating if the download was successful\n */\n const downloadFileTraditional = async (\n downloadUrl: string,\n fileName: string,\n ): Promise<boolean> => {\n try {\n const response = await fetch(downloadUrl)\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n\n const blob = await response.blob()\n const blobUrl = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = blobUrl\n anchor.download = fileName\n anchor.style.display = 'none'\n document.body.appendChild(anchor)\n anchor.click()\n anchor.remove()\n\n // Clean up blob URL after a delay to ensure download initiation\n setTimeout(() => URL.revokeObjectURL(blobUrl), 1000)\n\n return true\n } catch (error) {\n console.error(`Failed to download file ${fileName}:`, error)\n // Fallback to window.open method\n try {\n window.open(downloadUrl, '_blank', 'noopener,noreferrer')\n return true\n } catch (fallbackError) {\n console.error(`Fallback window.open also failed:`, fallbackError)\n return false\n }\n }\n }\n\n /**\n * Helper function to process a single file download\n * @returns boolean indicating if download is successful\n */\n const processFileDownload = async (\n fileResult: BatchFileResult['requestedFiles'][0],\n originalItem: (typeof nonPackageableFiles)[0] | undefined,\n ): Promise<boolean> => {\n try {\n let downloadUrl: string | undefined\n\n // Check if this is an external file handle\n if (\n fileResult.fileHandle &&\n implementsExternalFileHandleInterface(fileResult.fileHandle)\n ) {\n // For external file handles, use the externalURL\n downloadUrl = (fileResult.fileHandle as ExternalFileHandle)\n .externalURL\n setShowExternalFileWarning(true)\n } else if (fileResult.preSignedURL) {\n // For other file types, use the presigned URL\n downloadUrl = fileResult.preSignedURL\n }\n\n if (!downloadUrl) {\n return false\n }\n\n // Get filename from file result or create a default name\n const baseFileName = getFileName(fileResult, originalItem)\n\n // Handle filename collisions by adding a counter suffix\n const fileName = deduplicateFileName(baseFileName, usedFilenames)\n\n // Update progress with current file info\n const currentFileIndex = downloadedCount + 1\n fileDownloadStartRef.current = null\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n currentFile: fileName,\n fileIndex: currentFileIndex,\n bytesDownloaded: 0,\n totalBytes: 0,\n estimatedSecondsRemaining: null,\n }\n : null,\n )\n\n // Use traditional download method for unsupported browsers\n if (!useFileSystemAccess) {\n const success = await downloadFileTraditional(\n downloadUrl,\n fileName,\n )\n if (success) {\n downloadedCount = currentFileIndex\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n }\n return success\n }\n\n // Use File System Access API for supported browsers\n if (!directoryHandle) {\n return false\n }\n\n try {\n // Fetch the file\n abortControllerRef.current = new AbortController()\n const response = await fetch(downloadUrl, {\n signal: abortControllerRef.current.signal,\n })\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`)\n }\n\n // Get total file size from headers\n const contentLength = response.headers.get('content-length')\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0\n\n // Update progress with file size\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n bytesDownloaded: 0,\n totalBytes,\n }\n : null,\n )\n\n // Create file handle in selected directory\n const fileHandle = await directoryHandle.getFileHandle(fileName, {\n create: true,\n })\n const writableStream = await fileHandle.createWritable()\n\n // Stream the response body to the file with progress tracking\n if (response.body) {\n const reader = response.body.getReader()\n let bytesReceived = 0\n let streamAborted = false\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n bytesReceived += value.length\n await writableStream.write(value)\n\n // Check for cancellation on every chunk\n if (isCancelledRef.current) {\n streamAborted = true\n reader.cancel()\n await writableStream.abort()\n break\n }\n\n if (fileDownloadStartRef.current === null) {\n fileDownloadStartRef.current = Date.now()\n }\n const elapsedMs = Date.now() - fileDownloadStartRef.current\n let estimatedSecondsRemaining: number | null = null\n if (\n elapsedMs > ETA_DELAY_MS &&\n bytesReceived > 0 &&\n totalBytes > 0\n ) {\n const rate = bytesReceived / elapsedMs\n estimatedSecondsRemaining = Math.max(\n 0,\n (totalBytes - bytesReceived) / rate / 1000,\n )\n }\n\n // Update progress\n setDownloadProgress(prev =>\n prev\n ? {\n ...prev,\n bytesDownloaded: bytesReceived,\n ...(elapsedMs > ETA_DELAY_MS && {\n estimatedSecondsRemaining,\n }),\n }\n : null,\n )\n }\n } catch (streamError) {\n if (!streamAborted) {\n await writableStream.abort()\n streamAborted = true\n }\n throw streamError\n } finally {\n if (!streamAborted) {\n await writableStream.close()\n }\n }\n\n // If cancelled mid-stream, return false without falling through to success path\n if (isCancelledRef.current) {\n return false\n }\n } else {\n // Fallback if streaming not supported\n try {\n const blob = await response.blob()\n await writableStream.write(blob)\n } finally {\n await writableStream.close()\n }\n }\n\n downloadedCount = currentFileIndex\n\n // Track successfully downloaded item for batch removal\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n return true\n } catch (fetchError) {\n // If the fetch was aborted due to cancellation, do not fall back\n if (\n isCancelledRef.current ||\n (fetchError instanceof DOMException &&\n fetchError.name === 'AbortError')\n ) {\n return false\n }\n console.error(\n `Failed to fetch/write file ${fileResult.fileHandleId}:`,\n fetchError,\n )\n // Fallback to window.open if File System Access API fails\n try {\n downloadFileTraditional(downloadUrl, fileName)\n downloadedCount = currentFileIndex\n if (originalItem) {\n successfullyDownloadedItems.push(originalItem)\n }\n return true\n } catch (fallbackError) {\n console.error(\n `Fallback downloadFileTraditional also failed for ${fileResult.fileHandleId}:`,\n fallbackError,\n )\n return false\n }\n }\n } catch (error) {\n console.error(\n `Failed to download file ${fileResult.fileHandleId}:`,\n error,\n )\n return false\n }\n }\n\n /**\n * Fallback function to fetch files individually when batch fails\n */\n const fetchIndividually = async (\n batch: FileHandleAssociation[],\n ): Promise<void> => {\n console.info(\n `Attempting to fetch ${batch.length} files individually after batch failure`,\n )\n\n for (const fileHandleAssociation of batch) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info('Individual file fetch cancelled by user')\n break\n }\n\n const singleBatch = [fileHandleAssociation]\n try {\n const batchRequest: BatchFileRequest = {\n requestedFiles: singleBatch,\n includeFileHandles: true,\n includePreSignedURLs: true,\n includePreviewPreSignedURLs: false,\n }\n\n const batchResult = await getFiles(batchRequest, accessToken)\n\n if (batchResult.requestedFiles.length > 0) {\n const fileResult = batchResult.requestedFiles[0]\n const originalItem = nonPackageableFiles.find(\n item =>\n item.fileEntityId ===\n fileHandleAssociation.associateObjectId,\n )\n\n const success = await processFileDownload(\n fileResult,\n originalItem,\n )\n if (!success) {\n failedCount++\n }\n } else {\n failedCount++\n }\n } catch (error) {\n console.error(\n `Failed to fetch individual file ${fileHandleAssociation.fileHandleId}:`,\n error,\n )\n failedCount++\n }\n }\n }\n\n // Process each batch\n for (const batch of batches) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info('Download cancelled by user')\n break\n }\n\n // Try to fetch the entire batch (getFiles has built-in retry logic)\n let batchResult: BatchFileResult | null = null\n try {\n const batchRequest: BatchFileRequest = {\n requestedFiles: batch,\n includeFileHandles: true,\n includePreSignedURLs: true,\n includePreviewPreSignedURLs: false,\n }\n batchResult = await getFiles(batchRequest, accessToken)\n } catch (error) {\n console.error('Failed to fetch batch:', error)\n }\n\n if (batchResult) {\n // Batch fetch succeeded, process all files\n for (let i = 0; i < batchResult.requestedFiles.length; i++) {\n // Check if user cancelled the operation\n if (isCancelledRef.current) {\n console.info(\n 'Download cancelled by user during batch processing',\n )\n break\n }\n\n const fileResult = batchResult.requestedFiles[i]\n const originalItem = nonPackageableFiles.find(\n item => item.fileEntityId === batch[i].associateObjectId,\n )\n\n const success = await processFileDownload(\n fileResult,\n originalItem,\n )\n if (!success) {\n failedCount++\n }\n }\n } else {\n // Batch fetch failed after retries, try fetching files individually\n await fetchIndividually(batch)\n }\n }\n\n // Remove all successfully downloaded files from the download list in one batch\n if (successfullyDownloadedItems.length > 0) {\n await removeFilesFromDownloadList({\n batchToRemove: successfullyDownloadedItems.map(\n (item: (typeof nonPackageableFiles)[0]) => ({\n fileEntityId: item.fileEntityId,\n versionNumber: item.versionNumber,\n }),\n ),\n })\n // Refetch statistics after removing files\n await refetchDownloadListStatistics()\n // Scroll to top of page to show updated statistics\n window.scrollTo({ top: 0, behavior: 'smooth' })\n }\n\n // Show completion message\n if (isCancelledRef.current) {\n displayToast(\n `Download cancelled. ${downloadedCount} file${\n downloadedCount !== 1 ? 's were' : ' was'\n } downloaded before cancellation.`,\n 'info',\n )\n } else if (downloadedCount > 0) {\n displayToast(\n `Download started for ${downloadedCount} file${\n downloadedCount !== 1 ? 's' : ''\n }${\n failedCount > 0\n ? `. ${failedCount} file${failedCount !== 1 ? 's' : ''} failed.`\n : '.'\n }`,\n failedCount > 0 ? 'warning' : 'success',\n )\n } else {\n displayToast('No files could be downloaded', 'warning')\n }\n } catch (error) {\n console.error('Error downloading files:', error)\n const message =\n (error as SynapseClientError | undefined)?.reason ??\n (error instanceof Error ? error.message : undefined) ??\n 'An error occurred while downloading files'\n displayToast(message, 'danger')\n } finally {\n setDownloadProgress(null)\n setIsDownloading(false)\n isDownloadingRef.current = false\n }\n },\n [\n accessToken,\n isAuthenticated,\n queryClient,\n getEntityQueryOptions,\n removeFilesFromDownloadList,\n refetchDownloadListStatistics,\n ],\n )\n\n const handleClick = useCallback(async () => {\n if (isDownloading) {\n return\n }\n setIsDownloading(true)\n\n // Fetch all remaining pages imperatively, then download\n try {\n let stillHasNextPage = hasNextPage\n let latestData = data\n while (stillHasNextPage && fetchNextPage) {\n const result = await fetchNextPage()\n stillHasNextPage = result.hasNextPage\n if (result.data) {\n latestData = result.data\n }\n }\n\n // All pages loaded, now download\n if (status === 'success' && latestData) {\n void downloadAllFiles(latestData)\n } else {\n // Failed to load data\n setIsDownloading(false)\n isDownloadingRef.current = false\n displayToast(\n 'Failed to load download list. Please try again.',\n 'danger',\n )\n }\n } catch (error) {\n console.error('Error downloading files:', error)\n setIsDownloading(false)\n isDownloadingRef.current = false\n const message =\n (error as SynapseClientError | undefined)?.reason ??\n (error instanceof Error ? error.message : undefined) ??\n 'An error occurred while preparing files for download'\n displayToast(message, 'danger')\n }\n }, [\n isDownloading,\n hasNextPage,\n fetchNextPage,\n status,\n data,\n downloadAllFiles,\n ])\n\n const handleCancel = useCallback(() => {\n isCancelledRef.current = true\n abortControllerRef.current?.abort()\n setDownloadProgress(null)\n setIsDownloading(false)\n isDownloadingRef.current = false\n }, [])\n\n if (error) {\n return null\n }\n\n return (\n <>\n {/* Visually-hidden live region — announces file start and progress milestones to screen readers */}\n <span\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className={styles.visuallyHidden}\n >\n {announceText}\n </span>\n {!!downloadProgress && showExternalFileWarning && (\n <Paper\n elevation={8}\n className={styles.externalWarningPanel}\n sx={{ zIndex: theme => theme.zIndex.modal }}\n role=\"region\"\n aria-label=\"External file warning\"\n >\n <CloudWarning className={styles.warningIcon} />\n <Box className={styles.warningTextContainer}>\n <Typography className={styles.warningTitleText}>\n Some of your files are hosted externally.\n </Typography>\n <Typography className={styles.progressFileNameText}>\n Downloads may be slower than expected\n </Typography>\n </Box>\n <IconButton\n onClick={() => setShowExternalFileWarning(false)}\n size=\"small\"\n className={styles.warningCloseButton}\n aria-label=\"Dismiss external file warning\"\n >\n <Close />\n </IconButton>\n </Paper>\n )}\n {!!downloadProgress && (\n <Paper\n elevation={8}\n className={styles.progressPanel}\n sx={{ zIndex: theme => theme.zIndex.modal }}\n role=\"region\"\n aria-label=\"Download progress\"\n >\n <Typography className={styles.progressTitleText}>\n Downloading file {downloadProgress.fileIndex} of{' '}\n {downloadProgress.totalFiles}\n </Typography>\n <Typography className={styles.progressFileNameText}>\n {downloadProgress.currentFile}\n </Typography>\n <Box className={styles.progressFooter}>\n <Box className={styles.progressBarContainer}>\n <Box className={styles.progressStats}>\n <Typography className={styles.progressStatsText}>\n {downloadProgress.totalBytes > 0\n ? `${Math.round(\n (downloadProgress.bytesDownloaded /\n downloadProgress.totalBytes) *\n 100,\n )}% ( ${calculateFriendlyFileSize(\n downloadProgress.bytesDownloaded,\n )} / ${calculateFriendlyFileSize(\n downloadProgress.totalBytes,\n )} )`\n : ''}\n </Typography>\n <Typography className={styles.progressStatsText}>\n {downloadProgress.estimatedSecondsRemaining !== null\n ? `About ${dayjs\n .duration({\n seconds: downloadProgress.estimatedSecondsRemaining,\n })\n .humanize()} remaining`\n : ''}\n </Typography>\n </Box>\n <LinearProgress\n variant={\n downloadProgress.totalBytes > 0\n ? 'determinate'\n : 'indeterminate'\n }\n value={\n downloadProgress.totalBytes > 0\n ? (downloadProgress.bytesDownloaded /\n downloadProgress.totalBytes) *\n 100\n : undefined\n }\n aria-label=\"Download progress\"\n className={styles.progressBar}\n />\n </Box>\n <Box className={styles.cancelButtonContainer}>\n <Button\n variant=\"outlined\"\n onClick={handleCancel}\n className={styles.cancelButton}\n >\n Cancel\n </Button>\n </Box>\n </Box>\n </Paper>\n )}\n <Button\n variant={variant}\n onClick={() => {\n void handleClick()\n }}\n loading={isDownloading}\n startIcon={<Download />}\n >\n {buttonText}\n </Button>\n </>\n )\n}\n\nexport default DownloadIneligibleForPackagingFilesFromListButton\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE as p, LOCK_ACCESS_REQUIREMEN
|
|
|
10
10
|
//#region src/components/DownloadCart/MeetAccessRequirementCard.tsx
|
|
11
11
|
var v = "Requires Acceptance of Data-Specific Terms of Use", y = "Requires Acceptance of Data-Specific Terms of Use", b = "Requires Approval of Data-Specific Access Requirements", x = "Access Restricted";
|
|
12
12
|
function S({ accessRequirementId: S, count: C }) {
|
|
13
|
-
let { data: w, isLoading: T } = i(S, { throwOnError: !0 }), [E, D] = l(!1), O, k = "", A = "", j = c(() => w ? w.name
|
|
13
|
+
let { data: w, isLoading: T } = i(S, { throwOnError: !0 }), [E, D] = l(!1), O, k = "", A = "", j = c(() => w ? /^\d+$/.exec(w.name) ? "" : w.name : "", [w]);
|
|
14
14
|
if (!T && w) switch (w.concreteType) {
|
|
15
15
|
case _:
|
|
16
16
|
O = v, k = e, A = j;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MeetAccessRequirementCard.js","names":[],"sources":["../../../src/components/DownloadCart/MeetAccessRequirementCard.tsx"],"sourcesContent":["import WideButton from '@/components/styled/WideButton'\nimport {\n useGetAccessRequirements,\n useGetAccessRequirementStatus,\n} from '@/synapse-queries'\nimport {\n EASY_DIFFICULTY,\n MEDIUM_DIFFICULTY,\n VARIABLE_DIFFICULTY,\n} from '@/utils/SynapseConstants'\nimport {\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SelfSignAccessRequirement,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n} from '@sage-bionetworks/synapse-types'\nimport { useMemo, useState } from 'react'\nimport AccessRequirementList from '../AccessRequirementList/AccessRequirementList'\nimport { ActionRequiredCard } from './ActionRequiredCard/ActionRequiredCard'\n\nexport type MeetAccessRequirementCardProps = {\n accessRequirementId: number\n count?: number\n isComplete?: boolean\n}\nexport const TERMS_OF_USE_TITLE =\n 'Requires Acceptance of Data-Specific Terms of Use'\nexport const SELF_SIGN_TITLE =\n 'Requires Acceptance of Data-Specific Terms of Use'\nexport const ACT_TITLE =\n 'Requires Approval of Data-Specific Access Requirements'\nexport const LOCK_TITLE = 'Access Restricted'\n\nexport function MeetAccessRequirementCard({\n accessRequirementId,\n count,\n}: MeetAccessRequirementCardProps) {\n const { data: ar, isLoading } = useGetAccessRequirements(\n accessRequirementId,\n { throwOnError: true },\n )\n const [isShowingAccessRequirement, setIsShowingAccessRequirement] =\n useState<boolean>(false)\n let title: string | undefined = undefined\n let iconType = ''\n let description = ''\n\n const arFriendlyName = useMemo(() => {\n if (!ar) {\n return ''\n } else if (ar.name
|
|
1
|
+
{"version":3,"file":"MeetAccessRequirementCard.js","names":[],"sources":["../../../src/components/DownloadCart/MeetAccessRequirementCard.tsx"],"sourcesContent":["import WideButton from '@/components/styled/WideButton'\nimport {\n useGetAccessRequirements,\n useGetAccessRequirementStatus,\n} from '@/synapse-queries'\nimport {\n EASY_DIFFICULTY,\n MEDIUM_DIFFICULTY,\n VARIABLE_DIFFICULTY,\n} from '@/utils/SynapseConstants'\nimport {\n ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n SelfSignAccessRequirement,\n TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE,\n} from '@sage-bionetworks/synapse-types'\nimport { useMemo, useState } from 'react'\nimport AccessRequirementList from '../AccessRequirementList/AccessRequirementList'\nimport { ActionRequiredCard } from './ActionRequiredCard/ActionRequiredCard'\n\nexport type MeetAccessRequirementCardProps = {\n accessRequirementId: number\n count?: number\n isComplete?: boolean\n}\nexport const TERMS_OF_USE_TITLE =\n 'Requires Acceptance of Data-Specific Terms of Use'\nexport const SELF_SIGN_TITLE =\n 'Requires Acceptance of Data-Specific Terms of Use'\nexport const ACT_TITLE =\n 'Requires Approval of Data-Specific Access Requirements'\nexport const LOCK_TITLE = 'Access Restricted'\n\nexport function MeetAccessRequirementCard({\n accessRequirementId,\n count,\n}: MeetAccessRequirementCardProps) {\n const { data: ar, isLoading } = useGetAccessRequirements(\n accessRequirementId,\n { throwOnError: true },\n )\n const [isShowingAccessRequirement, setIsShowingAccessRequirement] =\n useState<boolean>(false)\n let title: string | undefined = undefined\n let iconType = ''\n let description = ''\n\n const arFriendlyName = useMemo(() => {\n if (!ar) {\n return ''\n } else if (/^\\d+$/.exec(ar.name)) {\n // Don't show the AR name to the user if it's just the numeric ID\n return ''\n }\n return ar.name\n }, [ar])\n\n if (!isLoading && ar) {\n switch (ar.concreteType) {\n case TERMS_OF_USE_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n title = TERMS_OF_USE_TITLE\n iconType = EASY_DIFFICULTY\n description = arFriendlyName\n break\n case SELF_SIGN_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE: {\n title = SELF_SIGN_TITLE\n const selfSignAR: SelfSignAccessRequirement = ar\n if (selfSignAR.isValidatedProfileRequired) {\n iconType = VARIABLE_DIFFICULTY\n } else if (selfSignAR.isCertifiedUserRequired) {\n iconType = MEDIUM_DIFFICULTY\n } else {\n iconType = EASY_DIFFICULTY\n }\n description = arFriendlyName\n break\n }\n case MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n case ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n title = ACT_TITLE\n iconType = VARIABLE_DIFFICULTY\n description = arFriendlyName\n break\n case LOCK_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE:\n title = LOCK_TITLE\n iconType = VARIABLE_DIFFICULTY\n description =\n 'Access restricted pending review by Synapse Access and Compliance Team.'\n break\n }\n }\n\n const { data: arStatus } = useGetAccessRequirementStatus(\n String(accessRequirementId),\n )\n\n const meetsAccessRequirement = Boolean(arStatus?.isApproved)\n const hasSubjectId = ar?.subjectIds && ar?.subjectIds.length > 0\n const subjectId = hasSubjectId ? ar?.subjectIds[0].id : undefined\n const subjectType = hasSubjectId ? ar?.subjectIds[0].type : undefined\n\n return (\n <>\n <ActionRequiredCard\n isLoading={isLoading}\n title={title}\n description={description}\n iconType={iconType}\n count={count}\n actionNode={\n <WideButton\n variant=\"contained\"\n onClick={() => setIsShowingAccessRequirement(true)}\n disabled={meetsAccessRequirement}\n >\n {meetsAccessRequirement ? 'Complete' : 'Start'}\n </WideButton>\n }\n />\n {isShowingAccessRequirement && ar && (\n <AccessRequirementList\n subjectId={subjectId}\n subjectType={subjectType}\n accessRequirementFromProps={[ar]}\n renderAsModal={true}\n numberOfFilesAffected={count}\n onHide={() => {\n setIsShowingAccessRequirement(false)\n }}\n />\n )}\n </>\n )\n}\n"],"mappings":";;;;;;;;;;AA2BA,IAAa,IACX,qDACW,IACX,qDACW,IACX,0DACW,IAAa;AAE1B,SAAgB,EAA0B,EACxC,wBACA,YACiC;CACjC,IAAM,EAAE,MAAM,GAAI,iBAAc,EAC9B,GACA,EAAE,cAAc,GAAK,CACvB,GACM,CAAC,GAA4B,KACjC,EAAkB,EAAK,GACrB,GACA,IAAW,IACX,IAAc,IAEZ,IAAiB,QAChB,IAEM,QAAQ,KAAK,EAAG,IAAI,IAEtB,KAEF,EAAG,OALD,IAMR,CAAC,CAAE,CAAC;CAEP,IAAI,CAAC,KAAa,GAChB,QAAQ,EAAG,cAAX;EACE,KAAK;GAGH,AAFA,IAAQ,GACR,IAAW,GACX,IAAc;GACd;EACF,KAAK,GAAkD;GACrD,IAAQ;GACR,IAAM,IAAwC;GAQ9C,AAPA,AAKE,IALE,EAAW,6BACF,IACF,EAAW,0BACT,IAEA,GAEb,IAAc;GACd;EACF;EACA,KAAK;EACL,KAAK;GAGH,AAFA,IAAQ,GACR,IAAW,GACX,IAAc;GACd;EACF,KAAK;GAGH,AAFA,IAAQ,GACR,IAAW,GACX,IACE;GACF;CACJ;CAGF,IAAM,EAAE,MAAM,MAAa,EACzB,OAAO,CAAmB,CAC5B,GAEM,IAAyB,EAAQ,GAAU,YAC3C,IAAe,GAAI,cAAc,GAAI,WAAW,SAAS,GACzD,IAAY,IAAe,GAAI,WAAW,GAAG,KAAK,KAAA,GAClD,IAAc,IAAe,GAAI,WAAW,GAAG,OAAO,KAAA;CAE5D,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACa;EACJ;EACM;EACH;EACH;EACP,YACE,kBAAC,GAAD;GACE,SAAQ;GACR,eAAe,EAA8B,EAAI;GACjD,UAAU;aAET,IAAyB,aAAa;EAC7B,CAAA;CAEf,CAAA,GACA,KAA8B,KAC7B,kBAAC,GAAD;EACa;EACE;EACb,4BAA4B,CAAC,CAAE;EAC/B,eAAe;EACf,uBAAuB;EACvB,cAAc;GACZ,EAA8B,EAAK;EACrC;CACD,CAAA,CAEH,EAAA,CAAA;AAEN"}
|
|
@@ -9,24 +9,24 @@ import { useEffect as o, useMemo as s } from "react";
|
|
|
9
9
|
import { jsx as c } from "react/jsx-runtime";
|
|
10
10
|
import { EntityType as l } from "@sage-bionetworks/synapse-client";
|
|
11
11
|
//#region src/components/EntityDownloadConfirmation/EntityDownloadConfirmation.tsx
|
|
12
|
-
var u = [
|
|
12
|
+
var u = new Set([
|
|
13
13
|
l.project,
|
|
14
14
|
l.folder,
|
|
15
15
|
l.dataset,
|
|
16
16
|
l.datasetcollection
|
|
17
|
-
], d = [l.entityview], f = [l.dataset, l.datasetcollection];
|
|
17
|
+
]), d = new Set([l.entityview]), f = new Set([l.dataset, l.datasetcollection]);
|
|
18
18
|
function p({ entityId: l, versionNumber: p, handleClose: m, onIsLoadingChange: h }) {
|
|
19
19
|
let { isAuthenticated: g } = n(), { data: _, isLoading: v } = r(g ? l : void 0), y = _?.concreteType ? e(_.concreteType) : void 0;
|
|
20
20
|
o(() => {
|
|
21
21
|
h(v);
|
|
22
22
|
}, [v, h]);
|
|
23
|
-
let b = s(() => y ? d.
|
|
23
|
+
let b = s(() => y ? d.has(y) ? {
|
|
24
24
|
concreteType: "org.sagebionetworks.repo.model.download.AddToDownloadListRequest",
|
|
25
25
|
query: { sql: `select * from ${l}${p == null ? "" : `.${p}`}` }
|
|
26
|
-
} : u.
|
|
26
|
+
} : u.has(y) ? {
|
|
27
27
|
concreteType: "org.sagebionetworks.repo.model.download.AddToDownloadListRequest",
|
|
28
28
|
parentId: l,
|
|
29
|
-
useVersionNumber: f.
|
|
29
|
+
useVersionNumber: f.has(y),
|
|
30
30
|
recursive: t(y)
|
|
31
31
|
} : null : null, [
|
|
32
32
|
y,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityDownloadConfirmation.js","names":[],"sources":["../../../src/components/EntityDownloadConfirmation/EntityDownloadConfirmation.tsx"],"sourcesContent":["import AddToDownloadListConfirmationAlert from '@/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert'\nimport DownloadConfirmationUI from '@/components/download_list/DownloadConfirmationUI'\nimport {\n convertToEntityType,\n isContainerType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSynapseContext } from '@/utils'\nimport {\n AddToDownloadListRequest,\n EntityType,\n} from '@sage-bionetworks/synapse-client'\nimport { useEffect, useMemo } from 'react'\nimport { useGetEntity } from '../../synapse-queries/'\n\n/**\n * Props for the EntityDownloadConfirmation component.\n *\n * @property entityId - The ID of the entity to be added to the download cart.\n */\nexport type EntityDownloadConfirmationProps = {\n entityId: string\n versionNumber?: number\n onIsLoadingChange: (isLoading: boolean) => void\n handleClose: () => void\n}\n\nconst typesToAddToDownloadListWithParentId: EntityType
|
|
1
|
+
{"version":3,"file":"EntityDownloadConfirmation.js","names":[],"sources":["../../../src/components/EntityDownloadConfirmation/EntityDownloadConfirmation.tsx"],"sourcesContent":["import AddToDownloadListConfirmationAlert from '@/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert'\nimport DownloadConfirmationUI from '@/components/download_list/DownloadConfirmationUI'\nimport {\n convertToEntityType,\n isContainerType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { useSynapseContext } from '@/utils'\nimport {\n AddToDownloadListRequest,\n EntityType,\n} from '@sage-bionetworks/synapse-client'\nimport { useEffect, useMemo } from 'react'\nimport { useGetEntity } from '../../synapse-queries/'\n\n/**\n * Props for the EntityDownloadConfirmation component.\n *\n * @property entityId - The ID of the entity to be added to the download cart.\n */\nexport type EntityDownloadConfirmationProps = {\n entityId: string\n versionNumber?: number\n onIsLoadingChange: (isLoading: boolean) => void\n handleClose: () => void\n}\n\nconst typesToAddToDownloadListWithParentId: ReadonlySet<EntityType> = new Set([\n EntityType.project,\n EntityType.folder,\n EntityType.dataset,\n EntityType.datasetcollection,\n])\nconst typesToAddToDownloadListWithQuery: ReadonlySet<EntityType> = new Set([\n EntityType.entityview,\n])\n/** Users expect the specific file version included in the dataset to be added to the cart */\nconst typesWhereFileVersionNumberShouldBeUsed: ReadonlySet<EntityType> =\n new Set([EntityType.dataset, EntityType.datasetcollection])\n\n/**\n * A component that allows users to add an entity to the download cart. It displays a confirmation dialog that displays\n * statistics about the set of items that will be added to the download cart.\n *\n * @param props - The properties for the component.\n * @param props.entityId - The ID of the entity to be added to the download cart.\n *\n * @returns The rendered EntityDownloadConfirmation component.\n */\nexport function EntityDownloadConfirmation({\n entityId,\n versionNumber,\n handleClose,\n onIsLoadingChange,\n}: EntityDownloadConfirmationProps) {\n const { isAuthenticated } = useSynapseContext()\n const { data: entity, isLoading: isLoadingEntity } = useGetEntity(\n isAuthenticated ? entityId : undefined,\n )\n const entityType = entity?.concreteType\n ? convertToEntityType(entity.concreteType)\n : undefined\n\n useEffect(() => {\n onIsLoadingChange(isLoadingEntity)\n }, [isLoadingEntity, onIsLoadingChange])\n\n const addToDownloadListRequest: AddToDownloadListRequest | null =\n useMemo(() => {\n if (!entityType) {\n return null\n }\n if (typesToAddToDownloadListWithQuery.has(entityType)) {\n return {\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListRequest',\n query: {\n sql: `select * from ${entityId}${\n versionNumber != undefined ? `.${versionNumber}` : ''\n }`,\n },\n }\n }\n if (typesToAddToDownloadListWithParentId.has(entityType)) {\n const useVersionNumber =\n typesWhereFileVersionNumberShouldBeUsed.has(entityType)\n return {\n concreteType:\n 'org.sagebionetworks.repo.model.download.AddToDownloadListRequest',\n // TODO: Specify version of dataset/dataset collection (PLFM-9311)\n parentId: entityId,\n useVersionNumber,\n recursive: isContainerType(entityType),\n }\n }\n\n return null\n }, [entityType, entityId, versionNumber])\n\n if (!addToDownloadListRequest) {\n if (!isAuthenticated) {\n return (\n <div>\n <DownloadConfirmationUI\n onAddToDownloadCart={() => {\n // Only displaying UI to prompt sign-in, so no-op is OK\n }}\n onCancel={handleClose}\n />\n </div>\n )\n }\n return null\n }\n\n return (\n <div>\n <AddToDownloadListConfirmationAlert\n addToDownloadListRequest={addToDownloadListRequest}\n onClose={handleClose}\n />\n </div>\n )\n}\n\nexport default EntityDownloadConfirmation\n"],"mappings":";;;;;;;;;;;AA0BA,IAAM,IAAgE,IAAI,IAAI;CAC5E,EAAW;CACX,EAAW;CACX,EAAW;CACX,EAAW;AACb,CAAC,GACK,IAA6D,IAAI,IAAI,CACzE,EAAW,UACb,CAAC,GAEK,IACJ,IAAI,IAAI,CAAC,EAAW,SAAS,EAAW,iBAAiB,CAAC;AAW5D,SAAgB,EAA2B,EACzC,aACA,kBACA,gBACA,wBACkC;CAClC,IAAM,EAAE,uBAAoB,EAAkB,GACxC,EAAE,MAAM,GAAQ,WAAW,MAAoB,EACnD,IAAkB,IAAW,KAAA,CAC/B,GACM,IAAa,GAAQ,eACvB,EAAoB,EAAO,YAAY,IACvC,KAAA;CAEJ,QAAgB;EACd,EAAkB,CAAe;CACnC,GAAG,CAAC,GAAiB,CAAiB,CAAC;CAEvC,IAAM,IACJ,QACO,IAGD,EAAkC,IAAI,CAAU,IAC3C;EACL,cACE;EACF,OAAO,EACL,KAAK,iBAAiB,IACpB,KAAiB,OAAkC,KAAtB,IAAI,MAErC;CACF,IAEE,EAAqC,IAAI,CAAU,IAG9C;EACL,cACE;EAEF,UAAU;EACV,kBANA,EAAwC,IAAI,CAM5C;EACA,WAAW,EAAgB,CAAU;CACvC,IAGK,OA1BE,MA2BR;EAAC;EAAY;EAAU;CAAa,CAAC;CAkB1C,OAhBK,IAiBH,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;EAC4B;EAC1B,SAAS;CACV,CAAA,EACE,CAAA,IArBA,IAYE,OAVH,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;EACE,2BAA2B,CAE3B;EACA,UAAU;CACX,CAAA,EACE,CAAA;AAcb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetailsView.d.ts","sourceRoot":"","sources":["../../../../../src/components/EntityFinder/details/view/DetailsView.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EACL,qBAAqB,EAGtB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAIL,UAAU,EACV,YAAY,EAGb,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,SAAS,EAAwC,MAAM,OAAO,CAAA;AAQvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAG7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AA4BnE;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B,IAAI,SAAS;IACb,WAAW,eAAe;IAC1B,EAAE,OAAO;IACT,UAAU,cAAc;IACxB,WAAW,eAAe;IAC1B,WAAW,eAAe;IAC1B,oBAAoB,sBAAsB;IAC1C,eAAe,mBAAmB;IAClC,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,gBAAgB,GAAG,4BAA4B,GAAG;IAC5D,QAAQ,EAAE,kBAAkB,EAAE,CAAA;IAC9B,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACrC,oCAAoC;IACpC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,iGAAiG;IACjG,eAAe,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;IAC1C,oBAAoB,CAAC,EAAE,SAAS,CAAA;IAChC,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,oGAAoG;IACpG,gCAAgC,CAAC,EAAE,qBAAqB,CAAA;IACxD,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,kBAAkB,GAAG;IAC9D,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AA2OD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"DetailsView.d.ts","sourceRoot":"","sources":["../../../../../src/components/EntityFinder/details/view/DetailsView.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EACL,qBAAqB,EAGtB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAIL,UAAU,EACV,YAAY,EAGb,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,SAAS,EAAwC,MAAM,OAAO,CAAA;AAQvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAG7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AA4BnE;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B,IAAI,SAAS;IACb,WAAW,eAAe;IAC1B,EAAE,OAAO;IACT,UAAU,cAAc;IACxB,WAAW,eAAe;IAC1B,WAAW,eAAe;IAC1B,oBAAoB,sBAAsB;IAC1C,eAAe,mBAAmB;IAClC,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,gBAAgB,GAAG,4BAA4B,GAAG;IAC5D,QAAQ,EAAE,kBAAkB,EAAE,CAAA;IAC9B,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACrC,oCAAoC;IACpC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,iGAAiG;IACjG,eAAe,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;IAC1C,oBAAoB,CAAC,EAAE,SAAS,CAAA;IAChC,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,oGAAoG;IACpG,gCAAgC,CAAC,EAAE,qBAAqB,CAAA;IACxD,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,kBAAkB,GAAG;IAC9D,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AA2OD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CA6YlD"}
|
|
@@ -229,7 +229,7 @@ function B(n) {
|
|
|
229
229
|
return !m.has(e.id) && y.includes(n) && v.includes(n);
|
|
230
230
|
}).map(async (n) => {
|
|
231
231
|
let r, a = t(n);
|
|
232
|
-
return f === _.REQUIRED && i(a) && (Object.
|
|
232
|
+
return f === _.REQUIRED && i(a) && (Object.hasOwn(n, "versionNumber") && !F(a, n) && (r = n.versionNumber), !r) && (Y(!0), r = (await U.fetchQuery({
|
|
233
233
|
queryKey: G.getPaginatedEntityVersionsQueryKey(n.id, 1, 0),
|
|
234
234
|
queryFn: () => e(n.id, W, 0, 1)
|
|
235
235
|
})).results[0]?.versionNumber), {
|
|
@@ -282,7 +282,7 @@ function B(n) {
|
|
|
282
282
|
m,
|
|
283
283
|
f,
|
|
284
284
|
v
|
|
285
|
-
]), X = L, Z = !(l || r.
|
|
285
|
+
]), X = L, Z = !(l || r.some((e) => y.includes(t(e)) && v.includes(t(e)))), le = w(() => re({
|
|
286
286
|
setCurrentContainer: V,
|
|
287
287
|
isSelectAllVisible: X,
|
|
288
288
|
isSelectAllDisabled: Z,
|
|
@@ -328,12 +328,12 @@ function B(n) {
|
|
|
328
328
|
count: B ?? Q.getRowModel().rows.length,
|
|
329
329
|
estimateSize: () => 40,
|
|
330
330
|
getScrollElement: () => $.current,
|
|
331
|
-
measureElement: typeof window < "u" && navigator.userAgent.
|
|
331
|
+
measureElement: typeof window < "u" && !navigator.userAgent.includes("Firefox") ? (e) => e?.getBoundingClientRect().height : void 0,
|
|
332
332
|
overscan: 5
|
|
333
333
|
});
|
|
334
334
|
function fe(e) {
|
|
335
335
|
let { id: t, isDisabled: n, isVersionableEntity: r, entityType: i } = e, { currentSelectedVersion: a } = e;
|
|
336
|
-
n || (r && f === _.REQUIRED && a == null && Object.
|
|
336
|
+
n || (r && f === _.REQUIRED && a == null && Object.hasOwn(e, "versionNumber") && (F(i, e) || (a = e.versionNumber)), b({
|
|
337
337
|
targetId: t,
|
|
338
338
|
targetVersionNumber: a
|
|
339
339
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetailsView.js","names":[],"sources":["../../../../../src/components/EntityFinder/details/view/DetailsView.tsx"],"sourcesContent":["import { getEntityVersions } from '@/synapse-client/SynapseClient'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport {\n getEntityTypeFromHeader,\n isContainerType,\n isTableType,\n isVersionableEntityType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { TABLE_VERSION_IN_PROGRESS } from '@/utils/SynapseConstants'\nimport { Checkbox, Tooltip } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityChildrenRequest,\n EntityHeader,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport {\n CellContext,\n createColumnHelper,\n getCoreRowModel,\n OnChangeFn,\n SortingState,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { ReactNode, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n BlockingLoader,\n SynapseSpinner,\n} from '../../../LoadingScreen/LoadingScreen'\nimport ColumnHeader from '../../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../../TanStackTable/StyledVirtualTanStackTable'\nimport { useFetchNextPageOnScrollToBottom } from '../../../TanStackTable/useFetchNextPageOnScrollToBottom'\nimport { EntityFinderHeader } from '../../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../../useEntitySelection'\nimport { VersionSelectionType } from '../../VersionSelectionType'\nimport { EntityDetailsListSharedProps } from '../EntityDetailsList'\nimport { AddFileToDownloadListCell } from './table/AddToDownloadListCell'\nimport { CreatedOnCell } from './table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from './table/EntityBadgeIconsCell'\nimport { EntityFinderCheckboxCell } from './table/EntityFinderCheckboxCell'\nimport { EntityFinderVersionCell } from './table/EntityFinderVersionCell'\nimport { EntityTypeCell } from './table/EntityTypeCell'\nimport { FileEntityDirectDownloadCell } from './table/FileEntityDirectDownloadCell'\nimport { FileEntityMD5Cell } from './table/FileEntityMD5Cell'\nimport { FileEntitySizeCell } from './table/FileEntitySizeCell'\nimport { ModifiedByCell } from './table/ModifiedByCell'\nimport { ModifiedOnCell } from './table/ModifiedOnCell'\nimport { VersionColumnHeader } from './VersionColumnHeader'\n\n/**\n * Check if a table type entity has the \"in progress\" version label.\n */\nfunction hasInProgressTableVersion(\n entityType: EntityType,\n header: EntityFinderHeader | EntityFinderTableViewRowData,\n): boolean {\n return (\n isTableType(entityType) &&\n 'versionLabel' in header &&\n header.versionLabel === TABLE_VERSION_IN_PROGRESS\n )\n}\n\n/**\n * Set of all columns that can be shown in the DetailsView\n * Note: Some of these values are used as accessors, so ensure that those columns match the accessor key in the row data\n */\nexport enum DetailsViewColumn {\n NAME = 'name',\n ENTITY_TYPE = 'entityType',\n ID = 'id',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifiedOn',\n MODIFIED_BY = 'modifiedBy',\n ADD_TO_DOWNLOAD_CART = 'addToDownloadCart',\n DIRECT_DOWNLOAD = 'directDownload',\n SELECTED = 'selected',\n VERSION = 'version',\n SIZE = 'size',\n MD5 = 'md5',\n BADGES = 'badges',\n}\n\nexport type DetailsViewProps = EntityDetailsListSharedProps & {\n entities: EntityFinderHeader[]\n isLoading: boolean\n hasNextPage?: boolean\n fetchNextPage?: () => Promise<unknown>\n isFetchingNextPage?: boolean\n enableSorting?: boolean\n enableMultiSort?: boolean\n sortableColumns?: DetailsViewColumn[]\n /** The current sort of the view. */\n sorting?: SortingState\n /** If enableSorting is true, `setSort` will be invoked when the user tries to change the sort */\n onSortingChange?: OnChangeFn<SortingState>\n noResultsPlaceholder?: ReactNode\n /** We defer to the configuration component to determine this */\n selectAllIsChecked?: boolean\n /** This request object is only used to tell react-query to cancel fetching all children at once. */\n getChildrenInfiniteRequestObject?: EntityChildrenRequest\n /** The total number of entities that can be retrieved */\n totalEntities?: number\n}\n\n/**\n * Describes the shape of the data passed to the BaseTable\n */\nexport type EntityFinderTableViewRowData = EntityFinderHeader & {\n entityId: string\n versionNumber?: number\n entityType: EntityType\n isSelected: boolean\n isDisabled: boolean\n isVersionableEntity: boolean\n currentSelectedVersion?: number\n}\n\nconst columnHelper = createColumnHelper<EntityFinderTableViewRowData>()\n\nfunction NameRenderer(props: {\n context: CellContext<EntityFinderTableViewRowData, string>\n setCurrentContainer?: (containerId: string) => void\n}) {\n const { context, setCurrentContainer } = props\n const { row, getValue } = context\n const rowName = getValue()\n if (setCurrentContainer && isContainerType(row.original.entityType)) {\n return (\n <span\n role=\"link\"\n className=\"EntityFinderTableCellContainerLink\"\n onClick={e => {\n e.stopPropagation()\n setCurrentContainer(row.original.id)\n }}\n >\n <Tooltip title={rowName}>\n <span className=\"nameColumnCell\">{rowName}</span>\n </Tooltip>\n </span>\n )\n } else {\n return (\n <Tooltip title={rowName}>\n <span className=\"nameColumnCell\">{rowName}</span>\n </Tooltip>\n )\n }\n}\n\nfunction SelectAllCheckboxRenderer(props: {\n isVisible: boolean\n disabled: boolean\n checked: boolean\n onSelectAll: () => void\n}) {\n const { isVisible, disabled, checked, onSelectAll } = props\n if (!isVisible) {\n return null\n }\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={checked}\n disabled={disabled}\n onChange={() => {\n onSelectAll()\n }}\n />\n )\n}\n\nfunction getColumns(opts: {\n setCurrentContainer?: (containerId: string) => void\n isSelectAllVisible: boolean\n isSelectAllDisabled: boolean\n isSelectAllChecked: boolean\n onSelectAll: () => void\n versionSelection: VersionSelectionType\n toggleSelection: (entity: Reference | Reference[]) => void\n setInitialVersion: (entityId: string, version: number) => void\n sortableColumns?: DetailsViewColumn[]\n}) {\n const {\n setCurrentContainer,\n isSelectAllVisible,\n isSelectAllDisabled,\n isSelectAllChecked,\n onSelectAll,\n versionSelection,\n toggleSelection,\n setInitialVersion,\n sortableColumns = [],\n } = opts\n return [\n columnHelper.display({\n id: DetailsViewColumn.SELECTED,\n minSize: 50,\n maxSize: 50,\n size: 50,\n header: () => (\n <SelectAllCheckboxRenderer\n isVisible={isSelectAllVisible}\n disabled={isSelectAllDisabled}\n checked={isSelectAllChecked}\n onSelectAll={onSelectAll}\n />\n ),\n cell: EntityFinderCheckboxCell,\n }),\n\n columnHelper.accessor(DetailsViewColumn.ENTITY_TYPE, {\n minSize: 45,\n maxSize: 45,\n size: 45,\n header: () => null,\n enableResizing: false,\n cell: EntityTypeCell,\n meta: {\n textAlign: 'center',\n },\n }),\n columnHelper.accessor(DetailsViewColumn.NAME, {\n size: 300,\n enableSorting: sortableColumns.includes(DetailsViewColumn.NAME),\n // sortable: sort != null,\n // resizable: true,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: context => (\n <NameRenderer\n context={context}\n setCurrentContainer={setCurrentContainer}\n />\n ),\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DetailsViewColumn.BADGES,\n minSize: 75,\n maxSize: 75,\n size: 75,\n header: () => null,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.accessor(DetailsViewColumn.ID, {\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n minSize: 130,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.ID),\n }),\n columnHelper.display({\n id: DetailsViewColumn.VERSION,\n minSize: 150,\n size: 200,\n header: () => <VersionColumnHeader versionSelection={versionSelection} />,\n cell: context => (\n <EntityFinderVersionCell\n versionSelection={versionSelection}\n toggleSelection={toggleSelection}\n setInitialVersion={setInitialVersion}\n context={context}\n />\n ),\n }),\n columnHelper.accessor(DetailsViewColumn.CREATED_ON, {\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.CREATED_ON),\n }),\n columnHelper.accessor(DetailsViewColumn.MODIFIED_ON, {\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n enableColumnFilter: false,\n cell: ModifiedOnCell,\n enableSorting: sortableColumns.includes(DetailsViewColumn.MODIFIED_ON),\n }),\n columnHelper.accessor(DetailsViewColumn.MODIFIED_BY, {\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.MODIFIED_BY),\n }),\n columnHelper.display({\n id: DetailsViewColumn.SIZE,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 120,\n minSize: 85,\n enableSorting: false,\n enableResizing: true,\n cell: FileEntitySizeCell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.MD5,\n header: props => <ColumnHeader {...props} title={'MD5'} />,\n size: 200,\n enableSorting: false,\n enableResizing: true,\n cell: FileEntityMD5Cell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.ADD_TO_DOWNLOAD_CART,\n header: () => null,\n size: 45,\n minSize: 45,\n enableSorting: false,\n enableResizing: false,\n cell: AddFileToDownloadListCell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.DIRECT_DOWNLOAD,\n header: props => <ColumnHeader {...props} title={'Actions'} />,\n size: 75,\n minSize: 75,\n enableSorting: false,\n enableResizing: false,\n cell: FileEntityDirectDownloadCell,\n }),\n ]\n}\n\ntype DetailsViewRowAppearance = 'hidden' | 'disabled' | 'selected' | 'default'\n\nconst determineRowAppearance = (args: {\n visibleTypes: EntityType[]\n selectableTypes: EntityType[]\n selected: EntitySelectionMapType\n entity: EntityFinderHeader\n}): DetailsViewRowAppearance => {\n const { visibleTypes, selectableTypes, selected, entity } = args\n if (!visibleTypes.includes(getEntityTypeFromHeader(entity))) {\n return 'hidden'\n } else if (!selectableTypes.includes(getEntityTypeFromHeader(entity))) {\n return 'disabled'\n } else if (selected.has(entity.id)) {\n return 'selected'\n } else {\n return 'default'\n }\n}\n\nconst DEFAULT_HIDDEN_COLUMNS = [DetailsViewColumn.DIRECT_DOWNLOAD]\n\n/**\n * Displays a list of entities in a table.\n *\n * If the list of entities is paginated, the `hasNextPage` prop can be set to indicate that there is more data to load.\n * When the view is ready to load more data, the `fetchNextPage` callback will be invoked. The view is designed to handle\n * an \"infinite scroll\" pattern, so entities should not be removed from the list when loading the next page.\n */\nexport function DetailsView(props: DetailsViewProps) {\n const {\n entities,\n isLoading,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n versionSelection,\n selectColumnType,\n selected,\n visibleTypes,\n selectableTypes,\n toggleSelection,\n setInitialVersion,\n enableSorting,\n enableMultiSort,\n sortableColumns,\n sorting,\n onSortingChange,\n noResultsPlaceholder,\n enableSelectAll,\n selectAllIsChecked = false,\n getChildrenInfiniteRequestObject,\n totalEntities,\n setCurrentContainer,\n hiddenColumns = DEFAULT_HIDDEN_COLUMNS,\n } = props\n const queryClient = useQueryClient()\n\n const { accessToken, keyFactory: queryClientKeyFactory } = useSynapseContext()\n\n const showSelectColumn = selectColumnType !== 'none'\n\n const [shouldSelectAll, setShouldSelectAll] = useState(false)\n const [showLoadingScreen, setShowLoadingScreen] = useState(false)\n\n const cancelQuery = () => {\n // It's likely that the user will be throttled by the Synapse backend and may be waiting a\n // noticeable amount of time for the current request, so cancel it (in addition to cancelling future requests)\n void queryClient.cancelQueries({\n queryKey: queryClientKeyFactory.getEntityChildrenQueryKey(\n getChildrenInfiniteRequestObject!,\n true,\n ),\n })\n setShowLoadingScreen(false)\n setShouldSelectAll(false)\n }\n\n useEffect(() => {\n async function handleSelectAll() {\n if (shouldSelectAll) {\n if (hasNextPage && fetchNextPage) {\n // Show the loading screen since we must fetch data (potentially a lot) to finish the task\n setShowLoadingScreen(true)\n if (!isFetchingNextPage) {\n void fetchNextPage()\n // The effect will re-run after fetch completes, and the next page (if it exists) will be fetched.\n }\n } else {\n if (selectAllIsChecked) {\n // All the items are selected, so we will deselect all\n toggleSelection(\n entities\n .filter(e => {\n // Collect just entities that are selected\n // An entity may be in the list and unselected because it isn't of a selectable type\n return selected.has(e.id)\n })\n .map(e => selected.get(e.id)!),\n )\n } else {\n // Not all the items are selected, so we will select all\n toggleSelection(\n await Promise.all(\n entities\n .filter(e => {\n // must filter just selectable types or else any entities of unselectable types will get selected\n const type = getEntityTypeFromHeader(e)\n // also exclude already-selected entities, since we don't want to toggle those\n return (\n !selected.has(e.id) &&\n selectableTypes.includes(type) &&\n visibleTypes.includes(type)\n )\n })\n .map(async e => {\n let latestVersion: number | undefined\n const entityType = getEntityTypeFromHeader(e)\n if (\n versionSelection === VersionSelectionType.REQUIRED &&\n isVersionableEntityType(entityType)\n ) {\n // If VersionSelectionType.REQUIRED, then we need to supply a version with the entity.\n // We may already have the version from the header, but only use it if it's a valid snapshot\n // (table types with \"in progress\" are not valid)\n if (\n Object.prototype.hasOwnProperty.call(\n e,\n 'versionNumber',\n ) &&\n !hasInProgressTableVersion(\n entityType,\n e as EntityHeader,\n )\n ) {\n latestVersion = (e as EntityHeader).versionNumber\n }\n if (!latestVersion) {\n // Failsafe if we didn't get the version in the header. This is rare/unlikely, since the only cases we're sure we don't get versions are:\n // - ProjectHeaders (which are versionless)\n // - Search Results (for which we don't support Select All)\n // - Table types, whose entity headers report the \"in progress\" version rather than the latest stable snapshot\n // For large lists, there's a good chance for this to trigger throttling.\n\n // Show the loading screen since we must fetch data (potentially a lot) to finish the task\n setShowLoadingScreen(true)\n\n const versionsQueryOffset = 0\n const versionsQueryLimit = 1\n const versions = await queryClient.fetchQuery({\n queryKey:\n queryClientKeyFactory.getPaginatedEntityVersionsQueryKey(\n e.id,\n versionsQueryLimit,\n versionsQueryOffset,\n ),\n queryFn: () =>\n getEntityVersions(\n e.id,\n accessToken,\n versionsQueryOffset,\n versionsQueryLimit,\n ),\n })\n // we pick the first version in the list because it is the most recent\n latestVersion = versions.results[0]?.versionNumber\n }\n }\n return {\n targetId: e.id,\n targetVersionNumber: latestVersion,\n }\n }),\n ),\n )\n }\n setShouldSelectAll(false)\n setShowLoadingScreen(false)\n }\n }\n }\n handleSelectAll()\n }, [\n accessToken,\n entities,\n fetchNextPage,\n hasNextPage,\n versionSelection,\n queryClient,\n isFetchingNextPage,\n selectAllIsChecked,\n selectableTypes,\n selected,\n shouldSelectAll,\n toggleSelection,\n visibleTypes,\n queryClientKeyFactory,\n ])\n\n const tableData = useMemo(\n () =>\n entities.reduce((entities: EntityFinderTableViewRowData[], entity) => {\n const appearance = determineRowAppearance({\n visibleTypes,\n selectableTypes,\n selected,\n entity,\n })\n if (appearance !== 'hidden') {\n // only include entities that should not be hidden\n const entityType = getEntityTypeFromHeader(entity)\n\n const currentSelectedVersion = selected.get(\n entity.id,\n )?.targetVersionNumber\n let versionNumber: number | undefined = undefined\n if ('versionNumber' in entity) {\n if (currentSelectedVersion != null) {\n // if a version is selected, the row should show that version's data\n versionNumber = currentSelectedVersion\n } else if (versionSelection === VersionSelectionType.REQUIRED) {\n // if a version is not selected, but version selection is required, the row should show the latest version's data\n // Only use EntityHeader's version if it's a valid snapshot (table types with \"in progress\" are not valid)\n if (!hasInProgressTableVersion(entityType, entity)) {\n versionNumber = entity.versionNumber\n }\n }\n // otherwise, show the current version's data (versionNumber is undefined)\n }\n\n entities.push({\n ...entity,\n entityId: entity.id,\n versionNumber: versionNumber,\n entityType: entityType,\n isSelected: appearance === 'selected',\n isDisabled: appearance === 'disabled',\n isVersionableEntity: isVersionableEntityType(entityType),\n currentSelectedVersion: currentSelectedVersion,\n })\n }\n return entities\n }, []),\n [entities, selectableTypes, selected, versionSelection, visibleTypes],\n )\n\n const isSelectAllVisible = enableSelectAll\n\n // Enabled if there's at least one visible & selectable entity, OR there's a page we haven't fetched\n const isSelectAllDisabled = !(\n hasNextPage ||\n entities.filter(\n e =>\n selectableTypes.includes(getEntityTypeFromHeader(e)) &&\n visibleTypes.includes(getEntityTypeFromHeader(e)),\n ).length > 0\n )\n\n const columns = useMemo(\n () =>\n getColumns({\n setCurrentContainer,\n isSelectAllVisible: isSelectAllVisible,\n isSelectAllDisabled: isSelectAllDisabled,\n isSelectAllChecked: selectAllIsChecked,\n onSelectAll: () => {\n setShouldSelectAll(true)\n },\n versionSelection,\n toggleSelection,\n setInitialVersion,\n sortableColumns,\n }),\n [\n isSelectAllDisabled,\n isSelectAllVisible,\n selectAllIsChecked,\n setCurrentContainer,\n setInitialVersion,\n sortableColumns,\n toggleSelection,\n versionSelection,\n ],\n )\n\n const hideColumnOverrides = useMemo(() => {\n return hiddenColumns.reduce(\n (acc: Partial<Record<DetailsViewColumn, boolean>>, column) => {\n acc[column] = false\n return acc\n },\n {},\n )\n }, [hiddenColumns])\n\n const table: Table<EntityFinderTableViewRowData> =\n useReactTable<EntityFinderTableViewRowData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n manualSorting: true,\n enableSorting,\n enableMultiSort,\n onSortingChange,\n state: {\n sorting,\n columnVisibility: {\n [DetailsViewColumn.SELECTED]: showSelectColumn,\n [DetailsViewColumn.VERSION]:\n versionSelection !== VersionSelectionType.DISALLOWED,\n [DetailsViewColumn.SIZE]: visibleTypes.includes(EntityType.file),\n [DetailsViewColumn.MD5]: visibleTypes.includes(EntityType.file),\n [DetailsViewColumn.ADD_TO_DOWNLOAD_CART]: visibleTypes.includes(\n EntityType.file,\n ),\n [DetailsViewColumn.DIRECT_DOWNLOAD]: visibleTypes.includes(\n EntityType.file,\n ),\n ...hideColumnOverrides,\n },\n },\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: totalEntities ?? table.getRowModel().rows.length,\n estimateSize: () => 40, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n function onRowClick(rowData: EntityFinderTableViewRowData) {\n const { id, isDisabled, isVersionableEntity, entityType } = rowData\n let { currentSelectedVersion } = rowData\n if (!isDisabled) {\n if (\n isVersionableEntity &&\n versionSelection === VersionSelectionType.REQUIRED &&\n currentSelectedVersion == null &&\n Object.prototype.hasOwnProperty.call(rowData, 'versionNumber')\n ) {\n // Only use EntityHeader's version if it's a valid snapshot (table types with \"in progress\" are not valid)\n if (!hasInProgressTableVersion(entityType, rowData)) {\n currentSelectedVersion = rowData.versionNumber\n }\n // Note that here we aren't handling the case where the header doesn't have a version, e.g. a search result\n // That case is actually handled by the VersionRenderer, which has an effect that will toggle the selection after data is fetched.\n }\n\n toggleSelection({\n targetId: id,\n targetVersionNumber: currentSelectedVersion,\n })\n }\n }\n\n //called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table\n const fetchMoreOnBottomReached = useFetchNextPageOnScrollToBottom({\n containerRef: tableContainerRef,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n data: entities,\n })\n\n return (\n <div className=\"EntityFinderDetailsView\">\n <BlockingLoader\n show={showLoadingScreen}\n currentProgress={entities.length}\n totalProgress={totalEntities}\n hintText={\n totalEntities\n ? `${entities.length.toLocaleString()} of ${totalEntities?.toLocaleString()}`\n : `Fetching ${entities.length.toLocaleString()}`\n }\n headlineText={'Fetching selected items'}\n onCancel={cancelQuery}\n />\n {!isLoading && entities.length > 0 && (\n <StyledVirtualTanStackTable<EntityFinderTableViewRowData>\n styledTableContainerProps={{\n className: 'DetailsViewTable',\n ref: tableContainerRef,\n height: '100%',\n }}\n onTableContainerScroll={target =>\n fetchMoreOnBottomReached(target as HTMLDivElement)\n }\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: ownerState => {\n const { tableRow } = ownerState\n\n return {\n className: `EntityFinderDetailsViewRow`,\n ['aria-selected']: tableRow?.original.isSelected,\n ['aria-disabled']: tableRow?.original.isDisabled,\n onClick: () => {\n if (tableRow) {\n onRowClick(tableRow.original)\n }\n },\n }\n },\n }}\n striped\n />\n )}\n {isLoading && (\n <div className=\"EntityFinderDetailsViewPlaceholder\">\n <SynapseSpinner size={30} />\n </div>\n )}\n {!isLoading && entities.length === 0 && (\n <div className=\"EntityFinderDetailsViewPlaceholder\">\n {noResultsPlaceholder || <div>Empty</div>}\n </div>\n )}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,SAAS,EACP,GACA,GACS;CACT,OACE,EAAY,CAAU,KACtB,kBAAkB,KAClB,EAAO,iBAAA;AAEX;AAMA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,cAAA,cACA,EAAA,KAAA,MACA,EAAA,aAAA,aACA,EAAA,cAAA,cACA,EAAA,cAAA,cACA,EAAA,uBAAA,qBACA,EAAA,kBAAA,kBACA,EAAA,WAAA,YACA,EAAA,UAAA,WACA,EAAA,OAAA,QACA,EAAA,MAAA,OACA,EAAA,SAAA;AACF,EAAA,CAAA,CAAA,GAqCM,IAAe,EAAiD;AAEtE,SAAS,EAAa,GAGnB;CACD,IAAM,EAAE,YAAS,2BAAwB,GACnC,EAAE,QAAK,gBAAa,GACpB,IAAU,EAAS;CAiBvB,OAhBE,KAAuB,EAAgB,EAAI,SAAS,UAAU,IAE9D,kBAAC,QAAD;EACE,MAAK;EACL,WAAU;EACV,UAAS,MAAK;GAEZ,AADA,EAAE,gBAAgB,GAClB,EAAoB,EAAI,SAAS,EAAE;EACrC;YAEA,kBAAC,GAAD;GAAS,OAAO;aACd,kBAAC,QAAD;IAAM,WAAU;cAAkB;GAAc,CAAA;EACzC,CAAA;CACL,CAAA,IAIN,kBAAC,GAAD;EAAS,OAAO;YACd,kBAAC,QAAD;GAAM,WAAU;aAAkB;EAAc,CAAA;CACzC,CAAA;AAGf;AAEA,SAAS,EAA0B,GAKhC;CACD,IAAM,EAAE,cAAW,aAAU,YAAS,mBAAgB;CAKtD,OAJK,IAKH,kBAAC,GAAD;EACE,YAAY,EAAE,cAAc,aAAa;EAChC;EACC;EACV,gBAAgB;GACd,EAAY;EACd;CACD,CAAA,IAXM;AAaX;AAEA,SAAS,GAAW,GAUjB;CACD,IAAM,EACJ,wBACA,uBACA,wBACA,uBACA,gBACA,qBACA,oBACA,sBACA,qBAAkB,CAAC,MACjB;CACJ,OAAO;EACL,EAAa,QAAQ;GACnB,IAAA;GACA,SAAS;GACT,SAAS;GACT,MAAM;GACN,cACE,kBAAC,GAAD;IACE,WAAW;IACX,UAAU;IACV,SAAS;IACI;GACd,CAAA;GAEH,MAAM;EACR,CAAC;EAED,EAAa,SAAA,cAAwC;GACnD,SAAS;GACT,SAAS;GACT,MAAM;GACN,cAAc;GACd,gBAAgB;GAChB,MAAM;GACN,MAAM,EACJ,WAAW,SACb;EACF,CAAC;EACD,EAAa,SAAA,QAAiC;GAC5C,MAAM;GACN,eAAe,EAAgB,SAAA,MAA+B;GAG9D,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAS,CAAA;GAC1D,OAAM,MACJ,kBAAC,GAAD;IACW;IACY;GACtB,CAAA;GAEH,oBAAoB;EACtB,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,SAAS;GACT,SAAS;GACT,MAAM;GACN,cAAc;GACd,MAAM;EACR,CAAC;EACD,EAAa,SAAA,MAA+B;GAC1C,MAAM;GACN,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAO,CAAA;GACxD,SAAS;GACT,oBAAoB;GACpB,eAAe,EAAgB,SAAA,IAA6B;EAC9D,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,SAAS;GACT,MAAM;GACN,cAAc,kBAAC,GAAD,EAAuC,oBAAmB,CAAA;GACxE,OAAM,MACJ,kBAAC,GAAD;IACoB;IACD;IACE;IACV;GACV,CAAA;EAEL,CAAC;EACD,EAAa,SAAA,aAAuC;GAClD,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAe,CAAA;GAChE,MAAM;GACN,SAAS;GACT,MAAM;GACN,oBAAoB;GACpB,eAAe,EAAgB,SAAA,WAAqC;EACtE,CAAC;EACD,EAAa,SAAA,cAAwC;GACnD,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAgB,CAAA;GACjE,MAAM;GACN,SAAS;GACT,oBAAoB;GACpB,MAAM;GACN,eAAe,EAAgB,SAAA,YAAsC;EACvE,CAAC;EACD,EAAa,SAAA,cAAwC;GACnD,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAgB,CAAA;GACjE,MAAM;GACN,gBAAgB;GAChB,MAAM;GACN,oBAAoB;GACpB,eAAe,EAAgB,SAAA,YAAsC;EACvE,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAS,CAAA;GAC1D,MAAM;GACN,SAAS;GACT,eAAe;GACf,gBAAgB;GAChB,MAAM;EACR,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAQ,CAAA;GACzD,MAAM;GACN,eAAe;GACf,gBAAgB;GAChB,MAAM;EACR,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,cAAc;GACd,MAAM;GACN,SAAS;GACT,eAAe;GACf,gBAAgB;GAChB,MAAM;EACR,CAAC;EACD,EAAa,QAAQ;GACnB,IAAA;GACA,SAAQ,MAAS,kBAAC,GAAD;IAAc,GAAI;IAAO,OAAO;GAAY,CAAA;GAC7D,MAAM;GACN,SAAS;GACT,eAAe;GACf,gBAAgB;GAChB,MAAM;EACR,CAAC;CACH;AACF;AAIA,IAAM,MAA0B,MAKA;CAC9B,IAAM,EAAE,iBAAc,oBAAiB,aAAU,cAAW;CAQ1D,OAPG,EAAa,SAAS,EAAwB,CAAM,CAAC,IAE9C,EAAgB,SAAS,EAAwB,CAAM,CAAC,IAEzD,EAAS,IAAI,EAAO,EAAE,IACxB,aAEA,YAJA,aAFA;AAQX,GAEM,KAAyB,CAAA,gBAAkC;AASjE,SAAgB,EAAY,GAAyB;CACnD,IAAM,EACJ,aACA,cACA,gBACA,kBACA,uBACA,qBACA,qBACA,aACA,iBACA,oBACA,oBACA,sBACA,kBACA,oBACA,oBACA,YACA,oBACA,yBACA,oBACA,wBAAqB,IACrB,qCACA,kBACA,wBACA,mBAAgB,OACd,GACE,IAAc,EAAe,GAE7B,EAAE,gBAAa,YAAY,MAA0B,EAAkB,GAEvE,IAAmB,MAAqB,QAExC,CAAC,GAAiB,KAAsB,EAAS,EAAK,GACtD,CAAC,IAAmB,KAAwB,EAAS,EAAK,GAE1D,WAAoB;EAUxB,AAPA,EAAiB,cAAc,EAC7B,UAAU,EAAsB,0BAC9B,GACA,EACF,EACF,CAAC,GACD,EAAqB,EAAK,GAC1B,EAAmB,EAAK;CAC1B;CAEA,SAAgB;EACd,eAAe,IAAkB;GAC/B,AAAI,MACE,KAAe,KAEjB,EAAqB,EAAI,GACpB,KACH,EAAmB,MAMnB,EAFE,IAGA,EACG,QAAO,MAGC,EAAS,IAAI,EAAE,EAAE,CACzB,EACA,KAAI,MAAK,EAAS,IAAI,EAAE,EAAE,CAAE,IAK/B,MAAM,QAAQ,IACZ,EACG,QAAO,MAAK;IAEX,IAAM,IAAO,EAAwB,CAAC;IAEtC,OACE,CAAC,EAAS,IAAI,EAAE,EAAE,KAClB,EAAgB,SAAS,CAAI,KAC7B,EAAa,SAAS,CAAI;GAE9B,CAAC,EACA,IAAI,OAAM,MAAK;IACd,IAAI,GACE,IAAa,EAAwB,CAAC;IAmD5C,OAjDE,MAAqB,EAAqB,YAC1C,EAAwB,CAAU,MAMhC,OAAO,UAAU,eAAe,KAC9B,GACA,eACF,KACA,CAAC,EACC,GACA,CACF,MAEA,IAAiB,EAAmB,gBAElC,CAAC,OAQH,EAAqB,EAAI,GAoBzB,KAAgB,MAhBO,EAAY,WAAW;KAC5C,UACE,EAAsB,mCACpB,EAAE,IACF,GACA,CACF;KACF,eACE,EACE,EAAE,IACF,GACA,GACA,CACF;IACJ,CAAC,GAEwB,QAAQ,IAAI,gBAGlC;KACL,UAAU,EAAE;KACZ,qBAAqB;IACvB;GACF,CAAC,CACL,CACF,GAEF,EAAmB,EAAK,GACxB,EAAqB,EAAK;EAGhC;EACA,EAAgB;CAClB,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,IAAM,KAAY,QAEd,EAAS,QAAQ,GAA0C,MAAW;EACpE,IAAM,IAAa,GAAuB;GACxC;GACA;GACA;GACA;EACF,CAAC;EACD,IAAI,MAAe,UAAU;GAE3B,IAAM,IAAa,EAAwB,CAAM,GAE3C,IAAyB,EAAS,IACtC,EAAO,EACT,GAAG,qBACC;GAeJ,AAdI,mBAAmB,MACjB,KAA0B,OAGnB,MAAqB,EAAqB,aAG9C,EAA0B,GAAY,CAAM,MAC/C,IAAgB,EAAO,kBALzB,IAAgB,IAWpB,EAAS,KAAK;IACZ,GAAG;IACH,UAAU,EAAO;IACF;IACH;IACZ,YAAY,MAAe;IAC3B,YAAY,MAAe;IAC3B,qBAAqB,EAAwB,CAAU;IAC/B;GAC1B,CAAC;EACH;EACA,OAAO;CACT,GAAG,CAAC,CAAC,GACP;EAAC;EAAU;EAAiB;EAAU;EAAkB;CAAY,CACtE,GAEM,IAAqB,GAGrB,IAAsB,EAC1B,KACA,EAAS,QACP,MACE,EAAgB,SAAS,EAAwB,CAAC,CAAC,KACnD,EAAa,SAAS,EAAwB,CAAC,CAAC,CACpD,EAAE,SAAS,IAGP,KAAU,QAEZ,GAAW;EACT;EACoB;EACC;EACrB,oBAAoB;EACpB,mBAAmB;GACjB,EAAmB,EAAI;EACzB;EACA;EACA;EACA;EACA;CACF,CAAC,GACH;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF,GAEM,KAAsB,QACnB,EAAc,QAClB,GAAkD,OACjD,EAAI,KAAU,IACP,IAET,CAAC,CACH,GACC,CAAC,CAAa,CAAC,GAEZ,IACJ,EAA4C;EAC1C,MAAM;EACN;EACA,iBAAiB,GAAgB;EACjC,kBAAkB;EAClB,eAAe;EACf;EACA;EACA;EACA,OAAO;GACL;GACA,kBAAkB;cACc;aAE5B,MAAqB,EAAqB;UAClB,EAAa,SAAS,EAAW,IAAI;SACtC,EAAa,SAAS,EAAW,IAAI;uBACpB,EAAa,SACrD,EAAW,IACb;oBACqC,EAAa,SAChD,EAAW,IACb;IACA,GAAG;GACL;EACF;CACF,CAAC,GAEG,IAAoB,EAAuB,IAAI,GAE/C,KAAiB,EAAe;EACpC,OAAO,KAAiB,EAAM,YAAY,EAAE,KAAK;EACjD,oBAAoB;EACpB,wBAAwB,EAAkB;EAE1C,gBACE,OAAO,SAAW,OAClB,UAAU,UAAU,QAAQ,SAAS,MAAM,MACvC,MAAW,GAAS,sBAAsB,EAAE,SAC5C,KAAA;EACN,UAAU;CACZ,CAAC;CAED,SAAS,GAAW,GAAuC;EACzD,IAAM,EAAE,OAAI,eAAY,wBAAqB,kBAAe,GACxD,EAAE,8BAA2B;EACjC,AAAK,MAED,KACA,MAAqB,EAAqB,YAC1C,KAA0B,QAC1B,OAAO,UAAU,eAAe,KAAK,GAAS,eAAe,MAGxD,EAA0B,GAAY,CAAO,MAChD,IAAyB,EAAQ,iBAMrC,EAAgB;GACd,UAAU;GACV,qBAAqB;EACvB,CAAC;CAEL;CAGA,IAAM,KAA2B,EAAiC;EAChE,cAAc;EACd;EACA;EACA;EACA,MAAM;CACR,CAAC;CAED,OACE,mBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD;IACE,MAAM;IACN,iBAAiB,EAAS;IAC1B,eAAe;IACf,UACE,IACI,GAAG,EAAS,OAAO,eAAe,EAAE,MAAM,GAAe,eAAe,MACxE,YAAY,EAAS,OAAO,eAAe;IAEjD,cAAc;IACd,UAAU;GACX,CAAA;GACA,CAAC,KAAa,EAAS,SAAS,KAC/B,kBAAC,GAAD;IACE,2BAA2B;KACzB,WAAW;KACX,KAAK;KACL,QAAQ;IACV;IACA,yBAAwB,MACtB,GAAyB,CAAwB;IAE5C;IACS;IAChB,WAAW,EACT,KAAI,MAAc;KAChB,IAAM,EAAE,gBAAa;KAErB,OAAO;MACL,WAAW;MACV,iBAAkB,GAAU,SAAS;MACrC,iBAAkB,GAAU,SAAS;MACtC,eAAe;OACb,AAAI,KACF,GAAW,EAAS,QAAQ;MAEhC;KACF;IACF,EACF;IACA,SAAA;GACD,CAAA;GAEF,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAgB,MAAM,GAAK,CAAA;GACxB,CAAA;GAEN,CAAC,KAAa,EAAS,WAAW,KACjC,kBAAC,OAAD;IAAK,WAAU;cACZ,KAAwB,kBAAC,OAAD,EAAA,UAAK,QAAU,CAAA;GACrC,CAAA;EAEJ;;AAET"}
|
|
1
|
+
{"version":3,"file":"DetailsView.js","names":[],"sources":["../../../../../src/components/EntityFinder/details/view/DetailsView.tsx"],"sourcesContent":["import { getEntityVersions } from '@/synapse-client/SynapseClient'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport {\n getEntityTypeFromHeader,\n isContainerType,\n isTableType,\n isVersionableEntityType,\n} from '@/utils/functions/EntityTypeUtils'\nimport { TABLE_VERSION_IN_PROGRESS } from '@/utils/SynapseConstants'\nimport { Checkbox, Tooltip } from '@mui/material'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport {\n EntityChildrenRequest,\n EntityHeader,\n Reference,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport {\n CellContext,\n createColumnHelper,\n getCoreRowModel,\n OnChangeFn,\n SortingState,\n Table,\n useReactTable,\n} from '@tanstack/react-table'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport { ReactNode, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n BlockingLoader,\n SynapseSpinner,\n} from '../../../LoadingScreen/LoadingScreen'\nimport ColumnHeader from '../../../TanStackTable/ColumnHeader'\nimport StyledVirtualTanStackTable from '../../../TanStackTable/StyledVirtualTanStackTable'\nimport { useFetchNextPageOnScrollToBottom } from '../../../TanStackTable/useFetchNextPageOnScrollToBottom'\nimport { EntityFinderHeader } from '../../EntityFinderHeader'\nimport { EntitySelectionMapType } from '../../useEntitySelection'\nimport { VersionSelectionType } from '../../VersionSelectionType'\nimport { EntityDetailsListSharedProps } from '../EntityDetailsList'\nimport { AddFileToDownloadListCell } from './table/AddToDownloadListCell'\nimport { CreatedOnCell } from './table/CreatedOnCell'\nimport { EntityBadgeIconsCell } from './table/EntityBadgeIconsCell'\nimport { EntityFinderCheckboxCell } from './table/EntityFinderCheckboxCell'\nimport { EntityFinderVersionCell } from './table/EntityFinderVersionCell'\nimport { EntityTypeCell } from './table/EntityTypeCell'\nimport { FileEntityDirectDownloadCell } from './table/FileEntityDirectDownloadCell'\nimport { FileEntityMD5Cell } from './table/FileEntityMD5Cell'\nimport { FileEntitySizeCell } from './table/FileEntitySizeCell'\nimport { ModifiedByCell } from './table/ModifiedByCell'\nimport { ModifiedOnCell } from './table/ModifiedOnCell'\nimport { VersionColumnHeader } from './VersionColumnHeader'\n\n/**\n * Check if a table type entity has the \"in progress\" version label.\n */\nfunction hasInProgressTableVersion(\n entityType: EntityType,\n header: EntityFinderHeader | EntityFinderTableViewRowData,\n): boolean {\n return (\n isTableType(entityType) &&\n 'versionLabel' in header &&\n header.versionLabel === TABLE_VERSION_IN_PROGRESS\n )\n}\n\n/**\n * Set of all columns that can be shown in the DetailsView\n * Note: Some of these values are used as accessors, so ensure that those columns match the accessor key in the row data\n */\nexport enum DetailsViewColumn {\n NAME = 'name',\n ENTITY_TYPE = 'entityType',\n ID = 'id',\n CREATED_ON = 'createdOn',\n MODIFIED_ON = 'modifiedOn',\n MODIFIED_BY = 'modifiedBy',\n ADD_TO_DOWNLOAD_CART = 'addToDownloadCart',\n DIRECT_DOWNLOAD = 'directDownload',\n SELECTED = 'selected',\n VERSION = 'version',\n SIZE = 'size',\n MD5 = 'md5',\n BADGES = 'badges',\n}\n\nexport type DetailsViewProps = EntityDetailsListSharedProps & {\n entities: EntityFinderHeader[]\n isLoading: boolean\n hasNextPage?: boolean\n fetchNextPage?: () => Promise<unknown>\n isFetchingNextPage?: boolean\n enableSorting?: boolean\n enableMultiSort?: boolean\n sortableColumns?: DetailsViewColumn[]\n /** The current sort of the view. */\n sorting?: SortingState\n /** If enableSorting is true, `setSort` will be invoked when the user tries to change the sort */\n onSortingChange?: OnChangeFn<SortingState>\n noResultsPlaceholder?: ReactNode\n /** We defer to the configuration component to determine this */\n selectAllIsChecked?: boolean\n /** This request object is only used to tell react-query to cancel fetching all children at once. */\n getChildrenInfiniteRequestObject?: EntityChildrenRequest\n /** The total number of entities that can be retrieved */\n totalEntities?: number\n}\n\n/**\n * Describes the shape of the data passed to the BaseTable\n */\nexport type EntityFinderTableViewRowData = EntityFinderHeader & {\n entityId: string\n versionNumber?: number\n entityType: EntityType\n isSelected: boolean\n isDisabled: boolean\n isVersionableEntity: boolean\n currentSelectedVersion?: number\n}\n\nconst columnHelper = createColumnHelper<EntityFinderTableViewRowData>()\n\nfunction NameRenderer(props: {\n context: CellContext<EntityFinderTableViewRowData, string>\n setCurrentContainer?: (containerId: string) => void\n}) {\n const { context, setCurrentContainer } = props\n const { row, getValue } = context\n const rowName = getValue()\n if (setCurrentContainer && isContainerType(row.original.entityType)) {\n return (\n <span\n role=\"link\"\n className=\"EntityFinderTableCellContainerLink\"\n onClick={e => {\n e.stopPropagation()\n setCurrentContainer(row.original.id)\n }}\n >\n <Tooltip title={rowName}>\n <span className=\"nameColumnCell\">{rowName}</span>\n </Tooltip>\n </span>\n )\n } else {\n return (\n <Tooltip title={rowName}>\n <span className=\"nameColumnCell\">{rowName}</span>\n </Tooltip>\n )\n }\n}\n\nfunction SelectAllCheckboxRenderer(props: {\n isVisible: boolean\n disabled: boolean\n checked: boolean\n onSelectAll: () => void\n}) {\n const { isVisible, disabled, checked, onSelectAll } = props\n if (!isVisible) {\n return null\n }\n\n return (\n <Checkbox\n inputProps={{ 'aria-label': 'Select All' }}\n checked={checked}\n disabled={disabled}\n onChange={() => {\n onSelectAll()\n }}\n />\n )\n}\n\nfunction getColumns(opts: {\n setCurrentContainer?: (containerId: string) => void\n isSelectAllVisible: boolean\n isSelectAllDisabled: boolean\n isSelectAllChecked: boolean\n onSelectAll: () => void\n versionSelection: VersionSelectionType\n toggleSelection: (entity: Reference | Reference[]) => void\n setInitialVersion: (entityId: string, version: number) => void\n sortableColumns?: DetailsViewColumn[]\n}) {\n const {\n setCurrentContainer,\n isSelectAllVisible,\n isSelectAllDisabled,\n isSelectAllChecked,\n onSelectAll,\n versionSelection,\n toggleSelection,\n setInitialVersion,\n sortableColumns = [],\n } = opts\n return [\n columnHelper.display({\n id: DetailsViewColumn.SELECTED,\n minSize: 50,\n maxSize: 50,\n size: 50,\n header: () => (\n <SelectAllCheckboxRenderer\n isVisible={isSelectAllVisible}\n disabled={isSelectAllDisabled}\n checked={isSelectAllChecked}\n onSelectAll={onSelectAll}\n />\n ),\n cell: EntityFinderCheckboxCell,\n }),\n\n columnHelper.accessor(DetailsViewColumn.ENTITY_TYPE, {\n minSize: 45,\n maxSize: 45,\n size: 45,\n header: () => null,\n enableResizing: false,\n cell: EntityTypeCell,\n meta: {\n textAlign: 'center',\n },\n }),\n columnHelper.accessor(DetailsViewColumn.NAME, {\n size: 300,\n enableSorting: sortableColumns.includes(DetailsViewColumn.NAME),\n // sortable: sort != null,\n // resizable: true,\n header: props => <ColumnHeader {...props} title={'Name'} />,\n cell: context => (\n <NameRenderer\n context={context}\n setCurrentContainer={setCurrentContainer}\n />\n ),\n enableColumnFilter: false,\n }),\n columnHelper.display({\n id: DetailsViewColumn.BADGES,\n minSize: 75,\n maxSize: 75,\n size: 75,\n header: () => null,\n cell: EntityBadgeIconsCell,\n }),\n columnHelper.accessor(DetailsViewColumn.ID, {\n size: 130,\n header: props => <ColumnHeader {...props} title={'ID'} />,\n minSize: 130,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.ID),\n }),\n columnHelper.display({\n id: DetailsViewColumn.VERSION,\n minSize: 150,\n size: 200,\n header: () => <VersionColumnHeader versionSelection={versionSelection} />,\n cell: context => (\n <EntityFinderVersionCell\n versionSelection={versionSelection}\n toggleSelection={toggleSelection}\n setInitialVersion={setInitialVersion}\n context={context}\n />\n ),\n }),\n columnHelper.accessor(DetailsViewColumn.CREATED_ON, {\n header: props => <ColumnHeader {...props} title={'Created On'} />,\n size: 220,\n minSize: 170,\n cell: CreatedOnCell,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.CREATED_ON),\n }),\n columnHelper.accessor(DetailsViewColumn.MODIFIED_ON, {\n header: props => <ColumnHeader {...props} title={'Modified On'} />,\n size: 220,\n minSize: 170,\n enableColumnFilter: false,\n cell: ModifiedOnCell,\n enableSorting: sortableColumns.includes(DetailsViewColumn.MODIFIED_ON),\n }),\n columnHelper.accessor(DetailsViewColumn.MODIFIED_BY, {\n header: props => <ColumnHeader {...props} title={'Modified By'} />,\n size: 250,\n enableResizing: true,\n cell: ModifiedByCell,\n enableColumnFilter: false,\n enableSorting: sortableColumns.includes(DetailsViewColumn.MODIFIED_BY),\n }),\n columnHelper.display({\n id: DetailsViewColumn.SIZE,\n header: props => <ColumnHeader {...props} title={'Size'} />,\n size: 120,\n minSize: 85,\n enableSorting: false,\n enableResizing: true,\n cell: FileEntitySizeCell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.MD5,\n header: props => <ColumnHeader {...props} title={'MD5'} />,\n size: 200,\n enableSorting: false,\n enableResizing: true,\n cell: FileEntityMD5Cell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.ADD_TO_DOWNLOAD_CART,\n header: () => null,\n size: 45,\n minSize: 45,\n enableSorting: false,\n enableResizing: false,\n cell: AddFileToDownloadListCell,\n }),\n columnHelper.display({\n id: DetailsViewColumn.DIRECT_DOWNLOAD,\n header: props => <ColumnHeader {...props} title={'Actions'} />,\n size: 75,\n minSize: 75,\n enableSorting: false,\n enableResizing: false,\n cell: FileEntityDirectDownloadCell,\n }),\n ]\n}\n\ntype DetailsViewRowAppearance = 'hidden' | 'disabled' | 'selected' | 'default'\n\nconst determineRowAppearance = (args: {\n visibleTypes: EntityType[]\n selectableTypes: EntityType[]\n selected: EntitySelectionMapType\n entity: EntityFinderHeader\n}): DetailsViewRowAppearance => {\n const { visibleTypes, selectableTypes, selected, entity } = args\n if (!visibleTypes.includes(getEntityTypeFromHeader(entity))) {\n return 'hidden'\n } else if (!selectableTypes.includes(getEntityTypeFromHeader(entity))) {\n return 'disabled'\n } else if (selected.has(entity.id)) {\n return 'selected'\n } else {\n return 'default'\n }\n}\n\nconst DEFAULT_HIDDEN_COLUMNS = [DetailsViewColumn.DIRECT_DOWNLOAD]\n\n/**\n * Displays a list of entities in a table.\n *\n * If the list of entities is paginated, the `hasNextPage` prop can be set to indicate that there is more data to load.\n * When the view is ready to load more data, the `fetchNextPage` callback will be invoked. The view is designed to handle\n * an \"infinite scroll\" pattern, so entities should not be removed from the list when loading the next page.\n */\nexport function DetailsView(props: DetailsViewProps) {\n const {\n entities,\n isLoading,\n hasNextPage,\n fetchNextPage,\n isFetchingNextPage,\n versionSelection,\n selectColumnType,\n selected,\n visibleTypes,\n selectableTypes,\n toggleSelection,\n setInitialVersion,\n enableSorting,\n enableMultiSort,\n sortableColumns,\n sorting,\n onSortingChange,\n noResultsPlaceholder,\n enableSelectAll,\n selectAllIsChecked = false,\n getChildrenInfiniteRequestObject,\n totalEntities,\n setCurrentContainer,\n hiddenColumns = DEFAULT_HIDDEN_COLUMNS,\n } = props\n const queryClient = useQueryClient()\n\n const { accessToken, keyFactory: queryClientKeyFactory } = useSynapseContext()\n\n const showSelectColumn = selectColumnType !== 'none'\n\n const [shouldSelectAll, setShouldSelectAll] = useState(false)\n const [showLoadingScreen, setShowLoadingScreen] = useState(false)\n\n const cancelQuery = () => {\n // It's likely that the user will be throttled by the Synapse backend and may be waiting a\n // noticeable amount of time for the current request, so cancel it (in addition to cancelling future requests)\n void queryClient.cancelQueries({\n queryKey: queryClientKeyFactory.getEntityChildrenQueryKey(\n getChildrenInfiniteRequestObject!,\n true,\n ),\n })\n setShowLoadingScreen(false)\n setShouldSelectAll(false)\n }\n\n useEffect(() => {\n async function handleSelectAll() {\n if (shouldSelectAll) {\n if (hasNextPage && fetchNextPage) {\n // Show the loading screen since we must fetch data (potentially a lot) to finish the task\n setShowLoadingScreen(true)\n if (!isFetchingNextPage) {\n void fetchNextPage()\n // The effect will re-run after fetch completes, and the next page (if it exists) will be fetched.\n }\n } else {\n if (selectAllIsChecked) {\n // All the items are selected, so we will deselect all\n toggleSelection(\n entities\n .filter(e => {\n // Collect just entities that are selected\n // An entity may be in the list and unselected because it isn't of a selectable type\n return selected.has(e.id)\n })\n .map(e => selected.get(e.id)!),\n )\n } else {\n // Not all the items are selected, so we will select all\n toggleSelection(\n await Promise.all(\n entities\n .filter(e => {\n // must filter just selectable types or else any entities of unselectable types will get selected\n const type = getEntityTypeFromHeader(e)\n // also exclude already-selected entities, since we don't want to toggle those\n return (\n !selected.has(e.id) &&\n selectableTypes.includes(type) &&\n visibleTypes.includes(type)\n )\n })\n .map(async e => {\n let latestVersion: number | undefined\n const entityType = getEntityTypeFromHeader(e)\n if (\n versionSelection === VersionSelectionType.REQUIRED &&\n isVersionableEntityType(entityType)\n ) {\n // If VersionSelectionType.REQUIRED, then we need to supply a version with the entity.\n // We may already have the version from the header, but only use it if it's a valid snapshot\n // (table types with \"in progress\" are not valid)\n if (\n Object.hasOwn(e, 'versionNumber') &&\n !hasInProgressTableVersion(\n entityType,\n e as EntityHeader,\n )\n ) {\n latestVersion = (e as EntityHeader).versionNumber\n }\n if (!latestVersion) {\n // Failsafe if we didn't get the version in the header. This is rare/unlikely, since the only cases we're sure we don't get versions are:\n // - ProjectHeaders (which are versionless)\n // - Search Results (for which we don't support Select All)\n // - Table types, whose entity headers report the \"in progress\" version rather than the latest stable snapshot\n // For large lists, there's a good chance for this to trigger throttling.\n\n // Show the loading screen since we must fetch data (potentially a lot) to finish the task\n setShowLoadingScreen(true)\n\n const versionsQueryOffset = 0\n const versionsQueryLimit = 1\n const versions = await queryClient.fetchQuery({\n queryKey:\n queryClientKeyFactory.getPaginatedEntityVersionsQueryKey(\n e.id,\n versionsQueryLimit,\n versionsQueryOffset,\n ),\n queryFn: () =>\n getEntityVersions(\n e.id,\n accessToken,\n versionsQueryOffset,\n versionsQueryLimit,\n ),\n })\n // we pick the first version in the list because it is the most recent\n latestVersion = versions.results[0]?.versionNumber\n }\n }\n return {\n targetId: e.id,\n targetVersionNumber: latestVersion,\n }\n }),\n ),\n )\n }\n setShouldSelectAll(false)\n setShowLoadingScreen(false)\n }\n }\n }\n handleSelectAll()\n }, [\n accessToken,\n entities,\n fetchNextPage,\n hasNextPage,\n versionSelection,\n queryClient,\n isFetchingNextPage,\n selectAllIsChecked,\n selectableTypes,\n selected,\n shouldSelectAll,\n toggleSelection,\n visibleTypes,\n queryClientKeyFactory,\n ])\n\n const tableData = useMemo(\n () =>\n entities.reduce((entities: EntityFinderTableViewRowData[], entity) => {\n const appearance = determineRowAppearance({\n visibleTypes,\n selectableTypes,\n selected,\n entity,\n })\n if (appearance !== 'hidden') {\n // only include entities that should not be hidden\n const entityType = getEntityTypeFromHeader(entity)\n\n const currentSelectedVersion = selected.get(\n entity.id,\n )?.targetVersionNumber\n let versionNumber: number | undefined = undefined\n if ('versionNumber' in entity) {\n if (currentSelectedVersion != null) {\n // if a version is selected, the row should show that version's data\n versionNumber = currentSelectedVersion\n } else if (versionSelection === VersionSelectionType.REQUIRED) {\n // if a version is not selected, but version selection is required, the row should show the latest version's data\n // Only use EntityHeader's version if it's a valid snapshot (table types with \"in progress\" are not valid)\n if (!hasInProgressTableVersion(entityType, entity)) {\n versionNumber = entity.versionNumber\n }\n }\n // otherwise, show the current version's data (versionNumber is undefined)\n }\n\n entities.push({\n ...entity,\n entityId: entity.id,\n versionNumber: versionNumber,\n entityType: entityType,\n isSelected: appearance === 'selected',\n isDisabled: appearance === 'disabled',\n isVersionableEntity: isVersionableEntityType(entityType),\n currentSelectedVersion: currentSelectedVersion,\n })\n }\n return entities\n }, []),\n [entities, selectableTypes, selected, versionSelection, visibleTypes],\n )\n\n const isSelectAllVisible = enableSelectAll\n\n // Enabled if there's at least one visible & selectable entity, OR there's a page we haven't fetched\n const isSelectAllDisabled = !(\n hasNextPage ||\n entities.some(\n e =>\n selectableTypes.includes(getEntityTypeFromHeader(e)) &&\n visibleTypes.includes(getEntityTypeFromHeader(e)),\n )\n )\n\n const columns = useMemo(\n () =>\n getColumns({\n setCurrentContainer,\n isSelectAllVisible: isSelectAllVisible,\n isSelectAllDisabled: isSelectAllDisabled,\n isSelectAllChecked: selectAllIsChecked,\n onSelectAll: () => {\n setShouldSelectAll(true)\n },\n versionSelection,\n toggleSelection,\n setInitialVersion,\n sortableColumns,\n }),\n [\n isSelectAllDisabled,\n isSelectAllVisible,\n selectAllIsChecked,\n setCurrentContainer,\n setInitialVersion,\n sortableColumns,\n toggleSelection,\n versionSelection,\n ],\n )\n\n const hideColumnOverrides = useMemo(() => {\n return hiddenColumns.reduce(\n (acc: Partial<Record<DetailsViewColumn, boolean>>, column) => {\n acc[column] = false\n return acc\n },\n {},\n )\n }, [hiddenColumns])\n\n const table: Table<EntityFinderTableViewRowData> =\n useReactTable<EntityFinderTableViewRowData>({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n columnResizeMode: 'onChange',\n manualSorting: true,\n enableSorting,\n enableMultiSort,\n onSortingChange,\n state: {\n sorting,\n columnVisibility: {\n [DetailsViewColumn.SELECTED]: showSelectColumn,\n [DetailsViewColumn.VERSION]:\n versionSelection !== VersionSelectionType.DISALLOWED,\n [DetailsViewColumn.SIZE]: visibleTypes.includes(EntityType.file),\n [DetailsViewColumn.MD5]: visibleTypes.includes(EntityType.file),\n [DetailsViewColumn.ADD_TO_DOWNLOAD_CART]: visibleTypes.includes(\n EntityType.file,\n ),\n [DetailsViewColumn.DIRECT_DOWNLOAD]: visibleTypes.includes(\n EntityType.file,\n ),\n ...hideColumnOverrides,\n },\n },\n })\n\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n const rowVirtualizer = useVirtualizer({\n count: totalEntities ?? table.getRowModel().rows.length,\n estimateSize: () => 40, // estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' && !navigator.userAgent.includes('Firefox')\n ? element => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n function onRowClick(rowData: EntityFinderTableViewRowData) {\n const { id, isDisabled, isVersionableEntity, entityType } = rowData\n let { currentSelectedVersion } = rowData\n if (!isDisabled) {\n if (\n isVersionableEntity &&\n versionSelection === VersionSelectionType.REQUIRED &&\n currentSelectedVersion == null &&\n Object.hasOwn(rowData, 'versionNumber')\n ) {\n // Only use EntityHeader's version if it's a valid snapshot (table types with \"in progress\" are not valid)\n if (!hasInProgressTableVersion(entityType, rowData)) {\n currentSelectedVersion = rowData.versionNumber\n }\n // Note that here we aren't handling the case where the header doesn't have a version, e.g. a search result\n // That case is actually handled by the VersionRenderer, which has an effect that will toggle the selection after data is fetched.\n }\n\n toggleSelection({\n targetId: id,\n targetVersionNumber: currentSelectedVersion,\n })\n }\n }\n\n //called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table\n const fetchMoreOnBottomReached = useFetchNextPageOnScrollToBottom({\n containerRef: tableContainerRef,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n data: entities,\n })\n\n return (\n <div className=\"EntityFinderDetailsView\">\n <BlockingLoader\n show={showLoadingScreen}\n currentProgress={entities.length}\n totalProgress={totalEntities}\n hintText={\n totalEntities\n ? `${entities.length.toLocaleString()} of ${totalEntities?.toLocaleString()}`\n : `Fetching ${entities.length.toLocaleString()}`\n }\n headlineText={'Fetching selected items'}\n onCancel={cancelQuery}\n />\n {!isLoading && entities.length > 0 && (\n <StyledVirtualTanStackTable<EntityFinderTableViewRowData>\n styledTableContainerProps={{\n className: 'DetailsViewTable',\n ref: tableContainerRef,\n height: '100%',\n }}\n onTableContainerScroll={target =>\n fetchMoreOnBottomReached(target as HTMLDivElement)\n }\n table={table}\n rowVirtualizer={rowVirtualizer}\n slotProps={{\n Tr: ownerState => {\n const { tableRow } = ownerState\n\n return {\n className: `EntityFinderDetailsViewRow`,\n ['aria-selected']: tableRow?.original.isSelected,\n ['aria-disabled']: tableRow?.original.isDisabled,\n onClick: () => {\n if (tableRow) {\n onRowClick(tableRow.original)\n }\n },\n }\n },\n }}\n striped\n />\n )}\n {isLoading && (\n <div className=\"EntityFinderDetailsViewPlaceholder\">\n <SynapseSpinner size={30} />\n </div>\n )}\n {!isLoading && entities.length === 0 && (\n <div className=\"EntityFinderDetailsViewPlaceholder\">\n {noResultsPlaceholder || <div>Empty</div>}\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -16,8 +16,8 @@ import { Fragment as l, useCallback as u, useEffect as d, useMemo as f, useState
|
|
|
16
16
|
import { noop as ue, upperFirst as de } from "lodash-es";
|
|
17
17
|
import { Alert as fe, AlertTitle as pe, Box as m, Button as h, IconButton as g, InputLabel as me, TextField as he, Tooltip as ge, Typography as _ } from "@mui/material";
|
|
18
18
|
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
19
|
-
import _e from "
|
|
20
|
-
import ve from "
|
|
19
|
+
import _e from "pluralize";
|
|
20
|
+
import ve from "@mui/icons-material/AddCircleTwoTone";
|
|
21
21
|
import { flexRender as x, getCoreRowModel as ye, getFacetedMinMaxValues as be, getFacetedRowModel as xe, getFacetedUniqueValues as Se, getFilteredRowModel as Ce, getSortedRowModel as S, useReactTable as C } from "@tanstack/react-table";
|
|
22
22
|
import w from "papaparse";
|
|
23
23
|
//#region src/components/EntityHeaderTable/EntityHeaderTable.tsx
|
|
@@ -46,7 +46,7 @@ var { parse: T } = w, E = {
|
|
|
46
46
|
B,
|
|
47
47
|
L,
|
|
48
48
|
z
|
|
49
|
-
]), H = de(
|
|
49
|
+
]), H = de(_e(Te)), U = f(() => [{
|
|
50
50
|
id: "select",
|
|
51
51
|
header: ae,
|
|
52
52
|
cell: ie
|
|
@@ -296,7 +296,7 @@ var { parse: T } = w, E = {
|
|
|
296
296
|
variant: "outlined",
|
|
297
297
|
onClick: je,
|
|
298
298
|
disabled: q || I.trim().length == 0 || O,
|
|
299
|
-
startIcon: /* @__PURE__ */ y(
|
|
299
|
+
startIcon: /* @__PURE__ */ y(ve, {}),
|
|
300
300
|
children: ["Add ", H]
|
|
301
301
|
})
|
|
302
302
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/EntityHeaderTable/Filter.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAGrD,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;CAClB,
|
|
1
|
+
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/EntityHeaderTable/Filter.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAGrD,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,KAAK,GACN,EAAE;IACD,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;CAClB,2CA2BA"}
|
|
@@ -6,7 +6,7 @@ function r({ column: r, table: i }) {
|
|
|
6
6
|
let a = i.getPreFilteredRowModel().flatRows[0]?.getValue(r.id), o = r.getFilterValue() ?? "";
|
|
7
7
|
return /* @__PURE__ */ n(e, {
|
|
8
8
|
type: "text",
|
|
9
|
-
options: t(() => typeof a == "number" ? [] : Array.from(r.getFacetedUniqueValues().keys()).
|
|
9
|
+
options: t(() => typeof a == "number" ? [] : Array.from(r.getFacetedUniqueValues().keys(), String).toSorted((e, t) => e.localeCompare(t)), [r.getFacetedUniqueValues()]),
|
|
10
10
|
initialValue: o,
|
|
11
11
|
onChange: (e) => r.setFilterValue(e),
|
|
12
12
|
label: `Filter by ${r.columnDef.header} (${r.getFacetedUniqueValues().size})`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filter.js","names":[],"sources":["../../../src/components/EntityHeaderTable/Filter.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { Column, Table } from '@tanstack/react-table'\nimport { DebouncedInput } from './DebouncedInput'\n\nexport function Filter({\n column,\n table,\n}: {\n column: Column<any, unknown>\n table: Table<any>\n}) {\n const firstValue = table\n .getPreFilteredRowModel()\n .flatRows[0]?.getValue(column.id)\n\n const columnFilterValue = (column.getFilterValue() as string) ?? ''\n\n const sortedUniqueValues: string[] = useMemo(\n () =>\n typeof firstValue === 'number'\n ? []\n : Array.from(column.getFacetedUniqueValues().keys()).
|
|
1
|
+
{"version":3,"file":"Filter.js","names":[],"sources":["../../../src/components/EntityHeaderTable/Filter.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { Column, Table } from '@tanstack/react-table'\nimport { DebouncedInput } from './DebouncedInput'\n\nexport function Filter({\n column,\n table,\n}: {\n column: Column<any, unknown>\n table: Table<any>\n}) {\n const firstValue = table\n .getPreFilteredRowModel()\n .flatRows[0]?.getValue(column.id)\n\n const columnFilterValue = (column.getFilterValue() as string) ?? ''\n\n const sortedUniqueValues: string[] = useMemo(\n () =>\n typeof firstValue === 'number'\n ? []\n : Array.from(column.getFacetedUniqueValues().keys(), String).toSorted(\n (a, b) => a.localeCompare(b),\n ),\n [column.getFacetedUniqueValues()],\n )\n return (\n <DebouncedInput\n type=\"text\"\n options={sortedUniqueValues}\n initialValue={columnFilterValue}\n onChange={value => column.setFilterValue(value)}\n label={`Filter by ${column.columnDef.header} (${\n column.getFacetedUniqueValues().size\n })`}\n />\n )\n}\n"],"mappings":";;;;AAIA,SAAgB,EAAO,EACrB,WACA,YAIC;CACD,IAAM,IAAa,EAChB,uBAAuB,EACvB,SAAS,IAAI,SAAS,EAAO,EAAE,GAE5B,IAAqB,EAAO,eAAe,KAAgB;CAWjE,OACE,kBAAC,GAAD;EACE,MAAK;EACL,SAZiC,QAEjC,OAAO,KAAe,WAClB,CAAC,IACD,MAAM,KAAK,EAAO,uBAAuB,EAAE,KAAK,GAAG,MAAM,EAAE,UACxD,GAAG,MAAM,EAAE,cAAc,CAAC,CAC7B,GACN,CAAC,EAAO,uBAAuB,CAAC,CAKrB;EACT,cAAc;EACd,WAAU,MAAS,EAAO,eAAe,CAAK;EAC9C,OAAO,aAAa,EAAO,UAAU,OAAO,IAC1C,EAAO,uBAAuB,EAAE,KACjC;CACF,CAAA;AAEL"}
|