feat: duplicate site #80

This commit is contained in:
0xJacky 2023-02-13 19:36:40 +08:00
parent 566a5c725e
commit a3dfc7af4a
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
3 changed files with 432 additions and 338 deletions

View file

@ -10,6 +10,7 @@ import domain from '@/api/domain'
import {Badge, message} from 'ant-design-vue'
import {h, ref} from 'vue'
import {input} from '@/components/StdDataEntry'
import SiteDuplicate from '@/views/domain/SiteDuplicate.vue'
const columns = [{
title: () => $gettext('Name'),
@ -25,7 +26,7 @@ const columns = [{
dataIndex: 'enabled',
customRender: (args: customRender) => {
const template: any = []
const {text, column} = args
const {text} = args
if (text === true || text > 0) {
template.push(<Badge status="success"/>)
template.push($gettext('Enabled'))
@ -83,6 +84,15 @@ function destroy(site_name: any) {
message.error(e?.message ?? $gettext('Server error'))
})
}
const show_duplicator = ref(false)
const target = ref('')
function handle_click_duplicate(name: string) {
show_duplicator.value = true
target.value = name
}
</script>
<template>
@ -99,25 +109,30 @@ function destroy(site_name: any) {
>
<template #actions="{record}">
<a-divider type="vertical"/>
<a v-if="record.enabled" @click="disable(record.name)">
<a-button type="link" size="small" v-if="record.enabled" @click="disable(record.name)">
{{ $gettext('Disabled') }}
</a>
<a v-else @click="enable(record.name)">
</a-button>
<a-button type="link" size="small" v-else @click="enable(record.name)">
{{ $gettext('Enabled') }}
</a>
<template v-if="!record.enabled">
</a-button>
<a-divider type="vertical"/>
<a-button type="link" size="small" @click="handle_click_duplicate(record.name)">
{{ $gettext('Duplicate') }}
</a-button>
<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-button type="link" size="small" :disabled="record.enabled">
{{ $gettext('Delete') }}
</a-button>
</a-popconfirm>
</template>
</template>
</std-table>
</a-card>
<site-duplicate v-model:visible="show_duplicator" :name="target" @duplicated="table.get_list()"/>
</template>
<style scoped>

View file

@ -0,0 +1,79 @@
<script setup lang="ts">
import {computed, nextTick, reactive, ref, watch} from 'vue'
import {useGettext} from 'vue3-gettext'
import {Form, message} from 'ant-design-vue'
import gettext from '@/gettext'
import domain from '@/api/domain'
const {$gettext} = useGettext()
const props = defineProps(['visible', 'name'])
const emit = defineEmits(['update:visible', 'duplicated'])
const show = computed({
get() {
return props.visible
},
set(v) {
emit('update:visible', v)
}
})
const modelRef = reactive({name: ''})
const rulesRef = reactive({
name: [
{
required: true,
message: () => $gettext('Please input name, ' +
'this will be used as the filename of the new configuration!')
}
]
})
const {validate, validateInfos, clearValidate} = Form.useForm(modelRef, rulesRef)
const loading = ref(false)
function onSubmit() {
validate().then(async () => {
loading.value = true
domain.duplicate(props.name, {name: modelRef.name}).then(() => {
message.success($gettext('Duplicated successfully'))
show.value = false
emit('duplicated')
}).catch((e: any) => {
message.error($gettext(e?.message ?? 'Server error'))
})
loading.value = false
})
}
watch(() => props.visible, (v) => {
if (v) {
modelRef.name = ''
nextTick(() => clearValidate())
}
})
watch(() => gettext.current, () => {
clearValidate()
})
</script>
<template>
<a-modal :title="$gettext('Duplicate')" v-model:visible="show" @ok="onSubmit"
:confirm-loading="loading">
<a-form layout="vertical">
<a-form-item :label="$gettext('Name')" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name"/>
</a-form-item>
</a-form>
</a-modal>
</template>
<style lang="less" scoped>
</style>

View file

@ -405,7 +405,7 @@ func DuplicateSite(c *gin.Context) {
name := c.Param("name")
var json struct {
Name string `json:"name"`
Name string `json:"name" binding:"required"`
}
if !BindAndValid(c, &json) {
@ -417,7 +417,7 @@ func DuplicateSite(c *gin.Context) {
if helper.FileExists(dst) {
c.JSON(http.StatusNotAcceptable, gin.H{
"message": "file exists",
"message": "File exists",
})
return
}