Added the stepper and App creation first step.

feature/appm-store/pbac
Menaka Jayawardena 7 years ago
parent c7c0f62ca2
commit d2705b1427

@ -15,6 +15,7 @@
"latest-version": "^3.1.0", "latest-version": "^3.1.0",
"material-ui": "^0.19.0", "material-ui": "^0.19.0",
"material-ui-datatables": "^0.18.2", "material-ui-datatables": "^0.18.2",
"qs": "^6.5.0",
"react": "^15.6.1", "react": "^15.6.1",
"react-dom": "^15.6.1", "react-dom": "^15.6.1",
"react-images-uploader": "^1.1.0", "react-images-uploader": "^1.1.0",

@ -16,41 +16,40 @@
* under the License. * under the License.
*/ */
import React, {Component} from 'react';
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom'
import './App.css' import './App.css'
import {BaseLayout, Create, Login, NotFound} from './components' import React, {Component} from 'react';
import createHistory from 'history/createBrowserHistory'; import createHistory from 'history/createHashHistory';
import {HashRouter as Router, Redirect, Route, Switch} from 'react-router-dom'
const history = createHistory({basename:'/publisher'}); import {BaseLayout, Create, Login, NotFound, PublisherOverview} from './components'
const history = createHistory({basename: '/publisher'});
class Base extends Component { class Base extends Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
user: "m" user: "s"
} }
} }
render() { render() {
if (this.state.user) { if (this.state.user) {
return( return (
<div className="container"> <div className="container">
<BaseLayout> <BaseLayout>
<Switch> <Switch>
<Redirect exact path={"/"} to={"/assets"}/> <Redirect exact path={"/"} to={"/overview"}/>
<Route exact path={"/assets"} component={NotFound}/> <Route exact path={"/overview"} component={PublisherOverview}/>
<Route path={"/assets/apps"} component={Create}/> {/*<Route path={"/assets/apps"} component={}/>*/}
<Route path={"/assets/apps/:app"}/> {/*<Route path={"/assets/apps/:app"} component={}/>*/}
<Route path={"/assets/apps/create"}/> <Route path={"/assets/apps/create"} component={Create}/>
<Route path={"/assets/apps/edit"}/> {/*<Route path={"/assets/apps/edit/:app"} component="app edit"/>*/}
<Route path={"/assets/platform/:platform"}/> <Route path={"/assets/platforms/:platform"}/>
<Route path={"/assets/platform/create"}/> <Route path={"/assets/platforms/create"}/>
<Route path={"/assets/platform/edit"}/> <Route path={"/assets/platforms/edit/:platform"}/>
<Route path={"/assets/reviews"}/> <Route path={"/assets/reviews"}/>
<Route path={"/assets/reviews/:review"}/> <Route path={"/assets/reviews/:review"}/>
<Route component={NotFound} /> <Route component={NotFound}/>
</Switch> </Switch>
</BaseLayout> </BaseLayout>
</div> </div>
@ -62,19 +61,19 @@ class Base extends Component {
} }
class Publisher extends Component { class Publisher extends Component {
render() { render() {
return ( return (
<div className="App"> <div className="App">
<Router basename="publisher" history={history}> <Router basename="publisher" history={history}>
<Switch> <Switch>
<Route path="/login" component={Login}/> <Route path="/login" component={Login}/>
<Route path="/logout" component={Login}/> <Route path="/logout" component={Login}/>
<Route component={Base}/> <Route component={Base}/>
</Switch> </Switch>
</Router> </Router>
</div> </div>
); );
} }
} }
export default Publisher; export default Publisher;

@ -15,3 +15,171 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import React, {Component} from 'react';
import Dialog from 'material-ui/Dialog';
import {withRouter} from 'react-router-dom';
import {Step1, Step2, Step3} from './Forms';
import FlatButton from 'material-ui/FlatButton';
import RaisedButton from 'material-ui/RaisedButton';
import {Card, CardActions, CardTitle} from 'material-ui/Card';
import {Step, StepLabel, Stepper,} from 'material-ui/Stepper';
class Create extends Component {
constructor() {
super();
this.setStepData.bind(this);
this.removeStepData.bind(this);
this.handleSubmit.bind(this);
this.handleCancel.bind(this);
this.handleYes.bind(this);
this.handleNo.bind(this);
this.state = {
finished: false,
stepIndex: 0,
stepData: [],
isDialogOpen: false
};
}
handleNext = () => {
const {stepIndex} = this.state;
this.setState({
stepIndex: stepIndex + 1,
finished: stepIndex >= 2,
});
};
handleSubmit = () => {
console.log(this.state.stepData);
};
handleCancel = () => {
this.setState({isDialogOpen: true});
};
handlePrev = () => {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.removeStepData();
this.setState({stepIndex: stepIndex - 1});
}
};
setStepData = (step, data) => {
console.log(step, data, this.state.stepData);
let tmpStepData = this.state.stepData;
tmpStepData.push({step: step, data: data});
this.setState({stepData: tmpStepData})
};
/**
* Remove the last data point
* */
removeStepData = () => {
let tempData = this.state.stepData;
tempData.pop();
this.setState({stepData: tempData});
};
handleYes = () => {
this.setState({finished: false, stepIndex: 0, stepData: [], isDialogOpen: false});
};
handleNo = () => {
this.setState({isDialogOpen: false});
};
getStepContent(stepIndex) {
switch (stepIndex) {
case 0:
return <Step1 handleNext={this.handleNext}
setData={this.setStepData}
removeData={this.removeStepData}/>;
case 1:
return <Step2 handleNext={this.handleNext}
handlePrev={this.handlePrev}
setData={this.setStepData}
removeData={this.removeStepData}/>;
case 2:
return <Step3 handleFinish={this.handleNext}
handlePrev={this.handlePrev}
setData={this.setStepData}
removeData={this.removeStepData}/>;
default:
return 'You\'re a long way from home sonny jim!';
}
}
render() {
const {finished, stepIndex} = this.state;
const contentStyle = {margin: '0 16px'};
const actions = [
<FlatButton
label="Yes"
primary={true}
onClick={this.handleYes}
/>,
<FlatButton
label="No"
secondary={true}
onClick={this.handleNo}
/>,
];
return (
<div className="middle" style={{width: '95%', height: '100%', marginTop: '1%'}}>
<Card>
<CardTitle title="Create Application"/>
{/**
* The stepper goes here.
*/}
<CardActions>
<div style={{width: '100%', margin: 'auto'}}>
<Stepper activeStep={stepIndex}>
<Step>
<StepLabel>Select Application Platform</StepLabel>
</Step>
<Step>
<StepLabel>Enter Application Details</StepLabel>
</Step>
<Step>
<StepLabel>Release</StepLabel>
</Step>
</Stepper>
<div style={contentStyle}>
{finished ? (
<div>
<p>Create App?</p>
<form onSubmit={this.handleSubmit}>
<RaisedButton primary={true} label="Create" onClick={this.handleSubmit}/>
<FlatButton label="Cancel" onClick={this.handleCancel}/>
</form>
</div>
) : (
<div>
{this.getStepContent(stepIndex)}
</div>
)}
</div>
</div>
</CardActions>
</Card>
<Dialog
actions={actions}
modal={false}
open={this.state.isDialogOpen}
onRequestClose={this.handleNo}
>
Do you really want to cancel?
</Dialog>
</div>);
}
}
export default withRouter(Create);

@ -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 React, {Component} from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
class Step1 extends Component {
constructor() {
super();
this.state = {
finished: false,
stepIndex: 0,
store: 1,
platform: 1,
stepData: []
};
}
handleNext = () => {
this.props.handleNext();
};
setStepData() {
this.props.setData("step1", {step:"Dfds"});
this.handleNext.bind(this);
}
handleClick() {
this.setStepData();
this.handleNext();
}
handlePrev() {
this.props.handlePrev();
}
onChangePlatform = (event, index, value) => {
this.setState({platform: value});
};
onChangeStore = (event, index, value) => {
this.setState({store: value});
};
render() {
const {finished, stepIndex} = this.state;
const contentStyle = {margin: '0 16px'};
return (
<div>
<div style={contentStyle}>
<div>
<div>
<TextField
hintText="Enter a title for your application."
floatingLabelText="Title*"
floatingLabelFixed={true}
/><br />
<SelectField
floatingLabelText="Store Type*"
value={this.state.store}
floatingLabelFixed={true}
onChange={this.onChangeStore.bind(this)}
>
<MenuItem value={1} primaryText="Enterprise" />
<MenuItem value={2} primaryText="Public" />
</SelectField> <br />
<SelectField
floatingLabelText="Platform*"
value={this.state.platform}
floatingLabelFixed={true}
onChange={this.onChangePlatform.bind(this)}
>
<MenuItem value={1} primaryText="Android" />
<MenuItem value={2} primaryText="iOS" />
<MenuItem value={3} primaryText="Web" />
</SelectField>
</div>
<div style={{marginTop: 12}}>
<FlatButton
label="< Back"
disabled= {true}
onClick={this.handlePrev.bind(this)}
style={{marginRight: 12}}
/>
<RaisedButton
label="Next >"
primary={true}
onClick={this.handleClick.bind(this)}
/>
</div>
</div>
</div>
</div>
);
}
}
export default Step1;

@ -0,0 +1,61 @@
/*
* 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 RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
class Step2 extends Component {
constructor() {
super();
}
handleNext() {
this.props.handleNext();
}
handlePrev() {
this.props.handlePrev();
}
render() {
const contentStyle = {margin: '0 16px'};
return (
<div style={contentStyle}>
Step2
<div>
<div style={{marginTop: 12}}>
<FlatButton
label="< Back"
disabled= {false}
onClick={this.handlePrev.bind(this)}
style={{marginRight: 12}}
/>
<RaisedButton
label="Next >"
primary={true}
onClick={this.handleNext.bind(this)}
/>
</div>
</div>
</div>
);
}
}
export default Step2;

@ -0,0 +1,61 @@
/*
* 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 RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
class Step3 extends Component {
constructor() {
super();
}
handleFinish() {
this.props.handleFinish();
}
handlePrev() {
this.props.handlePrev();
}
render() {
const contentStyle = {margin: '0 16px'};
return (
<div style={contentStyle}>
Step3
<div>
<div style={{marginTop: 12}}>
<FlatButton
label="< Back"
disabled= {false}
onClick={this.handlePrev.bind(this)}
style={{marginRight: 12}}
/>
<RaisedButton
label="Finish"
primary={true}
onClick={this.handleFinish.bind(this)}
/>
</div>
</div>
</div>
);
}
}
export default Step3;

@ -0,0 +1,23 @@
/*
* 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 Step1 from './Step1';
import Step2 from './Step2';
import Step3 from './Step3';
export {Step1, Step2, Step3};

@ -19,12 +19,17 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import AppBar from 'material-ui/AppBar'; import AppBar from 'material-ui/AppBar';
import Drawer from 'material-ui/Drawer'; import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import Menu from 'material-ui/Menu';
import IconButton from 'material-ui/IconButton'; import IconButton from 'material-ui/IconButton';
import Notifications from 'material-ui/svg-icons/social/notifications'; import NotificationsIcon from 'material-ui/svg-icons/social/notifications';
import Apps from 'material-ui/svg-icons/navigation/apps';
import DevicesOther from 'material-ui/svg-icons/hardware/devices-other';
import ActionAccountCircle from 'material-ui/svg-icons/action/account-circle'; import ActionAccountCircle from 'material-ui/svg-icons/action/account-circle';
import Dashboard from 'material-ui/svg-icons/action/dashboard';
import Add from 'material-ui/svg-icons/content/add-circle';
import Feedback from 'material-ui/svg-icons/action/feedback';
import {withRouter} from 'react-router-dom' import {withRouter} from 'react-router-dom'
import Badge from 'material-ui/Badge';
import {List, ListItem} from 'material-ui/List';
/** /**
@ -35,9 +40,48 @@ import {withRouter} from 'react-router-dom'
* */ * */
class BaseLayout extends Component { class BaseLayout extends Component {
constructor() {
super();
this.state = {
notifications: 0,
user: 'Admin'
}
}
componentWillMount() {
}
handleApplicationClick() { handleApplicationClick() {
console.log("Application"); this.handleHistory('/assets/apps');
window.location = '/publisher/assets/apps'; }
handleOverviewClick() {
this.handleHistory('/overview');
}
handleApplicationCreateClick() {
this.handleHistory('/assets/apps/create');
}
handlePlatformClick() {
this.handleHistory('/assets/platforms');
}
handlePlatformCreateClick() {
this.handleHistory('/assets/platforms/create');
}
handleReviewClick() {
this.handleHistory('/assets/reviews');
}
/**
* The method to update the history.
* to: The URL to route.
* */
handleHistory(to) {
this.props.history.push(to);
} }
render() { render() {
@ -46,9 +90,15 @@ class BaseLayout extends Component {
<AppBar title="App Publisher" <AppBar title="App Publisher"
iconElementRight={ iconElementRight={
<div> <div>
<IconButton> <Badge
<Notifications/> badgeContent={this.state.notifications}
</IconButton> secondary={true}
badgeStyle={{top: 12, right: 12}}
>
<IconButton tooltip="Notifications">
<NotificationsIcon/>
</IconButton>
</Badge>
<IconButton onClick={() => { <IconButton onClick={() => {
console.log("Clicked") console.log("Clicked")
}}> }}>
@ -58,12 +108,41 @@ class BaseLayout extends Component {
} }
/> />
<div> <div>
<Drawer containerStyle={{height: 'calc(100% - 64px)', width: '15%', top: 64}} open={true}> <Drawer containerStyle={{height: 'calc(100% - 64px)', width: '15%', top: '10%'}} open={true}>
<Menu> <List>
<MenuItem onClick={this.handleApplicationClick.bind(this)}>Applications</MenuItem> <ListItem primaryText="Overview"
<MenuItem>Platforms</MenuItem> onClick={this.handleOverviewClick.bind(this)}
<MenuItem>Reviews</MenuItem> leftIcon={<Dashboard/>}/>
</Menu> <ListItem primaryText="Applications"
leftIcon={<Apps/>}
initiallyOpen={false}
primaryTogglesNestedList={true}
onClick={this.handleApplicationClick.bind(this)}
nestedItems={[
<ListItem
key={1}
primaryText="Create"
onClick={this.handleApplicationCreateClick.bind(this)}
leftIcon={<Add/>}
/>]}
/>
<ListItem primaryText="Platforms"
leftIcon={<DevicesOther/>}
initiallyOpen={false}
primaryTogglesNestedList={true}
onClick={this.handlePlatformClick.bind(this)}
nestedItems={[
<ListItem
key={1}
primaryText="Create"
onClick={this.handlePlatformCreateClick.bind(this)}
leftIcon={<Add/>}
/>]}
/>
<ListItem primaryText="Reviews"
onClick={this.handleReviewClick.bind(this)}
leftIcon={<Feedback/>}/>
</List>
</Drawer> </Drawer>
</div> </div>
<div style= <div style=

@ -0,0 +1,41 @@
/*
* 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';
class PublisherOverview extends Component {
constructor() {
super();
}
componentWillMount() {
console.log("In Crate")
}
render() {
return (
<div>
Overview
</div>
);
}
}
export default PublisherOverview;

@ -16,27 +16,40 @@
* under the License. * under the License.
*/ */
import React, { Component } from 'react'; import React, {Component} from 'react';
import {Card, CardTitle, CardActions, CardMedia} from 'material-ui/Card'; import {Redirect, Switch} from 'react-router-dom';
import {Card, CardActions, CardMedia, CardTitle} from 'material-ui/Card';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
import { ValidatorForm, TextValidator} from 'react-material-ui-form-validator'; import {TextValidator, ValidatorForm} from 'react-material-ui-form-validator';
import Checkbox from 'material-ui/Checkbox'; import Checkbox from 'material-ui/Checkbox';
import qs from 'qs';
//todo: remove the {TextValidator, ValidatorForm} and implement it manually.
class Login extends Component { class Login extends Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
isLoggedIn: true,
referrer: "/",
userName: "", userName: "",
password: "", password: "",
rememberMe: true 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) { handleLogin(event) {
console.log(this.state);
event.preventDefault(); event.preventDefault();
} }
@ -45,7 +58,7 @@ class Login extends Component {
{ {
userName: event.target.value userName: event.target.value
} }
); );
} }
onPasswordChange(event) { onPasswordChange(event) {
@ -65,56 +78,62 @@ class Login extends Component {
} }
render() { render() {
return (
<div> if (!this.state.isLoggedIn) {
return (
{/*TODO: Style the components.*/} <div>
<Card> {/*TODO: Style the components.*/}
<CardTitle title="WSO2 IoT App Publisher"/>
<Card>
<CardMedia> <CardTitle title="WSO2 IoT App Publisher"/>
</CardMedia>
<CardActions>
<CardActions> <ValidatorForm
<ValidatorForm ref="form"
ref="form" onSubmit={this.handleLogin.bind(this)}
onSubmit={this.handleLogin.bind(this)} onError={errors => console.log(errors)}>
onError={errors => console.log(errors)}>
<TextValidator
<TextValidator floatingLabelText="User Name"
floatingLabelText="User Name" floatingLabelFixed={true}
floatingLabelFixed={true} onChange={this.onUserNameChange.bind(this)}
onChange={this.onUserNameChange.bind(this)} name="userName"
name="userName" validators={['required']}
validators={['required']} errorMessages={['User Name is required']}
errorMessages={['User Name is required']} value={this.state.userName}
value={this.state.userName} />
/> <br/>
<br/> <TextValidator
<TextValidator floatingLabelText="Password"
floatingLabelText="Password" floatingLabelFixed={true}
floatingLabelFixed={true} onChange={this.onPasswordChange.bind(this)}
onChange={this.onPasswordChange.bind(this)} name="password"
name="password" type="password"
type="password" value={this.state.password}
value={this.state.password} validators={['required']}
validators={['required']} errorMessages={['Password is required']}
errorMessages={['Password is required']} />
/> <br/>
<br/> <Checkbox label="Remember me."
<Checkbox label="Remember me." onCheck={this.rememberMe.bind(this)}
onCheck={this.rememberMe.bind(this)} checked={this.state.rememberMe}/>
checked={this.state.rememberMe}/> <br/>
<br/> <RaisedButton type="submit" label="Login"/>
<RaisedButton type="submit" label="Login"/> </ValidatorForm>
</ValidatorForm>
</CardActions>
</CardActions> </Card>
</Card> </div>);
</div>); } else {
return (
<Switch>
<Redirect to={this.state.referrer}/>
</Switch>
);
}
} }
} }
export default Login;
export default Login;

@ -20,9 +20,10 @@ import Login from './User/Login/Login'
import BaseLayout from './Base/BaseLayout' import BaseLayout from './Base/BaseLayout'
import Create from './Application/Create' import Create from './Application/Create'
import NotFound from './Error/NotFound' import NotFound from './Error/NotFound'
import PublisherOverview from './Overview/PublisherOverview'
/** /**
* Contains all UI components related to Application, Login and Platform * Contains all UI components related to Application, Login and Platform
*/ */
export {Login, BaseLayout, Create, NotFound}; export {Login, BaseLayout, Create, NotFound, PublisherOverview};
Loading…
Cancel
Save