From 602382b8648ed3083dba0816d6b02d4ab962127b Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Sun, 29 Apr 2018 23:19:09 +0200
Subject: [PATCH] Better contrast on new sidebar, added labels with
 notifications

---
 changes/changelog.d/sidebar.enhancement  |  2 +-
 front/src/components/Sidebar.vue         | 91 ++++++++++++++++++++++--
 front/src/components/library/Library.vue | 23 +-----
 3 files changed, 87 insertions(+), 29 deletions(-)

diff --git a/changes/changelog.d/sidebar.enhancement b/changes/changelog.d/sidebar.enhancement
index 280aaed51..1bc1a482f 100644
--- a/changes/changelog.d/sidebar.enhancement
+++ b/changes/changelog.d/sidebar.enhancement
@@ -1 +1 @@
-More structured menus in sidebar
+More structured menus in sidebar, added labels with notifications
diff --git a/front/src/components/Sidebar.vue b/front/src/components/Sidebar.vue
index 94815372e..8e0df8016 100644
--- a/front/src/components/Sidebar.vue
+++ b/front/src/components/Sidebar.vue
@@ -30,7 +30,7 @@
   </div>
   <div class="tabs">
     <div class="ui bottom attached active tab" data-tab="library">
-      <div class="ui inverted vertical fluid menu">
+      <div class="ui inverted vertical large fluid menu">
         <div class="item">
           <div class="header">{{ $t('My account') }}</div>
           <div class="menu">
@@ -55,12 +55,29 @@
               class="item" :to="{path: '/activity'}"><i class="bell icon"></i> {{ $t('Activity') }}</router-link>
           </div>
         </div>
-        <div class="item" v-if="$store.state.auth.availablePermissions['federation.manage']">
+        <div class="item" v-if="showAdmin">
           <div class="header">{{ $t('Administration') }}</div>
           <div class="menu">
             <router-link
               class="item"
-              :to="{path: '/manage/federation/libraries'}"><i class="sitemap icon"></i> {{ $t('Federation') }}</router-link>
+              v-if="$store.state.auth.availablePermissions['import.launch']"
+              :to="{name: 'library.requests', query: {status: 'pending' }}">
+              <i class="download icon"></i> {{ $t('Import requests') }}
+              <div
+                :class="['ui', {'teal': notifications.importRequests > 0}, 'label']"
+                :title="$t('Pending import requests')">
+                {{ notifications.importRequests }}</div>
+            </router-link>
+            <router-link
+              class="item"
+              v-if="$store.state.auth.availablePermissions['federation.manage']"
+              :to="{path: '/manage/federation/libraries'}">
+              <i class="sitemap icon"></i> {{ $t('Federation') }}
+              <div
+                :class="['ui', {'teal': notifications.federation > 0}, 'label']"
+                :title="$t('Pending follow requests')">
+                {{ notifications.federation }}</div>
+            </router-link>
           </div>
         </div>
       </div>
@@ -119,6 +136,7 @@
 
 <script>
 import {mapState, mapActions} from 'vuex'
+import axios from 'axios'
 
 import Player from '@/components/audio/Player'
 import Logo from '@/components/Logo'
@@ -140,22 +158,69 @@ export default {
     return {
       selectedTab: 'library',
       backend: backend,
-      isCollapsed: true
+      isCollapsed: true,
+      fetchInterval: null,
+      notifications: {
+        federation: 0,
+        importRequests: 0
+      }
     }
   },
   mounted () {
     $(this.$el).find('.menu .item').tab()
   },
+  created () {
+    this.fetchNotificationsCount()
+    this.fetchInterval = setInterval(
+        this.fetchNotificationsCount, 1000 * 60 * 15)
+  },
+  destroy () {
+    if (this.fetchInterval) {
+      clearInterval(this.fetchInterval)
+    }
+  },
   computed: {
     ...mapState({
       queue: state => state.queue,
       url: state => state.route.path
-    })
+    }),
+    showAdmin () {
+      let adminPermissions = [
+        this.$store.state.auth.availablePermissions['federation.manage'],
+        this.$store.state.auth.availablePermissions['import.launch']
+      ]
+      return adminPermissions.filter(e => {
+        return e
+      }).length > 0
+    }
   },
   methods: {
     ...mapActions({
       cleanTrack: 'queue/cleanTrack'
     }),
+    fetchNotificationsCount () {
+      this.fetchFederationNotificationsCount()
+      this.fetchFederationImportRequestsCount()
+    },
+    fetchFederationNotificationsCount () {
+      if (!this.$store.state.auth.availablePermissions['federation.manage']) {
+        return
+      }
+      let self = this
+      axios.get('federation/libraries/followers/', {params: {pending: true}}).then(response => {
+        self.notifications.federation = response.data.count
+      })
+    },
+    fetchFederationImportRequestsCount () {
+      if (!this.$store.state.auth.availablePermissions['import.launch']) {
+        return
+      }
+      let self = this
+      axios.get('requests/import-requests/', {params: {status: 'pending'}}).then(response => {
+        console.log('YOLo')
+        self.notifications.importRequests = response.data.count
+      })
+    },
     reorder: function (event) {
       this.$store.commit('queue/reorder', {
         oldIndex: event.oldIndex, newIndex: event.newIndex})
@@ -188,6 +253,13 @@ export default {
       if (this.selectedTab !== 'queue') {
         this.scrollToCurrent()
       }
+    },
+    '$store.state.availablePermissions': {
+      handler () {
+        console.log('YOLO')
+        this.fetchNotificationsCount()
+      },
+      deep: true
     }
   }
 }
@@ -197,7 +269,7 @@ export default {
 <style scoped lang="scss">
 @import '../style/vendor/media';
 
-$sidebar-color: #3D3E3F;
+$sidebar-color: #3d3e3f;
 
 .sidebar {
 	background: $sidebar-color;
@@ -249,6 +321,13 @@ $sidebar-color: #3D3E3F;
 .vertical.menu {
   .item .item {
     font-size: 1em;
+    > i.icon {
+      float: none;
+      margin: 0 0.5em 0 0;
+    }
+    &:not(.active) {
+      color: rgba(255, 255, 255, 0.75);
+    }
   }
 }
 .tabs {
diff --git a/front/src/components/library/Library.vue b/front/src/components/library/Library.vue
index fb5cc87ce..820d60a54 100644
--- a/front/src/components/library/Library.vue
+++ b/front/src/components/library/Library.vue
@@ -12,7 +12,6 @@
           :to="{name: 'library.requests', query: {status: 'pending' }}"
           exact>
           <i18next path="Requests"/>
-          <div class="ui teal label">{{ requestsCount }}</div>
         </router-link>
         <router-link v-if="$store.state.auth.availablePermissions['import.launch']" class="ui item" to="/library/import/launch" exact>
           <i18next path="Import"/>
@@ -27,28 +26,8 @@
 </template>
 
 <script>
-import axios from 'axios'
 export default {
-  name: 'library',
-  data () {
-    return {
-      requestsCount: 0
-    }
-  },
-  created () {
-    this.fetchRequestsCount()
-  },
-  methods: {
-    fetchRequestsCount () {
-      if (!this.$store.state.authenticated) {
-        return
-      }
-      let self = this
-      axios.get('requests/import-requests/', {params: {status: 'pending'}}).then(response => {
-        self.requestsCount = response.data.count
-      })
-    }
-  }
+  name: 'library'
 }
 </script>
 
-- 
GitLab