-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathpostProcessResults.ts
More file actions
147 lines (143 loc) · 4.88 KB
/
postProcessResults.ts
File metadata and controls
147 lines (143 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { DAILY_NOTE_PAGE_TITLE_REGEX } from "roamjs-components/date/constants";
import { Result } from "roamjs-components/types/query-builder";
import extractTag from "roamjs-components/util/extractTag";
import parseResultSettings from "./parseResultSettings";
import toCellValue from "./toCellValue";
const transform = (_val: Result[string]) =>
typeof _val === "string"
? DAILY_NOTE_PAGE_TITLE_REGEX.test(extractTag(_val))
? window.roamAlphaAPI.util.pageTitleToDate(extractTag(_val)) || new Date()
: /^(-)?\d+(\.\d*)?$/.test(_val)
? Number(_val)
: _val
: _val;
const getFilterCandidateValues = ({
value,
uid,
}: {
value: Result[string];
uid: string;
}) => {
const candidates = new Set<string>();
if (typeof value === "undefined" || value === null) return candidates;
if (value instanceof Date) {
candidates.add(window.roamAlphaAPI.util.dateToPageTitle(value));
return candidates;
}
const asString = value.toString();
candidates.add(asString);
candidates.add(extractTag(asString));
candidates.add(
toCellValue({
value: value as string | number,
uid,
})
);
return candidates;
};
const sortFunction =
(key: string, descending?: boolean) => (a: Result, b: Result) => {
const _aVal = a[key];
const _bVal = b[key];
const aVal = transform(_aVal);
const bVal = transform(_bVal);
if (aVal instanceof Date && bVal instanceof Date) {
return descending
? bVal.valueOf() - aVal.valueOf()
: aVal.valueOf() - bVal.valueOf();
} else if (typeof aVal === "number" && typeof bVal === "number") {
return descending ? bVal - aVal : aVal - bVal;
} else if (typeof aVal !== "undefined" && typeof bVal !== "undefined") {
return descending
? bVal.toString().localeCompare(aVal.toString())
: aVal.toString().localeCompare(bVal.toString());
} else {
return 0;
}
};
const postProcessResults = (
results: Result[],
settings: Omit<
ReturnType<typeof parseResultSettings>,
"views" | "layout" | "resultNodeUid"
>
) => {
const sortedResults = results
.filter((r) => {
const deprecatedFilter = Object.keys(settings.filters).every(
(filterKey) => {
const includeValues =
settings.filters[filterKey].includes.values || new Set();
const excludeValues =
settings.filters[filterKey].excludes.values || new Set();
const resultValueCandidates = getFilterCandidateValues({
value: r[filterKey],
uid: (r[`${filterKey}-uid`] as string) || "",
});
return (
(includeValues.size === 0 &&
!Array.from(resultValueCandidates).some((v) =>
excludeValues.has(v)
)) ||
Array.from(resultValueCandidates).some((v) => includeValues.has(v))
);
}
);
if (!deprecatedFilter) return false;
return settings.columnFilters.every((columnFilter) => {
switch (columnFilter.type) {
case "contains":
const resultValue = r[columnFilter.key];
const resultValueString =
typeof resultValue === "string" ? resultValue : `${resultValue}`;
return resultValueString.includes(columnFilter.value[0]);
case "equals":
if (
columnFilter.value.length === 1 &&
columnFilter.value[0] === ""
) {
return true;
}
return columnFilter.value.some((v) => r[columnFilter.key] === v);
case "greater than":
const gtFilter = transform(columnFilter.value[0]);
const gtResult = transform(r[columnFilter.key]);
return gtResult > gtFilter;
case "less than":
const ltFilter = transform(columnFilter.value[0]);
const ltResult = transform(r[columnFilter.key]);
return ltResult < ltFilter;
default:
return true;
}
});
})
.filter((r) => {
return settings.searchFilter
? Object.keys(r)
.filter((key) => !key.endsWith("-uid") && key !== "uid")
.some((key) =>
String(r[key])
.toLowerCase()
.includes(settings.searchFilter.toLowerCase())
)
: true;
})
.sort((a, b) => {
for (const sort of settings.activeSort) {
const cmpResult = sortFunction(sort.key, sort.descending)(a, b);
if (cmpResult !== 0) return cmpResult;
}
return 0;
});
const allProcessedResults =
settings.random > 0
? sortedResults.sort(() => 0.5 - Math.random()).slice(0, settings.random)
: sortedResults;
const paginatedResults = allProcessedResults.slice(
(settings.page - 1) * settings.pageSize,
settings.page * settings.pageSize
);
return { results, allProcessedResults, paginatedResults };
};
export default postProcessResults;