mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'migration' into 'master'
Migrate APPM Store UI from antd v3 to v4 Closes product-iots#579 See merge request entgra/carbon-device-mgt!585
This commit is contained in:
commit
21010b7996
@ -11,7 +11,7 @@
|
||||
"license": "Apache License 2.0",
|
||||
"dependencies": {
|
||||
"acorn": "^6.2.0",
|
||||
"antd": "^3.23.6",
|
||||
"antd": "^4.0.0",
|
||||
"axios": "^0.18.1",
|
||||
"babel-eslint": "^9.0.0",
|
||||
"d3": "^5.9.7",
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Menu, Icon } from 'antd';
|
||||
import { LogoutOutlined } from '@ant-design/icons';
|
||||
import { Menu } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { withConfigContext } from '../../../../components/context/ConfigContext';
|
||||
import { handleApiError } from '../../../../services/utils/errorHandler';
|
||||
@ -64,7 +65,7 @@ class Logout extends React.Component {
|
||||
return (
|
||||
<Menu>
|
||||
<Menu.Item key="1" onClick={this.handleSubmit}>
|
||||
<Icon type="logout" />
|
||||
<LogoutOutlined />
|
||||
Logout
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
|
||||
@ -17,7 +17,17 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Layout, Menu, Icon, Drawer, Button, Alert } from 'antd';
|
||||
import {
|
||||
UploadOutlined,
|
||||
UserOutlined,
|
||||
AndroidFilled,
|
||||
AppleFilled,
|
||||
WindowsFilled,
|
||||
HddFilled,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Layout, Menu, Drawer, Button, Alert } from 'antd';
|
||||
|
||||
const { Header, Content, Footer } = Layout;
|
||||
import { Link } from 'react-router-dom';
|
||||
@ -112,23 +122,27 @@ class Dashboard extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const config = this.props.context;
|
||||
const { selectedKeys, deviceTypes, forbiddenErrors } = this.state;
|
||||
|
||||
const DeviceTypesData = deviceTypes.map(deviceType => {
|
||||
const platform = deviceType.name;
|
||||
const defaultPlatformIcons = config.defaultPlatformIcons;
|
||||
let icon = defaultPlatformIcons.default.icon;
|
||||
let theme = defaultPlatformIcons.default.theme;
|
||||
if (defaultPlatformIcons.hasOwnProperty(platform)) {
|
||||
icon = defaultPlatformIcons[platform].icon;
|
||||
theme = defaultPlatformIcons[platform].theme;
|
||||
let icon;
|
||||
switch (deviceType.name) {
|
||||
case 'android':
|
||||
icon = <AndroidFilled />;
|
||||
break;
|
||||
case 'ios':
|
||||
icon = <AppleFilled />;
|
||||
break;
|
||||
case 'windows':
|
||||
icon = <WindowsFilled />;
|
||||
break;
|
||||
default:
|
||||
icon = <HddFilled />;
|
||||
}
|
||||
return (
|
||||
<Menu.Item key={platform}>
|
||||
<Link to={'/store/' + platform}>
|
||||
<Icon type={icon} theme={theme} />
|
||||
{platform}
|
||||
<Menu.Item key={deviceType.name}>
|
||||
<Link to={'/store/' + deviceType.name}>
|
||||
{icon}
|
||||
{deviceType.name}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
);
|
||||
@ -161,7 +175,7 @@ class Dashboard extends React.Component {
|
||||
|
||||
<Menu.Item key="web-clip">
|
||||
<Link to="/store/web-clip">
|
||||
<Icon type="upload" />
|
||||
<UploadOutlined />
|
||||
Web Clips
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
@ -170,7 +184,7 @@ class Dashboard extends React.Component {
|
||||
className="profile"
|
||||
title={
|
||||
<span className="submenu-title-wrapper">
|
||||
<Icon type="user" />
|
||||
<UserOutlined />
|
||||
{this.config.user.username}
|
||||
</span>
|
||||
}
|
||||
@ -185,10 +199,11 @@ class Dashboard extends React.Component {
|
||||
<Layout className="mobile-layout">
|
||||
<div className="mobile-menu-button">
|
||||
<Button type="link" onClick={this.showMobileNavigationBar}>
|
||||
<Icon
|
||||
type={this.state.collapsed ? 'menu-fold' : 'menu-unfold'}
|
||||
className="bar-icon"
|
||||
/>
|
||||
{this.state.collapsed ? (
|
||||
<MenuFoldOutlined />
|
||||
) : (
|
||||
<MenuUnfoldOutlined />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</Layout>
|
||||
@ -221,7 +236,7 @@ class Dashboard extends React.Component {
|
||||
|
||||
<Menu.Item key="web-clip">
|
||||
<Link to="/store/web-clip">
|
||||
<Icon type="upload" />
|
||||
<UploadOutlined />
|
||||
Web Clips
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
@ -236,7 +251,7 @@ class Dashboard extends React.Component {
|
||||
<SubMenu
|
||||
title={
|
||||
<span className="submenu-title-wrapper">
|
||||
<Icon type="user" />
|
||||
<UserOutlined />
|
||||
</span>
|
||||
}
|
||||
>
|
||||
|
||||
@ -143,11 +143,13 @@ class AppList extends React.Component {
|
||||
>
|
||||
<Row gutter={16}>
|
||||
{apps.length === 0 && (
|
||||
<Result
|
||||
status="404"
|
||||
title="No apps, yet."
|
||||
subTitle="No apps available, yet! When the administration uploads, apps will show up here."
|
||||
/>
|
||||
<Col span={24}>
|
||||
<Result
|
||||
status="404"
|
||||
title="No apps, yet."
|
||||
subTitle="No apps available, yet! When the administration uploads, apps will show up here."
|
||||
/>
|
||||
</Col>
|
||||
)}
|
||||
{apps.map(app => (
|
||||
<Col key={app.id} xs={12} sm={6} md={6} lg={4} xl={3}>
|
||||
|
||||
@ -17,10 +17,10 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { StarOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Drawer,
|
||||
Button,
|
||||
Icon,
|
||||
Row,
|
||||
Col,
|
||||
Typography,
|
||||
@ -127,7 +127,7 @@ class AddReview extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<Button type="primary" onClick={this.showDrawer}>
|
||||
<Icon type="star" /> Add a review
|
||||
<StarOutlined /> Add a review
|
||||
</Button>
|
||||
|
||||
<Drawer
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Row, Typography, Icon } from 'antd';
|
||||
import { TeamOutlined } from '@ant-design/icons';
|
||||
import { Row, Typography } from 'antd';
|
||||
import StarRatings from 'react-star-ratings';
|
||||
import './styles.css';
|
||||
import { withConfigContext } from '../../../../../../../../../../../../../../components/context/ConfigContext';
|
||||
@ -67,7 +68,7 @@ class Rating extends React.Component {
|
||||
/>
|
||||
<br />
|
||||
<Text type="secondary" className="people-count">
|
||||
<Icon type="team" /> {totalCount} total
|
||||
<TeamOutlined /> {totalCount} total
|
||||
</Text>
|
||||
</div>
|
||||
<div className="bar-containers">
|
||||
|
||||
@ -170,7 +170,7 @@ class Review extends React.Component {
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ width: '100%' }}>
|
||||
<List.Item.Meta
|
||||
avatar={
|
||||
<Avatar
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import axios from 'axios';
|
||||
import { SyncOutlined } from '@ant-design/icons';
|
||||
import { Tag, Table, Typography, Button, Alert } from 'antd';
|
||||
import TimeAgo from 'javascript-time-ago';
|
||||
|
||||
@ -235,7 +236,7 @@ class SubscriptionDetails extends React.Component {
|
||||
</Text>
|
||||
</div>
|
||||
<div style={{ textAlign: 'right', paddingBottom: 6 }}>
|
||||
<Button icon="sync" onClick={this.fetch}>
|
||||
<Button icon={<SyncOutlined />} onClick={this.fetch}>
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Divider,
|
||||
Row,
|
||||
@ -26,7 +27,6 @@ import {
|
||||
Dropdown,
|
||||
notification,
|
||||
Menu,
|
||||
Icon,
|
||||
Tabs,
|
||||
Tag,
|
||||
} from 'antd';
|
||||
@ -216,13 +216,13 @@ class ReleaseView extends React.Component {
|
||||
yes={
|
||||
<Dropdown overlay={menu}>
|
||||
<Button type="primary">
|
||||
Subscribe <Icon type="down" />
|
||||
Subscribe <DownOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
}
|
||||
no={
|
||||
<Button type="primary" disabled={true}>
|
||||
Subscribe <Icon type="down" />
|
||||
Subscribe <DownOutlined />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
@ -18,7 +18,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import '../../../../../../../../App.css';
|
||||
import { Skeleton, Typography, Row, Col, Card, Breadcrumb, Icon } from 'antd';
|
||||
import { HomeOutlined } from '@ant-design/icons';
|
||||
import { Skeleton, Typography, Row, Col, Card, Breadcrumb } from 'antd';
|
||||
import ReleaseView from './components/ReleaseView';
|
||||
import axios from 'axios';
|
||||
import { withConfigContext } from '../../../../../../../../components/context/ConfigContext';
|
||||
@ -110,7 +111,7 @@ class ReleasePage extends React.Component {
|
||||
<Breadcrumb style={{ paddingBottom: 16 }}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to={'/store/' + deviceType}>
|
||||
<Icon type="home" /> {deviceType + ' apps'}{' '}
|
||||
<HomeOutlined /> {deviceType + ' apps'}{' '}
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>{appName}</Breadcrumb.Item>
|
||||
|
||||
@ -17,14 +17,14 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Typography,
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Icon,
|
||||
Input,
|
||||
Button,
|
||||
Form,
|
||||
Checkbox,
|
||||
notification,
|
||||
} from 'antd';
|
||||
@ -36,6 +36,62 @@ const { Title } = Typography;
|
||||
const { Text } = Typography;
|
||||
|
||||
class Login extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
inValid: false,
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
handleSubmit = values => {
|
||||
this.setState({
|
||||
loading: true,
|
||||
inValid: false,
|
||||
});
|
||||
const parameters = {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
platform: 'store',
|
||||
};
|
||||
|
||||
const request = Object.keys(parameters)
|
||||
.map(key => key + '=' + parameters[key])
|
||||
.join('&');
|
||||
|
||||
axios
|
||||
.post(window.location.origin + '/store-ui-request-handler/login', request)
|
||||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
let redirectUrl = window.location.origin + '/store';
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
if (searchParams.has('redirect')) {
|
||||
redirectUrl = searchParams.get('redirect');
|
||||
}
|
||||
window.location = redirectUrl;
|
||||
} else {
|
||||
throw new Error();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||
this.setState({
|
||||
loading: false,
|
||||
inValid: true,
|
||||
});
|
||||
} else {
|
||||
notification.error({
|
||||
message: 'There was a problem',
|
||||
duration: 10,
|
||||
description: '',
|
||||
});
|
||||
this.setState({
|
||||
loading: false,
|
||||
inValid: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
render() {
|
||||
const config = this.props.context;
|
||||
return (
|
||||
@ -46,7 +102,13 @@ class Login extends React.Component {
|
||||
<Col xs={3} sm={3} md={10}></Col>
|
||||
<Col xs={18} sm={18} md={4}>
|
||||
<Row style={{ marginBottom: 20 }}>
|
||||
<Col style={{ textAlign: 'center' }}>
|
||||
<Col
|
||||
style={{
|
||||
display: 'block',
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
marginTop: 36,
|
||||
@ -57,7 +119,58 @@ class Login extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
<Title level={2}>Login</Title>
|
||||
<WrappedNormalLoginForm />
|
||||
<Form
|
||||
initialValues={{ remember: true }}
|
||||
onFinish={this.handleSubmit}
|
||||
>
|
||||
<Form.Item
|
||||
name="username"
|
||||
rules={[
|
||||
{ required: true, message: 'Please input your username!' },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
name="username"
|
||||
style={{ height: 32 }}
|
||||
prefix={
|
||||
<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />
|
||||
}
|
||||
placeholder="Username"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[
|
||||
{ required: true, message: 'Please input your password!' },
|
||||
]}
|
||||
>
|
||||
<Input.Password
|
||||
prefix={
|
||||
<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />
|
||||
}
|
||||
placeholder="Password"
|
||||
/>
|
||||
</Form.Item>
|
||||
{this.state.loading && <Text type="secondary">Loading..</Text>}
|
||||
{this.state.inValid && (
|
||||
<Text type="danger">Invalid Login Details</Text>
|
||||
)}
|
||||
<br />
|
||||
<a href="">Forgot password</a>
|
||||
<Form.Item name="remember" valuePropName="checked">
|
||||
<Checkbox>Remember me</Checkbox>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
block
|
||||
loading={this.state.loading}
|
||||
>
|
||||
Log in
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
@ -69,140 +182,4 @@ class Login extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
class NormalLoginForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
inValid: false,
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
const thisForm = this;
|
||||
const config = this.props.context;
|
||||
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((err, values) => {
|
||||
thisForm.setState({
|
||||
inValid: false,
|
||||
});
|
||||
if (!err) {
|
||||
thisForm.setState({
|
||||
loading: true,
|
||||
});
|
||||
const parameters = {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
platform: 'store',
|
||||
};
|
||||
|
||||
const request = Object.keys(parameters)
|
||||
.map(key => key + '=' + parameters[key])
|
||||
.join('&');
|
||||
|
||||
axios
|
||||
.post(window.location.origin + config.serverConfig.loginUri, request)
|
||||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
let redirectUrl = window.location.origin + '/store';
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
if (searchParams.has('redirect')) {
|
||||
redirectUrl = searchParams.get('redirect');
|
||||
}
|
||||
window.location = redirectUrl;
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
if (
|
||||
error.hasOwnProperty('response') &&
|
||||
error.response.status === 401
|
||||
) {
|
||||
thisForm.setState({
|
||||
loading: false,
|
||||
inValid: true,
|
||||
});
|
||||
} else {
|
||||
notification.error({
|
||||
message: 'There was a problem',
|
||||
duration: 10,
|
||||
description: '',
|
||||
});
|
||||
thisForm.setState({
|
||||
loading: false,
|
||||
inValid: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
let errorMsg = '';
|
||||
if (this.state.inValid) {
|
||||
errorMsg = <Text type="danger">Invalid Login Details</Text>;
|
||||
}
|
||||
let loading = '';
|
||||
if (this.state.loading) {
|
||||
loading = <Text type="secondary">Loading..</Text>;
|
||||
}
|
||||
return (
|
||||
<Form onSubmit={this.handleSubmit} className="login-form">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true, message: 'Please input your username!' }],
|
||||
})(
|
||||
<Input
|
||||
name="username"
|
||||
style={{ height: 32 }}
|
||||
prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
placeholder="Username"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [{ required: true, message: 'Please input your Password!' }],
|
||||
})(
|
||||
<Input
|
||||
name="password"
|
||||
style={{ height: 32 }}
|
||||
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
{loading}
|
||||
{errorMsg}
|
||||
<Form.Item>
|
||||
{getFieldDecorator('remember', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: true,
|
||||
})(<Checkbox>Remember me</Checkbox>)}
|
||||
<br />
|
||||
<a className="login-form-forgot" href="">
|
||||
Forgot password
|
||||
</a>
|
||||
<Button
|
||||
loading={this.state.loading}
|
||||
block
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
className="login-form-button"
|
||||
>
|
||||
Log in
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const WrappedNormalLoginForm = withConfigContext(
|
||||
Form.create({ name: 'normal_login' })(NormalLoginForm),
|
||||
);
|
||||
|
||||
export default withConfigContext(Login);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user