Skip to content

Commit

Permalink
Merge branch 'feature/115-step-4-no-pagination' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
polosson committed Mar 23, 2021
2 parents 6ec5dd7 + 815b14b commit 9ea514a
Show file tree
Hide file tree
Showing 15 changed files with 523 additions and 164 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Ce projet adhère au principe du [Semantic Versioning](https://semver.org/spec/v
- Dans le listing du matériel, ajoute un lien vers la gestion des caractéristiques spéciales.
- Ajoute la possibilité de modifier le nom des caractéristiques spéciales (#107).
- Améliore la disposition des filtres dans les pages de listing du matériel (#114).
- Supprime la pagination côté serveur pour le matériel à l'étape 4 de l'édition d'événement, et améliore l'UX (#115).

## 0.11.0 (2021-01-14)

Expand Down
9 changes: 8 additions & 1 deletion client/src/components/EventMaterials/EventMaterials.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,18 @@
margin-bottom: .35rem;
border-bottom: 1px dashed $list-left-border-color;

&__quantity-first {
flex: 0 0 35px;
color: $text-light-color;
padding-right: $content-padding-large-horizontal;
text-align: right;
}

&__quantity {
flex: 0 0 3rem;
margin: 0 .8rem 0 .8rem;

.fas {
.fa-times {
margin-right: .2rem;
color: $text-light-color;
font-size: .8rem;
Expand Down
3 changes: 3 additions & 0 deletions client/src/components/EventMaterials/EventMaterials.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
:key="material.id"
class="EventMaterials__item"
>
<div class="EventMaterials__item__quantity-first">
{{ material.pivot.quantity }}
</div>
<div class="EventMaterials__item__name">
{{ material.name }}
</div>
Expand Down
11 changes: 9 additions & 2 deletions client/src/components/MaterialsFilters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,21 @@ export default {
},

setQueryFilters() {
const query = {};
const {
park,
category,
subCategory,
tags,
} = this.filters;

const filters = {
park: park || null,
category: category || null,
subCategory: subCategory || null,
tags: tags.map((tag) => tag.label),
};

const query = {};
if (park) {
query.park = park;
}
Expand All @@ -110,7 +117,7 @@ export default {
}

this.$router.push({ path: this.baseRoute, query });
this.$emit('change');
this.$emit('change', filters);
},
},
};
2 changes: 2 additions & 0 deletions client/src/locale/en/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export default {
'saved': "Event saved.",
'not-saved': "Event has not saved modifications",
'display-only-selected-materials': "Display event's selected materials only?",
'display-all-materials-to-add-some': "Display all materials to add some",
'display-only-event-materials': "Display only event's materials",
'event-not-confirmed-help': "The event is not confirmed yet. It is subject to change at any time.",
'event-confirmed-help': "The event is confirmed: its information should no longer change.",
'event-missing-materials': "Missing materials",
Expand Down
2 changes: 2 additions & 0 deletions client/src/locale/fr/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export default {
'saved': "Événement sauvegardé.",
'not-saved': "L'événement comporte des modifications non sauvegardées",
'display-only-selected-materials': "Afficher uniquement le matériel de l'événement\u00a0?",
'display-all-materials-to-add-some': "Afficher tout le matériel pour en ajouter",
'display-only-event-materials': "Afficher uniquement le matériel de l'événement",
'event-not-confirmed-help': "L'événement n'est pas encore confirmé, il est susceptible de changer à tout moment.",
'event-confirmed-help': "L'événement est confirmé\u00a0: Ses informations ne devraient plus changer.",
'event-missing-materials': "Matériel manquant",
Expand Down
5 changes: 5 additions & 0 deletions client/src/pages/Event/Step4/MaterialsList/MaterialsList.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,9 @@
padding: 6px 8px;
}
}

&__add-more {
text-align: center;
margin: $content-padding-small-vertical 0 50px;
}
}
33 changes: 28 additions & 5 deletions client/src/pages/Event/Step4/MaterialsList/MaterialsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
<header class="MaterialsList__header">
<MaterialsFilter
:baseRoute="`/events/${eventId}`"
@change="refreshTableAndPagination"
@change="setFilters"
/>
<div class="MaterialsList__header__extra-filters">
<div class="MaterialsList__header__extra-filters__filter">
<div v-if="hasMaterial" class="MaterialsList__header__extra-filters__filter">
{{ $t('page-events.display-only-selected-materials') }}
<SwitchToggle
:value="showSelectedOnly"
Expand All @@ -21,11 +21,12 @@
<i class="fas fa-circle-notch fa-spin fa-2x" />
{{ $t('help-loading') }}
</div>
<v-server-table
<v-client-table
ref="DataTable"
name="materialsListTable"
:data="materials"
:columns="columns"
:options="options"
:options="tableOptions"
>
<div slot="qty" slot-scope="material">
<span :key="`qty-${material.row.id}-${renderId}`">
Expand Down Expand Up @@ -70,13 +71,35 @@
<button
:key="`clear-${material.row.id}-${renderId}`"
v-show="getQuantity(material.row.id) > 0"
type="button"
role="button"
class="warning"
@click="setQuantity(material.row.id, 0)"
>
<i class="fas fa-backspace" />
</button>
</div>
</v-server-table>
</v-client-table>
<div v-if="!isLoading && hasMaterial" class="MaterialsList__add-more">
<button
v-if="showSelectedOnly"
type="button"
role="button"
@click="handleToggleSelectedOnly(false)"
>
<i class="fas fa-plus" />
{{ $t('page-events.display-all-materials-to-add-some') }}
</button>
<button
v-if="!showSelectedOnly"
type="button"
role="button"
@click="handleToggleSelectedOnly(true)"
>
<i class="fas fa-eye" />
{{ $t('page-events.display-only-event-materials') }}
</button>
</div>
</div>
</div>
</template>
Expand Down
6 changes: 5 additions & 1 deletion client/src/pages/Event/Step4/MaterialsList/MaterialsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default new Vuex.Store({
setQuantity(state, { id, quantity }) {
state.quantities[id] = quantity;

if (!state.quantities[id]) {
if (state.quantities[id] === 0) {
delete state.quantities[id];
}
},
Expand All @@ -34,6 +34,10 @@ export default new Vuex.Store({
return;
}
state.quantities[id] -= 1;

if (state.quantities[id] === 0) {
delete state.quantities[id];
}
},
},
getters: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<template>
<div class="MaterialsListQuantity">
<button
type="button"
role="button"
:class="{ info: quantity > 0 }"
:disabled="quantity === 0"
@click="$emit('decrement')"
Expand All @@ -14,6 +16,8 @@
@focus="$event.target.select()"
>
<button
type="button"
role="button"
:class="{ info: quantity < maxQuantity }"
@click="$emit('increment')"
>
Expand Down
136 changes: 87 additions & 49 deletions client/src/pages/Event/Step4/MaterialsList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import SwitchToggle from '@/components/SwitchToggle/SwitchToggle.vue';
import Quantity from './Quantity/Quantity.vue';
import MaterialsStore from './MaterialsStore';

const noPaginationLimit = 100000;

export default {
name: 'MaterialsList',
components: { MaterialsFilter, SwitchToggle, Quantity },
Expand All @@ -30,18 +32,42 @@ export default {
return true;
});

const hasMaterial = this.initialList.length > 0;

const initFilters = {
onlySelected: hasMaterial,
};

if (this.$route.query.park) {
initFilters.park = this.$route.query.park;
}

if (this.$route.query.category) {
initFilters.category = this.$route.query.category;
}

if (this.$route.query.subCategory) {
initFilters.subCategory = this.$route.query.subCategory;
}

if (this.$route.query.tags) {
initFilters.tags = JSON.parse(this.$route.query.tags);
}

return {
error: null,
renderId: 1,
showSelectedOnly: this.initialList.length > 0,
hasMaterial,
showSelectedOnly: hasMaterial,
isLoading: true,
columns,
options: {
materials: [],
tableOptions: {
columnsDropdown: false,
preserveState: false,
orderBy: { column: 'reference', ascending: true },
initialPage: this.$route.query.page || 1,
sortable: ['reference', 'name'],
initialPage: 1,
perPage: hasMaterial ? noPaginationLimit : Config.defaultPaginationLimit,
columnsClasses: {
qty: 'MaterialsList__qty',
reference: 'MaterialsList__ref',
Expand All @@ -52,64 +78,69 @@ export default {
amount: 'MaterialsList__amount',
actions: 'MaterialsList__actions',
},
requestFunction: (pagination) => {
this.isLoading = true;
const filters = this.getFilters();
const params = { whileEvent: this.eventId, ...pagination, ...filters };
return this.$http
.get('materials', { params })
.then((response) => {
this.isLoading = false;
return response;
})
.catch(this.showError);
},
initFilters,
customFilters: [
{
name: 'park',
callback: (row, parkId) => row.park_id === parkId,
},
{
name: 'category',
callback: (row, categoryId) => row.category_id === categoryId,
},
{
name: 'subCategory',
callback: (row, subCategoryId) => row.sub_category_id === subCategoryId,
},
{
name: 'tags',
callback: (row, tags) => (
tags.length === 0 || row.tags.some((tag) => tags.includes(tag.name))
),
},
{
name: 'onlySelected',
callback: (row, isOnlySelected) => (
!isOnlySelected || this.getQuantity(row.id) > 0
),
},
],
},
};
},
created() {
MaterialsStore.commit('init', this.initialList);
},
mounted() {
this.fetchMaterials();
},
methods: {
getFilters() {
const params = {};
if (this.$route.query.park) {
params.park = this.$route.query.park;
async fetchMaterials() {
try {
this.isLoading = true;
this.$refs.DataTable.setLoadingState(true);
const { data } = await this.$http.get(`materials/while-event/${this.eventId}`);
this.materials = data;
} catch (error) {
this.showError(error);
} finally {
this.isLoading = false;
this.$refs.DataTable.setLoadingState(false);
}

if (this.$route.query.category) {
params.category = this.$route.query.category;
}

if (this.$route.query.subCategory) {
params.subCategory = this.$route.query.subCategory;
}

if (this.$route.query.tags) {
params.tags = JSON.parse(this.$route.query.tags);
}

if (this.showSelectedOnly) {
params.onlySelectedInEvent = this.eventId;
}

return params;
},

handleToggleSelectedOnly(newValue) {
this.$refs.DataTable.setCustomFilters({ onlySelected: newValue });
this.$refs.DataTable.setLimit(
newValue ? noPaginationLimit : Config.defaultPaginationLimit,
);
this.showSelectedOnly = newValue;
this.isLoading = true;
this.$refs.DataTable.refresh();
},

refreshTable() {
this.$refs.DataTable.getData();
},

refreshTableAndPagination() {
this.error = false;
this.isLoading = true;
this.$refs.DataTable.refresh();
setFilters(filters) {
const onlySelected = this.showSelectedOnly;
const newFilters = { ...filters, onlySelected };
this.$refs.DataTable.setCustomFilters(newFilters);
},

getQuantity(materialId) {
Expand Down Expand Up @@ -141,7 +172,14 @@ export default {
// - when quantities are changing.
this.renderId += 1;

const materials = Object.keys(MaterialsStore.state.quantities).map(
const materialIds = Object.keys(MaterialsStore.state.quantities);

this.hasMaterial = materialIds.length > 0;
if (!this.hasMaterial) {
this.handleToggleSelectedOnly(false);
}

const materials = materialIds.map(
(id) => ({ id: parseInt(id, 10), quantity: MaterialsStore.getters.getQuantity(id) }),
);
this.$emit('change', materials);
Expand Down
Loading

0 comments on commit 9ea514a

Please sign in to comment.