import React, { useCallback, Component } from 'react';
import ReactDOM from 'react-dom';
import Header from './parts/Header/Header.js';
import AddButton from './parts/AddButton/AddButton.js';
import ComboboxSelect from './parts/ComboboxSelect/ComboboxSelect.js';
import ConflictBlock from './parts/ConflictBlock/ConflictBlock.js';
import EditTableBtn from './parts/EditTableBtn/EditTableBtn.js';
import EditFieldBtn from './parts/EditFieldBtn/EditFieldBtn.js';
import EditPartBtn from './parts/EditPartBtn/EditPartBtn.js';
import Expert from './parts/Expert/Expert.js';
import EditMatchBtn from './parts/EditMatchBtn/EditMatchBtn.js';
import EditPartFieldsBtn from './parts/EditPartFieldsBtn/EditPartFieldsBtn.js';
import SubstitutionBlock from './parts/SubstitutionBlock/SubstitutionBlock.js';
import Preloader from './parts/Preloader/Preloader.js';
import Dragula from 'react-dragula';
import { Accordion, AccordionItem } from 'react-light-accordion';

//styles

const status1 = {
  display: 'block',
  marginBottom: '7px',
  fontSize: '13px',
  fontWeight: 'bold',
  lineHeight: '1.7em',
  position: 'relative',
  padding: '10px 15px',
  borderRadius: '7px',
  background: '#d9ffb2',
}

const status2 = {
  display: 'block',
  marginBottom: '7px',
  fontSize: '13px',
  fontWeight: 'bold',
  lineHeight: '1.7em',
  position: 'relative',
  padding: '10px 15px',
  borderRadius: '7px',
  background: '#ffc9bb',
}

const status3 = {
  display: 'block',
  marginBottom: '7px',
  fontSize: '13px',
  fontWeight: 'bold',
  lineHeight: '1.7em',
  position: 'relative',
  padding: '10px 15px',
  borderRadius: '7px',
  background: '#fffdbb',
};

const activeStyle = { 'background': '#fff6ad' };

var configIds = [];
var savedCbTabs = [];
var saved1cTabs = [];
var drakeTables;
var drakeMatchingBlocks;
const all1CTables = tables1C;
const allCbTables = result.allCbTables;
const allCbSubtables = result.allCbSubTables;
const all1CTabParts = tables1CTabparts;

class Config extends Component {
  constructor(props) {
    super(props);
    this.state = {
      menu: 2, // 1 - конфигурация, 2 - общие настройки, 3 - разрешение конфликтов
      configTables: data, // Объект текущих настроек конфигурации
      allTables1c: all1CTables, // Все таблицы 1С
      allTablesCb: allCbTables, // Все таблицы КБ
      allCbSubtables: allCbSubtables, // Все подтаблицы КБ
      all1CTabParts: all1CTabParts, // Все данные о таблицах 1С, их ТЧ и полях
      fieldsGroup: [], // Массив полей для вывода в блоке "Поля"
      curYellowTable: null,
      oldTableCbName: '', // Старое значение таблицы КБ
      oldTable1cName: '', // Старое значение таблицы 1с
      curCbTableName: '', // Имя текущей таблицы КБ
      cur1cTableName: '', // Имя текущей таблицы 1С
      curCbFieldName: '', // Имя текущего поля КБ
      cur1cFieldName: '', // Имя текущего поля 1С
      editId: null, // id редактируемого поля для таблиц
      editFieldId: null, // id редактируемого поля для Полей
      editPartId: null, // id редактируемой подтаблицы
      editPartFieldId: null, // id редактируемого поля подтаблицы
      editMatchingId: null,
      isEditMode: false, // открыто редактирование или нет (таблицы)
      isEditFieldMode: false, // открыто редактирование или нет (поля таблиц)
      isEditPartMode: false, // открыто редактирование или нет (табличная часть)
      isEditPartFieldsMode: false, // открыто редактирование или нет (поля табличной части)
      isEditMatchingFieldsMode: false, // открыто редактирование или нет (поля правил сопоставления)
      nextTable: null, // Следующая таблица
      nextField: null, // Следующее поле
      curTableId: null, // Текущий id таблицы КБ
      curTable1c: null, // Текущее название таблицы 1С
      curField1c: null, // Текущее название поля 1С
      curFieldCb: null, // Текущий id поля КБ
      openedSettings: false, // Текущее отображение блока с настройками полей
      openedTableRow: null, // id таблицы КБ, для которой открыт блок с настройками полей
      openedFieldRow: null, // id поля КБ, которое редактируется в данный момент
      openedPartRow: null, // id подтаблицы КБ, которое редактируется в данный момент
      openedPartFieldRow: null, // id подтаблицы КБ, которое редактируется в данный момент
      tabPartsSettings: false, // Отображение блока настроек ТЧ - подтаблица
      tabPartsConfig: {}, // Набор всех полей для текущих настроек ТЧ - подтаблица
      partFieldsGroup: [], // Массив полей для вывода в блоке "Поля табличная часть - подтаблица"
      nextTabPart: null, // Следующая строка для блока ТЧ - подтаблица
      nextTabPartFields: null, // Следующая строка для блока полей ТЧ - подтаблица
      tab1cPartsArray: [], // Массив текущих табличных частей 1С
      tabCbPartsArray: [], // Массив текущих подтаблиц КБ
      cur1cTabPart: '', // Имя текущей ТЧ 1С
      curCbTabPart: '', // id текущей подтаблицы КБ
      cur1cTabPartName: '', // Имя текущей подтаблицы КБ
      curCbTabPartName: '', // Имя текущей подтаблицы КБ
      cur1cTabPartField: '', // Имя текущего поля ТЧ 1С
      curCbTabPartField: '', // id текущего поля подтаблицы КБ
      cur1cTabPartFieldName: '', // Имя текущего поля ТЧ 1С
      curCbTabPartFieldName: '', // Имя текущего поля подтаблицы КБ
      cur1cMatchingFieldName: '', // Имя текущего поля сопоставления
      curMatchingBlock: '', // Имя текущего поля сопоставления
      tabPartFieldsSettings: false,
      curActivePartRow: null,
      openedPartSettings: false,
      openedPartFieldsSettings: false,
      matchingSettingsOpened: false,
      matchingDisplaySettings: {
        tableMinWidth: '750px'
      },
      nextMatchingField: null,
      bond: 0,
      strict: 0,
      tips_for_admin: result.tips_for_admin,
      conflicts: result.conflicts,
      struct_date: result.struct_date,
      struct: result.struct,
      edited_filters: {},
      show_substitution_block: false,
      substitution_data: null,
      substitution_table: null,
      substitution_field: null,
      substitution_field_cb: null,
      substitution_subfield: null,
      substitution_subfield_cb: null,
      show_expert: false,
    };

    this.setBond = this.setBond.bind(this);
    this.setStrict = this.setStrict.bind(this);
    this.changeTipsForAdmin = this.changeTipsForAdmin.bind(this);
    this.transformConfig = this.transformConfig.bind(this);
  }

  setBond(e) {
    this.setState({ bond: e.target.value });
  }

  setStrict(e) {
    this.setState({ strict: e.target.value });
  }

  changeTipsForAdmin(e) {
    this.setState({ tips_for_admin: e.target.value });
  }

  componentWillMount = () => {
    if (result.WRITE_CB == 1 && result.WRITE_1C == 1) {
      this.setState({ bond: 3 });
    }
    else if (result.WRITE_CB == 1 && result.WRITE_1C == 0) {
      this.setState({ bond: 2 });
    }
    else if (result.WRITE_CB == 0 && result.WRITE_1C == 1) {
      this.setState({ bond: 1 });
    }
    if(result.strict_mode == 1){
      this.setState({ strict: 1 });
    }

    this.createConfigIds();
    this.sortEmptyConfigFields();
  }

  componentDidMount = () => {
    this.createNexTableRow(this.state.configTables);

    if(result.is_conflicts) {
      $('#conf-conflict').trigger('click');
    }
    else if(result.is_config) {
      $('#conf-config').trigger('click');
    }
  }

  generateToken = (length) => {
    //edit the token allowed characters
    var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
    var b = [];
    for (var i = 0; i < length; i++) {
      var j = (Math.random() * (a.length - 1)).toFixed(0);
      b[i] = a[j];
    }
    return b.join('');
  }

  refreshToken = () => {
    let token = this.generateToken(64);
    $('input[name="token"]').val(token);
  }

  romanize = (num) => {
    const lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
    let roman = '',
        i;
    for ( i in lookup ) {
      while ( num >= lookup[i] ) {
        roman += i;
        num -= lookup[i];
      }
    }
    return roman;
  }

  getStruct = () => {
    $('input[name="get_struct"]').val(1);
    $('#save_button').trigger('click');
  }

  transformConfig = () => {
      const types = ["Строка", "Булево", "Дата", "Число", "ХранилищеЗначения"];
      let conf_tables = this.state.configTables;
      let config_transformed = {};
      for (let table in conf_tables) {
        let _fields = {
          'ПометкаУдаления': {
            type: "Булево",
            field_cb: "status",
            mode: conf_tables[table].mode,
          },
        };
        if(conf_tables[table].fields.length > 0){
          for (let _field of conf_tables[table].fields) {
            _fields[_field.name] = {
              type: this.state.struct[table][_field.name],
              field_cb: 'f' + _field.linkFields.id,
              mode: _field.mode,
              substitutions: _field.substitutions,
            };
            if(Array.isArray(_fields[_field.name].type)){
              _fields[_field.name].type = 'Строка';
            }
            else if(!types.includes(_fields[_field.name].type)){
              _fields[_field.name]['reftable_1c'] = _fields[_field.name].type;
              _fields[_field.name].type = 'ref';
            }
          }
        }
        const _tabparts = {};
        if(conf_tables[table].tablePart){
          for (let tabpart in conf_tables[table].tablePart){
            let _tabpart_fields = {};
            for (let tabpart_field of conf_tables[table].tablePart[tabpart].fields){
              _tabpart_fields[tabpart_field.name] = {
                type: this.state.struct[table][tabpart][tabpart_field.name],
                field_cb: 'f' + tabpart_field.link.id,
                substitutions: tabpart_field.substitutions,
                mode: tabpart_field.mode,
              }
              if(Array.isArray(_tabpart_fields[tabpart_field.name].type)){
                _tabpart_fields[tabpart_field.name].type = 'Строка';
              }
              else if(!types.includes(_tabpart_fields[tabpart_field.name].type)){
                _tabpart_fields[tabpart_field.name]['reftable_1c'] = _tabpart_fields[tabpart_field.name].type;
                _tabpart_fields[tabpart_field.name].type = 'ref';
              }
            }
            _tabparts[tabpart] = {
              type: 'tabpart',
              table_cb: conf_tables[table].tablePart[tabpart].id,
              fieldmap: _tabpart_fields,
              mode: _fields[tabpart].mode
            }
          }
        }

        let matchingSettings = [];
        if(conf_tables[table].matching){
          for(let block in conf_tables[table].matching) {
            let _block = {};

            for(let table1c in conf_tables[table].matching[block]){
              if(conf_tables[table].matching[block][table1c].name == 'ID'){
                _block[table1c] = 'id';
              }
              else if(conf_tables[table].matching[block][table1c].name == 'Кто добавил'){
                _block[table1c] = 'user_id';
              }
              else if(conf_tables[table].matching[block][table1c].name == 'Время добавления'){
                _block[table1c] = 'add_time';
              }
              else {
                _block[table1c] = 'f' + conf_tables[table].matching[block][table1c].id;
              }

            }

            matchingSettings.push(_block);
          }

        }
        _fields = Object.assign(_fields, _tabparts);
        config_transformed[table] = {
          table_cb: parseInt(conf_tables[table].id),
          fieldmap: _fields,
          matching: matchingSettings,
          filter: conf_tables[table].filter,
          mode: conf_tables[table].mode,
        };
      }

      return config_transformed;
  }

  submitForm = (e) => {
    // e.preventDefault();

    if (this.state.menu == 1) {
      if(this.state.editId != null || this.state.editFieldId != null || this.state.editMatchingId != null || this.state.editPartFieldId != null){
        alert('Сначала закончите редактирование!');
        e.preventDefault();
        return;
      }

      $('textarea[name="configJSON"]').val(JSON.stringify(this.transformConfig(), null, 4));
    }
  };

  openExpertWindow = () => {
    this.setState({'show_expert': true });
  };

  closeExpertWindow = () => {
    this.setState({'show_expert': false });
  };

  openSubstitutionWindow = (field1c, fieldCb, subfield1C = null, subfieldCb = null) => (e) => {
    const config = this.state.configTables;
    const table1cName = this.state.cur1cTableName;
    if(subfield1C == null){
      for(let key in config[table1cName].fields){
        if(config[table1cName].fields[key].name == field1c){
            this.setState({
                substitution_table: table1cName,
                substitution_field: field1c,
                substitution_subfield: subfield1C,
                substitution_field_cb: fieldCb,
                substitution_data: config[table1cName].fields[key].substitutions,
                show_substitution_block: true,
            });
            break;
        }
      }
    }
    else {
      for(let field of config[table1cName].tablePart[field1c].fields){
        if(field.name == subfield1C){
            this.setState({
                substitution_table: table1cName,
                substitution_field: field1c,
                substitution_subfield: subfield1C,
                substitution_field_cb: fieldCb,
                substitution_subfield_cb: subfieldCb,
                substitution_data: field.substitutions,
                show_substitution_block: true,
            });
            break;
        }
      }
    }
  }

  closeSubstitutionWindow = () => (e) => {
    this.setState({
        substitution_table: null,
        substitution_field: null,
        substitution_subfield: null,
        substitution_field_cb: null,
        substitution_subfield_cb: null,
        substitution_data: null,
        show_substitution_block: false,
    });
  }

  saveSubstitution = (data, table1c, field1c, subtable1c = '') => (e) => {
    e.preventDefault();

    let config = this.state.configTables;
    if(subtable1c == null || subtable1c.length == 0){
      for(let key in config[table1c].fields){
        if(config[table1c].fields[key].name == field1c){
          config[table1c].fields[key].substitutions = data;
          break;
        }
      }
    }
    else {
      for(let field of config[table1c].tablePart[field1c].fields){
        if(field.name == subtable1c){
          field.substitutions = data;
          break;
        }
      }
    }

    this.setState({
        configTables: config,
        substitution_table: null,
        substitution_field: null,
        substitution_subfield: null,
        substitution_field_cb: null,
        substitution_subfield_cb: null,
        substitution_data: null,
        show_substitution_block: false,
    });
  }

  createConfigIds = () => {
    const conf = this.state.configTables;
    let ids = [];

    for (let key in conf) {
      const obj = {};

      obj[[conf[key]['id']]] = key;
      ids.push(obj);
      savedCbTabs.push(conf[key]['id']); // Массив id всех выбранных таблиц КБ в конфигурации
      saved1cTabs.push(key); // Массив имен всех выбранных таблиц 1с в конфигурации
    }

    configIds = ids;
  }

  // Убираем из списков таблиц 1С и КБ те таблицы, которые уже есть в конфиге
  sortEmptyConfigFields = () => {
    const config = this.state.configTables;
    const all1c = this.state.allTables1c;
    const allCb = this.state.allTablesCb;
    let newCbData = {};

    //создаём клон данных 1С, иначе по ссылке будет удаляться из исходного объекта.
    let new1cData = {};

    for (let key in all1c) {
      new1cData[key] = all1c[key];
    }

    let cbIds = [];
    let names1c = [];

    for (let elem of configIds) {
      cbIds.push(Object.keys(elem)[0]);
      names1c.push(Object.values(elem)[0]);
    }

    for (let tab in allCb) {
      if (cbIds.indexOf(tab) === -1) {
        newCbData[tab] = allCb[tab];
      }
    }

    for (let tab1c in all1c) {
      for (let tab in config) {
        if (tab1c === tab) delete new1cData[tab1c];
      }
    }

    this.setState({ allTablesCb: newCbData, allTables1c: new1cData });
  }

  // Создание новой строки для основного блока "Таблицы"
  createNexTableRow = (configTables) => {
    const conf = configTables;
    const allCbTabs = this.state.allTablesCb;
    const allCbId = [];
    const all1cTabs = this.state.allTables1c;
    const all1cNames = [];
    const allConfCbTabs = [];
    const allConf1cTabs = [];
    let sortedCbTabs = [];
    let sorted1cTabs = [];

    for (let keyC in conf) {
      allConf1cTabs.push(keyC);
      allConfCbTabs.push(conf[keyC]['id']);
    }

    for (let key1 in all1cTabs) {
      all1cNames.push(key1);
    }

    for (let keyCb in allCbTabs) {
      allCbId.push(keyCb);
    }

    for (let i = 0; i < all1cNames.length; i++) {
      if (allConf1cTabs.indexOf(all1cNames[i]) === -1) sorted1cTabs.push(all1cNames[i]);
    }

    for (let j = 0; j < allCbId.length; j++) {
      if (allConfCbTabs.indexOf(allCbId[j]) === -1) sortedCbTabs.push(allCbId[j]);
    }

    let nextCb = sortedCbTabs.shift();
    let next1c = sorted1cTabs.shift();
    let nextTableObject = {};

    if (nextCb && next1c) {
      nextTableObject[next1c] = { id: nextCb, name: allCbTabs[nextCb]['name'], fields: [], tablePart: [], mode: this.state.bond }
    };

    if (Object.keys(nextTableObject).length !== 0 && Object.values(nextTableObject).length !== 0)
      return this.setState({ nextTable: nextTableObject });
    else
      return this.setState({ nextTable: null });
  }

  // Создание новой строки для блока "Поля" (для основных таблиц)
  createNextFieldRow = (curId, curTable) => {

    if(this.state.struct == void 0) return (this.setState({ nextField: null }));

    const config = this.state.configTables;
    let curFields = config[curTable]['fields'];
    let tabPartsConfig = this.state.tabPartsConfig;

    let allCbFields = [];
    let all1cFields = [];
    let allCbSubTables = [];
    let all1cTabparts = [];

    let curCbFields = [];
    let cur1cFields = [];
    let curCbSubtables = [];

    let sortedCbFields = [];
    let sorted1cFields = [];
    let sortedCbSubtables = [];
    let sorted1cTabparts = [];

    all1cFields = all1CTables[curTable];
    allCbFields = allCbTables[curId]['fields'];
    allCbSubTables = result.allCbSubTables[curId].subtables;
    for(let tabpart in tables1CTabparts[curTable]){
      all1cTabparts.push(tabpart);
    }
    for(let tabpart of all1cTabparts){
      if(!tabPartsConfig.hasOwnProperty(tabpart)) sorted1cTabparts.push(tabpart);
    }

    for(let tabpart in tabPartsConfig) curCbSubtables.push(tabPartsConfig[tabpart].id);

    for(let subtable of allCbSubTables){
      if(curCbSubtables.indexOf(subtable.id) === -1) sortedCbSubtables.push(subtable);
    }

    for (let i = 0; i < curFields.length; i++) {
      cur1cFields.push(curFields[i]['name']);
      curCbFields.push(curFields[i]['linkFields']['id']);
    }

    for (let j = 0; j < allCbFields.length; j++) {
      if (curCbFields.indexOf(allCbFields[j]['id']) === -1) sortedCbFields.push(allCbFields[j]);
    }

    for (let k = 0; k < all1cFields.length; k++) {
      if (cur1cFields.indexOf(all1cFields[k]) === -1) sorted1cFields.push(all1cFields[k]);
    }

    let nextCbField = sortedCbFields.shift();
    let next1cField = sorted1cFields.shift();

    let nextCbSubtable = sortedCbSubtables.shift();
    let next1cTabpart = sorted1cTabparts.shift();

    if (nextCbField && next1cField) return (this.setState({ nextField: { name: next1cField, linkFields: nextCbField, type: 'field', mode: this.state.bond } }));
    else if(nextCbSubtable && next1cTabpart) return (this.setState({ nextField: { name: next1cTabpart, linkFields: nextCbSubtable, type: 'tabpart', mode: this.state.bond } }));
    else return (this.setState({ nextField: null }));
  }

  // Добавление новой строки в блок "Таблицы конфиуграции"
  addNextTable = (e) => {
    e.preventDefault();

    const configTables = this.state.configTables;
    const nextTable = this.state.nextTable;
    const addNewRowMsg = this.state.struct ? 'Вы больше не можете добавлять таблицы для синхронизации!' : 'Вы больше не можете добавлять таблицы, так как отсутствует структура 1С!';

    if (nextTable) {
      const tableId = Object.values(nextTable)[0]['id'];
      const tableCbName = Object.values(nextTable)[0]['name'];
      const newConfig = Object.assign(configTables, nextTable);
      const table1cName = Object.keys(nextTable)[0];
      const part1cArray = this.state.all1CTabParts[table1cName] ? Object.keys(this.state.all1CTabParts[table1cName]) : [];
      const partCbArray = this.state.allCbSubtables[tableId] ? this.state.allCbSubtables[tableId]['subtables'] : [];

      let confFields = newConfig[table1cName]['fields'];
      let partConfig = newConfig[table1cName].hasOwnProperty('tablePart') ? newConfig[table1cName]['tablePart'] : {};
      let partsConfig = {};
      let partSettings = false;
      let partFieldsSettings = false;
      let partFields = [];

      if (Object.keys(partConfig).length == 0) {
        newConfig[table1cName]['tablePart'] = {};
      }

      this.setState({
                      matchingSettingsOpened: false,
                      configTables: newConfig,
                      curTableId: tableId,
                      tabPartsSettings: false,
                      cur1cTableName: table1cName,
                      curCbTableName: tableCbName,
                      openedSettings: false,
                      tab1cPartsArray: part1cArray,
                      tabCbPartsArray: partCbArray,
                      partFieldsGroup: [],
                      tabPartsConfig: {},
                      tabPartFieldsSettings: false,
                      editId: tableId,
                      openedTableRow: tableId,
                      curTable1c: table1cName,
                      isEditMode: true,
                      fieldsGroup: confFields,
                      tabPartsSettings: partSettings,
                      tabPartFieldsSettings: partFieldsSettings,
                      tabPartsConfig: partsConfig,
                      partFieldsGroup: partFields,
                    });
      this.createNexTableRow(newConfig);
      this.createNextFieldRow(tableId, table1cName);
    } else alert(addNewRowMsg);
  }

  // Доавбление новой строки в блок "Поля" (для основных таблиц)
  addNextField = (e) => {
    e.preventDefault();
    const configTables = this.state.configTables;
    const nextField = this.state.nextField;
    const curTabId = this.state.curTableId;
    const curTab1c = this.state.curTable1c;
    const addNewRowMsg = this.state.struct ? 'Вы больше не можете добавлять поля для данных таблиц!' : 'Вы больше не можете добавлять поля для данных таблиц, так как отсутствует структура 1С!';
    let tabPartsConfig = this.state.tabPartsConfig;

    this.setState({
      cur1cTabPart: '',
      curCbTabPart: '',
      curCbTabPartName: '',
      tabPartsConfig: [],
      tabPartFieldsSettings: false,
      partFieldsGroup: [],
      cur1cFieldName: '',
    });

    if(this.state.isEditFieldMode){
      alert("Сначала закончите редактирование!");
      return;
    }

    if (nextField) {
      const curId = nextField['linkFields']['id'];

      configTables[curTab1c]['fields'].push(nextField);
      if(nextField.type != 'field'){
        tabPartsConfig[nextField.name] = {
          fields: [],
          matching: {},
          id: nextField['linkFields']['id'],
          name: nextField['linkFields']['name'],
        }
      }
      this.setState({ configTables: configTables,
                      curCbFieldName: nextField['linkFields']['name'],
                      cur1cFieldName: nextField['name'],
                      openedFieldRow: curId,
                      curFieldCb: curId,
                      editFieldId: curId,
                      openedPartSettings: true,
                      isEditFieldMode: true,
                      curField1c: nextField['name'],
                      cur1cFieldName: nextField['name'],
                      curCbFieldName: nextField['linkFields']['name'],
                      tabPartsConfig,
                    });

      this.createNextFieldRow(curTabId, curTab1c);

    } else {
      alert(addNewRowMsg);
    }
  }

  // Блок конфигурации
  configPageContent() {
    const configTables = this.state.configTables;
    const isNotEmpty = Object.keys(configTables).length > 0;

    return (
      <>
        <tr className="noDrag">
          <td align='center' colSpan='2' className='config-title'>
            {configTables ? 'Таблицы конфигурации' : 'Новая настройка конфигурации'}
            <img
              src="./images/settings_b.gif"
              alt="Режим эксперта"
              title="Режим эксперта"
              onClick={this.openExpertWindow}
              className="open_expert_window" />
          </td>
        </tr>
        {configTables && isNotEmpty ?
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>{lang.Tables}<span className='help_bt' h_id='config_1c_tables'></span>:</td>
            <td align='left'>
            </td>
          </tr>) :
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>{lang.Tables}<span className='help_bt' h_id='config_1c_tables'></span>:</td>
            <td align='left'>
              <AddButton type='table' addNewRow={this.state.isEditMode ? this.editModeAttention() : this.addNextTable} />
            </td>
          </tr>)
        }
        {configTables && isNotEmpty ?
          this.createTablesRow() :
          ''
        }
        {configTables && isNotEmpty ?
        (<tr>
          <td></td>
          <td><AddButton type='table' addNewRow={this.state.isEditMode ? this.editModeAttention() : this.addNextTable} /></td>
        </tr>) : ''}
      </>
    );
  }

  dragulaDecoratorTables = (componentBackingInstance) => {
    if (componentBackingInstance) {
      let options = {
        moves: function (el, source, handle, sibling) {
          if($(el).hasClass("noDrag")){
            return false;
          }
          return true; // elements are always draggable by default
        },
        accepts: function (el, target, source, sibling) {
          if($(sibling).hasClass("noDrag")){
            return false;
          }
          return true; // elements can be dropped in any of the `containers` by default
        },
        direction: 'vertical',   // set the element that gets mirror elements appended
      };
      drakeTables = Dragula([componentBackingInstance], options);
      drakeTables.on('drop', (el, target) => {
        let conf_tables = this.state.configTables;
        let conf_tables_new = {};
        $('[id ^= "table_"]').each((i, el) => {
          let id_table = $(el).attr('id').slice(6);
          for(let table_1c in conf_tables){
            if(conf_tables[table_1c].id == id_table){
              conf_tables_new[table_1c] = conf_tables[table_1c];
            }
          }
        });
        this.setState({ configTables: conf_tables_new });
      });
    }
  };

  dragulaDecoratorMatchingBlocks = (componentBackingInstance) => {
    if (componentBackingInstance) {
      let options = {
        moves: function (el, source, handle, sibling) {
          if($(el).hasClass("noDrag")){
            return false;
          }
          return true; // elements are always draggable by default
        },
        accepts: function (el, target, source, sibling) {
          if($(sibling).hasClass("noDrag")){
            return false;
          }
          return true; // elements can be dropped in any of the `containers` by default
        },
        direction: 'vertical',   // set the element that gets mirror elements appended
      };
      drakeMatchingBlocks = Dragula([componentBackingInstance], options);
      drakeMatchingBlocks.on('drop', (el, target) => {
        let conf_tables = this.state.configTables;
        let cur1CTable = this.state.cur1cTableName;
        let matching = conf_tables[cur1CTable].matching;
        let matching_new = {};
        $('[id ^= "matching_block_"]').each((i, el) => {
          let block_id = $(el).attr('id').slice(15);
          if(!$(el).hasClass('gu-mirror')){
            matching_new[block_id] = matching[block_id];
          }
        });
        conf_tables[cur1CTable].matching = matching_new;
        this.setState({ configTables: conf_tables });
      });
    }
  };


  // Переход в меню "Конфигурация" при нажатии на ошибку в блоке "Ошибки"
  editConfigForErrorField = (tableName, fieldName) => (e) => {
    e.preventDefault();
    if(tableName == null && fieldName == null) return;
    const config = this.state.configTables;
    const fieldsConfig = this.state.configTables[tableName]['fields'];

    if (config[tableName]) {
      let stateConds = {
        cur1cTableName: tableName,
        curTable1c: tableName,
        curCbTableName: config[tableName]['name'],
        curTableId: config[tableName]['id'],
        openedSettings: true,
        tabPartsConfig: config[tableName]['tablePart'],
      };

      if (fieldName != null) {
        stateConds['cur1cFieldName'] = fieldName;
        stateConds['cur1cTabPart'] = fieldName;
        stateConds['cur1cTabPartName'] = fieldName;
        for(let field of fieldsConfig){
            if(field.name == fieldName){
                stateConds['curCbTabPart'] = field.linkFields.id;
                stateConds['curCbTabPartName'] = field.linkFields.name;
                stateConds['tabPartFieldsSettings'] = true;
                stateConds['partFieldsGroup'] = this.state.configTables[tableName].tablePart[fieldName].fields;
            }
        }
      }

        this.setState({
            ...stateConds,
            fieldsGroup: fieldsConfig,
        });

        setTimeout(() => {
            if (fieldName != null) this.createNextPartFieldRow();

            this.createNexTableRow(config);
            this.createNextFieldRow(config[tableName]['id'], tableName);
        }, 10);
    }

    $('#conf-config').trigger('click');
  }

  // Удаление строки с конфликтом
  deleteConflict = (index) => (e) => {
    e.preventDefault();

    $('input[name="deleteConf"]').val(index);
    $("#del-save-btn").trigger('click');
  }

  createConflictRow() {
    let allConflicts = this.state.conflicts;

    return (
      allConflicts.map((item, index) => {
        let table = item.params ? item.params.table : null;
        let field = item.params ? (item.params.tabpart_field ? item.params.field : null) : null;

        return (
            <Accordion atomic={true}>
                <ConflictBlock
                    index={index}
                    item={item}
                    deleteError={this.deleteConflict(index)}
                    openField={this.editConfigForErrorField(table, field)}
                />
            </Accordion>
        );
      })
    );
  }

  // Блок разрешения конфликтов
  conflictPageContent() {
    let allConflicts = this.state.conflicts;

    return (
      <>
        <tr className="noDrag">
          <td align='center' colSpan='2' className='config-title'>Разрешение ошибок</td>
        </tr>
        <tr className="noDrag"></tr>
        {allConflicts != null ? this.createConflictRow() :
          (
            <tr className="noDrag">
              <td align='center'>Список ошибок пуст</td>
            </tr>
          )}
      </>
    )
  }

  // Удаление строки из раздела таблиц
  deleteTableRow = (tableId, table1c) => (e) => {
    e.preventDefault();

    if(this.state.isEditMatchingFieldsMode || this.state.isEditFieldMode || this.state.isEditMode || this.state.isEditPartFieldsMode){
      alert('Сначала закончите редактирование!');
      return;
    }

    const config = this.state.configTables;
    const curTableId = this.state.curTableId;
    const delRow = config[table1c];
    let nextTable = {};
    let all1CTables = this.state.allTables1c;
    let allCbTables = this.state.allTablesCb;
    let newAll1CTables = {};

    if(tableId == this.state.editId && this.state.isEditMode){
      this.setState({
        isEditMode: false,
        editId: null,
      });
    }

    //nextTable[table1c] = { id: delRow['id'], name: delRow['name'], fields: [] };
    if(!all1CTables.hasOwnProperty(table1c)){
      newAll1CTables[table1c] = tables1C[table1c];
      all1CTables = Object.assign(newAll1CTables, all1CTables);
    }
    if(!allCbTables.hasOwnProperty(delRow['id'])){
      allCbTables[delRow['id']] = result.allCbTables[delRow['id']];
    }
    delete config[table1c];
    savedCbTabs.splice(savedCbTabs.indexOf(delRow['id']), 1);
    saved1cTabs.splice(saved1cTabs.indexOf(table1c), 1);

    for (let i = 0; i < configIds.length; i++) {
      if(Object.keys(configIds[i])[0] == delRow['id']){
        configIds.splice(configIds.indexOf(Object.keys(configIds[i])[0]), 1);
      }
    }

    if (tableId === curTableId) {
      this.setState({ configTables: config,
                      allTables1c: all1CTables,
                      allTablesCb: allCbTables,
                      fieldsGroup: [],
                      openedSettings: false,
                      curTabId: '',
                      curTable1c: '',
                      openedTableRow: null,
                      tabPartsSettings: false,
                      tabPartFieldsSettings: false,
                    });
    } else {
      this.setState({ configTables: config,
                      allTables1c: all1CTables,
                      allTablesCb: allCbTables,
                    });
    }

    this.createNexTableRow(this.state.configTables);
  }

  // Удаление строки из раздела полей
  deleteFieldRow = (fieldId, field1CName) => (e) => {
    e.preventDefault();
    if(this.state.isEditMatchingFieldsMode || this.state.isEditFieldMode || this.state.isEditMode || this.state.isEditPartFieldsMode){
      alert('Сначала закончите редактирование!');
      return;
    }
    const cur1cTab = this.state.curTable1c;
    let curFields = this.state.fieldsGroup;
    let config = this.state.configTables;
    let nextField = this.state.nextField;

    if(fieldId == this.state.editFieldId && this.state.isEditFieldMode){
      this.setState({
        editFieldId: null,
        isEditFieldMode: false,
      });
    }
    if(this.state.tabPartFieldsSettings && this.state.cur1cTabPart == field1CName && this.state.curCbTabPart == fieldId){
      this.setState({
        cur1cTabPart: '',
        curCbTabPart: '',
        curCbTabPartName: '',
        tabPartsConfig: [],
        tabPartFieldsSettings: false,
        partFieldsGroup: [],
        cur1cFieldName: '',
      });
    }
    curFields.forEach(field => { if (field['linkFields']['id'] === fieldId && field['name'] == field1CName) nextField = field });
    curFields = curFields.filter(field => field['linkFields']['id'] !== fieldId || field['linkFields']['id'] == fieldId && field['name'] !== field1CName);
    if(config[cur1cTab].tablePart[field1CName]){
      delete config[cur1cTab].tablePart[field1CName];
    }
    config[cur1cTab]['fields'] = curFields;
    this.setState({ fieldsGroup: curFields,
                    configTables: config,
                    nextField: nextField
                  });
  };

    changeSyncModeTable = (table1CName) => (e) => {
        let config = this.state.configTables;
        let curMode = config[table1CName].mode + 1;

        if(curMode > 3) curMode = 0;

        config[table1CName].mode = curMode;

        this.setState({
        configTables: config,
        });
    }

  changeSyncModeField = (field1CName) => (e) => {
    const cur1cTab = this.state.curTable1c;
    let curFields = this.state.fieldsGroup;
    let config = this.state.configTables;
    let curField = {};
    let num = -1;

    for(let field_num in curFields) {
      if(curFields[field_num].name == field1CName) {
        curField = curFields[field_num];
        num = field_num;
      }
    }

    let curMode = curField.mode + 1;

    if(curMode > 3) curMode = 0;

    curFields[num].mode = curMode;
    config[cur1cTab]['fields'] = curFields;

    this.setState({
      fieldsGroup: curFields,
      configTables: config,
    });
  }

  // Удаление строки из раздела ТЧ - подтаблица
  deletePartRow = (field1cName) => (e) => {
    let partConf = this.state.tabPartsConfig;

    if(partConf[field1cName].id == this.state.editPartId && this.state.isEditPartMode){
      alert('Нельзя удалять редактируемую пару табличной части - подтаблицы. Сначала закончите редактирование!');
      return;
    }

    let showFieldsSettings = true;
    delete partConf[field1cName];

    // Если это последняя строка - скрываем блок настроек полей
    if (Object.keys(partConf).length < 1) showFieldsSettings = false;

    this.createNextPartRow();
    this.setState({ tabPartsConfig: partConf, partFieldsGroup: [], tabPartFieldsSettings: showFieldsSettings });
  }

  // Удаление строки из раздела поля ТЧ - подтаблица
  deletePartFieldRow = (field1cName) => (e) => {
    if(this.state.isEditMatchingFieldsMode || this.state.isEditFieldMode || this.state.isEditMode || this.state.isEditPartFieldsMode){
      alert('Сначала закончите редактирование!');
      return;
    }
    let partConf = this.state.partFieldsGroup;

    for (let row of partConf) {
      if(row.name == field1cName && row.link.id == this.state.editPartFieldId && this.state.isEditPartFieldsMode){
        alert('Нельзя удалять редактируемую пару полей. Сначала закончите редактирование!');
        return;
      }
    }

    let num = -1;

    for (let row of partConf) if (row['name'] === field1cName) num = partConf.indexOf(row);
    partConf.splice(num, 1);

    this.createNextPartFieldRow();
    this.setState({ partFieldsGroup : partConf });
  }

  changePartFieldMode = (field1C) => (e) => {
    let partConf = this.state.partFieldsGroup;
    let curField = {};
    let num = -1;

    for(let field_num in partConf) {
      if(partConf[field_num].name == field1C) {
        curField = partConf[field_num];
        num = field_num;
      }
    }

    let curMode = curField.mode + 1;

    if(curMode > 3) curMode = 0;

    partConf[num].mode = curMode;

    this.setState({
      partFieldsGroup: partConf,
    });
  }

  // Отображение настроек полей для выбранной пары таблиц (при нажатии на желтое поле)
  setFieldsConfig = (tableId, confFields, table1cName) => (e) => {
    e.preventDefault();

    if(this.state.curTableId == tableId){
      this.setState({
        fieldsGroup: [],
        curTable1c: null,
        cur1cTableName: "",
        curTableId: null,
        openedTableRow: null,
        openedSettings: false,
        curCbTableName: "",
        tabPartsSettings: false,
        tabPartFieldsSettings: false,
        partFieldsGroup: [],
        tabPartsConfig: {},
        cur1cTabPartName: ''
      });

      return;
    }

    const tableCbName = allCbTables[tableId]['name'];
    const config = this.state.configTables;
    let partConfig = config[table1cName]['tablePart'];
    let partsConfig = {};
    let partSettings = false;
    let partFieldsSettings = false;
    let partFields = [];

    if (!partConfig) {
      partConfig = {};
      config[table1cName]['tablePart'] = {};
    }

    if (Object.keys(partConfig).length > 0) {
      const nameTable1c = Object.keys(partConfig)[0];
      const fields = partConfig[nameTable1c]['fields'];

      partsConfig = partConfig;
      if (fields.length > 0) {
        partFields = fields;
      }
    }

    this.setState({
      configTables: config,
      fieldsGroup: confFields,
      curTable1c: table1cName,
      cur1cTableName: table1cName,
      curTableId: tableId,
      openedTableRow: null,
      openedSettings: true,
      curCbTableName: tableCbName,
      tabPartsSettings: partSettings,
      tabPartFieldsSettings: partFieldsSettings,
      partFieldsGroup: partFields,
      tabPartsConfig: partsConfig,
    });
    this.createNextFieldRow(tableId, table1cName);
  };

  setTabpartsConfig = (field1C, fieldCb) => (e) => {
    let config = this.state.configTables;
    let tabPartFieldsSettings = this.state.tabPartFieldsSettings;
    let cur1CTable = this.state.cur1cTableName;
    let curCbTable = this.state.curTableId;

    if(tabPartFieldsSettings && this.state.cur1cTabPart == field1C){
      this.setState({
        cur1cTabPart: '',
        curCbTabPart: '',
        curCbTabPartName: '',
        tabPartsConfig: [],
        tabPartFieldsSettings: false,
        partFieldsGroup: [],
        cur1cFieldName: '',
      });
      return;
    }

    let partConfig = config[cur1CTable]['tablePart'];
    let partFieldsGroup = partConfig[field1C].fields || [];
    let cbTabpartName = '';
    for(let subtable of result.allCbSubTables[curCbTable].subtables){
      if(subtable.id == fieldCb){
        cbTabpartName = subtable.name;
      }
    }

    this.setState({
      cur1cTabPart: field1C,
      curCbTabPart: fieldCb,
      cur1cTabPartName: field1C,
      curCbTabPartName: cbTabpartName,
      tabPartsConfig: partConfig,
      tabPartFieldsSettings: true,
      partFieldsGroup,
      cur1cFieldName: field1C,
    });

    setTimeout(() => {
      this.createNextPartFieldRow();
    }, 0);
  }

  create1cTablePartsArray = (name) => {
    return this.state.all1CTabParts[name] ? Object.keys(this.state.all1CTabParts[name]) : [];
  }

  createCbSubtablesArray = (id) => {
    return this.state.allCbSubtables[id] ? this.state.allCbSubtables[id]['subtables'] : [];
  }

  // Отображение доп.настроек для пары "Табличная часть 1С - подтбалица КБ"
  showTablePartsConfig = () => (e) => {
    this.setState({ tabPartsSettings: true });
    this.createNextPartRow();
  };

  // Отображение настроек полей для пары "Табличная часть 1С - подтбалица КБ"
  showTablePartFieldsConfig = () => (e) => {
    this.setState({ tabPartFieldsSettings: true });
    this.createNextPartFieldRow();
  }

  // Добавление новой строки для блока ТЧ - подтаблица
  addNextTabPart = (e) => {
    e.preventDefault();

    if (this.state.isEditPartMode) {
      alert('Пожалуйста, сначала завершите редактирование');
      return false;
    }

    const config = this.state.configTables;
    const nextPart = this.state.nextTabPart;
    const parts1c = this.state.tab1cPartsArray;
    const partsCb = this.state.tabCbPartsArray;
    const addNewRowErrorMsg = 'Вы больше не можете добавлять строки для текущей настройки!';
    let tabParts = this.state.tabPartsConfig;

    if (nextPart) {
      const cur1cTablePart = Object.keys(nextPart)[0];
      const curCbTablePart = Object.values(nextPart)[0]['cbSubtable']['name'];
      const curCbTablePartId = Object.values(nextPart)[0]['cbSubtable']['id'];
      const sync1cPartsArray = parts1c.filter(name => name !== cur1cTablePart);
      const cbSubArray = partsCb.filter(tab => tab['name'] !== curCbTablePart);

      tabParts[cur1cTablePart] = Object.values(nextPart)[0]['cbSubtable'];
      tabParts[cur1cTablePart]['fields'] = [];
      config[this.state.cur1cTableName]['tablePart'] = tabParts; // Добавляем табличную часть в общий конфиг
      this.setState({ configTables: config,
                      tabPartsConfig: tabParts,
                      curCbTabPart: curCbTablePartId,
                      cur1cTabPart: cur1cTablePart,
                      cur1cTabPartName: cur1cTablePart,
                      tab1cPartsArray: sync1cPartsArray,
                      tabCbPartsArray: cbSubArray,
                      tabPartFieldsSettings: false,
                      partFieldsGroup: [],
                    });
      this.createNextPartRow();
      setTimeout(() => {
        $(`#edit-btn${curCbTablePartId}`).each((i, el) => {
          if($(el).attr('field_type') == 'table-part'){
            $(el).trigger('click');
          }
        });
      }, 5);
    } else alert(addNewRowErrorMsg);
  }

  // Создание новой строки для блока ТЧ - подтаблица
  createNextPartRow = () => {
    let tab1cParts = []
    let cbSubtables = [];
    let nextRow = {};
    const partConf = this.state.tabPartsConfig;
    const conf1cTables = Object.keys(partConf);
    const all1cTabParts = this.create1cTablePartsArray(this.state.cur1cTableName);
    const allCbSubtables = this.createCbSubtablesArray(this.state.curTableId);
    let confCbTables = [];

    for (let elem in partConf) confCbTables.push(partConf[elem]['id']);
    for (let tab of all1cTabParts) if (conf1cTables.indexOf(tab) === -1) tab1cParts.push({ id: tab, name: tab });
    for (let cb of allCbSubtables) if (confCbTables.indexOf(cb['id']) === -1) cbSubtables.push({ id: cb['id'], name: cb['name'] });

    const next1cName = tab1cParts[0];
    const nextCbSubtable = cbSubtables[0];

    if (next1cName && nextCbSubtable) {
      nextRow[next1cName['id']]  = { cbSubtable: nextCbSubtable };
      this.setState({ nextTabPart: nextRow,
                      tab1cPartsArray: tab1cParts,
                      tabCbPartsArray: cbSubtables,
                      curListParts1c: tab1cParts,
                      curListPartsCb: cbSubtables
      });
    }
    else this.setState({ nextTabPart: null });
  }

  // Добавление новой строки для блока полей ТЧ - подтаблица
  addNextTabPartField = (e) => {
    e.preventDefault();

    if (this.state.isEditPartFieldsMode) {
      alert('Пожалуйста, сначала завершите редактирование');
      return false;
    }

    const config = this.state.configTables;
    const nextPartFields = this.state.nextTabPartFields;
    const group = this.state.partFieldsGroup;
    const addNewRowErrorMsg = 'Вы больше не можете добавлять поля для текущей пары!';

    if (nextPartFields) {
      const main1cTable = this.state.cur1cTableName;
      const tabPart1cTable = this.state.cur1cTabPart;
      const field1cName = nextPartFields['name'];
      const fieldCb = nextPartFields['link'];
      group.push(nextPartFields);

      config[main1cTable]['tablePart'][tabPart1cTable]['fields'] = group;
      this.setState({ configTables: config,
                      partFieldsGroup: group,
                      cur1cTabPartField: field1cName,
                      cur1cTabPartFieldName: field1cName,
                      curCbTabPartField: fieldCb['id'],
                      curCbTabPartFieldName: fieldCb['name'],
                      editPartFieldId: fieldCb['id'],
                      isEditPartFieldsMode: true
                    });
      this.createNextPartFieldRow();
    } else alert(addNewRowErrorMsg);
  }

  // Создание новой строки для блока полей ТЧ - подтаблица
  createNextPartFieldRow = () => {
    const cur1cTableName = this.state.cur1cTableName;
    const allCbSubtables = this.createCbSubtablesArray(this.state.curTableId);
    const cur1cPartTable = this.state.cur1cTabPartName;
    const curCbPartTable = this.state.curCbTabPart;
    const fieldsConfig = this.state.partFieldsGroup;
    let all1cPartFields = this.state.all1CTabParts[cur1cTableName][cur1cPartTable];
    let allCbPartFields = [];
    let allCbConfFields = [];
    let all1cConfFields = [];
    let values1c = [];
    let valuesCb = [];
    let nextRow = {};

    for (let elem of allCbSubtables) if (elem['id'] == curCbPartTable) allCbPartFields = elem['fields'];
    for (let el of fieldsConfig) {
      allCbConfFields.push(el['link']['id']);
      all1cConfFields.push(el['name']);
    }
    for (let item of allCbPartFields) if (allCbConfFields.indexOf(item['id']) === -1) valuesCb.push(item);
    for (let val of all1cPartFields) if (all1cConfFields.indexOf(val) === -1) values1c.push(val);

    const next1cName = values1c[0];
    const nextCbField = valuesCb[0];
    if (next1cName && nextCbField) {
      nextRow = { name: next1cName, link: nextCbField, mode: this.state.bond };
      this.setState({ nextTabPartFields: nextRow });
    }
    else this.setState({ nextTabPartFields: null });
  }

  showMatchingConfig = () => (e) => {
    if(this.state.matchingSettingsOpened){
      this.setState({
        matchingSettingsOpened: false,
      });

      return;
    }
    let config = this.state.configTables;
    let currentTable1C = this.state.cur1cTableName;
    let matchingDisplaySettings = this.state.matchingDisplaySettings;

    matchingDisplaySettings.tableMinWidth = document.getElementById('main-module-table').offsetWidth;

    if(!config[currentTable1C].matching){
      config[currentTable1C].matching = {};
    }


    this.setState({
      configTables: config,
      matchingSettingsOpened: true,
      matchingDisplaySettings,
    });
  }

  createMatchingBlock = () => {
    let config = this.state.configTables;
    let cur1CTable = this.state.cur1cTableName;

    config[cur1CTable].matching['block-' + (Object.keys(config[cur1CTable].matching).length + 1)] = {};

    this.setState({
      configTables: config,
    });
  }

  createMatchingField = (blockId) => (e) => {
    let config = this.state.configTables;
    let cur1CTable = this.state.cur1cTableName;
    let curCbTable = this.state.curTableId;

    let matchingSettings = config[cur1CTable].matching[blockId];
    let match1CFields = [];
    let matchCbFields = [];

    let choose1c = null,
        chooseCb = null;

    for(let field1C in matchingSettings) {
      match1CFields.push(field1C);
      matchCbFields.push(matchingSettings[field1C].id);
    }

    for(let field1C of tables1C[cur1CTable]) if(match1CFields.indexOf(field1C) === -1) choose1c = field1C;
    for(let fieldCb of result.allCbTables[curCbTable].fields) if(matchCbFields.indexOf(fieldCb.id) === -1) chooseCb = {
      id: fieldCb.id,
      name: fieldCb.name,
    };
    if(choose1c !== null && chooseCb !== null){
      config[cur1CTable].matching[blockId][choose1c] = chooseCb;

      this.setState({
        configTables: config,
        isEditMatchingFieldsMode: true,
        editMatchingId: chooseCb.id,
        cur1cMatchingFieldName: choose1c,
        curMatchingBlock: blockId,
      });
    }
    else {
      alert(`Нельзя больше добавить полей для правила!`);
    }
  }

  changeSelectMatch1C = () => (e) => {
    let config = this.state.configTables;
    let cur1CTable = this.state.cur1cTableName;
    let newName = e.target.value;
    let curMatchBlock = this.state.curMatchingBlock;
    let matchingSettings = config[cur1CTable].matching[curMatchBlock];
    let cur1cMatchingFieldName = this.state.cur1cMatchingFieldName;

    let cbValue = matchingSettings[cur1cMatchingFieldName];
    delete matchingSettings[cur1cMatchingFieldName];
    matchingSettings[newName] = cbValue;

    config[cur1CTable].matching[curMatchBlock] = matchingSettings;

    this.setState({
      configTables: config,
      cur1cMatchingFieldName: newName,
      curMatchingBlock: curMatchBlock,
    });
  }

  changeSelectMatchCb = () => (e) => {
    let newId = e.target.value;
    let newName = '';
    for(let field of allCbTables[this.state.curTableId].fields){
      if(field.id == newId){
        newName = field.name;
      }
    }
    let config = this.state.configTables;
    let curMatchBlock = this.state.curMatchingBlock;
    let curMatch1CField = this.state.cur1cMatchingFieldName;
    let cur1CTable = this.state.cur1cTableName;

    config[cur1CTable].matching[curMatchBlock][curMatch1CField] = { id: newId, name: newName };

    this.setState({
      configTables: config,
      editMatchingId: newId,
      curMatchingBlock: curMatchBlock,
    });

  }

  deleteMatchRow = (blockId, field1CName) => (e) => {
    let config = this.state.configTables;
    let cur1cTableName = this.state.cur1cTableName;
    if(this.state.isEditMatchingFieldsMode || this.state.isEditFieldMode || this.state.isEditMode || this.state.isEditPartFieldsMode){
      alert('Сначала закончите редактирование!');
      return;
    }

    delete config[cur1cTableName].matching[blockId][field1CName];

    this.setState({
      configTables: config,
    });
  }

  deleteMatchBlock = (blockId) => (e) => {
    if(this.state.isEditMatchingFieldsMode || this.state.isEditFieldMode || this.state.isEditMode || this.state.isEditPartFieldsMode){
      alert('Сначала закончите редактирование!');
      return;
    }
    let config = this.state.configTables;
    let cur1cTableName = this.state.cur1cTableName;

    delete config[cur1cTableName].matching[blockId];

    this.setState({
      configTables: config,
    });
  }

  saveSelectMatchValue = () => (e) => {
    this.setState({
      curMatchingBlock: null,
      editMatchingId: null,
      cur1cMatchingFieldName: '',
      isEditMatchingFieldsMode: false
    });
  }

  matchingConfig = () => {
    let config = this.state.configTables;
    let cur1cTable = this.state.cur1cTableName;
    let matchingSettings = config[cur1cTable].matching;
    let curTableId = this.state.curTableId;
    let all1cOptions = []
    let allCbOption = [];

    for(let matching_id in matchingSettings){
      let _all1cOptions = [];
      let _allCbOption = [];

      let matchingCbFields = [];
      for (let key in matchingSettings[matching_id]) matchingCbFields.push(matchingSettings[matching_id][key]);

      for (let tab of tables1C[cur1cTable]){
        if(Object.keys(matchingSettings[matching_id]).indexOf(tab) == -1) {
          _all1cOptions.push({ id: tab, name: tab });
        }
      }
      for (let cb of result.allCbTables[curTableId].fields){
        let pos = matchingCbFields.map((e) => { return e.id }).indexOf(cb.id);
        if(pos == -1){
          _allCbOption.push({ id: cb['id'], name: cb['name'] });
        }
      }

      all1cOptions.push(_all1cOptions);
      allCbOption.push(_allCbOption);
    }
    return (
      <>
        <tr className="noDrag">
          <td className='config-title' align='center' colSpan='2'>
            Настройка правил сопоставления <br /> "{this.state.cur1cTableName}" и "{this.state.curCbTableName}"
          </td>
        </tr>
        {Object.keys(matchingSettings).length < 1 ?
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>Правила<span className='help_bt' h_id='config_1c_parts'></span>:</td>
            <td align='left'>
              <AddButton type='matching-block' addNewRow={this.createMatchingBlock} />
            </td>
          </tr>) :
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>Правила<span className='help_bt' h_id='config_1c_parts'></span>:</td>
            <td align='left'>
            </td>
          </tr>)
        }

        {Object.keys(matchingSettings).map((i) => (
          <tr id={`matching_block_${i}`} key={i} className={`matching_block`}>
            <td></td>
            <td style={{ borderBottom: '1px solid black' }}>
              <table style={{ minWidth: '677px' }}>
                <tbody>
                  <tr>
                    <td colSpan='8'>
                      <div className={'matching_block_title'}>
                        <img src="images/draggable.png"
                            className={"drag_symbol_1c"}
                            style={{ paddingLeft: "20px", marginBottom: '3px', position: "relative", cursor: "move", zIndex: "9999", visibility: "hidden" }}
                        />

                        <img src='images/b_drop.png' onClick={this.deleteMatchBlock(i)} style={{ margin: '-3px 12px 0 5px', cursor: 'pointer' }} />
                        Блок правил - <span style={{ fontSize: '16px', fontWeight: 'bold' }}>{this.romanize(i.replace('block-', ''))}</span>
                      </div>
                    </td>
                  </tr>
                </tbody>
                <tbody>
                  {Object.keys(matchingSettings[i]).map((names1c) => (
                    <tr key={names1c}>
                      <td className='table-settings-btn'>
                      </td>
                      <td>
                        <img src='images/b_drop.png'
                             id={`delete_match_row_${i.replace('block-', '')}_${matchingSettings[i][names1c]['id']}`}
                             className={'edit-table-settings'}
                             onClick={this.deleteMatchRow(i, names1c)}
                             style={{ margin: '-3px 0 0 5px', cursor: 'pointer' }}
                        />
                      </td>
                      <td></td>
                      <td>
                        <ComboboxSelect
                          curValue={names1c}
                          fieldId={names1c}
                          options={all1cOptions[i.replace('block-', '')-1]}
                          allIds={[]}
                          changeValue={this.changeSelectMatch1C()}
                          editMode={this.state.isEditMatchingFieldsMode}
                          editId={this.state.cur1cMatchingFieldName}
                          curBlockId={this.state.curMatchingBlock}
                          blockId={i}
                        />
                      </td>
                      <td>
                        <span> = </span>
                      </td>
                      <td>
                        <ComboboxSelect
                          curValue={matchingSettings[i][names1c]['name']}
                          fieldId={matchingSettings[i][names1c]['id']}
                          options={allCbOption[i.replace('block-', '')-1]}
                          allIds={[]}
                          changeValue={this.changeSelectMatchCb()}
                          editMode={this.state.isEditMatchingFieldsMode}
                          editId={this.state.editMatchingId}
                          curBlockId={this.state.curMatchingBlock}
                          blockId={i}
                        />
                      </td>
                      <td></td>
                      <td>
                        <EditMatchBtn
                          field1c={names1c}
                          fieldCb={matchingSettings[i][names1c]['id']}
                          id={matchingSettings[i][names1c]['id']}
                          editMode={this.state.isEditMatchingFieldsMode}
                          editId={this.state.editMatchingId}
                          curBlockId={this.state.curMatchingBlock}
                          blockId={i}
                          saveValue={this.saveSelectMatchValue()}
                        />
                      </td>
                    </tr>))}
                </tbody>
                <tbody>
                  <tr>
                    <td align='left' colSpan='8' style={{ padding: '10px 3px 7px 3px' }}>
                      <AddButton type='matching-fields' addNewRow={this.createMatchingField(i)} />
                    </td>
                  </tr>
                </tbody>
              </table>
            </td>
          </tr>
        ))}
        {Object.keys(matchingSettings).length > 0 ?
          (<tr>
            <td align='right' style={{ 'width': '120px' }}></td>
            <td align='left' style={{ padding: '10px 3px 7px 3px' }}>
              <AddButton type='matching-block' addNewRow={this.createMatchingBlock} />
            </td>
          </tr>) : ''
        }
      </>
    );
  }

  // Изменение поля таблицы КБ
  changeSelectCbVal = () => (e) => {
    e.preventDefault();
    const newCbId = e.target.value;
    const newName = allCbTables[newCbId]['name'];
    const oldName = this.state.curCbTableName;
    const keyField = this.state.cur1cTableName;
    const oldKey = this.state.curCbTableName;
    const cbTables = this.state.allTablesCb;
    const cbTable = cbTables[newCbId];
    const arrayConf = [];
    let _conf = this.state.configTables;
    let objFields = [];
    let num = -1;
    let newRow = {};
    let mode = _conf[keyField].mode;

    // Преобразуем объект конфигурации в массив, чтобы знать текущий порядок элементов
    Object.keys(_conf).map(function(key) {
      let obj = {};
      obj[key] = _conf[key];
      arrayConf.push(obj);
    });

    for (let elem of arrayConf) {
      if (Object.keys(elem)[0] === keyField) num = arrayConf.indexOf(elem);
    }
    if (num === -1) num = arrayConf.indexOf(_conf[keyField]);

    if (_conf[oldKey]) {
      if (_conf[oldKey]['id'] == newCbId) {
        objFields = _conf[oldKey]['fields'];
      }
    }

    const newCbObject = {
      id: newCbId,
      name: cbTable['name'],
      fields: objFields,
      mode: mode,
    }
    newRow[keyField] = newCbObject;

    arrayConf[num] = newRow;
    _conf = {};
    for (let elem of arrayConf) {
      const keyName = Object.keys(elem)[0];
      const val = Object.values(elem)[0];

      _conf[keyName] = val;
    }
    savedCbTabs.push(newCbId);
    saved1cTabs.push(keyField);
    this.setState({ configTables: _conf,
                    curTableId : newCbId,
                    curCbTableName : newName,
                    oldTableCbName : oldName,
                    isEditMode: true,
                    editId: newCbId,
                    openedSettings: false,
                    partFieldsGroup: [],
                    tabPartFieldsSettings: false,
                    tabPartsSettings: false,
                    tabPartsConfig: {},
                    openedTableRow: newCbId
                  });
  }

  // Изменение поля таблицы 1С
  changeSelect1cVal = () => (e) => {
    e.preventDefault();
    const newName = e.target.value;
    const keyField = this.state.cur1cTableName;
    const arrayConf = [];
    let _conf = this.state.configTables;
    let num = -1;
    let newRow = {};

    // Преобразуем объект конфигурации в массив, чтобы знать текущий порядок элементов
    Object.keys(_conf).map(function(key) {
      let obj = {};
      obj[key] = _conf[key];
      arrayConf.push(obj);
    });

    for (let elem of arrayConf) {
      if (Object.keys(elem)[0] === keyField) num = arrayConf.indexOf(elem);
    }

    if (num === -1) num = arrayConf.indexOf(_conf[keyField]);

    const newCbObject = _conf[keyField];
    newRow[newName] = newCbObject;

    arrayConf[num] = newRow;
    _conf = {};
    for (let elem of arrayConf) {
      const keyName = Object.keys(elem)[0];
      const val = Object.values(elem)[0];

      _conf[keyName] = val;
    }

    _conf[newName]['tablePart'] = {};
    saved1cTabs.push(keyField);
    this.setState({ configTables: _conf,
                    cur1cTableName : newName,
                    curTable1c: newName,
                    oldTable1cName : keyField,
                    isEditMode: true,
                    openedSettings: false,
                    tabPartFieldsSettings: false,
                    tabPartsSettings: false,
                    tabPartsConfig: {},
                    partFieldsGroup: []
                  });

  }

  // Изменения поля КБ в блоке "Поля" (для основных таблиц)
  changeSelectCbField = () => (e) => {
    const type = e.target.value.charAt(0) == 't' ? 'tabpart' : 'field';
    const newCbId = type == 'tabpart' ? e.target.value.slice(1) : e.target.value;
    const curTableId = this.state.curTableId;
    const allTableFields = this.state.allTablesCb.hasOwnProperty(curTableId)? this.state.allTablesCb[curTableId]['fields'] : result.allCbTables[curTableId]['fields'];
    const oldName = this.state.curCbTableName;
    const fieldsGroup = this.state.fieldsGroup;
    const cur1cField = this.state.cur1cFieldName;
    let num = -1;
    let newFieldName = '';

    let allSubtables = {};

    for(let subtable of result.allCbSubTables[this.state.curTableId].subtables) allSubtables[subtable.id] = subtable;

    if(type == 'field'){
      for (let elem of allTableFields) if (elem['id'] === newCbId) newFieldName = elem['name'];
    }
    else {
      newFieldName = allSubtables[newCbId].name;
    }
    for (let links of fieldsGroup) if (links['name'] === cur1cField) num = fieldsGroup.indexOf(links);
    fieldsGroup[num]['linkFields'] = { id : newCbId, name : newFieldName, type };

    this.setState({ fieldsGroup: fieldsGroup,
                    curFieldCb : newCbId,
                    curCbFieldName : newFieldName,
                    oldFieldCbName : oldName,
                    oldField1cName : cur1cField,
                    isEditFieldMode: true,
                    editFieldId: newCbId
                  });
  }

  // Изменение поля 1С в блоке "Поля" (для основных таблиц)
  changeSelect1cField = () => (e) => {
    const newName = e.target.value;
    const type = $(e.target).attr('type');
    const config = this.state.configTables;
    const fieldsGroup = this.state.fieldsGroup;
    const cur1cField = this.state.cur1cFieldName;
    const cur1cTableName = this.state.cur1cTableName;
    const tableParts = config[cur1cTableName]['tablePart'];

    let num = -1;
    let isTabPart = false;
    let newLinkFieldsData = {};

    for (let links of fieldsGroup) {
      if (links['name'] === cur1cField) {
        num = fieldsGroup.indexOf(links);
        newLinkFieldsData = links['linkFields'];
        if(links.type == "tabpart"){
            isTabPart = true;
        }
      }
    }
    fieldsGroup[num]['name'] = newName;
    fieldsGroup[num]['linkFields'] = newLinkFieldsData;

    if(isTabPart){
        let newTabPartData = tableParts[cur1cField];
        tableParts[newName] = newTabPartData;
        delete tableParts[cur1cField];
    }

    config[cur1cTableName]['fields'] = fieldsGroup;
    config[cur1cTableName]['tablePart'] = tableParts;

    this.setState({ configTables: config,
                    fieldsGroup: fieldsGroup,
                    cur1cFieldName: newName,
                    curField1c: newName,
                    isEditFieldMode: true
                  });
  }

  // Изменение поля КБ табличной части
  changeSelectCbPartVal = () => (e) => {
    const newPartId = e.target.value;
    const curTabId = this.state.curTableId;
    const allCbCurParts = this.createCbSubtablesArray(curTabId);
    const partConf = this.state.tabPartsConfig;
    const cur1cPart = this.state.cur1cTabPart;
    let newSubtableVal = {};
    let newCbName = '';

    for (let val of allCbCurParts) {
      if (val['id'] === newPartId) {
        newSubtableVal = { id: val['id'], name: val['name'], fields: [] };
        newCbName = val['name'];
      }
    }

    partConf[cur1cPart] = newSubtableVal;
    this.setState({ tabPartsConfig: partConf,
                    isEditPartMode: true,
                    editPartId: newPartId,
                    curCbTabPart: newPartId,
                    curCbTabPartName: newCbName,
                    partFieldsGroup: [],
                    tabPartFieldsSettings: false,
                  });
  }

  // Изменение поля 1С табличной части
  changeSelect1cPartVal = () => (e) => {
    const newPart1cname = e.target.value;
    const cur1cPart = this.state.cur1cTabPart;
    let partConf = this.state.tabPartsConfig;
    let newSubtableVal = {};
    let arrayConf = [];
    let num = -1;
    let cbObject = {};

    // Преобразуем объект конфигурации в массив, чтобы знать текущий порядок элементов
    Object.keys(partConf).map(function(key) {
      let obj = {};
      obj[key] = partConf[key];
      arrayConf.push(obj);
    });

    for (let elem of arrayConf) {
      if (Object.keys(elem)[0] === cur1cPart) {
        cbObject = elem[cur1cPart];
        num = arrayConf.indexOf(elem);
      }
    }

    newSubtableVal[newPart1cname] = cbObject;
    arrayConf[num] = newSubtableVal;

    partConf = {};
    for (let elem of arrayConf) {
      const keyName = Object.keys(elem)[0];
      const val = Object.values(elem)[0];

      partConf[keyName] = val;
    }
    this.setState({ tabPartsConfig: partConf,
                    isEditPartMode: true,
                    cur1cTabPart: newPart1cname,
                    cur1cTabPartName: newPart1cname,
                    partFieldsGroup: [],
                    tabPartFieldsSettings: false,
                  });
  }

  // Изменение поля КБ для блока болей табличной части
  changeSelectCbPartFieldVal = () => (e) => {
    const newId = e.target.value;
    const curField1c = this.state.cur1cTabPartField;
    const partConf = this.state.partFieldsGroup;
    const allCbSubtables = this.createCbSubtablesArray(this.state.curTableId);
    const curCbPartTable = this.state.curCbTabPart;
    let allCbPartFields = [];
    let newSubtableVal = {};
    let mode = this.state.bond;
    let newCbName = '';
    let num = -1;

    for (let val of partConf) {
      if (val['name'] === curField1c) {
        newSubtableVal = val['link'];
        newCbName = val['name'];
        mode = val.mode;
        num = partConf.indexOf(val);
      }
    }

    for (let elem of allCbSubtables) if (elem['id'] == curCbPartTable) allCbPartFields = elem['fields'];
    for (let link of allCbPartFields) if (link['id'] == newId) newSubtableVal = link;

    partConf[num] = { name : curField1c, link : newSubtableVal, mode };
    this.setState({ partFieldsGroup: partConf,
                    isEditPartFieldsMode: true,
                    editPartFieldId: newId,
                    curCbTabPartField: newId,
                    curCbTabPartFieldName: newCbName,
                    openedPartFieldRow: newId
                  });
  }

  // Изменение поля 1С для блока болей табличной части
  changeSelect1cPartFieldVal = () => (e) => {
    const newFieldName = e.target.value;
    const curField1c = this.state.cur1cTabPartField;
    let partConf = this.state.partFieldsGroup;
    let subtableVal = {};
    let mode = this.state.bond;
    let num = -1;

    for (let val of partConf) {
      if (val['name'] === curField1c) {
        subtableVal = val['link'];
        mode= val.mode;
        num = partConf.indexOf(val);
      }
    }

    partConf[num] = { name: newFieldName, link: subtableVal, mode };
    this.setState({ partFieldsGroup: partConf,
                    isEditPartFieldsMode: true,
                    cur1cTabPartField: newFieldName,
                    cur1cTabPartFieldName: newFieldName,
                  });
  }

  // Сохранение выбранных значений (нажатие на зеленый кружок) - Таблицы
  saveSelectTableValue = () => (e) => {
    const config = this.state.configTables;
    const cur1cTbale = this.state.cur1cTableName;
    const partConfig = this.state.tabPartsConfig;
    const curIdCb = this.state.editId;

    config[cur1cTbale]['tablePart'] = partConfig;
    this.createNexTableRow(this.state.configTables);
    this.setState({ openedTableRow: null, isEditMode: false, editId: null, configTables: config });
    setTimeout(() => {
      $(`#set_settings_${curIdCb}`).each((i, el) => {
        if($(el).attr('active-type') == 'table'){
          $(el).trigger('click');
          $(el).trigger('click');
        }
      });
      this.setState({ curTableId: curIdCb });
    }, 0);
  }

  // Сохранение выбранных значений (нажатие на зеленый кружок) - Поля
  saveSelectFieldValue = (field1C) => (e) => {
    const fieldConf = this.state.fieldsGroup;
    const config = this.state.configTables;
    const cur1cTable = this.state.cur1cTableName;
    let allTabparts = [];
    let allSubtables = [];
    let type1C = '';
    let typeCb = '';
    let curCbId = null;
    for(let tabpart in tables1CTabparts[cur1cTable]) allTabparts.push(tabpart);
    for(let subtable of result.allCbSubTables[this.state.curTableId].subtables) allSubtables.push(subtable.id);

    for(let fieldObj of fieldConf){
      if(fieldObj.name == field1C){
        if(allTabparts.indexOf(fieldObj.name) === -1){
          type1C = 'field';
        }
        else {
          type1C = 'tabpart';
        }
        typeCb = fieldObj.linkFields.type;
        if(typeCb != type1C){
          alert('Выбраны разные типы полей!');
          return;
        }
        else {
          fieldObj.type = typeCb;
          curCbId = fieldObj.linkFields.id;
          if(typeCb == 'tabpart'){
            config[cur1cTable].tablePart[fieldObj.name] = {
              id: fieldObj.linkFields.id,
              name: fieldObj.linkFields.name,
              fields: [],
              matching: {}
            };
          }
        }
      }
    }

    $(e.target).parent().parent().find('.chosen-container').each((i, item) => {
        $(item).css('display', 'none');
    });

    config[cur1cTable]['fields'] = fieldConf;
    this.createNextFieldRow(this.state.curTableId, this.state.cur1cTableName);
    this.setState({ openedFieldRow: null, isEditFieldMode: false, editFieldId: null, configTables: config });
    setTimeout(() => {
      if(typeCb == 'tabpart' && curCbId != null){
        $(`#set_settings_t${curCbId}`).each((i, el) => {
          if($(el).attr('active-type') == 'field'){
            $(el).trigger('click');
          }
        });
      }
    }, 0);
  }

  // Сохранение выбранных значений (нажатие на зеленый кружок) - Табличная часть
  saveSelectPartValue = () => (e) => {
    const partConf = this.state.tabPartsConfig;
    const config = this.state.configTables;
    const cur1cTable = this.state.cur1cTableName;

    config[cur1cTable]['tablePart'] = partConf;
    this.createNextPartRow();
    this.setState({ openedPartSettings: false, isEditPartMode: false, editPartId: null, configTables: config });
  }

  // Сохранение выбранных значений (нажатие на зеленый кружок) - Поля табличной части
  saveSelectPartFieldsValue = () => (e) => {
    const fieldConf = this.state.partFieldsGroup;
    const config = this.state.configTables;
    const cur1cTable = this.state.cur1cTableName;
    const cur1cTablePart = this.state.cur1cTabPart;

    config[cur1cTable]['tablePart'][cur1cTablePart]['fields'] = fieldConf;
    this.createNextPartFieldRow();
    this.setState({ openedPartFieldRow: null, isEditPartFieldsMode: false, editPartFieldId: null, configTables: config });
  }

  // Редактирование выбранных значений блока "Таблицы" (карандашик)
  editSelectTableValue = () => (e) => {
    const id = e.target.id.replace('edit-btn', '');
    const cur1cTable = e.target.getAttribute('table_1c');
    const curMaintableId = this.state.curTableId;
    const config = this.state.configTables;
    const confFields = config[cur1cTable]['fields'];
    let partConfig = config[cur1cTable]['tablePart'];
    let partsConfig = {};
    let partSettings = false;
    let partFieldsSettings = false;
    let partFields = [];

    if (!partConfig) {
      partConfig = {};
      config[cur1cTable]['tablePart'] = {};
    }

    if (curMaintableId !== id) {
      if (Object.keys(partConfig).length > 0) {
        const nameTable1c = Object.keys(partConfig)[0];
        const fields = partConfig[nameTable1c]['fields'];

        partsConfig = partConfig;
        partSettings = true;
        if (fields.length > 0) {
          partFieldsSettings = true;
          partFields = fields;
        }
      }
    }

    this.setState({ configTables: config,
                    openedTableRow: id,
                    curTableId: id,
                    editId: id,
                    curTable1c: cur1cTable,
                    cur1cTableName: cur1cTable,
                    curCbTableName: e.target.getAttribute('table_cb'),
                    isEditMode: true,
                    openedSettings: true,
                    fieldsGroup: confFields,
                    tabPartsSettings: partSettings,
                    tabPartFieldsSettings: partFieldsSettings,
                    tabPartsConfig: partsConfig,
                    partFieldsGroup: partFields,
                  });
  }

  // Редактирование выбранных значений блока "Поля" (карандашик)
  editSelectFieldValue = () => (e) => {
    const fieldId = e.target.id.replace('edit-btn', '');

    this.setState({
      openedFieldRow: fieldId,
      curFieldCb: fieldId,
      editFieldId: fieldId,
      openedPartSettings: true,
      isEditFieldMode: true,
      curField1c: e.target.getAttribute('field_1c'),
      cur1cFieldName: e.target.getAttribute('field_1c'),
      curCbFieldName: e.target.getAttribute('field_cb'),
    });
  }

  // Редактирование блока "ТЧ - подтаблица"
  editSelectPartValue = () => (e) => {
    const subId = e.target.id.replace('edit-btn', '');

    this.setState({ openedPartRow: subId,
                    editPartId: subId,
                    curCbTabPart: subId,
                    cur1cTabPart: e.target.getAttribute('field_1c'),
                    curCbTabPartName: e.target.getAttribute('field_cb'),
                    cur1cTabPartName: e.target.getAttribute('field_1c'),
                    isEditPartMode: true,
                    openedPartSettings: true,
                  });
  }

  // Редактирование полей в блоке "ТЧ - подтаблица"
  editSelectPartFieldValue = () => (e) => {
    const fieldId = e.target.id.replace('edit-btn', '');

    this.setState({ openedPartFieldRow: fieldId,
                    curCbTabPartField: fieldId,
                    editPartFieldId: fieldId,
                    cur1cTabPartField: e.target.getAttribute('field_1c'),
                    cur1cTabPartFieldName: e.target.getAttribute('field_1c'),
                    isEditPartFieldsMode: true,
    });
  }

  // Предупреждающее сообщение о том, что где-то открыто редактирование
  editModeAttention = () => (e) => {
    e.preventDefault();
    alert('Пожалуйста, сначала завершите редактирование');
    return false;
  }

  absenceStructAttention = () => (e) => {
    e.preventDefault();
    alert('Отсутствует структура 1С. Редактирование запрещено');
    return false;
  }

  // Смена блока настроек модуля
  changeConfigMenu = (e) => {
    e.preventDefault();
    const curMenu = $(e.target);
    const menuVal = curMenu.attr('menu');

    $('#editTables').hide();
    curMenu.parent().find('.active').removeClass('active');
    curMenu.addClass('active');
    this.setState(() => { return { menu: menuVal } });

    $('#editTables').show();
    bind_help_bt();
  }

  addFilterForTable = (table_1c) => (e) => {
    let edited_filters = this.state.edited_filters;
    edited_filters[table_1c] = this.state.configTables[table_1c].filter;

    this.setState({
        edited_filters,
    });
  }

  onchangeFilterSelect = () => (e) => {
    let edited_filters = this.state.edited_filters;
    edited_filters[e.target.getAttribute('table_1c')] = e.target.value;

    this.setState({
        edited_filters,
    });
  }

  closeFilterWindow = (table_1c, clear = false) => (e) => {
    let edited_filters = this.state.edited_filters;
    let config = this.state.configTables;
    delete edited_filters[table_1c];

    if(clear){
        config[table_1c].filter = '';
    }

    this.setState({
        configTables: config,
        edited_filters,
    });
  }

  saveFilter = (table_1c) => {
    let edited_filters = this.state.edited_filters;
    let config = this.state.configTables;
    config[table_1c].filter = edited_filters[table_1c];
    delete edited_filters[table_1c];

    this.setState({
        configTables: config,
        edited_filters,
    });
  }

  // Создание строк в разделе "Таблицы"
  createTablesRow() {
    const tables = this.state.configTables;
    const ids = configIds;
    const allCbTables = this.state.allTablesCb;
    const all1CTables = this.state.allTables1c;
    let comboboxTablesCb = [];
    let comboboxTables1c = [];
    let allArr = new Array();
    let confArr = new Array();
    const syncModeImgs = [
      'images/sync_disabled.png',
      'images/sync_passive.png',
      'images/sync_active.png',
      'images/sync_twoway.png'
    ];

    for (let key in allCbTables) allArr.push(key);
    for (let confKey in tables) confArr.push(tables[confKey]['id']);
    for (let val of allArr) if (confArr.indexOf(val) === -1) comboboxTablesCb.push({ id : val, name : allCbTables[val]['name'] });

    allArr = new Array();
    confArr = new Array();
    for (let key in all1CTables) allArr.push(key);
    for (let confKey in tables) confArr.push(confKey);
    for (let val of allArr) if (confArr.indexOf(val) === -1) comboboxTables1c.push({ id : val, name : val });

    return (
      Object.keys(tables).map((tableName) => (
        <tr id={`table_${tables[tableName]['id']}`} key={tableName}>
          <td></td>
          <td align='left'
            className={tables[tableName]['name'] == '' || !tables1C[tableName] ? 'tables-row tables-row-1cmodule tables-row__error' : tables[tableName]['id'] == this.state.curTableId ? 'tables-row tables-row-1cmodule tables-row__active' : 'tables-row tables-row-1cmodule'}
            id={`table-row_${tables[tableName]['id']}`}
            c1name={tableName}
          >
            <table>
              <tbody>
                <tr>
                  <td style={{ position: "relative", zIndex: "3" }}>
                    <div className={`filter_row${Object.keys(this.state.edited_filters).includes(tableName) ? '' : ' hidden'}`}
                         id={`set_settings_${tables[tableName]['id']}`}
                    >
                        <img src='images/b_drop.png'
                            className='edit-table-settings'
                            table_1c={tableName}
                            onClick={this.closeFilterWindow(tableName, true)}
                        />
                        <select
                            className="form-control form-control-250"
                            table_1c={tableName}
                            onChange={this.onchangeFilterSelect()}
                            value={this.state.edited_filters[tableName]}
                        >
                            {[{id:'', name: ''}, ...(result.filters[tables[tableName]['id']] ?? [])].map((item) => (<option value={item.id}>{item.name}</option>))}
                        </select>
                        <button
                            type="button"
                            className={`save_filter-btn`}
                            onClick={(e) => {
                                this.saveFilter(tableName);
                                this.closeFilterWindow(tableName);
                            }}
                        />
                    </div>
                  </td>
                  <td className='table-settings-btn'>
                    <img id={`table_${tables[tableName]['id']}_drag_img`}
                         src="images/draggable.png"
                         className={"drag_symbol_1c"}
                         style={{ paddingLeft: "20px", position: "relative", cursor: "move", zIndex: "9999", display: "block", visibility: "hidden" }}
                    />
                  </td>
                  <td>
                    <img src='images/b_drop.png'
                         id={`delete_table_${tables[tableName]['id']}`}
                         className='edit-table-settings'
                         onClick={this.deleteTableRow(tables[tableName]['id'], tableName)}
                    />
                  </td>
                  <td>
                      <img src={syncModeImgs[tables[tableName]['mode']]}
                           id={`sync_mode_table_${tables[tableName]['id']}`}
                           className='edit-table-settings'
                           onClick={this.changeSyncModeTable(tableName)}
                      />
                  </td>
                  <td style={{ position: "relative", zIndex: "2" }}>
                    <div className={`active-row-click${tables[tableName]['id'] == this.state.editId ? ' hidden' : ''}`}
                         id={`set_settings_${tables[tableName]['id']}`}
                         onClick={result.struct == null ?
                                  this.absenceStructAttention() :
                                  (this.state.isEditMode ?
                                    this.editModeAttention() :
                                    (
                                        tables[tableName]['name'] != '' && tables1C[tableName] ?
                                        this.setFieldsConfig(tables[tableName]['id'], tables[tableName]['fields'], tableName) :
                                        null
                                    )
                                  )}
                          active-type="table"
                    >
                    </div>
                  </td>
                  <td>
                    <ComboboxSelect
                      curValue={tableName}
                      fieldId={tableName}
                      options={comboboxTables1c}
                      changeValue={this.changeSelect1cVal()}
                      allIds={ids}
                      editMode={this.state.isEditMode}
                      editId={this.state.cur1cTableName}
                    />
                  </td>
                  <td>
                    <span> = </span>
                  </td>
                  <td>
                    <ComboboxSelect
                      curValue={tables[tableName]['id'] == this.state.curTableId ? this.state.curCbTableName : tables[tableName]['name']}
                      fieldId={tables[tableName]['id'] == this.state.curTableId ? this.state.curTableId : tables[tableName]['id']}
                      options={comboboxTablesCb}
                      changeValue={this.changeSelectCbVal()}
                      allIds={ids}
                      editMode={this.state.isEditMode}
                      editId={this.state.curTableId}
                    />
                  </td>
                  <td className="config__add-settings-btn">
                    <img
                        src="./images/1c-sync-filter.png"
                        alt="Фильтр"
                        title="Фильтр"
                        onClick={this.addFilterForTable(tableName)}
                        className="open_expert_window"
                        style={{ width: '16px', display: this.state.isEditMode && this.state.editId == tables[tableName]['id'] ? 'none' : 'block' }}
                      />
                  </td>
                  <td>
                    <EditTableBtn
                      allIds={ids}
                      table={tables}
                      tabName={tableName}
                      saveValue={this.saveSelectTableValue()}
                      editMode={this.state.isEditMode}
                      editId={this.state.editId}
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          </td>
        </tr>
      ))
    )
  }

  // Добавление новой строки в раздел "Поля"
  tableFieldsConfig = () => {
    const allTablesCb = this.state.allTablesCb;
    const allTables1c = this.state.allTables1c;
    const curTableId = this.state.curTableId;
    const curTable1c = this.state.curTable1c;
    const confTables = this.state.configTables;
    const syncModeImgs = [
      'images/sync_disabled.png',
      'images/sync_passive.png',
      'images/sync_active.png',
      'images/sync_twoway.png'
    ];
    let allCurTableFieldsCb = [];
    let allCurTableFields1c = [];
    let optionsFields1c = [];
    let optionsFieldsCb = [];
    let optionsTabparts1c = [];
    let optionsSubtablesCb = [];

    // Задаем массив значений для select для полей КБ
    const configFieldsCur = confTables[curTable1c]['fields'];
    let configCbFields = {};
    let allSubtablesNames = {};
    let curSubtables = {};
    for(let subtable of result.allCbSubTables[curTableId].subtables) allSubtablesNames[subtable.id] = subtable.name;
    for(let tabpart in confTables[curTable1c].tablePart) curSubtables[confTables[curTable1c].tablePart[tabpart].id] = confTables[curTable1c].tablePart[tabpart].name;
    if (allTablesCb[curTableId] && confTables[curTable1c]) {
      allCurTableFieldsCb = allTablesCb[curTableId]['fields'];
    }
    else {
      allCurTableFieldsCb = result.allCbTables[curTableId]['fields'];
    }
    for (let row of configFieldsCur) {
      if(!curSubtables.hasOwnProperty("" + row['linkFields']['id']) || curSubtables.hasOwnProperty("" + row['linkFields']['id']) && row['linkFields']['name'] != curSubtables["" + row['linkFields']['id']]){
        configCbFields["" + row['linkFields']['id']] = row['linkFields']['name'];
      }
    }
    for (let val of allCurTableFieldsCb){
      if (!configCbFields.hasOwnProperty(val['id']) || configCbFields.hasOwnProperty(val['id']) && configCbFields[val.id] != val.name) {
        val.type = 'field';
        optionsFieldsCb.push(val);
      }
    }
    for (let subtable in allSubtablesNames){
      if(!curSubtables.hasOwnProperty(subtable)){
        optionsSubtablesCb.push({ id: 't' + subtable, name: allSubtablesNames[subtable], type: 'tabpart'});
      }
    }

    // Задаем массив значений для select для полей 1С
    const configFields = confTables[curTable1c]['fields'];
    let config1cFields = {};
    let allTabpartsNames = [];
    let curTabparts = [];
    if (allTables1c[curTable1c] && confTables[curTable1c]) {
      allCurTableFields1c = allTables1c != void 0 && Object.keys(allTables1c).length > 0 ? allTables1c[curTable1c] : [];
    }
    else {
      allCurTableFields1c = all1CTables != void 0 && Object.keys(all1CTables).length > 0 ? all1CTables[curTable1c] : [];
    }
    for(let tabpart in tables1CTabparts[curTable1c]) allTabpartsNames.push(tabpart);
    for(let tabpart in confTables[curTable1c].tablePart) curTabparts.push(tabpart);

    for (let row of configFields) config1cFields[row['name']] = row['type'];
    for (let val of allCurTableFields1c) {
      if (!config1cFields.hasOwnProperty(val) && allTabpartsNames.indexOf(val) === -1){
        optionsFields1c.push({ id: val, name : val, type: 'field' });
      }
    }
    for (let val of allTabpartsNames) {
      if (curTabparts.indexOf(val) === -1){
        optionsTabparts1c.push({ id: val, name : val, type: 'tabpart' });
      }
    }

    return (
      <>
        <tr className="noDrag">
          <td className='config-title' align='center' colSpan='2'>Настройка полей для пары таблиц <br /> "{this.state.cur1cTableName}" и "{this.state.curCbTableName}"</td>
        </tr>
        {this.state.fieldsGroup.length > 0 ?
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>
              {lang.Fields}
              <span className='help_bt' h_id='config_1c_fields'></span>:
            </td>
            <td align='left'>
            </td>
          </tr>) :
          (<tr className="noDrag">
            <td align='right' style={{ 'width': '120px' }}>
              {lang.Fields}
              <span className='help_bt' h_id='config_1c_fields'></span>:
            </td>
            <td align='left'>
              <AddButton type='fields' addNewRow={this.addNextField} />
            </td>
          </tr>)
        }

        {this.state.fieldsGroup.map((field, i) => (
          <tr id={`field_${field['linkFields']['id']}`} key={i}>
            <td></td>
            <td align='left'
              style={field['name'] === this.state.cur1cFieldName ? activeStyle : null}
              className={ !result.struct[curTable1c][field['name']] || field['linkFields']['name'] == '' ? 'field-row tables-row__error' : 'field-row'}
              cb_id={field['linkFields']['id']}
              c1_name={field['name']}
            >
              <table>
                <tbody>
                  <tr>
                    <td className='table-settings-btn' id={`${field['linkFields']['id']}`}>
                    </td>
                    <td>
                      <img src='images/b_drop.png'
                           id={`delete_field_${field['linkFields']['id']}`}
                           className='edit-table-settings'
                           onClick={this.deleteFieldRow(field['linkFields']['id'], field['name'])}
                      />
                    </td>
                    <td>
                      <img src={syncModeImgs[field.mode]}
                           id={`sync_mode_field_${field['linkFields']['id']}`}
                           className='edit-table-settings'
                           onClick={this.changeSyncModeField(field['name'])}
                      />
                    </td>
                    <td style={{ position: "relative", zIndex: "2" }}>
                      {field['linkFields']['type'] == 'tabpart' ? (<div className={`active-row-click${field['linkFields']['id'] == this.state.editFieldId ? ' hidden' : ''}`}
                          id={`set_settings_${field['type'] == 'field' ? field['linkFields']['id'] : 't' + field['linkFields']['id']}`}
                          onClick={this.state.isEditMode ?
                                    this.editModeAttention() :
                                    (
                                        result.struct[curTable1c][field['name']] && field['linkFields']['name'] != ''?
                                        this.setTabpartsConfig(field['name'], field['linkFields']['id']) :
                                        null
                                    )}
                            active-type="field"
                      ></div>) : ''}
                    </td>
                    <td>
                      <ComboboxSelect
                        curValue={field['name']}
                        fieldId={field['name']}
                        options={optionsFields1c}
                        optionsSub={optionsTabparts1c}
                        changeValue={this.changeSelect1cField()}
                        allIds={[]}
                        editMode={this.state.isEditFieldMode}
                        editId={this.state.curField1c}
                      />
                    </td>
                    <td>
                      <span> = </span>
                    </td>
                    <td>
                      <ComboboxSelect
                        curValue={field['linkFields']['name']}
                        fieldId={field.type == 'field' ? field['linkFields']['id'] : 't' + field['linkFields']['id']}
                        field1C={field['name']}
                        curField1c={this.state.curField1c}
                        options={optionsFieldsCb}
                        optionsSub={optionsSubtablesCb}
                        changeValue={this.changeSelectCbField()}
                        allIds={[]}
                        editMode={this.state.isEditFieldMode}
                        editId={this.state.curFieldCb}
                        type={field['linkFields']['type']}
                      />
                    </td>
                    <td className="config__add-settings-btn">
                      <span style={{ visibility: field.type == 'field' ? 'visible' : 'hidden', 'margin-right': '3px' }} onClick={this.openSubstitutionWindow(field['name'], field['linkFields']['name'])}>ЗЗ</span>
                      <span style={{ visibility: field.type == 'field' ? 'hidden' : 'visible' }}>ТЧ</span>
                    </td>
                    <td>
                      <EditFieldBtn
                        field1c={field['name']}
                        curField1c={this.state.curField1c}
                        fieldCb={field['linkFields']['id']}
                        id={field['linkFields']['id']}
                        saveValue={this.saveSelectFieldValue(field['name'])}
                        editMode={this.state.isEditFieldMode}
                        editId={this.state.editFieldId}
                      />
                    </td>
                  </tr>
                </tbody>
              </table>
            </td>
          </tr>
        ))}
        {this.state.fieldsGroup.length > 0 ?
        (<tr>
          <td></td>
          <td>
            <AddButton type='fields' addNewRow={this.addNextField} />
          </td>
        </tr>) : ''}

      </>
    );
  }

  tablePartFields = () => {
    const fieldsConfig = this.state.partFieldsGroup;
    const cur1cTableName = this.state.cur1cTableName;
    const allCbSubtables = this.createCbSubtablesArray(this.state.curTableId);
    const cur1cPartTable = this.state.cur1cTabPart;
    const curCbPartTable = this.state.curCbTabPart;
    const syncModeImgs = [
      'images/sync_disabled.png',
      'images/sync_passive.png',
      'images/sync_active.png',
      'images/sync_twoway.png'
    ];
    let all1cPartFields = (cur1cPartTable && cur1cPartTable.length > 0) ?
                          this.state.all1CTabParts[cur1cTableName][cur1cPartTable] :
                          Object.values(this.state.all1CTabParts[cur1cTableName])[0];
    let allCbPartFields = [];
    let allCbConfFields = [];
    let all1cConfFields = [];
    let cbOptions = [];
    let options1c = [];

    for (let elem of allCbSubtables) if (elem['id'] == curCbPartTable) allCbPartFields = elem['fields'];
    for (let el of fieldsConfig) {
      allCbConfFields.push(el['link']['id']);
      all1cConfFields.push(el['name']);
    }

    for (let item of allCbPartFields) if (allCbConfFields.indexOf(item['id']) === -1) cbOptions.push({ id: item['id'], name: item['name'] });
    for (let val of all1cPartFields) if (all1cConfFields.indexOf(val) === -1) options1c.push({ id: val, name: val });

    return (
      <>
        <tr className="noDrag">
          <td className='config-title' align='center' colSpan='2'>
            Настройка полей для пары табличная часть - подтаблица<br /> "{this.state.cur1cTabPart}" и "{this.state.curCbTabPartName}"
          </td>
        </tr>
        {fieldsConfig.length > 0 ? (<tr className="noDrag">
          <td align='right' style={{ 'width': '120px' }}>Поля<span className='help_bt' h_id='config_1c_part_fields'></span>:</td>
          <td align='left'>
          </td>
        </tr>) :
        (<tr className="noDrag">
          <td align='right' style={{ 'width': '120px' }}>Поля<span className='help_bt' h_id='config_1c_part_fields'></span>:</td>
          <td align='left'>
            <AddButton type='table-part-fields' addNewRow={this.addNextTabPartField} />
          </td>
        </tr>)}
        {fieldsConfig.map((field, i) => (
          <tr id={`field_${field['link']['id']}`} key={i}>
            <td></td>
            <td align='left'
              className='field-row'
              cb_id={field['link']['id']}
              c1_name={field['name']}
              style={field['name'] === this.state.cur1cTabPartField ? activeStyle : null}
            >
              <table>
                <tbody>
                  <tr>
                    <td className='table-settings-btn' id={`${field['link']['id']}`}>
                    </td>
                    <td>
                      <img src='images/b_drop.png'
                           className='edit-table-settings'
                           onClick={this.deletePartFieldRow(field['name'])}
                      />
                    </td>
                    <td>
                      <img src={syncModeImgs[field.mode]}
                           className='edit-table-settings'
                           onClick={this.changePartFieldMode(field['name'])}
                      />
                    </td>
                    <td>
                      <ComboboxSelect
                        curValue={field['name']}
                        fieldId={field['name']}
                        options={options1c}
                        changeValue={this.changeSelect1cPartFieldVal()}
                        allIds={[]}
                        editMode={this.state.isEditPartFieldsMode}
                        editId={this.state.cur1cTabPartField}
                      />
                    </td>
                    <td>
                      <span> = </span>
                    </td>
                    <td>
                      <ComboboxSelect
                        curValue={field['link']['name']}
                        fieldId={field['link']['id']}
                        options={cbOptions}
                        changeValue={this.changeSelectCbPartFieldVal()}
                        allIds={[]}
                        editMode={this.state.isEditPartFieldsMode}
                        editId={this.state.editPartFieldId}
                      />
                    </td>
                    <td className="config__add-settings-btn">
                    <span style={{ 'margin-right': '3px' }} onClick={this.openSubstitutionWindow(this.state.cur1cTabPart, this.state.curCbTabPart, field['name'],field['link']['name'])}>ЗЗ</span>
                    </td>
                    <td>
                      <EditPartFieldsBtn
                        field1c={field['name']}
                        fieldCb={field['link']['id']}
                        id={field['link']['id']}
                        saveValue={this.saveSelectPartFieldsValue()}
                        changeValue={!this.state.openedPartFieldRow ? this.editSelectPartFieldValue() : this.editModeAttention()}
                        editMode={this.state.isEditPartFieldsMode}
                        editId={this.state.editPartFieldId}
                      />
                    </td>
                  </tr>
                </tbody>
              </table>
            </td>
          </tr>
        ))}
        {fieldsConfig.length > 0 ? (<tr className="noDrag">
          <td align='right' style={{ 'width': '120px' }}></td>
          <td align='left'>
            <AddButton type='table-part-fields' addNewRow={this.addNextTabPartField} />
          </td>
        </tr>) : '' }
      </>
    );
  }

  // Общие настройки
  generalPageContent() {
    return (
      <>
        <tr className="noDrag">
          <td align='center' colSpan='6'>
            <a href="https://clientbase.ru/1c_sync/agent.zip" target="_blank">
              Модуль и инструкция по его установке в 1С
            </a>
          </td>
        </tr>
        <tr className="noDrag">
          <td align='center' colSpan='6' className='config-title'>{lang.Status}</td>
        </tr>
        <tr className="noDrag" style={{ boxSizing: "border-box", width: "100%" }}>
          <td align='center' colSpan='6' style={{ boxSizing: "border-box", width: "100%" }}>
            {
              null !== result.conflicts ?
                (<div style={status2}>
                  Синхронизация остановлена: есть ошибки.
                </div>) :
              null === data || void 0 === data || Object.keys(data).length < 1 ?
                (<div style={status2}>
                  Синхронизация остановлена: не настроено сопоставление таблиц и полей.
                </div>)  :
              null === result.struct || void 0 === result.struct ?
              (<div style={status3}>
                Синхронизация работает: возможны ошибки при измении сопоставления таблиц и полей, так как отсутствует структура 1С.
              </div>):
              (<div style={status1}>
                Синхронизация работает.
              </div>)
            }
          </td>
        </tr>
        <tr className='separator-row noDrag'></tr>
        <tr className="noDrag">
          <td align='center' colSpan='6' className='config-title'>{lang.Common_settings}</td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Адрес<span className='help_bt' h_id='config_1c_address'></span>:</td>
          <td align='left' colSpan='4'>
            <input type='text' style={{ boxSizing: "border-box", width: "100%" }} readOnly name="address" className='form-control' value={result.address} />
          </td>
          <td></td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Токен<span className='help_bt' h_id='config_1c_token'></span>:</td>
          <td align='left' colSpan='4'>
            <input type='text' style={{ boxSizing: "border-box", width: "100%" }} readOnly name="token" className='form-control' value={result.token} />
          </td>
          <td align='left'>
            <img src='images/b_refresh.png' className='edit-table-settings' onClick={this.refreshToken} />
          </td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Режим работы<span className='help_bt' h_id='config_1c_mode'></span>:</td>
          <td align='left' colSpan='4'>
            <select className="form-control sync-mode-select" style={{ boxSizing: "border-box", width: "100%" }} name="bond" onChange={this.setBond} value={this.state.bond} >
              <option value="0">Не синхронизировать</option>
              <option value="1">Односторонняя в 1С</option>
              <option value="2">Односторонняя в КБ</option>
              <option value="3">Двусторонняя</option>
            </select>
          </td>
          <td></td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Строгий режим<span className='help_bt' h_id='config_1c_strict'></span>:</td>
          <td align='left' colSpan='4'>
            <select className="form-control strict-mode-select" style={{ boxSizing: "border-box", width: "100%" }} name="strict" onChange={this.setStrict} value={this.state.strict} >
              <option value="0">Выключен</option>
              <option value="1">Включён</option>
            </select>
          </td>
          <td></td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Структура<span className='help_bt' h_id='config_1c_struct'></span>:</td>
          <td align='left' colSpan='4'>
            { (this.state.struct_date === void 0 || this.state.struct_date === null) && (this.state.struct === void 0 || this.state.struct === null) ?
                "отсутствует" : (this.state.struct_date !== void 0 || this.state.struct_date !== null) && (this.state.struct === void 0 || this.state.struct === null) ?
                "запрошена" :
                `получена ${this.state.struct_date}`}
          </td>
          <td>

            <input type='hidden' name='get_struct' value='0' />
            <img src='images/b_refresh.png' className='edit-table-settings' onClick={this.getStruct} />
          </td>
        </tr>
        <tr className="noDrag">
          <td align='right'>Уведомления администраторам<span className='help_bt' h_id='config_1c_admin_tips'></span>:</td>
          <td align='left' colSpan='4'>
          <select className="form-control tips-for-admin-select" style={{ boxSizing: "border-box", width: "100%" }} name="tips_for_admin" onChange={this.changeTipsForAdmin} value={this.state.tips_for_admin} >
              <option value="0">Выключены</option>
              <option value="1">Включены</option>
            </select>
          </td>
          <td>
          </td>
        </tr>
        <tr className="noDrag">
            <td colSpan='6' align='center'>
                <input type='hidden' name='initial_unloading' value='0'/>
                <span
                    className={`config__menu-item`}
                    id='conf-config'
                    style={{
                        display: 'block',
                        marginTop: '20px',
                    }}
                    onClick={() => {
                        document.querySelector('[name=initial_unloading]').value = 1;
                        document.getElementById('save_button').click();
                    }}
                >
                    Первоначальная выгрузка
                </span>
            </td>
        </tr>
        <tr className="noDrag">
            <td colSpan='6' align='center'>
                <input type='hidden' name='initial_unloading_undo' value='0'/>
                <span
                    className={`config__menu-item`}
                    id='conf-config'
                    style={{
                        display: 'block',
                    }}
                    onClick={() => {
                        document.querySelector('[name=initial_unloading_undo]').value = 1;
                        document.getElementById('save_button').click();
                    }}
                >
                    Убрать все записи из обмена
                </span>
            </td>
        </tr>
      </>
    )
  }

  // Кнопка "Сохранить"
  saveButtons() {
    return (
      <tr>
        <td colSpan='6' align='center'>
          <br />
          <input type='hidden' name='edit_cron_mode' id='edit_cron_mode' />
          <input type='hidden' name='csrf' value={csrf} />
          <input type='hidden' name='save' value='1' />
          <input type='submit' name='save' id="save_button" className='btn btn-default btn-sm save-settings-btn' value={lang.Save} onClick={this.submitForm} />
        </td>
      </tr>
    );
  }

  renderConfigBlock() {
    const configTables = this.state.configTables;
    const error = this.state.error;

    return (
      <>
        <table align='center' border='0' cellPadding='3' cellSpacing='0' style={{ minWidth: "750px" }} id="main-module-table">
          <tbody id='editTables' className='container' ref={this.dragulaDecoratorTables}>
            {configTables ?
              this.configPageContent() :
              (error ?
                this.errorMessage() :
                this.configPageContent()
              )
            }
          </tbody>
          <tbody>
            <Preloader />
          </tbody>
          {this.state.openedSettings &&
            <>
              <tbody>
                <tr className='separator-row'></tr>
              </tbody>
              <tbody id='editFields'
                    cb_table={this.state.curTableId}
                    className='container'>
                {this.tableFieldsConfig()}
              </tbody>
            </>
          }
          <tbody>
            <tr className='separator-row'></tr>
          </tbody>
        </table>
        {this.state.tabPartFieldsSettings &&
          <table style={{ marginBottom: '20px', minWidth: '750px' }}>
            <tbody>
              <tr className="separator-row"></tr>
            </tbody>
            <tbody id='editTablePartFields'>
              {this.tablePartFields()}
            </tbody>
          </table>
        }

        {this.state.curTableId && this.state.openedSettings &&
          <div>
            <span className={`config__add-tab-part-link ${this.state.tabPartsSettings ? 'hidden' : ''}`} onClick={this.showMatchingConfig()}>
              Настройка правил сопоставления
            </span>
          </div>
        }
        {this.state.matchingSettingsOpened &&
          <table style={{ minWidth: this.state.matchingDisplaySettings.tableMinWidth }} >
            <tbody>
              <tr className='separator-row'></tr>
            </tbody>
            <tbody id='editMatching' className='container' ref={this.dragulaDecoratorMatchingBlocks}>
              {this.matchingConfig()}
            </tbody>
          </table>
        }
          <table>
            <tbody>
              <tr>
                <td colSpan="2">
                    <Expert
                        show={this.state.show_expert}
                        configHandler={this.transformConfig}
                        closeHandler={this.closeExpertWindow}
                    />
                </td>
              </tr>
            </tbody>
            <tbody>
              <tr>
                <td colSpan="2">
                  {
                    this.state.show_substitution_block ? (
                        <SubstitutionBlock
                            substitutions={this.state.substitution_data}
                            table={this.state.substitution_table}
                            field={this.state.substitution_field}
                            fieldCB={this.state.substitution_field_cb}
                            subfield={this.state.substitution_subfield}
                            subfieldCB={this.state.substitution_subfield_cb}
                            saveHandler={this.saveSubstitution}
                            closeHandler={this.closeSubstitutionWindow}
                        />
                    ) : ''
                  }
                </td>
              </tr>
            </tbody>
            <tbody>
              { this.saveButtons() }
            </tbody>
          </table>
      </>
    );
  }

  renderGeneralBlock() {
    return (
      <>
        <table align='center' border='0' cellPadding='3' cellSpacing='0' style={{ width: "35%" }}>
          <tbody id='editTables'>
            {this.generalPageContent()}
          </tbody>
          <tbody>
            {this.saveButtons()}
          </tbody>
        </table>
      </>
    );
  }

  renderConflictBlock() {
    let allConflicts = this.state.conflicts;
    return (
      <>
        <table align='center' border='0' cellPadding='3' cellSpacing='0'>
          <tbody id='editTables'>
            {this.conflictPageContent()}
          </tbody>
          <tbody>
            <tr className='separator-row'></tr>
          </tbody>
          {allConflicts != null ?
            (<tbody>
              <tr>
                <td colSpan='2' align='center'>
                  <br />
                  <input type='hidden' name='edit_cron_mode' id='edit_cron_mode' />
                  <input type='hidden' name='csrf' value={csrf} />
                  <input type='hidden' name='save' value='1' />
                  <input type='hidden' name='deleteConf' value='-2' />
                  <input type='submit' style={{ display: "none" }} name='save' id='del-save-btn' className='btn btn-default btn-sm save-settings-btn' value={lang.Save} />
                  <input type='submit' name='deleteAll' className='btn btn-default btn-sm save-settings-btn' value="Удалить все" onClick={this.deleteConflict(-1)} />
                </td>
              </tr>
            </tbody>) : ""}
        </table>
      </>
    );
  }

  render() {
    const menu = this.state.menu;
    return (
      <>
        <Header changeConfig={this.changeConfigMenu} menuVal={this.state.menu} />
        <form method="post" className="config__1c-module-form">
          {menu == 1 ?
            this.renderConfigBlock() :
            (menu == 2 ?
              this.renderGeneralBlock() :
              this.renderConflictBlock()
            )
          }
        </form>
      </>
    )
  }
}

ReactDOM.render(<Config />, document.getElementById('1scync-configuration'));
