2021-06-15 11:49:44 +02:00
|
|
|
<template>
|
|
|
|
<div>
|
2021-06-23 10:19:49 +02:00
|
|
|
<nav aria-label="breadcrumb" class="d-flex justify-content-between">
|
|
|
|
<ol class="breadcrumb mb-0">
|
2021-06-23 10:34:41 +02:00
|
|
|
<li class="breadcrumb-item" v-for="item in breadcrumb">
|
2021-06-23 10:19:49 +02:00
|
|
|
<a class="btn btn-sm" href="#" v-on:click="setDirectory(item.path)" v-html="item.label"></a>
|
2021-06-15 11:49:44 +02:00
|
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
|
2021-06-23 10:19:49 +02:00
|
|
|
<div class="d-flex">
|
|
|
|
<div class="breadcrumb mb-0 file-manager-actions">
|
2021-06-23 10:48:39 +02:00
|
|
|
<span class="btn btn-sm btn-primary ml-1" v-bind:data-modal="generateUploadLink(directory)">
|
2021-06-23 10:19:49 +02:00
|
|
|
<span class="fa fa-upload" v-bind:data-modal="generateUploadLink(directory)"></span>
|
|
|
|
</span>
|
2021-06-23 10:48:39 +02:00
|
|
|
<span class="btn btn-sm btn-primary ml-1" v-bind:data-modal="generateNewDirectoryLink(directory)">
|
2021-06-23 10:19:49 +02:00
|
|
|
<span class="fa fa-folder-plus" v-bind:data-modal="generateNewDirectoryLink(directory)"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
2021-06-15 11:49:44 +02:00
|
|
|
|
2021-06-23 10:19:49 +02:00
|
|
|
<div class="breadcrumb mb-0 file-manager-views">
|
2021-06-23 10:48:39 +02:00
|
|
|
<span class="btn btn-sm btn-dark ml-1" v-on:click="setView('grid')">
|
2021-06-23 10:19:49 +02:00
|
|
|
<span class="fa fa-grip-horizontal" v-on:click="setView('grid')"></span>
|
|
|
|
</span>
|
2021-06-23 10:48:39 +02:00
|
|
|
<span class="btn btn-sm btn-dark ml-1" v-on:click="setView('list')">
|
2021-06-23 10:19:49 +02:00
|
|
|
<span class="fa fa-list" v-on:click="setView('list')"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-06-15 11:49:44 +02:00
|
|
|
</nav>
|
|
|
|
|
|
|
|
<div class="card-deck" v-if="view == 'grid'">
|
|
|
|
<div v-if="parent" class="card mt-3 ml-3 mb-3 border-0">
|
|
|
|
<div class="card-body p-2">
|
|
|
|
<div class="card-text" v-on:dblclick="setDirectory(parent)">
|
|
|
|
<div class="text-center display-4 text-warning">
|
|
|
|
<span class="fa fa-folder"></span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="text-center">
|
|
|
|
..
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2021-06-23 10:34:41 +02:00
|
|
|
<div v-for="item in directories" class="card mt-3 ml-3 mb-3 border-0">
|
2021-06-15 11:49:44 +02:00
|
|
|
<div class="card-body p-2">
|
2021-06-16 18:41:05 +02:00
|
|
|
<div class="card-text" v-on:dblclick="setDirectory(item.path)" v-bind:data-modal="generateInfoLink(item, true, context)">
|
2021-06-15 11:49:44 +02:00
|
|
|
<div class="text-center">
|
|
|
|
<div class="display-4 text-warning">
|
|
|
|
<span class="fa fa-folder"></span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="item.locked" class="file-manager-grid-lock">
|
|
|
|
<span class="btn btn-sm">
|
|
|
|
<span class="fa fa-lock"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="text-center">
|
|
|
|
<span v-html="item.basename"></span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-06-23 10:34:41 +02:00
|
|
|
<div v-for="item in files" class="card mt-3 ml-3 mb-3 border-0" v-on:click="modalUrl = generateInfoLink(item, null, context)" v-bind:data-modal="generateInfoLink(item, null, context)">
|
2021-06-15 11:49:44 +02:00
|
|
|
<div class="card-body p-2">
|
|
|
|
<div class="card-text">
|
|
|
|
<div class="text-center">
|
|
|
|
<div class="display-4 text-muted">
|
2021-06-22 11:06:05 +02:00
|
|
|
<FileIcon v-bind:mime="item.mime" v-bind:path="item.webPath" v-bind:thumb="true" />
|
2021-06-15 11:49:44 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="item.locked" class="file-manager-grid-lock">
|
|
|
|
<span class="btn btn-sm">
|
|
|
|
<span class="fa fa-lock"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="text-center">
|
|
|
|
<span v-html="item.basename"></span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="table-responsive" v-if="view == 'list'">
|
|
|
|
<table class="table">
|
|
|
|
<tr v-if="parent" v-on:dblclick="setDirectory(parent)">
|
|
|
|
<td width="10">
|
|
|
|
<span class="fa fa-folder text-warning"></span>
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
..
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
|
2021-06-23 10:34:41 +02:00
|
|
|
<tr v-for="item in directories" v-on:dblclick="setDirectory(item.path)" v-bind:data-modal="generateInfoLink(item, true, context)">
|
2021-06-15 11:49:44 +02:00
|
|
|
<td width="10">
|
|
|
|
<span class="fa fa-folder text-warning"></span>
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<div v-if="item.locked" class="float-right">
|
|
|
|
<span class="btn btn-sm btn-light">
|
|
|
|
<span class="fa fa-lock"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<span v-html="item.basename"></span>
|
|
|
|
</td>
|
|
|
|
</tr>
|
2021-06-23 10:34:41 +02:00
|
|
|
<tr v-for="item in files">
|
2021-06-15 11:49:44 +02:00
|
|
|
<td width="10">
|
2021-06-22 11:06:05 +02:00
|
|
|
<FileIcon v-bind:mime="item.mime" v-bind:path="item.webPath" v-bind:thumb="false" />
|
2021-06-15 11:49:44 +02:00
|
|
|
</td>
|
2021-06-21 21:34:54 +02:00
|
|
|
<td v-on:click="modalUrl = generateInfoLink(item, null, context)" v-bind:data-modal="generateInfoLink(item, null, context)">
|
2021-06-15 11:49:44 +02:00
|
|
|
<div v-if="item.locked" class="float-right">
|
|
|
|
<span class="btn btn-sm btn-light">
|
|
|
|
<span class="fa fa-lock"></span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<span v-html="item.basename"></span>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.card {
|
|
|
|
margin-right: 5px;
|
|
|
|
flex: 0 0 170px;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
* {
|
|
|
|
user-select: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
.file-manager-views {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
.file-manager-grid-lock {
|
|
|
|
margin-top: -26px;
|
|
|
|
padding-left: 40px;
|
|
|
|
}
|
|
|
|
|
2021-06-23 10:19:49 +02:00
|
|
|
.breadcrumb, nav {
|
2021-06-15 11:49:44 +02:00
|
|
|
border-radius: 0;
|
2021-06-23 10:19:49 +02:00
|
|
|
background: #e9ecef;
|
2021-06-15 11:49:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.file-manager-actions .fa {
|
|
|
|
padding: 3px;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2021-06-23 10:19:49 +02:00
|
|
|
|
|
|
|
.breadcrumb-item + .breadcrumb-item::before {
|
|
|
|
margin-top: 4px;
|
|
|
|
}
|
2021-06-15 11:49:44 +02:00
|
|
|
</style>
|
|
|
|
|
|
|
|
<script>
|
2021-06-15 14:26:20 +02:00
|
|
|
import Routing from '../../../../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js'
|
|
|
|
import FileIcon from './FileIcon'
|
|
|
|
|
2021-06-15 11:49:44 +02:00
|
|
|
const axios = require('axios').default
|
2021-06-21 21:34:54 +02:00
|
|
|
const $ = require('jquery')
|
2021-06-15 11:49:44 +02:00
|
|
|
const routes = require('../../../../../public/js/fos_js_routes.json')
|
|
|
|
|
2021-06-15 14:30:14 +02:00
|
|
|
Routing.setRoutingData(routes)
|
|
|
|
|
2021-06-15 11:49:44 +02:00
|
|
|
export default {
|
2021-06-15 14:26:20 +02:00
|
|
|
name: 'Files',
|
|
|
|
components: {
|
|
|
|
FileIcon
|
|
|
|
},
|
2021-06-16 18:41:05 +02:00
|
|
|
props: {
|
|
|
|
context: {
|
|
|
|
type: String,
|
|
|
|
required: false
|
|
|
|
}
|
|
|
|
},
|
2021-06-15 14:26:20 +02:00
|
|
|
data () {
|
|
|
|
return {
|
|
|
|
view: 'list',
|
|
|
|
directory: null,
|
|
|
|
directories: [],
|
|
|
|
breadcrumb: [],
|
|
|
|
files: [],
|
2021-06-21 21:34:54 +02:00
|
|
|
parent: null,
|
|
|
|
modalUrl: null,
|
2021-06-22 11:06:05 +02:00
|
|
|
ajax: 0
|
2021-06-15 14:26:20 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
setDirectory (directory) {
|
2021-06-21 21:34:54 +02:00
|
|
|
if (!directory) {
|
|
|
|
directory = '/'
|
|
|
|
}
|
2021-06-15 14:26:20 +02:00
|
|
|
this.directory = directory
|
2021-06-15 11:49:44 +02:00
|
|
|
},
|
2021-06-15 14:26:20 +02:00
|
|
|
setView (view) {
|
|
|
|
this.view = view
|
|
|
|
|
|
|
|
localStorage.setItem('file-manager.view', view)
|
2021-06-15 11:49:44 +02:00
|
|
|
},
|
2021-06-16 18:41:05 +02:00
|
|
|
generateInfoLink (item, directory, context) {
|
2021-06-15 14:26:20 +02:00
|
|
|
if (directory) {
|
|
|
|
return Routing.generate('admin_file_manager_info', {
|
2021-06-16 18:41:05 +02:00
|
|
|
file: item.path,
|
2021-06-21 21:34:54 +02:00
|
|
|
context: context,
|
|
|
|
ajax: this.ajax
|
2021-06-15 14:26:20 +02:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
return Routing.generate('admin_file_manager_info', {
|
2021-06-16 18:41:05 +02:00
|
|
|
file: item.path + '/' + item.basename,
|
2021-06-21 21:34:54 +02:00
|
|
|
context: context,
|
|
|
|
ajax: this.ajax
|
2021-06-15 14:26:20 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
generateUploadLink (directory) {
|
|
|
|
return Routing.generate('admin_file_manager_upload', {
|
2021-06-21 21:34:54 +02:00
|
|
|
file: directory,
|
|
|
|
ajax: this.ajax
|
2021-06-15 14:26:20 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
generateNewDirectoryLink (directory) {
|
|
|
|
return Routing.generate('admin_file_manager_directory_new', {
|
2021-06-21 21:34:54 +02:00
|
|
|
file: directory,
|
|
|
|
ajax: this.ajax
|
2021-06-15 14:26:20 +02:00
|
|
|
})
|
2021-06-15 11:49:44 +02:00
|
|
|
},
|
2021-06-15 14:26:20 +02:00
|
|
|
buildBreadcrum (elements) {
|
|
|
|
let path = '/'
|
|
|
|
this.breadcrumb = []
|
2021-06-15 11:49:44 +02:00
|
|
|
|
2021-06-15 14:26:20 +02:00
|
|
|
for (const i in elements) {
|
|
|
|
const element = elements[i]
|
2021-06-15 11:49:44 +02:00
|
|
|
|
2021-06-15 14:26:20 +02:00
|
|
|
if (element !== '/') {
|
|
|
|
path = path + '/' + element
|
2021-06-15 11:49:44 +02:00
|
|
|
|
2021-06-15 14:26:20 +02:00
|
|
|
this.breadcrumb.push({
|
|
|
|
path: path,
|
|
|
|
label: element
|
|
|
|
})
|
2021-06-15 11:49:44 +02:00
|
|
|
} else {
|
2021-06-15 14:26:20 +02:00
|
|
|
this.breadcrumb.push({
|
|
|
|
path: '/',
|
|
|
|
label: 'Files'
|
|
|
|
})
|
2021-06-15 11:49:44 +02:00
|
|
|
}
|
2021-06-15 14:26:20 +02:00
|
|
|
}
|
2021-06-21 21:34:54 +02:00
|
|
|
},
|
|
|
|
refresh () {
|
|
|
|
const that = this
|
|
|
|
|
|
|
|
axios.get(Routing.generate('admin_file_manager_api_directory', {
|
|
|
|
directory: that.directory,
|
|
|
|
context: that.context,
|
2021-06-22 11:06:05 +02:00
|
|
|
ajax: this.ajax
|
2021-06-21 21:34:54 +02:00
|
|
|
}))
|
|
|
|
.then((response) => {
|
|
|
|
that.buildBreadcrum(response.data.breadcrumb)
|
|
|
|
that.parent = response.data.parent
|
|
|
|
that.directories = response.data.directories
|
|
|
|
that.files = response.data.files
|
|
|
|
|
|
|
|
const query = new URLSearchParams(window.location.search)
|
|
|
|
query.set('path', that.directory)
|
|
|
|
|
|
|
|
history.pushState(
|
|
|
|
null,
|
|
|
|
'',
|
|
|
|
window.location.pathname + '?' + query.toString()
|
|
|
|
)
|
|
|
|
})
|
|
|
|
.catch((e) => {
|
|
|
|
alert('An error occured')
|
|
|
|
})
|
2021-06-15 14:26:20 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted () {
|
|
|
|
const view = localStorage.getItem('file-manager.view')
|
|
|
|
|
|
|
|
if (['grid', 'list'].indexOf(view) !== -1) {
|
|
|
|
this.view = view
|
|
|
|
}
|
|
|
|
|
|
|
|
const query = new URLSearchParams(window.location.search)
|
|
|
|
|
|
|
|
if (query.has('path')) {
|
|
|
|
this.setDirectory(query.get('path'))
|
|
|
|
} else {
|
|
|
|
this.setDirectory('/')
|
|
|
|
}
|
2021-06-21 21:34:54 +02:00
|
|
|
|
|
|
|
this.ajax = (['crud'].indexOf(this.context) === -1 ? 1 : 0)
|
|
|
|
|
|
|
|
const body = $('body')
|
|
|
|
const events = ['file_manager.file.new', 'file_manager.directory.new', 'file_manager.directory.rename']
|
|
|
|
const that = this
|
|
|
|
|
|
|
|
$(events).each((k, event) => {
|
|
|
|
body.on(event + '.success', () => {
|
|
|
|
$('#modal-container').modal('hide')
|
|
|
|
that.refresh()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
body.on('file_manager.info.update.success', () => {
|
|
|
|
$('*[data-modal="' + that.modalUrl + '"]').click()
|
|
|
|
})
|
2021-06-15 14:26:20 +02:00
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
directory (directory) {
|
2021-06-21 21:34:54 +02:00
|
|
|
this.refresh()
|
2021-06-15 11:49:44 +02:00
|
|
|
}
|
2021-06-15 14:26:20 +02:00
|
|
|
}
|
2021-06-15 11:49:44 +02:00
|
|
|
}
|
|
|
|
</script>
|