<commit_before>import React, { Component, PropTypes } from "react";

import CreateDashboardModal from 'metabase/components/CreateDashboardModal.jsx';
import ModalContent from "metabase/components/ModalContent.jsx";
import SortableItemList from 'metabase/components/SortableItemList.jsx';

import Urls from "metabase/lib/urls";

import moment from 'moment';

export default class AddToDashSelectDashModal extends Component {
    constructor(props, context) {
        super(props, context);
        this.addToDashboard = this.addToDashboard.bind(this);
        this.createDashboard = this.createDashboard.bind(this);
        this.loadDashboardList();

        this.state = {
            dashboards: null
        };
    }

    static propTypes = {
        card: PropTypes.object.isRequired,
        dashboardApi: PropTypes.object.isRequired,
        closeFn: PropTypes.func.isRequired,
        onChangeLocation: PropTypes.func.isRequired
    };

    async loadDashboardList() {
        var dashboards = await this.props.dashboardApi.list({ f: "all" });
        for (var dashboard of dashboards) {
            dashboard.updated_at = moment(dashboard.updated_at);
        }
        this.setState({ dashboards });
    }

    addToDashboard(dashboard) {
        // we send the user over to the chosen dashboard in edit mode with the current card added
        this.props.onChangeLocation(Urls.dashboard(dashboard.id)+"?add="+this.props.card.id);
    }

    async createDashboard(newDashboard) {
        let dashboard = await this.props.dashboardApi.create(newDashboard);
        // this.props.notifyDashboardCreatedFn(dashboard);
        this.addToDashboard(dashboard);
    }

    render() {
        if (!this.state.dashboards) {
            return null;
        } else if (this.state.dashboards.length === 0) {
            return <CreateDashboardModal createDashboardFn={this.createDashboard} closeFn={this.props.closeFn} />
        } else {
            return (
                <ModalContent
                    id="AddToDashSelectDashModal"
                    title="Add Question to Dashboard"
                    closeFn={this.props.closeFn}
                >
                    <SortableItemList
                        items={this.state.dashboards}
                        onClickItemFn={this.addToDashboard}
                    />
                </ModalContent>
            );
        }
    }
}<commit_msg>Let user create a new dashboard when adding a question to a dashboard (#3598)<commit_after>import React, { Component, PropTypes } from "react";

import CreateDashboardModal from 'metabase/components/CreateDashboardModal.jsx';
import Icon from 'metabase/components/Icon.jsx';
import ModalContent from "metabase/components/ModalContent.jsx";
import SortableItemList from 'metabase/components/SortableItemList.jsx';

import Urls from "metabase/lib/urls";

import moment from 'moment';

export default class AddToDashSelectDashModal extends Component {
    constructor(props, context) {
        super(props, context);
        this.addToDashboard = this.addToDashboard.bind(this);
        this.createDashboard = this.createDashboard.bind(this);
        this.loadDashboardList();

        this.state = {
            dashboards: null,
            shouldCreateDashboard: false
        };
    }

    static propTypes = {
        card: PropTypes.object.isRequired,
        dashboardApi: PropTypes.object.isRequired,
        closeFn: PropTypes.func.isRequired,
        onChangeLocation: PropTypes.func.isRequired
    };

    async loadDashboardList() {
        var dashboards = await this.props.dashboardApi.list({ f: "all" });
        for (var dashboard of dashboards) {
            dashboard.updated_at = moment(dashboard.updated_at);
        }
        this.setState({ dashboards });
    }

    addToDashboard(dashboard) {
        // we send the user over to the chosen dashboard in edit mode with the current card added
        this.props.onChangeLocation(Urls.dashboard(dashboard.id)+"?add="+this.props.card.id);
    }

    async createDashboard(newDashboard) {
        let dashboard = await this.props.dashboardApi.create(newDashboard);
        // this.props.notifyDashboardCreatedFn(dashboard);
        this.addToDashboard(dashboard);
    }

    render() {
        if (!this.state.dashboards) {
            return null;
        } else if (this.state.dashboards.length === 0 || this.state.shouldCreateDashboard === true) {
            return <CreateDashboardModal createDashboardFn={this.createDashboard} closeFn={this.props.closeFn} />
        } else {
            return (
                <ModalContent
                    id="AddToDashSelectDashModal"
                    title="Add Question to Dashboard"
                    closeFn={this.props.closeFn}
                >
                <div className="flex flex-column">
                    <div
                        className="link flex-align-right px4 cursor-pointer"
                        onClick={() => this.setState({ shouldCreateDashboard: true })}
                    >
                        <div
                            className="flex align-center absolute"
                            style={ { right: 40 } }
                        >
                            <Icon name="add" size={16} />
                            <h3 className="ml1">Add to new dashboard</h3>
                        </div>
                    </div>
                    <SortableItemList
                        items={this.state.dashboards}
                        onClickItemFn={this.addToDashboard}
                    />
                </div>
                </ModalContent>
            );
        }
    }
}
{'fraction_non_alphanumeric': 0.09758249514734427, 'fraction_numerical': 0.0024704429151226398, 'mean_word_length': 1.9863013698630136, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '826859', 'n_tokens_mistral': 1499, 'n_tokens_neox': 1514, 'n_words': 299}