synapse-react-client 4.0.30 → 4.0.32
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 +4 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +2 -1
- package/dist/SWC.index.js.map +1 -1
- package/dist/assets/illustrations/curie_avatar.svg +52 -0
- package/dist/assets/illustrations/curie_avatar_head.js +91 -0
- package/dist/assets/illustrations/curie_avatar_head.js.map +1 -0
- package/dist/assets/illustrations/curie_avatar_head.svg +21 -0
- package/dist/assets/illustrations/discussions_illustration2.js +96 -0
- package/dist/assets/illustrations/discussions_illustration2.js.map +1 -0
- package/dist/assets/illustrations/discussions_illustration2.svg +17 -0
- package/dist/assets/illustrations/index.d.ts +3 -0
- package/dist/assets/illustrations/index.d.ts.map +1 -1
- package/dist/assets/illustrations/index.js +34 -32
- package/dist/assets/illustrations/index.js.map +1 -1
- package/dist/assets/mui_components/CurieAvatarHead.d.ts +5 -0
- package/dist/assets/mui_components/CurieAvatarHead.d.ts.map +1 -0
- package/dist/assets/mui_components/CurieAvatarHead.js +17 -0
- package/dist/assets/mui_components/CurieAvatarHead.js.map +1 -0
- package/dist/assets/themed_icons/Model.d.ts +3 -0
- package/dist/assets/themed_icons/Model.d.ts.map +1 -0
- package/dist/assets/themed_icons/Model.js +31 -0
- package/dist/assets/themed_icons/Model.js.map +1 -0
- package/dist/assets/themed_icons/index.d.ts +2 -1
- package/dist/assets/themed_icons/index.d.ts.map +1 -1
- package/dist/assets/themed_icons/index.js +19 -18
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.d.ts.map +1 -1
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js +49 -39
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +46 -45
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/utils/DataGridUtils.js +1 -1
- package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
- package/dist/components/EntityFinder/EntityFinder.js +127 -127
- package/dist/components/EntityFinder/EntityFinder.js.map +1 -1
- package/dist/components/EntityFinder/details/view/DetailsView.js +53 -53
- package/dist/components/EntitySidebar/EntitySidebar.css +1 -1
- package/dist/components/EntitySidebar/EntitySidebar.module.js +11 -11
- package/dist/components/EntitySidebar/EntitySidebar.module.js.map +1 -1
- package/dist/components/EntitySidebar/EntitySidebar.module.scss +2 -2
- package/dist/components/EntityTreeTable/EntityTreeTable.d.ts +7 -0
- package/dist/components/EntityTreeTable/EntityTreeTable.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/EntityTreeTable.js +24 -20
- package/dist/components/EntityTreeTable/EntityTreeTable.js.map +1 -1
- package/dist/components/EntityTreeTable/components/CheckboxCell.d.ts +4 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.d.ts.map +1 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.js +43 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.js.map +1 -0
- package/dist/components/EntityTreeTable/components/EntityNameCell.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityNameCell.js +10 -9
- package/dist/components/EntityTreeTable/components/EntityNameCell.js.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.d.ts +6 -0
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.js.map +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.d.ts +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.js +49 -39
- package/dist/components/EntityTreeTable/hooks/useTableColumns.js.map +1 -1
- package/dist/components/EntityUpload/EntityUpload.js +6 -6
- package/dist/components/Forum/DiscussionEmpty.css +1 -0
- package/dist/components/Forum/DiscussionEmpty.d.ts +6 -0
- package/dist/components/Forum/DiscussionEmpty.d.ts.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.js +30 -0
- package/dist/components/Forum/DiscussionEmpty.js.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.module.js +10 -0
- package/dist/components/Forum/DiscussionEmpty.module.js.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.module.scss +37 -0
- package/dist/components/Icon/Icon.d.ts.map +1 -1
- package/dist/components/Icon/Icon.js +82 -80
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.d.ts.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js +39 -41
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
- package/dist/components/SynapseChat/AccessLevelMenu.d.ts.map +1 -1
- package/dist/components/SynapseChat/AccessLevelMenu.js +1 -0
- package/dist/components/SynapseChat/AccessLevelMenu.js.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.js +34 -25
- package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts +10 -12
- package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.js +106 -103
- package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.css +1 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.d.ts +22 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.js +123 -94
- package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.module.js +8 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.module.js.map +1 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.module.scss +25 -0
- package/dist/components/SynapseChat/SynapseChatMessage.d.ts +16 -1
- package/dist/components/SynapseChat/SynapseChatMessage.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChatMessage.js +25 -11
- package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.d.ts +27 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.js +79 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.css +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.d.ts +33 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.js +77 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.js +8 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.scss +16 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.css +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.d.ts +23 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.js +24 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.js +9 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.scss +19 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.css +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.d.ts +22 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js +80 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.js +9 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.scss +39 -0
- package/dist/components/SynapseChat/useChatState.d.ts +12 -4
- package/dist/components/SynapseChat/useChatState.d.ts.map +1 -1
- package/dist/components/SynapseChat/useChatState.js +38 -20
- package/dist/components/SynapseChat/useChatState.js.map +1 -1
- package/dist/components/SynapseChat/utils/constants.d.ts +8 -0
- package/dist/components/SynapseChat/utils/constants.d.ts.map +1 -0
- package/dist/components/SynapseChat/utils/constants.js +12 -0
- package/dist/components/SynapseChat/utils/constants.js.map +1 -0
- package/dist/components/SynapseChat/utils/types.d.ts +13 -0
- package/dist/components/SynapseChat/utils/types.d.ts.map +1 -0
- package/dist/components/SynapseChat/utils/types.js +0 -0
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +101 -101
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts +1 -0
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +8 -0
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js.map +1 -1
- package/dist/components/file/upload/BasicFileHandleUpload.d.ts +35 -4
- package/dist/components/file/upload/BasicFileHandleUpload.d.ts.map +1 -1
- package/dist/components/file/upload/BasicFileHandleUpload.js +22 -16
- package/dist/components/file/upload/BasicFileHandleUpload.js.map +1 -1
- package/dist/components/file/upload/MultiFileUploadProgress.js +6 -6
- package/dist/components/file/upload/UploadFilePanel.d.ts +32 -0
- package/dist/components/file/upload/UploadFilePanel.d.ts.map +1 -1
- package/dist/components/file/upload/UploadFilePanel.js +58 -42
- package/dist/components/file/upload/UploadFilePanel.js.map +1 -1
- package/dist/components/file/upload/validateFileSelection.d.ts +25 -0
- package/dist/components/file/upload/validateFileSelection.d.ts.map +1 -0
- package/dist/components/file/upload/validateFileSelection.js +18 -0
- package/dist/components/file/upload/validateFileSelection.js.map +1 -0
- package/dist/components/menu/DropdownMenu.d.ts +3 -0
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +108 -83
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +13 -13
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +2 -1
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.d.ts.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js +35 -27
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js +131 -131
- package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map +1 -1
- package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.js +21 -18
- package/dist/features/entity/metadata-task/create-task/useCurationTaskFormState.js.map +1 -1
- package/dist/features/entity/metadata-task/utils/dueDate.d.ts +1 -1
- package/dist/features/entity/metadata-task/utils/dueDate.js.map +1 -1
- package/dist/mocks/chat/mockChat.d.ts +13 -1
- package/dist/mocks/chat/mockChat.d.ts.map +1 -1
- package/dist/mocks/chat/mockChat.js +34 -9
- package/dist/mocks/chat/mockChat.js.map +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.d.ts +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.js +21 -7
- package/dist/mocks/msw/handlers/chatHandlers.js.map +1 -1
- package/dist/synapse-client/SynapseClient.d.ts +2 -2
- package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
- package/dist/synapse-client/SynapseClient.js.map +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +10 -1
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +29 -2
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.d.ts +2 -2
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.d.ts.map +1 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.js +2 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.js.map +1 -1
- package/dist/synapse-queries/chat/useChat.d.ts +3 -2
- package/dist/synapse-queries/chat/useChat.d.ts.map +1 -1
- package/dist/synapse-queries/chat/useChat.js +7 -6
- package/dist/synapse-queries/chat/useChat.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.d.ts +1 -0
- package/dist/synapse-queries/dataaccess/index.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +4 -3
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts +44 -0
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useEDuc.js +75 -0
- package/dist/synapse-queries/dataaccess/useEDuc.js.map +1 -0
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.d.ts.map +1 -1
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.js +1 -1
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.js.map +1 -1
- package/dist/synapse-queries/file/useDirectUploadToS3.js +6 -6
- package/dist/synapse-queries/index.js +181 -172
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/SynapseConstants.d.ts +2 -0
- package/dist/utils/SynapseConstants.d.ts.map +1 -1
- package/dist/utils/SynapseConstants.js +122 -120
- package/dist/utils/SynapseConstants.js.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +3 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/hooks/useUploadFileEntity/useUploadFileEntities.js +5 -5
- package/dist/utils/hooks/useUploadFileEntity/useUploadFiles.js +14 -14
- package/package.json +4 -4
package/dist/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrUpdateCurationTaskDialog.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.tsx"],"sourcesContent":["import { ConfirmationDialog } from '@/components/ConfirmationDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport EntityIdTextField from '@/components/EntityFinder/EntityIdTextField'\nimport { FinderScope } from '@/components/EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '@/components/EntityFinder/VersionSelectionType'\nimport { TextField } from '@/components/TextField'\nimport { displayToast } from '@/components/ToastMessage'\nimport UserOrTeamBadge from '@/components/UserOrTeamBadge/UserOrTeamBadge'\nimport UserSearchBox from '@/components/UserSearchBox/UserSearchBox'\nimport WizardChoiceButton from '@/components/WizardChoiceButton/WizardChoiceButton'\nimport WizardChoiceButtonGroup from '@/components/WizardChoiceButton/WizardChoiceButtonGroup'\nimport {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { EntityTypeGroup } from '@/utils/functions/EntityTypeUtils'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport Close from '@mui/icons-material/Close'\nimport {\n Alert,\n Box,\n Button,\n FormControl,\n FormControlLabel,\n FormLabel,\n Grid,\n IconButton,\n InputLabel,\n MenuItem,\n Radio,\n RadioGroup,\n Select,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport {\n CurationTask,\n CurationTaskProperties,\n EntityType,\n FileBasedMetadataTaskPropertiesConcreteTypeEnum,\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { TYPE_FILTER } from '@sage-bionetworks/synapse-types'\nimport { useState } from 'react'\nimport {\n AUTH_MODE_CHANGED_WARNING,\n AUTH_MODE_NONE_TITLE,\n AUTH_MODE_NONE_TOOLTIP,\n AUTH_MODE_SESSION_OWNER_TITLE,\n AUTH_MODE_SESSION_OWNER_TOOLTIP,\n AUTH_MODE_SOURCE_BENEFACTOR_TITLE,\n AUTH_MODE_SOURCE_BENEFACTOR_TOOLTIP,\n COLLABORATORS_TOOLTIP,\n CREATE_CURATION_TASK_DIALOG_TITLE,\n TASK_STATUS_CONFIG,\n TASK_STATUS_INPUT_LABEL,\n DELETE_CURATION_TASK_CONFIRMATION_PROMPT,\n DELETE_CURATION_TASK_DIALOG_TITLE,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_GRID_SESSION_WARNING,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n EDIT_CURATION_TASK_DIALOG_TITLE,\n FILE_BASED_FILE_VIEW_INPUT_DESCRIPTION,\n FILE_BASED_TASK_DESCRIPTION,\n FILE_BASED_TASK_TITLE,\n FILE_BASED_UPLOAD_FOLDER_INPUT_DESCRIPTION,\n FILE_VIEW_FINDER_PROMPT,\n FILE_VIEW_FINDER_TITLE,\n GENERIC_SAVE_ERROR_MESSAGE,\n RECORD_BASED_RECORD_SET_INPUT_DESCRIPTION,\n RECORD_BASED_TASK_DESCRIPTION,\n RECORD_BASED_TASK_TITLE,\n RECORD_SET_FINDER_PROMPT,\n RECORD_SET_FINDER_TITLE,\n SELECT_TASK_TYPE_DESCRIPTION,\n TASK_INSTRUCTIONS_INPUT_DESCRIPTION,\n TASK_NAME_INPUT_DESCRIPTION,\n UNRECOGNIZED_TASK_TYPE_ERROR,\n UPLOAD_FOLDER_FINDER_PROMPT,\n UPLOAD_FOLDER_FINDER_TITLE,\n} from '../utils/constants'\nimport noop from 'lodash-es/noop'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { StyledFormControl } from '@/components/styled'\nimport { instanceOfGridSupportedTaskProperties } from '../utils/types'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type CreateOrUpdateCurationTaskDialogProps = {\n open: boolean\n onCancel: () => void\n onSuccess: (task: CurationTask) => void\n /**\n * Called after the task has been deleted from the dialog (edit mode only).\n * Parent is responsible for closing the dialog and any related cleanup.\n */\n onDeleteSuccess?: () => void\n projectId: string\n task?: CurationTask\n}\n\nconst FILE_BASED_CONCRETE_TYPE =\n FileBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties\nconst RECORD_BASED_CONCRETE_TYPE =\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties\n\n/** Null represents the \"Legacy\" / unset option for suggestedAuthorizationMode */\ntype AuthorizationModeOption = 'SESSION_OWNER' | 'SOURCE_BENEFACTOR' | 'NONE'\n\nfunction toAuthorizationModeOption(\n value: string | undefined,\n): AuthorizationModeOption {\n if (value === 'SESSION_OWNER' || value === 'SOURCE_BENEFACTOR') return value\n return 'NONE'\n}\n\ntype CreateOrUpdateCurationTaskDialogStep =\n | 'SELECT_TYPE'\n | 'TYPE_SPECIFIC_FIELDS'\n | 'COMMON_MUTABLE_FIELDS'\n\n/**\n * Dialog component that guides a user through creating a new CurationTask or editing an existing one.\n */\nexport default function CreateOrUpdateCurationTaskDialog(\n props: CreateOrUpdateCurationTaskDialogProps,\n) {\n const {\n open,\n onCancel,\n onSuccess,\n onDeleteSuccess = noop,\n projectId,\n task,\n } = props\n const isEditMode = task !== undefined\n const { data: permissions } = useGetEntityPermissions(projectId)\n const canDelete =\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n props.onDeleteSuccess != null\n\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n\n // In create mode: track which step we're on (1 = type selection, 2 = type-specific fields, 3 = common mutable fields)\n const [step, setStep] = useState<CreateOrUpdateCurationTaskDialogStep>(() =>\n task ? 'COMMON_MUTABLE_FIELDS' : 'SELECT_TYPE',\n )\n\n // Derive initial concrete type from the existing task (null in create mode\n // until the user picks a type in step 1)\n const [selectedConcreteType, setSelectedConcreteType] = useState<\n CurationTaskProperties['concreteType'] | null\n >(() => {\n const ct = task?.taskProperties?.concreteType\n if (ct === FILE_BASED_CONCRETE_TYPE || ct === RECORD_BASED_CONCRETE_TYPE)\n return ct\n return null\n })\n\n // Common task fields — lazily initialized from the existing task\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n const initialAuthMode =\n task?.taskProperties &&\n instanceOfGridSupportedTaskProperties(task?.taskProperties)\n ? toAuthorizationModeOption(\n task?.taskProperties?.suggestedAuthorizationMode,\n )\n : 'NONE'\n\n const [authorizationMode, setAuthorizationMode] =\n useState<AuthorizationModeOption>(initialAuthMode)\n // Track the original value to detect unsaved changes\n const [originalAuthorizationMode] =\n useState<AuthorizationModeOption>(initialAuthMode)\n\n // FileBasedMetadataTaskProperties fields\n const [uploadFolderId, setUploadFolderId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === FILE_BASED_CONCRETE_TYPE\n ? (tp.uploadFolderId ?? '')\n : ''\n })\n const [fileViewId, setFileViewId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === FILE_BASED_CONCRETE_TYPE\n ? (tp.fileViewId ?? '')\n : ''\n })\n\n // RecordBasedMetadataTaskProperties fields\n const [recordSetId, setRecordSetId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === RECORD_BASED_CONCRETE_TYPE\n ? (tp.recordSetId ?? '')\n : ''\n })\n\n // Shared taskProperties fields\n const [collaboratorPrincipalIds, setCollaboratorPrincipalIds] = useState<\n string[]\n >(() => {\n const ids =\n task &&\n task.taskProperties &&\n instanceOfGridSupportedTaskProperties(task.taskProperties)\n ? task.taskProperties.collaboratorPrincipalIds\n : undefined\n return ids ?? []\n })\n const [pendingCollaboratorId, setPendingCollaboratorId] = useState<\n string | null\n >(null)\n\n // Task status (edit mode only)\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n // undefined = user hasn't changed the status yet\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n\n // Due date (edit mode only, stored on TaskStatus)\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ??\n (isEditMode ? isoToDueDateInput(currentTaskStatus?.dueDate) : '')\n const originalDueDateForComparison = isoToDueDateInput(\n currentTaskStatus?.dueDate,\n )\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleteSuccess()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isDeletePending ||\n isStatusUpdatePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isTaskPropertiesValid =\n (selectedConcreteType === FILE_BASED_CONCRETE_TYPE &&\n uploadFolderId &&\n fileViewId) ||\n (selectedConcreteType === RECORD_BASED_CONCRETE_TYPE && recordSetId)\n\n function buildTaskPayload(): CurationTask {\n const suggestedAuthorizationMode =\n authorizationMode === 'NONE' ? undefined : authorizationMode\n\n const concreteType = selectedConcreteType!\n let taskProperties: CurationTask['taskProperties']\n const collaborators =\n collaboratorPrincipalIds.length > 0 ? collaboratorPrincipalIds : undefined\n\n if (concreteType === FILE_BASED_CONCRETE_TYPE) {\n taskProperties = {\n concreteType: FILE_BASED_CONCRETE_TYPE,\n uploadFolderId: uploadFolderId || undefined,\n fileViewId: fileViewId || undefined,\n suggestedAuthorizationMode,\n collaboratorPrincipalIds: collaborators,\n }\n } else {\n taskProperties = {\n concreteType: RECORD_BASED_CONCRETE_TYPE,\n recordSetId: recordSetId || undefined,\n suggestedAuthorizationMode,\n collaboratorPrincipalIds: collaborators,\n }\n }\n\n return {\n // Spread the existing task to carry over server-managed fields (taskId, etc.)\n ...(isEditMode ? task : {}),\n projectId,\n dataType: dataType || undefined,\n instructions: instructions || undefined,\n assigneePrincipalId: assigneePrincipalId || undefined,\n taskProperties,\n }\n }\n\n async function handleSave() {\n const payload = buildTaskPayload()\n if (isEditMode) {\n const latestTask = await updateTask(payload)\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n const dueDateChanged =\n pendingDueDate !== undefined &&\n pendingDueDate !== originalDueDateForComparison\n\n if ((statusStateChanged || dueDateChanged) && currentTaskStatus != null) {\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n dueDate:\n pendingDueDate !== undefined\n ? dueDateInputToIso(displayedDueDate)\n : currentTaskStatus.dueDate,\n etag: latestTask.etag,\n })\n }\n\n onSuccess(latestTask)\n } else {\n const created = await createTask(payload)\n onSuccess(created)\n }\n }\n\n const authModeChanged =\n isEditMode && authorizationMode !== originalAuthorizationMode\n\n // ── Authorization Mode radio group (shared between columns) ────────────\n const authModeField = (\n <FormControl>\n <FormLabel>Authorization Mode</FormLabel>\n <RadioGroup\n value={authorizationMode}\n onChange={(_e, v) => setAuthorizationMode(v as AuthorizationModeOption)}\n >\n <FormControlLabel\n value=\"NONE\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">{AUTH_MODE_NONE_TITLE}</Typography>\n <Tooltip title={AUTH_MODE_NONE_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n <FormControlLabel\n value=\"SESSION_OWNER\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">\n {AUTH_MODE_SESSION_OWNER_TITLE}\n </Typography>\n <Tooltip title={AUTH_MODE_SESSION_OWNER_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n <FormControlLabel\n value=\"SOURCE_BENEFACTOR\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">\n {AUTH_MODE_SOURCE_BENEFACTOR_TITLE}\n </Typography>\n <Tooltip title={AUTH_MODE_SOURCE_BENEFACTOR_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n </RadioGroup>\n </FormControl>\n )\n\n const assigneeField = (\n <Box>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <InputLabel htmlFor=\"dlg-set-task-assignee\">Assignee</InputLabel>\n </Box>\n <UserSearchBox\n inputId=\"dlg-set-task-assignee\"\n key={open.toString()}\n defaultValue={assigneePrincipalId}\n onChange={id => setAssigneePrincipalId(id ?? undefined)}\n typeFilter={TYPE_FILTER.ALL}\n />\n </Box>\n )\n\n // ── Form fields (used in both step 3 create and edit mode) ──────────────\n const commonFields = (\n <Stack gap={2}>\n <TextField\n label=\"Task Name\"\n fullWidth\n value={dataType}\n onChange={e => setDataType(e.target.value)}\n required\n description={TASK_NAME_INPUT_DESCRIPTION}\n />\n <TextField\n label=\"Instructions\"\n fullWidth\n multiline\n minRows={3}\n value={instructions}\n onChange={e => setInstructions(e.target.value)}\n description={TASK_INSTRUCTIONS_INPUT_DESCRIPTION}\n />\n {/* TODO: Display the below 'collaborators' once multiple owners are supported */}\n <Box display=\"none\">\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <InputLabel>Collaborators</InputLabel>\n <Tooltip title={COLLABORATORS_TOOLTIP}>\n <div>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </div>\n </Tooltip>\n </Box>\n <Stack gap={1}>\n <Stack direction=\"row\" gap={1} alignItems=\"center\">\n <Box flex={1}>\n <UserSearchBox\n value={pendingCollaboratorId}\n onChange={id => setPendingCollaboratorId(id)}\n typeFilter={TYPE_FILTER.ALL}\n placeholder=\"Search for a user or team\"\n />\n </Box>\n <Button\n variant=\"outlined\"\n onClick={() => {\n if (\n pendingCollaboratorId &&\n !collaboratorPrincipalIds.includes(pendingCollaboratorId)\n ) {\n setCollaboratorPrincipalIds(prev => [\n ...prev,\n pendingCollaboratorId,\n ])\n }\n setPendingCollaboratorId(null)\n }}\n disabled={!pendingCollaboratorId}\n >\n Add\n </Button>\n </Stack>\n {collaboratorPrincipalIds.map(id => (\n <Stack\n key={id}\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <UserOrTeamBadge principalId={id} />\n <IconButton\n size=\"small\"\n onClick={() =>\n setCollaboratorPrincipalIds(prev =>\n prev.filter(x => x !== id),\n )\n }\n >\n <Close fontSize=\"small\" />\n </IconButton>\n </Stack>\n ))}\n </Stack>\n </Box>\n </Stack>\n )\n\n // ── TaskProperties fields ────────────────────────────────────────────────\n const fileBasedFields = (\n <Stack gap={2}>\n <EntityIdTextField\n label=\"Upload Folder ID\"\n value={uploadFolderId}\n description={FILE_BASED_UPLOAD_FOLDER_INPUT_DESCRIPTION}\n onChange={setUploadFolderId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: UPLOAD_FOLDER_FINDER_TITLE,\n promptCopy: UPLOAD_FOLDER_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: EntityTypeGroup.CONTAINER,\n },\n }}\n />\n <EntityIdTextField\n label=\"File View ID\"\n value={fileViewId}\n description={FILE_BASED_FILE_VIEW_INPUT_DESCRIPTION}\n onChange={setFileViewId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: FILE_VIEW_FINDER_TITLE,\n promptCopy: FILE_VIEW_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: [EntityType.entityview],\n },\n }}\n />\n </Stack>\n )\n\n const recordBasedFields = (\n <EntityIdTextField\n label=\"Record Set ID\"\n value={recordSetId}\n description={RECORD_BASED_RECORD_SET_INPUT_DESCRIPTION}\n onChange={setRecordSetId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: RECORD_SET_FINDER_TITLE,\n promptCopy: RECORD_SET_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: [EntityType.recordset],\n },\n }}\n />\n )\n\n // ── Step 1: Type selection ───────────────────────────────────────────────\n const step1Content = (\n <Stack gap={2}>\n <Typography variant=\"body1\">{SELECT_TASK_TYPE_DESCRIPTION}</Typography>\n <WizardChoiceButtonGroup>\n <WizardChoiceButton\n title={FILE_BASED_TASK_TITLE}\n description={FILE_BASED_TASK_DESCRIPTION}\n onClick={() => {\n setSelectedConcreteType(FILE_BASED_CONCRETE_TYPE)\n setStep('TYPE_SPECIFIC_FIELDS')\n }}\n />\n <WizardChoiceButton\n title={RECORD_BASED_TASK_TITLE}\n description={RECORD_BASED_TASK_DESCRIPTION}\n onClick={() => {\n setSelectedConcreteType(RECORD_BASED_CONCRETE_TYPE)\n setStep('TYPE_SPECIFIC_FIELDS')\n }}\n />\n </WizardChoiceButtonGroup>\n </Stack>\n )\n\n // ── Step 2: Type-specific fields ───────────────────────────────────────────────\n const step2Content = (\n <Stack gap={2}>\n {selectedConcreteType === FILE_BASED_CONCRETE_TYPE && fileBasedFields}\n {selectedConcreteType === RECORD_BASED_CONCRETE_TYPE && recordBasedFields}\n </Stack>\n )\n\n // ── Step 3 / edit form content ───────────────────────────────────────────\n const step3Content = (\n <Stack gap={3}>\n <Grid container spacing={3} alignItems=\"flex-start\">\n <Grid size={{ xs: 12, sm: 6 }}>\n <Stack gap={2}>{commonFields}</Stack>\n </Grid>\n <Grid size={{ xs: 12, sm: 6 }}>\n <Stack gap={3}>\n {isEditMode && (\n <StyledFormControl fullWidth>\n <InputLabel id=\"dlg-task-status-label\">\n {TASK_STATUS_INPUT_LABEL}\n </InputLabel>\n <Select\n labelId=\"dlg-task-status-label\"\n value={displayedStatusState ?? ''}\n label={TASK_STATUS_INPUT_LABEL}\n disabled={isStatusFetching || currentTaskStatus == null}\n onChange={e =>\n setPendingStatusState(e.target.value as TaskStatusStateEnum)\n }\n >\n {Object.values(TaskStatusStateEnum).map(state => (\n <MenuItem key={state} value={state}>\n {TASK_STATUS_CONFIG[state].label}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n {isEditMode && (\n <Box>\n <TextField\n label=\"Due Date\"\n fullWidth\n type=\"date\"\n value={displayedDueDate}\n onChange={e => setPendingDueDate(e.target.value)}\n disabled={isStatusFetching}\n slotProps={{ inputLabel: { shrink: true } }}\n />\n </Box>\n )}\n {assigneeField}\n {authModeField}\n </Stack>\n </Grid>\n </Grid>\n\n {isEditMode && selectedConcreteType === null && (\n <Alert severity=\"error\">{UNRECOGNIZED_TASK_TYPE_ERROR}</Alert>\n )}\n {authModeChanged && (\n <Alert severity=\"warning\">{AUTH_MODE_CHANGED_WARNING}</Alert>\n )}\n {error && (\n <Alert severity=\"error\">\n {error.reason ?? GENERIC_SAVE_ERROR_MESSAGE}\n </Alert>\n )}\n </Stack>\n )\n\n const title = isEditMode\n ? EDIT_CURATION_TASK_DIALOG_TITLE\n : CREATE_CURATION_TASK_DIALOG_TITLE\n\n let dialogContent = null\n switch (step) {\n case 'SELECT_TYPE':\n dialogContent = step1Content\n break\n case 'TYPE_SPECIFIC_FIELDS':\n dialogContent = step2Content\n break\n case 'COMMON_MUTABLE_FIELDS':\n dialogContent = step3Content\n break\n }\n\n let dialogActions = null\n switch (step) {\n case 'SELECT_TYPE':\n dialogActions = null\n break\n case 'TYPE_SPECIFIC_FIELDS': {\n dialogActions = (\n <>\n <Button\n variant=\"outlined\"\n onClick={() => setStep('SELECT_TYPE')}\n disabled={isPending}\n >\n Back\n </Button>\n <Button\n variant=\"contained\"\n onClick={() => setStep('COMMON_MUTABLE_FIELDS')}\n disabled={isPending || !isTaskPropertiesValid}\n >\n Next\n </Button>\n </>\n )\n break\n }\n case 'COMMON_MUTABLE_FIELDS': {\n dialogActions = (\n <>\n {!isEditMode && (\n <Button\n variant=\"outlined\"\n onClick={() => setStep('TYPE_SPECIFIC_FIELDS')}\n disabled={isPending}\n >\n Back\n </Button>\n )}\n <Button\n variant=\"contained\"\n // errors surfaced via react-query error state\n onClick={() => void handleSave().catch(noop)}\n disabled={isPending || selectedConcreteType === null}\n >\n Save\n </Button>\n </>\n )\n break\n }\n }\n\n return (\n <>\n <DialogBase\n open={open}\n title={title}\n maxWidth=\"md\"\n fullWidth\n onCancel={onCancel}\n content={dialogContent}\n actions={\n <Stack\n direction=\"row\"\n gap={1}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n width=\"100%\"\n >\n <Box>\n {canDelete && (\n <Button\n variant=\"outlined\"\n color=\"error\"\n onClick={() => setShowDeleteConfirmation(true)}\n disabled={isPending}\n >\n Delete\n </Button>\n )}\n </Box>\n <Stack direction=\"row\" gap={1}>\n {dialogActions}\n </Stack>\n </Stack>\n }\n />\n <ConfirmationDialog\n title={DELETE_CURATION_TASK_DIALOG_TITLE}\n open={showDeleteConfirmation}\n content={\n <Stack gap={2}>\n <Typography variant=\"body1\">\n {DELETE_CURATION_TASK_CONFIRMATION_PROMPT}\n </Typography>\n <Alert severity=\"warning\">\n {DELETE_CURATION_TASK_GRID_SESSION_WARNING}\n </Alert>\n </Stack>\n }\n confirmButtonProps={{\n children: 'Delete',\n color: 'error',\n loading: isDeletePending,\n }}\n onConfirm={() => {\n if (task?.taskId != null) deleteTask(task.taskId)\n }}\n onCancel={() => setShowDeleteConfirmation(false)}\n />\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateOrUpdateCurationTaskDialog.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/components/CreateOrUpdateCurationTaskDialog.tsx"],"sourcesContent":["import { ConfirmationDialog } from '@/components/ConfirmationDialog'\nimport { DialogBase } from '@/components/DialogBase'\nimport EntityIdTextField from '@/components/EntityFinder/EntityIdTextField'\nimport { FinderScope } from '@/components/EntityFinder/tree/EntityTree'\nimport { VersionSelectionType } from '@/components/EntityFinder/VersionSelectionType'\nimport { TextField } from '@/components/TextField'\nimport { displayToast } from '@/components/ToastMessage'\nimport UserOrTeamBadge from '@/components/UserOrTeamBadge/UserOrTeamBadge'\nimport UserSearchBox from '@/components/UserSearchBox/UserSearchBox'\nimport WizardChoiceButton from '@/components/WizardChoiceButton/WizardChoiceButton'\nimport WizardChoiceButtonGroup from '@/components/WizardChoiceButton/WizardChoiceButtonGroup'\nimport {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { EntityTypeGroup } from '@/utils/functions/EntityTypeUtils'\nimport { HelpTwoTone } from '@mui/icons-material'\nimport Close from '@mui/icons-material/Close'\nimport {\n Alert,\n Box,\n Button,\n FormControl,\n FormControlLabel,\n FormLabel,\n Grid,\n IconButton,\n InputLabel,\n MenuItem,\n Radio,\n RadioGroup,\n Select,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport {\n CurationTask,\n CurationTaskProperties,\n EntityType,\n FileBasedMetadataTaskPropertiesConcreteTypeEnum,\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { TYPE_FILTER } from '@sage-bionetworks/synapse-types'\nimport { useState } from 'react'\nimport {\n AUTH_MODE_CHANGED_WARNING,\n AUTH_MODE_NONE_TITLE,\n AUTH_MODE_NONE_TOOLTIP,\n AUTH_MODE_SESSION_OWNER_TITLE,\n AUTH_MODE_SESSION_OWNER_TOOLTIP,\n AUTH_MODE_SOURCE_BENEFACTOR_TITLE,\n AUTH_MODE_SOURCE_BENEFACTOR_TOOLTIP,\n COLLABORATORS_TOOLTIP,\n CREATE_CURATION_TASK_DIALOG_TITLE,\n TASK_STATUS_CONFIG,\n TASK_STATUS_INPUT_LABEL,\n DELETE_CURATION_TASK_CONFIRMATION_PROMPT,\n DELETE_CURATION_TASK_DIALOG_TITLE,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_GRID_SESSION_WARNING,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n EDIT_CURATION_TASK_DIALOG_TITLE,\n FILE_BASED_FILE_VIEW_INPUT_DESCRIPTION,\n FILE_BASED_TASK_DESCRIPTION,\n FILE_BASED_TASK_TITLE,\n FILE_BASED_UPLOAD_FOLDER_INPUT_DESCRIPTION,\n FILE_VIEW_FINDER_PROMPT,\n FILE_VIEW_FINDER_TITLE,\n GENERIC_SAVE_ERROR_MESSAGE,\n RECORD_BASED_RECORD_SET_INPUT_DESCRIPTION,\n RECORD_BASED_TASK_DESCRIPTION,\n RECORD_BASED_TASK_TITLE,\n RECORD_SET_FINDER_PROMPT,\n RECORD_SET_FINDER_TITLE,\n SELECT_TASK_TYPE_DESCRIPTION,\n TASK_INSTRUCTIONS_INPUT_DESCRIPTION,\n TASK_NAME_INPUT_DESCRIPTION,\n UNRECOGNIZED_TASK_TYPE_ERROR,\n UPLOAD_FOLDER_FINDER_PROMPT,\n UPLOAD_FOLDER_FINDER_TITLE,\n} from '../utils/constants'\nimport noop from 'lodash-es/noop'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { StyledFormControl } from '@/components/styled'\nimport { instanceOfGridSupportedTaskProperties } from '../utils/types'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type CreateOrUpdateCurationTaskDialogProps = {\n open: boolean\n onCancel: () => void\n onSuccess: (task: CurationTask) => void\n /**\n * Called after the task has been deleted from the dialog (edit mode only).\n * Parent is responsible for closing the dialog and any related cleanup.\n */\n onDeleteSuccess?: () => void\n projectId: string\n task?: CurationTask\n}\n\nconst FILE_BASED_CONCRETE_TYPE =\n FileBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_FileBasedMetadataTaskProperties\nconst RECORD_BASED_CONCRETE_TYPE =\n RecordBasedMetadataTaskPropertiesConcreteTypeEnum.org_sagebionetworks_repo_model_curation_metadata_RecordBasedMetadataTaskProperties\n\n/** Null represents the \"Legacy\" / unset option for suggestedAuthorizationMode */\ntype AuthorizationModeOption = 'SESSION_OWNER' | 'SOURCE_BENEFACTOR' | 'NONE'\n\nfunction toAuthorizationModeOption(\n value: string | undefined,\n): AuthorizationModeOption {\n if (value === 'SESSION_OWNER' || value === 'SOURCE_BENEFACTOR') return value\n return 'NONE'\n}\n\ntype CreateOrUpdateCurationTaskDialogStep =\n | 'SELECT_TYPE'\n | 'TYPE_SPECIFIC_FIELDS'\n | 'COMMON_MUTABLE_FIELDS'\n\n/**\n * Dialog component that guides a user through creating a new CurationTask or editing an existing one.\n */\nexport default function CreateOrUpdateCurationTaskDialog(\n props: CreateOrUpdateCurationTaskDialogProps,\n) {\n const {\n open,\n onCancel,\n onSuccess,\n onDeleteSuccess = noop,\n projectId,\n task,\n } = props\n const isEditMode = task !== undefined\n const { data: permissions } = useGetEntityPermissions(projectId)\n const canDelete =\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n props.onDeleteSuccess != null\n\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n\n // In create mode: track which step we're on (1 = type selection, 2 = type-specific fields, 3 = common mutable fields)\n const [step, setStep] = useState<CreateOrUpdateCurationTaskDialogStep>(() =>\n task ? 'COMMON_MUTABLE_FIELDS' : 'SELECT_TYPE',\n )\n\n // Derive initial concrete type from the existing task (null in create mode\n // until the user picks a type in step 1)\n const [selectedConcreteType, setSelectedConcreteType] = useState<\n CurationTaskProperties['concreteType'] | null\n >(() => {\n const ct = task?.taskProperties?.concreteType\n if (ct === FILE_BASED_CONCRETE_TYPE || ct === RECORD_BASED_CONCRETE_TYPE)\n return ct\n return null\n })\n\n // Common task fields — lazily initialized from the existing task\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n const initialAuthMode =\n task?.taskProperties &&\n instanceOfGridSupportedTaskProperties(task?.taskProperties)\n ? toAuthorizationModeOption(\n task?.taskProperties?.suggestedAuthorizationMode,\n )\n : 'NONE'\n\n const [authorizationMode, setAuthorizationMode] =\n useState<AuthorizationModeOption>(initialAuthMode)\n // Track the original value to detect unsaved changes\n const [originalAuthorizationMode] =\n useState<AuthorizationModeOption>(initialAuthMode)\n\n // FileBasedMetadataTaskProperties fields\n const [uploadFolderId, setUploadFolderId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === FILE_BASED_CONCRETE_TYPE\n ? (tp.uploadFolderId ?? '')\n : ''\n })\n const [fileViewId, setFileViewId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === FILE_BASED_CONCRETE_TYPE\n ? (tp.fileViewId ?? '')\n : ''\n })\n\n // RecordBasedMetadataTaskProperties fields\n const [recordSetId, setRecordSetId] = useState(() => {\n const tp = task?.taskProperties\n return tp?.concreteType === RECORD_BASED_CONCRETE_TYPE\n ? (tp.recordSetId ?? '')\n : ''\n })\n\n // Shared taskProperties fields\n const [collaboratorPrincipalIds, setCollaboratorPrincipalIds] = useState<\n string[]\n >(() => {\n const ids =\n task &&\n task.taskProperties &&\n instanceOfGridSupportedTaskProperties(task.taskProperties)\n ? task.taskProperties.collaboratorPrincipalIds\n : undefined\n return ids ?? []\n })\n const [pendingCollaboratorId, setPendingCollaboratorId] = useState<\n string | null\n >(null)\n\n // Task status (edit mode only)\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n // undefined = user hasn't changed the status yet\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n\n // Due date (stored on CurationTask)\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ?? (isEditMode ? isoToDueDateInput(task?.dueDate) : '')\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleteSuccess()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isDeletePending ||\n isStatusUpdatePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isTaskPropertiesValid =\n (selectedConcreteType === FILE_BASED_CONCRETE_TYPE &&\n uploadFolderId &&\n fileViewId) ||\n (selectedConcreteType === RECORD_BASED_CONCRETE_TYPE && recordSetId)\n\n function buildTaskPayload(): CurationTask {\n const suggestedAuthorizationMode =\n authorizationMode === 'NONE' ? undefined : authorizationMode\n\n const concreteType = selectedConcreteType!\n let taskProperties: CurationTask['taskProperties']\n const collaborators =\n collaboratorPrincipalIds.length > 0 ? collaboratorPrincipalIds : undefined\n\n if (concreteType === FILE_BASED_CONCRETE_TYPE) {\n taskProperties = {\n concreteType: FILE_BASED_CONCRETE_TYPE,\n uploadFolderId: uploadFolderId || undefined,\n fileViewId: fileViewId || undefined,\n suggestedAuthorizationMode,\n collaboratorPrincipalIds: collaborators,\n }\n } else {\n taskProperties = {\n concreteType: RECORD_BASED_CONCRETE_TYPE,\n recordSetId: recordSetId || undefined,\n suggestedAuthorizationMode,\n collaboratorPrincipalIds: collaborators,\n }\n }\n\n return {\n // Spread the existing task to carry over server-managed fields (taskId, etc.)\n ...(isEditMode ? task : {}),\n projectId,\n dataType: dataType || undefined,\n instructions: instructions || undefined,\n assigneePrincipalId: assigneePrincipalId || undefined,\n // When the user hasn't changed the due date, pass the task's stored value through verbatim so\n // a field-only edit can never blank out or re-encode an existing due date.\n dueDate:\n pendingDueDate !== undefined\n ? dueDateInputToIso(pendingDueDate)\n : task?.dueDate,\n taskProperties,\n }\n }\n\n async function handleSave() {\n const payload = buildTaskPayload()\n if (isEditMode) {\n const latestTask = await updateTask(payload)\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n if (statusStateChanged && currentTaskStatus != null) {\n // The task and its status share an etag, and the preceding `updateTask` bumped it; the\n // status update must use the etag returned by that update, not the stale fetched one.\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n etag: latestTask.etag,\n })\n }\n\n onSuccess(latestTask)\n } else {\n const created = await createTask(payload)\n onSuccess(created)\n }\n }\n\n const authModeChanged =\n isEditMode && authorizationMode !== originalAuthorizationMode\n\n // ── Authorization Mode radio group (shared between columns) ────────────\n const authModeField = (\n <FormControl>\n <FormLabel>Authorization Mode</FormLabel>\n <RadioGroup\n value={authorizationMode}\n onChange={(_e, v) => setAuthorizationMode(v as AuthorizationModeOption)}\n >\n <FormControlLabel\n value=\"NONE\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">{AUTH_MODE_NONE_TITLE}</Typography>\n <Tooltip title={AUTH_MODE_NONE_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n <FormControlLabel\n value=\"SESSION_OWNER\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">\n {AUTH_MODE_SESSION_OWNER_TITLE}\n </Typography>\n <Tooltip title={AUTH_MODE_SESSION_OWNER_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n <FormControlLabel\n value=\"SOURCE_BENEFACTOR\"\n control={<Radio />}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <Typography variant=\"body1\">\n {AUTH_MODE_SOURCE_BENEFACTOR_TITLE}\n </Typography>\n <Tooltip title={AUTH_MODE_SOURCE_BENEFACTOR_TOOLTIP}>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </Tooltip>\n </Box>\n }\n />\n </RadioGroup>\n </FormControl>\n )\n\n const assigneeField = (\n <Box>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <InputLabel htmlFor=\"dlg-set-task-assignee\">Assignee</InputLabel>\n </Box>\n <UserSearchBox\n inputId=\"dlg-set-task-assignee\"\n key={open.toString()}\n defaultValue={assigneePrincipalId}\n onChange={id => setAssigneePrincipalId(id ?? undefined)}\n typeFilter={TYPE_FILTER.ALL}\n />\n </Box>\n )\n\n // ── Form fields (used in both step 3 create and edit mode) ──────────────\n const commonFields = (\n <Stack gap={2}>\n <TextField\n label=\"Task Name\"\n fullWidth\n value={dataType}\n onChange={e => setDataType(e.target.value)}\n required\n description={TASK_NAME_INPUT_DESCRIPTION}\n />\n <TextField\n label=\"Instructions\"\n fullWidth\n multiline\n minRows={3}\n value={instructions}\n onChange={e => setInstructions(e.target.value)}\n description={TASK_INSTRUCTIONS_INPUT_DESCRIPTION}\n />\n {/* TODO: Display the below 'collaborators' once multiple owners are supported */}\n <Box display=\"none\">\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <InputLabel>Collaborators</InputLabel>\n <Tooltip title={COLLABORATORS_TOOLTIP}>\n <div>\n <HelpTwoTone sx={{ color: 'grey.700' }} />\n </div>\n </Tooltip>\n </Box>\n <Stack gap={1}>\n <Stack direction=\"row\" gap={1} alignItems=\"center\">\n <Box flex={1}>\n <UserSearchBox\n value={pendingCollaboratorId}\n onChange={id => setPendingCollaboratorId(id)}\n typeFilter={TYPE_FILTER.ALL}\n placeholder=\"Search for a user or team\"\n />\n </Box>\n <Button\n variant=\"outlined\"\n onClick={() => {\n if (\n pendingCollaboratorId &&\n !collaboratorPrincipalIds.includes(pendingCollaboratorId)\n ) {\n setCollaboratorPrincipalIds(prev => [\n ...prev,\n pendingCollaboratorId,\n ])\n }\n setPendingCollaboratorId(null)\n }}\n disabled={!pendingCollaboratorId}\n >\n Add\n </Button>\n </Stack>\n {collaboratorPrincipalIds.map(id => (\n <Stack\n key={id}\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <UserOrTeamBadge principalId={id} />\n <IconButton\n size=\"small\"\n onClick={() =>\n setCollaboratorPrincipalIds(prev =>\n prev.filter(x => x !== id),\n )\n }\n >\n <Close fontSize=\"small\" />\n </IconButton>\n </Stack>\n ))}\n </Stack>\n </Box>\n </Stack>\n )\n\n // ── TaskProperties fields ────────────────────────────────────────────────\n const fileBasedFields = (\n <Stack gap={2}>\n <EntityIdTextField\n label=\"Upload Folder ID\"\n value={uploadFolderId}\n description={FILE_BASED_UPLOAD_FOLDER_INPUT_DESCRIPTION}\n onChange={setUploadFolderId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: UPLOAD_FOLDER_FINDER_TITLE,\n promptCopy: UPLOAD_FOLDER_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: EntityTypeGroup.CONTAINER,\n },\n }}\n />\n <EntityIdTextField\n label=\"File View ID\"\n value={fileViewId}\n description={FILE_BASED_FILE_VIEW_INPUT_DESCRIPTION}\n onChange={setFileViewId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: FILE_VIEW_FINDER_TITLE,\n promptCopy: FILE_VIEW_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: [EntityType.entityview],\n },\n }}\n />\n </Stack>\n )\n\n const recordBasedFields = (\n <EntityIdTextField\n label=\"Record Set ID\"\n value={recordSetId}\n description={RECORD_BASED_RECORD_SET_INPUT_DESCRIPTION}\n onChange={setRecordSetId}\n disabled={isEditMode}\n entityFinderModalProps={{\n title: RECORD_SET_FINDER_TITLE,\n promptCopy: RECORD_SET_FINDER_PROMPT,\n confirmButtonCopy: 'Select',\n configuration: {\n initialScope: FinderScope.ALL_PROJECTS,\n initialContainer: 'root',\n selectMultiple: false,\n treeOnly: false,\n versionSelection: VersionSelectionType.DISALLOWED,\n selectableTypes: [EntityType.recordset],\n },\n }}\n />\n )\n\n // ── Step 1: Type selection ───────────────────────────────────────────────\n const step1Content = (\n <Stack gap={2}>\n <Typography variant=\"body1\">{SELECT_TASK_TYPE_DESCRIPTION}</Typography>\n <WizardChoiceButtonGroup>\n <WizardChoiceButton\n title={FILE_BASED_TASK_TITLE}\n description={FILE_BASED_TASK_DESCRIPTION}\n onClick={() => {\n setSelectedConcreteType(FILE_BASED_CONCRETE_TYPE)\n setStep('TYPE_SPECIFIC_FIELDS')\n }}\n />\n <WizardChoiceButton\n title={RECORD_BASED_TASK_TITLE}\n description={RECORD_BASED_TASK_DESCRIPTION}\n onClick={() => {\n setSelectedConcreteType(RECORD_BASED_CONCRETE_TYPE)\n setStep('TYPE_SPECIFIC_FIELDS')\n }}\n />\n </WizardChoiceButtonGroup>\n </Stack>\n )\n\n // ── Step 2: Type-specific fields ───────────────────────────────────────────────\n const step2Content = (\n <Stack gap={2}>\n {selectedConcreteType === FILE_BASED_CONCRETE_TYPE && fileBasedFields}\n {selectedConcreteType === RECORD_BASED_CONCRETE_TYPE && recordBasedFields}\n </Stack>\n )\n\n // ── Step 3 / edit form content ───────────────────────────────────────────\n const step3Content = (\n <Stack gap={3}>\n <Grid container spacing={3} alignItems=\"flex-start\">\n <Grid size={{ xs: 12, sm: 6 }}>\n <Stack gap={2}>{commonFields}</Stack>\n </Grid>\n <Grid size={{ xs: 12, sm: 6 }}>\n <Stack gap={3}>\n {isEditMode && (\n <StyledFormControl fullWidth>\n <InputLabel id=\"dlg-task-status-label\">\n {TASK_STATUS_INPUT_LABEL}\n </InputLabel>\n <Select\n labelId=\"dlg-task-status-label\"\n value={displayedStatusState ?? ''}\n label={TASK_STATUS_INPUT_LABEL}\n disabled={isStatusFetching || currentTaskStatus == null}\n onChange={e =>\n setPendingStatusState(e.target.value as TaskStatusStateEnum)\n }\n >\n {Object.values(TaskStatusStateEnum).map(state => (\n <MenuItem key={state} value={state}>\n {TASK_STATUS_CONFIG[state].label}\n </MenuItem>\n ))}\n </Select>\n </StyledFormControl>\n )}\n {isEditMode && (\n <Box>\n <TextField\n label=\"Due Date\"\n fullWidth\n type=\"date\"\n value={displayedDueDate}\n onChange={e => setPendingDueDate(e.target.value)}\n disabled={isStatusFetching}\n slotProps={{ inputLabel: { shrink: true } }}\n />\n </Box>\n )}\n {assigneeField}\n {authModeField}\n </Stack>\n </Grid>\n </Grid>\n\n {isEditMode && selectedConcreteType === null && (\n <Alert severity=\"error\">{UNRECOGNIZED_TASK_TYPE_ERROR}</Alert>\n )}\n {authModeChanged && (\n <Alert severity=\"warning\">{AUTH_MODE_CHANGED_WARNING}</Alert>\n )}\n {error && (\n <Alert severity=\"error\">\n {error.reason ?? GENERIC_SAVE_ERROR_MESSAGE}\n </Alert>\n )}\n </Stack>\n )\n\n const title = isEditMode\n ? EDIT_CURATION_TASK_DIALOG_TITLE\n : CREATE_CURATION_TASK_DIALOG_TITLE\n\n let dialogContent = null\n switch (step) {\n case 'SELECT_TYPE':\n dialogContent = step1Content\n break\n case 'TYPE_SPECIFIC_FIELDS':\n dialogContent = step2Content\n break\n case 'COMMON_MUTABLE_FIELDS':\n dialogContent = step3Content\n break\n }\n\n let dialogActions = null\n switch (step) {\n case 'SELECT_TYPE':\n dialogActions = null\n break\n case 'TYPE_SPECIFIC_FIELDS': {\n dialogActions = (\n <>\n <Button\n variant=\"outlined\"\n onClick={() => setStep('SELECT_TYPE')}\n disabled={isPending}\n >\n Back\n </Button>\n <Button\n variant=\"contained\"\n onClick={() => setStep('COMMON_MUTABLE_FIELDS')}\n disabled={isPending || !isTaskPropertiesValid}\n >\n Next\n </Button>\n </>\n )\n break\n }\n case 'COMMON_MUTABLE_FIELDS': {\n dialogActions = (\n <>\n {!isEditMode && (\n <Button\n variant=\"outlined\"\n onClick={() => setStep('TYPE_SPECIFIC_FIELDS')}\n disabled={isPending}\n >\n Back\n </Button>\n )}\n <Button\n variant=\"contained\"\n // errors surfaced via react-query error state\n onClick={() => void handleSave().catch(noop)}\n disabled={isPending || selectedConcreteType === null}\n >\n Save\n </Button>\n </>\n )\n break\n }\n }\n\n return (\n <>\n <DialogBase\n open={open}\n title={title}\n maxWidth=\"md\"\n fullWidth\n onCancel={onCancel}\n content={dialogContent}\n actions={\n <Stack\n direction=\"row\"\n gap={1}\n justifyContent=\"space-between\"\n alignItems=\"center\"\n width=\"100%\"\n >\n <Box>\n {canDelete && (\n <Button\n variant=\"outlined\"\n color=\"error\"\n onClick={() => setShowDeleteConfirmation(true)}\n disabled={isPending}\n >\n Delete\n </Button>\n )}\n </Box>\n <Stack direction=\"row\" gap={1}>\n {dialogActions}\n </Stack>\n </Stack>\n }\n />\n <ConfirmationDialog\n title={DELETE_CURATION_TASK_DIALOG_TITLE}\n open={showDeleteConfirmation}\n content={\n <Stack gap={2}>\n <Typography variant=\"body1\">\n {DELETE_CURATION_TASK_CONFIRMATION_PROMPT}\n </Typography>\n <Alert severity=\"warning\">\n {DELETE_CURATION_TASK_GRID_SESSION_WARNING}\n </Alert>\n </Stack>\n }\n confirmButtonProps={{\n children: 'Delete',\n color: 'error',\n loading: isDeletePending,\n }}\n onConfirm={() => {\n if (task?.taskId != null) deleteTask(task.taskId)\n }}\n onCancel={() => setShowDeleteConfirmation(false)}\n />\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyGA,IAAM,IACJ,EAAgD,kFAC5C,IACJ,EAAkD;AAKpD,SAAS,GACP,GACyB;CAEzB,OADI,MAAU,mBAAmB,MAAU,sBAA4B,IAChE;AACT;AAUA,SAAwB,EACtB,GACA;CACA,IAAM,EACJ,SACA,aACA,cACA,sBAAkB,GAClB,cACA,YACE,GACE,IAAa,MAAS,KAAA,GACtB,EAAE,MAAM,OAAgB,EAAwB,CAAS,GACzD,KACJ,IAAa,aACb,KACA,GAAM,UAAU,QAChB,EAAM,mBAAmB,MAErB,CAAC,IAAwB,KAA6B,EAAS,EAAK,GAGpE,CAAC,IAAM,KAAW,QACtB,IAAO,0BAA0B,aACnC,GAIM,CAAC,GAAsB,MAA2B,QAEhD;EACN,IAAM,IAAK,GAAM,gBAAgB;EAGjC,OAFI,MAAO,KAA4B,MAAO,IACrC,IACF;CACT,CAAC,GAGK,CAAC,IAAU,MAAe,QAAe,GAAM,YAAY,EAAE,GAC7D,CAAC,IAAc,MAAmB,QAChC,GAAM,gBAAgB,EAC9B,GACM,CAAC,IAAqB,MAA0B,QAE9C,GAAM,mBAAmB,GAE3B,KACJ,GAAM,kBACN,EAAsC,GAAM,cAAc,IACtD,GACE,GAAM,gBAAgB,0BACxB,IACA,QAEA,CAAC,GAAmB,MACxB,EAAkC,EAAe,GAE7C,CAAC,MACL,EAAkC,EAAe,GAG7C,CAAC,GAAgB,MAAqB,QAAe;EACzD,IAAM,IAAK,GAAM;EACjB,OAAO,GAAI,iBAAiB,IACvB,EAAG,kBAAkB,KACtB;CACN,CAAC,GACK,CAAC,GAAY,MAAiB,QAAe;EACjD,IAAM,IAAK,GAAM;EACjB,OAAO,GAAI,iBAAiB,IACvB,EAAG,cAAc,KAClB;CACN,CAAC,GAGK,CAAC,GAAa,MAAkB,QAAe;EACnD,IAAM,IAAK,GAAM;EACjB,OAAO,GAAI,iBAAiB,IACvB,EAAG,eAAe,KACnB;CACN,CAAC,GAGK,CAAC,GAA0B,MAA+B,SAI5D,KACA,EAAK,kBACL,EAAsC,EAAK,cAAc,IACrD,EAAK,eAAe,2BACpB,KAAA,MACQ,CAAC,CAChB,GACK,CAAC,GAAuB,MAA4B,EAExD,IAAI,GAGA,EAAE,MAAM,GAAmB,YAAY,OAC3C,GAAyB,GAAM,UAAU,GAAG,EAC1C,SAAS,KAAc,GAAM,UAAU,KACzC,CAAC,GAEG,CAAC,GAAoB,MAAyB,EAElD,KAAA,CAAS,GACL,KAAuB,KAAsB,GAAmB,OAGhE,CAAC,GAAgB,MAAqB,EAC1C,KAAA,CACF,GACM,KACJ,MAAmB,IAAa,GAAkB,GAAM,OAAO,IAAI,KAE/D,EACJ,aAAa,IACb,WAAW,IACX,OAAO,OACL,GAAsB,GAEpB,EACJ,aAAa,IACb,WAAW,IACX,OAAO,OACL,GAAsB,GAEpB,EACJ,aAAa,IACb,WAAW,IACX,OAAO,OACL,GAA4B,GAE1B,EAAE,QAAQ,IAAY,WAAW,OACrC,GAAsB;EACpB,iBAAiB;GAGf,AAFA,EAAa,IAAoC,SAAS,GAC1D,EAA0B,EAAK,GAC/B,GAAgB;EAClB;EACA,UAAS,MAAO;GACd,EACE,KAA0C,EAAI,SAC9C,QACF;EACF;CACF,CAAC,GAEG,IACJ,MACA,MACA,MACA,IACI,IAAQ,MAAe,MAAe,IAEtC,KACH,MAAyB,KACxB,KACA,KACD,MAAyB,KAA8B;CAE1D,SAAS,KAAiC;EACxC,IAAM,IACJ,MAAsB,SAAS,KAAA,IAAY,GAEvC,IAAe,GACjB,GACE,IACJ,EAAyB,SAAS,IAAI,IAA2B,KAAA;EAmBnE,OAjBA,AASE,IATE,MAAiB,IACF;GACf,cAAc;GACd,gBAAgB,KAAkB,KAAA;GAClC,YAAY,KAAc,KAAA;GAC1B;GACA,0BAA0B;EAC5B,IAEiB;GACf,cAAc;GACd,aAAa,KAAe,KAAA;GAC5B;GACA,0BAA0B;EAC5B,GAGK;GAEL,GAAI,IAAa,IAAO,CAAC;GACzB;GACA,UAAU,MAAY,KAAA;GACtB,cAAc,MAAgB,KAAA;GAC9B,qBAAqB,MAAuB,KAAA;GAG5C,SACE,MAAmB,KAAA,IAEf,GAAM,UADN,GAAkB,CAAc;GAEtC;EACF;CACF;CAEA,eAAe,KAAa;EAC1B,IAAM,IAAU,GAAiB;EACjC,IAAI,GAAY;GACd,IAAM,IAAa,MAAM,GAAW,CAAO;GAe3C,AAZE,MAAuB,KAAA,KACvB,MAAuB,GAAmB,SAClB,KAAqB,QAG7C,MAAM,GAAiB;IACrB,GAAG;IACH,OAAO,KAAsB,EAAkB;IAC/C,MAAM,EAAW;GACnB,CAAC,GAGH,EAAU,CAAU;EACtB,OAEE,EAAU,MADY,GAAW,CAAO,CACvB;CAErB;CAEA,IAAM,KACJ,KAAc,MAAsB,IAGhC,KACJ,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAW,qBAA6B,CAAA,GACxC,kBAAC,IAAD;EACE,OAAO;EACP,WAAW,GAAI,MAAM,GAAqB,CAA4B;YAFxE;GAIE,kBAAC,GAAD;IACE,OAAM;IACN,SAAS,kBAAC,GAAD,CAAQ,CAAA;IACjB,OACE,kBAAC,GAAD;KAAK,IAAI;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;KAAI;eAA3D,CACE,kBAAC,GAAD;MAAY,SAAQ;gBAAS;KAAiC,CAAA,GAC9D,kBAAC,GAAD;MAAS,OAAO;gBACd,kBAAC,GAAD,EAAa,IAAI,EAAE,OAAO,WAAW,EAAI,CAAA;KAClC,CAAA,CACN;;GAER,CAAA;GACD,kBAAC,GAAD;IACE,OAAM;IACN,SAAS,kBAAC,GAAD,CAAQ,CAAA;IACjB,OACE,kBAAC,GAAD;KAAK,IAAI;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;KAAI;eAA3D,CACE,kBAAC,GAAD;MAAY,SAAQ;gBACjB;KACS,CAAA,GACZ,kBAAC,GAAD;MAAS,OAAO;gBACd,kBAAC,GAAD,EAAa,IAAI,EAAE,OAAO,WAAW,EAAI,CAAA;KAClC,CAAA,CACN;;GAER,CAAA;GACD,kBAAC,GAAD;IACE,OAAM;IACN,SAAS,kBAAC,GAAD,CAAQ,CAAA;IACjB,OACE,kBAAC,GAAD;KAAK,IAAI;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;KAAI;eAA3D,CACE,kBAAC,GAAD;MAAY,SAAQ;gBACjB;KACS,CAAA,GACZ,kBAAC,GAAD;MAAS,OAAO;gBACd,kBAAC,GAAD,EAAa,IAAI,EAAE,OAAO,WAAW,EAAI,CAAA;KAClC,CAAA,CACN;;GAER,CAAA;EACS;GACD,EAAA,CAAA,GAGT,KACJ,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,YAAY;GAAU,KAAK;EAAI;YACzD,kBAAC,GAAD;GAAY,SAAQ;aAAwB;EAAoB,CAAA;CAC7D,CAAA,GACL,kBAAC,GAAD;EACE,SAAQ;EAER,cAAc;EACd,WAAU,MAAM,GAAuB,KAAM,KAAA,CAAS;EACtD,YAAY,EAAY;CACzB,GAJM,EAAK,SAAS,CAIpB,CACE,EAAA,CAAA,GAID,KACJ,kBAAC,GAAD;EAAO,KAAK;YAAZ;GACE,kBAAC,GAAD;IACE,OAAM;IACN,WAAA;IACA,OAAO;IACP,WAAU,MAAK,GAAY,EAAE,OAAO,KAAK;IACzC,UAAA;IACA,aAAa;GACd,CAAA;GACD,kBAAC,GAAD;IACE,OAAM;IACN,WAAA;IACA,WAAA;IACA,SAAS;IACT,OAAO;IACP,WAAU,MAAK,GAAgB,EAAE,OAAO,KAAK;IAC7C,aAAa;GACd,CAAA;GAED,kBAAC,GAAD;IAAK,SAAQ;cAAb,CACE,kBAAC,GAAD;KAAK,IAAI;MAAE,SAAS;MAAQ,YAAY;MAAU,KAAK;KAAI;eAA3D,CACE,kBAAC,GAAD,EAAA,UAAY,gBAAyB,CAAA,GACrC,kBAAC,GAAD;MAAS,OAAO;gBACd,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD,EAAa,IAAI,EAAE,OAAO,WAAW,EAAI,CAAA,EACtC,CAAA;KACE,CAAA,CACN;QACL,kBAAC,GAAD;KAAO,KAAK;eAAZ,CACE,kBAAC,GAAD;MAAO,WAAU;MAAM,KAAK;MAAG,YAAW;gBAA1C,CACE,kBAAC,GAAD;OAAK,MAAM;iBACT,kBAAC,GAAD;QACE,OAAO;QACP,WAAU,MAAM,GAAyB,CAAE;QAC3C,YAAY,EAAY;QACxB,aAAY;OACb,CAAA;MACE,CAAA,GACL,kBAAC,GAAD;OACE,SAAQ;OACR,eAAe;QAUb,AARE,KACA,CAAC,EAAyB,SAAS,CAAqB,KAExD,IAA4B,MAAQ,CAClC,GAAG,GACH,CACF,CAAC,GAEH,GAAyB,IAAI;OAC/B;OACA,UAAU,CAAC;iBACZ;MAEO,CAAA,CACH;SACN,EAAyB,KAAI,MAC5B,kBAAC,GAAD;MAEE,WAAU;MACV,YAAW;MACX,gBAAe;gBAJjB,CAME,kBAAC,IAAD,EAAiB,aAAa,EAAK,CAAA,GACnC,kBAAC,IAAD;OACE,MAAK;OACL,eACE,IAA4B,MAC1B,EAAK,QAAO,MAAK,MAAM,CAAE,CAC3B;iBAGF,kBAAC,IAAD,EAAO,UAAS,QAAS,CAAA;MACf,CAAA,CACP;QAhBA,CAgBA,CACR,CACI;MACJ;;EACA;KAIH,KACJ,kBAAC,GAAD;EAAO,KAAK;YAAZ,CACE,kBAAC,GAAD;GACE,OAAM;GACN,OAAO;GACP,aAAa;GACb,UAAU;GACV,UAAU;GACV,wBAAwB;IACtB,OAAO;IACP,YAAY;IACZ,mBAAmB;IACnB,eAAe;KACb,cAAc,EAAY;KAC1B,kBAAkB;KAClB,gBAAgB;KAChB,UAAU;KACV,kBAAkB,EAAqB;KACvC,iBAAiB,EAAgB;IACnC;GACF;EACD,CAAA,GACD,kBAAC,GAAD;GACE,OAAM;GACN,OAAO;GACP,aAAa;GACb,UAAU;GACV,UAAU;GACV,wBAAwB;IACtB,OAAO;IACP,YAAY;IACZ,mBAAmB;IACnB,eAAe;KACb,cAAc,EAAY;KAC1B,kBAAkB;KAClB,gBAAgB;KAChB,UAAU;KACV,kBAAkB,EAAqB;KACvC,iBAAiB,CAAC,EAAW,UAAU;IACzC;GACF;EACD,CAAA,CACI;KAGH,KACJ,kBAAC,GAAD;EACE,OAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,UAAU;EACV,wBAAwB;GACtB,OAAO;GACP,YAAY;GACZ,mBAAmB;GACnB,eAAe;IACb,cAAc,EAAY;IAC1B,kBAAkB;IAClB,gBAAgB;IAChB,UAAU;IACV,kBAAkB,EAAqB;IACvC,iBAAiB,CAAC,EAAW,SAAS;GACxC;EACF;CACD,CAAA,GAIG,KACJ,kBAAC,GAAD;EAAO,KAAK;YAAZ,CACE,kBAAC,GAAD;GAAY,SAAQ;aAAS;EAAyC,CAAA,GACtE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,OAAO;GACP,aAAa;GACb,eAAe;IAEb,AADA,GAAwB,CAAwB,GAChD,EAAQ,sBAAsB;GAChC;EACD,CAAA,GACD,kBAAC,GAAD;GACE,OAAO;GACP,aAAa;GACb,eAAe;IAEb,AADA,GAAwB,CAA0B,GAClD,EAAQ,sBAAsB;GAChC;EACD,CAAA,CACsB,EAAA,CAAA,CACpB;KAIH,KACJ,kBAAC,GAAD;EAAO,KAAK;YAAZ,CACG,MAAyB,KAA4B,IACrD,MAAyB,KAA8B,EACnD;KAIH,KACJ,kBAAC,GAAD;EAAO,KAAK;YAAZ;GACE,kBAAC,GAAD;IAAM,WAAA;IAAU,SAAS;IAAG,YAAW;cAAvC,CACE,kBAAC,GAAD;KAAM,MAAM;MAAE,IAAI;MAAI,IAAI;KAAE;eAC1B,kBAAC,GAAD;MAAO,KAAK;gBAAI;KAAoB,CAAA;IAChC,CAAA,GACN,kBAAC,GAAD;KAAM,MAAM;MAAE,IAAI;MAAI,IAAI;KAAE;eAC1B,kBAAC,GAAD;MAAO,KAAK;gBAAZ;OACG,KACC,kBAAC,IAAD;QAAmB,WAAA;kBAAnB,CACE,kBAAC,GAAD;SAAY,IAAG;;QAEH,CAAA,GACZ,kBAAC,IAAD;SACE,SAAQ;SACR,OAAO,MAAwB;SAC/B,OAAA;SACA,UAAU,MAAoB,KAAqB;SACnD,WAAU,MACR,GAAsB,EAAE,OAAO,KAA4B;mBAG5D,OAAO,OAAO,EAAmB,EAAE,KAAI,MACtC,kBAAC,IAAD;UAAsB,OAAO;oBAC1B,GAAmB,GAAO;SACnB,GAFK,CAEL,CACX;QACK,CAAA,CACS;;OAEpB,KACC,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;QACE,OAAM;QACN,WAAA;QACA,MAAK;QACL,OAAO;QACP,WAAU,MAAK,GAAkB,EAAE,OAAO,KAAK;QAC/C,UAAU;QACV,WAAW,EAAE,YAAY,EAAE,QAAQ,GAAK,EAAE;OAC3C,CAAA,EACE,CAAA;OAEN;OACA;MACI;;IACH,CAAA,CACF;;GAEL,KAAc,MAAyB,QACtC,kBAAC,GAAD;IAAO,UAAS;;GAA6C,CAAA;GAE9D,MACC,kBAAC,GAAD;IAAO,UAAS;;GAA4C,CAAA;GAE7D,KACC,kBAAC,GAAD;IAAO,UAAS;cACb,EAAM,UAAA;GACF,CAAA;EAEJ;KAGH,KAAQ,IACV,KACA,IAEA,IAAgB;CACpB,QAAQ,IAAR;EACE,KAAK;GACH,IAAgB;GAChB;EACF,KAAK;GACH,IAAgB;GAChB;EACF,KAAK;GACH,IAAgB;GAChB;CACJ;CAEA,IAAI,IAAgB;CACpB,QAAQ,IAAR;EACE,KAAK;GACH,IAAgB;GAChB;EACF,KAAK;GACH,IACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe,EAAQ,aAAa;IACpC,UAAU;cACX;GAEO,CAAA,GACR,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe,EAAQ,uBAAuB;IAC9C,UAAU,KAAa,CAAC;cACzB;GAEO,CAAA,CACR,EAAA,CAAA;GAEJ;EAEF,KAAK;GACH,IACE,kBAAA,GAAA,EAAA,UAAA,CACG,CAAC,KACA,kBAAC,GAAD;IACE,SAAQ;IACR,eAAe,EAAQ,sBAAsB;IAC7C,UAAU;cACX;GAEO,CAAA,GAEV,kBAAC,GAAD;IACE,SAAQ;IAER,eAAe,KAAK,GAAW,EAAE,MAAM,CAAI;IAC3C,UAAU,KAAa,MAAyB;cACjD;GAEO,CAAA,CACR,EAAA,CAAA;GAEJ;CAEJ;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACQ;EACC;EACP,UAAS;EACT,WAAA;EACU;EACV,SAAS;EACT,SACE,kBAAC,GAAD;GACE,WAAU;GACV,KAAK;GACL,gBAAe;GACf,YAAW;GACX,OAAM;aALR,CAOE,kBAAC,GAAD,EAAA,UACG,MACC,kBAAC,GAAD;IACE,SAAQ;IACR,OAAM;IACN,eAAe,EAA0B,EAAI;IAC7C,UAAU;cACX;GAEO,CAAA,EAEP,CAAA,GACL,kBAAC,GAAD;IAAO,WAAU;IAAM,KAAK;cACzB;GACI,CAAA,CACF;;CAEV,CAAA,GACD,kBAAC,IAAD;EACE,OAAO;EACP,MAAM;EACN,SACE,kBAAC,GAAD;GAAO,KAAK;aAAZ,CACE,kBAAC,GAAD;IAAY,SAAQ;cACjB;GACS,CAAA,GACZ,kBAAC,GAAD;IAAO,UAAS;cACb;GACI,CAAA,CACF;;EAET,oBAAoB;GAClB,UAAU;GACV,OAAO;GACP,SAAS;EACX;EACA,iBAAiB;GACf,AAAI,GAAM,UAAU,QAAM,GAAW,EAAK,MAAM;EAClD;EACA,gBAAgB,EAA0B,EAAK;CAChD,CAAA,CACD,EAAA,CAAA;AAEN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurationTaskFormState.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,kCAAkC,CAAA;AASzC,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useCurationTaskFormState.d.ts","sourceRoot":"","sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,kCAAkC,CAAA;AASzC,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAiG9D,YAAY,YACX;QAAE,uBAAuB,CAAC,EAAE,oBAAoB,CAAA;KAAE,KAC3D,OAAO,CAAC,YAAY,CAAC;EA4FzB"}
|
|
@@ -3,43 +3,46 @@ import { useSynapseContext as t } from "../../../../utils/context/SynapseContext
|
|
|
3
3
|
import "../../../../components/ToastMessage/index.js";
|
|
4
4
|
import "../../../../utils/index.js";
|
|
5
5
|
import { useGetEntityPermissions as n } from "../../../../synapse-queries/entity/useEntity.js";
|
|
6
|
-
import { useCreateCurationTask as r, useDeleteCurationTask as
|
|
7
|
-
import { CREATE_TASK_STATUS_NOT_SAVED_WARNING as
|
|
8
|
-
import { dueDateInputToIso as
|
|
6
|
+
import { useCreateCurationTask as r, useDeleteCurationTask as ee, useGetCurationTaskStatus as i, useUpdateCurationTask as a, useUpdateCurationTaskStatus as o } from "../../../../synapse-queries/curation/task/useCurationTask.js";
|
|
7
|
+
import { CREATE_TASK_STATUS_NOT_SAVED_WARNING as s, DELETE_CURATION_TASK_ERROR_TOAST_PREFIX as c, DELETE_CURATION_TASK_SUCCESS_TOAST as l } from "../utils/constants.js";
|
|
8
|
+
import { dueDateInputToIso as u, isoToDueDateInput as d } from "../utils/dueDate.js";
|
|
9
9
|
import { useState as f } from "react";
|
|
10
10
|
//#region src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts
|
|
11
11
|
function p(p) {
|
|
12
|
-
let { projectId: m, task: h, onDeleted: g } = p, _ = h !== void 0, { synapseClient: v } = t(), y = !_ && !m, [b, x] = f(""), S = _ ? h?.projectId ?? "" : m ?? b, [C, w] = f(() => h?.dataType ?? ""), [T, E] = f(() => h?.instructions ?? ""), [D, O] = f(() => h?.assigneePrincipalId), { data: k, isFetching: A } =
|
|
12
|
+
let { projectId: m, task: h, onDeleted: g } = p, _ = h !== void 0, { synapseClient: v } = t(), y = !_ && !m, [b, x] = f(""), S = _ ? h?.projectId ?? "" : m ?? b, [C, w] = f(() => h?.dataType ?? ""), [T, E] = f(() => h?.instructions ?? ""), [D, O] = f(() => h?.assigneePrincipalId), { data: k, isFetching: A } = i(h?.taskId ?? 0, { enabled: _ && h?.taskId != null }), [j, M] = f(void 0), N = j ?? k?.state, [P, F] = f(void 0), I = P ?? (_ ? d(h?.dueDate) : ""), { data: L } = n(S, { enabled: !!S }), [R, z] = f(!1), B = !!(L?.canDelete && _ && h?.taskId != null && g != null), { mutateAsync: V, isPending: H, error: U } = r(), { mutateAsync: W, isPending: G, error: K } = a(), { mutateAsync: q, isPending: J, error: Y } = o(), { mutate: X, isPending: Z } = ee({
|
|
13
13
|
onSuccess: () => {
|
|
14
|
-
e(
|
|
14
|
+
e(l, "success"), z(!1), g?.();
|
|
15
15
|
},
|
|
16
16
|
onError: (t) => {
|
|
17
|
-
e(
|
|
17
|
+
e(c + t.message, "danger");
|
|
18
18
|
}
|
|
19
19
|
}), Q = H || G || J || Z, $ = U ?? K ?? Y, te = !!C.trim() && !!T.trim(), ne = !y || !!b.trim();
|
|
20
20
|
async function re(t, n) {
|
|
21
|
-
let r = ee(I);
|
|
22
21
|
if (_) {
|
|
23
|
-
let e = await W(
|
|
24
|
-
|
|
22
|
+
let e = await W({
|
|
23
|
+
...t,
|
|
24
|
+
dueDate: P === void 0 ? h?.dueDate : u(P)
|
|
25
|
+
});
|
|
26
|
+
return j !== void 0 && j !== k?.state && k != null && await q({
|
|
25
27
|
...k,
|
|
26
28
|
state: j ?? k.state,
|
|
27
|
-
dueDate: P === void 0 ? k.dueDate : r,
|
|
28
29
|
etag: e.etag
|
|
29
30
|
}), e;
|
|
30
31
|
}
|
|
31
|
-
let
|
|
32
|
-
|
|
32
|
+
let r = await V({
|
|
33
|
+
...t,
|
|
34
|
+
dueDate: u(I)
|
|
35
|
+
});
|
|
36
|
+
if (n?.initialExecutionDetails && r.taskId != null) try {
|
|
33
37
|
await q({
|
|
34
|
-
...await v.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus({ taskId:
|
|
35
|
-
taskId:
|
|
36
|
-
|
|
37
|
-
executionDetails: n?.initialExecutionDetails
|
|
38
|
+
...await v.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus({ taskId: r.taskId }),
|
|
39
|
+
taskId: r.taskId,
|
|
40
|
+
executionDetails: n.initialExecutionDetails
|
|
38
41
|
});
|
|
39
42
|
} catch {
|
|
40
|
-
e(
|
|
43
|
+
e(s, "warning");
|
|
41
44
|
}
|
|
42
|
-
return
|
|
45
|
+
return r;
|
|
43
46
|
}
|
|
44
47
|
return {
|
|
45
48
|
isEditMode: _,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCurationTaskFormState.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"sourcesContent":["import {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { displayToast } from '@/components/ToastMessage'\nimport { useSynapseContext } from '@/utils/index'\nimport {\n CurationTask,\n TaskExecutionDetails,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport {\n CREATE_TASK_STATUS_NOT_SAVED_WARNING,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n} from '../utils/constants'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type UseCurationTaskFormStateArgs = {\n /**\n * Present when the host page already has a project context. Absent when creating from a context\n * without one, in which case the caller renders a project selector. Ignored in edit mode -- the\n * project is always derived from `task`.\n */\n projectId?: string\n /** The task being edited. Undefined when creating a new task. */\n task?: CurationTask\n /** Called after the task is successfully deleted (edit mode only). */\n onDeleted?: () => void\n}\n\n/**\n * The state and persistence logic shared by every curation-task create/edit form\n * (`ComputeTaskForm`, `CurateTaskForm`): common fields, project selection, task status (state +\n * due date), permissions, the create/update/delete mutations, and the submit-with-status flow.\n * The type-specific fields, validity, and payload construction remain the responsibility of each\n * form -- the caller passes a fully-built `CurationTask` payload to `submitTaskAndStatus`.\n */\nexport function useCurationTaskFormState(args: UseCurationTaskFormStateArgs) {\n const { projectId, task, onDeleted } = args\n const isEditMode = task !== undefined\n const { synapseClient } = useSynapseContext()\n\n const showProjectSelector = !isEditMode && !projectId\n const [selectedProjectId, setSelectedProjectId] = useState('')\n const effectiveProjectId = isEditMode\n ? (task?.projectId ?? '')\n : (projectId ?? selectedProjectId)\n\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n // Task status (edit mode only). `dueDate` also lives on TaskStatus, so it's collected here even in\n // create mode (where there's no status to fetch yet -- it's applied to the auto-created status\n // immediately after the task itself is created, see `submitTaskAndStatus`).\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n // `pendingDueDate` and `displayedDueDate` are always the native date input's `YYYY-MM-DD` string.\n // The backend stores `TaskStatus.dueDate` as an ISO 8601 date-time string, so the fetched value is\n // converted for display and the entered value is converted back on write.\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ??\n (isEditMode ? isoToDueDateInput(currentTaskStatus?.dueDate) : '')\n\n const { data: permissions } = useGetEntityPermissions(effectiveProjectId, {\n enabled: !!effectiveProjectId,\n })\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n const canDelete = Boolean(\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n onDeleted != null,\n )\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleted?.()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isStatusUpdatePending ||\n isDeletePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isCommonFieldsValid = !!dataType.trim() && !!instructions.trim()\n const isProjectValid = !showProjectSelector || !!selectedProjectId.trim()\n\n /**\n * Persists `payload` as either a create or an update (based on edit mode), then reconciles the\n * task's `TaskStatus` (state + due date + `options.initialExecutionDetails`). Returns the persisted\n * task. On create, the status is fetched (it is created server-side automatically) and patched when\n * a due date was entered or `options.initialExecutionDetails` was supplied. On update, the status is\n * written only when the state or due date changed; clearing the due date (empty string) is a valid\n * change and persists as an absent due date. `initialExecutionDetails` is never backfilled on edit.\n */\n async function submitTaskAndStatus(\n payload: CurationTask,\n options?: { initialExecutionDetails?: TaskExecutionDetails },\n ): Promise<CurationTask> {\n const dueDateIso = dueDateInputToIso(displayedDueDate)\n\n if (isEditMode) {\n const latestTask = await updateTask(payload)\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n const dueDateChanged =\n pendingDueDate !== undefined &&\n dueDateIso !== (currentTaskStatus?.dueDate ?? undefined)\n if ((statusStateChanged || dueDateChanged) && currentTaskStatus != null) {\n // The task and its status share an etag, and the preceding `updateTask` bumped it; the\n // status update must use the etag returned by that update, not the stale fetched one. When\n // the user didn't touch the due date, preserve the stored value verbatim rather than the\n // re-encoded one, so a status-only edit can never blank out or rewrite an existing due date.\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n dueDate:\n pendingDueDate !== undefined\n ? dueDateIso\n : currentTaskStatus.dueDate,\n etag: latestTask.etag,\n })\n }\n\n return latestTask\n }\n\n const created = await createTask(payload)\n\n if (\n (dueDateIso || options?.initialExecutionDetails) &&\n created.taskId != null\n ) {\n // TODO(PLFM-9839): replace this best-effort status write with a single service that creates\n // the task and its status atomically. Until then, the task is created first and the due date\n // is applied to the auto-created status in a separate call; a failure there must not strand a\n // created task or surface as a hard error (which would tempt the user to re-create the task).\n try {\n // A CurationTask's TaskStatus is created automatically server-side; fetch it so the due date\n // can be applied to it. The freshly-fetched status carries the current shared etag.\n const status =\n await synapseClient.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus(\n { taskId: created.taskId },\n )\n await updateTaskStatus({\n ...status,\n taskId: created.taskId,\n dueDate: dueDateIso,\n executionDetails: options?.initialExecutionDetails,\n })\n } catch {\n displayToast(CREATE_TASK_STATUS_NOT_SAVED_WARNING, 'warning')\n }\n }\n\n return created\n }\n\n return {\n isEditMode,\n // project\n showProjectSelector,\n selectedProjectId,\n setSelectedProjectId,\n effectiveProjectId,\n // common fields\n dataType,\n setDataType,\n instructions,\n setInstructions,\n assigneePrincipalId,\n setAssigneePrincipalId,\n // status + due date\n currentTaskStatus,\n isStatusFetching,\n displayedStatusState,\n setPendingStatusState,\n displayedDueDate,\n setPendingDueDate,\n // permissions + delete\n canDelete,\n showDeleteConfirmation,\n setShowDeleteConfirmation,\n deleteTask,\n isDeletePending,\n // aggregate mutation state\n isPending,\n error,\n // validity (common portion; type-specific validity is the caller's responsibility)\n isCommonFieldsValid,\n isProjectValid,\n // submit\n submitTaskAndStatus,\n }\n}\n"],"mappings":";;;;;;;;;;AA2CA,SAAgB,EAAyB,GAAoC;CAC3E,IAAM,EAAE,cAAW,SAAM,iBAAc,GACjC,IAAa,MAAS,KAAA,GACtB,EAAE,qBAAkB,EAAkB,GAEtC,IAAsB,CAAC,KAAc,CAAC,GACtC,CAAC,GAAmB,KAAwB,EAAS,EAAE,GACvD,IAAqB,IACtB,GAAM,aAAa,KACnB,KAAa,GAEZ,CAAC,GAAU,KAAe,QAAe,GAAM,YAAY,EAAE,GAC7D,CAAC,GAAc,KAAmB,QAChC,GAAM,gBAAgB,EAC9B,GACM,CAAC,GAAqB,KAA0B,QAE9C,GAAM,mBAAmB,GAK3B,EAAE,MAAM,GAAmB,YAAY,MAC3C,EAAyB,GAAM,UAAU,GAAG,EAC1C,SAAS,KAAc,GAAM,UAAU,KACzC,CAAC,GACG,CAAC,GAAoB,KAAyB,EAElD,KAAA,CAAS,GACL,IAAuB,KAAsB,GAAmB,OAIhE,CAAC,GAAgB,KAAqB,EAC1C,KAAA,CACF,GACM,IACJ,MACC,IAAa,EAAkB,GAAmB,OAAO,IAAI,KAE1D,EAAE,MAAM,MAAgB,EAAwB,GAAoB,EACxE,SAAS,CAAC,CAAC,EACb,CAAC,GACK,CAAC,GAAwB,KAA6B,EAAS,EAAK,GACpE,IAAY,GAChB,GAAa,aACb,KACA,GAAM,UAAU,QAChB,KAAa,OAGT,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAA4B,GAC1B,EAAE,QAAQ,GAAY,WAAW,MACrC,EAAsB;EACpB,iBAAiB;GAGf,AAFA,EAAa,GAAoC,SAAS,GAC1D,EAA0B,EAAK,GAC/B,IAAY;EACd;EACA,UAAS,MAAO;GACd,EACE,IAA0C,EAAI,SAC9C,QACF;EACF;CACF,CAAC,GAEG,IACJ,KACA,KACA,KACA,GACI,IAAQ,KAAe,KAAe,GAEtC,KAAsB,CAAC,CAAC,EAAS,KAAK,KAAK,CAAC,CAAC,EAAa,KAAK,GAC/D,KAAiB,CAAC,KAAuB,CAAC,CAAC,EAAkB,KAAK;CAUxE,eAAe,GACb,GACA,GACuB;EACvB,IAAM,IAAa,GAAkB,CAAgB;EAErD,IAAI,GAAY;GACd,IAAM,IAAa,MAAM,EAAW,CAAO,GAErC,IACJ,MAAuB,KAAA,KACvB,MAAuB,GAAmB,OACtC,IACJ,MAAmB,KAAA,KACnB,OAAgB,GAAmB,WAAW,KAAA;GAiBhD,QAhBK,KAAsB,MAAmB,KAAqB,QAKjE,MAAM,EAAiB;IACrB,GAAG;IACH,OAAO,KAAsB,EAAkB;IAC/C,SACE,MAAmB,KAAA,IAEf,EAAkB,UADlB;IAEN,MAAM,EAAW;GACnB,CAAC,GAGI;EACT;EAEA,IAAM,IAAU,MAAM,EAAW,CAAO;EAExC,KACG,KAAc,GAAS,4BACxB,EAAQ,UAAU,MAMlB,IAAI;GAOF,MAAM,EAAiB;IACrB,GAAG,MAJG,EAAc,2BAA2B,kCAC7C,EAAE,QAAQ,EAAQ,OAAO,CAC3B;IAGA,QAAQ,EAAQ;IAChB,SAAS;IACT,kBAAkB,GAAS;GAC7B,CAAC;EACH,QAAQ;GACN,EAAa,GAAsC,SAAS;EAC9D;EAGF,OAAO;CACT;CAEA,OAAO;EACL;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EAEA;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"useCurationTaskFormState.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/create-task/useCurationTaskFormState.ts"],"sourcesContent":["import {\n useCreateCurationTask,\n useDeleteCurationTask,\n useGetCurationTaskStatus,\n useUpdateCurationTask,\n useUpdateCurationTaskStatus,\n} from '@/synapse-queries/curation/task/useCurationTask'\nimport { useGetEntityPermissions } from '@/synapse-queries/entity/useEntity'\nimport { displayToast } from '@/components/ToastMessage'\nimport { useSynapseContext } from '@/utils/index'\nimport {\n CurationTask,\n TaskExecutionDetails,\n TaskStatusStateEnum,\n} from '@sage-bionetworks/synapse-client'\nimport { useState } from 'react'\nimport {\n CREATE_TASK_STATUS_NOT_SAVED_WARNING,\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX,\n DELETE_CURATION_TASK_SUCCESS_TOAST,\n} from '../utils/constants'\nimport { dueDateInputToIso, isoToDueDateInput } from '../utils/dueDate'\n\nexport type UseCurationTaskFormStateArgs = {\n /**\n * Present when the host page already has a project context. Absent when creating from a context\n * without one, in which case the caller renders a project selector. Ignored in edit mode -- the\n * project is always derived from `task`.\n */\n projectId?: string\n /** The task being edited. Undefined when creating a new task. */\n task?: CurationTask\n /** Called after the task is successfully deleted (edit mode only). */\n onDeleted?: () => void\n}\n\n/**\n * The state and persistence logic shared by every curation-task create/edit form\n * (`ComputeTaskForm`, `CurateTaskForm`): common fields, project selection, task status (state +\n * due date), permissions, the create/update/delete mutations, and the submit-with-status flow.\n * The type-specific fields, validity, and payload construction remain the responsibility of each\n * form -- the caller passes a fully-built `CurationTask` payload to `submitTaskAndStatus`.\n */\nexport function useCurationTaskFormState(args: UseCurationTaskFormStateArgs) {\n const { projectId, task, onDeleted } = args\n const isEditMode = task !== undefined\n const { synapseClient } = useSynapseContext()\n\n const showProjectSelector = !isEditMode && !projectId\n const [selectedProjectId, setSelectedProjectId] = useState('')\n const effectiveProjectId = isEditMode\n ? (task?.projectId ?? '')\n : (projectId ?? selectedProjectId)\n\n const [dataType, setDataType] = useState(() => task?.dataType ?? '')\n const [instructions, setInstructions] = useState(\n () => task?.instructions ?? '',\n )\n const [assigneePrincipalId, setAssigneePrincipalId] = useState<\n string | undefined\n >(() => task?.assigneePrincipalId)\n\n // Task status (edit mode only, for the status state field).\n const { data: currentTaskStatus, isFetching: isStatusFetching } =\n useGetCurationTaskStatus(task?.taskId ?? 0, {\n enabled: isEditMode && task?.taskId != null,\n })\n const [pendingStatusState, setPendingStatusState] = useState<\n TaskStatusStateEnum | undefined\n >(undefined)\n const displayedStatusState = pendingStatusState ?? currentTaskStatus?.state\n // `pendingDueDate` and `displayedDueDate` are always the native date input's `YYYY-MM-DD` string.\n // `CurationTask.dueDate` is stored as an ISO 8601 date-time string, so the fetched value is\n // converted for display and the entered value is converted back on write.\n const [pendingDueDate, setPendingDueDate] = useState<string | undefined>(\n undefined,\n )\n const displayedDueDate =\n pendingDueDate ?? (isEditMode ? isoToDueDateInput(task?.dueDate) : '')\n\n const { data: permissions } = useGetEntityPermissions(effectiveProjectId, {\n enabled: !!effectiveProjectId,\n })\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)\n const canDelete = Boolean(\n permissions?.canDelete &&\n isEditMode &&\n task?.taskId != null &&\n onDeleted != null,\n )\n\n const {\n mutateAsync: createTask,\n isPending: isCreatePending,\n error: createError,\n } = useCreateCurationTask()\n const {\n mutateAsync: updateTask,\n isPending: isUpdatePending,\n error: updateError,\n } = useUpdateCurationTask()\n const {\n mutateAsync: updateTaskStatus,\n isPending: isStatusUpdatePending,\n error: statusUpdateError,\n } = useUpdateCurationTaskStatus()\n const { mutate: deleteTask, isPending: isDeletePending } =\n useDeleteCurationTask({\n onSuccess: () => {\n displayToast(DELETE_CURATION_TASK_SUCCESS_TOAST, 'success')\n setShowDeleteConfirmation(false)\n onDeleted?.()\n },\n onError: err => {\n displayToast(\n DELETE_CURATION_TASK_ERROR_TOAST_PREFIX + err.message,\n 'danger',\n )\n },\n })\n\n const isPending =\n isCreatePending ||\n isUpdatePending ||\n isStatusUpdatePending ||\n isDeletePending\n const error = createError ?? updateError ?? statusUpdateError\n\n const isCommonFieldsValid = !!dataType.trim() && !!instructions.trim()\n const isProjectValid = !showProjectSelector || !!selectedProjectId.trim()\n\n /**\n * Persists `payload` as either a create or an update (based on edit mode), then reconciles the\n * task's `TaskStatus` (state + `options.initialExecutionDetails`). Returns the persisted task.\n * `dueDate` is included directly in the task payload. On create, the status is fetched (it is\n * created server-side automatically) and patched only when `options.initialExecutionDetails` is\n * supplied. On update, the status is written only when the state changed.\n * `initialExecutionDetails` is never backfilled on edit.\n */\n async function submitTaskAndStatus(\n payload: CurationTask,\n options?: { initialExecutionDetails?: TaskExecutionDetails },\n ): Promise<CurationTask> {\n if (isEditMode) {\n // When the user hasn't changed the due date, pass the task's stored value through verbatim so\n // a state-only edit can never blank out or re-encode an existing due date.\n const latestTask = await updateTask({\n ...payload,\n dueDate:\n pendingDueDate !== undefined\n ? dueDateInputToIso(pendingDueDate)\n : task?.dueDate,\n })\n\n const statusStateChanged =\n pendingStatusState !== undefined &&\n pendingStatusState !== currentTaskStatus?.state\n if (statusStateChanged && currentTaskStatus != null) {\n // The task and its status share an etag, and the preceding `updateTask` bumped it; the\n // status update must use the etag returned by that update, not the stale fetched one.\n await updateTaskStatus({\n ...currentTaskStatus,\n state: pendingStatusState ?? currentTaskStatus.state,\n etag: latestTask.etag,\n })\n }\n\n return latestTask\n }\n\n const created = await createTask({\n ...payload,\n dueDate: dueDateInputToIso(displayedDueDate),\n })\n\n if (options?.initialExecutionDetails && created.taskId != null) {\n // TODO(PLFM-9839): replace this best-effort status write with a single service that creates\n // the task and its status atomically. Until then, execution details are applied to the\n // auto-created status in a separate call; a failure must not strand the created task or\n // surface as a hard error (which would tempt the user to re-create the task).\n try {\n const status =\n await synapseClient.curationTaskServicesClient.getRepoV1CurationTaskTaskIdStatus(\n { taskId: created.taskId },\n )\n await updateTaskStatus({\n ...status,\n taskId: created.taskId,\n executionDetails: options.initialExecutionDetails,\n })\n } catch {\n displayToast(CREATE_TASK_STATUS_NOT_SAVED_WARNING, 'warning')\n }\n }\n\n return created\n }\n\n return {\n isEditMode,\n // project\n showProjectSelector,\n selectedProjectId,\n setSelectedProjectId,\n effectiveProjectId,\n // common fields\n dataType,\n setDataType,\n instructions,\n setInstructions,\n assigneePrincipalId,\n setAssigneePrincipalId,\n // status + due date\n currentTaskStatus,\n isStatusFetching,\n displayedStatusState,\n setPendingStatusState,\n displayedDueDate,\n setPendingDueDate,\n // permissions + delete\n canDelete,\n showDeleteConfirmation,\n setShowDeleteConfirmation,\n deleteTask,\n isDeletePending,\n // aggregate mutation state\n isPending,\n error,\n // validity (common portion; type-specific validity is the caller's responsibility)\n isCommonFieldsValid,\n isProjectValid,\n // submit\n submitTaskAndStatus,\n }\n}\n"],"mappings":";;;;;;;;;;AA2CA,SAAgB,EAAyB,GAAoC;CAC3E,IAAM,EAAE,cAAW,SAAM,iBAAc,GACjC,IAAa,MAAS,KAAA,GACtB,EAAE,qBAAkB,EAAkB,GAEtC,IAAsB,CAAC,KAAc,CAAC,GACtC,CAAC,GAAmB,KAAwB,EAAS,EAAE,GACvD,IAAqB,IACtB,GAAM,aAAa,KACnB,KAAa,GAEZ,CAAC,GAAU,KAAe,QAAe,GAAM,YAAY,EAAE,GAC7D,CAAC,GAAc,KAAmB,QAChC,GAAM,gBAAgB,EAC9B,GACM,CAAC,GAAqB,KAA0B,QAE9C,GAAM,mBAAmB,GAG3B,EAAE,MAAM,GAAmB,YAAY,MAC3C,EAAyB,GAAM,UAAU,GAAG,EAC1C,SAAS,KAAc,GAAM,UAAU,KACzC,CAAC,GACG,CAAC,GAAoB,KAAyB,EAElD,KAAA,CAAS,GACL,IAAuB,KAAsB,GAAmB,OAIhE,CAAC,GAAgB,KAAqB,EAC1C,KAAA,CACF,GACM,IACJ,MAAmB,IAAa,EAAkB,GAAM,OAAO,IAAI,KAE/D,EAAE,MAAM,MAAgB,EAAwB,GAAoB,EACxE,SAAS,CAAC,CAAC,EACb,CAAC,GACK,CAAC,GAAwB,KAA6B,EAAS,EAAK,GACpE,IAAY,GAChB,GAAa,aACb,KACA,GAAM,UAAU,QAChB,KAAa,OAGT,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAAsB,GACpB,EACJ,aAAa,GACb,WAAW,GACX,OAAO,MACL,EAA4B,GAC1B,EAAE,QAAQ,GAAY,WAAW,MACrC,GAAsB;EACpB,iBAAiB;GAGf,AAFA,EAAa,GAAoC,SAAS,GAC1D,EAA0B,EAAK,GAC/B,IAAY;EACd;EACA,UAAS,MAAO;GACd,EACE,IAA0C,EAAI,SAC9C,QACF;EACF;CACF,CAAC,GAEG,IACJ,KACA,KACA,KACA,GACI,IAAQ,KAAe,KAAe,GAEtC,KAAsB,CAAC,CAAC,EAAS,KAAK,KAAK,CAAC,CAAC,EAAa,KAAK,GAC/D,KAAiB,CAAC,KAAuB,CAAC,CAAC,EAAkB,KAAK;CAUxE,eAAe,GACb,GACA,GACuB;EACvB,IAAI,GAAY;GAGd,IAAM,IAAa,MAAM,EAAW;IAClC,GAAG;IACH,SACE,MAAmB,KAAA,IAEf,GAAM,UADN,EAAkB,CAAc;GAExC,CAAC;GAeD,OAZE,MAAuB,KAAA,KACvB,MAAuB,GAAmB,SAClB,KAAqB,QAG7C,MAAM,EAAiB;IACrB,GAAG;IACH,OAAO,KAAsB,EAAkB;IAC/C,MAAM,EAAW;GACnB,CAAC,GAGI;EACT;EAEA,IAAM,IAAU,MAAM,EAAW;GAC/B,GAAG;GACH,SAAS,EAAkB,CAAgB;EAC7C,CAAC;EAED,IAAI,GAAS,2BAA2B,EAAQ,UAAU,MAKxD,IAAI;GAKF,MAAM,EAAiB;IACrB,GAAG,MAJG,EAAc,2BAA2B,kCAC7C,EAAE,QAAQ,EAAQ,OAAO,CAC3B;IAGA,QAAQ,EAAQ;IAChB,kBAAkB,EAAQ;GAC5B,CAAC;EACH,QAAQ;GACN,EAAa,GAAsC,SAAS;EAC9D;EAGF,OAAO;CACT;CAEA,OAAO;EACL;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EAEA;CACF;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Dayjs } from 'dayjs';
|
|
2
2
|
/**
|
|
3
3
|
* A native `<input type="date">` produces a bare `YYYY-MM-DD` calendar date with no timezone, but the
|
|
4
|
-
* backend's `
|
|
4
|
+
* backend's `CurationTask.dueDate` is an ISO 8601 date-time string. Both conversions here anchor the
|
|
5
5
|
* calendar date to UTC midnight so the date a user picks is the date every other user sees, regardless
|
|
6
6
|
* of their timezone. Returns `undefined` for an empty or malformed input so the caller can persist an
|
|
7
7
|
* absent due date.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dueDate.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/utils/dueDate.ts"],"sourcesContent":["import dayjs, { Dayjs } from 'dayjs'\nimport customParseFormat from 'dayjs/plugin/customParseFormat'\nimport utc from 'dayjs/plugin/utc'\n\ndayjs.extend(customParseFormat)\ndayjs.extend(utc)\n\nconst DUE_DATE_INPUT_FORMAT = 'YYYY-MM-DD'\n\n/**\n * A native `<input type=\"date\">` produces a bare `YYYY-MM-DD` calendar date with no timezone, but the\n * backend's `
|
|
1
|
+
{"version":3,"file":"dueDate.js","names":[],"sources":["../../../../../src/features/entity/metadata-task/utils/dueDate.ts"],"sourcesContent":["import dayjs, { Dayjs } from 'dayjs'\nimport customParseFormat from 'dayjs/plugin/customParseFormat'\nimport utc from 'dayjs/plugin/utc'\n\ndayjs.extend(customParseFormat)\ndayjs.extend(utc)\n\nconst DUE_DATE_INPUT_FORMAT = 'YYYY-MM-DD'\n\n/**\n * A native `<input type=\"date\">` produces a bare `YYYY-MM-DD` calendar date with no timezone, but the\n * backend's `CurationTask.dueDate` is an ISO 8601 date-time string. Both conversions here anchor the\n * calendar date to UTC midnight so the date a user picks is the date every other user sees, regardless\n * of their timezone. Returns `undefined` for an empty or malformed input so the caller can persist an\n * absent due date.\n */\nexport function dueDateInputToIso(yyyyMmDd: string): string | undefined {\n if (!yyyyMmDd) {\n return undefined\n }\n const parsed = dayjs.utc(yyyyMmDd, DUE_DATE_INPUT_FORMAT, true)\n return parsed.isValid() ? parsed.toISOString() : undefined\n}\n\n/**\n * Inverse of {@link dueDateInputToIso}: formats the backend's ISO 8601 `dueDate` string back to the\n * `YYYY-MM-DD` value a native date input expects, in UTC. Returns `''` when the due date is absent or\n * unparseable.\n */\nexport function isoToDueDateInput(dueDate: string | undefined): string {\n if (!dueDate) {\n return ''\n }\n const parsed = dayjs.utc(dueDate)\n return parsed.isValid() ? parsed.format(DUE_DATE_INPUT_FORMAT) : ''\n}\n\n/**\n * The `dueDate` as a UTC-anchored dayjs, or `null` when absent/unparseable. Anchoring to UTC (the same\n * as {@link isoToDueDateInput}) means the calendar date shown matches the date the user picked,\n * regardless of the viewer's timezone.\n */\nexport function parseDueDate(dueDate: string | undefined): Dayjs | null {\n if (!dueDate) {\n return null\n }\n const parsed = dayjs.utc(dueDate)\n return parsed.isValid() ? parsed : null\n}\n"],"mappings":";;;AAIA,EAAM,OAAO,CAAiB,GAC9B,EAAM,OAAO,CAAG;AAEhB,IAAM,IAAwB;AAS9B,SAAgB,EAAkB,GAAsC;CACtE,IAAI,CAAC,GACH;CAEF,IAAM,IAAS,EAAM,IAAI,GAAU,GAAuB,EAAI;CAC9D,OAAO,EAAO,QAAQ,IAAI,EAAO,YAAY,IAAI,KAAA;AACnD;AAOA,SAAgB,EAAkB,GAAqC;CACrE,IAAI,CAAC,GACH,OAAO;CAET,IAAM,IAAS,EAAM,IAAI,CAAO;CAChC,OAAO,EAAO,QAAQ,IAAI,EAAO,OAAO,CAAqB,IAAI;AACnE;AAOA,SAAgB,EAAa,GAA2C;CACtE,IAAI,CAAC,GACH,OAAO;CAET,IAAM,IAAS,EAAM,IAAI,CAAO;CAChC,OAAO,EAAO,QAAQ,IAAI,IAAS;AACrC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ChatAttachment } from '@/components/SynapseChat/utils/types';
|
|
2
|
+
import { AgentChatRequest, AgentChatResponse } from '@sage-bionetworks/synapse-client';
|
|
3
|
+
import { AgentSession, AsynchronousJobStatus, CreateAgentSessionRequest, ListAgentSessionsRequest, ListAgentSessionsResponse, SessionHistoryResponse, TraceEventsResponse } from '@sage-bionetworks/synapse-types';
|
|
2
4
|
export declare const mockChatSessionId = "session-456";
|
|
3
5
|
export declare const mockCreateAgentSessionRequest: CreateAgentSessionRequest;
|
|
4
6
|
export declare const mockAgentSession: AgentSession;
|
|
@@ -7,9 +9,19 @@ export declare const mockListAgentSessionsRequest: ListAgentSessionsRequest;
|
|
|
7
9
|
export declare const mockListAgentSessionsResponse: ListAgentSessionsResponse;
|
|
8
10
|
export declare const mockAgentChatRequest: AgentChatRequest;
|
|
9
11
|
export declare const mockAgentChatResponse: AgentChatResponse;
|
|
12
|
+
/**
|
|
13
|
+
* Builds a full `AsynchronousJobStatus` for the chat async job, for tests/stories that poll the
|
|
14
|
+
* job status endpoint directly (e.g. to exercise the PROCESSING state). `jobId` is required since
|
|
15
|
+
* it must match the id returned by the mocked start-chat-async endpoint; other fields default to
|
|
16
|
+
* placeholder values and can be overridden.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mockChatJobStatus(overrides: Partial<AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>> & {
|
|
19
|
+
jobId: string;
|
|
20
|
+
}): AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>;
|
|
10
21
|
export declare const mockSessionHistoryResponse: SessionHistoryResponse;
|
|
11
22
|
export declare const mockTraceEventsResponse1: TraceEventsResponse;
|
|
12
23
|
export declare const mockTraceEventsResponse2: TraceEventsResponse;
|
|
13
24
|
export declare const mockTraceEventsResponse3: TraceEventsResponse;
|
|
14
25
|
export declare const mockEmptyTraceEventsResponse: TraceEventsResponse;
|
|
26
|
+
export declare function mockChatAttachment(overrides?: Partial<ChatAttachment>): ChatAttachment;
|
|
15
27
|
//# sourceMappingURL=mockChat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockChat.d.ts","sourceRoot":"","sources":["../../../src/mocks/chat/mockChat.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"mockChat.d.ts","sourceRoot":"","sources":["../../../src/mocks/chat/mockChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAA;AACrE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAEL,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,iCAAiC,CAAA;AAExC,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAC9C,eAAO,MAAM,6BAA6B,EAAE,yBAG3C,CAAA;AACD,eAAO,MAAM,gBAAgB,EAAE,YAK9B,CAAA;AACD,eAAO,MAAM,iBAAiB,EAAE,YAK/B,CAAA;AACD,eAAO,MAAM,4BAA4B,EAAE,wBAE1C,CAAA;AAED,eAAO,MAAM,6BAA6B,EAAE,yBAG3C,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAKlC,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,iBAKnC,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,OAAO,CAChB,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAC3D,GAAG;IACF,KAAK,EAAE,MAAM,CAAA;CACd,GACA,qBAAqB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAY5D;AAED,eAAO,MAAM,0BAA0B,EAAE,sBAkBxC,CAAA;AAED,eAAO,MAAM,wBAAwB,EAAE,mBAQtC,CAAA;AAED,eAAO,MAAM,wBAAwB,EAAE,mBAQtC,CAAA;AACD,eAAO,MAAM,wBAAwB,EAAE,mBAStC,CAAA;AAGD,eAAO,MAAM,4BAA4B,EAAE,mBAG1C,CAAA;AAID,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,cAAc,CAShB"}
|
|
@@ -19,11 +19,27 @@ var t = "session-456", n = {
|
|
|
19
19
|
}, s = {
|
|
20
20
|
sessionId: t,
|
|
21
21
|
chatText: "Hello! How can I access My Projects?",
|
|
22
|
-
enableTrace: !0
|
|
22
|
+
enableTrace: !0,
|
|
23
|
+
concreteType: "org.sagebionetworks.repo.model.agent.AgentChatRequest"
|
|
23
24
|
}, c = {
|
|
24
25
|
sessionId: t,
|
|
25
|
-
responseText: "This is the only response this agent is told to respond with. \n\n<function_results>\n<result>\n<tool_name><REDACTED>_get_description</tool_name>\n<stdout> **Adapt**: You can remix, transform, and build upon the material **Attribution:** You must acknowledge the Data Contributor using the acknowledgment statement below: **Non-Commercial**: You may not use the material for commercial purposes. \n\nThe TOPACIO study was a phase 2 clinical trial of the investigational drug OPB-51602 in patients with advanced solid tumors. The study was sponsored by Oncopia Therapeutics, Inc. and conducted at multiple sites in the United States between 2013 and 2015.\n\nThis dataset contains de-identified clinical data, biomarker data, and pharmacokinetic/pharmacodynamic (PK/PD) data from the TOPACIO study. Specific data files include:\n\n- Demographics and baseline characteristics\n- Adverse events \n- Tumor response data\n- Pharmacokinetic data\n- Pharmacodynamic biomarker data\n\nThe data has been de-identified in accordance with HIPAA regulations. Please see the study protocol and data dictionary files for more details on the collected data and definitions.\n\n**Acknowledgment Statement**: The TOPACIO study data was contributed by Oncopia Therapeutics, Inc. Please use the following text to acknowledge the source of the data: \"The results published here are in part based upon data generated by the TOPACIO clinical trial, provided by Oncopia Therapeutics, Inc.\"\n</stdout>\n</result>\n"
|
|
26
|
-
|
|
26
|
+
responseText: "This is the only response this agent is told to respond with. \n\n<function_results>\n<result>\n<tool_name><REDACTED>_get_description</tool_name>\n<stdout> **Adapt**: You can remix, transform, and build upon the material **Attribution:** You must acknowledge the Data Contributor using the acknowledgment statement below: **Non-Commercial**: You may not use the material for commercial purposes. \n\nThe TOPACIO study was a phase 2 clinical trial of the investigational drug OPB-51602 in patients with advanced solid tumors. The study was sponsored by Oncopia Therapeutics, Inc. and conducted at multiple sites in the United States between 2013 and 2015.\n\nThis dataset contains de-identified clinical data, biomarker data, and pharmacokinetic/pharmacodynamic (PK/PD) data from the TOPACIO study. Specific data files include:\n\n- Demographics and baseline characteristics\n- Adverse events \n- Tumor response data\n- Pharmacokinetic data\n- Pharmacodynamic biomarker data\n\nThe data has been de-identified in accordance with HIPAA regulations. Please see the study protocol and data dictionary files for more details on the collected data and definitions.\n\n**Acknowledgment Statement**: The TOPACIO study data was contributed by Oncopia Therapeutics, Inc. Please use the following text to acknowledge the source of the data: \"The results published here are in part based upon data generated by the TOPACIO clinical trial, provided by Oncopia Therapeutics, Inc.\"\n</stdout>\n</result>\n",
|
|
27
|
+
concreteType: "org.sagebionetworks.repo.model.agent.AgentChatResponse"
|
|
28
|
+
};
|
|
29
|
+
function l(e) {
|
|
30
|
+
return {
|
|
31
|
+
jobState: "COMPLETE",
|
|
32
|
+
jobCanceling: !1,
|
|
33
|
+
requestBody: s,
|
|
34
|
+
etag: "00000000-0000-0000-0000-000000000000",
|
|
35
|
+
startedByUserId: 0,
|
|
36
|
+
startedOn: "",
|
|
37
|
+
changedOn: "",
|
|
38
|
+
runtimeMS: 100,
|
|
39
|
+
...e
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
var u = {
|
|
27
43
|
sessionId: t,
|
|
28
44
|
page: [{
|
|
29
45
|
usersRequestText: "What is the weather like today?",
|
|
@@ -37,29 +53,38 @@ var t = "session-456", n = {
|
|
|
37
53
|
agentResponseTimestamp: "2024-09-06T14:32:05Z"
|
|
38
54
|
}],
|
|
39
55
|
nextPageToken: void 0
|
|
40
|
-
},
|
|
56
|
+
}, d = {
|
|
41
57
|
jobId: ":id",
|
|
42
58
|
page: [{
|
|
43
59
|
timestamp: 1695567600,
|
|
44
60
|
message: "Executing search on Synapse"
|
|
45
61
|
}]
|
|
46
|
-
},
|
|
62
|
+
}, f = {
|
|
47
63
|
jobId: ":id",
|
|
48
64
|
page: [{
|
|
49
65
|
timestamp: 1695567700,
|
|
50
66
|
message: "Gathering entity metadata"
|
|
51
67
|
}]
|
|
52
|
-
},
|
|
68
|
+
}, p = {
|
|
53
69
|
jobId: ":id",
|
|
54
70
|
page: [{
|
|
55
71
|
timestamp: 1695567800,
|
|
56
72
|
message: "<thinking>The metadata shows that the entity with ID syn9602623 is a Synapse project named \"SearchIntegrationTest.Projecte475c6e8-414a-4842-b876-bf8232ce05d0\". Its description contains the search term \"e7b33c3a-2392-4ce7-a357-efa4612e4a41\". The metadata ..."
|
|
57
73
|
}]
|
|
58
|
-
},
|
|
74
|
+
}, m = {
|
|
59
75
|
jobId: ":id",
|
|
60
76
|
page: []
|
|
61
|
-
};
|
|
77
|
+
}, h = 0;
|
|
78
|
+
function g(e = {}) {
|
|
79
|
+
return h++, {
|
|
80
|
+
fileHandleId: `${9999990 + h}`,
|
|
81
|
+
fileName: `file-${h}.txt`,
|
|
82
|
+
contentType: "text/plain",
|
|
83
|
+
sizeBytes: 1024,
|
|
84
|
+
...e
|
|
85
|
+
};
|
|
86
|
+
}
|
|
62
87
|
//#endregion
|
|
63
|
-
export { s as mockAgentChatRequest, c as mockAgentChatResponse, r as mockAgentSession, i as mockAgentSession2, t as mockChatSessionId, n as mockCreateAgentSessionRequest,
|
|
88
|
+
export { s as mockAgentChatRequest, c as mockAgentChatResponse, r as mockAgentSession, i as mockAgentSession2, g as mockChatAttachment, l as mockChatJobStatus, t as mockChatSessionId, n as mockCreateAgentSessionRequest, m as mockEmptyTraceEventsResponse, a as mockListAgentSessionsRequest, o as mockListAgentSessionsResponse, u as mockSessionHistoryResponse, d as mockTraceEventsResponse1, f as mockTraceEventsResponse2, p as mockTraceEventsResponse3 };
|
|
64
89
|
|
|
65
90
|
//# sourceMappingURL=mockChat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockChat.js","names":[],"sources":["../../../src/mocks/chat/mockChat.ts"],"sourcesContent":["import {\n
|
|
1
|
+
{"version":3,"file":"mockChat.js","names":[],"sources":["../../../src/mocks/chat/mockChat.ts"],"sourcesContent":["import { ChatAttachment } from '@/components/SynapseChat/utils/types'\nimport {\n AgentChatRequest,\n AgentChatResponse,\n} from '@sage-bionetworks/synapse-client'\nimport {\n AgentAccessLevel,\n AgentSession,\n AsynchronousJobStatus,\n CreateAgentSessionRequest,\n ListAgentSessionsRequest,\n ListAgentSessionsResponse,\n SessionHistoryResponse,\n TraceEventsResponse,\n} from '@sage-bionetworks/synapse-types'\n\nexport const mockChatSessionId = 'session-456'\nexport const mockCreateAgentSessionRequest: CreateAgentSessionRequest = {\n agentAccessLevel: AgentAccessLevel.READ_YOUR_PRIVATE_DATA,\n agentRegistrationId: 'experimental-agent-123',\n}\nexport const mockAgentSession: AgentSession = {\n sessionId: mockChatSessionId,\n agentAccessLevel: AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n startedOn: '2024-09-01T12:00:00Z',\n agentRegistrationId: 'default-agent',\n}\nexport const mockAgentSession2: AgentSession = {\n sessionId: 'session-789',\n agentAccessLevel: AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA,\n startedOn: '2024-09-01T12:00:00Z',\n agentRegistrationId: 'default-agent',\n}\nexport const mockListAgentSessionsRequest: ListAgentSessionsRequest = {\n nextPageToken: 'token-789',\n}\n\nexport const mockListAgentSessionsResponse: ListAgentSessionsResponse = {\n page: [mockAgentSession, mockAgentSession2],\n nextPageToken: 'token-790',\n}\n\nexport const mockAgentChatRequest: AgentChatRequest = {\n sessionId: mockChatSessionId,\n chatText: 'Hello! How can I access My Projects?',\n enableTrace: true,\n concreteType: 'org.sagebionetworks.repo.model.agent.AgentChatRequest',\n}\n\nexport const mockAgentChatResponse: AgentChatResponse = {\n sessionId: mockChatSessionId,\n responseText:\n 'This is the only response this agent is told to respond with. \\n\\n<function_results>\\n<result>\\n<tool_name><REDACTED>_get_description</tool_name>\\n<stdout> **Adapt**: You can remix, transform, and build upon the material **Attribution:** You must acknowledge the Data Contributor using the acknowledgment statement below: **Non-Commercial**: You may not use the material for commercial purposes. \\n\\nThe TOPACIO study was a phase 2 clinical trial of the investigational drug OPB-51602 in patients with advanced solid tumors. The study was sponsored by Oncopia Therapeutics, Inc. and conducted at multiple sites in the United States between 2013 and 2015.\\n\\nThis dataset contains de-identified clinical data, biomarker data, and pharmacokinetic/pharmacodynamic (PK/PD) data from the TOPACIO study. Specific data files include:\\n\\n- Demographics and baseline characteristics\\n- Adverse events \\n- Tumor response data\\n- Pharmacokinetic data\\n- Pharmacodynamic biomarker data\\n\\nThe data has been de-identified in accordance with HIPAA regulations. Please see the study protocol and data dictionary files for more details on the collected data and definitions.\\n\\n**Acknowledgment Statement**: The TOPACIO study data was contributed by Oncopia Therapeutics, Inc. Please use the following text to acknowledge the source of the data: \"The results published here are in part based upon data generated by the TOPACIO clinical trial, provided by Oncopia Therapeutics, Inc.\"\\n</stdout>\\n</result>\\n',\n concreteType: 'org.sagebionetworks.repo.model.agent.AgentChatResponse',\n}\n\n/**\n * Builds a full `AsynchronousJobStatus` for the chat async job, for tests/stories that poll the\n * job status endpoint directly (e.g. to exercise the PROCESSING state). `jobId` is required since\n * it must match the id returned by the mocked start-chat-async endpoint; other fields default to\n * placeholder values and can be overridden.\n */\nexport function mockChatJobStatus(\n overrides: Partial<\n AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>\n > & {\n jobId: string\n },\n): AsynchronousJobStatus<AgentChatRequest, AgentChatResponse> {\n return {\n jobState: 'COMPLETE',\n jobCanceling: false,\n requestBody: mockAgentChatRequest,\n etag: '00000000-0000-0000-0000-000000000000',\n startedByUserId: 0,\n startedOn: '',\n changedOn: '',\n runtimeMS: 100,\n ...overrides,\n }\n}\n\nexport const mockSessionHistoryResponse: SessionHistoryResponse = {\n sessionId: mockChatSessionId,\n page: [\n {\n usersRequestText: 'What is the weather like today?',\n usersRequestTimestamp: '2024-09-06T14:30:00Z',\n agentResponseText: 'The weather is sunny with a high of 75°F.',\n agentResponseTimestamp: '2024-09-06T14:30:10Z',\n },\n {\n usersRequestText: 'Can you tell me a joke?',\n usersRequestTimestamp: '2024-09-06T14:32:00Z',\n agentResponseText:\n 'Why don’t scientists trust atoms? Because they make up everything!',\n agentResponseTimestamp: '2024-09-06T14:32:05Z',\n },\n ],\n nextPageToken: undefined,\n}\n\nexport const mockTraceEventsResponse1: TraceEventsResponse = {\n jobId: ':id',\n page: [\n {\n timestamp: 1695567600, // Example timestamp (in seconds)\n message: 'Executing search on Synapse',\n },\n ],\n}\n\nexport const mockTraceEventsResponse2: TraceEventsResponse = {\n jobId: ':id',\n page: [\n {\n timestamp: 1695567700, // Example timestamp (in seconds)\n message: 'Gathering entity metadata',\n },\n ],\n}\nexport const mockTraceEventsResponse3: TraceEventsResponse = {\n jobId: ':id',\n page: [\n {\n timestamp: 1695567800, // Example timestamp (in seconds)\n message:\n '<thinking>The metadata shows that the entity with ID syn9602623 is a Synapse project named \"SearchIntegrationTest.Projecte475c6e8-414a-4842-b876-bf8232ce05d0\". Its description contains the search term \"e7b33c3a-2392-4ce7-a357-efa4612e4a41\". The metadata ...',\n },\n ],\n}\n\n// no new trace events events\nexport const mockEmptyTraceEventsResponse: TraceEventsResponse = {\n jobId: ':id',\n page: [],\n}\n\nlet mockChatAttachmentIdCounter = 0\n\nexport function mockChatAttachment(\n overrides: Partial<ChatAttachment> = {},\n): ChatAttachment {\n mockChatAttachmentIdCounter++\n return {\n fileHandleId: `${9999990 + mockChatAttachmentIdCounter}`,\n fileName: `file-${mockChatAttachmentIdCounter}.txt`,\n contentType: 'text/plain',\n sizeBytes: 1024,\n ...overrides,\n }\n}\n"],"mappings":";;AAgBA,IAAa,IAAoB,eACpB,IAA2D;CACtE,kBAAkB,EAAiB;CACnC,qBAAqB;AACvB,GACa,IAAiC;CAC5C,WAAW;CACX,kBAAkB,EAAiB;CACnC,WAAW;CACX,qBAAqB;AACvB,GACa,IAAkC;CAC7C,WAAW;CACX,kBAAkB,EAAiB;CACnC,WAAW;CACX,qBAAqB;AACvB,GACa,IAAyD,EACpE,eAAe,YACjB,GAEa,IAA2D;CACtE,MAAM,CAAC,GAAkB,CAAiB;CAC1C,eAAe;AACjB,GAEa,IAAyC;CACpD,WAAW;CACX,UAAU;CACV,aAAa;CACb,cAAc;AAChB,GAEa,IAA2C;CACtD,WAAW;CACX,cACE;CACF,cAAc;AAChB;AAQA,SAAgB,EACd,GAK4D;CAC5D,OAAO;EACL,UAAU;EACV,cAAc;EACd,aAAa;EACb,MAAM;EACN,iBAAiB;EACjB,WAAW;EACX,WAAW;EACX,WAAW;EACX,GAAG;CACL;AACF;AAEA,IAAa,IAAqD;CAChE,WAAW;CACX,MAAM,CACJ;EACE,kBAAkB;EAClB,uBAAuB;EACvB,mBAAmB;EACnB,wBAAwB;CAC1B,GACA;EACE,kBAAkB;EAClB,uBAAuB;EACvB,mBACE;EACF,wBAAwB;CAC1B,CACF;CACA,eAAe,KAAA;AACjB,GAEa,IAAgD;CAC3D,OAAO;CACP,MAAM,CACJ;EACE,WAAW;EACX,SAAS;CACX,CACF;AACF,GAEa,IAAgD;CAC3D,OAAO;CACP,MAAM,CACJ;EACE,WAAW;EACX,SAAS;CACX,CACF;AACF,GACa,IAAgD;CAC3D,OAAO;CACP,MAAM,CACJ;EACE,WAAW;EACX,SACE;CACJ,CACF;AACF,GAGa,IAAoD;CAC/D,OAAO;CACP,MAAM,CAAC;AACT,GAEI,IAA8B;AAElC,SAAgB,EACd,IAAqC,CAAC,GACtB;CAEhB,OADA,KACO;EACL,cAAc,GAAG,UAAU;EAC3B,UAAU,QAAQ,EAA4B;EAC9C,aAAa;EACb,WAAW;EACX,GAAG;CACL;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const getChatbotHandlers: (backendOrigin?: string) =>
|
|
1
|
+
export declare const getChatbotHandlers: (backendOrigin?: string) => import("msw").HttpHandler[];
|
|
2
2
|
//# sourceMappingURL=chatHandlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatHandlers.d.ts","sourceRoot":"","sources":["../../../../src/mocks/msw/handlers/chatHandlers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chatHandlers.d.ts","sourceRoot":"","sources":["../../../../src/mocks/msw/handlers/chatHandlers.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,kBAAkB,GAC7B,sBAAiE,gCAwClE,CAAA"}
|
|
@@ -5,14 +5,28 @@ import { generateAsyncJobHandlers as c } from "./asyncJobHandlers.js";
|
|
|
5
5
|
import { mockAgentChatResponse as l, mockAgentSession as u, mockChatSessionId as d, mockEmptyTraceEventsResponse as f, mockListAgentSessionsResponse as p, mockSessionHistoryResponse as m, mockTraceEventsResponse1 as h, mockTraceEventsResponse2 as g, mockTraceEventsResponse3 as _ } from "../../chat/mockChat.js";
|
|
6
6
|
import { HttpResponse as v, http as y } from "msw";
|
|
7
7
|
//#region src/mocks/msw/handlers/chatHandlers.ts
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
function b(e) {
|
|
9
|
+
return !e.attachments || e.attachments.length === 0 ? l : {
|
|
10
|
+
...l,
|
|
11
|
+
attachmentStatuses: e.attachments.map((e, t) => t === 0 ? {
|
|
12
|
+
fileHandleId: e.fileHandleId,
|
|
13
|
+
status: "FAILED",
|
|
14
|
+
failureCode: "UNSUPPORTED_TYPE",
|
|
15
|
+
failureMessage: "This file type is not supported."
|
|
16
|
+
} : {
|
|
17
|
+
fileHandleId: e.fileHandleId,
|
|
18
|
+
status: "STAGED"
|
|
19
|
+
})
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
var x = 0, S = (l = t(e.REPO_ENDPOINT)) => [
|
|
23
|
+
y.post(`${l}${r}`, () => v.json(u, { status: 201 })),
|
|
24
|
+
y.post(`${l}${o}`, () => v.json(p, { status: 201 })),
|
|
25
|
+
y.post(`${l}${i(d)}`, () => v.json(m, { status: 201 })),
|
|
26
|
+
...c(s, (e) => a(e), b, l),
|
|
27
|
+
y.post(`${l}${n(":id")}`, () => (x++, x == 1 ? v.json(h, { status: 201 }) : x == 5 ? v.json(g, { status: 201 }) : x == 8 ? v.json(_, { status: 201 }) : v.json(f, { status: 201 })))
|
|
14
28
|
];
|
|
15
29
|
//#endregion
|
|
16
|
-
export {
|
|
30
|
+
export { S as getChatbotHandlers };
|
|
17
31
|
|
|
18
32
|
//# sourceMappingURL=chatHandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatHandlers.js","names":[],"sources":["../../../../src/mocks/msw/handlers/chatHandlers.ts"],"sourcesContent":["import {\n mockAgentChatResponse,\n mockAgentSession,\n mockChatSessionId,\n mockEmptyTraceEventsResponse,\n mockListAgentSessionsResponse,\n mockSessionHistoryResponse,\n mockTraceEventsResponse1,\n mockTraceEventsResponse2,\n mockTraceEventsResponse3,\n} from '@/mocks/chat/mockChat'\nimport {\n AGENT_CHAT_TRACE,\n AGENT_SESSION,\n AGENT_SESSION_HISTORY,\n GET_CHAT_ASYNC,\n LIST_AGENT_SESSIONS,\n START_CHAT_ASYNC,\n} from '@/utils/APIConstants'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport {\n AgentChatRequest,\n AgentChatResponse,\n} from '@sage-bionetworks/synapse-
|
|
1
|
+
{"version":3,"file":"chatHandlers.js","names":[],"sources":["../../../../src/mocks/msw/handlers/chatHandlers.ts"],"sourcesContent":["import {\n mockAgentChatResponse,\n mockAgentSession,\n mockChatSessionId,\n mockEmptyTraceEventsResponse,\n mockListAgentSessionsResponse,\n mockSessionHistoryResponse,\n mockTraceEventsResponse1,\n mockTraceEventsResponse2,\n mockTraceEventsResponse3,\n} from '@/mocks/chat/mockChat'\nimport {\n AGENT_CHAT_TRACE,\n AGENT_SESSION,\n AGENT_SESSION_HISTORY,\n GET_CHAT_ASYNC,\n LIST_AGENT_SESSIONS,\n START_CHAT_ASYNC,\n} from '@/utils/APIConstants'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport {\n AgentChatRequest,\n AgentChatResponse,\n} from '@sage-bionetworks/synapse-client'\nimport { http, HttpResponse } from 'msw'\nimport { generateAsyncJobHandlers } from './asyncJobHandlers'\n\nfunction buildMockChatResponse(request: AgentChatRequest): AgentChatResponse {\n if (!request.attachments || request.attachments.length === 0) {\n return mockAgentChatResponse\n }\n return {\n ...mockAgentChatResponse,\n attachmentStatuses: request.attachments.map((attachment, index) =>\n index === 0\n ? {\n fileHandleId: attachment.fileHandleId,\n status: 'FAILED',\n failureCode: 'UNSUPPORTED_TYPE',\n failureMessage: 'This file type is not supported.',\n }\n : {\n fileHandleId: attachment.fileHandleId,\n status: 'STAGED',\n },\n ),\n }\n}\n\nlet traceCallCount = 0\nexport const getChatbotHandlers = (\n backendOrigin = getEndpoint(BackendDestinationEnum.REPO_ENDPOINT),\n) => [\n http.post(`${backendOrigin}${AGENT_SESSION}`, () => {\n return HttpResponse.json(mockAgentSession, { status: 201 })\n }),\n\n //list chat sessions\n http.post(`${backendOrigin}${LIST_AGENT_SESSIONS}`, () => {\n // const request: ListAgentSessionsRequest = await request.json()\n return HttpResponse.json(mockListAgentSessionsResponse, { status: 201 })\n }),\n\n //session history\n http.post(\n `${backendOrigin}${AGENT_SESSION_HISTORY(mockChatSessionId)}`,\n () => {\n return HttpResponse.json(mockSessionHistoryResponse, { status: 201 })\n },\n ),\n //Async job to send chat message to the agent\n ...generateAsyncJobHandlers<AgentChatRequest, AgentChatResponse>(\n START_CHAT_ASYNC,\n tokenParam => GET_CHAT_ASYNC(tokenParam),\n buildMockChatResponse,\n backendOrigin,\n ),\n\n //trace events\n http.post(`${backendOrigin}${AGENT_CHAT_TRACE(':id')}`, () => {\n //mock showing progress (increasing number of items)\n traceCallCount++\n if (traceCallCount == 1) {\n return HttpResponse.json(mockTraceEventsResponse1, { status: 201 })\n } else if (traceCallCount == 5) {\n return HttpResponse.json(mockTraceEventsResponse2, { status: 201 })\n } else if (traceCallCount == 8) {\n return HttpResponse.json(mockTraceEventsResponse3, { status: 201 })\n } else\n return HttpResponse.json(mockEmptyTraceEventsResponse, { status: 201 })\n }),\n]\n"],"mappings":";;;;;;;AA2BA,SAAS,EAAsB,GAA8C;CAI3E,OAHI,CAAC,EAAQ,eAAe,EAAQ,YAAY,WAAW,IAClD,IAEF;EACL,GAAG;EACH,oBAAoB,EAAQ,YAAY,KAAK,GAAY,MACvD,MAAU,IACN;GACE,cAAc,EAAW;GACzB,QAAQ;GACR,aAAa;GACb,gBAAgB;EAClB,IACA;GACE,cAAc,EAAW;GACzB,QAAQ;EACV,CACN;CACF;AACF;AAEA,IAAI,IAAiB,GACR,KACX,IAAgB,EAAY,EAAuB,aAAa,MAC7D;CACH,EAAK,KAAK,GAAG,IAAgB,WACpB,EAAa,KAAK,GAAkB,EAAE,QAAQ,IAAI,CAAC,CAC3D;CAGD,EAAK,KAAK,GAAG,IAAgB,WAEpB,EAAa,KAAK,GAA+B,EAAE,QAAQ,IAAI,CAAC,CACxE;CAGD,EAAK,KACH,GAAG,IAAgB,EAAsB,CAAiB,WAEjD,EAAa,KAAK,GAA4B,EAAE,QAAQ,IAAI,CAAC,CAExE;CAEA,GAAG,EACD,IACA,MAAc,EAAe,CAAU,GACvC,GACA,CACF;CAGA,EAAK,KAAK,GAAG,IAAgB,EAAiB,KAAK,YAEjD,KACI,KAAkB,IACb,EAAa,KAAK,GAA0B,EAAE,QAAQ,IAAI,CAAC,IACzD,KAAkB,IACpB,EAAa,KAAK,GAA0B,EAAE,QAAQ,IAAI,CAAC,IACzD,KAAkB,IACpB,EAAa,KAAK,GAA0B,EAAE,QAAQ,IAAI,CAAC,IAE3D,EAAa,KAAK,GAA8B,EAAE,QAAQ,IAAI,CAAC,EACzE;AACH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BackendDestinationEnum } from '@/utils/functions/getEndpoint';
|
|
2
|
-
import { DoiAssociation, EntityType, OAuthValidationRequestProviderEnum, ViewEntityType, SearchIndexQuery, SearchQueryResults } from '@sage-bionetworks/synapse-client';
|
|
2
|
+
import { DoiAssociation, EntityType, OAuthValidationRequestProviderEnum, ViewEntityType, SearchIndexQuery, SearchQueryResults, AgentChatRequest, AgentChatResponse } from '@sage-bionetworks/synapse-client';
|
|
3
3
|
import { TwoFactorAuthErrorResponse } from '@sage-bionetworks/synapse-client/generated/models/TwoFactorAuthErrorResponse';
|
|
4
|
-
import { ACCESS_TYPE, AccessApproval, AccessApprovalSearchRequest, AccessApprovalSearchResponse, AccessCodeResponse, AccessControlList, AccessRequirement, AccessRequirementSearchRequest, AccessRequirementSearchResponse, AccessRequirementStatus, AccessToken, AccessTokenGenerationRequest, AccessTokenGenerationResponse, AccessTokenRecordList, AccountSetupInfo, ActionRequiredCount, ActionRequiredList, ActionRequiredRequest, ActionRequiredResponse, Activity, ACTSubmissionStatus, AddBatchOfFilesToDownloadListResponse, AddToDownloadListRequest, AddToDownloadListResponse,
|
|
4
|
+
import { ACCESS_TYPE, AccessApproval, AccessApprovalSearchRequest, AccessApprovalSearchResponse, AccessCodeResponse, AccessControlList, AccessRequirement, AccessRequirementSearchRequest, AccessRequirementSearchResponse, AccessRequirementStatus, AccessToken, AccessTokenGenerationRequest, AccessTokenGenerationResponse, AccessTokenRecordList, AccountSetupInfo, ActionRequiredCount, ActionRequiredList, ActionRequiredRequest, ActionRequiredResponse, Activity, ACTSubmissionStatus, AddBatchOfFilesToDownloadListResponse, AddToDownloadListRequest, AddToDownloadListResponse, AgentSession, AliasCheckRequest, AliasCheckResponse, AsynchronousJobStatus, AuthenticatedOn, AvailableFilesRequest, AvailableFilesResponse, BatchFileRequest, BatchFileResult, BulkFileDownloadRequest, BulkFileDownloadResponse, Challenge, ChallengePagedResults, ChallengeTeam, ChallengeTeamPagedResults, ChangePasswordWithCurrentPassword, ChangePasswordWithToken, ChangePasswordWithTwoFactorAuthToken, ColumnModel, CreateAccessApprovalRequest, CreateAgentSessionRequest, CreateChallengeTeamRequest, CreateDiscussionReply, CreateDiscussionThread, CreateMembershipInvitationRequest, CreateMembershipRequestRequest, CreateSubmissionRequest, CreateTeamRequest, Direction, DiscussionFilter, DiscussionReplyBundle, DiscussionReplyOrder, DiscussionSearchRequest, DiscussionSearchResponse, DiscussionThreadBundle, DiscussionThreadOrder, DockerCommit, Doi, DownloadFromTableRequest, DownloadFromTableResult, DownloadList, DownloadListPackageResponse, DownloadOrder, DownloadPFBRequest, DownloadPFBResult, EmailValidationSignedToken, Entity, EntityBundle, EntityBundleRequest, EntityChildrenRequest, EntityChildrenResponse, EntityHeader, EntityId, EntityJson, EntityLookupRequest, EntityPath, Evaluation, EvaluationRound, EvaluationRoundListRequest, EvaluationRoundListResponse, EvaluationSubmission as EvaluationSubmission, FavoriteSortBy, FavoriteSortDirection, FileEntity, FileHandle, FileHandleAssociateType, FileHandleAssociation, FileHandleResults, FileResult, FilesStatisticsResponse, FileUploadComplete, FormData, FormGroup, Forum, GetEvaluationParameters, GetProjectsParameters, HasAccessResponse, InviteeVerificationSignedToken, JoinTeamSignedToken, JsonSchemaObjectBinding, ListAgentSessionsRequest, ListAgentSessionsResponse, ListRequest, ListResponse, ListWrapper, LoginResponse, ManagedACTAccessRequirementStatus, MembershipInvitation, MembershipInvtnSignedToken, MembershipRequest, MessageToUser, MessageURL, MultipartUploadRequest, MultipartUploadStatus, NewUser, NotificationEmail, OAuthClient, OAuthClientIdAndSecret, OAuthClientList, OAuthClientPublic, OAuthClientVerificationPrecheckResult, OAuthConsentGrantedResponse, ObjectType, OIDCAuthorizationRequest, OIDCAuthorizationRequestDescription, PaginatedIds, PaginatedResults, PassingRecord, PrincipalAliasRequest, PrincipalAliasResponse, ProjectFilesStatisticsRequest, ProjectFilesStatisticsResponse, ProjectHeaderList, ProjectStorageUsage, QueryBundleRequest, QueryResultBundle, QueryTableResults, Quiz, QuizResponse, ReferenceList, RemoveBatchOfFilesFromDownloadListRequest, RemoveBatchOfFilesFromDownloadListResponse, Renewal, Request, ResearchProject, ResponseMessage, RestrictableObjectDescriptor, RestrictionInformationBatchRequest, RestrictionInformationBatchResponse, RestrictionInformationRequest, RestrictionInformationResponse, SearchQuery, SearchResults, SessionHistoryRequest, SessionHistoryResponse, SortBy, Submission as DataAccessSubmission, SubmissionInfoPage, SubmissionInfoPageRequest, SubmissionSearchRequest, SubmissionSearchResponse, SubmissionStateChangeRequest, SubscriberPagedResults, Subscription, SubscriptionPagedResults, SubscriptionQuery, SubscriptionRequest, SynapseVersion, TableUpdateTransactionRequest, Team, TeamMember, TeamMembershipStatus, TeamSubmissionEligibility, TermsOfServiceInfo, TermsOfServiceStatus, Topic, TotpSecret, TotpSecretActivationRequest, TraceEventsRequest, TraceEventsResponse, TrashedEntity, TwoFactorAuthDisableRequest, TwoFactorAuthLoginRequest, TwoFactorAuthRecoveryCodes, TwoFactorAuthResetRequest, TwoFactorAuthStatus, TYPE_FILTER, UpdateAgentSessionRequest, UpdateDiscussionReply, UpdateThreadMessageRequest, UpdateThreadTitleRequest, UploadDestination, UserBundle, UserEntityPermissions, UserEvaluationPermissions, UserGroupHeaderResponse, UserGroupHeaderResponsePage, UserProfile, ValidateDefiningSqlResponse, ValidationResults, VerificationState, VerificationSubmission, VersionInfo, ViewColumnModelRequest, WikiPage, WikiPageKey } from '@sage-bionetworks/synapse-types';
|
|
5
5
|
import { JSONSchema7 } from 'json-schema';
|
|
6
6
|
import { SetOptional } from 'type-fest';
|
|
7
7
|
import { OAuth2State } from '@/utils/types/OAuth2State';
|