[frontend-next] Refactored manage sites

This commit is contained in:
0xJacky 2022-08-01 16:54:44 +08:00
parent 0d4b126dd4
commit 2f91918f54
9 changed files with 165 additions and 121 deletions

View file

@ -7,6 +7,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
AButton: typeof import('ant-design-vue/es')['Button']
@ -32,11 +33,14 @@ declare module '@vue/runtime-core' {
APagination: typeof import('ant-design-vue/es')['Pagination']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
AreaChart: typeof import('./src/components/Chart/AreaChart.vue')['default']
AResult: typeof import('ant-design-vue/es')['Result']
ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space']
AStatistic: typeof import('ant-design-vue/es')['Statistic']
AStep: typeof import('ant-design-vue/es')['Step']
ASteps: typeof import('ant-design-vue/es')['Steps']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table']

View file

@ -52,7 +52,7 @@ export const routes = [
}, {
path: 'add',
name: () => $gettext('Add Site'),
// component: () => import('@/views/domain/DomainAdd.vue'),
component: () => import('@/views/domain/DomainAdd.vue'),
}, {
path: ':name',
name: () => $gettext('Edit Site'),

View file

@ -1,3 +1,86 @@
<script setup lang="ts">
import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
import NgxConfigEditor from '@/views/domain/ngx_conf/NgxConfigEditor.vue'
import {useGettext} from 'vue3-gettext'
import domain from '@/api/domain'
import ngx from '@/api/ngx'
import {computed, reactive, ref} from 'vue'
import {message} from 'ant-design-vue'
import {useRouter} from 'vue-router'
const {$gettext, interpolate} = useGettext()
const config = reactive({name: ''})
let ngx_config = reactive({
servers: [{
directives: [],
locations: []
}]
})
const error = reactive({})
const current_step = ref(0)
const enabled = ref(true)
const auto_cert = ref(false)
const update = ref(0)
init()
function init() {
domain.get_template().then(r => {
Object.assign(ngx_config, r.tokenized)
})
}
function save() {
ngx.build_config(ngx_config).then(r => {
domain.save(config.name, {content: r.content, enabled: true}).then(() => {
message.success($gettext('Saved successfully'))
domain.enable(config.name).then(() => {
message.success($gettext('Enabled successfully'))
current_step.value++
window.scroll({top: 0, left: 0, behavior: 'smooth'})
}).catch(r => {
message.error(r.message ?? $gettext('Enable failed'), 10)
})
}).catch(r => {
message.error(interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ''}), 10)
})
})
}
const router = useRouter()
function goto_modify() {
router.push('/domain/' + config.name)
}
function create_another() {
router.go(0)
}
const has_server_name = computed(() => {
const servers = ngx_config.servers
for (const server_key in servers) {
for (const k in servers[server_key].directives) {
const v = servers[server_key].directives[k]
if (v.directive === 'server_name' && v.params.trim() !== '') {
return true
}
}
}
return false
})
</script>
<template>
<a-card :title="$gettext('Add Site')">
<div class="domain-add-container">
@ -8,24 +91,25 @@
</a-steps>
<template v-if="current_step===0">
<a-form layout="vertical">
<a-form-item :label="$gettext('Configuration Name')">
<a-input v-model="config.name"/>
<a-input v-model:value="config.name"/>
</a-form-item>
</a-form>
<directive-editor :ngx_directives="ngx_config.servers[0].directives"/>
<br/>
<location-editor :locations="ngx_config.servers[0].locations"/>
<br/>
<a-alert
v-if="!has_server_name"
:message="$gettext('Warning')"
type="warning"
show-icon
>
<template slot="description">
<span v-translate>
server_name parameter is required
</span>
<template #description>
<span v-translate>server_name parameter is required</span>
</template>
</a-alert>
<br/>
@ -34,12 +118,14 @@
<template v-else-if="current_step===1">
<ngx-config-editor
ref="ngx_config"
ref="ngx-config-editor"
:ngx_config="ngx_config"
v-model="auto_cert"
v-model:auto_cert="auto_cert"
:enabled="enabled"
/>
<br/>
</template>
<a-space v-if="current_step<2">
@ -51,7 +137,6 @@
<translate>Next</translate>
</a-button>
</a-space>
<a-result
v-else-if="current_step===2"
status="success"
@ -71,82 +156,6 @@
</a-card>
</template>
<script>
import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor'
import LocationEditor from '@/views/domain/ngx_conf/LocationEditor'
import $gettext, {$interpolate} from '@/lib/translate/gettext'
import NgxConfigEditor from '@/views/domain/ngx_conf/NgxConfigEditor'
export default {
name: 'DomainAdd',
components: {NgxConfigEditor, LocationEditor, DirectiveEditor},
data() {
return {
config: {},
ngx_config: {
servers: [{}]
},
error: {},
current_step: 0,
enabled: true,
auto_cert: false
}
},
created() {
this.init()
},
methods: {
init() {
this.$api.domain.get_template().then(r => {
this.ngx_config = r.tokenized
})
},
save() {
this.$api.ngx.build_config(this.ngx_config).then(r => {
this.$api.domain.save(this.config.name, {content: r.content, enabled: true}).then(() => {
this.$message.success($gettext('Saved successfully'))
this.$api.domain.enable(this.config.name).then(() => {
this.$message.success($gettext('Enabled successfully'))
this.current_step++
}).catch(r => {
this.$message.error(r.message ?? $gettext('Enable failed'), 10)
})
}).catch(r => {
this.$message.error($interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ''}), 10)
})
})
},
goto_modify() {
this.$router.push('/domain/' + this.config.name)
},
create_another() {
this.current_step = 0
this.config = {}
this.ngx_config = {
servers: [{}]
}
},
},
computed: {
has_server_name() {
const servers = this.ngx_config.servers
for (const server_key in servers) {
for (const k in servers[server_key].directives) {
const v = servers[server_key].directives[k]
if (v.directive === 'server_name' && v.params.trim() !== '') {
return true
}
}
}
return false
}
}
}
</script>
<style lang="less" scoped>
.ant-steps {
padding: 10px 0 20px 0;

View file

@ -140,7 +140,7 @@ function disable() {
<div class="domain-edit-container" key="basic" v-else>
<a-form-item :label="$gettext('Enabled')">
<a-switch v-model="enabled" @change="checked=>{checked?enable():disable()}"/>
<a-switch v-model:checked="enabled" @change="checked=>{checked?enable():disable()}"/>
</a-form-item>
<ngx-config-editor
ref="ngx_config_editor"

View file

@ -68,6 +68,16 @@ function disable(name: any) {
message.error(interpolate($gettext('Failed to disable %{msg}'), {msg: r.message ?? ''}))
})
}
function destroy(site_name: any) {
domain.destroy(site_name).then(() => {
const t: Table | null = table.value
t!.get_list()
message.success(interpolate($gettext('Delete site: %{site_name}'), {site_name: site_name}))
}).catch((e: any) => {
message.error(e?.message ?? $gettext('Server error'))
})
}
</script>
<template>
@ -81,8 +91,19 @@ function disable(name: any) {
@clickEdit="r => this.$router.push({
path: '/domain/' + r
})"
:deletable="false"
>
<template #actions="{record}">
<template v-if="!record.enabled">
<a-divider type="vertical"/>
<a-popconfirm
:cancelText="$gettext('No')"
:okText="$gettext('OK')"
:title="$gettext('Are you sure you want to delete ?')"
@confirm="destroy(record['name'])">
<a v-translate>Delete</a>
</a-popconfirm>
</template>
<a-divider type="vertical"/>
<a v-if="record.enabled" @click="disable(record.name)">
{{ $gettext('Disabled') }}

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import CodeEditor from '@/components/CodeEditor'
import {useGettext} from 'vue3-gettext'
import {reactive} from 'vue'
import {reactive, ref} from 'vue'
const {$gettext} = useGettext()
@ -9,25 +9,30 @@ const {locations} = defineProps<{
locations?: any[]
}>()
let location = reactive({})
let location = reactive({
comments: '',
path: '',
content: '',
})
const adding = ref(false)
function add() {
adding.value = true
location = reactive({})
location = reactive({
comments: '',
path: '',
content: '',
})
}
function save() {
this.adding = false
if (this.locations) {
this.locations.push(this.location)
} else {
this.locations = [this.location]
}
adding.value = false
locations.push(this.location)
}
function remove(index) {
this.locations.splice(index, 1)
locations.splice(index, 1)
}
</script>
@ -36,27 +41,31 @@ function remove(index) {
<a-empty v-if="!locations"/>
<a-card v-for="(v,k) in locations" :key="k"
:title="$gettext('Location')" size="small">
<a-form-item :label="$gettext('Comments')" v-if="v.comments">
<p style="white-space: pre-wrap;">{{ v.comments }}</p>
<a-form layout="vertical">
<a-form-item :label="$gettext('Comments')">
<a-textarea v-model:value="v.comments"/>
</a-form-item>
<a-form-item :label="$gettext('Path')">
<a-input addon-before="location" v-model="v.path"/>
<a-input addon-before="location" v-model:value="v.path"/>
</a-form-item>
<a-form-item :label="$gettext('Content')">
<code-editor v-model:content="v.content" default-height="200px"/>
</a-form-item>
</a-form>
</a-card>
<a-modal :title="$gettext('Add Location')" v-model:visible="adding" @ok="save">
<a-form layout="vertical">
<a-form-item :label="$gettext('Comments')">
<a-textarea v-model="location.comments"></a-textarea>
<a-textarea v-model:value="location.comments"/>
</a-form-item>
<a-form-item :label="$gettext('Path')">
<a-input addon-before="location" v-model="location.path"/>
<a-input addon-before="location" v-model:value="location.path"/>
</a-form-item>
<a-form-item :label="$gettext('Content')">
<vue-itextarea v-model:content="location.content" default-height="200px"/>
<code-editor v-model:content="location.content" default-height="200px"/>
</a-form-item>
</a-form>
</a-modal>
<div>

View file

@ -19,6 +19,7 @@ const name = ref(route.params.name)
const init_ssl_status = ref(false)
function update_cert_info() {
// TODO
// if (name.value && this.$refs['cert-info' + this.current_server_index]) {
// this.$refs['cert-info' + this.current_server_index].get()
// }
@ -153,7 +154,7 @@ const current_support_ssl = computed(() => {
</template>
<directive-editor :ngx_directives="v.directives"/>
<br/>
<location-editor :locations="v.locations"/>
</div>

View file

@ -61,7 +61,7 @@ function onSave(idx: number) {
<div class="extra-content">
<a-form layout="vertical">
<a-form-item :label="$gettext('Comments')">
<a-textarea v-model="directive.comments"/>
<a-textarea v-model:value="directive.comments"/>
</a-form-item>
</a-form>
<directive-add :ngx_directives="ngx_directives" :idx="index" @save="onSave(index)"/>

View file

@ -1 +1 @@
{"version":"1.5.0","build_id":8,"total_build":78}
{"version":"1.5.0","build_id":9,"total_build":79}