FileUpload.vue 4.24 KB
Newer Older
Eliot Berriot's avatar
Eliot Berriot committed
1
2
<template>
  <div>
Eliot Berriot's avatar
Eliot Berriot committed
3
    <div v-if="batch" class="ui container">
4
5
6
7
      <div class="ui message">
        {{ $t('Ensure your music files are properly tagged before uploading them.') }}
        <a href="http://picard.musicbrainz.org/" target='_blank'>{{ $t('We recommend using Picard for that purpose.') }}</a>
      </div>
Eliot Berriot's avatar
Eliot Berriot committed
8
      <file-upload-widget
Eliot Berriot's avatar
Eliot Berriot committed
9
        :class="['ui', 'icon', 'left', 'floated', 'button']"
Eliot Berriot's avatar
Eliot Berriot committed
10
11
12
13
        :post-action="uploadUrl"
        :multiple="true"
        :data="uploadData"
        :drop="true"
14
        extensions="ogg,mp3,flac"
Eliot Berriot's avatar
Eliot Berriot committed
15
16
17
18
19
20
21
22
        accept="audio/*"
        v-model="files"
        name="audio_file"
        :thread="3"
        @input-filter="inputFilter"
        @input-file="inputFile"
        ref="upload">
        <i class="upload icon"></i>
Bat's avatar
Bat committed
23
        <i18next path="Select files to upload..."/>
Eliot Berriot's avatar
Eliot Berriot committed
24
    </file-upload-widget>
Eliot Berriot's avatar
Eliot Berriot committed
25
26
      <button
        :class="['ui', 'right', 'floated', 'icon', {disabled: files.length === 0}, 'button']"
27
        v-if="!$refs.upload || !$refs.upload.active" @click.prevent="startUpload()">
Eliot Berriot's avatar
Eliot Berriot committed
28
        <i class="play icon" aria-hidden="true"></i>
Bat's avatar
Bat committed
29
        <i18next path="Start Upload"/>
Eliot Berriot's avatar
Eliot Berriot committed
30
      </button>
Eliot Berriot's avatar
Eliot Berriot committed
31
      <button type="button" class="ui right floated icon yellow button" v-else @click.prevent="$refs.upload.active = false">
Eliot Berriot's avatar
Eliot Berriot committed
32
        <i class="pause icon" aria-hidden="true"></i>
Bat's avatar
Bat committed
33
        <i18next path="Stop Upload"/>
Eliot Berriot's avatar
Eliot Berriot committed
34
35
      </button>
    </div>
Eliot Berriot's avatar
Eliot Berriot committed
36
    <div class="ui hidden clearing divider"></div>
Bat's avatar
Bat committed
37
38
39
40
41
    <i18next v-if="batch" path="Once all your files are uploaded, simply head over {%0%} to check the import status.">
      <router-link :to="{name: 'library.import.batches.detail', params: {id: batch.id }}">
        <i18next path="import detail page"/>
      </router-link>
    </i18next>
Eliot Berriot's avatar
Eliot Berriot committed
42
43
44
    <table class="ui single line table">
      <thead>
        <tr>
Bat's avatar
Bat committed
45
46
47
          <i18next tag="th" path="File name"/>
          <i18next tag="th" path="Size"/>
          <i18next tag="th" path="Status"/>
Eliot Berriot's avatar
Eliot Berriot committed
48
49
50
51
52
53
54
55
56
57
        </tr>
      </thead>
      <tbody>
        <tr v-for="(file, index) in files" :key="file.id">
          <td>{{ file.name }}</td>
          <td>{{ file.size }}</td>
          <td>
            <span v-if="file.error" class="ui red label">
              {{ file.error }}
            </span>
Bat's avatar
Bat committed
58
59
            <i18next v-else-if="file.success" class="ui green label" path="Success"/>
            <i18next v-else-if="file.active" class="ui yellow label" path="Uploading..."/>
Eliot Berriot's avatar
Eliot Berriot committed
60
            <template v-else>
Bat's avatar
Bat committed
61
              <i18next class="ui label" path="Pending"/>
Eliot Berriot's avatar
Eliot Berriot committed
62
63
64
65
66
67
68
69
70
71
              <button class="ui tiny basic red icon button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
            </template>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
Eliot Berriot's avatar
Eliot Berriot committed
72
import axios from 'axios'
Eliot Berriot's avatar
Eliot Berriot committed
73
74
75
76
77
78
79
80
81
82
import logger from '@/logging'
import FileUploadWidget from './FileUploadWidget'

export default {
  components: {
    FileUploadWidget
  },
  data () {
    return {
      files: [],
Eliot Berriot's avatar
Eliot Berriot committed
83
      uploadUrl: '/api/v1/import-jobs/',
Eliot Berriot's avatar
Eliot Berriot committed
84
85
86
87
88
89
90
91
92
93
      batch: null
    }
  },
  mounted: function () {
    this.createBatch()
  },
  methods: {
    inputFilter (newFile, oldFile, prevent) {
      if (newFile && !oldFile) {
        let extension = newFile.name.split('.').pop()
94
        if (['ogg', 'mp3', 'flac'].indexOf(extension) < 0) {
Eliot Berriot's avatar
Eliot Berriot committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
          prevent()
        }
      }
    },
    inputFile (newFile, oldFile) {
      if (newFile && !oldFile) {
        // add
        if (!this.batch) {
          this.createBatch()
        }
      }
      if (newFile && oldFile) {
        // update
      }
      if (!newFile && oldFile) {
        // remove
      }
    },
    createBatch () {
      let self = this
Eliot Berriot's avatar
Eliot Berriot committed
115
      return axios.post('import-batches/', {}).then((response) => {
Eliot Berriot's avatar
Eliot Berriot committed
116
117
118
119
        self.batch = response.data
      }, (response) => {
        logger.default.error('error while launching creating batch')
      })
120
121
122
123
    },
    startUpload () {
      this.$emit('batch-created', this.batch)
      this.$refs.upload.active = true
Eliot Berriot's avatar
Eliot Berriot committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    }
  },
  computed: {
    batchId: function () {
      if (this.batch) {
        return this.batch.id
      }
      return null
    },
    uploadData: function () {
      return {
        'batch': this.batchId,
        'source': 'file://'
      }
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>