feat: manage config support dir

This commit is contained in:
0xJacky 2023-01-02 18:38:40 +08:00
parent 6bcb575442
commit 65b192c8be
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
5 changed files with 231 additions and 162 deletions

View file

@ -74,7 +74,17 @@ export const routes = [
}
},
{
path: 'config/:name',
path: 'config/:dir*',
name: () => $gettext('Manage Configs'),
component: () => import('@/views/config/Config.vue'),
meta: {
icon: FileOutlined,
hideChildren: true,
hiddenInSidebar: true
}
},
{
path: 'config/:name+/edit',
name: () => $gettext('Edit Configuration'),
component: () => import('@/views/config/ConfigEdit.vue'),
meta: {

View file

@ -2,43 +2,66 @@
import StdTable from '@/components/StdDataDisplay/StdTable.vue'
import gettext from '@/gettext'
import config from '@/api/config'
import {datetime} from '@/components/StdDataDisplay/StdTableTransformer'
import {customRender, datetime} from '@/components/StdDataDisplay/StdTableTransformer'
import {computed, h, nextTick, ref, watch} from 'vue'
const {$gettext} = gettext
const api = config
const columns = [{
title: () => $gettext('Name'),
dataIndex: 'name',
sorter: true,
pithy: true
}, {
title: () => $gettext('Updated at'),
dataIndex: 'modify',
customRender: datetime,
datetime: true,
sorter: true,
pithy: true
}, {
title: () => $gettext('Action'),
dataIndex: 'action'
}]
import configColumns from '@/views/config/config'
import {useRoute} from 'vue-router'
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import router from '@/routes'
const table = ref(null)
const route = useRoute()
const basePath = computed(() => {
let dir = route?.params?.dir ? (route?.params?.dir as string[])?.join('/') : ''
if (dir) dir += '/'
return dir
})
const get_params = computed(() => {
return {
dir: basePath.value
}
})
const update = ref(1)
watch(get_params, () => {
update.value++
})
</script>
<template>
<a-card :title="$gettext('Configurations')">
<std-table
:key="update"
ref="table"
:api="api"
:columns="columns"
:columns="configColumns"
:deletable="false"
:disable_search="true"
row-key="name"
@clickEdit="r => {
:get_params="get_params"
@clickEdit="(r, row) => {
if (!row.is_dir) {
$router.push({
path: '/config/' + r
path: '/config/' + basePath + r + '/edit'
})
} else {
$router.push({
path: '/config/' + basePath + r
})
}
}"
/>
<footer-tool-bar v-if="basePath">
<a-button @click="router.go(-1)">{{ $gettext('Back') }}</a-button>
</footer-tool-bar>
</a-card>
</template>

View file

@ -2,7 +2,7 @@
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import gettext from '@/gettext'
import {useRoute} from 'vue-router'
import {ref} from 'vue'
import {computed, ref} from 'vue'
import config from '@/api/config'
import {message} from 'ant-design-vue'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
@ -10,7 +10,13 @@ import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
const {$gettext, interpolate} = gettext
const route = useRoute()
const name = ref(route.params.name)
const name = computed(() => {
const n = route.params.name
if (typeof n === 'string') {
return n
}
return n?.join('/')
})
const configText = ref('')
@ -46,7 +52,7 @@ function save() {
<footer-tool-bar>
<a-space>
<a-button @click="$router.go(-1)">
<translate>Cancel</translate>
<translate>Back</translate>
</a-button>
<a-button type="primary" @click="save">
<translate>Save</translate>

View file

@ -0,0 +1,41 @@
import {customRender, datetime} from '@/components/StdDataDisplay/StdTableTransformer'
import gettext from '@/gettext'
const {$gettext} = gettext
import {Badge} from 'ant-design-vue'
import {h} from 'vue'
const configColumns = [{
title: () => $gettext('Name'),
dataIndex: 'name',
sorter: true,
pithy: true
}, {
title: () => $gettext('Type'),
dataIndex: 'is_dir',
customRender: (args: customRender) => {
const template: any = []
const {text, column} = args
if (text === true || text > 0) {
template.push($gettext('Dir'))
} else {
template.push($gettext('File'))
}
return h('div', template)
},
sorter: true,
pithy: true
}, {
title: () => $gettext('Updated at'),
dataIndex: 'modify',
customRender: datetime,
datetime: true,
sorter: true,
pithy: true
}, {
title: () => $gettext('Action'),
dataIndex: 'action'
}]
export default configColumns

View file

@ -14,13 +14,15 @@ import (
func GetConfigs(c *gin.Context) {
orderBy := c.Query("order_by")
sort := c.DefaultQuery("sort", "desc")
dir := c.DefaultQuery("dir", "/")
mySort := map[string]string{
"name": "string",
"modify": "time",
"is_dir": "bool",
}
configFiles, err := os.ReadDir(nginx.GetNginxConfPath("/"))
configFiles, err := os.ReadDir(nginx.GetNginxConfPath(dir))
if err != nil {
ErrHandler(c, err)
@ -45,25 +47,13 @@ func GetConfigs(c *gin.Context) {
log.Println("GetConfigs Read Symlink Error", targetPath, err)
continue
}
var targetInfo os.FileInfo
targetInfo, err = os.Stat(targetPath)
if err != nil {
log.Println("GetConfigs Stat Error", targetPath, err)
continue
}
// but target file is not a dir
if targetInfo.IsDir() {
continue
}
default:
continue
}
configs = append(configs, gin.H{
"name": file.Name(),
"size": fileInfo.Size(),
"modify": fileInfo.ModTime(),
"is_dir": file.IsDir(),
})
}
@ -109,7 +99,6 @@ func AddConfig(c *gin.Context) {
path := filepath.Join(nginx.GetNginxConfPath("/"), name)
log.Println(path)
if _, err = os.Stat(path); err == nil {
c.JSON(http.StatusNotAcceptable, gin.H{
"message": "config exist",