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