synapse-react-client 4.0.44 → 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.d.ts +1 -1
- package/dist/SWC.index.js +2 -2
- package/dist/SWC.index.js.map +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.d.ts +2 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js +126 -125
- package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListItem.d.ts +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListItem.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListItem.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/EDucPreviewStep/EDucPreviewStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js +28 -16
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js +99 -97
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.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/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/requestFlowTypes.d.ts +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/requestFlowTypes.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/RequestDataStep.d.ts +1 -4
- package/dist/components/AccessRequirementList/RequestDataStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/RequestDataStep.js +15 -18
- package/dist/components/AccessRequirementList/RequestDataStep.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/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.d.ts.map +1 -1
- package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js +52 -49
- package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.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/FormTemplateEditor/useSaveFormTemplate.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/useSaveFormTemplate.js.map +1 -1
- package/dist/components/FormTemplateReferenceField/FormTemplatePreviewDialog.d.ts +9 -0
- package/dist/components/FormTemplateReferenceField/FormTemplatePreviewDialog.d.ts.map +1 -0
- package/dist/components/FormTemplateReferenceField/FormTemplatePreviewDialog.js +45 -0
- package/dist/components/FormTemplateReferenceField/FormTemplatePreviewDialog.js.map +1 -0
- package/dist/components/FormTemplateReferenceField/FormTemplateReferenceField.d.ts +22 -0
- package/dist/components/FormTemplateReferenceField/FormTemplateReferenceField.d.ts.map +1 -0
- package/dist/components/FormTemplateReferenceField/FormTemplateReferenceField.js +139 -0
- package/dist/components/FormTemplateReferenceField/FormTemplateReferenceField.js.map +1 -0
- package/dist/components/Forum/ForumTable.d.ts +17 -5
- package/dist/components/Forum/ForumTable.d.ts.map +1 -1
- package/dist/components/Forum/ForumTable.js +94 -77
- package/dist/components/Forum/ForumTable.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.d.ts.map +1 -1
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js +142 -108
- package/dist/components/SetAccessRequirementCommonFields/SetAccessRequirementCommonFields.js.map +1 -1
- package/dist/components/SetBasicAccessRequirementFields/AccessorRequirements.d.ts.map +1 -1
- package/dist/components/SetBasicAccessRequirementFields/AccessorRequirements.js +15 -15
- package/dist/components/SetBasicAccessRequirementFields/AccessorRequirements.js.map +1 -1
- package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.d.ts.map +1 -1
- package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js +57 -55
- package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.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/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +4 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- 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/accessRequirement/mockJsonSchemaAccessRequirements.d.ts +5 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts.map +1 -1
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js +37 -26
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.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/discussionHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/discussionHandlers.js +40 -33
- package/dist/mocks/msw/handlers/discussionHandlers.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-client/SynapseClient.d.ts +10 -0
- package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
- package/dist/synapse-client/SynapseClient.js +486 -482
- package/dist/synapse-client/SynapseClient.js.map +1 -1
- package/dist/synapse-client/index.js +3 -3
- package/dist/synapse-queries/KeyFactory.d.ts +13 -1
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +11 -1
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +4 -4
- package/dist/synapse-queries/dataaccess/useAccessRequirements.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/useAccessRequirements.js +4 -1
- package/dist/synapse-queries/dataaccess/useAccessRequirements.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts +19 -5
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/useEDuc.js +29 -21
- package/dist/synapse-queries/dataaccess/useEDuc.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts +12 -0
- package/dist/synapse-queries/dataaccess/useFormTemplate.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/useFormTemplate.js +52 -30
- package/dist/synapse-queries/dataaccess/useFormTemplate.js.map +1 -1
- package/dist/synapse-queries/forum/useForum.d.ts +5 -1
- package/dist/synapse-queries/forum/useForum.d.ts.map +1 -1
- package/dist/synapse-queries/forum/useForum.js +23 -1
- package/dist/synapse-queries/forum/useForum.js.map +1 -1
- package/dist/synapse-queries/index.js +185 -184
- package/dist/synapse-queries/jsonschema/useCreateJsonSchema.d.ts +5 -3
- package/dist/synapse-queries/jsonschema/useCreateJsonSchema.d.ts.map +1 -1
- package/dist/synapse-queries/jsonschema/useCreateJsonSchema.js +12 -15
- package/dist/synapse-queries/jsonschema/useCreateJsonSchema.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/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/functions/EntityTypeUtils.d.ts.map +1 -1
- package/dist/utils/functions/EntityTypeUtils.js.map +1 -1
- package/dist/utils/functions/getEndpoint.d.ts +1 -0
- package/dist/utils/functions/getEndpoint.d.ts.map +1 -1
- package/dist/utils/functions/getEndpoint.js +3 -3
- package/dist/utils/functions/getEndpoint.js.map +1 -1
- package/dist/utils/types/RequestableAccessRequirement.d.ts +8 -0
- package/dist/utils/types/RequestableAccessRequirement.d.ts.map +1 -0
- package/dist/utils/types/RequestableAccessRequirement.js +9 -0
- package/dist/utils/types/RequestableAccessRequirement.js.map +1 -0
- package/package.json +6 -5
- package/dist/testutils/ReactQueryMockUtils.js +0 -676
- package/dist/testutils/ReactQueryMockUtils.js.map +0 -1
package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js
CHANGED
|
@@ -10,31 +10,37 @@ import { ExpirationPeriodField as s, getValidExpirationPeriodOrErrorMessage as c
|
|
|
10
10
|
import { forwardRef as l, useEffect as u, useImperativeHandle as d, useState as f } from "react";
|
|
11
11
|
import { Alert as p, Box as m, Checkbox as h, FormControlLabel as g, Typography as _ } from "@mui/material";
|
|
12
12
|
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
13
|
+
import { MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE as x } from "@sage-bionetworks/synapse-types";
|
|
13
14
|
//#region src/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.tsx
|
|
14
|
-
var
|
|
15
|
-
let { accessRequirementId:
|
|
15
|
+
var S = l(function(l, S) {
|
|
16
|
+
let { accessRequirementId: C, onSave: w, onError: T } = l, { data: E, error: D } = n(C, { staleTime: Infinity });
|
|
16
17
|
u(() => {
|
|
17
|
-
|
|
18
|
-
}, [
|
|
19
|
-
let [
|
|
20
|
-
onSuccess: () =>
|
|
21
|
-
onError: () =>
|
|
18
|
+
E && (j(E), N((E.expirationPeriod / e).toString()));
|
|
19
|
+
}, [E]);
|
|
20
|
+
let [O, k] = f(null), [A, j] = f(null), [M, N] = f(""), { mutate: P, isPending: F, error: I } = r({
|
|
21
|
+
onSuccess: () => w(),
|
|
22
|
+
onError: () => T()
|
|
22
23
|
});
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
let e = c(
|
|
26
|
-
typeof e == "string" ? (
|
|
27
|
-
...
|
|
24
|
+
if (d(S, () => ({ save() {
|
|
25
|
+
if (A) {
|
|
26
|
+
let e = c(M);
|
|
27
|
+
typeof e == "string" ? (k(e), T()) : P({
|
|
28
|
+
...A,
|
|
28
29
|
expirationPeriod: e
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
} }), [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
]),
|
|
37
|
-
|
|
33
|
+
M,
|
|
34
|
+
A,
|
|
35
|
+
P,
|
|
36
|
+
T
|
|
37
|
+
]), !A) return D ? /* @__PURE__ */ y(p, {
|
|
38
|
+
severity: "error",
|
|
39
|
+
children: D.reason
|
|
40
|
+
}) : /* @__PURE__ */ y(t, {});
|
|
41
|
+
let L = A.concreteType === x;
|
|
42
|
+
return /* @__PURE__ */ b(v, { children: [
|
|
43
|
+
/* @__PURE__ */ y(i, { accessRequirement: A }),
|
|
38
44
|
/* @__PURE__ */ b(m, { children: [/* @__PURE__ */ y(_, {
|
|
39
45
|
sx: {
|
|
40
46
|
bgcolor: "#f5f5f5",
|
|
@@ -50,61 +56,60 @@ var x = l(function(l, x) {
|
|
|
50
56
|
mb: 4
|
|
51
57
|
},
|
|
52
58
|
children: [/* @__PURE__ */ y(a, {
|
|
53
|
-
accessRequirement:
|
|
54
|
-
onChange: (e) =>
|
|
59
|
+
accessRequirement: A,
|
|
60
|
+
onChange: (e) => j(e)
|
|
55
61
|
}), /* @__PURE__ */ b(m, {
|
|
56
62
|
sx: { mb: 2 },
|
|
57
63
|
children: [
|
|
58
64
|
/* @__PURE__ */ y(o, {
|
|
59
|
-
accessRequirement:
|
|
60
|
-
isLoading:
|
|
61
|
-
onChange: (e) =>
|
|
62
|
-
...
|
|
65
|
+
accessRequirement: A,
|
|
66
|
+
isLoading: F,
|
|
67
|
+
onChange: (e) => j({
|
|
68
|
+
...A,
|
|
63
69
|
...e
|
|
64
70
|
})
|
|
65
71
|
}),
|
|
66
|
-
/* @__PURE__ */ y(g, {
|
|
72
|
+
L && /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(g, {
|
|
67
73
|
label: "IRB approval is required.",
|
|
68
|
-
checked:
|
|
74
|
+
checked: A.isIRBApprovalRequired,
|
|
69
75
|
control: /* @__PURE__ */ y(h, {}),
|
|
70
|
-
onChange: (e, t) =>
|
|
71
|
-
...
|
|
76
|
+
onChange: (e, t) => j({
|
|
77
|
+
...A,
|
|
72
78
|
isIRBApprovalRequired: t
|
|
73
79
|
}),
|
|
74
80
|
sx: { ml: 0 }
|
|
75
|
-
}),
|
|
76
|
-
/* @__PURE__ */ y(g, {
|
|
81
|
+
}), /* @__PURE__ */ y(g, {
|
|
77
82
|
control: /* @__PURE__ */ y(h, {}),
|
|
78
83
|
label: "Other documents are required.",
|
|
79
|
-
checked:
|
|
80
|
-
onChange: (e, t) =>
|
|
81
|
-
...
|
|
84
|
+
checked: A.areOtherAttachmentsRequired,
|
|
85
|
+
onChange: (e, t) => j({
|
|
86
|
+
...A,
|
|
82
87
|
areOtherAttachmentsRequired: t
|
|
83
88
|
})
|
|
84
|
-
}),
|
|
89
|
+
})] }),
|
|
85
90
|
/* @__PURE__ */ y(s, {
|
|
86
|
-
days:
|
|
87
|
-
error:
|
|
91
|
+
days: M,
|
|
92
|
+
error: O,
|
|
88
93
|
onChange: (e) => {
|
|
89
|
-
|
|
94
|
+
k(null), N(e);
|
|
90
95
|
},
|
|
91
96
|
onBlur: () => {
|
|
92
|
-
let e = c(
|
|
93
|
-
typeof e == "string" &&
|
|
97
|
+
let e = c(M);
|
|
98
|
+
typeof e == "string" && k(e);
|
|
94
99
|
}
|
|
95
100
|
}),
|
|
96
|
-
/* @__PURE__ */ b(m, {
|
|
101
|
+
L && /* @__PURE__ */ b(m, {
|
|
97
102
|
sx: { mt: 1 },
|
|
98
103
|
children: [/* @__PURE__ */ y(g, {
|
|
99
104
|
control: /* @__PURE__ */ y(h, {}),
|
|
100
105
|
label: "Intended Data Use statement is required.",
|
|
101
|
-
checked:
|
|
106
|
+
checked: A.isIDURequired,
|
|
102
107
|
onChange: (e, t) => {
|
|
103
|
-
|
|
104
|
-
...
|
|
108
|
+
j(t ? {
|
|
109
|
+
...A,
|
|
105
110
|
isIDURequired: !0
|
|
106
111
|
} : {
|
|
107
|
-
...
|
|
112
|
+
...A,
|
|
108
113
|
isIDURequired: !1,
|
|
109
114
|
isIDUPublic: !1
|
|
110
115
|
});
|
|
@@ -112,10 +117,10 @@ var x = l(function(l, x) {
|
|
|
112
117
|
}), /* @__PURE__ */ y(g, {
|
|
113
118
|
control: /* @__PURE__ */ y(h, {}),
|
|
114
119
|
label: "Intended Data Use statements will be publicly available.",
|
|
115
|
-
checked:
|
|
116
|
-
disabled: !
|
|
117
|
-
onChange: (e, t) =>
|
|
118
|
-
...
|
|
120
|
+
checked: A.isIDUPublic,
|
|
121
|
+
disabled: !A.isIDURequired,
|
|
122
|
+
onChange: (e, t) => j({
|
|
123
|
+
...A,
|
|
119
124
|
isIDUPublic: t
|
|
120
125
|
})
|
|
121
126
|
})]
|
|
@@ -123,17 +128,14 @@ var x = l(function(l, x) {
|
|
|
123
128
|
]
|
|
124
129
|
})]
|
|
125
130
|
})] }),
|
|
126
|
-
|
|
131
|
+
I && /* @__PURE__ */ y(p, {
|
|
127
132
|
severity: "error",
|
|
128
133
|
sx: { marginTop: 2 },
|
|
129
|
-
children:
|
|
134
|
+
children: I.reason
|
|
130
135
|
})
|
|
131
|
-
] })
|
|
132
|
-
severity: "error",
|
|
133
|
-
children: E.reason
|
|
134
|
-
}) : /* @__PURE__ */ y(t, {});
|
|
136
|
+
] });
|
|
135
137
|
});
|
|
136
138
|
//#endregion
|
|
137
|
-
export {
|
|
139
|
+
export { S as SetManagedAccessRequirementFields };
|
|
138
140
|
|
|
139
141
|
//# sourceMappingURL=SetManagedAccessRequirementFields.js.map
|
package/dist/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SetManagedAccessRequirementFields.js","names":[],"sources":["../../../src/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.tsx"],"sourcesContent":["import {\n useGetAccessRequirements,\n useUpdateAccessRequirement,\n} from '@/synapse-queries'\nimport { DAY_IN_MS } from '@/utils/SynapseConstants'\nimport {\n Alert,\n Box,\n Checkbox,\n FormControlLabel,\n Typography,\n} from '@mui/material'\nimport { ManagedACTAccessRequirement } from '@sage-bionetworks/synapse-types'\nimport {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport {\n AccessorRequirements,\n AccessRequirementWikiInstructions,\n} from '../SetBasicAccessRequirementFields'\nimport { DataUseCertificateFields } from './DataUseCertificateFields'\nimport {\n ExpirationPeriodField,\n getValidExpirationPeriodOrErrorMessage,\n} from './ExpirationPeriodField'\n\nexport type SetManagedAccessRequirementFieldsHandle = {\n /* Allow the parent component to trigger saving the AR, so this may be embedded in an arbitrary modal. */\n save: () => void\n}\n\nexport type SetManagedAccessRequirementFieldsProps = {\n accessRequirementId: string\n /* Called when AR has been saved successfully */\n onSave: () => void\n /* Called when error saving AR */\n onError: () => void\n}\n\nexport const SetManagedAccessRequirementFields = forwardRef(\n function SetManagedAccessRequirementFields(\n props: SetManagedAccessRequirementFieldsProps,\n ref: ForwardedRef<SetManagedAccessRequirementFieldsHandle>,\n ) {\n const { accessRequirementId, onSave, onError } = props\n\n const { data: accessRequirement, error: getArError } =\n useGetAccessRequirements<ManagedACTAccessRequirement>(\n accessRequirementId,\n { staleTime: Infinity },\n )\n useEffect(() => {\n if (accessRequirement) {\n setUpdatedAr(accessRequirement)\n setExpirationPeriodDays(\n (accessRequirement.expirationPeriod / DAY_IN_MS).toString(),\n )\n }\n }, [accessRequirement])\n\n const [expirationPeriodError, setExpirationPeriodError] = useState<\n string | null\n >(null)\n\n const [updatedAr, setUpdatedAr] =\n useState<ManagedACTAccessRequirement | null>(null)\n const [expirationPeriodDays, setExpirationPeriodDays] = useState<string>('')\n\n const {\n mutate: updateAccessRequirement,\n isPending: isUpdatingAccessRequirement,\n error: updateArError,\n } = useUpdateAccessRequirement<ManagedACTAccessRequirement>({\n onSuccess: () => onSave(),\n onError: () => onError(),\n })\n\n useImperativeHandle(ref, () => {\n return {\n save() {\n if (updatedAr) {\n const expirationPeriodOrErrorMessage =\n getValidExpirationPeriodOrErrorMessage(expirationPeriodDays)\n if (typeof expirationPeriodOrErrorMessage === 'string') {\n setExpirationPeriodError(expirationPeriodOrErrorMessage)\n onError()\n } else {\n updateAccessRequirement({\n ...updatedAr,\n expirationPeriod: expirationPeriodOrErrorMessage,\n })\n }\n }\n },\n }\n }, [expirationPeriodDays, updatedAr, updateAccessRequirement, onError])\n\n if (!updatedAr) {\n if (getArError) {\n return <Alert severity=\"error\">{getArError.reason}</Alert>\n } else {\n return <SynapseSpinner />\n }\n }\n\n return (\n <>\n <AccessRequirementWikiInstructions accessRequirement={updatedAr} />\n <Box>\n <Typography\n sx={{\n bgcolor: '#f5f5f5',\n borderBottom: '1px solid #ddd',\n color: '#333',\n px: 2,\n py: 1,\n }}\n >\n Data Access Request Parameters\n </Typography>\n <Box\n sx={{\n mt: 2,\n mb: 4,\n }}\n >\n <AccessorRequirements\n accessRequirement={updatedAr}\n onChange={updatedAr =>\n setUpdatedAr(updatedAr as ManagedACTAccessRequirement)\n }\n />\n <Box\n sx={{\n mb: 2,\n }}\n >\n <DataUseCertificateFields\n accessRequirement={updatedAr}\n isLoading={isUpdatingAccessRequirement}\n onChange={changes => setUpdatedAr({ ...updatedAr, ...changes })}\n />\n <FormControlLabel\n label=\"IRB approval is required.\"\n checked={updatedAr.isIRBApprovalRequired}\n control={<Checkbox />}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n isIRBApprovalRequired: checked,\n })\n }\n sx={{ ml: 0 }}\n />\n <FormControlLabel\n control={<Checkbox />}\n label=\"Other documents are required.\"\n checked={updatedAr.areOtherAttachmentsRequired}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n areOtherAttachmentsRequired: checked,\n })\n }\n />\n <ExpirationPeriodField\n days={expirationPeriodDays}\n error={expirationPeriodError}\n onChange={days => {\n setExpirationPeriodError(null)\n setExpirationPeriodDays(days)\n }}\n onBlur={() => {\n const expirationPeriodOrErrorMessage =\n getValidExpirationPeriodOrErrorMessage(expirationPeriodDays)\n if (typeof expirationPeriodOrErrorMessage === 'string') {\n setExpirationPeriodError(expirationPeriodOrErrorMessage)\n }\n }}\n />\n <Box\n sx={{\n mt: 1,\n }}\n >\n <FormControlLabel\n control={<Checkbox />}\n label=\"Intended Data Use statement is required.\"\n checked={updatedAr.isIDURequired}\n onChange={(_event, checked: boolean) => {\n if (checked) {\n setUpdatedAr({\n ...updatedAr,\n isIDURequired: true,\n })\n } else {\n setUpdatedAr({\n ...updatedAr,\n isIDURequired: false,\n isIDUPublic: false,\n })\n }\n }}\n />\n <FormControlLabel\n control={<Checkbox />}\n label=\"Intended Data Use statements will be publicly available.\"\n checked={updatedAr.isIDUPublic}\n disabled={!updatedAr.isIDURequired}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n isIDUPublic: checked,\n })\n }\n />\n </Box>\n </Box>\n </Box>\n </Box>\n {updateArError && (\n <Alert severity=\"error\" sx={{ marginTop: 2 }}>\n {updateArError.reason}\n </Alert>\n )}\n </>\n )\n },\n)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SetManagedAccessRequirementFields.js","names":[],"sources":["../../../src/components/SetManagedAccessRequirementFields/SetManagedAccessRequirementFields.tsx"],"sourcesContent":["import {\n useGetAccessRequirements,\n useUpdateAccessRequirement,\n} from '@/synapse-queries'\nimport { DAY_IN_MS } from '@/utils/SynapseConstants'\nimport {\n Alert,\n Box,\n Checkbox,\n FormControlLabel,\n Typography,\n} from '@mui/material'\nimport { RequestableAccessRequirement } from '@/utils/types/RequestableAccessRequirement'\nimport { MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE } from '@sage-bionetworks/synapse-types'\nimport {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react'\nimport { SynapseSpinner } from '../LoadingScreen/LoadingScreen'\nimport {\n AccessorRequirements,\n AccessRequirementWikiInstructions,\n} from '../SetBasicAccessRequirementFields'\nimport { DataUseCertificateFields } from './DataUseCertificateFields'\nimport {\n ExpirationPeriodField,\n getValidExpirationPeriodOrErrorMessage,\n} from './ExpirationPeriodField'\n\nexport type SetManagedAccessRequirementFieldsHandle = {\n /* Allow the parent component to trigger saving the AR, so this may be embedded in an arbitrary modal. */\n save: () => void\n}\n\nexport type SetManagedAccessRequirementFieldsProps = {\n accessRequirementId: string\n /* Called when AR has been saved successfully */\n onSave: () => void\n /* Called when error saving AR */\n onError: () => void\n}\n\nexport const SetManagedAccessRequirementFields = forwardRef(\n function SetManagedAccessRequirementFields(\n props: SetManagedAccessRequirementFieldsProps,\n ref: ForwardedRef<SetManagedAccessRequirementFieldsHandle>,\n ) {\n const { accessRequirementId, onSave, onError } = props\n\n const { data: accessRequirement, error: getArError } =\n useGetAccessRequirements<RequestableAccessRequirement>(\n accessRequirementId,\n {\n staleTime: Infinity,\n },\n )\n useEffect(() => {\n if (accessRequirement) {\n setUpdatedAr(accessRequirement)\n setExpirationPeriodDays(\n (accessRequirement.expirationPeriod / DAY_IN_MS).toString(),\n )\n }\n }, [accessRequirement])\n\n const [expirationPeriodError, setExpirationPeriodError] = useState<\n string | null\n >(null)\n\n const [updatedAr, setUpdatedAr] =\n useState<RequestableAccessRequirement | null>(null)\n const [expirationPeriodDays, setExpirationPeriodDays] = useState<string>('')\n\n const {\n mutate: updateAccessRequirement,\n isPending: isUpdatingAccessRequirement,\n error: updateArError,\n } = useUpdateAccessRequirement<RequestableAccessRequirement>({\n onSuccess: () => onSave(),\n onError: () => onError(),\n })\n\n useImperativeHandle(ref, () => {\n return {\n save() {\n if (updatedAr) {\n const expirationPeriodOrErrorMessage =\n getValidExpirationPeriodOrErrorMessage(expirationPeriodDays)\n if (typeof expirationPeriodOrErrorMessage === 'string') {\n setExpirationPeriodError(expirationPeriodOrErrorMessage)\n onError()\n } else {\n updateAccessRequirement({\n ...updatedAr,\n expirationPeriod: expirationPeriodOrErrorMessage,\n })\n }\n }\n },\n }\n }, [expirationPeriodDays, updatedAr, updateAccessRequirement, onError])\n\n if (!updatedAr) {\n if (getArError) {\n return <Alert severity=\"error\">{getArError.reason}</Alert>\n } else {\n return <SynapseSpinner />\n }\n }\n\n // A JsonSchemaAccessRequirement collects its remaining requirements through its form template,\n // so IRB approval, other documents, and Intended Data Use only apply to a Managed ACT AR.\n const isManagedAr =\n updatedAr.concreteType ===\n MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE\n\n return (\n <>\n <AccessRequirementWikiInstructions accessRequirement={updatedAr} />\n <Box>\n <Typography\n sx={{\n bgcolor: '#f5f5f5',\n borderBottom: '1px solid #ddd',\n color: '#333',\n px: 2,\n py: 1,\n }}\n >\n Data Access Request Parameters\n </Typography>\n <Box\n sx={{\n mt: 2,\n mb: 4,\n }}\n >\n <AccessorRequirements\n accessRequirement={updatedAr}\n onChange={updatedAr =>\n setUpdatedAr(updatedAr as RequestableAccessRequirement)\n }\n />\n <Box\n sx={{\n mb: 2,\n }}\n >\n <DataUseCertificateFields\n accessRequirement={updatedAr}\n isLoading={isUpdatingAccessRequirement}\n onChange={changes => setUpdatedAr({ ...updatedAr, ...changes })}\n />\n {isManagedAr && (\n <>\n <FormControlLabel\n label=\"IRB approval is required.\"\n checked={updatedAr.isIRBApprovalRequired}\n control={<Checkbox />}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n isIRBApprovalRequired: checked,\n })\n }\n sx={{ ml: 0 }}\n />\n <FormControlLabel\n control={<Checkbox />}\n label=\"Other documents are required.\"\n checked={updatedAr.areOtherAttachmentsRequired}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n areOtherAttachmentsRequired: checked,\n })\n }\n />\n </>\n )}\n <ExpirationPeriodField\n days={expirationPeriodDays}\n error={expirationPeriodError}\n onChange={days => {\n setExpirationPeriodError(null)\n setExpirationPeriodDays(days)\n }}\n onBlur={() => {\n const expirationPeriodOrErrorMessage =\n getValidExpirationPeriodOrErrorMessage(expirationPeriodDays)\n if (typeof expirationPeriodOrErrorMessage === 'string') {\n setExpirationPeriodError(expirationPeriodOrErrorMessage)\n }\n }}\n />\n {isManagedAr && (\n <Box\n sx={{\n mt: 1,\n }}\n >\n <FormControlLabel\n control={<Checkbox />}\n label=\"Intended Data Use statement is required.\"\n checked={updatedAr.isIDURequired}\n onChange={(_event, checked: boolean) => {\n if (checked) {\n setUpdatedAr({\n ...updatedAr,\n isIDURequired: true,\n })\n } else {\n setUpdatedAr({\n ...updatedAr,\n isIDURequired: false,\n isIDUPublic: false,\n })\n }\n }}\n />\n <FormControlLabel\n control={<Checkbox />}\n label=\"Intended Data Use statements will be publicly available.\"\n checked={updatedAr.isIDUPublic}\n disabled={!updatedAr.isIDURequired}\n onChange={(_event, checked: boolean) =>\n setUpdatedAr({\n ...updatedAr,\n isIDUPublic: checked,\n })\n }\n />\n </Box>\n )}\n </Box>\n </Box>\n </Box>\n {updateArError && (\n <Alert severity=\"error\" sx={{ marginTop: 2 }}>\n {updateArError.reason}\n </Alert>\n )}\n </>\n )\n },\n)\n"],"mappings":"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"}
|
|
@@ -5,8 +5,8 @@ import { useCreateShortUrl as r } from "../../utils/hooks/useCreateShortUrl.js";
|
|
|
5
5
|
import { useEffect as i, useState as a } from "react";
|
|
6
6
|
import { Box as o, Dialog as s, DialogContent as c, DialogTitle as l, IconButton as u, Input as d, Typography as f } from "@mui/material";
|
|
7
7
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
8
|
-
import
|
|
9
|
-
import g from "@mui/icons-material/
|
|
8
|
+
import h from "@mui/icons-material/Close";
|
|
9
|
+
import g from "@mui/icons-material/ShareTwoTone";
|
|
10
10
|
import { BlueskyIcon as _, BlueskyShareButton as v, LinkedinIcon as y, LinkedinShareButton as b, TwitterShareButton as x, XIcon as S } from "react-share";
|
|
11
11
|
//#region src/components/ShareThisPage/ShareThisPage.tsx
|
|
12
12
|
var C = ({ shortIoPublicApiKey: C, domain: w = "sageb.io", renderAs: T = "button", open: E, onClose: D }) => {
|
|
@@ -28,7 +28,7 @@ var C = ({ shortIoPublicApiKey: C, domain: w = "sageb.io", renderAs: T = "button
|
|
|
28
28
|
N && I();
|
|
29
29
|
}, [N, I]), /* @__PURE__ */ m("div", { children: [T === "button" && /* @__PURE__ */ p(e, {
|
|
30
30
|
variant: "outlined",
|
|
31
|
-
startIcon: /* @__PURE__ */ p(
|
|
31
|
+
startIcon: /* @__PURE__ */ p(g, { className: n.shareIcon }),
|
|
32
32
|
onClick: P,
|
|
33
33
|
children: "Share"
|
|
34
34
|
}), /* @__PURE__ */ m(s, {
|
|
@@ -41,7 +41,7 @@ var C = ({ shortIoPublicApiKey: C, domain: w = "sageb.io", renderAs: T = "button
|
|
|
41
41
|
children: ["Share this page", /* @__PURE__ */ p(u, {
|
|
42
42
|
onClick: F,
|
|
43
43
|
size: "small",
|
|
44
|
-
children: /* @__PURE__ */ p(
|
|
44
|
+
children: /* @__PURE__ */ p(h, { className: n.closeIcon })
|
|
45
45
|
})]
|
|
46
46
|
}), /* @__PURE__ */ p(c, {
|
|
47
47
|
className: n.dialogContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareThisPage.js","names":[],"sources":["../../../src/components/ShareThisPage/ShareThisPage.tsx"],"sourcesContent":["import {\n Dialog,\n DialogTitle,\n DialogContent,\n IconButton,\n Typography,\n Input,\n Box,\n} from '@mui/material'\nimport GenericCardActionButton from '../GenericCard/GenericCardActionButton'\nimport React from 'react'\nimport { useEffect, useState } from 'react'\nimport CloseIcon from '@mui/icons-material/Close'\nimport CopyToClipboardIcon from '../CopyToClipboardIcon'\nimport {\n LinkedinShareButton,\n LinkedinIcon,\n TwitterShareButton,\n BlueskyShareButton,\n BlueskyIcon,\n XIcon,\n} from 'react-share'\nimport styles from './ShareThisPage.module.scss'\nimport
|
|
1
|
+
{"version":3,"file":"ShareThisPage.js","names":[],"sources":["../../../src/components/ShareThisPage/ShareThisPage.tsx"],"sourcesContent":["import {\n Dialog,\n DialogTitle,\n DialogContent,\n IconButton,\n Typography,\n Input,\n Box,\n} from '@mui/material'\nimport GenericCardActionButton from '../GenericCard/GenericCardActionButton'\nimport React from 'react'\nimport { useEffect, useState } from 'react'\nimport CloseIcon from '@mui/icons-material/Close'\nimport CopyToClipboardIcon from '../CopyToClipboardIcon'\nimport {\n LinkedinShareButton,\n LinkedinIcon,\n TwitterShareButton,\n BlueskyShareButton,\n BlueskyIcon,\n XIcon,\n} from 'react-share'\nimport styles from './ShareThisPage.module.scss'\nimport ShareTwoTone from '@mui/icons-material/ShareTwoTone'\nimport { useCreateShortUrl } from '../../utils/hooks/useCreateShortUrl'\n\nexport type ShareThisPageProps = {\n shortIoPublicApiKey?: string\n domain?: string\n renderAs?: 'button' | 'icon'\n open?: boolean\n onClose?: () => void\n}\n\nconst ShareThisPage = ({\n shortIoPublicApiKey,\n domain = 'sageb.io',\n renderAs = 'button',\n open: externalOpen,\n onClose: externalOnClose,\n}: ShareThisPageProps): React.ReactNode => {\n const [url, setUrl] = useState('')\n const [internalOpen, setInternalOpen] = useState(false)\n\n // Use internal state if externalOpen is undefined\n // Otherwise, the open state is controlled externally by externalOpen\n const isControlled = externalOpen === undefined\n const open = isControlled ? internalOpen : externalOpen\n\n const handleOpen = () => {\n if (isControlled) {\n setInternalOpen(true)\n }\n }\n\n const handleClose = () => {\n if (isControlled) {\n setInternalOpen(false)\n }\n if (externalOnClose) {\n externalOnClose()\n }\n }\n\n const { mutate: createShortUrl, isPending } = useCreateShortUrl({\n shortIoPublicApiKey,\n domain,\n onSuccess: data => {\n setUrl(data)\n },\n onError: error => {\n console.error(error)\n setUrl(window.location.href)\n },\n })\n\n useEffect(() => {\n if (open) {\n createShortUrl()\n }\n }, [open, createShortUrl])\n\n return (\n <div>\n {renderAs === 'button' && (\n <GenericCardActionButton\n variant=\"outlined\"\n startIcon={<ShareTwoTone className={styles.shareIcon} />}\n onClick={handleOpen}\n >\n Share\n </GenericCardActionButton>\n )}\n\n <Dialog\n open={open}\n onClose={handleClose}\n maxWidth=\"xs\"\n className={styles.dialogPaper}\n >\n <DialogTitle className={styles.dialogTitle}>\n Share this page\n <IconButton onClick={handleClose} size=\"small\">\n <CloseIcon className={styles.closeIcon} />\n </IconButton>\n </DialogTitle>\n\n <DialogContent className={styles.dialogContent}>\n <Box className={styles.contentStack}>\n <div className={styles.shareButtonsContainer}>\n <LinkedinShareButton url={url} aria-label=\"Share on LinkedIn\">\n <div className={styles.shareItem}>\n <LinkedinIcon size={48} round />\n <Typography variant=\"body1\" className={styles.shareItemLabel}>\n LinkedIn\n </Typography>\n </div>\n </LinkedinShareButton>\n\n <TwitterShareButton url={url} aria-label=\"Share on X\">\n <div className={styles.shareItem}>\n <XIcon size={48} round />\n <Typography variant=\"body1\" className={styles.shareItemLabel}>\n X\n </Typography>\n </div>\n </TwitterShareButton>\n\n <BlueskyShareButton url={url} aria-label=\"Share on Bluesky\">\n <div className={styles.shareItem}>\n <BlueskyIcon size={48} round />\n <Typography variant=\"body1\" className={styles.shareItemLabel}>\n Bluesky\n </Typography>\n </div>\n </BlueskyShareButton>\n </div>\n\n <div className={styles.copySection}>\n <Typography className={styles.copyLabel}>Page Link</Typography>\n <div className={styles.copyRow}>\n <Input\n className={styles.urlInput}\n value={url}\n readOnly\n aria-label=\"Page URL\"\n placeholder={isPending ? 'Generating link...' : ''}\n />\n <CopyToClipboardIcon\n value={url}\n sizePx={24}\n className={styles.copyButton}\n />\n </div>\n </div>\n </Box>\n </DialogContent>\n </Dialog>\n </div>\n )\n}\n\nexport default ShareThisPage\n"],"mappings":";;;;;;;;;;;AAkCA,IAAM,KAAiB,EACrB,wBACA,YAAS,YACT,cAAW,UACX,MAAM,GACN,SAAS,QACgC;CACzC,IAAM,CAAC,GAAK,KAAU,EAAS,EAAE,GAC3B,CAAC,GAAc,KAAmB,EAAS,EAAK,GAIhD,IAAe,MAAiB,KAAA,GAChC,IAAO,IAAe,IAAe,GAErC,UAAmB;EACvB,AAAI,KACF,EAAgB,EAAI;CAExB,GAEM,UAAoB;EAIxB,AAHI,KACF,EAAgB,EAAK,GAEnB,KACF,EAAgB;CAEpB,GAEM,EAAE,QAAQ,GAAgB,iBAAc,EAAkB;EAC9D;EACA;EACA,YAAW,MAAQ;GACjB,EAAO,CAAI;EACb;EACA,UAAS,MAAS;GAEhB,AADA,QAAQ,MAAM,CAAK,GACnB,EAAO,OAAO,SAAS,IAAI;EAC7B;CACF,CAAC;CAQD,OANA,QAAgB;EACd,AAAI,KACF,EAAe;CAEnB,GAAG,CAAC,GAAM,CAAc,CAAC,GAGvB,kBAAC,OAAD,EAAA,UAAA,CACG,MAAa,YACZ,kBAAC,GAAD;EACE,SAAQ;EACR,WAAW,kBAAC,GAAD,EAAc,WAAW,EAAO,UAAY,CAAA;EACvD,SAAS;YACV;CAEwB,CAAA,GAG3B,kBAAC,GAAD;EACQ;EACN,SAAS;EACT,UAAS;EACT,WAAW,EAAO;YAJpB,CAME,kBAAC,GAAD;GAAa,WAAW,EAAO;aAA/B,CAA4C,mBAE1C,kBAAC,GAAD;IAAY,SAAS;IAAa,MAAK;cACrC,kBAAC,GAAD,EAAW,WAAW,EAAO,UAAY,CAAA;GAC/B,CAAA,CACD;MAEb,kBAAC,GAAD;GAAe,WAAW,EAAO;aAC/B,kBAAC,GAAD;IAAK,WAAW,EAAO;cAAvB,CACE,kBAAC,OAAD;KAAK,WAAW,EAAO;eAAvB;MACE,kBAAC,GAAD;OAA0B;OAAK,cAAW;iBACxC,kBAAC,OAAD;QAAK,WAAW,EAAO;kBAAvB,CACE,kBAAC,GAAD;SAAc,MAAM;SAAI,OAAA;QAAO,CAAA,GAC/B,kBAAC,GAAD;SAAY,SAAQ;SAAQ,WAAW,EAAO;mBAAgB;QAElD,CAAA,CACT;;MACc,CAAA;MAErB,kBAAC,GAAD;OAAyB;OAAK,cAAW;iBACvC,kBAAC,OAAD;QAAK,WAAW,EAAO;kBAAvB,CACE,kBAAC,GAAD;SAAO,MAAM;SAAI,OAAA;QAAO,CAAA,GACxB,kBAAC,GAAD;SAAY,SAAQ;SAAQ,WAAW,EAAO;mBAAgB;QAElD,CAAA,CACT;;MACa,CAAA;MAEpB,kBAAC,GAAD;OAAyB;OAAK,cAAW;iBACvC,kBAAC,OAAD;QAAK,WAAW,EAAO;kBAAvB,CACE,kBAAC,GAAD;SAAa,MAAM;SAAI,OAAA;QAAO,CAAA,GAC9B,kBAAC,GAAD;SAAY,SAAQ;SAAQ,WAAW,EAAO;mBAAgB;QAElD,CAAA,CACT;;MACa,CAAA;KACjB;QAEL,kBAAC,OAAD;KAAK,WAAW,EAAO;eAAvB,CACE,kBAAC,GAAD;MAAY,WAAW,EAAO;gBAAW;KAAqB,CAAA,GAC9D,kBAAC,OAAD;MAAK,WAAW,EAAO;gBAAvB,CACE,kBAAC,GAAD;OACE,WAAW,EAAO;OAClB,OAAO;OACP,UAAA;OACA,cAAW;OACX,aAAa,IAAY,uBAAuB;MACjD,CAAA,GACD,kBAAC,GAAD;OACE,OAAO;OACP,QAAQ;OACR,WAAW,EAAO;MACnB,CAAA,CACE;OACF;MACF;;EACQ,CAAA,CACT;GACL,EAAA,CAAA;AAET"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "react";
|
|
2
2
|
import { Box as e, Stack as t, Tooltip as n, Typography as r } from "@mui/material";
|
|
3
3
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
-
import
|
|
4
|
+
import o from "@mui/icons-material/InfoTwoTone";
|
|
5
5
|
//#region src/components/SustainabilityScorecard/DialLayout.tsx
|
|
6
6
|
var s = ({ dial: s, label: c, toolTipText: l }) => /* @__PURE__ */ a(t, {
|
|
7
7
|
sx: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialLayout.js","names":[],"sources":["../../../src/components/SustainabilityScorecard/DialLayout.tsx"],"sourcesContent":["import React from 'react'\nimport { Box, Stack, Tooltip, Typography } from '@mui/material'\nimport
|
|
1
|
+
{"version":3,"file":"DialLayout.js","names":[],"sources":["../../../src/components/SustainabilityScorecard/DialLayout.tsx"],"sourcesContent":["import React from 'react'\nimport { Box, Stack, Tooltip, Typography } from '@mui/material'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport { ReactElement } from 'react'\nimport { ScoreDescriptor } from './Dial'\n\nexport type DialLayoutProps = {\n dial: ReactElement\n label: ScoreDescriptor\n toolTipText?: string\n}\n\n// Displayed on entity header of details page\nconst DialLayout = ({\n dial,\n label,\n toolTipText,\n}: DialLayoutProps): React.ReactNode => {\n return (\n <Stack sx={{ alignItems: 'center', gap: '10px' }}>\n {dial}\n <Box sx={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n <Typography variant=\"smallText1\" sx={{ margin: '0 !important' }}>\n {label}\n </Typography>\n {toolTipText && (\n <Tooltip title={toolTipText}>\n <InfoTwoTone sx={{ width: '18px', height: '18px' }} />\n </Tooltip>\n )}\n </Box>\n </Stack>\n )\n}\n\nexport default DialLayout\n"],"mappings":";;;;;AAaA,IAAM,KAAc,EAClB,SACA,UACA,qBAGE,kBAAC,GAAD;CAAO,IAAI;EAAE,YAAY;EAAU,KAAK;CAAO;WAA/C,CACG,GACD,kBAAC,GAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,YAAY;GAAU,KAAK;EAAM;YAA7D,CACE,kBAAC,GAAD;GAAY,SAAQ;GAAa,IAAI,EAAE,QAAQ,eAAe;aAC3D;EACS,CAAA,GACX,KACC,kBAAC,GAAD;GAAS,OAAO;aACd,kBAAC,GAAD,EAAa,IAAI;IAAE,OAAO;IAAQ,QAAQ;GAAO,EAAI,CAAA;EAC9C,CAAA,CAER;GACA"}
|
|
@@ -7,7 +7,7 @@ import o from "./Dial.js";
|
|
|
7
7
|
import "react";
|
|
8
8
|
import { Box as s, Link as c, Skeleton as l, Stack as u, Tooltip as d, Typography as f } from "@mui/material";
|
|
9
9
|
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
10
|
-
import
|
|
10
|
+
import g from "@mui/icons-material/InfoTwoTone";
|
|
11
11
|
import { Link as _, useLocation as v } from "react-router";
|
|
12
12
|
import y from "@mui/icons-material/Close";
|
|
13
13
|
//#region src/components/SustainabilityScorecard/SustainabilityScorecard.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SustainabilityScorecard.js","names":[],"sources":["../../../src/components/SustainabilityScorecard/SustainabilityScorecard.tsx"],"sourcesContent":["import {\n Box,\n Link as MuiLink,\n Skeleton,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport React from 'react'\nimport CloseIcon from '@mui/icons-material/Close'\nimport useGetQueryResultBundle from '@/synapse-queries/entity/useGetQueryResultBundle'\nimport { getFieldIndex } from '@/utils/functions/queryUtils'\n\nimport { SxProps, Theme } from '@mui/material'\nimport {\n getMetricValues,\n SUSTAINABILITY_ICON_COLORS,\n SustainabilityScorecardBaseProps,\n} from './SustainabilityScorecardUtils'\nimport
|
|
1
|
+
{"version":3,"file":"SustainabilityScorecard.js","names":[],"sources":["../../../src/components/SustainabilityScorecard/SustainabilityScorecard.tsx"],"sourcesContent":["import {\n Box,\n Link as MuiLink,\n Skeleton,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport React from 'react'\nimport CloseIcon from '@mui/icons-material/Close'\nimport useGetQueryResultBundle from '@/synapse-queries/entity/useGetQueryResultBundle'\nimport { getFieldIndex } from '@/utils/functions/queryUtils'\n\nimport { SxProps, Theme } from '@mui/material'\nimport {\n getMetricValues,\n SUSTAINABILITY_ICON_COLORS,\n SustainabilityScorecardBaseProps,\n} from './SustainabilityScorecardUtils'\nimport InfoTwoTone from '@mui/icons-material/InfoTwoTone'\nimport { CheckIcon } from '@/assets/icons/terms/CheckIcon'\nimport NoContentAvailable from '../SynapseTable/NoContentAvailable'\nimport Dial from './Dial'\nimport { Link as RouterLink, useLocation } from 'react-router'\n\nexport type MetricsConfig = {\n /** Name of the metric column in the table */\n key: string\n /** Display label for the metric */\n label: string\n /** Shown as a tooltip in SustainabilityScorecard and as summary text in SustainabilityScorecardSummary */\n text?: string\n}\n\nexport type SustainabilityScorecardProps = SustainabilityScorecardBaseProps & {\n sx?: SxProps<Theme>\n sustainabilityReportLink?: string\n}\n\ntype MetricRowProps = {\n metricValues: string[]\n metricsConfig: MetricsConfig[]\n}\n\nconst MetricRow = ({\n metricValues,\n metricsConfig,\n}: MetricRowProps): React.ReactNode => {\n return (\n <>\n {metricsConfig.map((metric, index) => (\n <Box sx={{ display: 'flex', padding: '4px 20px' }} key={metric.key}>\n <Typography\n variant=\"smallText1\"\n sx={{ alignItems: 'center', display: 'flex', gap: '8px' }}\n >\n {metric.label}\n <Tooltip title={metric.text} placement=\"top\">\n <InfoTwoTone\n sx={{\n width: '18px',\n height: '18px',\n color: 'primary.contrastText',\n }}\n />\n </Tooltip>\n </Typography>\n {metricValues[index] === 'true' ? (\n <Box\n sx={{\n backgroundColor: SUSTAINABILITY_ICON_COLORS.check,\n borderRadius: '50%',\n width: 18,\n height: 18,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 'auto',\n }}\n >\n <CheckIcon\n sx={{ color: 'primary.contrastText', fontSize: '11px' }}\n />\n </Box>\n ) : (\n <Box\n sx={{\n backgroundColor: SUSTAINABILITY_ICON_COLORS.close,\n borderRadius: '50%',\n width: 18,\n height: 18,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 'auto',\n }}\n >\n <CloseIcon\n sx={{ color: 'primary.contrastText', fontSize: '14px' }}\n />\n </Box>\n )}\n </Box>\n ))}\n </>\n )\n}\n\n/* SustainabilityScorecard component displays sustainability metrics and a dial based on the sustainability score of the entity. */\nconst SustainabilityScorecard = ({\n metricsConfig,\n scoreDescriptorColumnName,\n queryRequest,\n sx,\n sustainabilityReportLink,\n}: SustainabilityScorecardProps): React.ReactNode => {\n const { data: queryResultBundle, isLoading } =\n useGetQueryResultBundle(queryRequest)\n const location = useLocation()\n const search = location.search\n\n if (isLoading) {\n return <Skeleton width={'100%'} height={'100%'} />\n }\n\n const data = queryResultBundle?.queryResult!.queryResults\n\n if (data?.rows?.length === 0) {\n return (\n <Stack sx={{ display: 'flex', padding: '20px', ...sx }}>\n <Typography sx={{ paddingBottom: '20px' }} variant=\"subsectionHeader\">\n Sustainability Index\n </Typography>\n <NoContentAvailable />\n </Stack>\n )\n }\n\n const scoreDescriptorColIndex = getFieldIndex(\n scoreDescriptorColumnName,\n queryResultBundle,\n )\n\n const scoreDescriptor = data?.rows[0].values[scoreDescriptorColIndex]\n\n const metricValues = getMetricValues(\n data?.rows[0],\n queryResultBundle,\n metricsConfig,\n )\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: { xs: 'column', sm: 'row' },\n padding: '20px',\n gap: '20px',\n ...sx,\n }}\n >\n <Stack sx={{ display: 'flex', gap: '20px', alignItems: 'center' }}>\n <Typography variant=\"subsectionHeader\">Sustainability Index</Typography>\n <Dial scoreDescriptor={scoreDescriptor ?? ''} />\n </Stack>\n <Stack sx={{ flex: 1, gap: '2px' }}>\n <MetricRow metricValues={metricValues} metricsConfig={metricsConfig} />\n {sustainabilityReportLink && (\n <MuiLink\n component={RouterLink}\n to={{ pathname: sustainabilityReportLink, search }}\n sx={{ padding: '4px 20px', fontSize: '14px' }}\n >\n View this tool’s sustainability and reusability report\n </MuiLink>\n )}\n </Stack>\n </Box>\n )\n}\n\nexport default SustainabilityScorecard\n"],"mappings":";;;;;;;;;;;;;AA4CA,IAAM,KAAa,EACjB,iBACA,uBAGE,kBAAA,GAAA,EAAA,UACG,EAAc,KAAK,GAAQ,MAC1B,kBAAC,GAAD;CAAK,IAAI;EAAE,SAAS;EAAQ,SAAS;CAAW;WAAhD,CACE,kBAAC,GAAD;EACE,SAAQ;EACR,IAAI;GAAE,YAAY;GAAU,SAAS;GAAQ,KAAK;EAAM;YAF1D,CAIG,EAAO,OACR,kBAAC,GAAD;GAAS,OAAO,EAAO;GAAM,WAAU;aACrC,kBAAC,GAAD,EACE,IAAI;IACF,OAAO;IACP,QAAQ;IACR,OAAO;GACT,EACD,CAAA;EACM,CAAA,CACC;KACX,EAAa,OAAW,SACvB,kBAAC,GAAD;EACE,IAAI;GACF,iBAAiB,EAA2B;GAC5C,cAAc;GACd,OAAO;GACP,QAAQ;GACR,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,YAAY;EACd;YAEA,kBAAC,GAAD,EACE,IAAI;GAAE,OAAO;GAAwB,UAAU;EAAO,EACvD,CAAA;CACE,CAAA,IAEL,kBAAC,GAAD;EACE,IAAI;GACF,iBAAiB,EAA2B;GAC5C,cAAc;GACd,OAAO;GACP,QAAQ;GACR,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,YAAY;EACd;YAEA,kBAAC,GAAD,EACE,IAAI;GAAE,OAAO;GAAwB,UAAU;EAAO,EACvD,CAAA;CACE,CAAA,CAEJ;GAnDmD,EAAO,GAmD1D,CACN,EACD,CAAA,GAKA,KAA2B,EAC/B,kBACA,8BACA,iBACA,OACA,kCACmD;CACnD,IAAM,EAAE,MAAM,GAAmB,iBAC/B,EAAwB,CAAY,GAEhC,IADW,EACF,EAAS;CAExB,IAAI,GACF,OAAO,kBAAC,GAAD;EAAU,OAAO;EAAQ,QAAQ;CAAS,CAAA;CAGnD,IAAM,IAAO,GAAmB,YAAa;CAE7C,IAAI,GAAM,MAAM,WAAW,GACzB,OACE,kBAAC,GAAD;EAAO,IAAI;GAAE,SAAS;GAAQ,SAAS;GAAQ,GAAG;EAAG;YAArD,CACE,kBAAC,GAAD;GAAY,IAAI,EAAE,eAAe,OAAO;GAAG,SAAQ;aAAmB;EAE1D,CAAA,GACZ,kBAAC,GAAD,CAAqB,CAAA,CAChB;;CAIX,IAAM,IAA0B,EAC9B,GACA,CACF,GAEM,IAAkB,GAAM,KAAK,GAAG,OAAO,IAEvC,IAAe,EACnB,GAAM,KAAK,IACX,GACA,CACF;CAEA,OACE,kBAAC,GAAD;EACE,IAAI;GACF,SAAS;GACT,eAAe;IAAE,IAAI;IAAU,IAAI;GAAM;GACzC,SAAS;GACT,KAAK;GACL,GAAG;EACL;YAPF,CASE,kBAAC,GAAD;GAAO,IAAI;IAAE,SAAS;IAAQ,KAAK;IAAQ,YAAY;GAAS;aAAhE,CACE,kBAAC,GAAD;IAAY,SAAQ;cAAmB;GAAgC,CAAA,GACvE,kBAAC,GAAD,EAAM,iBAAiB,KAAmB,GAAK,CAAA,CAC1C;MACP,kBAAC,GAAD;GAAO,IAAI;IAAE,MAAM;IAAG,KAAK;GAAM;aAAjC,CACE,kBAAC,GAAD;IAAyB;IAA6B;GAAgB,CAAA,GACrE,KACC,kBAAC,GAAD;IACE,WAAW;IACX,IAAI;KAAE,UAAU;KAA0B;IAAO;IACjD,IAAI;KAAE,SAAS;KAAY,UAAU;IAAO;cAC7C;GAEQ,CAAA,CAEN;IACJ;;AAET"}
|
|
@@ -18,7 +18,7 @@ import { Alert as u, Box as d, Chip as f, List as p, ListItem as m, Stack as h,
|
|
|
18
18
|
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
19
19
|
import { AgentAccessLevel as y } from "@sage-bionetworks/synapse-types";
|
|
20
20
|
import { FileHandleAssociateType as ae } from "@sage-bionetworks/synapse-client";
|
|
21
|
-
import
|
|
21
|
+
import b from "@mui/icons-material/SmartToyTwoTone";
|
|
22
22
|
//#region src/components/SynapseChat/SynapseChat.tsx
|
|
23
23
|
var oe = "Hi! How can I help you today?", se = {
|
|
24
24
|
[y.PUBLICLY_ACCESSIBLE]: " and can only read public data.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport {\n Alert,\n Box,\n Chip,\n List,\n ListItem,\n Stack,\n Typography,\n} from '@mui/material'\nimport {\n AgentSession,\n FileHandleAssociateType,\n GridAgentSessionContext,\n} from '@sage-bionetworks/synapse-client'\nimport { AgentAccessLevel } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport { ChatAttachment } from './utils/types'\nimport { ChatInputArea } from './components/ChatInputArea/ChatInputArea'\nimport SynapseChatMessage from './SynapseChatMessage'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { UserCard } from '../UserCard/UserCard'\nimport { useApplicationSessionContext } from '@/utils/AppUtils'\nimport { ReactComponent as CurieAvatarHead } from '@/assets/illustrations/curie_avatar_head.svg'\n\nconst CURIE_GREETING = 'Hi! How can I help you today?'\n\nconst CURIE_ACCESS_LEVEL_SUFFIX: Record<AgentAccessLevel, string> = {\n [AgentAccessLevel.PUBLICLY_ACCESSIBLE]: ' and can only read public data.',\n [AgentAccessLevel.READ_YOUR_PRIVATE_DATA]:\n ' and can read your public and private data in Synapse on your behalf.',\n [AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA]:\n ' and can read and write your public and private data in Synapse on your behalf.',\n}\n\nconst DEFAULT_AVATAR = (\n <Box\n sx={{\n p: '3px',\n borderRadius: '50%',\n borderStyle: 'solid',\n borderWidth: '1px',\n borderColor: 'grey.300',\n mt: '10px',\n height: '31px',\n }}\n >\n <SmartToyTwoTone sx={{ color: 'secondary.main' }} />\n </Box>\n)\n\nconst CURIE_AVATAR = (\n <Box\n sx={{\n mt: '10px',\n height: '30px',\n width: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <CurieAvatarHead />\n </Box>\n)\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n variant?: 'default' | 'curie'\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n /** Optional custom avatar for the chatbot agent */\n agentAvatar?: React.ReactNode\n /**\n * Whether to allow the user to attach local files to their chat message.\n * @default false\n */\n allowAttachments?: boolean\n /**\n * Invoked when creating the agent session fails because the current (anonymous) user is not\n * authorized to start a session with this agent. Callers should use this to prompt the user to\n * log in. When omitted, the session creation error is shown inline instead.\n */\n onSessionCreationUnauthenticated?: () => void\n}\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n variant = 'default',\n agentAvatar,\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n allowAttachments = false,\n onSessionCreationUnauthenticated,\n}: SynapseChatProps) {\n const { accessToken, isAuthenticated } = useSynapseContext()\n const { userId } = useApplicationSessionContext()\n\n const baseDisclaimerText = chatbotName + ' can make mistakes'\n\n const resolvedAgentAvatar =\n agentAvatar ?? (variant === 'curie' ? CURIE_AVATAR : DEFAULT_AVATAR)\n\n const userAvatar = (\n <UserCard ownerId={userId} size=\"AVATAR\" avatarSize=\"MEDIUM\" />\n )\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n onError: err => {\n // A registration that the ACT has not opened to anonymous chat rejects an anonymous\n // session with a 401/403. Defer to the caller to prompt the user to log in.\n if (!isAuthenticated && (err.status === 401 || err.status === 403)) {\n onSessionCreationUnauthenticated?.()\n }\n },\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { interactions, isAwaitingResponse, sendChat } = chatState\n\n const showGreeting = variant === 'curie' && interactions.length === 0\n\n const curieAccessLevelSuffix =\n variant === 'curie' ? CURIE_ACCESS_LEVEL_SUFFIX[agentAccessLevel] : ''\n const disclaimerText = baseDisclaimerText + curieAccessLevelSuffix\n\n // Only interactions added after this component instance mounted should play the entry\n // animation. Callers may lift state so history survives a `Dialog` closing, but the\n // `Dialog` unmounts its children, so every reopen would otherwise re-animate the whole\n // conversation.\n const presentAtMountRef = useRef<Set<string> | undefined>(undefined)\n if (presentAtMountRef.current === undefined) {\n presentAtMountRef.current = new Set(interactions.map(i => i.id))\n }\n const presentAtMount = presentAtMountRef.current\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // A copy of the attachments sent with the last interaction, so it can still show rich\n // (name/type) chips after ChatInputArea has cleared its own attachment state. This is passed to\n // the last interaction for its entire lifetime -- sent, then processing, then completed -- as a\n // fallback filename source, since the request body (FileHandleAssociation) never carries a\n // filename and the server-resolved filename (attachmentStatuses) only arrives once the job\n // completes. It's simply overwritten on the next send.\n const [lastSentAttachments, setLastSentAttachments] = useState<\n ChatAttachment[]\n >([])\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSend = (message: string, attachments: ChatAttachment[]) => {\n sendChat(\n message,\n attachments.length\n ? attachments.map(attachment => ({\n fileHandleId: attachment.fileHandleId,\n // The backend short-circuits the FileHandleAssociation auth check for a user's own\n // uploaded file handle, so associateObjectId/associateObjectType are not totally\n // accurate here. FileHandleAssociateType has no dedicated value for \"the uploader's\n // own bare file handle\", so this stubs associateObjectId to the fileHandleId itself\n // and the FileEntity associate type, which supports the short-circuit path.\n associateObjectId: attachment.fileHandleId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }))\n : undefined,\n )\n setUserChatTextfieldValue('')\n setLastSentAttachments(attachments)\n }\n\n if (createAgentSessionError) {\n // When an anonymous user can't start a session, the caller is redirecting them to log in, so\n // suppress the inline error in favor of that flow.\n const deferredToLogin =\n !isAuthenticated &&\n !!onSessionCreationUnauthenticated &&\n (createAgentSessionError.status === 401 ||\n createAgentSessionError.status === 403)\n if (!deferredToLogin) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: variant === 'curie' ? 'flex-start' : 'space-between',\n gap: variant === 'curie' ? '20px' : '0',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && variant !== 'curie' && isAuthenticated && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId!,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box\n sx={{\n flexGrow: 1,\n overflowY: 'auto',\n mb: variant === 'curie' ? 0 : 2,\n }}\n >\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n ...(variant === 'curie' && { pt: 0, pb: 0, gap: '20px' }),\n display: 'flex',\n flexDirection: 'column',\n ...(showGreeting && {\n minHeight: '100%',\n justifyContent: 'flex-end',\n }),\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {showGreeting && (\n <ListItem\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'start',\n alignItems: 'start',\n p: 0,\n }}\n >\n {resolvedAgentAvatar}\n <Typography sx={{ justifySelf: 'start', mt: '14px' }}>\n {CURIE_GREETING}\n </Typography>\n </ListItem>\n )}\n {interactions.map((interaction, index) => {\n const isLast = index === interactions.length - 1\n return (\n <SynapseChatMessage\n agentAvatar={resolvedAgentAvatar}\n userAvatar={userAvatar}\n key={interaction.id}\n userMessage={interaction.userMessage}\n chatJobId={interaction.jobId}\n showLoadingIcon={variant !== 'curie'}\n onSendChat={sendChat}\n scrollIntoView={isLast}\n animateEntry={!presentAtMount.has(interaction.id)}\n isAwaitingResponse={isAwaitingResponse}\n pendingAttachments={\n // Only one interaction can be in flight at a time (the composer is disabled\n // while isAwaitingResponse), so lastSentAttachments always corresponds to\n // whichever interaction is last.\n isLast ? lastSentAttachments : undefined\n }\n />\n )\n })}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: variant === 'curie' ? '0px' : textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n interactions.length === 0 && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box sx={{ mt: '5px' }}>\n <ChatInputArea\n value={userChatTextfieldValue}\n onValueChange={setUserChatTextfieldValue}\n onSend={handleSend}\n placeholder={\n variant === 'curie' ? 'Ask anything' : `Message ${chatbotName}`\n }\n disabled={!agentSession || isAwaitingResponse}\n allowAttachments={allowAttachments}\n />\n </Box>\n </Box>\n <Typography variant=\"smallText1\" sx={{ pt: '8px', textAlign: 'center' }}>\n {disclaimerText}\n </Typography>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport {\n Alert,\n Box,\n Chip,\n List,\n ListItem,\n Stack,\n Typography,\n} from '@mui/material'\nimport {\n AgentSession,\n FileHandleAssociateType,\n GridAgentSessionContext,\n} from '@sage-bionetworks/synapse-client'\nimport { AgentAccessLevel } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport { ChatAttachment } from './utils/types'\nimport { ChatInputArea } from './components/ChatInputArea/ChatInputArea'\nimport SynapseChatMessage from './SynapseChatMessage'\nimport SmartToyTwoTone from '@mui/icons-material/SmartToyTwoTone'\nimport { UserCard } from '../UserCard/UserCard'\nimport { useApplicationSessionContext } from '@/utils/AppUtils'\nimport { ReactComponent as CurieAvatarHead } from '@/assets/illustrations/curie_avatar_head.svg'\n\nconst CURIE_GREETING = 'Hi! How can I help you today?'\n\nconst CURIE_ACCESS_LEVEL_SUFFIX: Record<AgentAccessLevel, string> = {\n [AgentAccessLevel.PUBLICLY_ACCESSIBLE]: ' and can only read public data.',\n [AgentAccessLevel.READ_YOUR_PRIVATE_DATA]:\n ' and can read your public and private data in Synapse on your behalf.',\n [AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA]:\n ' and can read and write your public and private data in Synapse on your behalf.',\n}\n\nconst DEFAULT_AVATAR = (\n <Box\n sx={{\n p: '3px',\n borderRadius: '50%',\n borderStyle: 'solid',\n borderWidth: '1px',\n borderColor: 'grey.300',\n mt: '10px',\n height: '31px',\n }}\n >\n <SmartToyTwoTone sx={{ color: 'secondary.main' }} />\n </Box>\n)\n\nconst CURIE_AVATAR = (\n <Box\n sx={{\n mt: '10px',\n height: '30px',\n width: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <CurieAvatarHead />\n </Box>\n)\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n variant?: 'default' | 'curie'\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n /** Optional custom avatar for the chatbot agent */\n agentAvatar?: React.ReactNode\n /**\n * Whether to allow the user to attach local files to their chat message.\n * @default false\n */\n allowAttachments?: boolean\n /**\n * Invoked when creating the agent session fails because the current (anonymous) user is not\n * authorized to start a session with this agent. Callers should use this to prompt the user to\n * log in. When omitted, the session creation error is shown inline instead.\n */\n onSessionCreationUnauthenticated?: () => void\n}\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n variant = 'default',\n agentAvatar,\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n allowAttachments = false,\n onSessionCreationUnauthenticated,\n}: SynapseChatProps) {\n const { accessToken, isAuthenticated } = useSynapseContext()\n const { userId } = useApplicationSessionContext()\n\n const baseDisclaimerText = chatbotName + ' can make mistakes'\n\n const resolvedAgentAvatar =\n agentAvatar ?? (variant === 'curie' ? CURIE_AVATAR : DEFAULT_AVATAR)\n\n const userAvatar = (\n <UserCard ownerId={userId} size=\"AVATAR\" avatarSize=\"MEDIUM\" />\n )\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n onError: err => {\n // A registration that the ACT has not opened to anonymous chat rejects an anonymous\n // session with a 401/403. Defer to the caller to prompt the user to log in.\n if (!isAuthenticated && (err.status === 401 || err.status === 403)) {\n onSessionCreationUnauthenticated?.()\n }\n },\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { interactions, isAwaitingResponse, sendChat } = chatState\n\n const showGreeting = variant === 'curie' && interactions.length === 0\n\n const curieAccessLevelSuffix =\n variant === 'curie' ? CURIE_ACCESS_LEVEL_SUFFIX[agentAccessLevel] : ''\n const disclaimerText = baseDisclaimerText + curieAccessLevelSuffix\n\n // Only interactions added after this component instance mounted should play the entry\n // animation. Callers may lift state so history survives a `Dialog` closing, but the\n // `Dialog` unmounts its children, so every reopen would otherwise re-animate the whole\n // conversation.\n const presentAtMountRef = useRef<Set<string> | undefined>(undefined)\n if (presentAtMountRef.current === undefined) {\n presentAtMountRef.current = new Set(interactions.map(i => i.id))\n }\n const presentAtMount = presentAtMountRef.current\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // A copy of the attachments sent with the last interaction, so it can still show rich\n // (name/type) chips after ChatInputArea has cleared its own attachment state. This is passed to\n // the last interaction for its entire lifetime -- sent, then processing, then completed -- as a\n // fallback filename source, since the request body (FileHandleAssociation) never carries a\n // filename and the server-resolved filename (attachmentStatuses) only arrives once the job\n // completes. It's simply overwritten on the next send.\n const [lastSentAttachments, setLastSentAttachments] = useState<\n ChatAttachment[]\n >([])\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSend = (message: string, attachments: ChatAttachment[]) => {\n sendChat(\n message,\n attachments.length\n ? attachments.map(attachment => ({\n fileHandleId: attachment.fileHandleId,\n // The backend short-circuits the FileHandleAssociation auth check for a user's own\n // uploaded file handle, so associateObjectId/associateObjectType are not totally\n // accurate here. FileHandleAssociateType has no dedicated value for \"the uploader's\n // own bare file handle\", so this stubs associateObjectId to the fileHandleId itself\n // and the FileEntity associate type, which supports the short-circuit path.\n associateObjectId: attachment.fileHandleId,\n associateObjectType: FileHandleAssociateType.FileEntity,\n }))\n : undefined,\n )\n setUserChatTextfieldValue('')\n setLastSentAttachments(attachments)\n }\n\n if (createAgentSessionError) {\n // When an anonymous user can't start a session, the caller is redirecting them to log in, so\n // suppress the inline error in favor of that flow.\n const deferredToLogin =\n !isAuthenticated &&\n !!onSessionCreationUnauthenticated &&\n (createAgentSessionError.status === 401 ||\n createAgentSessionError.status === 403)\n if (!deferredToLogin) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: variant === 'curie' ? 'flex-start' : 'space-between',\n gap: variant === 'curie' ? '20px' : '0',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && variant !== 'curie' && isAuthenticated && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId!,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box\n sx={{\n flexGrow: 1,\n overflowY: 'auto',\n mb: variant === 'curie' ? 0 : 2,\n }}\n >\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n ...(variant === 'curie' && { pt: 0, pb: 0, gap: '20px' }),\n display: 'flex',\n flexDirection: 'column',\n ...(showGreeting && {\n minHeight: '100%',\n justifyContent: 'flex-end',\n }),\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {showGreeting && (\n <ListItem\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'start',\n alignItems: 'start',\n p: 0,\n }}\n >\n {resolvedAgentAvatar}\n <Typography sx={{ justifySelf: 'start', mt: '14px' }}>\n {CURIE_GREETING}\n </Typography>\n </ListItem>\n )}\n {interactions.map((interaction, index) => {\n const isLast = index === interactions.length - 1\n return (\n <SynapseChatMessage\n agentAvatar={resolvedAgentAvatar}\n userAvatar={userAvatar}\n key={interaction.id}\n userMessage={interaction.userMessage}\n chatJobId={interaction.jobId}\n showLoadingIcon={variant !== 'curie'}\n onSendChat={sendChat}\n scrollIntoView={isLast}\n animateEntry={!presentAtMount.has(interaction.id)}\n isAwaitingResponse={isAwaitingResponse}\n pendingAttachments={\n // Only one interaction can be in flight at a time (the composer is disabled\n // while isAwaitingResponse), so lastSentAttachments always corresponds to\n // whichever interaction is last.\n isLast ? lastSentAttachments : undefined\n }\n />\n )\n })}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: variant === 'curie' ? '0px' : textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n interactions.length === 0 && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box sx={{ mt: '5px' }}>\n <ChatInputArea\n value={userChatTextfieldValue}\n onValueChange={setUserChatTextfieldValue}\n onSend={handleSend}\n placeholder={\n variant === 'curie' ? 'Ask anything' : `Message ${chatbotName}`\n }\n disabled={!agentSession || isAwaitingResponse}\n allowAttachments={allowAttachments}\n />\n </Box>\n </Box>\n <Typography variant=\"smallText1\" sx={{ pt: '8px', textAlign: 'center' }}>\n {disclaimerText}\n </Typography>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChatInteraction.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SynapseChatInteraction.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAQ5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE5E;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG;IAC7C,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAA;IAChC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,gCAAgC,EAAE,CAAA;IAChD,sHAAsH;IACtH,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAA;IAChD,gFAAgF;IAChF,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAqBD,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAsB,EACtB,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAoB,EACpB,kBAA0B,EAC1B,WAAW,EACX,kBAAkB,EAClB,eAAsB,GACvB,EAAE,2BAA2B,2CAqP7B;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -6,7 +6,8 @@ import i from "./SynapseChatInteraction.module.js";
|
|
|
6
6
|
import { useEffect as a, useMemo as o, useRef as s, useState as c } from "react";
|
|
7
7
|
import { Alert as l, Box as u, Button as d, Chip as f, Collapse as p, ListItem as m, ListItemText as h, Stack as g, Tooltip as _, useTheme as v } from "@mui/material";
|
|
8
8
|
import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
9
|
-
import
|
|
9
|
+
import S from "@mui/icons-material/KeyboardArrowDown";
|
|
10
|
+
import C from "@mui/icons-material/KeyboardArrowRight";
|
|
10
11
|
//#region src/components/SynapseChat/SynapseChatInteraction.tsx
|
|
11
12
|
function w(e) {
|
|
12
13
|
return "reasoningText" in e ? e.reasoningText : "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChatInteraction.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"sourcesContent":["import { SynapseSpinner } from '@/components/LoadingScreen/LoadingScreen'\nimport extractMessageFromTraceEvent, {\n TraceMessage,\n} from '@/components/SynapseChat/extractMessageFromTraceEvent'\nimport { KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Collapse,\n ListItem,\n ListItemText,\n Stack,\n Tooltip,\n useTheme,\n} from '@mui/material'\nimport { TraceEvent } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\nimport styles from './SynapseChatInteraction.module.scss'\nimport {\n AttachmentStripItem,\n ChatAttachmentStrip,\n} from './components/ChatAttachmentStrip/ChatAttachmentStrip'\nimport { AgentChatAttachmentStatus } from '@sage-bionetworks/synapse-client'\n\n/**\n * A chat attachment to display on a sent/pending turn. Only `fileHandleId` is guaranteed --\n * `fileName`/`contentType` are omitted for a turn restored from history, where only the\n * fileHandleId that was sent to the server is known, with no in-session upload record to fall\n * back on (see SynapseChatMessage).\n */\nexport type SynapseChatInteractionAttachment = {\n fileHandleId: string\n fileName?: string\n contentType?: string\n}\n\nexport type SynapseChatInteractionProps = {\n userMessage: string\n chatResponseText?: string\n chatResponseTrace?: TraceEvent[]\n scrollIntoView?: boolean\n chatErrorReason?: string\n onSendChat?: (message: string) => void\n agentAvatar: React.ReactNode\n userAvatar: React.ReactNode\n /** Whether to play the fade/rise-in entry animation for this interaction on mount. */\n animateEntry?: boolean\n /** Whether a turn is currently in flight; gates the guide-prompt chips so they can't bypass the composer. */\n isAwaitingResponse?: boolean\n /** Attachments the user sent with this message, if any. */\n attachments?: SynapseChatInteractionAttachment[]\n /** Server-reported outcome of staging each attachment, if available (see AgentChatResponseWithAttachmentStatuses). */\n attachmentStatuses?: AgentChatAttachmentStatus[]\n /** Whether to show the loading spinner icon while the response is in flight. */\n showLoadingIcon?: boolean\n}\n\n// Show tool calls in the trace. Useful for development. We may want to show them to users in the future.\nconst SHOW_TOOL_USE = false\n\nfunction getMarkdownForTraceMessage(traceMessage: TraceMessage): string {\n if ('reasoningText' in traceMessage) {\n return traceMessage.reasoningText\n }\n if (SHOW_TOOL_USE && 'toolName' in traceMessage) {\n return `**Tool Used:** \\`${\n traceMessage.toolName\n }\\`\\n\\n**Tool Input:**\\n\\`\\`\\`json\\n${JSON.stringify(\n traceMessage.toolInput,\n null,\n 2,\n )}\\n\\`\\`\\`\\n`\n }\n return ''\n}\n\nexport function SynapseChatInteraction({\n userMessage,\n chatResponseText,\n chatErrorReason,\n chatResponseTrace,\n scrollIntoView = false,\n onSendChat,\n agentAvatar,\n userAvatar,\n animateEntry = false,\n isAwaitingResponse = false,\n attachments,\n attachmentStatuses,\n showLoadingIcon = true,\n}: SynapseChatInteractionProps) {\n const theme = useTheme()\n const userMessageRef = useRef<HTMLLIElement | null>(null)\n const responseRef = useRef<HTMLLIElement | null>(null)\n const [showTrace, setShowTrace] = useState(false)\n\n const isLoading = !chatResponseText && !chatErrorReason\n\n useEffect(() => {\n // on mount, scroll into view if instructed. This brings the \"Thinking...\" row to the top so\n // the answer's opening lines are usually visible as soon as it starts streaming in.\n if (scrollIntoView) {\n userMessageRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [scrollIntoView])\n\n useEffect(() => {\n // once the response (or an error) arrives, scroll all the way to the bottom so the full\n // answer - which may be taller than the viewport - is brought into view.\n if (scrollIntoView && !isLoading) {\n responseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' })\n }\n }, [scrollIntoView, isLoading])\n\n const traceMessages = useMemo(\n () =>\n (chatResponseTrace ?? [])\n .flatMap(traceEvent => extractMessageFromTraceEvent(traceEvent))\n ?.filter(trace => !!trace),\n [chatResponseTrace],\n )\n\n const hasTraceInfo = traceMessages.length > 0\n\n const lastReasoningMessage = useMemo(\n () => traceMessages.filter(trace => 'reasoningText' in trace).at(-1),\n [traceMessages],\n )\n\n const traceButtonLoadingText =\n lastReasoningMessage == null\n ? 'Thinking...'\n : lastReasoningMessage.reasoningText\n\n const traceButtonText = isLoading\n ? traceButtonLoadingText\n : `${showTrace ? 'Hide' : 'Show'} Trace`\n\n const { textContent, guidePrompts } = useMemo(() => {\n try {\n const parser = new DOMParser()\n const doc = parser.parseFromString(chatResponseText ?? '', 'text/html')\n\n // Remove tool_name and actions elements (AI XML tags not for display)\n doc\n .querySelectorAll('tool_name, actions')\n .forEach(element => element.remove())\n\n // Extract guideprompts before removing them\n const extractedGuidePrompts = Array.from(\n doc.querySelectorAll('guideprompt'),\n )\n .map(el => el.textContent?.trim())\n .filter((t): t is string => !!t)\n\n // Remove guideprompt elements\n doc.querySelectorAll('guideprompt').forEach(element => element.remove())\n\n // Extract text from <chat> element if present, otherwise use full body text\n const chatElement = doc.querySelector('chat')\n return {\n textContent: chatElement\n ? (chatElement.textContent ?? '')\n : (doc.body.textContent ?? ''),\n guidePrompts: extractedGuidePrompts,\n }\n } catch (e) {\n console.error(e)\n return { textContent: chatResponseText ?? '', guidePrompts: [] }\n }\n }, [chatResponseText])\n\n const attachmentItems: AttachmentStripItem[] = useMemo(\n () =>\n (attachments ?? []).map(attachment => {\n const status = attachmentStatuses?.find(\n s => s.fileHandleId === attachment.fileHandleId,\n )\n return {\n fileHandleId: attachment.fileHandleId,\n label: attachment.fileName ?? attachment.fileHandleId,\n contentType: attachment.contentType,\n status: status?.status === 'FAILED' ? 'failed' : 'default',\n errorMessage: status?.failureMessage,\n }\n }),\n [attachments, attachmentStatuses],\n )\n\n return (\n <>\n <ListItem\n ref={userMessageRef}\n sx={{\n alignSelf: 'flex-end',\n maxWidth: '82%',\n mb: '5px',\n wordWrap: 'break-word',\n width: 'auto',\n display: 'grid',\n gridTemplateColumns: 'auto auto',\n columnGap: '16px',\n alignItems: 'start',\n justifyItems: 'end',\n }}\n >\n <Box\n className={animateEntry ? styles.entryAnimation : undefined}\n sx={{\n p: '4px 14px',\n backgroundColor: '#F3F6F7',\n borderRadius: '8px',\n }}\n >\n <ListItemText primary={userMessage} />\n </Box>\n <Box sx={{ marginTop: '4px' }}>{userAvatar}</Box>\n </ListItem>\n {attachmentItems.length > 0 && (\n <ListItem sx={{ display: 'block', p: '0px', mb: '5px' }}>\n <ChatAttachmentStrip items={attachmentItems} wrap />\n </ListItem>\n )}\n <ListItem\n ref={responseRef}\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'center',\n alignItems: 'start',\n p: '0px',\n padding: '10px',\n }}\n >\n {agentAvatar}\n <Box\n sx={{\n borderRadius: '10px',\n maxWidth: '100%',\n overflow: 'auto',\n }}\n >\n <Box\n component={'aside'}\n sx={{\n '.markdown': {\n fontStyle: 'italic',\n borderLeft: `4px solid ${theme.palette.grey[300]}`,\n marginLeft: '4px',\n paddingLeft: '8px',\n mt: 1,\n mb: 2,\n },\n }}\n >\n <Button\n variant={'outlined'}\n size={'small'}\n startIcon={\n isLoading ? (\n showLoadingIcon ? (\n <SynapseSpinner size={14} />\n ) : undefined\n ) : showTrace ? (\n <KeyboardArrowDown sx={{ width: '14px' }} />\n ) : (\n <KeyboardArrowRight sx={{ width: '14px' }} />\n )\n }\n disabled={!hasTraceInfo}\n onClick={() => {\n setShowTrace(v => !v)\n }}\n sx={{\n height: '20px',\n fontSize: '12px',\n fontWeight: 600,\n mb: 1,\n border: 'none !important',\n color: 'grey.700',\n justifyContent: 'flex-start',\n whiteSpace: 'nowrap',\n maxWidth: '325px',\n textTransform: 'none',\n pl: 0,\n '.MuiButton-startIcon': { mr: 0.5 },\n }}\n >\n <Box sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {traceButtonText}\n </Box>\n </Button>\n {chatResponseTrace && (\n <Collapse in={showTrace}>\n <MarkdownSynapse\n markdown={traceMessages\n .map(getMarkdownForTraceMessage)\n .filter(md => md.trim().length > 0)\n .join('<br/><br/>')}\n />\n </Collapse>\n )}\n </Box>\n {(textContent || (onSendChat && guidePrompts.length > 0)) && (\n <Box className={animateEntry ? styles.entryAnimation : undefined}>\n {textContent && <MarkdownSynapse markdown={textContent} />}\n {onSendChat && guidePrompts.length > 0 && (\n <Stack direction=\"row\" flexWrap=\"wrap\" gap={1} mt={1}>\n {guidePrompts.map(prompt => (\n <Tooltip key={prompt} title={prompt}>\n <Chip\n label={prompt}\n variant=\"outlined\"\n color=\"primary\"\n clickable\n disabled={isAwaitingResponse}\n onClick={() => onSendChat(prompt)}\n sx={{ maxWidth: 200 }}\n />\n </Tooltip>\n ))}\n </Stack>\n )}\n </Box>\n )}\n </Box>\n </ListItem>\n {chatErrorReason && (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {chatErrorReason}\n </Alert>\n )}\n </>\n )\n}\n\nexport default SynapseChatInteraction\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SynapseChatInteraction.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"sourcesContent":["import { SynapseSpinner } from '@/components/LoadingScreen/LoadingScreen'\nimport extractMessageFromTraceEvent, {\n TraceMessage,\n} from '@/components/SynapseChat/extractMessageFromTraceEvent'\nimport KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'\nimport KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Collapse,\n ListItem,\n ListItemText,\n Stack,\n Tooltip,\n useTheme,\n} from '@mui/material'\nimport { TraceEvent } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport MarkdownSynapse from '../Markdown/MarkdownSynapse'\nimport styles from './SynapseChatInteraction.module.scss'\nimport {\n AttachmentStripItem,\n ChatAttachmentStrip,\n} from './components/ChatAttachmentStrip/ChatAttachmentStrip'\nimport { AgentChatAttachmentStatus } from '@sage-bionetworks/synapse-client'\n\n/**\n * A chat attachment to display on a sent/pending turn. Only `fileHandleId` is guaranteed --\n * `fileName`/`contentType` are omitted for a turn restored from history, where only the\n * fileHandleId that was sent to the server is known, with no in-session upload record to fall\n * back on (see SynapseChatMessage).\n */\nexport type SynapseChatInteractionAttachment = {\n fileHandleId: string\n fileName?: string\n contentType?: string\n}\n\nexport type SynapseChatInteractionProps = {\n userMessage: string\n chatResponseText?: string\n chatResponseTrace?: TraceEvent[]\n scrollIntoView?: boolean\n chatErrorReason?: string\n onSendChat?: (message: string) => void\n agentAvatar: React.ReactNode\n userAvatar: React.ReactNode\n /** Whether to play the fade/rise-in entry animation for this interaction on mount. */\n animateEntry?: boolean\n /** Whether a turn is currently in flight; gates the guide-prompt chips so they can't bypass the composer. */\n isAwaitingResponse?: boolean\n /** Attachments the user sent with this message, if any. */\n attachments?: SynapseChatInteractionAttachment[]\n /** Server-reported outcome of staging each attachment, if available (see AgentChatResponseWithAttachmentStatuses). */\n attachmentStatuses?: AgentChatAttachmentStatus[]\n /** Whether to show the loading spinner icon while the response is in flight. */\n showLoadingIcon?: boolean\n}\n\n// Show tool calls in the trace. Useful for development. We may want to show them to users in the future.\nconst SHOW_TOOL_USE = false\n\nfunction getMarkdownForTraceMessage(traceMessage: TraceMessage): string {\n if ('reasoningText' in traceMessage) {\n return traceMessage.reasoningText\n }\n if (SHOW_TOOL_USE && 'toolName' in traceMessage) {\n return `**Tool Used:** \\`${\n traceMessage.toolName\n }\\`\\n\\n**Tool Input:**\\n\\`\\`\\`json\\n${JSON.stringify(\n traceMessage.toolInput,\n null,\n 2,\n )}\\n\\`\\`\\`\\n`\n }\n return ''\n}\n\nexport function SynapseChatInteraction({\n userMessage,\n chatResponseText,\n chatErrorReason,\n chatResponseTrace,\n scrollIntoView = false,\n onSendChat,\n agentAvatar,\n userAvatar,\n animateEntry = false,\n isAwaitingResponse = false,\n attachments,\n attachmentStatuses,\n showLoadingIcon = true,\n}: SynapseChatInteractionProps) {\n const theme = useTheme()\n const userMessageRef = useRef<HTMLLIElement | null>(null)\n const responseRef = useRef<HTMLLIElement | null>(null)\n const [showTrace, setShowTrace] = useState(false)\n\n const isLoading = !chatResponseText && !chatErrorReason\n\n useEffect(() => {\n // on mount, scroll into view if instructed. This brings the \"Thinking...\" row to the top so\n // the answer's opening lines are usually visible as soon as it starts streaming in.\n if (scrollIntoView) {\n userMessageRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [scrollIntoView])\n\n useEffect(() => {\n // once the response (or an error) arrives, scroll all the way to the bottom so the full\n // answer - which may be taller than the viewport - is brought into view.\n if (scrollIntoView && !isLoading) {\n responseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' })\n }\n }, [scrollIntoView, isLoading])\n\n const traceMessages = useMemo(\n () =>\n (chatResponseTrace ?? [])\n .flatMap(traceEvent => extractMessageFromTraceEvent(traceEvent))\n ?.filter(trace => !!trace),\n [chatResponseTrace],\n )\n\n const hasTraceInfo = traceMessages.length > 0\n\n const lastReasoningMessage = useMemo(\n () => traceMessages.filter(trace => 'reasoningText' in trace).at(-1),\n [traceMessages],\n )\n\n const traceButtonLoadingText =\n lastReasoningMessage == null\n ? 'Thinking...'\n : lastReasoningMessage.reasoningText\n\n const traceButtonText = isLoading\n ? traceButtonLoadingText\n : `${showTrace ? 'Hide' : 'Show'} Trace`\n\n const { textContent, guidePrompts } = useMemo(() => {\n try {\n const parser = new DOMParser()\n const doc = parser.parseFromString(chatResponseText ?? '', 'text/html')\n\n // Remove tool_name and actions elements (AI XML tags not for display)\n doc\n .querySelectorAll('tool_name, actions')\n .forEach(element => element.remove())\n\n // Extract guideprompts before removing them\n const extractedGuidePrompts = Array.from(\n doc.querySelectorAll('guideprompt'),\n )\n .map(el => el.textContent?.trim())\n .filter((t): t is string => !!t)\n\n // Remove guideprompt elements\n doc.querySelectorAll('guideprompt').forEach(element => element.remove())\n\n // Extract text from <chat> element if present, otherwise use full body text\n const chatElement = doc.querySelector('chat')\n return {\n textContent: chatElement\n ? (chatElement.textContent ?? '')\n : (doc.body.textContent ?? ''),\n guidePrompts: extractedGuidePrompts,\n }\n } catch (e) {\n console.error(e)\n return { textContent: chatResponseText ?? '', guidePrompts: [] }\n }\n }, [chatResponseText])\n\n const attachmentItems: AttachmentStripItem[] = useMemo(\n () =>\n (attachments ?? []).map(attachment => {\n const status = attachmentStatuses?.find(\n s => s.fileHandleId === attachment.fileHandleId,\n )\n return {\n fileHandleId: attachment.fileHandleId,\n label: attachment.fileName ?? attachment.fileHandleId,\n contentType: attachment.contentType,\n status: status?.status === 'FAILED' ? 'failed' : 'default',\n errorMessage: status?.failureMessage,\n }\n }),\n [attachments, attachmentStatuses],\n )\n\n return (\n <>\n <ListItem\n ref={userMessageRef}\n sx={{\n alignSelf: 'flex-end',\n maxWidth: '82%',\n mb: '5px',\n wordWrap: 'break-word',\n width: 'auto',\n display: 'grid',\n gridTemplateColumns: 'auto auto',\n columnGap: '16px',\n alignItems: 'start',\n justifyItems: 'end',\n }}\n >\n <Box\n className={animateEntry ? styles.entryAnimation : undefined}\n sx={{\n p: '4px 14px',\n backgroundColor: '#F3F6F7',\n borderRadius: '8px',\n }}\n >\n <ListItemText primary={userMessage} />\n </Box>\n <Box sx={{ marginTop: '4px' }}>{userAvatar}</Box>\n </ListItem>\n {attachmentItems.length > 0 && (\n <ListItem sx={{ display: 'block', p: '0px', mb: '5px' }}>\n <ChatAttachmentStrip items={attachmentItems} wrap />\n </ListItem>\n )}\n <ListItem\n ref={responseRef}\n sx={{\n display: 'grid',\n gridTemplateColumns: '50px auto',\n columnGap: '16px',\n justifyItems: 'center',\n alignItems: 'start',\n p: '0px',\n padding: '10px',\n }}\n >\n {agentAvatar}\n <Box\n sx={{\n borderRadius: '10px',\n maxWidth: '100%',\n overflow: 'auto',\n }}\n >\n <Box\n component={'aside'}\n sx={{\n '.markdown': {\n fontStyle: 'italic',\n borderLeft: `4px solid ${theme.palette.grey[300]}`,\n marginLeft: '4px',\n paddingLeft: '8px',\n mt: 1,\n mb: 2,\n },\n }}\n >\n <Button\n variant={'outlined'}\n size={'small'}\n startIcon={\n isLoading ? (\n showLoadingIcon ? (\n <SynapseSpinner size={14} />\n ) : undefined\n ) : showTrace ? (\n <KeyboardArrowDown sx={{ width: '14px' }} />\n ) : (\n <KeyboardArrowRight sx={{ width: '14px' }} />\n )\n }\n disabled={!hasTraceInfo}\n onClick={() => {\n setShowTrace(v => !v)\n }}\n sx={{\n height: '20px',\n fontSize: '12px',\n fontWeight: 600,\n mb: 1,\n border: 'none !important',\n color: 'grey.700',\n justifyContent: 'flex-start',\n whiteSpace: 'nowrap',\n maxWidth: '325px',\n textTransform: 'none',\n pl: 0,\n '.MuiButton-startIcon': { mr: 0.5 },\n }}\n >\n <Box sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {traceButtonText}\n </Box>\n </Button>\n {chatResponseTrace && (\n <Collapse in={showTrace}>\n <MarkdownSynapse\n markdown={traceMessages\n .map(getMarkdownForTraceMessage)\n .filter(md => md.trim().length > 0)\n .join('<br/><br/>')}\n />\n </Collapse>\n )}\n </Box>\n {(textContent || (onSendChat && guidePrompts.length > 0)) && (\n <Box className={animateEntry ? styles.entryAnimation : undefined}>\n {textContent && <MarkdownSynapse markdown={textContent} />}\n {onSendChat && guidePrompts.length > 0 && (\n <Stack direction=\"row\" flexWrap=\"wrap\" gap={1} mt={1}>\n {guidePrompts.map(prompt => (\n <Tooltip key={prompt} title={prompt}>\n <Chip\n label={prompt}\n variant=\"outlined\"\n color=\"primary\"\n clickable\n disabled={isAwaitingResponse}\n onClick={() => onSendChat(prompt)}\n sx={{ maxWidth: 200 }}\n />\n </Tooltip>\n ))}\n </Stack>\n )}\n </Box>\n )}\n </Box>\n </ListItem>\n {chatErrorReason && (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {chatErrorReason}\n </Alert>\n )}\n </>\n )\n}\n\nexport default SynapseChatInteraction\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import r from "./ChatInputArea.module.js";
|
|
|
4
4
|
import { useMemo as i, useState as a } from "react";
|
|
5
5
|
import { Box as o, IconButton as s, TextareaAutosize as c, Tooltip as l } from "@mui/material";
|
|
6
6
|
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
7
|
-
import
|
|
7
|
+
import p from "@mui/icons-material/Add";
|
|
8
8
|
import m from "@mui/icons-material/ArrowUpward";
|
|
9
9
|
//#region src/components/SynapseChat/components/ChatInputArea/ChatInputArea.tsx
|
|
10
10
|
var h = 6, g = {
|