"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/es.regexp.exec.js");
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _warning = _interopRequireDefault(require("warning"));
var _useMergedState = _interopRequireDefault(require("rc-util/es/hooks/useMergedState"));
var _omit = _interopRequireDefault(require("omit.js"));
var _routeUtils = require("@umijs/route-utils");
var _swr = _interopRequireWildcard(require("swr"));
var _configProvider = _interopRequireDefault(require("../config-provider"));
var _layout = _interopRequireDefault(require("../layout"));
var _utils = require("../utils");
var _useMediaAntdQuery = _interopRequireDefault(require("use-media-antd-query"));
var _Header = _interopRequireDefault(require("./Header"));
var _getPageTitle = require("./getPageTitle");
var _defaultSettings = _interopRequireDefault(require("./defaultSettings"));
var _locales = _interopRequireDefault(require("./locales"));
var _Footer = _interopRequireDefault(require("./Footer"));
var _wauRouteContext = _interopRequireDefault(require("../wau-route-context"));
var _SiderMenu = _interopRequireDefault(require("./components/SiderMenu"));
var _getBreadcrumbProps = require("./utils/getBreadcrumbProps");
var _getMenuData = _interopRequireDefault(require("./utils/getMenuData"));
var _wauPageLoading = _interopRequireDefault(require("../wau-page-loading"));
var _Counter = _interopRequireDefault(require("./components/SiderMenu/Counter"));
var _WrapContent = _interopRequireDefault(require("./WrapContent"));
var _compatibleLayout = _interopRequireDefault(require("./utils/compatibleLayout"));
var _useCurrentMenuLayoutProps = _interopRequireDefault(require("./utils/useCurrentMenuLayoutProps"));
var _utils2 = require("./utils/utils");
var _jsxRuntime = require("react/jsx-runtime");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
let layoutIndex = 0;
const headerRender = (props, matchMenuKeys) => {
  if (props.headerRender === false || props.pure) {
    return null;
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Header.default, {
    matchMenuKeys: matchMenuKeys,
    ...props
  });
};
const footerRender = props => {
  if (props.footerRender === false || props.pure) {
    return null;
  }
  if (props.footerRender) {
    return props.footerRender({
      ...props
    }, /*#__PURE__*/(0, _jsxRuntime.jsx)(_Footer.default, {}));
  }
  return null;
};
const renderSiderMenu = (props, matchMenuKeys) => {
  const {
    layout,
    isMobile,
    openKeys,
    splitMenus,
    menuRender
  } = props;
  if (props.menuRender === false || props.pure) {
    return null;
  }
  let {
    menuData
  } = props;

  /** 如果是分割菜单模式，需要专门实现一下 */
  if (splitMenus && (openKeys !== false || layout === 'mix') && !isMobile) {
    const [key] = matchMenuKeys;
    if (key) {
      var _props$menuData;
      menuData = ((_props$menuData = props.menuData) === null || _props$menuData === void 0 || (_props$menuData = _props$menuData.find(item => item.key === key)) === null || _props$menuData === void 0 ? void 0 : _props$menuData.children) || [];
    } else {
      menuData = [];
    }
  }
  // 这里走了可以少一次循环
  const clearMenuData = (0, _utils2.clearMenuItem)(menuData || []);
  if (clearMenuData && (clearMenuData === null || clearMenuData === void 0 ? void 0 : clearMenuData.length) < 1 && splitMenus) {
    return null;
  }
  if (layout === 'top' && !isMobile) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SiderMenu.default, {
      matchMenuKeys: matchMenuKeys,
      ...props,
      hide: true
    });
  }
  if (menuRender) {
    const defaultDom = /*#__PURE__*/(0, _jsxRuntime.jsx)(_SiderMenu.default, {
      matchMenuKeys: matchMenuKeys,
      ...props,
      // 这里走了可以少一次循环
      menuData: clearMenuData
    });
    return menuRender(props, defaultDom);
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SiderMenu.default, {
    matchMenuKeys: matchMenuKeys,
    ...props,
    // 这里走了可以少一次循环
    menuData: clearMenuData
  });
};
const defaultPageTitleRender = (pageProps, props) => {
  const {
    pageTitleRender
  } = props;
  const pageTitleInfo = (0, _getPageTitle.getPageTitleInfo)(pageProps);
  if (pageTitleRender === false) {
    return {
      title: props.title || '',
      id: '',
      pageName: ''
    };
  }
  if (pageTitleRender) {
    const title = pageTitleRender(pageProps, pageTitleInfo.title, pageTitleInfo);
    if (typeof title === 'string') {
      return {
        ...pageTitleInfo,
        title
      };
    }
    (0, _warning.default)(typeof title === 'string', 'pro-layout: renderPageTitle return value should be a string');
  }
  return pageTitleInfo;
};
const getPaddingLeft = (hasLeftPadding, collapsed, siderWidth, collapsedWidth) => {
  if (hasLeftPadding) {
    return collapsed ? collapsedWidth : siderWidth;
  }
  return 0;
};

/**
 * 🌃 Powerful and easy to use beautiful layout 🏄‍ Support multiple topics and layout types
 *
 * @param props
 */
const BasicLayout = props => {
  var _props$prefixCls, _location$pathname;
  const {
    children,
    onCollapse: propsOnCollapse,
    location = {
      pathname: '/'
    },
    contentStyle,
    route,
    defaultCollapsed,
    style,
    disableContentMargin,
    siderWidth = 232,
    collapsedWidth = 64,
    menu,
    isChildrenLayout: propsIsChildrenLayout,
    menuDataRender,
    actionRef,
    formatMessage: propsFormatMessage,
    loading
  } = props || {};
  const context = (0, _react.useContext)(_configProvider.default.ConfigContext);
  const prefixCls = (_props$prefixCls = props.prefixCls) !== null && _props$prefixCls !== void 0 ? _props$prefixCls : context.getPrefixCls('pro');
  const [menuLoading, setMenuLoading] = (0, _utils.useMountMergeState)(false, {
    value: menu === null || menu === void 0 ? void 0 : menu.loading,
    onChange: menu === null || menu === void 0 ? void 0 : menu.onLoadingChange
  });

  // give a default key for swr
  const [defaultId] = (0, _react.useState)(() => {
    layoutIndex += 1;
    return `pro-layout-${layoutIndex}`;
  });
  const formatMessage = (0, _react.useCallback)(({
    id,
    defaultMessage,
    ...restParams
  }) => {
    if (propsFormatMessage) {
      return propsFormatMessage({
        id,
        defaultMessage,
        ...restParams
      });
    }
    const locales = (0, _locales.default)();
    return locales[id] ? locales[id] : defaultMessage;
  }, [propsFormatMessage]);
  const [menuInfoData, setMenuInfoData] = (0, _useMergedState.default)(() => (0, _getMenuData.default)((route === null || route === void 0 ? void 0 : route.routes) || [], menu, formatMessage, menuDataRender));
  const {
    breadcrumb = {},
    breadcrumbMap,
    menuData = []
  } = menuInfoData || {};
  const {
    data
  } = (0, _swr.default)(defaultId, async () => {
    var _menu$request;
    setMenuLoading(true);
    const msg = await (menu === null || menu === void 0 || (_menu$request = menu.request) === null || _menu$request === void 0 ? void 0 : _menu$request.call(menu, (menu === null || menu === void 0 ? void 0 : menu.params) || {}, (route === null || route === void 0 ? void 0 : route.routes) || []));
    setMenuLoading(false);
    return msg;
  }, {
    revalidateOnFocus: false,
    shouldRetryOnError: false,
    revalidateOnReconnect: false
  });

  // params 更新的时候重新请求
  (0, _react.useEffect)(() => {
    if (!data) {
      return;
    }
    (0, _swr.mutate)(defaultId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [defaultId, (0, _utils.safeJSONStringify)(menu === null || menu === void 0 ? void 0 : menu.params)]);
  if (actionRef && menu !== null && menu !== void 0 && menu.request) {
    actionRef.current = {
      reload: () => {
        (0, _swr.mutate)(defaultId);
      }
    };
  }
  (0, _utils.useDeepCompareEffect)(() => {
    if (!(menu !== null && menu !== void 0 && menu.request) || !(data !== null && data !== void 0 && data.length)) {
      return;
    }
    const menuDataMap = (0, _getMenuData.default)(data || (route === null || route === void 0 ? void 0 : route.routes) || [], menu, formatMessage, menuDataRender);
    setMenuInfoData(menuDataMap);
  }, [data, menu === null || menu === void 0 ? void 0 : menu.request, menu === null || menu === void 0 ? void 0 : menu.loading, route === null || route === void 0 ? void 0 : route.routes]);
  const matchMenus = (0, _react.useMemo)(() => {
    return (0, _routeUtils.getMatchMenu)(location.pathname || '/', menuData || [], true);
  }, [location.pathname, menuData]);
  const matchMenuKeys = (0, _react.useMemo)(() => Array.from(new Set(matchMenus.map(item => item.key || item.path || ''))), [matchMenus]);

  // 当前选中的menu，一般不会为空
  const currentMenu = matchMenus[matchMenus.length - 1] || {};
  const currentMenuLayoutProps = (0, _useCurrentMenuLayoutProps.default)(currentMenu);
  const {
    fixSiderbar,
    navTheme,
    layout: defaultPropsLayout,
    ...rest
  } = {
    ...props,
    ...currentMenuLayoutProps
  };
  const propsLayout = (0, _compatibleLayout.default)(defaultPropsLayout);
  const colSize = (0, _useMediaAntdQuery.default)();
  const isMobile = (colSize === 'sm' || colSize === 'xs') && !props.disableMobile;

  /** 如果 menuRender 不存在，可以做一下性能优化 只要 routers 没有更新就不需要重新计算 */
  (0, _utils.useDeepCompareEffect)(() => {
    if (menu !== null && menu !== void 0 && menu.loading || menu !== null && menu !== void 0 && menu.request) {
      return () => null;
    }
    const infoData = (0, _getMenuData.default)((route === null || route === void 0 ? void 0 : route.routes) || [], menu, formatMessage, menuDataRender);
    // 稍微慢一点 render，不然会造成性能问题，看起来像是菜单的卡顿
    const animationFrameId = requestAnimationFrame(() => {
      setMenuInfoData(infoData);
    });
    return () => window.cancelAnimationFrame && window.cancelAnimationFrame(animationFrameId);
  }, [menu === null || menu === void 0 ? void 0 : menu.loading, menu === null || menu === void 0 ? void 0 : menu.request, route === null || route === void 0 ? void 0 : route.routes, location === null || location === void 0 ? void 0 : location.pathname, menuDataRender]);

  // If it is a fix menu, calculate padding
  // don't need padding in phone mode
  const hasLeftPadding = propsLayout !== 'top' && !isMobile;
  const [collapsed, onCollapse] = (0, _useMergedState.default)(() => defaultCollapsed || false, {
    value: props.collapsed,
    onChange: propsOnCollapse
  });

  // Splicing parameters, adding menuData and formatMessage in props
  const defaultProps = (0, _omit.default)({
    prefixCls,
    ...props,
    siderWidth,
    ...currentMenuLayoutProps,
    formatMessage,
    breadcrumb,
    menu: {
      ...menu,
      loading: menuLoading
    },
    layout: propsLayout
  }, ['className', 'style', 'breadcrumbRender']);

  // gen page title
  const pageTitleInfo = defaultPageTitleRender({
    pathname: location.pathname,
    ...defaultProps,
    breadcrumbMap
  }, props);

  // gen breadcrumbProps, parameter for pageHeader
  const breadcrumbProps = (0, _getBreadcrumbProps.getBreadcrumbProps)({
    ...defaultProps,
    breadcrumbRender: props.breadcrumbRender,
    breadcrumbMap
  });

  // render sider dom
  const siderMenuDom = renderSiderMenu({
    ...defaultProps,
    menuData,
    onCollapse,
    isMobile,
    theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light',
    collapsed
  }, matchMenuKeys);

  // render header dom
  const headerDom = headerRender({
    ...defaultProps,
    hasSiderMenu: !!siderMenuDom,
    menuData,
    isMobile,
    collapsed,
    onCollapse,
    theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light'
  }, matchMenuKeys);

  // render footer dom
  const footerDom = footerRender({
    isMobile,
    collapsed,
    ...defaultProps
  });
  const {
    isChildrenLayout: contextIsChildrenLayout
  } = (0, _react.useContext)(_wauRouteContext.default);

  // 如果 props 中定义，以 props 为准
  const isChildrenLayout = propsIsChildrenLayout !== undefined ? propsIsChildrenLayout : contextIsChildrenLayout;
  const baseClassName = `${prefixCls}-basicLayout`;
  // gen className
  const className = (0, _classnames.default)(props.className, 'ant-design-pro', baseClassName, {
    [`screen-${colSize}`]: colSize,
    [`${baseClassName}-top-menu`]: propsLayout === 'top',
    [`${baseClassName}-is-children`]: isChildrenLayout,
    [`${baseClassName}-fix-siderbar`]: fixSiderbar,
    [`${baseClassName}-${propsLayout}`]: propsLayout
  });

  /** 计算 slider 的宽度 */
  const leftSiderWidth = getPaddingLeft(!!hasLeftPadding, collapsed, siderWidth, collapsedWidth);

  // siderMenuDom 为空的时候，不需要 padding
  const genLayoutStyle = {
    position: 'relative'
  };

  // if is some layout children, don't need min height
  if (isChildrenLayout || contentStyle && contentStyle.minHeight) {
    genLayoutStyle.minHeight = 0;
  }
  const contentClassName = (0, _classnames.default)(`${baseClassName}-content`, {
    [`${baseClassName}-has-header`]: headerDom,
    [`${baseClassName}-content-disable-margin`]: disableContentMargin
  });

  /** 页面切换的时候触发 */
  (0, _react.useEffect)(() => {
    var _props$onPageChange;
    (_props$onPageChange = props.onPageChange) === null || _props$onPageChange === void 0 ? void 0 : _props$onPageChange.call(props, props.location);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location.pathname, (_location$pathname = location.pathname) === null || _location$pathname === void 0 ? void 0 : _location$pathname.search]);
  const [hasFooterToolbar, setHasFooterToolbar] = (0, _react.useState)(false);
  (0, _utils.useDocumentTitle)(pageTitleInfo, props.title || false);
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Counter.default.Provider, {
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_wauRouteContext.default.Provider, {
      value: {
        ...defaultProps,
        breadcrumb: breadcrumbProps,
        menuData,
        isMobile,
        collapsed,
        isChildrenLayout: true,
        title: pageTitleInfo.pageName,
        hasSiderMenu: !!siderMenuDom,
        hasHeader: !!headerDom,
        siderWidth: leftSiderWidth,
        hasFooter: !!footerDom,
        hasFooterToolbar,
        setHasFooterToolbar,
        pageTitleInfo,
        matchMenus,
        matchMenuKeys,
        currentMenu
      },
      children: props.pure ? children : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
        className: className,
        children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_layout.default, {
          style: {
            minHeight: '100%',
            ...style
          },
          children: [siderMenuDom, /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
            style: genLayoutStyle,
            className: context.getPrefixCls('layout'),
            children: [headerDom, /*#__PURE__*/(0, _jsxRuntime.jsx)(_WrapContent.default, {
              isChildrenLayout: isChildrenLayout,
              ...rest,
              className: contentClassName,
              style: contentStyle,
              children: loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_wauPageLoading.default, {}) : children
            }), footerDom]
          })]
        })
      })
    })
  });
};
BasicLayout.defaultProps = {
  logo: 'data:image/png;base64, ',
  ..._defaultSettings.default,
  location: (0, _utils.isBrowser)() ? window.location : undefined
};
var _default = BasicLayout;
exports.default = _default;