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 |
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 |
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 |
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 |
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 |
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 |
/**
* 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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
/**
* 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 |
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 |
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 |
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 |
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 |
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 |
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 |
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);
}
}