upload file, work on delete file
This commit is contained in:
parent
e3fd809820
commit
631c066415
@ -2,15 +2,8 @@
|
||||
<div>
|
||||
<Menu />
|
||||
<b-container class="browser">
|
||||
<loading
|
||||
:active.sync="isLoading"
|
||||
:can-cancel="false"
|
||||
:is-full-page="false"
|
||||
background-color="#485159"
|
||||
color="#ff9c36"
|
||||
/>
|
||||
<div v-if="folderTree.tree" class="browser">
|
||||
<div>
|
||||
<div class="bread-div">
|
||||
<b-breadcrumb>
|
||||
<b-breadcrumb-item
|
||||
v-for="(crumb, index) in crumbs"
|
||||
@ -23,57 +16,166 @@
|
||||
</b-breadcrumb>
|
||||
</div>
|
||||
|
||||
<b-row>
|
||||
<b-col class="folder-col">
|
||||
<splitpanes class="browser-row default-theme pane-row">
|
||||
<pane min-size="20" size="24">
|
||||
<div class="browser-div">
|
||||
<b-list-group>
|
||||
<b-list-group-item
|
||||
v-for="folder in folderTree.tree[1]"
|
||||
:key="folder.key"
|
||||
class="browser-item"
|
||||
>
|
||||
<b-link @click="getPath(extensions, `${folderTree.tree[0]}/${folder}`)">
|
||||
<b-icon-folder-fill class="browser-icons" /> {{ folder }}
|
||||
</b-link>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
<perfect-scrollbar>
|
||||
<b-list-group class="folder-list">
|
||||
<b-list-group-item
|
||||
v-for="folder in folderTree.tree[1]"
|
||||
:key="folder.key"
|
||||
class="browser-item folder"
|
||||
>
|
||||
<b-row>
|
||||
<b-col cols="1" class="browser-icons-col">
|
||||
<b-icon-folder-fill class="browser-icons" />
|
||||
</b-col>
|
||||
<b-col class="browser-item-text">
|
||||
<b-link @click="getPath(extensions, `${folderTree.tree[0]}/${folder}`)">
|
||||
{{ folder }}
|
||||
</b-link>
|
||||
</b-col>
|
||||
<b-col v-if="folder !== '..'" cols="1" class="folder-delete">
|
||||
<b-link @click="showDeleteModal('Folder', `/${folderTree.tree[0]}/${folder}`)">
|
||||
<b-icon-x-circle-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</perfect-scrollbar>
|
||||
</div>
|
||||
</b-col>
|
||||
<b-col class="files-col">
|
||||
</pane>
|
||||
<pane class="files-col">
|
||||
<loading
|
||||
:active.sync="isLoading"
|
||||
:can-cancel="false"
|
||||
:is-full-page="false"
|
||||
background-color="#485159"
|
||||
color="#ff9c36"
|
||||
/>
|
||||
<div class="browser-div">
|
||||
<b-list-group>
|
||||
<b-list-group-item
|
||||
v-for="file in folderTree.tree[2]"
|
||||
:key="file.key"
|
||||
class="browser-item"
|
||||
>
|
||||
<b-link>
|
||||
<b-icon-film class="browser-icons" /> {{ file.file }}
|
||||
<span class="duration">{{ file.duration | toMin }}</span>
|
||||
</b-link>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
<perfect-scrollbar>
|
||||
<b-list-group class="files-list">
|
||||
<b-list-group-item
|
||||
v-for="file in folderTree.tree[2]"
|
||||
:key="file.key"
|
||||
class="browser-item"
|
||||
>
|
||||
<b-row>
|
||||
<b-col cols="1" class="browser-icons-col">
|
||||
<b-icon-film class="browser-icons" />
|
||||
</b-col>
|
||||
<b-col class="browser-item-text">
|
||||
{{ file.file }}
|
||||
</b-col>
|
||||
<b-col cols="1" class="browser-play-col">
|
||||
<b-link @click="showPreviewModal(`/${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-icon-play-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
<b-col cols="1" class="browser-dur-col">
|
||||
<span class="duration">{{ file.duration | toMin }}</span>
|
||||
</b-col>
|
||||
<b-col cols="1" class="text-center">
|
||||
<b-link @click="showDeleteModal('File', `/${folderTree.tree[0]}/${file.file}`)">
|
||||
<b-icon-x-circle-fill />
|
||||
</b-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</perfect-scrollbar>
|
||||
</div>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
<b-button class="upload-button" variant="primary" @click="showUploadModal()">
|
||||
File Upload
|
||||
</b-button>
|
||||
</div>
|
||||
</b-container>
|
||||
<b-modal
|
||||
id="preview-modal"
|
||||
ref="prev-modal"
|
||||
size="xl"
|
||||
centered
|
||||
:title="`Preview: ${previewName}`"
|
||||
hide-footer
|
||||
>
|
||||
<b-img v-if="isImage" :src="previewSource" fluid :alt="previewName" />
|
||||
<video-player v-else-if="!isImage && previewOptions" reference="previewPlayer" :options="previewOptions" />
|
||||
</b-modal>
|
||||
|
||||
<b-modal
|
||||
id="upload-modal"
|
||||
ref="up-modal"
|
||||
size="xl"
|
||||
centered
|
||||
title="File Upload"
|
||||
hide-footer
|
||||
>
|
||||
<b-form @submit="onSubmitUpload" @reset="onResetUpload">
|
||||
<b-form-file
|
||||
v-model="inputFiles"
|
||||
:state="Boolean(inputFiles)"
|
||||
placeholder="Choose files or drop them here..."
|
||||
drop-placeholder="Drop files here..."
|
||||
multiple
|
||||
:accept="extensions.replace(/ /g, ', ')"
|
||||
:file-name-formatter="formatNames"
|
||||
/>
|
||||
<b-row>
|
||||
<b-col cols="10">
|
||||
<b-row class="progress-row">
|
||||
<b-col cols="1">
|
||||
Overall:
|
||||
</b-col>
|
||||
<b-col cols="10">
|
||||
<b-progress :value="overallProgress" />
|
||||
</b-col>
|
||||
<div class="w-100" />
|
||||
<b-col cols="1">
|
||||
Current:
|
||||
</b-col>
|
||||
<b-col cols="10">
|
||||
<b-progress :value="currentProgress" />
|
||||
</b-col>
|
||||
<div class="w-100" />
|
||||
<b-col cols="1">
|
||||
Uploading:
|
||||
</b-col>
|
||||
<b-col cols="10">
|
||||
<strong>{{ uploadTask }}</strong>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
<b-col cols="2">
|
||||
<div class="upload-button">
|
||||
<b-button type="submit" variant="primary">
|
||||
Upload
|
||||
</b-button>
|
||||
<b-button type="reset" variant="primary">
|
||||
Cancel
|
||||
</b-button>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-form>
|
||||
</b-modal>
|
||||
<b-modal id="delete-modal" :title="`Delete ${deleteType}`" centered hide-footer>
|
||||
<p>
|
||||
Are you sure that you want to delete:<br>
|
||||
<strong>{{ previewName }}</strong>
|
||||
</p>
|
||||
<div class="upload-button">
|
||||
<b-button variant="primary" @click="deleteFileOrFolder()">
|
||||
Ok
|
||||
</b-button>
|
||||
<b-button variant="primary" @click="cancelDelete()">
|
||||
Cancel
|
||||
</b-button>
|
||||
</div>
|
||||
</b-container>
|
||||
<!--
|
||||
<b-form @submit="onSubmit">
|
||||
<b-form-file
|
||||
v-model="inputFile"
|
||||
:state="Boolean(inputFile)"
|
||||
placeholder="Choose a file or drop it here..."
|
||||
drop-placeholder="Drop file here..."
|
||||
/>
|
||||
<b-button type="submit" variant="primary">
|
||||
Submit
|
||||
</b-button>
|
||||
</b-form>
|
||||
<div class="mt-3">
|
||||
Selected file: {{ inputFile ? inputFile.name : '' }}
|
||||
</div>
|
||||
-->
|
||||
</b-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -92,7 +194,19 @@ export default {
|
||||
return {
|
||||
isLoading: false,
|
||||
extensions: '',
|
||||
inputFile: null
|
||||
inputFiles: null,
|
||||
previewOptions: {},
|
||||
previewComp: null,
|
||||
previewName: '',
|
||||
previewSource: '',
|
||||
deleteType: 'File',
|
||||
deleteSource: '',
|
||||
isImage: false,
|
||||
uploadTask: '',
|
||||
overallProgress: 0,
|
||||
currentProgress: 0,
|
||||
cancelTokenSource: this.$axios.CancelToken.source(),
|
||||
lastPath: ''
|
||||
}
|
||||
},
|
||||
|
||||
@ -112,31 +226,142 @@ export default {
|
||||
|
||||
methods: {
|
||||
async getPath (extensions, path) {
|
||||
this.lastPath = path
|
||||
this.isLoading = true
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
await this.$store.dispatch('media/getTree', { extensions, path })
|
||||
this.isLoading = false
|
||||
},
|
||||
|
||||
async onSubmit (evt) {
|
||||
showUploadModal () {
|
||||
this.uploadTask = ''
|
||||
this.currentProgress = 0
|
||||
this.overallProgress = 0
|
||||
this.$root.$emit('bv::show::modal', 'upload-modal')
|
||||
},
|
||||
|
||||
formatNames (files) {
|
||||
if (files.length === 1) {
|
||||
return files[0].name
|
||||
} else {
|
||||
return `${files.length} files selected`
|
||||
}
|
||||
},
|
||||
|
||||
async onSubmitUpload (evt) {
|
||||
evt.preventDefault()
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
|
||||
const config = {
|
||||
onUploadProgress: (progressEvent) => {
|
||||
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
||||
console.log(percentCompleted)
|
||||
},
|
||||
headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken }
|
||||
const uploadProgress = fileName => (progressEvent) => {
|
||||
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
||||
this.currentProgress = progress
|
||||
}
|
||||
|
||||
this.$axios.put(
|
||||
`/upload/${encodeURIComponent(this.inputFile.name)}?path=${encodeURIComponent(this.crumbs.map(e => e.text).join('/'))}`,
|
||||
this.inputFile,
|
||||
config
|
||||
for (const [i, file] of this.inputFiles.entries()) {
|
||||
this.uploadTask = file.name
|
||||
|
||||
const config = {
|
||||
onUploadProgress: uploadProgress(file.name),
|
||||
cancelToken: this.cancelTokenSource.token,
|
||||
headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken }
|
||||
}
|
||||
|
||||
await this.$axios.put(
|
||||
`/upload/${encodeURIComponent(file.name)}?path=${encodeURIComponent(this.crumbs.map(e => e.text).join('/'))}`,
|
||||
file,
|
||||
config
|
||||
)
|
||||
.then(
|
||||
this.overallProgress = (i + 1) * 100 / this.inputFiles.length,
|
||||
this.currentProgress = 0,
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
)
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
this.uploadTask = 'Done...'
|
||||
this.getPath(this.extensions, this.lastPath)
|
||||
},
|
||||
|
||||
onResetUpload (evt) {
|
||||
evt.preventDefault()
|
||||
this.inputFiles = null
|
||||
this.overallProgress = 0
|
||||
this.currentProgress = 0
|
||||
this.uploadTask = ''
|
||||
|
||||
this.cancelTokenSource.cancel('Upload cancelled')
|
||||
this.getPath(this.extensions, this.lastPath)
|
||||
|
||||
this.$root.$emit('bv::hide::modal', 'upload-modal')
|
||||
},
|
||||
|
||||
showPreviewModal (src) {
|
||||
this.previewSource = src
|
||||
this.previewName = src.split('/').slice(-1)[0]
|
||||
const ext = this.previewName.split('.').slice(-1)[0]
|
||||
|
||||
if (this.configPlayout.storage.extensions.includes(`.${ext}`)) {
|
||||
this.isImage = false
|
||||
this.previewOptions = {
|
||||
liveui: false,
|
||||
controls: true,
|
||||
suppressNotSupportedError: true,
|
||||
autoplay: false,
|
||||
preload: 'auto',
|
||||
sources: [
|
||||
{
|
||||
type: `video/${ext}`,
|
||||
src: encodeURIComponent(src)
|
||||
}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
this.isImage = true
|
||||
}
|
||||
this.$root.$emit('bv::show::modal', 'preview-modal')
|
||||
},
|
||||
|
||||
showDeleteModal (type, src) {
|
||||
this.deleteSource = src
|
||||
|
||||
if (type === 'File') {
|
||||
this.previewName = src.split('/').slice(-1)[0]
|
||||
} else {
|
||||
this.previewName = src
|
||||
}
|
||||
|
||||
this.deleteType = type
|
||||
this.$root.$emit('bv::show::modal', 'delete-modal')
|
||||
},
|
||||
|
||||
async deleteFileOrFolder () {
|
||||
await this.$store.dispatch('auth/inspectToken')
|
||||
let file
|
||||
|
||||
if (this.deleteType === 'File') {
|
||||
file = this.deleteSource.split('/').slice(-1)[0]
|
||||
} else {
|
||||
file = null
|
||||
}
|
||||
|
||||
const pathName = this.deleteSource.substring(0, this.deleteSource.lastIndexOf('/') + 1)
|
||||
|
||||
await this.$axios.delete(
|
||||
`/delete/?file=${encodeURIComponent(file)}&path=${encodeURIComponent(pathName)}`,
|
||||
{ headers: { Authorization: 'Bearer ' + this.$store.state.auth.jwtToken } }
|
||||
)
|
||||
.then(res => console.log(res))
|
||||
.then(response => console.log(response))
|
||||
.catch(err => console.log(err))
|
||||
|
||||
this.$root.$emit('bv::hide::modal', 'delete-modal')
|
||||
|
||||
this.getPath(this.extensions, this.lastPath)
|
||||
},
|
||||
|
||||
cancelDelete () {
|
||||
this.deleteSource = ''
|
||||
this.$root.$emit('bv::hide::modal', 'delete-modal')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,19 +371,11 @@ export default {
|
||||
.browser {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.folder-col {
|
||||
min-width: 320px;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.folder {
|
||||
padding: .3em;
|
||||
}
|
||||
|
||||
.files-col {
|
||||
min-width: 320px;
|
||||
.bread-div {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.browser-div {
|
||||
@ -167,4 +384,57 @@ export default {
|
||||
border: 1px solid #000;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.browser-row {
|
||||
height: calc(100% - 90px);
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.folder-col {
|
||||
min-width: 320px;
|
||||
max-width: 460px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.folder:hover > div > .folder-delete {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.folder-list {
|
||||
height: 100%;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.folder-delete {
|
||||
margin-right: .5em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.files-col {
|
||||
min-width: 320px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.files-list {
|
||||
width: 99.5%;
|
||||
height: 100%;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.upload-button {
|
||||
float: right;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.progress-row {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.progress-row .col-1 {
|
||||
min-width: 60px
|
||||
}
|
||||
|
||||
.progress-row .col-10 {
|
||||
margin: auto 0 auto 0
|
||||
}
|
||||
</style>
|
||||
|
@ -18,34 +18,32 @@ export const mutations = {
|
||||
|
||||
export const actions = {
|
||||
async getTree ({ commit, dispatch, state, rootState }, { extensions, path }) {
|
||||
if ((path !== state.currentPath || !state.folderTree)) {
|
||||
const crumbs = []
|
||||
let root = '/'
|
||||
const response = await this.$axios.get(`api/media/?extensions=${extensions}&path=${path}`, { headers: { Authorization: 'Bearer ' + rootState.auth.jwtToken } })
|
||||
const crumbs = []
|
||||
let root = '/'
|
||||
const response = await this.$axios.get(`api/media/?extensions=${extensions}&path=${path}`, { headers: { Authorization: 'Bearer ' + rootState.auth.jwtToken } })
|
||||
|
||||
if (response.data.tree) {
|
||||
const pathArr = response.data.tree[0].split('/')
|
||||
if (response.data.tree) {
|
||||
const pathArr = response.data.tree[0].split('/')
|
||||
|
||||
if (response.data.tree[1].length === 0) {
|
||||
response.data.tree[1].push(pathArr[pathArr.length - 1])
|
||||
}
|
||||
|
||||
if (path) {
|
||||
for (const crumb of pathArr) {
|
||||
if (crumb) {
|
||||
root += crumb + '/'
|
||||
crumbs.push({ text: crumb, path: root })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
crumbs.push({ text: pathArr[pathArr.length - 1], path: '' })
|
||||
}
|
||||
|
||||
// console.log(crumbs)
|
||||
commit('UPDATE_CURRENT_PATH', path)
|
||||
commit('UPDATE_CRUMBS', crumbs)
|
||||
commit('UPDATE_FOLDER_TREE', response.data)
|
||||
if (response.data.tree[1].length === 0) {
|
||||
response.data.tree[1].push(pathArr[pathArr.length - 1])
|
||||
}
|
||||
|
||||
if (path) {
|
||||
for (const crumb of pathArr) {
|
||||
if (crumb) {
|
||||
root += crumb + '/'
|
||||
crumbs.push({ text: crumb, path: root })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
crumbs.push({ text: pathArr[pathArr.length - 1], path: '' })
|
||||
}
|
||||
|
||||
// console.log(crumbs)
|
||||
commit('UPDATE_CURRENT_PATH', path)
|
||||
commit('UPDATE_CRUMBS', crumbs)
|
||||
commit('UPDATE_FOLDER_TREE', response.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user