You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ca...@apache.org on 2022/10/19 03:22:45 UTC

[dolphinscheduler] branch dev updated: [Feature] Optimizing data source centers (#12292)

This is an automated email from the ASF dual-hosted git repository.

caishunfeng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new a11892aea0 [Feature] Optimizing data source centers (#12292)
a11892aea0 is described below

commit a11892aea0dd16ea04d7a595b186a8ae1f32a9c0
Author: labbomb <73...@qq.com>
AuthorDate: Wed Oct 19 11:22:39 2022 +0800

    [Feature] Optimizing data source centers (#12292)
    
    * feat: Optimizing data source centers
    
    * add e2e class
    
    * update datasource e2e
    
    * fix hive e2e
    
    * fix: Modify the source type parameter
    
    Co-authored-by: caishunfeng <ca...@gmail.com>
---
 .../e2e/cases/HiveDataSourceE2ETest.java           |  2 +-
 .../e2e/pages/datasource/DataSourcePage.java       | 16 ++--
 .../e2e/core/DolphinSchedulerExtension.java        |  6 +-
 dolphinscheduler-ui/src/components/modal/index.tsx | 26 +++---
 .../src/locales/en_US/datasource.ts                |  1 +
 .../src/locales/zh_CN/datasource.ts                |  9 ++-
 dolphinscheduler-ui/src/locales/zh_CN/menu.ts      |  2 +-
 .../src/service/modules/data-source/types.ts       | 14 ++++
 .../src/views/datasource/list/detail.tsx           | 46 ++++++++---
 .../src/views/datasource/list/index.module.scss    | 56 +++++++++++++
 .../src/views/datasource/list/index.tsx            | 30 ++++++-
 .../src/views/datasource/list/source-modal.tsx     | 93 ++++++++++++++++++++++
 .../src/views/datasource/list/use-form.ts          |  1 +
 13 files changed, 260 insertions(+), 42 deletions(-)

diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java
index 6d8eb7b310..6381b2faab 100644
--- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java
+++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java
@@ -46,7 +46,7 @@ public class HiveDataSourceE2ETest {
 
     private static final String password = "dolphinscheduler123";
 
-    private static final String dataSourceType = "HIVE";
+    private static final String dataSourceType = "HIVE/IMPALA";
 
     private static final String dataSourceName = "hive_test";
 
diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java
index b5182a41b6..521cc6c972 100644
--- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java
+++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java
@@ -56,6 +56,11 @@ public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem
     })
     private WebElement buttonConfirm;
 
+    @FindBys({
+        @FindBy(className = "dialog-source-modal"),
+    })
+    private WebElement dataSourceModal;
+
     private final CreateDataSourceForm createDataSourceForm;
 
     public DataSourcePage(RemoteWebDriver driver) {
@@ -69,19 +74,12 @@ public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem
         buttonCreateDataSource().click();
 
         new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(
-            new By.ByClassName("dialog-create-data-source")));
+            new By.ByClassName("dialog-source-modal")));
 
-        createDataSourceForm().btnDataSourceTypeDropdown().click();
+        dataSourceModal().findElement(By.className(dataSourceType.toUpperCase()+"-box")).click();
 
         new WebDriverWait(driver, 10).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase()));
 
-        createDataSourceForm().selectDataSourceType()
-            .stream()
-            .filter(it -> it.getText().contains(dataSourceType.toUpperCase()))
-            .findFirst()
-            .orElseThrow(() -> new RuntimeException(String.format("No %s in data source type list", dataSourceType.toUpperCase())))
-            .click();
-
         createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName);
         createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription);
         createDataSourceForm().inputIP().sendKeys(ip);
diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
index 21e2f129db..b8683ca93e 100644
--- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
+++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
@@ -67,6 +67,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
 
     private final boolean M1_CHIP_FLAG = Objects.equals(System.getProperty("m1_chip"), "true");
 
+    private final int LOCAL_PORT = 5173;
+
     private RemoteWebDriver driver;
     private DockerComposeContainer<?> compose;
     private BrowserWebDriverContainer<?> browser;
@@ -117,8 +119,8 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall
     }
 
     private void runInLocal() {
-        Testcontainers.exposeHostPorts(3000);
-        address = HostAndPort.fromParts("host.testcontainers.internal", 3000);
+        Testcontainers.exposeHostPorts(LOCAL_PORT);
+        address = HostAndPort.fromParts("host.testcontainers.internal", LOCAL_PORT);
         rootPath = "/";
     }
 
diff --git a/dolphinscheduler-ui/src/components/modal/index.tsx b/dolphinscheduler-ui/src/components/modal/index.tsx
index 6b1dc0d3a6..79aeb0c4a6 100644
--- a/dolphinscheduler-ui/src/components/modal/index.tsx
+++ b/dolphinscheduler-ui/src/components/modal/index.tsx
@@ -38,6 +38,10 @@ const props = {
     type: Boolean as PropType<boolean>,
     default: true
   },
+  confirmShow: {
+    type: Boolean as PropType<boolean>,
+    default: true
+  },
   confirmText: {
     type: String as PropType<string>
   },
@@ -136,16 +140,18 @@ const Modal = defineComponent({
                 )}
                 {/* TODO: Add left and right slots later */}
                 {renderSlot($slots, 'btn-middle')}
-                <NButton
-                  class={[this.confirmClassName, 'btn-submit']}
-                  type='info'
-                  size='small'
-                  onClick={onConfirm}
-                  disabled={confirmDisabled}
-                  loading={confirmLoading}
-                >
-                  {this.confirmText || t('modal.confirm')}
-                </NButton>
+                {this.confirmShow && (
+                  <NButton
+                    class={[this.confirmClassName, 'btn-submit']}
+                    type='info'
+                    size='small'
+                    onClick={onConfirm}
+                    disabled={confirmDisabled}
+                    loading={confirmLoading}
+                  >
+                    {this.confirmText || t('modal.confirm')}
+                  </NButton>
+                )}
               </NSpace>
             )
           }}
diff --git a/dolphinscheduler-ui/src/locales/en_US/datasource.ts b/dolphinscheduler-ui/src/locales/en_US/datasource.ts
index dda4e99b6f..9d31bae284 100644
--- a/dolphinscheduler-ui/src/locales/en_US/datasource.ts
+++ b/dolphinscheduler-ui/src/locales/en_US/datasource.ts
@@ -18,6 +18,7 @@
 export default {
   datasource: 'DataSource',
   create_datasource: 'Create DataSource',
+  choose_datasource_type: 'Choose DataSource Type',
   search_input_tips: 'Please input the keywords',
   datasource_name: 'Datasource Name',
   datasource_name_tips: 'Please enter datasource name',
diff --git a/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts b/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
index 447ed7f7b5..f9baea3a8c 100644
--- a/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
+++ b/dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
@@ -17,13 +17,14 @@
 
 export default {
   datasource: '数据源',
-  create_datasource: '创建数据源',
+  create_datasource: '创建源',
+  choose_datasource_type: '选择源类型',
   search_input_tips: '请输入关键字',
-  datasource_name: '数据源名称',
+  datasource_name: '源名称',
   datasource_name_tips: '请输入数据源名称',
   datasource_user_name: '所属用户',
-  datasource_type: '数据源类型',
-  datasource_parameter: '数据源参数',
+  datasource_type: '源类型',
+  datasource_parameter: '参数',
   description: '描述',
   description_tips: '请输入描述',
   test_datasource: '测试数据源',
diff --git a/dolphinscheduler-ui/src/locales/zh_CN/menu.ts b/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
index 174ff54774..885cec6c17 100644
--- a/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
+++ b/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
@@ -19,7 +19,7 @@ export default {
   home: '首页',
   project: '项目管理',
   resources: '资源中心',
-  datasource: '数据源中心',
+  datasource: '源中心',
   monitor: '监控中心',
   security: '安全中心',
   ui_setting: '界面设置',
diff --git a/dolphinscheduler-ui/src/service/modules/data-source/types.ts b/dolphinscheduler-ui/src/service/modules/data-source/types.ts
index 333943a52f..ad431353c7 100644
--- a/dolphinscheduler-ui/src/service/modules/data-source/types.ts
+++ b/dolphinscheduler-ui/src/service/modules/data-source/types.ts
@@ -28,9 +28,23 @@ type IDataBase =
   | 'REDSHIFT'
   | 'ATHENA'
 
+type IDataBaseLabel =
+| 'MYSQL'
+| 'POSTGRESQL'
+| 'HIVE'
+| 'SPARK'
+| 'CLICKHOUSE'
+| 'ORACLE'
+| 'SQLSERVER'
+| 'DB2'
+| 'PRESTO'
+| 'REDSHIFT'
+| 'ATHENA'
+
 interface IDataSource {
   id?: number
   type?: IDataBase
+  label?: IDataBaseLabel
   name?: string
   note?: string
   host?: string
diff --git a/dolphinscheduler-ui/src/views/datasource/list/detail.tsx b/dolphinscheduler-ui/src/views/datasource/list/detail.tsx
index 9d92a82c6a..4fb36a8cc6 100644
--- a/dolphinscheduler-ui/src/views/datasource/list/detail.tsx
+++ b/dolphinscheduler-ui/src/views/datasource/list/detail.tsx
@@ -36,8 +36,9 @@ import {
 } from 'naive-ui'
 import Modal from '@/components/modal'
 import { useI18n } from 'vue-i18n'
-import { useForm, datasourceType, datasourceTypeList } from './use-form'
+import { useForm, datasourceType } from './use-form'
 import { useDetail } from './use-detail'
+import styles from './index.module.scss'
 
 const props = {
   show: {
@@ -46,13 +47,17 @@ const props = {
   },
   id: {
     type: Number as PropType<number>
+  },
+  selectType: {
+    type: String as PropType<any>,
+    default: 'MYSQL'
   }
 }
 
 const DetailModal = defineComponent({
   name: 'DetailModal',
   props,
-  emits: ['cancel', 'update'],
+  emits: ['cancel', 'update', 'open'],
   setup(props, ctx) {
     const { t } = useI18n()
 
@@ -95,9 +100,15 @@ const DetailModal = defineComponent({
 
     const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
 
+    const handleSourceModalOpen = () => {
+      ctx.emit('open')
+    }
+
     watch(
       () => props.show,
       async () => {
+        state.detailForm.type = props.selectType
+        state.detailForm.label = props.selectType === 'HIVE' ? 'HIVE/IMPALA' :  props.selectType
         props.show &&
           state.detailForm.type &&
           (await changeType(
@@ -109,6 +120,19 @@ const DetailModal = defineComponent({
       }
     )
 
+    watch(
+      () => props.selectType,
+      async () => {
+        state.detailForm.type = props.selectType
+        state.detailForm.label = props.selectType === 'HIVE' ? 'HIVE/IMPALA' :  props.selectType
+        state.detailForm.type &&
+        (await changeType(
+          state.detailForm.type,
+          datasourceType[state.detailForm.type]
+        ))
+      }
+    )
+
     return {
       t,
       ...toRefs(state),
@@ -119,7 +143,8 @@ const DetailModal = defineComponent({
       onSubmit,
       onTest,
       onCancel,
-      trim
+      trim,
+      handleSourceModalOpen
     }
   },
   render() {
@@ -138,12 +163,12 @@ const DetailModal = defineComponent({
       loading,
       saving,
       testing,
-      onChangeType,
       onChangeTestFlag,
       onChangePort,
       onCancel,
       onTest,
-      onSubmit
+      onSubmit,
+      handleSourceModalOpen
     } = this
     return (
       <Modal
@@ -172,13 +197,10 @@ const DetailModal = defineComponent({
                   path='type'
                   show-require-mark
                 >
-                  <NSelect
-                    class='btn-data-source-type-drop-down'
-                    v-model={[detailForm.type, 'value']}
-                    options={datasourceTypeList}
-                    disabled={!!id}
-                    on-update:value={onChangeType}
-                  />
+                  <div class={[styles.typeBox, !!id && styles.disabledBox]}>
+                    <div v-model={[detailForm.type, 'value']}>{detailForm.label}</div>
+                    <div class={[styles['text-color'], 'btn-data-source-type-drop-down']} onClick={handleSourceModalOpen}>更换</div>
+                  </div>
                 </NFormItem>
                 <NFormItem
                   label={t('datasource.datasource_name')}
diff --git a/dolphinscheduler-ui/src/views/datasource/list/index.module.scss b/dolphinscheduler-ui/src/views/datasource/list/index.module.scss
new file mode 100644
index 0000000000..68a26b99a3
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/datasource/list/index.module.scss
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+.content {
+  display: flex;
+  flex-wrap: wrap;
+
+  .itemBox {
+    padding: 5px 14px;
+    border: 1px solid rgb(224, 224, 230);
+    width: 120px;
+    text-align: center;
+    cursor: pointer;
+
+    &:hover {
+      color: #40a9ff;
+      border: 1px solid #40a9ff;
+    }
+  }
+}
+
+.typeBox {
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+  padding: 5px 14px;
+  border: 1px solid rgb(224, 224, 230);
+
+  &:hover {
+    border: 1px solid #40a9ff;
+  }
+
+  .text-color {
+    color: #1890ff;
+    cursor: pointer;
+  }
+}
+
+.disabledBox {
+  pointer-events: none;
+  opacity: 0.5;
+}
diff --git a/dolphinscheduler-ui/src/views/datasource/list/index.tsx b/dolphinscheduler-ui/src/views/datasource/list/index.tsx
index 0a6c6a4537..c3f65a340d 100644
--- a/dolphinscheduler-ui/src/views/datasource/list/index.tsx
+++ b/dolphinscheduler-ui/src/views/datasource/list/index.tsx
@@ -39,12 +39,15 @@ import { DefaultTableWidth } from '@/common/column-width-config'
 import Card from '@/components/card'
 import DetailModal from './detail'
 import type { TableColumns } from './types'
+import SourceModal from './source-modal'
 
 const list = defineComponent({
   name: 'list',
   setup() {
     const { t } = useI18n()
     const showDetailModal = ref(false)
+    const showSourceModal = ref(false)
+    const selectType = ref('MYSQL')
     const selectId = ref()
     const columns = ref({
       columns: [] as TableColumns,
@@ -64,11 +67,21 @@ const list = defineComponent({
 
     const onCreate = () => {
       selectId.value = null
-      showDetailModal.value = true
+      showSourceModal.value = true
     }
 
     const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
 
+    const handleSelectSourceType = (value: string) => {
+      selectType.value = value
+      showSourceModal.value = false
+      showDetailModal.value = true
+    }
+
+    const handleSourceModalOpen = () => {
+      showSourceModal.value = true
+    }
+
     onMounted(() => {
       changePage(1)
       columns.value = getColumns()
@@ -81,6 +94,7 @@ const list = defineComponent({
     return {
       t,
       showDetailModal,
+      showSourceModal,
       id: selectId,
       columns,
       ...toRefs(data),
@@ -88,7 +102,10 @@ const list = defineComponent({
       changePageSize,
       onCreate,
       onUpdatedList: updateList,
-      trim
+      trim,
+      handleSelectSourceType,
+      selectType,
+      handleSourceModalOpen
     }
   },
   render() {
@@ -96,6 +113,7 @@ const list = defineComponent({
       t,
       id,
       showDetailModal,
+      showSourceModal,
       columns,
       list,
       page,
@@ -105,7 +123,10 @@ const list = defineComponent({
       changePage,
       changePageSize,
       onCreate,
-      onUpdatedList
+      onUpdatedList,
+      handleSelectSourceType,
+      selectType,
+      handleSourceModalOpen
     } = this
 
     return (
@@ -159,11 +180,14 @@ const list = defineComponent({
             </NSpace>
           </NSpace>
         </Card>
+        <SourceModal show={showSourceModal} onChange={handleSelectSourceType}></SourceModal>
         <DetailModal
           show={showDetailModal}
           id={id}
+          selectType={selectType}
           onCancel={() => void (this.showDetailModal = false)}
           onUpdate={onUpdatedList}
+          onOpen={handleSourceModalOpen}
         />
       </NSpace>
     )
diff --git a/dolphinscheduler-ui/src/views/datasource/list/source-modal.tsx b/dolphinscheduler-ui/src/views/datasource/list/source-modal.tsx
new file mode 100644
index 0000000000..c874d6189f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/datasource/list/source-modal.tsx
@@ -0,0 +1,93 @@
+/*
+ * 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 {
+  defineComponent,
+  PropType,
+  toRefs
+} from 'vue'
+import {
+  NSpace
+} from 'naive-ui'
+import Modal from '@/components/modal'
+import { useI18n } from 'vue-i18n'
+import { useForm, datasourceTypeList } from './use-form'
+import styles from './index.module.scss'
+
+const props = {
+  show: {
+    type: Boolean as PropType<boolean>,
+    default: false
+  },
+  id: {
+    type: Number as PropType<number>
+  }
+}
+
+const SourceModal = defineComponent({
+  name: 'SourceModal',
+  props,
+  emits: ['change'],
+  setup(props, ctx) {
+    const { t } = useI18n()
+
+    const { state } = useForm(props.id)
+
+    const handleTypeSelect = (value: string) => {
+      ctx.emit('change', value)
+    }
+
+    return {
+      t,
+      ...toRefs(state),
+      handleTypeSelect
+    }
+  },
+  render() {
+    const {
+      show,
+      t,
+      handleTypeSelect
+    } = this
+
+    return (
+      <Modal
+        class='dialog-source-modal'
+        show={show}
+        title={t('datasource.choose_datasource_type')}
+        cancelShow={false}
+        confirmShow={false}
+      >
+        {{
+          default: () => (
+            <div class={styles.content}>
+              <NSpace>
+                {datasourceTypeList.map((item) => (
+                  <div class={[styles.itemBox, `${item.label}-box`]} onClick={() => handleTypeSelect(item.value)}>
+                    {item.label}
+                  </div>
+                ))}
+              </NSpace>
+            </div>
+          )
+        }}
+      </Modal>
+    )
+  }
+})
+
+export default SourceModal
diff --git a/dolphinscheduler-ui/src/views/datasource/list/use-form.ts b/dolphinscheduler-ui/src/views/datasource/list/use-form.ts
index 5c1259971e..2fb12b6efe 100644
--- a/dolphinscheduler-ui/src/views/datasource/list/use-form.ts
+++ b/dolphinscheduler-ui/src/views/datasource/list/use-form.ts
@@ -36,6 +36,7 @@ export function useForm(id?: number) {
 
   const initialValues = {
     type: 'MYSQL',
+    label: 'MYSQL',
     name: '',
     note: '',
     host: '',