diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js index 2ef88827be..dba024f2ed 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/detailed-rating/DetailedRating.js @@ -61,7 +61,7 @@ class DetailedRating extends React.Component{ } }).catch(function (error) { - handleApiError(error, "Error occurred while trying to load rating for the release."); + handleApiError(error, "Error occurred while trying to load rating for the release.", true); }); }; 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 6e5e6b4816..7eaea07d32 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 @@ -136,7 +136,7 @@ class AppDetailsDrawer extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load app details."); + handleApiError(error, "Error occurred while trying to load categories.", true); this.setState({ loading: false }); 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 e042def20d..14c76e24a7 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 @@ -30,7 +30,7 @@ import { Form, message, Radio, - notification + notification, Alert } from "antd"; import axios from "axios"; import {withConfigContext} from "../../../context/ConfigContext"; @@ -46,7 +46,12 @@ class FiltersForm extends React.Component { this.state = { categories: [], tags: [], - deviceTypes: [] + deviceTypes: [], + forbiddenErrors: { + categories: false, + tags: false, + deviceTypes: false + } }; } @@ -59,11 +64,11 @@ class FiltersForm extends React.Component { } } - if(values.hasOwnProperty("deviceType") && values.deviceType==="ALL"){ + if (values.hasOwnProperty("deviceType") && values.deviceType === "ALL") { delete values["deviceType"]; } - if(values.hasOwnProperty("appType") && values.appType==="ALL"){ + if (values.hasOwnProperty("appType") && values.appType === "ALL") { delete values["appType"]; } @@ -73,16 +78,17 @@ class FiltersForm extends React.Component { componentDidMount() { this.getCategories(); + this.getTags(); + this.getDeviceTypes(); } getCategories = () => { const config = this.props.context; axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories" + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories" ).then(res => { if (res.status === 200) { let categories = JSON.parse(res.data.data); - this.getTags(); this.setState({ categories: categories, loading: false @@ -90,21 +96,29 @@ class FiltersForm extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load categories."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load categories.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.categories = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; getTags = () => { const config = this.props.context; axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags" + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags" ).then(res => { if (res.status === 200) { let tags = JSON.parse(res.data.data); - this.getDeviceTypes(); this.setState({ tags: tags, loading: false, @@ -112,10 +126,19 @@ class FiltersForm extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load tags."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load tags.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.tags = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -123,7 +146,7 @@ class FiltersForm extends React.Component { getDeviceTypes = () => { const config = this.props.context; axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + "/device-types" + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + "/device-types" ).then(res => { if (res.status === 200) { const deviceTypes = JSON.parse(res.data.data); @@ -134,15 +157,24 @@ class FiltersForm 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 + }); + } }); }; render() { - const {categories, tags, deviceTypes} = this.state; + const {categories, tags, deviceTypes, forbiddenErrors} = this.state; const {getFieldDecorator} = this.props.form; return ( @@ -170,7 +202,13 @@ class FiltersForm extends React.Component { - + {(forbiddenErrors.categories) && ( + + )} {getFieldDecorator('categories', { rules: [{ @@ -182,8 +220,7 @@ class FiltersForm extends React.Component { mode="multiple" style={{width: '100%'}} placeholder="Select a Category" - onChange={this.handleCategoryChange} - > + onChange={this.handleCategoryChange}> { categories.map(category => { return ( @@ -198,7 +235,13 @@ class FiltersForm extends React.Component { )} - + {(forbiddenErrors.deviceTypes) && ( + + )} {getFieldDecorator('deviceType', { rules: [{ @@ -208,8 +251,7 @@ class FiltersForm extends React.Component { })( )} - + {(forbiddenErrors.tags) && ( + + )} {getFieldDecorator('tags', { rules: [{ 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 faaaf7b99d..01d6c8c159 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, Badge} from "antd"; +import {Avatar, Table, Tag, Icon, message, notification, Col, Badge, Alert} from "antd"; import axios from "axios"; import pSBC from 'shade-blend-color'; import "./AppsTable.css"; @@ -58,7 +58,7 @@ const columns = [ avatar = (hasPublishedRelease) ? ( @@ -147,7 +147,8 @@ class AppsTable extends React.Component { isDrawerVisible: false, selectedApp: null, selectedAppIndex: -1, - loading: false + loading: false, + isForbiddenErrorVisible: false }; config = this.props.context; } @@ -239,7 +240,12 @@ class AppsTable extends React.Component { }); } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load apps."); + handleApiError(error, "Error occurred while trying to load apps.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + this.setState({ + isForbiddenErrorVisible: true + }) + } this.setState({loading: false}); }); }; @@ -255,29 +261,37 @@ class AppsTable extends React.Component { render() { const {isDrawerVisible, loading} = this.state; return ( -
- record.id} - dataSource={this.state.apps} - columns={columns} - pagination={this.state.pagination} - onChange={this.handleTableChange} - rowClassName="app-row" - loading={loading} - onRow={(record, rowIndex) => { - return { - onClick: event => { - this.showDrawer(record, rowIndex); - }, - }; - }}/> - +
+ {(this.state.isForbiddenErrorVisible) && ( + + )} +
+
record.id} + dataSource={this.state.apps} + columns={columns} + pagination={this.state.pagination} + onChange={this.handleTableChange} + rowClassName="app-row" + loading={loading} + onRow={(record, rowIndex) => { + return { + onClick: event => { + this.showDrawer(record, rowIndex); + }, + }; + }}/> + + - ); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js index 0c208c776b..6ea67eee20 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/ReleaseView.js @@ -24,6 +24,7 @@ import "../../../App.css"; import DetailedRating from "../detailed-rating/DetailedRating"; import EditRelease from "./edit-release/EditRelease"; import {withConfigContext} from "../../../context/ConfigContext"; +import NewAppUploadForm from "../../new-app/subForms/NewAppUploadForm"; const {Title, Text, Paragraph} = Typography; @@ -97,6 +98,7 @@ class ReleaseView extends React.Component { Version : {release.version}
{(config.deviceTypes.mobileTypes.includes(deviceType)) && ( - - {getFieldDecorator('supportedOS')( -
- - -
- - {getFieldDecorator('lowerOsVersion', { - rules: [{ - required: true, - message: 'Please select Value' - }], - })( - - )} - - - -

-

- - - - {getFieldDecorator('upperOsVersion', { - rules: [{ - required: true, - message: 'Please select Value' - }], - })( - - )} - - - - - - +
+ {(this.props.forbiddenErrors.supportedOsVersions) && ( + )} - + + {getFieldDecorator('supportedOS')( +
+ + +
+ + {getFieldDecorator('lowerOsVersion', { + rules: [{ + required: true, + message: 'Please select Value' + }], + })( + + )} + + + +

-

+ + + + {getFieldDecorator('upperOsVersion', { + rules: [{ + required: true, + message: 'Please select Value' + }], + })( + + )} + + + + + + + )} + + )} {getFieldDecorator('meta', { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/review/Reviews.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/review/Reviews.js index 0e75a3d663..53aa43d298 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/review/Reviews.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/review/Reviews.js @@ -17,7 +17,7 @@ */ import React from "react"; -import {List, message, Avatar, Spin, Button, notification} from 'antd'; +import {List, message, Avatar, Spin, Button, notification, Alert} from 'antd'; import "./Reviews.css"; import InfiniteScroll from 'react-infinite-scroller'; @@ -33,7 +33,10 @@ class Reviews extends React.Component { data: [], loading: false, hasMore: false, - loadMore: false + loadMore: false, + forbiddenErrors: { + reviews: false + } }; @@ -49,17 +52,34 @@ class Reviews extends React.Component { const config = this.props.context; const {uuid, type} = this.props; - + this.setState({ + loading: true + }); axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/reviews/" + type + "/" + uuid + window.location.origin + + config.serverConfig.invoker.uri + + config.serverConfig.invoker.publisher + + "/admin/reviews/" + type + "/" + uuid ).then(res => { if (res.status === 200) { let reviews = res.data.data.data; 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,32 +121,39 @@ class Reviews extends React.Component { render() { return ( -
- - ( - - - - )} - > - {this.state.loading && this.state.hasMore && ( -
- -
- )} -
-
- {!this.state.loadMore && (this.state.data.length >= limit) && (
- -
)} +
+ {(this.state.forbiddenErrors.reviews) && ( + + )} +
+ + ( + + + + )}> + {this.state.loading && this.state.hasMore && ( +
+ +
+ )} +
+
+ {!this.state.loadMore && (this.state.data.length >= limit) && (
+ +
)} +
); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageCategories.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageCategories.js index 984cd5d67d..a4de159263 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageCategories.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageCategories.js @@ -32,7 +32,7 @@ import { Modal, Row, Col, - Typography + Typography, Alert } from "antd"; import axios from "axios"; import {TweenOneGroup} from 'rc-tween-one'; @@ -53,13 +53,16 @@ class ManageCategories extends React.Component { isAddNewVisible: false, isEditModalVisible: false, currentlyEditingId: null, - editingValue: null + editingValue: null, + forbiddenErrors: { + categories: false + } }; componentDidMount() { const config = this.props.context; axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories", + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/categories", ).then(res => { if (res.status === 200) { let categories = JSON.parse(res.data.data); @@ -70,10 +73,19 @@ class ManageCategories extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occured while trying to load categories"); - this.setState({ - loading: false - }); + handleApiError(error, "Error occured while trying to load categories", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.categories = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); } @@ -90,7 +102,7 @@ class ManageCategories extends React.Component { loading: true }); axios.delete( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/" + id, + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/" + id, ).then(res => { if (res.status === 200) { notification["success"]({ @@ -125,8 +137,7 @@ class ManageCategories extends React.Component { const tagElem = ( + style={{marginTop: 8}}> {categoryName} @@ -150,8 +161,7 @@ class ManageCategories extends React.Component { } }} okText="Yes" - cancelText="No" - > + cancelText="No"> @@ -168,7 +178,7 @@ class ManageCategories extends React.Component { const config = this.props.context; const tagElem = ( { e.preventDefault(); @@ -229,7 +239,7 @@ class ManageCategories extends React.Component { const data = tempElements.map(category => category.categoryName); axios.post( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories", + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories", data, ).then(res => { if (res.status === 200) { @@ -287,7 +297,7 @@ class ManageCategories extends React.Component { }); axios.put( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/rename?from=" + currentlyEditingId + "&to=" + editingValue, + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/categories/rename?from=" + currentlyEditingId + "&to=" + editingValue, {}, ).then(res => { if (res.status === 200) { @@ -324,11 +334,18 @@ class ManageCategories extends React.Component { }; render() { - const {categories, inputVisible, inputValue, tempElements, isAddNewVisible} = this.state; + const {categories, inputVisible, inputValue, tempElements, isAddNewVisible, forbiddenErrors} = this.state; const categoriesElements = categories.map(this.renderElement); const temporaryElements = tempElements.map(this.renderTempElement); return (
+ {(forbiddenErrors.categories) && ( + + )} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageTags.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageTags.js index 69c269bc17..8b9ed800b1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageTags.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/manage/categories/ManageTags.js @@ -31,7 +31,7 @@ import { Popconfirm, Modal, Row, Col, - Typography + Typography, Alert } from "antd"; import axios from "axios"; import {TweenOneGroup} from 'rc-tween-one'; @@ -51,13 +51,16 @@ class ManageTags extends React.Component { isAddNewVisible: false, isEditModalVisible: false, currentlyEditingId: null, - editingValue: null + editingValue: null, + forbiddenErrors: { + tags: false + } }; componentDidMount() { const config = this.props.context; axios.get( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags", + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags", ).then(res => { if (res.status === 200) { let tags = JSON.parse(res.data.data); @@ -68,10 +71,19 @@ class ManageTags extends React.Component { } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load tags."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load tags.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.tags = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); } @@ -90,7 +102,7 @@ class ManageTags extends React.Component { }); axios.delete( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/tags/" + id + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/admin/applications/tags/" + id ).then(res => { if (res.status === 200) { notification["success"]({ @@ -124,7 +136,7 @@ class ManageTags extends React.Component { const tagElem = ( {tagName} @@ -167,7 +179,7 @@ class ManageTags extends React.Component { const {tempElements} = this.state; const tagElem = ( { e.preventDefault(); @@ -226,7 +238,7 @@ class ManageTags extends React.Component { const data = tempElements.map(tag => tag.tagName); - axios.post(window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags", + axios.post(window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags", data, ).then(res => { if (res.status === 200) { @@ -284,7 +296,7 @@ class ManageTags extends React.Component { }); axios.put( - window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags/rename?from=" + currentlyEditingId + "&to=" + editingValue, + window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/tags/rename?from=" + currentlyEditingId + "&to=" + editingValue, {}, ).then(res => { if (res.status === 200) { @@ -321,11 +333,18 @@ class ManageTags extends React.Component { }; render() { - const {tags, inputVisible, inputValue, tempElements, isAddNewVisible} = this.state; + const {tags, inputVisible, inputValue, tempElements, isAddNewVisible, forbiddenErrors} = this.state; const tagsElements = tags.map(this.renderElement); const temporaryElements = tempElements.map(this.renderTempElement); return (
+ {(forbiddenErrors.tags) && ( + + )} @@ -365,8 +384,7 @@ class ManageTags extends React.Component { }, }} leave={{opacity: 0, width: 0, scale: 0, duration: 200}} - appear={false} - > + appear={false}> {temporaryElements} {inputVisible && ( 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 340d28aa93..39dc99ddb1 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 @@ -55,7 +55,10 @@ class AddNewAppFormComponent extends React.Component { isError: false, deviceType: null, supportedOsVersions: [], - errorText: "" + errorText: "", + forbiddenErrors: { + supportedOsVersions: false + } }; } @@ -143,15 +146,24 @@ class AddNewAppFormComponent extends React.Component { }); } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load supported OS versions."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load supported OS versions.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.supportedOsVersions = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; render() { - const {loading, current, isError, supportedOsVersions, errorText} = this.state; + const {loading, current, isError, supportedOsVersions, errorText, forbiddenErrors} = this.state; const {formConfig} = this.props; return (
@@ -171,6 +183,7 @@ class AddNewAppFormComponent extends React.Component {
{ @@ -64,7 +70,7 @@ class NewAppDetailsForm extends React.Component { }); const {name, description, categories, tags, unrestrictedRoles} = values; const unrestrictedRolesData = []; - unrestrictedRoles.map(val=>{ + unrestrictedRoles.map(val => { unrestrictedRolesData.push(val.key); }); const application = { @@ -89,6 +95,8 @@ class NewAppDetailsForm extends React.Component { componentDidMount() { this.getCategories(); + this.getTags(); + this.getDeviceTypes(); } getCategories = () => { @@ -103,13 +111,20 @@ class NewAppDetailsForm extends React.Component { loading: false }); } - this.getTags(); - }).catch((error) => { - handleApiError(error, "Error occurred while trying to load categories."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load categories.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.categories = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -125,13 +140,20 @@ class NewAppDetailsForm extends React.Component { loading: false, }); } - this.getDeviceTypes(); - }).catch((error) => { - handleApiError(error, "Error occurred while trying to load tags."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load tags.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.tags = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -169,10 +191,19 @@ class NewAppDetailsForm 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 + }); + } }); }; @@ -203,8 +234,19 @@ class NewAppDetailsForm 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) { + const {forbiddenErrors} = this.state; + forbiddenErrors.roles = true; + this.setState({ + forbiddenErrors, + fetching: false + }) + } else { + this.setState({ + fetching: false + }); + } }); }; @@ -218,7 +260,7 @@ class NewAppDetailsForm extends React.Component { render() { const {formConfig} = this.props; - const {categories, tags, deviceTypes, fetching, roleSearchValue, unrestrictedRoles} = this.state; + const {categories, tags, deviceTypes, fetching, roleSearchValue, unrestrictedRoles, forbiddenErrors} = this.state; const {getFieldDecorator} = this.props.form; return ( @@ -233,33 +275,41 @@ class NewAppDetailsForm extends React.Component { layout="horizontal" onSubmit={this.handleSubmit}> {formConfig.installationType !== "WEB_CLIP" && ( - - {getFieldDecorator('deviceType', { - rules: [ +
+ {(forbiddenErrors.deviceTypes) && ( + + )} + + {getFieldDecorator('deviceType', { + rules: [ + { + required: true, + message: 'Please select device type' + } + ], + } + )( + - { - deviceTypes.map(deviceType => { - return ( - - ) - }) - } - - )} - + + )} + +
)} {/*app name*/} @@ -287,6 +337,13 @@ class NewAppDetailsForm extends React.Component {
{/*Unrestricted Roles*/} + {(forbiddenErrors.roles) && ( + + )} {getFieldDecorator('unrestrictedRoles', { rules: [], @@ -295,7 +352,7 @@ class NewAppDetailsForm extends React.Component { )} + {(forbiddenErrors.categories) && ( + + )} {getFieldDecorator('categories', { rules: [{ @@ -333,6 +397,13 @@ class NewAppDetailsForm extends React.Component { )} + {(forbiddenErrors.tags) && ( + + )} {getFieldDecorator('tags', { rules: [{ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js index c7916c2c13..a0aa1e6efa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-app/subForms/NewAppUploadForm.js @@ -17,7 +17,7 @@ */ import React from "react"; -import {Button, Col, Form, Icon, Input, Row, Select, Switch, Upload, InputNumber, Modal} from "antd"; +import {Button, Col, Form, Icon, Input, Row, Select, Switch, Upload, InputNumber, Modal, Alert} from "antd"; import "@babel/polyfill"; import axios from "axios"; import {handleApiError} from "../../../js/Utils"; @@ -400,60 +400,69 @@ class NewAppUploadForm extends React.Component { {(formConfig.installationType !== "WEB_CLIP" && formConfig.installationType !== "CUSTOM") && ( - - {getFieldDecorator('supportedOS', { - rules: [{ - required: true - }], - initialValue: false - })( -
- - -
- - - -

-

- - - - - - - +
+ {(this.props.forbiddenErrors.supportedOsVersions) && ( + )} - + + {getFieldDecorator('supportedOS', { + rules: [{ + required: true + }], + initialValue: false + })( +
+ + +
+ + + +

-

+ + + + + + + + )} + + )} {getFieldDecorator('meta', {})( diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-release/AddReleaseForm.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-release/AddReleaseForm.js index 1fa47170e9..abaea5dbe9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-release/AddReleaseForm.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/new-release/AddReleaseForm.js @@ -41,7 +41,10 @@ class AddNewReleaseFormComponent extends React.Component { supportedOsVersions: [], application: null, release: null, - deviceType: null + deviceType: null, + forbiddenErrors: { + supportedOsVersions: false + } }; } @@ -63,10 +66,19 @@ class AddNewReleaseFormComponent extends React.Component { }); } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load supported OS versions."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load supported OS versions.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.supportedOsVersions = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; @@ -85,7 +97,7 @@ class AddNewReleaseFormComponent extends React.Component { data.append("applicationRelease", blob); const url = window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + - "/applications/" + deviceType + "/ent-app/" + appId; + "/applications/" + deviceType + "/ent-app/" + appId; axios.post( url, data @@ -122,14 +134,15 @@ class AddNewReleaseFormComponent extends React.Component { }; render() { - const {loading, supportedOsVersions} = this.state; + const {loading, supportedOsVersions, forbiddenErrors} = this.state; return (
-
+ { +export const handleApiError = (error, message, isForbiddenMessageSilent) => { if (error.hasOwnProperty("response") && error.response.status === 401) { const redirectUrl = encodeURI(window.location.href); window.location.href = window.location.origin + `/publisher/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: 10, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/apps/release/Release.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/apps/release/Release.js index 40fd63a0ba..fc653d7bf4 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/apps/release/Release.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/apps/release/Release.js @@ -24,6 +24,7 @@ import ReleaseView from "../../../../components/apps/release/ReleaseView"; import LifeCycle from "../../../../components/apps/release/lifeCycle/LifeCycle"; import {withConfigContext} from "../../../../context/ConfigContext"; import {handleApiError} from "../../../../js/Utils"; +import NewAppUploadForm from "../../../../components/new-app/subForms/NewAppUploadForm"; const {Title} = Typography; @@ -40,13 +41,19 @@ class Release extends React.Component { release: null, currentLifecycleStatus: null, lifecycle: null, - supportedOsVersions:[] + supportedOsVersions: [], + forbiddenErrors: { + supportedOsVersions: false, + lifeCycle: false + } }; } componentDidMount() { const {uuid} = this.props.match.params; this.fetchData(uuid); + this.getLifecycle(); + } componentDidUpdate(prevProps, prevState, snapshot) { @@ -86,10 +93,8 @@ class Release extends React.Component { loading: false, uuid: uuid }); - if(config.deviceTypes.mobileTypes.includes(app.deviceType)){ + if (config.deviceTypes.mobileTypes.includes(app.deviceType)) { this.getSupportedOsVersions(app.deviceType); - }else{ - this.getLifecycle(); } } @@ -111,8 +116,15 @@ class Release extends React.Component { }) } - }).catch(function (error) { - handleApiError(error, "Error occurred while trying to load lifecycle configuration."); + }).catch((error) => { + handleApiError(error, "Error occurred while trying to load lifecycle configuration.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.lifeCycle = true; + this.setState({ + forbiddenErrors + }) + } }); }; @@ -125,21 +137,28 @@ class Release extends React.Component { if (res.status === 200) { let supportedOsVersions = JSON.parse(res.data.data); this.setState({ - supportedOsVersions, - loading: false, + supportedOsVersions }); - this.getLifecycle(); } }).catch((error) => { - handleApiError(error, "Error occurred while trying to load supported OS versions."); - this.setState({ - loading: false - }); + handleApiError(error, "Error occurred while trying to load supported OS versions.", true); + if (error.hasOwnProperty("response") && error.response.status === 403) { + const {forbiddenErrors} = this.state; + forbiddenErrors.supportedOsVersions = true; + this.setState({ + forbiddenErrors, + loading: false + }) + } else { + this.setState({ + loading: false + }); + } }); }; render() { - const {app, release, currentLifecycleStatus, lifecycle, loading} = this.state; + const {app, release, currentLifecycleStatus, lifecycle, loading, forbiddenErrors} = this.state; if (release == null && loading === false) { return ( @@ -159,12 +178,13 @@ class Release extends React.Component { {(release !== null) && ( ) }