Skip to content

Commit

Permalink
MMT-3494: As a user, I can edit a published record (#1113)
Browse files Browse the repository at this point in the history
* MMT-3494: Added support for Editing a publish record

* MMT-3494: Added test cases for edit button

* MMT-3494: Moved ingestMutation in a hook

* MMT-3494: Removed one comment

* MMT-3494: Added loading when the user clicks publish btn

* MMT-3494: Addressed PR comments
  • Loading branch information
dmistry1 authored Feb 1, 2024
1 parent d6d8045 commit c5087ad
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 11 deletions.
1 change: 1 addition & 0 deletions static/src/js/components/DraftPreview/DraftPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ const DraftPreview = () => {
// Handle the user selecting publish draft
const handlePublish = () => {
// Calls publish mutation hook
setLoading(true)
publishMutation(derivedConceptType, nativeId)
}

Expand Down
49 changes: 38 additions & 11 deletions static/src/js/components/PublishPreview/PublishPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import ErrorBanner from '../ErrorBanner/ErrorBanner'
import LoadingBanner from '../LoadingBanner/LoadingBanner'
import MetadataPreview from '../MetadataPreview/MetadataPreview'
import Page from '../Page/Page'
import useAppContext from '../../hooks/useAppContext'
import useIngestDraftMutation from '../../hooks/useIngestDraftMutation'

/**
* Renders a PublishPreview component
Expand All @@ -35,20 +37,24 @@ const PublishPreview = () => {
revisionId
} = useParams()

const { user } = useAppContext()
const { providerId } = user
const navigate = useNavigate()

const [previewMetadata, setPreviewMetadata] = useState()
const [showDeleteModal, setShowDeleteModal] = useState(false)
const [ummMetadata, setUmmMetadata] = useState()
const [error, setError] = useState()
const [retries, setRetries] = useState(0)
const [loading, setLoading] = useState(true)
const [nativeId, setNativeId] = useState()
const [providerId, setProviderId] = useState()

const { addNotification } = useNotificationsContext()

const derivedConceptType = getConceptTypeByConceptId(conceptId)

const ingestMutation = useIngestDraftMutation()

const [deleteMutation] = useMutation(deleteMutationTypes[derivedConceptType])

// Calls CMR-Graphql to get the record
Expand All @@ -59,23 +65,23 @@ const PublishPreview = () => {
}
},
onCompleted: (getData) => {
const fetchedMetadata = getData[toLowerKebabCase(derivedConceptType)]
const fetchedPreviewMetadata = getData[toLowerKebabCase(derivedConceptType)]
const {
revisionId: savedRevisionId,
nativeId: savedNativeId,
providerId: savedProviderId
} = fetchedMetadata || {}
revisionId: fetchedRevisionId,
nativeId: fetchedNativeId,
ummMetadata: fetchedUmmMetadata
} = fetchedPreviewMetadata || {}

if (!fetchedMetadata || (savedRevisionId && revisionId !== savedRevisionId)) {
if (!fetchedPreviewMetadata || (fetchedRevisionId && revisionId !== fetchedRevisionId)) {
// If fetchedMetadata or the correct revision id does't exist in CMR, then call getMetadata again.
setRetries(retries + 1)
setPreviewMetadata()
} else {
// The correct version of the metadata has been fetched
setPreviewMetadata(fetchedMetadata)
setNativeId(savedNativeId)
setProviderId(savedProviderId)
setPreviewMetadata(fetchedPreviewMetadata)
setNativeId(fetchedNativeId)
setLoading(false)
setUmmMetadata(fetchedUmmMetadata)
}
},
onError: (getDraftError) => {
Expand All @@ -100,6 +106,12 @@ const PublishPreview = () => {
}
}, [previewMetadata, retries])

// Calls ingestDraft mutation with the same nativeId and ummMetadata
// TODO: Need to check if the record trying to edit is in the same provider
const handleEdit = () => {
ingestMutation(derivedConceptType, ummMetadata, nativeId, providerId)
}

// Handles the user selecting delete from the delete model
const handleDelete = () => {
deleteMutation({
Expand Down Expand Up @@ -158,6 +170,22 @@ const PublishPreview = () => {
<Page>
<Row>
<Col className="mb-5" md={12}>
<Button
className="btn btn-link"
type="button"
variant="link"
onClick={
() => {
handleEdit()
}
}
>
Edit
{' '}
{derivedConceptType}
{' '}
Record
</Button>
<Button
type="button"
variant="outline-danger"
Expand All @@ -173,7 +201,6 @@ const PublishPreview = () => {
{' '}
Record
</Button>

<CustomModal
message="Are you sure you want to delete this record?"
openModal={showDeleteModal}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import errorLogger from '../../../utils/errorLogger'
import ErrorBanner from '../../ErrorBanner/ErrorBanner'
import { GET_TOOL } from '../../../operations/queries/getTool'
import { DELETE_TOOL } from '../../../operations/mutations/deleteTool'
import { INGEST_DRAFT } from '../../../operations/mutations/ingestDraft'

jest.mock('../../MetadataPreview/MetadataPreview')
jest.mock('../../ErrorBanner/ErrorBanner')
Expand Down Expand Up @@ -76,6 +77,7 @@ const mock = {
}
],
type: 'Web User Interface',
ummMetadata: {},
url: {
urlContentType: 'DistributionURL',
type: 'DOWNLOAD SOFTWARE',
Expand Down Expand Up @@ -194,6 +196,7 @@ describe('PublishPreview', () => {
}
],
type: 'Web User Interface',
ummMetadata: {},
url: {
subtype: 'MOBILE APP',
type: 'DOWNLOAD SOFTWARE',
Expand Down Expand Up @@ -368,4 +371,76 @@ describe('PublishPreview', () => {
expect(navigateSpy).toHaveBeenCalledTimes(0)
})
})

describe('when clicking on Edit Tool Record button', () => {
test('calls the ingestDraftMutation and navigates to /drafts/tool/conceptId page', async () => {
const navigateSpy = jest.fn()
jest.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)

const { user } = setup({
additionalMocks: [{
request: {
query: INGEST_DRAFT,
variables: {
conceptType: 'Tool',
metadata: {},
nativeId: 'MMT_PUBLISH_8b8a1965-67a5-415c-ae4c-8ecbafd84131',
providerId: 'MMT_2',
ummVersion: '1.2.0'
}
},
result: {
data: {
ingestDraft: {
conceptId: 'TD1000000-MMT',
revisionId: '3'
}
}
}
}]
})

await waitForResponse()

const editButton = screen.getByRole('button', { name: 'Edit Tool Record' })
await user.click(editButton)

await waitForResponse()

expect(navigateSpy).toHaveBeenCalledTimes(1)
expect(navigateSpy).toHaveBeenCalledWith('/drafts/tools/TD1000000-MMT')
})

test('when ingest mutation returns an error', async () => {
const navigateSpy = jest.fn()
jest.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)

const { user } = setup({
additionalMocks: [{
request: {
query: INGEST_DRAFT,
variables: {
conceptType: 'Tool',
nativeId: 'MMT_PUBLISH_8b8a1965-67a5-415c-ae4c-8ecbafd84131',
metadata: {},
providerId: 'MMT_2',
ummVersion: '1.2.0'
}
},
error: new Error('An error occurred')
}]
})

await waitForResponse()

const editButton = screen.getByRole('button', { name: 'Edit Tool Record' })
await user.click(editButton)

await waitForResponse()

expect(navigateSpy).toHaveBeenCalledTimes(0)
expect(errorLogger).toHaveBeenCalledTimes(1)
expect(errorLogger).toHaveBeenCalledWith(new Error('An error occurred'), 'PublishPreview ingestDraftMutation Query')
})
})
})
48 changes: 48 additions & 0 deletions static/src/js/hooks/useIngestDraftMutation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useMutation } from '@apollo/client'
import pluralize from 'pluralize'
import { useNavigate } from 'react-router'
import { INGEST_DRAFT } from '../operations/mutations/ingestDraft'
import getUmmVersion from '../utils/getUmmVersion'
import errorLogger from '../utils/errorLogger'
import useNotificationsContext from './useNotificationsContext'

const useIngestDraftMutation = () => {
const [ingestDraftMutation] = useMutation(INGEST_DRAFT)

const navigate = useNavigate()

const { addNotification } = useNotificationsContext()

const ingestMutation = (conceptType, metadata, nativeId, providerId) => {
ingestDraftMutation({
variables: {
conceptType,
metadata,
nativeId,
providerId,
ummVersion: getUmmVersion(conceptType)
},
onCompleted: (getDraftData) => {
const { ingestDraft } = getDraftData
const { conceptId } = ingestDraft
navigate(`/drafts/${pluralize(conceptType).toLowerCase()}/${conceptId}`)
addNotification({
message: 'Draft created successfully',
variant: 'success'
})
},
onError: (getMutationError) => {
// Send the error to the errorLogger
errorLogger(getMutationError, 'PublishPreview ingestDraftMutation Query')
addNotification({
message: 'Error creating draft',
variant: 'danger'
})
}
})
}

return ingestMutation
}

export default useIngestDraftMutation
1 change: 1 addition & 0 deletions static/src/js/operations/queries/getCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const GET_COLLECTION = gql`
url
}
}
ummMetadata
useConstraints
variables {
count
Expand Down
1 change: 1 addition & 0 deletions static/src/js/operations/queries/getService.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const GET_SERVICE = gql`
supportedReformattings
serviceQuality
type
ummMetadata
url
useConstraints
version
Expand Down
1 change: 1 addition & 0 deletions static/src/js/operations/queries/getTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const GET_TOOL = gql`
supportedSoftwareLanguages
toolKeywords
type
ummMetadata
url
useConstraints
version
Expand Down
1 change: 1 addition & 0 deletions static/src/js/operations/queries/getVariable.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const GET_VARIABLE = gql`
scienceKeywords
sets
standardName
ummMetadata
units
validRanges
variableSubType
Expand Down

0 comments on commit c5087ad

Please sign in to comment.