synapse-react-client 4.0.45 → 4.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.js +1 -1
- package/dist/aridhia-queries/AridhiaKeyFactory.d.ts +1 -0
- package/dist/aridhia-queries/AridhiaKeyFactory.d.ts.map +1 -1
- package/dist/aridhia-queries/AridhiaKeyFactory.js +3 -0
- package/dist/aridhia-queries/AridhiaKeyFactory.js.map +1 -1
- package/dist/aridhia-queries/aridhiaTokenExchange.js +6 -6
- package/dist/aridhia-queries/index.d.ts +1 -0
- package/dist/aridhia-queries/index.d.ts.map +1 -1
- package/dist/aridhia-queries/index.js +11 -10
- package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.d.ts +19 -0
- package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.d.ts.map +1 -0
- package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.js +14 -0
- package/dist/aridhia-queries/useGetAridhiaVocabularyTerm.js.map +1 -0
- package/dist/components/AccessRequirementList/AccessApprovalCheckMark.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js +6 -4
- package/dist/components/AccessRequirementList/AccessApprovalCheckMark.js.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/AccessorRequirementHelpText.js +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/AccessorRequirementHelpText.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewCollaboratorsAndSigningOfficialAccordion.js +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewCollaboratorsAndSigningOfficialAccordion.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js +11 -8
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js.map +1 -1
- package/dist/components/AccessTokenPage/AccessTokenPage.js +1 -1
- package/dist/components/AccessTokenPage/AccessTokenPage.js.map +1 -1
- package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js +1 -1
- package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSectionForm.d.ts.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSectionForm.js +17 -13
- package/dist/components/Aridhia/DarWizard/DarSectionForm.js.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts +3 -3
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.d.ts.map +1 -1
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js +33 -34
- package/dist/components/Aridhia/DarWizard/DarSubmittedPanel.js.map +1 -1
- package/dist/components/Aridhia/fairFormToRjsf.js +1 -1
- package/dist/components/Aridhia/fairFormToRjsf.js.map +1 -1
- package/dist/components/Authentication/LastLoginInfo.js +1 -1
- package/dist/components/Authentication/LastLoginInfo.js.map +1 -1
- package/dist/components/CertificationQuiz/CertificationQuiz.js +1 -1
- package/dist/components/CertificationQuiz/CertificationQuiz.js.map +1 -1
- package/dist/components/ChallengeSubmission/AvailableEvaluationQueueList.js +1 -1
- package/dist/components/ChallengeSubmission/AvailableEvaluationQueueList.js.map +1 -1
- package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js +1 -1
- package/dist/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.js.map +1 -1
- package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js +6 -6
- package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
- package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.d.ts.map +1 -1
- package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.js +4 -4
- package/dist/components/ChallengeTeamWizard/ChallengeTeamTable.js.map +1 -1
- package/dist/components/ChallengeTeamWizard/SelectChallengeTeam.js +4 -4
- package/dist/components/CitationPopover/CitationPopoverContent.js +4 -4
- package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
- package/dist/components/ComponentCollapse.d.ts.map +1 -1
- package/dist/components/ComponentCollapse.js +2 -1
- package/dist/components/ComponentCollapse.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +231 -219
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/SyncGridWithSourceButton.d.ts.map +1 -1
- package/dist/components/DataGrid/SyncGridWithSourceButton.js +5 -4
- package/dist/components/DataGrid/SyncGridWithSourceButton.js.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js +7 -5
- package/dist/components/DataGrid/components/ColumnHeaderWithTooltip.js.map +1 -1
- package/dist/components/DataGrid/components/ExportCsvFromGridButton.js +4 -4
- package/dist/components/DataGrid/components/ExportCsvFromGridButton.js.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsButton.js +4 -4
- package/dist/components/DataGrid/components/ReorderColumnsButton.js.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsDialog.d.ts.map +1 -1
- package/dist/components/DataGrid/components/ReorderColumnsDialog.js +12 -8
- package/dist/components/DataGrid/components/ReorderColumnsDialog.js.map +1 -1
- package/dist/components/DataGrid/components/UploadCsvToGridButton.js +1 -1
- package/dist/components/DataGrid/components/UploadCsvToGridButton.js.map +1 -1
- package/dist/components/DataGrid/hooks/useGridUndoRedo.js +5 -5
- package/dist/components/DataGrid/utils/applyModelChange.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/applyModelChange.js +14 -14
- package/dist/components/DataGrid/utils/applyModelChange.js.map +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js +1 -1
- package/dist/components/DataGrid/utils/columnFactory.js.map +1 -1
- package/dist/components/DataGrid/utils/splitPatch.d.ts.map +1 -1
- package/dist/components/DataGrid/utils/splitPatch.js +22 -13
- package/dist/components/DataGrid/utils/splitPatch.js.map +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.js +1 -1
- package/dist/components/DownloadCart/DownloadCartPage.js.map +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.d.ts.map +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js +2 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.js.map +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.js.map +1 -1
- package/dist/components/DownloadCart/DownloadIneligibleForPackagingFilesFromListButton.module.scss +1 -3
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.d.ts.map +1 -1
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js +16 -10
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
- package/dist/components/EntityDownloadButton/EntityDownloadButton.js +1 -1
- package/dist/components/EntityDownloadButton/EntityDownloadButton.js.map +1 -1
- package/dist/components/EntityFinder/EntityFinder.js +4 -4
- package/dist/components/EntityFinder/EntityIdTextField.js +1 -1
- package/dist/components/EntityFinder/EntityIdTextField.js.map +1 -1
- package/dist/components/EntityFinder/tree/VirtualizedTree.d.ts.map +1 -1
- package/dist/components/EntityFinder/tree/VirtualizedTree.js +5 -4
- package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
- package/dist/components/EntityHeaderTable/EntityHeaderTable.js +1 -1
- package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityNameCell.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityNameCell.js +2 -1
- package/dist/components/EntityTreeTable/components/EntityNameCell.js.map +1 -1
- package/dist/components/EntityUpload/FileUploadProgress.d.ts.map +1 -1
- package/dist/components/EntityUpload/FileUploadProgress.js +11 -7
- package/dist/components/EntityUpload/FileUploadProgress.js.map +1 -1
- package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.d.ts.map +1 -1
- package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.js +4 -3
- package/dist/components/Evaluation/round_limits/EvaluationRoundLimitOptionsList.js.map +1 -1
- package/dist/components/ExperimentalMode/ExperimentalMode.js +1 -1
- package/dist/components/ExperimentalMode/ExperimentalMode.js.map +1 -1
- package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js +1 -1
- package/dist/components/ExternalFileHandleLink/ExternalFileHandleLink.js.map +1 -1
- package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.js +2 -1
- package/dist/components/FormTemplateEditor/ChoiceOptionsEditor.js.map +1 -1
- package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.js +2 -1
- package/dist/components/FormTemplateEditor/FieldDefinitionDrawer.js.map +1 -1
- package/dist/components/FormTemplateEditor/FieldLibrary.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/FieldLibrary.js +2 -1
- package/dist/components/FormTemplateEditor/FieldLibrary.js.map +1 -1
- package/dist/components/FormTemplateEditor/FieldLibraryRow.js +4 -4
- package/dist/components/FormTemplateEditor/FieldLibraryRow.js.map +1 -1
- package/dist/components/FormTemplateEditor/FormStructurePanel.js +1 -1
- package/dist/components/FormTemplateEditor/FormStructurePanel.js.map +1 -1
- package/dist/components/FormTemplateEditor/FormTemplateEditorForm.js +1 -1
- package/dist/components/FormTemplateEditor/FormTemplateEditorForm.js.map +1 -1
- package/dist/components/FormTemplateEditor/StepCard.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/StepCard.js +15 -10
- package/dist/components/FormTemplateEditor/StepCard.js.map +1 -1
- package/dist/components/FormTemplateEditor/StepFieldRow.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/StepFieldRow.js +11 -6
- package/dist/components/FormTemplateEditor/StepFieldRow.js.map +1 -1
- package/dist/components/FormTemplateEditor/TemplateFileHandleField.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/TemplateFileHandleField.js +2 -1
- package/dist/components/FormTemplateEditor/TemplateFileHandleField.js.map +1 -1
- package/dist/components/GenericCard/DuoTermTags/DuoTermTags.js +45 -45
- package/dist/components/GenericCard/PortalDOI/PortalDOI.js +5 -5
- package/dist/components/GenericCard/PortalDOI/PortalDOI.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/HelpPopover/HelpPopover.js +1 -1
- package/dist/components/HelpPopover/HelpPopover.js.map +1 -1
- package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
- package/dist/components/IconSvg/IconSvg.js +154 -47
- package/dist/components/IconSvg/IconSvg.js.map +1 -1
- package/dist/components/JsonSchemaForm/templates/ButtonTemplate.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/templates/ButtonTemplate.js +19 -16
- package/dist/components/JsonSchemaForm/templates/ButtonTemplate.js.map +1 -1
- package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js +2 -1
- package/dist/components/JsonSchemaForm/templates/RJSFInputLabel.js.map +1 -1
- package/dist/components/JsonSchemaForm/widgets/PhoneWidget.d.ts +9 -0
- package/dist/components/JsonSchemaForm/widgets/PhoneWidget.d.ts.map +1 -0
- package/dist/components/JsonSchemaForm/widgets/PhoneWidget.js +21 -0
- package/dist/components/JsonSchemaForm/widgets/PhoneWidget.js.map +1 -0
- package/dist/components/Markdown/MarkdownCollapse.d.ts.map +1 -1
- package/dist/components/Markdown/MarkdownCollapse.js +3 -1
- package/dist/components/Markdown/MarkdownCollapse.js.map +1 -1
- package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js +1 -1
- package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
- package/dist/components/OAuthClientManagement/OAuthManagement.js +14 -13
- package/dist/components/OAuthClientManagement/OAuthManagement.js.map +1 -1
- package/dist/components/PortalList/PortalCard.d.ts.map +1 -1
- package/dist/components/PortalList/PortalCard.js +6 -5
- package/dist/components/PortalList/PortalCard.js.map +1 -1
- package/dist/components/PortalList/PortalList.js +4 -4
- package/dist/components/PortalList/PortalList.js.map +1 -1
- package/dist/components/ProjectVisibilityChip/ProjectVisibilityChip.js +6 -6
- package/dist/components/QueryBuilder/FilterConditionRow.js +4 -4
- package/dist/components/QueryCountButton/QueryCountButton.js +5 -5
- package/dist/components/QueryCountButton/QueryCountButton.js.map +1 -1
- package/dist/components/ReleaseCard/ReleaseCardLarge.js +5 -5
- package/dist/components/ReleaseCard/ReleaseCardLarge.js.map +1 -1
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js +1 -1
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
- package/dist/components/ShareThisPage/ShareThisPage.js +4 -4
- package/dist/components/ShareThisPage/ShareThisPage.js.map +1 -1
- package/dist/components/SustainabilityScorecard/DialLayout.js +1 -1
- package/dist/components/SustainabilityScorecard/DialLayout.js.map +1 -1
- package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js +1 -1
- package/dist/components/SustainabilityScorecard/SustainabilityScorecard.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.js +1 -1
- package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.js +2 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js +1 -1
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js.map +1 -1
- package/dist/components/SynapseFooter/SynapseFooter.js +1 -1
- package/dist/components/SynapseFooter/SynapseFooter.js.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseFeaturedDatasetItem.js +1 -1
- package/dist/components/SynapseHomepageV2/SynapseFeaturedDatasetItem.js.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.d.ts.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.js +2 -1
- package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.js.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseInActionItem.js +4 -4
- package/dist/components/SynapseHomepageV2/SynapseInActionItem.js.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseTrendingProjectsItem.js +1 -1
- package/dist/components/SynapseHomepageV2/SynapseTrendingProjectsItem.js.map +1 -1
- package/dist/components/SynapseNavDrawer/SynapseNavDrawer.d.ts.map +1 -1
- package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js +4 -1
- package/dist/components/SynapseNavDrawer/SynapseNavDrawer.js.map +1 -1
- package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js +1 -1
- package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchPageResults.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.d.ts.map +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.js +12 -9
- package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.js.map +1 -1
- package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js +4 -4
- package/dist/components/SynapseTable/RowSelection/RowSelectionControls.js.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +140 -140
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.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/ImportTableColumnsButton.js +1 -1
- package/dist/components/TableColumnSchemaEditor/ImportTableColumnsButton.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditorUtils.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js +9 -9
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.d.ts.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.js +6 -4
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaFormActions.js.map +1 -1
- package/dist/components/TanStackTable/ColumnHeader.js +1 -1
- package/dist/components/TanStackTable/ColumnHeader.js.map +1 -1
- package/dist/components/TeamSubjectsSelector/TeamBadgeOrError.js +1 -1
- package/dist/components/TeamSubjectsSelector/TeamBadgeOrError.js.map +1 -1
- package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.d.ts.map +1 -1
- package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js +4 -3
- package/dist/components/TeamSubjectsSelector/TeamSubjectsSelector.js.map +1 -1
- package/dist/components/Webhook/WebhookDashboard.js +1 -1
- package/dist/components/Webhook/WebhookDashboard.js.map +1 -1
- package/dist/components/dataaccess/AccessRequirementDashboard.js +4 -4
- package/dist/components/dataaccess/AccessRequirementDashboard.js.map +1 -1
- package/dist/components/dataaccess/AccessRequirementTable.js +1 -1
- package/dist/components/dataaccess/AccessRequirementTable.js.map +1 -1
- package/dist/components/dataaccess/EDucTemplateTable.d.ts.map +1 -1
- package/dist/components/dataaccess/EDucTemplateTable.js +13 -11
- package/dist/components/dataaccess/EDucTemplateTable.js.map +1 -1
- package/dist/components/dataaccess/FormTemplateTable.js +6 -6
- package/dist/components/dataaccess/FormTemplateTable.js.map +1 -1
- package/dist/components/dataaccess/ReviewerDashboard.js +17 -17
- package/dist/components/dataaccess/ReviewerDashboard.js.map +1 -1
- package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +4 -4
- package/dist/components/doi/CreateOrUpdateDoiModal.js +1 -1
- package/dist/components/doi/CreateOrUpdateDoiModal.js.map +1 -1
- package/dist/components/download_list/DownloadDetails.d.ts.map +1 -1
- package/dist/components/download_list/DownloadDetails.js +12 -10
- package/dist/components/download_list/DownloadDetails.js.map +1 -1
- package/dist/components/entity/metadata/AnnotationsTable.js +1 -1
- package/dist/components/entity/metadata/AnnotationsTable.js.map +1 -1
- package/dist/components/entity/page/CreatedByModifiedBy.js +1 -1
- package/dist/components/entity/page/CreatedByModifiedBy.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js.map +1 -1
- package/dist/components/error/ErrorChip.d.ts.map +1 -1
- package/dist/components/error/ErrorChip.js +2 -1
- package/dist/components/error/ErrorChip.js.map +1 -1
- package/dist/components/table/CsvPreview/CreateTableFromCsvDialog.js +14 -14
- package/dist/components/table/CsvPreview/CsvPreviewWithOptions.js +4 -4
- package/dist/components/table/CsvPreview/CsvPreviewWithOptions.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
- package/dist/features/curator/dashboard/components/NextStepButton.d.ts.map +1 -1
- package/dist/features/curator/dashboard/components/NextStepButton.js +7 -6
- package/dist/features/curator/dashboard/components/NextStepButton.js.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +8 -8
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +4 -4
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +4 -4
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -1
- package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js +4 -4
- package/dist/features/entity/metadata-task/create-task/CurateTaskForm.js.map +1 -1
- package/dist/features/entity/metadata-task/create-task/TaskCategoryCard.js +1 -1
- package/dist/features/entity/metadata-task/create-task/TaskCategoryCard.js.map +1 -1
- package/dist/features/entity/metadata-task/create-task/TaskFormHeader.js +1 -1
- package/dist/features/entity/metadata-task/create-task/TaskFormHeader.js.map +1 -1
- package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js +10 -10
- package/dist/features/entity/metadata-task/create-task/curationTaskFlowRoutes.js.map +1 -1
- package/dist/features/team/invitation/components/OpenInvitationsToUserCard.js +1 -1
- package/dist/features/team/invitation/components/OpenInvitationsToUserCard.js.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts +8 -0
- package/dist/mocks/msw/handlers/aridhiaHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/aridhiaHandlers.js +52 -41
- package/dist/mocks/msw/handlers/aridhiaHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/entityHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/entityHandlers.js +70 -67
- package/dist/mocks/msw/handlers/entityHandlers.js.map +1 -1
- package/dist/mocks/msw/handlers/gridHandlers.js +2 -2
- package/dist/mocks/msw/handlers/gridHandlers.js.map +1 -1
- package/dist/mocks/msw/server.d.ts.map +1 -1
- package/dist/mocks/msw/server.js +4 -2
- package/dist/mocks/msw/server.js.map +1 -1
- package/dist/synapse-queries/user/useGetUserChallenges.d.ts.map +1 -1
- package/dist/synapse-queries/user/useGetUserChallenges.js.map +1 -1
- package/dist/theme/DefaultTheme.d.ts.map +1 -1
- package/dist/theme/DefaultTheme.js +4 -1
- package/dist/theme/DefaultTheme.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/APIConstants.d.ts.map +1 -1
- package/dist/utils/APIConstants.js.map +1 -1
- package/dist/utils/AppUtils/AppUtils.js +1 -1
- package/dist/utils/AppUtils/AppUtils.js.map +1 -1
- package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
- package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
- package/package.json +7 -6
|
@@ -16,7 +16,7 @@ import { Alert as m, AlertTitle as h, Box as g, Button as _, Link as v, Skeleton
|
|
|
16
16
|
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
17
17
|
import { MULTICHOICE_RESPONSE_CONCRETE_TYPE_VALUE as w } from "@sage-bionetworks/synapse-types";
|
|
18
18
|
import { useErrorHandler as T } from "react-error-boundary";
|
|
19
|
-
import
|
|
19
|
+
import E from "@mui/icons-material/HelpOutlineTwoTone";
|
|
20
20
|
import D from "dayjs";
|
|
21
21
|
//#region src/components/CertificationQuiz/CertificationQuiz.tsx
|
|
22
22
|
function O() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertificationQuiz.js","names":[],"sources":["../../../src/components/CertificationQuiz/CertificationQuiz.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport {\n useGetPassingRecord,\n usePostCertifiedUserTestResponse,\n} from '@/synapse-queries/user/useCertificationQuiz'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { USER_BUNDLE_MASK_IS_CERTIFIED } from '@/utils/SynapseConstants'\nimport { HelpOutlineTwoTone } from '@mui/icons-material'\nimport {\n Alert,\n AlertTitle,\n Box,\n Button,\n ButtonProps,\n Link,\n Skeleton,\n Typography,\n} from '@mui/material'\nimport {\n MULTICHOICE_RESPONSE_CONCRETE_TYPE_VALUE,\n MultichoiceQuestion,\n MultichoiceResponse,\n QuestionResponse,\n Quiz,\n QuizResponse,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { ReactNode, useEffect, useRef, useState } from 'react'\nimport { useErrorHandler } from 'react-error-boundary'\nimport { MarkdownPopover } from '../Markdown/MarkdownPopover'\nimport { SkeletonParagraph, SkeletonTable } from '../Skeleton'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport CertificationAnswer from './CertificationAnswer'\n\nfunction CertificationQuiz() {\n const { accessToken, isAuthenticated } = useSynapseContext()\n const handleError = useErrorHandler()\n const [quiz, setQuiz] = useState<Quiz | undefined>()\n const [isRetakingQuiz, setIsRetakingQuiz] = useState(false)\n const [questionResponse, setQuestionResponse] = useState<QuestionResponse[]>(\n [],\n )\n const { data: currentUserBundle } = useGetCurrentUserBundle(\n USER_BUNDLE_MASK_IS_CERTIFIED,\n )\n const isCertified = currentUserBundle?.isCertified\n const userId = currentUserBundle?.userId\n const { data: passingRecord, isLoading: isLoadingPassingRecord } =\n useGetPassingRecord(userId, {\n enabled: userId !== undefined,\n })\n const formRef = useRef<HTMLFormElement>(null)\n const GETTING_STARTED_URL =\n 'https://help.synapse.org/docs/Getting-Started.2055471150.html'\n\n const getQuiz = async () => {\n try {\n setQuiz(await SynapseClient.getCertifyQuiz(accessToken))\n } catch (err: any) {\n handleError(err)\n }\n }\n\n const { mutate: postCertifiedUserTestResponse, isPending: isSubmitting } =\n usePostCertifiedUserTestResponse({\n onSuccess: () => {\n setIsRetakingQuiz(false)\n window.scrollTo(0, 0)\n },\n throwOnError: true,\n })\n // user is taking the quiz if user is not certified, and either there is no passing record or if the user clicked to retake the quiz\n const isTakingQuiz = !isCertified && (passingRecord == null || isRetakingQuiz)\n useEffect(() => {\n if (isAuthenticated) {\n getQuiz()\n }\n }, [isAuthenticated])\n\n if (isLoadingPassingRecord || quiz == undefined) {\n return <CertificationQuizSkeleton />\n }\n\n const onUpdateAnswer = (questionIndex: number, answer: number) => {\n const newState = [\n ...questionResponse.filter(obj => obj.questionIndex !== questionIndex),\n {\n questionIndex,\n answerIndex: [answer],\n concreteType: MULTICHOICE_RESPONSE_CONCRETE_TYPE_VALUE,\n },\n ]\n setQuestionResponse(newState)\n }\n\n const handleRetakeQuiz = () => {\n formRef.current?.reset()\n setIsRetakingQuiz(true)\n setQuestionResponse([])\n getQuiz()\n }\n\n const handleSubmit = () => {\n try {\n if (quiz && quiz.questions.length === questionResponse.length) {\n const quizResponse: QuizResponse = {\n quizId: quiz.id,\n questionResponses: questionResponse,\n }\n postCertifiedUserTestResponse(quizResponse)\n } else {\n displayToast(\n 'Please answer all of the questions and try again.',\n 'warning',\n )\n }\n } catch (err: any) {\n displayToast(err.reason as string, 'danger')\n }\n }\n\n const actionButtonConfig = (helpUrl: string) =>\n helpUrl\n ? {\n content: <>More info</>,\n closePopoverOnClick: true,\n onClick: () => window.open(helpUrl, '_blank'),\n color: 'primary' as ButtonProps['color'],\n }\n : undefined\n return (\n <div>\n {passingRecord && !isTakingQuiz && (\n <>\n {(passingRecord.revokedOn || passingRecord.passed) &&\n !isCertified && (\n <Alert severity=\"error\">\n {!passingRecord.passed && (\n <AlertTitle>Certification Revoked</AlertTitle>\n )}\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n Your certification was revoked. To become certified, you must{' '}\n <Link\n href=\"#\"\n onClick={e => {\n e.preventDefault()\n handleRetakeQuiz()\n }}\n >\n retake the quiz\n </Link>\n .\n </Typography>\n </Alert>\n )}\n {!passingRecord.passed && !isCertified && (\n <Alert severity=\"error\">\n {!passingRecord.passed && <AlertTitle>Quiz Failed</AlertTitle>}\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n Please review the results from the previous attempt, and{' '}\n <Link\n href=\"#\"\n onClick={e => {\n e.preventDefault()\n handleRetakeQuiz()\n }}\n >\n retake the quiz\n </Link>\n .\n </Typography>\n </Alert>\n )}\n {passingRecord.passed && isCertified && (\n <Alert severity=\"success\">\n <AlertTitle>Quiz Passed</AlertTitle>\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n {`You passed the Synapse Certification Quiz on ${formatDate(\n dayjs(passingRecord.passedOn),\n )}`}\n </Typography>\n </Alert>\n )}\n <Typography\n variant=\"sectionTitle\"\n sx={{ marginTop: '20px', marginBottom: '20px' }}\n >\n Score: {passingRecord.score} / {passingRecord.corrections?.length}\n </Typography>\n </>\n )}\n <div className=\"CertificationQuiz__container\">\n {quiz && isTakingQuiz && (\n <>\n <Button\n onClick={() => window.open(GETTING_STARTED_URL, '_blank')}\n className=\"help-button\"\n color=\"primary\"\n variant=\"contained\"\n >\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <HelpOutlineTwoTone\n className=\"HelpButton\"\n style={{ marginRight: '4px', color: 'white' }}\n />\n <>Help</>\n </Box>\n </Button>\n <Typography variant=\"headline1\" sx={{ marginBottom: '25px' }}>\n Certified User Quiz\n </Typography>\n <Typography variant=\"body1\" sx={{ marginBottom: '15px' }}>\n Certified users are authorized to use the full Synapse\n functionality. In order to ensure that users who create content in\n the system and/or wish to interact more freely within Synapse are\n familiar with the governance process and Synapse operating\n procedures when dealing with possibly sensitive data, users must\n pass a short quiz (approximately 15 minutes) to become Synapse\n certified.\n </Typography>\n <Typography variant=\"body1\" sx={{ marginBottom: '15px' }}>\n Please answer the following questions to become certified.\n </Typography>\n <form ref={formRef} onSubmit={e => e.preventDefault()}>\n <ol>\n {quiz?.questions.map(question => {\n const isHelp = question.helpText || question.docLink\n return (\n <li\n key={question.questionIndex}\n role={question.exclusive ? 'radiogroup' : undefined}\n >\n <Typography\n variant={'headline3'}\n dangerouslySetInnerHTML={{ __html: question.prompt }}\n sx={{ marginTop: '40px', marginBottom: '10px' }}\n />\n {question.answers.map(choice => (\n <CertificationAnswer\n key={`${question.questionIndex}-${choice.answerIndex}`}\n question={question}\n answer={choice}\n onClick={e =>\n onUpdateAnswer(\n question.questionIndex,\n Number(e.currentTarget.value),\n )\n }\n />\n ))}\n {isHelp && (\n <MarkdownPopover\n contentProps={{ markdown: question.helpText }}\n placement=\"right\"\n sx={{\n table: {\n textAlign: 'center',\n th: {\n padding: '5px',\n },\n },\n }}\n actionButton={actionButtonConfig(question.docLink)}\n showCloseButton={true}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n marginTop: '10px',\n }}\n >\n <HelpOutlineTwoTone\n className=\"HelpButton\"\n style={{ marginRight: '4px' }}\n />\n <Link>Need help answering this question?</Link>\n </Box>\n </MarkdownPopover>\n )}\n </li>\n )\n })}\n </ol>\n </form>\n <Button\n className=\"help-button\"\n color=\"primary\"\n variant=\"contained\"\n size=\"large\"\n disabled={isSubmitting}\n onClick={() => {\n handleSubmit()\n }}\n >\n Submit\n </Button>\n </>\n )}\n\n {!isTakingQuiz && passingRecord?.corrections && (\n <ol>\n {passingRecord.corrections.map(responseCorrectness => {\n const question =\n responseCorrectness.question as MultichoiceQuestion\n const response =\n responseCorrectness.response as MultichoiceResponse\n return (\n <li key={question.questionIndex}>\n <Typography\n variant={'headline3'}\n dangerouslySetInnerHTML={{ __html: question.prompt }}\n className={\n responseCorrectness.isCorrect ? '' : 'incorrectQuestion'\n }\n sx={{ marginTop: '40px', marginBottom: '10px' }}\n />\n {question.answers.map(choice => (\n <CertificationAnswer\n key={`${question.questionIndex}-${choice.answerIndex}`}\n question={question}\n answer={choice}\n disabled={true}\n checked={response.answerIndex.includes(\n choice.answerIndex,\n )}\n />\n ))}\n </li>\n )\n })}\n </ol>\n )}\n </div>\n </div>\n )\n}\n\nfunction CertificationQuizSkeleton() {\n const questions: ReactNode[] = []\n for (let i = 0; i < 20; i++) {\n questions.push(\n <li key={i}>\n <SkeletonTable numCols={1} numRows={5} />\n </li>,\n )\n }\n return (\n <>\n <div>\n <Skeleton height=\"80px\" width=\"460px\" />\n </div>\n <SkeletonParagraph numRows={5} />\n <div className=\"CertificationQuiz__container\">\n <ol style={{ marginTop: '20px' }}>{questions}</ol>\n </div>\n </>\n )\n}\n\nexport default CertificationQuiz\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CertificationQuiz.js","names":[],"sources":["../../../src/components/CertificationQuiz/CertificationQuiz.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport {\n useGetPassingRecord,\n usePostCertifiedUserTestResponse,\n} from '@/synapse-queries/user/useCertificationQuiz'\nimport { useSynapseContext } from '@/utils/context/SynapseContext'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport { USER_BUNDLE_MASK_IS_CERTIFIED } from '@/utils/SynapseConstants'\nimport HelpOutlineTwoTone from '@mui/icons-material/HelpOutlineTwoTone'\nimport {\n Alert,\n AlertTitle,\n Box,\n Button,\n ButtonProps,\n Link,\n Skeleton,\n Typography,\n} from '@mui/material'\nimport {\n MULTICHOICE_RESPONSE_CONCRETE_TYPE_VALUE,\n MultichoiceQuestion,\n MultichoiceResponse,\n QuestionResponse,\n Quiz,\n QuizResponse,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { ReactNode, useEffect, useRef, useState } from 'react'\nimport { useErrorHandler } from 'react-error-boundary'\nimport { MarkdownPopover } from '../Markdown/MarkdownPopover'\nimport { SkeletonParagraph, SkeletonTable } from '../Skeleton'\nimport { displayToast } from '../ToastMessage/ToastMessage'\nimport CertificationAnswer from './CertificationAnswer'\n\nfunction CertificationQuiz() {\n const { accessToken, isAuthenticated } = useSynapseContext()\n const handleError = useErrorHandler()\n const [quiz, setQuiz] = useState<Quiz | undefined>()\n const [isRetakingQuiz, setIsRetakingQuiz] = useState(false)\n const [questionResponse, setQuestionResponse] = useState<QuestionResponse[]>(\n [],\n )\n const { data: currentUserBundle } = useGetCurrentUserBundle(\n USER_BUNDLE_MASK_IS_CERTIFIED,\n )\n const isCertified = currentUserBundle?.isCertified\n const userId = currentUserBundle?.userId\n const { data: passingRecord, isLoading: isLoadingPassingRecord } =\n useGetPassingRecord(userId, {\n enabled: userId !== undefined,\n })\n const formRef = useRef<HTMLFormElement>(null)\n const GETTING_STARTED_URL =\n 'https://help.synapse.org/docs/Getting-Started.2055471150.html'\n\n const getQuiz = async () => {\n try {\n setQuiz(await SynapseClient.getCertifyQuiz(accessToken))\n } catch (err: any) {\n handleError(err)\n }\n }\n\n const { mutate: postCertifiedUserTestResponse, isPending: isSubmitting } =\n usePostCertifiedUserTestResponse({\n onSuccess: () => {\n setIsRetakingQuiz(false)\n window.scrollTo(0, 0)\n },\n throwOnError: true,\n })\n // user is taking the quiz if user is not certified, and either there is no passing record or if the user clicked to retake the quiz\n const isTakingQuiz = !isCertified && (passingRecord == null || isRetakingQuiz)\n useEffect(() => {\n if (isAuthenticated) {\n getQuiz()\n }\n }, [isAuthenticated])\n\n if (isLoadingPassingRecord || quiz == undefined) {\n return <CertificationQuizSkeleton />\n }\n\n const onUpdateAnswer = (questionIndex: number, answer: number) => {\n const newState = [\n ...questionResponse.filter(obj => obj.questionIndex !== questionIndex),\n {\n questionIndex,\n answerIndex: [answer],\n concreteType: MULTICHOICE_RESPONSE_CONCRETE_TYPE_VALUE,\n },\n ]\n setQuestionResponse(newState)\n }\n\n const handleRetakeQuiz = () => {\n formRef.current?.reset()\n setIsRetakingQuiz(true)\n setQuestionResponse([])\n getQuiz()\n }\n\n const handleSubmit = () => {\n try {\n if (quiz && quiz.questions.length === questionResponse.length) {\n const quizResponse: QuizResponse = {\n quizId: quiz.id,\n questionResponses: questionResponse,\n }\n postCertifiedUserTestResponse(quizResponse)\n } else {\n displayToast(\n 'Please answer all of the questions and try again.',\n 'warning',\n )\n }\n } catch (err: any) {\n displayToast(err.reason as string, 'danger')\n }\n }\n\n const actionButtonConfig = (helpUrl: string) =>\n helpUrl\n ? {\n content: <>More info</>,\n closePopoverOnClick: true,\n onClick: () => window.open(helpUrl, '_blank'),\n color: 'primary' as ButtonProps['color'],\n }\n : undefined\n return (\n <div>\n {passingRecord && !isTakingQuiz && (\n <>\n {(passingRecord.revokedOn || passingRecord.passed) &&\n !isCertified && (\n <Alert severity=\"error\">\n {!passingRecord.passed && (\n <AlertTitle>Certification Revoked</AlertTitle>\n )}\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n Your certification was revoked. To become certified, you must{' '}\n <Link\n href=\"#\"\n onClick={e => {\n e.preventDefault()\n handleRetakeQuiz()\n }}\n >\n retake the quiz\n </Link>\n .\n </Typography>\n </Alert>\n )}\n {!passingRecord.passed && !isCertified && (\n <Alert severity=\"error\">\n {!passingRecord.passed && <AlertTitle>Quiz Failed</AlertTitle>}\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n Please review the results from the previous attempt, and{' '}\n <Link\n href=\"#\"\n onClick={e => {\n e.preventDefault()\n handleRetakeQuiz()\n }}\n >\n retake the quiz\n </Link>\n .\n </Typography>\n </Alert>\n )}\n {passingRecord.passed && isCertified && (\n <Alert severity=\"success\">\n <AlertTitle>Quiz Passed</AlertTitle>\n <Typography variant=\"body1\" sx={{ marginTop: '5px' }}>\n {`You passed the Synapse Certification Quiz on ${formatDate(\n dayjs(passingRecord.passedOn),\n )}`}\n </Typography>\n </Alert>\n )}\n <Typography\n variant=\"sectionTitle\"\n sx={{ marginTop: '20px', marginBottom: '20px' }}\n >\n Score: {passingRecord.score} / {passingRecord.corrections?.length}\n </Typography>\n </>\n )}\n <div className=\"CertificationQuiz__container\">\n {quiz && isTakingQuiz && (\n <>\n <Button\n onClick={() => window.open(GETTING_STARTED_URL, '_blank')}\n className=\"help-button\"\n color=\"primary\"\n variant=\"contained\"\n >\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <HelpOutlineTwoTone\n className=\"HelpButton\"\n style={{ marginRight: '4px', color: 'white' }}\n />\n <>Help</>\n </Box>\n </Button>\n <Typography variant=\"headline1\" sx={{ marginBottom: '25px' }}>\n Certified User Quiz\n </Typography>\n <Typography variant=\"body1\" sx={{ marginBottom: '15px' }}>\n Certified users are authorized to use the full Synapse\n functionality. In order to ensure that users who create content in\n the system and/or wish to interact more freely within Synapse are\n familiar with the governance process and Synapse operating\n procedures when dealing with possibly sensitive data, users must\n pass a short quiz (approximately 15 minutes) to become Synapse\n certified.\n </Typography>\n <Typography variant=\"body1\" sx={{ marginBottom: '15px' }}>\n Please answer the following questions to become certified.\n </Typography>\n <form ref={formRef} onSubmit={e => e.preventDefault()}>\n <ol>\n {quiz?.questions.map(question => {\n const isHelp = question.helpText || question.docLink\n return (\n <li\n key={question.questionIndex}\n role={question.exclusive ? 'radiogroup' : undefined}\n >\n <Typography\n variant={'headline3'}\n dangerouslySetInnerHTML={{ __html: question.prompt }}\n sx={{ marginTop: '40px', marginBottom: '10px' }}\n />\n {question.answers.map(choice => (\n <CertificationAnswer\n key={`${question.questionIndex}-${choice.answerIndex}`}\n question={question}\n answer={choice}\n onClick={e =>\n onUpdateAnswer(\n question.questionIndex,\n Number(e.currentTarget.value),\n )\n }\n />\n ))}\n {isHelp && (\n <MarkdownPopover\n contentProps={{ markdown: question.helpText }}\n placement=\"right\"\n sx={{\n table: {\n textAlign: 'center',\n th: {\n padding: '5px',\n },\n },\n }}\n actionButton={actionButtonConfig(question.docLink)}\n showCloseButton={true}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n marginTop: '10px',\n }}\n >\n <HelpOutlineTwoTone\n className=\"HelpButton\"\n style={{ marginRight: '4px' }}\n />\n <Link>Need help answering this question?</Link>\n </Box>\n </MarkdownPopover>\n )}\n </li>\n )\n })}\n </ol>\n </form>\n <Button\n className=\"help-button\"\n color=\"primary\"\n variant=\"contained\"\n size=\"large\"\n disabled={isSubmitting}\n onClick={() => {\n handleSubmit()\n }}\n >\n Submit\n </Button>\n </>\n )}\n\n {!isTakingQuiz && passingRecord?.corrections && (\n <ol>\n {passingRecord.corrections.map(responseCorrectness => {\n const question =\n responseCorrectness.question as MultichoiceQuestion\n const response =\n responseCorrectness.response as MultichoiceResponse\n return (\n <li key={question.questionIndex}>\n <Typography\n variant={'headline3'}\n dangerouslySetInnerHTML={{ __html: question.prompt }}\n className={\n responseCorrectness.isCorrect ? '' : 'incorrectQuestion'\n }\n sx={{ marginTop: '40px', marginBottom: '10px' }}\n />\n {question.answers.map(choice => (\n <CertificationAnswer\n key={`${question.questionIndex}-${choice.answerIndex}`}\n question={question}\n answer={choice}\n disabled={true}\n checked={response.answerIndex.includes(\n choice.answerIndex,\n )}\n />\n ))}\n </li>\n )\n })}\n </ol>\n )}\n </div>\n </div>\n )\n}\n\nfunction CertificationQuizSkeleton() {\n const questions: ReactNode[] = []\n for (let i = 0; i < 20; i++) {\n questions.push(\n <li key={i}>\n <SkeletonTable numCols={1} numRows={5} />\n </li>,\n )\n }\n return (\n <>\n <div>\n <Skeleton height=\"80px\" width=\"460px\" />\n </div>\n <SkeletonParagraph numRows={5} />\n <div className=\"CertificationQuiz__container\">\n <ol style={{ marginTop: '20px' }}>{questions}</ol>\n </div>\n </>\n )\n}\n\nexport default CertificationQuiz\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoCA,SAAS,IAAoB;CAC3B,IAAM,EAAE,gBAAa,uBAAoB,EAAkB,GACrD,IAAc,EAAgB,GAC9B,CAAC,GAAM,KAAW,EAA2B,GAC7C,CAAC,GAAgB,KAAqB,EAAS,EAAK,GACpD,CAAC,GAAkB,KAAuB,EAC9C,CAAC,CACH,GACM,EAAE,MAAM,MAAsB,EAAA,CAEpC,GACM,IAAc,GAAmB,aACjC,IAAS,GAAmB,QAC5B,EAAE,MAAM,GAAe,WAAW,MACtC,EAAoB,GAAQ,EAC1B,SAAS,MAAW,KAAA,EACtB,CAAC,GACG,IAAU,EAAwB,IAAI,GAItC,IAAU,YAAY;EAC1B,IAAI;GACF,EAAQ,MAAM,EAAc,eAAe,CAAW,CAAC;EACzD,SAAS,GAAU;GACjB,EAAY,CAAG;EACjB;CACF,GAEM,EAAE,QAAQ,GAA+B,WAAW,MACxD,EAAiC;EAC/B,iBAAiB;GAEf,AADA,EAAkB,EAAK,GACvB,OAAO,SAAS,GAAG,CAAC;EACtB;EACA,cAAc;CAChB,CAAC,GAEG,IAAe,CAAC,MAAgB,KAAiB,QAAQ;CAO/D,IANA,QAAgB;EACd,AAAI,KACF,EAAQ;CAEZ,GAAG,CAAC,CAAe,CAAC,GAEhB,KAA0B,KAAQ,MACpC,OAAO,kBAAC,GAAD,CAA4B,CAAA;CAGrC,IAAM,KAAkB,GAAuB,MAAmB;EAShE,EAAoB,CAPlB,GAAG,EAAiB,QAAO,MAAO,EAAI,kBAAkB,CAAa,GACrE;GACE;GACA,aAAa,CAAC,CAAM;GACpB,cAAc;EAChB,CAEkB,CAAQ;CAC9B,GAEM,UAAyB;EAI7B,AAHA,EAAQ,SAAS,MAAM,GACvB,EAAkB,EAAI,GACtB,EAAoB,CAAC,CAAC,GACtB,EAAQ;CACV,GAEM,UAAqB;EACzB,IAAI;GACF,AAAI,KAAQ,EAAK,UAAU,WAAW,EAAiB,SAKrD,EAA8B;IAH5B,QAAQ,EAAK;IACb,mBAAmB;GAES,CAAY,IAE1C,EACE,qDACA,SACF;EAEJ,SAAS,GAAU;GACjB,EAAa,EAAI,QAAkB,QAAQ;EAC7C;CACF,GAEM,KAAsB,MAC1B,IACI;EACE,SAAS,kBAAA,GAAA,EAAA,UAAE,YAAW,CAAA;EACtB,qBAAqB;EACrB,eAAe,OAAO,KAAK,GAAS,QAAQ;EAC5C,OAAO;CACT,IACA,KAAA;CACN,OACE,kBAAC,OAAD,EAAA,UAAA,CACG,KAAiB,CAAC,KACjB,kBAAA,GAAA,EAAA,UAAA;GACI,EAAc,aAAa,EAAc,WACzC,CAAC,KACC,kBAAC,GAAD;GAAO,UAAS;aAAhB,CACG,CAAC,EAAc,UACd,kBAAC,GAAD,EAAA,UAAY,wBAAiC,CAAA,GAE/C,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,WAAW,MAAM;cAAnD;KAAsD;KACU;KAC9D,kBAAC,GAAD;MACE,MAAK;MACL,UAAS,MAAK;OAEZ,AADA,EAAE,eAAe,GACjB,EAAiB;MACnB;gBACD;KAEK,CAAA;KAAC;IAEG;KACP;;EAEV,CAAC,EAAc,UAAU,CAAC,KACzB,kBAAC,GAAD;GAAO,UAAS;aAAhB,CACG,CAAC,EAAc,UAAU,kBAAC,GAAD,EAAA,UAAY,cAAuB,CAAA,GAC7D,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,WAAW,MAAM;cAAnD;KAAsD;KACK;KACzD,kBAAC,GAAD;MACE,MAAK;MACL,UAAS,MAAK;OAEZ,AADA,EAAE,eAAe,GACjB,EAAiB;MACnB;gBACD;KAEK,CAAA;KAAC;IAEG;KACP;;EAER,EAAc,UAAU,KACvB,kBAAC,GAAD;GAAO,UAAS;aAAhB,CACE,kBAAC,GAAD,EAAA,UAAY,cAAuB,CAAA,GACnC,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,WAAW,MAAM;cAChD,gDAAgD,EAC/C,EAAM,EAAc,QAAQ,CAC9B;GACU,CAAA,CACP;;EAET,kBAAC,GAAD;GACE,SAAQ;GACR,IAAI;IAAE,WAAW;IAAQ,cAAc;GAAO;aAFhD;IAGC;IACS,EAAc;IAAM;IAAI,EAAc,aAAa;GACjD;;CACZ,EAAA,CAAA,GAEJ,kBAAC,OAAD;EAAK,WAAU;YAAf,CACG,KAAQ,KACP,kBAAA,GAAA,EAAA,UAAA;GACE,kBAAC,GAAD;IACE,eAAe,OAAO,KAAK,iEAAqB,QAAQ;IACxD,WAAU;IACV,OAAM;IACN,SAAQ;cAER,kBAAC,GAAD;KAAK,IAAI;MAAE,SAAS;MAAQ,YAAY;KAAS;eAAjD,CACE,kBAAC,GAAD;MACE,WAAU;MACV,OAAO;OAAE,aAAa;OAAO,OAAO;MAAQ;KAC7C,CAAA,GACD,kBAAA,GAAA,EAAA,UAAE,OAAM,CAAA,CACL;;GACC,CAAA;GACR,kBAAC,GAAD;IAAY,SAAQ;IAAY,IAAI,EAAE,cAAc,OAAO;cAAG;GAElD,CAAA;GACZ,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,cAAc,OAAO;cAAG;GAQ9C,CAAA;GACZ,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,cAAc,OAAO;cAAG;GAE9C,CAAA;GACZ,kBAAC,QAAD;IAAM,KAAK;IAAS,WAAU,MAAK,EAAE,eAAe;cAClD,kBAAC,MAAD,EAAA,UACG,GAAM,UAAU,KAAI,MAAY;KAC/B,IAAM,IAAS,EAAS,YAAY,EAAS;KAC7C,OACE,kBAAC,MAAD;MAEE,MAAM,EAAS,YAAY,eAAe,KAAA;gBAF5C;OAIE,kBAAC,GAAD;QACE,SAAS;QACT,yBAAyB,EAAE,QAAQ,EAAS,OAAO;QACnD,IAAI;SAAE,WAAW;SAAQ,cAAc;QAAO;OAC/C,CAAA;OACA,EAAS,QAAQ,KAAI,MACpB,kBAAC,GAAD;QAEY;QACV,QAAQ;QACR,UAAS,MACP,EACE,EAAS,eACT,OAAO,EAAE,cAAc,KAAK,CAC9B;OAEH,GATM,GAAG,EAAS,cAAc,GAAG,EAAO,aAS1C,CACF;OACA,KACC,kBAAC,GAAD;QACE,cAAc,EAAE,UAAU,EAAS,SAAS;QAC5C,WAAU;QACV,IAAI,EACF,OAAO;SACL,WAAW;SACX,IAAI,EACF,SAAS,MACX;QACF,EACF;QACA,cAAc,EAAmB,EAAS,OAAO;QACjD,iBAAiB;kBAEjB,kBAAC,GAAD;SACE,IAAI;UACF,SAAS;UACT,YAAY;UACZ,WAAW;SACb;mBALF,CAOE,kBAAC,GAAD;UACE,WAAU;UACV,OAAO,EAAE,aAAa,MAAM;SAC7B,CAAA,GACD,kBAAC,GAAD,EAAA,UAAM,qCAAwC,CAAA,CAC3C;;OACU,CAAA;MAEjB;QAnDG,EAAS,aAmDZ;IAER,CAAC,EACC,CAAA;GACA,CAAA;GACN,kBAAC,GAAD;IACE,WAAU;IACV,OAAM;IACN,SAAQ;IACR,MAAK;IACL,UAAU;IACV,eAAe;KACb,EAAa;IACf;cACD;GAEO,CAAA;EACR,EAAA,CAAA,GAGH,CAAC,KAAgB,GAAe,eAC/B,kBAAC,MAAD,EAAA,UACG,EAAc,YAAY,KAAI,MAAuB;GACpD,IAAM,IACJ,EAAoB,UAChB,IACJ,EAAoB;GACtB,OACE,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IACE,SAAS;IACT,yBAAyB,EAAE,QAAQ,EAAS,OAAO;IACnD,WACE,EAAoB,YAAY,KAAK;IAEvC,IAAI;KAAE,WAAW;KAAQ,cAAc;IAAO;GAC/C,CAAA,GACA,EAAS,QAAQ,KAAI,MACpB,kBAAC,GAAD;IAEY;IACV,QAAQ;IACR,UAAU;IACV,SAAS,EAAS,YAAY,SAC5B,EAAO,WACT;GACD,GAPM,GAAG,EAAS,cAAc,GAAG,EAAO,aAO1C,CACF,CACC,EAAA,GApBK,EAAS,aAoBd;EAER,CAAC,EACC,CAAA,CAEH;GACF,EAAA,CAAA;AAET;AAEA,SAAS,IAA4B;CACnC,IAAM,IAAyB,CAAC;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KACtB,EAAU,KACR,kBAAC,MAAD,EAAA,UACE,kBAAC,GAAD;EAAe,SAAS;EAAG,SAAS;CAAI,CAAA,EACtC,GAFK,CAEL,CACN;CAEF,OACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;GAAU,QAAO;GAAO,OAAM;EAAS,CAAA,EACpC,CAAA;EACL,kBAAC,GAAD,EAAmB,SAAS,EAAI,CAAA;EAChC,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,MAAD;IAAI,OAAO,EAAE,WAAW,OAAO;cAAI;GAAc,CAAA;EAC9C,CAAA;CACL,EAAA,CAAA;AAEN"}
|
|
@@ -4,7 +4,7 @@ import { useEffect as n, useState as r } from "react";
|
|
|
4
4
|
import { noop as i } from "lodash-es";
|
|
5
5
|
import { Autocomplete as a, Box as o, Button as s, Collapse as c, List as l, ListItem as u, MenuItem as d, TextField as f, Typography as p } from "@mui/material";
|
|
6
6
|
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
7
|
-
import
|
|
7
|
+
import _ from "@mui/icons-material/HelpOutlineTwoTone";
|
|
8
8
|
//#region src/components/ChallengeSubmission/AvailableEvaluationQueueList.tsx
|
|
9
9
|
function v(n) {
|
|
10
10
|
let { text: r, tooltipMarkdownText: i } = n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AvailableEvaluationQueueList.js","names":[],"sources":["../../../src/components/ChallengeSubmission/AvailableEvaluationQueueList.tsx"],"sourcesContent":["import LightTooltip from '@/components/styled/LightTooltip'\nimport
|
|
1
|
+
{"version":3,"file":"AvailableEvaluationQueueList.js","names":[],"sources":["../../../src/components/ChallengeSubmission/AvailableEvaluationQueueList.tsx"],"sourcesContent":["import LightTooltip from '@/components/styled/LightTooltip'\nimport HelpOutlineTwoTone from '@mui/icons-material/HelpOutlineTwoTone'\nimport {\n Autocomplete,\n Box,\n Button,\n Collapse,\n List,\n ListItem,\n MenuItem,\n TextField,\n Typography,\n} from '@mui/material'\nimport { Evaluation } from '@sage-bionetworks/synapse-types'\nimport { noop } from 'lodash-es'\nimport { useEffect, useState } from 'react'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\n\ntype TextWithHelpIconProps = {\n text: string\n tooltipMarkdownText?: string\n}\n\nfunction TextWithHelpIcon(props: TextWithHelpIconProps) {\n const { text, tooltipMarkdownText } = props\n\n return (\n <>\n {text}\n {tooltipMarkdownText && (\n <LightTooltip\n title={\n <Typography\n variant=\"body1\"\n sx={{\n mb: 0,\n }}\n >\n <MarkdownSynapse markdown={tooltipMarkdownText} />\n </Typography>\n }\n >\n <HelpOutlineTwoTone\n sx={{\n ml: 1,\n color: 'grey.600',\n fontSize: '16px',\n }}\n />\n </LightTooltip>\n )}\n </>\n )\n}\n\ntype AvailableEvaluationQueueStaticListProps = Pick<\n AvailableEvaluationQueueListProps,\n 'evaluations'\n>\nfunction AvailableEvaluationQueueStaticList(\n props: AvailableEvaluationQueueStaticListProps,\n) {\n const { evaluations } = props\n return (\n <>\n <Typography variant=\"body1\">Available Evaluation Queues:</Typography>\n <List dense={true}>\n {evaluations.map(evaluation => (\n <ListItem key={evaluation.id}>\n <TextWithHelpIcon\n text={evaluation.name!}\n tooltipMarkdownText={evaluation.submissionInstructionsMessage}\n />\n </ListItem>\n ))}\n </List>\n </>\n )\n}\n\ntype AvailableEvaluationQueueCollapsableListProps = Pick<\n AvailableEvaluationQueueListProps,\n 'evaluations' | 'isSelectable'\n>\n\nfunction AvailableEvaluationQueueCollapsableList(\n props: AvailableEvaluationQueueCollapsableListProps,\n) {\n const { evaluations, isSelectable } = props\n const [showList, setShowList] = useState<boolean>(false)\n const nEvaluationsCollapseLimit = isSelectable ? 2 : 8\n const shouldCollapse = evaluations.length >= nEvaluationsCollapseLimit\n\n return (\n <Box\n sx={{\n mt: 2,\n }}\n >\n {shouldCollapse ? (\n <>\n <Button\n variant=\"contained\"\n sx={{ mb: 1 }}\n onClick={() => setShowList(!showList)}\n >\n {`${showList ? 'Hide' : 'Show'} All Available Evaluation Queues`}\n </Button>\n <Collapse in={showList}>\n <AvailableEvaluationQueueStaticList {...props} />\n </Collapse>\n </>\n ) : (\n <>\n <AvailableEvaluationQueueStaticList {...props} />\n </>\n )}\n </Box>\n )\n}\n\ntype AvailableEvaluationQueueAutocompleteListProps = Pick<\n AvailableEvaluationQueueListProps,\n 'evaluations' | 'onChangeSelectedEvaluation'\n>\n\nfunction AvailableEvaluationQueueAutocompleteList(\n props: AvailableEvaluationQueueAutocompleteListProps,\n) {\n const { evaluations, onChangeSelectedEvaluation = noop } = props\n const [value, setValue] = useState<Evaluation | null>(null)\n\n return (\n <Autocomplete\n // Must be set to false for dropdown list to be correctly positioned\n // when component is in a modal opened from a Markdown Widget in SWC\n disablePortal={false}\n value={value}\n onChange={(event, newValue: Evaluation | null) => {\n setValue(newValue)\n onChangeSelectedEvaluation(newValue)\n }}\n options={evaluations}\n getOptionLabel={option => option.name!}\n renderOption={(props, option, state, ownerState) => {\n return (\n <MenuItem {...props}>\n <TextWithHelpIcon\n text={ownerState.getOptionLabel(option)}\n tooltipMarkdownText={option.submissionInstructionsMessage}\n />\n </MenuItem>\n )\n }}\n renderInput={params => (\n <TextField {...params} label=\"Selected Evaluation Queue\" />\n )}\n />\n )\n}\n\nexport type AvailableEvaluationQueueListProps = {\n /* evaluation queues available to the current user */\n evaluations: Evaluation[]\n /* should the user be able to select an evaluation queue */\n isSelectable?: boolean\n /* will be called when the currently selected evaluation queue is changed */\n onChangeSelectedEvaluation?: (evaluation: Evaluation | null) => void\n}\n\nfunction AvailableEvaluationQueueList(\n props: AvailableEvaluationQueueListProps,\n) {\n const {\n isSelectable = true,\n onChangeSelectedEvaluation = noop,\n evaluations,\n } = props\n const nEvaluations = evaluations.length\n\n useEffect(() => {\n if (nEvaluations === 1 && isSelectable)\n onChangeSelectedEvaluation(evaluations[0])\n }, [evaluations, isSelectable, nEvaluations, onChangeSelectedEvaluation])\n\n if (nEvaluations === 0)\n return <Typography variant=\"body1\">No evaluations found</Typography>\n\n if (nEvaluations === 1) {\n const evaluation = evaluations[0]\n return (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n }}\n >\n <TextWithHelpIcon\n text={evaluation.name!}\n tooltipMarkdownText={evaluation.submissionInstructionsMessage}\n />\n </Box>\n )\n }\n\n return (\n <Box\n // Class name used in SWC to prevent markdown formatting from applying additional margin/padding\n className=\"AvailableEvaluationQueueList\"\n >\n {isSelectable && <AvailableEvaluationQueueAutocompleteList {...props} />}\n <AvailableEvaluationQueueCollapsableList {...props} />\n </Box>\n )\n}\n\nexport default AvailableEvaluationQueueList\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { useGetEvaluation as t, useGetEvaluationRoundsInfinite as n } from "../.
|
|
|
3
3
|
import { getCurrentOrNextOrLatestRound as r } from "../../utils/challenge/evaluation/EvaluationUtils.js";
|
|
4
4
|
import { useEffect as i, useMemo as a } from "react";
|
|
5
5
|
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
-
import
|
|
6
|
+
import l from "@mui/icons-material/InfoTwoTone";
|
|
7
7
|
import u from "dayjs";
|
|
8
8
|
import d from "@mui/material/Tooltip";
|
|
9
9
|
//#region src/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvaluationQueueCurrentRoundInfo.js","names":[],"sources":["../../../src/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.tsx"],"sourcesContent":["import {\n useGetEvaluation,\n useGetEvaluationRoundsInfinite,\n} from '@/synapse-queries/evaluation/useEvaluation'\nimport { getCurrentOrNextOrLatestRound } from '@/utils/challenge/evaluation/EvaluationUtils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport
|
|
1
|
+
{"version":3,"file":"EvaluationQueueCurrentRoundInfo.js","names":[],"sources":["../../../src/components/ChallengeSubmission/EvaluationQueueCurrentRoundInfo.tsx"],"sourcesContent":["import {\n useGetEvaluation,\n useGetEvaluationRoundsInfinite,\n} from '@/synapse-queries/evaluation/useEvaluation'\nimport { getCurrentOrNextOrLatestRound } from '@/utils/challenge/evaluation/EvaluationUtils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport Tooltip from '@mui/material/Tooltip'\nimport dayjs from 'dayjs'\nimport { useEffect, useMemo } from 'react'\n\ntype EvaluationQueueInfoProps = {\n evaluationId: string\n}\n\n/**\n * Displays an information tooltip about the current (or recent) round of an Evaluation Queue.\n * @param props\n * @constructor\n */\nfunction EvaluationQueueCurrentRoundInfo(props: EvaluationQueueInfoProps) {\n const { evaluationId } = props\n\n const { data: evaluation } = useGetEvaluation(evaluationId)\n\n const {\n data: infiniteData,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useGetEvaluationRoundsInfinite(evaluationId)\n\n useEffect(() => {\n // Fetch all pages\n if (hasNextPage && !isFetchingNextPage) {\n void fetchNextPage()\n }\n }, [fetchNextPage, hasNextPage, isFetchingNextPage])\n\n const rounds = useMemo(\n () => infiniteData?.pages.flatMap(page => page.page!) ?? [],\n [infiniteData?.pages],\n )\n\n const currentRound = getCurrentOrNextOrLatestRound(rounds)\n\n const title = (\n <>\n {evaluation?.description && <p>{evaluation?.description}</p>}\n {currentRound?.roundStart && (\n <p>\n <strong>Start:</strong> {formatDate(dayjs(currentRound?.roundStart))}\n </p>\n )}\n {currentRound?.roundEnd && (\n <p>\n <strong>End:</strong> {formatDate(dayjs(currentRound?.roundEnd))}\n </p>\n )}\n <p>\n <strong>Submission Limits:</strong>{' '}\n {currentRound?.limits\n ? `${currentRound?.limits\n .map(\n limit =>\n `${\n limit.maximumSubmissions\n } ${limit.limitType.toLowerCase()} submissions`,\n )\n .join(', ')}`\n : 'No limit'}\n </p>\n </>\n )\n\n return (\n <Tooltip title={title}>\n <InfoTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n )\n}\n\nexport default EvaluationQueueCurrentRoundInfo\n"],"mappings":";;;;;;;;;AAoBA,SAAS,EAAgC,GAAiC;CACxE,IAAM,EAAE,oBAAiB,GAEnB,EAAE,MAAM,MAAe,EAAiB,CAAY,GAEpD,EACJ,MAAM,GACN,gBACA,uBACA,qBACE,EAA+B,CAAY;CAE/C,QAAgB;EAEd,AAAI,KAAe,CAAC,KAClB,EAAmB;CAEvB,GAAG;EAAC;EAAe;EAAa;CAAkB,CAAC;CAOnD,IAAM,IAAe,EALN,QACP,GAAc,MAAM,SAAQ,MAAQ,EAAK,IAAK,KAAK,CAAC,GAC1D,CAAC,GAAc,KAAK,CAG6B,CAAM;CA+BzD,OACE,kBAAC,GAAD;EAAgB,OA7BhB,kBAAA,GAAA,EAAA,UAAA;GACG,GAAY,eAAe,kBAAC,KAAD,EAAA,UAAI,GAAY,YAAe,CAAA;GAC1D,GAAc,cACb,kBAAC,KAAD,EAAA,UAAA;IACE,kBAAC,UAAD,EAAA,UAAQ,SAAc,CAAA;IAAC;IAAE,EAAW,EAAM,GAAc,UAAU,CAAC;GAClE,EAAA,CAAA;GAEJ,GAAc,YACb,kBAAC,KAAD,EAAA,UAAA;IACE,kBAAC,UAAD,EAAA,UAAQ,OAAY,CAAA;IAAC;IAAE,EAAW,EAAM,GAAc,QAAQ,CAAC;GAC9D,EAAA,CAAA;GAEL,kBAAC,KAAD,EAAA,UAAA;IACE,kBAAC,UAAD,EAAA,UAAQ,qBAA0B,CAAA;IAAE;IACnC,GAAc,SACX,GAAG,GAAc,OACd,KACC,MACE,GACE,EAAM,mBACP,GAAG,EAAM,UAAU,YAAY,EAAE,aACtC,EACC,KAAK,IAAI,MACZ;GACH,EAAA,CAAA;EACH,EAAA,CAIc;YACd,kBAAC,GAAD,EAAa,IAAI,EAAE,OAAO,WAAW,EAAI,CAAA;CAClC,CAAA;AAEb"}
|
|
@@ -18,10 +18,10 @@ import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
|
18
18
|
import { Direction as ie, FILE_ENTITY_CONCRETE_TYPE_VALUE as y, SortBy as ae } from "@sage-bionetworks/synapse-types";
|
|
19
19
|
import { EntityType as b } from "@sage-bionetworks/synapse-client";
|
|
20
20
|
import { useQueryClient as x } from "@tanstack/react-query";
|
|
21
|
-
import { NotesTwoTone as oe } from "@mui/icons-material";
|
|
22
21
|
import { Link as S } from "react-router";
|
|
23
|
-
import
|
|
24
|
-
import { DataGrid as
|
|
22
|
+
import oe from "dayjs";
|
|
23
|
+
import { DataGrid as C } from "@mui/x-data-grid";
|
|
24
|
+
import se from "@mui/icons-material/NotesTwoTone";
|
|
25
25
|
//#region src/components/ChallengeSubmission/SubmissionDirectoryList.tsx
|
|
26
26
|
function w({ pageSize: w, challengeProjectId: T, entityType: E, onItemSelected: D }) {
|
|
27
27
|
let O = x(), { accessToken: k, keyFactory: A } = i(), [j, ce] = f(0), [M, N] = f(), [P, F] = f(), [I, L] = f(), [R, z] = f([]), [B, V] = f(), [H, U] = f(!1), [W, G] = f(!1), [K, q] = f(), J = w, Y = `${t(e.PORTAL_ENDPOINT)}Synapse:${T}`, { data: X, refetch: le } = o({
|
|
@@ -118,7 +118,7 @@ function w({ pageSize: w, challengeProjectId: T, entityType: E, onItemSelected:
|
|
|
118
118
|
t.push({
|
|
119
119
|
id: e.id,
|
|
120
120
|
name: E === b.dockerrepo ? e.repositoryName ?? e.name : e.name,
|
|
121
|
-
modifiedOn: c(
|
|
121
|
+
modifiedOn: c(oe(e.modifiedOn), "MM/DD/YY")
|
|
122
122
|
});
|
|
123
123
|
}), t;
|
|
124
124
|
}, he = (e) => {
|
|
@@ -227,7 +227,7 @@ function w({ pageSize: w, challengeProjectId: T, entityType: E, onItemSelected:
|
|
|
227
227
|
my: 3,
|
|
228
228
|
display: "flex"
|
|
229
229
|
},
|
|
230
|
-
children: [/* @__PURE__ */ _(
|
|
230
|
+
children: [/* @__PURE__ */ _(se, { sx: {
|
|
231
231
|
width: "16px",
|
|
232
232
|
height: "16px",
|
|
233
233
|
verticalAlign: "text-bottom"
|
|
@@ -248,7 +248,7 @@ function w({ pageSize: w, challengeProjectId: T, entityType: E, onItemSelected:
|
|
|
248
248
|
] })]
|
|
249
249
|
})]
|
|
250
250
|
}),
|
|
251
|
-
/* @__PURE__ */ _(p, { children: /* @__PURE__ */ _(
|
|
251
|
+
/* @__PURE__ */ _(p, { children: /* @__PURE__ */ _(C, {
|
|
252
252
|
loading: de,
|
|
253
253
|
columns: pe,
|
|
254
254
|
rows: me($),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubmissionDirectoryList.js","names":[],"sources":["../../../src/components/ChallengeSubmission/SubmissionDirectoryList.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport {\n invalidateAllQueriesForEntity,\n useGetEntities,\n useGetEntityChildren,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport { NotesTwoTone } from '@mui/icons-material'\nimport { Box, Button, Radio, Typography } from '@mui/material'\nimport { DataGrid, GridCellParams, GridColDef } from '@mui/x-data-grid'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport {\n Direction,\n Entity,\n EntityChildrenRequest,\n EntityHeader,\n EntityLookupRequest,\n FILE_ENTITY_CONCRETE_TYPE_VALUE,\n FileEntity,\n FileUploadComplete,\n SortBy,\n UploadCallbackResp,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport dayjs from 'dayjs'\nimport { useEffect, useMemo, useState } from 'react'\nimport { Link } from 'react-router'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport CopyToClipboardIcon from '../CopyToClipboardIcon'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FileUpload from '../FileUpload'\nimport IconSvg from '../IconSvg'\nimport { EntityItem } from './ChallengeSubmission'\n\ntype SubmissionDirectoryRow = {\n id: string\n name: string\n modifiedOn: string\n}\n\ntype SubmissionDirectoryListProps = {\n pageSize: number\n challengeProjectId: string\n entityType: typeof EntityType.dockerrepo | typeof EntityType.file\n onItemSelected: (selected: EntityItem) => void\n}\n\ntype FileUploadAttempt = FileUploadComplete & {\n entityId?: string\n}\n\nfunction SubmissionDirectoryList({\n pageSize,\n challengeProjectId,\n entityType,\n onItemSelected,\n}: SubmissionDirectoryListProps) {\n const queryClient = useQueryClient()\n const { accessToken, keyFactory } = useSynapseContext()\n const [page, setPage] = useState<number>(0)\n const [selectedItem, setSelectedItem] = useState<EntityItem | undefined>()\n const [errorMessage, setErrorMessage] = useState<string>()\n const [canSubmit, setCanSubmit] = useState<boolean>()\n const [fetchedHeaders, setFetchedHeaders] = useState<EntityHeader[]>([])\n const [nextPageToken, setNextPageToken] = useState<string | undefined>()\n const [fetchNextPage, setFetchNextPage] = useState<boolean>(false)\n const [confirmOpen, setConfirmOpen] = useState<boolean>(false)\n const [uploadAttempt, setUploadAttempt] = useState<FileUploadAttempt>()\n\n const PER_PAGE = pageSize\n const HEADERS_PER_PAGE = 50\n const PROJECT_URL = `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}Synapse:${challengeProjectId}`\n\n const request: EntityChildrenRequest = {\n parentId: challengeProjectId,\n nextPageToken: fetchNextPage ? nextPageToken : null,\n includeTypes: [entityType],\n includeTotalChildCount: true,\n sortBy: SortBy.MODIFIED_ON,\n sortDirection: Direction.DESC,\n }\n\n const { data: headerResults, refetch } = useGetEntityChildren(request, {\n enabled: !!challengeProjectId,\n throwOnError: true,\n })\n\n useEffect(() => {\n if (headerResults) {\n const newHeaders = [...fetchedHeaders]\n const headerPage = Math.floor(((page + 1) * PER_PAGE) / HEADERS_PER_PAGE)\n const start = headerPage * HEADERS_PER_PAGE\n newHeaders.splice(start, start + HEADERS_PER_PAGE, ...headerResults.page)\n setFetchedHeaders(newHeaders)\n setFetchNextPage(false)\n setNextPageToken(headerResults.nextPageToken)\n }\n // TODO: Temporary useEffect hook to remove onSuccess QueryOption for @tanstack/react-query v5\n // Refactor this component to remove this effect.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [headerResults])\n\n function getPageHeaders() {\n const pageStart = page * PER_PAGE\n const pageHeaders = fetchedHeaders.slice(pageStart, pageStart + PER_PAGE)\n return pageHeaders\n }\n\n function reset() {\n setErrorMessage(undefined)\n setCanSubmit(undefined)\n setFetchedHeaders([])\n setNextPageToken(undefined)\n setFetchNextPage(false)\n refetch()\n }\n\n useEffect(() => {\n reset()\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [entityType, pageSize])\n\n const queries = useGetEntities(getPageHeaders())\n const entities = useMemo(\n () =>\n queries\n .filter(q => q.status === 'success')\n .map(q => q.data) as EntityItem[],\n [queries],\n )\n const areEntitiesLoading = queries.some(q => q.isLoading)\n\n const entityChangeHandler = async (value: string) => {\n setCanSubmit(false)\n const entity = entities.find(entity => entity?.id === value)\n if (entity) {\n setSelectedItem(entity)\n if (entityType === EntityType.dockerrepo) {\n let commits\n try {\n commits = await SynapseClient.getDockerTag(\n entity.id!,\n accessToken,\n 0,\n 1,\n )\n } catch (e) {\n return setErrorMessage(e.message)\n }\n if (commits.totalNumberOfResults === 0) {\n return setErrorMessage(\n 'No commits have been made to this repository. Please select a repository with at least one commit.',\n )\n }\n }\n setCanSubmit(true)\n setErrorMessage(undefined)\n }\n }\n\n const columns: GridColDef[] = [\n {\n field: 'radiobutton',\n headerName: '',\n width: 25,\n sortable: false,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: params => {\n return (\n <Radio\n value={params.id}\n checked={params.id === selectedItem?.id}\n onChange={event => {\n entityChangeHandler(event.target.value)\n }}\n />\n )\n },\n },\n {\n field: 'name',\n headerName:\n entityType === EntityType.dockerrepo\n ? 'Docker Repository'\n : 'File Name',\n flex: 1,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: (params: GridCellParams<Entity, SubmissionDirectoryRow>) => (\n <Link\n to={{\n pathname: `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}Synapse:${params.row.id}`,\n }}\n target=\"_blank\"\n >\n {params.row.name}\n </Link>\n ),\n },\n {\n field: 'modifiedOn',\n headerName: 'Updated On',\n width: 100,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n },\n {\n field: 'id',\n headerName: 'ID',\n width: 200,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n },\n ]\n\n const getRows = (entities: EntityItem[]) => {\n const newRows: SubmissionDirectoryRow[] = []\n entities.forEach(entity => {\n newRows.push({\n id: entity.id!,\n name:\n entityType === EntityType.dockerrepo\n ? (entity.repositoryName ?? entity.name)\n : entity.name,\n modifiedOn: formatDate(dayjs(entity.modifiedOn), 'MM/DD/YY'),\n })\n })\n return newRows\n }\n\n const handlePageChange = (newPageNum: number) => {\n const lastIndexNeeded = Math.min(\n headerResults?.totalChildCount ?? 0,\n (newPageNum + 1) * PER_PAGE,\n )\n if (lastIndexNeeded > fetchedHeaders.length) {\n setFetchNextPage(true)\n }\n setPage(newPageNum)\n }\n\n const itemSelectedHandler = () => {\n onItemSelected(selectedItem!)\n }\n\n function createEntity(file: FileUploadAttempt) {\n // Create Entity\n if (!file) return\n const { fileHandleId, fileName } = file\n const newFileEntity: FileEntity = {\n parentId: challengeProjectId,\n name: fileName,\n concreteType: FILE_ENTITY_CONCRETE_TYPE_VALUE,\n dataFileHandleId: fileHandleId,\n }\n SynapseClient.createEntity(newFileEntity, accessToken)\n .then(() => {\n reset()\n })\n .catch((err: SynapseClientError) => {\n setErrorMessage(err.reason)\n })\n }\n\n async function updateEntity() {\n if (!uploadAttempt) return\n const { fileHandleId, entityId } = uploadAttempt\n if (!entityId)\n return setErrorMessage('Error: missing entityId. Please try again.')\n // Get the entity\n let entity: FileEntity\n try {\n entity = await SynapseClient.getEntity(accessToken, entityId)\n } catch (err) {\n return setErrorMessage(`The entity ${entityId} could not be retrieved.`)\n }\n\n const updateRequest: FileEntity = {\n id: entity.id,\n name: entity.name,\n dataFileHandleId: fileHandleId,\n concreteType: FILE_ENTITY_CONCRETE_TYPE_VALUE,\n parentId: entity.parentId,\n etag: entity.etag,\n modifiedOn: entity.modifiedOn,\n }\n\n try {\n const updatedEntity = await SynapseClient.updateEntity(\n updateRequest,\n accessToken,\n true,\n )\n await invalidateAllQueriesForEntity(\n queryClient,\n keyFactory,\n updatedEntity.id!,\n )\n queryClient.setQueryData(\n keyFactory.getEntityQueryKey(updatedEntity.id!),\n updatedEntity,\n )\n reset()\n } catch (err) {\n setErrorMessage(err.reason)\n }\n }\n\n const handleUpload = async (response: UploadCallbackResp) => {\n if (response.success && response.resp) {\n const { fileName } = response.resp\n\n // Lookup entity\n const entityLookupRequest: EntityLookupRequest = {\n entityName: fileName,\n parentId: challengeProjectId,\n }\n try {\n const entityId = await SynapseClient.lookupChildEntity(\n entityLookupRequest,\n accessToken,\n )\n // Entity exists, prompt user to update it\n if (entityId) {\n setUploadAttempt({ ...response.resp, entityId: entityId.id })\n setConfirmOpen(true)\n }\n } catch (err) {\n // An existing entity was not found for this file, create it\n setUploadAttempt(undefined)\n createEntity(response.resp)\n }\n } else if (!response.success && response.error) {\n setErrorMessage(response.error.reason as string)\n } else {\n setErrorMessage('An unknown error occurred. Please try again.')\n }\n }\n\n return (\n <Box>\n <Box\n sx={{\n display: 'flex',\n backgroundColor: '#FBFBFC',\n padding: '10px',\n justifyContent: 'space-between',\n }}\n >\n <Typography\n variant=\"h6\"\n sx={{ fontSize: '18px', lineHeight: '20px', fontWeight: 700 }}\n >\n {entityType === EntityType.file\n ? 'Submit File'\n : 'Submit Docker Image'}\n </Typography>\n <Box sx={{ display: 'flex' }}>\n <Typography\n variant=\"body1\"\n sx={{ fontSize: '14px', color: '#71767F' }}\n >\n Your Project SynID:{' '}\n <Link to={{ pathname: PROJECT_URL }} target=\"_blank\">\n {challengeProjectId}\n </Link>\n </Typography>\n <CopyToClipboardIcon value={PROJECT_URL} sx={{ marginTop: '-4px' }} />\n </Box>\n </Box>\n <Box\n sx={{\n my: 3,\n display: 'flex',\n }}\n >\n <NotesTwoTone\n sx={{\n width: '16px',\n height: '16px',\n verticalAlign: 'text-bottom',\n }}\n />\n <Box\n sx={{\n ml: 1,\n }}\n >\n {entityType === EntityType.file && (\n <>\n Choose a prediction file from your submission directory below and\n click \"Submit Selection\" to pick an evaluation queue. If you need\n to add a new file, click \"Upload File\" first.\n </>\n )}\n {entityType === EntityType.dockerrepo && (\n <>\n Choose a Docker image from your submission directory below and\n click \"Submit Selection\" to pick an image version and evaluation\n queue. If you need to upload a new image to your project (\n <code>{challengeProjectId}</code>), see our{' '}\n <Link\n to=\"https://github.com/Sage-Bionetworks-Challenges/sample-model-templates#build-your-model\"\n target=\"_blank\"\n >\n Docker model submission guide\n </Link>{' '}\n for command-line instructions on how to build and upload.\n </>\n )}\n </Box>\n </Box>\n <Box>\n <DataGrid\n loading={areEntitiesLoading}\n columns={columns}\n rows={getRows(entities)}\n rowCount={headerResults?.totalChildCount ?? 0}\n pagination\n paginationMode=\"server\"\n paginationModel={{ page, pageSize: PER_PAGE }}\n pageSizeOptions={[PER_PAGE]}\n onPaginationModelChange={({ page }) => {\n handlePageChange(page)\n }}\n density=\"compact\"\n autoHeight\n sx={{\n fontSize: '14px',\n border: 'none',\n height: '100%',\n '& .MuiDataGrid-columnHeader': {\n backgroundColor: '#F1F3F5',\n },\n '& .Mui-odd': {\n backgroundColor: '#FBFBFC',\n },\n '.MuiDataGrid-columnHeaderTitleContainer': {\n justifyContent: 'space-between',\n },\n '.radio': {\n display: 'flex',\n alignItems: 'center',\n height: '100%',\n },\n }}\n getRowClassName={params =>\n params.indexRelativeToCurrentPage % 2 === 0 ? 'Mui-even' : 'Mui-odd'\n }\n />\n </Box>\n {errorMessage && <ErrorBanner error={errorMessage}></ErrorBanner>}\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n {entityType === EntityType.file && (\n <FileUpload\n label=\"Upload File\"\n buttonProps={{\n variant: 'outlined',\n endIcon: <IconSvg icon=\"upload\" />,\n sx: { lineHeight: 1 },\n }}\n onComplete={resp => {\n handleUpload(resp)\n }}\n />\n )}\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={itemSelectedHandler}\n disabled={!canSubmit}\n >\n Submit Selection\n </Button>\n </Box>\n <ConfirmationDialog\n open={confirmOpen}\n title=\"File exists\"\n content={\n <Typography variant=\"body1\" sx={{ fontSize: '16px' }}>\n A file named "{uploadAttempt?.fileName}" (\n {uploadAttempt?.entityId}) already exists in this location. Do you\n want to update the existing file and create a new version?\n </Typography>\n }\n onCancel={() => setConfirmOpen(false)}\n onConfirm={() => {\n updateEntity()\n setConfirmOpen(false)\n }}\n />\n </Box>\n )\n}\n\nexport default SubmissionDirectoryList\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAS,EAAwB,EAC/B,aACA,uBACA,eACA,qBAC+B;CAC/B,IAAM,IAAc,EAAe,GAC7B,EAAE,gBAAa,kBAAe,EAAkB,GAChD,CAAC,GAAM,MAAW,EAAiB,CAAC,GACpC,CAAC,GAAc,KAAmB,EAAiC,GACnE,CAAC,GAAc,KAAmB,EAAiB,GACnD,CAAC,GAAW,KAAgB,EAAkB,GAC9C,CAAC,GAAgB,KAAqB,EAAyB,CAAC,CAAC,GACjE,CAAC,GAAe,KAAoB,EAA6B,GACjE,CAAC,GAAe,KAAoB,EAAkB,EAAK,GAC3D,CAAC,GAAa,KAAkB,EAAkB,EAAK,GACvD,CAAC,GAAe,KAAoB,EAA4B,GAEhE,IAAW,GAEX,IAAc,GAAG,EACrB,EAAuB,eACzB,EAAE,UAAU,KAWN,EAAE,MAAM,GAAe,gBAAY,EAAqB;EAR5D,UAAU;EACV,eAAe,IAAgB,IAAgB;EAC/C,cAAc,CAAC,CAAU;EACzB,wBAAwB;EACxB,QAAQ,GAAO;EACf,eAAe,GAAU;CAGmC,GAAS;EACrE,SAAS,CAAC,CAAC;EACX,cAAc;CAChB,CAAC;CAED,QAAgB;EACd,IAAI,GAAe;GACjB,IAAM,IAAa,CAAC,GAAG,CAAc,GAE/B,IADa,KAAK,OAAQ,IAAO,KAAK,IAAY,EAC1C,IAAa;GAI3B,AAHA,EAAW,OAAO,GAAO,IAAQ,IAAkB,GAAG,EAAc,IAAI,GACxE,EAAkB,CAAU,GAC5B,EAAiB,EAAK,GACtB,EAAiB,EAAc,aAAa;EAC9C;CAIF,GAAG,CAAC,CAAa,CAAC;CAElB,SAAS,KAAiB;EACxB,IAAM,IAAY,IAAO;EAEzB,OADoB,EAAe,MAAM,GAAW,IAAY,CACzD;CACT;CAEA,SAAS,IAAQ;EAMf,AALA,EAAgB,KAAA,CAAS,GACzB,EAAa,KAAA,CAAS,GACtB,EAAkB,CAAC,CAAC,GACpB,EAAiB,KAAA,CAAS,GAC1B,EAAiB,EAAK,GACtB,GAAQ;CACV;CAEA,QAAgB;EACd,EAAM;CAER,GAAG,CAAC,GAAY,CAAQ,CAAC;CAEzB,IAAM,IAAU,GAAe,GAAe,CAAC,GACzC,IAAW,QAEb,EACG,QAAO,MAAK,EAAE,WAAW,SAAS,EAClC,KAAI,MAAK,EAAE,IAAI,GACpB,CAAC,CAAO,CACV,GACM,KAAqB,EAAQ,MAAK,MAAK,EAAE,SAAS,GAElD,KAAsB,OAAO,MAAkB;EACnD,EAAa,EAAK;EAClB,IAAM,IAAS,EAAS,MAAK,MAAU,GAAQ,OAAO,CAAK;EAC3D,IAAI,GAAQ;GAEV,IADA,EAAgB,CAAM,GAClB,MAAe,EAAW,YAAY;IACxC,IAAI;IACJ,IAAI;KACF,IAAU,MAAM,EAAc,aAC5B,EAAO,IACP,GACA,GACA,CACF;IACF,SAAS,GAAG;KACV,OAAO,EAAgB,EAAE,OAAO;IAClC;IACA,IAAI,EAAQ,yBAAyB,GACnC,OAAO,EACL,oGACF;GAEJ;GAEA,AADA,EAAa,EAAI,GACjB,EAAgB,KAAA,CAAS;EAC3B;CACF,GAEM,KAAwB;EAC5B;GACE,OAAO;GACP,YAAY;GACZ,OAAO;GACP,UAAU;GACV,YAAY;GACZ,UAAU;GACV,mBAAmB;GACnB,aAAY,MAER,kBAAC,GAAD;IACE,OAAO,EAAO;IACd,SAAS,EAAO,OAAO,GAAc;IACrC,WAAU,MAAS;KACjB,GAAoB,EAAM,OAAO,KAAK;IACxC;GACD,CAAA;EAGP;EACA;GACE,OAAO;GACP,YACE,MAAe,EAAW,aACtB,sBACA;GACN,MAAM;GACN,YAAY;GACZ,UAAU;GACV,mBAAmB;GACnB,aAAa,MACX,kBAAC,GAAD;IACE,IAAI,EACF,UAAU,GAAG,EACX,EAAuB,eACzB,EAAE,UAAU,EAAO,IAAI,KACzB;IACA,QAAO;cAEN,EAAO,IAAI;GACR,CAAA;EAEV;EACA;GACE,OAAO;GACP,YAAY;GACZ,OAAO;GACP,YAAY;GACZ,UAAU;GACV,mBAAmB;EACrB;EACA;GACE,OAAO;GACP,YAAY;GACZ,OAAO;GACP,YAAY;GACZ,UAAU;GACV,mBAAmB;EACrB;CACF,GAEM,MAAW,MAA2B;EAC1C,IAAM,IAAoC,CAAC;EAW3C,OAVA,EAAS,SAAQ,MAAU;GACzB,EAAQ,KAAK;IACX,IAAI,EAAO;IACX,MACE,MAAe,EAAW,aACrB,EAAO,kBAAkB,EAAO,OACjC,EAAO;IACb,YAAY,EAAW,EAAM,EAAO,UAAU,GAAG,UAAU;GAC7D,CAAC;EACH,CAAC,GACM;CACT,GAEM,MAAoB,MAAuB;EAQ/C,AAPwB,KAAK,IAC3B,GAAe,mBAAmB,IACjC,IAAa,KAAK,CAEjB,IAAkB,EAAe,UACnC,EAAiB,EAAI,GAEvB,GAAQ,CAAU;CACpB,GAEM,WAA4B;EAChC,EAAe,CAAa;CAC9B;CAEA,SAAS,GAAa,GAAyB;EAE7C,IAAI,CAAC,GAAM;EACX,IAAM,EAAE,iBAAc,gBAAa,GAC7B,IAA4B;GAChC,UAAU;GACV,MAAM;GACN,cAAc;GACd,kBAAkB;EACpB;EACA,EAAc,aAAa,GAAe,CAAW,EAClD,WAAW;GACV,EAAM;EACR,CAAC,EACA,OAAO,MAA4B;GAClC,EAAgB,EAAI,MAAM;EAC5B,CAAC;CACL;CAEA,eAAe,KAAe;EAC5B,IAAI,CAAC,GAAe;EACpB,IAAM,EAAE,iBAAc,gBAAa;EACnC,IAAI,CAAC,GACH,OAAO,EAAgB,4CAA4C;EAErE,IAAI;EACJ,IAAI;GACF,IAAS,MAAM,EAAc,UAAU,GAAa,CAAQ;EAC9D,QAAc;GACZ,OAAO,EAAgB,cAAc,EAAS,yBAAyB;EACzE;EAEA,IAAM,IAA4B;GAChC,IAAI,EAAO;GACX,MAAM,EAAO;GACb,kBAAkB;GAClB,cAAc;GACd,UAAU,EAAO;GACjB,MAAM,EAAO;GACb,YAAY,EAAO;EACrB;EAEA,IAAI;GACF,IAAM,IAAgB,MAAM,EAAc,aACxC,GACA,GACA,EACF;GAUA,AATA,MAAM,EACJ,GACA,GACA,EAAc,EAChB,GACA,EAAY,aACV,EAAW,kBAAkB,EAAc,EAAG,GAC9C,CACF,GACA,EAAM;EACR,SAAS,GAAK;GACZ,EAAgB,EAAI,MAAM;EAC5B;CACF;CAEA,IAAM,KAAe,OAAO,MAAiC;EAC3D,IAAI,EAAS,WAAW,EAAS,MAAM;GACrC,IAAM,EAAE,gBAAa,EAAS,MAGxB,IAA2C;IAC/C,YAAY;IACZ,UAAU;GACZ;GACA,IAAI;IACF,IAAM,IAAW,MAAM,EAAc,kBACnC,GACA,CACF;IAEA,AAAI,MACF,EAAiB;KAAE,GAAG,EAAS;KAAM,UAAU,EAAS;IAAG,CAAC,GAC5D,EAAe,EAAI;GAEvB,QAAc;IAGZ,AADA,EAAiB,KAAA,CAAS,GAC1B,GAAa,EAAS,IAAI;GAC5B;EACF,OAAO,AAAI,CAAC,EAAS,WAAW,EAAS,QACvC,EAAgB,EAAS,MAAM,MAAgB,IAE/C,EAAgB,8CAA8C;CAElE;CAEA,OACE,kBAAC,GAAD,EAAA,UAAA;EACE,kBAAC,GAAD;GACE,IAAI;IACF,SAAS;IACT,iBAAiB;IACjB,SAAS;IACT,gBAAgB;GAClB;aANF,CAQE,kBAAC,GAAD;IACE,SAAQ;IACR,IAAI;KAAE,UAAU;KAAQ,YAAY;KAAQ,YAAY;IAAI;cAE3D,MAAe,EAAW,OACvB,gBACA;GACM,CAAA,GACZ,kBAAC,GAAD;IAAK,IAAI,EAAE,SAAS,OAAO;cAA3B,CACE,kBAAC,GAAD;KACE,SAAQ;KACR,IAAI;MAAE,UAAU;MAAQ,OAAO;KAAU;eAF3C;MAGC;MACqB;MACpB,kBAAC,GAAD;OAAM,IAAI,EAAE,UAAU,EAAY;OAAG,QAAO;iBACzC;MACG,CAAA;KACI;QACZ,kBAAC,IAAD;KAAqB,OAAO;KAAa,IAAI,EAAE,WAAW,OAAO;IAAI,CAAA,CAClE;KACF;;EACL,kBAAC,GAAD;GACE,IAAI;IACF,IAAI;IACJ,SAAS;GACX;aAJF,CAME,kBAAC,IAAD,EACE,IAAI;IACF,OAAO;IACP,QAAQ;IACR,eAAe;GACjB,EACD,CAAA,GACD,kBAAC,GAAD;IACE,IAAI,EACF,IAAI,EACN;cAHF,CAKG,MAAe,EAAW,QACzB,kBAAA,GAAA,EAAA,UAAE,wLAIA,CAAA,GAEH,MAAe,EAAW,cACzB,kBAAA,GAAA,EAAA,UAAA;KAAE;KAIA,kBAAC,QAAD,EAAA,UAAO,EAAyB,CAAA;KAAC;KAAW;KAC5C,kBAAC,GAAD;MACE,IAAG;MACH,QAAO;gBACR;KAEK,CAAA;KAAE;KAAI;IAEZ,EAAA,CAAA,CAED;KACF;;EACL,kBAAC,GAAD,EAAA,UACE,kBAAC,IAAD;GACE,SAAS;GACA;GACT,MAAM,GAAQ,CAAQ;GACtB,UAAU,GAAe,mBAAmB;GAC5C,YAAA;GACA,gBAAe;GACf,iBAAiB;IAAE;IAAM,UAAU;GAAS;GAC5C,iBAAiB,CAAC,CAAQ;GAC1B,0BAA0B,EAAE,cAAW;IACrC,GAAiB,CAAI;GACvB;GACA,SAAQ;GACR,YAAA;GACA,IAAI;IACF,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,+BAA+B,EAC7B,iBAAiB,UACnB;IACA,cAAc,EACZ,iBAAiB,UACnB;IACA,2CAA2C,EACzC,gBAAgB,gBAClB;IACA,UAAU;KACR,SAAS;KACT,YAAY;KACZ,QAAQ;IACV;GACF;GACA,kBAAiB,MACf,EAAO,6BAA6B,KAAM,IAAI,aAAa;EAE9D,CAAA,EACE,CAAA;EACJ,KAAgB,kBAAC,GAAD,EAAa,OAAO,EAA2B,CAAA;EAChE,kBAAC,GAAD;GACE,IAAI;IACF,SAAS;IACT,gBAAgB;GAClB;aAJF,CAMG,MAAe,EAAW,QACzB,kBAAC,GAAD;IACE,OAAM;IACN,aAAa;KACX,SAAS;KACT,SAAS,kBAAC,IAAD,EAAS,MAAK,SAAU,CAAA;KACjC,IAAI,EAAE,YAAY,EAAE;IACtB;IACA,aAAY,MAAQ;KAClB,GAAa,CAAI;IACnB;GACD,CAAA,GAEH,kBAAC,IAAD;IACE,OAAM;IACN,SAAQ;IACR,SAAS;IACT,UAAU,CAAC;cACZ;GAEO,CAAA,CACL;;EACL,kBAAC,GAAD;GACE,MAAM;GACN,OAAM;GACN,SACE,kBAAC,GAAD;IAAY,SAAQ;IAAQ,IAAI,EAAE,UAAU,OAAO;cAAnD;KAAsD;KAChC,GAAe;KAAS;KAC3C,GAAe;KAAS;IAEf;;GAEd,gBAAgB,EAAe,EAAK;GACpC,iBAAiB;IAEf,AADA,GAAa,GACb,EAAe,EAAK;GACtB;EACD,CAAA;CACE,EAAA,CAAA;AAET"}
|
|
1
|
+
{"version":3,"file":"SubmissionDirectoryList.js","names":[],"sources":["../../../src/components/ChallengeSubmission/SubmissionDirectoryList.tsx"],"sourcesContent":["import SynapseClient from '@/synapse-client'\nimport {\n invalidateAllQueriesForEntity,\n useGetEntities,\n useGetEntityChildren,\n} from '@/synapse-queries'\nimport { useSynapseContext } from '@/utils'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport {\n BackendDestinationEnum,\n getEndpoint,\n} from '@/utils/functions/getEndpoint'\nimport NotesTwoTone from '@mui/icons-material/NotesTwoTone'\nimport { Box, Button, Radio, Typography } from '@mui/material'\nimport { DataGrid, GridCellParams, GridColDef } from '@mui/x-data-grid'\nimport { EntityType } from '@sage-bionetworks/synapse-client'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport {\n Direction,\n Entity,\n EntityChildrenRequest,\n EntityHeader,\n EntityLookupRequest,\n FILE_ENTITY_CONCRETE_TYPE_VALUE,\n FileEntity,\n FileUploadComplete,\n SortBy,\n UploadCallbackResp,\n} from '@sage-bionetworks/synapse-types'\nimport { useQueryClient } from '@tanstack/react-query'\nimport dayjs from 'dayjs'\nimport { useEffect, useMemo, useState } from 'react'\nimport { Link } from 'react-router'\nimport ConfirmationDialog from '../ConfirmationDialog'\nimport CopyToClipboardIcon from '../CopyToClipboardIcon'\nimport { ErrorBanner } from '../error/ErrorBanner'\nimport FileUpload from '../FileUpload'\nimport IconSvg from '../IconSvg'\nimport { EntityItem } from './ChallengeSubmission'\n\ntype SubmissionDirectoryRow = {\n id: string\n name: string\n modifiedOn: string\n}\n\ntype SubmissionDirectoryListProps = {\n pageSize: number\n challengeProjectId: string\n entityType: typeof EntityType.dockerrepo | typeof EntityType.file\n onItemSelected: (selected: EntityItem) => void\n}\n\ntype FileUploadAttempt = FileUploadComplete & {\n entityId?: string\n}\n\nfunction SubmissionDirectoryList({\n pageSize,\n challengeProjectId,\n entityType,\n onItemSelected,\n}: SubmissionDirectoryListProps) {\n const queryClient = useQueryClient()\n const { accessToken, keyFactory } = useSynapseContext()\n const [page, setPage] = useState<number>(0)\n const [selectedItem, setSelectedItem] = useState<EntityItem | undefined>()\n const [errorMessage, setErrorMessage] = useState<string>()\n const [canSubmit, setCanSubmit] = useState<boolean>()\n const [fetchedHeaders, setFetchedHeaders] = useState<EntityHeader[]>([])\n const [nextPageToken, setNextPageToken] = useState<string | undefined>()\n const [fetchNextPage, setFetchNextPage] = useState<boolean>(false)\n const [confirmOpen, setConfirmOpen] = useState<boolean>(false)\n const [uploadAttempt, setUploadAttempt] = useState<FileUploadAttempt>()\n\n const PER_PAGE = pageSize\n const HEADERS_PER_PAGE = 50\n const PROJECT_URL = `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}Synapse:${challengeProjectId}`\n\n const request: EntityChildrenRequest = {\n parentId: challengeProjectId,\n nextPageToken: fetchNextPage ? nextPageToken : null,\n includeTypes: [entityType],\n includeTotalChildCount: true,\n sortBy: SortBy.MODIFIED_ON,\n sortDirection: Direction.DESC,\n }\n\n const { data: headerResults, refetch } = useGetEntityChildren(request, {\n enabled: !!challengeProjectId,\n throwOnError: true,\n })\n\n useEffect(() => {\n if (headerResults) {\n const newHeaders = [...fetchedHeaders]\n const headerPage = Math.floor(((page + 1) * PER_PAGE) / HEADERS_PER_PAGE)\n const start = headerPage * HEADERS_PER_PAGE\n newHeaders.splice(start, start + HEADERS_PER_PAGE, ...headerResults.page)\n setFetchedHeaders(newHeaders)\n setFetchNextPage(false)\n setNextPageToken(headerResults.nextPageToken)\n }\n // TODO: Temporary useEffect hook to remove onSuccess QueryOption for @tanstack/react-query v5\n // Refactor this component to remove this effect.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [headerResults])\n\n function getPageHeaders() {\n const pageStart = page * PER_PAGE\n const pageHeaders = fetchedHeaders.slice(pageStart, pageStart + PER_PAGE)\n return pageHeaders\n }\n\n function reset() {\n setErrorMessage(undefined)\n setCanSubmit(undefined)\n setFetchedHeaders([])\n setNextPageToken(undefined)\n setFetchNextPage(false)\n refetch()\n }\n\n useEffect(() => {\n reset()\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [entityType, pageSize])\n\n const queries = useGetEntities(getPageHeaders())\n const entities = useMemo(\n () =>\n queries\n .filter(q => q.status === 'success')\n .map(q => q.data) as EntityItem[],\n [queries],\n )\n const areEntitiesLoading = queries.some(q => q.isLoading)\n\n const entityChangeHandler = async (value: string) => {\n setCanSubmit(false)\n const entity = entities.find(entity => entity?.id === value)\n if (entity) {\n setSelectedItem(entity)\n if (entityType === EntityType.dockerrepo) {\n let commits\n try {\n commits = await SynapseClient.getDockerTag(\n entity.id!,\n accessToken,\n 0,\n 1,\n )\n } catch (e) {\n return setErrorMessage(e.message)\n }\n if (commits.totalNumberOfResults === 0) {\n return setErrorMessage(\n 'No commits have been made to this repository. Please select a repository with at least one commit.',\n )\n }\n }\n setCanSubmit(true)\n setErrorMessage(undefined)\n }\n }\n\n const columns: GridColDef[] = [\n {\n field: 'radiobutton',\n headerName: '',\n width: 25,\n sortable: false,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: params => {\n return (\n <Radio\n value={params.id}\n checked={params.id === selectedItem?.id}\n onChange={event => {\n entityChangeHandler(event.target.value)\n }}\n />\n )\n },\n },\n {\n field: 'name',\n headerName:\n entityType === EntityType.dockerrepo\n ? 'Docker Repository'\n : 'File Name',\n flex: 1,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: (params: GridCellParams<Entity, SubmissionDirectoryRow>) => (\n <Link\n to={{\n pathname: `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}Synapse:${params.row.id}`,\n }}\n target=\"_blank\"\n >\n {params.row.name}\n </Link>\n ),\n },\n {\n field: 'modifiedOn',\n headerName: 'Updated On',\n width: 100,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n },\n {\n field: 'id',\n headerName: 'ID',\n width: 200,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n },\n ]\n\n const getRows = (entities: EntityItem[]) => {\n const newRows: SubmissionDirectoryRow[] = []\n entities.forEach(entity => {\n newRows.push({\n id: entity.id!,\n name:\n entityType === EntityType.dockerrepo\n ? (entity.repositoryName ?? entity.name)\n : entity.name,\n modifiedOn: formatDate(dayjs(entity.modifiedOn), 'MM/DD/YY'),\n })\n })\n return newRows\n }\n\n const handlePageChange = (newPageNum: number) => {\n const lastIndexNeeded = Math.min(\n headerResults?.totalChildCount ?? 0,\n (newPageNum + 1) * PER_PAGE,\n )\n if (lastIndexNeeded > fetchedHeaders.length) {\n setFetchNextPage(true)\n }\n setPage(newPageNum)\n }\n\n const itemSelectedHandler = () => {\n onItemSelected(selectedItem!)\n }\n\n function createEntity(file: FileUploadAttempt) {\n // Create Entity\n if (!file) return\n const { fileHandleId, fileName } = file\n const newFileEntity: FileEntity = {\n parentId: challengeProjectId,\n name: fileName,\n concreteType: FILE_ENTITY_CONCRETE_TYPE_VALUE,\n dataFileHandleId: fileHandleId,\n }\n SynapseClient.createEntity(newFileEntity, accessToken)\n .then(() => {\n reset()\n })\n .catch((err: SynapseClientError) => {\n setErrorMessage(err.reason)\n })\n }\n\n async function updateEntity() {\n if (!uploadAttempt) return\n const { fileHandleId, entityId } = uploadAttempt\n if (!entityId)\n return setErrorMessage('Error: missing entityId. Please try again.')\n // Get the entity\n let entity: FileEntity\n try {\n entity = await SynapseClient.getEntity(accessToken, entityId)\n } catch (err) {\n return setErrorMessage(`The entity ${entityId} could not be retrieved.`)\n }\n\n const updateRequest: FileEntity = {\n id: entity.id,\n name: entity.name,\n dataFileHandleId: fileHandleId,\n concreteType: FILE_ENTITY_CONCRETE_TYPE_VALUE,\n parentId: entity.parentId,\n etag: entity.etag,\n modifiedOn: entity.modifiedOn,\n }\n\n try {\n const updatedEntity = await SynapseClient.updateEntity(\n updateRequest,\n accessToken,\n true,\n )\n await invalidateAllQueriesForEntity(\n queryClient,\n keyFactory,\n updatedEntity.id!,\n )\n queryClient.setQueryData(\n keyFactory.getEntityQueryKey(updatedEntity.id!),\n updatedEntity,\n )\n reset()\n } catch (err) {\n setErrorMessage(err.reason)\n }\n }\n\n const handleUpload = async (response: UploadCallbackResp) => {\n if (response.success && response.resp) {\n const { fileName } = response.resp\n\n // Lookup entity\n const entityLookupRequest: EntityLookupRequest = {\n entityName: fileName,\n parentId: challengeProjectId,\n }\n try {\n const entityId = await SynapseClient.lookupChildEntity(\n entityLookupRequest,\n accessToken,\n )\n // Entity exists, prompt user to update it\n if (entityId) {\n setUploadAttempt({ ...response.resp, entityId: entityId.id })\n setConfirmOpen(true)\n }\n } catch (err) {\n // An existing entity was not found for this file, create it\n setUploadAttempt(undefined)\n createEntity(response.resp)\n }\n } else if (!response.success && response.error) {\n setErrorMessage(response.error.reason as string)\n } else {\n setErrorMessage('An unknown error occurred. Please try again.')\n }\n }\n\n return (\n <Box>\n <Box\n sx={{\n display: 'flex',\n backgroundColor: '#FBFBFC',\n padding: '10px',\n justifyContent: 'space-between',\n }}\n >\n <Typography\n variant=\"h6\"\n sx={{ fontSize: '18px', lineHeight: '20px', fontWeight: 700 }}\n >\n {entityType === EntityType.file\n ? 'Submit File'\n : 'Submit Docker Image'}\n </Typography>\n <Box sx={{ display: 'flex' }}>\n <Typography\n variant=\"body1\"\n sx={{ fontSize: '14px', color: '#71767F' }}\n >\n Your Project SynID:{' '}\n <Link to={{ pathname: PROJECT_URL }} target=\"_blank\">\n {challengeProjectId}\n </Link>\n </Typography>\n <CopyToClipboardIcon value={PROJECT_URL} sx={{ marginTop: '-4px' }} />\n </Box>\n </Box>\n <Box\n sx={{\n my: 3,\n display: 'flex',\n }}\n >\n <NotesTwoTone\n sx={{\n width: '16px',\n height: '16px',\n verticalAlign: 'text-bottom',\n }}\n />\n <Box\n sx={{\n ml: 1,\n }}\n >\n {entityType === EntityType.file && (\n <>\n Choose a prediction file from your submission directory below and\n click \"Submit Selection\" to pick an evaluation queue. If you need\n to add a new file, click \"Upload File\" first.\n </>\n )}\n {entityType === EntityType.dockerrepo && (\n <>\n Choose a Docker image from your submission directory below and\n click \"Submit Selection\" to pick an image version and evaluation\n queue. If you need to upload a new image to your project (\n <code>{challengeProjectId}</code>), see our{' '}\n <Link\n to=\"https://github.com/Sage-Bionetworks-Challenges/sample-model-templates#build-your-model\"\n target=\"_blank\"\n >\n Docker model submission guide\n </Link>{' '}\n for command-line instructions on how to build and upload.\n </>\n )}\n </Box>\n </Box>\n <Box>\n <DataGrid\n loading={areEntitiesLoading}\n columns={columns}\n rows={getRows(entities)}\n rowCount={headerResults?.totalChildCount ?? 0}\n pagination\n paginationMode=\"server\"\n paginationModel={{ page, pageSize: PER_PAGE }}\n pageSizeOptions={[PER_PAGE]}\n onPaginationModelChange={({ page }) => {\n handlePageChange(page)\n }}\n density=\"compact\"\n autoHeight\n sx={{\n fontSize: '14px',\n border: 'none',\n height: '100%',\n '& .MuiDataGrid-columnHeader': {\n backgroundColor: '#F1F3F5',\n },\n '& .Mui-odd': {\n backgroundColor: '#FBFBFC',\n },\n '.MuiDataGrid-columnHeaderTitleContainer': {\n justifyContent: 'space-between',\n },\n '.radio': {\n display: 'flex',\n alignItems: 'center',\n height: '100%',\n },\n }}\n getRowClassName={params =>\n params.indexRelativeToCurrentPage % 2 === 0 ? 'Mui-even' : 'Mui-odd'\n }\n />\n </Box>\n {errorMessage && <ErrorBanner error={errorMessage}></ErrorBanner>}\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n {entityType === EntityType.file && (\n <FileUpload\n label=\"Upload File\"\n buttonProps={{\n variant: 'outlined',\n endIcon: <IconSvg icon=\"upload\" />,\n sx: { lineHeight: 1 },\n }}\n onComplete={resp => {\n handleUpload(resp)\n }}\n />\n )}\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={itemSelectedHandler}\n disabled={!canSubmit}\n >\n Submit Selection\n </Button>\n </Box>\n <ConfirmationDialog\n open={confirmOpen}\n title=\"File exists\"\n content={\n <Typography variant=\"body1\" sx={{ fontSize: '16px' }}>\n A file named "{uploadAttempt?.fileName}" (\n {uploadAttempt?.entityId}) already exists in this location. Do you\n want to update the existing file and create a new version?\n </Typography>\n }\n onCancel={() => setConfirmOpen(false)}\n onConfirm={() => {\n updateEntity()\n setConfirmOpen(false)\n }}\n />\n </Box>\n )\n}\n\nexport default SubmissionDirectoryList\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeTeamTable.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamTable.tsx"],"names":[],"mappings":"AAgBA,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC,CAAA;AAOD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"ChallengeTeamTable.d.ts","sourceRoot":"","sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamTable.tsx"],"names":[],"mappings":"AAgBA,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC,CAAA;AAOD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,2CAgLxE"}
|
|
@@ -9,8 +9,8 @@ import { ChallengeTeamSearch as s } from "./ChallengeTeamSearch.js";
|
|
|
9
9
|
import { useMemo as c, useState as l } from "react";
|
|
10
10
|
import { Box as u, Link as d, Radio as f, Tooltip as p } from "@mui/material";
|
|
11
11
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
12
|
-
import
|
|
13
|
-
import _ from "
|
|
12
|
+
import g from "dayjs";
|
|
13
|
+
import _ from "@mui/icons-material/EmailTwoTone";
|
|
14
14
|
import { DataGrid as v } from "@mui/x-data-grid";
|
|
15
15
|
//#region src/components/ChallengeTeamWizard/ChallengeTeamTable.tsx
|
|
16
16
|
function y(y) {
|
|
@@ -66,7 +66,7 @@ function y(y) {
|
|
|
66
66
|
align: "center",
|
|
67
67
|
renderCell: ({ value: e }) => e ? /* @__PURE__ */ m(p, {
|
|
68
68
|
title: "You have been invited to join this team",
|
|
69
|
-
children: /* @__PURE__ */ m(
|
|
69
|
+
children: /* @__PURE__ */ m(_, {
|
|
70
70
|
fontSize: "small",
|
|
71
71
|
sx: { color: "grey.700" }
|
|
72
72
|
})
|
|
@@ -79,7 +79,7 @@ function y(y) {
|
|
|
79
79
|
filterable: !1,
|
|
80
80
|
hideable: !1,
|
|
81
81
|
disableColumnMenu: !0,
|
|
82
|
-
renderCell: ({ value: e }) => o(
|
|
82
|
+
renderCell: ({ value: e }) => o(g(e), "MM/DD/YY")
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
field: "description",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeTeamTable.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamTable.tsx"],"sourcesContent":["import {\n useGetAllOpenMembershipInvitations,\n useGetChallengeTeamList,\n useGetCurrentUserProfile,\n useGetTeamList,\n} from '@/synapse-queries'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport
|
|
1
|
+
{"version":3,"file":"ChallengeTeamTable.js","names":[],"sources":["../../../src/components/ChallengeTeamWizard/ChallengeTeamTable.tsx"],"sourcesContent":["import {\n useGetAllOpenMembershipInvitations,\n useGetChallengeTeamList,\n useGetCurrentUserProfile,\n useGetTeamList,\n} from '@/synapse-queries'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport { formatDate } from '@/utils/functions/DateFormatter'\nimport EmailTwoTone from '@mui/icons-material/EmailTwoTone'\nimport { Box, Link, Radio, Tooltip } from '@mui/material'\nimport { DataGrid, GridColDef } from '@mui/x-data-grid'\nimport { Team } from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { useMemo, useState } from 'react'\nimport { ChallengeTeamSearch } from './ChallengeTeamSearch'\n\nexport type ChallengeTeamTableProps = {\n challengeId: string\n selectedTeamId?: string\n onSelectTeam: (teamId?: string) => void\n}\n\n// Custom type for the challenge team table that combines fields from the Team and the ChallengeTeam record\ntype RowData = Team & {\n hasInvitation: boolean\n}\n\n/**\n * Table component that displays teams that\n * 1. are registered for the challenge specified by the challengeId prop\n * 2. the current user is able to join, create a request to join, or accept an invitation to join\n */\nexport default function ChallengeTeamTable(props: ChallengeTeamTableProps) {\n const { challengeId, onSelectTeam, selectedTeamId } = props\n const { data: registeredTeams, isLoading: isLoadingChallengeTeams } =\n useGetChallengeTeamList(challengeId)\n const { data: user } = useGetCurrentUserProfile()\n const { data: openInvitationsToJoinTeams } =\n useGetAllOpenMembershipInvitations(user?.ownerId!, {\n enabled: Boolean(user?.ownerId),\n })\n const [searchValue, setSearchValue] = useState('')\n const teamIdList = registeredTeams?.map(team => team.teamId) ?? []\n const { data: teamsList, isLoading: isLoadingTeamList } = useGetTeamList(\n teamIdList,\n {\n enabled: !!teamIdList.length,\n },\n )\n\n const allRows: RowData[] = useMemo(() => {\n const term = searchValue.toLowerCase()\n const teams =\n teamsList?.list.filter(\n team =>\n team.canPublicJoin ||\n // `canRequestMembership` is true by default if the property is not present\n team.canRequestMembership !== false ||\n openInvitationsToJoinTeams?.some(\n invitation => invitation.teamId === team.id,\n ),\n ) ?? []\n\n let filtered = teams\n if (term.length) {\n filtered = teams.filter(team => {\n return (\n team.name.toLowerCase().includes(term) ||\n team.description?.toLowerCase().includes(term)\n )\n })\n }\n return filtered.map((team): RowData => ({\n ...team,\n hasInvitation: Boolean(\n openInvitationsToJoinTeams?.some(\n invitation => invitation.teamId === team.id,\n ),\n ),\n }))\n }, [openInvitationsToJoinTeams, searchValue, teamsList?.list])\n\n const isLoading = isLoadingChallengeTeams || isLoadingTeamList\n\n const columns: GridColDef<RowData>[] = useMemo(\n () => [\n {\n field: 'radiobutton',\n headerName: '',\n width: 25,\n sortable: false,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: ({ row }) => {\n return (\n <Radio\n value={row.id}\n checked={String(row.id) === selectedTeamId}\n onClick={() => {\n onSelectTeam(String(row.id))\n }}\n inputProps={{ 'aria-label': `Select ${row.name}` }}\n />\n )\n },\n },\n {\n field: 'name',\n headerName: 'Team Name',\n flex: 1,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: ({ row }) => (\n <Link\n href={`${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}/Team:${row.id}`}\n target=\"_blank\"\n underline={'hover'}\n >\n {row.name}\n </Link>\n ),\n },\n {\n field: 'hasInvitation',\n headerName: '',\n width: 15,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n align: 'center',\n renderCell: ({ value }) =>\n value ? (\n <Tooltip title={'You have been invited to join this team'}>\n <EmailTwoTone fontSize={'small'} sx={{ color: 'grey.700' }} />\n </Tooltip>\n ) : null,\n },\n {\n field: 'created',\n headerName: 'Created On',\n width: 100,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n renderCell: ({ value }) => formatDate(dayjs(value), 'MM/DD/YY'),\n },\n {\n field: 'description',\n headerName: 'Description',\n flex: 1,\n filterable: false,\n hideable: false,\n disableColumnMenu: true,\n },\n ],\n [onSelectTeam, selectedTeamId],\n )\n\n return (\n <Box sx={{ height: 220 }}>\n {!isLoading && (\n <ChallengeTeamSearch\n value={searchValue}\n onChange={e => setSearchValue(e.target.value)}\n rowCount={allRows.length}\n />\n )}\n <DataGrid\n initialState={{\n sorting: {\n sortModel: [{ field: 'hasInvitation', sort: 'desc' }],\n },\n }}\n loading={isLoading}\n rows={allRows}\n columns={columns}\n rowCount={5}\n hideFooter\n density=\"compact\"\n rowBufferPx={500} // Buffer ensures all rows required in test are loaded.\n sx={{\n border: 'none',\n height: '100%',\n '& .MuiDataGrid-columnHeader': {\n backgroundColor: '#F1F3F5',\n },\n '& .Mui-odd': {\n backgroundColor: '#FBFBFC',\n },\n '.MuiDataGrid-columnHeaderTitleContainer': {\n justifyContent: 'space-between',\n },\n '.radio': {\n display: 'flex',\n alignItems: 'center',\n height: '100%',\n },\n }}\n getRowClassName={params =>\n params.indexRelativeToCurrentPage % 2 === 0 ? 'Mui-even' : 'Mui-odd'\n }\n />\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
@@ -2,10 +2,10 @@ import e from "./ChallengeTeamTable.js";
|
|
|
2
2
|
import "react";
|
|
3
3
|
import { Box as t, Button as n, Typography as r } from "@mui/material";
|
|
4
4
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
|
-
import
|
|
6
|
-
import s from "@mui/
|
|
5
|
+
import o from "@mui/icons-material/AddCircleTwoTone";
|
|
6
|
+
import { Stack as s } from "@mui/system";
|
|
7
7
|
//#region src/components/ChallengeTeamWizard/SelectChallengeTeam.tsx
|
|
8
|
-
var c = "To participate in a challenge, you need to create a new Team or join an existing one. By default, the participant who creates a team is the \"Team Captain\" and has the ability to invite and remove members. All team members will need a Synapse account so that they can login and accept the team invitation.", l = ({ challengeId: l, onCreateTeam: u, selectedTeamId: d, onSelectTeam: f }) => /* @__PURE__ */ a(
|
|
8
|
+
var c = "To participate in a challenge, you need to create a new Team or join an existing one. By default, the participant who creates a team is the \"Team Captain\" and has the ability to invite and remove members. All team members will need a Synapse account so that they can login and accept the team invitation.", l = ({ challengeId: l, onCreateTeam: u, selectedTeamId: d, onSelectTeam: f }) => /* @__PURE__ */ a(s, {
|
|
9
9
|
spacing: 2,
|
|
10
10
|
children: [
|
|
11
11
|
/* @__PURE__ */ i(r, {
|
|
@@ -25,7 +25,7 @@ var c = "To participate in a challenge, you need to create a new Team or join an
|
|
|
25
25
|
color: "primary",
|
|
26
26
|
variant: "contained",
|
|
27
27
|
onClick: u,
|
|
28
|
-
startIcon: /* @__PURE__ */ i(
|
|
28
|
+
startIcon: /* @__PURE__ */ i(o, {}),
|
|
29
29
|
children: "Create New Team"
|
|
30
30
|
}) })
|
|
31
31
|
]
|
|
@@ -5,8 +5,8 @@ import { createLinkAndDownload as r } from "./CitationPopoverUtils.js";
|
|
|
5
5
|
import { useState as i } from "react";
|
|
6
6
|
import { Alert as a, Box as o, Button as s, FormControl as c, MenuItem as l, Popover as u, Select as d, Stack as f, Typography as p } from "@mui/material";
|
|
7
7
|
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
8
|
-
import
|
|
9
|
-
import v from "@mui/icons-material/
|
|
8
|
+
import _ from "@mui/icons-material/Close";
|
|
9
|
+
import v from "@mui/icons-material/KeyboardArrowDown";
|
|
10
10
|
//#region src/components/CitationPopover/CitationPopoverContent.tsx
|
|
11
11
|
var y = {
|
|
12
12
|
width: "100%",
|
|
@@ -82,7 +82,7 @@ var y = {
|
|
|
82
82
|
lineHeight: "normal"
|
|
83
83
|
},
|
|
84
84
|
children: "Cite As:"
|
|
85
|
-
}), /* @__PURE__ */ h(
|
|
85
|
+
}), /* @__PURE__ */ h(_, {
|
|
86
86
|
sx: {
|
|
87
87
|
cursor: "pointer",
|
|
88
88
|
display: {
|
|
@@ -148,7 +148,7 @@ var y = {
|
|
|
148
148
|
onChange: (e) => {
|
|
149
149
|
A(e.target.value);
|
|
150
150
|
},
|
|
151
|
-
IconComponent:
|
|
151
|
+
IconComponent: v,
|
|
152
152
|
children: [
|
|
153
153
|
/* @__PURE__ */ h(l, {
|
|
154
154
|
value: "bibtex",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CitationPopoverContent.js","names":[],"sources":["../../../src/components/CitationPopover/CitationPopoverContent.tsx"],"sourcesContent":["import {\n Alert,\n Box,\n Button,\n FormControl,\n MenuItem,\n Popover,\n Select,\n SelectChangeEvent,\n Stack,\n SxProps,\n Typography,\n PopoverProps,\n} from '@mui/material'\nimport React from 'react'\nimport { useCitation } from './useCitation'\nimport { createLinkAndDownload } from './CitationPopoverUtils'\nimport
|
|
1
|
+
{"version":3,"file":"CitationPopoverContent.js","names":[],"sources":["../../../src/components/CitationPopover/CitationPopoverContent.tsx"],"sourcesContent":["import {\n Alert,\n Box,\n Button,\n FormControl,\n MenuItem,\n Popover,\n Select,\n SelectChangeEvent,\n Stack,\n SxProps,\n Typography,\n PopoverProps,\n} from '@mui/material'\nimport React from 'react'\nimport { useCitation } from './useCitation'\nimport { createLinkAndDownload } from './CitationPopoverUtils'\nimport KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'\nimport CloseIcon from '@mui/icons-material/Close'\nimport { useState } from 'react'\nimport CopyToClipboardIcon from '../CopyToClipboardIcon'\nimport { CitationProps, CitationFormat } from './CitationTypes'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\n\nconst selectSx: SxProps = {\n width: '100%',\n '.MuiInputBase-root': {\n minHeight: '38px',\n borderRadius: 0,\n '&:before, &:after': {\n borderBottom: 'none !important',\n },\n },\n '& .MuiOutlinedInput-notchedOutline': {\n border: 0,\n },\n '&.MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline': {\n border: 'none',\n },\n '.MuiSelect-select': {\n display: 'flex',\n alignItems: 'center',\n },\n '.MuiInputBase-input': {\n padding: '7px 10px',\n },\n}\n\nexport type CitationPopoverProps = CitationProps &\n Pick<PopoverProps, 'anchorEl' | 'open' | 'id' | 'onClose'>\n\nexport const CitationPopoverContent = (\n props: CitationPopoverProps,\n): React.ReactNode => {\n const {\n doi,\n title,\n boilerplateText,\n defaultCitationFormat,\n onClose,\n anchorEl,\n open,\n id,\n } = props\n\n const [citationFormat, setCitationFormat] = useState<CitationFormat>(\n defaultCitationFormat || 'bibtex',\n )\n const {\n data: citation,\n isLoading,\n error,\n } = useCitation(doi || '', citationFormat, true)\n\n const handleDownload = (citation: string) => {\n if (!citation) {\n return\n }\n const extensionMap: Record<string, string> = {\n apa: 'ris',\n bibtex: 'bib',\n ieee: 'ris',\n nature: 'ris',\n science: 'ris',\n }\n const fileExtension = extensionMap[citationFormat] || 'txt'\n\n const blob = new Blob([citation], { type: 'text/plain' })\n const url = URL.createObjectURL(blob)\n\n createLinkAndDownload(title || 'citation', fileExtension, url)\n }\n\n const handleChange = (event: SelectChangeEvent<CitationFormat>) => {\n setCitationFormat(event.target.value as CitationFormat)\n }\n\n return (\n <Popover\n aria-label=\"Citation options\"\n role=\"dialog\"\n id={id}\n elevation={9}\n open={open}\n anchorEl={anchorEl}\n onClose={onClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n }}\n slotProps={{\n paper: {\n square: true,\n sx: theme => ({\n width: '500px',\n position: 'relative',\n [theme.breakpoints.down('sm')]: {\n maxWidth: '100%',\n maxHeight: '100%',\n top: '0 !important',\n left: '0 !important',\n bottom: '0 !important',\n },\n }),\n },\n }}\n >\n <Stack\n sx={{\n gap: '20px',\n padding: '20px',\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <Typography\n sx={{ fontSize: '20px', fontWeight: 700, lineHeight: 'normal' }}\n >\n Cite As:\n </Typography>\n <CloseIcon\n sx={{\n cursor: 'pointer',\n display: { xs: 'block', sm: 'none' },\n marginLeft: 'auto',\n color: '#878E95',\n }}\n onClick={() => {\n onClose?.({}, 'escapeKeyDown')\n }}\n />\n </Box>\n {error && (\n <Alert severity={'error'} sx={{ my: 2 }} icon={false}>\n {error.message}\n </Alert>\n )}\n <Typography\n variant=\"smallText1\"\n component={'div'}\n sx={{\n lineHeight: 'normal',\n maxHeight: '300px',\n overflowY: 'scroll',\n wordWrap: 'break-word',\n }}\n >\n {boilerplateText && (\n <>\n <MarkdownSynapse markdown={boilerplateText} />\n <br />\n </>\n )}\n {isLoading ? (\n <Box sx={{ fontWeight: 700 }}>\n <br />\n Loading citation...\n </Box>\n ) : (\n citation\n )}\n </Typography>\n <Box\n sx={{\n display: 'flex',\n flexDirection: { xs: 'column', sm: 'row' },\n gap: { xs: '10px', sm: '8px' },\n width: '100%',\n maxHeight: '38px',\n }}\n >\n <Box sx={{ flex: 1 }}>\n <FormControl sx={selectSx}>\n <Select\n variant=\"standard\"\n sx={{\n svg: {\n color: '#878E95',\n width: '24px',\n height: '24px',\n right: '10px',\n },\n }}\n value={citationFormat}\n onChange={handleChange}\n IconComponent={KeyboardArrowDown}\n >\n <MenuItem value={'bibtex'}>bibtex</MenuItem>\n <MenuItem value={'apa'}>apa</MenuItem>\n <MenuItem value={'ieee'}>ieee</MenuItem>\n <MenuItem value={'nature'}>nature</MenuItem>\n <MenuItem value={'science'}>science</MenuItem>\n </Select>\n </FormControl>\n </Box>\n <Button\n onClick={() => handleDownload(citation || '')}\n variant=\"contained\"\n sx={{\n padding: '6px 16px',\n borderRadius: 0,\n }}\n >\n Download Citation\n </Button>\n <CopyToClipboardIcon\n value={citation || ''}\n sx={{\n borderRadius: 0,\n padding: '6px 16px',\n border: '1px solid',\n borderColor: 'primary.main',\n }}\n />\n </Box>\n </Stack>\n </Popover>\n )\n}\n\nexport default CitationPopoverContent\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentCollapse.d.ts","sourceRoot":"","sources":["../../src/components/ComponentCollapse.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ComponentCollapse.d.ts","sourceRoot":"","sources":["../../src/components/ComponentCollapse.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAiB,OAAO,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAEL,iBAAiB,EACjB,SAAS,EAGV,MAAM,OAAO,CAAA;AAEd,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;IACrD,SAAS,EAAE,SAAS,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,MAAM,EACN,QAAQ,GACT,EAAE,sBAAsB,2CAsDxB"}
|
|
@@ -2,7 +2,8 @@ import { spreadSx as e } from "../theme/spreadSx.js";
|
|
|
2
2
|
import { useId as t, useState as n } from "react";
|
|
3
3
|
import { Box as r, Collapse as i } from "@mui/material";
|
|
4
4
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
-
import
|
|
5
|
+
import s from "@mui/icons-material/KeyboardArrowDownTwoTone";
|
|
6
|
+
import c from "@mui/icons-material/KeyboardArrowUpTwoTone";
|
|
6
7
|
//#region src/components/ComponentCollapse.tsx
|
|
7
8
|
function l({ component: l, defaultVisible: u, componentContainerSx: d, collapseBoxSx: f, iconSx: p, children: m }) {
|
|
8
9
|
let [h, g] = n(u), _ = t(), v = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentCollapse.js","names":[],"sources":["../../src/components/ComponentCollapse.tsx"],"sourcesContent":["import { spreadSx } from '@/theme/spreadSx'\nimport
|
|
1
|
+
{"version":3,"file":"ComponentCollapse.js","names":[],"sources":["../../src/components/ComponentCollapse.tsx"],"sourcesContent":["import { spreadSx } from '@/theme/spreadSx'\nimport KeyboardArrowDownTwoTone from '@mui/icons-material/KeyboardArrowDownTwoTone'\nimport KeyboardArrowUpTwoTone from '@mui/icons-material/KeyboardArrowUpTwoTone'\nimport { Box, Collapse, SxProps } from '@mui/material'\nimport {\n KeyboardEvent,\n PropsWithChildren,\n ReactNode,\n useId,\n useState,\n} from 'react'\n\nexport type ComponentCollapseProps = PropsWithChildren<{\n component: ReactNode\n defaultVisible?: boolean // default to false (collapsed)\n componentContainerSx?: SxProps\n collapseBoxSx?: SxProps\n iconSx?: SxProps\n}>\n\n/**\n * Wrap any child components in a collapse, using a custom component as the trigger\n */\nexport default function ComponentCollapse({\n component,\n defaultVisible,\n componentContainerSx,\n collapseBoxSx,\n iconSx,\n children,\n}: ComponentCollapseProps) {\n const [show, setShow] = useState(defaultVisible)\n const collapseId = useId()\n const allIconSx: SxProps = {\n color: 'grey.700',\n marginBottom: '-5px !important',\n height: '18px',\n ...iconSx,\n }\n\n const componentContainerDefaultSx: SxProps = {\n display: 'flex',\n textAlign: 'left',\n justifyContent: 'space-between',\n backgroundColor: 'grey.200',\n padding: '15px',\n '&:hover': {\n cursor: 'pointer',\n },\n }\n const collapseBoxDefaultSx: SxProps = {\n backgroundColor: 'grey.100',\n padding: '25px',\n }\n\n return (\n <div className=\"MarkdownCollapse\">\n <Box\n component=\"button\"\n sx={spreadSx(componentContainerDefaultSx, componentContainerSx)}\n onClick={() => setShow(!show)}\n onKeyDown={(e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n setShow(!show)\n }\n }}\n aria-controls={collapseId}\n aria-expanded={show}\n >\n {component}\n {show ? (\n <KeyboardArrowUpTwoTone sx={allIconSx} />\n ) : (\n <KeyboardArrowDownTwoTone sx={allIconSx} />\n )}\n </Box>\n <Collapse in={show}>\n <Box sx={spreadSx(collapseBoxDefaultSx, collapseBoxSx)}>\n <div id={collapseId}>{children}</div>\n </Box>\n </Collapse>\n </div>\n )\n}\n"],"mappings":";;;;;;;AAuBA,SAAwB,EAAkB,EACxC,cACA,mBACA,yBACA,kBACA,WACA,eACyB;CACzB,IAAM,CAAC,GAAM,KAAW,EAAS,CAAc,GACzC,IAAa,EAAM,GACnB,IAAqB;EACzB,OAAO;EACP,cAAc;EACd,QAAQ;EACR,GAAG;CACL;CAiBA,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD;GACE,WAAU;GACV,IAAI,EAAS;IAlBjB,SAAS;IACT,WAAW;IACX,gBAAgB;IAChB,iBAAiB;IACjB,SAAS;IACT,WAAW,EACT,QAAQ,UACV;GAWiB,GAA6B,CAAoB;GAC9D,eAAe,EAAQ,CAAC,CAAI;GAC5B,YAAY,MAAqB;IAC/B,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,EAAQ,CAAC,CAAI;GAEjB;GACA,iBAAe;GACf,iBAAe;aAXjB,CAaG,GAEC,EADD,IACE,IAEA,GAFD,EAAwB,IAAI,EAAY,CAEE,CAEzC;MACL,kBAAC,GAAD;GAAU,IAAI;aACZ,kBAAC,GAAD;IAAK,IAAI,EAAS;KA3BtB,iBAAiB;KACjB,SAAS;IA0Ba,GAAsB,CAAa;cACnD,kBAAC,OAAD;KAAK,IAAI;KAAa;IAAc,CAAA;GACjC,CAAA;EACG,CAAA,CACP;;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SynapseGrid.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"names":[],"mappings":"AAgCA,OAAO,EACL,iBAAiB,EAGlB,MAAM,kCAAkC,CAAA;AAEzC,OAAO,EACL,GAAG,EAOJ,MAAM,OAAO,CAAA;AAqBd,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,GAAG,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACpD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CACjD,CAAA;AA2hBD,iBAAS,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAM3C;AAED,eAAe,WAAW,CAAA"}
|