diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/Utils.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/Utils.js index 9be2810b0f..d5b976499e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/Utils.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/Utils.js @@ -18,12 +18,12 @@ import {notification} from "antd"; -export const handleApiError = (error, message, isForbiddenMessageSilent) => { +export const handleApiError = (error, message, isForbiddenMessageSilent = false) => { if (error.hasOwnProperty("response") && error.response.status === 401) { const redirectUrl = encodeURI(window.location.href); window.location.href = window.location.origin + `/publisher/login?redirect=${redirectUrl}`; // silence 403 forbidden message - } else if(!(isForbiddenMessageSilent && error.hasOwnProperty("response") && error.response.status === 403)){ + } else if (!(isForbiddenMessageSilent && error.hasOwnProperty("response") && error.response.status === 403)) { notification["error"]({ message: "There was a problem", duration: 10, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/AppList.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/AppList.js index 241ea12acd..710821f324 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/AppList.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/AppList.js @@ -18,7 +18,7 @@ import React from "react"; import AppCard from "./AppCard"; -import {Col, message, notification, Row, Result, Skeleton} from "antd"; +import {Col, message, notification, Row, Result, Skeleton, Alert} from "antd"; import axios from "axios"; import {withConfigContext} from "../../context/ConfigContext"; import {handleApiError} from "../../js/Utils"; @@ -28,7 +28,10 @@ class AppList extends React.Component { super(props); this.state = { apps: [], - loading: true + loading: true, + forbiddenErrors: { + apps: false + } } } @@ -60,7 +63,7 @@ class AppList extends React.Component { }); //send request to the invoker axios.post( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/applications/", + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/applications/", payload, ).then(res => { if (res.status === 200) { @@ -73,18 +76,37 @@ class AppList extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load apps."); - this.setState({loading: false}); + handleApiError(error, "Error occurred while trying to load apps.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.apps = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; render() { - const {apps,loading} = this.state; + const {apps, loading, forbiddenErrors} = this.state; return ( - {apps.length === 0 && ( + {(forbiddenErrors.apps) && ( + Back Home} + /> + )} + {!((forbiddenErrors.apps)) && apps.length === 0 && ( { - handleApiError(error, "Something went wrong when trying to load subscription data."); - this.setState({loading: false}); + handleApiError(error, "Something went wrong when trying to load subscription data.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -197,6 +220,13 @@ class SubscriptionDetails extends React.Component { const {data, pagination, loading, selectedRows} = this.state; return (
+ {(this.state.isForbidden) && ( + + )}
The following are the subscription details of the application in each respective device. diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js index 3e67c54c03..ed69db96ef 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/DeviceInstall.js @@ -18,7 +18,7 @@ import React from "react"; import axios from "axios"; -import {Button, message, DatePicker, Table, Typography} from "antd"; +import {Button, message, DatePicker, Table, Typography, Alert} from "antd"; import TimeAgo from 'javascript-time-ago' // Load locale-specific relative date/time formatting rules. @@ -112,7 +112,8 @@ class DeviceInstall extends React.Component { loading: false, selectedRows: [], scheduledTime: null, - isScheduledInstallVisible: false + isScheduledInstallVisible: false, + isForbidden: false }; } @@ -169,8 +170,17 @@ class DeviceInstall extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load devices."); - this.setState({loading: false}); + handleApiError(error, "Error occurred while trying to load devices.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -209,6 +219,13 @@ class DeviceInstall extends React.Component { Start installing the application for one or more users by entering the corresponding user name. Select install to automatically start downloading the application for the respective user/users. + {(this.state.isForbidden) && ( + + )} { - handleApiError(error, "Error occurred while trying to load devices."); - this.setState({loading: false}); + handleApiError(error, "Error occurred while trying to load devices.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -204,6 +214,13 @@ class DeviceUninstall extends React.Component { Start uninstalling the application for devices by selecting the corresponding devices. Select uninstall to automatically start uninstalling the application for the respective devices. + {(this.state.isForbidden) && ( + + )}
{ @@ -67,8 +68,17 @@ class GroupInstall extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load groups."); - this.setState({fetching: false}); + handleApiError(error,"Error occurred while trying to load groups.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -96,6 +106,13 @@ class GroupInstall extends React.Component { return (
Start installing the application for one or more groups by entering the corresponding group name. Select install to automatically start downloading the application for the respective device group/ groups. + {(this.state.isForbidden) && ( + + )}

: null} - filterOption={false} - onSearch={this.fetchUser} - onChange={this.handleChange} - style={{width: '100%'}}> - {data.map(d => ( - - ))} - - -
+
+ Start uninstalling the application for one or more groups by entering the corresponding group + name. Select uninstall to automatically start uninstalling the application for the respective device + group/ groups. + {(this.state.isForbidden) && ( + + )} +
+
+ + +
); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js index 1b29d7dcb6..063311953a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/RoleInstall.js @@ -17,7 +17,7 @@ */ import React from "react"; -import {Typography, Select, Spin, message, notification, Button} from "antd"; +import {Typography, Select, Spin, message, notification, Button, Alert} from "antd"; import debounce from 'lodash.debounce'; import axios from "axios"; import {withConfigContext} from "../../../../context/ConfigContext"; @@ -40,6 +40,7 @@ class RoleInstall extends React.Component { data: [], value: [], fetching: false, + isForbidden: false }; fetchUser = value => { @@ -67,8 +68,17 @@ class RoleInstall extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load roles."); - this.setState({fetching: false}); + handleApiError(error,"Error occurred while trying to load roles.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -96,6 +106,13 @@ class RoleInstall extends React.Component { return (
Start installing the application for one or more roles by entering the corresponding role name. Select install to automatically start downloading the application for the respective user role/roles. + {(this.state.isForbidden) && ( + + )}

: null} - filterOption={false} - onSearch={this.fetchUser} - onChange={this.handleChange} - style={{width: '100%'}} - > - {data.map(d => ( - - ))} - - -
+
+ Start uninstalling the application for one or more roles by entering the corresponding role name. + Select uninstall to automatically start uninstalling the application for the respective user + role/roles. + {(this.state.isForbidden) && ( + + )} +
+
+ + +
); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js index 82f91bddff..ddac89bcab 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/install/UserInstall.js @@ -17,7 +17,7 @@ */ import React from "react"; -import {Typography, Select, Spin, message, notification, Button} from "antd"; +import {Typography, Select, Spin, message, notification, Button, Alert} from "antd"; import debounce from 'lodash.debounce'; import axios from "axios"; import {withConfigContext} from "../../../../context/ConfigContext"; @@ -69,8 +69,17 @@ class UserInstall extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load users."); - this.setState({fetching: false}); + handleApiError(error,"Error occurred while trying to load users.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbidden: true, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -79,6 +88,7 @@ class UserInstall extends React.Component { value, data: [], fetching: false, + isForbidden: false }); }; @@ -97,6 +107,13 @@ class UserInstall extends React.Component { return (
Start installing the application for one or more users by entering the corresponding user name. Select install to automatically start downloading the application for the respective user/users. + {(this.state.isForbidden) && ( + + )}

Select users

MY REVIEW -
- {currentUserReviews.length > 0 && ( -
- ( - - - - )} - > - -
- )} + {(this.props.forbidden) && ( + + )} + {(!this.props.forbidden) && ( +
+ {currentUserReviews.length > 0 && ( +
+ ( + + + + )} + > + +
+ )} - {currentUserReviews.length === 0 && ( -
- Share your experience with your community by adding a review. - } - > - {/**/} - - -
- )} - -
+ {currentUserReviews.length === 0 && ( +
+ Share your experience with your community by adding a review. + }> + {/**/} + + +
+ )} +
+ )}
); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/review/ReviewContainer.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/review/ReviewContainer.js index 2b8f124cb2..291d032939 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/review/ReviewContainer.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/review/ReviewContainer.js @@ -32,7 +32,12 @@ class ReviewContainer extends React.Component { super(props); this.state = { currentUserReviews: [], - detailedRating: null + detailedRating: null, + forbiddenErrors: { + currentReview: false, + reviews: false, + rating: false + } } } @@ -54,7 +59,19 @@ class ReviewContainer extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to get your review."); + handleApiError(error, "Error occurred while trying to get your review.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.currentReview = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -79,7 +96,7 @@ class ReviewContainer extends React.Component { } }).catch(function (error) { - handleApiError(error, "Error occurred while trying to load ratings."); + handleApiError(error, "Error occurred while trying to load ratings.", true); }); }; @@ -90,10 +107,11 @@ class ReviewContainer extends React.Component { render() { const {uuid} = this.props; - const {currentUserReviews,detailedRating} = this.state; + const {currentUserReviews,detailedRating, forbiddenErrors} = this.state; return (
{ @@ -60,8 +63,20 @@ class Reviews extends React.Component { callback(reviews); } - }).catch(function (error) { - handleApiError(error,"Error occurred while trying to load reviews."); + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load reviews.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.reviews = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -101,7 +116,7 @@ class Reviews extends React.Component { }); }; - deleteCallback = () =>{ + deleteCallback = () => { this.fetchData(0, limit, res => { this.setState({ data: res, @@ -114,30 +129,40 @@ class Reviews extends React.Component { const {loading, hasMore, data, loadMore} = this.state; const {uuid} = this.props; return ( -
- - ( - - - - )}> - {loading && hasMore && ( -
- -
- )} -
-
- {!loadMore && (data.length >= limit) && (
- -
)} +
+ {(this.state.forbiddenErrors.reviews) && ( + + )} +
+ + ( + + + + )}> + {loading && hasMore && ( +
+ +
+ )} +
+
+ {!loadMore && (data.length >= limit) && (
+ +
)} +
); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/js/Utils.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/js/Utils.js index 7bdcef3eea..aea3333985 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/js/Utils.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/js/Utils.js @@ -18,14 +18,15 @@ import {notification} from "antd"; -export const handleApiError = (error, message) => { +export const handleApiError = (error, message, isForbiddenMessageSilent = false) => { if (error.hasOwnProperty("response") && error.response.status === 401) { const redirectUrl = encodeURI(window.location.href); window.location.href = window.location.origin + `/store/login?redirect=${redirectUrl}`; - } else { + // silence 403 forbidden message + } else if (!(isForbiddenMessageSilent && error.hasOwnProperty("response") && error.response.status === 403)) { notification["error"]({ message: "There was a problem", - duration: 2, + duration: 10, description: message, }); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js index 30c7da2df1..b0a5108ddf 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/Dashboard.js @@ -17,7 +17,8 @@ */ import React from "react"; -import {Layout, Menu, Icon, Drawer, Button} from 'antd'; +import {Layout, Menu, Icon, Drawer, Button, Alert} from 'antd'; + const {Header, Content, Footer} = Layout; import {Link} from "react-router-dom"; import RouteWithSubRoutes from "../../components/RouteWithSubRoutes"; @@ -38,7 +39,10 @@ class Dashboard extends React.Component { selectedKeys: [], deviceTypes: [], visible: false, - collapsed: false + collapsed: false, + forbiddenErrors: { + deviceTypes: false + } }; this.logo = this.props.context.theme.logo; this.config = this.props.context; @@ -62,10 +66,19 @@ class Dashboard extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load device types."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load device types.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.deviceTypes = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -81,7 +94,7 @@ class Dashboard extends React.Component { collapsed: !this.state.collapsed, }); }; - + onCloseMobileNavigationBar = () => { this.setState({ visible: false, @@ -90,7 +103,7 @@ class Dashboard extends React.Component { render() { const config = this.props.context; - const {selectedKeys, deviceTypes} = this.state; + const {selectedKeys, deviceTypes, forbiddenErrors} = this.state; const DeviceTypesData = deviceTypes.map((deviceType) => { const platform = deviceType.name; @@ -116,7 +129,7 @@ class Dashboard extends React.Component {
- logo + logo
@@ -131,7 +144,7 @@ class Dashboard extends React.Component { - Web Clips + Web Clips @@ -140,7 +153,7 @@ class Dashboard extends React.Component { {this.config.user} - }> + }> @@ -156,32 +169,32 @@ class Dashboard extends React.Component {
- - logo - } - placement="left" - closable={false} - onClose={this.onCloseMobileNavigationBar} - visible={this.state.visible} - getContainer={false} - style={{position: 'absolute'}}> - - - {DeviceTypesData} - - - + + logo + } + placement="left" + closable={false} + onClose={this.onCloseMobileNavigationBar} + visible={this.state.visible} + getContainer={false} + style={{position: 'absolute'}}> + + + {DeviceTypesData} + + + Web Clips - - - - + + + + + {(forbiddenErrors.deviceTypes) && ( + + )} {this.state.routes.map((route) => ( diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/apps/release/Release.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/apps/release/Release.js index adac67e737..80cfe2b9cb 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/apps/release/Release.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/pages/dashboard/apps/release/Release.js @@ -36,7 +36,10 @@ class Release extends React.Component { this.state = { loading: true, app: null, - uuid: null + uuid: null, + forbiddenErrors: { + app: false + } }; } @@ -72,8 +75,19 @@ class Release extends React.Component { } }).catch((error) => { - handleApiError(error,"Error occurred while trying to load releases."); - this.setState({loading: false}); + handleApiError(error,"Error occurred while trying to load releases.", false); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.app = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); };