Skip to content
Snippets Groups Projects
BatchDetail.vue 7.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bat's avatar
    Bat committed
      <div v-title="'Import Batch #' + id">
    
        <div v-if="isLoading && !batch" class="ui vertical segment">
          <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
        </div>
        <div v-if="batch" class="ui vertical stripe segment">
    
          <table class="ui very basic table">
            <tbody>
              <tr>
                <td>
                  <strong>{{ $t('Import batch') }}</strong>
                </td>
                <td>
                  #{{ batch.id }}
                </td>
              </tr>
              <tr>
                <td>
                  <strong>{{ $t('Launch date') }}</strong>
                </td>
                <td>
                  <human-date :date="batch.creation_date"></human-date>
                </td>
              </tr>
              <tr v-if="batch.user">
                <td>
                  <strong>{{ $t('Submitted by') }}</strong>
                </td>
                <td>
                  <username :username="batch.user.username" />
                </td>
              </tr>
              <tr v-if="stats">
                <td><strong>{{ $t('Pending') }}</strong></td>
                <td>{{ stats.pending }}</td>
              </tr>
              <tr v-if="stats">
                <td><strong>{{ $t('Skipped') }}</strong></td>
                <td>{{ stats.skipped }}</td>
              </tr>
              <tr v-if="stats">
                <td><strong>{{ $t('Errored') }}</strong></td>
    
                <td>
                  {{ stats.errored }}
                  <button
                    @click="rerun({batches: [batch.id], jobs: []})"
                    v-if="stats.errored > 0"
                    class="ui tiny basic icon button">
                    <i class="redo icon" />
                    {{ $t('Rerun errored jobs')}}
                  </button>
                </td>
    
              </tr>
              <tr v-if="stats">
                <td><strong>{{ $t('Finished') }}</strong></td>
                <td>{{ stats.finished }}/{{ stats.count}}</td>
              </tr>
            </tbody>
          </table>
          <div class="ui inline form">
            <div class="fields">
              <div class="ui field">
                <label>{{ $t('Search') }}</label>
                <input type="text" v-model="jobFilters.search" placeholder="Search by source..." />
              </div>
              <div class="ui field">
                <label>{{ $t('Status') }}</label>
                <select class="ui dropdown" v-model="jobFilters.status">
                  <option :value="null">{{ $t('Any') }}</option>
                  <option :value="'pending'">{{ $t('Pending') }}</option>
                  <option :value="'errored'">{{ $t('Errored') }}</option>
                  <option :value="'finished'">{{ $t('Success') }}</option>
                  <option :value="'skipped'">{{ $t('Skipped') }}</option>
                </select>
              </div>
    
          <table v-if="jobResult" class="ui unstackable table">
    
                <th>{{ $t('Job ID') }}</th>
                <th>{{ $t('Recording MusicBrainz ID') }}</th>
                <th>{{ $t('Source') }}</th>
                <th>{{ $t('Status') }}</th>
                <th>{{ $t('Track') }}</th>
    
              <tr v-for="job in jobResult.results">
    
                <td>{{ job.id }}</th>
                <td>
                  <a :href="'https://www.musicbrainz.org/recording/' + job.mbid" target="_blank">{{ job.mbid }}</a>
                </td>
                <td>
    
                  <a :title="job.source" :href="job.source" target="_blank">
                    {{ job.source|truncate(50) }}
                  </a>
    
                    :class="['ui', {'yellow': job.status === 'pending'}, {'red': job.status === 'errored'}, {'green': job.status === 'finished'}, 'label']">
                    {{ job.status }}</span>
                    <button
                      @click="rerun({batches: [], jobs: [job.id]})"
                      v-if="job.status === 'errored'"
                      :title="$t('Rerun job')"
                      class="ui tiny basic icon button">
                      <i class="redo icon" />
                    </button>
    
                <td>
                  <router-link v-if="job.track_file" :to="{name: 'library.tracks.detail', params: {id: job.track_file.track }}">{{ job.track_file.track }}</router-link>
                </td>
    
            <tfoot class="full-width">
              <tr>
                <th>
                  <pagination
                  v-if="jobResult && jobResult.results.length > 0"
                  @page-changed="selectPage"
                  :compact="true"
                  :current="jobFilters.page"
                  :paginate-by="jobFilters.paginateBy"
                  :total="jobResult.count"
                  ></pagination>
                </th>
                <th v-if="jobResult && jobResult.results.length > 0">
                  {{ $t('Showing results {%start%}-{%end%} on {%total%}', {start: ((jobFilters.page-1) * jobFilters.paginateBy) + 1 , end: ((jobFilters.page-1) * jobFilters.paginateBy) + jobResult.results.length, total: jobResult.count})}}
                <th>
                <th></th>
                <th></th>
                <th></th>
              </tr>
            </tfoot>
    
    import axios from 'axios'
    
    import Pagination from '@/components/Pagination'
    
          stats: null,
          jobResult: null,
          timeout: null,
          jobFilters: {
            status: null,
            source: null,
            search: '',
            paginateBy: 25,
            page: 1
          }
    
        let self = this
        this.fetchData().then(() => {
          self.fetchJobs()
          self.fetchStats()
        })
    
      destroyed () {
        if (this.timeout) {
          clearTimeout(this.timeout)
        }
      },
    
      methods: {
        fetchData () {
          var self = this
          this.isLoading = true
    
          let url = 'import-batches/' + this.id + '/'
    
          logger.default.debug('Fetching batch "' + this.id + '"')
    
          return axios.get(url).then((response) => {
    
            self.batch = response.data
            self.isLoading = false
          })
        },
    
        fetchStats () {
          var self = this
          let url = 'import-jobs/stats/'
          axios.get(url, {params: {batch: self.id}}).then((response) => {
            let old = self.stats
            self.stats = response.data
            self.isLoading = false
            if (!_.isEqual(old, self.stats)) {
              self.fetchJobs()
              self.fetchData()
            }
    
            if (self.stats.pending > 0) {
    
              self.timeout = setTimeout(
                self.fetchStats,
                5000
              )
            }
          })
        },
    
        rerun ({jobs, batches}) {
          let payload = {
            jobs, batches
          }
          let self = this
          axios.post('import-jobs/run/', payload).then((response) => {
            self.fetchStats()
          })
        },
    
        fetchJobs () {
          let params = {
            batch: this.id,
            page_size: this.jobFilters.paginateBy,
            page: this.jobFilters.page,
            q: this.jobFilters.search
          }
          if (this.jobFilters.status) {
            params.status = this.jobFilters.status
          }
          if (this.jobFilters.source) {
            params.source = this.jobFilters.source
          }
          let self = this
          axios.get('import-jobs/', {params}).then((response) => {
            self.jobResult = response.data
          })
        },
        selectPage: function (page) {
          this.jobFilters.page = page
    
        },
        jobFilters: {
          handler () {
            this.fetchJobs()
          },
          deep: true
    
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang="scss">
    
    </style>