You've already forked filebrowser
mirror of
https://github.com/filebrowser/filebrowser.git
synced 2025-11-26 14:25:26 +08:00
chore: files pages logic responsability
This commit is contained in:
138
frontend/src/views/files/Editor.vue
Normal file
138
frontend/src/views/files/Editor.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div id="editor-container">
|
||||
<header-bar>
|
||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||
<title>{{ req.name }}</title>
|
||||
|
||||
<template #actions>
|
||||
<action id="save-button" icon="save" :label="$t('buttons.save')" @action="save()" />
|
||||
</template>
|
||||
</header-bar>
|
||||
|
||||
<div id="breadcrumbs">
|
||||
<span><i class="material-icons">home</i></span>
|
||||
|
||||
<span v-for="(link, index) in breadcrumbs" :key="index">
|
||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
||||
<span>{{ link.name }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<form id="editor"></form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { files as api } from '@/api'
|
||||
import { theme } from '@/utils/constants'
|
||||
import buttons from '@/utils/buttons'
|
||||
import url from '@/utils/url'
|
||||
|
||||
import ace from 'ace-builds/src-min-noconflict/ace.js'
|
||||
import modelist from 'ace-builds/src-min-noconflict/ext-modelist.js'
|
||||
import 'ace-builds/webpack-resolver'
|
||||
|
||||
import HeaderBar from '@/components/header/HeaderBar'
|
||||
import Action from '@/components/header/Action'
|
||||
|
||||
export default {
|
||||
name: 'editor',
|
||||
components: {
|
||||
HeaderBar,
|
||||
Action
|
||||
},
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['req', 'user']),
|
||||
breadcrumbs () {
|
||||
let parts = this.$route.path.split('/')
|
||||
|
||||
if (parts[0] === '') {
|
||||
parts.shift()
|
||||
}
|
||||
|
||||
if (parts[parts.length - 1] === '') {
|
||||
parts.pop()
|
||||
}
|
||||
|
||||
let breadcrumbs = []
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]) })
|
||||
}
|
||||
|
||||
breadcrumbs.shift()
|
||||
|
||||
if (breadcrumbs.length > 3) {
|
||||
while (breadcrumbs.length !== 4) {
|
||||
breadcrumbs.shift()
|
||||
}
|
||||
|
||||
breadcrumbs[0].name = '...'
|
||||
}
|
||||
|
||||
return breadcrumbs
|
||||
}
|
||||
},
|
||||
created () {
|
||||
window.addEventListener('keydown', this.keyEvent)
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('keydown', this.keyEvent)
|
||||
this.editor.destroy();
|
||||
},
|
||||
mounted: function () {
|
||||
const fileContent = this.req.content || '';
|
||||
|
||||
this.editor = ace.edit('editor', {
|
||||
value: fileContent,
|
||||
showPrintMargin: false,
|
||||
readOnly: this.req.type === 'textImmutable',
|
||||
theme: 'ace/theme/chrome',
|
||||
mode: modelist.getModeForPath(this.req.name).mode,
|
||||
wrap: true
|
||||
})
|
||||
|
||||
if (theme == 'dark') {
|
||||
this.editor.setTheme("ace/theme/twilight");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back () {
|
||||
let uri = url.removeLastDir(this.$route.path) + '/'
|
||||
this.$router.push({ path: uri })
|
||||
},
|
||||
keyEvent (event) {
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return
|
||||
}
|
||||
|
||||
if (String.fromCharCode(event.which).toLowerCase() !== 's') {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
this.save()
|
||||
},
|
||||
async save () {
|
||||
const button = 'save'
|
||||
buttons.loading('save')
|
||||
|
||||
try {
|
||||
await api.put(this.$route.path, this.editor.getValue())
|
||||
buttons.success(button)
|
||||
} catch (e) {
|
||||
buttons.done(button)
|
||||
this.$showError(e)
|
||||
}
|
||||
},
|
||||
close () {
|
||||
let uri = url.removeLastDir(this.$route.path) + '/'
|
||||
this.$router.push({ path: uri })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user