Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Update DM Portal #417

Merged
merged 7 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dm/portal/dm-fe/README.md → dm/portal/frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ in the repo root folder:

### Run dm-fe

in the repo `dm-portal/dm-fe` folder:
in the repo `dm/dm/portal/frontend` folder:

1. `yarn install`
1. `yarn start`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useMemo, useRef } from 'react'
import { Button, Icon, Tree, Tooltip, message } from 'antd'
import { Button, Icon, Tree, Tooltip, message, Checkbox } from 'antd'
import styled from 'styled-components'
import {
IPageAction,
Expand Down Expand Up @@ -85,6 +85,10 @@ const Container = styled.div`
top: 10px;
right: 10px;
}

.auto-sync-option {
margin-top: 10px;
}
`

type LastStateRef = {
Expand Down Expand Up @@ -172,11 +176,14 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
// 左移,右移,拖拽,重命名需要记录 lastStateRef
const lastStateRef = useRef<LastStateRef | null>(null)

// 是否自动同步上游新增库和新增表的选项
const [autoSyncUpstream, setAutoSyncUpstream] = useState(false)

/////////////////////////////////

function cleanTargetInstance() {
// confirm
if (!window.confirm('你确定要清空下游实例吗?')) {
if (!window.confirm('你确定要重置所有操作吗?此操作会清空下游实例。')) {
return
}

Expand All @@ -196,7 +203,7 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {

function undo() {
// confirm
if (!window.confirm('你确定要撤消此次操作吗?')) {
if (!window.confirm('你确定要撤消此次操作,回到上一步吗?')) {
return
}

Expand Down Expand Up @@ -808,7 +815,8 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
instancesConfig,
sourceSchemas,
targetSchemas,
allTables
allTables,
autoSyncUpstream
)
let res = await generateConfig(finalConfig)
setLoading(false)
Expand Down Expand Up @@ -858,8 +866,8 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
<>
{sourceSchemas[schemaKey].schema}{' '}
<Icon
className="edit-icon"
type="edit"
className='edit-icon'
type='edit'
onClick={onEditIconClick}
/>
</>
Expand All @@ -877,8 +885,8 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
<>
{allTables[tableKey].table}{' '}
<Icon
className="edit-icon"
type="edit"
className='edit-icon'
type='edit'
onClick={onEditIconClick}
/>
</>
Expand Down Expand Up @@ -922,7 +930,7 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
title={
<Tooltip
title={`${schema.sourceId}:${schema.schema}`}
placement="right"
placement='right'
>
{schema.newName}
</Tooltip>
Expand All @@ -936,10 +944,8 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
<TreeNode
title={
<Tooltip
placement="right"
title={`${table.sourceId}:${table.schema}:${
table.table
}`}
placement='right'
title={`${table.sourceId}:${table.schema}:${table.table}`}
>
{table.newName}
</Tooltip>
Expand All @@ -954,10 +960,8 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {
<TreeNode
title={
<Tooltip
placement="right"
title={`${tb.sourceId}:${tb.schema}:${
tb.table
}`}
placement='right'
title={`${tb.sourceId}:${tb.schema}:${tb.table}`}
>
{tb.newName}
</Tooltip>
Expand All @@ -977,40 +981,56 @@ function MigrateStep({ onNext, onPrev, sourceConfig, ...remainProps }: Props) {

return (
<Container>
<div className="dbtable-shuttle-container">
<div className='dbtable-shuttle-container'>
<div>
<h2>上游实例</h2>
<div className="tree-container">{renderSourceTables()}</div>
<div className='tree-container'>{renderSourceTables()}</div>
<div className='auto-sync-option'>
<Checkbox
checked={autoSyncUpstream}
onChange={e => setAutoSyncUpstream(e.target.checked)}
>
自动同步上游新增库和新增表
</Checkbox>
<Tooltip title='当选中此选项时,后续如果上游有新增的库或表,也会同步到下游。否则,后续上游新增的库或表不会同步到下游。'>
<Icon type='question-circle' />
</Tooltip>
</div>
</div>
<div className="shuttle-arrows">
<div className='shuttle-arrows'>
<Button disabled={!enableMoveRight} onClick={moveRight}>
<Icon type="arrow-right" />
<Icon type='arrow-right' />
</Button>
<Button disabled={!enableMoveLeft} onClick={moveLeft}>
<Icon type="arrow-left" />
<Icon type='arrow-left' />
</Button>
</div>
<div>
<h2>下游实例</h2>
<div className="tree-container">
<div className='tree-container'>
{renderTargetTables()}
<div className="action-icons">
<Button onClick={undo} disabled={lastStateRef.current === null}>
<Icon type="undo" />
</Button>
<Button
onClick={cleanTargetInstance}
disabled={targetInstance.schemas.length === 0}
>
<Icon type="rollback" />
</Button>
<div className='action-icons'>
<Tooltip title='回到上一步'>
<Button onClick={undo} disabled={lastStateRef.current === null}>
<Icon type='undo' />
</Button>
</Tooltip>
<span>&nbsp;</span>
<Tooltip title='重置所有操作'>
<Button
onClick={cleanTargetInstance}
disabled={targetInstance.schemas.length === 0}
>
<Icon type='delete' />
</Button>
</Tooltip>
</div>
</div>
</div>
</div>
<div className="action-buttons">
<div className='action-buttons'>
<Button onClick={() => onPrev()}>上一步</Button>
<Button type="primary" onClick={handleSubmit} loading={loading}>
<Button type='primary' onClick={handleSubmit} loading={loading}>
完成并下载
</Button>
<Button onClick={goHome}>返回首页</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,42 +36,74 @@ type Props = IPageAction<ITaskInfo> & {
taskInfo: ITaskInfo
}

type TaskName = {
status: 'success' | 'error'
errMsg: string
value: string
}

function NamingStep({ onNext, onPrev, onData, taskInfo }: Props) {
const edit = useContext(EditContext)
const [taskName, setTaskName] = useState(taskInfo.taskName)
const [taskMode, setTaskMode] = useState(taskInfo.taskMode)
const [taskName, setTaskName] = useState<TaskName>(() =>
handleTaskNameChange(taskInfo.taskName)
)

function handleTaskNameChange(name: string): TaskName {
if (name.length === 0 || /^[a-zA-Z0-9$_]+$/.test(name)) {
return {
status: 'success',
errMsg: '',
value: name
}
} else {
return {
status: 'error',
errMsg: '任务名称不合法',
value: name
}
}
}

return (
<Container>
<Form {...formItemLayout}>
<Form.Item label="任务名称">
<Form.Item
label='任务名称'
validateStatus={taskName.status}
help={taskName.errMsg}
>
<Input
placeholder="test-task"
value={taskName}
onChange={(e: any) => setTaskName(e.target.value)}
placeholder='test-task'
value={taskName.value}
onChange={(e: any) =>
setTaskName(handleTaskNameChange(e.target.value))
}
/>
</Form.Item>
<Form.Item label="同步模式">
<Form.Item label='同步模式'>
<Radio.Group
disabled={edit}
onChange={(e: any) => setTaskMode(e.target.value)}
value={taskMode}
>
<Radio value="full">全量</Radio>
<Radio value="incremental">增量</Radio>
<Radio value="all">All</Radio>
<Radio value='full'>全量</Radio>
<Radio value='incremental'>增量</Radio>
<Radio value='all'>All</Radio>
</Radio.Group>
</Form.Item>
<Form.Item {...tailItemLayout}>
<Button onClick={() => onPrev()}>取消</Button>
<Button
type="primary"
htmlType="submit"
type='primary'
htmlType='submit'
onClick={() => {
onNext()
onData && onData({ taskName, taskMode })
onData && onData({ taskName: taskName.value, taskMode })
}}
disabled={taskName.length === 0}
disabled={
taskName.value.length === 0 || taskName.status === 'error'
}
>
下一步
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ function StartStep(props: Props) {
<Container>
<h1>DM 任务配置生成</h1>
<Button onClick={() => props.onNewRule()}>新建任务配置</Button>
<Button onClick={() => props.onEditRule()}>编辑任务配置</Button>
{/* 编辑功能目前看没有使用场景,先隐藏,后续再移除 */}
{/* <Button onClick={() => props.onEditRule()}>编辑任务配置</Button> */}
</Container>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,10 @@ export function genFiltersConfig(
return filters
}

export function genBlackWhiteList(allTables: IFullTables): IBWList {
export function genBlackWhiteList(
allTables: IFullTables,
autoSycnUpstream: boolean
): IBWList {
const bwList: IBWList = {}
const tables = Object.keys(allTables)
.map(tableKey => allTables[tableKey])
Expand All @@ -314,6 +317,9 @@ export function genBlackWhiteList(allTables: IFullTables): IBWList {
}
const bwType: 'do-tables' | 'ignore-tables' =
table.parentKey !== '' ? 'do-tables' : 'ignore-tables'
if (autoSycnUpstream && bwType === 'do-tables') {
return
}
bwList[bwListKey][bwType].push({
'db-name': table.schema,
'tbl-name': table.table
Expand All @@ -327,11 +333,12 @@ export function genFinalConfig(
instancesConfig: IInstances,
sourceSchemas: IFullSchemas,
targetSchemas: IFullSchemas,
allTables: IFullTables
allTables: IFullTables,
autoSycnUpstream: boolean
) {
const routes: IRoutes = genRoutesConfig(targetSchemas, allTables)
const filters: IFilters = genFiltersConfig(sourceSchemas, allTables)
const bwList: IBWList = genBlackWhiteList(allTables)
const bwList: IBWList = genBlackWhiteList(allTables, autoSycnUpstream)

const finalConfig = {
name: taskInfo.taskName,
Expand Down Expand Up @@ -603,9 +610,7 @@ export function parseFinalConfig(finalConfig: IFinalConfig) {
schema.filters = filterRule.events
} else {
// 说明此条 filter 属于 table
const tableKey = `${sourceId}:${filterRule['schema-pattern']}:${
filterRule['table-pattern']
}`
const tableKey = `${sourceId}:${filterRule['schema-pattern']}:${filterRule['table-pattern']}`
const table = allTables[tableKey]
table.filters = filterRule.events
}
Expand Down
File renamed without changes.