<template> <t-dropdown toggle-on-hover :hide-on-leave-timeout="0" :show.sync="show" :classes="{ dropdown: 'absolute right-0 rounded-md shadow-lg bg-white dark:bg-gray-600 border-gray-100 dark:border-gray-500 border transform translate-y-1', }" > <div slot="trigger" class="flex items-center ml-5"> <button type="button" aria-label="User menu" aria-haspopup="true" class="h-8 w-8 focus:ring-2 focus:outline-none rounded-full" > <img v-if="user" :src="user.avatar_url" class="rounded-full" /> <fa v-else icon="user-circle" class="text-3xl" /> </button> <fa icon="caret-down" class="pl-1.5" /> </div> <div class="my-1" style="min-width: 15rem"> <template v-if="user"> <div class="px-3 py-2"> <div>{{ user.name }}</div> <div class="text-sm text-gray-600 dark:text-gray-400"> @{{ user.username }} </div> </div> <hr class="border-t dark:border-gray-500 my-1" /> <a class="menu-item" href="/admin/#/" target="_blank" ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current text-gray-400 mr-1" > <path d="m13.366 3 5.625 5.493L19 19.169C19 20.176 18.156 21 17.125 21H5.865C4.836 21 4 20.176 4 19.17V4.83C4 3.825 4.834 3 5.866 3h7.5zM6.94 12.11a.94.94 0 1 0 0 1.88h9.12a.94.94 0 0 0 0-1.88H6.94zm0 3.89a.94.94 0 1 0 0 1.88h9.12a.94.94 0 1 0 0-1.88H6.94zm5.073-6h5.139l-5.14-5.053V10z" ></path></svg >Contenus </a> <a class="menu-item justify-between" href="/admin/#/workflow" target="_blank" > <div class="flex items-center"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current text-gray-400 mr-1.5" > <path d="M10 4h3a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zm7 0h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM3 4h3a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z" ></path></svg >Flux </div> <div v-if="git"> <span class="bg-purple-200 text-purple-800 font-medium py-0.5 px-1 text-sm rounded" v-text="git.draft.count" /> <span class="bg-yellow-200 text-yellow-800 font-medium py-0.5 px-1 text-sm rounded" v-text="git.pending_review.count" /> <span class="bg-green-200 text-green-800 font-medium py-0.5 px-1 text-sm rounded" v-text="git.pending_publish.count" /> </div> </a> <hr class="border-t dark:border-gray-500 my-1" /> <a class="menu-item justify-between" href="https://git.duniter.org/websites/monnaie-libre-fr" target="_blank" > <div>Dépôt gitlab</div> <span v-if="isLoading === true" class="loading-state h-6 w-6 border-gray-500" /> <fa v-if="isLoading === 'error'" icon="exclamation-triangle" class="w-3 ml-1.5 text-gray-500 opacity-75" /> </a> <template v-if="git"> <div class="flex text-xs"> <a class="menu-item whitespace-nowrap" href="https://git.duniter.org/websites/monnaie-libre-fr/-/issues" target="_blank" v-text="`${git.issueStatusCounts.opened} tickets`" /> <a class="menu-item whitespace-nowrap" href="https://git.duniter.org/websites/monnaie-libre-fr/-/merge_requests" target="_blank" v-text="`${git.mergeRequests.count} demandes de fusion`" /> </div> <a class="menu-item justify-between" :href="`https://git.duniter.org/websites/monnaie-libre-fr/-/issues?scope=all&utf8=%E2%9C%93&state=opened&author_username=${user.username}`" target="_blank" > <div>Mes tickets</div> <div class="bg-gray-200 text-gray-800 font-medium w-5 h-5 text-center text-sm rounded-full" v-text="git.my_issues.count" /> </a> <a class="menu-item justify-between" :href="`https://git.duniter.org/websites/monnaie-libre-fr/-/merge_requests?scope=all&utf8=%E2%9C%93&state=opened&author_username=${user.username}`" target="_blank" > <div>Mes demandes de fusion</div> <div class="bg-gray-200 text-gray-800 font-medium w-5 h-5 text-center text-sm rounded-full" v-text="git.my_merge_requests.count" /> </a> </template> </template> <template v-else> <a href="/admin/#/" target="_blank" class="menu-item group" @click="fetchLocalStorageChange" > <span>Se connecter</span> <fa icon="external-link-alt" class="w-3 ml-1.5 text-gray-500 opacity-75" /> </a> <nuxt-link to="/contribuer" class="menu-item"> <span>Contribuer</span> </nuxt-link> </template> <hr class="border-t dark:border-gray-500 my-1" /> <div class="flex"> <nuxt-link to="/aide" class="menu-item"> <fa icon="info-circle" class="text-gray-400 mr-2" /> <span>Aide</span> </nuxt-link> <AppA11y class="ml-2" /> </div> </div> </t-dropdown> </template> <script> export default { name: 'LayoutHeaderMenuAvatar', data() { return { show: false, user: null, git: null, lastFetch: null, isLoading: false, } }, watch: { show(newVal) { // Debounce fetch under 10s if (newVal && this.user && Date.now() - this.lastFetch > 10000) { // Fetch gitlab data this.fetchGitlab() } }, }, mounted() { this.fetchCmsUser() }, methods: { fetchCmsUser() { if (localStorage.getItem('netlify-cms-user')) { this.user = JSON.parse(localStorage.getItem('netlify-cms-user')) } }, // if User click on "Connect" link, wait for authentification fetchLocalStorageChange() { setInterval(() => { this.fetchCmsUser() }, 1000) }, fetchGitlab() { this.isLoading = true this.$axios .$post('https://git.duniter.org/api/graphql', { query: `#graphql query projectML($authorUsername: String) { project(fullPath: "websites/monnaie-libre-fr") { lastActivityAt issueStatusCounts { opened } mergeRequests(state: opened) { count } my_issues: issues(authorUsername: $authorUsername, state: opened) { count } my_merge_requests:mergeRequests(authorUsername: $authorUsername, state: opened) { count } draft: mergeRequests(labels: "netlify-cms/draft", state: opened) { count } pending_review: mergeRequests(labels: "netlify-cms/pending_review", state: opened) { count } pending_publish: mergeRequests(labels: "netlify-cms/pending_publish", state: opened) { count } } } `, variables: { authorUsername: this.user.username, }, }) .then(({ data }) => { this.git = data.project this.lastFetch = Date.now() this.isLoading = false }) .catch(() => { this.isLoading = 'error' }) }, }, } </script> <style lang="postcss" scoped> .menu-item { @apply flex items-center hover:bg-hover-light hover:text-gray-700 px-3 py-1 text-gray-600 dark:text-gray-200 w-full; } </style>