[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>
This commit is contained in:
parent
d46e4659d9
commit
a11892aea0
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 = "/";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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: '测试数据源',
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
home: '首页',
|
||||
project: '项目管理',
|
||||
resources: '资源中心',
|
||||
datasource: '数据源中心',
|
||||
datasource: '源中心',
|
||||
monitor: '监控中心',
|
||||
security: '安全中心',
|
||||
ui_setting: '界面设置',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -36,6 +36,7 @@ export function useForm(id?: number) {
|
|||
|
||||
const initialValues = {
|
||||
type: 'MYSQL',
|
||||
label: 'MYSQL',
|
||||
name: '',
|
||||
note: '',
|
||||
host: '',
|
||||
|
|
|
|||
Loading…
Reference in New Issue