@knowmax/genericlist-core
Version:
Knowmax Generic list with basic CRUD support without any user interface implementation.
131 lines (130 loc) • 5.3 kB
JavaScript
import { PARAM_PAGE, PARAM_ORDER, PARAM_DELETED, FilterOperator, FilterValueType } from "../types";
import { serializeFilterValue, serializeFilterOperator, parseOrderExpression, fieldIdForOperator, getParamId } from ".";
/** Deserialize GenericList settings from given URLSearchParams.
* @returns true if params have been updated. Caller is reposible to update params in state.
*/
export const deserializeListState = (list, params) => {
const initialstate = listState(list);
let paramsupdated = false;
deserializeDeleted(list, params);
if (deserializeFilters(list, params)) {
paramsupdated = true;
}
if (deserializeOrder(list, params)) {
paramsupdated = true;
}
if (deserializePage(list, params, initialstate)) {
paramsupdated = true;
}
return paramsupdated;
};
/** Current state of list used for state change detection */
const listState = (list) => `f=${list.filter ?? ''}&o=${list.orderExpression}&s=${list.search ?? ''}&d=${list.deleted}`;
const deserializeOrder = (list, params) => {
const orderparamid = getParamId(PARAM_ORDER, list.id);
const ordervalue = params.get(orderparamid);
if (ordervalue) {
const [field, descending] = parseOrderExpression(ordervalue);
const order = list.orderList.find((order) => order.field === field && (order.descending === descending || (order.descending === undefined && descending === false)));
if (order && (!order.isAvailable || order.isAvailable(order, params, list.id))) {
list.setOrder(order);
}
else {
// reset to default
params.delete(orderparamid);
list.setOrder(list.orderList?.find(o => o.default === true));
return true;
}
}
return false;
};
const deserializeFilters = (list, params) => {
let paramsupdated = false;
let hassearch = false;
const filters = [];
list.filterList.forEach((filter) => {
if (filter.deserializeCustom) {
const customfilters = filter.deserializeCustom(filter, params, list.id);
if (customfilters) {
filters.push(...customfilters);
}
}
else {
const paramid = getParamId(filter.id, list.id);
const value = params.get(paramid);
if (value && value !== '') {
if (filter.isAvailable && !filter.isAvailable(filter, params, list.id)) {
params.delete(paramid);
params.delete(fieldIdForOperator(paramid));
paramsupdated = true;
}
else if (filter.options) {
const option = filter.options.find((o) => o.id === value);
if (option) {
if (option.expression !== undefined && option.expression !== '') {
filters.push(option.expression);
}
else if (option.value !== undefined && (typeof option.value === 'number' || typeof option.value === 'boolean' || option.value !== '')) {
filters.push(`${filter.field ?? filter.id} ${serializeFilterOperator(option.operator)} ${serializeFilterValue(option.value, filter.valueType)}`);
}
}
}
else if (filter.isSearch === true) {
list.setSearch(value);
hassearch = true;
}
else {
filters.push(`${filter.field ?? filter.id} ${serializeFilterOperator(operatorForFilter(filter, params, list.id))} ${serializeFilterValue(value, filter.valueType)}`);
}
}
}
});
list.setFilter(filters.length > 0 ? filters.join(' and ') : undefined /*list.filter*/);
if (!hassearch) {
list.setSearch(undefined);
}
return paramsupdated;
};
const deserializePage = (list, params, initialState) => {
const pageparamid = getParamId(PARAM_PAGE, list.id);
const page = params.get(pageparamid);
if (page && initialState === listState(list)) {
const p = parseInt(page);
if (isNaN(p) || p === 1) {
if (list.page !== 1) {
list.setPage(1);
params.delete(pageparamid);
return true;
}
}
else {
list.setPage(p);
}
}
else if (list.page !== 1) {
list.setPage(1);
params.delete(pageparamid);
return true;
}
return false;
};
const deserializeDeleted = (list, params) => {
const paramid = getParamId(PARAM_DELETED, list.id);
const value = params.get(paramid);
list.setDeleted(params.has(paramid) && value !== 'false');
};
export const operatorForFilter = (filter, params, listId) => {
if (filter.valueType === FilterValueType.boolean) {
return FilterOperator.eq;
}
else {
const operatorvalue = params.get(fieldIdForOperator(getParamId(filter.id, listId)));
if (operatorvalue) {
const o = FilterOperator[operatorvalue];
if (filter.operators && filter.operators.indexOf(o) !== -1) {
return o;
}
}
return filter.operator;
}
};