Browse Source

[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 <caishunfeng2021@gmail.com>
3.2.0-release
labbomb 2 years ago committed by GitHub
parent
commit
a11892aea0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java
  2. 16
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java
  3. 6
      dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java
  4. 26
      dolphinscheduler-ui/src/components/modal/index.tsx
  5. 1
      dolphinscheduler-ui/src/locales/en_US/datasource.ts
  6. 9
      dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
  7. 2
      dolphinscheduler-ui/src/locales/zh_CN/menu.ts
  8. 14
      dolphinscheduler-ui/src/service/modules/data-source/types.ts
  9. 46
      dolphinscheduler-ui/src/views/datasource/list/detail.tsx
  10. 56
      dolphinscheduler-ui/src/views/datasource/list/index.module.scss
  11. 30
      dolphinscheduler-ui/src/views/datasource/list/index.tsx
  12. 93
      dolphinscheduler-ui/src/views/datasource/list/source-modal.tsx
  13. 1
      dolphinscheduler-ui/src/views/datasource/list/use-form.ts

2
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";

16
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);

6
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 = "/";
}

26
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>
)
}}

1
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',

9
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: '测试数据源',

2
dolphinscheduler-ui/src/locales/zh_CN/menu.ts

@ -19,7 +19,7 @@ export default {
home: '首页',
project: '项目管理',
resources: '资源中心',
datasource: '数据源中心',
datasource: '源中心',
monitor: '监控中心',
security: '安全中心',
ui_setting: '界面设置',

14
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

46
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')}

56
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;
}

30
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>
)

93
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

1
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: '',

Loading…
Cancel
Save