paperless-ngx/src-ui/src/app/utils/query-params.ts
shamoon aaf7590ed8
Just save this
[ci skip]
2025-03-16 21:00:29 -07:00

172 lines
5.6 KiB
TypeScript

import { ParamMap, Params } from '@angular/router'
import {
CustomFieldQueryLogicalOperator,
CustomFieldQueryOperator,
} from '../data/custom-field-query'
import { FilterRule } from '../data/filter-rule'
import {
FILTER_CUSTOM_FIELDS_QUERY,
FILTER_HAS_CUSTOM_FIELDS_ALL,
FILTER_HAS_CUSTOM_FIELDS_ANY,
FILTER_RULE_TYPES,
FilterRuleType,
NEGATIVE_NULL_FILTER_VALUE,
} from '../data/filter-rule-type'
import { ListViewState } from '../services/document-list-view.service'
const SORT_FIELD_PARAMETER = 'sort'
const SORT_REVERSE_PARAMETER = 'reverse'
const PAGE_PARAMETER = 'page'
export function paramsFromViewState(
viewState: ListViewState,
pageOnly: boolean = false
): Params {
let params = queryParamsFromFilterRules(viewState.filterRules)
params[SORT_FIELD_PARAMETER] = viewState.sortField
params[SORT_REVERSE_PARAMETER] = viewState.sortReverse ? 1 : undefined
if (pageOnly) params = {}
params[PAGE_PARAMETER] = isNaN(viewState.currentPage)
? 1
: viewState.currentPage
if (pageOnly && viewState.currentPage == 1) params[PAGE_PARAMETER] = undefined
return params
}
export function paramsToViewState(queryParams: ParamMap): ListViewState {
let filterRules = filterRulesFromQueryParams(queryParams)
let sortField = queryParams.get(SORT_FIELD_PARAMETER)
let sortReverse =
queryParams.has(SORT_REVERSE_PARAMETER) ||
(!queryParams.has(SORT_FIELD_PARAMETER) &&
!queryParams.has(SORT_REVERSE_PARAMETER))
let currentPage = queryParams.has(PAGE_PARAMETER)
? parseInt(queryParams.get(PAGE_PARAMETER))
: 1
return {
currentPage: currentPage,
filterRules: filterRules,
sortField: sortField,
sortReverse: sortReverse,
}
}
export function transformLegacyFilterRules(
filterRules: FilterRule[]
): FilterRule[] {
const LEGACY_CUSTOM_FIELD_FILTER_RULE_TYPES = [
FILTER_HAS_CUSTOM_FIELDS_ANY,
FILTER_HAS_CUSTOM_FIELDS_ALL,
]
if (
filterRules.filter((rule) =>
LEGACY_CUSTOM_FIELD_FILTER_RULE_TYPES.includes(rule.rule_type)
).length
) {
const anyRules = filterRules.filter(
(rule) => rule.rule_type === FILTER_HAS_CUSTOM_FIELDS_ANY
)
const allRules = filterRules.filter(
(rule) => rule.rule_type === FILTER_HAS_CUSTOM_FIELDS_ALL
)
const customFieldQueryLogicalOperator = allRules.length
? CustomFieldQueryLogicalOperator.And
: CustomFieldQueryLogicalOperator.Or
const valueRules = allRules.length ? allRules : anyRules
const customFieldQueryExpression = [
customFieldQueryLogicalOperator,
[
...valueRules.map((rule) => [
parseInt(rule.value),
CustomFieldQueryOperator.Exists,
true,
]),
],
]
filterRules.push({
rule_type: FILTER_CUSTOM_FIELDS_QUERY,
value: JSON.stringify(customFieldQueryExpression),
})
}
// TODO: can we support FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS or FILTER_HAS_ANY_CUSTOM_FIELDS?
return filterRules.filter(
(rule) => !LEGACY_CUSTOM_FIELD_FILTER_RULE_TYPES.includes(rule.rule_type)
)
}
export function filterRulesFromQueryParams(
queryParams: ParamMap
): FilterRule[] {
const allFilterRuleQueryParams: string[] = FILTER_RULE_TYPES.map(
(rt) => rt.filtervar
)
.concat(FILTER_RULE_TYPES.map((rt) => rt.isnull_filtervar))
.filter((rt) => rt !== undefined)
// transform query params to filter rules
let filterRulesFromQueryParams: FilterRule[] = []
allFilterRuleQueryParams
.filter((frqp) => queryParams.has(frqp))
.forEach((filterQueryParamName) => {
const rule_type: FilterRuleType = FILTER_RULE_TYPES.find(
(rt) =>
rt.filtervar == filterQueryParamName ||
rt.isnull_filtervar == filterQueryParamName
)
const isNullRuleType = rule_type.isnull_filtervar == filterQueryParamName
const nullRuleValue =
queryParams.get(filterQueryParamName) == '1'
? null
: NEGATIVE_NULL_FILTER_VALUE.toString()
const valueURIComponent: string = queryParams.get(filterQueryParamName)
const filterQueryParamValues: string[] = rule_type.multi
? valueURIComponent.split(',')
: [valueURIComponent]
filterRulesFromQueryParams = filterRulesFromQueryParams.concat(
// map all values to filter rules
filterQueryParamValues.map((val) => {
if (rule_type.datatype == 'boolean')
val = val.replace('1', 'true').replace('0', 'false')
return {
rule_type: rule_type.id,
value: isNullRuleType ? nullRuleValue : val,
}
})
)
})
filterRulesFromQueryParams = transformLegacyFilterRules(
filterRulesFromQueryParams
)
return filterRulesFromQueryParams
}
export function queryParamsFromFilterRules(filterRules: FilterRule[]): Params {
if (filterRules) {
let params = {}
for (let rule of filterRules) {
let ruleType = FILTER_RULE_TYPES.find((t) => t.id == rule.rule_type)
if (ruleType.isnull_filtervar && rule.value == null) {
params[ruleType.isnull_filtervar] = 1
} else if (
ruleType.isnull_filtervar &&
rule.value == NEGATIVE_NULL_FILTER_VALUE.toString()
) {
params[ruleType.isnull_filtervar] = 0
} else if (ruleType.multi) {
params[ruleType.filtervar] = params[ruleType.filtervar]
? params[ruleType.filtervar] + ',' + rule.value
: rule.value
} else {
params[ruleType.filtervar] = rule.value
if (ruleType.datatype == 'boolean')
params[ruleType.filtervar] =
rule.value == 'true' || rule.value == '1' ? 1 : 0
}
}
return params
} else {
return null
}
}