kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
refactor(front): library upload pages
rodzic
cb9ba7d153
commit
f754b397a9
|
@ -1,11 +1,23 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import Nav from '~/components/ui/Nav.vue'
|
||||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
|
||||
const tabs = ref([{
|
||||
title: t('views.content.Base.link.libraries'),
|
||||
to: { name: 'content.libraries.index'}
|
||||
},
|
||||
{
|
||||
title: t('views.content.Base.link.tracks'),
|
||||
to: { name: 'content.libraries.files' },
|
||||
}])
|
||||
|
||||
const labels = computed(() => ({
|
||||
secondaryMenu: t('views.content.Base.menu.secondary'),
|
||||
title: t('views.content.Base.title')
|
||||
|
@ -17,24 +29,11 @@ const labels = computed(() => ({
|
|||
v-title="labels.title"
|
||||
class="main"
|
||||
>
|
||||
<nav
|
||||
class="ui secondary pointing menu"
|
||||
role="navigation"
|
||||
<Nav
|
||||
v-model="tabs"
|
||||
:aria-label="labels.secondaryMenu"
|
||||
>
|
||||
<router-link
|
||||
class="ui item"
|
||||
:to="{name: 'content.libraries.index'}"
|
||||
>
|
||||
{{ t('views.content.Base.link.libraries') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
class="ui item"
|
||||
:to="{name: 'content.libraries.files'}"
|
||||
>
|
||||
{{ t('views.content.Base.link.tracks') }}
|
||||
</router-link>
|
||||
</nav>
|
||||
/>
|
||||
<Spacer />
|
||||
<router-view :key="route.fullPath" />
|
||||
</main>
|
||||
</template>
|
||||
|
|
|
@ -9,7 +9,5 @@ defineProps<Props>()
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<section class="ui vertical aligned stripe segment">
|
||||
<library-files-table :default-query="query" />
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
@ -227,6 +227,7 @@ const getImportStatusChoice = (importStatus: ImportStatus) => {
|
|||
</Layout>
|
||||
</Layout>
|
||||
</Layout>
|
||||
<Spacer />
|
||||
<import-status-modal
|
||||
v-if="detailedUpload"
|
||||
v-model:show="showUploadDetailModal"
|
||||
|
|
|
@ -2,20 +2,29 @@
|
|||
import type { Library } from '~/types'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
import { useStore } from '~/store'
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
import LibraryForm from './Form.vue'
|
||||
import LibraryCard from './Card.vue'
|
||||
import LibraryCard from '~/views/content/remote/Card.vue'
|
||||
import Quota from './Quota.vue'
|
||||
|
||||
import useErrorHandler from '~/composables/useErrorHandler'
|
||||
|
||||
import Loader from '~/components/ui/Loader.vue'
|
||||
import Section from '~/components/ui/Section.vue'
|
||||
import Alert from '~/components/ui/Alert.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const router = useRouter()
|
||||
const store = useStore()
|
||||
|
||||
const libraries = ref([] as Library[])
|
||||
const isLoading = ref(false)
|
||||
|
@ -44,61 +53,42 @@ const libraryCreated = (library: Library) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<section class="ui vertical aligned stripe segment">
|
||||
<!-- TODO: Modernise to new Ui -->
|
||||
<div
|
||||
v-if="isLoading"
|
||||
:class="['ui', {'active': isLoading}, 'inverted', 'dimmer']"
|
||||
>
|
||||
<div class="ui text loader">
|
||||
{{ t('views.content.libraries.Home.loading.libraries') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<Loader v-if="isLoading" />
|
||||
<Section
|
||||
v-else
|
||||
class="ui text container"
|
||||
:h1="t('views.content.libraries.Home.header.libraries')"
|
||||
page-header
|
||||
>
|
||||
<h1 class="ui header">
|
||||
{{ t('views.content.libraries.Home.header.libraries') }}
|
||||
</h1>
|
||||
|
||||
<p v-if="libraries.length == 0">
|
||||
{{ t('views.content.libraries.Home.empty.noLibrary') }}
|
||||
</p>
|
||||
<a
|
||||
:aria-expanded="!hiddenForm"
|
||||
href=""
|
||||
@click.prevent="hiddenForm = !hiddenForm"
|
||||
<Alert
|
||||
v-if="libraries.length == 0"
|
||||
yellow
|
||||
>
|
||||
<i
|
||||
v-if="hiddenForm"
|
||||
class="plus icon"
|
||||
/>
|
||||
<i
|
||||
v-else
|
||||
class="minus icon"
|
||||
/>
|
||||
{{ t('views.content.libraries.Home.link.createLibrary') }}
|
||||
</a>
|
||||
{{ t('views.content.libraries.Home.empty.noLibrary') }}
|
||||
<Button
|
||||
:aria-expanded="!hiddenForm"
|
||||
:icon="hiddenForm ? 'bi-plus' : 'bi-minus'"
|
||||
@click.prevent="hiddenForm = !hiddenForm"
|
||||
>
|
||||
{{ t('views.content.libraries.Home.link.createLibrary') }}
|
||||
</Button>
|
||||
</Alert>
|
||||
<library-form
|
||||
v-if="!hiddenForm"
|
||||
@created="libraryCreated"
|
||||
/>
|
||||
<div class="ui hidden divider" />
|
||||
<quota />
|
||||
<div class="ui hidden divider" />
|
||||
<div
|
||||
v-if="libraries.length > 0"
|
||||
class="ui two column grid"
|
||||
>
|
||||
<div
|
||||
v-for="library in libraries"
|
||||
:key="library.uuid"
|
||||
class="column"
|
||||
>
|
||||
<library-card :library="library" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Section>
|
||||
<quota />
|
||||
<Spacer />
|
||||
<Section
|
||||
v-if="libraries.length > 0"
|
||||
>
|
||||
<library-card
|
||||
v-for="library in libraries"
|
||||
:key="library.uuid"
|
||||
:display-scan="false"
|
||||
:display-follow="store.state.auth.authenticated && library.actor.full_username != store.state.auth.fullUsername"
|
||||
:initial-library="library"
|
||||
:display-copy-fid="true"
|
||||
/>
|
||||
</Section>
|
||||
</template>
|
||||
|
|
|
@ -12,6 +12,12 @@ import { useI18n } from 'vue-i18n'
|
|||
|
||||
import DangerousButton from '~/components/common/DangerousButton.vue'
|
||||
|
||||
import Alert from '~/components/ui/Alert.vue'
|
||||
import Section from '~/components/ui/Section.vue'
|
||||
import Layout from '~/components/ui/Layout.vue'
|
||||
import Link from '~/components/ui/Link.vue'
|
||||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const quotaStatus = ref()
|
||||
|
@ -56,10 +62,9 @@ const purgeErroredFiles = () => purge('errored')
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="ui segment">
|
||||
<h3 class="ui header">
|
||||
{{ t('views.content.libraries.Quota.header.currentUsage') }}
|
||||
</h3>
|
||||
<Section
|
||||
:h3="t('views.content.libraries.Quota.header.currentUsage')"
|
||||
>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
:class="['ui', {'active': isLoading}, 'inverted', 'dimmer']"
|
||||
|
@ -68,9 +73,11 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.loading.currentUsage') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="['ui', {'success': progress < 60}, {'warning': progress >= 60 && progress < 96}, {'error': progress >= 95}, 'progress']"
|
||||
<Alert
|
||||
data-percent="progress"
|
||||
:green="progress < 60"
|
||||
:yellow="progress >= 60 && progress < 96"
|
||||
:red="progress >= 95"
|
||||
>
|
||||
<div
|
||||
class="bar"
|
||||
|
@ -86,17 +93,16 @@ const purgeErroredFiles = () => purge('errored')
|
|||
>
|
||||
{{ t('views.content.libraries.Quota.label.currentUsage', {max: humanSize(quotaStatus.max * 1000 * 1000), currentAmount: humanSize(quotaStatus.current * 1000 * 1000)}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui hidden divider" />
|
||||
<div
|
||||
</Alert>
|
||||
<Layout
|
||||
v-if="quotaStatus"
|
||||
class="ui stackable three column grid"
|
||||
flex
|
||||
>
|
||||
<div
|
||||
<Alert
|
||||
v-if="quotaStatus.pending > 0"
|
||||
class="column"
|
||||
yellow
|
||||
>
|
||||
<div class="ui tiny warning statistic">
|
||||
<div class="statistic">
|
||||
<div class="value">
|
||||
{{ humanSize(quotaStatus.pending * 1000 * 1000) }}
|
||||
</div>
|
||||
|
@ -104,13 +110,16 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.label.pending') }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<router-link
|
||||
class="ui basic primary tiny button"
|
||||
<Spacer />
|
||||
<Layout flex>
|
||||
<Link
|
||||
primary
|
||||
solid
|
||||
low-height
|
||||
:to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'pending'}])}}"
|
||||
>
|
||||
{{ t('views.content.libraries.Quota.link.viewFiles') }}
|
||||
</router-link>
|
||||
</Link>
|
||||
|
||||
<dangerous-button
|
||||
low-height
|
||||
|
@ -125,11 +134,11 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.button.purge') }}
|
||||
</template>
|
||||
</dangerous-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
</Layout>
|
||||
</Alert>
|
||||
<Alert
|
||||
v-if="quotaStatus.skipped > 0"
|
||||
class="column"
|
||||
yellow
|
||||
>
|
||||
<div class="ui tiny statistic">
|
||||
<div class="value">
|
||||
|
@ -139,13 +148,16 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.label.skipped') }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<router-link
|
||||
class="ui basic primary tiny button"
|
||||
<Spacer />
|
||||
<Layout flex>
|
||||
<Link
|
||||
primary
|
||||
solid
|
||||
low-height
|
||||
:to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'skipped'}])}}"
|
||||
>
|
||||
{{ t('views.content.libraries.Quota.link.viewFiles') }}
|
||||
</router-link>
|
||||
</Link>
|
||||
<dangerous-button
|
||||
low-height
|
||||
:action="purgeSkippedFiles"
|
||||
|
@ -159,11 +171,11 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.button.purge') }}
|
||||
</template>
|
||||
</dangerous-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
</Layout>
|
||||
</Alert>
|
||||
<Alert
|
||||
v-if="quotaStatus.errored > 0"
|
||||
class="column"
|
||||
red
|
||||
>
|
||||
<div class="ui tiny danger statistic">
|
||||
<div class="value">
|
||||
|
@ -173,13 +185,16 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.label.errored') }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<router-link
|
||||
class="ui basic primary tiny button"
|
||||
<Spacer />
|
||||
<Layout flex>
|
||||
<Link
|
||||
primary
|
||||
solid
|
||||
low-height
|
||||
:to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'errored'}])}}"
|
||||
>
|
||||
{{ t('views.content.libraries.Quota.link.viewFiles') }}
|
||||
</router-link>
|
||||
</Link>
|
||||
<dangerous-button
|
||||
low-height
|
||||
:action="purgeErroredFiles"
|
||||
|
@ -193,8 +208,8 @@ const purgeErroredFiles = () => purge('errored')
|
|||
{{ t('views.content.libraries.Quota.button.purge') }}
|
||||
</template>
|
||||
</dangerous-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</Alert>
|
||||
</Layout>
|
||||
</Section>
|
||||
</template>
|
||||
|
|
Ładowanie…
Reference in New Issue