Skip to content

Commit a2907de

Browse files
committed
Add pagination for submissions
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
1 parent a953202 commit a2907de

3 files changed

Lines changed: 174 additions & 5 deletions

File tree

src/components/Results/Answer.vue

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,27 @@
1616
:key="answer.id"
1717
class="answer__text"
1818
dir="auto">
19-
<a :href="answer.url" target="_blank">
20-
<IconFile :size="20" class="answer__text-icon" />
21-
{{ answer.text }}
19+
<a :href="answer.url" target="_blank"
20+
><IconFile :size="20" class="answer__text-icon" />
21+
<NcHighlight :text="answer.text" :search="highlight" />
2222
</a>
2323
</p>
2424
</template>
2525
<p v-else class="answer__text" dir="auto">
26-
{{ answerText }}
26+
<NcHighlight :text="answerText" :search="highlight" />
2727
</p>
2828
</div>
2929
</template>
3030

3131
<script>
3232
import IconFile from 'vue-material-design-icons/File.vue'
33+
import NcHighlight from '@nextcloud/vue/components/NcHighlight'
3334
3435
export default {
3536
name: 'Answer',
3637
components: {
3738
IconFile,
39+
NcHighlight,
3840
},
3941
4042
props: {
@@ -52,6 +54,11 @@ export default {
5254
type: String,
5355
required: true,
5456
},
57+
highlight: {
58+
type: String,
59+
required: false,
60+
default: '',
61+
},
5562
},
5663
}
5764
</script>

src/components/Results/Submission.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
:key="question.id"
2828
:answer-text="question.squashedAnswers"
2929
:answers="question.answers"
30+
:highlight="highlight"
3031
:question-text="question.text" />
3132
</div>
3233
</template>
@@ -63,6 +64,9 @@ export default {
6364
type: Boolean,
6465
required: true,
6566
},
67+
highlight: {
68+
type: String,
69+
},
6670
},
6771
6872
computed: {

src/views/Results.vue

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,79 @@
201201

202202
<!-- Responses view for individual responses -->
203203
<section v-else>
204+
<div class="pagination-block" :class="{ 'large-width': isMobile }">
205+
<div class="pagination-items">
206+
<NcButton
207+
type="tertiary"
208+
:disabled="totalPages === 1 || pageNumber <= 1"
209+
:aria-label="t('tables', 'Go to first page')"
210+
@click="pageNumber = 1">
211+
<template #icon>
212+
<PageFirstIcon :size="20" />
213+
</template>
214+
</NcButton>
215+
<NcButton
216+
type="tertiary"
217+
:disabled="totalPages === 1 || pageNumber <= 1"
218+
:aria-label="t('tables', 'Go to previous page')"
219+
@click="pageNumber--">
220+
<template #icon>
221+
<IconChevronLeft :size="20" />
222+
</template>
223+
</NcButton>
224+
<div class="page-number">
225+
<NcSelect
226+
v-model="pageNumber"
227+
:options="allPageNumbersArray"
228+
:aria-label-combobox="t('tables', 'Page number')">
229+
<template #selected-option-container="{ option }">
230+
<span class="selected-page">
231+
{{ option.label }} of {{ totalPages }}
232+
</span>
233+
</template>
234+
</NcSelect>
235+
</div>
236+
<NcButton
237+
type="tertiary"
238+
:disabled="totalPages === 1 || pageNumber >= totalPages"
239+
:aria-label="t('tables', 'Go to next page')"
240+
@click="pageNumber++">
241+
<template #icon>
242+
<IconChevronRight :size="20" />
243+
</template>
244+
</NcButton>
245+
<NcButton
246+
type="tertiary"
247+
:disabled="totalPages === 1 || pageNumber >= totalPages"
248+
:aria-label="t('tables', 'Go to last page')"
249+
@click="pageNumber = totalPages">
250+
<template #icon>
251+
<PageLastIcon :size="20" />
252+
</template>
253+
</NcButton>
254+
255+
<div>
256+
<NcTextField
257+
v-model="submissionSearch"
258+
:label="t('forms', 'Search')"
259+
trailing-button-icon="close"
260+
:show-trailing-button="submissionSearch.length > 0"
261+
@trailing-button-click="submissionSearch = ''">
262+
<template #icon>
263+
<IconMagnify :size="20" />
264+
</template>
265+
</NcTextField>
266+
</div>
267+
</div>
268+
</div>
269+
204270
<Submission
205-
v-for="submission in submissions"
271+
v-for="submission in currentPageSubmissions"
206272
:key="submission.id"
207273
:submission="submission"
208274
:questions="questions"
209275
:can-delete-submission="canDeleteSubmissions"
276+
:highlight="submissionSearch"
210277
@delete="deleteSubmission(submission.id)" />
211278
</section>
212279
</template>
@@ -239,6 +306,7 @@ import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
239306
import NcAppContent from '@nextcloud/vue/components/NcAppContent'
240307
import NcButton from '@nextcloud/vue/components/NcButton'
241308
import NcDialog from '@nextcloud/vue/components/NcDialog'
309+
import NcTextField from '@nextcloud/vue/components/NcTextField'
242310
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
243311
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
244312
import axios from '@nextcloud/axios'
@@ -263,6 +331,11 @@ import IconRefresh from 'vue-material-design-icons/Refresh.vue'
263331
import IconShareVariant from 'vue-material-design-icons/ShareVariant.vue'
264332
import IconTable from 'vue-material-design-icons/Table.vue'
265333
import IconTableSvg from '@mdi/svg/svg/table.svg?raw'
334+
import NcSelect from '@nextcloud/vue/components/NcSelect'
335+
import PageLastIcon from 'vue-material-design-icons/PageLast.vue'
336+
import PageFirstIcon from 'vue-material-design-icons/PageFirst.vue'
337+
import IconChevronRight from 'vue-material-design-icons/ChevronRight.vue'
338+
import IconMagnify from 'vue-material-design-icons/Magnify.vue'
266339
267340
import { FormState } from '../models/FormStates.ts'
268341
import ResultsSummary from '../components/Results/ResultsSummary.vue'
@@ -316,6 +389,12 @@ export default {
316389
NcAppContent,
317390
NcButton,
318391
NcDialog,
392+
NcTextField,
393+
NcSelect,
394+
PageLastIcon,
395+
PageFirstIcon,
396+
IconChevronRight,
397+
IconMagnify,
319398
NcEmptyContent,
320399
NcLoadingIcon,
321400
PillMenu,
@@ -348,6 +427,10 @@ export default {
348427
picker: null,
349428
showConfirmDeleteDialog: false,
350429
430+
submissionSearch: '',
431+
pageNumber: 1,
432+
rowsPerPage: 50,
433+
351434
linkedFileNotAvailableButtons: [
352435
{
353436
label: t('forms', 'Unlink spreadsheet'),
@@ -428,6 +511,34 @@ export default {
428511
}
429512
return this.canEditForm && this.form.fileId && !this.form.filePath
430513
},
514+
515+
allPageNumbersArray() {
516+
return Array.from(
517+
{ length: this.totalPages },
518+
(value, index) => 1 + index,
519+
)
520+
},
521+
currentPageSubmissions() {
522+
return this.getFilteredSubmissions.slice(
523+
(this.pageNumber - 1) * this.rowsPerPage,
524+
(this.pageNumber - 1) * this.rowsPerPage + this.rowsPerPage,
525+
)
526+
},
527+
totalPages() {
528+
return Math.ceil(this.getFilteredSubmissions.length / this.rowsPerPage)
529+
},
530+
getFilteredSubmissions() {
531+
if (!this.submissionSearch) {
532+
return this.submissions
533+
}
534+
535+
const submissionFilter = (submission) =>
536+
submission.answers.filter((answer) =>
537+
answer.text.includes(this.submissionSearch),
538+
).length > 0
539+
540+
return this.submissions.filter(submissionFilter)
541+
},
431542
},
432543
433544
watch: {
@@ -836,4 +947,51 @@ export default {
836947
}
837948
}
838949
}
950+
951+
:deep(.vs__clear) {
952+
display: none;
953+
}
954+
955+
:deep(.v-select) {
956+
min-width: 95px !important;
957+
.vs__dropdown-toggle {
958+
background: none;
959+
}
960+
}
961+
962+
.selected-page {
963+
padding-left: 5px;
964+
965+
display: inline-flex;
966+
align-items: center;
967+
}
968+
969+
.page-number {
970+
padding-inline: 5px;
971+
}
972+
973+
.large-width {
974+
width: 100vw !important;
975+
left: 0 !important;
976+
}
977+
978+
.pagination-items {
979+
background-color: var(--color-main-background);
980+
border-radius: var(--border-radius-large);
981+
pointer-events: all;
982+
983+
display: flex;
984+
align-items: center;
985+
}
986+
987+
.pagination-block {
988+
box-shadow: var(--box-shadow);
989+
filter: drop-shadow(0 1px 6px var(--color-box-shadow));
990+
width: 100%;
991+
pointer-events: none;
992+
993+
display: flex;
994+
justify-content: center;
995+
align-items: center;
996+
}
839997
</style>

0 commit comments

Comments
 (0)