UNPKG

@knowmax/genericlist-core

Version:

Knowmax Generic list with basic CRUD support without any user interface implementation.

131 lines (130 loc) 5.3 kB
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; } };