'use strict';

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

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

require('antd/es/tabs/style');
var _Tabs = _interopDefault(require('antd/es/tabs'));
var React = require('react');
var React__default = _interopDefault(React);
var isEqual = _interopDefault(require('lodash/isEqual'));

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;
}

function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object);

  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object);
    if (enumerableOnly) symbols = symbols.filter(function (sym) {
      return Object.getOwnPropertyDescriptor(object, sym).enumerable;
    });
    keys.push.apply(keys, symbols);
  }

  return keys;
}

function _objectSpread2(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i] != null ? arguments[i] : {};

    if (i % 2) {
      ownKeys(Object(source), true).forEach(function (key) {
        _defineProperty(target, key, source[key]);
      });
    } else if (Object.getOwnPropertyDescriptors) {
      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
    } else {
      ownKeys(Object(source)).forEach(function (key) {
        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
      });
    }
  }

  return target;
}

function _objectWithoutPropertiesLoose(source, excluded) {
  if (source == null) return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;

  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0) continue;
    target[key] = source[key];
  }

  return target;
}

function _objectWithoutProperties(source, excluded) {
  if (source == null) return {};

  var target = _objectWithoutPropertiesLoose(source, excluded);

  var key, i;

  if (Object.getOwnPropertySymbols) {
    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);

    for (i = 0; i < sourceSymbolKeys.length; i++) {
      key = sourceSymbolKeys[i];
      if (excluded.indexOf(key) >= 0) continue;
      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
      target[key] = source[key];
    }
  }

  return target;
}

function _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}

function _toConsumableArray(arr) {
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}

function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

function _iterableToArray(iter) {
  if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}

function _iterableToArrayLimit(arr, i) {
  if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
  var _arr = [];
  var _n = true;
  var _d = false;
  var _e = undefined;

  try {
    for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

  return arr2;
}

function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var CONTEXT_ACTIONS;

(function (CONTEXT_ACTIONS) {
  CONTEXT_ACTIONS[CONTEXT_ACTIONS["UPDATE_TABS"] = 0] = "UPDATE_TABS";
})(CONTEXT_ACTIONS || (CONTEXT_ACTIONS = {}));

var initialState = {
  tabs: [],
  dispatch: function dispatch() {}
};

function reducer(state, action) {
  var type = action.type,
      payload = action.payload;

  switch (type) {
    case CONTEXT_ACTIONS.UPDATE_TABS:
      {
        return _objectSpread2(_objectSpread2({}, state), {}, {
          tabs: payload
        });
      }

    default:
      return state;
  }
}

var context = React__default.createContext(initialState);

function provider(props) {
  var children = props.children;

  var _useReducer = React.useReducer(reducer, initialState),
      _useReducer2 = _slicedToArray(_useReducer, 2),
      state = _useReducer2[0],
      dispatch = _useReducer2[1];

  state.dispatch = dispatch;
  return React__default.createElement(context.Provider, {
    value: state
  }, " ", children, " ");
}

function isTabActive(tabKey, location) {
  return tabKey === location.pathname;
}
function isLocationChanged(prevLoca, currLoca) {
  var key = prevLoca.key,
      otherPrevloca = _objectWithoutProperties(prevLoca, ["key"]);

  var currKey = currLoca.key,
      otherCurrloca = _objectWithoutProperties(currLoca, ["key"]);

  return !isEqual(otherPrevloca, otherCurrloca);
}

function styleInject(css, ref) {
  if ( ref === void 0 ) ref = {};
  var insertAt = ref.insertAt;

  if (!css || typeof document === 'undefined') { return; }

  var head = document.head || document.getElementsByTagName('head')[0];
  var style = document.createElement('style');
  style.type = 'text/css';

  if (insertAt === 'top') {
    if (head.firstChild) {
      head.insertBefore(style, head.firstChild);
    } else {
      head.appendChild(style);
    }
  } else {
    head.appendChild(style);
  }

  if (style.styleSheet) {
    style.styleSheet.cssText = css;
  } else {
    style.appendChild(document.createTextNode(css));
  }
}

var css = ".index_tabContainer__KpZz_ {\n  background-color: #fff;\n  padding-top: 48px;\n}\n.index_tabContainer__KpZz_ .ant-tabs-nav {\n  position: fixed;\n  top: 48px;\n  width: 100%;\n  background-color: #fff;\n}\n.index_contextMenu__GaY68 {\n  position: fixed;\n  display: none;\n  background-color: rgba(255, 255, 255, 0.98);\n  border: 1px solid #ccc;\n  list-style: none;\n  padding: 4px 0;\n  border-radius: 4px;\n  box-shadow: 0px 2px 6px 2px #ddd;\n}\n.index_contextMenu__GaY68 li {\n  padding: 8px 12px;\n  border-bottom: 1px solid #f0f2f5;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  transition: all 0.1s;\n}\n.index_contextMenu__GaY68 li:last-child {\n  border-bottom: none;\n}\n.index_contextMenu__GaY68 li:hover {\n  cursor: pointer;\n  background-color: #0170fe;\n  color: #fff;\n}\n.index_contextMenu__GaY68 li:active {\n  background-color: rgba(255, 255, 255, 0.6);\n  color: #000;\n}\n.index_show__HGFYh {\n  display: block;\n}\n.index_tabLabel__3YS8K {\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n";
var styles = {"tabContainer":"index_tabContainer__KpZz_","contextMenu":"index_contextMenu__GaY68","show":"index_show__HGFYh","tabLabel":"index_tabLabel__3YS8K"};
styleInject(css);

var ContextMenu = function ContextMenu(props) {
  var tab = props.tab,
      position = props.position,
      history = props.history,
      handleTabClose = props.handleTabClose,
      menuLabels = props.menuLabels;
  var store = React.useContext(context);
  var tabs = store.tabs,
      dispatch = store.dispatch;

  var updateTabs = function updateTabs(newTabs) {
    dispatch({
      type: CONTEXT_ACTIONS.UPDATE_TABS,
      payload: newTabs
    });
  };

  var closeTab = function closeTab() {
    if (!tab) return;
    handleTabClose(tab.location.pathname, 'remove');
  };

  var closeRightTabs = function closeRightTabs() {
    if (!tab) return;
    var index = tabs.indexOf(tab);
    if (index < 0) return;
    history.push(tab.location);
    updateTabs(tabs.slice(0, index + 1));
  };

  var closeAllTabs = function closeAllTabs() {
    history.push('/');
    updateTabs([]);
  };

  return React__default.createElement("ul", {
    className: "".concat(styles.contextMenu, " ").concat(tab && styles.show),
    style: {
      left: position === null || position === void 0 ? void 0 : position.x,
      top: position === null || position === void 0 ? void 0 : position.y
    }
  }, React__default.createElement("li", {
    onClick: closeTab
  }, (menuLabels === null || menuLabels === void 0 ? void 0 : menuLabels.closeTab) || 'Close Tab'), React__default.createElement("li", {
    onClick: closeRightTabs
  }, (menuLabels === null || menuLabels === void 0 ? void 0 : menuLabels.closeRightTabs) || 'Close Tabs to The Right'), React__default.createElement("li", {
    onClick: closeAllTabs
  }, (menuLabels === null || menuLabels === void 0 ? void 0 : menuLabels.closeAllTabs) || 'Close All Tabs'));
};

var TabPane = _Tabs.TabPane;
/**
 * TabBar component placed on top of a page
 */

var TabBar = function TabBar(props) {
  var _useState = React.useState(),
      _useState2 = _slicedToArray(_useState, 2),
      targetTab = _useState2[0],
      setTargetTab = _useState2[1];

  var _useState3 = React.useState(),
      _useState4 = _slicedToArray(_useState3, 2),
      position = _useState4[0],
      setPosition = _useState4[1];

  var store = React.useContext(context);
  var tabs = store.tabs,
      dispatch = store.dispatch;
  var location = props.location,
      defaultChildren = props.defaultChildren,
      history = props.history,
      contextMenuLabels = props.contextMenuLabels;
  var isLocationInTab = tabs.some(function (tab) {
    return tab.location.pathname === location.pathname;
  });

  var handleTabChange = function handleTabChange(key) {
    var tab = tabs.find(function (t) {
      return t.location.pathname === key;
    });

    if (tab) {
      history.push(tab.location);
    }
  };
  /**
   * Handle tab remove
   * @param tabKey Key of tab to be removed
   * @param action Name of action
   */


  var handleEdit = function handleEdit(tabKey, action) {
    if (action === 'remove') {
      var tabIndex = tabs.findIndex(function (tab) {
        return tab.location.pathname === tabKey;
      });
      if (tabIndex < 0) return;
      var nextActiveTab;

      if (isTabActive(tabKey, location)) {
        nextActiveTab = tabs[tabIndex + 1] || tabs[tabIndex - 1] || {
          location: '/'
        };
      }

      if (nextActiveTab) {
        history.push(nextActiveTab.location);
      }

      var newTabs = _toConsumableArray(tabs);

      newTabs.splice(tabIndex, 1);
      dispatch({
        type: CONTEXT_ACTIONS.UPDATE_TABS,
        payload: newTabs
      });
    }
  };
  /**
   * Show context menu when right click tab menus
   */


  var handleContextMenu = function handleContextMenu(e, tab) {
    e.preventDefault();
    setTargetTab(tab);
    setPosition({
      x: e.clientX,
      y: e.clientY
    });
  };

  var attachEvents = function attachEvents() {
    function cleanTargetTab() {
      setTargetTab(undefined);
    }

    document.addEventListener('click', cleanTargetTab);
    return function () {
      document.removeEventListener('click', cleanTargetTab);
    };
  };

  React.useEffect(attachEvents, []);
  return React__default.createElement("div", {
    className: styles.tabContainer
  }, React__default.createElement(_Tabs, {
    hideAdd: true,
    type: "editable-card",
    onChange: handleTabChange,
    onEdit: handleEdit,
    activeKey: location.pathname
  }, tabs.map(function (tab) {
    return React__default.createElement(TabPane, {
      tab: React__default.createElement("span", {
        onContextMenu: function onContextMenu(e) {
          handleContextMenu(e, tab);
        },
        className: styles.tabLabel
      }, tab.route.name),
      key: tab.location.pathname
    }, tab.children);
  })), !isLocationInTab && defaultChildren, React__default.createElement(ContextMenu, {
    tab: targetTab,
    position: position,
    history: history,
    handleTabClose: handleEdit,
    menuLabels: contextMenuLabels
  }));
};

var TabLayout = function TabLayout(props) {
  var children = props.children,
      location = props.location,
      history = props.history,
      contextMenuLabels = props.contextMenuLabels;
  return React__default.createElement(provider, null, React__default.createElement(TabBar, {
    history: history,
    location: location,
    defaultChildren: children,
    contextMenuLabels: contextMenuLabels
  }));
};

var RouteWatcher = function RouteWatcher(props) {
  var store = React.useContext(context);
  var tabs = store.tabs,
      dispatch = store.dispatch;
  var children = props.children,
      route = props.route,
      location = props.location;

  var updateTabs = function updateTabs() {
    var newTabs = _toConsumableArray(tabs);

    var exists = newTabs.find(function (t) {
      return t.route.path === route.path;
    });
    var tab = {
      route: route,
      location: location,
      children: children
    };

    if (!exists) {
      newTabs.push(tab);
    } else {
      // if tab of same route alreay exists and location change, replace the old with the new one
      if (isLocationChanged(exists.location, location)) {
        newTabs.splice(newTabs.indexOf(exists), 1, tab);
      }
    }

    dispatch({
      type: CONTEXT_ACTIONS.UPDATE_TABS,
      payload: newTabs
    });
  };

  React.useEffect(updateTabs, []);
  return React__default.createElement(React__default.Fragment, null);
};

exports.RouteWatcher = RouteWatcher;
exports.TabLayout = TabLayout;
