Stepper component created and added it to the application creation modal.

feature/appm-store/pbac
Menaka Jayawardena 7 years ago
parent fc44322776
commit 99af739f15

@ -57,5 +57,6 @@
"Yes" : "Yes", "Yes" : "Yes",
"No" : "No", "No" : "No",
"No.Platform.Tags" : "No Platform Tags", "No.Platform.Tags" : "No Platform Tags",
"Create.Platform" : "Create Platform" "Create.Platform" : "Create Platform",
"Optional": "Optional"
} }

@ -335,24 +335,6 @@ body {
padding: 24px; padding: 24px;
} }
.stepper-header {
width: 100%;
color: #BaBaBa;
padding-bottom: 5px;
margin-bottom: 10px;
}
#application-tag {
margin: 0 2px 0 2px;
background-color: blue;
height: 20px;
}
#application-tag:hover {
cursor: pointer;
background-color: #007bff;
}
.platform-link-placeholder { .platform-link-placeholder {
color: #888888; color: #888888;
float: right; float: right;
@ -484,26 +466,29 @@ body {
#modal-body-content { #modal-body-content {
max-height: 700px; max-height: 700px;
padding-left: 24px;
overflow-y: auto; overflow-y: auto;
} }
.step-index {
height: 20px;
width: 20px;
background-color: #2196F3;
border-radius: 50%;
}
#img-btn-screenshot { #img-btn-screenshot {
margin: 0 5px 0 5px; margin: 0 5px 0 5px;
} }
#app-create-modal { #app-create-modal {
max-width: 700px; max-width: 700px;
overflow-x: auto;
border-radius: 0% !important; border-radius: 0% !important;
} }
.app-create-modal-header {
background-color: #4353bd;
color: white;
padding: 24px !important;
}
.app-create-modal-content {
padding: 0 !important;
}
#store { #store {
border: none; border: none;
border-bottom: solid #BDBDBD 1px; border-bottom: solid #BDBDBD 1px;
@ -853,3 +838,19 @@ div.tab button.active {
font-weight: 500; font-weight: 500;
color: #9e9e9e; color: #9e9e9e;
} }
/**
If you need to change the color of active steps in stepper,
uncomment the following and set the background color and font color as needed.
*/
/*
.stepper-active-index {
background-color: #0a6eff !important;
color: white !important;
}
.stepper-passed-index {
background-color: #0a6eff !important;
color: green !important;
}
*/

@ -21,8 +21,9 @@ import {withRouter} from 'react-router-dom';
import AuthHandler from "../../../api/authHandler"; import AuthHandler from "../../../api/authHandler";
import {Step1, Step2, Step3, Step4} from './CreateSteps/index'; import {Step1, Step2, Step3, Step4} from './CreateSteps/index';
import ApplicationMgtApi from '../../../api/applicationMgtApi'; import ApplicationMgtApi from '../../../api/applicationMgtApi';
import {Col, Modal, ModalBody, ModalHeader, Row} from 'reactstrap'; import {Modal, ModalHeader} from 'reactstrap';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import Stepper from "../../UIComponents/StepprHeader/Stepper";
/** /**
@ -148,6 +149,18 @@ class ApplicationCreate extends Component {
} }
}; };
/**
* Defines the application creation stepper.
* */
getStepperHeaders() {
return [
{index: 1, text: <FormattedMessage id="General.Info" defaultMessage="General.Info"/>},
{index: 2, text: <FormattedMessage id="Select.Platform" defaultMessage="Select.Platform"/>},
{index: 3, text: <FormattedMessage id="Screenshots" defaultMessage="Screenshots"/>},
{index: 4, text: <FormattedMessage id="Release" defaultMessage="Release"/>, optional: true}
];
}
/** /**
* Remove the last data point * Remove the last data point
* */ * */
@ -239,51 +252,17 @@ class ApplicationCreate extends Component {
<div id="create-application-modal"> <div id="create-application-modal">
<Modal isOpen={this.state.open} toggle={this.toggle} id="app-create-modal" <Modal isOpen={this.state.open} toggle={this.toggle} id="app-create-modal"
backdrop={'static'}> backdrop={'static'}>
<ModalHeader toggle={this.toggle}> <ModalHeader toggle={this.toggle} className="app-create-modal-header">
<FormattedMessage id="Create.Application" defaultMessage="Create Application"/> <FormattedMessage id="Create.Application" defaultMessage="Create Application"/>
</ModalHeader> </ModalHeader>
<ModalBody id="modal-body-content"> <div className="container app-create-modal-content">
<Row> <Stepper
<Col> activeStep={stepIndex + 1}
<div className="stepper-header"> previousStep={stepIndex}
<Row> stepContent={this.getStepperHeaders()}
<Col> />
<div className="stepper-header-content">
<div className="step-index">1</div>
<div className="step-header">
<FormattedMessage id="General.Info" defaultMessage="General.Info"/>
</div>
</div>
</Col>
<Col>
<span className="step-index">2</span>
<span className="step-header">
<FormattedMessage id="Select.Platform"
defaultMessage="Select.Platform"/>
</span>
</Col>
<Col>
<span className="step-index">3</span>
<span className="step-header">
<FormattedMessage id="Screenshots" defaultMessage="Screenshots"/>
</span>
</Col>
<Col>
<span className="step-index">4</span>
<span className="step-header">
<FormattedMessage id="Release" defaultMessage="Release"/>
</span>
</Col>
</Row>
</div>
</Col>
</Row>
<Row>
<Col>
{this.getStepContent(stepIndex)} {this.getStepContent(stepIndex)}
</Col> </div>
</Row>
</ModalBody>
</Modal> </Modal>
</div>); </div>);
} }

@ -19,7 +19,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, {Component} from 'react'; import React, {Component} from 'react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {Button, Form, FormFeedback, FormGroup, Input, Label, ModalFooter} from 'reactstrap'; import {Button, Form, FormFeedback, FormGroup, Input, Label, ModalFooter, ModalBody} from 'reactstrap';
import * as validator from '../../../../common/validator'; import * as validator from '../../../../common/validator';
import Chip from "../../../UIComponents/Chip/Chip"; import Chip from "../../../UIComponents/Chip/Chip";
@ -166,6 +166,7 @@ class Step1 extends Component {
* Set text field values to state. * Set text field values to state.
* */ * */
onTextFieldChange(event) { onTextFieldChange(event) {
console.log(event.target.value);
let field = event.target.name; let field = event.target.name;
switch (field) { switch (field) {
case "appName": { case "appName": {
@ -236,8 +237,7 @@ class Step1 extends Component {
return ( return (
<div> <div>
<div> <ModalBody id="modal-body-content">
<div>
<FormGroup> <FormGroup>
<Label for="app-title"> <Label for="app-title">
<FormattedMessage id='Title' defaultMessage='Title'/>* <FormattedMessage id='Title' defaultMessage='Title'/>*
@ -342,8 +342,7 @@ class Step1 extends Component {
</div> </div>
<FormFeedback id="form-error">{this.state.errors.tags}</FormFeedback> <FormFeedback id="form-error">{this.state.errors.tags}</FormFeedback>
</FormGroup> </FormGroup>
</div> </ModalBody>
</div>
<ModalFooter> <ModalFooter>
<Button className="custom-flat danger-flat" onClick={this.onCancelClick}> <Button className="custom-flat danger-flat" onClick={this.onCancelClick}>
<FormattedMessage id="Cancel" defaultMessage="Cancel"/> <FormattedMessage id="Cancel" defaultMessage="Cancel"/>

@ -20,7 +20,7 @@ import PropTypes from 'prop-types';
import React, {Component} from 'react'; import React, {Component} from 'react';
import AuthHandler from "../../../../api/authHandler"; import AuthHandler from "../../../../api/authHandler";
import PlatformMgtApi from "../../../../api/platformMgtApi"; import PlatformMgtApi from "../../../../api/platformMgtApi";
import {Button, FormFeedback, FormGroup, Input, Label, ModalFooter} from 'reactstrap'; import {Button, FormFeedback, FormGroup, Input, Label, ModalBody, ModalFooter} from 'reactstrap';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import * as validator from '../../../../common/validator'; import * as validator from '../../../../common/validator';
@ -145,10 +145,11 @@ class Step2 extends Component {
render() { render() {
return ( return (
<div> <div>
<ModalBody id="modal-body-content">
<FormGroup> <FormGroup>
<Label for="store">Store Type</Label> <Label for="store">Store Type</Label>
<Input type="select" name="store" className="input-custom" onChange={this.onChangeStore.bind(this)}> <Input type="select" name="store" className="input-custom"
onChange={this.onChangeStore.bind(this)}>
<option>Enterprise</option> <option>Enterprise</option>
<option>Public</option> <option>Public</option>
</Input> </Input>
@ -161,7 +162,8 @@ class Step2 extends Component {
name="store" name="store"
onChange={this.onChangePlatform.bind(this)} onChange={this.onChangePlatform.bind(this)}
> >
<option id="app-visibility-default" disabled selected>Select the Application Platform</option> <option id="app-visibility-default" disabled selected>Select the Application Platform
</option>
{this.state.platforms.length > 0 ? this.state.platforms.map(platform => { {this.state.platforms.length > 0 ? this.state.platforms.map(platform => {
return ( return (
<option value={platform.identifier} key={platform.identifier}> <option value={platform.identifier} key={platform.identifier}>
@ -172,6 +174,7 @@ class Step2 extends Component {
</Input> </Input>
<FormFeedback id="form-error">{this.state.errors.platform}</FormFeedback> <FormFeedback id="form-error">{this.state.errors.platform}</FormFeedback>
</FormGroup> </FormGroup>
</ModalBody>
<ModalFooter> <ModalFooter>
<Button className="custom-flat primary-flat" onClick={this.onBackClick}> <Button className="custom-flat primary-flat" onClick={this.onBackClick}>
<FormattedMessage id="Back" defaultMessage="Back"/> <FormattedMessage id="Back" defaultMessage="Back"/>

@ -20,7 +20,7 @@ import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone'; import Dropzone from 'react-dropzone';
import React, {Component} from 'react'; import React, {Component} from 'react';
import * as validator from '../../../../common/validator'; import * as validator from '../../../../common/validator';
import {Button, FormFeedback, FormGroup, Label, ModalFooter} from 'reactstrap'; import {Button, FormFeedback, FormGroup, Label, ModalBody, ModalFooter} from 'reactstrap';
import AppImage from "../../../UIComponents/AppImage/AppImage"; import AppImage from "../../../UIComponents/AppImage/AppImage";
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
@ -138,6 +138,7 @@ class Step3 extends Component {
render() { render() {
return ( return (
<div className="createStep2Content"> <div className="createStep2Content">
<ModalBody id="modal-body-content">
<div> <div>
<FormGroup> <FormGroup>
<Label for="app-screenshots"> <Label for="app-screenshots">
@ -224,6 +225,7 @@ class Step3 extends Component {
</FormGroup> </FormGroup>
</div> </div>
</div> </div>
</ModalBody>
<ModalFooter> <ModalFooter>
<Button className="custom-flat primary-flat" onClick={this.onBackClick}> <Button className="custom-flat primary-flat" onClick={this.onBackClick}>
<FormattedMessage id="Back" defaultMessage="Back"/> <FormattedMessage id="Back" defaultMessage="Back"/>

@ -18,7 +18,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Button, Collapse, FormGroup, FormText, Input, Label, ModalFooter} from 'reactstrap'; import {Button, Collapse, FormGroup, FormText, Input, Label, ModalBody, ModalFooter} from 'reactstrap';
import Switch from '../../../UIComponents/Switch/Switch' import Switch from '../../../UIComponents/Switch/Switch'
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
@ -91,7 +91,7 @@ class Step4 extends Component {
render() { render() {
return ( return (
<div className="applicationCreateStepMiddle"> <div className="applicationCreateStepMiddle">
<div> <ModalBody id="modal-body-content">
<FormGroup> <FormGroup>
<div id="app-release-switch-content"> <div id="app-release-switch-content">
<div id="app-release-switch-label"> <div id="app-release-switch-label">
@ -150,7 +150,7 @@ class Step4 extends Component {
/> />
</FormGroup> </FormGroup>
</Collapse> </Collapse>
</div> </ModalBody>
<ModalFooter> <ModalFooter>
<Button className="custom-flat primary-flat" onClick={this.onBackClick}> <Button className="custom-flat primary-flat" onClick={this.onBackClick}>
<FormattedMessage id="Back" defaultMessage="Back"/> <FormattedMessage id="Back" defaultMessage="Back"/>

@ -0,0 +1,74 @@
/*
* 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 './stepper.css';
import {FormattedMessage} from "react-intl";
class Step extends Component {
render() {
const {index, text, active, passed, finalStep, optional} = this.props;
let activeStep = active ? "stepper-active-index" : "stepper-inactive-index";
let activeStepText = active ? " stepper-active-step-text" : "";
let stepPassed = index === passed || index < passed ? " stepper-passed-index" : "";
let stepPassedText = index === passed || index < passed ? " stepper-passed-step-text" : "";
let indexClassNames = "step-index " + activeStep + stepPassed;
let indexTextClassNames = "step-text " + activeStepText + stepPassedText;
let stepIndexContent = index === passed || index < passed ? <i className="fw fw-check"></i> : index;
return (
<div className="step">
<div className="step-content">
<div className={indexClassNames}>
<span>
{stepIndexContent}
</span>
</div>
<div className={indexTextClassNames}>
<div>
{text} {!finalStep? <i className="stepper-next-arrow fw fw-right-arrow"></i> : <i/>}
</div>
{optional ?
<div className="stepper-optional-text">
(<FormattedMessage id="Optional" defaultMessage="Optional"/>)
</div>: <div/>}
</div>
</div>
</div>
)
}
}
Step.propTypes = {
index: PropTypes.number,
text: PropTypes.node,
active: PropTypes.bool,
passed: PropTypes.number,
finalStep: PropTypes.bool,
optional: PropTypes.bool
}
export default Step;

@ -0,0 +1,52 @@
/*
* 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 './stepper.css';
import Step from "./Step";
class Stepper extends Component {
render() {
const {stepContent, activeStep, previousStep} = this.props;
return (
<div className="stepper-header">
{stepContent.map(content => {
return (
<Step
passed={previousStep}
text={content.text}
index={content.index}
optional={content.optional}
active={activeStep === content.index}
finalStep={content.index === stepContent.length}
/>
)
})}
</div>
)
}
}
Stepper.propTypes = {
stepContent: PropTypes.array,
activeStep: PropTypes.number
};
export default Stepper;

@ -0,0 +1,97 @@
/*
* 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.
*/
.stepper-header {
width: 100%;
padding: 24px;
height: 72px;
color: rgba(0, 0, 0, 0.38);
box-shadow: 1px 0px 1px 0 rgba(0, 0, 0, 0.2), 0 0px 20px 0 rgba(0, 0, 0, 0.19);
display: table;
align-items: baseline;
justify-content: space-between;
margin: 0 !important;
}
.step {
display: table-cell;
flex-direction: row;
align-items: baseline;
}
.step-content {
display: flex;
width: auto;
}
.step-index {
padding-top: 3px;
height: 24px;
width: 24px;
font-size: 12px;
border-radius: 50%;
text-align: center;
margin-right: 8px;
}
.stepper-inactive-index {
background-color: rgba(0, 0, 0, 0.38);
}
.stepper-active-index {
background-color: #0a6eff;
color: white;
}
.stepper-passed-index {
background-color: #0a6eff;
color: white;
}
.step-text {
padding-top: 3px;
font-family: Roboto-Regular;
font-size: 14px;
}
.inactive-text {
color: rgba(0, 0, 0, 0.54);
}
.stepper-active-step-text {
font-family: Roboto-Medium;
font-size: 14px;
color: rgba(0, 0, 0, 0.87);
font-weight: 300;
}
.stepper-passed-step-text {
font-family: Roboto-Medium;
color: rgba(0, 0, 0, 0.87);
}
.stepper-next-arrow {
margin-left: 15px;
}
.stepper-optional-text {
font-family: Roboto-Regular;
font-size: 12px;
color: rgba(0, 0, 0, 0.39)
}
Loading…
Cancel
Save