diff --git a/src/components/entity/feed-entry.vue b/src/components/entity/feed-entry.vue index 1dc8dac81..0b12cb064 100644 --- a/src/components/entity/feed-entry.vue +++ b/src/components/entity/feed-entry.vue @@ -18,9 +18,8 @@ except according to the terms contained in the LICENSE file. @@ -99,9 +98,8 @@ except according to the terms contained in the LICENSE file. @@ -147,9 +145,9 @@ import ActorLink from '../actor-link.vue'; import DatasetLink from '../dataset/link.vue'; import EntityDiff from './diff.vue'; import FeedEntry from '../feed-entry.vue'; +import SubmissionLink from '../submission/link.vue'; import useReviewState from '../../composables/review-state'; -import useRoutes from '../../composables/routes'; import { useRequestData } from '../../request-data'; defineOptions({ @@ -181,12 +179,6 @@ const wrapTitle = computed(() => { }); // submission.create, entity.update.version -const { submissionPath } = useRoutes(); -const sourceSubmissionPath = computed(() => submissionPath( - projectId, - props.submission.xmlFormId, - props.submission.instanceId -)); const { t } = useI18n(); const deletedSubmission = (key) => t(key, { id: props.submission.instanceId }); diff --git a/src/components/hover-card/submission.vue b/src/components/hover-card/submission.vue new file mode 100644 index 000000000..b7998f7da --- /dev/null +++ b/src/components/hover-card/submission.vue @@ -0,0 +1,52 @@ + + + + diff --git a/src/components/hover-cards.vue b/src/components/hover-cards.vue index 6f0720d3d..fd38cee2c 100644 --- a/src/components/hover-cards.vue +++ b/src/components/hover-cards.vue @@ -27,6 +27,7 @@ import { inject, nextTick, ref, shallowRef, watch } from 'vue'; import HoverCardDataset from './hover-card/dataset.vue'; import HoverCardEntity from './hover-card/entity.vue'; import HoverCardForm from './hover-card/form.vue'; +import HoverCardSubmission from './hover-card/submission.vue'; import Popover from './popover.vue'; import useHoverCardResources from '../request-data/hover-card'; @@ -47,6 +48,17 @@ const types = { form: { url: apiPaths.form(projectId, xmlFormId), extended: true } }) }, + submission: { + component: HoverCardSubmission, + requests: ({ projectId, xmlFormId, instanceId }) => ({ + form: { url: apiPaths.form(projectId, xmlFormId) }, + submission: { + url: apiPaths.odataSubmission(projectId, xmlFormId, instanceId, { + $select: '__id,__system,meta' + }) + } + }) + }, dataset: { component: HoverCardDataset, requests: ({ projectId, name }) => ({ diff --git a/src/components/submission/link.vue b/src/components/submission/link.vue new file mode 100644 index 000000000..e512c34c8 --- /dev/null +++ b/src/components/submission/link.vue @@ -0,0 +1,53 @@ + + + + diff --git a/src/locales/en.json5 b/src/locales/en.json5 index 50e6b5113..8fa025c67 100644 --- a/src/locales/en.json5 +++ b/src/locales/en.json5 @@ -317,6 +317,7 @@ "webUser": "Web User", "webUsers": "Web Users", "session": "Session", + "submission": "Submission", "submissions": "Submissions", "projectRoles": "Project Roles", "formPreview": "Form Preview" diff --git a/src/request-data/hover-card.js b/src/request-data/hover-card.js index 51628220f..d5f7b9b87 100644 --- a/src/request-data/hover-card.js +++ b/src/request-data/hover-card.js @@ -15,15 +15,18 @@ except according to the terms contained in the LICENSE file. // e.g., `form`. For simplicity, we want the hover card resources to be // independent of resources used in other components. +import useSubmission from './submission'; import { transformForm } from './util'; import { useRequestData } from './index'; export default () => { const { createResource } = useRequestData(); + const { submission } = useSubmission(); return { form: createResource('form', () => ({ transformResponse: ({ data }) => transformForm(data) })), + submission, dataset: createResource('dataset'), entity: createResource('entity') }; diff --git a/test/components/entity/feed-entry.spec.js b/test/components/entity/feed-entry.spec.js index bf4e26ca8..b3f639187 100644 --- a/test/components/entity/feed-entry.spec.js +++ b/test/components/entity/feed-entry.spec.js @@ -6,6 +6,7 @@ import DatasetLink from '../../../src/components/dataset/link.vue'; import EntityDiff from '../../../src/components/entity/diff.vue'; import EntityFeedEntry from '../../../src/components/entity/feed-entry.vue'; import FeedEntry from '../../../src/components/feed-entry.vue'; +import SubmissionLink from '../../../src/components/submission/link.vue'; import useEntity from '../../../src/request-data/entity'; import useEntityVersions from '../../../src/request-data/entity-versions'; @@ -99,10 +100,17 @@ describe('EntityFeedEntry', () => { }); it('links to the submission', () => { - const component = mountComponent({ props: createSubmission() }); + const component = mountComponent({ + props: createSubmission({ + meta: { instanceName: 'Some Name' } + }) + }); const title = component.get('.feed-entry-title'); - const { to } = title.getComponent(RouterLinkStub).props(); - to.should.equal('/projects/1/forms/f/submissions/s'); + const link = title.getComponent(SubmissionLink).props(); + link.projectId.should.equal('1'); + link.xmlFormId.should.equal('f'); + link.submission.instanceId.should.equal('s'); + link.submission.currentVersion.instanceName.should.equal('Some Name'); }); it('links to the submitter', () => { @@ -135,9 +143,7 @@ describe('EntityFeedEntry', () => { const component = mountComponent({ props: createSubmission({ deleted: true }) }); - const links = component.findAllComponents(RouterLinkStub); - links.length.should.equal(1); - links[0].props().to.should.startWith('/users/'); + component.findComponent(SubmissionLink).exists().should.be.false; }); }); }); @@ -382,10 +388,17 @@ describe('EntityFeedEntry', () => { }); it('links to the submission', () => { - const component = mountComponent({ props: updateEntityFromSubmission() }); + const component = mountComponent({ + props: updateEntityFromSubmission({ + meta: { instanceName: 'Some Name' } + }) + }); const title = component.get('.feed-entry-title'); - const { to } = title.getComponent(RouterLinkStub).props(); - to.should.equal('/projects/1/forms/f/submissions/s'); + const link = title.getComponent(SubmissionLink).props(); + link.projectId.should.equal('1'); + link.xmlFormId.should.equal('f'); + link.submission.instanceId.should.equal('s'); + link.submission.currentVersion.instanceName.should.equal('Some Name'); }); it('shows the correct text with deleted submission instance id', () => { @@ -399,8 +412,7 @@ describe('EntityFeedEntry', () => { const component = mountComponent({ props: updateEntityFromSubmission({ deleted: true }) }); - const links = component.findAllComponents(RouterLinkStub); - links.length.should.equal(1); // only link is anchor link on version tag + component.findComponent(SubmissionLink).exists().should.be.false; }); }); }); diff --git a/transifex/strings_en.json b/transifex/strings_en.json index 30a81d295..b1bda80ad 100644 --- a/transifex/strings_en.json +++ b/transifex/strings_en.json @@ -697,6 +697,10 @@ "string": "Session", "developer_comment": "This text appears on its own and is not part of a longer sentence. It may be shown as a title, for example, at the top of the page." }, + "submission": { + "string": "Submission", + "developer_comment": "This text appears on its own and is not part of a longer sentence. It may be shown as a title, for example, at the top of the page." + }, "submissions": { "string": "Submissions", "developer_comment": "This text appears on its own and is not part of a longer sentence. It may be shown as a title, for example, at the top of the page."