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.
-
- {{ submission.currentVersion.instanceName ?? submission.instanceId }}
-
+
@@ -99,9 +98,8 @@ except according to the terms contained in the LICENSE file.
-
- {{ submission.currentVersion.instanceName ?? submission.instanceId }}
-
+
@@ -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 @@
+
+
+
+ {{ submission.instanceNameOrId }}
+ {{ $t('resource.submission') }}
+
+
+ - {{ $t('resource.form') }}
+ - {{ form.nameOrId }}
+
+ - {{ $t('header.submitterName') }}
+ - {{ submission.__system.submitterName }}
+
+ - {{ $t('header.submissionDate') }}
+
+
+ - {{ $t('common.lastUpdate') }}
+
+
+
+
+
+
+
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 @@
+
+
+
+ {{ submission.currentVersion.instanceName ?? submission.instanceId }}
+
+
+
+
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."