lodash#defaults TypeScript Examples

The following examples show how to use lodash#defaults. 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: common.ts    From ovineherd with Apache License 2.0 6 votes vote down vote up
export function getAppCustom(): CustomType {
  const info = store.custom
  const defImg = 'https://static.igroupes.com/ovine_bg_cxd.jpeg'

  return defaults(info, {
    login_bg_img: defImg,
    login_intro_img: defImg,
    login_logo: info.logo,
    login_title: info.title,
  })
}
Example #2
Source File: runStreams.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function runStream(target: TestDataQuery, req: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
  const query = defaults(target.stream, defaultQuery);
  if ('signal' === query.type) {
    return runSignalStream(target, query, req);
  }
  if ('logs' === query.type) {
    return runLogsStream(target, query, req);
  }
  if ('fetch' === query.type) {
    return runFetchStream(target, query, req);
  }
  throw new Error(`Unknown Stream Type: ${query.type}`);
}
Example #3
Source File: FieldValidatorItem.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
export function FieldValidatorItem({
  value = {},
  onChange,
}: FieldValidatorItemProps): React.ReactElement {
  const { t } = useTranslation(NS_FLOW_BUILDER);
  const [fieldValue, setFieldValue] = useState<ProcessValidateField>(
    defaults(value, { compare: [] })
  );

  useEffect(() => {
    setFieldValue(defaults(value, { compare: [] }));
  }, [value]);

  const handleRegChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const value = e.target.value;
    const newFieldValue = update(fieldValue, { pattern: { $set: value } });
    setFieldValue(newFieldValue);

    onChange(newFieldValue);
  };

  const handleAdd = (): void => {
    const newFieldValue = update(fieldValue, {
      compare: { $push: [{ method: undefined, value: undefined }] },
    });
    setFieldValue(newFieldValue);
    onChange?.(newFieldValue);
  };

  const handleRemove = (index: number): void => {
    const newFieldValue = update(fieldValue, {
      compare: { $splice: [[index, 1]] },
    });

    setFieldValue(newFieldValue);
    onChange?.(newFieldValue);
  };

  const handleNumberValidatorChange = (list: NumberCompareItem[]): void => {
    const newFieldValue = {
      ...fieldValue,
      compare: list,
    };
    setFieldValue(newFieldValue);
    onChange?.(newFieldValue);
  };

  return (
    <div>
      {fieldValue.type === "string" && (
        <Input
          placeholder={t(K.PATTERN_INPUT_PLACEHOLDER)}
          value={fieldValue.pattern}
          onChange={handleRegChange}
        />
      )}
      {numberTypeList.includes(fieldValue.type) && (
        <NumberValidatorInput
          value={fieldValue.compare}
          onAdd={handleAdd}
          onRemove={handleRemove}
          onChange={handleNumberValidatorChange}
        />
      )}
    </div>
  );
}
Example #4
Source File: pack-external-module.ts    From malagu with MIT License 4 votes vote down vote up
/**
 * We need a performant algorithm to install the packages for each single
 * function (in case we package individually).
 * (1) We fetch ALL packages needed by ALL functions in a first step
 * and use this as a base npm checkout. The checkout will be done to a
 * separate temporary directory with a package.json that contains everything.
 * (2) For each single compile we copy the whole node_modules to the compile
 * directory and create a (function) compile specific package.json and store
 * it in the compile directory. Now we start npm again there, and npm will just
 * remove the superfluous packages and optimize the remaining dependencies.
 * This will utilize the npm cache at its best and give us the needed results
 * and performance.
 */
export async function packExternalModules(context: ConfigurationContext, stats: Stats | undefined): Promise<void> {
    const verbose = false;
    const { cfg, pkg, runtime } = context;
    const config = ConfigUtil.getMalaguConfig(cfg, BACKEND_TARGET);
    const configuration = ConfigurationContext.getConfiguration(BACKEND_TARGET, context.configurations);
    const includes = config.includeModules;
    const packagerOptions = { nonInteractive: true, ignoreOptional: true, ...config.packagerOptions };
    const scripts: any[] = packagerOptions.scripts || [];

    if (isEmpty(includes) && includes !== true || !configuration) {
        return;
    }

    const outputPath = configuration.output.get('path');

    // Read plugin configuration
    const packageForceIncludes = includes.forceInclude || [];
    const packageForceExcludes = includes.forceExclude || [];
    const packageForceIncludeAll = includes.forceIncludeAll;
    const packagePath = includes.packagePath && join(process.cwd(), includes.packagePath) || join(process.cwd(), 'package.json');
    const packageScripts = scripts.reduce((accumulator, script, index) => {
        accumulator[`script${index}`] = script;
        return accumulator;
    },
        {}
    );

    const packager = getPackager(context.cfg.rootConfig.packager, process.cwd());

    const sectionNames = packager.copyPackageSectionNames;
    const packageJson = await readJSON(packagePath);
    if (packageForceIncludeAll) {
        for (const d of Object.keys(packageJson.dependencies)) {
            if (!packageForceIncludes.includes(d)) {
                packageForceIncludes.push(d);
            }
        }
    }
    const packageSections = pick(packageJson, sectionNames);
    if (!isEmpty(packageSections)) {
        console.log(`Using package.json sections ${Object.keys(packageSections).join(', ')}`);
    }

    const dependencyGraph = await packager.getProdDependencies(1);

    const problems = dependencyGraph.problems || [];
    if (verbose && !isEmpty(problems)) {
        console.log(`Ignoring ${problems.length} NPM errors:`);
        problems.forEach((problem: any) => {
            console.log(`=> ${problem}`);
        });
    }

    // (1) Generate dependency composition
    const externalModules = getExternalModules(stats).concat(packageForceIncludes.map((whitelistedPackage: string) => ({
        external: whitelistedPackage
    })));
    const compositeModules = uniq(getProdModules(uniq(externalModules), packagePath, dependencyGraph, packageForceExcludes, runtime));
    removeExcludedModules(compositeModules, packageForceExcludes, true);

    if (isEmpty(compositeModules)) {
        // The compiled code does not reference any external modules at all
        console.log('No external modules needed');
        return;
    }

    // (1.a) Install all needed modules
    const compositeModulePath = outputPath;
    const compositePackageJson = join(compositeModulePath, 'package.json');

    // (1.a.1) Create a package.json
    const compositePackage = defaults(
        {
            name: pkg.pkg.name,
            version: pkg.pkg.version,
            description: `Packaged externals for ${pkg.pkg.name}`,
            private: true,
            scripts: packageScripts
        },
        packageSections
    );
    const relPath = relative(compositeModulePath, dirname(packagePath));
    addModulesToPackageJson(compositeModules, compositePackage, relPath);
    writeJSONSync(compositePackageJson, compositePackage, { spaces: 2 });

    // (1.a.2) Copy package-lock.json if it exists, to prevent unwanted upgrades
    const packageLockPath = join(dirname(packagePath), packager.lockfileName);
    const hasPackageLock = await pathExists(packageLockPath);
    if (hasPackageLock) {
        console.log('?  malagu package lock found - Using locked versions');
        try {
            let packageLockFile = await packager.readLockfile(packageLockPath);
            packageLockFile = packager.rebaseLockfile(relPath, packageLockFile);
            packager.writeLockfile(join(compositeModulePath, packager.lockfileName), packageLockFile);
        } catch (err) {
            console.warn(`Warning: Could not read lock file: ${err.message}`);
        }
    }

    const start = now();
    for (const compositeModule of compositeModules) {
        console.log(`?  malagu external modules - ${compositeModule}`);
    }
    await packager.install(packagerOptions, compositeModulePath);
    if (verbose) {
        console.log(`Package took [${now() - start} ms]`);
    }

    // Prune extraneous packages - removes not needed ones
    const startPrune = now();
    await packager.prune(packagerOptions, compositeModulePath);
    if (verbose) {
        console.log(`Prune: ${compositeModulePath} [${now() - startPrune} ms]`);
    }

    // Prune extraneous packages - removes not needed ones
    const startRunScripts = now();
    await packager.runScripts(Object.keys(packageScripts), compositeModulePath);
    if (verbose) {
        console.log(`Run scripts: ${compositeModulePath} [${now() - startRunScripts} ms]`);
    }
}
Example #5
Source File: CmdbInstanceSelect.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function CmdbInstanceSelectItem(
  props: CmdbInstanceSelectProps,
  ref: any
): React.ReactElement {
  const {
    showKeyField,
    // 默认显示 label 为模型的 name/hostname, value 为 instanceId
    // 当showKeyField时,实例展示是用showKey里的数据展示
    fields = {
      label: [showKeyField ? "#showKey" : getInstanceNameKey(props.objectId)],
      value: "instanceId",
    },

    minimumInputLength = 0,
    extraSearchKey = [],
    extraFields = [],
    mode,
    placeholder,
    allowClear,
    pageSize,
    showSearchTip,
    permission,
    ignoreMissingFieldError,
  } = props;
  const userQuery = formatUserQuery(props.instanceQuery);
  //istanbul ignore else
  if (!fields.value) {
    fields.value = "instanceId";
  }

  const [value, setValue] = React.useState();
  const [options, setOptions] = React.useState<ComplexOption[]>([]);
  const [selectedOptions, setSelectedOptions] = React.useState<ComplexOption[]>(
    []
  );
  const [total, setTotal] = React.useState(0);
  const [loading, setLoading] = React.useState(false);
  const computeFields = () => {
    const result = [
      fields.value,
      ...(Array.isArray(fields.label) ? fields.label : [fields.label]),
      ...extraSearchKey,
      ...extraFields,
    ];

    if (props.objectId === "USER") {
      result.push("user_icon");
    }
    return result;
  };

  const handleChange = (newValue: any): void => {
    let selected: any | any[];
    if (mode === "multiple") {
      const valueSet = new Set(newValue);
      selected = options.filter((item) => valueSet.has(item.value));
      const oldValueSet = new Set(
        difference(
          newValue,
          selected.map((item) => item.value)
        )
      );
      selected = selected.concat(
        selectedOptions.filter((item) => oldValueSet.has(item.value))
      );
    } else {
      selected = options.find((item) => item.value === newValue);
    }
    setValue(newValue);
    setSelectedOptions(selected);
    props.onChange && props.onChange(newValue, selected);
  };
  //istanbul ignore else
  const handleSearch = async (
    q: string,
    extraQuery: any,
    forceSearch = false,
    pageSizeQuery?: number
  ): Promise<ComplexOption[]> => {
    if (forceSearch || q.length >= minimumInputLength) {
      try {
        let list = [];
        if (!props.objectId) {
          return;
        }
        setLoading(true);
        const fieldsQuery = Array.isArray(fields.label)
          ? fields.label.map((label) => ({ [label]: { $like: `%${q}%` } }))
          : [{ [fields.label]: { $like: `%${q}%` } }];
        const data = await InstanceApi_postSearchV3(props.objectId, {
          query: {
            $and: [
              {
                $or: [
                  ...fieldsQuery,
                  ...extraSearchKey.map((key) => ({
                    [key]: { $like: `%${q}%` },
                  })),
                ],
              },

              ...extraQuery,
            ],
          },
          ...(permission ? { permission } : {}),
          fields: computeFields(),
          page_size: pageSizeQuery || pageSize,
          ignore_missing_field_error: ignoreMissingFieldError,
        });

        list = data.list;
        setTotal(data.total);
        // 根据用户设置路径显示特定的 label 和 value
        const option = list.map((item) => ({
          ...item,
          label: Array.isArray(fields.label)
            ? fields.label.map((label) => get(item, label))
            : get(item, fields.label),
          value: get(item, fields.value),
          ...(props.objectId === "USER"
            ? {
                user_icon: get(item, "user_icon", "defaultIcon"),
              }
            : {}),
        }));
        setOptions(option);
        return option;
      } catch (e) {
        handleHttpError(e);
      } finally {
        setLoading(false);
      }
    }
  };
  const fetchInstanceData = async (): Promise<void> => {
    await handleSearch("", userQuery);
  };
  const getLabelOptions = (op: any) => {
    if (props.labelTemplate) {
      return parseTemplate(props.labelTemplate, op);
    } else {
      const label = op.label;
      if (Array.isArray(label)) {
        const firstKey = label[0];
        const resKey = label.slice(1, label.length).join(",");
        if (Array.isArray(firstKey) && props.showKeyField) {
          const subFirstKey = firstKey[0];
          const subResKey = firstKey.slice(1, firstKey.length).join(",");
          return subResKey && props.isMultiLabel
            ? `${subFirstKey}(${subResKey})`
            : subFirstKey ?? "";
        }
        return resKey && props.isMultiLabel
          ? `${firstKey}(${resKey})`
          : firstKey ?? "";
      } else {
        return label;
      }
    }
  };

  React.useEffect(() => {
    // 初始化时通过用户的 value 得出首次 label 的值
    // 由于value的不确定性,可能存在首次查询的值不唯一,初始化时也添加instanceQuery
    (async () => {
      if (!isEqual(props.value, value) && props.value !== undefined) {
        const option = await handleSearch(
          "",
          [
            {
              [fields.value || "instanceId"]: {
                $in: castArray(props.value),
              },
            },

            ...userQuery,
          ],
          true,
          props.value?.length >= pageSize ? props.value.length : pageSize
        );
        setSelectedOptions(option);
      }
      setValue(props.value);
    })();
  }, [props.value]);

  React.useEffect(() => {
    if (!props.firstRender) {
      const resetVal: [] | "" = mode === "multiple" ? [] : "";
      setValue(resetVal);
    }
  }, [props.objectId]);
  //istanbul ignore else
  const debounceSearch = debounce(
    (q: string) => handleSearch(q, userQuery),
    500
  );

  return (
    <Spin spinning={loading}>
      <Select
        ref={ref}
        allowClear={allowClear}
        style={defaults(props.inputBoxStyle, { width: "100%" })}
        showSearch
        filterOption={false}
        value={value}
        mode={mode as ModeOption}
        placeholder={
          placeholder || i18n.t(`${NS_FORMS}:${K.BACKGROUND_SEARCH}`)
        }
        onChange={handleChange}
        onSearch={debounceSearch}
        onFocus={fetchInstanceData}
        optionLabelProp="label"
        disabled={props.disabled}
        dropdownRender={(menu) => {
          return (
            <div>
              {menu}
              {showSearchTip && total > pageSize && (
                <div className={style.moreChoices}>
                  仅显示前{pageSize}项,更多结果请搜索
                </div>
              )}
            </div>
          );
        }}
        {...(props.popoverPositionType === "parent"
          ? { getPopupContainer: (triggerNode) => triggerNode.parentElement }
          : {})}
      >
        {options.map((op, index) => {
          const optionLabel = getLabelOptions(op);
          return (
            <Select.Option key={index} value={op.value} label={optionLabel}>
              {props.showTooltip ? (
                <Tooltip title={optionLabel}>
                  {op.user_icon && (
                    <Avatar
                      src={op.user_icon}
                      size={24}
                      className={classNames(style.avatar, {
                        [style.defaultIcon]: op.user_icon === "defaultIcon",
                      })}
                    >
                      {op.user_icon === "defaultIcon" && op.label?.slice(0, 2)}
                    </Avatar>
                  )}
                  {optionLabel}
                </Tooltip>
              ) : (
                <>
                  {op.user_icon && (
                    <Avatar
                      src={op.user_icon}
                      size={24}
                      className={classNames(style.avatar, {
                        [style.defaultIcon]: op.user_icon === "defaultIcon",
                      })}
                    >
                      {op.user_icon === "defaultIcon" && op.label?.slice(0, 2)}
                    </Avatar>
                  )}
                  {optionLabel}
                </>
              )}
            </Select.Option>
          );
        })}
      </Select>
    </Spin>
  );
}
Example #6
Source File: CmdbObjectAttrValue.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function CmdbObjectAttrValueItem(
  props: CmdbObjectAttrValueProps,
  ref: any
): React.ReactElement {
  const { t } = useTranslation(NS_FORMS);
  const [valueType, setValueType] = React.useState();
  const [valueOptions, setValueOptions] = React.useState<ValueOptions[]>(
    valueTypeList
  );
  const { placeholder, inputBoxStyle } = props;
  const [value, setValue] = React.useState();

  React.useEffect(() => {
    setValueType(props.value?.type);
    setValue(props.value);
  }, [props.value]);

  React.useEffect(() => {
    props.valueType?.length > 0 &&
      setValueOptions(
        valueTypeList.filter((valueType) =>
          props.valueType?.includes(valueType.key)
        )
      );
  }, [props.valueType]);

  const onValueChange = (newValue?: any) => {
    if (!newValue.type) {
      props.onChange && props.onChange({ ...value, ...newValue });
    } else {
      props.onChange && props.onChange(newValue);
    }
  };

  const handleValueTypeChange = (valueType: ValueType): void => {
    setValueType(valueType);
    setValue({
      ...defaultValueMap.get(valueType),
      type: valueType,
    });
    onValueChange({
      ...defaultValueMap.get(valueType),
      type: valueType,
    });
  };

  const getContentByValueType = (): React.ReactElement => {
    switch (valueType) {
      case "str":
        return <ObjectAttrStr value={value} onChange={onValueChange} />;
      case "int":
        return <ObjectAttrInt value={value} onChange={onValueChange} />;
      case "date":
        return <ObjectAttrDate value={value} onChange={onValueChange} />;
      case "datetime":
        return <ObjectAttrDatetime value={value} onChange={onValueChange} />;
      case "enum":
        return <ObjectAttrEnum value={value} onChange={onValueChange} />;
      case "enums":
        return (
          <ObjectAttrEnum
            value={value}
            onChange={onValueChange}
            isMulti={true}
          />
        );
      case "arr":
        return <ObjectAttrArr value={value} onChange={onValueChange} />;
      case "struct":
        return <ObjectAttrStruct value={value} onChange={onValueChange} />;
      case "structs":
        return <ObjectAttrStruct value={value} onChange={onValueChange} />;
      case "bool":
        return <ObjectAttrBool value={props.value} onChange={onValueChange} />;
      case "float":
        return <ObjectAttrFloat value={props.value} onChange={onValueChange} />;
      case "ip":
        return <ObjectAttrIP value={props.value} onChange={onValueChange} />;
      case "json":
        return <ObjectAttrJson value={props.value} onChange={onValueChange} />;
      default:
        return <></>;
    }
  };

  return (
    <div ref={ref}>
      <Select
        style={defaults(inputBoxStyle, { width: "100%" })}
        placeholder={placeholder || t(K.PLEASE_SELECT_VALUE_TYPE)}
        value={valueType}
        onChange={handleValueTypeChange}
        disabled={props.disabled}
      >
        {valueOptions.map((option) => (
          <Option value={option.key} key={option.key}>
            {option.text}
          </Option>
        ))}
      </Select>
      {getContentByValueType()}
    </div>
  );
}
Example #7
Source File: ModalConfirm.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function ModalConfirm(props: ModalConfirmProps): React.ReactElement {
  const [modalEntity, contextHolder] = Modal.useModal();
  const { t } = useTranslation(NS_PRESENTATIONAL_BRICKS);
  const {
    visible,
    dataSource,
    title: _title,
    content: _content,
    contentBrick,
    expect: _expect,
    extraContent: _extraContent,
    okText: _okText,
    okType: _okType,
    okButtonProps,
    cancelText,
    cancelButtonProps,
    isDelete,
    type,
  } = props;
  const title = useMemo(() => {
    return _title ? parseTemplate(_title, dataSource) : _title;
  }, [_title, dataSource]);
  const content = useMemo(
    () => parseHTMLTemplate(_content, dataSource),
    [_content, dataSource]
  );

  const [inputValue, setInputValue] = useState("");
  const [okDisabled, setOkDisabled] = useState(false);
  const expect = useMemo(() => {
    const result = _expect ? parseTemplate(_expect, dataSource) : _expect;
    setInputValue("");
    setOkDisabled(!!result);
    return result;
  }, [_expect, dataSource]);

  const extraContent = useMemo(
    () => parseHTMLTemplate(_extraContent, dataSource),
    [_extraContent, dataSource]
  );

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setInputValue(value);
    if (value === expect) {
      setOkDisabled(false);
    } else {
      setOkDisabled(true);
    }
  };
  const expectContent = useMemo(
    () => (
      <Input
        style={{ marginTop: 15 }}
        size="small"
        defaultValue={inputValue}
        onChange={handleChange}
      />
    ),
    [inputValue, expect]
  );
  const brickContent = useMemo(() => {
    return (
      contentBrick?.useBrick && (
        <BrickAsComponent useBrick={contentBrick?.useBrick} data={dataSource} />
      )
    );
  }, [contentBrick, dataSource]);
  const okText = isDelete ? t(K.DELETE) : _okText;
  const [modal, setModal] = useState(null);

  const okType = isDelete ? "danger" : _okType || "primary";

  const onOk = () => {
    props.onOk?.();
    if (!props.closeWhenOk) {
      return Promise.reject();
    }
  };

  const onCancel = () => {
    props.onCancel?.();
  };

  const modalContent = (
    <div>
      <div className={styles.deleteConfirmContent}>
        {content}
        {extraContent && <p style={{ marginTop: "1em" }}>{extraContent}</p>}
      </div>
      {expect && expectContent}
    </div>
  );

  useEffect(() => {
    if (!modal && visible) {
      setModal(
        modalEntity[type]({
          title: title,
          content: contentBrick?.useBrick ? brickContent : modalContent,
          okText: okText,
          cancelText: cancelText,
          onOk: onOk,
          okButtonProps: merge(
            {
              type: okType,
              loading: props.confirmLoading,
              disabled: okDisabled,
            },
            okButtonProps
          ),
          cancelButtonProps: merge(
            {
              type: "link",
            },
            cancelButtonProps
          ),
          onCancel: onCancel,
        })
      );
    }
    if (modal && !visible) {
      modal.destroy();
      setModal(null);
      if (expect) {
        setInputValue("");
        setOkDisabled(true);
      }
    }
  }, [visible]);

  useEffect(() => {
    if (visible && modal) {
      modal.update({
        okButtonProps: defaults(
          { type: okType },
          okButtonProps,
          {
            loading: props.confirmLoading,
          },
          { disabled: okDisabled }
        ),
        cancelButtonProps: merge({ type: "link" }, okButtonProps),
      });
    }
  }, [props.confirmLoading, cancelButtonProps, okDisabled]);

  useEffect(() => {
    if (visible && modal) {
      modal.update({
        content: modalContent,
      });
    }
  }, [inputValue]);

  return <>{contextHolder}</>;
}