<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 classNames from 'classnames';

import TextBox from 'js/components/textBox';

import bem from 'js/bem';
import stores from 'js/stores';
import mixins from 'js/mixins';
import ui from 'js/ui';
import actions from 'js/actions';
import {MODAL_TYPES} from 'js/constants'

import {t, getLangAsObject, getLangString, notify} from 'utils';

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

    let translations;
    if (props.asset) {
      translations = props.asset.content.translations;
    }

    this.state = {
      assetUid: props.assetUid,
      asset: props.asset,
      translations: translations || [],
      showAddLanguageForm: false,
      isUpdatingDefaultLanguage: false,
      renameLanguageIndex: -1
    }
    autoBind(this);
  }
  componentDidMount () {
    this.listenTo(stores.asset, this.onAssetsChange);

    if (!this.state.asset && this.state.assetUid) {
      stores.allAssets.whenLoaded(this.props.assetUid, this.onAssetChange);
    }
  }
  onAssetChange(asset) {
    this.setState({
      asset: asset,
      translations: asset.content.translations || [],
      showAddLanguageForm: false,
      isUpdatingDefaultLanguage: false,
      renameLanguageIndex: -1
    })

    stores.pageState.showModal({
      type: MODAL_TYPES.FORM_LANGUAGES,
      asset: asset
    });
  }
  onAssetsChange(assetsList) {
    let uid;
    if (this.state.asset) {
      uid = this.state.asset.uid;
    } else if (this.state.assetUid) {
      uid = this.state.assetUid;
    }
    this.onAssetChange(assetsList[uid]);
  }
  showAddLanguageForm() {
    this.setState({
      showAddLanguageForm: true
    })
  }
  hideAddLanguageForm() {
    this.setState({
      showAddLanguageForm: false
    })
  }
  toggleRenameLanguageForm(evt) {
    const index = parseInt(evt.currentTarget.dataset.index);
    if (this.state.renameLanguageIndex === index) {
      this.setState({
        renameLanguageIndex: -1
      });
    } else {
      this.setState({
        renameLanguageIndex: index
      });
    }
  }
  launchTranslationTableModal(evt) {
    const index = evt.currentTarget.dataset.index;
    stores.pageState.switchModal({
      type: MODAL_TYPES.FORM_TRANSLATIONS_TABLE,
      asset: this.state.asset,
      langIndex: index
    });
  }
  onLanguageChange(lang, index) {
    let content = this.state.asset.content;
    if (index > -1) {
      content.translations[index] = getLangString(lang);
    } else {
      content.translations.push(getLangString(lang));
      content = this.prepareTranslations(content);
    }

    this.updateAsset(content);
  }
  canAddLanguages() {
    return !(this.state.translations.length === 1 && this.state.translations[0] === null);
  }
  getAllLanguages(thisLanguage) {
    return this.state.translations;
  }
  deleteLanguage(evt) {
    const index = evt.currentTarget.dataset.index;
    const content = this.deleteTranslations(this.state.asset.content, index);
    if (content) {
      content.translations.splice(index, 1);
      const dialog = alertify.dialog('confirm');
      const opts = {
        title: t('Delete language?'),
        message: t('Are you sure you want to delete this language? This action is not reversible.'),
        labels: {ok: t('Delete'), cancel: t('Cancel')},
        onok: () => {
          this.updateAsset(content);
          dialog.destroy();
        },
        oncancel: () => {dialog.destroy()}
      };
      dialog.set(opts).show();
    } else {
      notify('Error: translation index mismatch. Cannot delete language.');
    }
  }
  prepareTranslations(content) {
    let translated = content.translated,
        translationsLength = content.translations.length,
        survey = content.survey,
        choices = content.choices;

    // append null values to translations for each survey row
    for (var i = 0, len = survey.length; i < len; i++) {
      let row = survey[i];
      for (var j = 0, len2 = translated.length; j < len2; j++) {
        var property = translated[j];
        if (row[property] && row[property].length < translationsLength) {
          row[property].push(null);
        }
      }
    }

    // append null values to translations for choices
    if (content.choices && content.choices.length) {
      for (var i = 0, len = choices.length; i < len; i++) {
        if (choices[i].label.length < translationsLength) {
          choices[i].label.push(null);
        }
      }
    }
    return content;
  }
  deleteTranslations(content, langIndex) {
    let translated = content.translated,
        translationsLength = content.translations.length,
        survey = content.survey,
        choices = content.choices;

    for (var i = 0, len = survey.length; i < len; i++) {
      let row = survey[i];
      for (var j = 0, len2 = translated.length; j < len2; j++) {
        var property = translated[j];
        if (row[property]) {
          if (row[property].length === translationsLength) {
            row[property].splice(langIndex, 1);
          } else {
            console.error('Translations index mismatch');
            return false;
          }
        }
      }
    }

    if (content.choices && content.choices.length) {
      for (var i = 0, len = choices.length; i < len; i++) {
        if (choices[i].label) {
          if (choices[i].label.length === translationsLength) {
            choices[i].label.splice(langIndex, 1);
          } else {
            console.error('Translations index mismatch');
            return false;
          }
        }
      }
    }
    return content;
  }
  changeDefaultLanguage(evt) {
    this.setState({isUpdatingDefaultLanguage: true});
    const index = evt.currentTarget.dataset.index;
    const langString = this.state.translations[index];
    const content = this.state.asset.content;
    content.settings.default_language = langString;
    this.updateAsset(content);
  }
  updateAsset (content) {
    actions.resources.updateAsset(
      this.state.asset.uid,
      {content: JSON.stringify(content)}
    );
  }
  renderEmptyMessage() {
    return (
      <bem.FormModal m='translation-settings'>
        <bem.FormModal__item>
          <bem.FormView__cell>
            {t('There is nothing to translate in this form.')}
          </bem.FormView__cell>
        </bem.FormModal__item>
      </bem.FormModal>
    );
  }
  renderLoadingMessage() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );<commit_msg>confirm prompt for default language change<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 classNames from 'classnames';

import TextBox from 'js/components/textBox';

import bem from 'js/bem';
import stores from 'js/stores';
import mixins from 'js/mixins';
import ui from 'js/ui';
import actions from 'js/actions';
import {MODAL_TYPES} from 'js/constants'

import {t, getLangAsObject, getLangString, notify} from 'utils';

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

    let translations;
    if (props.asset) {
      translations = props.asset.content.translations;
    }

    this.state = {
      assetUid: props.assetUid,
      asset: props.asset,
      translations: translations || [],
      showAddLanguageForm: false,
      isUpdatingDefaultLanguage: false,
      renameLanguageIndex: -1
    }
    autoBind(this);
  }
  componentDidMount () {
    this.listenTo(stores.asset, this.onAssetsChange);

    if (!this.state.asset && this.state.assetUid) {
      stores.allAssets.whenLoaded(this.props.assetUid, this.onAssetChange);
    }
  }
  onAssetChange(asset) {
    this.setState({
      asset: asset,
      translations: asset.content.translations || [],
      showAddLanguageForm: false,
      isUpdatingDefaultLanguage: false,
      renameLanguageIndex: -1
    })

    stores.pageState.showModal({
      type: MODAL_TYPES.FORM_LANGUAGES,
      asset: asset
    });
  }
  onAssetsChange(assetsList) {
    let uid;
    if (this.state.asset) {
      uid = this.state.asset.uid;
    } else if (this.state.assetUid) {
      uid = this.state.assetUid;
    }
    this.onAssetChange(assetsList[uid]);
  }
  showAddLanguageForm() {
    this.setState({
      showAddLanguageForm: true
    })
  }
  hideAddLanguageForm() {
    this.setState({
      showAddLanguageForm: false
    })
  }
  toggleRenameLanguageForm(evt) {
    const index = parseInt(evt.currentTarget.dataset.index);
    if (this.state.renameLanguageIndex === index) {
      this.setState({
        renameLanguageIndex: -1
      });
    } else {
      this.setState({
        renameLanguageIndex: index
      });
    }
  }
  launchTranslationTableModal(evt) {
    const index = evt.currentTarget.dataset.index;
    stores.pageState.switchModal({
      type: MODAL_TYPES.FORM_TRANSLATIONS_TABLE,
      asset: this.state.asset,
      langIndex: index
    });
  }
  onLanguageChange(lang, index) {
    let content = this.state.asset.content;
    if (index > -1) {
      content.translations[index] = getLangString(lang);
    } else {
      content.translations.push(getLangString(lang));
      content = this.prepareTranslations(content);
    }

    this.updateAsset(content);
  }
  canAddLanguages() {
    return !(this.state.translations.length === 1 && this.state.translations[0] === null);
  }
  getAllLanguages(thisLanguage) {
    return this.state.translations;
  }
  deleteLanguage(evt) {
    const index = evt.currentTarget.dataset.index;
    const content = this.deleteTranslations(this.state.asset.content, index);
    if (content) {
      content.translations.splice(index, 1);
      const dialog = alertify.dialog('confirm');
      const opts = {
        title: t('Delete language?'),
        message: t('Are you sure you want to delete this language? This action is not reversible.'),
        labels: {ok: t('Delete'), cancel: t('Cancel')},
        onok: () => {
          this.updateAsset(content);
          dialog.destroy();
        },
        oncancel: () => {dialog.destroy()}
      };
      dialog.set(opts).show();
    } else {
      notify('Error: translation index mismatch. Cannot delete language.');
    }
  }
  prepareTranslations(content) {
    let translated = content.translated,
        translationsLength = content.translations.length,
        survey = content.survey,
        choices = content.choices;

    // append null values to translations for each survey row
    for (var i = 0, len = survey.length; i < len; i++) {
      let row = survey[i];
      for (var j = 0, len2 = translated.length; j < len2; j++) {
        var property = translated[j];
        if (row[property] && row[property].length < translationsLength) {
          row[property].push(null);
        }
      }
    }

    // append null values to translations for choices
    if (content.choices && content.choices.length) {
      for (var i = 0, len = choices.length; i < len; i++) {
        if (choices[i].label.length < translationsLength) {
          choices[i].label.push(null);
        }
      }
    }
    return content;
  }
  deleteTranslations(content, langIndex) {
    let translated = content.translated,
        translationsLength = content.translations.length,
        survey = content.survey,
        choices = content.choices;

    for (var i = 0, len = survey.length; i < len; i++) {
      let row = survey[i];
      for (var j = 0, len2 = translated.length; j < len2; j++) {
        var property = translated[j];
        if (row[property]) {
          if (row[property].length === translationsLength) {
            row[property].splice(langIndex, 1);
          } else {
            console.error('Translations index mismatch');
            return false;
          }
        }
      }
    }

    if (content.choices && content.choices.length) {
      for (var i = 0, len = choices.length; i < len; i++) {
        if (choices[i].label) {
          if (choices[i].label.length === translationsLength) {
            choices[i].label.splice(langIndex, 1);
          } else {
            console.error('Translations index mismatch');
            return false;
          }
        }
      }
    }
    return content;
  }
  changeDefaultLanguage(evt) {
    const index = evt.currentTarget.dataset.index;
    const langString = this.state.translations[index];

    const dialog = alertify.dialog('confirm');
    const opts = {
      title: t('Change default language?'),
      message: t('Are you sure you would like to set ##lang## as the default language for this form?').replace('##lang##', langString),
      labels: {ok: t('Confirm'), cancel: t('Cancel')},
      onok: () => {
        this.setState({isUpdatingDefaultLanguage: true});
        const content = this.state.asset.content;
        content.settings.default_language = langString;
        this.updateAsset(content);
        dialog.destroy();
      },
      oncancel: () => {dialog.destroy()}
    };
    dialog.set(opts).show();
  }
  updateAsset (content) {
    actions.resources.updateAsset(
      this.state.asset.uid,
      {content: JSON.stringify(content)}
    );
  }
  renderEmptyMessage() {
    return (
      <bem.FormModal m='translation-settings'>
        <bem.FormModal__item>
          <bem.FormView__cell>
            {t('There is nothing to translate in this form.')}
          </bem.FormView__cell>
        </bem.FormModal__item>
      </bem.FormModal>
    );
  }
  renderLoadingMessage() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );
{'fraction_non_alphanumeric': 0.12783989744320204, 'fraction_numerical': 0.0027063599458728013, 'mean_word_length': 2.562151192288179, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 33, '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': '526719', 'n_tokens_mistral': 4277, 'n_tokens_neox': 4260, 'n_words': 916}