lodash#isBoolean JavaScript Examples

The following examples show how to use lodash#isBoolean. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
function changelogFormatTransformer(accumulatorArray, changes, key) {
  let valueBefore, valueAfter;
  if (changes.length === 2) [valueBefore, valueAfter] = changes;
  if (changes.length === 1) [valueAfter] = changes;

  const label = getLabel(key);
  let displayedValueBefore = getDisplayValue(valueBefore);
  const displayedValueAfter = getDisplayValue(valueAfter);

  if (isBoolean(valueAfter) && isUndefined(valueBefore)) {
    displayedValueBefore = getDisplayValue(false);
  }

  const separator =
    (displayedValueBefore || '').toString().length < 120 ? '"' : '\n\n';

  accumulatorArray.push(
    `Changement ${label} de ${separator}${displayedValueBefore}${separator} en ${separator}${displayedValueAfter}${separator}`
  );

  return accumulatorArray;
}
Example #2
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
getDisplayValue = (rawValue) => {
  if (isBoolean(rawValue)) {
    return rawValue ? 'coché' : 'décoché';
  }

  if (isUndefined(rawValue)) {
    return 'non renseigné';
  }

  return rawValue;
}
Example #3
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
getStateFromUrlParams = (defaultState = {}) => {
  const urlParams = new URLSearchParams(window.location.search);

  return mapValues(defaultState, (value, key) => {
    if (!urlParams.has(key)) {
      return value;
    }

    const param = urlParams.getAll(key);

    if (isObject(value)) {
      return JSON.parse(param[0]);
    }

    if (isInteger(value)) {
      return parseInt(param[0]) || value;
    }

    if (isBoolean(value)) {
      return param[0] === 'true';
    }

    return param[0];
  });
}
Example #4
Source File: index.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
// field props
  getTabPaneConfigOfPropValues(allValues, newConfig) {
    if (isBoolean(allValues.forceRender)) {
      newConfig.push({
        attributeName: 'forceRender',
        attributeType: DataType.Boolean,
        value: allValues.forceRender,
      });
    }
  }
Example #5
Source File: DatePicker.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isBoolean(propValues.showToday)) {
    newConfig.push({
      [attributeNameProp]: 'showToday',
      [attributeValueProp]: propValues.showToday,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  return newConfig;
}
Example #6
Source File: Input.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
render() {
    const { form, propValues = {} } = this.props;
    return (
      <React.Fragment>
        <Form.Item>
          {form.getFieldDecorator('inputChinese', {
            initialValue: isBoolean(propValues.inputChinese) ? propValues.inputChinese : true,
          })(
            <Checkbox checkedValue={false} unCheckedValue>
              不允许输入中文
            </Checkbox>
          )}
        </Form.Item>
        <Form.Item>
          {form.getFieldDecorator('trimAll', {
            initialValue: isBoolean(propValues.trimAll) ? propValues.trimAll : false,
          })(
            <Checkbox checkedValue unCheckedValue={false}>
              删除所有空格
            </Checkbox>
          )}
        </Form.Item>
        <Form.Item label="大小写转换">
          {form.getFieldDecorator('typeCase', {
            initialValue: propValues.typeCase,
          })(<ValueList options={typeCaseOptions} className={pageStyles['full-width']} />)}
        </Form.Item>
      </React.Fragment>
    );
  }
Example #7
Source File: Input.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isBoolean(propValues.inputChinese)) {
    newConfig.push({
      [attributeNameProp]: 'inputChinese',
      [attributeValueProp]: propValues.inputChinese,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.typeCase)) {
    newConfig.push({
      [attributeNameProp]: 'typeCase',
      [attributeValueProp]: propValues.typeCase,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isBoolean(propValues.trimAll)) {
    newConfig.push({
      [attributeNameProp]: 'trimAll',
      [attributeValueProp]: propValues.trimAll,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  return newConfig;
}
Example #8
Source File: InputNumber.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isBoolean(propValues.allowThousandth)) {
    newConfig.push({
      [attributeNameProp]: 'allowThousandth',
      [attributeValueProp]: propValues.allowThousandth,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  if (isNumber(propValues.precision)) {
    newConfig.push({
      [attributeNameProp]: 'precision',
      [attributeValueProp]: propValues.precision,
      [attributeTypeProp]: DataType.Number,
    });
  }
  if (isNumber(propValues.max)) {
    newConfig.push({
      [attributeNameProp]: 'max',
      [attributeValueProp]: propValues.max,
      [attributeTypeProp]: DataType.Number,
    });
  }
  if (isNumber(propValues.min)) {
    newConfig.push({
      [attributeNameProp]: 'min',
      [attributeValueProp]: propValues.min,
      [attributeTypeProp]: DataType.Number,
    });
  }
  if (isNumber(propValues.step)) {
    newConfig.push({
      [attributeNameProp]: 'step',
      [attributeValueProp]: propValues.step,
      [attributeTypeProp]: DataType.Number,
    });
  }
  return newConfig;
}
Example #9
Source File: Lov.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isString(propValues.code)) {
    newConfig.push({
      [attributeNameProp]: 'code',
      [attributeValueProp]: propValues.code,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isBoolean(propValues.cascadeFlag)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFlag',
      [attributeValueProp]: propValues.cascadeFlag,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  if (isString(propValues.cascadeFrom)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFrom',
      [attributeValueProp]: propValues.cascadeFrom,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.cascadeField)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeField',
      [attributeValueProp]: propValues.cascadeField,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.textField)) {
    newConfig.push({
      [attributeNameProp]: 'textField',
      [attributeValueProp]: propValues.textField,
      [attributeTypeProp]: DataType.String,
    });
  }
  return newConfig;
}
Example #10
Source File: index.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
/**
   * deal component attribute change
   */
  handleComponentValuesChange(props, changeValues, allValues) {
    // 使用 allValues 重写 component 的属性
    // use allValues override component's props
    const { component, onRefresh } = this.props;
    const { validateFields } = this.editFormRef.current || {};
    if (validateFields) {
      validateFields(err => {
        if (!err) {
          const newConfig = [];
          // common component's prop;
          component.templateCode = allValues.templateCode;
          component.description = allValues.description;
          // todo enabledFlag 没有了
          // component.enabledFlag = allValues.enabledFlag;

          // DynamicForm's attributes;

          // 查询URL
          if (isString(allValues.queryUrl)) {
            newConfig.push({
              [attributeNameProp]: 'queryUrl',
              [attributeValueProp]: allValues.queryUrl,
              [attributeTypeProp]: DataType.String,
            });
          }
          // 提交URL
          if (isString(allValues.submitUrl)) {
            newConfig.push({
              [attributeNameProp]: 'submitUrl',
              [attributeValueProp]: allValues.submitUrl,
              [attributeTypeProp]: DataType.String,
            });
          }
          // // 提交事件
          // if (isString(allValues.submit)) {
          //   newConfig.push({
          //     [attributeNameProp]: 'submit',
          //     [attributeValueProp]: allValues.submit,
          //     [attributeTypeProp]: DataType.String,
          //   });
          // }
          // 数据主键
          if (isString(allValues.rowKey)) {
            newConfig.push({
              [attributeNameProp]: 'rowKey',
              [attributeValueProp]: allValues.rowKey,
              [attributeTypeProp]: DataType.String,
            });
          }
          // 是否可编辑
          if (isBoolean(allValues.editable)) {
            newConfig.push({
              [attributeNameProp]: 'editable',
              [attributeValueProp]: allValues.editable,
              [attributeTypeProp]: DataType.Boolean,
            });
          }

          const prevComponentConfigs = component.config;
          component.config = newConfig.map(componentConfig => {
            const prevComponentConfig = find(
              prevComponentConfigs,
              prevC => prevC[attributeNameProp] === componentConfig[attributeNameProp]
            );
            return { ...prevComponentConfig, ...componentConfig };
          });
          if (isFunction(onRefresh)) {
            onRefresh();
          }
        }
      });
    }
  }
Example #11
Source File: ValueList.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isString(propValues.lovCode)) {
    newConfig.push({
      [attributeNameProp]: 'lovCode',
      [attributeValueProp]: propValues.lovCode,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.queryUrl)) {
    newConfig.push({
      [attributeNameProp]: 'queryUrl',
      [attributeValueProp]: propValues.queryUrl,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isBoolean(propValues.lazyLoad)) {
    newConfig.push({
      [attributeNameProp]: 'lazyLoad',
      [attributeValueProp]: propValues.lazyLoad,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  if (isString(propValues.valueField)) {
    newConfig.push({
      [attributeNameProp]: 'valueField',
      [attributeValueProp]: propValues.valueField,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.displayField)) {
    newConfig.push({
      [attributeNameProp]: 'displayField',
      [attributeValueProp]: propValues.displayField,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.textField)) {
    newConfig.push({
      [attributeNameProp]: 'textField',
      [attributeValueProp]: propValues.textField,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isBoolean(propValues.cascadeFlag)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFlag',
      [attributeValueProp]: propValues.cascadeFlag,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  if (isString(propValues.cascadeFrom)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFrom',
      [attributeValueProp]: propValues.cascadeFrom,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.cascadeField)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeField',
      [attributeValueProp]: propValues.cascadeField,
      [attributeTypeProp]: DataType.String,
    });
  }
  return newConfig;
}
Example #12
Source File: RegisterSymbols.js    From bonded-stablecoin-ui with MIT License 4 votes vote down vote up
RegisterSymbols = (props) => {
  let initCurrentStep = 0;
  if (!props.symbol1 && !props.pendings.tokens1) {
    initCurrentStep = 0;
  } else if (!props.symbol2 && !props.pendings.tokens2) {
    initCurrentStep = 1;
  } else if (!props.symbol3 && !props.pendings.tokens3) {
    initCurrentStep = 2;
  } else if (!props.symbol4 && !props.pendings.tokens4) {
    initCurrentStep = 3;
  }

  const [width] = useWindowSize();
  const [currentStep, setCurrentStep] = useState(initCurrentStep);
  const currentSymbol = currentStep + 1;
  const [isAvailable, setIsAvailable] = useState(undefined);
  const [symbolByCurrentAsset, setSymbolByCurrentAsset] = useState(undefined);
  const [token, setToken] = useState(initStateValue);
  const [tokenSupport, setTokenSupport] = useState(initStateValue);
  const [descr, setDescr] = useState(initStateValue);
  const { params, bonded_state } = useSelector((state) => state.active);
  const { t } = useTranslation();
  const checkRef = useRef(null);
  const regRef = useRef(null);
  const symbolInputRef = useRef(null);

  let currentAsset;

  if (currentSymbol === 1 || currentSymbol === 2 || currentSymbol === 3) {
    currentAsset = props["asset" + currentSymbol];
  } else if (currentSymbol === 4) {
    currentAsset = props.fund_asset;
  }

  let currentDecimals;

  if (currentSymbol === 3 || currentSymbol === 2) {
    currentDecimals = props.decimals2;
  } else if (currentSymbol === 4) {
    currentDecimals = props.reserve_asset_decimals;
  } else {
    currentDecimals = props.decimals1;
  }

  useEffect(() => {
    if (!props.symbol1 && !props.pendings.tokens1) {
      setCurrentStep(0);
    } else if (!props.symbol2 && !props.pendings.tokens2) {
      setCurrentStep(1);
    } else if (!props.symbol3 && !props.pendings.tokens3) {
      setCurrentStep(2);
    } else if (!props.symbol4 && !props.pendings.tokens4) {
      setCurrentStep(3);
    }
  }, [props]);

  useEffect(() => {
    setIsAvailable(undefined);
    setToken(initStateValue);
    setTokenSupport(initStateValue);
    setDescr(initStateValue);
    (async () => {
      const symbol = await socket.api.getSymbolByAsset(
        config.TOKEN_REGISTRY,
        currentAsset
      );
      if (symbol !== currentAsset.replace(/[+=]/, "").substr(0, 6)) {
        setSymbolByCurrentAsset(symbol);
      } else {
        setSymbolByCurrentAsset(null);
      }
    })();
  }, [currentStep, setSymbolByCurrentAsset, currentAsset]);

  useEffect(() => {
    if (isAvailable === null) {
      (async () => {
        const asset = await socket.api.getAssetBySymbol(
          config.TOKEN_REGISTRY,
          token.value
        );
        if (!!asset) {
          setIsAvailable(false);
        } else {
          setIsAvailable(true);
          let initDescr;
          const targetCurrency = getTargetCurrency(params, bonded_state);

          if (currentSymbol === 4) {
            initDescr = `Stability fund shares for ${targetCurrency}-pegged stablecoin (${props.address})`;
          } if (currentSymbol === 3) {
            initDescr = `Stable token for ${targetCurrency}-pegged stablecoin (${props.address})`;
          } else if (currentSymbol === 2) {
            initDescr = `Interest token for ${targetCurrency}-pegged stablecoin (${props.address})`;
          } else if (currentSymbol === 1) {
            initDescr = `Growth token for ${targetCurrency}-pegged stablecoin (${props.address})`;
          }

          setDescr({
            value: initDescr,
            valid: true,
          });

          setTokenSupport({ value: "0.1", valid: true })
        }
      })();
      symbolInputRef?.current.blur();
    } else if (isAvailable === undefined) {
      symbolInputRef?.current.focus({
        cursor: 'start',
      });
    }
  }, [isAvailable, props.address, currentSymbol]);

  const data = {
    asset: currentAsset,
    symbol: token.value,
    decimals:
      (isAvailable && !symbolByCurrentAsset && currentDecimals) || undefined,
    description:
      (isAvailable && descr.valid && !symbolByCurrentAsset && descr.value) ||
      undefined,
  };

  const handleChangeSymbol = (ev) => {
    const targetToken = ev.target.value.toUpperCase();
    // eslint-disable-next-line no-useless-escape
    const reg = /^[0-9A-Z_\-]+$/;
    if (reg.test(targetToken) || !targetToken) {
      if (targetToken.length > 0) {
        if (targetToken.length <= 40) {
          if (reservedTokens.find((t) => targetToken === t)) {
            setToken({ ...token, value: targetToken, valid: false });
          } else {
            setToken({ ...token, value: targetToken, valid: true });
          }
        } else {
          setToken({
            ...token,
            value: targetToken,
            valid: false,
          });
        }
      } else {
        setToken({ ...token, value: targetToken, valid: false });
      }
    }
  };
  const handleChangeSupport = (ev) => {
    const support = ev.target.value;
    const reg = /^[0-9.]+$/;
    const f = (x) =>
      ~(x + "").indexOf(".") ? (x + "").split(".")[1].length : 0;
    if (support) {
      if (reg.test(support) && f(support) <= 9) {
        if (Number(support) >= 0.1) {
          setTokenSupport({ ...token, value: support, valid: true });
        } else {
          setTokenSupport({ ...token, value: support, valid: false });
        }
      }
    } else {
      setTokenSupport({ ...token, value: "", valid: false });
    }
  };
  const handleChangeDescr = (ev) => {
    const { value } = ev.target;
    if (value.length < 140) {
      setDescr({ value, valid: true });
    } else {
      setDescr({ value, valid: false });
    }
  };

  let helpSymbol = undefined;
  if (isBoolean(isAvailable)) {
    if (isAvailable) {
      helpSymbol = t("reg_symbol.available", "Symbol name {{value}} is available, you can register it", { value: token.value });
    } else {
      helpSymbol = t("reg_symbol.taken", "This token name is already taken. This will start a dispute");
    }
  }

  const clickOnRegBtn = (ev) => {
    if (ev.key === "Enter") {
      if (token.valid && descr.valid && tokenSupport.valid) {
        regRef.current.click();
      }
    }
  }

  return (
    <div>
      <Title level={3} type="secondary">
        {t("reg_symbol.title", "Register symbols")}
      </Title>

      <Steps
        current={currentStep}
        style={{ marginTop: 20 }}
        direction={width > 800 ? "horizontal" : "vertical"}
      >
        <Step title={t("reg_symbol.step_growth", "Symbol for growth token")} />
        <Step title={t("reg_symbol.step_interest", "Symbol for interest token")} />
        <Step style={!props.interest ? { display: 'none' } : {}} title={t("reg_symbol.step_stable", "Symbol for stable tokens")} />
        {props.isV2 && <Step title={t("reg_symbol.step_fond", "Symbol for fund tokens")} />}
      </Steps>

      {symbolByCurrentAsset && (
        <p style={{ paddingTop: 20, maxWidth: 600 }}>
          <Text type="secondary">
            {t("reg_symbol.taken_desc", "This stablecoin already has a symbol {{symbol}} assigned to it. Attempting to assign a new symbol will start a dispute process which can take more than 30 days. The symbol that gets more support (in terms of GBYTE deposits) eventually wins.", { symbol: symbolByCurrentAsset })}
          </Text>
        </p>
      )}
      <Form size="large" style={{ marginTop: 35 }}>
        <Form.Item
          hasFeedback
          extra={helpSymbol}
          validateStatus={
            (isAvailable === false && "warning") ||
            (isAvailable === true && "success")
          }
        >
          <Input
            placeholder={t("reg_symbol.symbol", "Symbol")}
            allowClear
            autoFocus={true}
            ref={symbolInputRef}
            disabled={isBoolean(isAvailable)}
            autoComplete="off"
            value={token.value}
            onChange={handleChangeSymbol}
            onKeyPress={(ev) => {
              if (ev.key === "Enter") {
                if (token.valid) {
                  checkRef.current.click();
                }
              }
            }}
          />
        </Form.Item>
        {isAvailable !== undefined && isAvailable !== null && (
          <Form.Item>
            <Input
              placeholder={t("reg_symbol.placeholder_support", "Support (Min amount 0.1 GB)")}
              suffix="GB"
              autoComplete="off"
              value={tokenSupport.value}
              onChange={handleChangeSupport}
              autoFocus={isBoolean(isAvailable)}
              onKeyPress={clickOnRegBtn}
            />
          </Form.Item>
        )}
        {isAvailable === true && !symbolByCurrentAsset && (
          <Form.Item>
            <Form.Item
              hasFeedback
            // validateStatus={descr && !descr.valid ? "error" : null}
            >
              <Input.TextArea
                style={{ fontSize: 16 }}
                rows={5}
                value={descr.value}
                onChange={handleChangeDescr}
                placeholder={t("reg_symbol.placeholder_desc", "Description of an asset (up to 140 characters)")}
              />
            </Form.Item>
          </Form.Item>
        )}
        <Form.Item>
          <Space>
            {isAvailable === undefined || isAvailable === null ? (
              <Button
                onClick={() => {
                  setIsAvailable(null);
                }}
                key="btn-check"
                loading={isAvailable === null}
                disabled={token.value === "" || !token.valid}
                ref={checkRef}
              >
                {t("reg_symbol.check_availability", "Check availability")}
              </Button>
            ) : (
              <QRButton
                disabled={!token.valid || !tokenSupport.valid}
                key="btn-reg"
                ref={regRef}
                href={generateLink(
                  tokenSupport.value * 1e9,
                  data,
                  props.activeWallet,
                  config.TOKEN_REGISTRY
                )}
              >
                {isAvailable && !symbolByCurrentAsset
                  ? t("reg_symbol.register", "Register")
                  : t("reg_symbol.register_anyway", "Register anyway")}
              </QRButton>
            )}
            <Button
              type="link"
              danger
              onClick={() => {
                props.handleSkip(true);
              }}
            >
              {t("reg_symbol.skip", "Skip")}
            </Button>
          </Space>
        </Form.Item>
      </Form>
    </div>
  );
}
Example #13
Source File: global.js    From hzero-front with Apache License 2.0 4 votes vote down vote up
function getGlobalModalConfig({ app, getWrapperRouterData = (e) => e }) {
  return {
    namespace: 'global',

    state: {
      collapsed: false,
      menu: [],
      language: '', // 当前语言
      // language: 'zh_CN',
      hzeroUILocale: {}, // 组件的国际化
      supportLanguage: [],
      routerData: {},
      notices: [],
      announces: [],
      layoutLoading: false,
      count: 0,
      menuLeafNode: [],
      tabs: [],
      activeTabKey: '/workplace',
      traceLogInfo: {}, // trace 数据
      traceStatus: false, // trace 状态
      traceGroupId: undefined, // trace id
      tabsIsInit: false, // menuTabs 初始化完成
      menuLoad: false, // 菜单加载完毕
      activeTabMenuId: undefined,
    },

    effects: {
      /**
       * 首屏 预加载内容
       * 初始化语言和菜单数据
       */ *init({ payload: { organizationId, language } }, { call, put, all }) {
        // 第一次加载肯定是没有切换语言的
        localLangCache[language] = {};
        const promiseAllLocale = [
          call(queryPromptLocale, organizationId, language, 'hzero.common'),
        ];
        const [promptLocale] = yield all(promiseAllLocale);
        const safePromptLocale = getResponse(promptLocale);
        const loadLocales = (intl && intl.options && intl.options.locales) || {}; // 设置或切换 当前intl的语言
        intl.init({
          currentLocale: language,
          locales: loadLocales,
          warningHandler: (/* e */) => {
            // todo
            // console.warn(e);
          },
        });
        intl.load({
          [language]: safePromptLocale,
        });
        yield put({
          type: 'loadUILocale',
          payload: {
            language,
          },
        });

        // 初始化 menuTabs
        yield put({ type: 'initMenuTabs' });
        // tab 初始化完成后才进入 menuTab 处理流程
        tabListen();
      },
      *lazyInit({ payload: { organizationId, language } }, { call, put, all }) {
        const [supportLanguage] = yield all([
          call(querySupportLanguage),
          // 获取角色列表, 角色切换用到
          put({ type: 'user/fetchRoleList', payload: { organizationId } }),
          // 获取动态表格数据
        ]);
        const safeSupportLanguage = getResponse(supportLanguage);
        const list = [];
        const menuListRes = yield call(queryMenu, { lang: language });
        const menuList = getResponse(menuListRes);
        const menuLocaleIntl = {};
        parseMenuToLocaleIntl(menuList, menuLocaleIntl);
        parseMenuData(list, null, menuList || []);
        const menus = list;
        parseMenuToLocaleIntl(menuList, menuLocaleIntl);
        intl.load({
          [language]: menuLocaleIntl,
        });
        const menuData = getFlatMenuData(menus);
        const routerConfig = getWrapperRouterData(app || getDvaApp());
        const routerData = {};
        // The route matches the menu
        Object.keys(routerConfig).forEach((path) => {
          // Regular match item name
          // eg.  router /user/:id === /user/chen
          const pathRegexp = pathToRegexp(path);
          const menuKey = Object.keys(menuData).find((key) => pathRegexp.test(`${key}`));
          let menuItem = {};
          // If menuKey is not empty
          if (menuKey) {
            menuItem = menuData[menuKey];
          }
          let router = routerConfig[path];
          // If you need to configure complex parameter routing,
          // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
          // eg . /list/:type/user/info/:id
          router = {
            ...router,
            name: router.name || menuItem.name,
            // tab 用到的数据
            pathRegexp,
            title: router.title || menuItem.name,
            icon: router.icon || menuItem.icon,
            closable: isBoolean(router.closable) ? router.closable : true,
            path,
            // tab 用到的数据
            authority: router.authority || menuItem.authority,
            hideInBreadcrumb: router.hideInBreadcrumb || menuItem.hideInBreadcrumb,
          };
          routerData[path] = router;
        });
        const queryMenus = getMenuNodeList(menus, []);

        yield put({
          type: 'updateState',
          payload: {
            routerData,
            language,
            menu: menus,
            menuLeafNode: queryMenus,
            supportLanguage: safeSupportLanguage,
            // 菜单加载完毕
            menuLoad: true,
          },
        });
      },
      *fetchCount(_, { call, put }) {
        const data = yield call(queryCount);
        if (data && isNumber(data.unreadMessageCount)) {
          const { unreadMessageCount } = data;
          yield put({
            type: 'saveNotices',
            payload: { count: unreadMessageCount },
          });
        }
      },
      *changeLanguage({ payload }, { put }) {
        const language = payload;
        const organizationId = getCurrentOrganizationId();
        const roleId = getCurrentRole().id;
        yield put({
          type: 'updateLocale',
          payload: {
            language,
            roleId,
            organizationId,
          },
        });
      },
      /**
       * 更新国际化
       * antdLocale, C7nUILocale, commonLocale, menuLocale
       */ *updateLocale({ payload }, { call, put, all }) {
        // 角色id是必须的
        const { language, organizationId } = payload;
        if (!localLangCache[language]) {
          localLangCache[language] = {};
          const [promptLocale, menuData] = yield all([
            call(queryPromptLocale, organizationId, language, 'hzero.common'),
            call(queryMenu, { lang: language }),
          ]);
          const safePromptLocale = getResponse(promptLocale);
          const safeMenuData = getResponse(menuData);
          const safeMenuLocale = {};
          parseMenuToLocaleIntl(safeMenuData, safeMenuLocale);

          // 设置或切换 当前intl的语言
          const loadLocales = (intl && intl.options && intl.options.locales) || {};
          intl.init({
            currentLocale: language,
            locales: loadLocales,
            warningHandler: (/* e */) => {
              // todo
              // console.warn(e);
            },
          });

          intl.load({
            [language]: { ...safePromptLocale, ...safeMenuLocale },
          });
          yield put({
            type: 'updateMenuLeafNode',
          });
          yield put({
            type: 'updateState',
            payload: {
              language,
            },
          });
        } else {
          // 设置或切换 当前intl的语言
          const loadLocales = (intl && intl.options && intl.options.locales) || {};
          intl.init({
            currentLocale: language,
            locales: loadLocales,
            warningHandler: (/* e */) => {
              // todo
              // console.warn(e);
            },
          });

          const updateState = { language };
          yield put({
            type: 'updateMenuLeafNode',
          });
          yield put({
            type: 'updateState',
            payload: updateState,
          });
        }
        yield put({
          type: 'loadUILocale',
          payload: {
            language,
          },
        });
      },

      /**
       * 加载 UI 的多语言
       */ *loadUILocale({ payload: { language } }, { call, put, all }) {
        let c7nLocale;
        let c7nProLocale;
        let hzeroUILocale;
        if (localLangCache[language] && localLangCache[language].c7nLocale) {
          [c7nLocale, c7nProLocale, hzeroUILocale] = [
            localLangCache[language].c7nLocale,
            localLangCache[language].c7nProLocale,
            localLangCache[language].hzeroUILocale,
          ];
        } else {
          const promiseAllLocale = [
            call(getC7nLocale, language),
            call(getC7nProLocale, language),
            call(getHzeroUILocale, language),
          ];
          [c7nLocale, c7nProLocale, hzeroUILocale] = yield all(promiseAllLocale);
          localLangCache[language].c7nLocale = c7nLocale;
          localLangCache[language].c7nProLocale = c7nProLocale;
          localLangCache[language].hzeroUILocale = c7nProLocale;
        }
        localeContext.setLocale(resolveRequire(c7nProLocale));
        if (hzeroUILocale) {
          // 保证一定有antd的语言,没有可能是调用了多次 updateLocale
          moment.locale(hzeroUILocale.locale); // TODO: LocaleProvider 中会设置 moment.locale,为何突然不起作用了?
        }
        yield put({
          type: 'updateState',
          payload: {
            c7nLocale,
            hzeroUILocale,
          },
        });
      },

      *updateDefaultLanguage({ payload }, { call }) {
        const res = yield call(updateDefaultLanguage, payload);
        return getResponse(res);
      },

      *clearNotices({ payload }, { put, select }) {
        yield put({
          type: 'saveClearedNotices',
          payload,
        });
        const count = yield select((state) => state.global.notices.length);
        yield put({
          type: 'user/changeNotifyCount',
          payload: count,
        });
      },
      *removeTab({ payload }, { put, select }) {
        const state = yield select((st) => st.global);
        const { tabs, activeTabKey } = state;
        let activeKey = activeTabKey;
        let lastIndex;
        tabs.forEach((pane, i) => {
          if (pane.key === payload) {
            lastIndex = i - 1;
          }
        });
        const panes = tabs.filter((pane) => pane.key !== payload);
        if (lastIndex >= 0 && activeTabKey === payload) {
          activeKey = panes[lastIndex].key;
        }
        const activeTabMenuId = getActiveTabMenuId(activeKey);
        yield put({
          type: 'updateState',
          payload: {
            // openTab 会更新 activeTabKey, 并且需要用到之前的 activeTabKey 来判断需不需要 push。
            // activeTabKey: activeKey,
            tabs: [...panes],
            activeTabMenuId: activeTabMenuId.id,
          },
        });
        return activeKey;
      },
      // 关闭其他tab 返回下一个激活的 activeKey
      *removeOtherMenuTab({ payload }, { put, select }) {
        const state = yield select((st) => st.global);
        const { tabs } = state;
        const { tab } = payload;
        const activeTabMenuId = getActiveTabMenuId(tab.key);
        yield put({
          type: 'updateState',
          payload: {
            // openTab 会更新 activeTabKey, 并且需要用到之前的 activeTabKey 来判断需不需要 push。
            // activeTabKey: tab.key,
            tabs: tabs.filter((t) => t.key === tab.key || !t.closable),
            activeTabMenuId: activeTabMenuId.id,
          },
        });
        return tab.key;
      },
      // 关闭其他tab 返回下一个激活的 activeKey
      *removeSomeMenuTab({ payload }, { put, select }) {
        const state = yield select((st) => st.global);
        const { tabs } = state;
        const { removeTabs } = payload;
        yield put({
          type: 'updateState',
          payload: {
            tabs: tabs.filter((t) => !removeTabs.includes(t.key) || !t.closable),
          },
        });
      },
      // 关闭所有tab 返回下一个激活的 activeKey
      *removeAllMenuTab({ payload }, { put, select }) {
        const state = yield select((st) => st.global);
        const { tabs } = state;
        const { tab } = payload;
        let closestTab1; // 记录遍历过程中的 不可关闭的Tab
        let closestTab2; // 记录左距离最近的 不可关闭的Tab
        const nextTabs = tabs.filter((t) => {
          if (t.key === tab.key) {
            if (!t.closable) {
              // 如果该Tab不可关闭, 那么该Tab为下一个打开的Tab
              closestTab2 = t;
            } else {
              // 如果该Tab可关闭, 那么新的Tab为之前最近的不可关闭的Tab
              closestTab2 = closestTab1;
            }
          }
          if (t.closable) {
            return false;
          }
          closestTab1 = t;
          return true;
        });
        const activeTabMenuId = getActiveTabMenuId(closestTab2 || closestTab1 || { key: '/' }.key);
        yield put({
          type: 'updateState',
          payload: {
            // 至少会有工作台tab 所有不对 nextTabs 做空判断
            // openTab 会更新 activeTabKey, 并且需要用到之前的 activeTabKey 来判断需不需要 push。
            // activeTabKey: closestTab2.key,
            activeTabMenuId: activeTabMenuId.id,
            tabs: nextTabs,
          },
        });
        // 如果没有固定tab, 则将
        return (closestTab2 || closestTab1 || { key: '/' }).key;
      },
      *getRemoveTabInfo({ payload }, { select }) {
        const state = yield select((st) => st.global);
        const { tabs, activeTabKey } = state;
        const closeTabKey = payload;
        const removeTabInfo = {
          nextTabs: [],
          nextActiveTabKey: '',
        };
        let isNextTabKeyNeedSet = activeTabKey === closeTabKey;
        forEach(tabs, (tab) => {
          if (tab.key !== closeTabKey) {
            removeTabInfo.nextTabs.push(tab);
            if (isNextTabKeyNeedSet) {
              removeTabInfo.nextActiveTabKey = tab.key;
              removeTabInfo.nextTab = tab;
            }
          } else {
            isNextTabKeyNeedSet = false;
          }
        });
        return removeTabInfo;
      },
      // 查询语言值集
      *querySupportLanguage(_, { call, put }) {
        const supportLanguage = getResponse(yield call(querySupportLanguage));
        if (supportLanguage) {
          yield put({
            type: 'updateState',
            payload: { supportLanguage },
          });
        }
      },
      /**
       * pubLayout 预加载
       * 首屏 预加载内容
       * 初始化语言和菜单数据
       */ *pubInit({ payload: { language, organizationId } }, { call, put, all }) {
        const supportLanguage = getResponse(yield call(querySupportLanguage));
        if (supportLanguage) {
          yield put({
            type: 'updateState',
            payload: { supportLanguage },
          });
        }
        // 第一次加载肯定是没有切换语言的
        localLangCache[language] = {};
        const promiseAllLocale = [
          call(queryPromptLocale, organizationId, language, 'hzero.common'),
        ];
        const [promptLocale] = yield all(promiseAllLocale);
        const safePromptLocale = getResponse(promptLocale);
        // 设置或切换 当前intl的语言
        const loadLocales = (intl && intl.options && intl.options.locales) || {};
        intl.init({
          currentLocale: language,
          locales: loadLocales,
          warningHandler: (/* e */) => {
            // todo
            // console.warn(e);
          },
        });
        intl.load({
          [language]: safePromptLocale,
        });
        yield put({
          type: 'loadUILocale',
          payload: {
            language,
          },
        });
      },
      /**
       * 用于 pubLayout 的懒加载
       */ *pubLazyInit({ payload: { language } }, { put }) {
        // 获取动态表格数据
        const routerConfig = getWrapperRouterData(app || getDvaApp());
        const routerData = {};
        // The route matches the menu
        Object.keys(routerConfig).forEach((path) => {
          // Regular match item name
          // eg.  router /user/:id === /user/chen
          const pathRegexp = pathToRegexp(path);
          let router = routerConfig[path];
          // If you need to configure complex parameter routing,
          // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
          // eg . /list/:type/user/info/:id
          router = {
            ...router,
            name: router.name,
            // tab 用到的数据
            pathRegexp,
            title: router.title,
            icon: router.icon,
            closable: isBoolean(router.closable) ? router.closable : true,
            path,
            // tab 用到的数据
            authority: router.authority,
          };
          routerData[path] = router;
        });
        // 初始化 menuTabs
        yield put({ type: 'initMenuTabs' });

        // tab 初始化完成后才进入 menuTab 处理流程
        tabListen();
        yield put({
          type: 'updateState',
          payload: {
            routerData,
            language,
            // TabListen 监听
            menuLoad: true,
          },
        });
      },

      /**
       * 用于 publicLayout 的懒加载
       */ *publicLazyInit(_, { put }) {
        // 获取动态表格数据
        const routerConfig = getWrapperRouterData(app || getDvaApp());
        const routerData = {};
        // The route matches the menu
        Object.keys(routerConfig).forEach((path) => {
          // Regular match item name
          // eg.  router /user/:id === /user/chen
          const pathRegexp = pathToRegexp(path);
          let router = routerConfig[path];
          // If you need to configure complex parameter routing,
          // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
          // eg . /list/:type/user/info/:id
          router = {
            ...router,
            name: router.name,
            // tab 用到的数据
            pathRegexp,
            title: router.title,
            icon: router.icon,
            closable: isBoolean(router.closable) ? router.closable : true,
            path,
            // tab 用到的数据
            authority: router.authority,
          };
          routerData[path] = router;
        });
        yield put({
          type: 'updateState',
          payload: {
            routerData,
            // TabListen 监听
            menuLoad: true,
            tabsIsInit: true,
          },
        });
      },

      *publicLayoutLanguage({ payload: { language } }, { put }) {
        const loadLocales = (intl && intl.options && intl.options.locales) || {}; // 设置或切换 当前intl的语言
        intl.init({
          currentLocale: language,
          locales: loadLocales,
        });
        yield put({
          type: 'updateState',
          payload: {
            language,
          },
        });
      },

      /**
       * 用于 privateLayout 的懒加载
       */ *privateLazyInit({ payload: { language, organizationId } }, { call, put, all }) {
        // 获取动态表格数据
        const routerConfig = getWrapperRouterData(app || getDvaApp());
        const routerData = {};
        Object.keys(routerConfig).forEach((path) => {
          const pathRegexp = pathToRegexp(path);
          let router = routerConfig[path];
          router = {
            ...router,
            name: router.name,
            // tab 用到的数据
            pathRegexp,
            title: router.title,
            icon: router.icon,
            closable: isBoolean(router.closable) ? router.closable : true,
            path,
            // tab 用到的数据
            authority: router.authority,
          };
          routerData[path] = router;
        });
        // 加载国际化
        // 第一次加载肯定是没有切换语言的
        localLangCache[language] = {};
        const promiseAllLocale = [
          call(queryPromptLocale, organizationId, language, 'hzero.common'),
        ];
        const [promptLocale] = yield all(promiseAllLocale);
        const safePromptLocale = getResponse(promptLocale);
        // 设置或切换 当前intl的语言
        const loadLocales = (intl && intl.options && intl.options.locales) || {};
        intl.init({
          currentLocale: language,
          locales: loadLocales,
          warningHandler: (/* e */) => {
            // todo
            // console.warn(e);
          },
        });
        intl.load({
          [language]: safePromptLocale,
        });

        yield put({
          type: 'loadUILocale',
          payload: {
            language,
          },
        });
        const supportLanguage = getResponse(yield call(querySupportLanguage));
        yield put({
          type: 'updateState',
          payload: {
            routerData,
            language,
            supportLanguage,
            // TabListen 监听
            menuLoad: true,
            tabsIsInit: true,
          },
        });
      },

      /**
       * 首屏 预加载内容
       * 初始化语言和菜单数据
       */ *baseInit({ payload: { language, organizationId } }, { call, put, all }) {
        // 第一次加载肯定是没有切换语言的
        localLangCache[language] = {};
        const promiseAllLocale = [
          call(queryPromptLocale, organizationId, language, 'hzero.common'),
        ];
        const [promptLocale] = yield all(promiseAllLocale);
        const safePromptLocale = getResponse(promptLocale);
        // 设置或切换 当前intl的语言
        const loadLocales = (intl && intl.options && intl.options.locales) || {};
        intl.init({
          currentLocale: language,
          locales: loadLocales,
          warningHandler: (/* e */) => {
            // todo
            // console.warn(e);
          },
        });
        intl.load({
          [language]: safePromptLocale,
        });
        // 初始化 menuTabs
        yield put({ type: 'initMenuTabs' });

        // tab 初始化完成后才进入 menuTab 处理流程
        tabListen();
        yield put({
          type: 'loadUILocale',
          payload: {
            language,
          },
        });
      },
      *baseLazyInit({ payload: { language } }, { call, put, all }) {
        const list = [];
        const menuListReq = call(queryMenu, { lang: language });
        // 获取动态表格数据
        const [menuListRes] = yield all([menuListReq]);
        // let lowCodeMenuDataRes = [];

        // const { hzeroFrontHlcdModelPlugin } = plugins;
        // if (hzeroFrontHlcdModelPlugin && VERSION_IS_OP) {
        //   lowCodeMenuDataRes = yield call(hzeroFrontHlcdModelPlugin.queryLowCodeMenuAll);
        // }
        // const menuList = hzeroFrontHlcdModelPlugin
        //   ? hzeroFrontHlcdModelPlugin.withLowCodeMenuData(
        //       lowCodeMenuDataRes,
        //       getResponse(menuListRes)
        //     )
        //   : getResponse(menuListRes);
        const menuList = getResponse(menuListRes);
        // TODO: 接口完成后 通过菜单来获取 菜单的国际化
        // const menuLocale = {};
        parseMenuData(list, null, menuList || []);
        const menus = list;
        const menuLocaleIntl = {};
        parseMenuToLocaleIntl(menuList, menuLocaleIntl);

        const menuData = getFlatMenuData(menus);
        intl.load({
          [language]: menuLocaleIntl,
        });
        const routerConfig = getWrapperRouterData(app || getDvaApp());
        const routerData = {};
        // The route matches the menu
        Object.keys(routerConfig).forEach((path) => {
          // Regular match item name
          // eg.  router /user/:id === /user/chen
          const pathRegexp = pathToRegexp(path);
          const menuKey = Object.keys(menuData).find((key) => pathRegexp.test(`${key}`));
          let menuItem = {};
          // If menuKey is not empty
          if (menuKey) {
            menuItem = menuData[menuKey];
          }
          let router = routerConfig[path];
          // If you need to configure complex parameter routing,
          // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
          // eg . /list/:type/user/info/:id
          router = {
            ...router,
            name: router.name || menuItem.name,
            // tab 用到的数据
            pathRegexp,
            title: router.title || menuItem.name,
            icon: router.icon || menuItem.icon,
            closable: isBoolean(router.closable) ? router.closable : true,
            path,
            // tab 用到的数据
            authority: router.authority || menuItem.authority,
            hideInBreadcrumb: router.hideInBreadcrumb || menuItem.hideInBreadcrumb,
          };
          routerData[path] = router;
        });
        const queryMenus = getMenuNodeList(menus, []);
        yield put({
          type: 'updateState',
          payload: {
            routerData,
            language,
            menu: menus,
            menuLeafNode: queryMenus,
            // 菜单加载完毕
            menuLoad: true,
            // lowCodeMenuDataRes,
          },
        });
      },

      // 获取 trace 状态
      *getTraceStatus(_, { call, put }) {
        const res = getResponse(yield call(getTraceStatus));
        if (res) {
          yield put({
            type: 'updateState',
            payload: { traceStatus: res },
          });
        }
        return res;
      },

      // trace 相关
      *startTrace(_, { call }) {
        return getResponse(yield call(startTrace));
      },

      *endTrace(_, { call, put }) {
        const res = getResponse(yield call(endTrace));
        if (res) {
          yield put({
            type: 'updateState',
            payload: {
              traceLogInfo: res,
            },
          });
        }
        return res;
      },
    },
    reducers: {
      updateState(state, { payload }) {
        return {
          ...state,
          ...payload,
        };
      },
      changeLayoutCollapsed(state, { payload }) {
        return {
          ...state,
          collapsed: payload,
        };
      },
      saveNotices(state, { payload }) {
        return {
          ...state,
          ...payload,
        };
      },
      saveAnnounces(state, { payload }) {
        return {
          ...state,
          ...payload,
        };
      },
      saveClearedNotices(state, { payload }) {
        return {
          ...state,
          notices: state.notices.filter((item) => item.type !== payload),
        };
      },
      addTab(state, { payload }) {
        const { newTab } = payload;
        const { tabs } = state;
        const activeTabMenuId = getActiveTabMenuId(newTab.key);
        return {
          ...state,
          activeTabKey: newTab.key,
          activeTabMenuId: activeTabMenuId.id,
          tabs: [...tabs, newTab],
        };
      },
      /**
       * 使用新的 tab 替换掉原先的tab
       * @param {Object} state - 之前的state
       * @param {Object} payload
       * @param {Object} payload.tab 需要被替换的tab
       * @param {String!} payload.tab.key 需要被替换的tab的key
       * @param {Object!} payload.newTab 新的tab
       */
      replaceTab(state, { payload }) {
        const { tab, newTab } = payload;
        const { tabs } = state;
        const newTabs = map(tabs, (lTab) => {
          if (lTab.key === tab.key) {
            return newTab;
          }
          return lTab;
        });
        const activeTabMenuId = getActiveTabMenuId(newTab.key);
        return {
          ...state,
          activeTabKey: newTab.key,
          activeTabMenuId: activeTabMenuId.id,
          tabs: newTabs,
        };
      },
      /**
       *
       * 更新 tabs 中对应key的tab, 不激活更新的tab
       * @param {Object} state - 之前的state
       * @param {Object} updateTab - 更新的 tab patch
       * @param {Object} updateTab.key - 更新的 tab 的key
       * @returns {{activeTabKey: *, tabs: *}}
       */
      updateTab(state, { payload: updateTab }) {
        const { tabs } = state;
        const newTabs = map(tabs, (lTab) => {
          if (lTab.key === updateTab.key) {
            return {
              ...lTab,
              ...updateTab,
            };
          }
          return lTab;
        });
        return {
          ...state,
          tabs: newTabs,
        };
      },
      cleanTabs(state) {
        const activeTabMenuId = getActiveTabMenuId(getInitialActiveTabKey());
        return {
          ...state,
          tabs: getInitialTabData(),
          activeTabKey: getInitialActiveTabKey(),
          activeTabMenuId: activeTabMenuId.id,
        };
      },
      updateMenuLeafNode(state) {
        return {
          ...state,
          menuLeafNode: state.menuLeafNode.map((menu) => ({
            ...menu,
            title: menu.name && intl.get(menu.name).d(menu.name),
          })),
        };
      },
      // 初始化 menuTabs
      initMenuTabs(state) {
        const tabs = getInitialTabData();
        const activeTabKey = getInitialActiveTabKey();
        return {
          ...state,
          activeTabKey: state.tabsIsInit ? state.activeTabKey : activeTabKey,
          tabs: state.tabsIsInit ? state.tabs : tabs,
          tabsIsInit: true,
        };
      },
      // 初始化 menuTabs
      initActiveTabMenuId(state) {
        const activeTabMenuId = getActiveTabMenuId(getInitialActiveTabKey());
        return {
          ...state,
          activeTabMenuId: activeTabMenuId.id,
        };
      },
      hideLayoutPageLoading(state) {
        return {
          ...state,
          layoutLoading: false,
        };
      },
      showLayoutPageLoading(state) {
        return {
          ...state,
          layoutLoading: true,
        };
      },
    },
    subscriptions: {
      setup({ history }) {
        // Subscribe history(url) change, trigger `load` action if pathname is `/`
        const unListen = history.listen(({ pathname }) => {
          tabListen(pathname);
        });
        return () => {
          unListen();
          persistMenuTabs();
        };
      },
    },
  };
}
Example #14
Source File: index.js    From hzero-front with Apache License 2.0 4 votes vote down vote up
/**
   * deal field's attribute change
   */
  handleFieldValuesChange(props, changeValues, allValues) {
    // 使用 allValues 重写 field 的属性
    const { field, component, onRefresh } = this.props;
    const { validateFields } = this.editFormRef.current || {};
    if (validateFields) {
      validateFields(err => {
        if (!err) {
          const newConfig = [];
          field[fieldLabelProp] = allValues[fieldLabelProp];
          field[fieldNameProp] = allValues[fieldNameProp];
          // fields's common prop;
          field.requiredFlag = allValues.requiredFlag;
          // enabledFlag 是用来字段禁用的
          field.enabledFlag = allValues.enabledFlag;
          if (isBoolean(allValues.labelDisplayFlag)) {
            newConfig.push({
              [attributeNameProp]: 'labelDisplayFlag',
              [attributeValueProp]: allValues.labelDisplayFlag,
              [attributeTypeProp]: DataType.Boolean,
            });
          }

          if (isString(allValues.description)) {
            newConfig.push({
              [attributeNameProp]: 'description',
              [attributeValueProp]: allValues.description,
              [attributeTypeProp]: DataType.String,
            });
          }
          if (isString(allValues.placeholder)) {
            newConfig.push({
              [attributeNameProp]: 'placeholder',
              [attributeValueProp]: allValues.placeholder,
              [attributeTypeProp]: DataType.String,
            });
          }
          if (isString(allValues.onChange)) {
            newConfig.push({
              [attributeNameProp]: 'onChange',
              [attributeValueProp]: allValues.onChange,
              [attributeTypeProp]: DataType.String,
            });
          }

          const FieldComponent = fieldComponents[field.componentType];
          if (FieldComponent) {
            FieldComponent.getConfigOfPropValues(allValues, newConfig);
          } else {
            const getConfigOfPropValuesFunc = `get${field.componentType}ConfigOfPropValues`;

            if (this[getConfigOfPropValuesFunc]) {
              this[getConfigOfPropValuesFunc](allValues, newConfig);
            }
          }

          const prevFieldConfigs = field.config;
          field.config = newConfig.map(fieldConfig => {
            const prevFieldConfig = find(
              prevFieldConfigs,
              prevC => prevC[attributeNameProp] === fieldConfig[attributeNameProp]
            );
            return { ...prevFieldConfig, ...fieldConfig };
          });
          const newField = field; // { ...field };
          // 更新 feild 在 component 中的引用
          let fieldRefUpdate = false;
          forEach(component.fields, (fArr, rowIndex) => {
            forEach(fArr, (f, colIndex) => {
              if (f === field) {
                fieldRefUpdate = true;
                component.fields[rowIndex][colIndex] = newField;
                return false;
              }
            });
            return !fieldRefUpdate;
          });
          if (isFunction(onRefresh)) {
            onRefresh();
          }
        }
      });
    }
  }