kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
				
				
				
			Request list and card
							rodzic
							
								
									2fb533c5f5
								
							
						
					
					
						commit
						fd60c968ba
					
				| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div :class="['ui', {collapsed: collapsed}, 'card']">
 | 
			
		||||
    <div class="content">
 | 
			
		||||
      <div class="header">{{ request.artist_name }}</div>
 | 
			
		||||
      <div class="description">
 | 
			
		||||
        <div
 | 
			
		||||
          v-if="request.albums" v-html="$options.filters.markdown(request.albums)"></div>
 | 
			
		||||
        <div v-if="request.comment" class="ui comments">
 | 
			
		||||
          <comment
 | 
			
		||||
            :user="request.user"
 | 
			
		||||
            :content="request.comment"
 | 
			
		||||
            :date="request.creation_date"></comment>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="extra content">
 | 
			
		||||
      <span >
 | 
			
		||||
        <i v-if="request.status === 'pending'" class="hourglass start icon"></i>
 | 
			
		||||
        <i v-if="request.status === 'accepted'" class="hourglass half icon"></i>
 | 
			
		||||
        <i v-if="request.status === 'imported'" class="check icon"></i>
 | 
			
		||||
        {{ request.status | capitalize }}
 | 
			
		||||
      </span>
 | 
			
		||||
      <button
 | 
			
		||||
        @click="createImport"
 | 
			
		||||
        v-if="request.status === 'pending' && importAction && $store.state.auth.availablePermissions['import.launch']"
 | 
			
		||||
        class="ui mini basic green right floated button">Create import</button>
 | 
			
		||||
      
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Comment from '@/components/discussion/Comment'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    request: {type: Object, required: true},
 | 
			
		||||
    importAction: {type: Boolean, default: true}
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    Comment
 | 
			
		||||
  },
 | 
			
		||||
  data () {
 | 
			
		||||
    return {
 | 
			
		||||
      collapsed: true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    createImport () {
 | 
			
		||||
      this.$router.push({
 | 
			
		||||
        name: 'library.import.launch',
 | 
			
		||||
        query: {request: this.request.id}})
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,163 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="ui vertical stripe segment">
 | 
			
		||||
      <h2 class="ui header">Music requests</h2>
 | 
			
		||||
      <div :class="['ui', {'loading': isLoading}, 'form']">
 | 
			
		||||
        <div class="fields">
 | 
			
		||||
          <div class="field">
 | 
			
		||||
            <label>Search</label>
 | 
			
		||||
            <input type="text" v-model="query" placeholder="Enter an artist name, a username..."/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="field">
 | 
			
		||||
            <label>Ordering</label>
 | 
			
		||||
            <select class="ui dropdown" v-model="ordering">
 | 
			
		||||
              <option v-for="option in orderingOptions" :value="option[0]">
 | 
			
		||||
                {{ option[1] }}
 | 
			
		||||
              </option>
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="field">
 | 
			
		||||
            <label>Ordering direction</label>
 | 
			
		||||
            <select class="ui dropdown" v-model="orderingDirection">
 | 
			
		||||
              <option value="">Ascending</option>
 | 
			
		||||
              <option value="-">Descending</option>
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="field">
 | 
			
		||||
            <label>Results per page</label>
 | 
			
		||||
            <select class="ui dropdown" v-model="paginateBy">
 | 
			
		||||
              <option :value="parseInt(12)">12</option>
 | 
			
		||||
              <option :value="parseInt(25)">25</option>
 | 
			
		||||
              <option :value="parseInt(50)">50</option>
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="ui hidden divider"></div>
 | 
			
		||||
      <div v-if="result" class="ui stackable three column grid">
 | 
			
		||||
        <div
 | 
			
		||||
          v-if="result.results.length > 0"
 | 
			
		||||
          v-for="request in result.results"
 | 
			
		||||
          :key="request.id"
 | 
			
		||||
          class="column">
 | 
			
		||||
          <request-card class="fluid" :request="request"></request-card>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="ui center aligned basic segment">
 | 
			
		||||
        <pagination
 | 
			
		||||
          v-if="result && result.results.length > 0"
 | 
			
		||||
          @page-changed="selectPage"
 | 
			
		||||
          :current="page"
 | 
			
		||||
          :paginate-by="paginateBy"
 | 
			
		||||
          :total="result.count"
 | 
			
		||||
          ></pagination>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import axios from 'axios'
 | 
			
		||||
import _ from 'lodash'
 | 
			
		||||
import $ from 'jquery'
 | 
			
		||||
 | 
			
		||||
import logger from '@/logging'
 | 
			
		||||
 | 
			
		||||
import OrderingMixin from '@/components/mixins/Ordering'
 | 
			
		||||
import PaginationMixin from '@/components/mixins/Pagination'
 | 
			
		||||
import RequestCard from '@/components/requests/Card'
 | 
			
		||||
import Pagination from '@/components/Pagination'
 | 
			
		||||
 | 
			
		||||
const FETCH_URL = 'requests/import-requests/'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  mixins: [OrderingMixin, PaginationMixin],
 | 
			
		||||
  props: {
 | 
			
		||||
    defaultQuery: {type: String, required: false, default: ''}
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    RequestCard,
 | 
			
		||||
    Pagination
 | 
			
		||||
  },
 | 
			
		||||
  data () {
 | 
			
		||||
    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
 | 
			
		||||
    return {
 | 
			
		||||
      isLoading: true,
 | 
			
		||||
      result: null,
 | 
			
		||||
      page: parseInt(this.defaultPage),
 | 
			
		||||
      query: this.defaultQuery,
 | 
			
		||||
      paginateBy: parseInt(this.defaultPaginateBy || 12),
 | 
			
		||||
      orderingDirection: defaultOrdering.direction,
 | 
			
		||||
      ordering: defaultOrdering.field,
 | 
			
		||||
      orderingOptions: [
 | 
			
		||||
        ['creation_date', 'Creation date'],
 | 
			
		||||
        ['artist_name', 'Artist name'],
 | 
			
		||||
        ['user__username', 'User']
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
    this.fetchData()
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
    $('.ui.dropdown').dropdown()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    updateQueryString: _.debounce(function () {
 | 
			
		||||
      this.$router.replace({
 | 
			
		||||
        query: {
 | 
			
		||||
          query: this.query,
 | 
			
		||||
          page: this.page,
 | 
			
		||||
          paginateBy: this.paginateBy,
 | 
			
		||||
          ordering: this.getOrderingAsString()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }, 500),
 | 
			
		||||
    fetchData: _.debounce(function () {
 | 
			
		||||
      var self = this
 | 
			
		||||
      this.isLoading = true
 | 
			
		||||
      let url = FETCH_URL
 | 
			
		||||
      let params = {
 | 
			
		||||
        page: this.page,
 | 
			
		||||
        page_size: this.paginateBy,
 | 
			
		||||
        search: this.query,
 | 
			
		||||
        ordering: this.getOrderingAsString()
 | 
			
		||||
      }
 | 
			
		||||
      logger.default.debug('Fetching request...')
 | 
			
		||||
      axios.get(url, {params: params}).then((response) => {
 | 
			
		||||
        self.result = response.data
 | 
			
		||||
        self.isLoading = false
 | 
			
		||||
      })
 | 
			
		||||
    }, 500),
 | 
			
		||||
    selectPage: function (page) {
 | 
			
		||||
      this.page = page
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    page () {
 | 
			
		||||
      this.updateQueryString()
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    },
 | 
			
		||||
    paginateBy () {
 | 
			
		||||
      this.updateQueryString()
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    },
 | 
			
		||||
    ordering () {
 | 
			
		||||
      this.updateQueryString()
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    },
 | 
			
		||||
    orderingDirection () {
 | 
			
		||||
      this.updateQueryString()
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    },
 | 
			
		||||
    query () {
 | 
			
		||||
      this.updateQueryString()
 | 
			
		||||
      this.fetchData()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
 | 
			
		||||
<style scoped>
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ import LibraryRadios from '@/components/library/Radios'
 | 
			
		|||
import RadioBuilder from '@/components/library/radios/Builder'
 | 
			
		||||
import BatchList from '@/components/library/import/BatchList'
 | 
			
		||||
import BatchDetail from '@/components/library/import/BatchDetail'
 | 
			
		||||
import RequestsList from '@/components/requests/RequestsList'
 | 
			
		||||
 | 
			
		||||
import Favorites from '@/components/favorites/List'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +101,7 @@ export default new Router({
 | 
			
		|||
          component: LibraryImport,
 | 
			
		||||
          props: (route) => ({
 | 
			
		||||
            source: route.query.source,
 | 
			
		||||
            request: route.query.request,
 | 
			
		||||
            mbType: route.query.type,
 | 
			
		||||
            mbId: route.query.id })
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +112,21 @@ export default new Router({
 | 
			
		|||
          children: [
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
        { path: 'import/batches/:id', name: 'library.import.batches.detail', component: BatchDetail, props: true }
 | 
			
		||||
        { path: 'import/batches/:id', name: 'library.import.batches.detail', component: BatchDetail, props: true },
 | 
			
		||||
        {
 | 
			
		||||
          path: 'requests/',
 | 
			
		||||
          name: 'library.requests',
 | 
			
		||||
          component: RequestsList,
 | 
			
		||||
          props: (route) => ({
 | 
			
		||||
            defaultOrdering: route.query.ordering,
 | 
			
		||||
            defaultQuery: route.query.query,
 | 
			
		||||
            defaultPaginateBy: route.query.paginateBy,
 | 
			
		||||
            defaultPage: route.query.page,
 | 
			
		||||
            defaultStatus: route.query.status || 'pending'
 | 
			
		||||
          }),
 | 
			
		||||
          children: [
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    { path: '*', component: PageNotFound }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue