Skip to content

Commit 8a8f747

Browse files
committed
Add spinner to the delete/undelete buttons in the Submission list
1 parent 5b56745 commit 8a8f747

File tree

4 files changed

+47
-7
lines changed

4 files changed

+47
-7
lines changed

src/components/submission/list.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ except according to the terms contained in the LICENSE file.
3636
<submission-table v-show="odata.dataExists && odata.value.length !== 0 && odata.removedCount < odata.value.length"
3737
ref="table" :project-id="projectId" :xml-form-id="xmlFormId"
3838
:draft="draft" :fields="selectedFields"
39-
:deleted="deleted"
39+
:deleted="deleted" :awaiting-deleted-responses="awaitingDeletedResponses"
4040
@review="reviewModal.show({ submission: $event })"
4141
@delete="showDelete"
4242
@restore="showRestore"/>
@@ -218,6 +218,8 @@ export default {
218218
confirmDelete: true,
219219
// state that indicates whether we need to show restore confirmation dialog
220220
confirmRestore: true,
221+
222+
awaitingDeletedResponses: new Set()
221223
};
222224
},
223225
computed: {
@@ -388,6 +390,7 @@ export default {
388390
const [{ __id: instanceId }, confirm] = event;
389391
390392
if (this.deleteModal.state) this.deleteModal.awaitingResponse = true;
393+
this.awaitingDeletedResponses.add(instanceId);
391394
392395
this.request({
393396
method: 'DELETE',
@@ -396,6 +399,7 @@ export default {
396399
.then(() => {
397400
this.deleteModal.hide();
398401
this.deletedSubmissionCount.value += 1;
402+
this.awaitingDeletedResponses.delete(instanceId);
399403
400404
this.alert.success(this.$t('alert.deleted'));
401405
if (confirm != null) this.confirmDelete = confirm;
@@ -419,12 +423,14 @@ export default {
419423
})
420424
.catch(() => {
421425
this.deleteModal.awaitingResponse = false;
426+
this.awaitingDeletedResponses.delete(instanceId);
422427
});
423428
},
424429
requestRestore(e) {
425430
const [{ __id: instanceId }, confirm] = e;
426431
427432
if (this.restoreModal.state) this.restoreModal.awaitingResponse = true;
433+
this.awaitingDeletedResponses.add(instanceId);
428434
429435
this.request({
430436
method: 'POST',
@@ -433,6 +439,7 @@ export default {
433439
.then(() => {
434440
this.restoreModal.hide();
435441
this.deletedSubmissionCount.value -= 1;
442+
this.awaitingDeletedResponses.delete(instanceId);
436443
437444
this.alert.success(this.$t('alert.restored'));
438445
if (confirm != null) this.confirmRestore = confirm;
@@ -456,6 +463,7 @@ export default {
456463
})
457464
.catch(() => {
458465
this.restoreModal.awaitingResponse = false;
466+
this.awaitingDeletedResponses.delete(instanceId);
459467
});
460468
}
461469
}

src/components/submission/metadata-row.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ except according to the terms contained in the LICENSE file.
3131
<button v-if="verbs.has('submission.delete')" type="button"
3232
class="delete-button btn btn-default"
3333
:aria-label="$t('action.delete')" v-tooltip.aria-label>
34-
<span class="icon-trash"></span>
34+
<span class="icon-trash"></span><spinner :state="awaitingResponse"/>
3535
</button>
3636
<template v-if="verbs.has('submission.update')">
3737
<button type="button" class="review-button btn btn-default"
@@ -66,8 +66,9 @@ except according to the terms contained in the LICENSE file.
6666
<template v-if="verbs.has('submission.delete')">
6767
<button type="button"
6868
class="restore-button btn btn-default"
69+
:aria-disabled="awaitingResponse"
6970
:aria-label="$t('action.restore')" v-tooltip.aria-label>
70-
<span class="icon-recycle"></span>
71+
<span class="icon-recycle"></span><spinner :state="awaitingResponse"/>
7172
</button>
7273
</template>
7374
</div>
@@ -81,10 +82,11 @@ import DateTime from '../date-time.vue';
8182
import useReviewState from '../../composables/review-state';
8283
import useRoutes from '../../composables/routes';
8384
import { apiPaths } from '../../util/request';
85+
import Spinner from '../spinner.vue';
8486
8587
export default {
8688
name: 'SubmissionMetadataRow',
87-
components: { DateTime },
89+
components: { DateTime, Spinner },
8890
props: {
8991
projectId: {
9092
type: String,
@@ -110,7 +112,8 @@ export default {
110112
verbs: {
111113
type: Set,
112114
required: true
113-
}
115+
},
116+
awaitingResponse: Boolean
114117
},
115118
setup() {
116119
const { reviewStateIcon } = useReviewState();

src/components/submission/table.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ except according to the terms contained in the LICENSE file.
3131

3232
<template #data-frozen="{ data, index }">
3333
<submission-metadata-row :project-id="projectId" :xml-form-id="xmlFormId"
34-
:draft="draft" :submission="data" :deleted="deleted"
34+
:draft="draft" :submission="data" :deleted="deleted" :awaiting-response="awaitingDeletedResponses?.has(data.__id)"
3535
:row-number="odata.originalCount - index" :verbs="project.verbs"/>
3636
</template>
3737
<template #data-scrolling="{ data }">
@@ -69,7 +69,8 @@ defineProps({
6969
default: false
7070
},
7171
draft: Boolean,
72-
fields: Array
72+
fields: Array,
73+
awaitingDeletedResponses: Object
7374
});
7475
const emit = defineEmits(['review', 'delete', 'restore']);
7576

test/components/submission/list.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,20 @@ describe('SubmissionList', () => {
845845
})
846846
.respondWithProblem());
847847

848+
it('shows spinner', () =>
849+
delAndCheck()
850+
.request(async (component) => {
851+
await component.get('.submission-metadata-row .delete-button').trigger('click');
852+
component.getComponent(SubmissionDelete).props().state.should.be.false;
853+
})
854+
.beforeAnyResponse(component => {
855+
component.find('.delete-button .spinner').classes().should.contain('active');
856+
})
857+
.respondWithSuccess()
858+
.afterResponse(component => {
859+
component.find('.delete-button .spinner').classes().should.not.contain('active');
860+
}));
861+
848862
it('shows the correct alert', () =>
849863
delAndCheck()
850864
.request(component =>
@@ -1069,6 +1083,20 @@ describe('SubmissionList', () => {
10691083
})
10701084
.respondWithProblem());
10711085

1086+
it('shows spinner', () =>
1087+
restoreAndCheck()
1088+
.request(async (component) => {
1089+
await component.get('.submission-metadata-row .restore-button').trigger('click');
1090+
component.getComponent(SubmissionDelete).props().state.should.be.false;
1091+
})
1092+
.beforeAnyResponse(component => {
1093+
component.find('.restore-button .spinner').classes().should.contain('active');
1094+
})
1095+
.respondWithSuccess()
1096+
.afterResponse(component => {
1097+
component.find('.restore-button .spinner').classes().should.not.contain('active');
1098+
}));
1099+
10721100
it('shows the correct alert', () =>
10731101
restoreAndCheck()
10741102
.request(component =>

0 commit comments

Comments
 (0)