Skip to content

Commit

Permalink
feat:支持配置灰度发布UI交互 (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
chuntaojun committed Dec 9, 2023
1 parent 6bda8e6 commit fedcf8c
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 30 deletions.
2 changes: 2 additions & 0 deletions router/config_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func ConfigRouter(r *gin.Engine, config *bootstrap.Config) {
configV1.POST("configfiles/releases/delete", handlers.ReverseProxyForServer(&config.PolarisServer, config))
// 查询配置发布的版本列表
configV1.GET("configfiles/release/versions", handlers.ReverseProxyForServer(&config.PolarisServer, config))
// 取消配置灰度发布
configV1.POST("configfiles/releases/stopbeta", handlers.ReverseProxyForServer(&config.PolarisServer, config))
// 配置文件发布历史
configV1.GET("configfiles/releasehistory", handlers.ReverseProxyForServer(&config.PolarisServer, config))
//配置文件模板
Expand Down
47 changes: 36 additions & 11 deletions web/src/polaris/configuration/fileGroup/detail/file/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { Link } from 'react-router-dom'
import { FileFormat } from './operation/Create'
import router from '@src/polaris/common/util/router'
import { TAB } from '../Page'
import { ConfigFile } from '../../types'

export const NoSearchResultKey = '__NO_SEARCH_RESULT__'
const getHandlers = memorize(({ creators }: Duck, dispatch) => ({
Expand All @@ -49,6 +50,8 @@ const getHandlers = memorize(({ creators }: Duck, dispatch) => ({
fetchData: path => dispatch(creators.fetchData(path)),
setEditContent: v => dispatch(creators.setEditContent(v)),
releaseCurrentFile: () => dispatch(creators.releaseCurrentFile()),
betaReleaseCurrentFile: () => dispatch(creators.betaReleaseCurrentFile()),
stopBetaReleaseCurrentFile: () => dispatch(creators.stopBetaReleaseCurrentFile()),
showReleaseHistory: v => dispatch(creators.showReleaseHistory(v)),
select: v => dispatch(creators.select(v)),
cancel: () => dispatch(creators.cancel()),
Expand Down Expand Up @@ -221,12 +224,12 @@ export default function Page(props: DuckCmpProps<Duck>) {
fullExpandable
height={900}
style={{ width: '450px', maxWidth: '450px' }}
// onSelect={v => {
// handlers.select(v)
// }}
// selectable
// selectedIds={selection}
// selectValueMode={'onlyLeaf'}
// onSelect={v => {
// handlers.select(v)
// }}
// selectable
// selectedIds={selection}
// selectValueMode={'onlyLeaf'}
>
{renderTree(props, fileTree, '', '')}
</Tree>
Expand Down Expand Up @@ -277,8 +280,8 @@ export default function Page(props: DuckCmpProps<Duck>) {
content={
currentNode.tags.length > 3
? currentNode.tags?.map(item => (
<Text parent={'div'} key={item.key}>{`${item.key}:${item.value}`}</Text>
))
<Text parent={'div'} key={item.key}>{`${item.key}:${item.value}`}</Text>
))
: null
}
>
Expand Down Expand Up @@ -325,12 +328,30 @@ export default function Page(props: DuckCmpProps<Duck>) {
<>
<Button
type={'primary'}
disabled={editing || !data.editable}
disabled={editing || !data.editable || isBetaingRelease(currentNode)}
onClick={() => handlers.releaseCurrentFile()}
>
发布
</Button>

{isBetaingRelease(currentNode) ?
(
<Button
type={'primary'}
disabled={editing || !data.editable}
onClick={() => handlers.stopBetaReleaseCurrentFile()}
>
停止灰度
</Button>
) : (
<Button
type={'weak'}
disabled={editing || !data.editable}
onClick={() => handlers.betaReleaseCurrentFile()}
>
灰度发布
</Button>
)
}
{editing ? (
<>
<Button type={'weak'} onClick={() => handlers.getTemplate(currentNode)}>
Expand All @@ -342,7 +363,7 @@ export default function Page(props: DuckCmpProps<Duck>) {
</>
) : (
<Button
disabled={!data.editable}
disabled={!data.editable || isBetaingRelease(currentNode)}
type={'weak'}
onClick={() => handlers.editCurrentNode()}
>
Expand Down Expand Up @@ -428,6 +449,10 @@ export default function Page(props: DuckCmpProps<Duck>) {
)
}

function isBetaingRelease(file: ConfigFile) {
return file.status === FileStatus.Betaing
}

function getFileNameContext(fileName, status, file, props) {
const splitArray = fileName.split('/')
return (
Expand Down
62 changes: 46 additions & 16 deletions web/src/polaris/configuration/fileGroup/detail/file/PageDuck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ import {
deleteConfigFiles,
describeConfigFilesByGroup,
describeLastReleaseConfigFile,
stopBetaReleaseConfigFile,
} from '../../model'
import Fetcher from '@src/polaris/common/ducks/Fetcher'
import { describeConfigFileReleaseHistories } from '@src/polaris/configuration/releaseHistory/model'
import GetFileTemplate from './operation/GetFileTemplate'
import GetFileTemplateDuck from './operation/GetFileTemplateDuck'
import router from '@src/polaris/common/util/router'
import ReleaseConfigDuck from './operation/ReleaseConfigDuck'
import BetaReleaseConfigDuck from './operation/BetaReleaseConfigDuck'
import { TAB } from '../Page'
import { ClientLabel } from '../../types'
interface MyFilter {
namespace: string
group: string
Expand Down Expand Up @@ -128,6 +131,8 @@ export default class PageDuck extends Base {
SET_EDITING,
SET_EDIT_CONTENT,
RELEASE_CURRENT_NODE,
BETA_RELEASE_CURRENT_NODE,
STOP_BETA_RELEASE_CURRENT_NODE,
SAVE_CURRENT_NODE,
SHOW_RELEASE_HISTORY,
SET_HISTORY_MAP,
Expand Down Expand Up @@ -188,6 +193,8 @@ export default class PageDuck extends Base {
edit: createToPayload<string>(types.EDIT_FILE_META),
setEditContent: createToPayload<string>(types.SET_EDIT_CONTENT),
releaseCurrentFile: createToPayload<void>(types.RELEASE_CURRENT_NODE),
betaReleaseCurrentFile: createToPayload<void>(types.BETA_RELEASE_CURRENT_NODE),
stopBetaReleaseCurrentFile: createToPayload<void>(types.STOP_BETA_RELEASE_CURRENT_NODE),
showReleaseHistory: createToPayload<ConfigFile>(types.SHOW_RELEASE_HISTORY),
save: createToPayload<void>(types.SAVE_CURRENT_NODE),
select: createToPayload<string[]>(types.SELECT),
Expand All @@ -213,20 +220,20 @@ export default class PageDuck extends Base {
*saga() {
yield* super.saga()
const { types, selectors, creators, selector, ducks } = this
yield takeLatest(types.LOAD, function*(action) {
yield takeLatest(types.LOAD, function* (action) {
const { composedId, data } = action.payload
yield put({ type: types.SET_DATA, payload: data })
yield put({ type: types.SET_COMPOSE_ID, payload: composedId })
yield put({ type: types.FETCH_DATA })
// 重置搜索框
yield put({ type: types.SET_SEARCH_PATH_KEYWORD, payload: '' })
})
yield takeLatest(types.ADD, function*() {
yield takeLatest(types.ADD, function* () {
const composedId = selectors.composedId(yield select())

const res = yield* resolvePromise(
new Promise(resolve => {
showDialog(Create, CreateDuck, function*(duck: CreateDuck) {
showDialog(Create, CreateDuck, function* (duck: CreateDuck) {
try {
resolve(
yield* duck.execute({ namespace: composedId.namespace, group: composedId.group }, { isModify: false }),
Expand All @@ -241,11 +248,11 @@ export default class PageDuck extends Base {
yield put({ type: types.FETCH_DATA })
}
})
yield takeLatest(types.GET_FILE_TEMPLATE, function*(action) {
yield takeLatest(types.GET_FILE_TEMPLATE, function* (action) {
const file = action.payload
const templateContent = yield* resolvePromise(
new Promise(resolve => {
showDialog(GetFileTemplate, GetFileTemplateDuck, function*(duck: GetFileTemplateDuck) {
showDialog(GetFileTemplate, GetFileTemplateDuck, function* (duck: GetFileTemplateDuck) {
try {
const result = yield* duck.execute({}, { file })
resolve(result)
Expand All @@ -260,11 +267,11 @@ export default class PageDuck extends Base {
yield put(creators.setEditContent(templateContent as string))
}
})
yield takeLatest(types.EDIT_FILE_META, function*(action) {
yield takeLatest(types.EDIT_FILE_META, function* (action) {
const { fileMap } = selector(yield select())
const res = yield* resolvePromise(
new Promise(resolve => {
showDialog(Create, CreateDuck, function*(duck: CreateDuck) {
showDialog(Create, CreateDuck, function* (duck: CreateDuck) {
try {
resolve(yield* duck.execute(fileMap[action.payload], { isModify: true }))
} finally {
Expand All @@ -277,17 +284,17 @@ export default class PageDuck extends Base {
yield put({ type: types.FETCH_DATA })
}
})
yield takeLatest(types.CANCEL, function*() {
yield takeLatest(types.CANCEL, function* () {
const currentNode = selectors.currentNode(yield select())
yield put({ type: types.SET_EDITING, payload: false })
yield put(creators.setEditContent(currentNode.content))
})
yield takeLatest(types.EDIT_CURRENT_NODE, function*() {
yield takeLatest(types.EDIT_CURRENT_NODE, function* () {
const currentNode = selectors.currentNode(yield select())
yield put({ type: types.SET_EDITING, payload: true })
yield put(creators.setEditContent(currentNode.content))
})
yield takeLatest(types.DELETE, function*(action) {
yield takeLatest(types.DELETE, function* (action) {
const { namespace, group } = selectors.composedId(yield select())
const confirm = yield Modal.confirm({
message: '确认删除配置文件?',
Expand All @@ -304,7 +311,7 @@ export default class PageDuck extends Base {
}
}
})
yield takeLatest(types.FETCH_DATA, function*() {
yield takeLatest(types.FETCH_DATA, function* () {
const composedId = selectors.composedId(yield select())
const searchKeyword = selectors.searchKeyword(yield select())
const currentNode = selectors.currentNode(yield select())
Expand All @@ -326,7 +333,7 @@ export default class PageDuck extends Base {
yield put({ type: types.SET_CURRENT_SHOW_NODE, payload: fileMap[currentNode.name] })
}
})
yield takeLatest(types.SEARCH_PATH, function*(action) {
yield takeLatest(types.SEARCH_PATH, function* (action) {
if (action.payload === '') {
yield put({ type: types.SET_EXPANDED_IDS, payload: [...new Set([])] })
yield put({ type: types.SET_HIT_PATH, payload: [...new Set([])] })
Expand All @@ -351,7 +358,7 @@ export default class PageDuck extends Base {
yield put({ type: types.SET_EXPANDED_IDS, payload: [...new Set(hitPath)] })
yield put({ type: types.SET_HIT_PATH, payload: [...new Set(hitPath)] })
})
yield takeLatest(types.CLICK_FILE_ITEM, function*(action) {
yield takeLatest(types.CLICK_FILE_ITEM, function* (action) {
const { editing, currentNode, fileMap } = selector(yield select())
const nextNode = fileMap[action.payload]
if (editing && currentNode.name !== nextNode.name) {
Expand All @@ -364,7 +371,7 @@ export default class PageDuck extends Base {
yield put({ type: types.SET_CURRENT_SHOW_NODE, payload: nextNode })
yield put({ type: types.SET_EDITING, payload: false })
})
yield takeLatest(types.SHOW_RELEASE_HISTORY, function*(action) {
yield takeLatest(types.SHOW_RELEASE_HISTORY, function* (action) {
const { showHistoryMap } = selector(yield select())
const { fileName, namespace, group } = action.payload
if (showHistoryMap[fileName]) {
Expand All @@ -379,7 +386,7 @@ export default class PageDuck extends Base {
}
yield put(releaseHistoryDuck.creators.fetch({ name: fileName, namespace, group }))
})
yield takeLatest(types.RELEASE_CURRENT_NODE, function*() {
yield takeLatest(types.RELEASE_CURRENT_NODE, function* () {
const currentNode = selectors.currentNode(yield select())
const { namespace, group, name } = currentNode
const { configFileRelease: lastRelease } = yield describeLastReleaseConfigFile({ namespace, name, group })
Expand All @@ -391,7 +398,30 @@ export default class PageDuck extends Base {
notification.error({ description: '发布失败' })
}
})
yield takeLatest(types.SAVE_CURRENT_NODE, function*() {
yield takeLatest(types.BETA_RELEASE_CURRENT_NODE, function* () {
const currentNode = selectors.currentNode(yield select())
const { namespace, group, name } = currentNode
const { configFileRelease: lastRelease } = yield describeLastReleaseConfigFile({ namespace, name, group })
const result = yield BetaReleaseConfigDuck.show({ ...currentNode, lastRelease })
if (result) {
notification.success({ description: '发布成功' })
router.navigate(`/filegroup-detail?namespace=${namespace}&group=${group}&fileName=${name}&tab=${TAB.History}`)
} else {
notification.error({ description: '发布失败' })
}
})
yield takeLatest(types.STOP_BETA_RELEASE_CURRENT_NODE, function* () {
const currentNode = selectors.currentNode(yield select())
const { namespace, group, name } = currentNode
const result = yield stopBetaReleaseConfigFile([{ namespace, file_name: name, group }])
if (result) {
notification.success({ description: '停止灰度发布成功' })
yield put({ type: types.FETCH_DATA })
} else {
notification.error({ description: '停止灰度发布成功失败' })
}
})
yield takeLatest(types.SAVE_CURRENT_NODE, function* () {
const {
editContent,
currentNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export enum FileStatus {
Success = 'success',
Fail = 'failure',
Edited = 'to-be-released',
Betaing = "betaing"
}
export const FileStatusMap = {
[FileStatus.Normal]: {
Expand All @@ -17,6 +18,10 @@ export const FileStatusMap = {
text: '发布失败',
theme: 'danger',
},
[FileStatus.Betaing]: {
text: '灰度发布中',
theme: 'warning',
},
[FileStatus.Edited]: {
text: '编辑待发布',
theme: 'warning',
Expand Down
Loading

0 comments on commit fedcf8c

Please sign in to comment.