[#333] Added file browser UI panel.

Closes: #333
This commit is contained in:
Fabio Manganiello 2024-08-25 03:12:21 +02:00
parent 496dfdb50b
commit a152b0d734
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
9 changed files with 253 additions and 8 deletions

View file

@ -44,6 +44,9 @@
"execute": {
"class": "fa fa-play"
},
"file": {
"class": "fas fa-folder"
},
"extensions": {
"class": "fas fa-puzzle-piece"
},

View file

@ -173,7 +173,7 @@
<TextPrompt :visible="fileToRename != null"
:value="displayedFileToRename"
@input="renameFile"
@close="fileToRename = null" >
@close="fileToRename = null">
Enter a new name for this file:<br/><br/>
<b>{{ fileToRename }}</b>
</TextPrompt>
@ -310,7 +310,7 @@ export default {
computed: {
displayedFileToRename() {
return this.fileToRename?.slice(this.path.length + 1)
return this.fileToRename?.slice(this.path.length + 1) || ''
},
editedFileName() {
@ -358,7 +358,7 @@ export default {
const mime = this.mimeTypes[file.path] || ''
obj[file.path] = {}
if (mime.startsWith('audio/') || mime.startsWith('video/'))
if (this.isMedia && (mime.startsWith('audio/') || mime.startsWith('video/')))
obj[file.path] = {
play: {
iconClass: 'fa fa-play',
@ -730,7 +730,7 @@ export default {
},
path(val, oldVal) {
if (oldVal === val || !oldVal)
if (oldVal === val)
return
this.refresh()

View file

@ -117,7 +117,7 @@ export default {
computed: {
specialPlugins() {
return ['execute', 'entities']
return ['execute', 'entities', 'file']
},
panelNames() {
@ -130,6 +130,7 @@ export default {
}
let panelNames = Object.keys(this.panels).sort()
panelNames = prepend(panelNames, 'file')
panelNames = prepend(panelNames, 'execute')
panelNames = prepend(panelNames, 'entities')
return panelNames
@ -153,6 +154,8 @@ export default {
return 'Home'
if (name === 'execute')
return 'Execute'
if (name === 'file')
return 'Files'
return name
},

View file

@ -113,9 +113,6 @@ export default {
mounted() {
this.visible_ = this.visible
this.value_ = this.value || ""
this.$nextTick(() => {
this.$refs.input.focus()
})
},
}
</script>

View file

@ -0,0 +1,64 @@
<template>
<div class="header">
<div class="row">
<div class="col-s-8 col-m-7 left side">
<label class="search-box">
<input type="search"
placeholder="Filter"
v-model="filter"
@change="$emit('filter', $event.target.value)"
@keyup="$emit('filter', $event.target.value)">
</label>
</div>
</div>
</div>
</template>
<script>
import Utils from '@/Utils'
export default {
mixins: [Utils],
emits: [
'filter',
],
data() {
return {
filter: '',
}
},
}
</script>
<style lang="scss" scoped>
@import "./vars";
.header {
width: 100%;
height: $header-height;
position: relative;
background: $menu-panel-bg;
padding: .5em;
box-shadow: $border-shadow-bottom;
:deep(button) {
background: none;
padding: 0 .5em;
border: 0;
&:hover {
color: $default-hover-fg-2;
}
}
.search-box {
width: 100%;
margin-left: .5em;
input[type=search] {
width: 100%;
}
}
}
</style>

View file

@ -0,0 +1,123 @@
<template>
<div class="row plugin file-container">
<Loading v-if="loading" />
<div class="file-browser" v-else>
<Header :filter="filter" @filter="filter = $event" />
<Browser :initial-path="null" :filter="filter" :homepage="displayedBookmarks" />
</div>
</div>
</template>
<script>
import Browser from '@/components/File/Browser'
import Header from './Header'
import Loading from '@/components/Loading'
import Utils from '@/Utils'
export default {
mixins: [Utils],
components: {
Browser,
Header,
Loading,
},
data() {
return {
bookmarks: {},
configDir: null,
filter: '',
homeDir: null,
loading: false,
}
},
computed: {
displayedBookmarks() {
const items = {
Root: {
name: 'Root',
path: '/',
icon: {
class: 'fas fa-hard-drive',
},
},
}
if (this.homeDir) {
items.Home = {
name: 'Home',
path: this.homeDir,
icon: {
class: 'fas fa-home',
},
}
}
if (this.configDir) {
items.Configuration = {
name: 'Configuration',
path: this.configDir,
icon: {
class: 'fas fa-cogs',
},
}
}
return {
...items,
...this.bookmarks,
}
},
},
methods: {
async getConfig() {
this.loading = true
try {
let configFile = null;
[this.homeDir, this.bookmarks, configFile] = await Promise.all([
this.request('file.get_user_home'),
this.request('file.get_bookmarks'),
this.request('config.get_config_file'),
])
if (configFile) {
this.configDir = configFile.split('/').slice(0, -1).join('/')
}
} finally {
this.loading = false
}
},
},
mounted() {
this.getConfig()
},
}
</script>
<style lang="scss" scoped>
@import "./vars";
.file-container {
display: flex;
width: 100%;
height: 100%;
position: relative;
.file-browser {
width: 100%;
height: calc(100% - #{$header-height});
display: flex;
flex-direction: column;
}
:deep(.browser) {
width: 100%;
height: 100%;
background: $background-color;
}
}
</style>

View file

@ -0,0 +1 @@
$header-height: 3.3em;

View file

@ -0,0 +1,53 @@
<template>
<div class="row plugin execute-container">
<!-- Action executor container -->
<main>
<h1>Execute Action</h1>
<ActionEditor />
</main>
</div>
</template>
<script>
import ActionEditor from '@/components/Action/ActionEditor'
export default {
components: {
ActionEditor,
},
}
</script>
<style lang="scss" scoped>
@import "@/components/Action/common";
.execute-container {
width: 100%;
height: 100%;
color: $default-fg-2;
font-weight: 400;
border-radius: 0 0 1em 1em;
display: flex;
flex-direction: column;
align-items: center;
main {
width: 100%;
max-width: 1000px;
display: flex;
flex-direction: column;
box-shadow: $section-shadow;
@include from($desktop) {
margin: 1em;
border-radius: 1em 1em 0 0;
}
:deep(.action-editor-container) {
.action-editor {
height: 100%;
}
}
}
}
</style>

View file

@ -102,6 +102,7 @@ export default {
initializeDefaultViews() {
this.plugins.entities = {}
this.plugins.execute = {}
this.plugins.file = this.plugins.file || {}
},
},