<commit_before>import $ from 'jquery';
import React from 'react';
import PropTypes from 'prop-types';
import reactMixin from 'react-mixin';
import autoBind from 'react-autobind';
import Reflux from 'reflux';
import alertify from 'alertifyjs';
import editableFormMixin from '../editorMixins/editableForm';
import Select from 'react-select';
import Dropzone from 'react-dropzone';
import moment from 'moment';
import ui from '../ui';
import bem from '../bem';
import DocumentTitle from 'react-document-title';
import TextareaAutosize from 'react-autosize-textarea';
import stores from '../stores';
import {hashHistory} from 'react-router';
import {DebounceInput} from 'react-debounce-input';

import {session} from '../stores';
import mixins from '../mixins';

const newFormMixins = [
    Reflux.ListenerMixin,
    editableFormMixin
];
import TemplatesList from './formEditors/templatesList';

import actions from '../actions';
import {dataInterface} from '../dataInterface';
import {
  t,
  redirectTo,
  assign,
  formatTime,
  validFileTypes,
  isAValidUrl
} from '../utils';

import {
  update_states,
  PROJECT_SETTINGS_CONTEXTS
} from '../constants';

var formViaUrlHelpLink = 'http://help.kobotoolbox.org/creating-forms/importing-an-xlsform-via-url';

/*
This is used for multiple different purposes:

1. When creating new project
2. When replacing project with new one
3. When editing project in /settings

Identifying the purpose is done by checking `context` and `formAsset`.
*/
export class ProjectSettings extends React.Component {
  constructor(props){
    super(props);

    this.STEPS = {
      FORM_SOURCE: 'form-source',
      CHOOSE_TEMPLATE: 'choose-template',
      UPLOAD_FILE: 'upload-file',
      IMPORT_URL: 'import-url',
      PROJECT_DETAILS: 'project-details'
    }

    const formAsset = this.props.formAsset;

    this.state = {
      isSessionLoaded: !!session.currentAccount,
      isSubmitPending: false,
      formAsset: formAsset,
      // project details
      name: formAsset ? formAsset.name : '',
      description: formAsset ? formAsset.settings.description : '',
      sector: formAsset ? formAsset.settings.sector : null,
      country: formAsset ? formAsset.settings.country : null,
      'share-metadata': formAsset ? formAsset.settings['share-metadata'] : false,
      // steps
      currentStep: null,
      previousStep: null,
      // importing url
      importUrl: '',
      importUrlButtonEnabled: false,
      importUrlButton: t('Import'),
      // template
      isApplyTemplatePending: false,
      applyTemplateButton: t('Choose'),
      chosenTemplateUid: null
    };

    autoBind(this);
  }

  /*
   * setup
   */

  componentDidMount () {
    this.setInitialStep();
    this.listenTo(session, (session) => {
      this.setState({
        isSessionLoaded: true,
      });
    });
  }

  setInitialStep() {
    switch (this.props.context) {
      case PROJECT_SETTINGS_CONTEXTS.NEW:
      case PROJECT_SETTINGS_CONTEXTS.REPLACE:
        return this.displayStep(this.STEPS.FORM_SOURCE);
      case PROJECT_SETTINGS_CONTEXTS.EXISTING:
        return this.displayStep(this.STEPS.PROJECT_DETAILS);
      default:
        throw new Error(`Unknown context: ${this.props.context}!`);
    }
  }

  getStepTitle(step) {
    switch (step) {
      case this.STEPS.FORM_SOURCE: return t('Form source');
      case this.STEPS.CHOOSE_TEMPLATE: return t('Choose template');
      case this.STEPS.UPLOAD_FILE: return t('Upload XLSForm');
      case this.STEPS.IMPORT_URL: return t('Import XLSForm');
      case this.STEPS.PROJECT_DETAILS: return t('Project details');
      default: return '';
    }
  }

  /*
   * handling user input
   */

  onNameChange (evt) {
    this.setState({name: evt.target.value});
  }

  onDescriptionChange (evt) {
    this.setState({description: evt.target.value});
  }

  onCountryChange (val) {
    this.setState({country: val});
  }

  onSectorChange (val) {
    this.setState({sector: val});
  }

  onShareMetadataChange (evt) {
    this.setState({'share-metadata': evt.target.checked});
  }

  onImportUrlChange (value) {
    this.setState({
      importUrl: value,
      importUrlButtonEnabled: value.length > 6 ? true : false,
      importUrlButton: t('Import')
    });
  }

  onTemplateChange(templateUid) {
    this.setState({
      chosenTemplateUid: templateUid
    });
  }

  resetApplyTemplateButton() {
    this.setState({
      isApplyTemplatePending: false,
      applyTemplateButton: t('Choose')
    });
  }

  /*
   * routes navigation
   */

  goToFormBuilder(assetUid) {
    stores.pageState.hideModal();
    hashHistory.push(`/forms/${assetUid}/edit`);
  }

  goToFormLanding() {
    stores.pageState.hideModal();
    hashHistory.push(`/forms/${this.state.formAsset.uid}/landing`);
  }

  /*
   * modal steps navigation
   */

  displayStep(targetStep) {
    const currentStep = this.state.currentStep;
    const previousStep = this.state.previousStep;

    if (targetStep === currentStep) {
      return;
    } else if (targetStep === previousStep) {
      this.setState({
        currentStep: previousStep,
        previousStep: null
      });
    } else {
      this.setState({
        currentStep: targetStep,
        previousStep: currentStep
      });
    }

    if (this.props.onSetModalTitle) {
      const stepTitle = this.getStepTitle(targetStep);
      this.props.onSetModalTitle(`${t('Create new project')}: ${stepTitle}`);
    }
  }

  displayPreviousStep() {
    if (this.state.previousStep) {
      this.displayStep(this.state.previousStep);
    }
  }

  /*
   * handling asset creation
   */

  getOrCreateFormAsset() {
    const assetPromise = new Promise((resolve, reject) => {
      if (this.state.formAsset) {
        resolve(this.state.FormAsset)
      } else {
        dataInterface.createResource({
          name: 'Untitled',
          asset_type: 'survey',
          settings: JSON.stringify({
            description: '',
            sector: null,
            country: null,
            'share-metadata': false
          })
        }).done((asset) => {
          resolve(asset);
        }).fail(function(r){
          reject(t('Error: asset could not be created.') + ` (code: ${r.statusText})`);
        });
      }
    });
    return assetPromise;
  }

  createAssetAndOpenInBuilder() {
    dataInterface.createResource({
      name: this.state.name,
      settings: JSON.stringify({
        description: this.state.description,
        sector: this.state.sector,
        country: this.state.country,
        'share-metadata': this.state['share-metadata']
      }),
      asset_type: 'survey',
    }).done((asset) => {
      this.goToFormBuilder(asset.uid);
    }).fail(function(r){
      notify(t('Error: new project could not be created.') + ` (code: ${r.statusText})`);
    });
  }

  updateAndOpenAsset() {
    actions.resources.updateAsset(
      this.state.formAsset.uid,
      {
        name: this.state.name,
        settings: JSON.stringify({
          description: this.state.description,
          sector: this.state.sector,
          country: this.state.country,
          'share-metadata': this.state['share-metadata']
        }),
      }, {
        onComplete: () => {
          // no need to open asset from withing asset's settings view
          if (this.props.context !== PROJECT_SETTINGS_CONTEXTS.EXISTING) {
            this.goToFormLanding();
          }
        },
        hideDefaultDoneNotification: true
      }
    );
  }

  applyTemplate(evt) {
    evt.preventDefault();

    this.setState({
      isApplyTemplatePending: true,
      applyTemplateButton: t('Creating…')
    });

    actions.resources.cloneAsset({
      uid: this.state.chosenTemplateUid,
      new_asset_type: 'survey'
    }, {
      onComplete: (asset) => {
        this.setState({
          formAsset: asset,
          name: asset.name,
          description: asset.settings.description,
          sector: asset.settings.sector,
          country: asset.settings.country,
          'share-metadata': asset.settings['share-metadata'] || false,
        });
        this.resetApplyTemplateButton();
        this.displayStep(this.STEPS.PROJECT_DETAILS);
      },
      onFailed: (asset) => {
        this.resetApplyTemplateButton();
        alertify.error(t('Could not create project!'));
      }
    });
  }

  importFromURL(evt) {
    evt.preventDefault();

    if (isAValidUrl(this.state.importUrl)) {
      this.setState({
        importUrlButtonEnabled: false,
        importUrlButton: t('Retrieving form, please wait...')
      });

      this.getOrCreateFormAsset().then(
        (asset) => {
          this._forEachDroppedFile({
            destination: asset.url,
            url: this.state.importUrl,
            name: asset.name,
            assetUid: asset.uid
          });
        },
        (errorMessage) => {
          alertify.error(t('Could not import XLSForm!'))
        }
      );
    }
  }

  onDrop (files, rejectedFiles, evt) {
    if (files.length === 0) {
      return;
    }
    this.dropFiles(files, [], evt, { destination: this.state.formAsset.url });
  }

  handleSubmit(evt) {
    evt.preventDefault();

    // simple non-empty name validation
    if (!this.state.name.trim()) {
      alertify.error(t('Please enter a title for your project!'));
      return
    }

    this.setState({isSubmitPending: true});

    if (this.state.formAsset) {
      this.updateAndOpenAsset();
    } else {
      this.createAssetAndOpenInBuilder();
    }
  }

  /*
   * rendering
   */

  renderStepFormSource() {
    return (
      <bem.FormModal__item className='project-settings'>
        <bem.Modal__subheader>
          {t('Choose one of the options below to continue. You will be prompted to enter name and other details in further steps.')}
        </bem.Modal__subheader>

        <bem.FormModal__item m='form-source-buttons'>
          {this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW &&
            <button onClick={this.displayStep.bind(this, this.STEPS.PROJECT_DETAILS)}>
              <i className="k-icon-edit" />
              {t('Build from scratch')}
            </button>
          }

          <button onClick={this.displayStep.bind(this, this.STEPS.CHOOSE_TEMPLATE)}>
            <i className="k-icon-template" />
            {t('Use a template')}
          </button>

          <button onClick={this.displayStep.bind(this, this.STEPS.UPLOAD_FILE)}>
            <i className="k-icon-upload" />
            {t('Upload an XLSForm')}
          </button>

          <button onClick={this.displayStep.bind(this, this.STEPS.IMPORT_URL)}>
            <i className="k-icon-link" />
            {t('Import an XLSForm via URL')}
          </button>
        </bem.FormModal__item>
      </bem.FormModal__item>
    );
  }

  renderStepChooseTemplate() {
    return (
      <bem.FormModal__item className='project-settings'>
        <TemplatesList onSelectTemplate={this.onTemplateChange}/>

        <bem.Modal__footer>
          <bem.Modal__footerButton
            m='primary'
            onClick={this.applyTemplate}
            disabled={!this.state.chosenTemplateUid || this.state.isApplyTemplatePending}
            className="mdl-js-button"
          >
            {this.state.applyTemplateButton}
          </bem.Modal__footerButton>

          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepUploadFile() {
    return (
      <bem.FormModal__item className='project-settings'>
        <bem.Modal__subheader>
          {t('Import an XLSForm from your computer.')}
        </bem.Modal__subheader>

        <Dropzone
          onDrop={this.onDrop.bind(this)}
          multiple={false}
          className='dropzone'
          activeClassName='dropzone-active'
          rejectClassName='dropzone-reject'
          accept={validFileTypes()}
        >
          <i className="k-icon-xls-file" />
          {t(' Drag and drop the XLSForm file here or click to browse')}
        </Dropzone>

        <bem.Modal__footer>
          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepImportUrl() {
    return (
      <bem.FormModal__item className='project-settings'>
        <div className="intro">
          {t('Enter a valid XLSForm URL in the field below.')}<br/>
          <a href={formViaUrlHelpLink} target="_blank">
            {t('Having issues? See this help article.')}
          </a>
        </div>

        <label htmlFor="url">
          {t('URL')}
        </label>

        <DebounceInput
          type="text"
          id="importUrl"
          debounceTimeout={300}
          value={this.state.importUrl}
          placeholder='https://'
          onChange={event => this.onImportUrlChange(event.target.value)}
        />

        <bem.Modal__footer>
          <bem.Modal__footerButton
            m='primary'
            onClick={this.importFromURL}
            disabled={!this.state.importUrlButtonEnabled}
            className="mdl-js-button"
          >
            {this.state.importUrlButton}
          </bem.Modal__footerButton>

          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepProjectDetails() {
    const sectors = session.currentAccount.available_sectors;
    const countries = session.currentAccount.available_countries;

    return (
      <bem.FormModal__form
        onSubmit={this.handleSubmit}
        className='project-settings'
      >
        {(this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW || this.props.context === PROJECT_SETTINGS_CONTEXTS.REPLACE) &&
          <bem.Modal__subheader>
            <i className="k-icon-alert" />
            {t('Enter your project details below. In the next step, you can import an XLSForm (via upload or URL) or design the form from scratch in the Form Builder. ')}
          </bem.Modal__subheader>
        }

        {this.props.context === PROJECT_SETTINGS_CONTEXTS.EXISTING &&
          <bem.Modal__footer>
            <bem.Modal__footerButton
              m='primary'
              onClick={this.handleSubmit}
              className="mdl-js-button"
            >
              {t('Save Changes')}
            </bem.Modal__footerButton>
          </bem.Modal__footer>
        }

        <bem.FormModal__item m='wrapper'>
          <bem.FormModal__item>
            <label htmlFor="name">
              {t('Project Name')}
            </label>
            <input type="text"
              id="name"
              placeholder={t('Enter title of project here')}
              value={this.state.name}
              onChange={this.onNameChange}
            />
          </bem.FormModal__item>

          <bem.FormModal__item>
            <label htmlFor="description">
              {t('Description')}
            </label>
            <TextareaAutosize
              onChange={this.onDescriptionChange}
              value={this.state.description}
              placeholder={t('Enter short description here')}
            />
          </bem.FormModal__item>

          <bem.FormModal__item>
            <label className="long">
              {t('Please specify the country and the sector where this project will be deployed. ')}
              {/*t('This information will be used to help you filter results on the project list page.')*/}
            </label>
          </bem.FormModal__item>

          <bem.FormModal__item m='sector'>
            <label htmlFor="sector">
              {t('Sector')}
            </label>
            <Select
              id="sector"
              value={this.state.sector}
              onChange={this.onSectorChange}
              options={sectors}
            />
          </bem.FormModal__item>

          <bem.FormModal__item  m='country'>
            <label htmlFor="country">
              {t('Country')}
            </label>
            <Select
              id="country"
              value={this.state.country}
              onChange={this.onCountryChange}
              options={countries}
            />
          </bem.FormModal__item>

          <bem.FormModal__item m='metadata-share'>
            <input
              type="checkbox"
              id="share-metadata"
              checked={this.state['share-metadata']}
              onChange={this.onShareMetadataChange}
            />
            <label htmlFor="share-metadata">
              {t('Help KoboToolbox improve this product by sharing the sector and country where this project will be deployed.')}
              &nbsp;
              {t('All the information is submitted anonymously, and will not include the project name or description listed above.')}
            </label>
          </bem.FormModal__item>

          {(this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW || this.props.context === PROJECT_SETTINGS_CONTEXTS.REPLACE) &&
            <bem.Modal__footer>
              <bem.Modal__footerButton
                m='primary'
                onClick={this.handleSubmit}
                className="mdl-js-button"
                disabled={this.state.isSubmitPending}
              >
                {this.state.isSubmitPending ? t('Creating…') : t('Crate Project')}
              </bem.Modal__footerButton>

              {/* Don't allow going back if asset already exist */}
              {!this.state.formAsset &&
                this.renderBackButton()
              }
            </bem.Modal__footer>
          }

          {this.props.context === PROJECT_SETTINGS_CONTEXTS.EXISTING && this.props.iframeUrl &&
            <bem.FormView__cell m='iframe'>
              <iframe src={this.props.iframeUrl} />
            </bem.FormView__cell>
          }
        </bem.FormModal__item>
      </bem.FormModal__form>
    );
  }

  renderBackButton() {
    if (this.state.previousStep) {
      return (
        <bem.Modal__footerButton
          m='back'
          onClick={this.displayPreviousStep}
          disabled={this.state.isSubmitPending || this.state.isApplyTemplatePending}
        >
          {t('Back')}
        </bem.Modal__footerButton>
      )
    } else {
      return false;
    }
  }

  renderLoading() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );
  }

  render () {
    if (!this.state.isSessionLoaded || !this.state.currentStep) {
      return this.renderLoading();
    }

    switch (this.state.currentStep) {
      case this.STEPS.FORM_SOURCE: return this.renderStepFormSource();
      case this.STEPS.CHOOSE_TEMPLATE: return this.renderStepChooseTemplate();
      case this.STEPS.UPLOAD_FILE: return this.renderStepUploadFile();
      case this.STEPS.IMPORT_URL: return this.renderStepImportUrl();
      case this.STEPS.PROJECT_DETAILS: return this.renderStepProjectDetails();
      default:
        throw new Error(`Unknown step: ${this.state.currentStep}!`);
    }
  }
};

reactMixin(ProjectSettings.prototype, Reflux.ListenerMixin);
reactMixin(ProjectSettings.prototype, mixins.droppable);

ProjectSettings.contextTypes = {
  router: PropTypes.object
};

export class ProjectDownloads extends React.Component {
  constructor(props){<commit_msg>file upload step<commit_after>import $ from 'jquery';
import React from 'react';
import PropTypes from 'prop-types';
import reactMixin from 'react-mixin';
import autoBind from 'react-autobind';
import Reflux from 'reflux';
import alertify from 'alertifyjs';
import editableFormMixin from '../editorMixins/editableForm';
import Select from 'react-select';
import Dropzone from 'react-dropzone';
import moment from 'moment';
import ui from '../ui';
import bem from '../bem';
import DocumentTitle from 'react-document-title';
import TextareaAutosize from 'react-autosize-textarea';
import stores from '../stores';
import {hashHistory} from 'react-router';
import {DebounceInput} from 'react-debounce-input';

import {session} from '../stores';
import mixins from '../mixins';

const newFormMixins = [
    Reflux.ListenerMixin,
    editableFormMixin
];
import TemplatesList from './formEditors/templatesList';

import actions from '../actions';
import {dataInterface} from '../dataInterface';
import {
  t,
  redirectTo,
  assign,
  formatTime,
  validFileTypes,
  isAValidUrl
} from '../utils';

import {
  update_states,
  PROJECT_SETTINGS_CONTEXTS
} from '../constants';

var formViaUrlHelpLink = 'http://help.kobotoolbox.org/creating-forms/importing-an-xlsform-via-url';

/*
This is used for multiple different purposes:

1. When creating new project
2. When replacing project with new one
3. When editing project in /settings

Identifying the purpose is done by checking `context` and `formAsset`.
*/
export class ProjectSettings extends React.Component {
  constructor(props){
    super(props);

    this.STEPS = {
      FORM_SOURCE: 'form-source',
      CHOOSE_TEMPLATE: 'choose-template',
      UPLOAD_FILE: 'upload-file',
      IMPORT_URL: 'import-url',
      PROJECT_DETAILS: 'project-details'
    }

    const formAsset = this.props.formAsset;

    this.state = {
      isSessionLoaded: !!session.currentAccount,
      isSubmitPending: false,
      formAsset: formAsset,
      // project details
      name: formAsset ? formAsset.name : '',
      description: formAsset ? formAsset.settings.description : '',
      sector: formAsset ? formAsset.settings.sector : null,
      country: formAsset ? formAsset.settings.country : null,
      'share-metadata': formAsset ? formAsset.settings['share-metadata'] : false,
      // steps
      currentStep: null,
      previousStep: null,
      // importing url
      isImportFromURLPending: false,
      importUrl: '',
      importUrlButtonEnabled: false,
      importUrlButton: t('Import'),
      // template
      isApplyTemplatePending: false,
      applyTemplateButton: t('Choose'),
      chosenTemplateUid: null,
      // upload files
      isUploadFilePending: false
    };

    autoBind(this);
  }

  /*
   * setup
   */

  componentDidMount() {
    this.setInitialStep();
    this.listenTo(session, (session) => {
      this.setState({
        isSessionLoaded: true,
      });
    });
  }

  setInitialStep() {
    switch (this.props.context) {
      case PROJECT_SETTINGS_CONTEXTS.NEW:
      case PROJECT_SETTINGS_CONTEXTS.REPLACE:
        return this.displayStep(this.STEPS.FORM_SOURCE);
      case PROJECT_SETTINGS_CONTEXTS.EXISTING:
        return this.displayStep(this.STEPS.PROJECT_DETAILS);
      default:
        throw new Error(`Unknown context: ${this.props.context}!`);
    }
  }

  getStepTitle(step) {
    switch (step) {
      case this.STEPS.FORM_SOURCE: return t('Form source');
      case this.STEPS.CHOOSE_TEMPLATE: return t('Choose template');
      case this.STEPS.UPLOAD_FILE: return t('Upload XLSForm');
      case this.STEPS.IMPORT_URL: return t('Import XLSForm');
      case this.STEPS.PROJECT_DETAILS: return t('Project details');
      default: return '';
    }
  }

  /*
   * handling user input
   */

  onNameChange(evt) {
    this.setState({name: evt.target.value});
  }

  onDescriptionChange(evt) {
    this.setState({description: evt.target.value});
  }

  onCountryChange(val) {
    this.setState({country: val});
  }

  onSectorChange(val) {
    this.setState({sector: val});
  }

  onShareMetadataChange(evt) {
    this.setState({'share-metadata': evt.target.checked});
  }

  onImportUrlChange(value) {
    this.setState({
      importUrl: value,
      importUrlButtonEnabled: value.length > 6 ? true : false,
      importUrlButton: t('Import')
    });
  }

  onTemplateChange(templateUid) {
    this.setState({
      chosenTemplateUid: templateUid
    });
  }

  resetApplyTemplateButton() {
    this.setState({
      isApplyTemplatePending: false,
      applyTemplateButton: t('Choose')
    });
  }

  /*
   * routes navigation
   */

  goToFormBuilder(assetUid) {
    stores.pageState.hideModal();
    hashHistory.push(`/forms/${assetUid}/edit`);
  }

  goToFormLanding() {
    stores.pageState.hideModal();
    hashHistory.push(`/forms/${this.state.formAsset.uid}/landing`);
  }

  /*
   * modal steps navigation
   */

  displayStep(targetStep) {
    const currentStep = this.state.currentStep;
    const previousStep = this.state.previousStep;

    if (targetStep === currentStep) {
      return;
    } else if (targetStep === previousStep) {
      this.setState({
        currentStep: previousStep,
        previousStep: null
      });
    } else {
      this.setState({
        currentStep: targetStep,
        previousStep: currentStep
      });
    }

    if (this.props.onSetModalTitle) {
      const stepTitle = this.getStepTitle(targetStep);
      this.props.onSetModalTitle(`${t('Create new project')}: ${stepTitle}`);
    }
  }

  displayPreviousStep() {
    if (this.state.previousStep) {
      this.displayStep(this.state.previousStep);
    }
  }

  /*
   * handling asset creation
   */

  getOrCreateFormAsset() {
    const assetPromise = new Promise((resolve, reject) => {
      if (this.state.formAsset) {
        resolve(this.state.FormAsset)
      } else {
        dataInterface.createResource({
          name: 'Untitled',
          asset_type: 'survey',
          settings: JSON.stringify({
            description: '',
            sector: null,
            country: null,
            'share-metadata': false
          })
        }).done((asset) => {
          resolve(asset);
        }).fail(function(r){
          reject(t('Error: asset could not be created.') + ` (code: ${r.statusText})`);
        });
      }
    });
    return assetPromise;
  }

  createAssetAndOpenInBuilder() {
    dataInterface.createResource({
      name: this.state.name,
      settings: JSON.stringify({
        description: this.state.description,
        sector: this.state.sector,
        country: this.state.country,
        'share-metadata': this.state['share-metadata']
      }),
      asset_type: 'survey',
    }).done((asset) => {
      this.goToFormBuilder(asset.uid);
    }).fail(function(r){
      notify(t('Error: new project could not be created.') + ` (code: ${r.statusText})`);
    });
  }

  updateAndOpenAsset() {
    actions.resources.updateAsset(
      this.state.formAsset.uid,
      {
        name: this.state.name,
        settings: JSON.stringify({
          description: this.state.description,
          sector: this.state.sector,
          country: this.state.country,
          'share-metadata': this.state['share-metadata']
        }),
      }, {
        onComplete: () => {
          // no need to open asset from withing asset's settings view
          if (this.props.context !== PROJECT_SETTINGS_CONTEXTS.EXISTING) {
            this.goToFormLanding();
          }
        },
        hideDefaultDoneNotification: true
      }
    );
  }

  applyTemplate(evt) {
    evt.preventDefault();

    this.setState({
      isApplyTemplatePending: true,
      applyTemplateButton: t('Creating…')
    });

    actions.resources.cloneAsset({
      uid: this.state.chosenTemplateUid,
      new_asset_type: 'survey'
    }, {
      onComplete: (asset) => {
        this.setState({
          formAsset: asset,
          name: asset.name,
          description: asset.settings.description,
          sector: asset.settings.sector,
          country: asset.settings.country,
          'share-metadata': asset.settings['share-metadata'] || false,
        });
        this.resetApplyTemplateButton();
        this.displayStep(this.STEPS.PROJECT_DETAILS);
      },
      onFailed: (asset) => {
        this.resetApplyTemplateButton();
        alertify.error(t('Could not create project!'));
      }
    });
  }

  importFromURL(evt) {
    evt.preventDefault();

    if (isAValidUrl(this.state.importUrl)) {
      this.setState({
        isImportFromURLPending: true,
        importUrlButtonEnabled: false,
        importUrlButton: t('Retrieving form, please wait...')
      });

      this.getOrCreateFormAsset().then(
        (asset) => {
          this.setState({
            isImportFromURLPending: false,
            formAsset: asset
          });
          this._forEachDroppedFile({
            destination: asset.url,
            url: this.state.importUrl,
            name: asset.name,
            assetUid: asset.uid
          });
        },
        (errorMessage) => {
          alertify.error(t('Could not import XLSForm!'))
        }
      );
    }
  }

  onFileDrop(files, rejectedFiles, evt) {
    if (files.length >= 1) {
      this.setState({
        isUploadFilePending: true,
        importUrlButtonEnabled: false,
        importUrlButton: t('Retrieving form, please wait...')
      });

      this.getOrCreateFormAsset().then(
        (asset) => {
          this.setState({
            formAsset: asset,
            isUploadFilePending: false
          });
          this.dropFiles(files, [], evt, {destination: asset.url});
        },
        (errorMessage) => {
          alertify.error(t('Could not import XLSForm!'))
        }
      );
    }
  }

  handleSubmit(evt) {
    evt.preventDefault();

    // simple non-empty name validation
    if (!this.state.name.trim()) {
      alertify.error(t('Please enter a title for your project!'));
      return
    }

    this.setState({isSubmitPending: true});

    if (this.state.formAsset) {
      this.updateAndOpenAsset();
    } else {
      this.createAssetAndOpenInBuilder();
    }
  }

  /*
   * rendering
   */

  renderStepFormSource() {
    return (
      <bem.FormModal__item className='project-settings'>
        <bem.Modal__subheader>
          {t('Choose one of the options below to continue. You will be prompted to enter name and other details in further steps.')}
        </bem.Modal__subheader>

        <bem.FormModal__item m='form-source-buttons'>
          {this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW &&
            <button onClick={this.displayStep.bind(this, this.STEPS.PROJECT_DETAILS)}>
              <i className="k-icon-edit" />
              {t('Build from scratch')}
            </button>
          }

          <button onClick={this.displayStep.bind(this, this.STEPS.CHOOSE_TEMPLATE)}>
            <i className="k-icon-template" />
            {t('Use a template')}
          </button>

          <button onClick={this.displayStep.bind(this, this.STEPS.UPLOAD_FILE)}>
            <i className="k-icon-upload" />
            {t('Upload an XLSForm')}
          </button>

          <button onClick={this.displayStep.bind(this, this.STEPS.IMPORT_URL)}>
            <i className="k-icon-link" />
            {t('Import an XLSForm via URL')}
          </button>
        </bem.FormModal__item>
      </bem.FormModal__item>
    );
  }

  renderStepChooseTemplate() {
    return (
      <bem.FormModal__item className='project-settings'>
        <TemplatesList onSelectTemplate={this.onTemplateChange}/>

        <bem.Modal__footer>
          <bem.Modal__footerButton
            m='primary'
            onClick={this.applyTemplate}
            disabled={!this.state.chosenTemplateUid || this.state.isApplyTemplatePending}
            className="mdl-js-button"
          >
            {this.state.applyTemplateButton}
          </bem.Modal__footerButton>

          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepUploadFile() {
    return (
      <bem.FormModal__item className='project-settings'>
        <bem.Modal__subheader>
          {t('Import an XLSForm from your computer.')}
        </bem.Modal__subheader>

        <Dropzone
          onDrop={this.onFileDrop.bind(this)}
          multiple={false}
          className='dropzone'
          activeClassName='dropzone-active'
          rejectClassName='dropzone-reject'
          accept={validFileTypes()}
        >
          <i className="k-icon-xls-file" />
          {t(' Drag and drop the XLSForm file here or click to browse')}
        </Dropzone>

        <bem.Modal__footer>
          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepImportUrl() {
    return (
      <bem.FormModal__item className='project-settings'>
        <div className="intro">
          {t('Enter a valid XLSForm URL in the field below.')}<br/>
          <a href={formViaUrlHelpLink} target="_blank">
            {t('Having issues? See this help article.')}
          </a>
        </div>

        <label htmlFor="url">
          {t('URL')}
        </label>

        <DebounceInput
          type="text"
          id="importUrl"
          debounceTimeout={300}
          value={this.state.importUrl}
          placeholder='https://'
          onChange={event => this.onImportUrlChange(event.target.value)}
        />

        <bem.Modal__footer>
          <bem.Modal__footerButton
            m='primary'
            onClick={this.importFromURL}
            disabled={!this.state.importUrlButtonEnabled}
            className="mdl-js-button"
          >
            {this.state.importUrlButton}
          </bem.Modal__footerButton>

          {this.renderBackButton()}
        </bem.Modal__footer>
      </bem.FormModal__item>
    );
  }

  renderStepProjectDetails() {
    const sectors = session.currentAccount.available_sectors;
    const countries = session.currentAccount.available_countries;

    return (
      <bem.FormModal__form
        onSubmit={this.handleSubmit}
        className='project-settings'
      >
        {(this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW || this.props.context === PROJECT_SETTINGS_CONTEXTS.REPLACE) &&
          <bem.Modal__subheader>
            <i className="k-icon-alert" />
            {t('Enter your project details below. In the next step, you can import an XLSForm (via upload or URL) or design the form from scratch in the Form Builder. ')}
          </bem.Modal__subheader>
        }

        {this.props.context === PROJECT_SETTINGS_CONTEXTS.EXISTING &&
          <bem.Modal__footer>
            <bem.Modal__footerButton
              m='primary'
              onClick={this.handleSubmit}
              className="mdl-js-button"
            >
              {t('Save Changes')}
            </bem.Modal__footerButton>
          </bem.Modal__footer>
        }

        <bem.FormModal__item m='wrapper'>
          <bem.FormModal__item>
            <label htmlFor="name">
              {t('Project Name')}
            </label>
            <input type="text"
              id="name"
              placeholder={t('Enter title of project here')}
              value={this.state.name}
              onChange={this.onNameChange}
            />
          </bem.FormModal__item>

          <bem.FormModal__item>
            <label htmlFor="description">
              {t('Description')}
            </label>
            <TextareaAutosize
              onChange={this.onDescriptionChange}
              value={this.state.description}
              placeholder={t('Enter short description here')}
            />
          </bem.FormModal__item>

          <bem.FormModal__item>
            <label className="long">
              {t('Please specify the country and the sector where this project will be deployed. ')}
              {/*t('This information will be used to help you filter results on the project list page.')*/}
            </label>
          </bem.FormModal__item>

          <bem.FormModal__item m='sector'>
            <label htmlFor="sector">
              {t('Sector')}
            </label>
            <Select
              id="sector"
              value={this.state.sector}
              onChange={this.onSectorChange}
              options={sectors}
            />
          </bem.FormModal__item>

          <bem.FormModal__item  m='country'>
            <label htmlFor="country">
              {t('Country')}
            </label>
            <Select
              id="country"
              value={this.state.country}
              onChange={this.onCountryChange}
              options={countries}
            />
          </bem.FormModal__item>

          <bem.FormModal__item m='metadata-share'>
            <input
              type="checkbox"
              id="share-metadata"
              checked={this.state['share-metadata']}
              onChange={this.onShareMetadataChange}
            />
            <label htmlFor="share-metadata">
              {t('Help KoboToolbox improve this product by sharing the sector and country where this project will be deployed.')}
              &nbsp;
              {t('All the information is submitted anonymously, and will not include the project name or description listed above.')}
            </label>
          </bem.FormModal__item>

          {(this.props.context === PROJECT_SETTINGS_CONTEXTS.NEW || this.props.context === PROJECT_SETTINGS_CONTEXTS.REPLACE) &&
            <bem.Modal__footer>
              <bem.Modal__footerButton
                m='primary'
                onClick={this.handleSubmit}
                className="mdl-js-button"
                disabled={this.state.isSubmitPending}
              >
                {this.state.isSubmitPending ? t('Creating…') : t('Crate Project')}
              </bem.Modal__footerButton>

              {/* Don't allow going back if asset already exist */}
              {!this.state.formAsset &&
                this.renderBackButton()
              }
            </bem.Modal__footer>
          }

          {this.props.context === PROJECT_SETTINGS_CONTEXTS.EXISTING && this.props.iframeUrl &&
            <bem.FormView__cell m='iframe'>
              <iframe src={this.props.iframeUrl} />
            </bem.FormView__cell>
          }
        </bem.FormModal__item>
      </bem.FormModal__form>
    );
  }

  renderBackButton() {
    if (this.state.previousStep) {
      const isBackButtonDisabled = (
        this.state.isSubmitPending ||
        this.state.isApplyTemplatePending ||
        this.state.isImportFromURLPending ||
        this.state.isUploadFilePending
      )
      return (
        <bem.Modal__footerButton
          m='back'
          onClick={this.displayPreviousStep}
          disabled={isBackButtonDisabled}
        >
          {t('Back')}
        </bem.Modal__footerButton>
      )
    } else {
      return false;
    }
  }

  renderLoading() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );
  }

  render() {
    if (!this.state.isSessionLoaded || !this.state.currentStep) {
      return this.renderLoading();
    }

    switch (this.state.currentStep) {
      case this.STEPS.FORM_SOURCE: return this.renderStepFormSource();
      case this.STEPS.CHOOSE_TEMPLATE: return this.renderStepChooseTemplate();
      case this.STEPS.UPLOAD_FILE: return this.renderStepUploadFile();
      case this.STEPS.IMPORT_URL: return this.renderStepImportUrl();
      case this.STEPS.PROJECT_DETAILS: return this.renderStepProjectDetails();
      default:
        throw new Error(`Unknown step: ${this.state.currentStep}!`);
    }
  }
};

reactMixin(ProjectSettings.prototype, Reflux.ListenerMixin);
reactMixin(ProjectSettings.prototype, mixins.droppable);

ProjectSettings.contextTypes = {
  router: PropTypes.object
};

export class ProjectDownloads extends React.Component {
  constructor(props){
{'fraction_non_alphanumeric': 0.12456712161336321, 'fraction_numerical': 0.00040741495212874313, 'mean_word_length': 2.193705781898024, 'pattern_counts': {'":': 0, '<': 207, '<?xml version=': 0, '>': 232, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5610747', 'n_tokens_mistral': 11536, 'n_tokens_neox': 11459, 'n_words': 2117}