Add UI improvemnts to APPM UI

The following imrovements are with this commit
- Fix issues and change ui in manage page
- Change error messages to closable notifications
- Create a view to inform user when no apps available
- Change error messages
- Change install mode order in store
- Change the lifecycle UI
- Fix typo in error messages in APPM UI
feature/appm-store/pbac
Jayasanka 6 years ago
parent a5f75df99a
commit 4d59b8d900

@ -2,7 +2,7 @@
"theme": { "theme": {
"type": "default", "type": "default",
"value": "lightBaseTheme", "value": "lightBaseTheme",
"logo" : "https://entgra.io/assets/images/svg/logo.svg", "logo": "https://entgra.io/assets/images/svg/logo.svg",
"primaryColor": "rgb(24, 144, 255)" "primaryColor": "rgb(24, 144, 255)"
}, },
"serverConfig": { "serverConfig": {
@ -13,7 +13,7 @@
"uri": "/publisher-ui-request-handler/invoke", "uri": "/publisher-ui-request-handler/invoke",
"publisher": "/application-mgt-publisher/v1.0", "publisher": "/application-mgt-publisher/v1.0",
"store": "/application-mgt-store/v1.0", "store": "/application-mgt-store/v1.0",
"deviceMgt" : "/device-mgt/v1.0" "deviceMgt": "/device-mgt/v1.0"
}, },
"loginUri": "/publisher-ui-request-handler/login", "loginUri": "/publisher-ui-request-handler/login",
"platform": "publisher" "platform": "publisher"
@ -39,5 +39,31 @@
"color": "#008cc4", "color": "#008cc4",
"theme": "filled" "theme": "filled"
} }
},
"lifecycle": {
"CREATED": {
"text": "The initial most state of an application."
},
"IN-REVIEW": {
"text": "This state can be applied when the application is being reviewed by approvers."
},
"APPROVED": {
"text": "The approved state is a compulsory state prior to publishing the application."
},
"REJECTED": {
"text": "The Approvers can reject an application due to a faulty of the app or not being in compliance with company policies."
},
"PUBLISHED": {
"text": "The state which is applied for applications which are qualified for your Corporate App Store. Only the applications of Published state can be installed to your corporate devices."
},
"BLOCKED": {
"text": "This state allows you to block your application either to publish or deprecate at a future date."
},
"DEPRECATED": {
"text": "The applications which are outdated and no longer suit your app store."
},
"RETIRED": {
"text": "The final state of an application, where no transition of states will be allowed after this."
}
} }
} }

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {Row, Typography, Icon, message} from "antd"; import {Row, Typography, Icon, message, notification} from "antd";
import StarRatings from "react-star-ratings"; import StarRatings from "react-star-ratings";
import "./DetailedRating.css"; import "./DetailedRating.css";
import config from "../../../../public/conf/config.json"; import config from "../../../../public/conf/config.json";
@ -44,7 +44,12 @@ class DetailedRating extends React.Component{
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else { } else {
message.error('Something went wrong while trying to load rating for the release... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load rating for the release.",
});
} }
}); });
}; };

@ -116,8 +116,12 @@ class AppDetailsDrawer extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong while trying to load app details... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load app details.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -151,8 +155,12 @@ class AppDetailsDrawer extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load tags.'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load tags.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -186,7 +194,12 @@ class AppDetailsDrawer extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.error('Something went wrong when trying to save the app name... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to save the app name.",
});
} }
this.setState({loading: false}); this.setState({loading: false});
@ -262,7 +275,12 @@ class AppDetailsDrawer extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.error('Something went wrong when trying to updating categories'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to updating categories.",
});
} }
this.setState({loading: false}); this.setState({loading: false});
@ -320,7 +338,12 @@ class AppDetailsDrawer extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.error('Something went wrong when trying to update tags'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to update tags",
});
} }
this.setState({loading: false}); this.setState({loading: false});

@ -1,5 +1,19 @@
import React from "react"; import React from "react";
import {Card, Col, Row,Typography, Input, Divider, Icon, Select, Button, Form, message, Radio} from "antd"; import {
Card,
Col,
Row,
Typography,
Input,
Divider,
Icon,
Select,
Button,
Form,
message,
Radio,
notification
} from "antd";
import axios from "axios"; import axios from "axios";
import config from "../../../../public/conf/config.json"; import config from "../../../../public/conf/config.json";
@ -63,8 +77,12 @@ class FiltersForm extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong while trying to load categories... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load categories.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -88,8 +106,12 @@ class FiltersForm extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load tags'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load tags.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -114,8 +136,12 @@ class FiltersForm extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load device types'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load device types.",
});
} }
this.setState({ this.setState({
loading: false loading: false

@ -1,7 +1,5 @@
import React from "react"; import React from "react";
import {Avatar, Card, Col, Row, Table, Typography, Input, Divider, Checkbox, Select, Button} from "antd"; import {Avatar, Card, Col, Row, Table, Typography, Input, Divider, Checkbox, Select, Button} from "antd";
import {connect} from "react-redux";
import {getApps} from "../../../js/actions";
import AppsTable from "./appsTable/AppsTable"; import AppsTable from "./appsTable/AppsTable";
import Filters from "./Filters"; import Filters from "./Filters";
import AppDetailsDrawer from "./AppDetailsDrawer/AppDetailsDrawer"; import AppDetailsDrawer from "./AppDetailsDrawer/AppDetailsDrawer";

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {Avatar, Table, Tag, Icon, message} from "antd"; import {Avatar, Table, Tag, Icon, message, notification} from "antd";
import axios from "axios"; import axios from "axios";
import pSBC from 'shade-blend-color'; import pSBC from 'shade-blend-color';
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
@ -155,7 +155,12 @@ class AppsTable extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else { } else {
message.error('Something went wrong while trying to load apps... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load the apps.",
});
} }
this.setState({loading: false}); this.setState({loading: false});

@ -2,10 +2,11 @@ import React from "react";
import {Typography, Tag, Divider, Select, Button, Modal, message, notification, Collapse} from "antd"; import {Typography, Tag, Divider, Select, Button, Modal, message, notification, Collapse} from "antd";
import axios from "axios"; import axios from "axios";
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
import pSBC from "shade-blend-color";
import ReactQuill from 'react-quill'; import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css'; import 'react-quill/dist/quill.snow.css';
import './LifeCycle.css'; import './LifeCycle.css';
import LifeCycleDetailsModal from "./lifeCycleDetailsModal/lifeCycleDetailsModal";
const {Text, Title, Paragraph} = Typography; const {Text, Title, Paragraph} = Typography;
const {Option} = Select; const {Option} = Select;
@ -27,6 +28,7 @@ const formats = [
'link', 'image' 'link', 'image'
]; ];
class LifeCycle extends React.Component { class LifeCycle extends React.Component {
constructor(props) { constructor(props) {
@ -69,7 +71,12 @@ class LifeCycle extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.error('Something went wrong when trying to load lifecycle configuration'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load lifecycle configuration.",
});
} }
}); });
}; };
@ -133,7 +140,7 @@ class LifeCycle extends React.Component {
notification["error"]({ notification["error"]({
message: "Error", message: "Error",
description: description:
"Something went wrong when trying to add lifecycle", "Error occurred while trying to add lifecycle",
}); });
} }
this.setState({ this.setState({
@ -152,7 +159,6 @@ class LifeCycle extends React.Component {
if((lifecycle.hasOwnProperty(currentStatus)) && lifecycle[currentStatus].hasOwnProperty("proceedingStates")){ if((lifecycle.hasOwnProperty(currentStatus)) && lifecycle[currentStatus].hasOwnProperty("proceedingStates")){
proceedingStates = lifecycle[currentStatus].proceedingStates; proceedingStates = lifecycle[currentStatus].proceedingStates;
} }
console.log(lifecycle);
return ( return (
<div> <div>
<Title level={4}>Manage Lifecycle</Title> <Title level={4}>Manage Lifecycle</Title>
@ -163,6 +169,7 @@ class LifeCycle extends React.Component {
state to another. <br/>Note: Change State To displays only the next states allowed from the state to another. <br/>Note: Change State To displays only the next states allowed from the
current state current state
</Paragraph> </Paragraph>
<LifeCycleDetailsModal lifecycle={lifecycle}/>
<Divider dashed={true}/> <Divider dashed={true}/>
<Text strong={true}>Current State: </Text> <Tag color="blue">{currentStatus}</Tag><br/><br/> <Text strong={true}>Current State: </Text> <Tag color="blue">{currentStatus}</Tag><br/><br/>
<Text>Change State to: </Text> <Text>Change State to: </Text>
@ -198,30 +205,6 @@ class LifeCycle extends React.Component {
<Divider/> <Divider/>
<Text strong={true}>Lorem Ipsum</Text>
<Collapse defaultActiveKey={currentStatus}>
{
Object.keys(lifecycle).map(lifecycleState => {
return (
<Panel header={lifecycleState} key={lifecycleState}>
{
Object.keys(lifecycle).map(state => {
// console.log(lifecycle[lifecycleState].proceedingStates);
const isEnabled = lifecycle[lifecycleState].hasOwnProperty("proceedingStates") && (lifecycle[lifecycleState].proceedingStates.includes(state));
const color = isEnabled ? "green" : "";
return (
<Tag
disabled={!isEnabled}
key={state} style={{marginBottom: 5}} color={color}>{state}</Tag>
)
})
}
</Panel>
)
})
}
</Collapse>
<Modal <Modal
title="Confirm changing lifecycle state" title="Confirm changing lifecycle state"

@ -0,0 +1,96 @@
import React from "react";
import {Modal, Button, Tag, Collapse, List,Typography} from 'antd';
import pSBC from "shade-blend-color";
import config from "../../../../../../public/conf/config.json";
const {Text} = Typography;
const lifeCycleConfig = config.lifecycle;
class LifeCycleDetailsModal extends React.Component {
constructor(props) {
super(props);
this.state = {visible: false};
}
showModal = () => {
this.setState({
visible: true,
});
};
handleCancel = e => {
console.log(e);
this.setState({
visible: false,
});
};
render() {
const {lifecycle} = this.props;
return (
<div>
<Button
size="small"
icon="question-circle"
onClick={this.showModal}
>
Learn more
</Button>
<Modal
title="Lifecycle"
visible={this.state.visible}
footer = {null}
onCancel={this.handleCancel}
>
<List
itemLayout="horizontal"
dataSource={Object.keys(lifecycle)}
renderItem={lifecycleState => {
let text = "";
let footerText = "";
let nextProceedingStates = [];
if (lifeCycleConfig.hasOwnProperty(lifecycleState)) {
text = lifeCycleConfig[lifecycleState].text;
}
if (lifecycle[lifecycleState].hasOwnProperty("proceedingStates")) {
nextProceedingStates = lifecycle[lifecycleState].proceedingStates;
footerText = "You can only proceed to one of the following states:"
}
return (
<List.Item>
<List.Item.Meta
title={lifecycleState}
/>
{text}
<br/>
<Text type="secondary">{footerText}</Text>
<div>
{
nextProceedingStates.map(lifecycleState => {
return (
<Tag
key={lifecycleState}
style={{margin: 5}}
color={pSBC(0.30, config.theme.primaryColor)}
>
{lifecycleState}
</Tag>
)
})
}
</div>
</List.Item>
)
}}
/>
</Modal>
</div>
);
}
}
export default LifeCycleDetailsModal;

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {List, message, Avatar, Spin, Button} from 'antd'; import {List, message, Avatar, Spin, Button, notification} from 'antd';
import "./Reviews.css"; import "./Reviews.css";
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
@ -42,8 +42,12 @@ class Reviews extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load reviews'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load reviews.",
});
} }
}); });
}; };

@ -1,10 +1,27 @@
import React from "react"; import React from "react";
import {Card, Tag, message, Icon, Input, notification, Divider, Button, Spin, Tooltip, Popconfirm, Modal} from "antd"; import {
Card,
Tag,
message,
Icon,
Input,
notification,
Divider,
Button,
Spin,
Tooltip,
Popconfirm,
Modal,
Row,
Col,
Typography
} from "antd";
import axios from "axios"; import axios from "axios";
import config from "../../../../public/conf/config.json"; import config from "../../../../public/conf/config.json";
import {TweenOneGroup} from 'rc-tween-one'; import {TweenOneGroup} from 'rc-tween-one';
import pSBC from "shade-blend-color"; import pSBC from "shade-blend-color";
const {Title} = Typography;
class ManageCategories extends React.Component { class ManageCategories extends React.Component {
state = { state = {
@ -22,8 +39,8 @@ class ManageCategories extends React.Component {
componentDidMount() { componentDidMount() {
axios.get( axios.get(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/applications/categories", config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories",
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
let categories = JSON.parse(res.data.data); let categories = JSON.parse(res.data.data);
this.setState({ this.setState({
@ -34,7 +51,7 @@ class ManageCategories extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong'); message.warning('Something went wrong');
@ -57,8 +74,7 @@ class ManageCategories extends React.Component {
loading: true loading: true
}); });
axios.delete( axios.delete(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/admin/applications/categories/"+id, config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/" + id,
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
@ -82,9 +98,14 @@ class ManageCategories extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load categories'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load categories.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -96,7 +117,7 @@ class ManageCategories extends React.Component {
const categoryName = category.categoryName; const categoryName = category.categoryName;
const tagElem = ( const tagElem = (
<Tag <Tag
color={pSBC ( 0.30, config.theme.primaryColor )} color={pSBC(0.30, config.theme.primaryColor)}
> >
{categoryName} {categoryName}
<Divider type="vertical"/> <Divider type="vertical"/>
@ -139,7 +160,7 @@ class ManageCategories extends React.Component {
const tagElem = ( const tagElem = (
<Tag <Tag
closable closable
onClose={e=>{ onClose={e => {
e.preventDefault(); e.preventDefault();
const {tempElements} = this.state; const {tempElements} = this.state;
const remainingElements = tempElements.filter(function (value) { const remainingElements = tempElements.filter(function (value) {
@ -197,9 +218,8 @@ class ManageCategories extends React.Component {
const data = tempElements.map(category => category.categoryName); const data = tempElements.map(category => category.categoryName);
axios.post( axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/admin/applications/categories", config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories",
data, data,
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
@ -221,9 +241,14 @@ class ManageCategories extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to add categories'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to add categories.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -260,9 +285,8 @@ class ManageCategories extends React.Component {
}); });
axios.put( axios.put(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/admin/applications/categories/rename?from="+currentlyEditingId+"&to="+editingValue, config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/rename?from=" + currentlyEditingId + "&to=" + editingValue,
{}, {},
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
@ -283,9 +307,14 @@ class ManageCategories extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to delete the category'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to delete the category.",
});
} }
this.setState({ this.setState({
loading: false, loading: false,
@ -308,21 +337,33 @@ class ManageCategories extends React.Component {
const temporaryElements = tempElements.map(this.renderTempElement); const temporaryElements = tempElements.map(this.renderTempElement);
return ( return (
<div style={{marginBottom: 16}}> <div style={{marginBottom: 16}}>
<Card title="Categories"> <Card>
<Spin tip="Working on it..." spinning={this.state.loading}> <Spin tip="Working on it..." spinning={this.state.loading}>
{!isAddNewVisible && <Row>
<Button <Col span={16}>
size="small" <Title level={4}>Categories</Title>
onClick={() => { </Col>
this.setState({ <Col span={8}>
isAddNewVisible: true, {!isAddNewVisible &&
inputVisible: true <div style={{float: "right"}}>
}, () => this.input.focus()) <Button
}} htmlType="button">Add Categories icon="plus"
</Button> // type="primary"
} size="small"
onClick={() => {
this.setState({
isAddNewVisible: true,
inputVisible: true
}, () => this.input.focus())
}} htmlType="button">Add
</Button>
</div>
}
</Col>
</Row>
{isAddNewVisible && {isAddNewVisible &&
<div> <div>
<Divider/>
<div style={{marginBottom: 16}}> <div style={{marginBottom: 16}}>
<TweenOneGroup <TweenOneGroup
enter={{ enter={{
@ -360,14 +401,18 @@ class ManageCategories extends React.Component {
</TweenOneGroup> </TweenOneGroup>
</div> </div>
<div> <div>
<Button {tempElements.length > 0 && (
onClick={this.handleSave} <span>
htmlType="button" type="primary" <Button
size="small" onClick={this.handleSave}
disabled={tempElements.length === 0}> htmlType="button" type="primary"
size="small"
>
Save Save
</Button> </Button>
<Divider type="vertical"/> <Divider type="vertical"/>
</span>
)}
<Button <Button
onClick={this.handleCloseButton} onClick={this.handleCloseButton}
size="small"> size="small">
@ -402,7 +447,8 @@ class ManageCategories extends React.Component {
onCancel={this.closeEditModal} onCancel={this.closeEditModal}
onOk={this.editItem} onOk={this.editItem}
> >
<Input value={this.state.editingValue} ref={(input) => this.editingInput = input} onChange={this.handleEditInputChange}/> <Input value={this.state.editingValue} ref={(input) => this.editingInput = input}
onChange={this.handleEditInputChange}/>
</Modal> </Modal>
</div> </div>
); );

@ -1,9 +1,25 @@
import React from "react"; import React from "react";
import {Card, Tag, message, Icon, Input, notification, Divider, Button, Spin, Tooltip, Popconfirm, Modal} from "antd"; import {
Card,
Tag,
message,
Icon,
Input,
notification,
Divider,
Button,
Spin,
Tooltip,
Popconfirm,
Modal,
Row, Col,
Typography
} from "antd";
import axios from "axios"; import axios from "axios";
import config from "../../../../public/conf/config.json"; import config from "../../../../public/conf/config.json";
import {TweenOneGroup} from 'rc-tween-one'; import {TweenOneGroup} from 'rc-tween-one';
const {Title} = Typography;
class ManageTags extends React.Component { class ManageTags extends React.Component {
state = { state = {
@ -21,8 +37,8 @@ class ManageTags extends React.Component {
componentDidMount() { componentDidMount() {
axios.get( axios.get(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/applications/tags", config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags",
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
let tags = JSON.parse(res.data.data); let tags = JSON.parse(res.data.data);
this.setState({ this.setState({
@ -33,10 +49,14 @@ class ManageTags extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load tags'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load tags.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -58,7 +78,7 @@ class ManageTags extends React.Component {
}); });
axios.delete( axios.delete(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/admin/applications/tags/"+id config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/tags/" + id
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
@ -82,9 +102,14 @@ class ManageTags extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to delete the tag'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to delete the tag.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -196,9 +221,9 @@ class ManageTags extends React.Component {
const data = tempElements.map(tag => tag.tagName); const data = tempElements.map(tag => tag.tagName);
axios.post(config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/applications/tags", axios.post(config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags",
data, data,
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
message: "Done!", message: "Done!",
@ -219,9 +244,14 @@ class ManageTags extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to delete tag'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to delete tag.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -258,9 +288,8 @@ class ManageTags extends React.Component {
}); });
axios.put( axios.put(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher+"/applications/tags/rename?from="+currentlyEditingId+"&to="+editingValue, config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags/rename?from=" + currentlyEditingId + "&to=" + editingValue,
{}, {},
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
notification["success"]({ notification["success"]({
@ -281,9 +310,14 @@ class ManageTags extends React.Component {
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to edit tag'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to edit tag.",
});
} }
this.setState({ this.setState({
loading: false, loading: false,
@ -306,21 +340,33 @@ class ManageTags extends React.Component {
const temporaryElements = tempElements.map(this.renderTempElement); const temporaryElements = tempElements.map(this.renderTempElement);
return ( return (
<div style={{marginBottom: 16}}> <div style={{marginBottom: 16}}>
<Card title="Tags"> <Card>
<Spin tip="Working on it..." spinning={this.state.loading}> <Spin tip="Working on it..." spinning={this.state.loading}>
{!isAddNewVisible && <Row>
<Button <Col span={16}>
size="small" <Title level={4}>Tags</Title>
onClick={() => { </Col>
this.setState({ <Col span={8}>
isAddNewVisible: true, {!isAddNewVisible &&
inputVisible: true <div style={{float: "right"}}>
}, () => this.input.focus()) <Button
}} htmlType="button">Add Tags icon="plus"
</Button> // type="primary"
} size="small"
onClick={() => {
this.setState({
isAddNewVisible: true,
inputVisible: true
}, () => this.input.focus())
}} htmlType="button">Add
</Button>
</div>
}
</Col>
</Row>
{isAddNewVisible && {isAddNewVisible &&
<div> <div>
<Divider/>
<div style={{marginBottom: 16}}> <div style={{marginBottom: 16}}>
<TweenOneGroup <TweenOneGroup
enter={{ enter={{
@ -358,53 +404,57 @@ class ManageTags extends React.Component {
</TweenOneGroup> </TweenOneGroup>
</div> </div>
<div> <div>
<Button {tempElements.length > 0 && (
onClick={this.handleSave} <span>
htmlType="button" type="primary" <Button
size="small" onClick={this.handleSave}
disabled={tempElements.length === 0}> htmlType="button" type="primary"
Save size="small"
</Button> disabled={tempElements.length === 0}>
<Divider type="vertical"/> Save
<Button </Button>
<Divider type="vertical"/>
</span>
)}
< Button
onClick={this.handleCloseButton} onClick={this.handleCloseButton}
size="small"> size="small">
Cancel Cancel
</Button> </Button>
</div>
</div>
}
<Divider dashed="true"/>
<div style={{marginTop: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{tagsElements}
</TweenOneGroup>
</div>
</Spin>
</Card>
< Modal
title="Edit"
visible={this.state.isEditModalVisible}
onCancel={this.closeEditModal}
onOk={this.editItem}
>
<Input value={this.state.editingValue} ref={(input) => this.editingInput = input} onChange={this.handleEditInputChange}/>
</Modal>
</div> </div>
</div> );
}
} }
<Divider dashed="true"/>
<div style={{marginTop: 16}}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: 'from',
duration: 100,
onComplete: e => {
e.target.style = '';
},
}}
leave={{opacity: 0, width: 0, scale: 0, duration: 200}}
appear={false}
>
{tagsElements}
</TweenOneGroup>
</div>
</Spin>
</Card>
<Modal
title="Edit"
visible={this.state.isEditModalVisible}
onCancel={this.closeEditModal}
onOk={this.editItem}
>
<Input value={this.state.editingValue} ref={(input) => this.editingInput = input} onChange={this.handleEditInputChange}/>
</Modal>
</div>
);
}
}
export default ManageTags; export default ManageTags;

@ -68,8 +68,12 @@ class AddNewAppFormComponent extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load categories'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load categories.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -93,8 +97,12 @@ class AddNewAppFormComponent extends React.Component {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.warning('Something went wrong when trying to load tags'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load tags.",
});
} }
this.setState({ this.setState({
loading: false loading: false
@ -116,7 +124,7 @@ class AddNewAppFormComponent extends React.Component {
this.setState({ this.setState({
loading: true loading: true
}); });
const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription,releaseType} = values; const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values;
const application = { const application = {
name, name,
description, description,
@ -130,9 +138,9 @@ class AddNewAppFormComponent extends React.Component {
if (formConfig.installationType !== "WEB_CLIP") { if (formConfig.installationType !== "WEB_CLIP") {
application.deviceType = values.deviceType; application.deviceType = values.deviceType;
}else{ } else {
application.type = "WEB_CLIP"; application.type = "WEB_CLIP";
application.deviceType ="ALL"; application.deviceType = "ALL";
} }
if (specificElements.hasOwnProperty("binaryFile")) { if (specificElements.hasOwnProperty("binaryFile")) {

@ -1,136 +0,0 @@
import axios from "axios";
import ActionTypes from "../constants/ActionTypes";
import config from "../../../public/conf/config.json";
import {message} from "antd";
export const getApps = () => dispatch => {
const request = "method=post&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications";
return axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher,
request
).then(res => {
if (res.status === 200) {
let apps = [];
if (res.data.data.hasOwnProperty("applications")) {
apps = res.data.data.applications;
}
dispatch({type: ActionTypes.GET_APPS, payload: apps});
}
}).catch(function (error) {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else {
message.error('Something went wrong when trying to load applications... :(');
}
});
};
export const getRelease = (uuid) => dispatch => {
const request = "method=get&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications/release/" + uuid;
return axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher, request
).then(res => {
if (res.status === 200) {
let release = res.data.data;
dispatch({type: ActionTypes.GET_RELEASE, payload: release});
}
}).catch(function (error) {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else {
message.error('Something went wrong... :(');
}
});
};
export const openReleasesModal = (app) => dispatch => {
dispatch({
type: ActionTypes.OPEN_RELEASES_MODAL,
payload: {
app: app
}
});
};
export const openLifecycleModal = (nextState) => dispatch => {
dispatch({
type: ActionTypes.OPEN_LIFECYCLE_MODAL,
payload: {
nextState: nextState
}
});
};
export const closeLifecycleModal = () => dispatch => {
dispatch({
type: ActionTypes.CLOSE_LIFECYCLE_MODAL
});
};
export const getLifecycle = () => dispatch => {
const request = "method=get&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications/lifecycle-config";
return axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher, request
).then(res => {
if (res.status === 200) {
let lifecycle = res.data.data;
dispatch({type: ActionTypes.GET_LIFECYCLE, payload: lifecycle});
}
}).catch(function (error) {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else {
message.error('Something went wrong... :(');
}
});
};
export const updateLifecycleState = (uuid, nextState, reason) => dispatch => {
const payload = {
action: nextState,
reason: reason
};
const request = "method=post&content-type=application/json&payload=" + JSON.stringify(payload) + "&api-endpoint=/application-mgt-publisher/v1.0/applications/life-cycle/" + uuid;
return axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.publisher, request
).then(res => {
if (res.status === 201) {
let release = res.data.data;
dispatch({type: ActionTypes.UPDATE_LIFECYCLE_STATE, payload: release});
}else {
alert("error");
dispatch({
type: ActionTypes.CLOSE_LIFECYCLE_MODAL
});
}
}).catch(function (error) {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/publisher/login';
} else if (error.response.status === 500) {
alert("error");
dispatch({
type: ActionTypes.CLOSE_LIFECYCLE_MODAL
});
}
});
};

@ -1,15 +0,0 @@
import keyMirror from 'keymirror';
const ActionTypes = keyMirror({
LOGIN: null,
GET_APPS: null,
OPEN_RELEASES_MODAL: null,
CLOSE_RELEASES_MODAL: null,
GET_RELEASE: null,
GET_LIFECYCLE: null,
OPEN_LIFECYCLE_MODAL: null,
CLOSE_LIFECYCLE_MODAL: null,
UPDATE_LIFECYCLE_STATE: null,
});
export default ActionTypes;

@ -1,64 +0,0 @@
import ActionTypes from "../constants/ActionTypes";
const initialState = {
apps: [],
releaseView: {
visible: false,
app: null
},
release: null,
lifecycle: null,
lifecycleModal:{
visible: false,
nextState: null
}
};
function rootReducer(state = initialState, action) {
if (action.type === ActionTypes.GET_APPS) {
return Object.assign({}, state, {
apps: action.payload
});
} else if (action.type === ActionTypes.OPEN_RELEASES_MODAL) {
return Object.assign({}, state, {
releaseView: {
visible: true,
app: action.payload.app
}
});
} else if (action.type === ActionTypes.GET_RELEASE) {
return Object.assign({}, state, {
release: action.payload
});
} else if (action.type === ActionTypes.GET_LIFECYCLE) {
return Object.assign({}, state, {
lifecycle: action.payload
});
}else if (action.type === ActionTypes.OPEN_LIFECYCLE_MODAL) {
return Object.assign({}, state, {
lifecycleModal: {
visible: true,
nextState: action.payload.nextState
}
});
}else if (action.type === ActionTypes.CLOSE_LIFECYCLE_MODAL) {
return Object.assign({}, state, {
lifecycleModal: {
visible: false,
nextState: null
}
});
}else if (action.type === ActionTypes.UPDATE_LIFECYCLE_STATE) {
return Object.assign({}, state, {
lifecycleModal: {
visible: false,
nextState: null,
},
release: action.payload
});
}
return state;
}
export default rootReducer;

@ -1,5 +0,0 @@
import { createStore, applyMiddleware } from "redux";
import rootReducer from "../reducers/index";
import thunk from "redux-thunk";
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;

@ -1,56 +0,0 @@
import * as dagre from "dagre";
import * as _ from "lodash";
const size = {
width: 60,
height: 60
};
export function distributeElements(model) {
let clonedModel = _.cloneDeep(model);
let nodes = distributeGraph(clonedModel);
nodes.forEach(node => {
let modelNode = clonedModel.nodes.find(item => item.id === node.id);
modelNode.x = node.x - node.width / 2;
modelNode.y = node.y - node.height / 2;
});
return clonedModel;
}
function distributeGraph(model) {
let nodes = mapElements(model);
let edges = mapEdges(model);
let graph = new dagre.graphlib.Graph();
graph.setGraph({});
graph.setDefaultEdgeLabel(() => ({}));
//add elements to dagre graph
nodes.forEach(node => {
graph.setNode(node.id, node.metadata);
});
edges.forEach(edge => {
if (edge.from && edge.to) {
graph.setEdge(edge.from, edge.to);
}
});
//auto-distribute
dagre.layout(graph);
return graph.nodes().map(node => graph.node(node));
}
function mapElements(model) {
// dagre compatible format
return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } }));
}
function mapEdges(model) {
// returns links which connects nodes
// we check are there both from and to nodes in the model. Sometimes links can be detached
return model.links
.map(link => ({
from: link.source,
to: link.target
}))
.filter(
item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to)
);
}

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox, message} from 'antd'; import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox, message, notification} from 'antd';
import './Login.css'; import './Login.css';
import axios from 'axios'; import axios from 'axios';
import config from "../../public/conf/config.json"; import config from "../../public/conf/config.json";
@ -86,7 +86,12 @@ class NormalLoginForm extends React.Component {
inValid: true inValid: true
}); });
} else { } else {
message.error('Something went wrong when trying to login... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to login.",
});
} }
thisForm.setState({ thisForm.setState({
loading: false loading: false

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import '../../../../App.css'; import '../../../../App.css';
import {Typography, Row, Col, message, Card} from "antd"; import {Typography, Row, Col, message, Card, notification} from "antd";
import axios from 'axios'; import axios from 'axios';
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
import ReleaseView from "../../../../components/apps/release/ReleaseView"; import ReleaseView from "../../../../components/apps/release/ReleaseView";
@ -67,9 +67,13 @@ class Release extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else { } else {
message.error('Something went wrong when trying to load the release... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load the release.",
});
} }
this.setState({loading: false}); this.setState({loading: false});
}); });
}; };

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import AppCard from "./AppCard"; import AppCard from "./AppCard";
import {Col, message, Row} from "antd"; import {Col, message, notification, Row, Result, Skeleton} from "antd";
import axios from "axios"; import axios from "axios";
import config from "../../../public/conf/config.json"; import config from "../../../public/conf/config.json";
@ -9,7 +9,7 @@ class AppList extends React.Component {
super(props); super(props);
this.state = { this.state = {
apps: [], apps: [],
loading: false loading: true
} }
} }
@ -31,19 +31,18 @@ class AppList extends React.Component {
fetchData = (deviceType) => { fetchData = (deviceType) => {
const payload = {}; const payload = {};
if(deviceType==="web-clip"){ if (deviceType === "web-clip") {
payload.appType= "WEB_CLIP"; payload.appType = "WEB_CLIP";
}else{ } else {
payload.deviceType= deviceType; payload.deviceType = deviceType;
} }
this.setState({
console.log("b",config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store+"/applications/"); loading: true
});
//send request to the invoker //send request to the invoker
axios.post( axios.post(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store+"/applications/", config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/applications/",
payload, payload,
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
//todo remove this property check after backend improvement //todo remove this property check after backend improvement
@ -54,13 +53,19 @@ class AppList extends React.Component {
}) })
} }
}).catch((error) => { console.log(error.response); }).catch((error) => {
console.log(error.response);
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
//todo display a popup with error //todo display a popup with error
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load apps.",
});
} }
this.setState({loading: false}); this.setState({loading: false});
@ -68,18 +73,28 @@ class AppList extends React.Component {
}; };
render() { render() {
const {apps} = this.state; const {apps,loading} = this.state;
return ( return (
<Row gutter={16}> <Skeleton loading={loading} active>
{apps.map(app => ( <Row gutter={16}>
<Col key={app.id} xs={12} sm={6} md={6} lg={4} xl={3}> {apps.length === 0 && (
<AppCard key={app.id} <Result
app={app} status="404"
title="No apps, yet."
subTitle="No apps available, yet! When the administration uploads, apps will show up here."
// extra={<Button type="primary">Back Home</Button>}
/> />
</Col> )}
))} {apps.map(app => (
</Row> <Col key={app.id} xs={12} sm={6} md={6} lg={4} xl={3}>
<AppCard key={app.id}
app={app}
/>
</Col>
))}
</Row>
</Skeleton>
); );
} }
} }

@ -52,7 +52,8 @@ class ReleaseView extends React.Component {
loading: false loading: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to install the app.", "We are unable to install the app.",
}); });
@ -68,7 +69,8 @@ class ReleaseView extends React.Component {
visible: false visible: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to add your review right now.", "We are unable to add your review right now.",
}); });

@ -17,21 +17,20 @@ class AppInstallModal extends React.Component{
<Modal <Modal
title="Install App" title="Install App"
visible={this.props.visible} visible={this.props.visible}
// onOk={this.handleOk}
onCancel={this.props.onClose} onCancel={this.props.onClose}
footer={null} footer={null}
> >
<Tabs defaultActiveKey="1"> <Tabs defaultActiveKey="device">
<TabPane tab="User" key="1"> <TabPane tab="Device" key="device">
<UserInstall onInstall={this.props.onInstall}/>
</TabPane>
<TabPane tab="Device" key="2">
<DeviceInstall onInstall={this.props.onInstall}/> <DeviceInstall onInstall={this.props.onInstall}/>
</TabPane> </TabPane>
<TabPane tab="Role" key="3"> <TabPane tab="User" key="user">
<UserInstall onInstall={this.props.onInstall}/>
</TabPane>
<TabPane tab="Role" key="role">
<RoleInstall onInstall={this.props.onInstall}/> <RoleInstall onInstall={this.props.onInstall}/>
</TabPane> </TabPane>
<TabPane tab="Group" key="4"> <TabPane tab="Group" key="group">
<GroupInstall onInstall={this.props.onInstall}/> <GroupInstall onInstall={this.props.onInstall}/>
</TabPane> </TabPane>
</Tabs> </Tabs>

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import axios from "axios"; import axios from "axios";
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
import {Button, message, Table, Typography} from "antd"; import {Button, message, notification, Table, Typography} from "antd";
import TimeAgo from 'javascript-time-ago' import TimeAgo from 'javascript-time-ago'
// Load locale-specific relative date/time formatting rules. // Load locale-specific relative date/time formatting rules.
@ -120,7 +120,7 @@ class DeviceInstall extends React.Component {
const extraParams = { const extraParams = {
offset: 10 * (currentPage - 1), //calculate the offset offset: 10 * (currentPage - 1), //calculate the offset
limit: 10, limit: 10,
status: "INACTIVE", status: "ACTIVE",
requireDeviceInfo: true requireDeviceInfo: true
}; };
@ -158,7 +158,12 @@ class DeviceInstall extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load devices.",
});
} }
this.setState({loading: false}); this.setState({loading: false});

@ -50,7 +50,12 @@ class GroupInstall extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load groups.",
});
} }
this.setState({fetching: false}); this.setState({fetching: false});

@ -50,7 +50,12 @@ class RoleInstall extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+'/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load roles.",
});
} }
this.setState({fetching: false}); this.setState({fetching: false});

@ -52,7 +52,12 @@ class UserInstall extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load users.",
});
} }
this.setState({fetching: false}); this.setState({fetching: false});

@ -76,7 +76,8 @@ class AddReview extends React.Component {
visible: false visible: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to add your review right now.", "We are unable to add your review right now.",
}); });
@ -91,7 +92,8 @@ class AddReview extends React.Component {
visible: false visible: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to add your review right now.", "We are unable to add your review right now.",
}); });

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {List, message, Typography, Empty, Button, Row, Col} from "antd"; import {List, message, Typography, Empty, Button, Row, Col, notification} from "antd";
import SingleReview from "./singleReview/SingleReview"; import SingleReview from "./singleReview/SingleReview";
import axios from "axios"; import axios from "axios";
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
@ -37,7 +37,12 @@ class CurrentUsersReview extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.error('Something went wrong when trying to get your review... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to get your review.",
});
} }
}); });
}; };

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import {List, message, Avatar, Spin, Button} from 'antd'; import {List, message, Avatar, Spin, Button, notification} from 'antd';
import "./Reviews.css"; import "./Reviews.css";
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
@ -44,8 +44,12 @@ class Reviews extends React.Component {
if (error.response.status === 401) { if (error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.warning('Something went wrong'); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load reviews.",
});
} }
}); });
}; };

@ -65,7 +65,8 @@ class SingleReview extends React.Component {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We were unable to delete the review..", "We were unable to delete the review..",
}); });

@ -88,7 +88,8 @@ class EditReview extends React.Component {
visible: false visible: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to update your review right now.", "We are unable to update your review right now.",
}); });
@ -104,7 +105,8 @@ class EditReview extends React.Component {
visible: false visible: false
}); });
notification["error"]({ notification["error"]({
message: 'Something went wrong', message: "There was a problem",
duration: 0,
description: description:
"We are unable to add your review right now.", "We are unable to add your review right now.",
}); });

@ -14,7 +14,7 @@ class Apps extends React.Component {
const {deviceType} = this.props.match.params; const {deviceType} = this.props.match.params;
return ( return (
<div> <div>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}> <div style={{background: '#f0f2f5', padding: 24, minHeight: 760}}>
{deviceType!==null && <AppList changeSelectedMenuItem={this.props.changeSelectedMenuItem} deviceType={deviceType}/>} {deviceType!==null && <AppList changeSelectedMenuItem={this.props.changeSelectedMenuItem} deviceType={deviceType}/>}
</div> </div>

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import '../../../../App.css'; import '../../../../App.css';
import {Skeleton, Typography, Row, Col, Card, message} from "antd"; import {Skeleton, Typography, Row, Col, Card, message, notification} from "antd";
import ReleaseView from "../../../../components/apps/release/ReleaseView"; import ReleaseView from "../../../../components/apps/release/ReleaseView";
import axios from "axios"; import axios from "axios";
import config from "../../../../../public/conf/config.json"; import config from "../../../../../public/conf/config.json";
@ -57,7 +57,12 @@ class Release extends React.Component {
message.error('You are not logged in'); message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login'; window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
} else { } else {
message.error('Something went wrong... :('); notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Error occurred while trying to load releases.",
});
} }
this.setState({loading: false}); this.setState({loading: false});

Loading…
Cancel
Save