Skip to content

Commit

Permalink
feat(generic-table): add pagination to generic-table
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasRichel committed Mar 24, 2021
1 parent 697edca commit 6d39685
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 73 deletions.
55 changes: 35 additions & 20 deletions src/components/generic/generic-table/GenericTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,48 @@
font-size: 0.9rem;
background-color: $color-white;

table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
&__container {
table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;

tbody tr:nth-child(odd) {
background-color: $color-tertiary-lightest;
}
tbody tr:nth-child(odd) {
background-color: $color-tertiary-lightest;
}

th,
td {
min-height: $spacing-unit * 2;
height: 50px;
padding: 0 $spacing-unit;
th,
td {
min-height: $spacing-unit * 2;
min-height: 50px;
max-height: 50px;
height: 50px;
padding: 0 $spacing-unit;

&.cell-checkbox:deep() {
width: 42px;
&.cell-checkbox:deep() {
width: 42px;
}
}

th {
font-weight: bold;
color: $color-primary;
}
}

th {
font-weight: bold;
color: $color-primary;
td {
color: $color-tertiary-darkest;
}
}
}

&__page-nav {
display: flex;
justify-content: flex-end;
align-items: center;
padding: $spacing-unit/2 $spacing-unit;

td {
color: $color-tertiary-darkest;
&__text {
margin: 0 $spacing-unit;
}
}
}
173 changes: 122 additions & 51 deletions src/components/generic/generic-table/GenericTable.vue
Original file line number Diff line number Diff line change
@@ -1,63 +1,108 @@
<template>
<div class="generic-table">
<table>
<thead>
<tr key="head-row-0">
<th class="cell-checkbox" v-if="selectable">
<BIMDataCheckbox
:disabled="rows.length === 0"
:modelValue="rows.length > 0 && selection.size === rows.length"
@update:modelValue="toggleFullSelection"
/>
</th>
<template v-for="(column, j) of columns" :key="`head-row-0-col-${j}`">
<th
:style="{
width: column.width || 'auto',
textAlign: column.align || 'left'
}"
>
{{ column.id ? column.label || column.id : column }}
</th>
</template>
</tr>
</thead>
<tbody>
<template v-for="(row, i) of rows" :key="`body-row-${i}`">
<tr v-if="row">
<td class="cell-checkbox" v-if="selectable">
<div
class="generic-table__container"
:style="{ minHeight: paginated ? `${(perPage + 1) * 50}px` : undefined }"
>
<table>
<thead>
<tr key="head-row-0">
<th class="cell-checkbox" v-if="selectable">
<BIMDataCheckbox
:modelValue="selection.has(i)"
@update:modelValue="toggleSelection(i)"
:disabled="rows.length === 0"
:modelValue="rows.length > 0 && selection.size === rows.length"
@update:modelValue="toggleFullSelection"
/>
</td>
<td
</th>
<template
v-for="(column, j) of columns"
:key="`body-row-${i}-col-${j}`"
:style="{
width: column.width || 'auto',
textAlign: column.align || 'left'
}"
:key="`head-row-0-col-${j}`"
>
<slot :name="`cell-${column.id}`" :row="row">
{{ row[column.id] || row[j] || "" }}
</slot>
</td>
<th
:style="{
width: column.width || 'auto',
textAlign: column.align || 'left'
}"
>
{{ column.id ? column.label || column.id : column }}
</th>
</template>
</tr>
</template>
</tbody>
</table>
</thead>
<tbody>
<template v-for="(row, i) of rows" :key="`body-row-${i}`">
<tr v-if="row" v-show="displayedRows.includes(i)">
<td class="cell-checkbox" v-if="selectable">
<BIMDataCheckbox
:modelValue="selection.has(i)"
@update:modelValue="toggleSelection(i)"
/>
</td>
<td
v-for="(column, j) of columns"
:key="`body-row-${i}-col-${j}`"
:style="{
width: column.width || 'auto',
textAlign: column.align || 'left'
}"
>
<slot :name="`cell-${column.id}`" :row="row">
{{ row[column.id] || row[j] || "" }}
</slot>
</td>
</tr>
</template>
</tbody>
</table>
</div>
<div
class="generic-table__page-nav"
v-if="paginated"
:style="{ visibility: rows.length > perPage ? 'visible' : 'hidden' }"
>
<BIMDataButton
ghost
rounded
icon
:disabled="pageStartIndex === 1"
@click="pageIndex--"
>
<BIMDataIcon name="chevron" size="s" :rotate="180" />
</BIMDataButton>
<span class="generic-table__page-nav__text">
{{
$t("GenericTable.pagination", {
start: pageStartIndex,
end: pageEndIndex,
total: rows.length
})
}}
</span>
<BIMDataButton
ghost
rounded
icon
:disabled="pageEndIndex === rows.length"
@click="pageIndex++"
>
<BIMDataIcon name="chevron" size="s" />
</BIMDataButton>
</div>
</div>
</template>

<script>
import { ref, watch, watchEffect } from "vue";
import { ref, watch } from "vue";
// Components
import BIMDataButton from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js";
import BIMDataCheckbox from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataCheckbox.js";
import BIMDataIcon from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataIcon.js";
export default {
components: {
BIMDataCheckbox
BIMDataButton,
BIMDataCheckbox,
BIMDataIcon
},
props: {
columns: {
Expand All @@ -68,10 +113,6 @@ export default {
type: Array,
required: true
},
rowKey: {
type: String,
default: "id"
},
selectable: {
type: Boolean,
default: false
Expand Down Expand Up @@ -134,9 +175,35 @@ export default {
}
});
watchEffect(() => {
buildSelectionRefs(props.rows, false);
});
const displayedRows = ref([]);
const pageIndex = ref(0);
const pageStartIndex = ref(1);
const pageEndIndex = ref(props.perPage);
watch(
() => props.rows,
() => {
selection.value = new Map();
buildSelectionRefs(props.rows, false);
},
{ immediate: true }
);
watch(
[() => props.rows, () => props.paginated, () => props.perPage, pageIndex],
() => {
const rowIndexes = props.rows.map((_, i) => i);
if (props.paginated) {
const start = props.perPage * pageIndex.value;
const end = start + props.perPage;
displayedRows.value = rowIndexes.slice(start, end);
pageStartIndex.value = start + 1;
pageEndIndex.value = Math.min(end, props.rows.length);
} else {
displayedRows.value = rowIndexes;
}
},
{ immediate: true }
);
const toggleSelection = i => {
selectionRefs[i].value = !selectionRefs[i].value;
Expand All @@ -148,6 +215,10 @@ export default {
return {
// Refrences
displayedRows,
pageEndIndex,
pageIndex,
pageStartIndex,
selection,
// Methods
toggleFullSelection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
}

&__table-container {
max-height: calc(100% - 92px);
max-height: calc(100% - 80px);
margin-top: $spacing-unit * 2;
padding: $spacing-unit 0;
overflow-x: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
<GenericTable
:columns="columns"
:rows="rows"
:paginated="true"
:perPage="6"
:selectable="true"
@selection-change="() => {}"
>
<template #cell-version>?</template>
<template #cell-creator="{ row: { creator } }">
{{ creator ? `${creator.firstname} ${creator.lastname[0]}.` : "" }}
{{ creator ? `${creator.firstname} ${creator.lastname[0]}.` : "?" }}
</template>
<template #cell-lastupdate="{ row: { updatedAt } }">
{{
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,8 @@ export default {
buttonCheck: "Check",
buttonSubmit: "Validate",
buttonCancel: "Change"
},
GenericTable: {
pagination: "{start} - {end} of {total}"
}
};
3 changes: 3 additions & 0 deletions src/i18n/lang/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,8 @@ export default {
buttonCheck: "Vérifier",
buttonSubmit: "Valider",
buttonCancel: "Changer"
},
GenericTable: {
pagination: "{start} - {end} sur {total}"
}
};

0 comments on commit 6d39685

Please sign in to comment.