mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-26 17:49:15 +01:00
added file management
This commit is contained in:
61
frontend/src/components/File/FileDetail.vue
Normal file
61
frontend/src/components/File/FileDetail.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<codemirror
|
||||
class="file-content"
|
||||
:options="options"
|
||||
v-model="fileContent"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from 'vuex'
|
||||
import { codemirror } from 'vue-codemirror'
|
||||
|
||||
require('codemirror/mode/python/python.js')
|
||||
require('codemirror/mode/javascript/javascript.js')
|
||||
require('codemirror/mode/go/go.js')
|
||||
require('codemirror/mode/shell/shell.js')
|
||||
require('codemirror/addon/fold/foldcode.js')
|
||||
require('codemirror/addon/fold/foldgutter.js')
|
||||
require('codemirror/addon/fold/brace-fold.js')
|
||||
require('codemirror/addon/fold/xml-fold.js')
|
||||
require('codemirror/addon/fold/indent-fold.js')
|
||||
require('codemirror/addon/fold/markdown-fold.js')
|
||||
require('codemirror/addon/fold/comment-fold.js')
|
||||
|
||||
export default {
|
||||
name: 'FileDetail',
|
||||
components: { codemirror },
|
||||
data () {
|
||||
return {
|
||||
internalFileContent: '',
|
||||
options: {
|
||||
theme: 'darcula',
|
||||
mode: 'python',
|
||||
lineNumbers: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fileContent: {
|
||||
get () {
|
||||
return this.$store.state.file.fileContent
|
||||
},
|
||||
set (value) {
|
||||
return this.$store.commit('file/SET_FILE_CONTENT', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.internalFileContent = this.fileContent
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.file-content {
|
||||
border: 1px solid #eaecef;
|
||||
min-height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,43 +1,54 @@
|
||||
<template>
|
||||
<div class="file-list-container">
|
||||
<div class="top-part">
|
||||
<!--back-->
|
||||
<div class="action-container" v-if="showFile">
|
||||
<el-button type="primary" size="small" style="margin-right: 10px;" @click="showFile=false">
|
||||
<font-awesome-icon :icon="['fa', 'arrow-left']"/>
|
||||
{{$t('Back')}}
|
||||
</el-button>
|
||||
</div>
|
||||
<!--./back-->
|
||||
|
||||
<!--file path-->
|
||||
<div class="file-path-container">
|
||||
<div class="left">
|
||||
<i class="el-icon-back" @click="onBack"></i>
|
||||
<div class="file-path" v-show="!isEdit">{{currentPath}}</div>
|
||||
<el-input class="file-path"
|
||||
v-show="isEdit"
|
||||
v-model="currentPath"
|
||||
@change="onChange"
|
||||
@keypress.enter.native="onChangeSubmit">
|
||||
</el-input>
|
||||
</div>
|
||||
<i class="el-icon-edit" @click="onEdit"></i>
|
||||
<div class="file-path">. / {{currentPath}}</div>
|
||||
</div>
|
||||
<!--./file path-->
|
||||
|
||||
<!--action-->
|
||||
<div class="action-container">
|
||||
<el-button type="success" size="mini">{{$t('Choose Folder')}}</el-button>
|
||||
<el-button type="primary" size="small">
|
||||
<font-awesome-icon :icon="['fa', 'upload']"/>
|
||||
{{$t('Upload')}}
|
||||
</el-button>
|
||||
</div>
|
||||
<!--./action-->
|
||||
|
||||
</div>
|
||||
|
||||
<!--file list-->
|
||||
<template v-if="true">
|
||||
<!--<code-mirror v-model="code"/>-->
|
||||
<ul class="file-list">
|
||||
<li v-for="(item, index) in fileList" :key="index" class="item" @click="onItemClick(item)">
|
||||
<span class="item-icon">
|
||||
<i class="fa" :class="getIcon(item.type)"></i>
|
||||
</span>
|
||||
<span class="item-name">
|
||||
{{item.path}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-else>
|
||||
</template>
|
||||
<ul v-if="!showFile" class="file-list">
|
||||
<li v-if="currentPath" class="item" @click="onBack">
|
||||
<span class="item-icon"></span>
|
||||
<span class="item-name">..</span>
|
||||
</li>
|
||||
<li v-for="(item, index) in fileList" :key="index" class="item" @click="onItemClick(item)">
|
||||
<span class="item-icon">
|
||||
<font-awesome-icon v-if="item.is_dir" :icon="['fa', 'folder']" color="rgba(3,47,98,.5)"/>
|
||||
<font-awesome-icon v-else-if="item.path.match(/\.py$/)" :icon="['fab','python']"
|
||||
color="rgba(3,47,98,.5)"/>
|
||||
<font-awesome-icon v-else-if="item.path.match(/\.zip$/)" :icon="['fa','file-archive']"
|
||||
color="rgba(3,47,98,.5)"/>
|
||||
<font-awesome-icon v-else icon="file-alt" color="rgba(3,47,98,.5)"/>
|
||||
</span>
|
||||
<span class="item-name">
|
||||
{{item.name}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<file-detail v-else/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -45,18 +56,16 @@
|
||||
import {
|
||||
mapState
|
||||
} from 'vuex'
|
||||
import path from 'path'
|
||||
// import { codemirror } from 'vue-codemirror-lite'
|
||||
import FileDetail from './FileDetail'
|
||||
|
||||
export default {
|
||||
name: 'FileList',
|
||||
components: {
|
||||
// CodeMirror: codemirror
|
||||
},
|
||||
components: { FileDetail },
|
||||
data () {
|
||||
return {
|
||||
code: 'var hello = \'world\'',
|
||||
isEdit: false
|
||||
isEdit: false,
|
||||
showFile: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -88,12 +97,17 @@ export default {
|
||||
},
|
||||
onChangeSubmit () {
|
||||
this.isEdit = false
|
||||
this.$store.dispatch('file/getFileList', this.currentPath)
|
||||
this.$store.dispatch('file/getFileList', { path: this.currentPath })
|
||||
},
|
||||
onItemClick (item) {
|
||||
if (item.type === 2) {
|
||||
this.$store.commit('file/SET_CURRENT_PATH', path.join(this.currentPath, item.path))
|
||||
this.$store.dispatch('file/getFileList', this.currentPath)
|
||||
if (item.is_dir) {
|
||||
// 目录
|
||||
this.$store.dispatch('file/getFileList', { path: item.path })
|
||||
} else {
|
||||
// 文件
|
||||
this.showFile = true
|
||||
this.$store.commit('file/SET_CURRENT_PATH', item.path)
|
||||
this.$store.dispatch('file/getFileContent', { path: item.path })
|
||||
}
|
||||
},
|
||||
onBack () {
|
||||
@@ -102,7 +116,7 @@ export default {
|
||||
arr.splice(arr.length - 1, 1)
|
||||
const path = arr.join(sep)
|
||||
this.$store.commit('file/SET_CURRENT_PATH', path)
|
||||
this.$store.dispatch('file/getFileList', this.currentPath)
|
||||
this.$store.dispatch('file/getFileList', { path: this.currentPath })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,16 +128,18 @@ export default {
|
||||
|
||||
.top-part {
|
||||
display: flex;
|
||||
height: 33px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.file-path-container {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
margin: 0 10px;
|
||||
margin: 0 10px 0 0;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(48, 65, 86, 0.4);
|
||||
border: 1px solid #eaecef;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: rgba(3, 47, 98, 1);
|
||||
|
||||
.left {
|
||||
width: 100%;
|
||||
@@ -148,8 +164,9 @@ export default {
|
||||
|
||||
.action-container {
|
||||
text-align: right;
|
||||
padding: 1px 5px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
/*padding: 1px 5px;*/
|
||||
/*height: 24px;*/
|
||||
|
||||
.el-button {
|
||||
margin: 0;
|
||||
@@ -163,6 +180,9 @@ export default {
|
||||
list-style: none;
|
||||
height: 450px;
|
||||
overflow-y: auto;
|
||||
min-height: 100%;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #eaecef;
|
||||
|
||||
.item {
|
||||
padding: 10px 20px;
|
||||
@@ -197,4 +217,18 @@ export default {
|
||||
.CodeMirror-line {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.item {
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
display: inline-block;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 14px;
|
||||
color: rgba(3, 47, 98, 1);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user