mirror of https://github.com/kubevela/velaux.git
Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
|
be7a7ba470 | |
|
9a30505e4e | |
|
56c4dc9ed5 | |
|
7d64df983d | |
|
430a9c36ad | |
|
d007fc3f35 | |
|
b9f1663867 | |
|
a18675b341 | |
|
e431a48460 |
|
@ -1,6 +1,7 @@
|
||||||
import { post, get, rdelete, put } from './request';
|
import { post, get, rdelete, put } from './request';
|
||||||
import { addons, addonRegistries, enabledAddon } from './productionLink';
|
import { addons, addonRegistries, enabledAddon } from './productionLink';
|
||||||
import { getDomain } from '../utils/common';
|
import { getDomain } from '../utils/common';
|
||||||
|
import type { EnableAddonRequest } from '../interface/addon';
|
||||||
|
|
||||||
const baseURLOject = getDomain();
|
const baseURLOject = getDomain();
|
||||||
const base = baseURLOject.MOCK || baseURLOject.APIBASE;
|
const base = baseURLOject.MOCK || baseURLOject.APIBASE;
|
||||||
|
@ -23,7 +24,16 @@ export function getAddonsList(params: any) {
|
||||||
|
|
||||||
export function getAddonsDetails(params: { name: string; version?: string }) {
|
export function getAddonsDetails(params: { name: string; version?: string }) {
|
||||||
const gurl = `${base + addons}/${params.name}`;
|
const gurl = `${base + addons}/${params.name}`;
|
||||||
return get(gurl, params).then((res) => res);
|
return get(
|
||||||
|
gurl,
|
||||||
|
params.version
|
||||||
|
? {
|
||||||
|
params: {
|
||||||
|
version: params.version,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
).then((res) => res);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function disableAddon(params: { name: string }) {
|
export function disableAddon(params: { name: string }) {
|
||||||
|
@ -31,12 +41,7 @@ export function disableAddon(params: { name: string }) {
|
||||||
return post(gurl, params).then((res) => res);
|
return post(gurl, params).then((res) => res);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function enableAddon(params: {
|
export function enableAddon(params: EnableAddonRequest) {
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
clusters?: string[];
|
|
||||||
properties: any;
|
|
||||||
}) {
|
|
||||||
const gurl = `${base + addons}/${params.name}/enable`;
|
const gurl = `${base + addons}/${params.name}/enable`;
|
||||||
const req: any = { args: params.properties, version: params.version };
|
const req: any = { args: params.properties, version: params.version };
|
||||||
if (params.clusters) {
|
if (params.clusters) {
|
||||||
|
@ -45,12 +50,7 @@ export function enableAddon(params: {
|
||||||
return post(gurl, req).then((res) => res);
|
return post(gurl, req).then((res) => res);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function upgradeAddon(params: {
|
export function upgradeAddon(params: EnableAddonRequest) {
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
clusters?: string[];
|
|
||||||
properties: any;
|
|
||||||
}) {
|
|
||||||
const gurl = `${base + addons}/${params.name}/update`;
|
const gurl = `${base + addons}/${params.name}/update`;
|
||||||
const req: any = { args: params.properties, version: params.version };
|
const req: any = { args: params.properties, version: params.version };
|
||||||
if (params.clusters) {
|
if (params.clusters) {
|
||||||
|
|
|
@ -470,15 +470,6 @@ a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-drawer-close {
|
|
||||||
right: 24px;
|
|
||||||
|
|
||||||
.next-drawer-close-icon.next-icon::before {
|
|
||||||
width: 16px !important;
|
|
||||||
height: 16px !important;
|
|
||||||
font-size: 16px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.next-btn.danger-btn {
|
.next-btn.danger-btn {
|
||||||
color: @dangerColor !important;
|
color: @dangerColor !important;
|
||||||
border: @dangerColor 1px solid !important;
|
border: @dangerColor 1px solid !important;
|
||||||
|
|
|
@ -8,3 +8,46 @@
|
||||||
height: 60px;
|
height: 60px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.next-drawer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.next-drawer-header {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
flex: 0;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 55px;
|
||||||
|
padding: 16px 24px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.next-drawer-body {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
margin-top: 71px;
|
||||||
|
padding: 24px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-drawer-close {
|
||||||
|
right: 26px !important;
|
||||||
|
|
||||||
|
.next-drawer-close-icon.next-icon::before {
|
||||||
|
color: #000;
|
||||||
|
font-weight: 800 !important;
|
||||||
|
font-size: 24px !important;
|
||||||
|
line-height: 24px !important;
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -288,9 +288,6 @@ class UISchema extends Component<Props, State> {
|
||||||
if (!uiSchema || enableCodeEdit) {
|
if (!uiSchema || enableCodeEdit) {
|
||||||
return this.renderCodeEdit();
|
return this.renderCodeEdit();
|
||||||
}
|
}
|
||||||
if (mode == 'edit' && value === undefined) {
|
|
||||||
return <div />;
|
|
||||||
}
|
|
||||||
let onlyShowRequired = false;
|
let onlyShowRequired = false;
|
||||||
let couldShowParamCount = 0;
|
let couldShowParamCount = 0;
|
||||||
uiSchema.map((param) => {
|
uiSchema.map((param) => {
|
||||||
|
@ -359,7 +356,7 @@ class UISchema extends Component<Props, State> {
|
||||||
if (initValue === undefined) {
|
if (initValue === undefined) {
|
||||||
initValue = param.validate?.defaultValue;
|
initValue = param.validate?.defaultValue;
|
||||||
}
|
}
|
||||||
const disableEdit = (param.validate?.immutable && this.props.mode == 'edit') || false;
|
const disableEdit = (param.validate?.immutable && mode == 'edit') || false;
|
||||||
const getGroup = (children: React.ReactNode) => {
|
const getGroup = (children: React.ReactNode) => {
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
|
|
|
@ -120,8 +120,8 @@ class Group extends React.Component<Props, State> {
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
content: (
|
content: (
|
||||||
<Translation>
|
<Translation>
|
||||||
If Switch is turned off, The configuration will be reset. Are you
|
The configuration will be reset if the switch is turned off. Are you
|
||||||
sure you want to do this?
|
sure want to do this?
|
||||||
</Translation>
|
</Translation>
|
||||||
),
|
),
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
|
|
|
@ -16,6 +16,10 @@ export interface Addon {
|
||||||
registryName?: string;
|
registryName?: string;
|
||||||
availableVersions?: string[];
|
availableVersions?: string[];
|
||||||
url?: string;
|
url?: string;
|
||||||
|
system?: {
|
||||||
|
vela?: string;
|
||||||
|
kubernetes?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddonStatus {
|
export interface AddonStatus {
|
||||||
|
@ -69,3 +73,10 @@ export interface AddonBaseStatus {
|
||||||
name: string;
|
name: string;
|
||||||
phase: 'disabled' | 'enabled' | 'enabling' | 'suspend' | 'disabling';
|
phase: 'disabled' | 'enabled' | 'enabling' | 'suspend' | 'disabling';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EnableAddonRequest {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
properties: Record<string, any>;
|
||||||
|
clusters?: string[];
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
.next-drawer-body {
|
.next-drawer-body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
background: rgb(59, 59, 59);
|
background: rgb(59, 59, 59);
|
||||||
.prepare {
|
.prepare {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -2,9 +2,10 @@ import React, { Component, Fragment } from 'react';
|
||||||
import { Grid, Form, Input, Field, Button, Message, Icon, Dialog } from '@b-design/ui';
|
import { Grid, Form, Input, Field, Button, Message, Icon, Dialog } from '@b-design/ui';
|
||||||
import { updateUser } from '../../../../api/users';
|
import { updateUser } from '../../../../api/users';
|
||||||
import type { LoginUserInfo } from '../../../../interface/user';
|
import type { LoginUserInfo } from '../../../../interface/user';
|
||||||
import { checkUserPassword, checkUserEmail } from '../../../../utils/common';
|
import { checkUserPassword } from '../../../../utils/common';
|
||||||
import Translation from '../../../../components/Translation';
|
import Translation from '../../../../components/Translation';
|
||||||
import i18n from '../../../../i18n';
|
import i18n from '../../../../i18n';
|
||||||
|
import locale from '../../../../utils/locale';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
userInfo?: LoginUserInfo;
|
userInfo?: LoginUserInfo;
|
||||||
|
@ -96,6 +97,7 @@ class EditPlatFormUserDialog extends Component<Props, State> {
|
||||||
title={this.showTitle()}
|
title={this.showTitle()}
|
||||||
style={{ width: '600px' }}
|
style={{ width: '600px' }}
|
||||||
onOk={this.onUpdateUser}
|
onOk={this.onUpdateUser}
|
||||||
|
locale={locale().Dialog}
|
||||||
footerActions={['ok']}
|
footerActions={['ok']}
|
||||||
>
|
>
|
||||||
<Form {...formItemLayout} field={this.field}>
|
<Form {...formItemLayout} field={this.field}>
|
||||||
|
@ -143,7 +145,7 @@ class EditPlatFormUserDialog extends Component<Props, State> {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
pattern: checkUserEmail,
|
format: 'email',
|
||||||
message: <Translation>Please input a valid email</Translation>,
|
message: <Translation>Please input a valid email</Translation>,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
:root {
|
||||||
|
--primary-color: #1b58f4;
|
||||||
|
--warning-color: var(--message-warning-color-icon-inline, #fac800);
|
||||||
|
}
|
||||||
@border-radius-8: 8px;
|
@border-radius-8: 8px;
|
||||||
@F7F7F7: #f7f7f7;
|
@F7F7F7: #f7f7f7;
|
||||||
@F9F8FF: #f9f8ff;
|
@F9F8FF: #f9f8ff;
|
||||||
|
|
|
@ -342,7 +342,7 @@
|
||||||
"Instructions for assessing whether the container is alive.": "容器健康状态探针",
|
"Instructions for assessing whether the container is alive.": "容器健康状态探针",
|
||||||
"Specify the annotations in the workload": "指定工作负载的注释",
|
"Specify the annotations in the workload": "指定工作负载的注释",
|
||||||
"Specify the labels in the workload": "指定工作负载的标签",
|
"Specify the labels in the workload": "指定工作负载的标签",
|
||||||
"If Switch is turned off, The configuration will be reset. Are you sure you want to do this?": "如果关闭,配置将重置。确定操作吗?",
|
"The configuration will be reset if the switch is turned off. Are you sure want to do this?": "如果关闭,配置将重置。确定操作吗?",
|
||||||
"Mount PVC type volume": "挂载 PVC 数据卷",
|
"Mount PVC type volume": "挂载 PVC 数据卷",
|
||||||
"Mount HostPath type volume": "挂载 HostPath 数据卷",
|
"Mount HostPath type volume": "挂载 HostPath 数据卷",
|
||||||
"Mount EmptyDir type volume": "挂载 EmptyDir 数据卷",
|
"Mount EmptyDir type volume": "挂载 EmptyDir 数据卷",
|
||||||
|
|
|
@ -146,7 +146,12 @@ class CardContent extends React.Component<Props, State> {
|
||||||
<Row className="content-main-btn">
|
<Row className="content-main-btn">
|
||||||
{tags?.map((tag: string) => {
|
{tags?.map((tag: string) => {
|
||||||
return (
|
return (
|
||||||
<Tag style={{ marginRight: '8px' }} color={getTagColor(tag)} key={tag}>
|
<Tag
|
||||||
|
title={tag}
|
||||||
|
style={{ marginRight: '8px' }}
|
||||||
|
color={getTagColor(tag)}
|
||||||
|
key={tag}
|
||||||
|
>
|
||||||
{tag}
|
{tag}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,13 +13,18 @@
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
ol, ul {
|
ol,
|
||||||
|
ul {
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.addon-readme li>p {
|
.addon-readme li > p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning-text {
|
||||||
|
color: var(--warning-color);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
Button,
|
Button,
|
||||||
|
@ -10,6 +10,10 @@ import {
|
||||||
Message,
|
Message,
|
||||||
Select,
|
Select,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Grid,
|
||||||
|
Dropdown,
|
||||||
|
Menu,
|
||||||
|
Icon,
|
||||||
} from '@b-design/ui';
|
} from '@b-design/ui';
|
||||||
import type { Rule } from '@alifd/field';
|
import type { Rule } from '@alifd/field';
|
||||||
import { If } from 'tsx-control-statements/components';
|
import { If } from 'tsx-control-statements/components';
|
||||||
|
@ -24,18 +28,23 @@ import ReactMarkdown from 'react-markdown';
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
import Empty from '../../../../components/Empty';
|
import Empty from '../../../../components/Empty';
|
||||||
import DrawerWithFooter from '../../../../components/Drawer';
|
import DrawerWithFooter from '../../../../components/Drawer';
|
||||||
import Group from '../../../../extends/Group';
|
|
||||||
import Translation from '../../../../components/Translation';
|
import Translation from '../../../../components/Translation';
|
||||||
import UISchema from '../../../../components/UISchema';
|
import UISchema from '../../../../components/UISchema';
|
||||||
import type { Addon, AddonStatus } from '../../../../interface/addon';
|
import type { Addon, AddonStatus, EnableAddonRequest } from '../../../../interface/addon';
|
||||||
import locale from '../../../../utils/locale';
|
import locale from '../../../../utils/locale';
|
||||||
import StatusShow from '../../../../components/StatusShow';
|
import StatusShow from '../../../../components/StatusShow';
|
||||||
import type { ApplicationStatus } from '../../../../interface/application';
|
import type { ApplicationStatus, UIParam } from '../../../../interface/application';
|
||||||
import i18n from '../../../../i18n';
|
import i18n from '../../../../i18n';
|
||||||
import type { NameAlias } from '../../../../interface/env';
|
import type { NameAlias } from '../../../../interface/env';
|
||||||
import Permission from '../../../../components/Permission';
|
import Permission from '../../../../components/Permission';
|
||||||
import 'github-markdown-css/github-markdown-light.css';
|
import 'github-markdown-css/github-markdown-light.css';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
import { Link } from 'dva/router';
|
||||||
|
import { listApplicationServiceEndpoints } from '../../../../api/observation';
|
||||||
|
import type { Endpoint } from '../../../../interface/observation';
|
||||||
|
import { getLink } from '../../../../utils/utils';
|
||||||
|
|
||||||
|
const { Col, Row } = Grid;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
addonName: string;
|
addonName: string;
|
||||||
|
@ -58,17 +67,19 @@ type State = {
|
||||||
clusters?: string[];
|
clusters?: string[];
|
||||||
allClusters?: NameAlias[];
|
allClusters?: NameAlias[];
|
||||||
enabledClusters?: string[];
|
enabledClusters?: string[];
|
||||||
|
endpoints?: Endpoint[];
|
||||||
|
propertiesMode: 'code' | 'native';
|
||||||
|
schema?: UIParam[];
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddonDetailDialog extends React.Component<Props, State> {
|
class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
timer?: number;
|
|
||||||
readonly refreshTime = 1000;
|
|
||||||
form: Field;
|
form: Field;
|
||||||
statusLoop: boolean;
|
statusLoop: boolean;
|
||||||
uiSchemaRef: React.RefObject<UISchema>;
|
uiSchemaRef: React.RefObject<UISchema>;
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
propertiesMode: 'native',
|
||||||
addonDetailInfo: {
|
addonDetailInfo: {
|
||||||
name: '',
|
name: '',
|
||||||
},
|
},
|
||||||
|
@ -86,12 +97,7 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.loadAddonDetail();
|
this.loadAddonDetail();
|
||||||
this.loadAddonStatus();
|
this.loadAddonStatus();
|
||||||
}
|
this.loadAddonEndpoints();
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this.timer) {
|
|
||||||
window.clearInterval(this.timer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAddonDetail = async () => {
|
loadAddonDetail = async () => {
|
||||||
|
@ -100,7 +106,7 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
getAddonsDetails({ name: this.props.addonName, version: version })
|
getAddonsDetails({ name: this.props.addonName, version: version })
|
||||||
.then((res: Addon) => {
|
.then((res: Addon) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.setState({ addonDetailInfo: res, loading: false });
|
this.setState({ addonDetailInfo: res, schema: res.uiSchema, loading: false });
|
||||||
if (!this.state.version && res.version) {
|
if (!this.state.version && res.version) {
|
||||||
this.setState({ version: res.version });
|
this.setState({ version: res.version });
|
||||||
}
|
}
|
||||||
|
@ -116,7 +122,7 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
getAddonsStatus({ name: this.props.addonName })
|
getAddonsStatus({ name: this.props.addonName })
|
||||||
.then((res: AddonStatus) => {
|
.then((res: AddonStatus) => {
|
||||||
if (!res) return;
|
if (!res) return;
|
||||||
if (res.phase == 'enabling' && !this.statusLoop) {
|
if ((res.phase == 'enabling' || res.phase === 'disabling') && !this.statusLoop) {
|
||||||
this.statusLoop = true;
|
this.statusLoop = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.statusLoop = false;
|
this.statusLoop = false;
|
||||||
|
@ -158,26 +164,40 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubmit = () => {
|
loadAddonEndpoints = () => {
|
||||||
const { status } = this.state;
|
// TODO: the app name and namespace should get from the api server.
|
||||||
if (status === 'enabled') {
|
const appName = 'addon-' + this.props.addonName;
|
||||||
Dialog.confirm({
|
listApplicationServiceEndpoints({
|
||||||
content:
|
appName: appName,
|
||||||
'Please make sure that the Addon is no longer in use and the related application has been recycled.',
|
appNs: 'vela-system',
|
||||||
onOk: this.disableAddon,
|
}).then((re) => {
|
||||||
locale: locale().Dialog,
|
if (re && re.endpoints) {
|
||||||
});
|
this.setState({ endpoints: re.endpoints });
|
||||||
return;
|
} else {
|
||||||
}
|
this.setState({ endpoints: [] });
|
||||||
if (status === 'disabled') {
|
}
|
||||||
this.form.validate((errors: any, values: any) => {
|
});
|
||||||
if (errors) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.enableAddon(values.properties);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onDisable = () => {
|
||||||
|
Dialog.confirm({
|
||||||
|
content:
|
||||||
|
'Please make sure that the Addon is no longer in use and the related application has been recycled.',
|
||||||
|
onOk: this.disableAddon,
|
||||||
|
locale: locale().Dialog,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
onEnable = () => {
|
||||||
|
this.form.validate((errors: any, values: any) => {
|
||||||
|
if (errors) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.enableAddon(values.properties);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onUpgrade = () => {
|
onUpgrade = () => {
|
||||||
this.form.validate((errors: any, values: any) => {
|
this.form.validate((errors: any, values: any) => {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
|
@ -195,17 +215,21 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({ upgradeLoading: true });
|
this.setState({ upgradeLoading: true });
|
||||||
upgradeAddon({
|
const params: EnableAddonRequest = {
|
||||||
name: this.props.addonName,
|
name: this.props.addonName,
|
||||||
version: this.state.version,
|
version: this.state.version,
|
||||||
clusters: this.state.clusters,
|
|
||||||
properties: values.properties,
|
properties: values.properties,
|
||||||
}).then(() => {
|
};
|
||||||
|
if (this.state.addonDetailInfo?.deployTo?.runtimeCluster) {
|
||||||
|
params.clusters = this.state.clusters;
|
||||||
|
}
|
||||||
|
upgradeAddon(params).then(() => {
|
||||||
this.loadAddonStatus();
|
this.loadAddonStatus();
|
||||||
this.setState({ upgradeLoading: false });
|
this.setState({ upgradeLoading: false });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
enableAddon = async (properties: any) => {
|
enableAddon = async (properties: any) => {
|
||||||
if (!this.state.version) {
|
if (!this.state.version) {
|
||||||
Message.warning(i18n.t('Please firstly select want to enable version'));
|
Message.warning(i18n.t('Please firstly select want to enable version'));
|
||||||
|
@ -220,12 +244,15 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
this.setState({ statusLoading: true }, () => {
|
this.setState({ statusLoading: true }, () => {
|
||||||
if (this.state.version) {
|
if (this.state.version) {
|
||||||
enableAddon({
|
const params: EnableAddonRequest = {
|
||||||
name: this.props.addonName,
|
name: this.props.addonName,
|
||||||
version: this.state.version,
|
version: this.state.version,
|
||||||
clusters: this.state.clusters,
|
|
||||||
properties: properties,
|
properties: properties,
|
||||||
}).then(() => {
|
};
|
||||||
|
if (this.state.addonDetailInfo?.deployTo?.runtimeCluster) {
|
||||||
|
params.clusters = this.state.clusters;
|
||||||
|
}
|
||||||
|
enableAddon(params).then(() => {
|
||||||
this.loadAddonStatus();
|
this.loadAddonStatus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -253,7 +280,9 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
changeVersion = (version: string) => {
|
changeVersion = (version: string) => {
|
||||||
this.setState({ version: version }, () => {
|
this.setState({ version: version }, () => {
|
||||||
this.loadAddonDetail();
|
this.setState({ schema: undefined }, () => {
|
||||||
|
this.loadAddonDetail();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,6 +307,9 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
clusters,
|
clusters,
|
||||||
allClusters,
|
allClusters,
|
||||||
enabledClusters,
|
enabledClusters,
|
||||||
|
endpoints,
|
||||||
|
propertiesMode,
|
||||||
|
schema,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { showAddon, addonName } = this.props;
|
const { showAddon, addonName } = this.props;
|
||||||
const validator = (rule: Rule, value: any, callback: (error?: string) => void) => {
|
const validator = (rule: Rule, value: any, callback: (error?: string) => void) => {
|
||||||
|
@ -293,32 +325,30 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
item.uiType = 'Password';
|
item.uiType = 'Password';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const buttons = [
|
const buttons = [];
|
||||||
<Fragment>
|
if (status === 'enabled' || status === 'enabling' || status === 'disabling') {
|
||||||
<Button type="secondary" onClick={this.onClose} style={{ marginRight: '16px' }}>
|
buttons.push(
|
||||||
<Translation>Cancel</Translation>
|
|
||||||
</Button>
|
|
||||||
<Permission
|
<Permission
|
||||||
request={{
|
request={{
|
||||||
resource: `addon:${addonName}`,
|
resource: `addon:${addonName}`,
|
||||||
action: status === 'enabled' ? 'disable' : 'enable',
|
action: 'disable',
|
||||||
}}
|
}}
|
||||||
project={''}
|
project={''}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="secondary"
|
||||||
onClick={this.handleSubmit}
|
onClick={this.onDisable}
|
||||||
warning={status === 'enabled'}
|
|
||||||
title={status}
|
title={status}
|
||||||
style={{ backgroundColor: status === 'enabled' ? 'red' : '' }}
|
className="danger-btn"
|
||||||
loading={statusLoading || loading || status == 'enabling' || status == 'disabling'}
|
loading={status === 'disabling'}
|
||||||
disabled={status == 'enabling' || status == 'disabling' || version == ''}
|
disabled={status === 'disabling'}
|
||||||
>
|
>
|
||||||
<Translation>{status === 'enabled' ? 'Disable' : 'Enable'}</Translation>
|
<Translation>Disable</Translation>
|
||||||
</Button>
|
</Button>
|
||||||
</Permission>
|
</Permission>,
|
||||||
</Fragment>,
|
);
|
||||||
];
|
}
|
||||||
|
|
||||||
if (status == 'enabled' || status == 'suspend') {
|
if (status == 'enabled' || status == 'suspend') {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
<Permission request={{ resource: `addon:${addonName}`, action: 'update' }} project={''}>
|
<Permission request={{ resource: `addon:${addonName}`, action: 'update' }} project={''}>
|
||||||
|
@ -334,6 +364,21 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status === 'disabled' || status === 'enabling') {
|
||||||
|
buttons.push(
|
||||||
|
<Permission request={{ resource: `addon:${addonName}`, action: 'enable' }} project={''}>
|
||||||
|
<Button
|
||||||
|
loading={status === 'enabling'}
|
||||||
|
type="primary"
|
||||||
|
onClick={this.onEnable}
|
||||||
|
style={{ marginLeft: '16px' }}
|
||||||
|
>
|
||||||
|
<Translation>Enable</Translation>
|
||||||
|
</Button>
|
||||||
|
</Permission>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const getAppStatusShowType = (statusInfo: string | undefined) => {
|
const getAppStatusShowType = (statusInfo: string | undefined) => {
|
||||||
if (!statusInfo) {
|
if (!statusInfo) {
|
||||||
return 'notice';
|
return 'notice';
|
||||||
|
@ -364,6 +409,8 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const outerEndpoint = endpoints?.filter((end) => !end.endpoint.inner);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="basic">
|
<div className="basic">
|
||||||
<DrawerWithFooter
|
<DrawerWithFooter
|
||||||
|
@ -383,16 +430,52 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<If condition={addonsStatus && addonsStatus.status}>
|
<If condition={addonsStatus && addonsStatus.status}>
|
||||||
<Message
|
<Row>
|
||||||
type={getAppStatusShowType(addonsStatus?.status)}
|
<Col span={16}>
|
||||||
size="medium"
|
<Message
|
||||||
style={{ padding: '8px', marginBottom: '10px' }}
|
type={getAppStatusShowType(addonsStatus?.status)}
|
||||||
>
|
size="medium"
|
||||||
{`${i18n.t('Addon status is ')}${addonsStatus?.status || 'Initing'}`}
|
style={{ padding: '8px', marginBottom: '10px' }}
|
||||||
<a style={{ marginLeft: '16px' }} onClick={() => this.updateStatusShow(true)}>
|
>
|
||||||
<Translation>Check the details</Translation>
|
{`${i18n.t('Addon status is ')}${addonsStatus?.status || 'Init'}`}
|
||||||
</a>
|
<Link
|
||||||
</Message>
|
style={{ marginLeft: '16px' }}
|
||||||
|
to={`/applications/addon-${addonDetailInfo?.name}`}
|
||||||
|
>
|
||||||
|
<Translation>Check the details</Translation>
|
||||||
|
</Link>
|
||||||
|
</Message>
|
||||||
|
</Col>
|
||||||
|
<If condition={outerEndpoint && outerEndpoint?.length > 0}>
|
||||||
|
<Col span={8} className={'flexright'}>
|
||||||
|
<Dropdown
|
||||||
|
trigger={
|
||||||
|
<Button style={{ marginLeft: '16px' }} type="secondary">
|
||||||
|
<Translation>Endpoints</Translation>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Menu>
|
||||||
|
{outerEndpoint?.map((item) => {
|
||||||
|
const linkURL = getLink(item);
|
||||||
|
return (
|
||||||
|
<Menu.Item key={linkURL}>
|
||||||
|
<a
|
||||||
|
style={{ color: '#1b58f4' }}
|
||||||
|
target="_blank"
|
||||||
|
href={linkURL}
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{linkURL}
|
||||||
|
</a>
|
||||||
|
</Menu.Item>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Menu>
|
||||||
|
</Dropdown>
|
||||||
|
</Col>
|
||||||
|
</If>
|
||||||
|
</Row>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
{/* select the addon version */}
|
{/* select the addon version */}
|
||||||
|
@ -405,6 +488,18 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
value={version}
|
value={version}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{addonDetailInfo?.system && (
|
||||||
|
<span className="warning-text">
|
||||||
|
This version requirements: (
|
||||||
|
{addonDetailInfo?.system.vela
|
||||||
|
? `KubeVela: ${addonDetailInfo?.system.vela}`
|
||||||
|
: ''}
|
||||||
|
{addonDetailInfo?.system.kubernetes
|
||||||
|
? ` Kubernetes: ${addonDetailInfo?.system.kubernetes}`
|
||||||
|
: ''}
|
||||||
|
)
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
<If condition={addonDetailInfo?.deployTo?.runtimeCluster}>
|
<If condition={addonDetailInfo?.deployTo?.runtimeCluster}>
|
||||||
|
@ -419,34 +514,69 @@ class AddonDetailDialog extends React.Component<Props, State> {
|
||||||
</If>
|
</If>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<If condition={addonDetailInfo?.uiSchema}>
|
<If condition={schema}>
|
||||||
<Group
|
<Card
|
||||||
title={<Translation>Properties</Translation>}
|
contentHeight={'auto'}
|
||||||
description={<Translation>Set the addon configuration parameters</Translation>}
|
className="withActions"
|
||||||
required={true}
|
title="Properties"
|
||||||
closed={status === 'enabled'}
|
subTitle={
|
||||||
alwaysShow={true}
|
schema
|
||||||
disableAddon={true}
|
? [
|
||||||
hasToggleIcon={true}
|
<Button
|
||||||
|
style={{ marginTop: '-12px' }}
|
||||||
|
onClick={() => {
|
||||||
|
if (propertiesMode === 'native') {
|
||||||
|
this.setState({ propertiesMode: 'code' });
|
||||||
|
} else {
|
||||||
|
this.setState({ propertiesMode: 'native' });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<If condition={propertiesMode === 'native'}>
|
||||||
|
<Icon
|
||||||
|
style={{ color: '#1b58f4' }}
|
||||||
|
type={'display-code'}
|
||||||
|
title={'Switch to the coding mode'}
|
||||||
|
/>
|
||||||
|
</If>
|
||||||
|
<If condition={propertiesMode === 'code'}>
|
||||||
|
<Icon
|
||||||
|
style={{ color: '#1b58f4' }}
|
||||||
|
type={'laptop'}
|
||||||
|
title={'Switch to the native mode'}
|
||||||
|
/>
|
||||||
|
</If>
|
||||||
|
</Button>,
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Form field={this.form}>
|
<Row>
|
||||||
{this.state.mode && (
|
<If condition={schema}>
|
||||||
<UISchema
|
{this.state.mode && (
|
||||||
{...this.form.init('properties', {
|
<UISchema
|
||||||
rules: [
|
{...this.form.init(`properties`, {
|
||||||
{
|
rules: [
|
||||||
validator: validator,
|
{
|
||||||
message: 'Please check addon properties',
|
validator: validator,
|
||||||
},
|
message: i18n.t('Please check the addon properties'),
|
||||||
],
|
},
|
||||||
})}
|
],
|
||||||
ref={this.uiSchemaRef}
|
})}
|
||||||
uiSchema={addonDetailInfo?.uiSchema}
|
enableCodeEdit={propertiesMode === 'code'}
|
||||||
mode={this.state.mode}
|
uiSchema={schema}
|
||||||
/>
|
definition={{
|
||||||
)}
|
name: addonDetailInfo?.name || '',
|
||||||
</Form>
|
type: 'addon',
|
||||||
</Group>
|
description: addonDetailInfo?.description || '',
|
||||||
|
}}
|
||||||
|
ref={this.uiSchemaRef}
|
||||||
|
mode={this.state.mode}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</If>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
</If>
|
</If>
|
||||||
<If condition={addonDetailInfo?.dependencies}>
|
<If condition={addonDetailInfo?.dependencies}>
|
||||||
<Card
|
<Card
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
Divider,
|
|
||||||
Icon,
|
Icon,
|
||||||
Card,
|
Card,
|
||||||
Loading,
|
Loading,
|
||||||
|
@ -246,14 +245,12 @@ class ComponentDialog extends React.Component<Props, State> {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<span>{alias ? `${alias}(${name})` : name}</span>
|
<span>{alias ? `${alias}(${name})` : name}</span>
|
||||||
<Divider />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<span>{i18n.t('New Component')} </span>
|
<span>{i18n.t('New Component')} </span>
|
||||||
<Divider />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,12 @@ class Header extends Component<Props, State> {
|
||||||
if (item && !item.endpoint.inner) {
|
if (item && !item.endpoint.inner) {
|
||||||
return (
|
return (
|
||||||
<Menu.Item key={linkURL}>
|
<Menu.Item key={linkURL}>
|
||||||
<a style={{ color: '#1b58f4' }} target="_blank" href={linkURL}>
|
<a
|
||||||
|
style={{ color: '#1b58f4' }}
|
||||||
|
target="_blank"
|
||||||
|
href={linkURL}
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
{linkURL}
|
{linkURL}
|
||||||
</a>
|
</a>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
|
|
@ -71,8 +71,8 @@ class PodDetail extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onOpenCloudShell = () => {
|
onOpenCloudShell = (containerName: string) => {
|
||||||
const { env } = this.props;
|
const { env, pod } = this.props;
|
||||||
if (!checkEnabledAddon('cloudshell', this.props.enabledAddons)) {
|
if (!checkEnabledAddon('cloudshell', this.props.enabledAddons)) {
|
||||||
Dialog.alert({
|
Dialog.alert({
|
||||||
title: i18n.t('CloudShell feature is not enabled'),
|
title: i18n.t('CloudShell feature is not enabled'),
|
||||||
|
@ -97,13 +97,15 @@ class PodDetail extends React.Component<Props, State> {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const shellScript = `vela exec ${env?.appDeployName} -e ${env?.appDeployNamespace} -- bash`;
|
const shellScript = `vela exec ${env?.appDeployName} -n ${env?.appDeployNamespace} --component ${pod.component} --cluster ${pod.cluster} --pod ${pod.metadata.name} --container ${containerName} -- bash`;
|
||||||
Dialog.show({
|
Dialog.show({
|
||||||
footer: false,
|
footer: false,
|
||||||
style: { width: 400 },
|
style: { width: 600 },
|
||||||
content: (
|
content: (
|
||||||
<div>
|
<div>
|
||||||
<h5>1. Copy the command:</h5>
|
<h5>
|
||||||
|
1. <Translation>Copy the command</Translation>:
|
||||||
|
</h5>
|
||||||
<code className="code">
|
<code className="code">
|
||||||
{shellScript}{' '}
|
{shellScript}{' '}
|
||||||
<CopyToClipboard
|
<CopyToClipboard
|
||||||
|
@ -115,7 +117,9 @@ class PodDetail extends React.Component<Props, State> {
|
||||||
<AiOutlineCopy size={14} />
|
<AiOutlineCopy size={14} />
|
||||||
</CopyToClipboard>
|
</CopyToClipboard>
|
||||||
</code>
|
</code>
|
||||||
<h5>2. Open Cloud Shell:</h5>
|
<h5>
|
||||||
|
2. <Translation>Open Cloud Shell</Translation>:
|
||||||
|
</h5>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -128,7 +132,7 @@ class PodDetail extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Open Cloud Shell
|
<Translation>Open Cloud Shell</Translation>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -264,7 +268,7 @@ class PodDetail extends React.Component<Props, State> {
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
title="Console Shell"
|
title="Console Shell"
|
||||||
onClick={() => this.onOpenCloudShell()}
|
onClick={() => this.onOpenCloudShell(record.name)}
|
||||||
className="actionIcon"
|
className="actionIcon"
|
||||||
>
|
>
|
||||||
<AiOutlineCode size={20} />
|
<AiOutlineCode size={20} />
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const ShowRevision = (props: RevisionProps) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
loadRevisionDetail(props.appName, props.revision, setDetail);
|
loadRevisionDetail(props.appName, props.revision, setDetail);
|
||||||
}, [props.appName, props.revision]);
|
}, [props.appName, props.revision]);
|
||||||
const containerId = props.revision.version;
|
const containerId = props.revision.version + 'detail';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default class CallBackPage extends React.Component<Props> {
|
||||||
if (res && res.accessToken) {
|
if (res && res.accessToken) {
|
||||||
localStorage.setItem('token', res.accessToken);
|
localStorage.setItem('token', res.accessToken);
|
||||||
localStorage.setItem('refreshToken', res.refreshToken);
|
localStorage.setItem('refreshToken', res.refreshToken);
|
||||||
this.props.history.push('/');
|
this.props.history.push('/applications');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.dialog-cluoudService-wraper {
|
.dialog-cloudService-wrapper {
|
||||||
width: 1000px;
|
width: 1000px;
|
||||||
.cloud-server-wraper {
|
.cloud-server-wrapper {
|
||||||
.next-select-trigger {
|
.next-select-trigger {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,7 +271,7 @@ class CloudServiceDialog extends React.Component<Props, State> {
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Dialog
|
<Dialog
|
||||||
locale={locale().Dialog}
|
locale={locale().Dialog}
|
||||||
className="dialog-cluoudService-wraper"
|
className="dialog-cloudService-wrapper"
|
||||||
title={<Translation>Connect Kubernetes Cluster From Cloud</Translation>}
|
title={<Translation>Connect Kubernetes Cluster From Cloud</Translation>}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
@ -294,7 +294,7 @@ class CloudServiceDialog extends React.Component<Props, State> {
|
||||||
available permission set
|
available permission set
|
||||||
</Translation>
|
</Translation>
|
||||||
</Message>
|
</Message>
|
||||||
<Form {...formItemLayout} field={this.field} className="cloud-server-wraper">
|
<Form {...formItemLayout} field={this.field} className="cloud-server-wrapper">
|
||||||
<FormItem label={<Translation>Provider</Translation>} required={true}>
|
<FormItem label={<Translation>Provider</Translation>} required={true}>
|
||||||
<Select
|
<Select
|
||||||
locale={locale().Select}
|
locale={locale().Select}
|
||||||
|
|
|
@ -25,7 +25,7 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
dexConfig: DexConfig;
|
dexConfig?: DexConfig;
|
||||||
loginType: string;
|
loginType: string;
|
||||||
loginErrorMessage: string;
|
loginErrorMessage: string;
|
||||||
loginLoading: boolean;
|
loginLoading: boolean;
|
||||||
|
@ -36,19 +36,12 @@ export default class LoginPage extends Component<Props, State> {
|
||||||
super(props);
|
super(props);
|
||||||
this.field = new Field(this);
|
this.field = new Field(this);
|
||||||
this.state = {
|
this.state = {
|
||||||
dexConfig: {
|
|
||||||
clientID: '',
|
|
||||||
clientSecret: '',
|
|
||||||
issuer: '',
|
|
||||||
redirectURL: '',
|
|
||||||
},
|
|
||||||
loginType: '',
|
loginType: '',
|
||||||
loginErrorMessage: '',
|
loginErrorMessage: '',
|
||||||
loginLoading: false,
|
loginLoading: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.ontDexConfig();
|
|
||||||
this.onGetLoginType();
|
this.onGetLoginType();
|
||||||
}
|
}
|
||||||
onGetLoginType = () => {
|
onGetLoginType = () => {
|
||||||
|
@ -62,7 +55,7 @@ export default class LoginPage extends Component<Props, State> {
|
||||||
() => {
|
() => {
|
||||||
const { loginType } = this.state;
|
const { loginType } = this.state;
|
||||||
if (loginType === 'dex') {
|
if (loginType === 'dex') {
|
||||||
this.onGetDexCode();
|
this.ontDexConfig();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -74,9 +67,14 @@ export default class LoginPage extends Component<Props, State> {
|
||||||
getDexConfig()
|
getDexConfig()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.setState({
|
this.setState(
|
||||||
dexConfig: res,
|
{
|
||||||
});
|
dexConfig: res,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.onGetDexCode();
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch();
|
.catch();
|
||||||
|
@ -116,10 +114,12 @@ export default class LoginPage extends Component<Props, State> {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
onGetDexCode = () => {
|
onGetDexCode = () => {
|
||||||
const { clientID, issuer, redirectURL } = this.state.dexConfig;
|
if (this.state.dexConfig) {
|
||||||
const newRedirectURl = encodeURIComponent(redirectURL);
|
const { clientID, issuer, redirectURL } = this.state.dexConfig;
|
||||||
const dexClientURL = `${issuer}/auth?client_id=${clientID}&redirect_uri=${newRedirectURl}&response_type=code&scope=openid+profile+email+offline_access&state=velaux`;
|
const newRedirectURl = encodeURIComponent(redirectURL);
|
||||||
window.location.href = dexClientURL;
|
const dexClientURL = `${issuer}/auth?client_id=${clientID}&redirect_uri=${newRedirectURl}&response_type=code&scope=openid+profile+email+offline_access&state=velaux`;
|
||||||
|
window.location.href = dexClientURL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
render() {
|
render() {
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Group from '../../extends/Group';
|
|
||||||
export default function NotFound() {
|
export default function NotFound() {
|
||||||
return (
|
return <div>The route is not exist(404)</div>;
|
||||||
<div>
|
|
||||||
<Group title="envplan" description="envplan" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Grid, Form, Input, Field, Button, Message, Select } from '@b-design/ui';
|
import { Grid, Form, Input, Field, Button, Message, Select } from '@b-design/ui';
|
||||||
import DrawerWithFooter from '../../../../components/Drawer';
|
import DrawerWithFooter from '../../../../components/Drawer';
|
||||||
import { checkUserPassword, checkUserEmail } from '../../../../utils/common';
|
import { checkUserPassword } from '../../../../utils/common';
|
||||||
import Translation from '../../../../components/Translation';
|
import Translation from '../../../../components/Translation';
|
||||||
import { createUser, updateUser } from '../../../../api/users';
|
import { createUser, updateUser } from '../../../../api/users';
|
||||||
import { checkName } from '../../../../utils/common';
|
import { checkName } from '../../../../utils/common';
|
||||||
|
@ -231,7 +231,7 @@ class CreateUser extends React.Component<Props, State> {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
pattern: checkUserEmail,
|
format: 'email',
|
||||||
message: <Translation>Please input a valid email</Translation>,
|
message: <Translation>Please input a valid email</Translation>,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -203,7 +203,6 @@ export const replaceUrl = function (text: string) {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkUserPassword = /^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]{8,16})$/;
|
export const checkUserPassword = /^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]{8,16})$/;
|
||||||
export const checkUserEmail = /^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$/;
|
|
||||||
|
|
||||||
export function isMatchBusinessCode(businessCode: number) {
|
export function isMatchBusinessCode(businessCode: number) {
|
||||||
const tokenExpiredList = [12002, 12010];
|
const tokenExpiredList = [12002, 12010];
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Dialog } from '@b-design/ui';
|
import { Dialog } from '@b-design/ui';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
|
import locale from './locale';
|
||||||
|
|
||||||
class ResetLogin {
|
class ResetLogin {
|
||||||
private static singleton: ResetLogin;
|
private static singleton: ResetLogin;
|
||||||
|
@ -14,6 +15,7 @@ class ResetLogin {
|
||||||
content: i18n.t('Authentication failed, please log in again'),
|
content: i18n.t('Authentication failed, please log in again'),
|
||||||
closeable: true,
|
closeable: true,
|
||||||
closeMode: [],
|
closeMode: [],
|
||||||
|
locale: locale().Dialog,
|
||||||
footerActions: ['ok'],
|
footerActions: ['ok'],
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
|
|
|
@ -110,6 +110,13 @@ export function getLink(endpointObj: Endpoint) {
|
||||||
if (appProtocol && appProtocol !== '') {
|
if (appProtocol && appProtocol !== '') {
|
||||||
protocol = appProtocol;
|
protocol = appProtocol;
|
||||||
}
|
}
|
||||||
|
// Support to open this address in a new window directly.
|
||||||
|
if (protocol == 'tcp') {
|
||||||
|
protocol = 'http';
|
||||||
|
}
|
||||||
|
if (host == '') {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
if (path === '/') {
|
if (path === '/') {
|
||||||
path = '';
|
path = '';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue