blob: 6f56d2a2a50014b5763729a16cc3cf09b32ffee8 [file] [log] [blame]
<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<template>
<div class="schema">
<el-row :gutter="10">
<el-col
v-for="(item, index) in schemaData"
:key="index"
:xs="24"
:sm="12"
:md="6"
:lg="4"
:xl="3"
>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>{{ item.title }}</span>
<i v-if="schemaData.length > 1" class="el-icon-delete" @click="handleDelete(item.title)"/>
</div>
<div v-for="(itm, idex) in item.children" :key="idex" class="coll-item">
<div :class="'itm icon-' + idex" />
<div class="txt">{{ itm }}</div>
<i class="icon-edit" @click="handlerClick(item.title, itm)" />
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-button type="primary" icon="el-icon-plus" @click="add" />
</el-row>
<el-dialog :visible.sync="showMetadataDialogVisible" :title="type" width="60%" top="3vh">
<el-row :gutter="20">
<el-col :span="24">
<el-input
:rows="20"
:placeholder="$t('ruleConfig.form.inputPlaceholder')"
v-model="textarea"
type="textarea"
readonly
class="show-text"
/>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="showMetadataDialogVisible = false">{{ $t('btn.cancel') }}</el-button>
</span>
</el-dialog>
<el-dialog :visible.sync="centerDialogVisible" :title="type" width="60%" top="3vh">
<el-row :gutter="20">
<el-col :span="24">
<el-input
:rows="20"
:placeholder="$t('ruleConfig.form.inputPlaceholder')"
v-model="textarea"
type="textarea"
class="edit-text"
/>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="centerDialogVisible = false">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="onConfirm">{{ $t('btn.submit') }}</el-button>
</span>
</el-dialog>
<el-dialog
:visible.sync="addSchemaDialogVisible"
:title="$t('ruleConfig.schema.title')"
width="80%"
top="3vh">
<el-form ref="form" :model="form" :rules="rules" label-width="170px">
<el-form-item :label="$t('ruleConfig.schema.name')" prop="name">
<el-input
:placeholder="$t('ruleConfig.schemaRules.name')"
v-model="form.name"
autocomplete="off"
/>
</el-form-item>
<el-form-item :label="$t('ruleConfig.schema.ruleConfig')" prop="ruleConfig">
<el-input
:placeholder="$t('ruleConfig.schemaRules.ruleConfig')"
:rows="8"
v-model="form.ruleConfig"
autocomplete="off"
type="textarea"
class="edit-text"
/>
</el-form-item>
<el-form-item :label="$t('ruleConfig.schema.dataSourceConfig')" prop="dataSourceConfig">
<el-input
:placeholder="$t('ruleConfig.schemaRules.dataSourceConfig')"
:rows="8"
v-model="form.dataSourceConfig"
autocomplete="off"
type="textarea"
class="edit-text"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addSchemaDialogVisible = false">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="addSchema('form')">{{ $t('btn.submit') }}</el-button>
</div>
</el-dialog>
<el-dialog
:visible.sync="deleteDialogVisible"
:title="$t('common.notify.title')"
width="30%">
<span>{{ $t('common.notify.confirmDelOperator') }} {{ schemaName }} ?</span>
<span slot="footer" class="dialog-footer">
<el-button @click="deleteDialogVisible = false">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="deleteSchema()">{{ $t('btn.confirm') }}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import yaml from 'js-yaml'
import API from '../api'
export default {
name: 'Schema',
data() {
return {
treeData: [],
textarea: ``,
schemaData: [],
centerDialogVisible: false,
type: null,
sname: '',
scname: '',
addSchemaDialogVisible: false,
deleteDialogVisible: false,
schemaName: ``,
rueleConfigTextArea: ``,
dataSourceConfigTextArea: ``,
metadataConfigTextArea: ``,
showMetadataDialogVisible: false,
form: {
name: '',
ruleConfig: '',
dataSourceConfig: ''
},
rules: {
name: [
{
required: true,
message: this.$t('ruleConfig').schemaRules.name,
trigger: 'change'
}
],
ruleConfig: [
{
required: true,
message: this.$t('ruleConfig').schemaRules.ruleConfig,
trigger: 'change'
}
],
dataSourceConfig: [
{
required: true,
message: this.$t('ruleConfig').schemaRules.dataSourceConfig,
trigger: 'change'
}
],
metadataConfig: [
{
required: true,
message: this.$t('ruleConfig').schemaRules.metadataConfig,
trigger: 'change'
}
]
}
}
},
computed: {
textarea2() {
const shardingYamlType = new yaml.Type(
'!SHARDING',
{
kind: 'mapping',
construct(data) {
return data !== null ? data : {}
}
}
)
const encryptYamlType = new yaml.Type(
'!ENCRYPT',
{
kind: 'mapping',
construct(data) {
return data !== null ? data : {}
}
}
)
const masterSlaveYamlType = new yaml.Type(
'!READ_WRITE_SPLITTING',
{
kind: 'mapping',
construct(data) {
return data !== null ? data : {}
}
}
)
const shadowYamlType = new yaml.Type(
'!SHADOW',
{
kind: 'mapping',
construct(data) {
return data !== null ? data : {}
}
}
)
const DS_SCHEMA = yaml.Schema.create([shardingYamlType, encryptYamlType, masterSlaveYamlType, shadowYamlType])
return JSON.stringify(
yaml.load(this.textarea, { schema: DS_SCHEMA }),
null,
'\t'
)
}
},
created() {
this.getSchema()
},
methods: {
add() {
this.addSchemaDialogVisible = true
},
handlerClick(parent, child) {
if (child === 'rule') {
API.getSchemaRule(parent).then(res => {
this.renderYaml(parent, child, res)
})
} else if (child === 'datasource') {
API.getSchemaDataSource(parent).then(res => {
this.renderYaml(parent, child, res)
})
} else {
API.getSchemaMetadata(parent).then(res => {
this.renderMetadataYaml(parent, child, res)
})
}
},
renderMetadataYaml(parent, child, res) {
if (!res.success) return
const model = res.model
if (Object.prototype.toString.call(model) === '[object String]') {
this.textarea = model
} else {
this.textarea = JSON.stringify(model, null, '\t')
}
this.sname = parent
this.scname = child
this.type = `${parent}-${child}`
this.showMetadataDialogVisible = true
},
renderYaml(parent, child, res) {
if (!res.success) return
const model = res.model
if (Object.prototype.toString.call(model) === '[object String]') {
this.textarea = model
} else {
this.textarea = JSON.stringify(model, null, '\t')
}
this.sname = parent
this.scname = child
this.type = `${parent}-${child}`
this.centerDialogVisible = true
},
getSchema() {
API.getSchema().then(res => {
const data = res.model
const base = ['rule', 'datasource', 'metadata']
const newData = []
for (const v of data) {
newData.push({
title: v,
children: base
})
}
this.schemaData = newData
})
},
onConfirm() {
if (this.scname === 'rule') {
API.putSchemaRule(this.sname, { ruleConfig: this.textarea }).then(
res => {
this._onConfirm(res)
}
)
} else {
API.putSchemaDataSource(this.sname, {
dataSourceConfig: this.textarea
}).then(res => {
this._onConfirm(res)
})
}
},
_onConfirm(res, type) {
if (res.success) {
this.$notify({
title: this.$t('common').notify.title,
message: this.$t('common').notify.updateCompletedMessage,
type: 'success'
})
this.centerDialogVisible = false
if (type === 'ADD_SCHEMA') {
this.addSchemaDialogVisible = false
this.getSchema()
}
} else {
this.$notify({
title: this.$t('common').notify.title,
message: this.$t('common').notify.updateFaildMessage,
type: 'error'
})
}
},
addSchema(form) {
this.$refs[form].validate(valid => {
if (valid) {
API.addSchema({
name: this.form.name,
ruleConfiguration: this.form.ruleConfig,
dataSourceConfiguration: this.form.dataSourceConfig
}).then(res => {
this._onConfirm(res, 'ADD_SCHEMA')
})
} else {
console.log('error submit!!')
return false
}
})
},
handleDelete(schemaName) {
this.deleteDialogVisible = true
this.schemaName = schemaName
},
deleteSchema() {
API.deleteSchema(this.schemaName).then(res => {
this.$notify({
title: this.$t('common').notify.title,
message: this.$t('common').notify.delSucMessage,
type: 'success'
})
this.deleteDialogVisible = false
this.schemaName = ''
this.getSchema()
})
}
}
}
</script>
<style lang='scss'>
.schema {
margin-top: 20px;
.coll-item {
height: 16px;
line-height: 16px;
width: 100%;
float: left;
margin-bottom: 22px;
.txt {
color: rgb(51, 51, 51);
font-size: 14px;
padding-left: 10px;
float: left;
margin-right: 10px;
}
.itm {
float: left;
width: 16px;
height: 16px;
}
.icon-0 {
background: url('../../../assets/img/rules.png') no-repeat left center;
}
.icon-1 {
background: url('../../../assets/img/data-source.png') no-repeat left
center;
}
.icon-2 {
background: url('../../../assets/img/meta-data.png') no-repeat left
center;
}
.edit-btn {
float: right;
}
}
.el-row {
margin-bottom: 20px;
}
.el-collapse-item__header {
font-size: 16px;
}
.edit-text {
margin-top: 5px;
textarea {
background: #fffffb;
}
}
.show-text {
margin-top: 5px;
textarea {
background: rgb(246, 246, 246);
}
}
.icon-edit {
background: url('../../../assets/img/edit.png') no-repeat left center;
width: 16px;
height: 16px;
display: inline-block;
float: right;
cursor: pointer;
}
.el-dialog__body {
padding: 10px 20px;
}
.el-input {
width: 30%;
}
.el-input__inner {
height: 35px;
line-height: 35px;
}
.el-icon-delete {
color: #F56C6C;
float: right;
cursor: pointer;
}
}
</style>