lodash#mapKeys TypeScript Examples

The following examples show how to use lodash#mapKeys. 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: utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
function parseStatsApiConfig(maybeConfig: {
  [key: string]: any;
}): StatsApi | undefined {
  const config = mapKeys(maybeConfig, (v, k) => camelCase(k));
  if (checkRequiredKeys(StatsApi, config, true)) {
    return config as StatsApi;
  }
  return undefined;
}
Example #2
Source File: utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
function getTableByKey(key: TableKey): TableType {
  // Typescript does not handle our configuration methods very well
  // So we temporarily override the type of rawTables to make it more flexible.
  const tables = rawTables as Record<string, any>;
  const rawDefinition = {
    id: key,
    ...mapKeys(isTableKey(key) ? tables[key] : {}, (v, k) => camelCase(k)),
  };

  if (isValidTableDefinition(rawDefinition)) {
    return rawDefinition;
  }
  throw new Error(
    `Found invalid table definition for table '${key}'. Check config/tables.json`,
  );
}
Example #3
Source File: utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
function formatLayersCategories(layersList: {
  [key: string]: Array<LayerKey | TableKey>;
}): LayersCategoriesType {
  return map(layersList, (layerKeys, layersListKey) => {
    return {
      title: startCase(layersListKey),
      layers: layerKeys.filter(isLayerKey).map(key => {
        if (typeof key === 'object') {
          const group = (mapKeys(key, (_v, k: string) =>
            camelCase(k),
          ) as unknown) as MenuGroup;
          const mainLayer = group.layers.find(l => l.main);
          const layer = LayerDefinitions[mainLayer?.id as LayerKey];
          // eslint-disable-next-line fp/no-mutation
          layer.group = group;
          return layer;
        }
        return LayerDefinitions[key as LayerKey];
      }),
      tables: layerKeys.filter(isTableKey).map(key => TableDefinitions[key]),
    };
  });
}
Example #4
Source File: utils.ts    From yforms with MIT License 7 votes vote down vote up
getLabelLayout = ({ labelCol, wrapperCol, offset = 0 }: NoLabelLayoutValueProps) => {
  const labelLayoutValue = {};
  const noLabelLayoutValue = {};
  const labelSpan = get(labelCol, 'span');
  const wrapperSpan = get(wrapperCol, 'span');
  if (labelSpan) {
    set(labelLayoutValue, ['labelCol', 'span'], Number(labelSpan) + offset);
    set(labelLayoutValue, ['wrapperCol', 'span'], Number(wrapperSpan) - offset);
    set(noLabelLayoutValue, ['wrapperCol', 'offset'], Number(labelSpan) + offset);
    set(noLabelLayoutValue, ['wrapperCol', 'span'], Number(wrapperSpan) - offset);
  } else {
    mapKeys(labelCol, (value, key) => {
      set(labelLayoutValue, ['labelCol', key, 'span'], value.span + offset);
      set(noLabelLayoutValue, ['wrapperCol', key, 'offset'], value.span + offset);
    });
    mapKeys(wrapperCol, (value, key) => {
      set(labelLayoutValue, ['wrapperCol', key, 'span'], value.span - offset);
      set(noLabelLayoutValue, ['wrapperCol', key, 'span'], value.span - offset);
    });
  }

  return { noLabelLayoutValue, labelLayoutValue };
}
Example #5
Source File: utils.ts    From prism-frontend with MIT License 6 votes vote down vote up
getLayerByKey = (layerKey: LayerKey): LayerType => {
  const rawDefinition = rawLayers[layerKey];

  const definition: { id: LayerKey; type: LayerType['type'] } = {
    id: layerKey,
    type: rawDefinition.type as LayerType['type'],
    ...mapKeys(rawDefinition, (v, k) => camelCase(k)),
  };

  const throwInvalidLayer = () => {
    throw new Error(
      `Found invalid layer definition for layer '${layerKey}'. Check console for more details.`,
    );
  };

  switch (definition.type) {
    case 'wms':
      if (checkRequiredKeys(WMSLayerProps, definition, true)) {
        return definition;
      }
      return throwInvalidLayer();
    case 'admin_level_data':
      if (checkRequiredKeys(AdminLevelDataLayerProps, definition, true)) {
        if (typeof (definition.adminLevel as unknown) !== 'number') {
          console.error(
            `admin_level in layer ${definition.id} isn't a number.`,
          );
          return throwInvalidLayer();
        }

        return definition;
      }
      return throwInvalidLayer();
    case 'impact':
      if (checkRequiredKeys(ImpactLayerProps, definition, true)) {
        return {
          ...definition,
          api: definition.api && parseStatsApiConfig(definition.api),
        };
      }
      return throwInvalidLayer();
    case 'point_data':
      if (checkRequiredKeys(PointDataLayerProps, definition, true)) {
        return definition;
      }
      return throwInvalidLayer();
    case 'boundary':
      if (checkRequiredKeys(BoundaryLayerProps, definition, true)) {
        return definition as BoundaryLayerProps;
      }
      return throwInvalidLayer();
    default:
      // doesn't do anything, but it helps catch any layer type cases we forgot above compile time via TS.
      // https://stackoverflow.com/questions/39419170/how-do-i-check-that-a-switch-block-is-exhaustive-in-typescript
      // eslint-disable-next-line no-unused-vars
      ((_: never) => {})(definition.type);
      throw new Error(
        `Found invalid layer definition for layer '${layerKey}' (Unknown type '${definition.type}'). Check config/layers.json.`,
      );
  }
}
Example #6
Source File: query-builder.ts    From typeorm-query-builder-wrapper with MIT License 6 votes vote down vote up
/**
   * Apply Query Builder with Order.
   *
   * @param {string} alias Alias, ex. t1, optional.
   * @return {*} {QueryBuilder}
   */
  private applyOrder(alias?: string) {
    if (!this.queryObject['order']) return this;

    const order = {};
    const orderFields = this.queryObject['order'].split(',');
    for (const field of orderFields) {
        const orderCriteria = this.getOrderCriteria(field);
        order[field.substr(1, field.length)] = orderCriteria;
    }
    if (order) {
      const orderObject = mapKeys(order, (value, key) => {
        return this.transformKey(key, alias);
      });
      const orders = Object.keys(orderObject);
      for (const orderKey of orders) {
        if (orders.indexOf(orderKey) === 0) {
          this.qb.orderBy(orderKey, orderObject[orderKey]);
        } else {
          this.qb.addOrderBy(orderKey, orderObject[orderKey]);
        }
      }
    }

    return this;
  }
Example #7
Source File: url.ts    From subscan-multisig-react with Apache License 2.0 6 votes vote down vote up
export function patchUrl(info: HashInfo): void {
  const data = mapKeys(info, (_, key) => toShort[key as keyof HashInfo]);
  const oData = hashToObj();
  const hash = Object.entries({ ...oData, ...data })
    .filter(([_, value]) => !!value)
    .reduce((acc, cur) => {
      const pair = `${cur[0]}=${cur[1]}`;

      return acc !== '' ? `${acc}&${pair}` : pair;
    }, '');

  if (hash !== '') {
    location.hash = encodeURIComponent(hash);
  }
}
Example #8
Source File: detail.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
convertChartData = (data: ALARM_REPORT.AlarmTimesChart) => {
  if (isEmpty(data)) return {};

  const { time = [], results = [], title } = data || {};
  const yAxis = [];
  const metricData = [] as object[];
  forEach(get(results, '[0].data') || [], (item) => {
    mapKeys(item, (v) => {
      const { chartType, ...rest } = v;
      yAxis[v.axisIndex] = 1;
      metricData.push({
        ...rest,
        name: v.tag || v.name,
        type: chartType,
      });
    });
  });
  const yAxisLength = yAxis.length;
  return { time, metricData, yAxisLength, xAxisIsTime: true, title };
}
Example #9
Source File: convertor.ts    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
monitorDataConvertor = (responseData: any) => {
  if (isEmpty(responseData)) return {};
  const { time = [], results = [] } = responseData || {};
  const data = get(results, '[0].data') || [];
  const yAxis = [];
  const metricData = [] as object[];
  // data: [{ k: {...} }, { k: {...} }]
  forEach(data, (item) => {
    mapKeys(item, (v) => {
      const { chartType, ...rest } = v;
      yAxis[v.axisIndex] = 1;
      metricData.push({
        ...rest,
        name: v.tag || v.name,
        type: chartType,
      });
    });
  });
  const yAxisLength = yAxis.length;
  return { xData: time, metricData, yAxisLength, xAxisIsTime: true };
}
Example #10
Source File: index.ts    From free-swagger with MIT License 5 votes vote down vote up
normalizeDefinitions = (
  definitions: OpenAPIV2.DefinitionsObject
) => mapKeys(definitions, (value, key) => normalizeDefinitionName(key))
Example #11
Source File: url.ts    From subscan-multisig-react with Apache License 2.0 5 votes vote down vote up
export function getInfoFromHash(): HashInfo {
  const info = hashToObj();

  return mapKeys(info, (_, key) => toLong[key as keyof HashShort]);
}
Example #12
Source File: decorator.ts    From nestjs-paginate with MIT License 5 votes vote down vote up
Paginate = createParamDecorator((_data: unknown, ctx: ExecutionContext): PaginateQuery => {
    const request: Request = ctx.switchToHttp().getRequest()
    const { query } = request

    // Determine if Express or Fastify to rebuild the original url and reduce down to protocol, host and base url
    let originalUrl
    if (request.originalUrl) {
        originalUrl = request.protocol + '://' + request.get('host') + request.originalUrl
    } else {
        originalUrl = request.protocol + '://' + request.hostname + request.url
    }
    const urlParts = new URL(originalUrl)
    const path = urlParts.protocol + '//' + urlParts.host + urlParts.pathname

    const sortBy: [string, string][] = []
    const searchBy: string[] = []

    if (query.sortBy) {
        const params = !Array.isArray(query.sortBy) ? [query.sortBy] : query.sortBy
        for (const param of params) {
            if (isString(param)) {
                const items = param.split(':')
                if (items.length === 2) {
                    sortBy.push(items as [string, string])
                }
            }
        }
    }

    if (query.searchBy) {
        const params = !Array.isArray(query.searchBy) ? [query.searchBy] : query.searchBy
        for (const param of params) {
            if (isString(param)) {
                searchBy.push(param)
            }
        }
    }

    const filter = mapKeys(
        pickBy(
            query,
            (param, name) =>
                name.includes('filter.') &&
                (isString(param) || (Array.isArray(param) && (param as any[]).every((p) => isString(p))))
        ) as Dictionary<string | string[]>,
        (_param, name) => name.replace('filter.', '')
    )

    return {
        page: query.page ? parseInt(query.page.toString(), 10) : undefined,
        limit: query.limit ? parseInt(query.limit.toString(), 10) : undefined,
        sortBy: sortBy.length ? sortBy : undefined,
        search: query.search ? query.search.toString() : undefined,
        searchBy: searchBy.length ? searchBy : undefined,
        filter: Object.keys(filter).length ? filter : undefined,
        path,
    }
})
Example #13
Source File: Items.tsx    From yforms with MIT License 5 votes vote down vote up
Items = (props: YFormItemsProps) => {
  const formProps = useContext(YForm.YFormContext);
  const { getScene } = formProps;
  const itemsProps = useContext(YForm.YFormItemsContext);

  const mergeProps = merge(
    {},
    pick(formProps, ['scenes', 'offset', 'disabled']),
    itemsProps,
    props,
  );
  const { scenes: thisScenes } = mergeProps;
  const _defaultData = { formProps, itemsProps: props };
  mapKeys(thisScenes, (value: boolean, key: string) => {
    if (value && getScene[key] && getScene[key].items) {
      const data = getScene[key].items(_defaultData);
      if (data) {
        _defaultData.itemsProps = { ..._defaultData.itemsProps, ...data.itemsProps };
      }
    }
  });

  const _props = mergeWithDom({}, mergeProps, _defaultData.itemsProps, {
    offset: (props.offset || 0) + (itemsProps.offset || 0),
  });

  const { isShow, className, style, children, noStyle, shouldUpdate } = _props;

  const itemList = [];
  const eachItem = (
    list: YFormItemProps['children'][] | React.ReactFragment[],
    pIndex?: number,
  ) => {
    if (isArray(list)) {
      forEach(list, (item, index) => {
        // 如果还是是数组就回调该方法
        // if (isArray(item)) return eachItem(item, index);
        if (isArray(item)) {
          return eachItem(item, index);
        }
        const _index = pIndex ? `${pIndex}_${index}` : index;
        // 如果是 dom 直接渲染
        if (isValidElement(item)) {
          return itemList.push(item);
        }
        // 如果不是对象直接渲染
        if (!isObject(item)) {
          return itemList.push(item);
        }
        return itemList.push(<YForm.Item {...item} key={_index} />);
      });
    }
  };
  // 遍历元素
  eachItem(isArray(children) ? children : [children]);
  const child = (
    <YForm.YFormItemsContext.Provider value={pick(_props, ['scenes', 'offset', 'disabled'])}>
      {itemList}
    </YForm.YFormItemsContext.Provider>
  );
  const dom = noStyle ? (
    child
  ) : (
    <div className={classNames('yform-items', className)} style={style}>
      {child}
    </div>
  );

  if (typeof isShow === 'function') {
    return (
      <Form.Item noStyle shouldUpdate={shouldUpdate}>
        {(form) => isShow(form.getFieldsValue(true)) && dom}
      </Form.Item>
    );
  }
  if ('isShow' in props && !props.isShow) return null;

  return dom;
}
Example #14
Source File: query-builder.ts    From typeorm-query-builder-wrapper with MIT License 5 votes vote down vote up
/**
   * Apply Query Builder with Filter Query.
   *
   * @param {any} query Query params.
   * @return {*} {QueryBuilder}
   */
  public applyFilterQueries() {
    const { fieldResolverMap, queryObject } = this;
    if (fieldResolverMap) {
      mapKeys(fieldResolverMap, (field, key) => {
        if (queryObject[key]) {
          const operator = FilterHelper.getOperator(key);
          const value = queryObject[key];
          switch (operator) {
            case LookupFilter.CONTAINS:
              this.qb.andWhere(`${field} LIKE '%${value}%'`);
              break;
            case LookupFilter.I_CONTAINS:
              this.qb.andWhere(`${field} ILIKE '%${value}%'`);
              break;
            case LookupFilter.STARTS_WITH:
              this.qb.andWhere(`${field} LIKE '${value}%'`);
              break;
            case LookupFilter.I_STARTS_WITH:
              this.qb.andWhere(`${field} ILIKE '${value}%'`);
              break;
            case LookupFilter.ENDS_WITH:
              this.qb.andWhere(`${field} LIKE '%${value}'`);
              break;
            case LookupFilter.I_ENDS_WITH:
              this.qb.andWhere(`${field} ILIKE '%${value}'`);
              break;
            case LookupFilter.IS_NULL:
              this.qb.andWhere(`${field} IS NULL`);
              break;
            case LookupFilter.LT:
              this.qb.andWhere(`${field} < '${value}'`);
              break;
            case LookupFilter.LTE:
              this.qb.andWhere(`${field} <= '${value}'`);
              break;
            case LookupFilter.GT:
              this.qb.andWhere(`${field} > '${value}'`);
              break;
            case LookupFilter.GTE:
              this.qb.andWhere(`${field} >= '${value}'`);
              break;
            case LookupFilter.IN:
              this.qb.andWhere(`${field} IN ('${value}')`);
              break;
            case LookupFilter.BETWEEN:
              this.qb.andWhere(`${field} BETWEEN '${value[0]}' AND '${value[1]}'`);
              break;
            case LookupFilter.NOT_EQUAL:
              this.qb.andWhere(`${field} <> '${value}'`);
              break;
            default:
              this.qb.andWhere(`${field} = '${value}'`);
              break;
          }
        }
      });
    }

    return this;
  }
Example #15
Source File: helpers.ts    From aqualink-app with MIT License 5 votes vote down vote up
mapMetrics = <T>(
  data: Partial<Record<MetricsKeys, T>>
): Partial<Record<Metrics, T>> =>
  mapKeys(pick(data, metricsKeysList), (_, key) => camelCase(key)) as Partial<
    Record<Metrics, T>
  >
Example #16
Source File: tooltip.ts    From S2 with MIT License 5 votes vote down vote up
getSummaries = (params: SummaryParam): TooltipSummaryOptions[] => {
  const { spreadsheet, getShowValue, targetCell, options = {} } = params;
  const summaries: TooltipSummaryOptions[] = [];
  const summary: TooltipDataItem = {};
  const isTableMode = spreadsheet.isTableMode();

  if (isTableMode && options?.showSingleTips) {
    const selectedCellsData = spreadsheet.dataSet.getMultiData({});
    return [{ selectedData: selectedCellsData, name: '', value: '' }];
  }

  // 拿到选择的所有 dataCell的数据
  const selectedCellsData = getSelectedCellsData(
    spreadsheet,
    targetCell,
    options.showSingleTips,
  );

  forEach(selectedCellsData, (item) => {
    if (summary[item?.[EXTRA_FIELD]]) {
      summary[item?.[EXTRA_FIELD]]?.push(item);
    } else {
      summary[item?.[EXTRA_FIELD]] = [item];
    }
  });

  mapKeys(summary, (selected, field) => {
    const name = getSummaryName(spreadsheet, field, options?.isTotals);
    let value: number | string = getShowValue?.(selected, VALUE_FIELD);

    if (isTableMode) {
      value = '';
    } else if (every(selected, (item) => isNotNumber(get(item, VALUE_FIELD)))) {
      const { placeholder } = spreadsheet.options;
      const emptyPlaceholder = getEmptyPlaceholder(summary, placeholder);
      // 如果选中的单元格都无数据,则显示"-" 或 options 里配置的占位符
      value = emptyPlaceholder;
    } else {
      const currentFormatter = getFieldFormatter(spreadsheet, field);
      const dataSum = getDataSumByField(selected, VALUE_FIELD);
      value =
        currentFormatter?.(dataSum, selected) ??
        parseFloat(dataSum.toPrecision(PRECISION)); // solve accuracy problems;
    }
    summaries.push({
      selectedData: selected,
      name,
      value,
    });
  });

  return summaries;
}
Example #17
Source File: Item.tsx    From yforms with MIT License 4 votes vote down vote up
Item: React.FC<YFormDataSource> = (props) => {
  // 这里解析出来的参数最好不要在 scenes 中更改
  const { scenes, ...rest } = props;

  const { name, children } = rest;
  const formProps = useContext(YForm.YFormContext);

  const {
    itemsType = {},
    onDeFormatFieldsValue,
    oldValues,
    getScene,
    onFormatFieldsValue,
  } = formProps;

  const itemsProps = useContext(YForm.YFormItemsContext);
  const { scenes: thisScenes } = itemsProps;

  const listContext = useContext(YForm.ListContent);
  const { prefixName } = listContext;

  // List 会有拼接 name ,这里获取 all name path
  const allName = prefixName ? concat(prefixName, name) : name;

  const mergeProps = mergeWithDom(
    {},
    pick(formProps, ['scenes', 'offset', 'disabled']),
    itemsProps,
    props,
  );

  if ('isShow' in props && !props.isShow) return null;

  const _scenes = mergeWithDom({}, thisScenes, scenes);
  let _props = mergeWithDom({}, mergeProps, rest, {
    offset: (props.offset || 0) + (itemsProps.offset || 0),
  });

  let _componentProps = { ...props.componentProps };

  const typeProps = get(itemsType, props.type) || {};
  // 原类型
  typeProps.type = props.type;
  const defaultData = {
    formProps,
    itemsProps: mergeProps,
    itemProps: _props,
    componentProps: _componentProps,
    typeProps,
  };

  // 参数修改
  const _defaultData = defaultData;
  const { modifyProps } = typeProps;
  if (modifyProps) {
    mergeWithDom(_defaultData, modifyProps(defaultData));
  }

  mapKeys(_scenes, (value: boolean, key: string) => {
    if (value && getScene[key] && getScene[key].item) {
      const data = getScene[key].item(_defaultData);
      if (data) {
        _defaultData.itemProps = { ..._defaultData.itemProps, ...data.itemProps };
        _defaultData.componentProps = { ..._defaultData.componentProps, ...data.componentProps };
      }
    }
  });

  _props = { ..._defaultData.itemProps };
  _componentProps = _defaultData.componentProps;

  const { type, dataSource, componentProps, format, ...formItemProps } = _props;
  const _formItemProps = formItemProps;
  const { isShow, shouldUpdate } = _formItemProps;

  const { deFormat } = _defaultData.itemProps;

  // 获取前格式化
  if (deFormat) {
    onDeFormatFieldsValue({ name: allName, format: deFormat });
    if (oldValues && _scenes.diff) {
      _defaultData.itemProps = {
        oldValue: deFormat(
          get(oldValues, allName),
          getParentNameData(oldValues, allName),
          oldValues,
        ),
        ..._defaultData.itemProps,
      };
    }
  }

  // 提交前格式化
  if (format) {
    let _format = [];
    if (typeof format === 'function') {
      _format = [{ name: allName, format }];
    } else {
      _format = map(format, (item) => {
        const _item = { ...item };
        if (item.name) {
          _item.name = prefixName ? concat(prefixName, item.name) : item.name;
        }
        return _item;
      });
    }
    onFormatFieldsValue(_format);
  }

  let _children;
  // 默认用 FormItem 包裹
  let _hasFormItem = true;
  const thisComponentProps = _componentProps;
  if (type) {
    const _fieldData = itemsType[type];
    if (_fieldData) {
      const { component } = _fieldData;
      _hasFormItem = 'hasFormItem' in _fieldData ? _fieldData.hasFormItem : _hasFormItem;
      const _component = children || component;
      _children = isValidElement(_component)
        ? React.cloneElement(_component, {
            ...(_component.props as Record<string, any>),
            ...thisComponentProps,
          })
        : _component;
    } else {
      warning(false, `[YFom.Items] ${type} 类型未找到`);
    }
  } else {
    // 没有 type 单独有 dataSource 情况
    if (dataSource) {
      _children = (
        <Items scenes={_scenes} {...thisComponentProps}>
          {dataSource}
        </Items>
      );
    } else {
      _children = isValidElement(children)
        ? React.cloneElement(children, { ...children.props, ...thisComponentProps })
        : children;
    }
  }
  const domChildren =
    typeof _children === 'function'
      ? (form: YFormInstance) => {
          return (
            <Items noStyle scenes={_scenes}>
              {(_children as YFormRenderChildren)(form)}
            </Items>
          );
        }
      : _children;
  let dom = domChildren;
  if (_hasFormItem) {
    dom = (
      <ItemChildren
        {...omit(_formItemProps, [
          'component',
          'scenes',
          'viewProps',
          'deFormat',
          'format',
          'oldValue',
          'items',
          'offset',
          'hideLable',
        ])}
      >
        {domChildren}
      </ItemChildren>
    );
  }

  const render = (props?: any) => {
    return (
      <YForm.YFormItemContext.Provider value={mergeWithDom(omit(_props, ['children']), props)}>
        {dom}
      </YForm.YFormItemContext.Provider>
    );
  };

  if (shouldUpdate) {
    let reRender = false;
    return (
      <Form.Item noStyle shouldUpdate={shouldUpdate}>
        {(form) => {
          if (typeof isShow === 'function') {
            const fieldsValue = form.getFieldsValue(true);
            const parentValue = getParentNameData(fieldsValue, name);
            if (!isShow(parentValue, fieldsValue)) {
              return;
            }
          }
          reRender = !reRender;
          return render({ reRender });
        }}
      </Form.Item>
    );
  }
  return render();
}
Example #18
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
MiddlewareChart = () => {
  const { addon_id, timestamp, cluster_name } = routeInfoStore.useStore((s) => s.query);
  const [containerChartMetas, middlewareChartMetas] = middlewareChartStore.useStore((s) => [
    s.containerChartMetas,
    s.middlewareChartMetas,
  ]);
  const { getChartMeta, getContainerChart } = middlewareChartStore.effects;
  const [loading] = useLoading(middlewareChartStore, ['getChartMeta']);
  const timestampMap = React.useMemo(() => {
    const curTimestamp = moment().valueOf();
    const _timestampMap = { start: curTimestamp - 30 * 60 * 1000, end: curTimestamp };
    if (Number(timestamp) + 30 * 60 * 1000 < curTimestamp) {
      _timestampMap.start = Number(timestamp) - 30 * 60 * 1000;
      _timestampMap.end = Number(timestamp) + 30 * 60 * 1000;
    }
    return _timestampMap;
  }, [timestamp]);

  useMount(() => {
    // 容器图表元数据
    getChartMeta({ type: 'addon_container' });
    // 中间件图表元数据
    getChartMeta({ type: addon_id });
  });

  const getLayout = (chartMetas: any) =>
    map(chartMetas, ({ title, name, parameters }, index) => ({
      w: 12,
      h: 9,
      x: 12 * (index % 2),
      y: 0,
      i: `middleware-chart-${name}`,
      moved: false,
      static: false,
      view: {
        title,
        chartType: 'chart:line',
        hideReload: true,
        chartQuery: {
          start: timestampMap.start,
          end: timestampMap.end,
          filter_cluster_name: cluster_name,
          filter_addon_id: addon_id,
          name,
          ...parameters,
        },
        loadData: getContainerChart,
        dataConvertor(responseData: any) {
          if (isEmpty(responseData)) return {};
          const { time = [], results = [] } = responseData || {};
          const data = get(results, '[0].data') || [];
          const metricData = [] as object[];
          const yAxis = [];
          forEach(data, (item) => {
            mapKeys(item, (v) => {
              const { chartType, ...rest } = v;
              yAxis[v.axisIndex] = 1;
              metricData.push({
                ...rest,
                type: chartType || 'line',
              });
            });
          });
          const yAxisLength = yAxis.length;
          const formatTime = time.map((t) => moment(t).format('MM-DD HH:mm'));
          return { xData: formatTime, metricData, yAxisLength, xAxisIsTime: true };
        },
      },
    }));

  return (
    <Spin spinning={loading}>
      {/* <h3 className="title mb-4">{i18n.t('cmp:middleware container chart')}</h3> */}
      <BoardGrid.Pure layout={getLayout([...containerChartMetas, ...middlewareChartMetas])} />
      {/* <h3 className="title mt-6 mb-4">{i18n.t('cmp:middleware indicator chart')}</h3>
      <BoardGrid.Pure
        layout={getLayout(middlewareChartMetas)}
      /> */}
    </Spin>
  );
}
Example #19
Source File: Form.tsx    From yforms with MIT License 4 votes vote down vote up
InternalForm = React.memo<YFormProps>((thisProps) => {
  const props = { ...globalConfig.defaultFormProps, ...thisProps };
  const { scenes, getScene = globalConfig.getScene, offset = 0 } = props;
  const _scenes = merge({}, globalConfig.scenes, scenes);
  const _defaultData = { formProps: props };
  mapKeys(_scenes, (value: boolean, key: string) => {
    if (value && getScene[key] && getScene[key].form) {
      const data = getScene[key].form(_defaultData);
      if (data) {
        _defaultData.formProps = { ..._defaultData.formProps, ...data.formProps };
      }
    }
  });
  const _props = _defaultData.formProps;

  const {
    disabled,
    loading,
    itemsType,
    children,
    onFinish,
    onSave,
    formatFieldsValue: formFormatFieldsValue,
    onCancel,
    params,
    form: propsForm,
    className,
    submitComponentProps,
    submit,
    initialValues,
    minBtnLoadingTime = 500,
    getInitialValues,
    ...rest
  } = _props;

  const [form] = useForm(propsForm);
  const formatRef = useRef([]);
  const { resetFields, getFieldsValue } = form;
  const _params = submit ? submit.params : paramsType(params);
  const { create, edit, view } = _params;
  // 同 useSubmit 使用 view 当默认值
  const [thisDisabled, setDisabled] = useState(view);
  const [submitLoading, setSubmitLoading] = useState(false);
  const timeOut = useRef<number | null>(null);
  // 下面地方请使用 _thisDisabled
  let _thisDisabled = thisDisabled;
  if (submit) {
    _thisDisabled = submit.disabled;
  }
  // 改变状态
  const handleOnDisabled = useCallback(
    (disabled) => {
      if (submit) {
        submit.onDisabled(disabled);
      } else {
        setDisabled(disabled);
      }
    },
    [submit],
  );
  const [_getInitialValues, setGetInitialValues] = useState({});
  const [getLoading, setGetLoading] = useState(true);
  const immutableGetDetail = usePersistFn<YFormProps['getInitialValues']>(getInitialValues);

  // 传了 getInitialValues 则使用该数据,没传则使用 initialValues、loading
  const _initialValues = getInitialValues ? _getInitialValues : initialValues;
  const _loading = getInitialValues ? getLoading : loading;

  const hasGetInitialValues = typeof getInitialValues === 'function';
  const loadData = useCallback(
    async (params: getInitialValuesParamsType) => {
      // 只有传了 getInitialValues 调用
      if (hasGetInitialValues) {
        setGetInitialValues(await immutableGetDetail(params));
        setGetLoading(false);
      }
    },
    [hasGetInitialValues, immutableGetDetail],
  );

  useEffect(() => {
    loadData({ isInit: true });
  }, [loadData]);

  useEffect(() => {
    return () => {
      clearTimeout(timeOut.current);
    };
  }, []);

  const goBack = () => {
    window.history.back();
  };

  const handleReset: (p: { type: CancelType }) => void = useCallback(
    async ({ type }) => {
      if (typeof onCancel === 'function') {
        onCancel({ type });
      } else {
        resetFields();
        if (create) {
          goBack();
        } else if (edit || view) {
          handleOnDisabled(true);
        }
      }
    },
    [create, edit, handleOnDisabled, onCancel, resetFields, view],
  );
  const itemsTypeAll = { ...baseItemsType, ...globalConfig.itemsType, ...itemsType };

  // 内部格式化功能
  const { formatFieldsValue, onFormatFieldsValue } = useFormatFieldsValue();

  const handleFormatFieldsValue = (value) => {
    const _value = value || getFieldsValue(true);
    const _formatFieldsValue = concat(formFormatFieldsValue, formatFieldsValue).filter((x) => x);

    // 忽略字段
    const omitNames = [];
    forEach(_formatFieldsValue, (item) => {
      if (item.isOmit) omitNames.push(item.name);
    });
    const formatValues = { ...submitFormatValues(_value, _formatFieldsValue) };
    return omit(formatValues, omitNames);
  };

  if (!form.getFormatFieldsValue) {
    form.getFormatFieldsValue = handleFormatFieldsValue;
  }

  const handleOnFinish = async (value: KeyValue) => {
    if (onFinish) {
      if (submitLoading) return;
      const begin = new Date().getTime();
      setSubmitLoading(true);
      try {
        await onFinish(form.getFormatFieldsValue(value));
        await loadData({ isInit: false });
        const end = new Date().getTime();
        timeOut.current = window.setTimeout(
          () => {
            setSubmitLoading(false);
            handleReset({ type: 'onSubmit' });
          },
          // loading 时间不到 0.5s 的加载 0.5s,超过的立刻结束。
          end - begin > minBtnLoadingTime ? 0 : minBtnLoadingTime,
        );
      } catch (error) {
        console.log('error', error);
        setSubmitLoading(false);
      }
    }
  };

  const handleOnEdit = (e) => {
    e.preventDefault();
    handleOnDisabled(false);
  };
  const {
    formatFieldsValue: deFormatFieldsValue,
    onFormatFieldsValue: onDeFormatFieldsValue,
  } = useFormatFieldsValue();

  // deFormatFieldsValue 第一次为空需要下面 set(deFormatValues, name, value) 设置值
  // 当执行 resetFields 后,就需要 deFormatFieldsValue 的格式化。
  const deFormatValues = submitFormatValues(_initialValues, deFormatFieldsValue);

  const handleDeFormatFieldsValue = useCallback(
    (data: FormatFieldsValue) => {
      const { name, format } = data;
      const parentValue = getParentNameData(_initialValues, name);
      const value = format(get(_initialValues, name), parentValue, _initialValues);
      if (!find(formatRef.current, { name })) {
        form.setFields([{ name, value }]);
        formatRef.current.push({ name, value });
        // 初始化使用 deFormat 后的数据
        set(deFormatValues, name, value);
        onDeFormatFieldsValue([{ name, format }]);
      }
    },
    [_initialValues, form, deFormatValues, onDeFormatFieldsValue],
  );
  const providerProps = mergeWithDom(
    {
      form,
      scenes: _scenes,
      disabled: _thisDisabled,
      getScene,
      onFormatFieldsValue,
      onDeFormatFieldsValue: handleDeFormatFieldsValue,
      submitComponentProps: {
        showBtns: {
          // form submit 触发后设置 loading = true
          showSubmit: { loading: submitLoading },
          showEdit: { onClick: handleOnEdit },
          showCancel: { onClick: () => handleReset({ type: 'onCancel' }) },
          showSave: { onLoaded: () => handleReset({ type: 'onSave' }) },
          showBack: { onClick: goBack },
        },
      },
    },
    { ...omit(_props, ['name', 'initialValues']) },
    { initialValues: deFormatValues },
  );
  if ('isShow' in _props && !_props.isShow) {
    return null;
  }
  if (_loading) {
    return (
      <div className="form-spin">
        <Spin />
      </div>
    );
  }
  return (
    <Form
      {...omit(rest, ['scenes', 'oldValues'])}
      initialValues={deFormatValues}
      form={form}
      className={classNames('yforms', className)}
      onFinish={handleOnFinish}
    >
      <YFormContext.Provider value={{ ...providerProps, itemsType: itemsTypeAll }}>
        <Items offset={offset}>{children}</Items>
      </YFormContext.Provider>
    </Form>
  );
})
Example #20
Source File: paginate.ts    From nestjs-paginate with MIT License 4 votes vote down vote up
export async function paginate<T>(
    query: PaginateQuery,
    repo: Repository<T> | SelectQueryBuilder<T>,
    config: PaginateConfig<T>
): Promise<Paginated<T>> {
    let page = query.page || 1
    const limit = Math.min(query.limit || config.defaultLimit || 20, config.maxLimit || 100)
    const sortBy = [] as SortBy<T>
    const searchBy: Column<T>[] = []
    const path = query.path

    function isEntityKey(entityColumns: Column<T>[], column: string): column is Column<T> {
        return !!entityColumns.find((c) => c === column)
    }

    if (config.sortableColumns.length < 1) throw new ServiceUnavailableException()

    if (query.sortBy) {
        for (const order of query.sortBy) {
            if (isEntityKey(config.sortableColumns, order[0]) && ['ASC', 'DESC'].includes(order[1])) {
                sortBy.push(order as Order<T>)
            }
        }
    }

    if (!sortBy.length) {
        sortBy.push(...(config.defaultSortBy || [[config.sortableColumns[0], 'ASC']]))
    }

    if (config.searchableColumns) {
        if (query.searchBy) {
            for (const column of query.searchBy) {
                if (isEntityKey(config.searchableColumns, column)) {
                    searchBy.push(column)
                }
            }
        } else {
            searchBy.push(...config.searchableColumns)
        }
    }

    if (page < 1) page = 1

    let [items, totalItems]: [T[], number] = [[], 0]

    let queryBuilder: SelectQueryBuilder<T>

    if (repo instanceof Repository) {
        queryBuilder = repo
            .createQueryBuilder('e')
            .take(limit)
            .skip((page - 1) * limit)
    } else {
        queryBuilder = repo.take(limit).skip((page - 1) * limit)
    }

    if (config.relations?.length) {
        config.relations.forEach((relation) => {
            queryBuilder.leftJoinAndSelect(`${queryBuilder.alias}.${relation}`, `${queryBuilder.alias}_${relation}`)
        })
    }

    for (const order of sortBy) {
        if (order[0].split('.').length > 1) {
            queryBuilder.addOrderBy(`${queryBuilder.alias}_${order[0]}`, order[1])
        } else {
            queryBuilder.addOrderBy(`${queryBuilder.alias}.${order[0]}`, order[1])
        }
    }

    if (config.where) {
        queryBuilder.andWhere(new Brackets((qb) => qb.andWhere(config.where)))
    }

    if (config.withDeleted) {
        queryBuilder.withDeleted()
    }

    if (query.search && searchBy.length) {
        queryBuilder.andWhere(
            new Brackets((qb: SelectQueryBuilder<T>) => {
                for (const column of searchBy) {
                    const propertyPath = (column as string).split('.')
                    if (propertyPath.length > 1) {
                        const condition: WherePredicateOperator = {
                            operator: 'ilike',
                            parameters: [`${qb.alias}_${column}`, `:${column}`],
                        }
                        qb.orWhere(qb['createWhereConditionExpression'](condition), {
                            [column]: `%${query.search}%`,
                        })
                    } else {
                        qb.orWhere({
                            [column]: ILike(`%${query.search}%`),
                        })
                    }
                }
            })
        )
    }

    if (query.filter) {
        const filter = parseFilter(query, config)
        queryBuilder.andWhere(
            new Brackets((qb: SelectQueryBuilder<T>) => {
                for (const column in filter) {
                    const propertyPath = (column as string).split('.')
                    if (propertyPath.length > 1) {
                        const condition = qb['getWherePredicateCondition'](
                            column,
                            filter[column]
                        ) as WherePredicateOperator
                        let parameters = { [column]: filter[column].value }
                        // TODO: refactor below
                        switch (condition.operator) {
                            case 'between':
                                condition.parameters = [`${qb.alias}_${column}`, `:${column}_from`, `:${column}_to`]
                                parameters = {
                                    [column + '_from']: filter[column].value[0],
                                    [column + '_to']: filter[column].value[1],
                                }
                                break
                            case 'in':
                                condition.parameters = [`${qb.alias}_${column}`, `:...${column}`]
                                break
                            default:
                                condition.parameters = [`${qb.alias}_${column}`, `:${column}`]
                                break
                        }
                        qb.andWhere(qb['createWhereConditionExpression'](condition), parameters)
                    } else {
                        qb.andWhere({
                            [column]: filter[column],
                        })
                    }
                }
            })
        )
    }

    ;[items, totalItems] = await queryBuilder.getManyAndCount()

    let totalPages = totalItems / limit
    if (totalItems % limit) totalPages = Math.ceil(totalPages)

    const sortByQuery = sortBy.map((order) => `&sortBy=${order.join(':')}`).join('')
    const searchQuery = query.search ? `&search=${query.search}` : ''

    const searchByQuery =
        query.searchBy && searchBy.length ? searchBy.map((column) => `&searchBy=${column}`).join('') : ''

    const filterQuery = query.filter
        ? '&' +
          stringify(
              mapKeys(query.filter, (_param, name) => 'filter.' + name),
              '&',
              '=',
              { encodeURIComponent: (str) => str }
          )
        : ''

    const options = `&limit=${limit}${sortByQuery}${searchQuery}${searchByQuery}${filterQuery}`

    const buildLink = (p: number): string => path + '?page=' + p + options

    const results: Paginated<T> = {
        data: items,
        meta: {
            itemsPerPage: limit,
            totalItems,
            currentPage: page,
            totalPages: totalPages,
            sortBy,
            search: query.search,
            searchBy: query.search ? searchBy : undefined,
            filter: query.filter,
        },
        links: {
            first: page == 1 ? undefined : buildLink(1),
            previous: page - 1 < 1 ? undefined : buildLink(page - 1),
            current: buildLink(page),
            next: page + 1 > totalPages ? undefined : buildLink(page + 1),
            last: page == totalPages || !totalItems ? undefined : buildLink(totalPages),
        },
    }

    return Object.assign(new Paginated<T>(), results)
}
Example #21
Source File: generate.ts    From prisma-nestjs-graphql with MIT License 4 votes vote down vote up
export async function generate(
  args: GeneratorOptions & {
    skipAddOutputSourceFiles?: boolean;
    connectCallback?: (
      emitter: AwaitEventEmitter,
      eventArguments: EventArguments,
    ) => void | Promise<void>;
  },
) {
  const { connectCallback, generator, skipAddOutputSourceFiles, dmmf } = args;

  const generatorOutputValue = generator.output?.value;
  ok(generatorOutputValue, 'Missing generator configuration: output');

  const eventEmitter = new AwaitEventEmitter();
  eventEmitter.on('Warning', warning);
  eventEmitter.on('Model', modelData);
  eventEmitter.on('EnumType', registerEnum);
  eventEmitter.on('OutputType', outputType);
  eventEmitter.on('ModelOutputType', modelOutputType);
  eventEmitter.on('AggregateOutput', createAggregateInput);
  eventEmitter.on('InputType', inputType);
  eventEmitter.on('ArgsType', argsType);
  eventEmitter.on('GenerateFiles', generateFiles);

  const config = createConfig(generator.config);
  for (const message of config.$warnings) {
    eventEmitter.emitSync('Warning', message);
  }

  const project = new Project({
    tsConfigFilePath: config.tsConfigFilePath,
    skipAddingFilesFromTsConfig: true,
    skipLoadingLibFiles: !config.emitCompiled,
    manipulationSettings: {
      quoteKind: QuoteKind.Single,
    },
  });

  if (!skipAddOutputSourceFiles) {
    project.addSourceFilesAtPaths([
      `${generatorOutputValue}/**/*.ts`,
      `!${generatorOutputValue}/**/*.d.ts`,
    ]);
  }

  config.combineScalarFilters && combineScalarFilters(eventEmitter);
  config.noAtomicOperations && noAtomicOperations(eventEmitter);
  config.reExport !== ReExport.None && reExport(eventEmitter);
  config.emitSingle && emitSingle(eventEmitter);
  config.purgeOutput && purgeOutput(eventEmitter);
  config.requireSingleFieldsInWhereUniqueInput &&
    requireSingleFieldsInWhereUniqueInput(eventEmitter);

  const models = new Map<string, Model>();
  const modelNames: string[] = [];
  const modelFields = new Map<string, Map<string, Field>>();
  const fieldSettings = new Map<string, Map<string, ObjectSettings>>();
  const getModelName = createGetModelName(modelNames);
  const getSourceFile = factoryGetSourceFile({
    output: generatorOutputValue,
    project,
    getModelName,
    outputFilePattern: config.outputFilePattern,
    eventEmitter,
  });
  const {
    datamodel,
    schema: { inputObjectTypes, outputObjectTypes, enumTypes },
  } = JSON.parse(JSON.stringify(dmmf)) as DMMF.Document;
  const removeTypes = new Set<string>();
  const eventArguments: EventArguments = {
    models,
    config,
    modelNames,
    modelFields,
    fieldSettings,
    project,
    output: generatorOutputValue,
    getSourceFile,
    eventEmitter,
    typeNames: new Set<string>(),
    enums: mapKeys(datamodel.enums, x => x.name),
    getModelName,
    removeTypes,
    classTransformerTypeModels: new Set(),
  };

  if (connectCallback) {
    await connectCallback(eventEmitter, eventArguments);
  }

  await eventEmitter.emit('Begin', eventArguments);

  for (const model of datamodel.models) {
    await eventEmitter.emit('Model', model, eventArguments);
  }

  // Types behaves like model
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  for (const model of datamodel.types || []) {
    await eventEmitter.emit('Model', model, eventArguments);
  }

  await eventEmitter.emit('PostBegin', eventArguments);

  for (const enumType of enumTypes.prisma.concat(enumTypes.model || [])) {
    await eventEmitter.emit('EnumType', enumType, eventArguments);
  }

  for (const outputType of outputObjectTypes.model) {
    await eventEmitter.emit('ModelOutputType', outputType, eventArguments);
  }

  const queryOutputTypes: OutputType[] = [];

  for (const outputType of outputObjectTypes.prisma) {
    if (['Query', 'Mutation'].includes(outputType.name)) {
      queryOutputTypes.push(outputType);
      continue;
    }
    await eventEmitter.emit('OutputType', outputType, eventArguments);
  }

  const inputTypes = inputObjectTypes.prisma.concat(inputObjectTypes.model || []);

  for (const inputType of inputTypes) {
    const event = {
      ...eventArguments,
      inputType,
      fileType: 'input',
      classDecoratorName: 'InputType',
    };
    if (inputType.fields.length === 0) {
      removeTypes.add(inputType.name);
      continue;
    }
    await eventEmitter.emit('BeforeInputType', event);
    await eventEmitter.emit('InputType', event);
  }

  for (const outputType of queryOutputTypes) {
    for (const field of outputType.fields) {
      await eventEmitter.emit('ArgsType', field, eventArguments);
    }
  }

  await eventEmitter.emit('BeforeGenerateFiles', eventArguments);
  await eventEmitter.emit('GenerateFiles', eventArguments);
  await eventEmitter.emit('End', eventArguments);

  for (const name of Object.keys(eventEmitter._events)) {
    eventEmitter.off(name);
  }
}