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 6 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.