chore: update license to agpl

This commit is contained in:
luohoufu 2024-12-02 17:18:51 +08:00
parent 9dc4615235
commit dba375b29a
No known key found for this signature in database
GPG Key ID: 9D8E0A78772AB5A0
27 changed files with 74 additions and 894 deletions

1
web/.gitignore vendored
View File

@ -35,3 +35,4 @@ log/
.env
/web/
.github
src/common*/

View File

@ -10,6 +10,7 @@
# production
/build
/dist
# misc
.DS_Store
@ -21,5 +22,3 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/dist

View File

@ -208,10 +208,10 @@ export default class GlobalHeaderRight extends PureComponent {
</Menu.Item>
<Menu.Item key="ticket">
<a
href={`${getWebsitePathByLang()}/company/contact/`}
href={`https://github.com/infinilabs/console/issues/new`}
target="_blank"
>
<Icon type="mobile" />
<Icon type="github" />
<FormattedMessage id="menu.header.help.ticket" />
</a>
</Menu.Item>

File diff suppressed because one or more lines are too long

View File

@ -1,317 +0,0 @@
import request from "@/utils/request";
import {
Modal,
Checkbox,
Button,
Form,
Icon,
Input,
message,
Alert,
Divider,
} from "antd";
import { useEffect, useMemo, useState } from "react";
import { formatMessage, getLocale } from "umi/locale";
import { getWebsitePathByLang } from "@/utils/utils";
import "./ApplyTrial.scss";
import LicenceDesc from "./LicenceDesc";
const { TextArea } = Input;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 6,
},
},
};
const tipsFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 20,
offset: 2,
},
},
};
export default Form.create()((props) => {
const { form, onLicenceUpdate } = props;
const { getFieldDecorator } = form;
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const defaultState = {
status: -1,
error_msg: "",
licensed: false,
};
const [state, setState] = useState(defaultState);
const onSubmit = () => {
form.validateFields(async (err, values) => {
if (err) {
return false;
}
setLoading(true);
const res = await request(`/_license/request_trial?lang=${getLocale()}`, {
method: "POST",
body: values,
});
if (res?.acknowledged) {
let ack = { status: 1 };
if (res?.license) {
ack.licensed = true;
onLicenceUpdate();
}
setState({ ...state, ...ack });
} else {
let error_msg = "";
if (typeof res === "undefined") {
error_msg = "Request timeout or network problem";
} else if (res?.error?.reason) {
error_msg = res.error.reason;
}
setState({ ...state, status: 0, error_msg: error_msg });
}
setLoading(false);
});
};
const onClose = () => {
props.onClose(); //close parent modal
setVisible(false);
setState({ ...state, ...defaultState });
};
return (
<>
<Button type="primary" size="small" onClick={() => setVisible(true)}>
{formatMessage({ id: "license.button.apply_trial" })}
</Button>
<Modal
title={formatMessage({ id: "license.label.apply_trial.title" })}
visible={visible}
closable
footer={null}
onCancel={onClose}
destroyOnClose
width={560}
className={"apply-trial-modal"}
>
{state.status === -1 ? (
<Form {...formItemLayout} colon={false}>
<Form.Item {...tipsFormItemLayout}>
<div className="tips-wrap">
<Icon type="info-circle" theme="twoTone" />
<span className="tips-text">
{formatMessage({
id: "license.label.apply.trial_tips",
})}
</span>
</div>
</Form.Item>
<Form.Item
label={formatMessage({
id: "license.label.apply.organization",
})}
>
{getFieldDecorator("organization", {
initialValue: "",
rules: [
{
required: true,
message: formatMessage({
id: "license.label.apply.organization.required",
}),
},
],
})(<Input maxLength={100} />)}
</Form.Item>
<Form.Item
label={formatMessage({
id: "license.label.apply.contact",
})}
>
{getFieldDecorator("contact", {
initialValue: "",
rules: [
{
required: true,
message: formatMessage({
id: "license.label.apply.contact.required",
}),
},
],
})(<Input maxLength={50} />)}
</Form.Item>
<Form.Item
label={formatMessage({
id: "license.label.apply.email",
})}
>
{getFieldDecorator("email", {
initialValue: "",
rules: [
{
type: "email",
message: formatMessage({
id: "license.label.apply.email.valid",
}),
},
{
required: true,
message: formatMessage({
id: "license.label.apply.email.required",
}),
},
],
})(
<Input
maxLength={50}
placeholder={formatMessage({
id: "license.label.apply.email.placeholder",
})}
/>
)}
</Form.Item>
<Form.Item
label={formatMessage({
id: "license.label.apply.phone",
})}
>
{getFieldDecorator("phone", {
initialValue: "",
rules: [
{
required: true,
message: formatMessage({
id: "license.label.apply.phone.required",
}),
},
],
})(<Input maxLength={20} />)}
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" block loading={loading} onClick={onSubmit}>
{formatMessage({ id: "license.label.apply.submit" })}
</Button>
</Form.Item>
<Form.Item {...tailFormItemLayout}>
{getFieldDecorator("agreement", {
valuePropName: "checked",
rules: [
{
required: true,
message: formatMessage({
id: "license.label.agree.required",
}),
},
],
})(
<Checkbox>
{formatMessage({ id: "license.label.agree" })}{" "}
<a
target="_blank"
href={`${getWebsitePathByLang()}/agreement/console`}
>
{formatMessage({ id: "license.label.agreement" })}
</a>
</Checkbox>
)}
</Form.Item>
</Form>
) : null}
{state.status === 0 ? (
<div className="status-content">
<Icon
type="close-circle"
theme="filled"
style={{
fontSize: 48,
color: "#FF0000",
marginTop: -20,
marginBottom: 10,
}}
/>
{state.error_msg ? (
<Alert
message={"Error Message"}
description={state.error_msg}
type="error"
/>
) : null}
<div>
{formatMessage({ id: "license.label.apply.submit.failed.tips" })}
</div>
<div>
{formatMessage({
id: "license.label.apply.submit.official_website.link",
})}
<a
target="_blank"
href={`${APP_OFFICIAL_WEBSITE}/company/contact`}
>{`${APP_OFFICIAL_WEBSITE}/company/contact`}</a>
</div>
</div>
) : null}
{state.status === 1 ? (
<div className="status-content">
<Icon
type="check-circle"
theme="filled"
style={{
fontSize: 48,
color: "#1890ff",
marginTop: 0,
marginBottom: 10,
}}
/>
<div className="successfully-tips">
{formatMessage({
id: "license.label.apply.submit.successfully.tips",
})}
</div>
<div>
{state.licensed && props.licence?.license_type ? (
<>
<Divider orientation="left">
{formatMessage({
id: "license.label.apply.submit.divider",
})}
</Divider>
<div>
<LicenceDesc licence={props.licence} />
</div>
</>
) : null}
</div>
</div>
) : null}
</Modal>
</>
);
});

View File

@ -1,25 +0,0 @@
.apply-trial-modal {
.ant-modal-header {
.ant-modal-title {
text-align: center;
color: #1890ff;
}
}
.tips-wrap {
line-height: 24px;
.tips-text {
padding-left: 5px;
}
}
.status-content {
min-height: 305px;
display: flex;
align-items: center;
justify-content: center;
flex-flow: column;
gap: 15px;
.successfully-tips {
word-break: break-all;
}
}
}

View File

@ -1,20 +0,0 @@
import { Button } from "antd";
import styles from "./Buy.less";
import { formatMessage } from "umi/locale";
import ApplyTrial from "./ApplyTrial";
export default (props) => {
return APP_OFFICIAL_WEBSITE ? (
<div className={styles.buy}>
{props?.trialVisible ? <ApplyTrial {...props} /> : null}
<Button
type="primary"
size="small"
onClick={() => window.open(APP_OFFICIAL_WEBSITE)}
>
{formatMessage({ id: "license.button.buy" })}
</Button>
</div>
) : null;
};

View File

@ -1,14 +0,0 @@
.buy {
text-align: right;
margin-bottom: 16px;
display: flex;
gap: 10px;
justify-content: right;
:global {
.ant-btn {
padding: 0 15px;
}
}
}

View File

@ -1,42 +0,0 @@
import { Button, Icon, Descriptions, Result } from 'antd';
import styles from './Features.less';
import { LICENCE_ROUTES, FEATURES, checkLicenceType } from '.'
import { formatMessage } from "umi/locale";
export default ({ licence }) => {
const { license_type, expire_at } = licence;
return (
<div className={styles.features}>
<Descriptions title={formatMessage({ id: 'license.features.title' })} colon={false} column={4}>
{
FEATURES.map((item, index) => {
const isAllowed =
checkLicenceType(license_type, expire_at) ||
!item.route ||
LICENCE_ROUTES.every((r) => !r.includes(item.route))
return (
<Descriptions.Item
key={index}
className={`${styles.default} ${isAllowed ? styles.allow : ''}` }
label={''}
>
<span className={styles.icon}></span>{item.name}
</Descriptions.Item>
)
})
}
<Descriptions.Item
key={-1}
className={styles.default}
label={(
<span className={styles.icon}></span>
)}
>
{formatMessage({ id: 'license.feature.more' })}···
</Descriptions.Item>
</Descriptions>
</div>
)
}

View File

@ -1,58 +0,0 @@
.features {
margin-top: 12px;
margin-bottom: 12px;
padding: 12px;
background-color: #f7f9fc;
:global {
.ant-descriptions-title {
text-align: center;
margin-bottom: 12px;
}
.ant-descriptions-row > th, .ant-descriptions-row > td {
padding-bottom: 8px;
vertical-align: top;
.ant-descriptions-item-content {
word-break: break-all;
}
}
}
.default {
:global {
.ant-descriptions-item-content {
font-weight: 400;
font-size: 14px;
color: #bbb;
padding-right: 4px;
}
}
&.allow {
:global {
.ant-descriptions-item-content {
color: #575757;
}
}
.icon {
background-color: #27b148;
}
}
}
.icon {
width: 6px;
height: 6px;
background-color: #bbb;
display: inline-block;
border-radius: 50%;
vertical-align: 2px;
margin-right: 4px;
}
}

View File

@ -1,88 +0,0 @@
import styles from "./Licence.less";
import { Icon, Input, Button, Descriptions, message } from "antd";
import { forwardRef, useImperativeHandle, useEffect, useState } from "react";
import { DATE_FORMAT } from ".";
import moment from "moment";
import request from "@/utils/request";
import { formatMessage } from "umi/locale";
import LicenceDesc from "./LicenceDesc";
export default ({ licence, onLicenceUpdate }, ref) => {
const {
license_type,
license_id,
issue_to = "-",
issue_at,
valid_from,
expire_at,
max_nodes = "-",
} = licence || {};
const [isEdit, setIsEdit] = useState(false);
const [code, setCode] = useState();
const [loading, setLoading] = useState(false);
const onUpdate = async () => {
if (code) {
setLoading(true);
const res = await request(
"/_license/apply",
{
method: "POST",
body: { license: code },
},
undefined,
false
);
if (res?.acknowledged) {
message.success("Licence update succeeded.");
setIsEdit(false);
onLicenceUpdate();
} else {
message.error("Licence update failed.");
}
setLoading(false);
}
};
useImperativeHandle(ref, () => ({
resetCode: () => {
setIsEdit(false);
setCode();
},
}));
return (
<div className={styles.licence}>
<div className={styles.header}>
<LicenceDesc licence={licence} />
</div>
<div className={styles.licenceBox}>
{isEdit ? (
<Input.TextArea
rows={5}
value={code}
onChange={(e) => setCode(e.target.value)}
autoFocus
/>
) : (
<div className={styles.edit}>
<a onClick={() => setIsEdit(true)}>
<Icon type="edit" />
</a>
</div>
)}
</div>
<div className={styles.footer}>
<Button
loading={loading}
type="primary"
size="small"
onClick={onUpdate}
>
{formatMessage({ id: "license.button.update_license" })}
</Button>
</div>
</div>
);
};

View File

@ -1,51 +0,0 @@
.licence {
.header {
:global {
.ant-descriptions-title {
margin-bottom: 8px;
}
.ant-descriptions-item {
padding-bottom: 4px;
}
}
}
.licenceBox {
height: 133px;
background-color: #f7f9fc;
margin-top: 12px;
margin-bottom: 12px;
overflow-y: hidden;
font-weight: 400;
font-size: 14px;
color: rgba(187, 187, 187, 1);
padding: 8px;
display: flex;
justify-self: center;
align-items: center;
.edit {
width: 100%;
text-align: center;
margin-top: 4px;
:global {
.anticon {
font-size: 22px;
}
}
}
}
.footer {
text-align: right;
margin-bottom: 16px;
:global {
.ant-btn {
padding: 0 15px;
}
}
}
}

View File

@ -1,46 +0,0 @@
import { Descriptions } from "antd";
import { formatMessage } from "umi/locale";
import { DATE_FORMAT } from ".";
import moment from "moment";
export default ({ licence }) => {
const {
license_type,
license_id,
issue_to = "-",
issue_at,
valid_from,
expire_at,
max_nodes = "-",
} = licence || {};
return (
<Descriptions size="small" title="" column={1}>
<Descriptions.Item
label={formatMessage({ id: "license.label.license_type" })}
>
{license_type}
</Descriptions.Item>
<Descriptions.Item
label={formatMessage({ id: "license.label.max_nodes" })}
>
{max_nodes}
</Descriptions.Item>
<Descriptions.Item
label={formatMessage({ id: "license.label.issue_to" })}
>
{issue_to}
</Descriptions.Item>
<Descriptions.Item
label={formatMessage({ id: "license.label.issue_at" })}
>
{issue_at ? moment(issue_at).format(DATE_FORMAT) : "-"}
</Descriptions.Item>
<Descriptions.Item
label={formatMessage({ id: "license.label.expire_at" })}
>
{expire_at ? moment(expire_at).format(DATE_FORMAT) : "-"}
</Descriptions.Item>
</Descriptions>
);
};

View File

@ -1,60 +0,0 @@
import { useEffect, useMemo, useState } from "react";
import { Icon, Result } from "antd";
import moment from "moment";
import styles from "./Tips.less";
import Features from "./Features";
import Buy from "./Buy";
import { formatMessage } from "umi/locale";
import { LICENCE_ROUTES } from ".";
export default (props) => {
const licence = props.licence;
const { license_type, expire_at } = licence;
const needProLicense = LICENCE_ROUTES.some((item) =>
props.location.pathname.includes(item)
);
const renderHeader = () => {
if (moment(expire_at).diff(moment(), "seconds") < 0) {
return (
<Result
className={styles.content}
status="error"
title={formatMessage({ id: "license.tips.expired.title" })}
subTitle={formatMessage({ id: "license.tips.expired.desc" })}
icon={<Icon type="clock-circle" />}
/>
);
}
//pro Edition
if (needProLicense) {
return (
<Result
className={styles.content}
status="warning"
title={formatMessage({ id: "license.tips.pro.title" })}
subTitle={formatMessage({ id: "license.tips.pro.desc" })}
icon={<Icon type="sketch" />}
/>
);
}
return (
<Result
className={styles.content}
status="error"
title={formatMessage({ id: "license.tips.unlicensed.title" })}
subTitle={formatMessage({ id: "license.tips.unlicensed.desc" })}
icon={<Icon type="close-circle" />}
/>
);
};
return (
<div className={styles.tips}>
<div className={styles.header}>{renderHeader()}</div>
<Features licence={licence} />
<Buy trialVisible={!needProLicense} {...props} />
</div>
);
};

View File

@ -1,29 +0,0 @@
.tips {
.header {
.content {
padding: 8px 0px;
:global {
.ant-result-icon {
margin-bottom: 8px;
.anticon {
font-size: 34px;
}
}
.ant-result-title {
font-size: 18px;
color: #101010;
font-weight: 700;
margin-bottom: 4px;
}
.ant-result-subtitle {
color: #5f5f5f;
font-weight: 400;
}
}
}
}
}

View File

@ -1,10 +1,10 @@
import { Descriptions } from "antd";
import { Descriptions, Icon, Typography } from "antd";
import moment from "moment";
import styles from "./Version.less";
import { DATE_FORMAT } from ".";
import Features from "./Features";
import Buy from "./Buy";
import { formatMessage } from "umi/locale";
import AGPL from "./AGPL";
const { Paragraph, Text } = Typography;
export default ({ application, licence }) => {
const { number, build_date, build_hash } = application?.version || {};
@ -26,8 +26,29 @@ export default ({ application, licence }) => {
<Descriptions.Item label="Hash">{build_hash}</Descriptions.Item>
</Descriptions>
</div>
<Features licence={licence} />
<Buy />
<div style={{ margin: '10px 0', height: 217, overflow: 'hidden' }}>
<Icon style={{ transform: 'scale(0.6)', position: 'relative', top: -70, left: -172 }} component={AGPL}/>
</div>
<div className={styles.licence}>
<Paragraph>
Copyright (C) INFINI Labs & INFINI LIMITED.
</Paragraph>
<Paragraph>The INFINI Console is offered under the GNU Affero General Public License v3.0 and as commercial software.</Paragraph>
<Paragraph>
For commercial licensing, contact us at:
<ul>
<li>Email: hello@infini.ltd</li>
<li>Website: <a href="http://www.infinilabs.com" target="_blank">infinilabs.com</a></li>
</ul>
</Paragraph>
<Paragraph>
Open Source licensed under AGPL V3:
<br />
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
</Paragraph>
<Paragraph>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.</Paragraph>
<Paragraph>{`You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.`}</Paragraph>
</div>
</div>
);
};

View File

@ -10,4 +10,9 @@
}
}
}
.licence {
word-break: break-all;
p {
}
}
}

View File

@ -9,86 +9,26 @@ import React, {
import { Tabs, Modal } from "antd";
import styles from "./index.less";
import Version from "./Version";
import Tips from "./Tips";
import Licence from "./Licence";
import moment from "moment";
import { formatMessage } from "umi/locale";
export const DATE_FORMAT = "YYYY.MM.DD HH:mm";
export const LICENCE_ROUTES = ["/data_tools", "/alerting/channel"];
export const LICENCE_NOOPEN_ROUTES = ["/", "/overview"];
export const FEATURES = [
{ name: formatMessage({ id: "license.feature.multi_cluster_access" }) },
{ name: formatMessage({ id: "license.feature.multi_cluster_manage" }) },
{ name: formatMessage({ id: "license.feature.log_audit" }) },
{ name: formatMessage({ id: "license.feature.query_analysis" }) },
{ name: formatMessage({ id: "license.feature.visual_analysis" }) },
{ name: formatMessage({ id: "license.feature.platform_monitoring" }) },
{ name: formatMessage({ id: "license.feature.identity_control" }) },
{
name: formatMessage({ id: "license.feature.alarm_notification" }),
route: "/alerting",
},
{
name: formatMessage({ id: "license.feature.data_migration" }),
route: "/data_tools",
},
{
name: formatMessage({ id: "license.feature.data_backup" }),
route: "/data_tools",
},
{
name: formatMessage({ id: "license.feature.data_disaster_recovery" }),
route: "/data_tools",
},
];
export const checkLicenceType = (licenceType, expireAt, isProEdition) => {
if (isProEdition) {
if (
!licenceType ||
licenceType === "UnLicensed" ||
licenceType === "Free" ||
!expireAt
)
return false;
} else {
if (!licenceType || licenceType === "UnLicensed" || !expireAt) return false;
}
if (moment(expireAt).diff(moment(), "seconds") > 0) return true;
return false;
};
const tabs = [
{
key: "version",
title: formatMessage({ id: "license.tab.version.title" }),
component: Version,
},
{
key: "tips",
title: formatMessage({ id: "license.tab.tips.title" }),
component: Tips,
},
{
key: "licence",
title: formatMessage({ id: "license.tab.license.title" }),
component: Licence,
},
];
export default forwardRef((props, ref) => {
const [visible, setVisible] = useState(false);
const [isTips, setIsTips] = useState(false);
const triggerTimeRef = useRef(null);
const tabRef = useRef(null);
const {
location: { pathname },
licence: { license_type, expire_at, loading },
} = props;
useImperativeHandle(ref, () => ({
@ -96,63 +36,18 @@ export default forwardRef((props, ref) => {
close: onClose,
}));
const onOpen = (isTips) => {
const onOpen = () => {
const isFirstLogin = localStorage.getItem("first-login");
if (isFirstLogin !== "true") {
setIsTips(isTips);
setVisible(true);
}
};
const onClose = () => {
setIsTips();
setVisible();
if (tabRef.current.resetCode) tabRef.current.resetCode();
};
const checkRoutes = (license_type, expire_at, is_pro) => {
if (checkLicenceType(license_type, expire_at, is_pro)) {
return;
}
if (triggerTimeRef.current) {
const now = moment();
if (now.diff(triggerTimeRef.current, "seconds") > 60) {
//未授权时每1分钟弹窗提示
onOpen(true);
triggerTimeRef.current = now;
}
} else {
onOpen(true);
triggerTimeRef.current = moment();
}
};
useEffect(() => {
if (loading) {
return;
}
//home overview do not open license window
if (LICENCE_NOOPEN_ROUTES.includes(props.location.pathname)) {
return;
}
if (LICENCE_ROUTES.some((item) => props.location.pathname.includes(item))) {
//pro Edition
checkRoutes(license_type, expire_at, true);
} else {
//all routes checkexcept pro Edition)
checkRoutes(license_type, expire_at);
}
}, [pathname, license_type, expire_at, loading]);
const formatTabs = useMemo(() => {
return tabs.filter((item) => {
if (isTips && item.key === "version") return false;
if (!isTips && item.key === "tips") return false;
return true;
});
}, [isTips]);
return (
<Modal
visible={visible}
@ -161,10 +56,10 @@ export default forwardRef((props, ref) => {
footer={null}
onCancel={onClose}
destroyOnClose
width={560}
width={580}
>
<Tabs defaultActiveKey="version">
{formatTabs.map((item) => (
{tabs.map((item) => (
<Tabs.TabPane tab={item.title} key={item.key}>
<div className={styles.content}>
{item.component({ ...props, onClose }, tabRef)}

View File

@ -2,7 +2,7 @@
:global {
.ant-modal-body {
padding: 20px 0 0 0;
padding: 0px 0 0 0;
.ant-tabs-top-bar {
justify-content: center;

View File

@ -3,6 +3,7 @@ import { Menu, Icon } from 'antd';
import styles from './BottomMenu.less';
import Debounce from "lodash-decorators/debounce";
import Licence from "@/components/Licence";
import { formatMessage } from "umi/locale";
export default class BottomMenu extends PureComponent {
@ -23,7 +24,7 @@ export default class BottomMenu extends PureComponent {
const { theme, collapsed, global: { consoleInfo = {}, consoleLicence = {} }, onLicenceShow } = this.props;
const text = `${consoleLicence.license_type} (${consoleInfo?.application?.version?.number})`
const text = `${formatMessage({ id: "license.menu.label" })} (${consoleInfo?.application?.version?.number})`
return (
<div className={styles.bottomMenu}>

View File

@ -166,8 +166,6 @@ class BasicLayout extends React.PureComponent {
type: "global/fetchConsoleInfo",
});
this.fetchConsoleLicence();
this.renderRef = requestAnimationFrame(() => {
this.setState({
rendering: false,
@ -339,13 +337,6 @@ class BasicLayout extends React.PureComponent {
return <SettingDrawer />;
}
fetchConsoleLicence = () => {
const { dispatch } = this.props;
dispatch({
type: "global/fetchConsoleLicence",
});
};
render() {
this.init();
@ -437,7 +428,6 @@ class BasicLayout extends React.PureComponent {
version={this.props.global.consoleInfo?.application}
licence={this.props.global.consoleLicence}
location={this.props.location}
onLicenceUpdate={this.fetchConsoleLicence}
/>
</React.Fragment>
);

View File

@ -310,7 +310,7 @@ export default {
"menu.header.help.official_website": "Official website",
"menu.header.help.release_notes": "Release notes",
"menu.header.help.document": "Documentation",
"menu.header.help.ticket": "Request support",
"menu.header.help.ticket": "Report issue",
"app.message.operate.success": "Operate successfully",
"app.message.operate.failed": "Operate failure",

View File

@ -1,4 +1,5 @@
export default {
"license.menu.label": "About",
"license.tab.version.title": "Version",
"license.tab.tips.title": "License Tips",
"license.tab.license.title": "License",

View File

@ -315,7 +315,7 @@ export default {
"menu.header.help.official_website": "官方网站",
"menu.header.help.release_notes": "更新日志",
"menu.header.help.document": "产品文档",
"menu.header.help.ticket": "提交工单",
"menu.header.help.ticket": "提交问题",
"app.message.operate.success": "操作成功",
"app.message.operate.failed": "操作失败",

View File

@ -1,4 +1,5 @@
export default {
"license.menu.label": "关于",
"license.tab.version.title": "版本信息",
"license.tab.tips.title": "授权提示",
"license.tab.license.title": "授权信息",

View File

@ -2,7 +2,6 @@ import {
queryNotices,
clearNotices,
queryConsoleInfo,
queryConsoleLicence,
} from "@/services/api";
import { message } from "antd";
import { searchClusterConfig, getClusterStatus } from "@/services/cluster";
@ -291,14 +290,6 @@ export default {
payload: data,
});
},
*fetchConsoleLicence(_, { call, put }) {
const data = yield call(queryConsoleLicence);
yield put({
type: "saveConsoleLicence",
payload: data || {},
});
},
},
reducers: {

View File

@ -5,10 +5,6 @@ export async function queryConsoleInfo() {
return request("/_info");
}
export async function queryConsoleLicence() {
return request("/_license/info");
}
export async function queryProjectNotice() {
return request("/api/project/notice");
}