diff --git a/assets/css/_bootstrap.scss b/assets/css/_bootstrap.scss index 826ad6053365e179488a1fa9cecf47c828ba1d6d..9e8b2e040d3cf8ecd4ac239aea5987b959c39302 100644 --- a/assets/css/_bootstrap.scss +++ b/assets/css/_bootstrap.scss @@ -12,6 +12,8 @@ @import "~bootstrap/scss/mixins"; @import "~bootstrap/scss/utilities"; +@import "./override-mixins"; + // Layout @import "~bootstrap/scss/root"; @import "~bootstrap/scss/reboot"; @@ -33,7 +35,7 @@ // @import "~bootstrap/scss/forms/validation"; // Components -@import "~bootstrap/scss/buttons"; +@import "./custom_buttons"; @import "~bootstrap/scss/transitions"; // @import "~bootstrap/scss/dropdown"; @import "~bootstrap/scss/button-group"; @@ -42,7 +44,7 @@ @import "~bootstrap/scss/card"; // @import "~bootstrap/scss/accordion"; @import "~bootstrap/scss/breadcrumb"; -@import "~bootstrap/scss/pagination"; +// @import "~bootstrap/scss/pagination"; @import "~bootstrap/scss/badge"; @import "~bootstrap/scss/alert"; // @import "~bootstrap/scss/progress"; diff --git a/assets/css/_custom_buttons.scss b/assets/css/_custom_buttons.scss new file mode 100644 index 0000000000000000000000000000000000000000..6b14c934f1d31b5df4ca039bde13410d1b0c7144 --- /dev/null +++ b/assets/css/_custom_buttons.scss @@ -0,0 +1,122 @@ +// +// Base styles +// + +.btn { + display: inline-block; + font-family: $btn-font-family; + font-weight: $btn-font-weight; + line-height: $btn-line-height; + color: $body-color; + text-align: center; + text-decoration: if($link-decoration == none, null, none); + white-space: $btn-white-space; + vertical-align: middle; + cursor: if($enable-button-pointers, pointer, null); + user-select: none; + background-color: transparent; + border: $btn-border-width solid transparent; + @include button-size( + $btn-padding-y, + $btn-padding-x, + $btn-font-size, + $btn-border-radius + ); + @include transition($btn-transition); + + &:hover { + text-decoration: if($link-hover-decoration == underline, none, null); + } + + .btn-check:focus + &, + &:focus { + outline: 0; + box-shadow: $btn-focus-box-shadow; + } + + .btn-check:checked + &, + .btn-check:active + &, + &:active, + &.active { + @include box-shadow($btn-active-box-shadow); + + &:focus { + @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); + } + } + + &:disabled, + &.disabled, + fieldset:disabled & { + pointer-events: none; + opacity: $btn-disabled-opacity; + @include box-shadow(none); + } +} + +// +// Alternate buttons +// + +// scss-docs-start btn-variant-loops +@each $color, $value in $theme-colors { + .btn-#{$color} { + @include button-variant($value, $value); + } +} + +@each $color, $value in $theme-colors { + .btn-outline-#{$color} { + @include button-outline-variant($value); + } +} +// scss-docs-end btn-variant-loops + +// +// Link buttons +// + +// Make a button look and behave like a link +.btn-link { + font-weight: $font-weight-normal; + color: $btn-link-color; + text-decoration: $link-decoration; + + &:hover { + color: $btn-link-hover-color; + text-decoration: $link-hover-decoration; + } + + &:focus { + text-decoration: $link-hover-decoration; + } + + &:disabled, + &.disabled { + color: $btn-link-disabled-color; + } + + // No need for an active state here +} + +// +// Button Sizes +// + +.btn-lg { + @include button-size( + $btn-padding-y-lg, + $btn-padding-x-lg, + $btn-font-size-lg, + $btn-border-radius-lg + ); +} + +.btn-sm { + @include button-size( + $btn-padding-y-sm, + $btn-padding-x-sm, + $btn-font-size-sm, + $btn-border-radius-sm + ); +} diff --git a/assets/css/_override-mixins.scss b/assets/css/_override-mixins.scss new file mode 100644 index 0000000000000000000000000000000000000000..5bbb36c70f2cfecad28084d0dcc463b057b34813 --- /dev/null +++ b/assets/css/_override-mixins.scss @@ -0,0 +1,43 @@ +@mixin button-outline-variant( + $color, + $color-hover: color-contrast($color), + $active-background: $color, + $active-border: $color, + $active-color: color-contrast($active-background) +) { + color: $color; + border-color: $color; + + .btn-check:focus + &, + &:focus { + box-shadow: 0 0 0 $btn-focus-width rgba($color, 0.5); + } + + .btn-check:checked + &, + .btn-check:active + &, + &:active, + &.active, + &.dropdown-toggle.show { + color: $active-color; + background-color: $active-background; + border-color: $active-border; + + &:focus { + @if $enable-shadows { + @include box-shadow( + $btn-active-box-shadow, + 0 0 0 $btn-focus-width rgba($color, 0.5) + ); + } @else { + // Avoid using mixin so we can pass custom focus shadow properly + box-shadow: 0 0 0 $btn-focus-width rgba($color, 0.5); + } + } + } + + &:disabled, + &.disabled { + color: $color; + background-color: transparent; + } +} diff --git a/assets/css/style.scss b/assets/css/style.scss index eb6eb00f86617d56c3252fbbbd11387e9720e608..2ba153896882a4a72b616459451bbc716e298206 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -51,27 +51,6 @@ $list-group-hover-bg: var(--bg-secondary-color); // Cards $card-bg: var(--bg-secondary-color); -// Pagination -$pagination-border-color: var(--border-color); -$pagination-bg: var(--bg-menu-color); -$pagination-color: var(--txt-secondary-color); - -$pagination-hover-border-color: $pagination-border-color; -$pagination-hover-bg: var(--bg-secondary-color); -$pagination-hover-color: var(--txt-secondary-color); - -$pagination-active-border-color: $pagination-border-color; -$pagination-active-bg: var(--bg-secondary-color); -$pagination-active-color: var(--txt-secondary-color); - -$pagination-focus-border-color: $pagination-hover-border-color; -$pagination-focus-bg: $pagination-hover-bg; -$pagination-focus-color: $pagination-hover-color; - -$pagination-disabled-border-color: $pagination-border-color; -$pagination-disabled-bg: var(--bg-menu-color); -$pagination-disabled-color: var(--txt-secondary-color); - // Tooltips $tooltip-max-width: 300px; $tooltip-opacity: 1; @@ -81,6 +60,18 @@ $tooltip-font-size: 1rem; $tooltip-arrow-height: 1rem; $tooltip-arrow-width: 1.5rem; +// Tabs +$nav-tabs-link-active-bg: var(--txt-secondary-color); +$nav-tabs-link-active-color: var(--bg-primary-color); +$nav-tabs-link-hover-bg: $nav-tabs-link-active-bg; +$nav-tabs-border-color: var(--txt-primary-color); +$nav-tabs-link-active-border-color: $nav-tabs-border-color + $nav-tabs-border-color $nav-tabs-link-active-bg; +$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color + $nav-tabs-link-hover-bg; +$nav-link-color: var(--txt-link); +$nav-link-hover-color: $nav-tabs-link-active-color; + @import "font"; @import "bootstrap"; @@ -110,6 +101,21 @@ a:hover { table-layout: fixed; } + &-responsive { + tbody { + display: block; + overflow: auto; + scrollbar-width: thin; + } + + thead, + tbody tr { + display: table; + width: 100%; + table-layout: fixed; + } + } + &.sortable { thead { th:not(:last-child) { @@ -122,6 +128,7 @@ a:hover { border-top: none; } } + tbody tr > * { vertical-align: middle; } @@ -165,3 +172,31 @@ a:hover { .pointer { cursor: pointer; } + +.tab-content { + border-width: 0 1px 1px; + border-color: var(--txt-primary-color); + border-style: solid; + min-height: 420px; +} + +.nav-tabs { + .nav-link { + border-color: var(--txt-primary-color); + + &:focus { + background: var(--txt-secondary-color); + box-shadow: 0 0 0 0.25rem rgba(173, 181, 189, 0.5); + } + + &:not(.active):hover { + background: $nav-tabs-link-hover-bg; + } + } + + @media (min-width: 768px) { + .nav-item + .nav-item { + margin-left: 0.5rem; + } + } +} diff --git a/components/badge/Danger.vue b/components/badge/Danger.vue index 080111ef957885d3aef2fa24e8258ec08615ae73..acbfc02efa6a841b64b3fbbed6da4f76c06f9a4c 100644 --- a/components/badge/Danger.vue +++ b/components/badge/Danger.vue @@ -1,6 +1,6 @@ <template> <span - class="d-inline-block help" + class="d-inline-block help flex-shrink-0" :class="classBadge" :title="title" v-if="!['NEWCOMER', 'REVOKED'].includes(memberStatus)" diff --git a/components/badge/Status.vue b/components/badge/Status.vue index fe79dfb570748bec26d1ea2bccfde345edd50b7b..38951de3ca473ba4d14916c926ad60bab47c5df3 100644 --- a/components/badge/Status.vue +++ b/components/badge/Status.vue @@ -20,13 +20,14 @@ export default { case "MISSING": return { str: this.$i18n.t("statut.missing"), class: "bg-danger" } case "MEMBER": + return { + str: this.$i18n.t("statut.member"), + class: "bg-success" + } + case "RENEW": if (this.$options.filters.dateStatus(member.limitDate) == "warning") { return { str: this.$i18n.t("statut.renew"), class: "bg-warning" } } else { - return { - str: this.$i18n.t("statut.member"), - class: "bg-success" - } } case "REVOKED": return { diff --git a/components/btn/Favori.vue b/components/btn/Favori.vue index 604408d915ddb8568f92696486087a73b845cb29..ee4dffca8ce875cd1d10899079351135c165586d 100644 --- a/components/btn/Favori.vue +++ b/components/btn/Favori.vue @@ -1,17 +1,16 @@ <template> <button - id="favori" class="btn btn-secondary" v-tooltip-click=" $favourites.list.includes(uid) - ? $t('favoris.enregistre') - : $t('favoris.supprime') + ? $t('suivis.enregistre') + : $t('suivis.supprime') " @click="$favourites.toggleFavourite(uid, $event)"> <span class="visually-hidden">{{ $favourites.list.includes(uid) - ? $t("favoris.supprimer") - : $t("favoris.ajouter") + ? $t("suivis.supprimer") + : $t("suivis.ajouter") }}</span> <solid-user-add-icon aria-hidden="true" @@ -34,15 +33,3 @@ export default { } } </script> - -<style lang="scss"> -#favori { - width: 50px; - height: 50px; - margin-bottom: 1rem; - - @media (min-width: 576px) { - margin-bottom: 0; - } -} -</style> diff --git a/components/btn/FavoriArray.vue b/components/btn/FavoriArray.vue index 5846f41356e59927e7f968fd3bc773c24c3bef11..3e927280f02885200d0b7de1783fa5636421a738 100644 --- a/components/btn/FavoriArray.vue +++ b/components/btn/FavoriArray.vue @@ -2,7 +2,7 @@ <button v-if="membersToAdd.length != 0" class="btn btn-secondary position-relative" - v-tooltip="{ title: $t('favoris.ajouter'), placement: 'left' }" + v-tooltip="{ title: $t('suivis.ajouter'), placement: 'left' }" @click="$favourites.addFavorisArray(membersToAdd, $event)"> <solid-user-group-icon aria-hidden="true" class="icon" /> <span diff --git a/components/btn/Pagination.vue b/components/btn/Pagination.vue deleted file mode 100644 index d76bc198282b4f95c3943abd0e0d776f717c7599..0000000000000000000000000000000000000000 --- a/components/btn/Pagination.vue +++ /dev/null @@ -1,112 +0,0 @@ -<template> - <nav :aria-label="$t('pagination.title')" v-if="nbPages > 1"> - <ul class="pagination justify-content-center m-0"> - <li class="page-item" v-if="currentPage > 2 && nbPages > 3"> - <a class="page-link" href="#" @click="goto(1, $event)"> - <span :aria-label="$t('pagination.page') + ' 1'">1</span> - </a> - </li> - <li class="page-item disabled" v-if="currentPage > 3 && nbPages > 4"> - <span class="page-link"><span aria-hidden="true">...</span></span> - </li> - <li - class="page-item" - v-for="index in listPagesUtiles" - :key="index" - :class="{ active: index == currentPage }"> - <a - v-if="index != currentPage" - class="page-link" - href="#" - @click="goto(index, $event)"> - <span :aria-label="$t('pagination.page') + ' ' + index">{{ - index - }}</span></a - > - <span v-else class="page-link">{{ index }}</span> - </li> - <li - class="page-item disabled" - v-if="currentPage < nbPages - 2 && nbPages > 4"> - <span class="page-link"><span aria-hidden="true">...</span></span> - </li> - <li class="page-item" v-if="currentPage < nbPages - 1 && nbPages > 3"> - <a class="page-link" href="#" @click="goto(nbPages, $event)"> - <span :aria-label="$t('pagination.page') + ' ' + nbPages">{{ - nbPages - }}</span> - </a> - </li> - </ul> - </nav> -</template> - -<script> -export default { - props: { - target: String, - currentPage: { - type: Number, - required: true - }, - pageSize: { - type: Number, - required: true - }, - arrayLength: { - type: Number, - required: true - } - }, - methods: { - goto(i, e) { - if (e !== undefined) e.preventDefault() - let query = { ...this.$route.query } - query["page-" + this.target] = i - this.$router.push({ - path: this.$route.path, - query: query - }) - this.$emit("update:currentPage", i) - } - }, - computed: { - nbPages() { - return Math.ceil(this.arrayLength / this.pageSize) - }, - listPagesUtiles() { - if (this.nbPages < 3) { - return [1, 2] - } - - if (this.currentPage == 1) { - return [1, 2, 3] - } - - if (this.currentPage == this.nbPages) { - return [this.nbPages - 2, this.nbPages - 1, this.nbPages] - } - - return [this.currentPage - 1, this.currentPage, this.currentPage + 1] - } - }, - watch: { - arrayLength: { - handler(n, o) { - this.goto(1) - } - } - } -} -</script> - -<style lang="scss" scoped> -.pagination { - user-select: none; -} - -.disabled, -.active { - cursor: not-allowed; -} -</style> diff --git a/components/btn/Search.vue b/components/btn/Search.vue index 756f701b716efbcf0ec9585ca38416952769a375..701727551d2d7afeed69d95ad7c6ef199b922ef4 100644 --- a/components/btn/Search.vue +++ b/components/btn/Search.vue @@ -15,6 +15,7 @@ :aria-label="$t('recherche.title')" :aria-describedby="help ? 'rechHelp' : null" /> <button + v-if="value != ''" :title="$t('recherche.effacer')" class="btn" type="button" diff --git a/components/certif/Group.vue b/components/certif/Group.vue index 83df611bf2f691fb9d935955c1791fd05fa7537c..39627e6c5af373c0dcd6eccd266c9ff79ca76800 100644 --- a/components/certif/Group.vue +++ b/components/certif/Group.vue @@ -25,7 +25,9 @@ :limitDate="limitDate" :memberStatus="memberStatus" /> </h3> - <BtnFavoriArray :listUID="certifsNotPending" /> + <BtnFavoriArray + :listUID="certifsNotPending" + v-if="$parent.$parent.registeredAccount.hash != $route.query.hash" /> </div> <CertifList :title="$t('certification.enattente')" diff --git a/components/certif/List.vue b/components/certif/List.vue index 43b8611bf129c770bc5a822d6c79f09c96d92b77..3369d44854997e8cbfa4bf5d28b989d25c65847d 100644 --- a/components/certif/List.vue +++ b/components/certif/List.vue @@ -1,5 +1,5 @@ <template> - <div v-if="certifs.length > 0"> + <div class="certifList" v-if="certifs.length > 0"> <button :title=" isOpen ? $t('certification.masquer') : $t('certification.afficher') @@ -66,7 +66,7 @@ @click=" $router.push( localePath({ - name: 'membre', + name: 'membres-profil', query: { hash: certif.hash } }) ) @@ -74,7 +74,7 @@ @keyup.enter=" $router.push( localePath({ - name: 'membre', + name: 'membres-profil', query: { hash: certif.hash } }) ) @@ -102,7 +102,7 @@ v-if="certif.status == 'MEMBER'" /> </td> <td class="p-0 text-center col-4"> - <div class="d-flex flex-column gap-1"> + <div class="d-inline-flex flex-column gap-1"> <BadgeDate :date="certif.expires_on" /> <span class="badge bg-secondary text-truncate d-block" @@ -114,13 +114,6 @@ </tr> </tbody> </table> - <BtnPagination - class="mt-3" - :target="collapseId" - :currentPage.sync="currentPage" - :pageSize="pageSize" - :arrayLength="certifsFiltrees.length" - v-if="certifsFiltrees.length > pageSize" /> </div> </div> </template> @@ -132,8 +125,6 @@ export default { search: "", currentSort: "expires_on", currentSortDir: "asc", - currentPage: 1, - pageSize: 5, isOpen: this.openDefault } }, @@ -153,20 +144,6 @@ export default { this.currentSortDir = this.currentSortDir === "asc" ? "desc" : "asc" } this.currentSort = s - }, - setPage() { - let page = this.$route.query["page-" + this.collapseId] - ? parseInt(this.$route.query["page-" + this.collapseId]) - : 1 - - if ( - isNaN(page) || - page > Math.ceil(this.certifsFiltrees.length / this.pageSize) || - page < 1 - ) - page = 1 - - this.currentPage = page } }, computed: { @@ -180,6 +157,13 @@ export default { }, certifsTriees() { return this.certifsFiltrees + .map((el) => { + el.status = + this.$options.filters.dateStatus(el.limitDate) == "warning" + ? "RENEW" + : el.status + return el + }) .sort((a, b) => { let modifier = this.currentSortDir === "desc" ? -1 : 1 @@ -195,11 +179,6 @@ export default { return 0 }) - .filter((row, index) => { - let start = (this.currentPage - 1) * this.pageSize - let end = this.currentPage * this.pageSize - if (index >= start && index < end) return true - }) }, collapseClass() { if (this.collapseId.includes("entraitement")) return "bg-secondary" @@ -223,8 +202,6 @@ export default { } }, mounted() { - this.setPage() - if (this.openDefault && this.certifs.length > 0) { document.querySelector("#" + this.collapseId).classList.add("show") } @@ -234,26 +211,29 @@ export default { handler(n, o) { this.search = "" } - }, - $route(to, from) { - this.setPage() } } } </script> -<style lang="scss" scoped> -tbody tr { - height: 80px; -} - -@media (min-width: 576px) { - button { - font-size: 1.3rem; +<style lang="scss"> +.certifList { + .table-responsive tbody { + max-height: 456px; } tbody tr { - height: initial; + height: 80px; + } + + @media (min-width: 576px) { + button { + font-size: 1.3rem; + } + + tbody tr { + height: initial; + } } } </style> diff --git a/components/member/Card.vue b/components/member/Card.vue index 2cb26461b5cfdb70e39a2780d3807bcd2d193e33..1f0d4f5766b0d94dbf21708aa290329a7f03da04 100644 --- a/components/member/Card.vue +++ b/components/member/Card.vue @@ -9,7 +9,27 @@ </span> <small><BadgeStatus class="ms-2" :membre="hash" /></small> </h2> - <BtnFavori :uid="hash.uid" /> + <div class="btn-group" role="group"> + <button + v-if=" + $parent.registeredAccount.uid == '' || + $parent.registeredAccount.uid == hash.uid + " + class="btn" + :class="{ + 'btn-success': $parent.registeredAccount.uid != hash.uid, + 'btn-warning': $parent.registeredAccount.uid == hash.uid + }" + @click="updateCurrentHash($event)"> + <span v-if="$parent.registeredAccount.uid != hash.uid">{{ + $t("suivis.iam") + }}</span> + <span v-else>{{ $t("suivis.iamnot") }}</span> + </button> + <BtnFavori + :uid="hash.uid" + v-if="$parent.registeredAccount.uid != hash.uid" /> + </div> </div> <BtnClipboard :textContent="hash.pubkey" /> <AlertMember :hash="hash" /> @@ -113,11 +133,6 @@ <script> export default { - data() { - return { - favourites: [] - } - }, props: { hash: Object }, @@ -125,6 +140,21 @@ export default { sentCertNotExpired() { return this.hash.sent_certifications.filter((el) => !el.expired) } + }, + methods: { + updateCurrentHash(e) { + if (this.$parent.registeredAccount.uid == this.hash.uid) { + this.$parent.registeredAccount = { hash: "", uid: "" } + } else { + this.$parent.registeredAccount = { + hash: this.hash.hash, + uid: this.hash.uid + } + if (this.$favourites.list.includes(this.hash.uid)) { + this.$favourites.toggleFavourite(this.hash.uid, e) + } + } + } } } </script> diff --git a/components/member/Filter.vue b/components/member/Filter.vue index 94e5f40161be0390bdc1078c2643dd42f5b54b47..95420b9ad14d24eb757a5db6be53c75073a60c77 100644 --- a/components/member/Filter.vue +++ b/components/member/Filter.vue @@ -1,52 +1,101 @@ <template> <div class="text-muted"> <p id="filterStatutTitle">{{ $t("filter.statut") }} :</p> - <ul class="p-0" aria-labelledby="filterStatutTitle" role="group"> - <li class="form-check form-check-inline"> + <ul class="p-0 m-0" aria-labelledby="filterStatutTitle" role="group"> + <li + class="form-check form-check-inline mb-3" + v-if="type != 'certificateurs'"> <input - class="form-check-input" + class="btn-check" v-model="checkedStatus" type="checkbox" - id="check-newcomer" - value="NEWCOMER" /> - <label class="form-check-label" for="check-newcomer">{{ + :id="'check-newcomer-' + _uid" + value="NEWCOMER" + @change="fixColumns" /> + <label class="btn btn-outline-info" :for="'check-newcomer-' + _uid">{{ $t("statut.newcomer") }}</label> </li> - <li class="form-check form-check-inline"> + <li class="form-check form-check-inline mb-3"> <input - class="form-check-input" + class="btn-check" v-model="checkedStatus" type="checkbox" - id="check-member" - value="MEMBER" /> - <label class="form-check-label" for="check-member">{{ + :id="'check-member-' + _uid" + value="MEMBER" + @change="fixColumns" /> + <label class="btn btn-outline-success" :for="'check-member-' + _uid">{{ $t("statut.member") }}</label> </li> - <li class="form-check form-check-inline"> + <li class="form-check form-check-inline mb-3"> <input - class="form-check-input" + class="btn-check" v-model="checkedStatus" type="checkbox" - id="check-missing" - value="MISSING" /> - <label class="form-check-label" for="check-missing">{{ - $t("statut.missing") + :id="'check-renew-' + _uid" + value="RENEW" + @change="fixColumns" /> + <label class="btn btn-outline-warning" :for="'check-renew-' + _uid">{{ + $t("statut.renew") }}</label> </li> - <li class="form-check form-check-inline"> + <li class="form-check form-check-inline mb-3"> <input - class="form-check-input" + class="btn-check" v-model="checkedStatus" type="checkbox" - id="check-revoked" - value="REVOKED" /> - <label class="form-check-label" for="check-revoked">{{ - $t("statut.revoked") + :id="'check-missing-' + _uid" + value="MISSING" + @change="fixColumns" /> + <label class="btn btn-outline-danger" :for="'check-missing-' + _uid">{{ + $t("statut.missing") }}</label> </li> + <li class="form-check form-check-inline mb-3" v-if="type == 'favoris'"> + <input + class="btn-check" + v-model="checkedStatus" + type="checkbox" + :id="'check-revoked-' + _uid" + value="REVOKED" + @change="fixColumns" /> + <label + class="btn btn-outline-secondary" + :for="'check-revoked-' + _uid" + >{{ $t("statut.revoked") }}</label + > + </li> </ul> + <div v-if="type != 'favoris'"> + <p>{{ $t("filter.certif") }} :</p> + <input + class="btn-check" + v-model="certifStatus" + type="radio" + :name="'certifStatus-' + _uid" + :id="'radio-current-' + _uid" + value="current" + autocomplete="off" /> + <label + class="btn btn-outline-success me-3 mb-3" + :for="'radio-current-' + _uid"> + {{ $t("certification.title") + " " + $t("certification.encours") }} + </label> + <input + class="btn-check" + v-model="certifStatus" + type="radio" + :name="'certifStatus-' + _uid" + :id="'radio-outdated-' + _uid" + value="outdated" + autocomplete="off" /> + <label + class="btn btn-outline-danger mb-3" + :for="'radio-outdated-' + _uid"> + {{ $t("certification.title") + " " + $t("certification.perimees") }} + </label> + </div> </div> </template> @@ -54,13 +103,29 @@ export default { data() { return { - checkedStatus: this.selectedStatus + checkedStatus: this.selectedStatus, + certifStatus: this.selectedCertifStatus } }, props: { selectedStatus: { type: Array, required: true + }, + selectedCertifStatus: { + type: String, + required: true + }, + type: { + type: String, + default: "" + } + }, + methods: { + fixColumns(e) { + setTimeout(() => { + this.$favourites.fixColumns() + }, 5) } }, watch: { @@ -68,6 +133,11 @@ export default { handler(n, o) { this.$emit("update:selectedStatus", n) } + }, + certifStatus: { + handler(n, o) { + this.$emit("update:selectedCertifStatus", n) + } } } } diff --git a/components/member/List.vue b/components/member/List.vue index 1fe5e2a5703acc099d982775d9d99a4796beef3b..5f348ce090f5087fad13610a4eefe9c54f6aaef4 100644 --- a/components/member/List.vue +++ b/components/member/List.vue @@ -30,7 +30,9 @@ <th scope="col" class="td-quality d-none d-lg-table-cell p-0" - v-if="['favoris', 'search'].includes(id)" + v-if=" + ['favoris', 'search', 'certificateurs', 'certifies'].includes(id) + " @click="sort('quality')" @keyup.enter="sort('quality')"> <BtnSort @@ -42,7 +44,9 @@ <th scope="col" class="d-none d-xl-table-cell p-0" - v-if="['favoris', 'search'].includes(id)" + v-if=" + ['favoris', 'search', 'certificateurs', 'certifies'].includes(id) + " @click="sort('dispo')" @keyup.enter="sort('dispo')"> <BtnSort @@ -56,7 +60,15 @@ class="td-date d-none d-sm-table-cell p-0" @click="sort('date_membership')" @keyup.enter="sort('date_membership')" - v-if="['adhesion', 'favoris', 'search'].includes(id)"> + v-if=" + [ + 'adhesion', + 'favoris', + 'search', + 'certificateurs', + 'certifies' + ].includes(id) + "> <BtnSort fieldName="date_membership" :title=" @@ -76,7 +88,15 @@ }" @click="sort('date_certs')" @keyup.enter="sort('date_certs')" - v-if="['certif', 'favoris', 'search'].includes(id)"> + v-if=" + [ + 'certif', + 'favoris', + 'search', + 'certificateurs', + 'certifies' + ].includes(id) + "> <BtnSort fieldName="date_certs" :title=" @@ -101,7 +121,7 @@ <td> <div class="d-flex"> <div - class="d-flex flex-column align-items-center justify-content-evenly flex-grow-1"> + class="d-flex flex-column align-items-center justify-content-evenly flex-grow-1 mw-100"> <div class="d-flex justify-content-center mw-100"> <span v-if="$favourites.list.includes(member.uid)" >★ </span @@ -124,7 +144,11 @@ </div> <div class="w-50 d-flex flex-column align-items-center justify-content-evenly gap-1 d-lg-none" - v-if="['favoris', 'search'].includes(id)"> + v-if=" + ['favoris', 'search', 'certificateurs', 'certifies'].includes( + id + ) + "> <BadgeStatus :membre="member" class="mw-100 text-truncate" /> <BadgeQuality :quality="member.quality.ratio" /> <BadgeDispo @@ -140,12 +164,16 @@ </td> <td class="d-none d-lg-table-cell" - v-if="['favoris', 'search'].includes(id)"> + v-if=" + ['favoris', 'search', 'certificateurs', 'certifies'].includes(id) + "> <BadgeQuality :quality="member.quality.ratio" /> </td> <td class="d-none d-xl-table-cell" - v-if="['favoris', 'search'].includes(id)"> + v-if=" + ['favoris', 'search', 'certificateurs', 'certifies'].includes(id) + "> <BadgeDispo :isDispo="member.minDatePassed" :dateDispo="member.minDate" @@ -153,7 +181,15 @@ </td> <td class="d-none d-sm-table-cell" - v-if="['adhesion', 'favoris', 'search'].includes(id)"> + v-if=" + [ + 'adhesion', + 'favoris', + 'search', + 'certificateurs', + 'certifies' + ].includes(id) + "> <BadgeDate :date="member.limitDate" /> </td> <td @@ -162,7 +198,15 @@ 'd-sm-table-cell': id == 'certif', 'd-md-table-cell': id != 'certif' }" - v-if="['certif', 'favoris', 'search'].includes(id)"> + v-if=" + [ + 'certif', + 'favoris', + 'search', + 'certificateurs', + 'certifies' + ].includes(id) + "> <BadgeDate :date="member.certsLimit" /> </td> <td class="py-1" v-if="id == 'favoris'" style="width: 60px"> @@ -170,18 +214,13 @@ class="btn btn-danger" v-if="$favourites.list.includes(member.uid)" @click="$favourites.toggleFavourite(member.uid, $event)" - :title="$t('favoris.supprimer')"> + :title="$t('suivis.supprimer')"> <solid-trash-icon class="icon" aria-hidden="true" /> </button> </td> </tr> </tbody> </table> - <BtnPagination - :target="id" - :currentPage.sync="currentPage" - :pageSize="pageSize" - :arrayLength="members.length" /> </div> </template> @@ -190,9 +229,7 @@ export default { data() { return { currentSort: this.defaultSort, - currentSortDir: this.defaultSortDir, - pageSize: 5, - currentPage: 1 + currentSortDir: this.defaultSortDir } }, props: { @@ -215,7 +252,9 @@ export default { }, methods: { redirect(hash) { - this.$router.push(this.localePath({ name: "membre", query: { hash } })) + this.$router.push( + this.localePath({ name: "membres-profil", query: { hash } }) + ) }, sort(s) { if (s === this.currentSort) { @@ -232,63 +271,38 @@ export default { if (a < b) return -1 * order if (a > b) return 1 * order return 0 - }, - setPage() { - let page = this.$route.query["page-" + this.id] - ? parseInt(this.$route.query["page-" + this.id]) - : 1 - - if ( - isNaN(page) || - page > Math.ceil(this.members.length / this.pageSize) || - page < 1 - ) - page = 1 - - this.currentPage = page } }, computed: { membersSorted() { - return this.members - .sort((a, b) => { - let modifier = this.currentSortDir === "desc" ? -1 : 1 + return this.members.sort((a, b) => { + let modifier = this.currentSortDir === "desc" ? -1 : 1 - if (this.currentSort == "uid") { - return this.getOrder( - a["uid"].toLowerCase(), - b["uid"].toLowerCase(), - modifier - ) - } else if (this.currentSort == "dispo") { - if (a.minDate == null) return 1 * modifier - if (b.minDate == null) return -1 * modifier - return this.getOrder(a.minDate, b.minDate, modifier) - } else if (this.currentSort == "quality") { - return this.getOrder(a.quality.ratio, b.quality.ratio, modifier) - } else if (this.currentSort == "statut") { - return this.getOrder(a["status"], b["status"], modifier) - } else if (this.currentSort == "date_membership") { - return this.getOrder(a["limitDate"], b["limitDate"], modifier) - } else if (this.currentSort == "date_certs") { - return this.getOrder(a["certsLimit"], b["certsLimit"], modifier) - } - return 0 - }) - .filter((row, index) => { - let start = (this.currentPage - 1) * this.pageSize - let end = this.currentPage * this.pageSize - if (index >= start && index < end) return true - }) + if (this.currentSort == "uid") { + return this.getOrder( + a["uid"].toLowerCase(), + b["uid"].toLowerCase(), + modifier + ) + } else if (this.currentSort == "dispo") { + if (a.minDate == null) return 1 * modifier + if (b.minDate == null) return -1 * modifier + return this.getOrder(a.minDate, b.minDate, modifier) + } else if (this.currentSort == "quality") { + return this.getOrder(a.quality.ratio, b.quality.ratio, modifier) + } else if (this.currentSort == "statut") { + return this.getOrder(a["status"], b["status"], modifier) + } else if (this.currentSort == "date_membership") { + return this.getOrder(a["limitDate"], b["limitDate"], modifier) + } else if (this.currentSort == "date_certs") { + return this.getOrder(a["certsLimit"], b["certsLimit"], modifier) + } + return 0 + }) } }, mounted() { - this.setPage() - }, - watch: { - $route(to, from) { - this.setPage() - } + this.$favourites.fixColumns() } } </script> diff --git a/components/navigation/menu/Sidebar.vue b/components/navigation/menu/Sidebar.vue index d9a79ee6ec7f21b2b8481b13b1c21ed9ad1b6950..671bee7074439003478304e3c929414ace5f27c3 100644 --- a/components/navigation/menu/Sidebar.vue +++ b/components/navigation/menu/Sidebar.vue @@ -77,6 +77,7 @@ export default { this.$emit("toggleMenu") }, onResize() { + this.$favourites.fixColumns() this.screenwidth = window.innerWidth } }, diff --git a/components/suivis/Tableau.vue b/components/suivis/Tableau.vue new file mode 100644 index 0000000000000000000000000000000000000000..8d63f646507324422177dcfaced8cb5cdd7c023d --- /dev/null +++ b/components/suivis/Tableau.vue @@ -0,0 +1,78 @@ +<template> + <div class="container pt-5"> + <div class="row suivis"> + <div class="col"> + <div v-if="members && members.length != 0"> + <BtnSearch + @erase="search = ''" + v-model="search" + class="col-sm-7 col-md-6 col-lg-5 col-xl-4 mx-auto mb-4" /> + <MemberFilter + :selectedStatus.sync="filterStatus" + :selectedCertifStatus.sync="filterCerts" + :type="type" /> + <MemberList + defaultSort="date_membership" + :members="filteredMembers" + :id="type" /> + <button + class="btn btn-danger d-block m-auto mb-3" + v-if="type == 'favoris'" + @click="deleteAllFavorites"> + <solid-trash-icon class="icon" aria-hidden="true" /> + {{ $t("suivis.supprimer_tous") }} + </button> + </div> + <div class="alert alert-info" v-if="members && members.length == 0"> + {{ $t("suivis.none") }} + </div> + </div> + </div> + </div> +</template> + +<script> +export default { + data() { + return { + search: "", + filterStatus: ["NEWCOMER", "", "RENEW", "MISSING", ""], + filterCerts: "current" + } + }, + props: { + type: { + type: String, + default: "" + }, + members: { + type: Array, + required: true + } + }, + computed: { + filteredMembers() { + return this.members.filter( + (el) => + el.uid.toLowerCase().includes(this.search.toLowerCase()) && + this.filterStatus.includes(el.status) && + el.expired == (this.filterCerts == "outdated") + ) + } + }, + methods: { + deleteAllFavorites() { + if (window.confirm(this.$t("suivis.confirm"))) { + this.$favourites.list = [] + localStorage.removeItem("favourites") + } + } + } +} +</script> + +<style lang="scss"> +.suivis .table-responsive tbody { + max-height: 43.5vh; +} +</style> diff --git a/graphql/endpoints/coindufeu.js b/graphql/endpoints/coindufeu.js deleted file mode 100644 index a7d180116825c4aff08cfa651505351869452b77..0000000000000000000000000000000000000000 --- a/graphql/endpoints/coindufeu.js +++ /dev/null @@ -1,26 +0,0 @@ -import { HttpLink } from "apollo-link-http" -import { setContext } from "apollo-link-context" -import { from } from "apollo-link" -import { cache } from "../cache" - -export default (ctx) => { - const ssrMiddleware = setContext((_, { headers }) => { - if (process.client) return headers - return { - headers - } - }) - - const httpLink = new HttpLink({ - uri: "https://wwgql.coinduf.eu" - }) - - const link = from([ssrMiddleware, httpLink]) - - return { - link, - cache, - // https://github.com/nuxt-community/apollo-module/issues/306#issuecomment-607225431 - defaultHttpLink: false - } -} diff --git a/graphql/queries.js b/graphql/queries.js index 0fe8e8024f2f5fa8465e59b40375d617cc9a4346..a96726d63affcc0240bd8df96605038be4cb0c2b 100644 --- a/graphql/queries.js +++ b/graphql/queries.js @@ -169,6 +169,7 @@ export const SEARCH_MEMBER = gql` __typename uid hash + pubkey status certsLimit limitDate @@ -211,9 +212,9 @@ export const PARAMS = gql` } } ` -// Pour la page favoris -export const FAVORIS = gql` - query getFavoris($group: [String!]!) { +// Pour la page des suivis +export const MEMBERS = gql` + query getMembers($group: [String!]!) { filterGroup(group: $group) { __typename selected { diff --git a/i18n/locales/de.json b/i18n/locales/de.json index 33bfa6d4f84dbf6cba6a8bdedc437542c4c76d90..e7a1986a134644680d422316fd5e03a1da58b50e 100644 --- a/i18n/locales/de.json +++ b/i18n/locales/de.json @@ -108,17 +108,9 @@ "title": "Duniter" }, "expire": "Ablaufdatum", - "favoris": { - "ajouter": "Zu den Favoriten hinzufügen", - "enregistre": "In den Favoriten gespeichert!", - "none": "Sie haben noch keine Favoriten", - "supprime": "Aus den Favoriten entfernt!", - "supprimer": "Aus den Favoriten entfernen", - "title": "Meine Favoriten", - "use": "Nur meine Favoriten" - }, "filter": { - "statut": "Nach Status filtern" + "certif": "Nach Zertifizierungsstatus filtern", + "statut": "Nach Mitgliedsstatus filtern" }, "infos": "Informationen", "inout": "Bei- und Austritte des Vertrauensnetz in den 2 letzten Tagen", @@ -181,10 +173,6 @@ "nom": "Name", "non": "Nein", "oui": "Ja", - "pagination": { - "page": "Buchseite", - "title": "Paginierungsschaltflächen" - }, "params": { "breadcrumb": "Parameter", "name": { @@ -236,7 +224,6 @@ "pubkey": "Öffentlicher Schlüssel", "recherche": { "desc": { - "favourites": "Suchen Sie unter Ihren Favoriten", "lexicon": "Suche im Lexikon", "member": "Geben Sie den Anfang eines Pseudonyms oder eines öffentlichen Schlüssels ein" }, @@ -260,6 +247,31 @@ "revoked": "Widerrufenes Mitglied", "title": "Status" }, + "suivis": { + "ajouter": "Zu den Favoriten hinzufügen", + "alert": { + "btn": "Finden Sie Ihre Identität", + "desc": "Bitte geben Sie ein Mitglied als Ihre Identität an, indem Sie auf die Schaltfläche « Ich bin dieses Mitglied » klicken.", + "title": "Sie sind noch nicht registriert" + }, + "confirm": "Sind Sie sicher ?", + "enregistre": "In den Favoriten gespeichert!", + "enregistre_uid": "Schützen", + "iam": "Ich bin dieses Mitglied", + "iamnot": "Ich bin nicht dieses Mitglied", + "none": "Die Liste ist leer", + "supprime": "Aus den Favoriten entfernt!", + "supprimer": "Aus den Favoriten entfernen", + "supprimer_tous": "Alle Favoriten löschen", + "tabs": { + "certificateurs": "Meine Zertifizierer", + "certifies": "Meine Zertifizierten", + "favoris": "Meine Favoriten" + }, + "title": "Meine Nachfolge", + "use": "Nur meine Favoriten", + "voir_profil": "Siehe mein Profil" + }, "time": { "a": "um" }, diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 73cccc64de3dd771c1efa62f54e75313c3fe3cfe..a0e34b6801af8fc7487b8ec0f78781e64c3e71da 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -109,17 +109,9 @@ "title": "Duniter" }, "expire": "Expiry", - "favoris": { - "ajouter": "Add to favorites", - "enregistre": "Saved to favorites !", - "none": "You don't have any favorites yet", - "supprime": "Deleted from favourites !", - "supprimer": "Delete from favourites", - "title": "My favourites", - "use": "My favorites only" - }, "filter": { - "statut": "Filter by status" + "certif": "Filter by certification status", + "statut": "Filter by member status" }, "infos": "Informations", "inout": "Entries and exits of the web of trust for the last 2 days", @@ -182,10 +174,6 @@ "nom": "Name", "non": "No", "oui": "Yes", - "pagination": { - "page": "Page", - "title": "Pagination buttons" - }, "params": { "breadcrumb": "Parameters", "name": { @@ -237,7 +225,6 @@ "pubkey": "Public key", "recherche": { "desc": { - "favourites": "Search among your favorites", "lexicon": "Search in the lexicon", "member": "Enter the start of a nickname or public key" }, @@ -261,6 +248,31 @@ "revoked": "Revoked member", "title": "Status" }, + "suivis": { + "ajouter": "Add to favorites", + "alert": { + "btn": "Find your identity", + "desc": "Please indicate a member as your identity by clicking on the button « I am this member »", + "title": "You're not registered yet" + }, + "confirm": "Are you sure ?", + "enregistre": "Saved to favorites !", + "enregistre_uid": "Save", + "iam": "I am that member", + "iamnot": "I am not that member", + "none": "The list is empty", + "supprime": "Deleted from favourites !", + "supprimer": "Delete from favourites", + "supprimer_tous": "Delete all favourites", + "tabs": { + "certificateurs": " My certifiers", + "certifies": "My certified members", + "favoris": "My favorites" + }, + "title": "My follow-ups", + "use": "My favorites only", + "voir_profil": "See my profile" + }, "time": { "a": "at" }, diff --git a/i18n/locales/es.json b/i18n/locales/es.json index 490dfc58796b8049a53a9fe8ed43420f3e7ba405..b41228f13020b5c5fb2ed24a66c7a515e6cce719 100644 --- a/i18n/locales/es.json +++ b/i18n/locales/es.json @@ -109,17 +109,9 @@ "title": "Duniter" }, "expire": "Expiración", - "favoris": { - "ajouter": "Agregar a los favoritos", - "enregistre": "¡Guardado en favoritos!", - "none": "Aún no tienes favoritos", - "supprime": "¡Eliminado de favoritos!", - "supprimer": "Eliminar de favoritos", - "title": "Mis favoritos", - "use": "Solo mis favoritos" - }, "filter": { - "statut": "Filtrar por estado" + "certif": "Filtrar por estado de certificación", + "statut": "Filtrar por estado de miembro" }, "infos": "Informaciones", "inout": "Entradas y salidas de la red de confianza en los últimos 2 dÃas", @@ -182,10 +174,6 @@ "nom": "Nombre", "non": "No", "oui": "SÃ", - "pagination": { - "page": "Página", - "title": "Botones de paginación" - }, "params": { "breadcrumb": "Parámetros", "name": { @@ -237,7 +225,6 @@ "pubkey": "Llave pública", "recherche": { "desc": { - "favourites": "Busca entre tus favoritos", "lexicon": "Buscar en el léxico", "member": "Introduce el comienzo de un pseudónimo o llave pública" }, @@ -261,6 +248,31 @@ "revoked": "MembresÃa revocada", "title": "Estado" }, + "suivis": { + "ajouter": "Agregar a los favoritos", + "alert": { + "btn": "Encuentra tu identidad", + "desc": "Indique un miembro como su identidad haciendo clic en el botón « Soy este miembro »", + "title": "Aún no estás registrado" + }, + "confirm": "Está usted seguro ?", + "enregistre": "¡Guardado en favoritos!", + "enregistre_uid": "Salvaguardar", + "iam": "Soy este miembro", + "iamnot": "No soy este miembro", + "none": "La lista está vacÃa", + "supprime": "¡Eliminado de favoritos!", + "supprimer": "Eliminar de favoritos", + "supprimer_tous": "Eliminar todos los favoritos", + "tabs": { + "certificateurs": "Mis certificadores", + "certifies": "Mis miembros certificados", + "favoris": "Mis favoritos" + }, + "title": "Mis seguimientos", + "use": "Solo mis favoritos", + "voir_profil": "Mira mi perfil" + }, "time": { "a": "a" }, diff --git a/i18n/locales/fr.json b/i18n/locales/fr.json index d20ce91a73bd109388c2f00980d42f9deaabede2..93ce14633369bc05333cb6de9dbc2f6e7ba8646e 100644 --- a/i18n/locales/fr.json +++ b/i18n/locales/fr.json @@ -109,17 +109,9 @@ "title": "Duniter" }, "expire": "Expiration", - "favoris": { - "ajouter": "Ajouter aux favoris", - "enregistre": "Enregistré dans les favoris !", - "none": "Vous n'avez pas encore de favoris", - "supprime": "Supprimé des favoris !", - "supprimer": "Supprimer des favoris", - "title": "Mes favoris", - "use": "Mes favoris uniquement" - }, "filter": { - "statut": "Filtrer par statut" + "certif": "Filtrer en fonction du statut de la certification", + "statut": "Filtrer par statut du membre" }, "infos": "Informations", "inout": "Entrées et sorties de la toile de confiance des 2 derniers jours", @@ -182,10 +174,6 @@ "nom": "Nom", "non": "Non", "oui": "Oui", - "pagination": { - "page": "Page", - "title": "Boutons de pagination" - }, "params": { "breadcrumb": "Paramètres", "name": { @@ -237,7 +225,6 @@ "pubkey": "Clef publique", "recherche": { "desc": { - "favourites": "Recherchez dans vos favoris", "lexicon": "Recherchez dans le lexique", "member": "Saisissez le début d'un pseudo ou d'une clé publique" }, @@ -261,6 +248,31 @@ "revoked": "Membre révoqué", "title": "Statut" }, + "suivis": { + "ajouter": "Ajouter aux favoris", + "alert": { + "btn": "Rechercher votre identité", + "desc": "Veuillez indiquer un membre comme étant votre identité en cliquant sur le bouton « Je suis ce membre »", + "title": "Vous n'êtes pas encore enregistré" + }, + "confirm": "Êtes-vous sûr ?", + "enregistre": "Enregistré dans les favoris !", + "enregistre_uid": "Sauvegarder", + "iam": "Je suis ce membre", + "iamnot": "Je ne suis pas ce membre", + "none": "La liste est vide", + "supprime": "Supprimé des favoris !", + "supprimer": "Supprimer des favoris", + "supprimer_tous": "Supprimer tous les favoris", + "tabs": { + "certificateurs": "Mes certificateurs", + "certifies": "Mes certifiés", + "favoris": "Mes favoris" + }, + "title": "Mes suivis", + "use": "Mes favoris uniquement", + "voir_profil": "Voir mon profil" + }, "time": { "a": "à " }, diff --git a/i18n/locales/it.json b/i18n/locales/it.json index 1edfa4b1561401a6034445ef82d097cc01217a31..d95bea310685400bd8f26c29c8cb24c32260f691 100644 --- a/i18n/locales/it.json +++ b/i18n/locales/it.json @@ -109,17 +109,9 @@ "title": "Duniter" }, "expire": "Scadenza", - "favoris": { - "ajouter": "Aggiungere ai favoriti", - "enregistre": "Salvato nei favoriti!", - "none": "Non hay ancora favoriti", - "supprime": "¡Eliminato dai favoriti!", - "supprimer": "Eliminare dai favoriti", - "title": "I miei favoriti", - "use": "Solo i miei favoriti" - }, "filter": { - "statut": "Filtrare per lo stato" + "certif": "Filtra per stato di certificazione", + "statut": "Filtra per stato membro" }, "infos": "Informacioni", "inout": "Entrate e uscite dalla Rete di Fiducia negli ultimi 2 giorni", @@ -182,10 +174,6 @@ "nom": "Nome", "non": "No", "oui": "SÃ", - "pagination": { - "page": "Pagina", - "title": "Bottoni di impaginazione" - }, "params": { "breadcrumb": "Parametri", "name": { @@ -237,7 +225,6 @@ "pubkey": "Chiave pubblica", "recherche": { "desc": { - "favourites": "Cerca tra i tuoi favoriti", "lexicon": "Cerca nel lessico", "member": "Introduci l'inizio di uno pseudonimo o chiave pubblica" }, @@ -261,6 +248,31 @@ "revoked": "Adesione alla RdF revocata", "title": "Stado" }, + "suivis": { + "ajouter": "Aggiungere ai favoriti", + "alert": { + "btn": "Trova la tua identità ", + "desc": "Indica un membro come tua identità facendo clic sul pulsante « Sono questo membro »", + "title": "Non sei ancora registrato" + }, + "confirm": "Sei sicuro ?", + "enregistre": "Salvato nei favoriti!", + "enregistre_uid": "Salvaguardare", + "iam": "Sono questo membro", + "iamnot": "Non sono questo membro", + "none": "L'elenco è vuoto", + "supprime": "¡Eliminato dai favoriti!", + "supprimer": "Eliminare dai favoriti", + "supprimer_tous": "Elimina tutti i favoriti", + "tabs": { + "certificateurs": "I mei certificatori", + "certifies": "I miei membri certificati", + "favoris": "I mei favoriti" + }, + "title": "I miei follow-up", + "use": "Solo i miei favoriti", + "voir_profil": "Guarda il mio profilo" + }, "time": { "a": "a" }, diff --git a/layouts/default.vue b/layouts/default.vue index 8ad84509a769c4693d346091adc0aaf93343edc5..75687f5f74ddacc4dd9489efd9bd2bb0964c587b 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -24,7 +24,7 @@ export default { title: "wot.title", items: [ { path: "/membres", title: "membres", icon: "search" }, - { path: "/favoris", title: "favoris.title", icon: "user-group" } + { path: "/mes-suivis", title: "suivis.title", icon: "user-group" } ] }, { diff --git a/nuxt.config.js b/nuxt.config.js index 316cd0a98787ff318edad23b1c518dfff5811e1f..3031e2fa351275f6f8441ca6e972938c9a1e237c 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -127,7 +127,6 @@ export default { apollo: { clientConfigs: { - coindufeu: "~/graphql/endpoints/coindufeu", trentesaux: "~/graphql/endpoints/trentesaux" } }, diff --git a/package.json b/package.json index 56449c5b13f8739d12423e3778c88dfdcb61cf2e..aca3ec603312ad1be388eed638b271b3601eea5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wotwizard-ui", - "version": "2.4.2", + "version": "2.5.0", "private": true, "scripts": { "dev": "nuxt", diff --git a/pages/a-propos.vue b/pages/a-propos.vue index 930f3baa338092790f0587d786d10aca0e1d1f74..b4403f37aac99f43105212822c9e905fed651002 100644 --- a/pages/a-propos.vue +++ b/pages/a-propos.vue @@ -7,6 +7,31 @@ :title="$t('alert.information')"> <span v-html="$t('apropos.alert')"></span> </AlertDefault> + <div class="text-center my-4"> + <div class="btn-group" role="group"> + <a + href="https://wotwizard.axiom-team.fr" + target="_blank" + title="web version" + class="btn btn-secondary"> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> + <!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --> + <path + d="M352 256c0 22.2-1.2 43.6-3.3 64H163.3c-2.2-20.4-3.3-41.8-3.3-64s1.2-43.6 3.3-64H348.7c2.2 20.4 3.3 41.8 3.3 64zm28.8-64H503.9c5.3 20.5 8.1 41.9 8.1 64s-2.8 43.5-8.1 64H380.8c2.1-20.6 3.2-42 3.2-64s-1.1-43.4-3.2-64zm112.6-32H376.7c-10-63.9-29.8-117.4-55.3-151.6c78.3 20.7 142 77.5 171.9 151.6zm-149.1 0H167.7c6.1-36.4 15.5-68.6 27-94.7c10.5-23.6 22.2-40.7 33.5-51.5C239.4 3.2 248.7 0 256 0s16.6 3.2 27.8 13.8c11.3 10.8 23 27.9 33.5 51.5c11.6 26 21 58.2 27 94.7zm-209 0H18.6C48.6 85.9 112.2 29.1 190.6 8.4C165.1 42.6 145.3 96.1 135.3 160zM8.1 192H131.2c-2.1 20.6-3.2 42-3.2 64s1.1 43.4 3.2 64H8.1C2.8 299.5 0 278.1 0 256s2.8-43.5 8.1-64zM194.7 446.6c-11.6-26-20.9-58.2-27-94.6H344.3c-6.1 36.4-15.5 68.6-27 94.6c-10.5 23.6-22.2 40.7-33.5 51.5C272.6 508.8 263.3 512 256 512s-16.6-3.2-27.8-13.8c-11.3-10.8-23-27.9-33.5-51.5zM135.3 352c10 63.9 29.8 117.4 55.3 151.6C112.2 482.9 48.6 426.1 18.6 352H135.3zm358.1 0c-30 74.1-93.6 130.9-171.9 151.6c25.5-34.2 45.2-87.7 55.3-151.6H493.4z" /> + </svg> + </a> + <a + href="https://addons.mozilla.org/fr/firefox/addon/wotwizard-ui" + target="_blank" + title="Firefox extension" + class="btn btn-secondary"> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> + <path + d="M130.22 127.548C130.38 127.558 130.3 127.558 130.22 127.548V127.548ZM481.64 172.898C471.03 147.398 449.56 119.898 432.7 111.168C446.42 138.058 454.37 165.048 457.4 185.168C457.405 185.306 457.422 185.443 457.45 185.578C429.87 116.828 383.098 89.1089 344.9 28.7479C329.908 5.05792 333.976 3.51792 331.82 4.08792L331.7 4.15792C284.99 30.1109 256.365 82.5289 249.12 126.898C232.503 127.771 216.219 131.895 201.19 139.035C199.838 139.649 198.736 140.706 198.066 142.031C197.396 143.356 197.199 144.87 197.506 146.323C197.7 147.162 198.068 147.951 198.586 148.639C199.103 149.327 199.76 149.899 200.512 150.318C201.264 150.737 202.096 150.993 202.954 151.071C203.811 151.148 204.676 151.045 205.491 150.768L206.011 150.558C221.511 143.255 238.408 139.393 255.541 139.238C318.369 138.669 352.698 183.262 363.161 201.528C350.161 192.378 326.811 183.338 304.341 187.248C392.081 231.108 368.541 381.784 246.951 376.448C187.487 373.838 149.881 325.467 146.421 285.648C146.421 285.648 157.671 243.698 227.041 243.698C234.541 243.698 255.971 222.778 256.371 216.698C256.281 214.698 213.836 197.822 197.281 181.518C188.434 172.805 184.229 168.611 180.511 165.458C178.499 163.75 176.392 162.158 174.201 160.688C168.638 141.231 168.399 120.638 173.51 101.058C148.45 112.468 128.96 130.508 114.8 146.428H114.68C105.01 134.178 105.68 93.7779 106.25 85.3479C106.13 84.8179 99.022 89.0159 98.1 89.6579C89.5342 95.7103 81.5528 102.55 74.26 110.088C57.969 126.688 30.128 160.242 18.76 211.318C14.224 231.701 12 255.739 12 263.618C12 398.318 121.21 507.508 255.92 507.508C376.56 507.508 478.939 420.281 496.35 304.888C507.922 228.192 481.64 173.82 481.64 172.898Z" /> + </svg> + </a> + </div> + </div> <p class="lead"> {{ $t("apropos.desc") }} </p> @@ -130,7 +155,9 @@ export default { methods: { chemin(contrib) { if (this.hash_contrib[contrib] != "") { - return this.localePath("/membre?hash=" + this.hash_contrib[contrib]) + return this.localePath( + "/membres/profil?hash=" + this.hash_contrib[contrib] + ) } else { return this.localePath("/") } @@ -141,7 +168,8 @@ export default { fr: "/a-propos", en: "/about", es: "/a-proposito", - de: "/uber" + de: "/uber", + it: "/di" } }, mounted() { @@ -156,4 +184,8 @@ export default { border-top-width: thin; } } + +svg { + width: 50px; +} </style> diff --git a/pages/favoris.vue b/pages/favoris.vue deleted file mode 100644 index 34af878e1b4b3033f1df6b03ee629da1fa94d687..0000000000000000000000000000000000000000 --- a/pages/favoris.vue +++ /dev/null @@ -1,107 +0,0 @@ -<template> - <main class="container"> - <h2 class="text-center my-5 font-weight-light"> - <solid-user-group-icon style="width: 2rem" aria-hidden="true" /> {{ - $t("favoris.title") - }} - </h2> - <NavigationLoader :isLoading="$apollo.queries.favoris.loading" /> - <div class="row"> - <div class="col"> - <transition name="fade"> - <AlertDefault type="danger" v-if="error">{{ error }}</AlertDefault> - </transition> - <transition name="fade"> - <div - v-if=" - !$apollo.queries.favoris.loading && favoris && favoris.length != 0 - "> - <BtnSearch - v-if="favoris.length > 5" - @erase="search = ''" - v-model="search" - :help="$t('recherche.desc.favourites')" - class="col-sm-7 col-md-6 col-lg-5 col-xl-4 mx-auto mb-4" /> - <MemberFilter :selectedStatus.sync="filterStatus" /> - <MemberList - defaultSort="date_membership" - :members="filteredFavoris" - id="favoris" /> - </div> - </transition> - <transition name="fade"> - <div - class="alert alert-info" - v-if=" - !$apollo.queries.favoris.loading && favoris && favoris.length == 0 - "> - {{ $t("favoris.none") }} - </div> - </transition> - </div> - </div> - </main> -</template> - -<script> -import { FAVORIS } from "@/graphql/queries.js" - -export default { - data() { - return { - breadcrumb: [ - { - text: this.$t("accueil"), - to: "/" - }, - { - text: this.$t("favoris.title"), - active: true - } - ], - search: "", - error: null, - filterStatus: ["NEWCOMER", "MEMBER", "MISSING", "REVOKED"] - } - }, - computed: { - filteredFavoris() { - return this.favoris.filter( - (el) => - el.uid.toLowerCase().includes(this.search.toLowerCase()) && - this.filterStatus.includes(el.status) - ) - } - }, - apollo: { - $client() { - return this.getApolloClient - }, - favoris: { - query: FAVORIS, - variables() { - return { - group: this.$favourites.list - } - }, - update(data) { - return data.filterGroup.selected.map((el) => el.id) - }, - error(err) { - this.error = err.message - } - } - }, - nuxtI18n: { - paths: { - fr: "/favoris", - en: "/favourites", - es: "/favoritos", - de: "/favoriten" - } - }, - mounted() { - $nuxt.$emit("changeRoute", this.breadcrumb) - } -} -</script> diff --git a/pages/index.vue b/pages/index.vue index 40c21267428d2b10089da320edadff7a97865b28..0b8f09296372bd905904116a6f48721dc4fc913f 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -133,3 +133,9 @@ export default { } } </script> + +<style lang="scss"> +.result .table-responsive tbody { + max-height: 56vh; +} +</style> diff --git a/pages/lexique.vue b/pages/lexique.vue index e32ae481904baef121c09f44a1f4b44dc28be032..e0dd7c38f30634465de6b03c3e2623113f86a7f8 100644 --- a/pages/lexique.vue +++ b/pages/lexique.vue @@ -79,7 +79,8 @@ export default { fr: "/lexique", en: "/lexicon", es: "/lexico", - de: "/lexikon" + de: "/lexikon", + it: "/lessico" } }, methods: { diff --git a/pages/membres/index.vue b/pages/membres/index.vue index 18e0157e89444c654c70dae63313c326b57414d6..f4bc6d9a57ac1f4d04bdefe4eed95705b456d73d 100644 --- a/pages/membres/index.vue +++ b/pages/membres/index.vue @@ -20,7 +20,7 @@ </transition> <transition name="fade"> <div - class="row" + class="row result" v-if=" idSearch && param.length > 2 && !$apollo.queries.idSearch.loading "> @@ -79,7 +79,8 @@ export default { fr: "/membres", en: "/members", es: "/miembros", - de: "/mitglieder" + de: "/mitglieder", + it: "membri" } }, mounted() { diff --git a/pages/membre.vue b/pages/membres/profil.vue similarity index 61% rename from pages/membre.vue rename to pages/membres/profil.vue index fd0c819faacb99c6d45042c44c77921e8cdb4264..2d899f8d15121e094a8641950189f94f226a1f88 100644 --- a/pages/membre.vue +++ b/pages/membres/profil.vue @@ -40,7 +40,8 @@ export default { active: true } ], - error: null + error: null, + registeredAccount: {} } }, apollo: { @@ -69,11 +70,11 @@ export default { return { ...idFromHash, - sent_certifications: this.compileArrays( + sent_certifications: this.$favourites.compileArrays( idFromHash.all_certifiedIO, sent_certifications ), - received_certifications: this.compileArrays( + received_certifications: this.$favourites.compileArrays( idFromHash.all_certifiersIO, received_certifications ) @@ -84,62 +85,29 @@ export default { } } }, - methods: { - compileArrays(allIO, actualIO) { - let all = allIO.map(function (CertHist) { - return { - ...CertHist.id, - dateout: CertHist.hist - .filter((CertEvent) => !CertEvent.in) - .reduce( - function (prev, current) { - return prev.block.utc0 > current.block.utc0 ? prev : current - }, - { block: { utc0: 0 } } - ).block.utc0 - } - }) - - all.forEach((certifier) => { - let isFound = false - - for (const certif of actualIO) { - if (certifier.uid == certif.uid) { - isFound = true - break - } - } - - if (!isFound && certifier.status != "REVOKED") { - actualIO.push({ - __typename: "Certification", - expires_on: certifier.dateout, - ...certifier, - expired: true - }) - } - }) - - return actualIO - } - }, nuxtI18n: { paths: { - fr: "/membre", - en: "/member", - es: "/miembro", - de: "/mitglied" + fr: "/membres/profil", + en: "/members/profile", + es: "/miembros/perfil", + de: "/mitglieder/profil", + it: "/membri/profilo" } }, mounted() { $nuxt.$emit("changeRoute", this.breadcrumb) + this.registeredAccount = JSON.parse(localStorage.getItem("my_account")) || { + hash: "", + uid: "" + } }, watch: { - idFromHash: { - handler(n, o) { - this.breadcrumb[2].text = this.idFromHash.uid - $nuxt.$emit("changeRoute", this.breadcrumb) - } + idFromHash(n, o) { + this.breadcrumb[2].text = this.idFromHash.uid + $nuxt.$emit("changeRoute", this.breadcrumb) + }, + registeredAccount(n, o) { + localStorage.setItem("my_account", JSON.stringify(n)) } } } diff --git a/pages/mes-suivis.vue b/pages/mes-suivis.vue new file mode 100644 index 0000000000000000000000000000000000000000..57e4934bb389dbeca4b6bb593819d4d2c78bfb55 --- /dev/null +++ b/pages/mes-suivis.vue @@ -0,0 +1,322 @@ +<template> + <main class="container"> + <h2 class="text-center my-5 font-weight-light"> + <solid-user-group-icon style="width: 2rem" aria-hidden="true" /> {{ + $t("suivis.title") + }} + </h2> + <div v-if="currentAccount.hash == ''"> + <AlertDefault + type="info" + :title="$t('suivis.alert.title')" + icon="exclamation"> + {{ $t("suivis.alert.desc") }} + <br /> + <NuxtLink :to="localePath('membres')" class="btn btn-info mt-3"> + <solid-search-icon width="1.5rem" /> {{ $t("suivis.alert.btn") }} + </NuxtLink> + </AlertDefault> + </div> + <div v-else> + <div class="row"> + <div class="col text-center"> + <NuxtLink + class="btn btn-secondary mb-4" + :to="localePath('/membres/profil?hash=' + currentAccount.hash)"> + <solid-user-circle-icon class="icon" aria-hidden="true" /> + {{ $t("suivis.voir_profil") }} ({{ currentAccount.uid }}) + </NuxtLink> + <ul class="nav nav-tabs nav-justified" id="suivis" role="tablist"> + <li class="nav-item" role="presentation"> + <button + class="nav-link active" + id="favoris" + @click="pushRoute($event)" + data-bs-toggle="tab" + data-bs-target="#favoris-tab-pane" + type="button" + role="tab" + aria-controls="favoris-tab-pane" + aria-selected="true"> + {{ $t("suivis.tabs.favoris") }} ({{ $favourites.list.length }}) + </button> + </li> + <li class="nav-item" role="presentation"> + <button + class="nav-link" + id="certificateurs" + @click="pushRoute($event)" + data-bs-toggle="tab" + data-bs-target="#certificateurs-tab-pane" + type="button" + role="tab" + aria-controls="certificateurs-tab-pane" + aria-selected="false"> + {{ $t("suivis.tabs.certificateurs") }} + <span v-if="!$apollo.queries.contacts.loading"> + ({{ contacts.received_certifications.length }}) + </span> + </button> + </li> + <li class="nav-item" role="presentation"> + <button + class="nav-link" + id="certifies" + @click="pushRoute($event)" + data-bs-toggle="tab" + data-bs-target="#certifies-tab-pane" + type="button" + role="tab" + aria-controls="certifies-tab-pane" + aria-selected="false"> + {{ $t("suivis.tabs.certifies") }} + <span v-if="!$apollo.queries.contacts.loading"> + ({{ contacts.sent_certifications.length }}) + </span> + </button> + </li> + </ul> + <div class="tab-content"> + <div + class="tab-pane fade show active" + id="favoris-tab-pane" + role="tabpanel" + aria-labelledby="favoris" + tabindex="0"> + <NavigationLoader :isLoading="$apollo.queries.favoris.loading" /> + <transition name="fade"> + <AlertDefault type="danger" v-if="error">{{ + error + }}</AlertDefault> + </transition> + <SuivisTableau :members="favoris" type="favoris" /> + </div> + <div + class="tab-pane fade" + id="certificateurs-tab-pane" + role="tabpanel" + aria-labelledby="certificateurs" + tabindex="0"> + <NavigationLoader :isLoading="$apollo.queries.contacts.loading" /> + <transition name="fade"> + <AlertDefault type="danger" v-if="error">{{ + error + }}</AlertDefault> + </transition> + <transition name="fade"> + <div v-if="!$apollo.queries.contacts.loading"> + <SuivisTableau + :members="contacts.received_certifications" + type="certificateurs" /> + </div> + </transition> + </div> + <div + class="tab-pane fade" + id="certifies-tab-pane" + role="tabpanel" + aria-labelledby="certifies" + tabindex="0"> + <NavigationLoader :isLoading="$apollo.queries.contacts.loading" /> + <transition name="fade"> + <AlertDefault type="danger" v-if="error">{{ + error + }}</AlertDefault> + </transition> + <transition name="fade"> + <div v-if="!$apollo.queries.contacts.loading"> + <SuivisTableau + :members="contacts.sent_certifications" + type="certifies" /> + </div> + </transition> + </div> + </div> + </div> + </div> + </div> + </main> +</template> + +<script> +import Tab from "~/node_modules/bootstrap/js/dist/tab" +import { SEARCH_MEMBER, MEMBERS } from "@/graphql/queries" + +export default { + data() { + return { + breadcrumb: [ + { + text: this.$t("accueil"), + to: "/" + }, + { + text: this.$t("suivis.title"), + active: true + } + ], + error: null + } + }, + computed: { + currentAccount() { + const account = JSON.parse(localStorage.getItem("my_account")) || { + hash: "", + uid: "" + } + return account + } + }, + apollo: { + $client() { + return this.getApolloClient + }, + favoris: { + query: MEMBERS, + variables() { + return { + group: this.$favourites.list + } + }, + update(data) { + return data.filterGroup.selected.map((el) => { + return { + ...el.id, + status: + this.$options.filters.dateStatus(el.id.limitDate) == "warning" && + el.id.status != "NEWCOMER" + ? "RENEW" + : el.id.status, + expired: false + } + }) + }, + error(err) { + this.error = err.message + } + }, + contacts: { + query: SEARCH_MEMBER, + variables() { + return { + hash: this.currentAccount.hash + } + }, + update(data) { + if (!data.idFromHash) return {} + let idFromHash = data.idFromHash + + let received_certifications = this.$favourites + .compileArrays( + idFromHash.all_certifiersIO, + idFromHash.received_certifications.map((certif) => ({ + ...certif, + ...certif.from + })) + ) + .map((el) => { + const ret = el.from ? el.from : el + const member = el.id ? el.id : el + + return { + ...ret, + status: + this.$options.filters.dateStatus(member.limitDate) == + "warning" && member.status != "NEWCOMER" + ? "RENEW" + : member.status, + expired: member.expired || false + } + }) + + let sent_certifications = this.$favourites + .compileArrays( + idFromHash.all_certifiedIO, + idFromHash.sent_certifications.map((certif) => ({ + ...certif, + ...certif.to + })) + ) + .map((el) => { + const ret = el.to ? el.to : el + const member = el.id ? el.id : el + + return { + ...ret, + status: + this.$options.filters.dateStatus(member.limitDate) == + "warning" && member.status != "NEWCOMER" + ? "RENEW" + : member.status, + expired: member.expired || false + } + }) + + return { + sent_certifications, + received_certifications + } + }, + error(err) { + this.error = err.message + } + } + }, + methods: { + saveUID() { + localStorage.setItem("UID", document.getElementById("UID").value) + }, + showPane(pane) { + const panel = new Tab(pane) + + if (panel) panel.show() + }, + pushRoute(e) { + this.$router.push( + this.localePath({ + name: "mes-suivis", + hash: "#" + e.target.id + }) + ) + } + }, + nuxtI18n: { + paths: { + fr: "/mes-suivis", + en: "/my-follow-ups", + es: "/mis-seguimientos", + de: "/meine-nachfolge", + it: "/i-miei-follow-up" + } + }, + mounted() { + $nuxt.$emit("changeRoute", this.breadcrumb) + + const $this = this + document.querySelectorAll('button[data-bs-toggle="tab"]').forEach((el) => { + el.addEventListener("shown.bs.tab", function (event) { + $this.$favourites.fixColumns() + }) + }) + + if (this.$route.hash && this.currentAccount.hash != "") { + this.showPane(this.$route.hash) + } + }, + watch: { + $route(n, o) { + this.showPane(n.hash ? n.hash : "#favoris") + } + } +} +</script> + +<style lang="scss"> +#suivis { + flex-direction: column; + + @media (min-width: 768px) { + flex-direction: row; + } +} +</style> diff --git a/pages/parametres.vue b/pages/parametres.vue index 62ebdacba3eb7d64710b4c40bc6e5caf696d29dd..652db797bf5517e9554059903720e446e73b1ff1 100644 --- a/pages/parametres.vue +++ b/pages/parametres.vue @@ -113,7 +113,8 @@ export default { fr: "/parametres", en: "/parameters", es: "/parametros", - de: "/einstellungen" + de: "/einstellungen", + it: "/impostazioni" } }, mounted() { diff --git a/pages/previsions/futures_entrees.vue b/pages/previsions/futures_entrees.vue index a6d1155491e13f408ee781896d3f2859719d1eff..302da1c16821bfa2817a62cc92d5dee880b6d06b 100644 --- a/pages/previsions/futures_entrees.vue +++ b/pages/previsions/futures_entrees.vue @@ -58,7 +58,7 @@ @click=" $router.push( localePath({ - name: 'membre', + name: 'membres-profil', query: { hash: forecast.member.hash } }) ) @@ -66,7 +66,7 @@ @keyup.enter=" $router.push( localePath({ - name: 'membre', + name: 'membres-profil', query: { hash: forecast.member.hash } }) ) @@ -135,7 +135,9 @@ class="list-group-item list-group-item-action border-0 d-flex justify-content-between align-items-center" :title="$t('membre.voirinfos')" :to=" - localePath('/membre/?hash=' + member.member.hash) + localePath( + '/membres/profil/?hash=' + member.member.hash + ) " v-for="member in forecast.forecasts" :key="member.member.uid"> @@ -285,9 +287,10 @@ export default { nuxtI18n: { paths: { fr: "/previsions/futures_entrees", - en: "/forecasts/future_exits2", - es: "/pronosticos/futuras_salidas2", - de: "/prognosen/zukunftige_veroffentlichungen2" + en: "/forecasts/future_exits", + es: "/pronosticos/futuras_salidas", + de: "/prognosen/zukunftige_veroffentlichungen", + it: "/previsioni/ingressi-futuri" } }, mounted() { diff --git a/pages/previsions/futures_sorties.vue b/pages/previsions/futures_sorties.vue index c5d5218bea132528b430a371efdfd8d18d21f724..1123ab6b0d154235e94aa85e9f8230081082923f 100644 --- a/pages/previsions/futures_sorties.vue +++ b/pages/previsions/futures_sorties.vue @@ -14,7 +14,7 @@ v-model="favoris" @change="save()" /> <label for="favoris" class="form-check-label">{{ - $t("favoris.use") + $t("suivis.use") }}</label> </div> <NavigationLoader :isLoading="$apollo.loading" /> @@ -22,7 +22,7 @@ <AlertDefault type="danger" v-if="error">{{ error }}</AlertDefault> </transition> <transition name="fade"> - <div class="row" v-if="!$apollo.loading"> + <div class="row result" v-if="!$apollo.loading"> <div class="col-md-6 mb-5" v-if="memEnds"> <h2 class="h4 text-danger text-center text-truncate"> {{ $t("statut.renew") }} @@ -115,7 +115,8 @@ export default { fr: "/previsions/futures_sorties", en: "/forecasts/future_exits", es: "/pronosticos/futuras_salidas", - de: "/prognosen/zukunftige_veroffentlichungen" + de: "/prognosen/zukunftige_veroffentlichungen", + it: "/previsioni/future-uscite" } }, mounted() { diff --git a/plugins/bootstrap.js b/plugins/bootstrap.js index eb028a58516500ee6a239429caf6984a555fd66b..5c8a2ad31464761b67702a1741e34622d6c4de45 100644 --- a/plugins/bootstrap.js +++ b/plugins/bootstrap.js @@ -27,13 +27,11 @@ Vue.directive("tooltip", function (el, binding, vnode) { trigger: "hover" }) - vnode.context.$nextTick(() => { - var x = new MutationObserver(function (e) { - if (e[0].removedNodes) tooltip.hide() - }); - - x.observe(el.parentNode, { childList: true }) - - }); + // vnode.context.$nextTick(() => { + // var x = new MutationObserver(function (e) { + // if (e[0].removedNodes) tooltip.hide() + // }) + // x.observe(el.parentNode, { childList: true }) + // }) } }) diff --git a/plugins/favourites.js b/plugins/favourites.js index 23f56b501a46a98dd8c84e32fef8aafa1480cb02..219cf51f597fdcf47f30654d6c563c579d1387cf 100644 --- a/plugins/favourites.js +++ b/plugins/favourites.js @@ -24,12 +24,68 @@ export default (context, inject) => { } } + let compileArrays = (allIO, actualIO) => { + let all = allIO.map(function (CertHist) { + return { + ...CertHist.id, + dateout: CertHist.hist + .filter((CertEvent) => !CertEvent.in) + .reduce( + function (prev, current) { + return prev.block.utc0 > current.block.utc0 ? prev : current + }, + { block: { utc0: 0 } } + ).block.utc0 + } + }) + + all.forEach((certifier) => { + let isFound = false + + for (const certif of actualIO) { + if (certifier.uid == certif.uid) { + isFound = true + break + } + } + + if (!isFound && certifier.status != "REVOKED") { + actualIO.push({ + __typename: "Certification", + expires_on: certifier.dateout, + ...certifier, + expired: true + }) + } + }) + + return actualIO + } + + let fixColumns = () => { + let tables = document.querySelectorAll(".table-responsive table") + + tables.forEach((table) => { + let colWidth = [...table.querySelectorAll("tbody tr:first-child td")].map( + function (el) { + return el.offsetWidth + } + ) + + table.querySelectorAll("thead tr th").forEach((el, i) => { + el.style.width = colWidth[i] - 0.5 + "px" + }) + }) + } + inject( "favourites", Vue.observable({ list: liste_favoris, toggleFavourite: toggleFavourite, - addFavorisArray: addFavorisArray + addFavorisArray: addFavorisArray, + compileArrays: compileArrays, + fixColumns: fixColumns }) ) } diff --git a/plugins/getApolloClient.js b/plugins/getApolloClient.js index 0ce80661c44c94746255c65b04d67d33cf7625ec..0e1981fd99aa11d1796fc2ac01449591e1ac0fe6 100644 --- a/plugins/getApolloClient.js +++ b/plugins/getApolloClient.js @@ -3,10 +3,7 @@ import Vue from "vue" let mixin = { computed: { getApolloClient() { - return ( - localStorage.getItem("apollo-client") || - Object.keys($nuxt.$apolloProvider.clients)[0] - ) + return localStorage.getItem("apollo-client") || "trentesaux" } } } diff --git a/web-ext/manifest.json b/web-ext/manifest.json index 68b4a3905eacec53e99a2bea8d194c3898a7b323..8c4605a8f26b4a5c9a1a3556a25119acfe8f7e79 100644 --- a/web-ext/manifest.json +++ b/web-ext/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Wotwizard UI", "description": "Le magicien de la toile de confiance", - "version": "2.4.2", + "version": "2.4.3", "homepage_url": "https://wotwizard.axiom-team.fr", "browser_action": { "browser_style": true,