@adminforth/universal-search 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.log +2 -2
- package/custom/UniversalSearchInput.vue +20 -17
- package/custom/tsconfig.json +2 -5
- package/dist/custom/UniversalSearchInput.vue +20 -17
- package/dist/custom/tsconfig.json +2 -5
- package/dist/index.js +41 -50
- package/index.ts +64 -65
- package/package.json +1 -1
package/build.log
CHANGED
|
@@ -21,38 +21,41 @@
|
|
|
21
21
|
</template>
|
|
22
22
|
<script setup lang="ts">
|
|
23
23
|
import { ref, watch } from 'vue';
|
|
24
|
-
|
|
24
|
+
import adminforth from '@/adminforth';
|
|
25
|
+
import { AdminForthFilterOperators } from '@/types/Common';
|
|
25
26
|
|
|
26
27
|
const props = defineProps<{ meta?: any; resource?: any; adminUser?: any }>();
|
|
27
28
|
const localValue = ref('');
|
|
28
|
-
let
|
|
29
|
+
let t: any = null;
|
|
29
30
|
|
|
30
|
-
function
|
|
31
|
+
function send(term?: string) {
|
|
32
|
+
adminforth?.list?.updateFilter?.({
|
|
33
|
+
field: '_universal_search',
|
|
34
|
+
operator: AdminForthFilterOperators.EQ,
|
|
35
|
+
value: term || '',
|
|
36
|
+
});
|
|
37
|
+
adminforth?.list?.refresh?.();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function apply() {
|
|
31
41
|
const term = localValue.value.trim();
|
|
32
|
-
|
|
33
|
-
adminforth.list.refresh && adminforth.list.refresh();
|
|
42
|
+
send(term || '');
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
function applyImmediate() {
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
applyInternal();
|
|
46
|
+
if (t) clearTimeout(t);
|
|
47
|
+
t = null;
|
|
48
|
+
apply();
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
watch(localValue, () => {
|
|
45
52
|
const delay = props.meta?.debounceMs ?? 500;
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
debounceTimer = setTimeout(() => {
|
|
50
|
-
applyInternal();
|
|
51
|
-
}, delay);
|
|
53
|
+
if (t) clearTimeout(t);
|
|
54
|
+
t = setTimeout(apply, delay);
|
|
52
55
|
});
|
|
53
56
|
|
|
54
57
|
function clear() {
|
|
55
58
|
localValue.value = '';
|
|
56
59
|
applyImmediate();
|
|
57
60
|
}
|
|
58
|
-
</script>
|
|
61
|
+
</script>
|
package/custom/tsconfig.json
CHANGED
|
@@ -4,15 +4,12 @@
|
|
|
4
4
|
"esModuleInterop": true,
|
|
5
5
|
"paths": {
|
|
6
6
|
"@/*": [
|
|
7
|
-
|
|
8
|
-
"../../../spa/src/*"
|
|
7
|
+
"../node_modules/adminforth/dist/spa/src/*"
|
|
9
8
|
],
|
|
10
9
|
"*": [
|
|
11
|
-
|
|
12
|
-
"../../../spa/node_modules/*"
|
|
10
|
+
"../node_modules/adminforth/dist/spa/node_modules/*"
|
|
13
11
|
],
|
|
14
12
|
"@@/*": [
|
|
15
|
-
// "node_modules/adminforth/dist/spa/src/*"
|
|
16
13
|
"."
|
|
17
14
|
]
|
|
18
15
|
}
|
|
@@ -21,38 +21,41 @@
|
|
|
21
21
|
</template>
|
|
22
22
|
<script setup lang="ts">
|
|
23
23
|
import { ref, watch } from 'vue';
|
|
24
|
-
|
|
24
|
+
import adminforth from '@/adminforth';
|
|
25
|
+
import { AdminForthFilterOperators } from '@/types/Common';
|
|
25
26
|
|
|
26
27
|
const props = defineProps<{ meta?: any; resource?: any; adminUser?: any }>();
|
|
27
28
|
const localValue = ref('');
|
|
28
|
-
let
|
|
29
|
+
let t: any = null;
|
|
29
30
|
|
|
30
|
-
function
|
|
31
|
+
function send(term?: string) {
|
|
32
|
+
adminforth?.list?.updateFilter?.({
|
|
33
|
+
field: '_universal_search',
|
|
34
|
+
operator: AdminForthFilterOperators.EQ,
|
|
35
|
+
value: term || '',
|
|
36
|
+
});
|
|
37
|
+
adminforth?.list?.refresh?.();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function apply() {
|
|
31
41
|
const term = localValue.value.trim();
|
|
32
|
-
|
|
33
|
-
adminforth.list.refresh && adminforth.list.refresh();
|
|
42
|
+
send(term || '');
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
function applyImmediate() {
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
applyInternal();
|
|
46
|
+
if (t) clearTimeout(t);
|
|
47
|
+
t = null;
|
|
48
|
+
apply();
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
watch(localValue, () => {
|
|
45
52
|
const delay = props.meta?.debounceMs ?? 500;
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
debounceTimer = setTimeout(() => {
|
|
50
|
-
applyInternal();
|
|
51
|
-
}, delay);
|
|
53
|
+
if (t) clearTimeout(t);
|
|
54
|
+
t = setTimeout(apply, delay);
|
|
52
55
|
});
|
|
53
56
|
|
|
54
57
|
function clear() {
|
|
55
58
|
localValue.value = '';
|
|
56
59
|
applyImmediate();
|
|
57
60
|
}
|
|
58
|
-
</script>
|
|
61
|
+
</script>
|
|
@@ -4,15 +4,12 @@
|
|
|
4
4
|
"esModuleInterop": true,
|
|
5
5
|
"paths": {
|
|
6
6
|
"@/*": [
|
|
7
|
-
|
|
8
|
-
"../../../spa/src/*"
|
|
7
|
+
"../node_modules/adminforth/dist/spa/src/*"
|
|
9
8
|
],
|
|
10
9
|
"*": [
|
|
11
|
-
|
|
12
|
-
"../../../spa/node_modules/*"
|
|
10
|
+
"../node_modules/adminforth/dist/spa/node_modules/*"
|
|
13
11
|
],
|
|
14
12
|
"@@/*": [
|
|
15
|
-
// "node_modules/adminforth/dist/spa/src/*"
|
|
16
13
|
"."
|
|
17
14
|
]
|
|
18
15
|
}
|
package/dist/index.js
CHANGED
|
@@ -85,81 +85,72 @@ export default class UniversalSearchPlugin extends AdminForthPlugin {
|
|
|
85
85
|
if (!this.resourceConfig.hooks.list)
|
|
86
86
|
this.resourceConfig.hooks.list = {};
|
|
87
87
|
const originalBefore = this.resourceConfig.hooks.list.beforeDatasourceRequest;
|
|
88
|
+
const VIRTUAL_FIELD = '_universal_search';
|
|
88
89
|
const transformFilters = (filters) => {
|
|
89
|
-
return filters.flatMap(f => {
|
|
90
|
+
return (filters !== null && filters !== void 0 ? filters : []).flatMap(f => {
|
|
91
|
+
var _a, _b;
|
|
90
92
|
if (!f)
|
|
91
93
|
return [];
|
|
92
|
-
|
|
94
|
+
const op = String((_a = f.operator) !== null && _a !== void 0 ? _a : '').toLowerCase();
|
|
95
|
+
if (op === 'or' || op === 'and') {
|
|
93
96
|
return [Object.assign(Object.assign({}, f), { subFilters: transformFilters(f.subFilters || []) })];
|
|
94
97
|
}
|
|
95
|
-
if (f.field ===
|
|
96
|
-
const term = (f.value
|
|
98
|
+
if (f.field === VIRTUAL_FIELD) {
|
|
99
|
+
const term = String((_b = f.value) !== null && _b !== void 0 ? _b : '').trim();
|
|
97
100
|
if (!term)
|
|
98
101
|
return [];
|
|
99
102
|
const sub = [];
|
|
100
|
-
|
|
103
|
+
for (const col of columns) {
|
|
101
104
|
const searchBy = (col.searchBy === 'labelOnly' ? 'keyOnly' : col.searchBy) || 'valueOnly';
|
|
102
|
-
const
|
|
105
|
+
const add = (field) => {
|
|
103
106
|
if (col.exact) {
|
|
104
|
-
if (col.caseSensitive)
|
|
107
|
+
if (col.caseSensitive)
|
|
105
108
|
sub.push(Filters.LIKE(field, term));
|
|
106
|
-
|
|
107
|
-
else {
|
|
109
|
+
else
|
|
108
110
|
sub.push(Filters.EQ(field, term));
|
|
109
|
-
}
|
|
110
111
|
}
|
|
111
112
|
else {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
else
|
|
116
|
-
sub.push(Filters.ILIKE
|
|
117
|
-
|
|
113
|
+
const likeVal = `${term}`;
|
|
114
|
+
if (col.caseSensitive)
|
|
115
|
+
sub.push(Filters.LIKE(field, likeVal));
|
|
116
|
+
else if (Filters.ILIKE)
|
|
117
|
+
sub.push(Filters.ILIKE(field, likeVal));
|
|
118
|
+
else
|
|
119
|
+
sub.push(Filters.LIKE(field, likeVal));
|
|
118
120
|
}
|
|
119
121
|
};
|
|
120
122
|
if (searchBy === 'valueOnly')
|
|
121
|
-
|
|
123
|
+
add(col.name);
|
|
122
124
|
else if (searchBy === 'keyOnly')
|
|
123
|
-
|
|
124
|
-
else
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
add(`${col.name}__key`);
|
|
126
|
+
else {
|
|
127
|
+
add(col.name);
|
|
128
|
+
add(`${col.name}__key`);
|
|
127
129
|
}
|
|
128
|
-
}
|
|
130
|
+
}
|
|
129
131
|
if (!sub.length)
|
|
130
132
|
return [];
|
|
131
|
-
|
|
132
|
-
return [Filters.OR(sub)];
|
|
133
|
+
return [Filters.OR(...sub)];
|
|
133
134
|
}
|
|
134
135
|
return [f];
|
|
135
136
|
});
|
|
136
137
|
};
|
|
137
|
-
const transformer = (
|
|
138
|
-
var
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
if (Array.isArray(query.filters)) {
|
|
157
|
-
query.filters = query.filters.filter(f => (f === null || f === void 0 ? void 0 : f.field) !== virtualFieldName);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (Array.isArray(query === null || query === void 0 ? void 0 : query.filters)) {
|
|
162
|
-
query.filters = transformFilters(query.filters);
|
|
138
|
+
const transformer = (_a) => __awaiter(this, [_a], void 0, function* ({ query }) {
|
|
139
|
+
var _b, _c, _d, _e, _f;
|
|
140
|
+
const term = String(((_e = (_d = (_c = (_b = query === null || query === void 0 ? void 0 : query.body) === null || _b === void 0 ? void 0 : _b.__universal_search_term) !== null && _c !== void 0 ? _c : query === null || query === void 0 ? void 0 : query.__universal_search_term) !== null && _d !== void 0 ? _d : global.__universal_search_term) !== null && _e !== void 0 ? _e : '')).trim();
|
|
141
|
+
const incoming = Array.isArray(query === null || query === void 0 ? void 0 : query.filters)
|
|
142
|
+
? query.filters
|
|
143
|
+
: Array.isArray((_f = query === null || query === void 0 ? void 0 : query.body) === null || _f === void 0 ? void 0 : _f.filters)
|
|
144
|
+
? query.body.filters
|
|
145
|
+
: [];
|
|
146
|
+
const withVirtual = term
|
|
147
|
+
? [...incoming, { field: VIRTUAL_FIELD, operator: 'eq', value: term }]
|
|
148
|
+
: incoming;
|
|
149
|
+
const transformed = transformFilters(withVirtual);
|
|
150
|
+
query.filters = transformed;
|
|
151
|
+
query.body = Object.assign(Object.assign({}, (query.body || {})), { filters: transformed });
|
|
152
|
+
if (query.body.__universal_search_term !== undefined) {
|
|
153
|
+
delete query.body.__universal_search_term;
|
|
163
154
|
}
|
|
164
155
|
return { ok: true, error: '' };
|
|
165
156
|
});
|
package/index.ts
CHANGED
|
@@ -76,75 +76,74 @@ export default class UniversalSearchPlugin extends AdminForthPlugin {
|
|
|
76
76
|
if (!this.resourceConfig.hooks.list) this.resourceConfig.hooks.list = {} as any;
|
|
77
77
|
const originalBefore = this.resourceConfig.hooks.list.beforeDatasourceRequest;
|
|
78
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
|
-
if (searchBy === 'valueOnly') addFilter(col.name);
|
|
107
|
-
else if (searchBy === 'keyOnly') addFilter(`${col.name}__key`);
|
|
108
|
-
else if (searchBy === 'both') { addFilter(col.name); addFilter(`${col.name}__key`); }
|
|
109
|
-
});
|
|
110
|
-
if (!sub.length) return [];
|
|
111
|
-
console.log('UniversalSearchPlugin: transformed filter', f, '=>', sub);
|
|
112
|
-
return [Filters.OR(sub)];
|
|
113
|
-
}
|
|
114
|
-
return [f];
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const transformer = async (ctx: any) => {
|
|
119
|
-
const { query } = ctx;
|
|
120
|
-
|
|
121
|
-
let incomingTerm = (query?.body?.__universal_search_term ?? query?.__universal_search_term ?? '').toString().trim();
|
|
122
|
-
if (!incomingTerm && Array.isArray(query?.filters)) {
|
|
123
|
-
const vf = (query.filters as any[]).find(f => f?.field === virtualFieldName && typeof f.value === 'string');
|
|
124
|
-
if (vf) incomingTerm = vf.value.trim();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (ephemeral) {
|
|
128
|
-
if (incomingTerm) {
|
|
129
|
-
query.__universal_search_term = incomingTerm;
|
|
130
|
-
const alreadyHas = Array.isArray(query.filters) && (query.filters as any[]).some(f => f?.field === virtualFieldName);
|
|
131
|
-
if (!alreadyHas) {
|
|
132
|
-
const tempFilter = { field: virtualFieldName, operator: 'eq', value: incomingTerm };
|
|
133
|
-
query.filters = Array.isArray(query.filters) ? [...query.filters, tempFilter] : [tempFilter];
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
if (Array.isArray(query.filters)) {
|
|
137
|
-
query.filters = (query.filters as any[]).filter(f => f?.field !== virtualFieldName);
|
|
79
|
+
const VIRTUAL_FIELD = '_universal_search';
|
|
80
|
+
|
|
81
|
+
const transformFilters = (filters: any[]): any[] => {
|
|
82
|
+
return (filters ?? []).flatMap(f => {
|
|
83
|
+
if (!f) return [];
|
|
84
|
+
const op = String(f.operator ?? '').toLowerCase();
|
|
85
|
+
if (op === 'or' || op === 'and') {
|
|
86
|
+
return [{ ...f, subFilters: transformFilters(f.subFilters || []) }];
|
|
87
|
+
}
|
|
88
|
+
if (f.field === VIRTUAL_FIELD) {
|
|
89
|
+
const term = String(f.value ?? '').trim();
|
|
90
|
+
if (!term) return [];
|
|
91
|
+
const sub: any[] = [];
|
|
92
|
+
|
|
93
|
+
for (const col of columns) {
|
|
94
|
+
const searchBy = (col.searchBy === 'labelOnly' ? 'keyOnly' : col.searchBy) || 'valueOnly';
|
|
95
|
+
const add = (field: string) => {
|
|
96
|
+
if (col.exact) {
|
|
97
|
+
if (col.caseSensitive) sub.push(Filters.LIKE(field, term));
|
|
98
|
+
else sub.push(Filters.EQ(field, term));
|
|
99
|
+
} else {
|
|
100
|
+
const likeVal = `${term}`;
|
|
101
|
+
if (col.caseSensitive) sub.push(Filters.LIKE(field, likeVal));
|
|
102
|
+
else if ((Filters as any).ILIKE) sub.push((Filters as any).ILIKE(field, likeVal));
|
|
103
|
+
else sub.push(Filters.LIKE(field, likeVal));
|
|
138
104
|
}
|
|
139
|
-
}
|
|
105
|
+
};
|
|
106
|
+
if (searchBy === 'valueOnly') add(col.name);
|
|
107
|
+
else if (searchBy === 'keyOnly') add(`${col.name}__key`);
|
|
108
|
+
else { add(col.name); add(`${col.name}__key`); }
|
|
140
109
|
}
|
|
141
110
|
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
111
|
+
if (!sub.length) return [];
|
|
112
|
+
return [Filters.OR(...sub)];
|
|
113
|
+
}
|
|
114
|
+
return [f];
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const transformer = async ({ query }: { query: any }) => {
|
|
119
|
+
const term = String(
|
|
120
|
+
(query?.body?.__universal_search_term ??
|
|
121
|
+
query?.__universal_search_term ??
|
|
122
|
+
(global as any).__universal_search_term ??
|
|
123
|
+
'')
|
|
124
|
+
).trim();
|
|
125
|
+
|
|
126
|
+
const incoming = Array.isArray(query?.filters)
|
|
127
|
+
? query.filters
|
|
128
|
+
: Array.isArray(query?.body?.filters)
|
|
129
|
+
? query.body.filters
|
|
130
|
+
: [];
|
|
131
|
+
|
|
132
|
+
const withVirtual = term
|
|
133
|
+
? [...incoming, { field: VIRTUAL_FIELD, operator: 'eq', value: term }]
|
|
134
|
+
: incoming;
|
|
135
|
+
|
|
136
|
+
const transformed = transformFilters(withVirtual);
|
|
137
|
+
|
|
138
|
+
query.filters = transformed;
|
|
139
|
+
query.body = { ...(query.body || {}), filters: transformed };
|
|
140
|
+
|
|
141
|
+
if (query.body.__universal_search_term !== undefined) {
|
|
142
|
+
delete query.body.__universal_search_term;
|
|
143
|
+
}
|
|
145
144
|
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
return { ok: true, error: '' };
|
|
146
|
+
};
|
|
148
147
|
|
|
149
148
|
if (!originalBefore) {
|
|
150
149
|
this.resourceConfig.hooks.list.beforeDatasourceRequest = [transformer];
|