You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@linkis.apache.org by pe...@apache.org on 2022/02/15 02:55:29 UTC
[incubator-linkis] 01/06: add linkis datasource web
This is an automated email from the ASF dual-hosted git repository.
peacewong pushed a commit to branch dev-1.1.0-datasource
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git
commit e42c146e3460b12d0e94e1cd0ca549e4b6ca23b2
Author: luxiaolong <li...@126.com>
AuthorDate: Mon Dec 6 19:40:04 2021 +0800
add linkis datasource web
---
web/src/apps/linkis/i18n/common/en.json | 43 +-
web/src/apps/linkis/i18n/common/zh.json | 46 +-
.../apps/linkis/module/datasource/dataSourceApi.js | 167 ++++++
.../module/datasource/datasourceForm/index.scss | 78 +++
.../module/datasource/datasourceForm/index.vue | 272 +++++++++
.../module/datasource/datasourceType/index.scss | 111 ++++
.../module/datasource/datasourceType/index.vue | 76 +++
web/src/apps/linkis/module/datasource/index.js | 21 +
web/src/apps/linkis/module/datasource/index.scss | 65 +++
web/src/apps/linkis/module/datasource/index.vue | 613 +++++++++++++++++++++
web/src/apps/linkis/router.js | 16 +-
web/src/apps/linkis/view/linkis/index.vue | 1 +
web/src/main.js | 8 +-
13 files changed, 1505 insertions(+), 12 deletions(-)
diff --git a/web/src/apps/linkis/i18n/common/en.json b/web/src/apps/linkis/i18n/common/en.json
index 89b5509..22a0ade 100644
--- a/web/src/apps/linkis/i18n/common/en.json
+++ b/web/src/apps/linkis/i18n/common/en.json
@@ -65,7 +65,7 @@
"resourceManagement": {
"resourceUsage": "Resource usage",
"applicationList": "Application List"
- },
+ },
"time": {
"second": "Second",
"minute": "Minute",
@@ -120,7 +120,8 @@
"dateReport": "Global Variables",
"globalValiable": "Frequently Asked",
"microserviceManage": "Microservice management",
- "ECMManage": "ECM Management"
+ "ECMManage": "ECM Management",
+ "dataSourceManage": "DataSource Manage"
}
}
},
@@ -235,7 +236,43 @@
},
"success": {
"update": "Successfully updated global variables!"
+ },
+ "datasource": {
+ "pleaseInput": "Please input",
+ "datasourceSrc": "Datasource",
+ "connectTest": "Test Connection",
+ "sourceName": "Data source name",
+ "sourceDec": "Data source description",
+ "sourceType": "Data source type:",
+ "creator": "Creator:",
+ "create": "New data source",
+ "exports": "Demonstration export data source",
+ "imports": "Demonstration of importing data sources",
+ "Expired": "Expired",
+ "versionList": "Version List",
+ "dataSourceName": "Data Source Name",
+ "dataSourceType": "Data Source Type",
+ "dataSourceEnv": "Available Space",
+ "status": "Status",
+ "permissions": "Permissions",
+ "label": "label",
+ "Version": "Version",
+ "desc": "Description",
+ "action": "Action",
+ "createUser": "Create User",
+ "createTime": "Create Time",
+ "versionDec": "Version Description",
+ "watch": "View",
+ "rollback": "Rollback",
+ "publish": "Publish",
+ "initVersion": "Initial Version",
+ "updateVersion": "Version update",
+ "published": "Published",
+ "unpublish": "Unpublished",
+ "cannotPublish": "Cannot Publish",
+ "used": "Available",
+ "commentValue": "Roll back from version {text}"
}
}
}
-}
+}
\ No newline at end of file
diff --git a/web/src/apps/linkis/i18n/common/zh.json b/web/src/apps/linkis/i18n/common/zh.json
index e6dbed1..e56b79c 100644
--- a/web/src/apps/linkis/i18n/common/zh.json
+++ b/web/src/apps/linkis/i18n/common/zh.json
@@ -6,7 +6,7 @@
"emptyString": "空字符串",
"addAppType": "新增应用类型",
"editContents": "编辑目录",
- "eurekeRegisterCenter": "Eureke注册中心",
+ "eurekeRegisterCenter": "Eureke注册中心",
"addParameterConfig": "新增参数配置",
"editDescriptionEngineConfig": "编辑引擎配置",
"name": "名称",
@@ -54,6 +54,9 @@
"generalView": "切换普通视图",
"manageView": "切换管理员视图",
"back": "返回",
+ "prev": "上一步",
+ "complete": "完成",
+ "close": "关闭",
"warning": {
"api": "接口请求中,请稍候!",
"data": "数据请求中,请稍候!",
@@ -120,7 +123,8 @@
"dateReport": "全局变量",
"globalValiable": "常见问题",
"ECMManage": "ECM管理",
- "microserviceManage": "微服务管理"
+ "microserviceManage": "微服务管理",
+ "dataSourceManage": "数据源管理"
}
}
},
@@ -235,7 +239,43 @@
},
"success": {
"update": "全局变量更新成功!"
+ },
+ "datasource": {
+ "pleaseInput": "请输入",
+ "datasourceSrc": "数据源",
+ "connectTest": "测试连接",
+ "sourceName": "数据源名称",
+ "sourceDec": "数据源描述",
+ "sourceType": "数据源类型:",
+ "creator": "创建人:",
+ "create": "新增数据源",
+ "exports": "批量导出数据源",
+ "imports": "批量导入数据源",
+ "overdue": "过期",
+ "versionList": "版本列表",
+ "dataSourceName": "数据源名称",
+ "dataSourceType": "数据源类型",
+ "dataSourceEnv": "可用集群",
+ "status": "状态",
+ "permissions": "权限",
+ "label": "标签",
+ "version": "版本",
+ "desc": "描述",
+ "action": "操作",
+ "createUser": "创建人",
+ "createTime": "创建时间",
+ "versionDec": "版本描述",
+ "watch": "查看",
+ "rollback": "回滚",
+ "publish": "发布",
+ "initVersion": "初始化版本",
+ "updateVersion": "版本更新",
+ "published": "已发布",
+ "unpublish": "未发布",
+ "cannotPublish": "不可发布",
+ "used": "可用",
+ "commentValue": "从版本 {text} 回滚"
}
}
}
-}
+}
\ No newline at end of file
diff --git a/web/src/apps/linkis/module/datasource/dataSourceApi.js b/web/src/apps/linkis/module/datasource/dataSourceApi.js
new file mode 100644
index 0000000..d718501
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/dataSourceApi.js
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+import api from '@/common/service/api';
+import { serialize } from 'object-to-formdata';
+
+/**
+ * 获取数据源列表
+ */
+const getDataSourceList = (params)=>{
+ return api.fetch('data_source/info', params, 'get')
+}
+
+/**
+ * 获取数据源类型列表
+ */
+const getDataSourceTypeList = ()=>{
+ return api.fetch('/data_source/type/all', {}, 'get')
+}
+
+/**
+ * 获取环境列表
+ */
+const getEnvList = ()=>{
+ return api.fetch('data_source/env', {}, 'get')
+}
+
+/**
+ *
+ * @returns 获取datasource key定义
+ */
+const getKeyDefine = (id)=>{
+ return api.fetch(`/data_source/key_define/type/${id}`, {}, 'get')
+}
+
+/**
+ * 创建数据源
+ * @param {*} realFormData
+ * @returns
+ */
+const createDataSource = (realFormData)=>{
+ return api.fetch('data_source/info/json', realFormData)
+}
+
+/**
+ * 创建数据源 formdata
+ * @param {*} realFormData
+ * @returns
+ */
+const createDataSourceForm = (realFormData)=>{
+ return api.fetch('data_source/info/form', realFormData, {methed: 'post', 'Content-Type': 'text/plain'})
+}
+
+/**
+ * 更新数据源
+ * @param {*} datasourceId
+ * @param {*} data
+ * @returns
+ */
+const updateDataSource = (data, datasourceId)=>{
+ return api.fetch(`data_source/info/${datasourceId}/json`, data, 'put')
+}
+
+/**
+ *
+ * @param {数据源id} datasourceId
+ * @param {连接参数} data
+ * @returns
+ */
+const saveConnectParams = (datasourceId, data, comment)=>{
+ return api.fetch(`/data_source/parameter/${datasourceId}/json`, {connectParams: data, comment})//{connectParams: data, comment}
+}
+
+/**
+ * 创建数据源 formdata
+ * @param {*} realFormData
+ * @returns
+ */
+const saveConnectParamsForm = (datasourceId, data, comment)=>{
+ const formData = serialize({connectParams: data, comment});
+ return api.fetch(`/data_source/parameter/${datasourceId}/form`, formData, {methed: 'post', 'Content-Type': 'text/plain'})
+}
+
+
+/**
+ *
+ * @param {数据源id} datasourceId
+ * @returns 数据源详情
+ */
+const getDataSourceByIdAndVersion = (datasourceId, version)=>{
+ return api.fetch(`/data_source/info/${datasourceId}/${version}`, {}, 'get')
+}
+/**
+ * 获取版本列表
+ * @param {数据源id}} datasourceId
+ * @returns
+ */
+const getVersionListByDatasourceId = (datasourceId)=>{
+ return api.fetch(`/data_source/${datasourceId}/versions`, {}, 'get')
+}
+
+
+
+
+/**
+ * 设置过期=软删除
+ * @param {数据源id} datasourceId
+ * @returns
+ */
+const expire = (datasourceId)=>{
+ return api.fetch(`/data_source/info/${datasourceId}/expire`, {}, 'put')
+}
+
+/**
+ * 发布数据源
+ * @param {*} datasourceId
+ * @param {*} versionId
+ * @returns
+ */
+const publish = (datasourceId, versionId)=>{
+ return api.fetch(`data_source/publish/${datasourceId}/${versionId}`, {}, 'post')
+}
+
+/**
+ * 连接数据源
+ * @param {连接信息} data
+ * @returns
+ */
+const connect = (data)=> {
+ return api.fetch(`data_source/op/connect/json`, data);
+}
+
+
+//过期done
+//创建数据源,创建版本done
+//
+
+export {
+ getDataSourceList,
+ getDataSourceTypeList,
+ getEnvList,
+ getKeyDefine,
+ createDataSource,
+ saveConnectParams,
+ getDataSourceByIdAndVersion,
+ updateDataSource,
+ expire,
+ publish,
+ connect,
+ createDataSourceForm,
+ getVersionListByDatasourceId,
+ saveConnectParamsForm
+}
\ No newline at end of file
diff --git a/web/src/apps/linkis/module/datasource/datasourceForm/index.scss b/web/src/apps/linkis/module/datasource/datasourceForm/index.scss
new file mode 100644
index 0000000..2a1033b
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/datasourceForm/index.scss
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+@import '@/common/style/variables.scss';
+
+.search-bar {
+ .search-item {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ font-size: $font-size-base;
+
+ .lable {
+ min-width: 90px;
+ // flex-basis: 130px;
+ text-align: right;
+ }
+ }
+
+ .ivu-col {
+ display: flex;
+ justify-content: center;
+ }
+
+}
+
+.table-content {
+ margin-top: 25px;
+}
+
+.datasource-type-wrap {
+ .project-header {
+ height: 32px;
+
+ .header-title {
+ font-size: $font-size-large;
+ font-weight: bold;
+ padding-left: 12px;
+ border-left: 3px solid $primary-color;
+ color: $text-title-color;
+ }
+
+ .header-tool {
+ float: right;
+ margin-right: 6%;
+ color: $primary-color;
+ cursor: pointer;
+
+ .sort-icon {
+ margin-right: 20px;
+
+ .icon {
+ margin-left: 5px;
+ color: $primary-color;
+ }
+ }
+
+ .search-input {
+ width: 200px;
+ margin-right: 30px;
+ }
+ }
+ }
+
+}
diff --git a/web/src/apps/linkis/module/datasource/datasourceForm/index.vue b/web/src/apps/linkis/module/datasource/datasourceForm/index.vue
new file mode 100644
index 0000000..6960314
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/datasourceForm/index.vue
@@ -0,0 +1,272 @@
+<!--
+ ~ 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="table-warp">
+ <form-create :rule="rule" v-model="fApi" :option="options" :value.sync="formData"/>
+ </div>
+</template>
+<script>
+import _, { merge, mergeWith} from 'lodash';
+import api from '@/common/service/api';
+import {getKeyDefine, getDataSourceByIdAndVersion} from '../dataSourceApi';
+// import {mysql, hive} from '../datasource';
+
+const type = {
+ TEXT: {type: 'input'},
+ NUMBER: {type: 'input', props: {type: 'number'}},
+ PASSWORD: {type: 'input', props: {type: 'password'}},
+ EMAIL: {type: 'input', props: {type: 'email'}},
+ DATE: {type: 'input', props: {type: 'date'}},
+ TEL: {type: 'input', props: {type: 'tel'}},
+ TEXTAREA: {type: 'input', props: {type: 'textarea'}},
+ URL: {type: 'input', props: {type: 'url'}},
+ FILE: (self, source)=>{
+ return {type: 'upload', props: {uploadType: 'file', action: '',allowRemove: true, "maxLength": 1,
+ beforeUpload: (file)=>{
+ self.file = file;
+ source.props.value = file.name;
+ return false;
+ }}}
+ },
+ SELECT: {type: 'select', props: {placement: "bottom"}}
+}
+const typesMap = {
+ valueType: (data, source, self)=>{
+ if(type[data.valueType]){
+ if(typeof type[data.valueType] === 'function'){
+ return type[data.valueType](self, source);
+ }
+ return type[data.valueType]
+ }else{
+ return {type: data.valueType}
+ }
+ },
+ name: 'title',
+
+ defaultValue: 'value',
+ // dataSource: 'options',
+ dataSource: (data, source, self)=>{
+ const fApi = self.fApi;
+ if(/^https?:/.test(data.dataSource)){
+ api.fetch(data.dataSource, {}, 'get').then(result=>{
+ delete source.options;
+ source.options = result.env_list.map(item=>{
+ return {label: item.envName, value: ''+item.id}
+ });
+ // console.log('self.rule',self.rule)
+ fApi.refreshOptions();
+ })
+ return {options: []}
+ }else {
+ try {
+ return {options: JSON.parse(data.dataSource)}
+ } catch (error) {
+ return {options: []}
+ }
+ }
+ },
+ key: 'field',
+ description: (data)=>{
+ return {props: {placeholder: data.description}}
+ },
+ require: (data)=>{
+ if(data.require) //&& !data.valueRegex
+ return {validate: [{ required: true, message: `请输入${data.name}`, trigger: 'blur' }]}
+ else return null
+ },
+ valueRegex: (data)=>{
+ if(data.valueRegex){
+ return {validate: [{pattern: new RegExp(data.valueRegex), message: '不符合规则', trigger: 'blur'}]}
+ }
+ else return null;
+ },
+ // valueRegex: (data)=>{
+ // if(data.valueRegex)
+ // return {validate: { pattern: new RegExp(data.valueRegex), message: '不符合规则', trigger: 'blur' }}
+ // else return null
+ // },
+
+ refId: 'refId',
+ refValue: 'refValue',
+ id: 'id',
+}
+export default {
+ props: {
+ data: Object
+ },
+ data () {
+ return {
+ sourceConnectData: {},
+ fApi: {},
+ loading: false,
+ formData: {file: 'adn'},
+ options: {
+ submitBtn: false,
+ },
+ rule: [
+ {
+ type: "input",
+ title: this.$t('message.linkis.datasource.sourceName'),
+ field: "dataSourceName",
+ value: "",
+ props: {
+ "placeholder": this.$t('message.linkis.datasource.sourceName'),
+ },
+ validate: [{
+ required: true,
+ message: `${this.$t('message.linkis.datasource.pleaseInput')}${this.$t('message.linkis.datasource.sourceName')}`,
+ trigger: 'blur'
+ },
+ ],
+ },
+ {
+ type: "input",
+ title: this.$t('message.linkis.datasource.sourceDec'),
+ field: "dataSourceDesc",
+ value: "",
+ props: {
+ "placeholder": this.$t('message.linkis.datasource.sourceDec'),
+ }
+ },
+ {
+ type: "input",
+ title: this.$t('message.linkis.datasource.label'),
+ field: "labels",
+ value: "",
+ props: {
+ "placeholder": this.$t('message.linkis.datasource.label'),
+ }
+ }
+ ],
+
+ }
+ },
+ created(){
+ this.loading = true;
+
+ this.getDataSource(this.data);
+
+ getKeyDefine(this.data.dataSourceTypeId).then((data)=>{
+ this.loading = false;
+ this.transformData(data.key_define);
+ })
+ },
+ watch: {
+ data: {
+ handler (newV) {
+
+ this.getDataSource(newV);
+ },
+ deep: true
+ }
+ },
+ methods: {
+ getDataSource(newV){
+ if(this.data.id){
+ getDataSourceByIdAndVersion(newV.id, newV.versionId||0).then(result=>{
+
+ const mConnect = result.info.connectParams;
+ this.sourceConnectData = mConnect;
+ delete result.info.connectParams;
+ this.dataSrc = { ...result.info, ...mConnect};
+ this.formData = { ...result.info, ...mConnect};
+ })
+ }else{
+ const connectParams = newV.connectParams;
+ delete newV.connectParams;
+ this.formData = {...newV, ...connectParams};
+ this.dataSrc = {...newV, ...connectParams};
+ }
+ },
+ transformData(keyDefinitions){
+ const tempData = [];
+
+ keyDefinitions.forEach((obj)=>{
+ let item = {};
+ Object.keys(obj).forEach((keyName) =>{
+
+ switch (typeof typesMap[keyName]) {
+ case 'object':
+ item = merge({}, item, typesMap[keyName])
+ break;
+
+ case 'function':
+
+ item = mergeWith(item, typesMap[keyName](obj, item, this), function(objValue, srcValue){
+ if(_.isArray(objValue)) {
+ return objValue.concat(srcValue);
+ }
+ });
+ break;
+
+ case 'string':
+ item[typesMap[keyName]] = obj[keyName];
+ break;
+ }
+ });
+ tempData.push(item);
+ });
+
+ const insertParent = (id, child)=>{
+
+ let parent = tempData.find(item=> id==item.id);
+ if(parent && child){
+
+ if(!parent.control || parent.control.length===0) {
+ parent.control = [ //不存在新建
+ {
+ value: child.refValue,
+ rule: [{...child} ]
+ }
+ ]
+ }else {
+ let index = parent.control.findIndex(item=>item.value+'' === child.refValue+'');
+ if(index > -1){
+ parent.control[index].rule.push({...child})
+ }else {
+ parent.control.push(
+ {
+ value: child.refValue,
+ rule: [{...child} ]
+ }
+ )
+ }
+
+ }
+
+ }
+
+ }
+
+ for(var i =0; i<tempData.length; i++){
+ let item = tempData[i];
+ if(item.refId && item.refId > 0){
+ let children = tempData.splice(i, 1);
+ i--;
+ insertParent(item.refId, children[0]);
+ }
+ }
+ this.rule = this.rule.concat(tempData);
+ return tempData;
+
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped src="./index.scss"></style>
diff --git a/web/src/apps/linkis/module/datasource/datasourceType/index.scss b/web/src/apps/linkis/module/datasource/datasourceType/index.scss
new file mode 100644
index 0000000..0b66b25
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/datasourceType/index.scss
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+@import '@/common/style/variables.scss';
+
+.datasource-type-wrap {
+ position: relative;
+ height: 400px;
+ overflow-y: auto;
+
+ .header-tool {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin-right: 6%;
+ color: $primary-color;
+ cursor: pointer;
+
+ .sort-icon {
+ margin-right: 20px;
+
+ .icon {
+ margin-left: 5px;
+ color: $primary-color;
+ }
+ }
+
+ .search-input {
+ width: 200px;
+ margin-right: 30px;
+ }
+ }
+
+ .classifier {
+ // padding-top: 20px;
+
+ .project-header {
+ height: 32px;
+
+ .header-title {
+ font-size: $font-size-large;
+ font-weight: bold;
+ padding-left: 12px;
+ border-left: 3px solid $primary-color;
+ color: $text-title-color;
+ }
+ }
+
+ .resource-item {
+
+ background-color: #fff;
+ box-shadow: 0 0 6px 0 rgba(0 ,0 ,0,0.2);
+ margin-right: 12px;
+ margin-bottom: 16px;
+ display: inline-block;
+ text-align: center;
+ width: 140px;
+ height: 96px;
+ cursor: pointer;
+ position: relative;
+ vertical-align: top;
+ margin-left: 20px;
+
+ &:hover {
+ box-shadow: 0 0 6px 0 rgba(0,154,176,0.6);
+ }
+
+ .resource-img {
+ width: 140px;
+ height: 87px;
+ display: block;
+ box-sizing: content-box;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 10px;
+ }
+
+ .resource-name {
+ text-align: center;
+ display: block;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ font-size: 12px;
+ height: 30px;
+ padding: 4px;
+ display: flex;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ }
+ }
+ }
+
+}
diff --git a/web/src/apps/linkis/module/datasource/datasourceType/index.vue b/web/src/apps/linkis/module/datasource/datasourceType/index.vue
new file mode 100644
index 0000000..4371b8e
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/datasourceType/index.vue
@@ -0,0 +1,76 @@
+<!--
+ ~ 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="datasource-type-wrap">
+
+ <div class="classifier" v-for="(item, name) in sourceType" :key="name">
+ <h3 class="project-header">
+ <span class="header-title" >{{name}}</span>
+ </h3>
+
+ <div class="resource-item" v-for="sourceItem in item" :key="sourceItem.name"
+ @click="onSelected(sourceItem)">
+ <img class="resource-img" :src="sourceItem.icon"/>
+ <span class="resource-name">{{sourceItem.name}}</span>
+ </div>
+ </div>
+
+ <Spin size="large" fix v-if="loading"></Spin>
+
+ </div>
+</template>
+
+<script>
+export default {
+ props: {
+ onSelected: Function,
+ data: Array
+ },
+ methods: {
+ transformTypeData(data){
+ const tempObj = {};
+ data.forEach(item=>{
+ if(!tempObj[item.classifier]){
+ tempObj[item.classifier] = [];
+ }
+ tempObj[item.classifier].push(item)
+ })
+ this.sourceType = tempObj;
+ }
+ },
+ computed: {
+ sourceType: function(){
+ const tempObj = {};
+ this.data.forEach(item=>{
+ if(!tempObj[item.classifier]){
+ tempObj[item.classifier] = [];
+ }
+ tempObj[item.classifier].push(item)
+ })
+ return tempObj;
+ }
+ },
+ data() {
+ return {
+ loading: false
+ }
+ },
+}
+</script>
+
+<style lang="scss" scoped src="./index.scss"></style>
\ No newline at end of file
diff --git a/web/src/apps/linkis/module/datasource/index.js b/web/src/apps/linkis/module/datasource/index.js
new file mode 100644
index 0000000..8218e73
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/index.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+export default {
+ name: 'datasourceManager',
+ component: () => import('./index.vue'),
+};
\ No newline at end of file
diff --git a/web/src/apps/linkis/module/datasource/index.scss b/web/src/apps/linkis/module/datasource/index.scss
new file mode 100644
index 0000000..7ea4fd6
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/index.scss
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+@import '@/common/style/variables.scss';
+
+.search-bar {
+ .search-item {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ font-size: $font-size-base;
+
+ .lable {
+ min-width: 90px;
+ // flex-basis: 130px;
+ text-align: right;
+ }
+ }
+
+ .ivu-col {
+ display: flex;
+ justify-content: center;
+ }
+
+}
+
+.table-content {
+ margin-top: 25px;
+}
+
+.datasource-type-wrap {
+ .project-header {
+ height: 32px;
+
+ .header-title {
+ font-size: $font-size-large;
+ font-weight: bold;
+ padding-left: 12px;
+ border-left: 3px solid $primary-color;
+ color: $text-title-color;
+ }
+
+ }
+
+}
+
+.modal {
+ .footer {
+ display: flex;
+ justify-content: space-between;
+ }
+}
diff --git a/web/src/apps/linkis/module/datasource/index.vue b/web/src/apps/linkis/module/datasource/index.vue
new file mode 100644
index 0000000..839ff08
--- /dev/null
+++ b/web/src/apps/linkis/module/datasource/index.vue
@@ -0,0 +1,613 @@
+<!--
+ ~ 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>
+ <Modal
+ width="800"
+ class="modal"
+ v-model="showVersionList"
+ :loading="loadingForm"
+ :title="`${actionType}${$t('message.linkis.datasource.versionList')}`">
+ <Spin size="large" fix v-if="loadingVersionList"></Spin>
+ <Table
+ border
+ size="small"
+ align="center"
+ :columns="versionTableColumnNum"
+ :data="currentVersionList"
+ max-height="300"
+ class="table-content">
+ <template
+ slot-scope="{row, index}"
+ slot="action"
+ >
+ <ButtonGroup size="small" :key="row.versionId">
+
+ <Button v-if="row.status==0" size="small" type="text" @click="onPublish(row)"> {{$t('message.linkis.datasource.publish')}} </Button>
+
+ <Button size="small" type="text" @click="watch(row, index)">{{$t('message.linkis.datasource.watch')}}</Button>
+ <Button v-if="row.status==2" size="small" type="text" @click="onRollback(row)"> {{$t('message.linkis.datasource.rollback')}} </Button>
+
+ <Button type="primary" @click="onConnectTestFromVersion(row)">{{$t('message.linkis.datasource.connectTest')}}</Button>
+ </ButtonGroup>
+ </template>
+ </Table>
+ <div slot="footer">
+ <div v-if="currentStep===0">
+ <Button @click="showVersionList = false">{{$t('message.linkis.cancel')}}</Button>
+ </div>
+ </div>
+ </Modal>
+ <Modal
+ width="800"
+ class="modal"
+ v-model="showDataSource"
+ :title="`${actionType}${$t('message.linkis.datasource.datasourceSrc')}`">
+ <Spin size="large" fix v-if="loadingForm"></Spin>
+ <DataSourceType :data="type_list" v-show="currentStep===0" :onSelected="onSelect"/>
+ <DatasourceForm :data="currentSourceData" ref="datasourceForm" v-if="showDataSource&¤tStep===1"/>
+
+ <div slot="footer">
+ <div v-if="currentStep===0">
+ <Button @click="showDataSource = false">{{$t('message.linkis.cancel')}}</Button>
+ </div>
+
+ <div v-else class="footer">
+ <div><Button type="primary" @click="onConnectFormTest">{{$t('message.linkis.datasource.connectTest')}}</Button></div>
+ <div>
+ <Button v-if="actionType==$t('message.linkis.create')" @click="stepChange(-1)">{{$t('message.linkis.prev')}}</Button>
+ <Button v-if="actionType==$t('message.linkis.datasource.watch')" type="primary" @click="showDataSource = false">{{$t('message.linkis.close')}}</Button>
+ <Button v-else type="primary" @click="onSubmit">{{$t('message.linkis.complete')}}</Button>
+ </div>
+ </div>
+ </div>
+ </Modal>
+ <Row class="search-bar" type="flex" justify="space-around">
+ <Col span="6">
+ <Input clearable v-model="searchName" suffix="ios-search" class="input" :placeholder="$t('message.linkis.datasource.sourceName')" @on-enter="searchList(true)"></Input>
+ </Col>
+ <Col span="6" class="search-item">
+ <span class="lable">{{$t('message.linkis.datasource.sourceType')}}</span>
+ <Select v-model="dataSourceTypeId" class="input">
+ <Option v-for="item in type_list" :value="item.id" :key="item.id">{{item.name}}</Option>
+ <Option value="null">{{$t('message.linkis.statusType.all')}}</Option>
+ </Select>
+ </Col>
+ <Col span="3">
+ <Button type="primary" class="button" @click="searchList(true)">{{$t('message.linkis.search')}}</Button>
+ </Col>
+ <Col span="3">
+ <Button type="primary" @click="createDatasource">{{$t('message.linkis.datasource.create')}}</Button>
+ </Col>
+ <Col span="3">
+ <Button type="primary" disabled>{{$t('message.linkis.datasource.exports')}}</Button>
+ </Col>
+ <Col span="3">
+ <Button type="primary" disabled>{{$t('message.linkis.datasource.imports')}}</Button>
+ </Col>
+ </Row>
+ <Table
+ border
+ size="small"
+ align="center"
+ :columns="tableColumnNum"
+ :data="pageDatalist"
+ max-height="420"
+ :loading="tableLoading"
+ class="table-content">
+ <template
+ slot-scope="{row, index}"
+ slot="version"
+ >
+ <Button size="small" type="primary" :disabled="row.expire" @click="openVersionList(row, index)">{{`${row.versionId||'-'}`}}</Button>
+ </template>
+ <template
+ slot-scope="{row, index}"
+ slot="action"
+ >
+ <ButtonGroup size="small">
+ <Button :disabled="row.expire" size="small" type="primary" @click="modify(row, index)">{{$t('message.linkis.edit')}}</Button>
+
+ <Button :disabled="row.expire" size="small" type="primary" @click="overdue(row)"> {{$t('message.linkis.datasource.overdue')}} </Button>
+
+ <Button type="primary" @click="onConnectTest(row)"> {{$t('message.linkis.datasource.connectTest')}} </Button>
+ </ButtonGroup>
+ </template>
+ </Table>
+ <div style="margin: 10px;overflow: hidden">
+ <div style="float: right;">
+ <Page :page-size="page.pageSize" :total="page.totalSize" :current="page.pageNow" @on-change="changePage"></Page>
+ </div>
+ </div>
+ </div>
+</template>
+<script>
+import DatasourceForm from './datasourceForm/index';
+import DataSourceType from './datasourceType/index';
+import { //createDataSourceForm
+ getDataSourceList,getDataSourceTypeList,getEnvList,createDataSource, saveConnectParams, saveConnectParamsForm,
+ expire, updateDataSource, publish, connect, getDataSourceByIdAndVersion, getVersionListByDatasourceId
+} from './dataSourceApi';
+// import _ from 'lodash';
+const FORM_KEYS = ['dataSourceName', 'dataSourceDesc', 'labels']; //'dataSourceEnvId'
+export default {
+ components: {
+ DatasourceForm,
+ DataSourceType
+ },
+ data() {
+ return {
+ currentStep: 0,
+ currentSourceData: null,
+ dataSourceTypeId: null,
+ isCreate: true,
+ showDataSource: false,
+ searchName: '',
+ searchCreator: '',
+ actionType: '',
+ loadingForm: false,
+ tableLoading: false,
+ loadingVersionList: false,
+ page: {
+ totalSize: 0,
+ pageSize: 10,
+ pageNow: 1
+ },
+ tableColumnNum: [
+ {
+ title: this.$t('message.linkis.datasource.dataSourceName'),
+ key: 'dataSourceName',
+ minWidth: 120,
+ tooltip: true,
+ align: 'center'
+ },
+ {
+ title: this.$t('message.linkis.datasource.dataSourceType'),
+ key: 'dataSourceTypeId',
+ minWidth: 100,
+ render: (h, params)=>{
+ let result = {};
+ if(this.type_list){
+ result = this.type_list.find(item => params.row.dataSourceTypeId == item.id) || {};
+ }
+ return h('span', result.name);
+ },
+ align: 'center'
+ },
+ // {
+ // title: this.$t('message.linkis.datasource.dataSourceEnv'),
+ // key: 'dataSourceEnvId',
+ // tooltip: true,
+ // minWidth: 100,
+ // render: (h, params)=>{
+ // let result = {};
+ // if(this.env_list){
+ // result = this.env_list.find(item => params.row.dataSourceEnvId == item.id) || {envName: '无'};
+ // }
+ // return h('span', result.envName);
+ // },
+ // align: 'center'
+ // },
+ {
+ title: this.$t('message.linkis.datasource.status'),
+ key: 'status',
+ tooltip: true,
+ minWidth: 60,
+ align: 'center',
+ render: (h, params)=>{
+ let result = {};
+ if(this.env_list){
+
+ result = this.tableStatusMap.find(item => params.row.expire == item.status) || {};
+ }
+ var color = 'green';
+ if(result.status){
+ color = 'red';
+ }
+ return h('p',{style: {color: color,},}, result.name);
+ }
+ },
+ {
+ title: this.$t('message.linkis.datasource.label'),
+ key: 'labels',
+ tooltip: true,
+ minWidth: 80,
+ align: 'center',
+ },
+ {
+ title: this.$t('message.linkis.datasource.version'),
+ key: 'version',
+ slot: "version",
+ minWidth: 60,
+ // render: (h, params)=>{
+ // return h('span', params.row.versionId || '-');
+ // },
+ align: 'center',
+ },
+ {
+ title: this.$t('message.linkis.datasource.desc'),
+ key: 'dataSourceDesc',
+ minWidth: 120,
+
+ tooltip: true,
+ align: 'center'
+ },
+ {
+ title: this.$t('message.linkis.datasource.createUser'),
+ key: 'createUser',
+ minWidth: 80,
+ tooltip: true,
+ align: 'center'
+ },
+ {
+ title: this.$t('message.linkis.datasource.action'),
+ minWidth: 170,
+ slot: "action",
+ align: 'center'
+ },
+ ],
+ pageDatalist: [],
+ type_list: [],
+ versionStatusMap: [{status: 1, name: this.$t('message.linkis.datasource.published')}, {status: 0, name: this.$t('message.linkis.datasource.unpublish')}, {status: 2, name: this.$t('message.linkis.datasource.cannotPublish')} ],
+ tableStatusMap: [{status: false, name: this.$t('message.linkis.datasource.used')}, {status: true, name: this.$t('message.linkis.datasource.overdue')} ],
+ currentVersionList: [],
+ showVersionList: false,
+ versionTableColumnNum: [
+ {
+ title: this.$t('message.linkis.datasource.version'),
+ key: 'versionId',
+ tooltip: true,
+ minWidth: 60,
+ align: 'center'
+ },
+ {
+ title: this.$t('message.linkis.datasource.status'),
+ key: 'status',
+ tooltip: true,
+ minWidth: 60,
+ align: 'center',
+ render: (h, params)=>{
+ let result = {};
+ result = this.versionStatusMap.find(item => params.row.status == item.status) || {};
+ return h('span', result.name);
+ },
+ },
+ {
+ title: this.$t('message.linkis.datasource.versionDec'),
+ key: 'comment',
+ tooltip: true,
+ minWidth: 60,
+ align: 'center'
+ },
+ // {
+ // title: this.$t('message.linkis.datasource.createTime'),
+ // key: 'createTime',
+ // tooltip: true,
+ // minWidth: 60,
+ // align: 'center'
+ // },
+ {
+ title: this.$t('message.linkis.datasource.action'),
+ key: 'action',
+ tooltip: true,
+ minWidth: 120,
+ align: 'center',
+ slot: 'action'
+ }
+ ]
+ }
+ },
+ created(){
+
+ getDataSourceTypeList().then((data)=>{
+ this.type_list = data.type_list;
+
+ getEnvList().then((data)=>{
+ this.env_list = data.query_list;
+
+ this.searchList();
+ })
+ })
+
+
+
+
+ },
+ methods: {
+ overdue(data){
+ expire(data.id).then(()=>{
+ this.searchList();
+ })
+ },
+ searchList(isSearch){
+ this.loadingTable = true;
+ if(isSearch) {
+ this.page.pageNow = 1;
+ }
+ const data = {
+ typeId: this.dataSourceTypeId,
+ pageSize: this.page.pageSize,
+ currentPage: this.page.pageNow,
+ name: this.searchName
+ };
+
+ if(data.typeId == 'null'){
+ delete data.typeId;
+ }
+
+ getDataSourceList(
+ {
+ ...data
+ }).then(result=>{
+ this.tableLoading = false;
+ this.pageDatalist = result.query_list;
+ this.page.totalSize = result.totalPage;
+ });
+ },
+ getVersionListBySourceId(){
+
+ getVersionListByDatasourceId(this.currentSourceData.id).then(result=>{
+ this.currentVersionList = result.versions;
+ this.currentVersionList.sort((a, b)=>{
+ if(a.versionId > b.versionId){
+ return -1;
+ }
+ if(a.versionId < b.versionId){
+ return 1;
+ }
+ return 0
+ })
+ let lastPulishIndex = Infinity;
+ for (let index = 0; index < this.currentVersionList.length; index++) {
+ const element = this.currentVersionList[index];
+ if(lastPulishIndex < index){ //不能发布
+ element.status = 2;
+ }else{
+ element.status = 0;
+ }
+
+ if(this.currentSourceData.publishedVersionId == element.versionId){
+ lastPulishIndex = index;
+ element.status = 1;
+ }
+
+ }
+ })
+
+
+
+
+ },
+ openVersionList(row){
+ this.currentSourceData = row;
+ this.getVersionListBySourceId();
+ this.showVersionList = true;
+ },
+
+ changePage(value){
+ this.page.pageNow = value;
+ this.searchList();
+ },
+ watch(data) {
+ this.actionType = this.$t('message.linkis.datasource.watch');
+ this.showDataSource = true;
+ this.currentSourceData.versionId = data.versionId;
+ this.currentStep = 1;
+ },
+ modify(data) {
+ this.actionType = this.$t('message.linkis.edit');
+ this.showDataSource = true;
+ this.currentSourceData = data;
+ this.currentStep = 1;
+ },
+ createDatasource(){
+ this.currentStep = 0;
+ this.currentSourceData = null;
+ this.actionType = this.$t('message.linkis.create');
+ this.showDataSource = true;
+ },
+ onSelect(item){
+ this.currentSourceData = {dataSourceTypeId: item.id};
+ this.currentStep = 1;
+ },
+ stepChange(step){
+
+ this.currentStep += step;
+ if(this.currentStep<0){
+ this.currentStep = 0;
+ }else if(this.currentStep>1){
+ this.currentStep = 1;
+ }
+
+ },
+ tranceFormData(data){
+ const formData = new FormData();
+ Object.keys(data).forEach((key) => {
+ if(typeof data[key] === 'object'){
+ formData.append(key, JSON.stringify(data[key]));
+ }else {
+ formData.append(key, data[key]);
+ }
+
+ });
+ return formData;
+ },
+ isEqual(obj1, obj2) {
+ const isObject = (obj)=> {
+ return typeof obj === 'object' && obj !== null
+ }
+ if (!isObject(obj1) || !isObject(obj2)) {
+ return obj1 === obj2
+ }
+ if (obj1 === obj2) {
+ return true
+ }
+ let obj1Keys = Object.keys(obj1)
+ let obj2Keys = Object.keys(obj2)
+ if (obj1Keys.length !== obj2Keys.length) {
+ return false
+ }
+ for (let key in obj1) {
+ const res = this.isEqual(obj1[key], obj2[key])
+ if (!res) {
+ return false
+ }
+ }
+ // 否则全相等
+ return true
+ },
+ onSubmit(){
+ this.$refs.datasourceForm.fApi.submit((formData)=>{
+
+ const realFormData = {};
+ FORM_KEYS.forEach(key=>{
+ realFormData[key] = formData[key];
+ delete formData[key];
+ })
+ realFormData.connectParams = formData;
+ realFormData.createSystem = "Linkis";
+ realFormData.dataSourceTypeId = this.currentSourceData.dataSourceTypeId;
+
+
+
+
+
+ let postDataSource = createDataSource;
+ let commentMsg = this.$t('message.linkis.datasource.initVersion');
+ if(!this.currentSourceData.id){ //新增数据源
+ postDataSource = createDataSource;
+ }else{
+ postDataSource = updateDataSource;
+ commentMsg = this.$t('message.linkis.datasource.updateVersion');
+ }
+ this.loadingForm = true;
+ postDataSource(realFormData, this.currentSourceData.id).then(data=>{
+ this.loadingForm = false;
+ // if(连接信息有变化)
+
+ const sourceId = data.id || data.insert_id || data.update_id;
+
+ console.log()
+ if(!this.currentSourceData.id || !this.isEqual(this.preProcessData(this.$refs.datasourceForm.sourceConnectData), formData)){
+ if(this.$refs.datasourceForm.file){
+ formData.file = this.$refs.datasourceForm.file;
+ saveConnectParamsForm(sourceId, formData, commentMsg).then(()=>{
+ this.$Message.success('Success');
+ this.searchList();
+ });
+ this.showDataSource = false;
+ }else {
+ saveConnectParams(sourceId, formData, commentMsg).then(()=>{
+ this.$Message.success('Success');
+ this.searchList();
+ });
+ this.showDataSource = false;
+ }
+ }else {
+ this.$Message.success('Success');
+ this.searchList();
+ this.showDataSource = false;
+ }
+
+ }).catch(()=>{
+ this.loadingForm = false;
+ })
+ })
+ },
+ preProcessData(data){
+ Object.keys(data).forEach(item=>{
+ let obj = data[item]
+ if(typeof obj === 'undefined' || obj === null || obj === '') {
+ delete data[item];
+ }
+ })
+ return data;
+ },
+ onConnectTestFromVersion(data){
+ this.loadingVersionList = true;
+ getDataSourceByIdAndVersion(data.datasourceId, data.versionId).then(data=>{
+ connect(data.info).then(()=>{
+ this.loadingVersionList = false;
+ this.$Message.success('Connect Success');
+
+ }).catch(()=>{
+ this.loadingVersionList = false;
+ })
+ })
+ },
+ onConnectTest(data){
+ this.currentSourceData = data;
+ this.tableLoading = true;
+ getDataSourceByIdAndVersion(this.currentSourceData.id, this.currentSourceData.versionId).then(data=>{
+ connect(data.info).then(()=>{
+ this.tableLoading = false;
+ this.$Message.success('Connect Success');
+
+ }).catch(()=>{
+ this.tableLoading = false;
+ })
+ }).catch(()=>{
+ this.tableLoading = false;
+ })
+
+ },
+ onConnectFormTest(){
+ this.$refs.datasourceForm.fApi.submit(()=>{
+ this.loadingForm = true;
+ this.$refs.datasourceForm.fApi.submit((formData)=>{
+ const realFormData = {};
+ FORM_KEYS.forEach(key=>{
+ realFormData[key] = formData[key];
+ delete formData[key];
+ })
+
+ realFormData.connectParams = formData;
+ realFormData.createSystem = "Linkis";
+ realFormData.dataSourceTypeId = this.currentSourceData.dataSourceTypeId;
+ realFormData.dataSourceEnvId = parseInt(realFormData.dataSourceEnvId);
+ connect(realFormData).then(()=>{
+ this.loadingForm = false;
+ this.$Message.success('Connect Success');
+ }).catch(()=>{this.loadingForm = false;})
+ })
+ })
+
+ },
+ onPublish(data){
+ this.loadingVersionList = true;
+ publish(data.datasourceId, data.versionId).then(()=>{
+ this.showVersionList = false;
+ this.loadingVersionList = false;
+ this.$Message.success('Publish Success');
+ this.searchList();
+ })
+ },
+ onRollback(data){
+ this.showVersionList = false;
+ const sourceId = data.id || data.datasourceId || data.update_id;
+
+ saveConnectParams(sourceId, data.connectParams, this.$t('message.linkis.datasource.commentValue', {text: data.versionId})).then(()=>{
+ this.$Message.success('onRollback Success');
+ this.searchList();
+ });
+ }
+
+ }
+}
+</script>
+<style lang="scss" src="./index.scss" scoped></style>
\ No newline at end of file
diff --git a/web/src/apps/linkis/router.js b/web/src/apps/linkis/router.js
index bc662f9..1523561 100644
--- a/web/src/apps/linkis/router.js
+++ b/web/src/apps/linkis/router.js
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
export const subAppRoutes = {
path: '',
name: 'layout',
@@ -75,7 +75,7 @@ export default [
title: 'setting',
publicPage: true,
},
- },{
+ }, {
name: 'ECM',
path: 'ECM',
component: () =>
@@ -84,7 +84,7 @@ export default [
title: 'ECM',
publicPage: true,
},
- },{
+ }, {
name: 'EngineConnList',
path: 'EngineConnList',
component: () =>
@@ -121,6 +121,16 @@ export default [
title: 'microServiceManagement',
publicPage: true,
},
+ },
+ {
+ name: 'datasource',
+ path: 'datasource',
+ component: () =>
+ import('./module/datasource/index.vue'),
+ meta: {
+ title: 'datasourceManagement',
+ publicPage: true,
+ },
}
],
},
diff --git a/web/src/apps/linkis/view/linkis/index.vue b/web/src/apps/linkis/view/linkis/index.vue
index 0510647..69bba89 100644
--- a/web/src/apps/linkis/view/linkis/index.vue
+++ b/web/src/apps/linkis/view/linkis/index.vue
@@ -85,6 +85,7 @@ export default {
{ key: '1-6', name: this.$t('message.linkis.sideNavList.function.children.ECMManage'), path: '/console/ECM' },
{ key: '1-7', name: this.$t('message.linkis.sideNavList.function.children.microserviceManage'), path: '/console/microService' },
{ key: '1-5', name: this.$t('message.linkis.sideNavList.function.children.globalValiable'), path: '/console/FAQ' },
+ { key: '1-8', name: this.$t('message.linkis.sideNavList.function.children.dataSourceManage'), path: '/console/dataSource' },
],
},
breadcrumbSecondName: this.$t('message.linkis.sideNavList.function.children.globalHistory')
diff --git a/web/src/main.js b/web/src/main.js
index 698a85c..3f297f0 100644
--- a/web/src/main.js
+++ b/web/src/main.js
@@ -14,11 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
import Vue from 'vue'
import iView from 'iview'
import VueRouter from 'vue-router'
+import formCreate from '@form-create/iview'
import { apps } from './dynamic-apps'
import component from './components'
import App from './dss/view/app.vue'
@@ -35,12 +36,12 @@ import './dss/module/index.js'
// moduleMixin
if (apps.requireComponent) {
- apps.requireComponent.forEach(item=>{
+ apps.requireComponent.forEach(item => {
mixinDispatch(item)
})
}
if (apps.requireComponentVue) {
- apps.requireComponentVue.forEach(item=>{
+ apps.requireComponentVue.forEach(item => {
mixinDispatch(undefined, item)
})
}
@@ -50,6 +51,7 @@ Vue.use(component)
Vue.use(iView, {
i18n: (key, value) => i18n.t(key, value)
})
+Vue.use(formCreate)
Vue.config.productionTip = false
Vue.prototype.$Message.config({
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@linkis.apache.org
For additional commands, e-mail: commits-help@linkis.apache.org