diff --git a/front/src/components/common/ActionTable.vue b/front/src/components/common/ActionTable.vue
index b9822ca4de4ea57a38c3b43e5e581a20ef4bf207..718e57b19b61672913d0de6145ec7447c69ac0cf 100644
--- a/front/src/components/common/ActionTable.vue
+++ b/front/src/components/common/ActionTable.vue
@@ -1,29 +1,42 @@
 <template>
   <table class="ui compact very basic single line unstackable table">
     <thead>
-      <tr v-if="actions.length > 0 && objectsData.count > 0">
+      <tr v-if="actions.length > 0">
         <th colspan="1000">
           <div class="ui small form">
             <div class="ui inline fields">
               <div class="field">
                 <label>{{ $t('Actions') }}</label>
-                <select class="ui dropdown" v-model="currentAction">
-                  <option v-for="action in actions" :value="action[0]">
-                    {{ action[1] }}
+                <select class="ui dropdown" v-model="currentActionName">
+                  <option v-for="action in actions" :value="action.name">
+                    {{ action.label }}
                   </option>
                 </select>
               </div>
               <div class="field">
                 <div
+                  v-if="!selectAll"
                   @click="launchAction"
                   :disabled="checked.length === 0"
                   :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
                   {{ $t('Go') }}</div>
+                <dangerous-button
+                  v-else :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
+                  confirm-color="green"
+                  color=""
+                  @confirm="launchAction">
+                  {{ $t('Go') }}
+                  <p slot="modal-header">{{ $t('Do you want to launch action "{% action %}" on {% total %} elements?', {action: currentActionName, total: objectsData.count}) }}
+                  <p slot="modal-content">
+                    {{ $t('This may affect a lot of elements, please double check this is really what you want.')}}
+                  </p>
+                  <p slot="modal-confirm">{{ $t('Launch') }}</p>
+                </dangerous-button>
               </div>
               <div class="count field">
                 <span v-if="selectAll">{{ $t('{% count %} on {% total %} selected', {count: objectsData.count, total: objectsData.count}) }}</span>
                 <span v-else>{{ $t('{% count %} on {% total %} selected', {count: checked.length, total: objectsData.count}) }}</span>
-                <template v-if="checked.length === objectsData.results.length">
+                <template v-if="checkable.length === checked.length">
                   <a @click="selectAll = true" v-if="!selectAll">
                     {{ $t('Select all {% total %} elements', {total: objectsData.count}) }}
                   </a>
@@ -53,18 +66,20 @@
             <input
               type="checkbox"
               @change="toggleCheckAll"
-              :checked="objectsData.results.length === checked.length"><label>&nbsp;</label>
+              :disabled="checkable.length === 0"
+              :checked="checkable.length > 0 && checked.length === checkable.length"><label>&nbsp;</label>
           </div>
         </th>
         <slot name="header-cells"></slot>
       </tr>
     </thead>
-    <tbody>
-      <tr v-for="obj in objectsData.results">
+    <tbody v-if="objectsData.count > 0">
+      <tr v-for="(obj, index) in objectsData.results">
         <td class="collapsing">
           <input
             type="checkbox"
-            @change="toggleCheck(obj.id)"
+            :disabled="checkable.indexOf(obj.id) === -1"
+            @click="toggleCheck($event, obj.id, index)"
             :checked="checked.indexOf(obj.id) > -1"><label>&nbsp;</label>
           </div>
         </td>
@@ -90,38 +105,60 @@ export default {
       actionLoading: false,
       actionResult: null,
       actionErrors: [],
-      currentAction: null,
-      selectAll: false
+      currentActionName: null,
+      selectAll: false,
+      lastCheckedIndex: -1
     }
     if (this.actions.length > 0) {
-      d.currentAction = this.actions[0][0]
+      d.currentActionName = this.actions[0].name
     }
     return d
   },
   methods: {
     toggleCheckAll () {
-      if (this.checked.length === this.objectsData.results.length) {
+      this.lastCheckedIndex = -1
+      if (this.checked.length === this.checkable.length) {
         // we uncheck
         this.checked = []
       } else {
-        this.checked = this.objectsData.results.map(t => { return t.id })
+        this.checked = this.checkable.map(i => { return i })
       }
     },
-    toggleCheck (id) {
+    toggleCheck (event, id, index) {
+      let self = this
+      let affectedIds = [id]
+      let newValue = null
       if (this.checked.indexOf(id) > -1) {
         // we uncheck
         this.selectAll = false
-        this.checked.splice(this.checked.indexOf(id), 1)
+        newValue = false
       } else {
-        this.checked.push(id)
+        newValue = true
+      }
+      if (event.shiftKey && this.lastCheckedIndex > -1) {
+        // we also add inbetween ids to the list of affected ids
+        let idxs = [index, this.lastCheckedIndex]
+        idxs.sort((a, b) => a - b)
+        let objs = this.objectsData.results.slice(idxs[0], idxs[1] + 1)
+        affectedIds = affectedIds.concat(objs.map((o) => { return o.id }))
       }
+      affectedIds.forEach((i) => {
+        let checked = self.checked.indexOf(i) > -1
+        if (newValue && !checked && self.checkable.indexOf(i) > -1) {
+          return self.checked.push(i)
+        }
+        if (!newValue && checked) {
+          self.checked.splice(self.checked.indexOf(i), 1)
+        }
+      })
+      this.lastCheckedIndex = index
     },
     launchAction () {
       let self = this
       self.actionLoading = true
       self.result = null
       let payload = {
-        action: this.currentAction,
+        action: this.currentActionName,
         filters: this.filters
       }
       if (this.selectAll) {
@@ -132,11 +169,39 @@ export default {
       axios.post(this.actionUrl, payload).then((response) => {
         self.actionResult = response.data
         self.actionLoading = false
+        self.$emit('action-launched', response.data)
       }, error => {
         self.actionLoading = false
         self.actionErrors = error.backendErrors
       })
     }
+  },
+  computed: {
+    currentAction () {
+      let self = this
+      return this.actions.filter((a) => {
+        return a.name === self.currentActionName
+      })[0]
+    },
+    checkable () {
+      let objs = this.objectsData.results
+      let filter = this.currentAction.filterCheckable
+      if (filter) {
+        objs = objs.filter((o) => {
+          return filter(o)
+        })
+      }
+      return objs.map((o) => { return o.id })
+    }
+  },
+  watch: {
+    objectsData: {
+      handler () {
+        this.checked = []
+        this.selectAll = false
+      },
+      deep: true
+    }
   }
 }
 </script>
diff --git a/front/src/components/common/DangerousButton.vue b/front/src/components/common/DangerousButton.vue
index 690291d5b1d08abaa60f8576fce71b25a73f1047..52fcdca6136528bea7cb7b36125074654e62800e 100644
--- a/front/src/components/common/DangerousButton.vue
+++ b/front/src/components/common/DangerousButton.vue
@@ -13,7 +13,7 @@
       </div>
       <div class="actions">
         <div class="ui cancel button"><i18next path="Cancel"/></div>
-        <div :class="['ui', 'confirm', color, 'button']" @click="confirm">
+        <div :class="['ui', 'confirm', confirmButtonColor, 'button']" @click="confirm">
           <slot name="modal-confirm"><i18next path="Confirm"/></slot>
         </div>
       </div>
@@ -28,7 +28,8 @@ export default {
   props: {
     action: {type: Function, required: false},
     disabled: {type: Boolean, default: false},
-    color: {type: String, default: 'red'}
+    color: {type: String, default: 'red'},
+    confirmColor: {type: String, default: null, required: false}
   },
   components: {
     Modal
@@ -38,6 +39,14 @@ export default {
       showModal: false
     }
   },
+  computed: {
+    confirmButtonColor () {
+      if (this.confirmColor) {
+        return this.confirmColor
+      }
+      return this.color
+    }
+  },
   methods: {
     confirm () {
       this.showModal = false
diff --git a/front/src/components/federation/LibraryTrackTable.vue b/front/src/components/federation/LibraryTrackTable.vue
index 551fb992a6518966b829b2ef9cdf2aff08caa356..43b52c835bb84ec3434f5a8fca110e70ecd24ff7 100644
--- a/front/src/components/federation/LibraryTrackTable.vue
+++ b/front/src/components/federation/LibraryTrackTable.vue
@@ -10,55 +10,63 @@
           <label>{{ $t('Import status') }}</label>
           <select class="ui dropdown" v-model="importedFilter">
             <option :value="null">{{ $t('Any') }}</option>
-            <option :value="true">{{ $t('Imported') }}</option>
-            <option :value="false">{{ $t('Not imported') }}</option>
+            <option :value="'imported'">{{ $t('Imported') }}</option>
+            <option :value="'not_imported'">{{ $t('Not imported') }}</option>
+            <option :value="'import_pending'">{{ $t('Import pending') }}</option>
           </select>
         </div>
       </div>
     </div>
-    <action-table
-      v-if="result"
-      :objects-data="result"
-      :actions="[['import', $t('Import')]]"
-      :action-url="'federation/library-tracks/action/'"
-      :filters="actionFilters">
-      <template slot="header-cells">
-        <th>{{ $t('Status') }}</th>
-        <th>{{ $t('Title') }}</th>
-        <th>{{ $t('Artist') }}</th>
-        <th>{{ $t('Album') }}</th>
-        <th>{{ $t('Published date') }}</th>
-        <th v-if="showLibrary">{{ $t('Library') }}</th>
-      </template>
-      <template slot="action-success-footer" slot-scope="scope">
-        <router-link
-          v-if="scope.result.action === 'import'"
-          :to="{name: 'library.import.batches.detail', params: {id: scope.result.result.batch.id }}">
-          {{ $t('Import #{% id %} launched', {id: scope.result.result.batch.id}) }}
-        </router-link>
-      </template>
-      <template slot="row-cells" slot-scope="scope">
-        <td>
-          <span v-if="scope.obj.local_track_file" class="ui basic green label">{{ $t('In library') }}</span>
-          <span v-else class="ui basic yellow label">{{ $t('Not imported') }}</span>
-        </td>
-        <td>
-          <span :title="scope.obj.title">{{ scope.obj.title|truncate(30) }}</span>
-        </td>
-        <td>
-          <span :title="scope.obj.artist_name">{{ scope.obj.artist_name|truncate(30) }}</span>
-        </td>
-        <td>
-          <span :title="scope.obj.album_title">{{ scope.obj.album_title|truncate(20) }}</span>
-        </td>
-        <td>
-          <human-date :date="scope.obj.published_date"></human-date>
-        </td>
-        <td v-if="showLibrary">
-          {{ scope.obj.library.actor.domain }}
-        </td>
-      </template>
-    </action-table>
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+          <div class="ui loader"></div>
+      </div>
+      <action-table
+        v-if="result"
+        @action-launched="fetchData"
+        :objects-data="result"
+        :actions="actions"
+        :action-url="'federation/library-tracks/action/'"
+        :filters="actionFilters">
+        <template slot="header-cells">
+          <th>{{ $t('Status') }}</th>
+          <th>{{ $t('Title') }}</th>
+          <th>{{ $t('Artist') }}</th>
+          <th>{{ $t('Album') }}</th>
+          <th>{{ $t('Published date') }}</th>
+          <th v-if="showLibrary">{{ $t('Library') }}</th>
+        </template>
+        <template slot="action-success-footer" slot-scope="scope">
+          <router-link
+            v-if="scope.result.action === 'import'"
+            :to="{name: 'library.import.batches.detail', params: {id: scope.result.result.batch.id }}">
+            {{ $t('Import #{% id %} launched', {id: scope.result.result.batch.id}) }}
+          </router-link>
+        </template>
+        <template slot="row-cells" slot-scope="scope">
+          <td>
+            <span v-if="scope.obj.status === 'imported'" class="ui basic green label">{{ $t('In library') }}</span>
+            <span v-else-if="scope.obj.status === 'import_pending'" class="ui basic yellow label">{{ $t('Import pending') }}</span>
+            <span v-else class="ui basic label">{{ $t('Not imported') }}</span>
+          </td>
+          <td>
+            <span :title="scope.obj.title">{{ scope.obj.title|truncate(30) }}</span>
+          </td>
+          <td>
+            <span :title="scope.obj.artist_name">{{ scope.obj.artist_name|truncate(30) }}</span>
+          </td>
+          <td>
+            <span :title="scope.obj.album_title">{{ scope.obj.album_title|truncate(20) }}</span>
+          </td>
+          <td>
+            <human-date :date="scope.obj.published_date"></human-date>
+          </td>
+          <td v-if="showLibrary">
+            {{ scope.obj.library.actor.domain }}
+          </td>
+        </template>
+      </action-table>
+    </div>
     <div>
       <pagination
         v-if="result && result.results.length > 0"
@@ -113,7 +121,7 @@ export default {
         'q': this.search
       }, this.filters)
       if (this.importedFilter !== null) {
-        params.imported = this.importedFilter
+        params.status = this.importedFilter
       }
       let self = this
       self.isLoading = true
@@ -140,14 +148,21 @@ export default {
       } else {
         return currentFilters
       }
+    },
+    actions () {
+      return [
+        {
+          name: 'import',
+          label: this.$t('Import'),
+          filterCheckable: (obj) => { return obj.status === 'not_imported' }
+        }
+      ]
     }
   },
   watch: {
     search (newValue) {
-      if (newValue.length > 0) {
-        this.page = 1
-        this.fetchData()
-      }
+      this.page = 1
+      this.fetchData()
     },
     page () {
       this.fetchData()