commit
66f8472da7
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 axios from 'axios';
|
||||||
|
import Constants from './constants';
|
||||||
|
|
||||||
|
|
||||||
|
class Configuration {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.serverConfig = {};
|
||||||
|
this.hostConstants = {
|
||||||
|
baseURL: window.location.origin,
|
||||||
|
appContext: window.location.pathname.split("/")[1]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
loadConfiguration(callback) {
|
||||||
|
let thisObject = this;
|
||||||
|
axios.get(thisObject.hostConstants.baseURL + '/' + thisObject.hostConstants.appContext + "/config.json").
|
||||||
|
then(function (response) {
|
||||||
|
console.log('server config was read successfully! ');
|
||||||
|
thisObject.serverConfig = response.data.config;
|
||||||
|
Constants.load();
|
||||||
|
callback();
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('unable to load the config file!' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (new Configuration());
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"es2015"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"theme": {
|
||||||
|
"type": "default",
|
||||||
|
"value": "lightBaseTheme"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"hostname": "localhost",
|
||||||
|
"httpsPort": "9443",
|
||||||
|
"apiPort": "8243"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 443 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"Title" : "Title",
|
||||||
|
"Description" : "Description",
|
||||||
|
"Category" : "Category",
|
||||||
|
"Visibility" : "Visibility",
|
||||||
|
"Devices" : "Devices",
|
||||||
|
"Roles" : "Roles",
|
||||||
|
"Groups" : "Groups",
|
||||||
|
"Tags" : "Tags",
|
||||||
|
"Platform" : "Platform",
|
||||||
|
"Platforms" : "Platfomrs",
|
||||||
|
"No.Platform" : "No Platforms",
|
||||||
|
"Screenshots" : "Screenshots",
|
||||||
|
"Icon" : "Icon",
|
||||||
|
"Banner" : "Banner",
|
||||||
|
"Create.Application" : "Create Application",
|
||||||
|
"Back" : "Back",
|
||||||
|
"Cancel" : "Cancel",
|
||||||
|
"Finish" : "Finish",
|
||||||
|
"Continue" : "Continue",
|
||||||
|
"Application.Name" : "Application Name",
|
||||||
|
"General" : "General",
|
||||||
|
"App.Releases" : "Application Releases",
|
||||||
|
"Package.Manager" : "Package Manager",
|
||||||
|
"Save" : "Save",
|
||||||
|
"Create.Release" : "Create Release",
|
||||||
|
"Release" : "Release",
|
||||||
|
"New.Release.For" : "New Release for",
|
||||||
|
"Upload.Package.File" : "Upload Package File",
|
||||||
|
"Upload" : "Upload",
|
||||||
|
"Select.from.package.library" : "Select from package library",
|
||||||
|
"Release.Name" : "Release Name",
|
||||||
|
"Release.Notes" : "Release Notes",
|
||||||
|
"Send.for.Review" : "Send for Review",
|
||||||
|
"Production.Releases" : "Production Releases",
|
||||||
|
"Beta.Releases" : "Beta Releases",
|
||||||
|
"Alpha.Releases" : "Alpha Releases",
|
||||||
|
"Version" : "Version",
|
||||||
|
"Status" : "Status",
|
||||||
|
"App.Publisher" : "Application Publisher"
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
opacity: 1;
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
height: auto;
|
||||||
|
transition: .5s ease;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-content {
|
||||||
|
transition: .5s ease;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
background-color: rgba(243, 243, 243, 0.43);
|
||||||
|
border-radius: 50%;
|
||||||
|
border: solid 1px #ffffff;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
-ms-transform: translate(-50%, -50%)
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container:hover .image {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container:hover .btn-content {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 20px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.chip {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 25px;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 50px;
|
||||||
|
border-radius: 25px;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chip img {
|
||||||
|
float: left;
|
||||||
|
margin: 0 10px 0 -25px;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
padding-left: 10px;
|
||||||
|
color: #888;
|
||||||
|
font-weight: bold;
|
||||||
|
float: right;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
@ -0,0 +1,483 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Body Styling */
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
font-family: Roboto sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Login page styles*/
|
||||||
|
#userName {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#password {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-btn {
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: navy;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-container {
|
||||||
|
width: 50%;
|
||||||
|
margin: 0 auto
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-card {
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: #BaBaBa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base layout container */
|
||||||
|
#container {
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Base layout header content*/
|
||||||
|
#header-content {
|
||||||
|
height: 125px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
background-color: #3b33bd;
|
||||||
|
position: fixed; /* Set the navbar to fixed position */
|
||||||
|
top: 0; /* Position the navbar at the top of the page */
|
||||||
|
z-index: 2;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Contains the header styles.*/
|
||||||
|
#header {
|
||||||
|
margin: 16px 16px 20px 16px;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-text {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 25px;
|
||||||
|
top: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The buttons in the header (User and Notification)*/
|
||||||
|
#header-btn-container {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-header {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-right: 20px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search box styles */
|
||||||
|
.search-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-box {
|
||||||
|
display: flex;
|
||||||
|
color: #a8a8a8;
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
top: 75px;
|
||||||
|
left: 80px;
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search {
|
||||||
|
position: relative;
|
||||||
|
color: white;
|
||||||
|
background-color: transparent;
|
||||||
|
left: 15px;
|
||||||
|
top: 0px;
|
||||||
|
height: 25px;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Application Add button */
|
||||||
|
#add-btn-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 12%;
|
||||||
|
top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holds the app publisher pages. */
|
||||||
|
#application-content {
|
||||||
|
height: auto;
|
||||||
|
width: 80%;
|
||||||
|
margin: 150px auto;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
padding: 10px 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-header {
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: solid 1px cornflowerblue;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-link-placeholder {
|
||||||
|
color: #888888;
|
||||||
|
float: right;
|
||||||
|
margin-right: 20px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#application-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
transition: margin-right .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-screenshot {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-icon {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-image-banner {
|
||||||
|
width: 400px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-banner-dropzone {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
border-radius: 5%;
|
||||||
|
position: relative;
|
||||||
|
background-color: rgba(157, 159, 157, 0.53);
|
||||||
|
border: dashed #888888 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-banner-dropzone i {
|
||||||
|
position: absolute;
|
||||||
|
top: 65px;
|
||||||
|
left: 145px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-screenshot-dropzone {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
margin: 0 5px 0 5px;
|
||||||
|
border-radius: 10%;
|
||||||
|
position: relative;
|
||||||
|
background-color: rgba(157, 159, 157, 0.53);
|
||||||
|
border: dashed #888888 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-screenshot-dropzone i {
|
||||||
|
position: absolute;
|
||||||
|
top: 65px;
|
||||||
|
left: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-icon-dropzone {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
border-radius: 10%;
|
||||||
|
position: relative;
|
||||||
|
background-color: rgba(157, 159, 157, 0.53);
|
||||||
|
border: dashed #888888 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-create-icon-dropzone i {
|
||||||
|
position: absolute;
|
||||||
|
top: 65px;
|
||||||
|
left: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenshot-container {
|
||||||
|
display: flex;
|
||||||
|
overflow-x: auto;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-icon-container {
|
||||||
|
height: 300px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-body-content {
|
||||||
|
max-height: 700px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#img-btn-screenshot {
|
||||||
|
margin: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-create-modal {
|
||||||
|
max-width: 700px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#store {
|
||||||
|
border: none;
|
||||||
|
border-bottom: solid #BDBDBD 1px;
|
||||||
|
border-radius: 0px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#version {
|
||||||
|
border: none;
|
||||||
|
border-bottom: solid #BDBDBD 1px;
|
||||||
|
border-radius: 0px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-release-switch-content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-release-switch-label {
|
||||||
|
position: absolute;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-release-switch-switch {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-sub-title {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #818181;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Application View */
|
||||||
|
#application-view-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#application-view-row {
|
||||||
|
margin: 10px 10px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-icon {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
border: solid 1px black;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-updated-date {
|
||||||
|
color: #888888;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-install-count {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-details-tbl {
|
||||||
|
outline: none;
|
||||||
|
border-color: #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-details-tbl tr {
|
||||||
|
margin: 20px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-details-tbl td {
|
||||||
|
margin-left: 10px;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Application Edit Base Layout */
|
||||||
|
#application-edit-header {
|
||||||
|
height: 50px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
border-bottom: solid 1px #d8d8d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-header-text {
|
||||||
|
margin: 10px 0px 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-btn-content {
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-save-btn {
|
||||||
|
border-radius: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn {
|
||||||
|
margin: 5px 5px 5px 0px;
|
||||||
|
height: 70%;
|
||||||
|
width: 50%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Tab styling*/
|
||||||
|
div.tab {
|
||||||
|
float: left;
|
||||||
|
border-right: 1px solid #d8d8d8;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the tab buttons */
|
||||||
|
div.tab button {
|
||||||
|
display: block;
|
||||||
|
background-color: inherit;
|
||||||
|
color: black;
|
||||||
|
padding: 15px 16px;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change background color of buttons on hover */
|
||||||
|
div.tab button:hover {
|
||||||
|
background-color: #ddd6d7;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an active/current "tab button" class */
|
||||||
|
div.tab button.active {
|
||||||
|
background-color: #1b3bcc;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#application-edit-main-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#application-edit-outer-content {
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#application-edit-content {
|
||||||
|
margin: 5px 10px 5px 10px;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-edit-content {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-app {
|
||||||
|
position: absolute;
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-app i {
|
||||||
|
padding: 10px 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-app:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #dedede;
|
||||||
|
transition: .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Release and Release management */
|
||||||
|
.release-header {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-create {
|
||||||
|
height: 150px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-detail-content {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-btn {
|
||||||
|
float: right;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-content {
|
||||||
|
height: 180px;
|
||||||
|
width: 95%;
|
||||||
|
border: dashed 1px #626262;
|
||||||
|
border-radius: 2%;
|
||||||
|
position: relative;
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-content:after {
|
||||||
|
content: "";
|
||||||
|
letter-spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release {
|
||||||
|
margin: 30px 10px 20px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-release-content {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 10px;
|
||||||
|
left: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-add:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-inner {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Application Edit General Info */
|
||||||
|
.app-edit-general-info {
|
||||||
|
margin-top: 20px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-info {
|
||||||
|
float: right;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.app-view-drawer {
|
||||||
|
height: 100%; /* 100% Full-height */
|
||||||
|
width: 0; /* 0 width - change this with JavaScript */
|
||||||
|
position: fixed; /* Stay in place */
|
||||||
|
z-index: 1; /* Stay on top */
|
||||||
|
top: 8%;
|
||||||
|
right: 0%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
overflow-x: hidden; /* Disable horizontal scroll */
|
||||||
|
padding-top: 60px; /* Place content 60px from the top */
|
||||||
|
transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-view-drawer a {
|
||||||
|
padding: 8px 8px 8px 32px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 25px;
|
||||||
|
color: #818181;
|
||||||
|
display: block;
|
||||||
|
transition: 0.3s
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Position and style the close button (top right corner) */
|
||||||
|
.app-view-drawer .closebtn {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 25px;
|
||||||
|
font-size: 36px;
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-close-btn {
|
||||||
|
height: 40px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-close-btn:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #818181;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
|
||||||
|
#main {
|
||||||
|
transition: margin-left .5s;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
|
||||||
|
@media screen and (max-height: 450px) {
|
||||||
|
.sidenav {padding-top: 15px;}
|
||||||
|
.sidenav a {font-size: 18px;}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.btn-circle {
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
background-color: #e65100;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-circle i {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 37%;
|
||||||
|
margin-left: 37%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medium {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-circle:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: rgb(255, 93, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.notification-app-icon {
|
||||||
|
border-radius: 50%;
|
||||||
|
border: solid 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medium {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-view-content {
|
||||||
|
width: 50%;
|
||||||
|
border: solid 1px black;
|
||||||
|
margin: 0 auto;
|
||||||
|
box-shadow: -2px 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-content {
|
||||||
|
margin: 20px 10px 20px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app-reject-msg {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #888888;
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The switch - the box around the slider */
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 40px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide default HTML checkbox */
|
||||||
|
.switch input {display:none;}
|
||||||
|
|
||||||
|
/* The slider */
|
||||||
|
.slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #ccc;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-transition: .4s;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider {
|
||||||
|
background-color: #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus + .slider {
|
||||||
|
box-shadow: 0 0 1px #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .slider:before {
|
||||||
|
-webkit-transform: translateX(16px);
|
||||||
|
-ms-transform: translateX(16px);
|
||||||
|
transform: translateX(16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rounded sliders */
|
||||||
|
.slider.round {
|
||||||
|
border-radius: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider.round:before {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 ReactDOM from 'react-dom';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
it('renders without crashing', () => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
ReactDOM.render(<App />, div);
|
||||||
|
});
|
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import Axios from 'axios';
|
||||||
|
import AuthHandler from './authHandler';
|
||||||
|
import Constants from '../common/constants';
|
||||||
|
import Helper from './helpers/appMgtApiHelpers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api definitions related to application management.
|
||||||
|
* TODO: Work to be done on Application release.
|
||||||
|
* */
|
||||||
|
export default class ApplicationMgtApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api for create an application.
|
||||||
|
* @param: applicationData: The application data object. This contains an object array of each step data from
|
||||||
|
* application creation wizard.
|
||||||
|
*
|
||||||
|
* From applicationData, the proper application object will be created and send it to the api.
|
||||||
|
* */
|
||||||
|
static createApplication(applicationData) {
|
||||||
|
let {application, images} = Helper.buildApplication(applicationData);
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
console.log(application);
|
||||||
|
console.log(images);
|
||||||
|
Axios.post(Constants.appManagerEndpoints.CREATE_APP, application, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload the image artifacts (banner, icon, screenshots) related to the application.
|
||||||
|
* @param appId: The application uuid of the application which the images should be uploaded to.
|
||||||
|
* @param images: The images object. This contains icon, banner and screenshots.
|
||||||
|
* */
|
||||||
|
static uploadImageArtifacts(appId, images) {
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('icon', images.icon);
|
||||||
|
formData.append('banner', images.banner);
|
||||||
|
formData.append('screenshot', images.screenshots);
|
||||||
|
console.log("Image", formData);
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("multipart/form-data");
|
||||||
|
return Axios.post(Constants.appManagerEndpoints.UPLOAD_IMAGE_ARTIFACTS + appId, formData, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to handle application release process.
|
||||||
|
* */
|
||||||
|
static releaseApplication(appId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promote the current life cycle state of the application.
|
||||||
|
* @param appId: The uuid of the application which the state should be updated.
|
||||||
|
* @param nextState: The next lifecycle state that the application can be updated to.
|
||||||
|
*
|
||||||
|
* URL Pattern : /application/1.0/
|
||||||
|
* */
|
||||||
|
static updateLifeCycleState(appId, nextState) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next possible state, which the application can be promoted to.
|
||||||
|
* @param appId: The application uuid.
|
||||||
|
*/
|
||||||
|
static getNextLifeCycleState(appId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit created application.
|
||||||
|
* @param applicationData: The modified application data.
|
||||||
|
* */
|
||||||
|
static editApplication(applicationData) {
|
||||||
|
let app = Helper.buildApplication(applicationData).application;
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.put(Constants.appManagerEndpoints.CREATE_APP, app, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getApplicationArtifacts(appId, artifactName) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("image/png");
|
||||||
|
return Axios.get(Constants.appManagerEndpoints.GET_IMAGE_ARTIFACTS + appId + "?name=" + artifactName,
|
||||||
|
{headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
static editApplicationArtifacts(appId, images) {
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('icon', images.icon);
|
||||||
|
formData.append('banner', images.banner);
|
||||||
|
formData.append('screenshot', images.screenshots);
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.put(Constants.appManagerEndpoints.UPLOAD_IMAGE_ARTIFACTS + appId, formData, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the created applications for the user.
|
||||||
|
* @return Object: The response object from the axios post.
|
||||||
|
* */
|
||||||
|
static getApplications() {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.get(Constants.appManagerEndpoints.GET_ALL_APPS, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get specific application.
|
||||||
|
* @param appId: The application Id.
|
||||||
|
* */
|
||||||
|
static getApplication(appId) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.get(Constants.appManagerEndpoints.GET_ALL_APPS + appId, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete specified application.
|
||||||
|
* @param appId: The id of the application which is to be deleted.
|
||||||
|
* */
|
||||||
|
static deleteApplication(appId) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.delete(Constants.appManagerEndpoints.GET_ALL_APPS + appId, {headers: headers});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import Axios from 'axios';
|
||||||
|
import User from './data/user';
|
||||||
|
import Utils from './data/utils';
|
||||||
|
import Constants from "../common/constants";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles all tasks related to Authentication and Authorization.
|
||||||
|
* Generate access tokens, verify the user has necessary permissions etc.
|
||||||
|
* */
|
||||||
|
class AuthHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the auth handler endpoint (auth/application-mgt/v1.0/auth/login) and generate token pair.
|
||||||
|
* @param userName: The user name of the user.
|
||||||
|
* @param password: The user password.
|
||||||
|
* @return Object: The response object from the axios post.
|
||||||
|
* */
|
||||||
|
static login(userName, password) {
|
||||||
|
const headers = {"Content-type": "application/json"};
|
||||||
|
let login_promise =
|
||||||
|
Axios.post(Constants.userConstants.LOGIN_URL+"?userName=" + userName+ "&password=" + password,
|
||||||
|
null, {headers: headers});
|
||||||
|
|
||||||
|
login_promise.then(response => {
|
||||||
|
console.log(response);
|
||||||
|
const userName = response.data.userName;
|
||||||
|
const validityPeriod = response.data.expires_in; // In seconds
|
||||||
|
const WSO2_IOT_TOKEN = response.data.access_token;
|
||||||
|
const refreshToken = response.data.refresh_token;
|
||||||
|
const clientId = response.data.application_info[0].consumerKey;
|
||||||
|
const clientSecret = response.data.application_info[0].consumerSecret;
|
||||||
|
|
||||||
|
const user = new User(userName, clientId, clientSecret, validityPeriod);
|
||||||
|
console.log(user);
|
||||||
|
user.setAuthToken(WSO2_IOT_TOKEN, validityPeriod);
|
||||||
|
let expiresIn = Date.now() + (validityPeriod * 1000);
|
||||||
|
localStorage.setItem("expiresIn", expiresIn);
|
||||||
|
AuthHandler.setUser(user);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return login_promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
static loginAsAnonymous(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists the user object in browser's local storage.
|
||||||
|
* @param user: The user object.
|
||||||
|
* */
|
||||||
|
static setUser(user) {
|
||||||
|
if (!user instanceof User) {
|
||||||
|
throw "Invalid user object";
|
||||||
|
}
|
||||||
|
user.created = Date.now();
|
||||||
|
localStorage.setItem(Constants.userConstants.WSO2_USER, JSON.stringify(user.toJson()));
|
||||||
|
/* TODO: IMHO it's better to get this key (`wso2_user`) from configs */
|
||||||
|
}
|
||||||
|
|
||||||
|
static unauthorizedErrorHandler(error_response) {
|
||||||
|
if (error_response.status !== 401) { /* Skip unrelated response code to handle in unauthorizedErrorHandler*/
|
||||||
|
throw error_response;
|
||||||
|
/* re throwing the error since we don't handle it here and propagate to downstream error handlers in catch chain*/
|
||||||
|
}
|
||||||
|
let message = "The session has expired" + ".<br/> You will be redirect to the login page ...";
|
||||||
|
if (true) {
|
||||||
|
alert(message);
|
||||||
|
} else {
|
||||||
|
throw error_response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the logged in user.
|
||||||
|
* @return User: The logged in user object.
|
||||||
|
* */
|
||||||
|
static getUser() {
|
||||||
|
const userData = localStorage.getItem(Constants.userConstants.WSO2_USER);
|
||||||
|
const partialToken = Utils.getCookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||||
|
|
||||||
|
if (!(userData && partialToken)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return User.fromJson(JSON.parse(userData));
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoggedIn() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static logout() {
|
||||||
|
const user = AuthHandler.getUser();
|
||||||
|
const clientId = user.getClientId();
|
||||||
|
const clientSecret = user.getClientSecret();
|
||||||
|
const token = user.getAuthToken();
|
||||||
|
const headers = {"Content-type": "application/json"};
|
||||||
|
|
||||||
|
let login_promise = Axios.post(Constants.userConstants.LOGOUT_URL+"?token=" + token + "&clientId=" + clientId
|
||||||
|
+ "&clientSecret=" + clientSecret,
|
||||||
|
null, {headers: headers});
|
||||||
|
login_promise.then(
|
||||||
|
(response) => {
|
||||||
|
Utils.delete_cookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||||
|
localStorage.removeItem(Constants.userConstants.WSO2_USER);
|
||||||
|
window.location = "/";
|
||||||
|
}
|
||||||
|
).catch(
|
||||||
|
(err) => {
|
||||||
|
AuthHandler.unauthorizedErrorHandler(err);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the access token is expired.
|
||||||
|
* @return boolean: True if expired. False otherwise.
|
||||||
|
* */
|
||||||
|
static isTokenExpired() {
|
||||||
|
const expiresIn = localStorage.getItem("expiresIn");
|
||||||
|
return (expiresIn < Date.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
static createAuthenticationHeaders(contentType) {
|
||||||
|
if (AuthHandler.getUser().getAuthToken()) {
|
||||||
|
return {
|
||||||
|
"Authorization": "Bearer " + AuthHandler.getUser().getAuthToken(),
|
||||||
|
"Content-Type": contentType,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return "User not found";
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthHandler;
|
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import Utils from './utils'
|
||||||
|
import Constants from '../../common/constants';
|
||||||
|
/**
|
||||||
|
* Represent an user logged in to the application, There will be allays one user per session and
|
||||||
|
* this user details will be persist in browser localstorage.
|
||||||
|
*/
|
||||||
|
export default class User {
|
||||||
|
constructor(name, clientId, clientSecret, validityPeriod) {
|
||||||
|
if (User._instance) {
|
||||||
|
return User._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._userName = name;
|
||||||
|
this._clientId = clientId;
|
||||||
|
this._clientSecret = clientSecret;
|
||||||
|
this._expires = validityPeriod;
|
||||||
|
User._instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth scopes which are available for use by this user
|
||||||
|
* @returns {Array} : An array of scopes
|
||||||
|
*/
|
||||||
|
get scopes() {
|
||||||
|
return this._scopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set OAuth scopes available to be used by this user
|
||||||
|
* @param {Array} newScopes : An array of scopes
|
||||||
|
*/
|
||||||
|
set scopes(newScopes) {
|
||||||
|
Object.assign(this.scopes, newScopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JS accessible access token fragment from cookie storage.
|
||||||
|
* @returns {String|null}
|
||||||
|
*/
|
||||||
|
getAuthToken() {
|
||||||
|
return Utils.getCookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientId() {
|
||||||
|
return this._clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
getClientSecret() {
|
||||||
|
return this._clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the JavaScript accessible access token segment in cookie storage
|
||||||
|
* @param {String} newToken : Part of the access token which needs when accessing REST API
|
||||||
|
* @param {Number} validityPeriod : Validity period of the cookie in seconds
|
||||||
|
*/
|
||||||
|
setAuthToken(newToken, validityPeriod) {
|
||||||
|
Utils.delete_cookie(Constants.userConstants.PARTIAL_TOKEN);
|
||||||
|
Utils.setCookie(Constants.userConstants.PARTIAL_TOKEN, newToken, validityPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user name of logged in user.
|
||||||
|
* @return String: User name
|
||||||
|
* */
|
||||||
|
getUserName() {
|
||||||
|
return this._userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide user data in JSON structure.
|
||||||
|
* @returns {JSON} : JSON representation of the user object
|
||||||
|
*/
|
||||||
|
toJson() {
|
||||||
|
return {
|
||||||
|
name: this._userName,
|
||||||
|
clientId: this._clientId,
|
||||||
|
clientSecret: this._clientSecret,
|
||||||
|
expires: this._expires
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User utility method to create an user from JSON object.
|
||||||
|
* @param {JSON} userJson : Need to provide user information in JSON structure to create an user object
|
||||||
|
* @returns {User} : An instance of User(this) class.
|
||||||
|
*/
|
||||||
|
static fromJson(userJson) {
|
||||||
|
const _user = new User(userJson.name);
|
||||||
|
_user._clientId = userJson.clientId;
|
||||||
|
_user._clientSecret = userJson.clientSecret;
|
||||||
|
_user._expires = userJson.expires;
|
||||||
|
|
||||||
|
console.log(_user);
|
||||||
|
return _user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
User._instance = null; // A private class variable to preserve the single instance of a swaggerClient
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for Publisher application
|
||||||
|
*/
|
||||||
|
class StoreUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Remove this method one the initial phase is done, This is used to continue the API class until the login page is create
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
// static autoLogin() {
|
||||||
|
// let auth = new AuthManager();
|
||||||
|
// return auth.authenticateUser('admin', 'admin');
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get JavaScript accessible cookies saved in browser, by giving the cooke name.
|
||||||
|
* @param {String} name : Name of the cookie which need to be retrived
|
||||||
|
* @returns {String|null} : If found a cookie with given name , return its value,Else null value is returned
|
||||||
|
*/
|
||||||
|
static getCookie(name) {
|
||||||
|
let pairs = document.cookie.split(";");
|
||||||
|
let cookie = null;
|
||||||
|
for (let pair of pairs) {
|
||||||
|
pair = pair.split("=");
|
||||||
|
let cookie_name = pair[0].trim();
|
||||||
|
let value = encodeURIComponent(pair[1]);
|
||||||
|
if (cookie_name === name) {
|
||||||
|
cookie = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a browser cookie given its name
|
||||||
|
* @param {String} name : Name of the cookie which need to be deleted
|
||||||
|
*/
|
||||||
|
static delete_cookie(name) {
|
||||||
|
document.cookie = name + '=; Path=' + "/" + '; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a cookie with given name and value assigned to it. Cookies can be only set to the same origin,
|
||||||
|
* which the script is running
|
||||||
|
* @param {String} name : Name of the cookie which need to be set
|
||||||
|
* @param {String} value : Value of the cookie, expect it to be URLEncoded
|
||||||
|
* @param {number} validityPeriod : (Optional) Validity period of the cookie in seconds
|
||||||
|
* @param {String} path : Path which needs to set the given cookie
|
||||||
|
* @param {boolean} secured : secured parameter is set
|
||||||
|
*/
|
||||||
|
static setCookie(name, value, validityPeriod, path = "/", secured = true) {
|
||||||
|
let expires = "";
|
||||||
|
const securedDirective = secured ? "; Secure" : "";
|
||||||
|
if (validityPeriod) {
|
||||||
|
const date = new Date();
|
||||||
|
date.setTime(date.getTime() + validityPeriod * 1000);
|
||||||
|
expires = "; expires=" + date.toUTCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.cookie = name + "=" + value + expires + "; path=" + path + securedDirective + validityPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an object returns whether the object is empty or not
|
||||||
|
* @param {Object} object : Any JSON object
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static isEmptyObject(object) {
|
||||||
|
return Object.keys(object).length === 0 && object.constructor === Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StoreUtils;
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper methods for app store.
|
||||||
|
* */
|
||||||
|
export default class Helper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate application object from form data passed.
|
||||||
|
* @param appData: Application data from the application creation form.
|
||||||
|
* @return {Object, Object}: The application object and the set of images related to the application.
|
||||||
|
* */
|
||||||
|
static buildApplication(appData) {
|
||||||
|
|
||||||
|
let application = {};
|
||||||
|
let images = {};
|
||||||
|
|
||||||
|
for (let step in appData) {
|
||||||
|
let tmpData = appData[step].data.step;
|
||||||
|
for (let prop in tmpData) {
|
||||||
|
if (prop === 'banner' || prop === 'screenshots' || prop === 'icon') {
|
||||||
|
images[prop] = tmpData[prop];
|
||||||
|
} else if(prop === 'tags') {
|
||||||
|
application[prop] = Helper.stringifyTags(tmpData[prop]);
|
||||||
|
} else {
|
||||||
|
application[prop] = tmpData[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {application, images};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a String array from tags array.
|
||||||
|
* */
|
||||||
|
static stringifyTags(tags) {
|
||||||
|
let tmpTags = [];
|
||||||
|
for (let tag in tags) {
|
||||||
|
console.log(tag);
|
||||||
|
tmpTags.push(tags[tag].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import Axios from 'axios';
|
||||||
|
import AuthHandler from './authHandler';
|
||||||
|
import Constants from '../common/constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api definitions for Platform management.
|
||||||
|
* */
|
||||||
|
export default class PlatformMgtApi{
|
||||||
|
/**
|
||||||
|
* Create a new Platform
|
||||||
|
* @param platformData: The platform data object.
|
||||||
|
* */
|
||||||
|
static createPlatform(platformData) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
Axios.post(Constants.platformManagerEndpoints.CREATE_PLATFORM, platformData, {headers: headers}).then(
|
||||||
|
function (response) {
|
||||||
|
console.log(response);
|
||||||
|
}
|
||||||
|
).catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get available platforms
|
||||||
|
* */
|
||||||
|
static getPlatforms() {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.get(Constants.platformManagerEndpoints.GET_ENABLED_PLATFORMS, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user specified platform
|
||||||
|
* @param platformId: The identifier of the platform
|
||||||
|
* */
|
||||||
|
static getPlatform(platformId) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.get(Constants.platformManagerEndpoints.GET_PLATFORM + platformId, {headers: headers});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete specified platform
|
||||||
|
* @param platformId: The id of the platform which is to be deleted.
|
||||||
|
* */
|
||||||
|
static deletePlatform(platformId) {
|
||||||
|
const headers = AuthHandler.createAuthenticationHeaders("application/json");
|
||||||
|
return Axios.delete(Constants.platformManagerEndpoints.GET_PLATFORM + platformId, {headers: headers});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 axios from 'axios';
|
||||||
|
import Constants from './constants';
|
||||||
|
|
||||||
|
|
||||||
|
class Configuration {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.serverConfig = {};
|
||||||
|
this.hostConstants = {
|
||||||
|
baseURL: window.location.origin,
|
||||||
|
appContext: window.location.pathname.split("/")[1]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
loadConfiguration(callback) {
|
||||||
|
let thisObject = this;
|
||||||
|
axios.get(thisObject.hostConstants.baseURL + '/' + thisObject.hostConstants.appContext + "/config.json").
|
||||||
|
then(function (response) {
|
||||||
|
console.log('successfully loaded the configuration!');
|
||||||
|
thisObject.serverConfig = response.data.config;
|
||||||
|
Constants.load();
|
||||||
|
callback();
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log('unable to load the config file!' + error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (new Configuration());
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 Configuration from './configuration';
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
//TODO: Replace the server address with response from auth endpoint and remove hardcoded ids etc.
|
||||||
|
class Constants {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.scopes = 'perm:application:get perm:application:create perm:application:update perm:application-mgt:login' +
|
||||||
|
' perm:application:delete perm:platform:add perm:platform:remove perm:roles:view perm:devices:view';
|
||||||
|
this.appManagerEndpoints = {};
|
||||||
|
this.platformManagerEndpoints = {};
|
||||||
|
this.userConstants = {};
|
||||||
|
this.defaultLocale = "en";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
let apiBaseUrl = 'https://' + Configuration.serverConfig.hostname + ':' + Configuration.serverConfig.apiPort;
|
||||||
|
let httpBaseUrl = 'https://' + Configuration.serverConfig.hostname + ':' + Configuration.serverConfig.httpsPort;
|
||||||
|
|
||||||
|
this.appManagerEndpoints = {
|
||||||
|
GET_ALL_APPS: apiBaseUrl + '/api/application-mgt/v1.0/applications/1.0.0/',
|
||||||
|
CREATE_APP: apiBaseUrl + '/api/application-mgt/v1.0/applications/1.0.0/',
|
||||||
|
UPLOAD_IMAGE_ARTIFACTS: apiBaseUrl + '/api/application-mgt/v1.0/applications/1.0.0/upload-image-artifacts/', //+appId
|
||||||
|
GET_IMAGE_ARTIFACTS: apiBaseUrl + '/api/application-mgt/v1.0/applications/1.0.0/image-artifacts/'
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: remove the platform manager endpoints
|
||||||
|
this.platformManagerEndpoints = {
|
||||||
|
CREATE_PLATFORM: 'https://localhost:8243/api/application-mgt/v1.0/platforms/1.0.0',
|
||||||
|
GET_ENABLED_PLATFORMS: 'https://localhost:8243/api/application-mgt/v1.0/platforms/1.0.0?status=ENABLED',
|
||||||
|
GET_PLATFORM: 'https://localhost:8243/api/application-mgt/v1.0/platforms/1.0.0/'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.userConstants = {
|
||||||
|
LOGIN_URL: httpBaseUrl + '/auth/application-mgt/v1.0/auth/login',
|
||||||
|
LOGOUT_URL: httpBaseUrl + '/auth/application-mgt/v1.0/auth/logout',
|
||||||
|
REFRESH_TOKEN_URL: "",
|
||||||
|
WSO2_USER: 'wso2_user',
|
||||||
|
PARTIAL_TOKEN: 'WSO2_IOT_TOKEN'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default(new Constants);
|
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {withRouter} from 'react-router-dom';
|
||||||
|
import AuthHandler from "../../api/authHandler";
|
||||||
|
import {Col, Container, Input, Row,} from 'reactstrap';
|
||||||
|
import FloatingButton from "../UIComponents/FloatingButton/FloatingButton";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Layout:
|
||||||
|
* App bar
|
||||||
|
* Left Navigation
|
||||||
|
* Middle content.
|
||||||
|
* */
|
||||||
|
class BaseLayout extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
notifications: 0,
|
||||||
|
user: 'Admin',
|
||||||
|
openModal: false
|
||||||
|
};
|
||||||
|
this.logout = this.logout.bind(this);
|
||||||
|
this.closeModal = this.closeModal.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleApplicationClick() {
|
||||||
|
this.handleHistory('/assets/apps');
|
||||||
|
}
|
||||||
|
|
||||||
|
handleApplicationCreateClick(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
this.setState({openModal: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method to update the history.
|
||||||
|
* to: The URL to route.
|
||||||
|
* */
|
||||||
|
handleHistory(to) {
|
||||||
|
this.props.history.push(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(event, index, value) {
|
||||||
|
AuthHandler.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeModal() {
|
||||||
|
this.setState({openModal: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container noGutters fluid id="container">
|
||||||
|
<div id="header-content">
|
||||||
|
<div id="header">
|
||||||
|
<span id="header-text">
|
||||||
|
WSO2 IoT App Store
|
||||||
|
</span>
|
||||||
|
<div id="header-btn-container">
|
||||||
|
<i className="fw fw-notification btn-header"></i>
|
||||||
|
<i className="fw fw-user btn-header"></i>
|
||||||
|
</div>
|
||||||
|
<div id="search-box">
|
||||||
|
<i className="fw fw-search search-icon">
|
||||||
|
</i>
|
||||||
|
<Input
|
||||||
|
id="search"
|
||||||
|
name="search"
|
||||||
|
placeholder={'Search for Applications'}
|
||||||
|
onChange={(event) => console.log(event.target.value)} //TODO: Remove this
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="add-btn-container">
|
||||||
|
<FloatingButton
|
||||||
|
className="add-btn small"
|
||||||
|
onClick={this.handleApplicationCreateClick.bind(this)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="application-content" style={this.state.style}>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
{this.props.children}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseLayout.propTypes = {
|
||||||
|
children: PropTypes.element
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withRouter(BaseLayout);
|
@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import {withRouter} from 'react-router-dom';
|
||||||
|
import {Button, Col, Row, Table} from 'reactstrap';
|
||||||
|
import Drawer from '../UIComponents/Drawer/Drawer';
|
||||||
|
import ApplicationView from './View/ApplicationView';
|
||||||
|
import Configuration from '../../common/configuration';
|
||||||
|
import Constants from '../../common/constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The App Create Component.
|
||||||
|
*
|
||||||
|
* Application creation is handled through a Wizard. (We use Material UI Stepper.)
|
||||||
|
*
|
||||||
|
* In each step, data will be set to the state separately.
|
||||||
|
* When the wizard is completed, data will be arranged and sent to the api.
|
||||||
|
* */
|
||||||
|
class ApplicationListing extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.searchApplications = this.searchApplications.bind(this);
|
||||||
|
this.onRowClick = this.onRowClick.bind(this);
|
||||||
|
this.setData = this.setData.bind(this);
|
||||||
|
this.sortData = this.sortData.bind(this);
|
||||||
|
this.compare = this.compare.bind(this);
|
||||||
|
this.handleButtonClick = this.handleButtonClick.bind(this);
|
||||||
|
this.state = {
|
||||||
|
searchedApplications: [],
|
||||||
|
applications: [],
|
||||||
|
asc: true,
|
||||||
|
open: false,
|
||||||
|
application: {},
|
||||||
|
drawer: {},
|
||||||
|
appListStyle: {},
|
||||||
|
//TODO: Remove this declaration.
|
||||||
|
image: [{id: "1", src: "https://www.greenfoot.org/images/logos/macos.png"},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
src: "http://dl1.cbsistatic.com/i/r/2016/08/08/0e67e43a-5a45-41ab-b81d-acfba8708044/resize/736x552/0c0ee669677b5060a0fa1bfb0c7873b4/android-logo-promo-470.png"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = [
|
||||||
|
{
|
||||||
|
data_id: "image",
|
||||||
|
data_type: "image",
|
||||||
|
sortable: false,
|
||||||
|
label: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data_id: "applicationName",
|
||||||
|
data_type: "string",
|
||||||
|
sortable: true,
|
||||||
|
label: "Application Name",
|
||||||
|
sort: this.sortData
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data_id: "platform",
|
||||||
|
data_type: "image_array",
|
||||||
|
sortable: false,
|
||||||
|
label: "Platform"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data_id: "category",
|
||||||
|
data_type: "string",
|
||||||
|
sortable: false,
|
||||||
|
label: "Category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data_id: "status",
|
||||||
|
data_type: "string",
|
||||||
|
sortable: false,
|
||||||
|
label: "Status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data_id: "edit",
|
||||||
|
data_type: "button",
|
||||||
|
sortable: false,
|
||||||
|
label: ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
applications = [
|
||||||
|
{
|
||||||
|
id: "3242342ffww3423",
|
||||||
|
applicationName: "Facebook",
|
||||||
|
platform: "android",
|
||||||
|
category: "Business",
|
||||||
|
status: "Published"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "http://dl1.cbsistatic.com/i/r/2016/08/08/0e67e43a-5a45-41ab-b81d-acfba8708044/resize/736x552/0c0ee669677b5060a0fa1bfb0c7873b4/android-logo-promo-470.png",
|
||||||
|
id: "324234233423423",
|
||||||
|
applicationName: "Twitter",
|
||||||
|
platform: "android",
|
||||||
|
category: "Business",
|
||||||
|
status: "Created"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "https://www.greenfoot.org/images/logos/macos.png",
|
||||||
|
id: "3242d3423423423",
|
||||||
|
applicationName: "Massenger",
|
||||||
|
platform: "android",
|
||||||
|
category: "Business",
|
||||||
|
status: "In Review"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
|
||||||
|
// let getApps = ApplicationMgtApi.getApplications();
|
||||||
|
// getApps.then(response => {
|
||||||
|
// let apps = this.setData(response.data.applications);
|
||||||
|
// console.log(apps); //TODO: Remove this.
|
||||||
|
// this.setState({searchedApplications: apps});
|
||||||
|
// // console.log(this.setState({data: response.data}), console.log(this.state));
|
||||||
|
// }).catch(err => {
|
||||||
|
// AuthHandler.unauthorizedErrorHandler(err);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract application from application list and update the state.
|
||||||
|
* */
|
||||||
|
setData(applications) {
|
||||||
|
let apps = [];
|
||||||
|
for (let app in applications) {
|
||||||
|
let application = {};
|
||||||
|
application.id = applications[app].uuid;
|
||||||
|
application.applicationName = applications[app].name;
|
||||||
|
application.platform = applications[app].platform.name;
|
||||||
|
application.category = applications[app].category.id;
|
||||||
|
application.status = applications[app].currentLifecycle.lifecycleState.name;
|
||||||
|
apps.push(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({searchedApplications: apps});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the search action.
|
||||||
|
* When typing in the search bar, this method will be invoked.
|
||||||
|
* @param event: The event triggered from typing in the search box.
|
||||||
|
* @param searchText: The text that typed in the search box.
|
||||||
|
* */
|
||||||
|
searchApplications(event, searchText) {
|
||||||
|
let searchedData;
|
||||||
|
if (searchText) {
|
||||||
|
searchedData = this.state.applications.filter((dataItem) => {
|
||||||
|
return dataItem.applicationName.includes(searchText);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
searchedData = this.state.applications;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Remove the console log.
|
||||||
|
this.setState({searchedApplications: searchedData}, console.log("Searched data ", this.state.searchedApplications));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles sort data function and toggles the asc state.
|
||||||
|
* asc: true : sort in ascending order.
|
||||||
|
* */
|
||||||
|
sortData() {
|
||||||
|
console.log(this.state);
|
||||||
|
let isAsc = this.state.asc;
|
||||||
|
let sortedData = isAsc ? this.state.searchedApplications.sort(this.compare) : this.data.reverse();
|
||||||
|
this.setState({searchedApplications: sortedData, asc: !isAsc});
|
||||||
|
}
|
||||||
|
|
||||||
|
compare(a, b) {
|
||||||
|
if (a.applicationName < b.applicationName)
|
||||||
|
return -1;
|
||||||
|
if (a.applicationName > b.applicationName)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowClick() {
|
||||||
|
let style = {
|
||||||
|
width: '500px',
|
||||||
|
marginLeft: '500px'
|
||||||
|
};
|
||||||
|
|
||||||
|
let appListStyle = {
|
||||||
|
marginRight: '500px'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setState({drawer: style, appListStyle: appListStyle});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleButtonClick() {
|
||||||
|
console.log("Application Listing");
|
||||||
|
this.props.history.push("apps/edit/fdsfdsf343");
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(imageId) {
|
||||||
|
let tmp = this.state.image;
|
||||||
|
|
||||||
|
console.log(imageId);
|
||||||
|
|
||||||
|
let rem = tmp.filter((image) => {
|
||||||
|
return image.id !== imageId
|
||||||
|
|
||||||
|
});
|
||||||
|
this.setState({image: rem});
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDrawer() {
|
||||||
|
let style = {
|
||||||
|
width: '0',
|
||||||
|
marginLeft: '0'
|
||||||
|
};
|
||||||
|
|
||||||
|
let appListStyle = {
|
||||||
|
marginRight: '0',
|
||||||
|
};
|
||||||
|
this.setState({drawer: style, appListStyle: appListStyle});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div id="application-list" style={this.state.appListStyle}>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Table striped hover>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
{/* TODO: Remove console.log and add sort method. */}
|
||||||
|
<th onClick={() => {
|
||||||
|
console.log("sort")
|
||||||
|
}}>Application Name
|
||||||
|
</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>Platform</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{this.applications.map(
|
||||||
|
(application) => {
|
||||||
|
return (
|
||||||
|
<tr key={application.id} onClick={this.onRowClick}>
|
||||||
|
<td>
|
||||||
|
{/* TODO: Move this styles to css. */}
|
||||||
|
<img
|
||||||
|
src={application.icon}
|
||||||
|
height='50px'
|
||||||
|
width='50px'
|
||||||
|
style={{border: 'solid 1px black', borderRadius: "100%"}}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>{application.applicationName}</td>
|
||||||
|
<td>{application.category}</td>
|
||||||
|
<td>{application.platform}</td>
|
||||||
|
<td>{application.status}</td>
|
||||||
|
<td>
|
||||||
|
<Button onClick={this.handleButtonClick}>
|
||||||
|
<i className="fw fw-edit"></i>
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Drawer onClose={this.closeDrawer.bind(this)} style={this.state.drawer}>
|
||||||
|
<ApplicationView/>
|
||||||
|
</Drawer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationListing.propTypes = {};
|
||||||
|
|
||||||
|
export default withRouter(ApplicationListing);
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import {withRouter} from 'react-router-dom';
|
||||||
|
import {Col, Row} from "reactstrap";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application view component.
|
||||||
|
* Shows the details of the application.
|
||||||
|
* */
|
||||||
|
class ApplicationView extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
application: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(props, nextProps) {
|
||||||
|
this.setState({application: props.application});
|
||||||
|
console.log(props.application, nextProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
//TODO: Download image artifacts.
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEdit() {
|
||||||
|
this.props.history.push("/assets/apps/edit/" + this.state.application.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const platform = this.state.application;
|
||||||
|
console.log(platform);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id="application-view-content">
|
||||||
|
<div id="application-view-row">
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<div id="app-icon">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Row>
|
||||||
|
<span><strong>Facebook</strong></span>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<span className="app-updated-date">Last updated on 2017-09-23</span>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
<div id="application-view-row">
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<span className="app-install-count">2k Installs</span>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<i className="fw fw-star"></i>
|
||||||
|
<i className="fw fw-star"></i>
|
||||||
|
<i className="fw fw-star"></i>
|
||||||
|
<i className="fw fw-star"></i>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<a href="#">View in Store</a>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<div id="application-view-row">
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<span><strong>Description: </strong></span>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<p>sdfjlkdsjfsjdfjsdf sfjdslkjfdsflkjdsfslkdjfl j</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<span><strong>Tags: </strong></span>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<p>[list of tags...]</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<span><strong>Release: </strong></span>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<p>Production</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<span><strong>Version: </strong></span>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<p>v1.0</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withRouter(ApplicationView);
|
@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
|
||||||
import Badge from 'material-ui/Badge';
|
|
||||||
import React, {Component} from 'react';
|
|
||||||
import AppBar from 'material-ui/AppBar';
|
|
||||||
import Drawer from 'material-ui/Drawer';
|
|
||||||
import IconButton from 'material-ui/IconButton';
|
|
||||||
import {List, ListItem} from 'material-ui/List';
|
|
||||||
import Apps from 'material-ui/svg-icons/navigation/apps';
|
|
||||||
import NotificationsIcon from 'material-ui/svg-icons/social/notifications';
|
|
||||||
import ActionAccountCircle from 'material-ui/svg-icons/action/account-circle';
|
|
||||||
import {Link, withRouter} from 'react-router-dom';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base Layout:
|
|
||||||
* App bar
|
|
||||||
* Left Navigation
|
|
||||||
* Middle content.
|
|
||||||
* */
|
|
||||||
class BaseLayout extends Component {
|
|
||||||
|
|
||||||
handleApplicationClick() {
|
|
||||||
this.handleHistory('/assets/apps');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The method to update the history.
|
|
||||||
* to: The URL to route.
|
|
||||||
* */
|
|
||||||
handleHistory(to) {
|
|
||||||
this.props.history.push(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleUserLogin() {
|
|
||||||
if (this.props.state.store.user) {
|
|
||||||
return (
|
|
||||||
<IconButton tooltip={this.props.state.store.user}>
|
|
||||||
<ActionAccountCircle/>
|
|
||||||
</IconButton>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<Link to='/login'> Login</Link>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNotification() {
|
|
||||||
if (this.props.state.store.user) {
|
|
||||||
return (
|
|
||||||
<Badge
|
|
||||||
badgeContent={this.props.state.store.notifications}
|
|
||||||
secondary={true}
|
|
||||||
badgeStyle={{top: 12, right: 12}}>
|
|
||||||
<IconButton tooltip="Notifications">
|
|
||||||
<NotificationsIcon/>
|
|
||||||
</IconButton>
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<AppBar title="App Store"
|
|
||||||
iconElementRight={
|
|
||||||
<div>
|
|
||||||
{this.handleNotification()}
|
|
||||||
{this.handleUserLogin()}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<Drawer containerStyle={{height: 'calc(100% - 64px)', width: '15%', top: '13%', left: '1%'}}
|
|
||||||
open={true}>
|
|
||||||
<List>
|
|
||||||
<ListItem primaryText="Applications"
|
|
||||||
leftIcon={<Apps/>}
|
|
||||||
initiallyOpen={false}
|
|
||||||
primaryTogglesNestedList={true}
|
|
||||||
onClick={this.handleApplicationClick.bind(this)}
|
|
||||||
nestedItems={[
|
|
||||||
<ListItem
|
|
||||||
key={1}
|
|
||||||
primaryText="Business" //TODO: categoryies ...
|
|
||||||
leftIcon={<List/>}
|
|
||||||
/>]}
|
|
||||||
/>
|
|
||||||
</List>
|
|
||||||
</Drawer>
|
|
||||||
</div>
|
|
||||||
<div style=
|
|
||||||
{
|
|
||||||
{
|
|
||||||
height: 'calc(100% - 64px)',
|
|
||||||
marginLeft: '16%',
|
|
||||||
width: 'calc(100%-15%)',
|
|
||||||
top: 64,
|
|
||||||
left: "-100px"
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
{this.props.children}
|
|
||||||
</div>
|
|
||||||
</div>);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseLayout.propTypes = {
|
|
||||||
children: PropTypes.element
|
|
||||||
};
|
|
||||||
|
|
||||||
export default withRouter(BaseLayout);
|
|
@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* WSO2 Inc. 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 qs from 'qs';
|
|
||||||
import React, {Component} from 'react';
|
|
||||||
import Checkbox from 'material-ui/Checkbox';
|
|
||||||
import {Redirect, Route} from 'react-router-dom';
|
|
||||||
import RaisedButton from 'material-ui/RaisedButton';
|
|
||||||
import {Card, CardActions, CardTitle} from 'material-ui/Card';
|
|
||||||
import {TextValidator, ValidatorForm} from 'react-material-ui-form-validator';
|
|
||||||
import Store from '../App';
|
|
||||||
|
|
||||||
|
|
||||||
//todo: remove the {TextValidator, ValidatorForm} and implement it manually.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Login Component.
|
|
||||||
*
|
|
||||||
* This component contains the Login form and methods to handle field change events.
|
|
||||||
* The user name and password will be set to the state and sent to the api.
|
|
||||||
*
|
|
||||||
* If the user is already logged in, it will redirect to the last point where the user was.
|
|
||||||
* */
|
|
||||||
class Login extends Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
isLoggedIn: false,
|
|
||||||
referrer: "/",
|
|
||||||
userName: "",
|
|
||||||
rememberMe: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
let queryString = this.props.location.search;
|
|
||||||
console.log(queryString);
|
|
||||||
queryString = queryString.replace(/^\?/, '');
|
|
||||||
/* With QS version up we can directly use {ignoreQueryPrefix: true} option */
|
|
||||||
let params = qs.parse(queryString);
|
|
||||||
if (params.referrer) {
|
|
||||||
this.setState({referrer: params.referrer});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleLogin(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
console.log(this.props);
|
|
||||||
//TODO: send authentication request.
|
|
||||||
let location = {
|
|
||||||
pathname: this.state.referrer
|
|
||||||
};
|
|
||||||
let storeState = {
|
|
||||||
store : {
|
|
||||||
user: this.state.userName,
|
|
||||||
notifications: 0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.props.updateState(storeState);
|
|
||||||
this.props.history.push(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the username field change event.
|
|
||||||
* */
|
|
||||||
onUserNameChange(event) {
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
userName: event.target.value
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the password field change event.
|
|
||||||
* */
|
|
||||||
onPasswordChange(event) {
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
password: event.target.value
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the remember me check.
|
|
||||||
* */
|
|
||||||
handleRememberMe() {
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
rememberMe: !this.state.rememberMe
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSuccessfulLogin() {
|
|
||||||
return (
|
|
||||||
<Redirect to='/store'/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!(this.state.isLoggedIn && this.state.userName)) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
|
|
||||||
{/*TODO: Style the components.*/}
|
|
||||||
|
|
||||||
<Card>
|
|
||||||
<CardTitle title="WSO2 IoT App Store"/>
|
|
||||||
<CardActions>
|
|
||||||
<ValidatorForm
|
|
||||||
ref="form"
|
|
||||||
onSubmit={this.handleLogin.bind(this)}
|
|
||||||
onError={errors => console.log(errors)}>
|
|
||||||
<TextValidator
|
|
||||||
floatingLabelText="User Name"
|
|
||||||
floatingLabelFixed={true}
|
|
||||||
onChange={this.onUserNameChange.bind(this)}
|
|
||||||
name="userName"
|
|
||||||
validators={['required']}
|
|
||||||
errorMessages={['User Name is required']}
|
|
||||||
value={this.state.userName}
|
|
||||||
/>
|
|
||||||
<br/>
|
|
||||||
<TextValidator
|
|
||||||
floatingLabelText="Password"
|
|
||||||
floatingLabelFixed={true}
|
|
||||||
onChange={this.onPasswordChange.bind(this)}
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
value={this.state.password}
|
|
||||||
validators={['required']}
|
|
||||||
errorMessages={['Password is required']}
|
|
||||||
/>
|
|
||||||
<br/>
|
|
||||||
<Checkbox label="Remember me."
|
|
||||||
onCheck={this.handleRememberMe.bind(this)}
|
|
||||||
checked={this.state.rememberMe}/>
|
|
||||||
<br/>
|
|
||||||
<RaisedButton type="submit" label="Login"/>
|
|
||||||
</ValidatorForm>
|
|
||||||
</CardActions>
|
|
||||||
</Card>
|
|
||||||
</div>);
|
|
||||||
} else {
|
|
||||||
this.handleSuccessfulLogin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Login;
|
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Review Listing.
|
||||||
|
* */
|
||||||
|
class ReviewListing extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Reviews List
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReviewListing;
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Review details view.
|
||||||
|
* */
|
||||||
|
class ReviewView extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Review
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReviewView;
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import Theme from '../../../theme';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for holding uploaded image.
|
||||||
|
* This component has the feature to remove selected image from the array.
|
||||||
|
* */
|
||||||
|
class AppImage extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.removeImage = this.removeImage.bind(this);
|
||||||
|
this.scriptId = "appImage";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the parent method to remove the selected image.
|
||||||
|
* @param event: The click event of the component.
|
||||||
|
* */
|
||||||
|
removeImage(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.props.onRemove(event.target.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {image, imageId} = this.props;
|
||||||
|
return (
|
||||||
|
<div className="image-container" style={this.props.imageStyles}>
|
||||||
|
<img src={image} className="image" id={imageId}/>
|
||||||
|
<div className="btn-content">
|
||||||
|
<i className="close-btn" id={imageId} onClick={this.removeImage}>X</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppImage.propTypes = {
|
||||||
|
image: PropTypes.string,
|
||||||
|
imageId: PropTypes.string,
|
||||||
|
onRemove: PropTypes.func,
|
||||||
|
imageStyles: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppImage;
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import Theme from '../../../theme';
|
||||||
|
|
||||||
|
class Chip extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.scriptId = "chip";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="chip">
|
||||||
|
{this.props.image?<img src={this.props.image} alt="Person" width="96" height="96" />:<div/>}
|
||||||
|
{this.props.text}
|
||||||
|
<span className="close-btn" >×</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Chip;
|
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 Theme from '../../../theme';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import DataTableRow from './DataTableRow';
|
||||||
|
import DataTableHeader from './DataTableHeader';
|
||||||
|
import RaisedButton from 'material-ui/RaisedButton';
|
||||||
|
import {Table, TableBody, TableHeader, TableRow} from 'material-ui/Table';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Custom Table Component.
|
||||||
|
* This component wraps the material-ui Table component and add some extra functionalities.
|
||||||
|
* 1. Table header click. (For sorting)
|
||||||
|
* 2. Table row click.
|
||||||
|
*
|
||||||
|
* The main sort function is defined in the component where the data table is created and passed to the
|
||||||
|
* DataTable component via props.
|
||||||
|
*
|
||||||
|
* Following are the DataTable proptypes.
|
||||||
|
* 1. Headers: Table headers. This is an array of Json Objects.
|
||||||
|
* An Header Object contains the properties of each header. Currently following properties
|
||||||
|
* are supported.
|
||||||
|
* * sortable: boolean : whether the table column is sortable or not.
|
||||||
|
* * sort: func : If sortable, the sort function.
|
||||||
|
* * sort: func : If sortable, the sort function.
|
||||||
|
* * sort: func : If sortable, the sort function.
|
||||||
|
* * label: String: The Table header string.
|
||||||
|
* * id: String: Unique id for header.
|
||||||
|
*
|
||||||
|
* 2. Data: The list of data that needs to be displayed in the table.
|
||||||
|
* This is also a json array of data objects.
|
||||||
|
* The Json object should contain key: value pair where the key is the header id.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
class DataTable extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.handleRowClick = this.handleRowClick.bind(this);
|
||||||
|
this.handleBtnClick = this.handleBtnClick.bind(this);
|
||||||
|
this.state = {
|
||||||
|
data: [],
|
||||||
|
headers: [],
|
||||||
|
};
|
||||||
|
this.scriptId = "data-table"
|
||||||
|
};
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
console.log("Will mount", this.props.data); //TODO: Remove this
|
||||||
|
this.setState({data: this.props.data, headers: this.props.headers}, Theme.insertThemingScripts(this.scriptId));
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
if (!nextProps.data) {
|
||||||
|
this.setState({data: nextState.data});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.setState({data: nextProps.data});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers when user click on table row.
|
||||||
|
* This method invokes the parent method handleRowClick, which is passed via props.
|
||||||
|
* */
|
||||||
|
handleRowClick(id) {
|
||||||
|
this.props.handleRowClick(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBtnClick(id) {
|
||||||
|
this.props.handleButtonClick(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {data, headers} = this.state;
|
||||||
|
|
||||||
|
//TODO: Remove this
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
let noDataContent = null;
|
||||||
|
|
||||||
|
if (this.props.noDataMessage.type === 'button') {
|
||||||
|
noDataContent = <div><RaisedButton label={this.props.noDataMessage.text}/></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
return (<Table
|
||||||
|
selectable={false}>
|
||||||
|
<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
|
||||||
|
<TableRow>
|
||||||
|
{headers.map((header) => {
|
||||||
|
return (
|
||||||
|
<DataTableHeader
|
||||||
|
key={header.data_id}
|
||||||
|
className="datatableRowColumn"
|
||||||
|
header={header}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{data.map((dataItem) => {
|
||||||
|
return (
|
||||||
|
<DataTableRow
|
||||||
|
key={dataItem.id}
|
||||||
|
dataItem={dataItem}
|
||||||
|
handleButtonClick={this.handleBtnClick}
|
||||||
|
handleClick={this.handleRowClick}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>)
|
||||||
|
}
|
||||||
|
return (<div>{noDataContent}</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTable.prototypes = {
|
||||||
|
data: PropTypes.arrayOf(Object),
|
||||||
|
headers: PropTypes.arrayOf(Object),
|
||||||
|
sortData: PropTypes.func,
|
||||||
|
handleRowClick: PropTypes.func,
|
||||||
|
noDataMessage: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataTable;
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 Theme from '../../../theme';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import FlatButton from 'material-ui/FlatButton';
|
||||||
|
import {TableHeaderColumn} from 'material-ui/Table';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Table header component.
|
||||||
|
* This component creates the header elements of the table.
|
||||||
|
* */
|
||||||
|
class DataTableHeader extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.tableHeaderClick = this.tableHeaderClick.bind(this);
|
||||||
|
this.scriptId = "data-table";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The onClick function of the table header.
|
||||||
|
* Invokes the function passed in the header object.
|
||||||
|
* */
|
||||||
|
tableHeaderClick() {
|
||||||
|
this.props.header.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let headerCell = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the header is sortable, create a button with onClick handler.
|
||||||
|
* else create a span element with label as the table header.
|
||||||
|
* */
|
||||||
|
if (this.props.header.sortable) {
|
||||||
|
headerCell =
|
||||||
|
<FlatButton
|
||||||
|
label={this.props.header.label}
|
||||||
|
onClick={this.tableHeaderClick}
|
||||||
|
className="sortableHeaderCell"
|
||||||
|
/>
|
||||||
|
} else {
|
||||||
|
headerCell = <span className="notsortableHeaderCell">{this.props.header.label}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableHeaderColumn key={this.props.header.id} className="datatableHeaderColumn">
|
||||||
|
{headerCell}
|
||||||
|
</TableHeaderColumn>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTableHeader.prototypes = {
|
||||||
|
header: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataTableHeader;
|
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 Theme from '../../../theme';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import IconButton from 'material-ui/IconButton';
|
||||||
|
import Create from 'material-ui/svg-icons/content/create'
|
||||||
|
import {TableRow, TableRowColumn} from 'material-ui/Table';
|
||||||
|
import Avatar from 'material-ui/Avatar';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data table row component.
|
||||||
|
* This component created a row in the data table according to the props.
|
||||||
|
* */
|
||||||
|
class DataTableRow extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
dataItem: {}
|
||||||
|
};
|
||||||
|
this.scriptId = "data-table";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.setState({dataItem: this.props.dataItem});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the click event on the data table row.
|
||||||
|
* */
|
||||||
|
handleClick(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.props.handleClick(this.state.dataItem.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBtnClick(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
console.log(event.target['id'])
|
||||||
|
this.props.handleButtonClick(event.target['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {dataItem} = this.state;
|
||||||
|
return (
|
||||||
|
<TableRow
|
||||||
|
key={this.props.key}
|
||||||
|
onClick={this.handleClick.bind(this)}
|
||||||
|
>
|
||||||
|
<TableRowColumn
|
||||||
|
className="datatableRowColumn"
|
||||||
|
key={Math.random()}
|
||||||
|
>
|
||||||
|
<Avatar>{dataItem.name}</Avatar>
|
||||||
|
</TableRowColumn>
|
||||||
|
{Object.keys(dataItem).map((key) => {
|
||||||
|
if (key !== 'id') {
|
||||||
|
return (
|
||||||
|
<TableRowColumn
|
||||||
|
className="datatableRowColumn"
|
||||||
|
key={key}
|
||||||
|
>
|
||||||
|
{dataItem[key]}
|
||||||
|
</TableRowColumn>)
|
||||||
|
}
|
||||||
|
|
||||||
|
})}
|
||||||
|
<TableRowColumn
|
||||||
|
className="datatableRowColumn"
|
||||||
|
key={dataItem.id}
|
||||||
|
>
|
||||||
|
<IconButton id={dataItem.id} onClick={this.handleBtnClick.bind(this)}>
|
||||||
|
<Create id={dataItem.id}/>
|
||||||
|
</IconButton>
|
||||||
|
</TableRowColumn>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTableRow.propTypes = {
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
data: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataTableRow;
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import Theme from '../../../theme'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom React component for Application View.
|
||||||
|
* */
|
||||||
|
class Drawer extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.closeDrawer = this.closeDrawer.bind(this);
|
||||||
|
this.scriptId = "drawer";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the drawer.
|
||||||
|
* */
|
||||||
|
closeDrawer() {
|
||||||
|
this.props.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div id="app-view" className="app-view-drawer" style={this.props.style}>
|
||||||
|
<a onClick={this.closeDrawer} className="drawer-close-btn"><i className="fw fw-uncheck"></i></a>
|
||||||
|
{this.props.children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Drawer.propTypes = {
|
||||||
|
style: PropTypes.object,
|
||||||
|
children: PropTypes.node,
|
||||||
|
onClose: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Drawer;
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import Theme from '../../../theme';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Floating Action button.
|
||||||
|
* */
|
||||||
|
class FloatingButton extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.scriptId = "floatingButton";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick(event) {
|
||||||
|
this.props.onClick(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let classes = 'btn-circle ' + this.props.className;
|
||||||
|
return (
|
||||||
|
<div className={classes} onClick={this.handleClick.bind(this)}>
|
||||||
|
<i className="fw fw-add"></i>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatingButton.propTypes = {
|
||||||
|
classNames: PropTypes.string,
|
||||||
|
onClick: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FloatingButton;
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 PropTypes from 'prop-types';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import Dropzone from "react-dropzone";
|
||||||
|
import {Row} from "reactstrap";
|
||||||
|
import Theme from '../../../theme';
|
||||||
|
|
||||||
|
|
||||||
|
class ImageUploader extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.setImages = this.setImages.bind(this);
|
||||||
|
this.state = {
|
||||||
|
images: []
|
||||||
|
};
|
||||||
|
this.scriptId = "imageUploader";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
setImages(images) {
|
||||||
|
this.props.setImages(images);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {images, height, width, accepted, multiple, maxAmount} = this.props;
|
||||||
|
return (
|
||||||
|
<div id="screenshot-container">
|
||||||
|
<Row>
|
||||||
|
{images.map((tile) => (
|
||||||
|
<input type="image" src={tile[0].preview} onClick=""/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
{this.state.screenshots.length < maxAmount ?
|
||||||
|
<Dropzone
|
||||||
|
className="add-image"
|
||||||
|
accept="image/jpeg, image/png"
|
||||||
|
onDrop={(accepted, rejected) => {
|
||||||
|
this.setImages(accepted);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p className="add-image-symbol">+</p>
|
||||||
|
</Dropzone> : <div/>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageUploader.prototypes = {
|
||||||
|
height: PropTypes.string,
|
||||||
|
width: PropTypes.string,
|
||||||
|
accepted: PropTypes.array,
|
||||||
|
multiple: PropTypes.bool,
|
||||||
|
maxAmount: PropTypes.number,
|
||||||
|
setImages: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default ImageUploader;
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import {Col, Row} from "reactstrap";
|
||||||
|
import Theme from '../../../theme'
|
||||||
|
|
||||||
|
class NotificationItem extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.scriptId = "notification";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<div className="notification-app-icon small">
|
||||||
|
<img/>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<p>Your application, Facebook has been published.</p>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NotificationItem;
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import {Col, Row} from "reactstrap";
|
||||||
|
import './notification.css';
|
||||||
|
import Theme from '../../../theme'
|
||||||
|
|
||||||
|
class NotificationView extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.scriptId = "notification";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div id="notification-view-content">
|
||||||
|
<div>
|
||||||
|
<Row id="notification-content">
|
||||||
|
<Col xs="3">
|
||||||
|
<div className="notification-app-icon medium">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col xs="9">
|
||||||
|
<Row>
|
||||||
|
<span><strong>Application Name</strong></span>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<span>Version 1.0</span>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<p id="app-reject-msg">Your Application was rejected</p>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<hr/>
|
||||||
|
<Row id="notification-content">
|
||||||
|
<Col xs="12">
|
||||||
|
<p>Following validations were detected in your review submission.
|
||||||
|
Please attend to them and re-submit</p>
|
||||||
|
<ul>
|
||||||
|
<li>sdjjfsdfsdfkjs shdfjhlkds hflkhfdslkd </li>
|
||||||
|
<li>sdfkds jfdsljfklsdfjksdjlksdjdlkf</li>
|
||||||
|
<li>sfksdf slkjskd jfjds lkfjdsfdsfdslkf sjf lkdsf</li>
|
||||||
|
<li>skfjslkdjfsdjfjksldjf sdkl jflkds jfkslfjs</li>
|
||||||
|
<li>ksdf jks;kshflk hlkjhds lkjhdsklhsd lkf</li>
|
||||||
|
<li> jsdljflksd jfklsdfskljfkjshf;ks ldj</li>
|
||||||
|
</ul>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NotificationView;
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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, {Component} from 'react';
|
||||||
|
import Theme from '../../../theme';
|
||||||
|
|
||||||
|
class Switch extends Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.scriptId = "switch";
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
/**
|
||||||
|
*Loading the theme files based on the the user-preference.
|
||||||
|
*/
|
||||||
|
Theme.insertThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
Theme.removeThemingScripts(this.scriptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {height, width} = this.props;
|
||||||
|
return (
|
||||||
|
<label className="switch">
|
||||||
|
<input type="checkbox" onChange={this.props.onChange}/>
|
||||||
|
<span className="slider round"></span>
|
||||||
|
</label>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Switch;
|
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 qs from 'qs';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import {Redirect, Switch} from 'react-router-dom';
|
||||||
|
import AuthHandler from '../../../api/authHandler';
|
||||||
|
import {Button, Card, CardBlock, CardTitle, Col, Form, FormGroup, Input, Label} from 'reactstrap';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Login Component.
|
||||||
|
*
|
||||||
|
* This component contains the Login form and methods to handle field change events.
|
||||||
|
* The user name and password will be set to the state and sent to the api.
|
||||||
|
*
|
||||||
|
* If the user is already logged in, it will redirect to the last point where the user was.
|
||||||
|
* */
|
||||||
|
class Login extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
isLoggedIn: false,
|
||||||
|
referrer: "/",
|
||||||
|
userName: "",
|
||||||
|
password: "",
|
||||||
|
rememberMe: true,
|
||||||
|
errors: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
let queryString = this.props.location.search;
|
||||||
|
console.log(queryString);
|
||||||
|
queryString = queryString.replace(/^\?/, '');
|
||||||
|
/* With QS version up we can directly use {ignoreQueryPrefix: true} option */
|
||||||
|
let params = qs.parse(queryString);
|
||||||
|
if (params.referrer) {
|
||||||
|
this.setState({referrer: params.referrer});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleLogin(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.validateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the username field change event.
|
||||||
|
* */
|
||||||
|
onUserNameChange(event, value) {
|
||||||
|
console.log(event.target.value);
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
userName: event.target.value
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the password field change event.
|
||||||
|
* */
|
||||||
|
onPasswordChange(event, value) {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
password: event.target.value
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the remember me check.
|
||||||
|
* */
|
||||||
|
handleRememberMe() {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
rememberMe: !this.state.rememberMe
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the login form.
|
||||||
|
* */
|
||||||
|
validateForm() {
|
||||||
|
let errors = {};
|
||||||
|
let validationFailed = true;
|
||||||
|
if (!this.state.password) {
|
||||||
|
errors["passwordError"] = "Password is Required";
|
||||||
|
validationFailed = true;
|
||||||
|
} else {
|
||||||
|
validationFailed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.userName) {
|
||||||
|
errors["userNameError"] = "User Name is Required";
|
||||||
|
validationFailed = true;
|
||||||
|
} else {
|
||||||
|
validationFailed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validationFailed) {
|
||||||
|
this.setState({errors: errors}, console.log(errors));
|
||||||
|
} else {
|
||||||
|
let loginPromis = AuthHandler.login(this.state.userName, this.state.password);
|
||||||
|
loginPromis.then(response => {
|
||||||
|
console.log(AuthHandler.getUser());
|
||||||
|
this.setState({isLoggedIn: AuthHandler.getUser()});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
if (!this.state.isLoggedIn) {
|
||||||
|
return (
|
||||||
|
<div id="login-container">
|
||||||
|
{/*TODO: Style the components.*/}
|
||||||
|
<Card id="login-card">
|
||||||
|
<CardBlock>
|
||||||
|
<CardTitle>WSO2 IoT APP Store</CardTitle>
|
||||||
|
<Form onSubmit={this.handleLogin.bind(this)}>
|
||||||
|
<FormGroup row>
|
||||||
|
<Label for="userName" sm={2}>User Name:</Label>
|
||||||
|
<Col sm={10}>
|
||||||
|
<Input type="text" name="userName" id="userName" placeholder="User Name"
|
||||||
|
onChange={this.onUserNameChange.bind(this)}/>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup row>
|
||||||
|
<Label for="password" sm={2}>Password:</Label>
|
||||||
|
<Col sm={10}>
|
||||||
|
<Input type="password" name="text" id="password" placeholder="Password"
|
||||||
|
onChange={this.onPasswordChange.bind(this)}/>
|
||||||
|
</Col>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup check row>
|
||||||
|
<Col sm={{size: 10, offset: 2}}>
|
||||||
|
<Button type="submit" id="login-btn">Login</Button>
|
||||||
|
</Col>
|
||||||
|
</FormGroup>
|
||||||
|
</Form>
|
||||||
|
</CardBlock>
|
||||||
|
</Card>
|
||||||
|
</div>);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Switch>
|
||||||
|
<Redirect to={this.state.referrer}/>
|
||||||
|
</Switch>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Login;
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"theme" : {
|
|
||||||
"current" : "default",
|
|
||||||
"default" : "lightBaseTheme",
|
|
||||||
"custom" : "custom-theme"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import Store from './App';
|
import Store from './App';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
|
import {IntlProvider, addLocaleData, defineMessages} from 'react-intl';
|
||||||
|
import Axios from 'axios';
|
||||||
|
import Constants from './common/constants';
|
||||||
|
import Configuration from './common/configuration';
|
||||||
|
|
||||||
|
function loadStore() {
|
||||||
|
const possibleLocale = navigator.language.split("-")[0];
|
||||||
|
let loadLocaleFile = Axios.create({
|
||||||
|
baseURL: Configuration.hostConstants.baseURL + "/" + Configuration.hostConstants.appContext + "/locales/"
|
||||||
|
+ possibleLocale + ".json"
|
||||||
|
}).get();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the base js file of the app. All the content will be rendered in the root element.
|
||||||
|
* */
|
||||||
|
loadLocaleFile.then(response => {
|
||||||
|
const messages = defineMessages(response.data);
|
||||||
|
addLocaleData(require('react-intl/locale-data/' + possibleLocale));
|
||||||
|
ReactDOM.render(<IntlProvider locale={possibleLocale}
|
||||||
|
messages={messages}><Store/></IntlProvider>, document.getElementById('root'));
|
||||||
|
registerServiceWorker();
|
||||||
|
}).catch(error => {
|
||||||
|
addLocaleData(require('react-intl/locale-data/en'));
|
||||||
|
let defaultLocale = Axios.create({
|
||||||
|
baseURL: Configuration.hostConstants.baseURL + "/" + Configuration.hostConstants.appContext + "/locales"
|
||||||
|
+ Constants.defaultLocale + ".json"
|
||||||
|
}).get();
|
||||||
|
defaultLocale.then(response => {
|
||||||
|
const messages = defineMessages(response.data);
|
||||||
|
ReactDOM.render(<IntlProvider locale={possibleLocale}
|
||||||
|
messages={messages}><Store/></IntlProvider>, document.getElementById('root'));
|
||||||
|
registerServiceWorker();
|
||||||
|
}).catch(error => {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ReactDOM.render(<Store />, document.getElementById('root'));
|
Configuration.loadConfiguration(loadStore);
|
||||||
|
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// In production, we register a service worker to serve assets from local cache.
|
||||||
|
|
||||||
|
// This lets the app load faster on subsequent visits in production, and gives
|
||||||
|
// it offline capabilities. However, it also means that developers (and users)
|
||||||
|
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||||
|
// cached resources are updated in the background.
|
||||||
|
|
||||||
|
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||||
|
// This link also includes instructions on opting out of this behavior.
|
||||||
|
|
||||||
|
const isLocalhost = Boolean(
|
||||||
|
window.location.hostname === 'localhost' ||
|
||||||
|
// [::1] is the IPv6 localhost address.
|
||||||
|
window.location.hostname === '[::1]' ||
|
||||||
|
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||||
|
window.location.hostname.match(
|
||||||
|
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function register() {
|
||||||
|
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||||
|
// The URL constructor is available in all browsers that support SW.
|
||||||
|
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||||
|
if (publicUrl.origin !== window.location.origin) {
|
||||||
|
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||||
|
// from what our page is served on. This might happen if a CDN is used to
|
||||||
|
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
const swUrl = `${process.env.PUBLIC_URL}/store/service-worker.js`;
|
||||||
|
|
||||||
|
if (!isLocalhost) {
|
||||||
|
// Is not local host. Just register service worker
|
||||||
|
registerValidSW(swUrl);
|
||||||
|
} else {
|
||||||
|
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||||
|
checkValidServiceWorker(swUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerValidSW(swUrl) {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register(swUrl)
|
||||||
|
.then(registration => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing;
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
if (installingWorker.state === 'installed') {
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// At this point, the old content will have been purged and
|
||||||
|
// the fresh content will have been added to the cache.
|
||||||
|
// It's the perfect time to display a "New content is
|
||||||
|
// available; please refresh." message in your web app.
|
||||||
|
console.log('New content is available; please refresh.');
|
||||||
|
} else {
|
||||||
|
// At this point, everything has been precached.
|
||||||
|
// It's the perfect time to display a
|
||||||
|
// "Content is cached for offline use." message.
|
||||||
|
console.log('Content is cached for offline use.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error during service worker registration:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkValidServiceWorker(swUrl) {
|
||||||
|
// Check if the service worker can be found. If it can't reload the page.
|
||||||
|
fetch(swUrl)
|
||||||
|
.then(response => {
|
||||||
|
// Ensure service worker exists, and that we really are getting a JS file.
|
||||||
|
if (
|
||||||
|
response.status === 404 ||
|
||||||
|
response.headers.get('content-type').indexOf('javascript') === -1
|
||||||
|
) {
|
||||||
|
// No service worker found. Probably a different app. Reload the page.
|
||||||
|
navigator.serviceWorker.ready.then(registration => {
|
||||||
|
registration.unregister().then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Service worker found. Proceed as normal.
|
||||||
|
registerValidSW(swUrl);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log(
|
||||||
|
'No internet connection found. App is running in offline mode.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregister() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.ready.then(registration => {
|
||||||
|
registration.unregister();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. 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 axios from 'axios';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will read through the configuration file and saves the theme names for the usage in other files.
|
||||||
|
* User can define the themes in the config.json. The themes will be loaded based on the user preference.
|
||||||
|
*/
|
||||||
|
class Theme {
|
||||||
|
constructor() {
|
||||||
|
this.defaultThemeType = "default";
|
||||||
|
this.currentThemeType = this.defaultThemeType;
|
||||||
|
this.currentTheme = "lightBaseTheme";
|
||||||
|
this.themeFolder = "themes";
|
||||||
|
this.styleSheetType = "text/css";
|
||||||
|
this.styleSheetRel = "stylesheet";
|
||||||
|
this.selectedTheme = this.defaultThemeType;
|
||||||
|
|
||||||
|
//TODO Need to get the app context properly when the server is ready
|
||||||
|
this.baseURL = window.location.origin;
|
||||||
|
this.appContext = window.location.pathname.split("/")[1];
|
||||||
|
this.loadThemeConfigs = this.loadThemeConfigs.bind(this);
|
||||||
|
this.loadThemeFiles = this.loadThemeFiles.bind(this);
|
||||||
|
this.insertThemingScripts = this.insertThemingScripts.bind(this);
|
||||||
|
this.removeThemingScripts = this.removeThemingScripts.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To load the theme related configurations from the configuration file.
|
||||||
|
* @returns the http response.
|
||||||
|
*/
|
||||||
|
loadThemeConfigs () {
|
||||||
|
let httpClient = axios.create({
|
||||||
|
baseURL: this.baseURL + "/" + this.appContext + "/config.json",
|
||||||
|
timeout: 2000
|
||||||
|
});
|
||||||
|
httpClient.defaults.headers.post['Content-Type'] = 'application/json';
|
||||||
|
return httpClient.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To load the particular theme file from the path.
|
||||||
|
* @param path Path to load the theme files
|
||||||
|
* @returns Http response from the particular file.
|
||||||
|
*/
|
||||||
|
loadThemeFiles (path) {
|
||||||
|
let httpClient = axios.create({
|
||||||
|
baseURL: this.baseURL + "/" + this.appContext + path,
|
||||||
|
timeout: 2000
|
||||||
|
});
|
||||||
|
return httpClient.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To insert the css files to the document.
|
||||||
|
* @param scriptId ID of the script that need to be inserted
|
||||||
|
*/
|
||||||
|
insertThemingScripts(scriptId) {
|
||||||
|
const script = scriptId + ".css";
|
||||||
|
let themePath = "/" + this.themeFolder + "/" + this.selectedTheme + "/" + script;
|
||||||
|
let themeFile = this.loadThemeFiles(themePath);
|
||||||
|
let head = document.getElementsByTagName("head")[0];
|
||||||
|
let link = document.createElement("link");
|
||||||
|
link.type = this.styleSheetType;
|
||||||
|
link.href = this.baseURL + "/" + this.appContext + themePath;
|
||||||
|
link.id = scriptId;
|
||||||
|
link.rel = this.styleSheetRel;
|
||||||
|
this.removeThemingScripts(scriptId);
|
||||||
|
|
||||||
|
themeFile.then(function () {
|
||||||
|
head.appendChild(link);
|
||||||
|
}).catch(error => {
|
||||||
|
// If there is no customized css file, load the default one.
|
||||||
|
themePath = "/" + this.themeFolder + "/" + this.defaultThemeType + "/" + script;
|
||||||
|
link.href = this.baseURL + "/" + this.appContext + themePath;
|
||||||
|
head.appendChild(link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To remove the css scripts that are inserted before.
|
||||||
|
* @param scriptId Id of the script that need to be removed
|
||||||
|
*/
|
||||||
|
removeThemingScripts(scriptId) {
|
||||||
|
let styleSheet = document.getElementById(scriptId);
|
||||||
|
if (styleSheet !== null) {
|
||||||
|
styleSheet.disabled = true;
|
||||||
|
styleSheet.parentNode.removeChild(styleSheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (new Theme);
|
Loading…
Reference in new issue