193 lines
5.7 KiB
TypeScript
193 lines
5.7 KiB
TypeScript
import { differenceWith, isEmpty, isEqual, reverse, unionWith } from 'lodash';
|
|
|
|
export const parseQueryString = (queryString: Record<string, string>) => {
|
|
// pagination
|
|
const pageIndex = parseInt(queryString.page ?? '0', 0) - 1;
|
|
const pageSize = Math.min(parseInt(queryString.limit ?? '10', 10), 100);
|
|
const pagination =
|
|
pageIndex >= 0 && pageSize > 0 ? { pageIndex, pageSize } : undefined;
|
|
|
|
// pagination
|
|
/*let pagination = undefined;
|
|
if (page !== undefined && limit !== undefined) {
|
|
let parsedPage = toSafeInteger(queryString['page']) - 1;
|
|
if (parsedPage < 0) parsedPage = 0;
|
|
|
|
let parsedPageSize = toSafeInteger(queryString['limit']);
|
|
if (parsedPageSize > 100) parsedPageSize = 100;
|
|
if (parsedPageSize < 5) parsedPageSize = 5;
|
|
|
|
pagination = {
|
|
pageIndex: parsedPage,
|
|
pageSize: parsedPageSize,
|
|
};
|
|
}*/
|
|
|
|
// sorter
|
|
// sorter
|
|
const sorter = (queryString.sort ?? '')
|
|
.split(',')
|
|
.map((token) => token.match(/([+-]?)([\w_]+)/i))
|
|
.slice(0, 3)
|
|
.map((item) => (item ? { id: item[2], desc: item[1] === '-' } : null))
|
|
.filter(Boolean);
|
|
|
|
/*let sorter = [];
|
|
if (sort !== undefined) {
|
|
sorter = sort
|
|
.split(',')
|
|
.map((token) => token.match(/([+-]?)([\w_]+)/i))
|
|
.slice(0, 3)
|
|
.map((item) =>
|
|
item ? { id: item[2], desc: item[1] === '-' } : null
|
|
);
|
|
}*/
|
|
|
|
// filters
|
|
const filters = Object.entries(queryString)
|
|
.filter(([key]) => key !== 'page' && key !== 'limit' && key !== 'sort')
|
|
.map(([key, value]) => {
|
|
const [, field, , , operator] =
|
|
key.match(/([\w]+)(([\[])([\w]+)([\]]))*/i) ?? [];
|
|
const sanitizedOperator = _sanitizeOperator(operator ?? '');
|
|
return !isEmpty(value)
|
|
? { field, operator: sanitizedOperator, value }
|
|
: null;
|
|
})
|
|
.filter(Boolean);
|
|
|
|
/*let filters = [];
|
|
if (filterCandidates !== undefined) {
|
|
Object.keys(filterCandidates).map((token) => {
|
|
const [, field, , , operator] = token.match( */
|
|
// /([\w]+)(([\[])([\w]+)([\]]))*/i
|
|
/* );
|
|
const value = filterCandidates[token];
|
|
|
|
if (!isEmpty(value)) {
|
|
filters.push({
|
|
field,
|
|
operator: _sanitizeOperator(operator),
|
|
value,
|
|
});
|
|
}
|
|
});
|
|
}*/
|
|
|
|
return {
|
|
pagination,
|
|
sorter,
|
|
filters,
|
|
};
|
|
};
|
|
|
|
export const buildQueryString = ({ pagination, sorter, filters }) => {
|
|
const params = new URLSearchParams();
|
|
|
|
if (
|
|
pagination &&
|
|
pagination.pageIndex !== undefined &&
|
|
pagination.pageSize !== undefined
|
|
) {
|
|
params.append('page', String(pagination.pageIndex + 1));
|
|
params.append('limit', String(pagination.pageSize));
|
|
}
|
|
|
|
if (sorter && Array.isArray(sorter) && sorter.length > 0) {
|
|
params.append(
|
|
'sort',
|
|
sorter.map(({ id, desc }) => `${desc ? '-' : ''}${id}`).toString()
|
|
);
|
|
}
|
|
|
|
if (filters && Array.isArray(filters) && filters.length > 0) {
|
|
filters.forEach((filterItem) => {
|
|
if (filterItem.value !== undefined) {
|
|
let operator = _mapFilterOperator(filterItem.operator);
|
|
if (operator === 'eq') {
|
|
params.append(`${filterItem.field}`, filterItem.value);
|
|
} else {
|
|
params.append(
|
|
`${filterItem.field}[${_mapFilterOperator(
|
|
filterItem.operator
|
|
)}]`,
|
|
filterItem.value
|
|
);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return params.toString();
|
|
};
|
|
|
|
export const combineFilters = (requiredFilters = [], otherFilters = []) => [
|
|
...differenceWith(otherFilters, requiredFilters, isEqual),
|
|
...requiredFilters,
|
|
];
|
|
|
|
export const unionFilters = (
|
|
permanentFilter = [],
|
|
newFilters = [],
|
|
prevFilters = []
|
|
) =>
|
|
reverse(
|
|
unionWith(
|
|
permanentFilter,
|
|
newFilters,
|
|
prevFilters,
|
|
(left, right) =>
|
|
left.field == right.field && left.operator == right.operator
|
|
)
|
|
).filter(
|
|
(crudFilter) =>
|
|
crudFilter.value !== undefined && crudFilter.value !== null
|
|
);
|
|
|
|
export const extractTableSortPropertiesFromColumn = (columns) => {
|
|
const _extractColumnSortProperies = (column) => {
|
|
const { canSort, isSorted, sortedIndex, isSortedDesc } = column;
|
|
if (!isSorted || !canSort) {
|
|
return undefined;
|
|
} else {
|
|
return {
|
|
index: sortedIndex,
|
|
field: column.id,
|
|
order: isSortedDesc ? 'DESC' : 'ASC',
|
|
};
|
|
}
|
|
};
|
|
|
|
return columns
|
|
.map((column) => _extractColumnSortProperies(column))
|
|
.filter((item) => item)
|
|
.sort((a, b) => a.index - b.index);
|
|
};
|
|
|
|
export const extractTableSortProperties = (sorter) => {
|
|
return sorter.map((sortItem, index) => ({
|
|
index,
|
|
field: sortItem.id,
|
|
order: sortItem.desc ? 'DESC' : 'ASC',
|
|
}));
|
|
};
|
|
|
|
export const extractTableFilterProperties = (filters) =>
|
|
filters.filter((item) => !isEmpty(item.value));
|
|
|
|
const _sanitizeOperator = (operator) =>
|
|
['eq', 'ne', 'gte', 'lte', 'like'].includes(operator) ? operator : 'eq';
|
|
|
|
const _mapFilterOperator = (operator) => {
|
|
switch (operator) {
|
|
case 'ne':
|
|
case 'gte':
|
|
case 'lte':
|
|
return `[${operator}]`;
|
|
case 'contains':
|
|
return '[like]';
|
|
default:
|
|
return 'eq';
|
|
}
|
|
};
|