<commit_before>/*
 * 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 {Link} from 'react-router-dom'
import {Col, Popconfirm, Row, Form, Dropdown, Tag, Menu, Badge, message} from 'antd';

const FormItem = Form.Item;
import Loading from '../../Base/Loading/Loading'
import ResourceNotFound from "../../Base/Errors/ResourceNotFound";
import Api from '../../../data/api'

import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import Card, { CardActions, CardContent, CardMedia } from 'material-ui/Card';
import { MenuItem } from 'material-ui/Menu';
import { Delete, Edit, CreateNewFolder, Description  }from 'material-ui-icons';
import Table, { TableBody, TableCell, TableRow } from 'material-ui/Table';
import Select from 'material-ui/Select';
import 'react-select/dist/react-select.css';
import Subscriptions  from 'material-ui-icons/Subscriptions';
import { FormControl } from 'material-ui/Form';

class BasicInfo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            api: null,
            applications: null,
            policies: null,
            dropDownApplications: null,
            dropDownPolicies: null,
            notFound: false,
            matDropVisible: false,
            matDropValue: 'one',
            subscribedApplicationIds: [],
            options: [],
            tiers: [],
            applicationId: null,
            policyName: null
        };
        this.api_uuid = this.props.uuid;
        this.logChange = this.logChange.bind(this);
       // this.handleStarRatingUpdate = this.handleStarRatingUpdate(this);
    }

    componentDidMount() {
        const api = new Api();
        let promised_api = api.getAPIById(this.api_uuid);
        promised_api.then(
            response => {
                console.info(response.obj);
                this.setState({api: response.obj});
                let apiTiers = response.obj.policies;
                let tiers = [];
                for (let i = 0; i < apiTiers.length; i++) {
                    let tierName = apiTiers[i];
                    tiers.push({value: tierName, label: tierName});
                }
                this.setState({tiers: tiers});
                if (tiers.length > 0) {
                    this.setState({policyName: tiers[0].value});
                }
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let existing_subscriptions = api.getSubscriptions(this.api_uuid, null);
        existing_subscriptions.then((response) => {
            let subscribedApplications = [];
            //get the application IDs of existing subscriptions
            response.body.list.map(element => subscribedApplications.push(element.applicationId));
            this.setState({subscribedApplicationIds: subscribedApplications});
        }).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let promised_applications = api.getAllApplications();
        promised_applications.then(
            (response) => {
                let applicationResponseObj = response.body;
                let applications = [];
                for (let i = 0; i < applicationResponseObj.list.length; i++) {
                    let applicationId = applicationResponseObj.list[i].applicationId;
                    let applicationName = applicationResponseObj.list[i].name;
                    //include the application only if it does not has an existing subscriptions
                    if (this.state.subscribedApplicationIds.includes(applicationId)) {
                        continue;
                    } else {
                        applications.push({value: applicationId, label: applicationName});
                    }
                }
                this.setState({options: applications});
                if (options.length > 0) {
                    this.setState({applicationId: options[0].value});
                }
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let promised_subscriptions = api.getSubscriptions(this.api_uuid, null);
        promised_subscriptions.then(
            response => {
                this.dropDownApplications = [<Option key="custom" onClick={this.handleClick} >New Application</Option>];

                for (var i = 0; i < this.api.policies.length; i++) {
                    this.dropDownPolicies.push(<Option key={this.api.policies[i]}>{this.api.policies[i]}</Option>);
                }
                var subscription = {};
                var subscriptions = response.obj.list;
                var application = {};
                var subscribedApp = false;
                for (var i = 0; i < this.applications.length; i++) {
                    subscribedApp = false;
                    application = applications[i];
                    if (application.lifeCycleStatus != "APPROVED") {
                        continue;
                    }
                    for (var j = 0; j < subscriptions.length; j++) {
                        subscription = subscriptions[j];
                        if (subscription.applicationId === application.applicationId) {
                            subscribedApp = true;
                            continue;
                        }
                    }
                    if(!subscribedApp) {
                        this.dropDownApplications.push(<Option key={application.id}>{application.name}</Option>);
                    }
                }
                this.policies = this.api.policies;
                console.info(this.api.policies)
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );
    }

    handleChange = name => event => {
        this.setState({ [name]: event.target.value });
    };

    createSubscription = (e) => {
        e.preventDefault();
        let apiId = this.api_uuid;
        let applicationId = this.state.applicationId;
        let policy = this.state.policyName;
        let api = new Api();
        let promised_subscribe = api.subscribe(apiId, applicationId, policy);
        promised_subscribe.then(response => {
            console.log("Subscription created successfully with ID : " + response.body.subscriptionId);
        }).catch(
            function (error_response) {
                console.log("Error while creating the subscription.");
            }
        );
    };

    populateApplicationDropdown(){
        return this.dropDownApplications;
    }

    populatePolicyDropdown(){
        return this.dropDownPolicies;
    }

    handleClick(){
        this.setState({redirect: true});
    }

    selectChange(){
        this.setState({matDropVisible:!this.state.matDropVisible})
    }
    onBlur(e){
        console.info(document.activeElement);
        if ( !e.currentTarget.contains( document.activeElement ) ){
            this.setState({matDropVisible: false});
        }
    }
    selectOption(option){
        console.info(option);
        this.setState({selectOption: option});
    }
    logChange(val) {
        this.setState({matDropValue: val.value});
        console.log("Selected: " + JSON.stringify(val));
    }
    render() {
        const formItemLayout = {
            labelCol: {span: 6},
            wrapperCol: {span: 18}
        };
        if (this.state.notFound) {
            return <ResourceNotFound />
        }

        if (this.state.redirect) {
            return <Redirect push to="/application-create" />;
        }

        const api = this.state.api;

        return (
            this.state.api ?
                <Grid container>
                    <Grid item xs={12}>
                        <Paper style={{display:"flex"}}>
                            <Typography type="display2" gutterBottom className="page-title">
                                {api.name} - Overview
                            </Typography>
                            {/*<Button aria-owns="simple-menu" aria-haspopup="true" >
                                <Edit /> Edit
                            </Button>
                            <Button aria-owns="simple-menu" aria-haspopup="true" >
                                <CreateNewFolder /> Create New Version
                            </Button>
                            <Button aria-owns="simple-menu" aria-haspopup="true" >
                                <Description /> View Swagger
                            </Button>*/}
                        </Paper>
                    </Grid>
                    <Grid item xs={12} sm={12} md={3} lg={3} xl={2} style={{paddingLeft:"40px"}}>

                        <Card>
                            <CardMedia image="/store/public/images/api/api-default.png" >
                            </CardMedia>
                            <CardContent>

                                    <Badge status="processing" text={api.lifeCycleStatus}/>

11 Apps

                                    View in store

                            </CardContent>
                            <CardActions>
                                {api.lifeCycleStatus}

                                <Button dense color="primary">
                                    View in store
                                </Button>
                            </CardActions>
                        </Card>
                    </Grid>
                    <Grid item xs={12} sm={6} md={3} lg={3} xl={2} style={{paddingLeft:"40px"}}>

                            <TableBody>

                                <TableRow>
                                    <TableCell>Version</TableCell><TableCell>{api.version}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Context</TableCell><TableCell>{api.context}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Context</TableCell><TableCell>{api.provider}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Date Created</TableCell><TableCell>{api.createdTime}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Date Last Updated</TableCell><TableCell>{api.lastUpdatedTime}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Default API Version</TableCell><TableCell>{api.isDefaultVersion}</TableCell>
                                </TableRow>
                                 <TableRow>
                                    <TableCell>Default API Version</TableCell><TableCell>{api.lifeCycleStatus}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Rating</TableCell>
                                    <TableCell>
                                        <StarRatingBar apiIdProp = {this.api_uuid}></StarRatingBar>
                                    </TableCell>
                                </TableRow>

                            </TableBody>

                    </Grid>
                    <Grid item xs={12} sm={6} md={6} lg={6} xl={8} style={{paddingLeft:"40px"}}>
                        <Typography type="subheading" gutterBottom>
                            Applications
                        </Typography>
                        {this.state.options &&
                        <FormControl style={{width:"100%",marginBottom:"20px"}}>
                            <Select
                                style={{width:"100%"}}
                                value={this.state.applicationId}
                                onChange={this.handleChange('applicationId')}
                            >
                                {this.state.options.map((option) => <MenuItem key={option.value} value={option.value}>{option.label}</MenuItem>)}
                            </Select>
                        </FormControl>
                        }
                        <Typography type="subheading" gutterBottom>
                            Tiers
                        </Typography>
                        {this.state.tiers &&
                        <FormControl style={{width:"100%"}}>
                            <Select
                                style={{width:"100%"}}
                                value={this.state.policyName}
                                onChange={this.handleChange('policyName')}
                            >
                                {this.state.tiers.map((tier) => <MenuItem key={tier.value} value={tier.value}>{tier.label}</MenuItem>)}
                            </Select>
                        </FormControl>
                        }

                        <Button onClick={this.createSubscription} raised color="primary" style={{paddingTop: '20px'}}>
                            <Subscriptions style={{paddingRight: '10px'}} /> Subscribe
                        </Button>

                            {/*<Select>
                                {this.populateApplicationDropdown()}
                            </Select>
                            <Select>
                                {this.populatePolicyDropdown()}
                            </Select>*/}

                    </Grid>
                </Grid>
                : <Loading/>
        );
    }
}

class Star extends React.Component {
    constructor(props) {
        super(props);

        this.handleHoveringOver = this.handleHoveringOver.bind(this);
    }

    handleHoveringOver(event) {
        this.props.hoverOver(this.props.name);
    }

    render() {
        return this.props.isRated ?

                ★
             :

                ☆
            ;
    }
}

class StarRatingBar extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
                        previousRating : 0,
                        rating : 0
                     };

        this.handleMouseOver = this.handleMouseOver.bind(this);
        this.handleRatingUpdate = this.handleRatingUpdate.bind(this);
        this.handleMouseOut = this.handleMouseOut.bind(this);
    }

    componentDidMount() {
        var api = new Api();
        let promised_api = api.getAPIById(this.props.apiIdProp);
        promised_api.then(
            response => {
                console.info(response.obj);
            }
        );

        //get user rating
        let promised_rating = api.getRatingFromUser(this.props.apiIdProp, null);
        promised_rating.then(
            response => {
                console.log(response.obj.userRating);
                this.setState({rating :response.obj.userRating});
                this.setState({previousRating :response.obj.userRating});
            }
        );
    }

    handleMouseOver(index) {
        this.setState({rating : index});
    }

    handleMouseOut() {
        this.setState({rating : this.state.previousRating});
    }

    handleRatingUpdate() {
        this.setState({previousRating : this.state.rating});
        this.setState({rating : this.state.rating});

        var api = new Api();
        let ratingInfo = {"rating" : this.state.rating};
        let promise = api.addRating(this.props.apiIdProp, ratingInfo);
        promise.then(
            response => {
                message.success("Rating updated successfully");
            }).catch (
                 error => {
                     message.error("Error occurred while adding ratings!");
                 }
             );
    }

    render() {
        return (

                <Star name = {1} isRated = {this.state.rating >= 1} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {2} isRated = {this.state.rating >= 2} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {3} isRated = {this.state.rating >= 3} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {4} isRated = {this.state.rating >= 4} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {5} isRated = {this.state.rating >= 5} hoverOver = {this.handleMouseOver} > </Star>

);
    }
}

export default BasicInfo
<commit_msg>review changes<commit_after>/*
 * 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 {Link} from 'react-router-dom'
import {Col, Popconfirm, Row, Form, Dropdown, Tag, Menu, Badge, message} from 'antd';

const FormItem = Form.Item;
import Loading from '../../Base/Loading/Loading'
import ResourceNotFound from "../../Base/Errors/ResourceNotFound";
import Api from '../../../data/api'

import Paper from 'material-ui/Paper';
import Grid from 'material-ui/Grid';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import Card, { CardActions, CardContent, CardMedia } from 'material-ui/Card';
import { MenuItem } from 'material-ui/Menu';
import { Delete, Edit, CreateNewFolder, Description  }from 'material-ui-icons';
import Table, { TableBody, TableCell, TableRow } from 'material-ui/Table';
import Select from 'material-ui/Select';
import 'react-select/dist/react-select.css';
import Subscriptions  from 'material-ui-icons/Subscriptions';
import { FormControl } from 'material-ui/Form';

class BasicInfo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            api: null,
            applications: null,
            policies: null,
            dropDownApplications: null,
            dropDownPolicies: null,
            notFound: false,
            matDropVisible: false,
            matDropValue: 'one',
            subscribedApplicationIds: [],
            options: [],
            tiers: [],
            applicationId: null,
            policyName: null
        };
        this.api_uuid = this.props.uuid;
        this.logChange = this.logChange.bind(this);
    }

    componentDidMount() {
        const api = new Api();
        let promised_api = api.getAPIById(this.api_uuid);
        promised_api.then(
            response => {
                console.info(response.obj);
                this.setState({api: response.obj});
                let apiTiers = response.obj.policies;
                let tiers = [];
                for (let i = 0; i < apiTiers.length; i++) {
                    let tierName = apiTiers[i];
                    tiers.push({value: tierName, label: tierName});
                }
                this.setState({tiers: tiers});
                if (tiers.length > 0) {
                    this.setState({policyName: tiers[0].value});
                }
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let existing_subscriptions = api.getSubscriptions(this.api_uuid, null);
        existing_subscriptions.then((response) => {
            let subscribedApplications = [];
            //get the application IDs of existing subscriptions
            response.body.list.map(element => subscribedApplications.push(element.applicationId));
            this.setState({subscribedApplicationIds: subscribedApplications});
        }).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let promised_applications = api.getAllApplications();
        promised_applications.then(
            (response) => {
                let applicationResponseObj = response.body;
                let applications = [];
                for (let i = 0; i < applicationResponseObj.list.length; i++) {
                    let applicationId = applicationResponseObj.list[i].applicationId;
                    let applicationName = applicationResponseObj.list[i].name;
                    //include the application only if it does not has an existing subscriptions
                    if (this.state.subscribedApplicationIds.includes(applicationId)) {
                        continue;
                    } else {
                        applications.push({value: applicationId, label: applicationName});
                    }
                }
                this.setState({options: applications});
                if (options.length > 0) {
                    this.setState({applicationId: options[0].value});
                }
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );

        let promised_subscriptions = api.getSubscriptions(this.api_uuid, null);
        promised_subscriptions.then(
            response => {
                this.dropDownApplications = [<Option key="custom" onClick={this.handleClick} >New Application</Option>];

                for (var i = 0; i < this.api.policies.length; i++) {
                    this.dropDownPolicies.push(<Option key={this.api.policies[i]}>{this.api.policies[i]}</Option>);
                }
                var subscription = {};
                var subscriptions = response.obj.list;
                var application = {};
                var subscribedApp = false;
                for (var i = 0; i < this.applications.length; i++) {
                    subscribedApp = false;
                    application = applications[i];
                    if (application.lifeCycleStatus != "APPROVED") {
                        continue;
                    }
                    for (var j = 0; j < subscriptions.length; j++) {
                        subscription = subscriptions[j];
                        if (subscription.applicationId === application.applicationId) {
                            subscribedApp = true;
                            continue;
                        }
                    }
                    if(!subscribedApp) {
                        this.dropDownApplications.push(<Option key={application.id}>{application.name}</Option>);
                    }
                }
                this.policies = this.api.policies;
                console.info(this.api.policies)
            }
        ).catch(
            error => {
                if (process.env.NODE_ENV !== "production") {
                    console.log(error);
                }
                let status = error.status;
                if (status === 404) {
                    this.setState({notFound: true});
                }
            }
        );
    }

    handleChange = name => event => {
        this.setState({ [name]: event.target.value });
    };

    createSubscription = (e) => {
        e.preventDefault();
        let apiId = this.api_uuid;
        let applicationId = this.state.applicationId;
        let policy = this.state.policyName;
        let api = new Api();
        let promised_subscribe = api.subscribe(apiId, applicationId, policy);
        promised_subscribe.then(response => {
            console.log("Subscription created successfully with ID : " + response.body.subscriptionId);
        }).catch(
            function (error_response) {
                console.log("Error while creating the subscription.");
            }
        );
    };

    populateApplicationDropdown(){
        return this.dropDownApplications;
    }

    populatePolicyDropdown(){
        return this.dropDownPolicies;
    }

    handleClick(){
        this.setState({redirect: true});
    }

    selectChange(){
        this.setState({matDropVisible:!this.state.matDropVisible})
    }
    onBlur(e){
        console.info(document.activeElement);
        if ( !e.currentTarget.contains( document.activeElement ) ){
            this.setState({matDropVisible: false});
        }
    }
    selectOption(option){
        console.info(option);
        this.setState({selectOption: option});
    }
    logChange(val) {
        this.setState({matDropValue: val.value});
        console.log("Selected: " + JSON.stringify(val));
    }
    render() {
        const formItemLayout = {
            labelCol: {span: 6},
            wrapperCol: {span: 18}
        };
        if (this.state.notFound) {
            return <ResourceNotFound />
        }

        if (this.state.redirect) {
            return <Redirect push to="/application-create" />;
        }

        const api = this.state.api;

        return (
            this.state.api ?
                <Grid container>
                    <Grid item xs={12}>
                        <Paper style={{display:"flex"}}>
                            <Typography type="display2" gutterBottom className="page-title">
                                {api.name} - Overview
                            </Typography>
                            {/*<Button aria-owns="simple-menu" aria-haspopup="true" >
                                <Edit /> Edit
                            </Button>
                            <Button aria-owns="simple-menu" aria-haspopup="true" >
                                <CreateNewFolder /> Create New Version
                            </Button>
                            <Button aria-owns="simple-menu" aria-haspopup="true" >
                                <Description /> View Swagger
                            </Button>*/}
                        </Paper>
                    </Grid>
                    <Grid item xs={12} sm={12} md={3} lg={3} xl={2} style={{paddingLeft:"40px"}}>

                        <Card>
                            <CardMedia image="/store/public/images/api/api-default.png" >
                            </CardMedia>
                            <CardContent>

                                    <Badge status="processing" text={api.lifeCycleStatus}/>

11 Apps

                                    View in store

                            </CardContent>
                            <CardActions>
                                {api.lifeCycleStatus}

                                <Button dense color="primary">
                                    View in store
                                </Button>
                            </CardActions>
                        </Card>
                    </Grid>
                    <Grid item xs={12} sm={6} md={3} lg={3} xl={2} style={{paddingLeft:"40px"}}>

                            <TableBody>

                                <TableRow>
                                    <TableCell>Version</TableCell><TableCell>{api.version}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Context</TableCell><TableCell>{api.context}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Context</TableCell><TableCell>{api.provider}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Date Created</TableCell><TableCell>{api.createdTime}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Date Last Updated</TableCell><TableCell>{api.lastUpdatedTime}</TableCell>
                                </TableRow>

                                <TableRow>
                                    <TableCell>Default API Version</TableCell><TableCell>{api.isDefaultVersion}</TableCell>
                                </TableRow>
                                 <TableRow>
                                    <TableCell>Default API Version</TableCell><TableCell>{api.lifeCycleStatus}</TableCell>
                                </TableRow>
                                <TableRow>
                                    <TableCell>Rating</TableCell>
                                    <TableCell>
                                        <StarRatingBar apiIdProp = {this.api_uuid}></StarRatingBar>
                                    </TableCell>
                                </TableRow>

                            </TableBody>

                    </Grid>
                    <Grid item xs={12} sm={6} md={6} lg={6} xl={8} style={{paddingLeft:"40px"}}>
                        <Typography type="subheading" gutterBottom>
                            Applications
                        </Typography>
                        {this.state.options &&
                        <FormControl style={{width:"100%",marginBottom:"20px"}}>
                            <Select
                                style={{width:"100%"}}
                                value={this.state.applicationId}
                                onChange={this.handleChange('applicationId')}
                            >
                                {this.state.options.map((option) => <MenuItem key={option.value} value={option.value}>{option.label}</MenuItem>)}
                            </Select>
                        </FormControl>
                        }
                        <Typography type="subheading" gutterBottom>
                            Tiers
                        </Typography>
                        {this.state.tiers &&
                        <FormControl style={{width:"100%"}}>
                            <Select
                                style={{width:"100%"}}
                                value={this.state.policyName}
                                onChange={this.handleChange('policyName')}
                            >
                                {this.state.tiers.map((tier) => <MenuItem key={tier.value} value={tier.value}>{tier.label}</MenuItem>)}
                            </Select>
                        </FormControl>
                        }

                        <Button onClick={this.createSubscription} raised color="primary" style={{paddingTop: '20px'}}>
                            <Subscriptions style={{paddingRight: '10px'}} /> Subscribe
                        </Button>

                            {/*<Select>
                                {this.populateApplicationDropdown()}
                            </Select>
                            <Select>
                                {this.populatePolicyDropdown()}
                            </Select>*/}

                    </Grid>
                </Grid>
                : <Loading/>
        );
    }
}

class Star extends React.Component {
    constructor(props) {
        super(props);

        this.handleHoveringOver = this.handleHoveringOver.bind(this);
    }

    handleHoveringOver(event) {
        this.props.hoverOver(this.props.name);
    }

    render() {
        return this.props.isRated ?

                ★
             :

                ☆
            ;
    }
}

class StarRatingBar extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
                        previousRating : 0,
                        rating : 0
                     };

        this.handleMouseOver = this.handleMouseOver.bind(this);
        this.handleRatingUpdate = this.handleRatingUpdate.bind(this);
        this.handleMouseOut = this.handleMouseOut.bind(this);
    }

    componentDidMount() {
        var api = new Api();
        let promised_api = api.getAPIById(this.props.apiIdProp);
        promised_api.then(
            response => {
                console.info(response.obj);
            }
        );

        //get user rating
        let promised_rating = api.getRatingFromUser(this.props.apiIdProp, null);
        promised_rating.then(
            response => {
                console.log(response.obj.userRating);
                this.setState({rating :response.obj.userRating});
                this.setState({previousRating :response.obj.userRating});
            }
        );
    }

    handleMouseOver(index) {
        this.setState({rating : index});
    }

    handleMouseOut() {
        this.setState({rating : this.state.previousRating});
    }

    handleRatingUpdate() {
        this.setState({previousRating : this.state.rating});
        this.setState({rating : this.state.rating});

        var api = new Api();
        let ratingInfo = {"rating" : this.state.rating};
        let promise = api.addRating(this.props.apiIdProp, ratingInfo);
        promise.then(
            response => {
                message.success("Rating updated successfully");
            }).catch (
                 error => {
                     message.error("Error occurred while adding ratings!");
                 }
             );
    }

    render() {
        return (

                <Star name = {1} isRated = {this.state.rating >= 1} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {2} isRated = {this.state.rating >= 2} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {3} isRated = {this.state.rating >= 3} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {4} isRated = {this.state.rating >= 4} hoverOver = {this.handleMouseOver} > </Star>
                <Star name = {5} isRated = {this.state.rating >= 5} hoverOver = {this.handleMouseOver} > </Star>

);
    }
}

export default BasicInfo
<|endoftext|>


<commit_before>const EmberCordovaError = function(content) {
  let message = content.message ? content.message : content;
  let stack = content.stack ? content.stack : (new Error()).stack;

  this.name = 'CorberError';
  this.message = message;
  this.stack = stack.substr(stack.indexOf('\n') + 1);
};

EmberCordovaError.prototype = Object.create(Error.prototype);
EmberCordovaError.prototype.toString = function() {
  return `Corber: ${this.message}`;
};
EmberCordovaError.constructor = EmberCordovaError;

module.exports = EmberCordovaError;
<commit_msg>refactor(corber-error): remove traces of ember cordova<commit_after>const CorberError = function(content) {
  let message = content.message ? content.message : content;
  let stack = content.stack ? content.stack : (new Error()).stack;

  this.name = 'CorberError';
  this.message = message;
  this.stack = stack.substr(stack.indexOf('\n') + 1);
};

CorberError.prototype = Object.create(Error.prototype);
CorberError.prototype.toString = function() {
  return `Corber: ${this.message}`;
};
CorberError.constructor = CorberError;

module.exports = CorberError;
<|endoftext|>


<commit_before>import dispatcher from "../dispatcher";
import constants from "./constants";
import {fetchJson, pluck, years, identity} from "../../tools";
import URI from "urijs";
import {toImmutable} from "nuclear-js";
import * as endpoints from "./endpoints";

var options2arr = options => Object.keys(options)
    .filter(key => options[key].selected)
    .map(identity);

var addFilters = (filters, url) => null === filters ? url :
    new URI(url).addSearch({
      bidTypeId: options2arr(filters.bidTypes.options),
      bidSelectionMethod: options2arr(filters.bidSelectionMethods.options),
      procuringEntityId: options2arr(filters.procuringEntities.options),
      year: Object.keys(filters.years).filter(year => filters.years[year])
    }).toString();

var regroup = ([head, ...tail]) => head.map((el, index) => [el].concat(tail.map(pluck(index))));

var transformCostEffectivenessData = ([tenderResponse, awardResponse]) => {
  var response2obj = (field, arr) => arr.reduce((obj, elem) => {
    obj[elem._id] = elem[field];
    return obj;
  }, {});

  var tender = response2obj('totalTenderAmount', tenderResponse);
  var award = response2obj('totalAwardAmount', awardResponse);
  return Object.keys(tender).map(year => ({
    year: year,
    tender: tender[year],
    diff: tender[year] - award[year]
  }))
};

var transformBidPeriodData = ([tenders, awards]) => {
  var awardsHash = awards.reduce((obj, award) => {
    obj[award._id] = award.averageAwardDays
    return obj;
  }, {});
  return tenders.map(tender => ({
        year: tender._id,
        tender: tender.averageTenderDays,
        award: awardsHash[tender._id] || 0
      })
  )
}

export default {
  changeTab(slug){
    dispatcher.dispatch(constants.TAB_CHANGED, slug);
  },

  toggleYear(year, selected){
    dispatcher.dispatch(constants.YEAR_TOGGLED, {
      year: year,
      selected: selected
    });
  },

  changeContentWidth(newWidth){
    dispatcher.dispatch(constants.CONTENT_WIDTH_CHANGED, newWidth);
  },

  loadServerSideYearFilteredData(filters = null){
    var load = url => fetchJson(addFilters(filters, url));
    load('/api/topTenLargestTenders').then(data => dispatcher.dispatch(constants.TOP_TENDERS_DATA_UPDATED, data));
    load('/api/topTenLargestAwards').then(data => dispatcher.dispatch(constants.TOP_AWARDS_DATA_UPDATED, data));
  },

  loadData(filters = null){
    var load = url => fetchJson(addFilters(filters, url));
    this.loadServerSideYearFilteredData(filters);
    Promise.all([
      load(endpoints.COUNT_BID_PLANS_BY_YEAR),
      load(endpoints.COUNT_TENDERS_BY_YEAR),
      load(endpoints.COUNT_AWARDS_BY_YEAR)
    ]).then(([bidplans, tenders, awards]) => dispatcher.dispatch(constants.OVERVIEW_DATA_UPDATED, {
      bidplans: bidplans,
      tenders: tenders,
      awards: awards
    }));

    load(endpoints.PLANNED_FUNDING_BY_LOCATION).then(data => dispatcher.dispatch(constants.LOCATION_UPDATED, data));

    Promise.all([
      load(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT),
      load(endpoints.COST_EFFECTIVENESS_AWARD_AMOUNT)
    ])
        .then(transformCostEffectivenessData)
        .then(data => dispatcher.dispatch(constants.COST_EFFECTIVENESS_DATA_UPDATED, data));

    Promise.all([
      load(endpoints.AVERAGE_TENDER_PERIOD),
      load(endpoints.AVERAGE_AWARD_PERIOD)
    ]).then(transformBidPeriodData).then(data => dispatcher.dispatch(constants.BID_PERIOD_DATA_UPDATED, data));

    load(endpoints.TENDER_PRICE_BY_VN_TYPE_YEAR).then(data => dispatcher.dispatch(constants.BID_TYPE_DATA_UPDATED, data));

    load(endpoints.TOTAL_CANCELLED_TENDERS_BY_YEAR)
        .then(data => dispatcher.dispatch(constants.CANCELLED_DATA_UPDATED, data));
  },

  bootstrap(){
    this.loadData();
    Promise.all([
      fetchJson('/api/ocds/bidType/all'),
      fetchJson('/api/ocds/bidSelectionMethod/all')
    ]).then(([bidTypes, bidSelectionMethods]) => dispatcher.dispatch(constants.FILTERS_DATA_UPDATED, {
      years: years().reduce((map, year) => map.set(year, true), toImmutable({})),
      bidTypes: {
        open: true,
        options: bidTypes.reduce((accum, bidType) => {
          var {id} = bidType;
          accum[id] = {
            id: id,
            description: bidType.description,
            selected: false
          };
          return accum;
        }, {})
      },
      bidSelectionMethods: {
        open: true,
        options: bidSelectionMethods
            .filter(method => !!method._id)
            .reduce((accum, {_id}) => {
              accum[_id] = {
                id: _id,
                description: _id,
                selected: false
              };
              return accum;
            }, {})
      },
      procuringEntities: {
        open: true,
        options: []
      }
    }));
  },

  loadComparisonData(criteria, filters){
    if("none" == criteria) return;
    var comparisonUrl = new URI(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT).addSearch({
      groupByCategory: criteria,
      pageSize: 3
    }).toString();
    fetchJson(addFilters(filters, comparisonUrl)).then(comparisonData => {
      var addComparisionFilters = url => {
        var uri = new URI(addFilters(filters, url));
        var criteriaValues = comparisonData.map(pluck("bidTypeId" == criteria ? "0" : "_id"));
        return criteriaValues
            .map(criteriaValue => uri.clone().addSearch(criteria, criteriaValue).toString())
            .concat([
              uri.clone().addSearch(criteria, criteriaValues).addSearch('invert', 'true').toString()
            ]);
      };

      var load = url => Promise.all(addComparisionFilters(url).map(fetchJson));

      Promise.all([
          load(endpoints.COUNT_BID_PLANS_BY_YEAR),
          load(endpoints.COUNT_TENDERS_BY_YEAR),
          load(endpoints.COUNT_AWARDS_BY_YEAR)
      ]).then(data => regroup(data).map(([bidplans, tenders, awards]) => {
        return {
          bidplans: bidplans,
          tenders: tenders,
          awards: awards
        }
      })).then(data => dispatcher.dispatch(constants.OVERVIEW_COMPARISON_DATA_UPDATED, data));

      Promise.all([
        load(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT),
        load(endpoints.COST_EFFECTIVENESS_AWARD_AMOUNT)
      ]).then(data => regroup(data).map(transformCostEffectivenessData))
          .then(data => dispatcher.dispatch(constants.COST_EFFECTIVENESS_COMPARISON_DATA_UPDATED, data));

      Promise.all([
        load(endpoints.AVERAGE_TENDER_PERIOD),
        load(endpoints.AVERAGE_AWARD_PERIOD)
      ]).then(data => regroup(data).map(transformBidPeriodData))
          .then(data => dispatcher.dispatch(constants.BID_PERIOD_COMPARISON_DATA_UPDATED, data));

      load(endpoints.TENDER_PRICE_BY_VN_TYPE_YEAR).then(data =>
          dispatcher.dispatch(constants.BID_TYPE_COMPARISON_DATA_UPDATED, data));

      load(endpoints.TOTAL_CANCELLED_TENDERS_BY_YEAR)
          .then(data => dispatcher.dispatch(constants.CANCELLED_COMPARISON_DATA_UPDATED, data));
    });
  },

  setFiltersBox(slug){
    dispatcher.dispatch(constants.FILTER_BOX_CHANGED, slug);
  },

  toggleFilter(slug, open){
    dispatcher.dispatch(constants.FILTER_TOGGLED, {
      slug: slug,
      open: open
    })
  },

  toggleFilterOption(slug, option, selected){
    dispatcher.dispatch(constants.FILTER_OPTIONS_TOGGLED, {
      slug: slug,
      option: option,
      selected: selected
    })
  },

  updateProcuringEntityQuery(newQuery){
    dispatcher.dispatch(constants.PROCURING_ENTITY_QUERY_UPDATED, newQuery);
    if (newQuery.length >= 3) {
      fetchJson(new URI('/api/ocds/organization/procuringEntity/all').addSearch('text', newQuery).toString())
          .then(data => {
            dispatcher.dispatch(constants.PROCURING_ENTITIES_UPDATED, data.reduce((accum, procuringEntity) => {
              var {id} = procuringEntity;
              accum[id] = procuringEntity;
              return accum;
            }, {}))
          });
    }
  },

  updateComparisonCriteria(criteria){
    dispatcher.dispatch(constants.COMPARISON_CRITERIA_UPDATED, criteria);
  }
}<commit_msg>OCVN-93 Refactored transformBidPeriodData, documented regroup<commit_after>import dispatcher from "../dispatcher";
import constants from "./constants";
import {fetchJson, pluck, years, identity} from "../../tools";
import URI from "urijs";
import {toImmutable} from "nuclear-js";
import * as endpoints from "./endpoints";

var options2arr = options => Object.keys(options)
    .filter(key => options[key].selected)
    .map(identity);

var addFilters = (filters, url) => null === filters ? url :
    new URI(url).addSearch({
      bidTypeId: options2arr(filters.bidTypes.options),
      bidSelectionMethod: options2arr(filters.bidSelectionMethods.options),
      procuringEntityId: options2arr(filters.procuringEntities.options),
      year: Object.keys(filters.years).filter(year => filters.years[year])
    }).toString();

/*
  Given [[1,2,3], ['a','b','c']] will produce [[1, 'a'], [2, 'b'], [3, 'c']]
 */
var regroup = ([head, ...tail]) => head.map((el, index) => [el].concat(tail.map(pluck(index))));

var response2obj = (field, arr) => arr.reduce((obj, elem) => {
  obj[elem._id] = elem[field];
  return obj;
}, {});

var transformCostEffectivenessData = ([tenderResponse, awardResponse]) => {
  var tender = response2obj('totalTenderAmount', tenderResponse);
  var award = response2obj('totalAwardAmount', awardResponse);
  return Object.keys(tender).map(year => ({
    year: year,
    tender: tender[year],
    diff: tender[year] - award[year]
  }))
};

var transformBidPeriodData = ([tenders, awards]) => {
  var awardsHash = response2obj('averageAwardDays', awards);
  return tenders.map(tender => ({
      year: tender._id,
      tender: tender.averageTenderDays,
      award: awardsHash[tender._id] || 0
    })
  )
};

export default {
  changeTab(slug){
    dispatcher.dispatch(constants.TAB_CHANGED, slug);
  },

  toggleYear(year, selected){
    dispatcher.dispatch(constants.YEAR_TOGGLED, {
      year: year,
      selected: selected
    });
  },

  changeContentWidth(newWidth){
    dispatcher.dispatch(constants.CONTENT_WIDTH_CHANGED, newWidth);
  },

  loadServerSideYearFilteredData(filters = null){
    var load = url => fetchJson(addFilters(filters, url));
    load('/api/topTenLargestTenders').then(data => dispatcher.dispatch(constants.TOP_TENDERS_DATA_UPDATED, data));
    load('/api/topTenLargestAwards').then(data => dispatcher.dispatch(constants.TOP_AWARDS_DATA_UPDATED, data));
  },

  loadData(filters = null){
    var load = url => fetchJson(addFilters(filters, url));
    this.loadServerSideYearFilteredData(filters);
    Promise.all([
      load(endpoints.COUNT_BID_PLANS_BY_YEAR),
      load(endpoints.COUNT_TENDERS_BY_YEAR),
      load(endpoints.COUNT_AWARDS_BY_YEAR)
    ]).then(([bidplans, tenders, awards]) => dispatcher.dispatch(constants.OVERVIEW_DATA_UPDATED, {
      bidplans: bidplans,
      tenders: tenders,
      awards: awards
    }));

    load(endpoints.PLANNED_FUNDING_BY_LOCATION).then(data => dispatcher.dispatch(constants.LOCATION_UPDATED, data));

    Promise.all([
      load(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT),
      load(endpoints.COST_EFFECTIVENESS_AWARD_AMOUNT)
    ])
        .then(transformCostEffectivenessData)
        .then(data => dispatcher.dispatch(constants.COST_EFFECTIVENESS_DATA_UPDATED, data));

    Promise.all([
      load(endpoints.AVERAGE_TENDER_PERIOD),
      load(endpoints.AVERAGE_AWARD_PERIOD)
    ]).then(transformBidPeriodData).then(data => dispatcher.dispatch(constants.BID_PERIOD_DATA_UPDATED, data));

    load(endpoints.TENDER_PRICE_BY_VN_TYPE_YEAR).then(data => dispatcher.dispatch(constants.BID_TYPE_DATA_UPDATED, data));

    load(endpoints.TOTAL_CANCELLED_TENDERS_BY_YEAR)
        .then(data => dispatcher.dispatch(constants.CANCELLED_DATA_UPDATED, data));
  },

  bootstrap(){
    this.loadData();
    Promise.all([
      fetchJson('/api/ocds/bidType/all'),
      fetchJson('/api/ocds/bidSelectionMethod/all')
    ]).then(([bidTypes, bidSelectionMethods]) => dispatcher.dispatch(constants.FILTERS_DATA_UPDATED, {
      years: years().reduce((map, year) => map.set(year, true), toImmutable({})),
      bidTypes: {
        open: true,
        options: bidTypes.reduce((accum, bidType) => {
          var {id} = bidType;
          accum[id] = {
            id: id,
            description: bidType.description,
            selected: false
          };
          return accum;
        }, {})
      },
      bidSelectionMethods: {
        open: true,
        options: bidSelectionMethods
            .filter(method => !!method._id)
            .reduce((accum, {_id}) => {
              accum[_id] = {
                id: _id,
                description: _id,
                selected: false
              };
              return accum;
            }, {})
      },
      procuringEntities: {
        open: true,
        options: []
      }
    }));
  },

  loadComparisonData(criteria, filters){
    if("none" == criteria) return;
    var comparisonUrl = new URI(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT).addSearch({
      groupByCategory: criteria,
      pageSize: 3
    }).toString();
    fetchJson(addFilters(filters, comparisonUrl)).then(comparisonData => {
      var addComparisionFilters = url => {
        var uri = new URI(addFilters(filters, url));
        var criteriaValues = comparisonData.map(pluck("bidTypeId" == criteria ? "0" : "_id"));
        return criteriaValues
            .map(criteriaValue => uri.clone().addSearch(criteria, criteriaValue).toString())
            .concat([
              uri.clone().addSearch(criteria, criteriaValues).addSearch('invert', 'true').toString()
            ]);
      };

      var load = url => Promise.all(addComparisionFilters(url).map(fetchJson));

      Promise.all([
          load(endpoints.COUNT_BID_PLANS_BY_YEAR),
          load(endpoints.COUNT_TENDERS_BY_YEAR),
          load(endpoints.COUNT_AWARDS_BY_YEAR)
      ]).then(data => regroup(data).map(([bidplans, tenders, awards]) => {
        return {
          bidplans: bidplans,
          tenders: tenders,
          awards: awards
        }
      })).then(data => dispatcher.dispatch(constants.OVERVIEW_COMPARISON_DATA_UPDATED, data));

      Promise.all([
        load(endpoints.COST_EFFECTIVENESS_TENDER_AMOUNT),
        load(endpoints.COST_EFFECTIVENESS_AWARD_AMOUNT)
      ]).then(data => regroup(data).map(transformCostEffectivenessData))
          .then(data => dispatcher.dispatch(constants.COST_EFFECTIVENESS_COMPARISON_DATA_UPDATED, data));

      Promise.all([
        load(endpoints.AVERAGE_TENDER_PERIOD),
        load(endpoints.AVERAGE_AWARD_PERIOD)
      ]).then(data => regroup(data).map(transformBidPeriodData))
          .then(data => dispatcher.dispatch(constants.BID_PERIOD_COMPARISON_DATA_UPDATED, data));

      load(endpoints.TENDER_PRICE_BY_VN_TYPE_YEAR).then(data =>
          dispatcher.dispatch(constants.BID_TYPE_COMPARISON_DATA_UPDATED, data));

      load(endpoints.TOTAL_CANCELLED_TENDERS_BY_YEAR)
          .then(data => dispatcher.dispatch(constants.CANCELLED_COMPARISON_DATA_UPDATED, data));
    });
  },

  setFiltersBox(slug){
    dispatcher.dispatch(constants.FILTER_BOX_CHANGED, slug);
  },

  toggleFilter(slug, open){
    dispatcher.dispatch(constants.FILTER_TOGGLED, {
      slug: slug,
      open: open
    })
  },

  toggleFilterOption(slug, option, selected){
    dispatcher.dispatch(constants.FILTER_OPTIONS_TOGGLED, {
      slug: slug,
      option: option,
      selected: selected
    })
  },

  updateProcuringEntityQuery(newQuery){
    dispatcher.dispatch(constants.PROCURING_ENTITY_QUERY_UPDATED, newQuery);
    if (newQuery.length >= 3) {
      fetchJson(new URI('/api/ocds/organization/procuringEntity/all').addSearch('text', newQuery).toString())
          .then(data => {
            dispatcher.dispatch(constants.PROCURING_ENTITIES_UPDATED, data.reduce((accum, procuringEntity) => {
              var {id} = procuringEntity;
              accum[id] = procuringEntity;
              return accum;
            }, {}))
          });
    }
  },

  updateComparisonCriteria(criteria){
    dispatcher.dispatch(constants.COMPARISON_CRITERIA_UPDATED, criteria);
  }
}<|endoftext|>


<commit_before>"use strict";

var esprima = require("esprima"),
    escodegen = require("escodegen"),
    identifierCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

/**
 * AST Reducer
 *
 * @class ASTreducer
 */
var ASTreducer = function() {
    this._identifiers = {};
    this._identifiersStack = [];
};

ASTreducer.prototype = {

    // Process the AST to reduce the generated source
    reduce: function (ast) {
        this._walk(ast);
    },

    /**
     * Create new variable names for the provided name list.
     *
     * @param {String[]} names
     * @param {Boolean} forVariables
     */
    beginIdentifierMapping: function (names, forVariables) {
        var
            len = names.length,
            idx,
            name,
            newNames;
        if (forVariables) {
            names.isVariables = true;
        }
        names.identifierCount = this._identifierCount;
        this._identifiersStack.push(names);
        for (idx = 0; idx < len; ++idx) {
            name = " " + names[idx];
            newNames = this._identifiers[name];
            if (undefined === newNames) {
                newNames = this._identifiers[name] = [];
            }
            newNames.unshift(this._newName());
        }
    },

    // Roll back new variable names created with beginIdentifierMapping
    endIdentifierMapping: function () {
        // Undo identifiers stack until a non 'isVariables' one is found
        var
            stack = this._identifiersStack,
            names,
            len,
            idx,
            name,
            newNames;
        do {
            names = stack.pop();
            len = names.length;
            for (idx = 0; idx < len; ++idx) {
                name = " " + names[idx];
                newNames = this._identifiers[name];
                if (newNames.length === 1) {
                    delete this._identifiers[name];
                } else {
                    newNames.shift();
                }
            }
            this._identifierCount = names.identifierCount;
        } while (names.isVariables);
    },

    /**
     * Return the nmapped identifier (if any)
     *
     * @param {String} name
     * @returns {String|undefined}
     */
    isIdentifierMapped: function (name) {
        name = " " + name;
        if (this._identifiers.hasOwnProperty(name)) {
            return this._identifiers[name][0];
        }
        return undefined;
    },

    // @property {String[][]} Stack of name arrays (corresponding to the cumulated calls to beginIdentifierMapping)
    _identifiersStack: [],

    // Number of identifiers mapped
    _identifierCount: 0,

    // Dictionary of name to mapped identifiers (Array)
    _identifiers: {}, // NOTE key is escaped to avoid collision with existing members

    /**
     * Explore the AST array and apply the necessary transformations
     *
     * @param {Array} astArray
     */
    _walkArray: function (astArray) {
        var
            idx,
            subItem,
            names;
        // First pass to see if any FunctionDeclaration names
        for (idx = 0; idx < astArray.length; ++idx) {
            subItem = astArray[idx];
            if (subItem.type === "FunctionDeclaration") {
                if (undefined === names) {
                    names = [];
                }
                names.push(subItem.id.name);
            }
        }
        if (undefined !== names) {
            this.beginIdentifierMapping(names, true);
        }
        // Second pass to reduce
        for (idx = 0; idx < astArray.length; ++idx) {
            this._walk(astArray[idx]);
        }
    },

    /**
     * Explore the AST members and apply the necessary transformations
     *
     * @param {Object} ast
     */
    _walkItem: function (ast) {
        var member,
            subItem;
        for (member in ast) {
            if (ast.hasOwnProperty(member)) {
                subItem = ast[member];
                if ("object" === typeof subItem && subItem) {
                    this._walk(subItem);
                }
            }
        }
    },

    _reduce: function (ast) {
        var
            myStatics = this.constructor,
            processor = myStatics[ast.type] || {};
        if (processor.pre) {
            processor.pre(ast, this);
        }
        if (processor.walk) {
            processor.walk(ast, this);
        } else {
            this._walkItem(ast);
        }
        if (processor.post) {
            processor.post(this, ast);
        }
    },

    /**
     * Explore the AST structure and apply the necessary transformations
     * The transformations are based on processors declared as static
     * members of this class.
     * Each processor is matched using the AST type and it may contain:
     * - pre: function to apply before exploring the AST
     * - post: function to apply after exploring the AST
     * - walk: override the AST exploring
     *
     * @param {Object} ast
     */
    _walk: function (ast) {
        if (ast instanceof Array) {
            this._walkArray(ast);
        } else {
            this._reduce(ast);
        }
    },

    /**
     * New name allocator (based on number of identifiers)
     *
     * @returns {String}
     */
    _newName: function () {
        var
            id,
            newName,
            mod = identifierCharacters.length;
        do {
            id = this._identifierCount++;
            newName = [];
            while (id >= identifierCharacters.length) {
                newName.push(identifierCharacters.charAt(id % mod));
                id = id / mod;
            }
            newName.push(identifierCharacters.charAt(id));
            newName = newName.join("");
        } while (undefined !== gpf.test(gpf.js.keywords(), newName));
        return newName;
    }

};

/**
 * Test if the AST item has the request gpf: tag
 *
 * @param {Object} ast
 * @param {String} tag
 * @returns {boolean}
 */
ASTreducer.isTaggedWith = function (ast, tag) {
    var array,
        len,
        idx;
    if (!ast.leadingComments) {
        return false;
    }
    tag = "gpf:" + tag;
    array = ast.leadingComments;
    len = array.length;
    for (idx = 0; idx < len; ++idx) {
        if (array[idx].value === tag) {
            return true;
        }
    }
    return false;
};

ASTreducer.VariableDeclaration = {

    pre: function (ast, reducer) {
        var
            names = [],
            len = ast.declarations.length,
            idx,
            decl;
        for (idx = 0; idx < len; ++idx) {
            decl = ast.declarations[idx];
            if (!ASTreducer.isTaggedWith(decl, "no-reduce")) {
                names.push(decl.id.name);
            }
        }
        // TODO distinguish 'globals' from inner variables
        reducer.beginIdentifierMapping(names, true);
    }

};

ASTreducer.FunctionDeclaration = {

    pre: function (ast, reducer) {
        // Name is reduced at an higher level
        var
            names = [],
            idx,
            len;
        // Process parameters
        if (ast.params && ast.params.length) {
            len = ast.params.length;
            for (idx = 0; idx < len; ++idx) {
                names.push(ast.params[idx].name);
            }
        }
        reducer.beginIdentifierMapping(names, false);
    },

    post: function (reducer/*, ast*/) {
        // Clean parameters (and inner variables) substitutions
        reducer.endIdentifierMapping();
    }

};

ASTreducer.FunctionExpression = {

    pre: function (ast, reducer) {
        var
            names = [],
            len,
            idx,
            param;
        // Process parameters
        if (ast.params && ast.params.length) {
            len = ast.params.length;
            for (idx = 0; idx < len; ++idx) {
                param = ast.params[idx];
                if (!ASTreducer.isTaggedWith(param, "no-reduce")) {
                    names.push(ast.params[idx].name);
                }
            }
        }
        reducer.beginIdentifierMapping(names, false);
    },

    post: function (reducer/*, ast*/) {
        // Clean parameters (and inner variables) substitutions
        reducer.endIdentifierMapping();
    }

};

ASTreducer.Identifier = {

    pre: function (astItem, reducer) {
        // TODO Check the astParent avoid !MemberExpression.property
        var newName = reducer.isIdentifierMapped(astItem.name);
        if (undefined !== newName) {
            astItem.name = newName;
        }
    }

};

ASTreducer.MemberExpression = {

    walk: function (astItem, reducer) {
        reducer.reduce(astItem.object);
        // Reduce property only if computed
        if (astItem.computed) {
            reducer.reduce(astItem.property);
        }
    }

};

ASTreducer.ObjectExpression = {

    walk: function (astItem, reducer) {
        var len, idx;
        len = astItem.properties.length;
        for (idx = 0; idx < len; ++idx) {
            reducer.reduce(astItem.properties[idx].value);
        }
    }

};

module.exports = {

    /**
     * Transform the source into an AST representation
     *
     * @param {String} src
     * @return {Object} AST representation
     */
    transform: function (src) {
        // https://github.com/Constellation/escodegen/issues/85
        var
            ast = esprima.parse(src, {
                range: true,
                tokens: true,
                comment: true
            });
        ast = escodegen.attachComments(ast, ast.comments, ast.tokens);
        delete ast.tokens;
        delete ast.comments;
        return ast;
    },

    /**
     * Apply the reduction algorithm
     *
     * @param {Object} ast
     * @return {Object}
     */
    reduce: function (ast) {
        var reducer = new ASTreducer();
        reducer.reduce(ast);
        return ast;
    },

    /**
     * Generate source code from the AST
     *
     * @param {Object} ast
     * @param {Object} options
     * @return {String}
     */
    rewrite: function (ast, options) {
        return escodegen.generate(ast, options);
    }

};
<commit_msg>Documentation<commit_after>"use strict";

var esprima = require("esprima"),
    escodegen = require("escodegen"),
    identifierCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

/**
 * AST Reducer
 *
 * @class ASTreducer
 */
var ASTreducer = function() {
    this._identifiers = {};
    this._identifiersStack = [];
};

ASTreducer.prototype = {

    // Process the AST to reduce the generated source
    reduce: function (ast) {
        this._walk(ast);
    },

    /**
     * Create new variable names for the provided name list.
     *
     * @param {String[]} names
     * @param {Boolean} forVariables
     */
    beginIdentifierMapping: function (names, forVariables) {
        var
            len = names.length,
            idx,
            name,
            newNames;
        if (forVariables) {
            names.isVariables = true;
        }
        names.identifierCount = this._identifierCount;
        this._identifiersStack.push(names);
        for (idx = 0; idx < len; ++idx) {
            name = " " + names[idx];
            newNames = this._identifiers[name];
            if (undefined === newNames) {
                newNames = this._identifiers[name] = [];
            }
            newNames.unshift(this._newName());
        }
    },

    // Roll back new variable names created with beginIdentifierMapping
    endIdentifierMapping: function () {
        // Undo identifiers stack until a non 'isVariables' one is found
        var
            stack = this._identifiersStack,
            names,
            len,
            idx,
            name,
            newNames;
        do {
            names = stack.pop();
            len = names.length;
            for (idx = 0; idx < len; ++idx) {
                name = " " + names[idx];
                newNames = this._identifiers[name];
                if (newNames.length === 1) {
                    delete this._identifiers[name];
                } else {
                    newNames.shift();
                }
            }
            this._identifierCount = names.identifierCount;
        } while (names.isVariables);
    },

    /**
     * Return the nmapped identifier (if any)
     *
     * @param {String} name
     * @returns {String|undefined}
     */
    isIdentifierMapped: function (name) {
        name = " " + name;
        if (this._identifiers.hasOwnProperty(name)) {
            return this._identifiers[name][0];
        }
        return undefined;
    },

    // @property {String[][]} Stack of name arrays (corresponding to the cumulated calls to beginIdentifierMapping)
    _identifiersStack: [],

    // Number of identifiers mapped
    _identifierCount: 0,

    // Dictionary of name to mapped identifiers (Array)
    _identifiers: {}, // NOTE key is escaped to avoid collision with existing members

    /**
     * Explore the AST array and apply the necessary transformations
     *
     * @param {Array} astArray
     */
    _walkArray: function (astArray) {
        var
            idx,
            subItem,
            names;
        // First pass to see if any FunctionDeclaration names
        for (idx = 0; idx < astArray.length; ++idx) {
            subItem = astArray[idx];
            if (subItem.type === "FunctionDeclaration") {
                if (undefined === names) {
                    names = [];
                }
                names.push(subItem.id.name);
            }
        }
        if (undefined !== names) {
            this.beginIdentifierMapping(names, true);
        }
        // Second pass to reduce
        for (idx = 0; idx < astArray.length; ++idx) {
            this._walk(astArray[idx]);
        }
    },

    /**
     * Explore the AST members and apply the necessary transformations
     *
     * @param {Object} ast
     */
    _walkItem: function (ast) {
        var member,
            subItem;
        for (member in ast) {
            if (ast.hasOwnProperty(member)) {
                subItem = ast[member];
                if ("object" === typeof subItem && subItem) {
                    this._walk(subItem);
                }
            }
        }
    },

    /**
     * Apply AST reducer to reduce it
     *
     * @param {Object} ast
     */
    _reduce: function (ast) {
        var
            myStatics = this.constructor,
            processor = myStatics[ast.type] || {};
        if (processor.pre) {
            processor.pre(ast, this);
        }
        if (processor.walk) {
            processor.walk(ast, this);
        } else {
            this._walkItem(ast);
        }
        if (processor.post) {
            processor.post(this, ast);
        }
    },

    /**
     * Explore the AST structure and apply the necessary transformations.
     * The transformations are based on processors declared as static members of this class.
     * Each processor is matched using the AST type and it may contain:
     * - pre: function to apply before exploring the AST
     * - post: function to apply after exploring the AST
     * - walk: override the AST exploring
     *
     * @param {Object} ast
     */
    _walk: function (ast) {
        if (ast instanceof Array) {
            this._walkArray(ast);
        } else {
            this._reduce(ast);
        }
    },

    /**
     * New name allocator (based on number of identifiers)
     *
     * @returns {String}
     */
    _newName: function () {
        var
            id,
            newName,
            mod = identifierCharacters.length;
        do {
            id = this._identifierCount++;
            newName = [];
            while (id >= identifierCharacters.length) {
                newName.push(identifierCharacters.charAt(id % mod));
                id = id / mod;
            }
            newName.push(identifierCharacters.charAt(id));
            newName = newName.join("");
        } while (undefined !== gpf.test(gpf.js.keywords(), newName));
        return newName;
    }

};

/**
 * Test if the AST item has the request gpf: tag
 *
 * @param {Object} ast
 * @param {String} tag
 * @returns {boolean}
 */
ASTreducer.isTaggedWith = function (ast, tag) {
    var array,
        len,
        idx;
    if (!ast.leadingComments) {
        return false;
    }
    tag = "gpf:" + tag;
    array = ast.leadingComments;
    len = array.length;
    for (idx = 0; idx < len; ++idx) {
        if (array[idx].value === tag) {
            return true;
        }
    }
    return false;
};

ASTreducer.VariableDeclaration = {

    pre: function (ast, reducer) {
        var
            names = [],
            len = ast.declarations.length,
            idx,
            decl;
        for (idx = 0; idx < len; ++idx) {
            decl = ast.declarations[idx];
            if (!ASTreducer.isTaggedWith(decl, "no-reduce")) {
                names.push(decl.id.name);
            }
        }
        // TODO distinguish 'globals' from inner variables
        reducer.beginIdentifierMapping(names, true);
    }

};

ASTreducer.FunctionDeclaration = {

    pre: function (ast, reducer) {
        // Name is reduced at an higher level
        var
            names = [],
            idx,
            len;
        // Process parameters
        if (ast.params && ast.params.length) {
            len = ast.params.length;
            for (idx = 0; idx < len; ++idx) {
                names.push(ast.params[idx].name);
            }
        }
        reducer.beginIdentifierMapping(names, false);
    },

    post: function (reducer/*, ast*/) {
        // Clean parameters (and inner variables) substitutions
        reducer.endIdentifierMapping();
    }

};

ASTreducer.FunctionExpression = {

    pre: function (ast, reducer) {
        var
            names = [],
            len,
            idx,
            param;
        // Process parameters
        if (ast.params && ast.params.length) {
            len = ast.params.length;
            for (idx = 0; idx < len; ++idx) {
                param = ast.params[idx];
                if (!ASTreducer.isTaggedWith(param, "no-reduce")) {
                    names.push(ast.params[idx].name);
                }
            }
        }
        reducer.beginIdentifierMapping(names, false);
    },

    post: function (reducer/*, ast*/) {
        // Clean parameters (and inner variables) substitutions
        reducer.endIdentifierMapping();
    }

};

ASTreducer.Identifier = {

    pre: function (astItem, reducer) {
        // TODO Check the astParent avoid !MemberExpression.property
        var newName = reducer.isIdentifierMapped(astItem.name);
        if (undefined !== newName) {
            astItem.name = newName;
        }
    }

};

ASTreducer.MemberExpression = {

    walk: function (astItem, reducer) {
        reducer.reduce(astItem.object);
        // Reduce property only if computed
        if (astItem.computed) {
            reducer.reduce(astItem.property);
        }
    }

};

ASTreducer.ObjectExpression = {

    walk: function (astItem, reducer) {
        var len, idx;
        len = astItem.properties.length;
        for (idx = 0; idx < len; ++idx) {
            reducer.reduce(astItem.properties[idx].value);
        }
    }

};

module.exports = {

    /**
     * Transform the source into an AST representation
     *
     * @param {String} src
     * @return {Object} AST representation
     */
    transform: function (src) {
        // https://github.com/Constellation/escodegen/issues/85
        var
            ast = esprima.parse(src, {
                range: true,
                tokens: true,
                comment: true
            });
        ast = escodegen.attachComments(ast, ast.comments, ast.tokens);
        delete ast.tokens;
        delete ast.comments;
        return ast;
    },

    /**
     * Apply the reduction algorithm
     *
     * @param {Object} ast
     * @return {Object}
     */
    reduce: function (ast) {
        var reducer = new ASTreducer();
        reducer.reduce(ast);
        return ast;
    },

    /**
     * Generate source code from the AST
     *
     * @param {Object} ast
     * @param {Object} options
     * @return {String}
     */
    rewrite: function (ast, options) {
        return escodegen.generate(ast, options);
    }

};
<|endoftext|>


<commit_before>var ZabbixSender = require('./index.js');
var Sender = new ZabbixSender({host: '10.121.202.100'});
//var Sender = new ZabbixSender({host: 'zabbix.example.com'});

// Add items to request
Sender.addItem('webserver', 'httpd.running', 0);
Sender.addItem('dbserver', 'mysql.ping', 1);

// Add item with default host
Sender.addItem('httpd.logs.size', 1024);

// Send the items to zabbix trapper
Sender.send(function(err, res) {
    if (err) {
        throw err;
    }

    // print the response object
    console.dir(res);
});
<commit_msg>update/simplify example.js<commit_after>var ZabbixSender = require('node-zabbix-sender');
var Sender = new ZabbixSender({host: 'zabbix.example.com'});

// Add items to request
Sender.addItem('webserver', 'httpd.running', 0);
Sender.addItem('dbserver', 'mysql.ping', 1);

// Add item with default host
Sender.addItem('httpd.logs.size', 1024);

// Send the items to zabbix trapper
Sender.send(function(err, res) {
    if (err) {
        throw err;
    }

    // print the response object
    console.dir(res);
});

<|endoftext|>


<commit_before>module.exports = {
  displayName: "test",
  rootDir: "../",
  testRegex: "\\.test\\.(js|ts|tsx)$",
  globals: {
    SENTRY_DSN: null,
  },
  moduleFileExtensions: ["js", "tsx", "ts"],
  moduleNameMapper: {
    "\\.css$": "<rootDir>/js/__mocks__/styleMock.js",
    "\\.wsz$": "<rootDir>/js/__mocks__/fileMock.js",
    "\\.mp3$": "<rootDir>/js/__mocks__/fileMock.js",
  },
  transform: {
    "^.+\\.(js|ts|tsx)$": "babel-jest",
  },
  testPathIgnorePatterns: ["/node_modules/"],
};
<commit_msg>Remove unused mocks<commit_after>module.exports = {
  displayName: "test",
  rootDir: "../",
  testRegex: "\\.test\\.(js|ts|tsx)$",
  globals: {
    SENTRY_DSN: null,
  },
  moduleFileExtensions: ["js", "tsx", "ts"],
  moduleNameMapper: {
    // "\\.css$": "<rootDir>/js/__mocks__/styleMock.js",
    // "\\.wsz$": "<rootDir>/js/__mocks__/fileMock.js",
    // "\\.mp3$": "<rootDir>/js/__mocks__/fileMock.js",
  },
  transform: {
    "^.+\\.(js|ts|tsx)$": "babel-jest",
  },
  testPathIgnorePatterns: ["/node_modules/"],
};
<|endoftext|>


<commit_before>"use strict";

const {strict: assert} = require("assert");

const {mock_cjs, mock_esm, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const $ = require("../zjsunit/zjquery");

mock_cjs("jquery", $);
const muting_ui = mock_esm("../../static/js/muting_ui");

const settings_muting = zrequire("settings_muting");
const stream_data = zrequire("stream_data");
const muting = zrequire("muting");

const noop = () => {};

const frontend = {
    stream_id: 101,
    name: "frontend",
};
stream_data.add_sub(frontend);

run_test("settings", () => {
    muting.add_muted_topic(frontend.stream_id, "js", 1577836800);
    let set_up_topic_ui_called = false;
    muting_ui.set_up_muted_topics_ui = () => {
        const opts = muting.get_muted_topics();
        assert.deepEqual(opts, [
            {
                date_muted: 1577836800000,
                date_muted_str: "Jan\u00A001,\u00A02020",
                stream: frontend.name,
                stream_id: frontend.stream_id,
                topic: "js",
            },
        ]);
        set_up_topic_ui_called = true;
    };

    assert.equal(settings_muting.loaded, false);

    settings_muting.set_up();
    assert.equal(settings_muting.loaded, true);

    const topic_click_handler = $("body").get_on_handler("click", ".settings-unmute-topic");
    assert.equal(typeof topic_click_handler, "function");

    const event = {
        stopImmediatePropagation: noop,
    };

    const topic_fake_this = $.create("fake.settings-unmute-topic");
    const topic_tr_html = $('tr[data-topic="js"]');
    topic_fake_this.closest = (opts) => {
        assert.equal(opts, "tr");
        return topic_tr_html;
    };

    topic_tr_html.remove = () => {};

    let topic_data_called = 0;
    topic_tr_html.attr = (opts) => {
        if (opts === "data-stream-id") {
            topic_data_called += 1;
            return frontend.stream_id;
        }
        if (opts === "data-topic") {
            topic_data_called += 1;
            return "js";
        }
        throw new Error(`Unknown attribute ${opts}`);
    };

    let unmute_topic_called = false;
    muting_ui.unmute_topic = (stream_id, topic) => {
        assert.equal(stream_id, frontend.stream_id);
        assert.equal(topic, "js");
        unmute_topic_called = true;
    };
    topic_click_handler.call(topic_fake_this, event);
    assert(unmute_topic_called);
    assert(set_up_topic_ui_called);
    assert.equal(topic_data_called, 2);
});

run_test("reset", () => {
    settings_muting.reset();
    assert.equal(settings_muting.loaded, false);
});
<commit_msg>node tests: Remove needless reset test.<commit_after>"use strict";

const {strict: assert} = require("assert");

const {mock_cjs, mock_esm, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const $ = require("../zjsunit/zjquery");

mock_cjs("jquery", $);
const muting_ui = mock_esm("../../static/js/muting_ui");

const settings_muting = zrequire("settings_muting");
const stream_data = zrequire("stream_data");
const muting = zrequire("muting");

const noop = () => {};

const frontend = {
    stream_id: 101,
    name: "frontend",
};
stream_data.add_sub(frontend);

run_test("settings", () => {
    muting.add_muted_topic(frontend.stream_id, "js", 1577836800);
    let set_up_topic_ui_called = false;
    muting_ui.set_up_muted_topics_ui = () => {
        const opts = muting.get_muted_topics();
        assert.deepEqual(opts, [
            {
                date_muted: 1577836800000,
                date_muted_str: "Jan\u00A001,\u00A02020",
                stream: frontend.name,
                stream_id: frontend.stream_id,
                topic: "js",
            },
        ]);
        set_up_topic_ui_called = true;
    };

    settings_muting.reset();
    assert.equal(settings_muting.loaded, false);

    settings_muting.set_up();
    assert.equal(settings_muting.loaded, true);

    const topic_click_handler = $("body").get_on_handler("click", ".settings-unmute-topic");
    assert.equal(typeof topic_click_handler, "function");

    const event = {
        stopImmediatePropagation: noop,
    };

    const topic_fake_this = $.create("fake.settings-unmute-topic");
    const topic_tr_html = $('tr[data-topic="js"]');
    topic_fake_this.closest = (opts) => {
        assert.equal(opts, "tr");
        return topic_tr_html;
    };

    topic_tr_html.remove = () => {};

    let topic_data_called = 0;
    topic_tr_html.attr = (opts) => {
        if (opts === "data-stream-id") {
            topic_data_called += 1;
            return frontend.stream_id;
        }
        if (opts === "data-topic") {
            topic_data_called += 1;
            return "js";
        }
        throw new Error(`Unknown attribute ${opts}`);
    };

    let unmute_topic_called = false;
    muting_ui.unmute_topic = (stream_id, topic) => {
        assert.equal(stream_id, frontend.stream_id);
        assert.equal(topic, "js");
        unmute_topic_called = true;
    };
    topic_click_handler.call(topic_fake_this, event);
    assert(unmute_topic_called);
    assert(set_up_topic_ui_called);
    assert.equal(topic_data_called, 2);
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import Carousel from 'nuka-carousel';
import moment from 'moment';
import { Container, Grid, Image, Header, Divider, Message, List, Loader } from 'semantic-ui-react';
import GoogleMapContainer from './AllListings/AllListingsComponents/GoogleMap/GoogleMapContainer';
import { getCurrentListing } from '../../actions/fullListingActions';
import Listing from '../shared/Listing';

class FullListing extends Component {
  constructor(props) {
    super(props);
    this.listingId = this.props.params.id;
  }

  componentDidMount() {
    console.log('Listing ID: ', this.listingId);
    this.props.dispatch(getCurrentListing(this.listingId));
  }

  convertTime(time) {
    return moment(time).fromNow();
  }

  cutBody(body) {
    let newBody;
    if (body.length > 20) {
      newBody = `${body.slice(0, 20)}...`;
      return newBody;
    }
    return body;
  }

  render() {
    const { isFetching, currentListing, userListings } = this.props;
    console.log('Listing ID: ', this.listingId);

    if (isFetching) {
      return <Loader active inline="centered" />;
    }

    return (
      <Container textAlign="center">
        -- {currentListing.title || 'Current Listing'} --

        {`Created ${this.convertTime(currentListing.createdAt)}` || 'Time Created'}

        <Divider />

        <Message color="grey">
          <Grid columns={2} textAlign="left">
            <Grid.Column>
              Job Description
              <Grid.Row>

{currentListing.body}

              </Grid.Row>
              <Grid.Row verticalAlign="bottom">
                <Divider hidden section />
                <Carousel>
                  {
                    currentListing.pictures.map(p => <Image key={p.id} src={p.img_path} />)
                  }
                </Carousel>
              </Grid.Row>
            </Grid.Column>
            <Grid.Column>
              <Grid.Row>
                <GoogleMapContainer />
              </Grid.Row>
              <Divider hidden />
              <Grid.Row>
                <List>
                  <List.Item>
                    <List.Icon name="users" />
                    <List.Content>Customer Name</List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="marker" />
                    <List.Content>New York, NY</List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="mail" />
                    <List.Content>
                      jack@semantic-ui.com
                    </List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="linkify" />
                    <List.Content>
                      semantic-ui.com
                    </List.Content>
                  </List.Item>
                </List>
              </Grid.Row>
            </Grid.Column>
          </Grid>

          <Divider clearing />
          <Divider hidden />

          <Grid textAlign="center">
            Related Listings
            <Grid.Row columns={3}>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[0]) {
                      return (<Listing
                        key={userListings[0].id}
                        listingId={userListings[0].id}
                        title={userListings[0].title}
                        createdAt={this.convertTime(userListings[0].createdAt)}
                        body={userListings[0].body}
                        type={userListings[0].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[1]) {
                      return (<Listing
                        key={userListings[1].id}
                        listingId={userListings[1].id}
                        title={userListings[1].title}
                        createdAt={this.convertTime(userListings[1].createdAt)}
                        body={userListings[1].body}
                        type={userListings[1].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[2]) {
                      return (<Listing
                        key={userListings[2].id}
                        listingId={userListings[2].id}
                        title={userListings[2].title}
                        createdAt={this.convertTime(userListings[2].createdAt)}
                        body={userListings[2].body}
                        type={userListings[2].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
            </Grid.Row>
          </Grid>

        </Message>
      </Container>
    );
  }
}

const mapStateToProps = (state) => {
  const { currentListing, userListings, isFetching } = state.listing;
  const { id } = state.auth.loggedInUser;
  return {
    id,
    currentListing,
    userListings,
    isFetching,
  };
};

FullListing.propTypes = {
  isFetching: React.PropTypes.bool.isRequired,
};

export default connect(mapStateToProps)(FullListing);
<commit_msg>Add more broken code that doesnt work yet<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import Carousel from 'nuka-carousel';
import moment from 'moment';
import { Container, Grid, Image, Header, Divider, Message, List, Loader } from 'semantic-ui-react';
import GoogleMapContainer from './AllListings/AllListingsComponents/GoogleMap/GoogleMapContainer';
import { getCurrentListing } from '../../actions/fullListingActions';
import Listing from '../shared/Listing';

class FullListing extends Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    console.log('Listing ID: ', this.props.listingId);
    this.props.dispatch(getCurrentListing(this.props.listingId));
  }

  convertTime(time) {
    return moment(time).fromNow();
  }

  cutBody(body) {
    let newBody;
    if (body.length > 20) {
      newBody = `${body.slice(0, 20)}...`;
      return newBody;
    }
    return body;
  }

  render() {
    const { isFetching, currentListing, userListings } = this.props;
    console.log('Listing ID: ', this.listingId);

    if (isFetching) {
      return <Loader active inline="centered" />;
    }

    return (
      <Container textAlign="center">
        -- {currentListing.title || 'Current Listing'} --

        {`Created ${this.convertTime(currentListing.createdAt)}` || 'Time Created'}

        <Divider />

        <Message color="grey">
          <Grid columns={2} textAlign="left">
            <Grid.Column>
              Job Description
              <Grid.Row>

{currentListing.body}

              </Grid.Row>
              <Grid.Row verticalAlign="bottom">
                <Divider hidden section />
                <Carousel>
                  {
                    currentListing.pictures.map(p => <Image key={p.id} src={p.img_path} />)
                  }
                </Carousel>
              </Grid.Row>
            </Grid.Column>
            <Grid.Column>
              <Grid.Row>
                <GoogleMapContainer />
              </Grid.Row>
              <Divider hidden />
              <Grid.Row>
                <List>
                  <List.Item>
                    <List.Icon name="users" />
                    <List.Content>Customer Name</List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="marker" />
                    <List.Content>New York, NY</List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="mail" />
                    <List.Content>
                      jack@semantic-ui.com
                    </List.Content>
                  </List.Item>
                  <List.Item>
                    <List.Icon name="linkify" />
                    <List.Content>
                      semantic-ui.com
                    </List.Content>
                  </List.Item>
                </List>
              </Grid.Row>
            </Grid.Column>
          </Grid>

          <Divider clearing />
          <Divider hidden />

          <Grid textAlign="center">
            Related Listings
            <Grid.Row columns={3}>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[0]) {
                      return (<Listing
                        key={userListings[0].id}
                        listingId={userListings[0].id}
                        title={userListings[0].title}
                        createdAt={this.convertTime(userListings[0].createdAt)}
                        body={userListings[0].body}
                        type={userListings[0].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[1]) {
                      return (<Listing
                        key={userListings[1].id}
                        listingId={userListings[1].id}
                        title={userListings[1].title}
                        createdAt={this.convertTime(userListings[1].createdAt)}
                        body={userListings[1].body}
                        type={userListings[1].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
              <Grid.Column>
                {
                  (() => {
                    if (userListings[2]) {
                      return (<Listing
                        key={userListings[2].id}
                        listingId={userListings[2].id}
                        title={userListings[2].title}
                        createdAt={this.convertTime(userListings[2].createdAt)}
                        body={userListings[2].body}
                        type={userListings[2].type}
                        cutBody={this.cutBody}
                      />);
                    }
                    return <Image src="http://semantic-ui.com/images/wireframe/media-paragraph.png" />;
                  })()
                }
              </Grid.Column>
            </Grid.Row>
          </Grid>

        </Message>
      </Container>
    );
  }
}

const mapStateToProps = (state) => {
  const { currentListing, userListings, isFetching } = state.listing;
  const { id } = state.auth.loggedInUser;
  const { pathname } = state.routing.locationBeforeTransitions;

  const listingId = pathname.split('/')[2];
  return {
    id,
    currentListing,
    userListings,
    isFetching,
    listingId,
  };
};

FullListing.propTypes = {
  isFetching: React.PropTypes.bool.isRequired,
};

export default connect(mapStateToProps)(FullListing);
<|endoftext|>