menu.js 2.95 KB
Newer Older
1 2 3 4
import memoizeOne from 'memoize-one';
import isEqual from 'lodash/isEqual';
import { formatMessage } from 'umi/locale';
import Authorized from '@/utils/Authorized';
Yu's avatar
Yu committed
5
import { menu } from '../defaultSettings';
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

const { check } = Authorized;

// Conversion router to menu.
function formatter(data, parentAuthority, parentName) {
  return data
    .map(item => {
      if (!item.name || !item.path) {
        return null;
      }

      let locale = 'menu';
      if (parentName) {
        locale = `${parentName}.${item.name}`;
      } else {
        locale = `menu.${item.name}`;
      }
Yu's avatar
Yu committed
23 24 25 26 27
      // if enableMenuLocale use item.name,
      // close menu international
      const name = menu.disableLocal
        ? item.name
        : formatMessage({ id: locale, defaultMessage: item.name });
28 29
      const result = {
        ...item,
Yu's avatar
Yu committed
30
        name,
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
        locale,
        authority: item.authority || parentAuthority,
      };
      if (item.routes) {
        const children = formatter(item.routes, item.authority, locale);
        // Reduce memory usage
        result.children = children;
      }
      delete result.routes;
      return result;
    })
    .filter(item => item);
}

const memoizeOneFormatter = memoizeOne(formatter, isEqual);

/**
 * get SubMenu or Item
 */
const getSubMenu = item => {
  // doc: add hideChildrenInMenu
  if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
    return {
      ...item,
      children: filterMenuData(item.children), // eslint-disable-line
    };
  }
  return item;
};

/**
 * filter menuData
 */
const filterMenuData = menuData => {
  if (!menuData) {
    return [];
  }
  return menuData
    .filter(item => item.name && !item.hideInMenu)
70
    .map(item => check(item.authority, getSubMenu(item)))
71 72
    .filter(item => item);
};
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
/**
 * ่Žทๅ–้ขๅŒ…ๅฑ‘ๆ˜ ๅฐ„
 * @param {Object} menuData ่œๅ•้…็ฝฎ
 */
const getBreadcrumbNameMap = menuData => {
  const routerMap = {};

  const flattenMenuData = data => {
    data.forEach(menuItem => {
      if (menuItem.children) {
        flattenMenuData(menuItem.children);
      }
      // Reduce memory usage
      routerMap[menuItem.path] = menuItem;
    });
  };
  flattenMenuData(menuData);
  return routerMap;
};

const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);
94 95 96 97 98 99

export default {
  namespace: 'menu',

  state: {
    menuData: [],
Yu's avatar
Yu committed
100
    routerData: [],
101
    breadcrumbNameMap: {},
102 103 104 105 106
  },

  effects: {
    *getMenuData({ payload }, { put }) {
      const { routes, authority } = payload;
Yu's avatar
Yu committed
107 108 109
      const originalMenuData = memoizeOneFormatter(routes, authority);
      const menuData = filterMenuData(originalMenuData);
      const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(originalMenuData);
110 111
      yield put({
        type: 'save',
Yu's avatar
Yu committed
112
        payload: { menuData, breadcrumbNameMap, routerData: routes },
113 114 115 116 117 118 119 120
      });
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
121
        ...action.payload,
122 123 124 125
      };
    },
  },
};