"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

exports.toTableColumns = toTableColumns;

var _react = require("react");

var _react2 = _interopRequireDefault(_react);

var _reactBootstrapTable = require("react-bootstrap-table");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var DEFAULT_TABLE_CONF = {
  cellEdit: {
    mode: "click",
    blurToSave: true
  },
  options: {},
  selectRow: {
    mode: "checkbox"
  },
  deleteRow: true,
  handleConfirmDeleteRow: function handleConfirmDeleteRow(next) {
    return next();
  }
};

var POSITION_KEY = "_position";

function addIndex(data) {
  return data.map(function (el, i) {
    return Object.assign({}, el, _defineProperty({}, POSITION_KEY, i));
  });
}

function removeIndex(data) {
  return data.map(function (el) {
    var newEl = Object.assign({}, el);
    delete newEl[POSITION_KEY];
    return newEl;
  });
}

function toDataFormat(fieldProp) {
  if (fieldProp.enum && fieldProp.enumNames) {
    return function (cell) {
      return fieldProp.enumNames[fieldProp.enum.indexOf(cell)];
    };
  }
  return undefined;
}

function toEditable(fieldProp) {
  if (fieldProp.enum) {
    if (fieldProp.enumNames) {
      var values = fieldProp.enum.map(function (value, i) {
        var text = fieldProp.enumNames[i];
        return { value: value, text: text };
      });
      return {
        type: "select",
        options: { values: values }
      };
    } else {
      return {
        type: "select",
        options: { values: fieldProp.enum }
      };
    }
  } else if (fieldProp.type === "boolean") {
    return {
      type: "checkbox"
    };
  } else if (fieldProp.type === "date-time") {
    return {
      type: "datetime"
    };
  } else if (fieldProp.type === "date") {
    return {
      type: "date"
    };
  } else if (fieldProp.type === "time") {
    return {
      type: "time"
    };
  }
  return true;
}

function setColumnCSSIfMissing(col, css) {
  col.className = col.className ? col.className : css;
  col.columnClassName = col.columnClassName ? col.columnClassName : col.className;
  col.editColumnClassName = col.editColumnClassName ? col.editColumnClassName : col.className;
}

function withColumnCss(columns) {
  var shownColumns = columns.filter(function (_ref) {
    var hidden = _ref.hidden;
    return !hidden;
  });
  var numCols = shownColumns.length;
  var colSize = Math.floor(12 / numCols);
  if (colSize === 0) {
    return columns;
  }

  var colCss = "col-md-" + colSize;
  shownColumns.forEach(function (col, i) {
    if (i !== 0) {
      setColumnCSSIfMissing(col, colCss);
    }
  });
  return columns;
}

function orderColumns(columns, order) {
  if (!order || order.length === 0) {
    return columns;
  }

  var orderedColumns = columns.filter(function (_ref2) {
    var dataField = _ref2.dataField;
    return order.includes(dataField);
  }).sort(function (a, b) {
    return order.indexOf(a.dataField) - order.indexOf(b.dataField);
  });
  if (orderedColumns.length === 0) {
    return columns;
  }
  if (orderedColumns.length === columns.length) {
    return orderedColumns;
  }

  var nonOrderedColumns = columns.filter(function (nav) {
    return !orderedColumns.includes(nav);
  });
  return orderedColumns.concat(nonOrderedColumns);
}

function toTableColumns(schema) {
  var tableCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var fields = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var properties = schema.items.properties;


  var schemaCols = Object.keys(properties).map(function (dataField) {
    var title = properties[dataField].title;

    var editable = toEditable(properties[dataField]);
    var dataFormat = toDataFormat(properties[dataField]);
    return { dataField: dataField, displayName: title, editable: editable, dataFormat: dataFormat };
  });

  var orderedSchemaColumns = orderColumns(schemaCols, tableCols.map(function (_ref3) {
    var dataField = _ref3.dataField;
    return dataField;
  }));

  var columnsWithOverrides = orderedSchemaColumns.map(function (sCol) {
    var tCol = tableCols.find(function (col) {
      return col.dataField === sCol.dataField;
    });
    if (tCol && typeof tCol.dataFormat === "string") {
      var field = tCol.dataFormat;
      tCol.dataFormat = function (cell, row) {
        return row[sCol.dataField] ? row[sCol.dataField][field] : undefined;
      };
    }
    if (tCol && tCol.field && fields[tCol.field]) {
      var FieldEditor = fields[tCol.field];
      var fieldUISchema = tCol.uiSchema;
      var fieldSchema = properties[tCol.dataField];
      tCol.customEditor = {
        getElement: function getElement(onUpdate, props) {
          return _react2.default.createElement(FieldEditor, {
            formData: props.defaultValue,
            schema: fieldSchema,
            uiSchema: fieldUISchema,
            onChange: onUpdate
          });
        }
      };
    }
    return Object.assign(sCol, tCol);
  });

  return withColumnCss(columnsWithOverrides);
}

var TableField = function (_Component) {
  _inherits(TableField, _Component);

  function TableField() {
    var _ref4;

    var _temp, _this, _ret;

    _classCallCheck(this, TableField);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref4 = TableField.__proto__ || Object.getPrototypeOf(TableField)).call.apply(_ref4, [this].concat(args))), _this), _this.toTableConf = function () {
      var _this$props = _this.props,
          _this$props$uiSchema$ = _this$props.uiSchema.table,
          table = _this$props$uiSchema$ === undefined ? {} : _this$props$uiSchema$,
          _this$props$formData = _this$props.formData,
          formData = _this$props$formData === undefined ? [] : _this$props$formData;


      if (table.keyField === undefined || table.keyField === POSITION_KEY) {
        table.keyField = POSITION_KEY;
        formData = addIndex(formData);
      }

      var tableConf = Object.assign({}, DEFAULT_TABLE_CONF, table, {
        data: formData
      });

      tableConf.cellEdit.afterSaveCell = _this.handleCellSave;
      tableConf.options.afterDeleteRow = _this.handleRowsDelete;

      return tableConf;
    }, _this.handleCellSave = function (updRow) {
      var _this$toTableConf = _this.toTableConf(),
          keyField = _this$toTableConf.keyField,
          data = _this$toTableConf.data;

      var targetKey = updRow[keyField];
      var updTable = data.map(function (row) {
        return row[keyField] === targetKey ? updRow : row;
      });

      _this.props.onChange(removeIndex(updTable));
      return updTable;
    }, _this.handleRowsDelete = function (removedKeys) {
      var _this$toTableConf2 = _this.toTableConf(),
          keyField = _this$toTableConf2.keyField,
          data = _this$toTableConf2.data;

      var filteredRows = data.filter(function (row) {
        var rowKey = row[keyField];
        return !removedKeys.includes(rowKey);
      });

      _this.props.onChange(removeIndex(filteredRows));
    }, _temp), _possibleConstructorReturn(_this, _ret);
  }

  _createClass(TableField, [{
    key: "render",
    value: function render() {
      var tableConf = this.toTableConf();
      var columns = toTableColumns(this.props.schema, tableConf.tableCols, this.props.registry.fields);

      return _react2.default.createElement(
        _reactBootstrapTable.BootstrapTable,
        tableConf,
        columns.map(function (column, i) {
          return _react2.default.createElement(
            _reactBootstrapTable.TableHeaderColumn,
            _extends({ key: i }, column),
            column.displayName
          );
        })
      );
    }
  }]);

  return TableField;
}(_react.Component);

exports.default = TableField;