mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'application-mgt-new' into 'application-mgt-new'
Add UI improvements to APPM UI See merge request entgra/carbon-device-mgt!281
This commit is contained in:
commit
220aba8e90
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"theme": {
|
"theme": {
|
||||||
"logo": "https://entgra.io/assets/images/svg/logo.svg",
|
"logo": "https://entgra.io/assets/images/svg/logo.svg",
|
||||||
"primaryColor": "#badc58"
|
"primaryColor": "rgb(24, 144, 255)"
|
||||||
},
|
},
|
||||||
"serverConfig": {
|
"serverConfig": {
|
||||||
"invoker": {
|
"invoker": {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import StarRatings from "react-star-ratings";
|
|||||||
import "./DetailedRating.css";
|
import "./DetailedRating.css";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../js/Utils";
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
@ -60,16 +61,7 @@ class DetailedRating extends React.Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load rating for the release.");
|
||||||
window.location.href = window.location.origin+'/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to load rating for the release.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import pSBC from "shade-blend-color";
|
|||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import ManagedConfigurationsIframe
|
import ManagedConfigurationsIframe
|
||||||
from "../../../manage/android-enterprise/ManagedConfigurationsIframe/ManagedConfigurationsIframe";
|
from "../../../manage/android-enterprise/ManagedConfigurationsIframe/ManagedConfigurationsIframe";
|
||||||
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
|
||||||
const {Meta} = Card;
|
const {Meta} = Card;
|
||||||
const {Text, Title} = Typography;
|
const {Text, Title} = Typography;
|
||||||
@ -135,16 +136,7 @@ class AppDetailsDrawer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load app details.");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -175,16 +167,7 @@ class AppDetailsDrawer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load tags.");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import {
|
|||||||
} from "antd";
|
} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../js/Utils";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
@ -92,16 +93,7 @@ class FiltersForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load categories.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -123,16 +115,7 @@ class FiltersForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load tags.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -154,16 +137,7 @@ class FiltersForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load device types.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
|
|||||||
@ -17,10 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Card, Col, Row, Typography, Input, Divider} from "antd";
|
import {Card, Col, Row, Typography, Input, Divider, notification} from "antd";
|
||||||
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";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
const Search = Input.Search;
|
const Search = Input.Search;
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import pSBC from 'shade-blend-color';
|
|||||||
import "./AppsTable.css";
|
import "./AppsTable.css";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import AppDetailsDrawer from "../AppDetailsDrawer/AppDetailsDrawer";
|
import AppDetailsDrawer from "../AppDetailsDrawer/AppDetailsDrawer";
|
||||||
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
|
||||||
let config = null;
|
let config = null;
|
||||||
|
|
||||||
@ -214,18 +215,7 @@ class AppsTable extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load apps.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -117,7 +117,7 @@ class EditReleaseModal extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
showModal = () => {
|
showModal = () => {
|
||||||
const {release} = this.props;
|
const {app, release} = this.props;
|
||||||
const {formConfig} = this.state;
|
const {formConfig} = this.state;
|
||||||
const {specificElements} = formConfig;
|
const {specificElements} = formConfig;
|
||||||
let metaData = [];
|
let metaData = [];
|
||||||
@ -143,6 +143,14 @@ class EditReleaseModal extends React.Component {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// if (specificElements.hasOwnProperty("packageName")) {
|
||||||
|
// this.props.form.setFields({
|
||||||
|
// packageName: {
|
||||||
|
// value: app.packageName
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
if (specificElements.hasOwnProperty("version")) {
|
if (specificElements.hasOwnProperty("version")) {
|
||||||
this.props.form.setFields({
|
this.props.form.setFields({
|
||||||
version: {
|
version: {
|
||||||
@ -238,10 +246,10 @@ class EditReleaseModal extends React.Component {
|
|||||||
if (specificElements.hasOwnProperty("url")) {
|
if (specificElements.hasOwnProperty("url")) {
|
||||||
release.url = values.url;
|
release.url = values.url;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
if (specificElements.hasOwnProperty("packageName")) {
|
// if (specificElements.hasOwnProperty("packageName")) {
|
||||||
release.packageName = values.packageName;
|
// release.packageName = values.packageName;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (icons.length === 1) {
|
if (icons.length === 1) {
|
||||||
data.append('icon', icons[0].originFileObj);
|
data.append('icon', icons[0].originFileObj);
|
||||||
@ -362,18 +370,18 @@ class EditReleaseModal extends React.Component {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{formConfig.specificElements.hasOwnProperty("packageName") && (
|
{/*{formConfig.specificElements.hasOwnProperty("packageName") && (*/}
|
||||||
<Form.Item {...formItemLayout} label="Package Name">
|
{/* <Form.Item {...formItemLayout} label="Package Name">*/}
|
||||||
{getFieldDecorator('packageName', {
|
{/* {getFieldDecorator('packageName', {*/}
|
||||||
rules: [{
|
{/* rules: [{*/}
|
||||||
required: true,
|
{/* required: true,*/}
|
||||||
message: 'Please input the package name'
|
{/* message: 'Please input the package name'*/}
|
||||||
}],
|
{/* }],*/}
|
||||||
})(
|
{/* })(*/}
|
||||||
<Input placeholder="Package Name"/>
|
{/* <Input placeholder="Package Name"/>*/}
|
||||||
)}
|
{/* )}*/}
|
||||||
</Form.Item>
|
{/* </Form.Item>*/}
|
||||||
)}
|
{/*)}*/}
|
||||||
|
|
||||||
{formConfig.specificElements.hasOwnProperty("url") && (
|
{formConfig.specificElements.hasOwnProperty("url") && (
|
||||||
<Form.Item {...formItemLayout} label="URL">
|
<Form.Item {...formItemLayout} label="URL">
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import 'react-quill/dist/quill.snow.css';
|
|||||||
import './LifeCycle.css';
|
import './LifeCycle.css';
|
||||||
import LifeCycleDetailsModal from "./lifeCycleDetailsModal/lifeCycleDetailsModal";
|
import LifeCycleDetailsModal from "./lifeCycleDetailsModal/lifeCycleDetailsModal";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
|
||||||
const {Text, Title, Paragraph} = Typography;
|
const {Text, Title, Paragraph} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -120,15 +121,7 @@ class LifeCycle extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to add lifecycle");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "Error",
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to add lifecycle",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isConfirmButtonLoading: false
|
isConfirmButtonLoading: false
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
import "./CustomNode.css";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component that renders a person's name and gender, along with icons
|
|
||||||
* representing if they have a driver license for bike and / or car.
|
|
||||||
* @param {Object} props component props to render.
|
|
||||||
*/
|
|
||||||
function CustomNode({ node }) {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="node" style={{backgroundColor: node.color}}>
|
|
||||||
<div className="name">{node.id}</div>
|
|
||||||
|
|
||||||
{/*<div className="flex-container fill-space flex-container-row">*/}
|
|
||||||
{/*<div className="fill-space">*/}
|
|
||||||
{/*<div*/}
|
|
||||||
{/*className="icon"*/}
|
|
||||||
{/*style={{ backgroundImage: `url('${isMale ? ICON_TYPES.MAN : ICON_TYPES.WOMAN}')` }}*/}
|
|
||||||
{/*/>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
|
|
||||||
{/*<div className="icon-bar">*/}
|
|
||||||
{/*{person.hasBike && (*/}
|
|
||||||
{/*<div className="icon" style={{ backgroundImage: `url('${ICON_TYPES.BIKE}')` }} />*/}
|
|
||||||
{/*)}*/}
|
|
||||||
{/*{person.hasCar && <div className="icon" style={{ backgroundImage: `url('${ICON_TYPES.CAR}')` }} />}*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CustomNode;
|
|
||||||
@ -24,6 +24,7 @@ import InfiniteScroll from 'react-infinite-scroller';
|
|||||||
import SingleReview from "./SingleReview";
|
import SingleReview from "./SingleReview";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
|
||||||
const limit = 5;
|
const limit = 5;
|
||||||
|
|
||||||
@ -58,16 +59,7 @@ class Reviews extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load reviews.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to load reviews.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import * as SRD from "storm-react-diagrams";
|
|
||||||
import "storm-react-diagrams/dist/style.min.css";
|
|
||||||
import "./LifeCycle.css";
|
|
||||||
import {distributeElements} from "../../../js/utils/dagre-utils.ts";
|
|
||||||
|
|
||||||
const inPortName = "IN";
|
|
||||||
const outPortName = "OUT";
|
|
||||||
|
|
||||||
class LifeCycleGraph extends React.Component {
|
|
||||||
render() {
|
|
||||||
|
|
||||||
const lifecycle = this.props.lifecycle;
|
|
||||||
const nodes = [];
|
|
||||||
const links = [];
|
|
||||||
|
|
||||||
const engine = new SRD.DiagramEngine();
|
|
||||||
engine.installDefaultFactories();
|
|
||||||
|
|
||||||
const model = new SRD.DiagramModel();
|
|
||||||
const nextStates = lifecycle[this.props.currentStatus].proceedingStates;
|
|
||||||
|
|
||||||
|
|
||||||
Object.keys(lifecycle).forEach((stateName) => {
|
|
||||||
let color = "rgb(83, 92, 104)";
|
|
||||||
if (stateName === this.props.currentStatus) {
|
|
||||||
color = "rgb(192,255,0)";
|
|
||||||
} else if (nextStates.includes(stateName)) {
|
|
||||||
color = "rgb(0,192,255)";
|
|
||||||
}
|
|
||||||
const node = createNode(stateName, color);
|
|
||||||
nodes.push(node);
|
|
||||||
lifecycle[stateName].node = node;
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(lifecycle).forEach((stateName) => {
|
|
||||||
const state = lifecycle[stateName];
|
|
||||||
//todo: remove checking property
|
|
||||||
if (state.hasOwnProperty("proceedingStates")) {
|
|
||||||
|
|
||||||
state.proceedingStates.forEach((proceedingState) => {
|
|
||||||
links.push(connectNodes(state.node, lifecycle[proceedingState].node));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
nodes.forEach((node) => {
|
|
||||||
model.addNode(node);
|
|
||||||
// node.addListener({
|
|
||||||
// selectionChanged: (node, isSelected) => {
|
|
||||||
// console.log(isSelected);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
links.forEach((link) => {
|
|
||||||
model.addLink(link);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let distributedModel = getDistributedModel(engine, model);
|
|
||||||
engine.setDiagramModel(distributedModel);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{height: 500}}>
|
|
||||||
<SRD.DiagramWidget diagramEngine={engine} maxNumberPointsPerLink={10} smartRouting={true}/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDistributedModel(engine, model) {
|
|
||||||
const serialized = model.serializeDiagram();
|
|
||||||
const distributedSerializedDiagram = distributeElements(serialized);
|
|
||||||
|
|
||||||
//deserialize the model
|
|
||||||
let deSerializedModel = new SRD.DiagramModel();
|
|
||||||
deSerializedModel.deSerializeDiagram(distributedSerializedDiagram, engine);
|
|
||||||
return deSerializedModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNode(name, color) {
|
|
||||||
const node = new SRD.DefaultNodeModel(name, color);
|
|
||||||
node.addPort(new SRD.DefaultPortModel(true, inPortName, " "));
|
|
||||||
node.addPort(new SRD.DefaultPortModel(false, outPortName, " "));
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
function connectNodes(nodeFrom, nodeTo) {
|
|
||||||
return nodeFrom.getPort(outPortName).link(nodeTo.getPort(inPortName));
|
|
||||||
}
|
|
||||||
|
|
||||||
function f() {
|
|
||||||
// console.log(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LifeCycleGraph;
|
|
||||||
@ -75,18 +75,7 @@ class ManagedConfigurationsIframe extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load configurations.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to load configurations.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({loading: false, visible: false});
|
this.setState({loading: false, visible: false});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -154,18 +143,7 @@ class ManagedConfigurationsIframe extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to update configurations.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to update configurations.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import axios from "axios";
|
|||||||
import {TweenOneGroup} from 'rc-tween-one';
|
import {TweenOneGroup} from 'rc-tween-one';
|
||||||
import pSBC from "shade-blend-color";
|
import pSBC from "shade-blend-color";
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../js/Utils";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
|
|
||||||
@ -69,12 +70,7 @@ class ManageCategories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occured while trying to load categories");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
message.warning('Something went wrong');
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
@ -116,17 +112,7 @@ class ManageCategories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load categories.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -264,17 +250,7 @@ class ManageCategories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to add categories.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -331,17 +307,7 @@ class ManageCategories extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to delete the category.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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,
|
||||||
editingValue: null
|
editingValue: null
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import {
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {TweenOneGroup} from 'rc-tween-one';
|
import {TweenOneGroup} from 'rc-tween-one';
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../js/Utils";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
|
|
||||||
@ -67,16 +68,7 @@ class ManageTags extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load tags.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -120,17 +112,7 @@ class ManageTags extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to delete the tag.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -265,17 +247,7 @@ class ManageTags extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to delete tag.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -332,17 +304,7 @@ class ManageTags extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to edit tag.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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,
|
||||||
editingValue: null
|
editingValue: null
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import {withRouter} from 'react-router-dom';
|
|||||||
import NewAppDetailsForm from "./subForms/NewAppDetailsForm";
|
import NewAppDetailsForm from "./subForms/NewAppDetailsForm";
|
||||||
import NewAppUploadForm from "./subForms/NewAppUploadForm";
|
import NewAppUploadForm from "./subForms/NewAppUploadForm";
|
||||||
import {withConfigContext} from "../../context/ConfigContext";
|
import {withConfigContext} from "../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../js/Utils";
|
||||||
|
|
||||||
const {Step} = Steps;
|
const {Step} = Steps;
|
||||||
|
|
||||||
@ -103,16 +104,7 @@ class AddNewAppFormComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Sorry, we were unable to complete your request.")
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "Something went wrong!",
|
|
||||||
description:
|
|
||||||
"Sorry, we were unable to complete your request.",
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
isError: true,
|
isError: true,
|
||||||
|
|||||||
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Upload, Icon, message } from 'antd';
|
|
||||||
|
|
||||||
function getBase64(img, callback) {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.addEventListener('load', () => callback(reader.result));
|
|
||||||
reader.readAsDataURL(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
function beforeUpload(file) {
|
|
||||||
const isJPG = file.type === 'image/jpeg';
|
|
||||||
if (!isJPG) {
|
|
||||||
message.error('You can only upload JPG file!');
|
|
||||||
}
|
|
||||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
||||||
if (!isLt2M) {
|
|
||||||
message.error('Image must smaller than 2MB!');
|
|
||||||
}
|
|
||||||
return isJPG && isLt2M;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class IconImage extends React.Component {
|
|
||||||
state = {
|
|
||||||
loading: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleChange = (info) => {
|
|
||||||
if (info.file.status === 'uploading') {
|
|
||||||
this.setState({ loading: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (info.file.status === 'done') {
|
|
||||||
// Get this url from response in real world.
|
|
||||||
getBase64(info.file.originFileObj, imageUrl => this.setState({
|
|
||||||
imageUrl,
|
|
||||||
loading: false,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const uploadButton = (
|
|
||||||
<div>
|
|
||||||
<Icon type={this.state.loading ? 'loading' : 'plus'} />
|
|
||||||
<div className="ant-upload-text">Upload</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
const imageUrl = this.state.imageUrl;
|
|
||||||
return (
|
|
||||||
<Upload
|
|
||||||
name="avatar"
|
|
||||||
listType="picture-card"
|
|
||||||
className="avatar-uploader"
|
|
||||||
showUploadList={false}
|
|
||||||
action="//jsonplaceholder.typicode.com/posts/"
|
|
||||||
beforeUpload={beforeUpload}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
>
|
|
||||||
{imageUrl ? <img src={imageUrl} alt="avatar" /> : uploadButton}
|
|
||||||
</Upload>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IconImage;
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Upload, Icon, Modal} from 'antd';
|
|
||||||
|
|
||||||
|
|
||||||
class UploadScreenshots extends React.Component {
|
|
||||||
state = {
|
|
||||||
previewVisible: false,
|
|
||||||
previewImage: '',
|
|
||||||
fileList: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
handleCancel = () => this.setState({ previewVisible: false });
|
|
||||||
|
|
||||||
handlePreview = (file) => {
|
|
||||||
this.setState({
|
|
||||||
previewImage: file.url || file.thumbUrl,
|
|
||||||
previewVisible: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleChange = ({ fileList }) => this.setState({ fileList });
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { previewVisible, previewImage, fileList } = this.state;
|
|
||||||
const uploadButton = (
|
|
||||||
<div>
|
|
||||||
<Icon type="plus" />
|
|
||||||
<div className="ant-upload-text">Upload</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div className="clearfix">
|
|
||||||
<Upload
|
|
||||||
action="//jsonplaceholder.typicode.com/posts/"
|
|
||||||
listType="picture-card"
|
|
||||||
fileList={fileList}
|
|
||||||
onPreview={this.handlePreview}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
>
|
|
||||||
{fileList.length >= 3 ? null : uploadButton}
|
|
||||||
</Upload>
|
|
||||||
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
|
|
||||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default UploadScreenshots;
|
|
||||||
@ -20,6 +20,7 @@ import React from "react";
|
|||||||
import {Button, Col, Divider, Form, Icon, Input, notification, Row, Select, Switch, Upload} from "antd";
|
import {Button, Col, Divider, Form, Icon, Input, notification, Row, Select, Switch, Upload} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../js/Utils";
|
||||||
|
|
||||||
const formItemLayout = {
|
const formItemLayout = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
@ -80,8 +81,6 @@ class NewAppDetailsForm extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.getCategories();
|
this.getCategories();
|
||||||
this.getTags();
|
|
||||||
this.getDeviceTypes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategories = () => {
|
getCategories = () => {
|
||||||
@ -96,18 +95,10 @@ class NewAppDetailsForm extends React.Component {
|
|||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.getTags();
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load categories.");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -126,18 +117,10 @@ class NewAppDetailsForm extends React.Component {
|
|||||||
loading: false,
|
loading: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.getDeviceTypes();
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load tags.");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
@ -180,17 +163,7 @@ class NewAppDetailsForm extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.log(error);
|
handleApiError(error, "Error occurred while trying to load device types.");
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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
|
||||||
});
|
});
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import {
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withRouter} from 'react-router-dom'
|
import {withRouter} from 'react-router-dom'
|
||||||
import {withConfigContext} from "../../context/ConfigContext";
|
import {withConfigContext} from "../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../js/Utils";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
const {TextArea} = Input;
|
const {TextArea} = Input;
|
||||||
@ -127,16 +128,7 @@ class AddNewReleaseFormComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Sorry, we were unable to complete your request.");
|
||||||
window.location.href = window.location.origin+ '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "Something went wrong!",
|
|
||||||
description:
|
|
||||||
"Sorry, we were unable to complete your request.",
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,16 +16,16 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {message, notification} from "antd";
|
import {notification} from "antd";
|
||||||
|
|
||||||
export const handleApiError = (error, message) => {
|
export const handleApiError = (error, message) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
||||||
message.error('You are not logged in');
|
const redirectUrl = encodeURI(window.location.href);
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
window.location.href = window.location.origin + `/publisher/login?redirect=${redirectUrl}`;
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: "There was a problem",
|
message: "There was a problem",
|
||||||
duration: 0,
|
duration: 10,
|
||||||
description: message,
|
description: message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import './Login.css';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import "./Login.css";
|
import "./Login.css";
|
||||||
import {withConfigContext} from "../context/ConfigContext";
|
import {withConfigContext} from "../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../js/Utils";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
@ -98,21 +99,15 @@ class NormalLoginForm extends React.Component {
|
|||||||
axios.post(window.location.origin+ config.serverConfig.loginUri, request
|
axios.post(window.location.origin+ config.serverConfig.loginUri, request
|
||||||
).then(res=>{
|
).then(res=>{
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
window.location = window.location.origin+"/publisher";
|
let redirectUrl = window.location.origin+"/publisher";
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
if(searchParams.has("redirect")){
|
||||||
|
redirectUrl = searchParams.get("redirect");
|
||||||
|
}
|
||||||
|
window.location = redirectUrl;
|
||||||
}
|
}
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 400) {
|
handleApiError(error, "Error occurred while trying to login.");
|
||||||
thisForm.setState({
|
|
||||||
inValid: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to login.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
thisForm.setState({
|
thisForm.setState({
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
@ -162,7 +157,7 @@ class NormalLoginForm extends React.Component {
|
|||||||
)}
|
)}
|
||||||
<br/>
|
<br/>
|
||||||
<a className="login-form-forgot" href="">Forgot password</a>
|
<a className="login-form-forgot" href="">Forgot password</a>
|
||||||
<Button block type="primary" htmlType="submit" className="login-form-button">
|
<Button loading={this.state.loading} block type="primary" htmlType="submit" className="login-form-button">
|
||||||
Log in
|
Log in
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@ -81,12 +81,12 @@ class Dashboard extends React.Component {
|
|||||||
>
|
>
|
||||||
<Menu.Item key="add-new-public-app">
|
<Menu.Item key="add-new-public-app">
|
||||||
<Link to="/publisher/add-new-app/public">
|
<Link to="/publisher/add-new-app/public">
|
||||||
Public APP
|
Public App
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="add-new-enterprise-app">
|
<Menu.Item key="add-new-enterprise-app">
|
||||||
<Link to="/publisher/add-new-app/enterprise">
|
<Link to="/publisher/add-new-app/enterprise">
|
||||||
Enterprise APP
|
Enterprise App
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="add-new-web-clip">
|
<Menu.Item key="add-new-web-clip">
|
||||||
@ -94,6 +94,11 @@ class Dashboard extends React.Component {
|
|||||||
Web Clip
|
Web Clip
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item key="add-new-custom-app">
|
||||||
|
<Link to="/publisher/add-new-app/custom-app">
|
||||||
|
Custom App
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
</SubMenu>
|
</SubMenu>
|
||||||
|
|
||||||
<SubMenu
|
<SubMenu
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Upload, Icon, Modal} from 'antd';
|
|
||||||
|
|
||||||
|
|
||||||
class AddTagModal extends React.Component {
|
|
||||||
state = {
|
|
||||||
previewVisible: false,
|
|
||||||
previewImage: '',
|
|
||||||
fileList: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
handleCancel = () => this.setState({ previewVisible: false });
|
|
||||||
|
|
||||||
handlePreview = (file) => {
|
|
||||||
this.setState({
|
|
||||||
previewImage: file.url || file.thumbUrl,
|
|
||||||
previewVisible: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleChange = ({ fileList }) => this.setState({ fileList });
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { previewVisible, previewImage, fileList } = this.state;
|
|
||||||
const uploadButton = (
|
|
||||||
<div>
|
|
||||||
<Icon type="plus" />
|
|
||||||
<div className="ant-upload-text">Upload</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div className="clearfix">
|
|
||||||
<Upload
|
|
||||||
action="//jsonplaceholder.typicode.com/posts/"
|
|
||||||
listType="picture-card"
|
|
||||||
fileList={fileList}
|
|
||||||
onPreview={this.handlePreview}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
>
|
|
||||||
{fileList.length >= 3 ? null : uploadButton}
|
|
||||||
</Upload>
|
|
||||||
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
|
|
||||||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default AddTagModal;
|
|
||||||
@ -23,6 +23,7 @@ import axios from 'axios';
|
|||||||
import ReleaseView from "../../../../components/apps/release/ReleaseView";
|
import ReleaseView from "../../../../components/apps/release/ReleaseView";
|
||||||
import LifeCycle from "../../../../components/apps/release/lifeCycle/LifeCycle";
|
import LifeCycle from "../../../../components/apps/release/lifeCycle/LifeCycle";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
|
|
||||||
@ -87,18 +88,7 @@ class Release extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load the release.");
|
||||||
//todo display a popop with error
|
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
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});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -118,16 +108,7 @@ class Release extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to load lifecycle configuration.");
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to load lifecycle configuration.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,6 @@ class Logout extends React.Component {
|
|||||||
window.location = window.location.origin + "/publisher/login";
|
window.location = window.location.origin + "/publisher/login";
|
||||||
}
|
}
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
|
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 400) {
|
if (error.hasOwnProperty("response") && error.response.status === 400) {
|
||||||
thisForm.setState({
|
thisForm.setState({
|
||||||
inValid: true
|
inValid: true
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import {withConfigContext} from "../../../../../context/ConfigContext";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Cluster from "../../../../../components/manage/android-enterprise/Pages/Cluster/Cluster";
|
import Cluster from "../../../../../components/manage/android-enterprise/Pages/Cluster/Cluster";
|
||||||
import EditLinks from "../../../../../components/manage/android-enterprise/Pages/EditLinks/EditLinks";
|
import EditLinks from "../../../../../components/manage/android-enterprise/Pages/EditLinks/EditLinks";
|
||||||
|
import {handleApiError} from "../../../../../js/Utils";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
const {Title, Text} = Typography;
|
const {Title, Text} = Typography;
|
||||||
@ -110,18 +111,7 @@ class Page extends React.Component {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
handleApiError(error, "Error occurred while trying to save the page name.");
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/publisher/login';
|
|
||||||
} else {
|
|
||||||
notification["error"]({
|
|
||||||
message: "There was a problem",
|
|
||||||
duration: 0,
|
|
||||||
description:
|
|
||||||
"Error occurred while trying to save the page name.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,25 +15,42 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
.app-icon {
|
||||||
|
min-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Shape for the nodes --- */
|
.box {
|
||||||
|
position: relative;
|
||||||
|
width: 100%; /* desired width */
|
||||||
|
}
|
||||||
|
|
||||||
.node {
|
.box:before {
|
||||||
width: 75px;
|
content: "";
|
||||||
height: 30px;
|
display: block;
|
||||||
border-radius: 20% 20% 20% 20%;
|
padding-top: 100%; /* initial ratio of 1:1*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-icon {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .release-icon img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 28%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release .app-name{
|
||||||
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
width: 100%;
|
||||||
display: flex;
|
text-overflow: ellipsis;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.node .name {
|
|
||||||
padding: 5%;
|
|
||||||
font-size: 0.5rem;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@
|
|||||||
import {Card, Typography, Col, Row} from 'antd';
|
import {Card, Typography, Col, Row} from 'antd';
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import "../../App.css";
|
import "./AppCard.css";
|
||||||
import StarRatings from 'react-star-ratings';
|
import StarRatings from 'react-star-ratings';
|
||||||
|
|
||||||
const {Meta} = Card;
|
const {Meta} = Card;
|
||||||
@ -29,11 +29,6 @@ class AppCard extends React.Component {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleReleasesClick = this.handleReleasesClick.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleReleasesClick() {
|
|
||||||
this.props.openReleasesModal(this.props.app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -45,12 +40,17 @@ class AppCard extends React.Component {
|
|||||||
<Link to={"/store/"+app.deviceType+"/apps/" + release.uuid}>
|
<Link to={"/store/"+app.deviceType+"/apps/" + release.uuid}>
|
||||||
<Row className="release">
|
<Row className="release">
|
||||||
<Col span={24} className="release-icon">
|
<Col span={24} className="release-icon">
|
||||||
<img src={release.iconPath} alt="icon"/>
|
<div className='box'>
|
||||||
|
<div className='content'>
|
||||||
|
<img className='app-icon' src={release.iconPath} alt="icon"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/*<img src={release.iconPath} alt="icon"/>*/}
|
||||||
{/*<Avatar shape="square" size={128} src={release.iconPath} />*/}
|
{/*<Avatar shape="square" size={128} src={release.iconPath} />*/}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24} style={{paddingTop:10}}>
|
||||||
<Text strong level={4}>{app.name}</Text><br/>
|
<Text className="app-name" strong level={4}>{app.name}</Text><br/>
|
||||||
<Text type="secondary" level={4}>{app.deviceType}</Text><br/>
|
<Text type="secondary" level={4}>{app.subMethod.toLowerCase()}</Text><br/>
|
||||||
<StarRatings
|
<StarRatings
|
||||||
rating={app.rating}
|
rating={app.rating}
|
||||||
starRatedColor="#777"
|
starRatedColor="#777"
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class ReleaseView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appOperation = (type, payload, operation) => {
|
appOperation = (type, payload, operation, timestamp=null) => {
|
||||||
const config = this.props.context;
|
const config = this.props.context;
|
||||||
const release = this.props.app.applicationReleases[0];
|
const release = this.props.app.applicationReleases[0];
|
||||||
const {uuid} = release;
|
const {uuid} = release;
|
||||||
@ -50,7 +50,11 @@ class ReleaseView extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
loading: true,
|
||||||
});
|
});
|
||||||
const url = window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/" + operation;
|
let url = window.location.origin+ config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/" + operation;
|
||||||
|
if(timestamp!= null){
|
||||||
|
url += `?timestamp=${timestamp}`;
|
||||||
|
}
|
||||||
axios.post(
|
axios.post(
|
||||||
url,
|
url,
|
||||||
payload,
|
payload,
|
||||||
@ -61,7 +65,8 @@ class ReleaseView extends React.Component {
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
appInstallModalVisible: false
|
appInstallModalVisible: false,
|
||||||
|
appUnInstallModalVisible: false,
|
||||||
});
|
});
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: 'Done!',
|
message: 'Done!',
|
||||||
|
|||||||
@ -18,13 +18,14 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {Button, message, notification, Table, Typography} from "antd";
|
import {Button, message, DatePicker, 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.
|
||||||
import en from 'javascript-time-ago/locale/en'
|
import en from 'javascript-time-ago/locale/en'
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -109,7 +110,9 @@ class DeviceInstall extends React.Component {
|
|||||||
data: [],
|
data: [],
|
||||||
pagination: {},
|
pagination: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
selectedRows: []
|
selectedRows: [],
|
||||||
|
scheduledTime: null,
|
||||||
|
isScheduledInstallVisible: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,11 +166,10 @@ class DeviceInstall extends React.Component {
|
|||||||
data: res.data.data.devices,
|
data: res.data.data.devices,
|
||||||
pagination,
|
pagination,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
handleApiError(error,"Error occurred while trying to load devices.");
|
handleApiError(error, "Error occurred while trying to load devices.");
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -187,7 +189,7 @@ class DeviceInstall extends React.Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
install = () => {
|
install = (timestamp=null) => {
|
||||||
const {selectedRows} = this.state;
|
const {selectedRows} = this.state;
|
||||||
const payload = [];
|
const payload = [];
|
||||||
selectedRows.map(device => {
|
selectedRows.map(device => {
|
||||||
@ -196,11 +198,11 @@ class DeviceInstall extends React.Component {
|
|||||||
type: device.type
|
type: device.type
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.props.onInstall("devices", payload, "install");
|
this.props.onInstall("devices", payload, "install",timestamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {data, pagination, loading, selectedRows} = this.state;
|
const {data, pagination, loading, selectedRows, scheduledTime,isScheduledInstallVisible} = this.state;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Text>
|
<Text>
|
||||||
@ -224,12 +226,7 @@ class DeviceInstall extends React.Component {
|
|||||||
rowSelection={this.rowSelection}
|
rowSelection={this.rowSelection}
|
||||||
scroll={{x: 1000}}
|
scroll={{x: 1000}}
|
||||||
/>
|
/>
|
||||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
<InstallModalFooter type="Install" operation={this.install} disabled={selectedRows.length === 0}/>
|
||||||
<Button disabled={selectedRows.length === 0} htmlType="button" type="primary"
|
|
||||||
onClick={this.install}>
|
|
||||||
Install
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,14 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {Button,Table, Typography} from "antd";
|
import {Button, Select, 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.
|
||||||
import en from 'javascript-time-ago/locale/en'
|
import en from 'javascript-time-ago/locale/en'
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -115,8 +116,8 @@ class DeviceUninstall extends React.Component {
|
|||||||
rowSelection = {
|
rowSelection = {
|
||||||
onChange: (selectedRowKeys, selectedRows) => {
|
onChange: (selectedRowKeys, selectedRows) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedRows: selectedRows
|
selectedRows: selectedRows
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getCheckboxProps: record => ({
|
getCheckboxProps: record => ({
|
||||||
disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
||||||
@ -151,7 +152,7 @@ class DeviceUninstall extends React.Component {
|
|||||||
|
|
||||||
const uuid = this.props.uuid;
|
const uuid = this.props.uuid;
|
||||||
axios.get(
|
axios.get(
|
||||||
window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/"+
|
window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" +
|
||||||
"/devices?" + encodedExtraParams,
|
"/devices?" + encodedExtraParams,
|
||||||
).then(res => {
|
).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
@ -163,7 +164,7 @@ class DeviceUninstall extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
handleApiError(error,"Error occurred while trying to load devices.");
|
handleApiError(error, "Error occurred while trying to load devices.");
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -172,59 +173,54 @@ class DeviceUninstall extends React.Component {
|
|||||||
const pager = {...this.state.pagination};
|
const pager = {...this.state.pagination};
|
||||||
pager.current = pagination.current;
|
pager.current = pagination.current;
|
||||||
this.setState({
|
this.setState({
|
||||||
pagination: pager,
|
pagination: pager,
|
||||||
});
|
});
|
||||||
this.fetch({
|
this.fetch({
|
||||||
results: pagination.pageSize,
|
results: pagination.pageSize,
|
||||||
page: pagination.current,
|
page: pagination.current,
|
||||||
sortField: sorter.field,
|
sortField: sorter.field,
|
||||||
sortOrder: sorter.order,
|
sortOrder: sorter.order,
|
||||||
...filters,
|
...filters,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
uninstall = () => {
|
uninstall = (timestamp = null) => {
|
||||||
const {selectedRows} = this.state;
|
const {selectedRows} = this.state;
|
||||||
const payload = [];
|
const payload = [];
|
||||||
selectedRows.map(device => {
|
selectedRows.map(device => {
|
||||||
payload.push({
|
payload.push({
|
||||||
id: device.deviceIdentifier,
|
id: device.deviceIdentifier,
|
||||||
type: device.type
|
type: device.type
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.props.onUninstall("devices", payload, "uninstall");
|
this.props.onUninstall("devices", payload, "uninstall", null);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {data, pagination, loading, selectedRows} = this.state;
|
const {data, pagination, loading, selectedRows} = this.state;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Text>
|
<Text>
|
||||||
Start uninstalling the application for devices by selecting the corresponding devices.
|
Start uninstalling the application for devices by selecting the corresponding devices.
|
||||||
Select uninstall to automatically start uninstalling the application for the respective devices.
|
Select uninstall to automatically start uninstalling the application for the respective devices.
|
||||||
</Text>
|
</Text>
|
||||||
<Table
|
<Table
|
||||||
style={{paddingTop: 20}}
|
style={{paddingTop: 20}}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey={record => record.deviceIdentifier}
|
rowKey={record => record.deviceIdentifier}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
pagination={{
|
pagination={{
|
||||||
...pagination,
|
...pagination,
|
||||||
size: "small",
|
size: "small",
|
||||||
showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
|
showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
|
||||||
}}
|
}}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onChange={this.handleTableChange}
|
onChange={this.handleTableChange}
|
||||||
rowSelection={this.rowSelection}
|
rowSelection={this.rowSelection}
|
||||||
scroll={{x: 1000}}
|
scroll={{x: 1000}}
|
||||||
/>
|
/>
|
||||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
<InstallModalFooter type="Uninstall" operation={this.uninstall} disabled={selectedRows.length === 0}/>
|
||||||
<Button disabled={selectedRows.length === 0} htmlType="button" type="primary"
|
</div>
|
||||||
onClick={this.uninstall}>
|
|
||||||
Uninstall
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -112,9 +113,7 @@ class GroupInstall extends React.Component {
|
|||||||
<Option key={d.value}>{d.text}</Option>
|
<Option key={d.value}>{d.text}</Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
<InstallModalFooter type="Install" operation={this.install} disabled={value.length===0}/>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -75,19 +76,19 @@ class GroupUninstall extends React.Component {
|
|||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
this.setState({
|
this.setState({
|
||||||
value,
|
value,
|
||||||
data: [],
|
data: [],
|
||||||
fetching: false,
|
fetching: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
install = () =>{
|
uninstall = (timestamp=null) =>{
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
const data = [];
|
const data = [];
|
||||||
value.map(val=>{
|
value.map(val=>{
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("group", data, "uninstall");
|
this.props.onUninstall("group", data, "uninstall",null);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -108,15 +109,12 @@ class GroupUninstall extends React.Component {
|
|||||||
filterOption={false}
|
filterOption={false}
|
||||||
onSearch={this.fetchUser}
|
onSearch={this.fetchUser}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
style={{width: '100%'}}
|
style={{width: '100%'}}>
|
||||||
>
|
|
||||||
{data.map(d => (
|
{data.map(d => (
|
||||||
<Option key={d.value}>{d.text}</Option>
|
<Option key={d.value}>{d.text}</Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
<InstallModalFooter type="Uninstall" operation={this.uninstall} disabled={value.length===0}/>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -79,13 +80,13 @@ class RoleInstall extends React.Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
install = () =>{
|
install = (timestamp=null) =>{
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
const data = [];
|
const data = [];
|
||||||
value.map(val=>{
|
value.map(val=>{
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("role", data, "install");
|
this.props.onInstall("role", data, "install", timestamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -112,9 +113,7 @@ class RoleInstall extends React.Component {
|
|||||||
<Option key={d.value}>{d.text}</Option>
|
<Option key={d.value}>{d.text}</Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
<InstallModalFooter type="Install" operation={this.install} disabled={value.length===0}/>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -80,17 +81,16 @@ class RoleUninstall extends React.Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
install = () =>{
|
uninstall = (timestamp=null) =>{
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
const data = [];
|
const data = [];
|
||||||
value.map(val=>{
|
value.map(val=>{
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("role", data, "uninstall");
|
this.props.onUninstall("role", data, "uninstall",null);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const {fetching, data, value} = this.state;
|
const {fetching, data, value} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -113,9 +113,7 @@ class RoleUninstall extends React.Component {
|
|||||||
<Option key={d.value}>{d.text}</Option>
|
<Option key={d.value}>{d.text}</Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
<InstallModalFooter type="Uninstall" operation={this.uninstall} disabled={value.length===0}/>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -81,13 +82,13 @@ class UserInstall extends React.Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
install = () => {
|
install = (timestamp=null) => {
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
const data = [];
|
const data = [];
|
||||||
value.map(val => {
|
value.map(val => {
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("user", data, "install");
|
this.props.onInstall("user", data, "install",timestamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -112,9 +113,7 @@ class UserInstall extends React.Component {
|
|||||||
<Option key={d.value}>{d.text}</Option>
|
<Option key={d.value}>{d.text}</Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
<InstallModalFooter type="Install" operation={this.install} disabled={value.length===0}/>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import debounce from 'lodash.debounce';
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../../js/Utils";
|
import {handleApiError} from "../../../../js/Utils";
|
||||||
|
import InstallModalFooter from "./installModalFooter/InstallModalFooter";
|
||||||
|
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
@ -49,9 +50,8 @@ class UserUninstall extends React.Component {
|
|||||||
const uuid = this.props.uuid;
|
const uuid = this.props.uuid;
|
||||||
|
|
||||||
axios.get(
|
axios.get(
|
||||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+
|
window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" +
|
||||||
"/USER?",
|
"/USER?",
|
||||||
|
|
||||||
).then(res => {
|
).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (fetchId !== this.lastFetchId) {
|
if (fetchId !== this.lastFetchId) {
|
||||||
@ -67,54 +67,53 @@ class UserUninstall extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
handleApiError(error,"Error occurred while trying to load users.");
|
handleApiError(error, "Error occurred while trying to load users.");
|
||||||
this.setState({fetching: false});
|
this.setState({fetching: false});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
this.setState({
|
this.setState({
|
||||||
value,
|
value,
|
||||||
data: [],
|
data: [],
|
||||||
fetching: false,
|
fetching: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
uninstall = () => {
|
uninstall = (timestamp=null) => {
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
const data = [];
|
const data = [];
|
||||||
value.map(val => {
|
value.map(val => {
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onUninstall("user", data, "uninstall");
|
this.props.onUninstall("user", data, "uninstall",null);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {fetching, data, value} = this.state;
|
const {fetching, data, value} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Text>Start uninstalling the application for one or more users by entering the corresponding user name. Select uninstall to automatically start uninstalling the application for the respective user/users. </Text>
|
<Text>Start uninstalling the application for one or more users by entering the corresponding user name.
|
||||||
<p>Select users</p>
|
Select uninstall to automatically start uninstalling the application for the respective
|
||||||
<Select
|
user/users. </Text>
|
||||||
mode="multiple"
|
<p>Select users</p>
|
||||||
labelInValue
|
<Select
|
||||||
value={value}
|
mode="multiple"
|
||||||
placeholder="Enter the username"
|
labelInValue
|
||||||
notFoundContent={fetching ? <Spin size="small"/> : null}
|
value={value}
|
||||||
filterOption={false}
|
placeholder="Enter the username"
|
||||||
onSearch={this.fetchUser}
|
notFoundContent={fetching ? <Spin size="small"/> : null}
|
||||||
onChange={this.handleChange}
|
filterOption={false}
|
||||||
style={{width: '100%'}}
|
onSearch={this.fetchUser}
|
||||||
>
|
onChange={this.handleChange}
|
||||||
{data.map(d => (
|
style={{width: '100%'}}>
|
||||||
<Option key={d.value}>{d.text}</Option>
|
{data.map(d => (
|
||||||
))}
|
<Option key={d.value}>{d.text}</Option>
|
||||||
</Select>
|
))}
|
||||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
</Select>
|
||||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.uninstall}>Uninstall</Button>
|
<InstallModalFooter type="Uninstall" operation={this.uninstall} disabled={value.length === 0}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import {Button, DatePicker} from "antd";
|
||||||
|
|
||||||
|
class InstallModalFooter extends React.Component{
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state={
|
||||||
|
scheduledTime: null,
|
||||||
|
isScheduledInstallVisible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDateTimeChange = (value, dateString) => {
|
||||||
|
this.setState({
|
||||||
|
scheduledTime: dateString
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
showScheduledInstall = ()=>{
|
||||||
|
this.setState({
|
||||||
|
isScheduledInstallVisible: true
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
hideScheduledInstall = ()=>{
|
||||||
|
this.setState({
|
||||||
|
isScheduledInstallVisible: false
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {scheduledTime,isScheduledInstallVisible} =this.state;
|
||||||
|
const {disabled, type} = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
textAlign: "right",
|
||||||
|
display: (!isScheduledInstallVisible)?'block':'none'
|
||||||
|
}}>
|
||||||
|
<Button style={{margin: 5}} disabled={disabled} htmlType="button" type="primary"
|
||||||
|
onClick={this.props.operation}>
|
||||||
|
{type}
|
||||||
|
</Button>
|
||||||
|
<Button style={{margin: 5}} disabled={disabled} htmlType="button"
|
||||||
|
onClick={this.showScheduledInstall}>
|
||||||
|
Scheduled {type}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
textAlign: "right",
|
||||||
|
display: (isScheduledInstallVisible)?'block':'none'
|
||||||
|
}}>
|
||||||
|
<DatePicker showTime
|
||||||
|
placeholder="Select Time"
|
||||||
|
format="YYYY-MM-DDTHH:mm"
|
||||||
|
onChange={this.onDateTimeChange}/>
|
||||||
|
<Button disabled={scheduledTime == null}
|
||||||
|
style={{margin: 5}}
|
||||||
|
htmlType="button"
|
||||||
|
type="primary"
|
||||||
|
onClick={()=>{
|
||||||
|
this.props.operation(scheduledTime);
|
||||||
|
}}>
|
||||||
|
Schedule
|
||||||
|
</Button>
|
||||||
|
<Button style={{margin: 5}} htmlType="button"
|
||||||
|
onClick={this.hideScheduledInstall}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InstallModalFooter;
|
||||||
@ -25,7 +25,7 @@ export const handleApiError = (error, message) => {
|
|||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: "There was a problem",
|
message: "There was a problem",
|
||||||
duration: 0,
|
duration: 2,
|
||||||
description: message,
|
description: message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user