feat(front): layout upload modal; use new components
This commit is contained in:
parent
e05a5b9d7a
commit
6eb5c14176
|
@ -18,7 +18,7 @@ interface Action {
|
||||||
label: string
|
label: string
|
||||||
isDangerous?: boolean
|
isDangerous?: boolean
|
||||||
allowAll?: boolean
|
allowAll?: boolean
|
||||||
confirmColor?: string
|
confirmColor?: 'success' | 'danger'
|
||||||
confirmationMessage?: string
|
confirmationMessage?: string
|
||||||
filterChackable?: (item: any) => boolean
|
filterChackable?: (item: any) => boolean
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,13 @@ const checkable = computed(() => {
|
||||||
.map(item => item[props.idField] as string)
|
.map(item => item[props.idField] as string)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// objects is `any`.
|
||||||
|
// Can we narrow down this type?
|
||||||
|
// TODO: Search `action-table` globally and narrow all
|
||||||
|
// `objectsData` props
|
||||||
|
|
||||||
|
// Type Custom = A | B | C
|
||||||
|
|
||||||
const objects = computed(() => props.objectsData.results.map(object => {
|
const objects = computed(() => props.objectsData.results.map(object => {
|
||||||
return props.customObjects.find(custom => custom[props.idField] === object[props.idField])
|
return props.customObjects.find(custom => custom[props.idField] === object[props.idField])
|
||||||
?? object
|
?? object
|
||||||
|
@ -178,27 +185,27 @@ const gridColumns = computed(() => {
|
||||||
columns += 1
|
columns += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.from({ length: columns }, () => 'auto' as 'auto')
|
return Array.from({ length: columns }, () => 'auto' as const)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="table-wrapper component-action-table">
|
<div class="table-wrapper component-action-table">
|
||||||
<Table
|
<Table
|
||||||
v-if="objectsData.count > 0"
|
v-if="objectsData.count > 0"
|
||||||
:grid-template-columns="gridColumns"
|
:grid-template-columns="gridColumns"
|
||||||
class="ui compact very basic unstackable table"
|
class="ui compact very basic unstackable table"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<label v-if="actions.length > 0">
|
<label v-if="actions.length > 0">
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<!-- TODO (wvffle): Check if we don't have to migrate to v-model -->
|
<!-- TODO (wvffle): Check if we don't have to migrate to v-model -->
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:aria-label="labels.selectAllItems"
|
:aria-label="labels.selectAllItems"
|
||||||
:disabled="checkable.length === 0"
|
:disabled="checkable.length === 0"
|
||||||
:checked="checkable.length > 0 && checked.length === checkable.length"
|
:checked="checkable.length > 0 && checked.length === checkable.length"
|
||||||
@change="toggleCheckAll"
|
@change="toggleCheckAll"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
@ -209,14 +216,16 @@ const gridColumns = computed(() => {
|
||||||
v-if="actionUrl && actions.length > 0 || refreshable"
|
v-if="actionUrl && actions.length > 0 || refreshable"
|
||||||
:style="{ gridColumn: `span ${gridColumns.length}`, height: '128px' }"
|
:style="{ gridColumn: `span ${gridColumns.length}`, height: '128px' }"
|
||||||
>
|
>
|
||||||
|
|
||||||
<Layout
|
<Layout
|
||||||
|
v-if="actionUrl && actions.length > 0"
|
||||||
stack
|
stack
|
||||||
no-gap
|
no-gap
|
||||||
v-if="actionUrl && actions.length > 0"
|
|
||||||
>
|
>
|
||||||
<label for="actions-select">{{ t('components.common.ActionTable.label.actions') }}</label>
|
<label for="actions-select">{{ t('components.common.ActionTable.label.actions') }}</label>
|
||||||
<Layout flex class="ui form">
|
<Layout
|
||||||
|
flex
|
||||||
|
class="ui form"
|
||||||
|
>
|
||||||
<select
|
<select
|
||||||
id="actions-select"
|
id="actions-select"
|
||||||
v-model="currentActionName"
|
v-model="currentActionName"
|
||||||
|
@ -331,8 +340,8 @@ const gridColumns = computed(() => {
|
||||||
<Spacer grow />
|
<Spacer grow />
|
||||||
|
|
||||||
<Layout
|
<Layout
|
||||||
label
|
|
||||||
v-if="refreshable"
|
v-if="refreshable"
|
||||||
|
label
|
||||||
class="right floated"
|
class="right floated"
|
||||||
>
|
>
|
||||||
<span v-if="needsRefresh">
|
<span v-if="needsRefresh">
|
||||||
|
@ -343,10 +352,10 @@ const gridColumns = computed(() => {
|
||||||
icon="bi-arrow-clockwise"
|
icon="bi-arrow-clockwise"
|
||||||
:title="labels.refresh"
|
:title="labels.refresh"
|
||||||
:aria-label="labels.refresh"
|
:aria-label="labels.refresh"
|
||||||
@click="$emit('refresh')"
|
|
||||||
style="align-self: end;"
|
style="align-self: end;"
|
||||||
|
@click="$emit('refresh')"
|
||||||
>
|
>
|
||||||
{{ labels.refresh }}
|
{{ labels.refresh }}
|
||||||
</Button>
|
</Button>
|
||||||
</Layout>
|
</Layout>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,6 +25,10 @@ import useSharedLabels from '~/composables/locale/useSharedLabels'
|
||||||
import Alert from '~/components/ui/Alert.vue'
|
import Alert from '~/components/ui/Alert.vue'
|
||||||
import Button from '~/components/ui/Button.vue'
|
import Button from '~/components/ui/Button.vue'
|
||||||
import Slider from '~/components/ui/Slider.vue'
|
import Slider from '~/components/ui/Slider.vue'
|
||||||
|
import Section from '~/components/ui/Section.vue'
|
||||||
|
import Pill from '~/components/ui/Pill.vue'
|
||||||
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
|
import Table from '~/components/ui/Table.vue'
|
||||||
|
|
||||||
interface Events {
|
interface Events {
|
||||||
(e: 'uploads-finished', delta: number):void
|
(e: 'uploads-finished', delta: number):void
|
||||||
|
@ -343,6 +347,9 @@ useEventListener(window, 'beforeunload', (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
return (event.returnValue = t('components.library.FileUpload.message.listener'))
|
return (event.returnValue = t('components.library.FileUpload.message.listener'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// collapse section
|
||||||
|
const section = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -361,27 +368,8 @@ useEventListener(window, 'beforeunload', (event) => {
|
||||||
:options="options"
|
:options="options"
|
||||||
:label="t('components.manage.library.UploadsTable.label.visibility')"
|
:label="t('components.manage.library.UploadsTable.label.visibility')"
|
||||||
/>
|
/>
|
||||||
<file-upload-widget
|
|
||||||
ref="upload"
|
|
||||||
v-model="files"
|
|
||||||
:data="uploadData"
|
|
||||||
@input-file="inputFile"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
primary
|
|
||||||
icon="bi bi-upload"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.label.uploadWidget') }}
|
|
||||||
</Button>
|
|
||||||
<p>
|
|
||||||
{{ t('components.library.FileUpload.label.extensions', {extensions: supportedExtensions.join(', ')}) }}
|
|
||||||
</p>
|
|
||||||
</file-upload-widget>
|
|
||||||
|
|
||||||
<Alert blue>
|
<Alert blue>
|
||||||
<h2 class="ui header">
|
|
||||||
{{ t('components.library.FileUpload.header.local') }}
|
|
||||||
</h2>
|
|
||||||
<p>
|
<p>
|
||||||
{{ t('components.library.FileUpload.message.local.message') }}
|
{{ t('components.library.FileUpload.message.local.message') }}
|
||||||
</p>
|
</p>
|
||||||
|
@ -402,9 +390,55 @@ useEventListener(window, 'beforeunload', (event) => {
|
||||||
</ul>
|
</ul>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
<h2 class="ui header">
|
<file-upload-widget
|
||||||
{{ t('components.library.FileUpload.header.server') }}
|
ref="upload"
|
||||||
</h2>
|
v-model="files"
|
||||||
|
:data="uploadData"
|
||||||
|
@input-file="inputFile"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
icon="bi bi-upload"
|
||||||
|
>
|
||||||
|
{{ t('components.library.FileUpload.label.uploadWidget') }}
|
||||||
|
</Button>
|
||||||
|
<p>
|
||||||
|
{{ t('components.library.FileUpload.label.extensions', {extensions: supportedExtensions.join(', ')}) }}
|
||||||
|
</p>
|
||||||
|
</file-upload-widget>
|
||||||
|
|
||||||
|
<!-- Show how many files are uploading and processing -->
|
||||||
|
|
||||||
|
<Layout
|
||||||
|
v-if="files.length > 0"
|
||||||
|
flex
|
||||||
|
>
|
||||||
|
<Layout
|
||||||
|
flex
|
||||||
|
gap-8
|
||||||
|
>
|
||||||
|
<label>{{ t('components.library.FileUpload.link.uploading') }}</label>
|
||||||
|
<Pill
|
||||||
|
v-bind="{
|
||||||
|
'green': erroredFilesCount === 0,
|
||||||
|
'red': erroredFilesCount > 0,
|
||||||
|
'yellow': files.length > uploadedFilesCount + erroredFilesCount
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ uploadedFilesCount + erroredFilesCount }} / {{ files.length }}
|
||||||
|
</Pill>
|
||||||
|
</Layout>
|
||||||
|
<Layout
|
||||||
|
flex
|
||||||
|
gap-8
|
||||||
|
>
|
||||||
|
<label>{{ t('components.library.FileUpload.link.processing') }}</label>
|
||||||
|
<Pill>
|
||||||
|
{{ processedFilesCount }} / {{ processableFiles }}
|
||||||
|
</Pill>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
<Alert
|
<Alert
|
||||||
v-if="fsErrors.length > 0"
|
v-if="fsErrors.length > 0"
|
||||||
red
|
red
|
||||||
|
@ -421,32 +455,8 @@ useEventListener(window, 'beforeunload', (event) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Alert>
|
</Alert>
|
||||||
<fs-browser
|
|
||||||
v-model="fsPath"
|
|
||||||
:loading="isLoadingFs"
|
|
||||||
:data="fsStatus"
|
|
||||||
@import="importFs"
|
|
||||||
/>
|
|
||||||
<template v-if="fsStatus && fsStatus.import">
|
|
||||||
<h3 class="ui header">
|
|
||||||
{{ t('components.library.FileUpload.header.status') }}
|
|
||||||
</h3>
|
|
||||||
<p v-if="fsStatus.import.reference !== importReference">
|
|
||||||
{{ t('components.library.FileUpload.description.previousImport') }}
|
|
||||||
</p>
|
|
||||||
<p v-else>
|
|
||||||
{{ t('components.library.FileUpload.description.import') }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Button
|
<!-- Show list of processed files -->
|
||||||
v-if="fsStatus.import.status === 'started' || fsStatus.import.status === 'pending'"
|
|
||||||
secondary
|
|
||||||
@click="cancelFsScan"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.button.cancel') }}
|
|
||||||
</Button>
|
|
||||||
<fs-logs :data="fsStatus.import" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<library-files-table
|
<library-files-table
|
||||||
:needs-refresh="needsRefresh"
|
:needs-refresh="needsRefresh"
|
||||||
|
@ -455,177 +465,164 @@ useEventListener(window, 'beforeunload', (event) => {
|
||||||
:custom-objects="Object.values(uploads.objects)"
|
:custom-objects="Object.values(uploads.objects)"
|
||||||
@fetch-start="needsRefresh = false"
|
@fetch-start="needsRefresh = false"
|
||||||
/>
|
/>
|
||||||
<div class="ui top attached tabular menu">
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
:class="['item', {active: currentTab === 'uploads'}]"
|
|
||||||
@click.prevent="currentTab = 'uploads'"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.link.uploading') }}
|
|
||||||
<div
|
|
||||||
v-if="files.length === 0"
|
|
||||||
class="ui label"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.empty.noFiles') }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else-if="files.length > uploadedFilesCount + erroredFilesCount"
|
|
||||||
class="ui warning label"
|
|
||||||
>
|
|
||||||
{{ uploadedFilesCount + erroredFilesCount }}
|
|
||||||
<span class="bi bi-slash-circle" />
|
|
||||||
{{ files.length }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
:class="['ui', {'success': erroredFilesCount === 0}, {'danger': erroredFilesCount > 0}, 'label']"
|
|
||||||
>
|
|
||||||
{{ uploadedFilesCount + erroredFilesCount }}
|
|
||||||
<span class="bi bi-slash-circle" />
|
|
||||||
{{ files.length }}
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href=""
|
|
||||||
:class="['item', {active: currentTab === 'processing'}]"
|
|
||||||
@click.prevent="currentTab = 'processing'"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.link.processing') }}
|
|
||||||
<div
|
|
||||||
v-if="processableFiles === 0"
|
|
||||||
class="ui label"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.empty.noFiles') }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else-if="processableFiles > processedFilesCount"
|
|
||||||
class="ui warning label"
|
|
||||||
>
|
|
||||||
{{ processedFilesCount }}
|
|
||||||
<span class="bi bi-slash-circle" />
|
|
||||||
{{ processableFiles }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
:class="['ui', {'success': uploads.errored === 0}, {'danger': uploads.errored > 0}, 'label']"
|
|
||||||
>
|
|
||||||
{{ processedFilesCount }}
|
|
||||||
<span class="bi bi-slash-circle" />
|
|
||||||
{{ processableFiles }}
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="files.length > 0"
|
|
||||||
class="table-wrapper"
|
|
||||||
>
|
|
||||||
<table class="ui unstackable table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="ten wide">
|
|
||||||
{{ t('components.library.FileUpload.table.upload.header.filename') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.library.FileUpload.table.upload.header.size') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.library.FileUpload.table.upload.header.status') }}
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
{{ t('components.library.FileUpload.table.upload.header.actions') }}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="retryableFiles.length > 1">
|
|
||||||
<th class="ten wide" />
|
|
||||||
<th />
|
|
||||||
<th />
|
|
||||||
<th>
|
|
||||||
<Button
|
|
||||||
tiny
|
|
||||||
style="float: right;"
|
|
||||||
@click.prevent="retry(retryableFiles)"
|
|
||||||
>
|
|
||||||
{{ t('components.library.FileUpload.button.retry') }}
|
|
||||||
</Button>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr
|
|
||||||
v-for="file in sortedFiles"
|
|
||||||
:key="file.id"
|
|
||||||
>
|
|
||||||
<td :title="file.name">
|
|
||||||
{{ truncate(file.name ?? '', 60) }}
|
|
||||||
</td>
|
|
||||||
<td>{{ humanSize(file.size ?? 0) }}</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
v-if="typeof file.error === 'string' && file.error"
|
|
||||||
class="ui tooltip"
|
|
||||||
:data-tooltip="labels.tooltips[file.error]"
|
|
||||||
>
|
|
||||||
<span class="ui danger icon label">
|
|
||||||
<i class="bi bi-question-circle-fill" /> {{ file.error }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-else-if="file.success"
|
|
||||||
class="ui success label"
|
|
||||||
>
|
|
||||||
<span key="1">
|
|
||||||
{{ t('components.library.FileUpload.table.upload.status.uploaded') }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-else-if="file.active"
|
|
||||||
class="ui warning label"
|
|
||||||
>
|
|
||||||
<span key="2">
|
|
||||||
{{ t('components.library.FileUpload.table.upload.status.uploading') }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{{ t('components.library.FileUpload.table.upload.progress', {percent: parseFloat(file.progress ?? '0.00')}) }}
|
<!-- Edit the metadata of uploaded files -->
|
||||||
</span>
|
|
||||||
<span
|
<Table
|
||||||
v-else
|
:class="$style.table"
|
||||||
class="ui label"
|
v-if="files.length > 0"
|
||||||
>
|
:grid-template-columns="['1fr', 'auto', 'auto', 'auto']"
|
||||||
<span key="3">
|
>
|
||||||
{{ t('components.library.FileUpload.table.upload.status.pending') }}
|
<template #header>
|
||||||
</span>
|
<b class="ten wide">
|
||||||
</span>
|
{{ t('components.library.FileUpload.table.upload.header.filename') }}
|
||||||
</td>
|
</b>
|
||||||
<td>
|
<b>
|
||||||
<template v-if="file.error">
|
{{ t('components.library.FileUpload.table.upload.header.size') }}
|
||||||
<Button
|
</b>
|
||||||
v-if="retryableFiles.includes(file)"
|
<b>
|
||||||
tiny
|
{{ t('components.library.FileUpload.table.upload.header.status') }}
|
||||||
style="float: right;"
|
</b>
|
||||||
:title="labels.tooltips.retry"
|
<b>
|
||||||
icon="bi-arrow-clockwise"
|
{{ t('components.library.FileUpload.table.upload.header.actions') }}
|
||||||
@click.prevent="retry([file])"
|
</b>
|
||||||
/>
|
</template>
|
||||||
</template>
|
|
||||||
<template v-else-if="!file.success">
|
<!-- Retry row -->
|
||||||
<Button
|
<template v-if="retryableFiles.length > 1">
|
||||||
tiny
|
<b> </b>
|
||||||
style="float: right;"
|
<b />
|
||||||
icon="bi-trash-fill"
|
<b />
|
||||||
@click.prevent="upload.remove(file)"
|
<b>
|
||||||
/>
|
<Button
|
||||||
</template>
|
auto
|
||||||
</td>
|
primary
|
||||||
</tr>
|
@click.prevent="retry(retryableFiles)"
|
||||||
</tbody>
|
>
|
||||||
</table>
|
{{ t('components.library.FileUpload.button.retry') }}
|
||||||
</div>
|
</Button>
|
||||||
|
</b>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Rows for each file -->
|
||||||
|
<template
|
||||||
|
v-for="file in sortedFiles"
|
||||||
|
:key="file.id"
|
||||||
|
>
|
||||||
|
<b :title="file.name">
|
||||||
|
{{ truncate(file.name ?? '', 60) }}
|
||||||
|
</b>
|
||||||
|
<b>{{ humanSize(file.size ?? 0) }}</b>
|
||||||
|
<b>
|
||||||
|
<span
|
||||||
|
v-if="typeof file.error === 'string' && file.error"
|
||||||
|
class="ui tooltip"
|
||||||
|
:data-tooltip="labels.tooltips[file.error]"
|
||||||
|
>
|
||||||
|
<span class="ui danger icon label">
|
||||||
|
<i class="bi bi-question-circle-fill" /> {{ file.error }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="file.success"
|
||||||
|
class="ui success label"
|
||||||
|
>
|
||||||
|
<span key="1">
|
||||||
|
{{ t('components.library.FileUpload.table.upload.status.uploaded') }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="file.active"
|
||||||
|
class="ui warning label"
|
||||||
|
>
|
||||||
|
<span key="2">
|
||||||
|
{{ t('components.library.FileUpload.table.upload.status.uploading') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{{ t('components.library.FileUpload.table.upload.progress', {percent: parseFloat(file.progress ?? '0.00')}) }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
class="ui label"
|
||||||
|
>
|
||||||
|
<span key="3">
|
||||||
|
{{ t('components.library.FileUpload.table.upload.status.pending') }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</b>
|
||||||
|
<b>
|
||||||
|
<template v-if="file.error">
|
||||||
|
<Button
|
||||||
|
v-if="retryableFiles.includes(file)"
|
||||||
|
square
|
||||||
|
secondary
|
||||||
|
:title="labels.tooltips.retry"
|
||||||
|
icon="bi-arrow-clockwise"
|
||||||
|
@click.prevent="retry([file])"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="!file.success">
|
||||||
|
<Button
|
||||||
|
square-small
|
||||||
|
destructive
|
||||||
|
icon="bi-trash-fill"
|
||||||
|
@click.prevent="upload.remove(file)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</b>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
|
||||||
|
<!-- Progressive disclosure: Import from server -->
|
||||||
|
|
||||||
|
<Section
|
||||||
|
:h2="t('components.library.FileUpload.header.server')"
|
||||||
|
align-left
|
||||||
|
no-items
|
||||||
|
v-bind="
|
||||||
|
section
|
||||||
|
? { collapse: () => { section = false } }
|
||||||
|
: { expand: () => { section = true } }
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div style="grid-column: 1 / -1">
|
||||||
|
<fs-browser
|
||||||
|
v-model="fsPath"
|
||||||
|
:loading="isLoadingFs"
|
||||||
|
:data="fsStatus"
|
||||||
|
@import="importFs"
|
||||||
|
/>
|
||||||
|
<template v-if="fsStatus && fsStatus.import">
|
||||||
|
<h3 class="ui header">
|
||||||
|
{{ t('components.library.FileUpload.header.status') }}
|
||||||
|
</h3>
|
||||||
|
<p v-if="fsStatus.import.reference !== importReference">
|
||||||
|
{{ t('components.library.FileUpload.description.previousImport') }}
|
||||||
|
</p>
|
||||||
|
<p v-else>
|
||||||
|
{{ t('components.library.FileUpload.description.import') }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
v-if="fsStatus.import.status === 'started' || fsStatus.import.status === 'pending'"
|
||||||
|
secondary
|
||||||
|
@click="cancelFsScan"
|
||||||
|
>
|
||||||
|
{{ t('components.library.FileUpload.button.cancel') }}
|
||||||
|
</Button>
|
||||||
|
<fs-logs :data="fsStatus.import" />
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style module lang="scss">
|
||||||
.file-uploads {
|
.file-uploads {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
border-radius: var(--fw-border-radius);
|
border-radius: var(--fw-border-radius);
|
||||||
border: 2px dashed var(--border-color);
|
border: 2px dashed var(--border-color);
|
||||||
}
|
}
|
||||||
|
.table {
|
||||||
|
b:not(:first-child) { margin-left: 12px; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { useStore } from '~/store'
|
||||||
import FileUpload from 'vue-upload-component'
|
import FileUpload from 'vue-upload-component'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
channel: components['schemas']['Channel']['uuid'];
|
channel?: components['schemas']['Channel']['uuid'];
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { get } = useCookies()
|
const { get } = useCookies()
|
||||||
|
@ -94,6 +94,7 @@ export default { inheritAttrs: false }
|
||||||
<file-upload
|
<file-upload
|
||||||
ref="upload"
|
ref="upload"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:class="$style.uploader"
|
||||||
:post-action="store.getters['instance/absoluteUrl']('/api/v2/uploads/')"
|
:post-action="store.getters['instance/absoluteUrl']('/api/v2/uploads/')"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
:thread="1"
|
:thread="1"
|
||||||
|
@ -106,3 +107,10 @@ export default { inheritAttrs: false }
|
||||||
<slot />
|
<slot />
|
||||||
</file-upload>
|
</file-upload>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style module lang="scss">
|
||||||
|
.uploader label {
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -28,6 +28,8 @@ import Button from '~/components/ui/Button.vue'
|
||||||
import Input from '~/components/ui/Input.vue'
|
import Input from '~/components/ui/Input.vue'
|
||||||
import Loader from '~/components/ui/Loader.vue'
|
import Loader from '~/components/ui/Loader.vue'
|
||||||
|
|
||||||
|
// This is the 'processing' tab in the old upload process
|
||||||
|
|
||||||
interface Events {
|
interface Events {
|
||||||
(e: 'fetch-start'): void
|
(e: 'fetch-start'): void
|
||||||
}
|
}
|
||||||
|
@ -141,17 +143,6 @@ const getImportStatusChoice = (importStatus: ImportStatus) => {
|
||||||
<template>
|
<template>
|
||||||
<Layout form>
|
<Layout form>
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="ui six wide field">
|
|
||||||
<form @submit.prevent="console.log(search);query = search">
|
|
||||||
<Input
|
|
||||||
id="files-search"
|
|
||||||
v-model="search"
|
|
||||||
search
|
|
||||||
:label="t('views.content.libraries.FilesTable.label.search')"
|
|
||||||
:placeholder="labels.searchPlaceholder"
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="import-status">
|
<label for="import-status">
|
||||||
{{ t('views.content.libraries.FilesTable.label.importStatus') }}
|
{{ t('views.content.libraries.FilesTable.label.importStatus') }}
|
||||||
|
|
Loading…
Reference in New Issue