From 6c784914824e859e4cdf5c06c1ae89e79363b251 Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Mon, 21 Oct 2019 17:00:46 +0530 Subject: [PATCH 01/10] Add loading animation to filter & lifecycle components in APPM --- .../components/apps/list-apps/appsTable/AppsTable.js | 8 +++++--- .../components/apps/release/lifeCycle/LifeCycle.js | 12 ++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) 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 aae593fb2a..24e43a89c6 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 3230939c72..34384f7f24 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 Date: Mon, 21 Oct 2019 21:50:12 +0530 Subject: [PATCH 02/10] Create UI to display installed devices --- .../apps/release/InstalledDevicesTable.js | 199 ++++++++++++++++++ .../components/apps/release/ReleaseView.js | 67 +++--- 2 files changed, 240 insertions(+), 26 deletions(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js 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 0000000000..6284808ef8 --- /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,199 @@ +/* + * 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: 'name', + width: 100, + }, + { + title: 'Owner', + dataIndex: 'enrolmentInfo', + key: 'owner', + render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Ownership', + dataIndex: 'enrolmentInfo', + key: 'ownership', + render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'Status', + dataIndex: 'enrolmentInfo', + key: 'status', + render: (enrolmentInfo) => { + const status = 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}; + } + // todo add filtering options + }, + { + title: 'Last Updated', + dataIndex: 'enrolmentInfo', + key: 'dateOfLastUpdate', + render: (data) => { + const {dateOfLastUpdate} = data; + const timeAgoString = getTimeAgo(dateOfLastUpdate); + return {timeAgoString}; + } + // todo add filtering options + } +]; + +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.deviceMgt + + "/devices?" + encodedExtraParams, + ).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.devices, + 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.deviceIdentifier + record.enrolmentInfo.owner + record.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 6994f16e47..a35ccb5e51 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 = ( @@ -171,31 +179,38 @@ class ReleaseView extends React.Component { - - - - - - - {release.description} - - - META DATA - - { - metaData.map((data, index) => { - return ( - - {data.key}
- {data.value} - - ) - }) - } - {(metaData.length === 0) && (No meta data available.)} - - - + + + + + + + + + {release.description} + + + META DATA + + { + metaData.map((data, index) => { + return ( + + {data.key}
+ {data.value} + + ) + }) + } + {(metaData.length === 0) && (No meta data available.)} + + + + + + + + ); From 951325ee75ff7d93ede759640b22345bb06d9e76 Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Tue, 22 Oct 2019 16:08:09 +0530 Subject: [PATCH 03/10] Add ui improvements to APPM Publisher UI The following changes are with this commit - View subscription status of devices in release view - Display server error response in add new app form --- .../src/components/new-app/AddNewAppForm.js | 12 ++- .../apps/release/InstalledDevicesTable.js | 94 +++++++++++++------ .../components/apps/release/ReleaseView.js | 2 +- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js index 6e731679e1..340d28aa93 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/AddNewAppForm.js @@ -54,7 +54,8 @@ class AddNewAppFormComponent extends React.Component { release: null, isError: false, deviceType: null, - supportedOsVersions: [] + supportedOsVersions: [], + errorText: "" }; } @@ -112,11 +113,12 @@ class AddNewAppFormComponent extends React.Component { } }).catch((error) => { - 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 index 6284808ef8..1b6642f3d4 100644 --- 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 @@ -32,29 +32,72 @@ let config = null; const columns = [ { title: 'Device', - dataIndex: 'name', + dataIndex: 'device', width: 100, + render: device => device.name }, { title: 'Owner', - dataIndex: 'enrolmentInfo', + dataIndex: 'device', key: 'owner', - render: enrolmentInfo => enrolmentInfo.owner - // todo add filtering options + render: device => device.enrolmentInfo.owner }, { - title: 'Ownership', - dataIndex: 'enrolmentInfo', - key: 'ownership', - render: enrolmentInfo => enrolmentInfo.ownership - // todo add filtering options + title: 'Action Type', + dataIndex: 'actionType', + key: 'actionType', + render: actionType => actionType.toLowerCase() }, { - title: 'Status', - dataIndex: 'enrolmentInfo', - key: 'status', - render: (enrolmentInfo) => { - const status = enrolmentInfo.status.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": @@ -75,18 +118,6 @@ const columns = [ } return {status}; } - // todo add filtering options - }, - { - title: 'Last Updated', - dataIndex: 'enrolmentInfo', - key: 'dateOfLastUpdate', - render: (data) => { - const {dateOfLastUpdate} = data; - const timeAgoString = getTimeAgo(dateOfLastUpdate); - return {timeAgoString}; - } - // todo add filtering options } ]; @@ -135,14 +166,15 @@ class InstalledDevicesTable extends React.Component { //send request to the invoker axios.get( window.location.origin + config.serverConfig.invoker.uri + - config.serverConfig.invoker.deviceMgt + - "/devices?" + encodedExtraParams, + 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.devices, + data: res.data.data.data, pagination, }); } @@ -169,7 +201,7 @@ class InstalledDevicesTable extends React.Component { const {data, pagination, loading, selectedRows} = this.state; return (
-
+
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, @@ -179,7 +211,7 @@ class InstalledDevicesTable extends React.Component {
(record.deviceIdentifier + record.enrolmentInfo.owner + record.enrolmentInfo.ownership)} + rowKey={record => (record.device.deviceIdentifier + record.device.enrolmentInfo.owner + record.device.enrolmentInfo.ownership)} dataSource={data} pagination={{ ...pagination, 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 a35ccb5e51..51ab619df2 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 @@ -208,7 +208,7 @@ class ReleaseView extends React.Component { - + From e762d35a74a07a72b09ba8831bd93e5439a290cc Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Tue, 22 Oct 2019 22:28:44 +0530 Subject: [PATCH 04/10] Remove subscription type from APPM publisher filter UI --- .../src/components/apps/list-apps/Filters.js | 14 -------------- 1 file changed, 14 deletions(-) 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 de8bbf8357..e042def20d 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 - , - )} - - ); From cd062f0788d37954d5d4bf869d71b0dfb1a219a3 Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Thu, 24 Oct 2019 16:56:24 +0530 Subject: [PATCH 05/10] Add UI improvements to APPM UI The following changes are with this commit - Fix wrong 401 redirection in Subscription details table - Add pagination to releases list in App Details Drawer - Show published badge on app icon in apps table and releases list --- .../AppDetailsDrawer/AppDetailsDrawer.js | 55 +++++++++++++++---- .../apps/list-apps/appsTable/AppsTable.js | 32 +++++++++-- .../apps/release/InstalledDevicesTable.js | 20 +------ .../components/apps/release/ReleaseView.js | 5 +- 4 files changed, 76 insertions(+), 36 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js index 335e1c46dd..fc54ab399b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js @@ -30,7 +30,7 @@ import { Spin, message, Icon, - Card + Card, Badge } from 'antd'; import DetailedRating from "../../detailed-rating/DetailedRating"; import {Link} from "react-router-dom"; @@ -487,18 +487,14 @@ class AppDetailsDrawer extends React.Component { )} Releases - {/*display add new release only if app type is enterprise*/} -
- - {(app.type === "ENTERPRISE") && ( - )} (
@@ -507,7 +503,27 @@ class AppDetailsDrawer extends React.Component { +
+ {(release.currentStatus === "PUBLISHED") ? ( + + }> + + + ) : ( + + )} +
} title={release.version} description={ @@ -529,10 +545,27 @@ class AppDetailsDrawer extends React.Component {
)} /> -
+ {/*display add new release only if app type is enterprise*/} + {(app.type === "ENTERPRISE") && ( +
+
+ + Add new release for the application + +
+ + + +
)} + Description {!isDescriptionEditEnabled && ( 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 24e43a89c6..d008cf5609 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 @@ -17,7 +17,7 @@ */ import React from "react"; -import {Avatar, Table, Tag, Icon, message, notification, Col} from "antd"; +import {Avatar, Table, Tag, Icon, message, notification, Col, Badge} from "antd"; import axios from "axios"; import pSBC from 'shade-blend-color'; import "./AppsTable.css"; @@ -47,7 +47,31 @@ const columns = [ ); } else { - avatar = ( + const {applicationReleases} = row; + let hasPublishedRelease = false; + for (let i = 0; i < applicationReleases.length; i++) { + if (applicationReleases[i].currentStatus === "PUBLISHED") { + hasPublishedRelease = true; + break; + } + } + avatar = (hasPublishedRelease) ? ( + + }> + + + ) : ( - ) + ); } return (
{avatar} - {name} + {name}
); } }, 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 index 1b6642f3d4..39fd3ef27c 100644 --- 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 @@ -24,6 +24,7 @@ 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"; +import {handleApiError} from "../../../js/Utils"; const {Text} = Typography; @@ -180,19 +181,7 @@ class InstalledDevicesTable extends React.Component { } }).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.", - }); - } - + handleApiError(error, "Something went wrong when trying to load subscription data."); this.setState({loading: false}); }); }; @@ -203,10 +192,7 @@ class InstalledDevicesTable extends React.Component {
- 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. + The following are the subscription details of the application in each respective device.
- + From 9dd7444cd7b78c0735266a174a631280b0089601 Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Sat, 26 Oct 2019 11:33:03 +0530 Subject: [PATCH 06/10] Add unrestricted roles field to Add new app form --- .../react-app/package.json | 3 +- .../AppDetailsDrawer/AppDetailsDrawer.js | 6 +- .../apps/list-apps/appsTable/AppsTable.js | 1 - .../new-app/subForms/NewAppDetailsForm.js | 106 ++++++++++++++---- .../apps/release/install/RoleInstall.js | 3 +- 5 files changed, 93 insertions(+), 26 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index dece5f9363..dbba25e052 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -39,7 +39,8 @@ "redux-thunk": "^2.3.0", "shade-blend-color": "^1.0.0", "storm-react-diagrams": "^5.2.1", - "typescript": "^3.6.4" + "typescript": "^3.6.4", + "lodash.debounce": "latest" }, "devDependencies": { "@babel/core": "^7.5.0", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js index fc54ab399b..6e5e6b4816 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/AppDetailsDrawer/AppDetailsDrawer.js @@ -509,8 +509,8 @@ class AppDetailsDrawer extends React.Component { title="Published" style={{ backgroundColor: '#52c41a', - borderRadius:"50%", - color:"white" + borderRadius: "50%", + color: "white" }} count={ - {/*display add new release only if app type is enterprise*/} {(app.type === "ENTERPRISE") && (
+
Add new release for the application 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 d008cf5609..faaaf7b99d 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 @@ -74,7 +74,6 @@ const columns = [ ) : ( { e.preventDefault(); const {formConfig} = this.props; @@ -58,13 +62,17 @@ class NewAppDetailsForm extends React.Component { this.setState({ loading: true }); - const {name, description, categories, tags, price, isSharedWithAllTenants, binaryFile, icon, screenshots, releaseDescription, releaseType} = values; + const {name, description, categories, tags, unrestrictedRoles} = values; + const unrestrictedRolesData = []; + unrestrictedRoles.map(val=>{ + unrestrictedRolesData.push(val.key); + }); const application = { name, description, categories, tags, - unrestrictedRoles: [], + unrestrictedRoles: unrestrictedRolesData, }; if (formConfig.installationType !== "WEB_CLIP") { @@ -141,15 +149,15 @@ class NewAppDetailsForm extends React.Component { const allowedDeviceTypes = []; // exclude mobile device types if installation type is custom - if(installationType==="CUSTOM"){ - allDeviceTypes.forEach(deviceType=>{ - if(!mobileDeviceTypes.includes(deviceType.name)){ + if (installationType === "CUSTOM") { + allDeviceTypes.forEach(deviceType => { + if (!mobileDeviceTypes.includes(deviceType.name)) { allowedDeviceTypes.push(deviceType); } }); - }else{ - allDeviceTypes.forEach(deviceType=>{ - if(mobileDeviceTypes.includes(deviceType.name)){ + } else { + allDeviceTypes.forEach(deviceType => { + if (mobileDeviceTypes.includes(deviceType.name)) { allowedDeviceTypes.push(deviceType); } }); @@ -168,9 +176,49 @@ class NewAppDetailsForm extends React.Component { }); }; + fetchRoles = value => { + const config = this.props.context; + this.lastFetchId += 1; + const fetchId = this.lastFetchId; + this.setState({data: [], fetching: true}); + + axios.get( + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + "/roles?filter=" + value, + ).then(res => { + if (res.status === 200) { + if (fetchId !== this.lastFetchId) { + // for fetch callback order + return; + } + + const data = res.data.data.roles.map(role => ({ + text: role, + value: role, + })); + + this.setState({ + unrestrictedRoles: data, + fetching: false + }); + } + + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load roles."); + this.setState({fetching: false}); + }); + }; + + handleRoleSearch = roleSearchValue => { + this.setState({ + roleSearchValue, + unrestrictedRoles: [], + fetching: false, + }); + }; + render() { const {formConfig} = this.props; - const {categories, tags, deviceTypes} = this.state; + const {categories, tags, deviceTypes, fetching, roleSearchValue, unrestrictedRoles} = this.state; const {getFieldDecorator} = this.props.form; return ( @@ -198,8 +246,7 @@ class NewAppDetailsForm extends React.Component {