refactor: ui

master
xiaojunnuo 2021-02-07 18:32:38 +08:00
parent 68c1eff81d
commit 2a07442a85
7 changed files with 142 additions and 68 deletions

View File

@ -27,9 +27,9 @@
}
},
"@ant-design-vue/use": {
"version": "0.0.1-alpha.8",
"resolved": "https://registry.npmjs.org/@ant-design-vue/use/-/use-0.0.1-alpha.8.tgz",
"integrity": "sha512-E8OLKvsVZjthRfGCA1CT2s7FoWl1HcgxTJFrHTcfMSaNXVT9jZEcJNM3K454gvfpgz3Iu35hwDknSKC4+kMYpA==",
"version": "0.0.1-alpha.9",
"resolved": "https://registry.npmjs.org/@ant-design-vue/use/-/use-0.0.1-alpha.9.tgz",
"integrity": "sha512-X+ESJt+e95sRwlSkpzETjc0opE5l34tCjMEm92JkoM4BVl6YxG9IgyX1dBy0W2jF74SSCOiCc7GdIlsPFQvE/g==",
"requires": {
"async-validator": "^3.4.0",
"lodash-es": "^4.17.15",
@ -51,13 +51,12 @@
"integrity": "sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ=="
},
"@ant-design/icons-vue": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-5.1.9.tgz",
"integrity": "sha512-4SJ8v9tXESKHNerrPPAkV9+EnuJhpY99wXgvtnbnTfE3QfpWaIw+7dP3wDxzD/Rjyz3wl3mj3mFlI889oPZoHg==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-6.0.1.tgz",
"integrity": "sha512-HigIgEVV6bbcrz2A92/qDzi/aKWB5EC6b6E1mxMB6aQA7ksiKY+gi4U94TpqyEIIhR23uaDrjufJ+xCZQ+vx6Q==",
"requires": {
"@ant-design/colors": "^5.0.0",
"@ant-design/icons-svg": "^4.0.0",
"@babel/runtime": "^7.10.4",
"@types/lodash": "^4.14.165",
"lodash": "^4.17.15"
}
@ -1121,9 +1120,9 @@
}
},
"@certd/api": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/@certd/api/-/api-0.1.12.tgz",
"integrity": "sha512-ZieyUWUZv7PxmsHdQ1C9EReqIz4dbun29S+LBlc/PhqrSqTglNMgKSr+mNfWYVOeHGdfYFvrVI2YI9aYKoG2AQ==",
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/@certd/api/-/api-0.1.13.tgz",
"integrity": "sha512-klb4B5D+lu1SAtopCyU4sfe12Q9U4k5x+GTaSLLk1Dr3cX0Mpq7/fySQIW5yPH2ZJGQQAbKm/vciBnUGYWFy/A==",
"requires": {
"axios": "^0.21.1",
"dayjs": "^1.9.7",
@ -1140,23 +1139,23 @@
}
},
"@certd/dns-providers": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/@certd/dns-providers/-/dns-providers-0.1.12.tgz",
"integrity": "sha512-xthDzmrc2Lc1q4SxZ3zJwreBecZWQIzCFXqz2/i7zvgBguWMdYiEw1O9Quqblfq4O4HpGZEgT1INfcrbcvJ/IQ==",
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/@certd/dns-providers/-/dns-providers-0.1.13.tgz",
"integrity": "sha512-a9eD61t6dnacTLJqEUWijhVf1OUmZmPyrm8asTxMAPt7zw60xNxFSJFGHGJYM0bMGPsqUP4WBsSZ5JU4SHy5bg==",
"requires": {
"@alicloud/pop-core": "^1.7.10",
"@certd/api": "^0.1.12",
"@certd/api": "^0.1.13",
"lodash-es": "^4.17.20",
"tencentcloud-sdk-nodejs": "^4.0.44"
}
},
"@certd/plugins": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/@certd/plugins/-/plugins-0.1.12.tgz",
"integrity": "sha512-5e75m2YNV8CsvOjV4pA91L2pjfFJxbR8umA0htPKZqZ+zN+cThzioshKQCZpKdVLJlPlHaKyc21NNh3qjWT0Eg==",
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/@certd/plugins/-/plugins-0.1.13.tgz",
"integrity": "sha512-RFUxCPb70px0FAB54H3Iv1GP1+e2l/PgNfSRTRcfO8jmiCEW9lwWBQ1Yw20zZzxCTrcOXuUGDUHQjmXaQ9Vu/A==",
"requires": {
"@alicloud/pop-core": "^1.7.10",
"@certd/api": "^0.1.12",
"@certd/api": "^0.1.13",
"dayjs": "^1.9.7",
"kubernetes-client": "^9.0.0",
"lodash-es": "^4.17.20",
@ -1165,9 +1164,9 @@
}
},
"@ctrl/tinycolor": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.3.1.tgz",
"integrity": "sha512-jUJrjU62MUgHDSu5JfONfgRM2V7GfN5KknsygfIbxwRZXGeayIzxk4O9GiYgEAr9DG5HJThTF5+a5x3wtrOKzQ=="
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.3.4.tgz",
"integrity": "sha512-8vmPV/nIULFDWsnJalQJDqFLC2uTPx6A/ASA2t27QGp+7oXnbWWXCe0uV8xasIH2rGbI/XoB2vmkdP/94WvMrw=="
},
"@eslint/eslintrc": {
"version": "0.3.0",
@ -1445,11 +1444,11 @@
"dev": true
},
"@simonwep/pickr": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.7.4.tgz",
"integrity": "sha512-fq7jgKJT21uWGC1mARBHvvd1JYlEf93o7SuVOB4Lr0x/2UPuNC9Oe9n/GzVeg4oVtqMDfh1wIEJpsdOJEZb+3g==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.0.tgz",
"integrity": "sha512-VaSD7TwktOsro5nQ/FjRx5JAJ09k5CNfGRHacgVRxeVPolUQwelz1SjL8HAOKZwTSmcnIObptpHABQS4zgN7sw==",
"requires": {
"core-js": "^3.6.5",
"core-js": "^3.8.0",
"nanopop": "^2.1.0"
}
},
@ -1695,9 +1694,9 @@
"dev": true
},
"@types/lodash": {
"version": "4.14.167",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.167.tgz",
"integrity": "sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw=="
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
},
"@types/mime": {
"version": "1.3.2",
@ -3954,14 +3953,14 @@
}
},
"ant-design-vue": {
"version": "2.0.0-rc.8",
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.8.tgz",
"integrity": "sha512-sPH/raQZhnzxUpFT5z8ONEvaf3SvUss6Llv9eBK05wqDTaj/+QSnJYflFGPZh4ScXGpJ4Pth9FMd+F0ogusGHg==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0.tgz",
"integrity": "sha512-Uv35Z9V+8iT1PBO0QOqWHaVE4Gju94UfikL8NGxtAqy/yZDnTn8K2gz5n7PfQbB5oBqkEyn2O0mtOpUBUEXZ+g==",
"requires": {
"@ant-design-vue/use": "^0.0.1-0",
"@ant-design/icons-vue": "^5.1.9",
"@ant-design/icons-vue": "^6.0.0",
"@babel/runtime": "^7.10.5",
"@simonwep/pickr": "~1.7.0",
"@simonwep/pickr": "~1.8.0",
"array-tree-filter": "^2.1.0",
"async-validator": "^3.3.0",
"dom-align": "^1.10.4",
@ -17378,9 +17377,9 @@
"dev": true
},
"vue-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.1.tgz",
"integrity": "sha512-UbvbzPu8DNzZRfMB1RDTFKBB6seMm80scMFdP+GkKaw00EugC3cjq9AtlS4y258vDkpAe9HfqbRO4cp63qVHXQ==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz",
"integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
"requires": {
"is-plain-object": "3.0.1"
},

View File

@ -11,12 +11,11 @@
"dependencies": {
"@certd/dns-providers": "^0.1.13",
"@certd/plugins": "^0.1.13",
"ant-design-vue": "^2.0.0-rc.8",
"ant-design-vue": "^2.0.0",
"core-js": "^3.8.1",
"lodash-es": "^4.17.20",
"vue": "^3.0.4",
"vue-i18n": "^9.0.0-rc.2",
"vue-json-editor": "^1.4.2",
"vue-router": "^4.0.1"
},
"devDependencies": {

View File

@ -1,6 +1,7 @@
import DContainer from './d-container'
import ComponentRender from './component-render'
import AccessProviderSelector from './access-provider-selector/access-provider-selector'
import vueJsonEditor from 'vue-json-editor'
const list = [
DContainer,
@ -12,5 +13,7 @@ export default {
for (const item of list) {
app.component(item.name, item)
}
app.component(vueJsonEditor.name, vueJsonEditor)
}
}

View File

@ -27,8 +27,8 @@
</a-tab-pane>
<a-tab-pane key="2" tab="从配置导入" force-render>
<a-textarea class="textarea" type="textarea" :auto-size="autoSize" allow-clear></a-textarea>
<a-button class="mt-10" type="primary" >导入</a-button>
<a-textarea v-model:value="optionsText" class="textarea" type="textarea" :auto-size="autoSize" allow-clear></a-textarea>
<a-button class="mt-10" type="primary" @click="createFromText"></a-button>
</a-tab-pane>
</a-tabs>
</div>
@ -38,7 +38,7 @@
</template>
<script>
// eslint-disable-next-line no-unused-vars
import { reactive, toRaw } from 'vue'
import { reactive, toRaw, ref } from 'vue'
import { useRouter } from 'vue-router'
export default {
setup () {
@ -51,14 +51,31 @@ export default {
})
const router = useRouter()
const createFromDomain = () => {
router.push({ name: 'detail', params: { options: JSON.stringify(formData) } })
goToDetail(JSON.stringify(formData))
}
const goToDetail = (options) => {
router.push({ name: 'detail', params: { options } })
}
const autoSize = reactive({ minRows: 8, maxRows: 10 })
const optionsText = ref()
const createFromText = () => {
try {
JSON.parse(optionsText.value)
} catch (e) {
throw new Error('json格式有误', e)
}
goToDetail(optionsText.value)
}
return {
createFromDomain,
formData,
autoSize
autoSize,
optionsText,
createFromText
}
}
}

View File

@ -34,7 +34,7 @@
</a-select>
</a-form-item>
<template v-if="currentDnsProviderDefine">
<a-form-item v-for="(item,key) in currentDnsProviderDefine.input" v-bind="item.component || {}" :key="key" :label="item.label" :name="key">
<a-form-item v-for="(item,key) in currentDnsProviderDefine.input" v-bind="item.component || {}" :key="key" :label="item.label" :name="'dnsProvider.'+key">
<component-render v-model:value="formData.dnsProvider[key]" v-bind="item.component || {}"></component-render>
<template #extra v-if="item.desc" >
{{item.desc}}
@ -127,7 +127,7 @@ export default {
const certFormData = {
domains: [],
email: undefined,
dnsProvider: {},
dnsProvider: { type: undefined, accessProvider: undefined },
ca: 'LetEncrypt',
csr: {
country: '',
@ -171,8 +171,9 @@ export default {
'csr.emailAddress': [{ required: false, message: '请输入邮箱' }]
})
// eslint-disable-next-line no-unused-vars
const { resetFields, validate, validateInfos } = useForm(formData, rules)
const { resetFields, validate, validateInfos, mergeValidateInfo } = useForm(formData, rules)
console.log('validateInfos', validateInfos)
const onSubmit = async e => {
e.preventDefault()
try {
@ -212,6 +213,7 @@ export default {
if (type == null) {
return
}
formData.dnsProvider.type = type
formData.dnsProvider.accessProvider = null
for (const item of dnsProviderDefineList.value) {

View File

@ -44,8 +44,8 @@
></a-input>
</a-form-item>
<a-form-item v-for="(item,key) in currentPlugin.input" v-bind="item.component || {}" :key="key" :label="item.label" :name="key">
<component-render v-model:value="currentTask.props[key]" v-bind="item.component || {}"></component-render>
<a-form-item v-for="(item,key) in currentPlugin.input" v-bind="item.component || {}" :key="key" :label="item.label" :name="'props.'+key">
<component-render v-model:value="currentTask['props.'+key]" v-bind="item.component || {}"></component-render>
<template #extra v-if="item.desc" >
{{item.desc}}
</template>
@ -101,16 +101,20 @@ function useTaskForm (context) {
}]
})
const taskAdd = (deploy) => {
const task = { taskName: '新任务', type: undefined, _isAdd: true, props: {} }
const task = { taskName: '新任务', type: undefined, _isAdd: true }
currentDeploy.value = deploy
currentDeploy.value.tasks.push(task)
currentTask.value = deploy.tasks[deploy.tasks.length - 1]
const index = deploy.tasks.length - 1
currentTask.value = deploy.tasks[index]
currentTaskIndex.value = index
taskDrawerShow()
console.log('currentTaskTypeChanged:', currentTask.value)
}
const taskTypeSelected = (item) => {
currentTask.value.type = item.name
currentTask.value.taskName = item.label
console.log('currentTaskTypeChanged:', currentTask.value)
}
const taskTypeSave = () => {
@ -122,10 +126,13 @@ function useTaskForm (context) {
// taskinput
changeCurrentPlugin(currentTask.value)
if (currentTask.value.props) {
currentTask.value.props = {}
}
for (const key in currentPlugin.value.input) {
const input = currentPlugin.value.input[key]
if (input.default != null) {
currentTask.value[key] = input.default
currentTask.value.props[key] = input.default
}
}
}
@ -142,10 +149,9 @@ function useTaskForm (context) {
}
const taskEdit = (deploy, task, index) => {
if (task) {
currentTask.value = task
currentTask.value = flatData(_.cloneDeep(task))
console.log('currentTaskEdit', currentTask.value)
currentTaskIndex.value = index
}
currentDeploy.value = deploy
changeCurrentPlugin(currentTask.value)
@ -163,20 +169,52 @@ function useTaskForm (context) {
// throw new Error('' + taskType)
}
currentPlugin.value = currentPlugins[0]
console.log('currentTaskTypeChanged:', currentTask.value)
}
const taskSave = async (e) => {
console.log('currentTask', currentTask)
const flatData = (obj, parentKey = '', member = obj) => {
_.forEach(member, (value, key) => {
const pathKey = parentKey + key
if (!_.isArray(value) && _.isObjectLike(value)) {
parentKey = pathKey + '.'
flatData(obj, parentKey, value)
if (parentKey === '') {
delete (obj[key])
}
} else {
obj[pathKey] = value
}
})
return obj
}
const unFlatData = (obj) => {
const newObj = {}
_.merge(newObj, obj)
for (const key in obj) {
const value = obj[key]
if (key.indexOf('.') >= 0) {
delete newObj[key]
_.set(newObj, key, value)
}
}
return newObj
}
const taskSave = async (e) => {
console.log('currentTaskSave', currentTask.value, currentTaskIndex.value)
e.preventDefault()
await taskFormRef.value.validate()
// context.emit('update', currentTask.value)
const newTask = unFlatData(currentTask.value)
currentDeploy.value.tasks[currentTaskIndex.value] = newTask
// context.emit('update', newTask)
taskDrawerClose()
}
const taskDelete = () => {
if (currentTaskIndex.value != null) {
currentDeploy.value.tasks.splice(currentTaskIndex.value)
currentDeploy.value.tasks.splice(currentTaskIndex.value, 1)
}
taskDrawerClose()
}

View File

@ -8,7 +8,7 @@
证书申请
</h3>
<a-divider></a-divider>
<div class="cert-display">
<div class="cert-display group-body">
<a-button class="cert-edit-btn" type="link" @click="certFormOpen">
编辑
</a-button>
@ -101,7 +101,7 @@
</h3>
<a-divider></a-divider>
<div class="deploy-list">
<div class="group-body deploy-list">
<a-card class="deploy-item" v-for="(deploy,index) of options.deploy" :key="index">
<template #title>
@ -156,18 +156,26 @@
</h3>
<a-divider></a-divider>
<div class="export">
<div class="export group-body" >
<d-container>
<template #header>
<div><a-button @click="exportsToZip"></a-button></div>
<br/>
<div> <a-button @click="exportsToJson"></a-button></div>
<div> <a-button @click="exportsToJson">options.json</a-button></div>
<br/>
</template>
<pre class="json">{{options}}</pre>
</d-container>
</div>
</div>
</div>
<cert-form ref="certFormRef" v-model:cert="options.cert" v-model:access-providers="options.accessProviders"></cert-form>
<task-form ref="taskFormRef" ></task-form>
<task-form ref="taskFormRef" @update="taskUpdated" ></task-form>
</div>
</template>
@ -181,6 +189,7 @@ import CertForm from '@/views/detail/components/cert-form'
import TaskForm from './components/task-form'
import exportsApi from '@/api/api.exports'
import _ from 'lodash-es'
import DContainer from '@/components/d-container'
function useDeploy (options) {
const deployAdd = () => {
@ -234,7 +243,7 @@ function useExports (options) {
}
export default {
components: { CertForm, TaskForm },
components: { DContainer, CertForm, TaskForm },
setup () {
const route = useRoute()
console.log('route', route)
@ -350,6 +359,10 @@ export default {
border-right: 1px #eee solid;
padding: 20px;
flex: 1;
display: flex;
flex-direction: column;
.group-head {
display: flex;
flex-direction: row;
@ -362,6 +375,9 @@ export default {
color: #737070;
}
}
.group-body{
flex:1
}
}
.flow-cert {
@ -408,7 +424,7 @@ export default {
}
.flow-export{
max-width: 300px;
max-width: 500px;
}
}