From a9683487af03382436fb80820867e21b1f2d15cd Mon Sep 17 00:00:00 2001 From: barnettZQG Date: Thu, 5 Jan 2023 17:44:23 +0800 Subject: [PATCH] Feat: support to rollback the application (#657) Signed-off-by: barnettZQG Signed-off-by: barnettZQG --- src/api/application.ts | 212 +++++------------- src/api/definitions.ts | 32 +++ src/components/ApplicationDiff/index.less | 2 +- src/components/ApplicationDiff/index.tsx | 40 ++-- src/components/DiffEditor/index.tsx | 28 +++ src/interface/application.ts | 4 + src/model/application.js | 3 +- .../components/ComponentDialog/index.tsx | 2 +- .../components/PolicyDialog/index.tsx | 8 +- .../components/TraitDialog/index.tsx | 9 +- .../components/TriggerDialog/index.tsx | 3 +- src/pages/ApplicationConfig/index.tsx | 6 +- .../components/Header/index.tsx | 4 +- .../components/AddAppDialog/index.tsx | 3 +- src/pages/ApplicationList/index.tsx | 9 +- .../components/List/index.tsx | 106 +++++++-- src/pages/ApplicationRevisionList/index.tsx | 6 +- .../components/WorkflowRecord/index.tsx | 12 +- .../components/CreateConfigDialog/index.tsx | 16 +- .../components/Header/index.tsx | 6 +- src/pages/ProjectApplications/index.tsx | 11 +- .../components/ConfigDistribution/index.tsx | 4 +- .../components/Configs/index.tsx | 4 +- 23 files changed, 297 insertions(+), 233 deletions(-) create mode 100644 src/components/DiffEditor/index.tsx diff --git a/src/api/application.ts b/src/api/application.ts index eda4ecc82..111fcac97 100644 --- a/src/api/application.ts +++ b/src/api/application.ts @@ -1,22 +1,6 @@ import { post, get, rdelete, put } from './request'; -import { - application_mock, - getApplicationDetails_mock, - getApplicationComponents_mock, - createApplicationComponent_mock, - getComponentDetails_mock, - updateApplication_mock, - getPolicyList_mock, - createPolicy_mock, - getPolicyDetails_mock, - createApplicationTemplate_mock, - createApplicationEnv_mock, - getTraitDefinitionsDetails_mock, - getTraitDefinitions_mock, - getTrait_mock, - updateApplicationEnv_mock, -} from './devLink'; -import { application, definition } from './productionLink'; + +import { application } from './productionLink'; import { getDomain } from '../utils/common'; import type { ApplicationDeployRequest, @@ -45,8 +29,7 @@ interface listRevisionsQuery { } const baseURLOject = getDomain(); -const isMock = baseURLOject.MOCK; -const url = isMock ? application_mock : application; +const url = baseURLOject.APIBASE + application; export function getApplicationList(params: ApplicationQuery) { return get(url, { params: params }).then((res) => res); @@ -58,204 +41,141 @@ export function createApplication(params: any) { } export function getApplicationDetails(params: any) { - const gurl = isMock ? `${getApplicationDetails_mock}` : `${application}/${params.name}`; - return get(gurl, params).then((res) => res); + return get(`${url}/${params.name}`, params).then((res) => res); } export function getApplicationStatus(params: { name: string; envName: string }) { - const gurl = isMock - ? `${getApplicationDetails_mock}` - : `${application}/${params.name}/envs/${params.envName}/status`; - return get(gurl, params).then((res) => res); + return get(`${url}/${params.name}/envs/${params.envName}/status`, params).then((res) => res); } -export function deleteApplicationPlan(params: { name: string }) { +export function deleteApplication(params: { name: string }) { return rdelete(url + '/' + params.name, params); } export function getApplicationComponents(params: { appName: string }) { const { appName } = params; - const gurl = isMock ? `${getApplicationComponents_mock}` : `${application}/${appName}/components`; - return get(gurl, {}).then((res) => res); + return get(`${url}/${appName}/components`, {}).then((res) => res); } export function createApplicationComponent( params: ApplicationComponentConfig, query: { appName: string }, ) { - const gurl = isMock - ? `${createApplicationComponent_mock}` - : `${application}/${query.appName}/components`; - return post(gurl, params).then((res) => res); + return post(`${url}/${query.appName}/components`, params).then((res) => res); } export function getComponentDetails(params: any) { - const gurl = isMock - ? `${getComponentDetails_mock}` - : `${application}/${params.name}/components/${params.componentName}`; - return post(gurl, params).then((res) => res); + return post(`${url}/${params.name}/components/${params.componentName}`, params).then( + (res) => res, + ); } export function deployApplication(params: ApplicationDeployRequest, customError?: boolean) { - const gurl = isMock ? `${updateApplication_mock}` : `${application}/${params.appName}/deploy`; - return post(gurl, params, customError); + return post(`${url}/${params.appName}/deploy`, params, customError); } export function getPolicyList(params: { appName: string }) { - const gurl = isMock ? `${getPolicyList_mock}` : `${application}/${params.appName}/policies`; - return get(gurl, params).then((res) => res); + return get(`${url}/${params.appName}/policies`, params).then((res) => res); } export function createPolicy(appName: string, params: CreatePolicyRequest) { - const gurl = isMock ? `${createPolicy_mock}` : `${application}/${appName}/policies`; - return post(gurl, params).then((res) => res); + return post(`${url}/${appName}/policies`, params).then((res) => res); } export function updatePolicy(appName: string, policyName: string, params: UpdatePolicyRequest) { - const gurl = `${application}/${appName}/policies/${policyName}`; - return put(gurl, params).then((res) => res); + return put(`${url}/${appName}/policies/${policyName}`, params).then((res) => res); } export function getPolicyDetail(params: { appName: string; policyName: string }) { - const gurl = isMock - ? `${getPolicyDetails_mock}` - : `${application}/${params.appName}/policies/${params.policyName}`; - return get(gurl, params).then((res) => res); + return get(`${url}/${params.appName}/policies/${params.policyName}`, params).then((res) => res); } export function deletePolicy(params: { appName: string; policyName: string; force?: boolean }) { - const gurl = `${application}/${params.appName}/policies/${params.policyName}`; + const gURL = `${url}/${params.appName}/policies/${params.policyName}`; if (params.force) { - return rdelete(gurl, { params: { force: true } }, true).then((res) => res); + return rdelete(gURL, { params: { force: true } }, true).then((res) => res); } - return rdelete(gurl, {}, true).then((res) => res); + return rdelete(gURL, {}, true).then((res) => res); } export function createApplicationTemplate(params: any) { - const gurl = isMock - ? `${createApplicationTemplate_mock}` - : `${application}/${params.name}/template`; - return post(gurl, params).then((res) => res); -} - -export function getComponentDefinitions() { - const gurl = isMock ? `${getPolicyDetails_mock}` : `${definition}`; - return get(gurl, { params: { type: 'component' } }).then((res) => res); -} - -export function detailComponentDefinition(params: { name: string }) { - const gurl = isMock ? `${getPolicyDetails_mock}` : `${definition}/${params.name}`; - return get(gurl, { params: { type: 'component' } }).then((res) => res); -} - -export function getPolicyDefinitions() { - const gurl = isMock ? `${getPolicyDetails_mock}` : `${definition}`; - return get(gurl, { params: { type: 'policy' } }).then((res) => res); -} - -export function detailPolicyDefinition(params: { name: string }) { - const gurl = isMock ? `${getPolicyDetails_mock}` : `${definition}/${params.name}`; - return get(gurl, { params: { type: 'policy' } }).then((res) => res); + return post(`${url}/${params.name}/template`, params).then((res) => res); } export function createApplicationEnv(params: { appName?: string }) { - const gurl = isMock ? `${createApplicationEnv_mock}` : `${application}/${params.appName}/envs`; delete params.appName; - return post(gurl, params).then((res) => res); + return post(`${url}/${params.appName}/envs`, params).then((res) => res); } export function updateApplicationEnv(params: { appName?: string; name: string }) { - const gurl = isMock - ? `${updateApplicationEnv_mock}` - : `${application}/${params.appName}/envs/${params.name}`; - return put(gurl, params).then((res) => res); + return put(`${url}/${params.appName}/envs/${params.name}`, params).then((res) => res); } export function getApplicationEnvbinding(params: { appName: string }) { - return get(`${application}/${params.appName}/envs`, params).then((res) => res); + return get(`${url}/${params.appName}/envs`, params).then((res) => res); } export function deleteApplicationEnvbinding(params: { appName: string; envName: string }) { - return rdelete(`${application}/${params.appName}/envs/${params.envName}`, {}).then((res) => res); + return rdelete(`${url}/${params.appName}/envs/${params.envName}`, {}).then((res) => res); } export function recycleApplicationEnvbinding(params: { appName: string; envName: string }) { - return post(`${application}/${params.appName}/envs/${params.envName}/recycle`, {}).then( - (res) => res, - ); -} - -export function getTraitDefinitions(params: { appliedWorkload: string }) { - const gurl = isMock ? `${getTraitDefinitions_mock}` : `${definition}`; - return get(gurl, { params: { type: 'trait', appliedWorkload: params.appliedWorkload } }).then( - (res) => res, - ); -} - -export function detailTraitDefinition(params: { name: string }) { - const gurl = isMock ? `${getTraitDefinitionsDetails_mock}` : `${definition}/${params.name}`; - return get(gurl, { params: { type: 'trait' } }).then((res) => res); + return post(`${url}/${params.appName}/envs/${params.envName}/recycle`, {}).then((res) => res); } export function getApplicationComponent(appName: string, componentName: string) { - const gurl = isMock - ? `${getTrait_mock}` - : `${application}/${appName}/components/${componentName}`; - return get(gurl, {}).then((res) => res); + return get(`${url}/${appName}/components/${componentName}`, {}).then((res) => res); } export function createTrait(params: Trait, query: TraitQuery) { const { appName, componentName } = query; - const gurl = isMock - ? `${getTrait_mock}` - : `${application}/${appName}/components/${componentName}/traits`; - return post(gurl, params).then((res) => res); + return post(`${url}/${appName}/components/${componentName}/traits`, params).then((res) => res); } export function updateTrait(params: Trait, query: TraitQuery) { const { appName, componentName, traitType } = query; - const gurl = isMock - ? `${getTrait_mock}` - : `${application}/${appName}/components/${componentName}/traits/${traitType}`; - return put(gurl, params).then((res) => res); + return put(`${url}/${appName}/components/${componentName}/traits/${traitType}`, params).then( + (res) => res, + ); } export function deleteTrait(query: TraitQuery) { const { appName, componentName, traitType } = query; - const gurl = isMock - ? `${getTrait_mock}` - : `${application}/${appName}/components/${componentName}/traits/${traitType}`; - return rdelete(gurl, {}).then((res) => res); + return rdelete(`${url}/${appName}/components/${componentName}/traits/${traitType}`, {}).then( + (res) => res, + ); } export function listRevisions(query: listRevisionsQuery) { const { appName } = query; - const gurl = isMock ? `${getTrait_mock}` : `${application}/${appName}/revisions`; - return get(gurl, { params: query }).then((res) => res); + return get(`${url}/${appName}/revisions`, { params: query }).then((res) => res); } export function detailRevision(query: { appName: string; revision: string }) { const { appName, revision } = query; - const gurl = isMock ? `${getTrait_mock}` : `${application}/${appName}/revisions/${revision}`; - return get(gurl, {}).then((res) => res); + return get(`${url}/${appName}/revisions/${revision}`, {}).then((res) => res); +} + +export function rollbackWithRevision(query: { appName: string; revision: string }) { + const { appName, revision } = query; + return post(`${url}/${appName}/revisions/${revision}/rollback`, {}).then((res) => res); } export function getApplicationStatistics(params: { appName: string }) { - return get(`${application}/${params.appName}/statistics`, params).then((res) => res); + return get(`${url}/${params.appName}/statistics`, params).then((res) => res); } export function getApplicationWorkflowRecord(params: { appName: string }) { - return get(`${application}/${params.appName}/records`, params).then((res) => res); + return get(`${url}/${params.appName}/records`, params).then((res) => res); } export function updateComponentProperties( params: ApplicationComponentConfig, query: { appName: string; componentName: string }, ) { - const gurl = isMock - ? `${getComponentDetails_mock}` - : `${application}/${query.appName}/components/${query.componentName}`; - return put(gurl, params).then((res) => res); + return put(`${url}/${query.appName}/components/${query.componentName}`, params).then( + (res) => res, + ); } export function resumeApplicationWorkflowRecord(params: { @@ -264,10 +184,9 @@ export function resumeApplicationWorkflowRecord(params: { recordName: string; }) { const { appName, workflowName, recordName } = params; - return get( - `${application}/${appName}/workflows/${workflowName}/records/${recordName}/resume`, - {}, - ).then((res) => res); + return get(`${url}/${appName}/workflows/${workflowName}/records/${recordName}/resume`, {}).then( + (res) => res, + ); } export function rollbackApplicationWorkflowRecord(params: { @@ -276,10 +195,9 @@ export function rollbackApplicationWorkflowRecord(params: { recordName: string; }) { const { appName, workflowName, recordName } = params; - return get( - `${application}/${appName}/workflows/${workflowName}/records/${recordName}/rollback`, - {}, - ).then((res) => res); + return get(`${url}/${appName}/workflows/${workflowName}/records/${recordName}/rollback`, {}).then( + (res) => res, + ); } export function terminateApplicationWorkflowRecord(params: { @@ -289,47 +207,41 @@ export function terminateApplicationWorkflowRecord(params: { }) { const { appName, workflowName, recordName } = params; return get( - `${application}/${appName}/workflows/${workflowName}/records/${recordName}/terminate`, + `${url}/${appName}/workflows/${workflowName}/records/${recordName}/terminate`, {}, ).then((res) => res); } export function getApplicationTriggers(params: { appName: string }) { const { appName } = params; - const gurl = isMock ? `${getTrait_mock}` : `${application}/${appName}/triggers`; - return get(gurl, {}).then((res) => res); + return get(`${url}/${appName}/triggers`, {}).then((res) => res); } export function updateApplication(params: any) { - const _url = isMock ? `${updateApplicationEnv_mock}` : `${application}/${params.name}`; - return put(_url, params).then((res) => res); + return put(`${url}/${params.name}`, params).then((res) => res); } export function createTriggers(params: Trigger, query: { appName: string }) { const { appName } = query; - const gurl = isMock ? `${getTrait_mock}` : `${application}/${appName}/triggers`; - return post(gurl, params).then((res) => res); + return post(`${url}/${appName}/triggers`, params).then((res) => res); } export function deleteTriggers(params: { appName: string; token: string }) { const { appName, token } = params; - const gurl = isMock ? `${getTrait_mock}` : `${application}/${appName}/triggers/${token}`; - return rdelete(gurl, {}).then((res) => res); + return rdelete(`${url}/${appName}/triggers/${token}`, {}).then((res) => res); } export function deleteComponent(query: { appName: string; componentName: string }) { - const gurl = isMock - ? `${getTrait_mock}` - : `${application}/${query.appName}/components/${query.componentName}`; - return rdelete(gurl, {}).then((res) => res); + return rdelete(`${url}/${query.appName}/components/${query.componentName}`, {}).then( + (res) => res, + ); } export function compareApplication(appName: string, params: ApplicationCompareRequest) { - const gurl = `${application}/${appName}/compare`; - return post(gurl, params).then((res) => res); + const _url = `${url}/${appName}/compare`; + return post(_url, params).then((res) => res); } export function dryRunApplication(appName: string, params: ApplicationDryRunRequest) { - const gurl = `${application}/${appName}/dry-run`; - return post(gurl, params, true).then((res) => res); + return post(`${url}/${appName}/dry-run`, params, true).then((res) => res); } diff --git a/src/api/definitions.ts b/src/api/definitions.ts index 060e5a5fc..d45523e11 100644 --- a/src/api/definitions.ts +++ b/src/api/definitions.ts @@ -45,3 +45,35 @@ export function updateUISchema(params: { }; return put(url, paramsData).then((res) => res); } + +export function getComponentDefinitions() { + const _url = base + definition; + return get(_url, { params: { type: 'component' } }).then((res) => res); +} + +export function detailComponentDefinition(params: { name: string }) { + const _url = `${base + definition}/${params.name}`; + return get(_url, { params: { type: 'component' } }).then((res) => res); +} + +export function getPolicyDefinitions() { + const _url = base + definition; + return get(_url, { params: { type: 'policy' } }).then((res) => res); +} + +export function detailPolicyDefinition(params: { name: string }) { + const _url = `${base + definition}/${params.name}`; + return get(_url, { params: { type: 'policy' } }).then((res) => res); +} + +export function getTraitDefinitions(params: { appliedWorkload: string }) { + const _url = base + definition; + return get(_url, { params: { type: 'trait', appliedWorkload: params.appliedWorkload } }).then( + (res) => res, + ); +} + +export function detailTraitDefinition(params: { name: string }) { + const _url = `${base + definition}/${params.name}`; + return get(_url, { params: { type: 'trait' } }).then((res) => res); +} diff --git a/src/components/ApplicationDiff/index.less b/src/components/ApplicationDiff/index.less index 6ace48c46..c955942c3 100644 --- a/src/components/ApplicationDiff/index.less +++ b/src/components/ApplicationDiff/index.less @@ -1,5 +1,5 @@ .diff-box { - max-height: 600px; + height: 600px; overflow-y: auto; background: #000; p { diff --git a/src/components/ApplicationDiff/index.tsx b/src/components/ApplicationDiff/index.tsx index e0c32d5af..6cc77b17a 100644 --- a/src/components/ApplicationDiff/index.tsx +++ b/src/components/ApplicationDiff/index.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; -import { Dialog } from '@b-design/ui'; +import { Dialog, Message } from '@b-design/ui'; import type { ApplicationCompareResponse } from '../../interface/application'; -const Convert = require('ansi-to-html'); -const convert = new Convert(); import './index.less'; +import { DiffEditor } from '../DiffEditor'; +import { If } from 'tsx-control-statements/components'; +import Translation from '../Translation'; type ApplicationDiffProps = { baseName: string; @@ -14,15 +15,8 @@ type ApplicationDiffProps = { }; export const ApplicationDiff = (props: ApplicationDiffProps) => { - const lines = props.compare.diffReport.split('\n'); - const parseToDOM = (str: string, padding: number) => { - return ( -
- ); - }; + const { baseName, targetName, compare } = props; + const container = 'revision' + baseName + targetName; return ( { title={
{' Differences between '} - {props.baseName} + {props.baseName} {' and '} - {props.targetName} + {props.targetName}
} > -
- {lines.map((line) => { - let parsed: string = line.replaceAll(' ', ' '); - parsed = convert.toHtml(parsed); - return parseToDOM(parsed.trimStart(), 0); - })} + + + There is no change + + +
+
); diff --git a/src/components/DiffEditor/index.tsx b/src/components/DiffEditor/index.tsx new file mode 100644 index 000000000..558c7f573 --- /dev/null +++ b/src/components/DiffEditor/index.tsx @@ -0,0 +1,28 @@ +import React, { useEffect } from 'react'; +import * as monaco from 'monaco-editor'; +import defineTheme from '../DefinitionCode/theme'; +export const DiffEditor = (props: { + id: string; + base: string; + target: string; + language?: string; +}) => { + const { language = 'yaml', base, target, id } = props; + useEffect(() => { + const container: any = document.getElementById(id); + if (container) { + container.innerHTML = ''; + } + if (defineTheme) { + monaco.editor.defineTheme('default', defineTheme as any); + monaco.editor.setTheme('default'); + } + const diffEditor = monaco.editor.createDiffEditor(container); + + diffEditor.setModel({ + original: monaco.editor.createModel(base, language), + modified: monaco.editor.createModel(target, language), + }); + }, [id, language, base, target]); + return <>; +}; diff --git a/src/interface/application.ts b/src/interface/application.ts index a40661837..0f6c5a013 100644 --- a/src/interface/application.ts +++ b/src/interface/application.ts @@ -100,6 +100,10 @@ export interface ApplicationDeployResponse extends ApplicationRevision { record?: WorkflowRecordBase; } +export interface ApplicationRollbackResponse { + record: WorkflowRecordBase; +} + export interface ApplicationStatus { conditions: Condition[]; status: string; diff --git a/src/model/application.js b/src/model/application.js index 39d609b33..64b75c5fc 100644 --- a/src/model/application.js +++ b/src/model/application.js @@ -6,10 +6,11 @@ import { getApplicationStatus, getApplicationComponents, getPolicyList, - getComponentDefinitions, getApplicationEnvbinding, } from '../api/application'; +import { getComponentDefinitions } from '../api/definitions'; + import { listWorkflow } from '../api/workflows'; import { getProjectList } from '../api/project'; diff --git a/src/pages/ApplicationConfig/components/ComponentDialog/index.tsx b/src/pages/ApplicationConfig/components/ComponentDialog/index.tsx index ffb788833..28b66f2d9 100644 --- a/src/pages/ApplicationConfig/components/ComponentDialog/index.tsx +++ b/src/pages/ApplicationConfig/components/ComponentDialog/index.tsx @@ -16,9 +16,9 @@ import { withTranslation } from 'react-i18next'; import { createApplicationComponent, updateComponentProperties, - detailComponentDefinition, getApplicationComponent, } from '../../../../api/application'; +import { detailComponentDefinition } from '../../../../api/definitions'; import type { DefinitionDetail, Trait, diff --git a/src/pages/ApplicationConfig/components/PolicyDialog/index.tsx b/src/pages/ApplicationConfig/components/PolicyDialog/index.tsx index 7c3a11e77..80b4ba308 100644 --- a/src/pages/ApplicationConfig/components/PolicyDialog/index.tsx +++ b/src/pages/ApplicationConfig/components/PolicyDialog/index.tsx @@ -36,12 +36,8 @@ import { If } from 'tsx-control-statements/components'; import classNames from 'classnames'; import Permission from '../../../../components/Permission'; import locale from '../../../../utils/locale'; -import { - createPolicy, - detailPolicyDefinition, - getPolicyDefinitions, - updatePolicy, -} from '../../../../api/application'; +import { createPolicy, updatePolicy } from '../../../../api/application'; +import { detailPolicyDefinition, getPolicyDefinitions } from '../../../../api/definitions'; import type { DefinitionBase } from '../../../../interface/definitions'; import { checkName } from '../../../../utils/common'; import UISchema from '../../../../components/UISchema'; diff --git a/src/pages/ApplicationConfig/components/TraitDialog/index.tsx b/src/pages/ApplicationConfig/components/TraitDialog/index.tsx index 78f5c9f06..d94e08788 100644 --- a/src/pages/ApplicationConfig/components/TraitDialog/index.tsx +++ b/src/pages/ApplicationConfig/components/TraitDialog/index.tsx @@ -4,13 +4,8 @@ import type { Rule } from '@alifd/field'; import { withTranslation } from 'react-i18next'; import Group from '../../../../extends/Group'; import { If } from 'tsx-control-statements/components'; -import { - detailTraitDefinition, - updateTrait, - createTrait, - getTraitDefinitions, - getApplicationComponent, -} from '../../../../api/application'; +import { updateTrait, createTrait, getApplicationComponent } from '../../../../api/application'; +import { detailTraitDefinition, getTraitDefinitions } from '../../../../api/definitions'; import type { ApplicationComponent, DefinitionDetail, diff --git a/src/pages/ApplicationConfig/components/TriggerDialog/index.tsx b/src/pages/ApplicationConfig/components/TriggerDialog/index.tsx index 67ea6363d..a54fe1f01 100644 --- a/src/pages/ApplicationConfig/components/TriggerDialog/index.tsx +++ b/src/pages/ApplicationConfig/components/TriggerDialog/index.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { Grid, Field, Form, Select, Message, Button, Input } from '@b-design/ui'; import { withTranslation } from 'react-i18next'; -import { createTriggers, detailComponentDefinition } from '../../../../api/application'; +import { createTriggers } from '../../../../api/application'; import { getPayloadType } from '../../../../api/payload'; +import { detailComponentDefinition } from '../../../../api/definitions'; import type { Workflow, Trigger, diff --git a/src/pages/ApplicationConfig/index.tsx b/src/pages/ApplicationConfig/index.tsx index debaaeb07..482480bb2 100644 --- a/src/pages/ApplicationConfig/index.tsx +++ b/src/pages/ApplicationConfig/index.tsx @@ -8,12 +8,12 @@ import { getApplicationTriggers, deleteTriggers, deleteComponent, - getComponentDefinitions, - deleteApplicationPlan, + deleteApplication, deletePolicy, getPolicyDetail, getApplicationStatistics, } from '../../api/application'; +import { getComponentDefinitions } from '../../api/definitions'; import Translation from '../../components/Translation'; import Title from '../../components/Title'; import { routerRedux } from 'dva/router'; @@ -387,7 +387,7 @@ class ApplicationConfig extends Component { type: 'confirm', content: Unrecoverable after deletion, are you sure to delete it?, onOk: () => { - deleteApplicationPlan({ name: appName }).then((re) => { + deleteApplication({ name: appName }).then((re) => { if (re) { Message.success('Application deleted successfully'); this.props.dispatch(routerRedux.push('/applications')); diff --git a/src/pages/ApplicationInstanceList/components/Header/index.tsx b/src/pages/ApplicationInstanceList/components/Header/index.tsx index 5b73de8a2..478240cd4 100644 --- a/src/pages/ApplicationInstanceList/components/Header/index.tsx +++ b/src/pages/ApplicationInstanceList/components/Header/index.tsx @@ -381,8 +381,8 @@ class Header extends Component { {compare && ( { this.setState({ visibleApplicationDiff: false }); diff --git a/src/pages/ApplicationList/components/AddAppDialog/index.tsx b/src/pages/ApplicationList/components/AddAppDialog/index.tsx index 6eb8927fb..510cb6f3f 100644 --- a/src/pages/ApplicationList/components/AddAppDialog/index.tsx +++ b/src/pages/ApplicationList/components/AddAppDialog/index.tsx @@ -5,7 +5,7 @@ import { Link } from 'dva/router'; import { If } from 'tsx-control-statements/components'; import GeneralConfig from '../GeneralConfig'; import type { Rule } from '@alifd/field'; -import { detailComponentDefinition, createApplication } from '../../../../api/application'; +import { createApplication } from '../../../../api/application'; import type { DefinitionDetail } from '../../../../interface/application'; import UISchema from '../../../../components/UISchema'; import DrawerWithFooter from '../../../../components/Drawer'; @@ -18,6 +18,7 @@ import type { Env } from '../../../../interface/env'; import type { Target } from '../../../../interface/target'; import EnvDialog from '../../../EnvPage/components/EnvDialog'; import type { LoginUserInfo } from '../../../../interface/user'; +import { detailComponentDefinition } from '../../../../api/definitions'; type Props = { visible: boolean; diff --git a/src/pages/ApplicationList/index.tsx b/src/pages/ApplicationList/index.tsx index 1c045a1e5..9e3283733 100644 --- a/src/pages/ApplicationList/index.tsx +++ b/src/pages/ApplicationList/index.tsx @@ -6,7 +6,8 @@ import SelectSearch from './components/SelectSearch'; import CardContend from './components/CardContent'; import AppDialog from './components/AddAppDialog'; import { If } from 'tsx-control-statements/components'; -import { deleteApplicationPlan, getComponentDefinitions } from '../../api/application'; +import { deleteApplication } from '../../api/application'; +import { getComponentDefinitions } from '../../api/definitions'; import type { ApplicationBase } from '../../interface/application'; import EditAppDialog from './components/EditAppDialog'; import type { LoginUserInfo } from '../../interface/user'; @@ -78,8 +79,8 @@ class Application extends Component { }); }; - onDeleteAppPlan = (name: string) => { - deleteApplicationPlan({ name: name }).then((re) => { + onDeleteApp = (name: string) => { + deleteApplication({ name: name }).then((re) => { if (re) { Message.success('Application deleted successfully'); this.getApplications({}); @@ -172,7 +173,7 @@ class Application extends Component { this.editAppPlan(item); }} showMode={showMode} - deleteAppPlan={this.onDeleteAppPlan} + deleteAppPlan={this.onDeleteApp} setVisible={(visible) => { this.setState({ showAddApplication: visible }); }} diff --git a/src/pages/ApplicationRevisionList/components/List/index.tsx b/src/pages/ApplicationRevisionList/components/List/index.tsx index f279d2365..0a4dae2fc 100644 --- a/src/pages/ApplicationRevisionList/components/List/index.tsx +++ b/src/pages/ApplicationRevisionList/components/List/index.tsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { Balloon, Button, Dropdown, Menu, Table } from '@b-design/ui'; +import { Balloon, Button, Dialog, Dropdown, Menu, Message, Table } from '@b-design/ui'; import Empty from '../Empty'; import Translation from '../../../../components/Translation'; import type { @@ -7,22 +7,27 @@ import type { ApplicationCompareResponse, ApplicationDetail, ApplicationRevision, + ApplicationRollbackResponse, } from '../../../../interface/application'; import { statusList } from '../../constants'; -import { momentDate } from '../../../../utils/common'; -import { Link } from 'dva/router'; +import { momentDate, showAlias } from '../../../../utils/common'; +import { Link, routerRedux } from 'dva/router'; import './index.less'; import locale from '../../../../utils/locale'; import Item from '../../../../components/Item'; -import { compareApplication } from '../../../../api/application'; +import { compareApplication, rollbackWithRevision } from '../../../../api/application'; import { If } from 'tsx-control-statements/components'; import { ApplicationDiff } from '../../../../components/ApplicationDiff'; +import Permission from '../../../../components/Permission'; +import type { Dispatch } from 'redux'; +import type { NameAlias } from '../../../../interface/env'; type Props = { list: ApplicationRevision[]; getRevisionList: () => void; applicationDetail?: ApplicationDetail; onShowAppModel: (record: ApplicationRevision) => void; + dispatch: Dispatch; }; type State = { @@ -40,8 +45,39 @@ class TableList extends Component { }; } - onRollback = (record: ApplicationRevision) => { - console.log(record); + onRollback = (record: ApplicationRevision, ok?: boolean) => { + const { applicationDetail, dispatch } = this.props; + if (record.status === 'terminated' && !ok) { + Dialog.confirm({ + type: 'confirm', + content: ( + + This revision status is terminated, are you sure to rollback to this revision? + + ), + onOk: () => { + this.onRollback(record, true); + }, + locale: locale().Dialog, + }); + return; + } + if (applicationDetail) { + rollbackWithRevision({ appName: applicationDetail?.name, revision: record.version }).then( + (res: ApplicationRollbackResponse) => { + if (res) { + Message.success('Application rollback successfully'); + if (res.record && res.record.name && dispatch) { + dispatch( + routerRedux.push( + `/applications/${applicationDetail.name}/envbinding/${record.envName}/workflow/records/${res.record.name}`, + ), + ); + } + } + }, + ); + } }; loadChanges = (revision: string, mode: 'latest' | 'cluster') => { @@ -88,6 +124,14 @@ class TableList extends Component { return {v}; }, }, + { + key: 'deployUser', + title: Deploy User, + dataIndex: 'deployUser', + cell: (v: NameAlias) => { + return showAlias(v.name, v.alias); + }, + }, { key: 'status', title: Status, @@ -99,6 +143,7 @@ class TableList extends Component {
{v === 'failure' && } {v === 'terminated' && } + {v === 'complete' && } {findObj.label}
); @@ -148,17 +193,25 @@ class TableList extends Component { cell: (v: string, i: number, record: ApplicationRevision) => { return (
- + + { + + + + + + +
); }, diff --git a/src/pages/ApplicationRevisionList/index.tsx b/src/pages/ApplicationRevisionList/index.tsx index 6620514fb..cf0de6ba2 100644 --- a/src/pages/ApplicationRevisionList/index.tsx +++ b/src/pages/ApplicationRevisionList/index.tsx @@ -14,12 +14,13 @@ import './index.less'; import locale from '../../utils/locale'; import { If } from 'tsx-control-statements/components'; import { ShowRevision } from './components/Detail'; +import type { Dispatch } from 'redux'; type Props = { revisions: []; applicationDetail?: ApplicationDetail; envbinding?: EnvBinding[]; - dispatch: ({}) => {}; + dispatch: Dispatch; match: { params: { appName: string; @@ -116,7 +117,7 @@ class ApplicationRevisionList extends React.Component { render() { const { revisionsList, showAppRevision, revision, appName } = this.state; - const { envbinding, applicationDetail } = this.props; + const { envbinding, applicationDetail, dispatch } = this.props; return (
@@ -136,6 +137,7 @@ class ApplicationRevisionList extends React.Component { list={revisionsList} onShowAppModel={this.showAppModel} getRevisionList={this.getRevisionList} + dispatch={dispatch} /> { }; render() { - const { workflow } = this.props; + const { workflow, applicationDetail } = this.props; const { statusLoading, zoom, @@ -350,6 +350,14 @@ class ApplicationWorkflowRecord extends React.Component { Mode:
+
+ Revision: + +
diff --git a/src/pages/Configs/components/CreateConfigDialog/index.tsx b/src/pages/Configs/components/CreateConfigDialog/index.tsx index cf6173cc0..2628bf97b 100644 --- a/src/pages/Configs/components/CreateConfigDialog/index.tsx +++ b/src/pages/Configs/components/CreateConfigDialog/index.tsx @@ -248,7 +248,13 @@ class CreateConfigDialog extends React.Component { ]; if (!edit) { buttons.push( - + @@ -256,7 +262,13 @@ class CreateConfigDialog extends React.Component { ); } else { buttons.push( - + diff --git a/src/pages/PipelineRunPage/components/Header/index.tsx b/src/pages/PipelineRunPage/components/Header/index.tsx index a7a831293..df0e1a7fa 100644 --- a/src/pages/PipelineRunPage/components/Header/index.tsx +++ b/src/pages/PipelineRunPage/components/Header/index.tsx @@ -105,7 +105,6 @@ class Header extends Component { }; onTerminatePipelineRun = () => { - this.setState({ terminateLoading: true }); const { pipeline, runBase, loadRunStatus } = this.props; if (!pipeline || !runBase) { return; @@ -129,7 +128,6 @@ class Header extends Component { }; onResumePipelineRun = () => { - this.setState({ terminateLoading: true }); const { pipeline, runBase, loadRunStatus } = this.props; if (!pipeline || !runBase) { return; @@ -139,7 +137,7 @@ class Header extends Component { pipelineName: runBase.pipelineName, runName: runBase?.pipelineRunName, }; - this.setState({ terminateLoading: true }); + this.setState({ resumeLoading: true }); resumePipelineRun(params) .then((re) => { if (re) { @@ -148,7 +146,7 @@ class Header extends Component { } }) .finally(() => { - this.setState({ terminateLoading: false }); + this.setState({ resumeLoading: false }); }); }; diff --git a/src/pages/ProjectApplications/index.tsx b/src/pages/ProjectApplications/index.tsx index 914653e7c..f6bf91001 100644 --- a/src/pages/ProjectApplications/index.tsx +++ b/src/pages/ProjectApplications/index.tsx @@ -3,11 +3,8 @@ import { connect } from 'dva'; import { Loading, Message } from '@b-design/ui'; import CardContend from '../ApplicationList/components/CardContent'; import type { ApplicationBase, ApplicationQuery } from '../../interface/application'; -import { - getApplicationList, - deleteApplicationPlan, - getComponentDefinitions, -} from '../../api/application'; +import { getApplicationList, deleteApplication } from '../../api/application'; +import { getComponentDefinitions } from '../../api/definitions'; import { getEnvs } from '../../api/env'; import { If } from 'tsx-control-statements/components'; import EditAppDialog from '../ApplicationList/components/EditAppDialog'; @@ -134,9 +131,9 @@ class ProjectApplications extends Component { }; onDeleteApplicationItem = (name: string) => { - deleteApplicationPlan({ name: name }).then((re) => { + deleteApplication({ name: name }).then((re) => { if (re) { - Message.success('Application delete success'); + Message.success('Application deleted successfully'); this.listApplication(); } }); diff --git a/src/pages/ProjectSummary/components/ConfigDistribution/index.tsx b/src/pages/ProjectSummary/components/ConfigDistribution/index.tsx index d279d9d48..a736e7ff2 100644 --- a/src/pages/ProjectSummary/components/ConfigDistribution/index.tsx +++ b/src/pages/ProjectSummary/components/ConfigDistribution/index.tsx @@ -119,7 +119,7 @@ class ConfigDistributionPage extends Component { record.status?.workflow?.steps?.map((step) => { if (step.name) { const target = step.name.split('-'); - if (target.length == 3 && target[0] == 'deploy') { + if (target.length >= 3 && target[0] == 'deploy') { targetStatus.set(step.name.replace('deploy-', ''), step); } } @@ -139,7 +139,7 @@ class ConfigDistributionPage extends Component { : 'yellow' } > - {t.clusterName}/{t.namespace} + {t.clusterName}/{t.namespace}/{step?.phase} ); return step?.message ? {step.message} : tag; diff --git a/src/pages/ProjectSummary/components/Configs/index.tsx b/src/pages/ProjectSummary/components/Configs/index.tsx index cc03be37a..35f31a7e6 100644 --- a/src/pages/ProjectSummary/components/Configs/index.tsx +++ b/src/pages/ProjectSummary/components/Configs/index.tsx @@ -159,7 +159,7 @@ class Configs extends Component { resource: `project:${projectName}/config:${record.name}`, action: 'delete', }} - project={''} + project={projectName} >