Migrate APPM Store UI from antd v3 to v4

revert-70ac1926
anjula-sack 4 years ago
parent 4ff9a9222c
commit 080aeb39e0

@ -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">

@ -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…
Cancel
Save