diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js
index de8bbf83578..e042def20da 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js
@@ -63,9 +63,6 @@ class FiltersForm extends React.Component {
delete values["deviceType"];
}
- if(values.hasOwnProperty("subscriptionType") && values.subscriptionType==="ALL"){
- delete values["subscriptionType"];
- }
if(values.hasOwnProperty("appType") && values.appType==="ALL"){
delete values["appType"];
}
@@ -271,17 +268,6 @@ class FiltersForm extends React.Component {
)}
-
-
- {getFieldDecorator('subscriptionType', {})(
-
- Free
- Paid
- All
- ,
- )}
-
-
);
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js
index aae593fb2af..24e43a89c61 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js
@@ -123,7 +123,8 @@ class AppsTable extends React.Component {
filters: {},
isDrawerVisible: false,
selectedApp: null,
- selectedAppIndex: -1
+ selectedAppIndex: -1,
+ loading: false
};
config = this.props.context;
}
@@ -222,14 +223,14 @@ class AppsTable extends React.Component {
onUpdateApp = (key, value) => {
const apps = [...this.state.apps];
- apps[this.state.selectedAppIndex][key]= value;
+ apps[this.state.selectedAppIndex][key] = value;
this.setState({
apps
});
};
render() {
- const {isDrawerVisible} = this.state;
+ const {isDrawerVisible, loading} = this.state;
return (
{
return {
onClick: event => {
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js
index 3230939c727..34384f7f24c 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js
@@ -132,7 +132,7 @@ class LifeCycle extends React.Component {
render() {
- const {currentStatus, selectedStatus} = this.state;
+ const {currentStatus, selectedStatus, isConfirmButtonLoading} = this.state;
const {lifecycle} = this.props;
const selectedValue = selectedStatus == null ? [] : selectedStatus;
let proceedingStates = [];
@@ -180,21 +180,17 @@ class LifeCycle extends React.Component {
type="primary"
htmlType="button"
onClick={this.showReasonModal}
- disabled={selectedStatus == null}
- >
+ loading={isConfirmButtonLoading}
+ disabled={selectedStatus == null}>
Change
-
-
-
+ okText="Confirm">
You are going to change the lifecycle state from,
{currentStatus}to {
- handleApiError(error, "Sorry, we were unable to complete your request.")
+ handleApiError(error, error.response.data.data);
this.setState({
loading: false,
isError: true,
- current: 2
+ current: 2,
+ errorText: error.response.data.data
});
});
@@ -149,7 +151,7 @@ class AddNewAppFormComponent extends React.Component {
};
render() {
- const {loading, current, isError, supportedOsVersions} = this.state;
+ const {loading, current, isError, supportedOsVersions, errorText} = this.state;
const {formConfig} = this.props;
return (
@@ -190,7 +192,7 @@ class AddNewAppFormComponent extends React.Component {
{isError && (
Back}
/>)}
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js
new file mode 100644
index 00000000000..1b6642f3d41
--- /dev/null
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js
@@ -0,0 +1,231 @@
+/*
+ * 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 axios from "axios";
+import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Button, Modal, Select} from "antd";
+import TimeAgo from 'javascript-time-ago'
+
+// Load locale-specific relative date/time formatting rules.
+import en from 'javascript-time-ago/locale/en'
+import {withConfigContext} from "../../../context/ConfigContext";
+
+const {Text} = Typography;
+
+let config = null;
+
+const columns = [
+ {
+ title: 'Device',
+ dataIndex: 'device',
+ width: 100,
+ render: device => device.name
+ },
+ {
+ title: 'Owner',
+ dataIndex: 'device',
+ key: 'owner',
+ render: device => device.enrolmentInfo.owner
+ },
+ {
+ title: 'Action Type',
+ dataIndex: 'actionType',
+ key: 'actionType',
+ render: actionType => actionType.toLowerCase()
+ },
+ {
+ title: 'Action',
+ dataIndex: 'action',
+ key: 'action',
+ render: action => action.toLowerCase()
+ },
+ {
+ title: 'Triggered By',
+ dataIndex: 'actionTriggeredBy',
+ key: 'actionTriggeredBy'
+ },
+ {
+ title: 'Action Triggered At',
+ dataIndex: 'actionTriggeredTimestamp',
+ key: 'actionTriggeredTimestamp'
+ },
+ {
+ title: 'Action Status',
+ dataIndex: 'status',
+ key: 'actionStatus',
+ render: (status) => {
+ let color = "#f9ca24";
+ switch (status) {
+ case "COMPLETED":
+ color = "#badc58";
+ break;
+ case "REPEATED":
+ color = "#6ab04c";
+ break;
+ case "ERROR":
+ case "INVALID":
+ case "UNAUTHORIZED":
+ color = "#ff7979";
+ break;
+ case "IN_PROGRESS":
+ color = "#f9ca24";
+ break;
+ case "PENDING":
+ color = "#636e72";
+ break;
+ }
+ return {status.toLowerCase()};
+ }
+ },
+ {
+ title: 'Device Status',
+ dataIndex: 'device',
+ key: 'deviceStatus',
+ render: (device) => {
+ const status = device.enrolmentInfo.status.toLowerCase();
+ let color = "#f9ca24";
+ switch (status) {
+ case "active":
+ color = "#badc58";
+ break;
+ case "created":
+ color = "#6ab04c";
+ break;
+ case "removed":
+ color = "#ff7979";
+ break;
+ case "inactive":
+ color = "#f9ca24";
+ break;
+ case "blocked":
+ color = "#636e72";
+ break;
+ }
+ return {status};
+ }
+ }
+];
+
+const getTimeAgo = (time) => {
+ const timeAgo = new TimeAgo('en-US');
+ return timeAgo.format(time);
+};
+
+
+class InstalledDevicesTable extends React.Component {
+ constructor(props) {
+ super(props);
+ config = this.props.context;
+ TimeAgo.addLocale(en);
+ this.state = {
+ data: [],
+ pagination: {},
+ loading: false,
+ selectedRows: [],
+ deviceGroups: [],
+ groupModalVisible: false,
+ selectedGroupId: []
+ };
+ }
+
+ componentDidMount() {
+ this.fetch();
+ }
+
+ //fetch data from api
+ fetch = (params = {}) => {
+ const config = this.props.context;
+ this.setState({loading: true});
+ // get current page
+ const currentPage = (params.hasOwnProperty("page")) ? params.page : 1;
+
+ const extraParams = {
+ offset: 10 * (currentPage - 1), //calculate the offset
+ limit: 10,
+ requireDeviceInfo: true,
+ };
+
+ const encodedExtraParams = Object.keys(extraParams)
+ .map(key => key + '=' + extraParams[key]).join('&');
+
+ //send request to the invoker
+ axios.get(
+ window.location.origin + config.serverConfig.invoker.uri +
+ config.serverConfig.invoker.store +
+ `/admin/subscription/${this.props.uuid}?` + encodedExtraParams,
+ ).then(res => {
+ if (res.status === 200) {
+ const pagination = {...this.state.pagination};
+ console.log(res.data.data.data);
+ this.setState({
+ loading: false,
+ data: res.data.data.data,
+ pagination,
+ });
+ }
+
+ }).catch((error) => {
+ if (error.hasOwnProperty("response") && error.response.status === 401) {
+ //todo display a popop with error
+ message.error('You are not logged in');
+ window.location.href = window.location.origin + '/entgra/login';
+ } else {
+ notification["error"]({
+ message: "There was a problem",
+ duration: 0,
+ description:
+ "Error occurred while trying to load devices.",
+ });
+ }
+
+ this.setState({loading: false});
+ });
+ };
+
+ render() {
+ const {data, pagination, loading, selectedRows} = this.state;
+ return (
+
+
+
+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
+ laudantium,
+ totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae
+ dicta sunt explicabo.
+
+
+
(record.device.deviceIdentifier + record.device.enrolmentInfo.owner + record.device.enrolmentInfo.ownership)}
+ dataSource={data}
+ pagination={{
+ ...pagination,
+ size: "small",
+ // position: "top",
+ showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
+ // showQuickJumper: true
+ }}
+ loading={loading}
+ scroll={{x: 1000}}
+ />
+
+ );
+ }
+}
+
+export default withConfigContext(InstalledDevicesTable);
\ No newline at end of file
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js
index 6994f16e476..51ab619df26 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js
@@ -17,7 +17,7 @@
*/
import React from "react";
-import {Divider, Row, Col, Typography, Button, Dropdown, notification, Menu, Icon, Spin} from "antd";
+import {Divider, Row, Col, Typography, Button, Dropdown, notification, Menu, Icon, Spin, Tabs} from "antd";
import "../../../App.css";
import ImgViewer from "../../apps/release/images/ImgViewer";
import StarRatings from "react-star-ratings";
@@ -30,8 +30,10 @@ import CurrentUsersReview from "./review/CurrentUsersReview";
import {withConfigContext} from "../../../context/ConfigContext";
import {handleApiError} from "../../../js/Utils";
import ReviewContainer from "./review/ReviewContainer";
+import InstalledDevicesTable from "./InstalledDevicesTable";
const {Title, Text, Paragraph} = Typography;
+const {TabPane} = Tabs;
class ReleaseView extends React.Component {
constructor(props) {
@@ -118,6 +120,12 @@ class ReleaseView extends React.Component {
metaData = JSON.parse(release.metaData);
} catch (e) {
+ }
+ if (app.hasOwnProperty("packageName")) {
+ metaData.push({
+ key: "Package Name",
+ value: app.packageName
+ });
}
const menu = (