react-hook-core 0.4.23 → 0.5.1
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/lib/common.js +0 -57
- package/lib/core.js +16 -1
- package/lib/edit.js +27 -27
- package/lib/index.js +0 -4
- package/lib/reflect.js +18 -39
- package/lib/route.js +5 -0
- package/lib/search.js +71 -16
- package/lib/state.js +61 -219
- package/lib/util.js +13 -2
- package/package.json +1 -1
- package/src/com.ts +1 -1
- package/src/common.ts +1 -61
- package/src/core.ts +14 -10
- package/src/edit.ts +36 -36
- package/src/index.ts +5 -5
- package/src/route.ts +15 -0
- package/src/search.ts +69 -17
- package/src/state.ts +71 -223
- package/src/util.ts +14 -2
- package/lib/formutil.js +0 -76
- package/lib/update.js +0 -151
- package/lib/useEdit.js +0 -582
- package/lib/useSearch.js +0 -591
- package/src/formutil.ts +0 -69
- package/src/update.ts +0 -138
- package/src/useEdit.ts +0 -699
- package/src/useSearch.ts +0 -750
package/src/useSearch.ts
DELETED
|
@@ -1,750 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react"
|
|
2
|
-
import { error, hideLoading, initForm, showLoading } from "./common"
|
|
3
|
-
import { LoadingService, Locale, pageSizes, resources, StringMap, UIService } from "./core"
|
|
4
|
-
import { clone } from "./reflect"
|
|
5
|
-
import { buildFromUrl } from "./route"
|
|
6
|
-
import {
|
|
7
|
-
addParametersIntoUrl,
|
|
8
|
-
buildMessage,
|
|
9
|
-
Filter,
|
|
10
|
-
getFields,
|
|
11
|
-
getPageTotal,
|
|
12
|
-
handleSort,
|
|
13
|
-
handleToggle,
|
|
14
|
-
initFilter,
|
|
15
|
-
mergeFilter as mergeFilter2,
|
|
16
|
-
PageChange,
|
|
17
|
-
Pagination,
|
|
18
|
-
removeSortStatus,
|
|
19
|
-
SearchResult,
|
|
20
|
-
SearchService,
|
|
21
|
-
Sortable,
|
|
22
|
-
} from "./search"
|
|
23
|
-
import { enLocale } from "./state"
|
|
24
|
-
import { DispatchWithCallback, useMergeState, useUpdate } from "./update"
|
|
25
|
-
|
|
26
|
-
export function showPaging<T>(com: Pagination, list: T[], pageSize?: number, total?: number): void {
|
|
27
|
-
com.total = total
|
|
28
|
-
const pageTotal = getPageTotal(pageSize, total)
|
|
29
|
-
com.pages = pageTotal
|
|
30
|
-
com.showPaging = !total || com.pages <= 1 || (list && list.length >= total) ? false : true
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface Searchable extends Pagination, Sortable {
|
|
34
|
-
nextPageToken?: string
|
|
35
|
-
excluding?: string[] | number[]
|
|
36
|
-
}
|
|
37
|
-
export interface SearchParameter {
|
|
38
|
-
showMessage: (msg: string, option?: string) => void
|
|
39
|
-
showError: (m: string, callback?: () => void, h?: string) => void
|
|
40
|
-
ui?: UIService
|
|
41
|
-
getLocale?: (profile?: string) => Locale
|
|
42
|
-
loading?: LoadingService
|
|
43
|
-
auto?: boolean
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface UIParameter {
|
|
47
|
-
ui?: UIService
|
|
48
|
-
}
|
|
49
|
-
export function removeFormError(u?: UIParameter, f?: HTMLFormElement): void {
|
|
50
|
-
if (f && u && u.ui) {
|
|
51
|
-
u.ui.removeFormError(f)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
export function getValidateForm(
|
|
55
|
-
u?: UIParameter,
|
|
56
|
-
vf?: (form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean,
|
|
57
|
-
): ((form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean) | undefined {
|
|
58
|
-
if (vf) {
|
|
59
|
-
return vf
|
|
60
|
-
}
|
|
61
|
-
return u && u.ui ? u.ui.validateForm : undefined
|
|
62
|
-
}
|
|
63
|
-
export function getRemoveError(u?: UIParameter, rmErr?: (el: HTMLInputElement) => void): ((el: HTMLInputElement) => void) | undefined {
|
|
64
|
-
if (rmErr) {
|
|
65
|
-
return rmErr
|
|
66
|
-
}
|
|
67
|
-
return u && u.ui ? u.ui.removeError : undefined
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function getModel<S extends Filter>(state: any, modelName: string, searchable: Searchable, fields?: string[], excluding?: string[] | number[]): S {
|
|
71
|
-
let obj2 = getModelFromState(state, modelName)
|
|
72
|
-
|
|
73
|
-
const obj: any = obj2 ? obj2 : {}
|
|
74
|
-
const obj3 = optimizeFilter(obj, searchable, fields)
|
|
75
|
-
obj3.excluding = excluding
|
|
76
|
-
return obj3
|
|
77
|
-
}
|
|
78
|
-
export function optimizeFilter<S extends Filter>(obj: S, searchable: Searchable, fields?: string[]): S {
|
|
79
|
-
// const sLimit = searchable.limit;
|
|
80
|
-
obj.fields = fields
|
|
81
|
-
if (searchable.page && searchable.page > 1) {
|
|
82
|
-
obj.page = searchable.page
|
|
83
|
-
} else {
|
|
84
|
-
delete obj.page
|
|
85
|
-
}
|
|
86
|
-
obj.limit = searchable.limit
|
|
87
|
-
|
|
88
|
-
if (searchable.appendMode && searchable.initLimit !== searchable.limit) {
|
|
89
|
-
obj.firstLimit = searchable.initLimit
|
|
90
|
-
} else {
|
|
91
|
-
delete obj.firstLimit
|
|
92
|
-
}
|
|
93
|
-
if (searchable.sortField && searchable.sortField.length > 0) {
|
|
94
|
-
obj.sort = searchable.sortType === "-" ? "-" + searchable.sortField : searchable.sortField
|
|
95
|
-
} else {
|
|
96
|
-
delete obj.sort
|
|
97
|
-
}
|
|
98
|
-
if (searchable) {
|
|
99
|
-
mapObjects(obj, searchable as any)
|
|
100
|
-
}
|
|
101
|
-
return obj
|
|
102
|
-
}
|
|
103
|
-
function mapObjects(dest: any, src: any): void {
|
|
104
|
-
for (let key in dest) {
|
|
105
|
-
if (src.hasOwnProperty(key) && src[key] !== null && src[key] !== undefined) {
|
|
106
|
-
if (Array.isArray(dest[key]) && typeof src[key] === "string" && src[key].length > 0) {
|
|
107
|
-
const arrayObjKeySrc = src[key].length > 0 ? src[key]?.split(",") : []
|
|
108
|
-
if (arrayObjKeySrc && arrayObjKeySrc.length > 1) {
|
|
109
|
-
dest[key] = [...arrayObjKeySrc]
|
|
110
|
-
} else {
|
|
111
|
-
dest[key] = []
|
|
112
|
-
dest[key].push(src[key])
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
dest[key] = src[key]
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function getModelFromState(state: any, modelName: string): any {
|
|
121
|
-
if (!modelName || modelName.length === 0) {
|
|
122
|
-
return state
|
|
123
|
-
}
|
|
124
|
-
if (!state) {
|
|
125
|
-
return state
|
|
126
|
-
}
|
|
127
|
-
return state[modelName]
|
|
128
|
-
}
|
|
129
|
-
export function getFieldsFromForm(fields?: string[], initFields?: boolean, form?: HTMLFormElement | null): string[] | undefined {
|
|
130
|
-
if (fields && fields.length > 0) {
|
|
131
|
-
return fields
|
|
132
|
-
}
|
|
133
|
-
if (!initFields) {
|
|
134
|
-
if (form) {
|
|
135
|
-
return getFields(form)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return fields
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function append<T>(list?: T[], results?: T[]): T[] {
|
|
142
|
-
if (list && results) {
|
|
143
|
-
for (const obj of results) {
|
|
144
|
-
list.push(obj)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (!list) {
|
|
148
|
-
return []
|
|
149
|
-
}
|
|
150
|
-
return list
|
|
151
|
-
}
|
|
152
|
-
export function handleAppend<T>(com: Pagination, list: T[], limit?: number, nextPageToken?: string): void {
|
|
153
|
-
if (!limit || limit === 0) {
|
|
154
|
-
com.appendable = false
|
|
155
|
-
} else {
|
|
156
|
-
if (!nextPageToken || nextPageToken.length === 0 || list.length < limit) {
|
|
157
|
-
com.appendable = false
|
|
158
|
-
} else {
|
|
159
|
-
com.appendable = true
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (!list || list.length === 0) {
|
|
163
|
-
com.appendable = false
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
export function formatResults<T>(
|
|
167
|
-
results: T[],
|
|
168
|
-
page?: number,
|
|
169
|
-
limit?: number,
|
|
170
|
-
initPageSize?: number,
|
|
171
|
-
sequenceNo?: string,
|
|
172
|
-
ft?: (oj: T, lc?: Locale) => T,
|
|
173
|
-
lc?: Locale,
|
|
174
|
-
): void {
|
|
175
|
-
if (results && results.length > 0) {
|
|
176
|
-
let hasSequencePro = false
|
|
177
|
-
if (ft) {
|
|
178
|
-
if (sequenceNo && sequenceNo.length > 0) {
|
|
179
|
-
for (const obj of results) {
|
|
180
|
-
if ((obj as any)[sequenceNo]) {
|
|
181
|
-
hasSequencePro = true
|
|
182
|
-
}
|
|
183
|
-
ft(obj, lc)
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
for (const obj of results) {
|
|
187
|
-
ft(obj, lc)
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
} else if (sequenceNo && sequenceNo.length > 0) {
|
|
191
|
-
for (const obj of results) {
|
|
192
|
-
if ((obj as any)[sequenceNo]) {
|
|
193
|
-
hasSequencePro = true
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
if (sequenceNo && sequenceNo.length > 0 && !hasSequencePro) {
|
|
198
|
-
if (!page) {
|
|
199
|
-
page = 1
|
|
200
|
-
}
|
|
201
|
-
if (limit) {
|
|
202
|
-
if (!initPageSize) {
|
|
203
|
-
initPageSize = limit
|
|
204
|
-
}
|
|
205
|
-
if (page <= 1) {
|
|
206
|
-
for (let i = 0; i < results.length; i++) {
|
|
207
|
-
;(results[i] as any)[sequenceNo] = i - limit + limit * page + 1
|
|
208
|
-
}
|
|
209
|
-
} else {
|
|
210
|
-
for (let i = 0; i < results.length; i++) {
|
|
211
|
-
;(results[i] as any)[sequenceNo] = i - limit + limit * page + 1 - (limit - initPageSize)
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
for (let i = 0; i < results.length; i++) {
|
|
216
|
-
;(results[i] as any)[sequenceNo] = i + 1
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
export function validate<S extends Filter>(
|
|
223
|
-
se: S,
|
|
224
|
-
callback: () => void,
|
|
225
|
-
form?: HTMLFormElement | null,
|
|
226
|
-
lc?: Locale,
|
|
227
|
-
vf?: (f: HTMLFormElement, lc2?: Locale, focus?: boolean, scr?: boolean) => boolean,
|
|
228
|
-
): void {
|
|
229
|
-
let valid = true
|
|
230
|
-
if (form && vf) {
|
|
231
|
-
valid = vf(form, lc)
|
|
232
|
-
}
|
|
233
|
-
if (valid === true) {
|
|
234
|
-
callback()
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export const callSearch = <T, S extends Filter>(
|
|
239
|
-
se: S,
|
|
240
|
-
search3: (s: S, limit?: number, page?: number | string, fields?: string[]) => Promise<SearchResult<T>>,
|
|
241
|
-
showResults3: (s: S, sr: SearchResult<T>, lc: Locale) => void,
|
|
242
|
-
searchError3: (err: any) => void,
|
|
243
|
-
lc: Locale,
|
|
244
|
-
nextPageToken?: string,
|
|
245
|
-
) => {
|
|
246
|
-
const s = clone(se)
|
|
247
|
-
let page = se.page
|
|
248
|
-
if (!page || page < 1) {
|
|
249
|
-
page = 1
|
|
250
|
-
}
|
|
251
|
-
if (!se.limit || se.limit <= 0) {
|
|
252
|
-
se.limit = resources.defaultLimit
|
|
253
|
-
}
|
|
254
|
-
const limit = page <= 1 && se.firstLimit && se.firstLimit > 0 ? se.firstLimit : se.limit
|
|
255
|
-
const next = nextPageToken && nextPageToken.length > 0 ? nextPageToken : page
|
|
256
|
-
const fields = se.fields
|
|
257
|
-
delete se["page"]
|
|
258
|
-
delete se["fields"]
|
|
259
|
-
// delete se['limit'];
|
|
260
|
-
delete se["firstLimit"]
|
|
261
|
-
search3(s, limit, next, fields)
|
|
262
|
-
.then((sr) => {
|
|
263
|
-
showResults3(s, sr, lc)
|
|
264
|
-
})
|
|
265
|
-
.catch((err) => err && searchError3(err))
|
|
266
|
-
}
|
|
267
|
-
const appendListOfState = <T, S extends Filter>(results: T[], list: T[] | undefined, setState2: DispatchWithCallback<Partial<SearchComponentState<T, S>>>) => {
|
|
268
|
-
const arr = append(list, results)
|
|
269
|
-
setState2({ list: arr } as any)
|
|
270
|
-
}
|
|
271
|
-
const setListOfState = <T, S extends Filter>(list: T[], setState2: DispatchWithCallback<Partial<SearchComponentState<T, S>>>) => {
|
|
272
|
-
setState2({ list } as any)
|
|
273
|
-
}
|
|
274
|
-
export interface InitSearchComponentParam<T, M extends Filter, S> extends SearchComponentParam<T, M> {
|
|
275
|
-
createFilter?: () => M
|
|
276
|
-
initialize?: (ld: (s: M, auto?: boolean) => void, setState2: DispatchWithCallback<Partial<S>>, com?: SearchComponentState<T, M>) => void
|
|
277
|
-
}
|
|
278
|
-
export interface HookPropsSearchParameter<T, S extends Filter, ST extends SearchComponentState<T, S>, P> extends HookPropsBaseSearchParameter<T, S, ST, P> {
|
|
279
|
-
createFilter?: () => S
|
|
280
|
-
initialize?: (ld: (s: S, auto?: boolean) => void, setState2: DispatchWithCallback<Partial<ST>>, com?: SearchComponentState<T, S>) => void
|
|
281
|
-
}
|
|
282
|
-
export interface SearchComponentParam<T, M extends Filter> {
|
|
283
|
-
// addable?: boolean;
|
|
284
|
-
// editable?: boolean;
|
|
285
|
-
// approvable?: boolean;
|
|
286
|
-
// deletable?: boolean;
|
|
287
|
-
|
|
288
|
-
keys?: string[]
|
|
289
|
-
sequenceNo?: string
|
|
290
|
-
hideFilter?: boolean
|
|
291
|
-
name?: string
|
|
292
|
-
fields?: string[]
|
|
293
|
-
appendMode?: boolean
|
|
294
|
-
pageSizes?: number[]
|
|
295
|
-
pageIndex?: number
|
|
296
|
-
limit: number
|
|
297
|
-
pageMaxSize?: number
|
|
298
|
-
ignoreUrlParam?: boolean
|
|
299
|
-
|
|
300
|
-
load?: (s: M, auto?: boolean) => void
|
|
301
|
-
getModelName?: () => string
|
|
302
|
-
getCurrencyCode?: () => string
|
|
303
|
-
setFilter?: (s: M) => void
|
|
304
|
-
getFilter?: (se?: Searchable) => M
|
|
305
|
-
getFields?: () => string[] | undefined
|
|
306
|
-
validateSearch?: (se: M, callback: () => void) => void
|
|
307
|
-
// prepareCustomData?: (data: any) => void;
|
|
308
|
-
format?(obj: T, locale?: Locale): T
|
|
309
|
-
showResults?(s: M, sr: SearchResult<T>, lc: Locale): void
|
|
310
|
-
appendList?(results: T[], list: T[] | undefined, s: DispatchWithCallback<Partial<SearchComponentState<T, M>>>): void
|
|
311
|
-
setList?(list: T[], s: DispatchWithCallback<Partial<SearchComponentState<T, M>>>): void
|
|
312
|
-
/*
|
|
313
|
-
showLoading?(firstTime?: boolean): void;
|
|
314
|
-
hideLoading?(): void;
|
|
315
|
-
decodeFromForm?(form: HTMLFormElement, locale?: Locale, currencyCode?: string): any;
|
|
316
|
-
registerEvents?(form: HTMLFormElement): void;
|
|
317
|
-
validateForm?(form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean): boolean;
|
|
318
|
-
removeFormError?(form: HTMLFormElement): void;
|
|
319
|
-
removeError?(el: HTMLInputElement): void;
|
|
320
|
-
*/
|
|
321
|
-
}
|
|
322
|
-
export interface HookBaseSearchParameter<T, S extends Filter, ST extends SearchComponentState<T, S>> extends SearchComponentParam<T, S> {
|
|
323
|
-
refForm: any
|
|
324
|
-
initialState: ST
|
|
325
|
-
service: ((s: S, limit?: number, offset?: number | string, fields?: string[]) => Promise<SearchResult<T>>) | SearchService<T, S>
|
|
326
|
-
// resource: ResourceService
|
|
327
|
-
showMessage: (msg: string) => void
|
|
328
|
-
showError: (m: string, callback?: () => void, header?: string) => void
|
|
329
|
-
getLocale?: () => Locale
|
|
330
|
-
autoSearch?: boolean
|
|
331
|
-
}
|
|
332
|
-
export interface HookPropsBaseSearchParameter<T, S extends Filter, ST extends SearchComponentState<T, S>, P> extends HookBaseSearchParameter<T, S, ST> {
|
|
333
|
-
props?: P
|
|
334
|
-
// prepareCustomData?: (data: any) => void;
|
|
335
|
-
}
|
|
336
|
-
export interface SearchComponentState<T, S> extends Pagination, Sortable {
|
|
337
|
-
view?: string
|
|
338
|
-
nextPageToken?: string
|
|
339
|
-
keys?: string[]
|
|
340
|
-
filter?: S
|
|
341
|
-
list?: T[]
|
|
342
|
-
|
|
343
|
-
format?: (obj: T, locale: Locale) => T
|
|
344
|
-
fields?: string[]
|
|
345
|
-
initFields?: boolean
|
|
346
|
-
triggerSearch?: boolean
|
|
347
|
-
tmpPageIndex?: number
|
|
348
|
-
|
|
349
|
-
pageMaxSize?: number
|
|
350
|
-
pageSizes?: number[]
|
|
351
|
-
excluding?: string[] | number[]
|
|
352
|
-
hideFilter?: boolean
|
|
353
|
-
|
|
354
|
-
ignoreUrlParam?: boolean
|
|
355
|
-
// viewable?: boolean;
|
|
356
|
-
// addable?: boolean;
|
|
357
|
-
// editable?: boolean;
|
|
358
|
-
// approvable?: boolean;
|
|
359
|
-
// deletable?: boolean;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
export function mergeParam<T, S extends Filter>(p?: SearchComponentParam<T, S>): SearchComponentParam<T, S> {
|
|
363
|
-
if (p) {
|
|
364
|
-
if (!p.sequenceNo) {
|
|
365
|
-
p.sequenceNo = "sequenceNo"
|
|
366
|
-
}
|
|
367
|
-
if (!p.limit) {
|
|
368
|
-
p.limit = 24
|
|
369
|
-
}
|
|
370
|
-
if (!p.pageSizes) {
|
|
371
|
-
p.pageSizes = pageSizes
|
|
372
|
-
}
|
|
373
|
-
if (!p.pageMaxSize || p.pageMaxSize <= 0) {
|
|
374
|
-
p.pageMaxSize = 7
|
|
375
|
-
}
|
|
376
|
-
if (p.hideFilter === undefined) {
|
|
377
|
-
p.hideFilter = true
|
|
378
|
-
}
|
|
379
|
-
/*
|
|
380
|
-
if (p.addable === undefined) {
|
|
381
|
-
p.addable = true;
|
|
382
|
-
}
|
|
383
|
-
if (p.editable === undefined) {
|
|
384
|
-
p.editable = true;
|
|
385
|
-
}
|
|
386
|
-
if (p.approvable === undefined) {
|
|
387
|
-
p.approvable = true;
|
|
388
|
-
}
|
|
389
|
-
if (p.deletable === undefined) {
|
|
390
|
-
p.deletable = true;
|
|
391
|
-
}
|
|
392
|
-
*/
|
|
393
|
-
return p
|
|
394
|
-
} else {
|
|
395
|
-
return {
|
|
396
|
-
sequenceNo: "sequenceNo",
|
|
397
|
-
limit: 24,
|
|
398
|
-
pageSizes,
|
|
399
|
-
pageMaxSize: 7,
|
|
400
|
-
hideFilter: true,
|
|
401
|
-
// addable: true,
|
|
402
|
-
// editable: true,
|
|
403
|
-
// approvable: true,
|
|
404
|
-
// deletable: true
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
export const useSearch = <T, S extends Filter, ST extends SearchComponentState<T, S>>(
|
|
409
|
-
refForm: any,
|
|
410
|
-
initialState: ST,
|
|
411
|
-
service: ((s: S, limit?: number, offset?: number | string, fields?: string[]) => Promise<SearchResult<T>>) | SearchService<T, S>,
|
|
412
|
-
resource: StringMap,
|
|
413
|
-
p2: SearchParameter,
|
|
414
|
-
p?: InitSearchComponentParam<T, S, ST>,
|
|
415
|
-
) => {
|
|
416
|
-
const baseProps = useCoreSearch(refForm, initialState, service, resource, p2, p)
|
|
417
|
-
|
|
418
|
-
useEffect(() => {
|
|
419
|
-
const { load, setState, component, searchError } = baseProps
|
|
420
|
-
if (refForm) {
|
|
421
|
-
const registerEvents = p2.ui ? p2.ui.registerEvents : undefined
|
|
422
|
-
initForm(refForm.current, registerEvents)
|
|
423
|
-
}
|
|
424
|
-
if (p && p.initialize) {
|
|
425
|
-
p.initialize(load, setState, component)
|
|
426
|
-
} else {
|
|
427
|
-
const se: S | undefined = p && p.createFilter ? p.createFilter() : undefined
|
|
428
|
-
try {
|
|
429
|
-
const s: any = mergeFilter2(buildFromUrl<S>(se), se, component.pageSizes)
|
|
430
|
-
load(s, p2.auto)
|
|
431
|
-
} catch (error) {
|
|
432
|
-
searchError(error)
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
436
|
-
}, [])
|
|
437
|
-
return { ...baseProps }
|
|
438
|
-
}
|
|
439
|
-
export const useSearchOneProps = <T, S extends Filter, ST extends SearchComponentState<T, S>, P>(
|
|
440
|
-
resource: StringMap,
|
|
441
|
-
p: HookPropsSearchParameter<T, S, ST, P>,
|
|
442
|
-
) => {
|
|
443
|
-
return useSearch(p.refForm, p.initialState, p.service, resource, p, p)
|
|
444
|
-
}
|
|
445
|
-
export const useSearchOne = <T, S extends Filter, ST extends SearchComponentState<T, S>>(resource: StringMap, p: HookBaseSearchParameter<T, S, ST>) => {
|
|
446
|
-
return useCoreSearch(p.refForm, p.initialState, p.service, resource, p, p)
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
export function getName(d: string, n?: string): string {
|
|
450
|
-
return n && n.length > 0 ? n : d
|
|
451
|
-
}
|
|
452
|
-
export const useCoreSearch = <T, S extends Filter, ST>(
|
|
453
|
-
refForm: any,
|
|
454
|
-
initialState: ST,
|
|
455
|
-
service: ((s: S, limit?: number, offset?: number | string, fields?: string[]) => Promise<SearchResult<T>>) | SearchService<T, S>,
|
|
456
|
-
resource: StringMap,
|
|
457
|
-
p1: SearchParameter,
|
|
458
|
-
p2?: SearchComponentParam<T, S>,
|
|
459
|
-
) => {
|
|
460
|
-
const p = mergeParam(p2)
|
|
461
|
-
const [running, setRunning] = useState<boolean>()
|
|
462
|
-
|
|
463
|
-
const _getModelName = (): string => {
|
|
464
|
-
return getName("filter", p && p.name ? p.name : undefined)
|
|
465
|
-
}
|
|
466
|
-
const getModelName = p && p.getModelName ? p.getModelName : _getModelName
|
|
467
|
-
|
|
468
|
-
// const setState2: <K extends keyof S, P>(st: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null), cb?: () => void) => void;
|
|
469
|
-
const baseProps = useUpdate<ST>(initialState, getModelName, p1.getLocale, getRemoveError(p1))
|
|
470
|
-
const { state, setState } = baseProps
|
|
471
|
-
const [rerender, setRerender] = useState(false)
|
|
472
|
-
|
|
473
|
-
// trigger re-render page when change state in useSearch
|
|
474
|
-
useEffect(() => {
|
|
475
|
-
setRerender(!rerender)
|
|
476
|
-
}, [state])
|
|
477
|
-
|
|
478
|
-
const _getCurrencyCode = (): string => {
|
|
479
|
-
return refForm && refForm.current ? refForm.current.getAttribute("currency-code") : "USD"
|
|
480
|
-
}
|
|
481
|
-
const getCurrencyCode = p && p.getCurrencyCode ? p.getCurrencyCode : _getCurrencyCode
|
|
482
|
-
|
|
483
|
-
// const p = createSearchComponentState<T, S>(p1);
|
|
484
|
-
const [component, setComponent] = useMergeState<SearchComponentState<T, S>>(p)
|
|
485
|
-
|
|
486
|
-
const toggleFilter = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
|
|
487
|
-
const hideFilter = handleToggle(event.target as HTMLInputElement, component.hideFilter)
|
|
488
|
-
setComponent({ hideFilter })
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
const _getFields = (): string[] | undefined => {
|
|
492
|
-
const { fields, initFields } = component
|
|
493
|
-
const fs = getFieldsFromForm(fields, initFields, refForm.current)
|
|
494
|
-
setComponent({ fields: fs, initFields: true })
|
|
495
|
-
return fs
|
|
496
|
-
}
|
|
497
|
-
const getFields = p && p.getFields ? p.getFields : _getFields
|
|
498
|
-
|
|
499
|
-
const _getFilter = (se?: Searchable): S => {
|
|
500
|
-
if (!se) {
|
|
501
|
-
se = component
|
|
502
|
-
}
|
|
503
|
-
let keys = p && p.keys ? p.keys : undefined
|
|
504
|
-
if (!keys && typeof service !== "function" && service.keys) {
|
|
505
|
-
keys = service.keys()
|
|
506
|
-
}
|
|
507
|
-
const n = getModelName()
|
|
508
|
-
let fs = p && p.fields
|
|
509
|
-
if (!fs || fs.length <= 0) {
|
|
510
|
-
fs = getFields()
|
|
511
|
-
}
|
|
512
|
-
const obj3 = getModel<S>(state, n, se, fs, se.excluding)
|
|
513
|
-
return obj3
|
|
514
|
-
}
|
|
515
|
-
const getFilter = p && p.getFilter ? p.getFilter : _getFilter
|
|
516
|
-
const _setFilter = (s: S): void => {
|
|
517
|
-
const objSet: any = {}
|
|
518
|
-
const n = getModelName()
|
|
519
|
-
objSet[n] = s
|
|
520
|
-
setState(objSet)
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
const setFilter = p && p.setFilter ? p.setFilter : _setFilter
|
|
524
|
-
|
|
525
|
-
const _load = (s: S, auto?: boolean): void => {
|
|
526
|
-
const com = Object.assign({}, component)
|
|
527
|
-
const obj2 = initFilter(s, com)
|
|
528
|
-
setComponent(com)
|
|
529
|
-
setFilter(obj2)
|
|
530
|
-
const runSearch = doSearch
|
|
531
|
-
if (auto) {
|
|
532
|
-
setTimeout(() => {
|
|
533
|
-
runSearch(obj2 as any, true)
|
|
534
|
-
}, 0)
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
const load = p && p.load ? p.load : _load
|
|
538
|
-
|
|
539
|
-
const doSearch = (se: Searchable, isFirstLoad?: boolean) => {
|
|
540
|
-
removeFormError(p1, refForm.current)
|
|
541
|
-
const s = getFilter(se)
|
|
542
|
-
|
|
543
|
-
if (isFirstLoad) {
|
|
544
|
-
setState(state) // force update state if we refresh again page
|
|
545
|
-
}
|
|
546
|
-
const isStillRunning = running
|
|
547
|
-
validateSearch(s, () => {
|
|
548
|
-
if (isStillRunning === true) {
|
|
549
|
-
return
|
|
550
|
-
}
|
|
551
|
-
setRunning(true)
|
|
552
|
-
showLoading(p1.loading)
|
|
553
|
-
if (p && !p.ignoreUrlParam) {
|
|
554
|
-
addParametersIntoUrl(s, isFirstLoad)
|
|
555
|
-
}
|
|
556
|
-
const lc = p1.getLocale ? p1.getLocale() : enLocale
|
|
557
|
-
if (typeof service === "function") {
|
|
558
|
-
callSearch<T, S>(s, service, showResults, searchError, lc, se.nextPageToken)
|
|
559
|
-
} else {
|
|
560
|
-
callSearch<T, S>(s, service.search, showResults, searchError, lc, se.nextPageToken)
|
|
561
|
-
}
|
|
562
|
-
})
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
const _validateSearch = (se: S, callback: () => void) => {
|
|
566
|
-
validate(se, callback, refForm.current, p1.getLocale ? p1.getLocale() : undefined, getValidateForm(p1))
|
|
567
|
-
}
|
|
568
|
-
const validateSearch = p && p.validateSearch ? p.validateSearch : _validateSearch
|
|
569
|
-
|
|
570
|
-
const pageSizeChanged = (event: any) => {
|
|
571
|
-
const size = parseInt(event.currentTarget.value, 10)
|
|
572
|
-
component.limit = size
|
|
573
|
-
component.page = 1
|
|
574
|
-
component.tmpPageIndex = 1
|
|
575
|
-
setComponent({
|
|
576
|
-
limit: size,
|
|
577
|
-
page: 1,
|
|
578
|
-
tmpPageIndex: 1,
|
|
579
|
-
})
|
|
580
|
-
doSearch(component)
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
const clearQ = (e?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
584
|
-
if (e) {
|
|
585
|
-
e.preventDefault()
|
|
586
|
-
}
|
|
587
|
-
const n = getModelName()
|
|
588
|
-
if (n && n.length > 0) {
|
|
589
|
-
const m = (state as any)[n]
|
|
590
|
-
if (m) {
|
|
591
|
-
m.q = ""
|
|
592
|
-
const setObj: any = {}
|
|
593
|
-
setObj[n] = m
|
|
594
|
-
setState(setObj)
|
|
595
|
-
return
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
const search = (event?: React.MouseEvent<HTMLButtonElement, MouseEvent> | React.MouseEvent<HTMLElement, MouseEvent>): void => {
|
|
601
|
-
if (event) {
|
|
602
|
-
event.preventDefault()
|
|
603
|
-
}
|
|
604
|
-
resetAndSearch()
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
const sort = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
|
608
|
-
event.preventDefault()
|
|
609
|
-
if (event && event.target) {
|
|
610
|
-
const target = event.target as any
|
|
611
|
-
const s = handleSort(target, component.sortTarget, component.sortField, component.sortType)
|
|
612
|
-
setComponent({
|
|
613
|
-
sortField: s.field,
|
|
614
|
-
sortType: s.type,
|
|
615
|
-
sortTarget: target,
|
|
616
|
-
})
|
|
617
|
-
component.sortField = s.field
|
|
618
|
-
component.sortType = s.type
|
|
619
|
-
component.sortTarget = target
|
|
620
|
-
}
|
|
621
|
-
if (!component.appendMode) {
|
|
622
|
-
doSearch(component)
|
|
623
|
-
} else {
|
|
624
|
-
resetAndSearch()
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
const changeView = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>, view?: string) => {
|
|
628
|
-
if (view && view.length > 0) {
|
|
629
|
-
setComponent({ view })
|
|
630
|
-
} else if (event && event.target) {
|
|
631
|
-
const target = event.target as any
|
|
632
|
-
const v: string = target.getAttribute("data-view")
|
|
633
|
-
if (v && v.length > 0) {
|
|
634
|
-
setComponent({ view: v })
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
const resetAndSearch = () => {
|
|
640
|
-
if (running === true) {
|
|
641
|
-
setComponent({ page: 1, triggerSearch: true })
|
|
642
|
-
return
|
|
643
|
-
}
|
|
644
|
-
setComponent({ page: 1, tmpPageIndex: 1 })
|
|
645
|
-
removeSortStatus(component.sortTarget)
|
|
646
|
-
setComponent({
|
|
647
|
-
sortTarget: undefined,
|
|
648
|
-
sortField: undefined,
|
|
649
|
-
append: false,
|
|
650
|
-
page: 1,
|
|
651
|
-
})
|
|
652
|
-
component.sortTarget = undefined
|
|
653
|
-
component.sortField = undefined
|
|
654
|
-
component.append = false
|
|
655
|
-
component.page = 1
|
|
656
|
-
doSearch(component)
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
const searchError = (err: any): void => {
|
|
660
|
-
setComponent({ page: component.tmpPageIndex })
|
|
661
|
-
error(err, resource, p1.showError)
|
|
662
|
-
hideLoading(p1.loading)
|
|
663
|
-
}
|
|
664
|
-
const appendList = p && p.appendList ? p.appendList : appendListOfState
|
|
665
|
-
const setList = p && p.setList ? p.setList : setListOfState
|
|
666
|
-
const _showResults = (s: S, sr: SearchResult<T>, lc: Locale) => {
|
|
667
|
-
if (sr === undefined) {
|
|
668
|
-
return
|
|
669
|
-
}
|
|
670
|
-
const results = sr?.list || []
|
|
671
|
-
if (results && results.length > 0) {
|
|
672
|
-
formatResults(results, component.page, component.limit, component.limit, p ? p.sequenceNo : undefined, p ? p.format : undefined, lc)
|
|
673
|
-
}
|
|
674
|
-
const am = component.appendMode
|
|
675
|
-
const pi = s.page && s.page >= 1 ? s.page : 1
|
|
676
|
-
setComponent({ total: sr.total, page: pi, nextPageToken: sr.next })
|
|
677
|
-
if (am) {
|
|
678
|
-
let limit = s.limit
|
|
679
|
-
if ((!s.page || s.page <= 1) && s.firstLimit && s.firstLimit > 0) {
|
|
680
|
-
limit = s.firstLimit
|
|
681
|
-
}
|
|
682
|
-
handleAppend(component, sr.list, limit, sr.next)
|
|
683
|
-
if (component.append && s.page && s.page > 1) {
|
|
684
|
-
appendList(results, component.list, setState as any)
|
|
685
|
-
} else {
|
|
686
|
-
setList(results, setState as any)
|
|
687
|
-
}
|
|
688
|
-
} else {
|
|
689
|
-
showPaging(component, sr.list, s.limit, sr.total)
|
|
690
|
-
setList(results, setState as any)
|
|
691
|
-
setComponent({ tmpPageIndex: s.page })
|
|
692
|
-
if (s.limit) {
|
|
693
|
-
const m1 = buildMessage(resource, sr.list, s.limit, s.page, sr.total)
|
|
694
|
-
p1.showMessage(m1)
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
setRunning(false)
|
|
698
|
-
hideLoading(p1.loading)
|
|
699
|
-
if (component.triggerSearch) {
|
|
700
|
-
setComponent({ triggerSearch: false })
|
|
701
|
-
resetAndSearch()
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
const showResults = p && p.showResults ? p.showResults : _showResults
|
|
705
|
-
|
|
706
|
-
const showMore = (event: any) => {
|
|
707
|
-
event.preventDefault()
|
|
708
|
-
const n = component.page ? component.page + 1 : 2
|
|
709
|
-
const m = component.page
|
|
710
|
-
setComponent({ tmpPageIndex: m, page: n, append: true })
|
|
711
|
-
component.tmpPageIndex = m
|
|
712
|
-
component.page = n
|
|
713
|
-
component.append = true
|
|
714
|
-
doSearch(component)
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
const pageChanged = (data: PageChange) => {
|
|
718
|
-
const { page, size } = data
|
|
719
|
-
setComponent({ page: page, limit: size, append: false })
|
|
720
|
-
component.page = page
|
|
721
|
-
component.limit = size
|
|
722
|
-
component.append = false
|
|
723
|
-
doSearch(component)
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
return {
|
|
727
|
-
...baseProps,
|
|
728
|
-
running,
|
|
729
|
-
setRunning,
|
|
730
|
-
getCurrencyCode,
|
|
731
|
-
setComponent,
|
|
732
|
-
component,
|
|
733
|
-
showMessage: p1.showMessage,
|
|
734
|
-
load,
|
|
735
|
-
search,
|
|
736
|
-
sort,
|
|
737
|
-
changeView,
|
|
738
|
-
showMore,
|
|
739
|
-
toggleFilter,
|
|
740
|
-
doSearch,
|
|
741
|
-
pageChanged,
|
|
742
|
-
pageSizeChanged,
|
|
743
|
-
clearQ,
|
|
744
|
-
showResults,
|
|
745
|
-
getFields,
|
|
746
|
-
getModelName,
|
|
747
|
-
format: p ? p.format : undefined,
|
|
748
|
-
searchError,
|
|
749
|
-
}
|
|
750
|
-
}
|