Skip to content
Snippets Groups Projects
Forked from websites / monnaie-libre-fr
1561 commits behind the upstream repository.
LayoutHeaderMenuAvatar.vue 8.25 KiB
<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>