chore(front): refactor admin manage library pages
This commit is contained in:
parent
551af184c0
commit
f9f53c32db
|
@ -10,7 +10,6 @@ import { useI18n } from 'vue-i18n'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
|
@ -18,6 +17,12 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -88,22 +93,24 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="channel-search">{{ t('components.manage.ChannelsTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="channel-search"
|
||||||
<input
|
ref="search"
|
||||||
id="channel-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.ChannelsTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="channel-category">{{ t('components.manage.ChannelsTable.label.category') }}</label>
|
<label for="channel-category">{{ t('components.manage.ChannelsTable.label.category') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -157,108 +164,99 @@ const labels = computed(() => ({
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="[]"
|
|
||||||
action-url="manage/library/artists/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.account') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.albums') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.tracks') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.ChannelsTable.table.channel.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
#row-cells="scope"
|
|
||||||
>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.channels.detail', params: {id: scope.obj.actor.full_username }}">
|
|
||||||
{{ scope.obj.artist.name }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.attributed_to.full_username }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
@click.prevent="addSearchToken('account', scope.obj.attributed_to.full_username)"
|
|
||||||
>{{ scope.obj.attributed_to.preferred_username }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.attributed_to.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)"
|
|
||||||
>{{ scope.obj.attributed_to.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.ChannelsTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.artist.albums_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.artist.tracks_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.ChannelsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="[]"
|
||||||
|
action-url="manage/library/artists/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.account') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.albums') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.tracks') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.ChannelsTable.table.channel.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
#row-cells="scope"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.channels.detail', params: {id: scope.obj.actor.full_username }}">
|
||||||
|
{{ scope.obj.artist.name }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.attributed_to.full_username }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
@click.prevent="addSearchToken('account', scope.obj.attributed_to.full_username)"
|
||||||
|
>{{ scope.obj.attributed_to.preferred_username }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.attributed_to.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)"
|
||||||
|
>{{ scope.obj.attributed_to.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.ChannelsTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.artist.albums_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.artist.tracks_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<div>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.ChannelsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { useI18n } from 'vue-i18n'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
|
@ -18,6 +17,12 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -100,22 +105,24 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="albums-search">{{ t('components.manage.library.AlbumsTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="albums-search"
|
||||||
<input
|
ref="search"
|
||||||
id="albums-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.AlbumsTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="albums-ordering">{{ t('components.manage.library.AlbumsTable.ordering.label') }}</label>
|
<label for="albums-ordering">{{ t('components.manage.library.AlbumsTable.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -146,115 +153,104 @@ const labels = computed(() => ({
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/library/albums/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.artist') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.tracks') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.releaseDate') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.table.album.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
#row-cells="scope"
|
|
||||||
>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.id }}">
|
|
||||||
{{ scope.obj.title }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.artist.name"
|
|
||||||
@click.prevent="addSearchToken('artist', scope.obj.artist.name)"
|
|
||||||
>{{ scope.obj.artist.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>{{ scope.obj.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.library.AlbumsTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.tracks_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date
|
|
||||||
v-if="scope.obj.release_date"
|
|
||||||
:date="scope.obj.release_date"
|
|
||||||
/>
|
|
||||||
<span v-else>
|
|
||||||
{{ t('components.manage.library.AlbumsTable.notApplicable') }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.AlbumsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/library/albums/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.artist') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.tracks') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.releaseDate') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.table.album.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
#row-cells="scope"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.id }}">
|
||||||
|
{{ scope.obj.title }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.artist.name"
|
||||||
|
@click.prevent="addSearchToken('artist', scope.obj.artist.name)"
|
||||||
|
>{{ scope.obj.artist.name }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
<span class="visually-hidden">{{ labels.openModeration }}</span>
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>{{ scope.obj.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.library.AlbumsTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.tracks_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date
|
||||||
|
v-if="scope.obj.release_date"
|
||||||
|
:date="scope.obj.release_date"
|
||||||
|
/>
|
||||||
|
<span v-else>
|
||||||
|
{{ t('components.manage.library.AlbumsTable.notApplicable') }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.AlbumsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { useI18n } from 'vue-i18n'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
|
@ -18,6 +17,12 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -104,22 +109,24 @@ const getUrl = (artist: { channel?: number; id: number }) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="artists-serarch">{{ t('components.manage.library.ArtistsTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="artists-search"
|
||||||
<input
|
ref="search"
|
||||||
id="artists-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.ArtistsTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="artists-category">{{ t('components.manage.library.ArtistsTable.label.category') }}</label>
|
<label for="artists-category">{{ t('components.manage.library.ArtistsTable.label.category') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -173,94 +180,83 @@ const getUrl = (artist: { channel?: number; id: number }) => {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/library/artists/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.ArtistsTable.table.artist.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.ArtistsTable.table.artist.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.ArtistsTable.table.artist.header.albums') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.ArtistsTable.table.artist.header.tracks') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.ArtistsTable.table.artist.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
#row-cells="scope"
|
|
||||||
>
|
|
||||||
<td>
|
|
||||||
<router-link :to="getUrl(scope.obj)">
|
|
||||||
{{ scope.obj.name }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.domain"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>{{ scope.obj.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.library.ArtistsTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.albums_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.tracks_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.ArtistsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/library/artists/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.ArtistsTable.table.artist.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.ArtistsTable.table.artist.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.ArtistsTable.table.artist.header.albums') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.ArtistsTable.table.artist.header.tracks') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.ArtistsTable.table.artist.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
#row-cells="scope"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
<router-link :to="getUrl(scope.obj)">
|
||||||
|
{{ scope.obj.name }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.domain"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>{{ scope.obj.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.library.ArtistsTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.albums_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.tracks_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.ArtistsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { uniq } from 'lodash-es'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
import EditCard from '~/components/library/EditCard.vue'
|
import EditCard from '~/components/library/EditCard.vue'
|
||||||
|
|
||||||
import useEditConfigs from '~/composables/moderation/useEditConfigs'
|
import useEditConfigs from '~/composables/moderation/useEditConfigs'
|
||||||
|
@ -22,6 +21,13 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Section from '~/components/ui/Section.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -159,28 +165,36 @@ const getCurrentState = (target?: StateTarget): ReviewState => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="ui text container">
|
<slot />
|
||||||
<slot />
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui field">
|
||||||
<div class="ui field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="search-edits">{{ t('components.manage.library.EditsCardList.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
search
|
||||||
<input
|
id="search-edits"
|
||||||
id="search-edits"
|
ref="search"
|
||||||
ref="search"
|
name="search"
|
||||||
name="search"
|
v-model="query"
|
||||||
type="text"
|
:label="t('components.manage.library.EditsCardList.label.search')"
|
||||||
:value="query"
|
autofocus
|
||||||
:placeholder="labels.searchPlaceholder"
|
:placeholder="labels.searchPlaceholder"
|
||||||
>
|
/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<Spacer :size="16" />
|
||||||
<label for="edit-status">{{ t('components.manage.library.EditsCardList.label.status') }}</label>
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
|
<Layout
|
||||||
|
stack
|
||||||
|
no-gap
|
||||||
|
label
|
||||||
|
for="edit-status"
|
||||||
|
>
|
||||||
|
<span class="label">{{ t('components.manage.library.EditsCardList.label.status') }}</span>
|
||||||
<select
|
<select
|
||||||
id="edit-status"
|
id="edit-status"
|
||||||
class="ui dropdown"
|
class="dropdown"
|
||||||
:value="getTokenValue('is_approved', '')"
|
:value="getTokenValue('is_approved', '')"
|
||||||
@change="addSearchToken('is_approved', ($event.target as HTMLSelectElement).value)"
|
@change="addSearchToken('is_approved', ($event.target as HTMLSelectElement).value)"
|
||||||
>
|
>
|
||||||
|
@ -197,7 +211,7 @@ const getCurrentState = (target?: StateTarget): ReviewState => {
|
||||||
{{ t('components.manage.library.EditsCardList.option.rejected') }}
|
{{ t('components.manage.library.EditsCardList.option.rejected') }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</Layout>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="edit-ordering">{{ t('components.manage.library.EditsCardList.ordering.label') }}</label>
|
<label for="edit-ordering">{{ t('components.manage.library.EditsCardList.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -229,44 +243,35 @@ const getCurrentState = (target?: StateTarget): ReviewState => {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<div v-else-if="(result?.count ?? 0) > 0">
|
|
||||||
<edit-card
|
|
||||||
v-for="obj in result?.results ?? []"
|
|
||||||
:key="obj.uuid"
|
|
||||||
:obj="obj"
|
|
||||||
:current-state="getCurrentState(obj.target)"
|
|
||||||
@deleted="handle('delete', obj.uuid, false)"
|
|
||||||
@approved="handle('approved', obj.uuid, $event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<empty-state
|
|
||||||
v-else
|
|
||||||
:refresh="true"
|
|
||||||
@refresh="fetchData()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="ui hidden divider" />
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.EditsCardList.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<Section
|
||||||
|
v-else-if="(result?.count ?? 0) > 0"
|
||||||
|
small-items
|
||||||
|
>
|
||||||
|
<edit-card
|
||||||
|
v-for="obj in result?.results ?? []"
|
||||||
|
:key="obj.uuid"
|
||||||
|
:obj="obj"
|
||||||
|
:current-state="getCurrentState(obj.target)"
|
||||||
|
@deleted="handle('delete', obj.uuid, false)"
|
||||||
|
@approved="handle('approved', obj.uuid, $event)"
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
<empty-state
|
||||||
|
v-else
|
||||||
|
:refresh="true"
|
||||||
|
@refresh="fetchData()"
|
||||||
|
/>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.EditsCardList.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
|
@ -18,6 +17,12 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -103,22 +108,24 @@ const getPrivacyLevelChoice = (privacyLevel: PrivacyLevel) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="libraries-search">{{ t('components.manage.library.LibrariesTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="libraries-search"
|
||||||
<input
|
ref="search"
|
||||||
id="libraries-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.LibrariesTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="libraries-visibility">{{ t('components.manage.library.LibrariesTable.label.visibility') }}</label>
|
<label for="libraries-visibility">{{ t('components.manage.library.LibrariesTable.label.visibility') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -172,119 +179,108 @@ const getPrivacyLevelChoice = (privacyLevel: PrivacyLevel) => {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/library/libraries/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.account') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.visibility') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.uploads') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.followers') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.LibrariesTable.table.library.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template #row-cells="scope">
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.uuid }}">
|
|
||||||
{{ scope.obj.name }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.actor.full_username }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.actor.full_username"
|
|
||||||
@click.prevent="addSearchToken('account', scope.obj.actor.full_username)"
|
|
||||||
>{{ scope.obj.actor.preferred_username }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.domain"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>{{ scope.obj.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.library.LibrariesTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="getPrivacyLevelChoice(scope.obj.privacy_level)"
|
|
||||||
@click.prevent="addSearchToken('privacy_level', scope.obj.privacy_level)"
|
|
||||||
>
|
|
||||||
{{ getPrivacyLevelChoice(scope.obj.privacy_level) }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.uploads_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.followers_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.LibrariesTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/library/libraries/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.account') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.visibility') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.uploads') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.followers') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.LibrariesTable.table.library.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template #row-cells="scope">
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.uuid }}">
|
||||||
|
{{ scope.obj.name }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.actor.full_username }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.actor.full_username"
|
||||||
|
@click.prevent="addSearchToken('account', scope.obj.actor.full_username)"
|
||||||
|
>{{ scope.obj.actor.preferred_username }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.domain"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>{{ scope.obj.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.library.LibrariesTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="getPrivacyLevelChoice(scope.obj.privacy_level)"
|
||||||
|
@click.prevent="addSearchToken('privacy_level', scope.obj.privacy_level)"
|
||||||
|
>
|
||||||
|
{{ getPrivacyLevelChoice(scope.obj.privacy_level) }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.uploads_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.followers_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.LibrariesTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -12,7 +12,6 @@ import axios from 'axios'
|
||||||
|
|
||||||
import ImportStatusModal from '~/components/library/ImportStatusModal.vue'
|
import ImportStatusModal from '~/components/library/ImportStatusModal.vue'
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
|
@ -20,6 +19,12 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -105,22 +110,24 @@ const showUploadDetailModal = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="tags-search">{{ t('components.manage.library.TagsTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="tags-search"
|
||||||
<input
|
ref="search"
|
||||||
id="tags-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.TagsTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="tags-ordering">{{ t('components.manage.library.TagsTable.ordering.label') }}</label>
|
<label for="tags-ordering">{{ t('components.manage.library.TagsTable.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -152,81 +159,70 @@ const showUploadDetailModal = ref(false)
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<import-status-modal
|
|
||||||
v-if="detailedUpload"
|
|
||||||
v-model:show="showUploadDetailModal"
|
|
||||||
:upload="detailedUpload"
|
|
||||||
/>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/tags/action/"
|
|
||||||
id-field="name"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TagsTable.table.tag.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TagsTable.table.tag.header.artists') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TagsTable.table.tag.header.albums') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TagsTable.table.tag.header.tracks') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TagsTable.table.tag.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
#row-cells="scope"
|
|
||||||
>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.tags.detail', params: {id: scope.obj.name }}">
|
|
||||||
{{ truncate(scope.obj.name, 30, undefined, true) }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.artists_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.albums_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ scope.obj.tracks_count }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.TagsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<import-status-modal
|
||||||
|
v-if="detailedUpload"
|
||||||
|
v-model:show="showUploadDetailModal"
|
||||||
|
:upload="detailedUpload"
|
||||||
|
/>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/tags/action/"
|
||||||
|
id-field="name"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TagsTable.table.tag.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TagsTable.table.tag.header.artists') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TagsTable.table.tag.header.albums') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TagsTable.table.tag.header.tracks') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TagsTable.table.tag.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
#row-cells="scope"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.tags.detail', params: {id: scope.obj.name }}">
|
||||||
|
{{ truncate(scope.obj.name, 30, undefined, true) }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.artists_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.albums_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ scope.obj.tracks_count }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.TagsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -11,13 +11,18 @@ import axios from 'axios'
|
||||||
|
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
|
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
import useOrdering from '~/composables/navigation/useOrdering'
|
import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -97,22 +102,24 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="tracks-search">{{ t('components.manage.library.TracksTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="tracks-search"
|
||||||
<input
|
ref="search"
|
||||||
id="tracks-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.TracksTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="tracks-ordering">{{ t('components.manage.library.TracksTable.ordering.label') }}</label>
|
<label for="tracks-ordering">{{ t('components.manage.library.TracksTable.ordering.label') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -144,127 +151,118 @@ const labels = computed(() => ({
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/library/tracks/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.title') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.album') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.artist') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.license') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.TracksTable.table.track.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
#row-cells="scope"
|
|
||||||
>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.tracks.detail', params: {id: scope.obj.id }}">
|
|
||||||
{{ scope.obj.title }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="scope.obj.album">
|
|
||||||
<router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.album.id }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.album.title"
|
|
||||||
@click.prevent="addSearchToken('album_id', scope.obj.album.id)"
|
|
||||||
>{{ scope.obj.album.title }}</a>
|
|
||||||
</template>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.artist.name"
|
|
||||||
@click.prevent="addSearchToken('artist_id', scope.obj.artist.id)"
|
|
||||||
>{{ scope.obj.artist.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.domain"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>{{ scope.obj.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.library.TracksTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a
|
|
||||||
v-if="scope.obj.license"
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.license"
|
|
||||||
@click.prevent="addSearchToken('license', scope.obj.license)"
|
|
||||||
>{{ scope.obj.license }}</a>
|
|
||||||
<span v-else>
|
|
||||||
{{ t('components.manage.library.TracksTable.notApplicable') }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.TracksTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/library/tracks/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.title') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.album') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.artist') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.license') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.TracksTable.table.track.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
#row-cells="scope"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.tracks.detail', params: {id: scope.obj.id }}">
|
||||||
|
{{ scope.obj.title }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="scope.obj.album">
|
||||||
|
<router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.album.id }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.album.title"
|
||||||
|
@click.prevent="addSearchToken('album_id', scope.obj.album.id)"
|
||||||
|
>{{ scope.obj.album.title }}</a>
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.artist.name"
|
||||||
|
@click.prevent="addSearchToken('artist_id', scope.obj.artist.id)"
|
||||||
|
>{{ scope.obj.artist.name }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.domain"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>{{ scope.obj.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.library.TracksTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a
|
||||||
|
v-if="scope.obj.license"
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.license"
|
||||||
|
@click.prevent="addSearchToken('license', scope.obj.license)"
|
||||||
|
>{{ scope.obj.license }}</a>
|
||||||
|
<span v-else>
|
||||||
|
{{ t('components.manage.library.TracksTable.notApplicable') }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<div>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.TracksTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -13,8 +13,6 @@ import axios from 'axios'
|
||||||
|
|
||||||
import ImportStatusModal from '~/components/library/ImportStatusModal.vue'
|
import ImportStatusModal from '~/components/library/ImportStatusModal.vue'
|
||||||
import ActionTable from '~/components/common/ActionTable.vue'
|
import ActionTable from '~/components/common/ActionTable.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
|
||||||
import Button from '~/components/ui/Button.vue'
|
|
||||||
|
|
||||||
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
import useSmartSearch from '~/composables/navigation/useSmartSearch'
|
||||||
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
|
@ -22,6 +20,13 @@ import useOrdering from '~/composables/navigation/useOrdering'
|
||||||
import useErrorHandler from '~/composables/useErrorHandler'
|
import useErrorHandler from '~/composables/useErrorHandler'
|
||||||
import usePage from '~/composables/navigation/usePage'
|
import usePage from '~/composables/navigation/usePage'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Spacer from '~/components/ui/Spacer.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
import Input from '~/components/ui/Input.vue'
|
||||||
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
import Pagination from '~/components/ui/Pagination.vue'
|
||||||
|
|
||||||
interface Props extends SmartSearchProps, OrderingProps {
|
interface Props extends SmartSearchProps, OrderingProps {
|
||||||
filters?: object
|
filters?: object
|
||||||
|
|
||||||
|
@ -120,22 +125,24 @@ const getPrivacyLevelChoice = (privacyLevel: PrivacyLevel) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="ui inline form">
|
||||||
<div class="ui inline form">
|
<div class="fields">
|
||||||
<div class="fields">
|
<div class="ui six wide field">
|
||||||
<div class="ui six wide field">
|
<form @submit.prevent="query = search.value">
|
||||||
<label for="uploads-search">{{ t('components.manage.library.UploadsTable.label.search') }}</label>
|
<Input
|
||||||
<form @submit.prevent="query = search.value">
|
id="uploads-search"
|
||||||
<input
|
ref="search"
|
||||||
id="uploads-search"
|
name="search"
|
||||||
ref="search"
|
search
|
||||||
name="search"
|
:label="t('components.manage.library.UploadsTable.label.search')"
|
||||||
type="text"
|
v-model="query"
|
||||||
:value="query"
|
:placeholder="labels.searchPlaceholder"
|
||||||
:placeholder="labels.searchPlaceholder"
|
/>
|
||||||
>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<Spacer :size="16" />
|
||||||
|
<Layout flex>
|
||||||
|
<Spacer grow />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="uploads-visibility">{{ t('components.manage.library.UploadsTable.label.visibility') }}</label>
|
<label for="uploads-visibility">{{ t('components.manage.library.UploadsTable.label.visibility') }}</label>
|
||||||
<select
|
<select
|
||||||
|
@ -214,167 +221,156 @@ const getPrivacyLevelChoice = (privacyLevel: PrivacyLevel) => {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Layout>
|
||||||
</div>
|
|
||||||
<!-- TODO (wvffle): Check if :upload shouldn't be v-model:upload -->
|
|
||||||
<import-status-modal
|
|
||||||
v-if="detailedUpload"
|
|
||||||
v-model:show="showUploadDetailModal"
|
|
||||||
:upload="detailedUpload"
|
|
||||||
/>
|
|
||||||
<div class="dimmable">
|
|
||||||
<div
|
|
||||||
v-if="isLoading"
|
|
||||||
class="ui active inverted dimmer"
|
|
||||||
>
|
|
||||||
<div class="ui loader" />
|
|
||||||
</div>
|
|
||||||
<action-table
|
|
||||||
v-if="result"
|
|
||||||
:objects-data="result"
|
|
||||||
:actions="actions"
|
|
||||||
action-url="manage/library/uploads/action/"
|
|
||||||
:filters="actionFilters"
|
|
||||||
@action-launched="fetchData"
|
|
||||||
>
|
|
||||||
<template #header-cells>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.name') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.library') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.account') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.domain') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.visibility') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.importStatus') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.size') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.creationDate') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.manage.library.UploadsTable.table.upload.header.accessedDate') }}
|
|
||||||
</th>
|
|
||||||
</template>
|
|
||||||
<template #row-cells="scope">
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.uploads.detail', params: {id: scope.obj.uuid }}">
|
|
||||||
{{ truncate(displayName(scope.obj), 30, undefined, true) }}
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.library.uuid }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.library.name"
|
|
||||||
@click.prevent="addSearchToken('library_id', scope.obj.library.id)"
|
|
||||||
>
|
|
||||||
{{ truncate(scope.obj.library.name, 20) }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.library.actor.full_username }}" />
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.library.actor.full_username"
|
|
||||||
@click.prevent="addSearchToken('account', scope.obj.library.actor.full_username)"
|
|
||||||
>{{ scope.obj.library.actor.preferred_username }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="!scope.obj.is_local">
|
|
||||||
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
|
||||||
<i class="wrench icon" />
|
|
||||||
</router-link>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="scope.obj.domain"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>{{ scope.obj.domain }}</a>
|
|
||||||
</template>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
href=""
|
|
||||||
class="ui tiny accent icon link label"
|
|
||||||
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
|
||||||
>
|
|
||||||
<i class="home icon" />
|
|
||||||
{{ t('components.manage.library.UploadsTable.link.local') }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="getPrivacyLevelChoice(scope.obj.library.privacy_level)"
|
|
||||||
@click.prevent="addSearchToken('privacy_level', scope.obj.library.privacy_level)"
|
|
||||||
>
|
|
||||||
{{ getPrivacyLevelChoice(scope.obj.library.privacy_level) }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
class="discrete link"
|
|
||||||
:title="getImportStatusChoice(scope.obj.import_status).help"
|
|
||||||
@click.prevent="addSearchToken('status', scope.obj.import_status)"
|
|
||||||
>
|
|
||||||
{{ getImportStatusChoice(scope.obj.import_status).label }}
|
|
||||||
</a>
|
|
||||||
<Button
|
|
||||||
class="tiny"
|
|
||||||
icon="bi-question-circle"
|
|
||||||
:title="sharedLabels.fields.import_status.label"
|
|
||||||
@click="detailedUpload = scope.obj; showUploadDetailModal = true"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span v-if="scope.obj.size">{{ humanSize(scope.obj.size) }}</span>
|
|
||||||
<span v-else>
|
|
||||||
{{ t('components.manage.library.UploadsTable.notApplicable') }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date :date="scope.obj.creation_date" />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<human-date
|
|
||||||
v-if="scope.obj.accessed_date"
|
|
||||||
:date="scope.obj.accessed_date"
|
|
||||||
/>
|
|
||||||
<span v-else>
|
|
||||||
{{ t('components.manage.library.UploadsTable.notApplicable') }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
</action-table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<pagination
|
|
||||||
v-if="result && result.count > paginateBy"
|
|
||||||
v-model:current="page"
|
|
||||||
:compact="true"
|
|
||||||
:paginate-by="paginateBy"
|
|
||||||
:total="result.count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span v-if="result && result.results.length > 0">
|
|
||||||
{{ t('components.manage.library.UploadsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO (wvffle): Check if :upload shouldn't be v-model:upload -->
|
||||||
|
<import-status-modal
|
||||||
|
v-if="detailedUpload"
|
||||||
|
v-model:show="showUploadDetailModal"
|
||||||
|
:upload="detailedUpload"
|
||||||
|
/>
|
||||||
|
<Loader v-if="isLoading" />
|
||||||
|
<action-table
|
||||||
|
v-if="result"
|
||||||
|
:objects-data="result"
|
||||||
|
:actions="actions"
|
||||||
|
action-url="manage/library/uploads/action/"
|
||||||
|
:filters="actionFilters"
|
||||||
|
@action-launched="fetchData"
|
||||||
|
>
|
||||||
|
<template #header-cells>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.name') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.library') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.account') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.domain') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.visibility') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.importStatus') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.size') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.creationDate') }}
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
{{ t('components.manage.library.UploadsTable.table.upload.header.accessedDate') }}
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
<template #row-cells="scope">
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.uploads.detail', params: {id: scope.obj.uuid }}">
|
||||||
|
{{ truncate(displayName(scope.obj), 30, undefined, true) }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.library.uuid }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.library.name"
|
||||||
|
@click.prevent="addSearchToken('library_id', scope.obj.library.id)"
|
||||||
|
>
|
||||||
|
{{ truncate(scope.obj.library.name, 20) }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.library.actor.full_username }}" />
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.library.actor.full_username"
|
||||||
|
@click.prevent="addSearchToken('account', scope.obj.library.actor.full_username)"
|
||||||
|
>{{ scope.obj.library.actor.preferred_username }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<template v-if="!scope.obj.is_local">
|
||||||
|
<router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
|
||||||
|
<i class="wrench icon" />
|
||||||
|
</router-link>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="scope.obj.domain"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>{{ scope.obj.domain }}</a>
|
||||||
|
</template>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href=""
|
||||||
|
class="ui tiny accent icon link label"
|
||||||
|
@click.prevent="addSearchToken('domain', scope.obj.domain)"
|
||||||
|
>
|
||||||
|
<i class="home icon" />
|
||||||
|
{{ t('components.manage.library.UploadsTable.link.local') }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="getPrivacyLevelChoice(scope.obj.library.privacy_level)"
|
||||||
|
@click.prevent="addSearchToken('privacy_level', scope.obj.library.privacy_level)"
|
||||||
|
>
|
||||||
|
{{ getPrivacyLevelChoice(scope.obj.library.privacy_level) }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="discrete link"
|
||||||
|
:title="getImportStatusChoice(scope.obj.import_status).help"
|
||||||
|
@click.prevent="addSearchToken('status', scope.obj.import_status)"
|
||||||
|
>
|
||||||
|
{{ getImportStatusChoice(scope.obj.import_status).label }}
|
||||||
|
</a>
|
||||||
|
<Button
|
||||||
|
class="tiny"
|
||||||
|
icon="bi-question-circle"
|
||||||
|
:title="sharedLabels.fields.import_status.label"
|
||||||
|
@click="detailedUpload = scope.obj; showUploadDetailModal = true"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="scope.obj.size">{{ humanSize(scope.obj.size) }}</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ t('components.manage.library.UploadsTable.notApplicable') }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date :date="scope.obj.creation_date" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<human-date
|
||||||
|
v-if="scope.obj.accessed_date"
|
||||||
|
:date="scope.obj.accessed_date"
|
||||||
|
/>
|
||||||
|
<span v-else>
|
||||||
|
{{ t('components.manage.library.UploadsTable.notApplicable') }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</action-table>
|
||||||
|
<Pagination
|
||||||
|
v-if="result && result.count > paginateBy"
|
||||||
|
v-model:page="page"
|
||||||
|
:pages="Math.ceil(result.count / paginateBy)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span v-if="result && result.results.length > 0">
|
||||||
|
{{ t('components.manage.library.UploadsTable.pagination.results', {start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}) }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,73 +1,62 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Tabs from '~/components/ui/Tabs.vue'
|
||||||
|
import Tab from '~/components/ui/Tab.vue'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const labels = computed(() => ({
|
const labels = computed(() => ({
|
||||||
title: t('views.admin.library.Base.title'),
|
title: t('views.admin.library.Base.title'),
|
||||||
secondaryMenu: t('views.admin.library.Base.menu.secondary')
|
secondaryMenu: t('views.admin.library.Base.menu.secondary')
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<Layout
|
||||||
v-title="labels.title"
|
v-title="labels.title"
|
||||||
class="main page-admin-library"
|
main
|
||||||
|
stack
|
||||||
|
class="page-admin-library"
|
||||||
>
|
>
|
||||||
<nav
|
<Tabs>
|
||||||
class="ui secondary pointing menu"
|
<Tab
|
||||||
role="navigation"
|
:title="t('views.admin.library.Base.link.edits')"
|
||||||
:aria-label="labels.secondaryMenu"
|
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.edits'}"
|
:to="{name: 'manage.library.edits'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.edits') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.channels')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.channels'}"
|
:to="{name: 'manage.channels'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.channels') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.artists')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.artists'}"
|
:to="{name: 'manage.library.artists'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.artists') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.albums')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.albums'}"
|
:to="{name: 'manage.library.albums'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.albums') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.tracks')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.tracks'}"
|
:to="{name: 'manage.library.tracks'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.tracks') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.libraries')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.libraries'}"
|
:to="{name: 'manage.library.libraries'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.libraries') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.uploads')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.uploads'}"
|
:to="{name: 'manage.library.uploads'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.uploads') }}
|
<Tab
|
||||||
</router-link>
|
:title="t('views.admin.library.Base.link.tags')"
|
||||||
<router-link
|
|
||||||
class="ui item"
|
|
||||||
:to="{name: 'manage.library.tags'}"
|
:to="{name: 'manage.library.tags'}"
|
||||||
>
|
/>
|
||||||
{{ t('views.admin.library.Base.link.tags') }}
|
</Tabs>
|
||||||
</router-link>
|
<router-view :key="route.fullPath" />
|
||||||
</nav>
|
</Layout>
|
||||||
<router-view :key="$route.fullPath" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { computed } from 'vue'
|
||||||
|
|
||||||
import EditsCardList from '~/components/manage/library/EditsCardList.vue'
|
import EditsCardList from '~/components/manage/library/EditsCardList.vue'
|
||||||
|
|
||||||
|
import Header from '~/components/ui/Header.vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
defaultQuery?: string
|
defaultQuery?: string
|
||||||
}
|
}
|
||||||
|
@ -19,16 +21,13 @@ const labels = computed(() => ({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main v-title="labels.title">
|
<Header
|
||||||
<section class="ui vertical stripe segment">
|
align-left
|
||||||
<edits-card-list
|
no-items
|
||||||
:update-url="true"
|
:h1="t('views.admin.library.EditsList.header.edits')"
|
||||||
:default-query="defaultQuery"
|
/>
|
||||||
>
|
<edits-card-list
|
||||||
<h2 class="ui header">
|
:update-url="true"
|
||||||
{{ t('views.admin.library.EditsList.header.edits') }}
|
:default-query="defaultQuery"
|
||||||
</h2>
|
/>
|
||||||
</edits-card-list>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue