react-hook-core 0.4.8 → 0.4.10
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 +30 -0
- package/lib/core.js +0 -118
- package/lib/formutil.js +0 -28
- package/lib/index.js +25 -0
- package/lib/input.js +57 -0
- package/lib/reflect.js +38 -48
- package/lib/route.js +11 -0
- package/lib/search.js +11 -28
- package/lib/update.js +56 -4
- package/lib/useEdit.js +38 -41
- package/lib/useSearch.js +44 -11
- package/lib/util.js +3 -3
- package/package.json +1 -1
- package/src/common.ts +28 -0
- package/src/core.ts +14 -134
- package/src/formutil.ts +0 -27
- package/src/index.ts +26 -0
- package/src/input.ts +55 -15
- package/src/reflect.ts +38 -56
- package/src/route.ts +19 -0
- package/src/search.ts +12 -33
- package/src/update.ts +56 -4
- package/src/useEdit.ts +28 -44
- package/src/useSearch.ts +43 -19
- package/src/util.ts +3 -3
- package/lib/error.js +0 -53
- package/lib/merge.js +0 -28
- package/src/error.ts +0 -55
- package/src/merge.ts +0 -26
package/src/input.ts
CHANGED
|
@@ -81,23 +81,63 @@ export function getErrorFunc(
|
|
|
81
81
|
}
|
|
82
82
|
return (p as any).showError
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
export
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
|
|
85
|
+
export function showLoading(loading?: LoadingService | ((firstTime?: boolean) => void)): void {
|
|
86
|
+
if (loading) {
|
|
87
|
+
if (typeof loading === "function") {
|
|
88
|
+
loading()
|
|
89
|
+
} else {
|
|
90
|
+
loading.showLoading()
|
|
91
|
+
}
|
|
91
92
|
}
|
|
92
|
-
return (p as any).status;
|
|
93
93
|
}
|
|
94
|
-
export
|
|
95
|
-
|
|
94
|
+
export function hideLoading(loading?: LoadingService | (() => void)): void {
|
|
95
|
+
if (loading) {
|
|
96
|
+
if (typeof loading === "function") {
|
|
97
|
+
loading()
|
|
98
|
+
} else {
|
|
99
|
+
loading.hideLoading()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
96
102
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
|
|
104
|
+
export function initForm(form?: HTMLFormElement, initMat?: (f: HTMLFormElement) => void): HTMLFormElement | undefined {
|
|
105
|
+
if (form) {
|
|
106
|
+
setTimeout(() => {
|
|
107
|
+
if (initMat) {
|
|
108
|
+
initMat(form)
|
|
109
|
+
}
|
|
110
|
+
focusFirstElement(form)
|
|
111
|
+
}, 100)
|
|
112
|
+
}
|
|
113
|
+
return form
|
|
114
|
+
}
|
|
115
|
+
export function focusFirstElement(form: HTMLFormElement): void {
|
|
116
|
+
let i = 0
|
|
117
|
+
const len = form.length
|
|
118
|
+
for (i = 0; i < len; i++) {
|
|
119
|
+
const ctrl = form[i] as HTMLInputElement
|
|
120
|
+
if (!(ctrl.readOnly || ctrl.disabled)) {
|
|
121
|
+
let nodeName = ctrl.nodeName
|
|
122
|
+
const type = ctrl.getAttribute("type")
|
|
123
|
+
if (type) {
|
|
124
|
+
const t = type.toUpperCase()
|
|
125
|
+
if (t === "BUTTON" || t === "SUBMIT") {
|
|
126
|
+
ctrl.focus()
|
|
127
|
+
}
|
|
128
|
+
if (nodeName === "INPUT") {
|
|
129
|
+
nodeName = t
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (nodeName !== "BUTTON" && nodeName !== "RESET" && nodeName !== "SUBMIT" && nodeName !== "CHECKBOX" && nodeName !== "RADIO") {
|
|
133
|
+
ctrl.focus()
|
|
134
|
+
/*
|
|
135
|
+
try {
|
|
136
|
+
ctrl.setSelectionRange(0, ctrl.value.length)
|
|
137
|
+
} catch (err) {}
|
|
138
|
+
*/
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
}
|
|
100
142
|
}
|
|
101
|
-
return (p as any).status;
|
|
102
143
|
}
|
|
103
|
-
*/
|
package/src/reflect.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { NavigateFunction } from "react-router-dom"
|
|
2
|
-
import { StringMap } from "./core"
|
|
3
|
-
|
|
4
1
|
export function clone(obj: any): any {
|
|
5
2
|
if (!obj) {
|
|
6
3
|
return obj
|
|
@@ -39,43 +36,6 @@ export function clone(obj: any): any {
|
|
|
39
36
|
return x
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
export function getDirectValue(obj: any, key: string): any {
|
|
43
|
-
if (obj && obj.hasOwnProperty(key)) {
|
|
44
|
-
return obj[key]
|
|
45
|
-
}
|
|
46
|
-
return null
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function setValue(obj: any, key: string, value: any): any {
|
|
50
|
-
let replaceKey = key.replace(/\[/g, ".[").replace(/\.\./g, ".")
|
|
51
|
-
if (replaceKey.indexOf(".") === 0) {
|
|
52
|
-
replaceKey = replaceKey.slice(1, replaceKey.length)
|
|
53
|
-
}
|
|
54
|
-
const keys = replaceKey.split(".")
|
|
55
|
-
const firstKey = keys.shift()
|
|
56
|
-
if (!firstKey) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
const isArrayKey = /\[([0-9]+)\]/.test(firstKey)
|
|
60
|
-
if (keys.length > 0) {
|
|
61
|
-
const firstKeyValue = obj[firstKey] || {}
|
|
62
|
-
const returnValue = setValue(firstKeyValue, keys.join("."), value)
|
|
63
|
-
return setKey(obj, isArrayKey, firstKey, returnValue)
|
|
64
|
-
}
|
|
65
|
-
return setKey(obj, isArrayKey, firstKey, value)
|
|
66
|
-
}
|
|
67
|
-
const setKey = (_object: any, _isArrayKey: boolean, _key: string, _nextValue: any) => {
|
|
68
|
-
if (_isArrayKey) {
|
|
69
|
-
if (_object.length > _key) {
|
|
70
|
-
_object[_key] = _nextValue
|
|
71
|
-
} else {
|
|
72
|
-
_object.push(_nextValue)
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
_object[_key] = _nextValue
|
|
76
|
-
}
|
|
77
|
-
return _object
|
|
78
|
-
}
|
|
79
39
|
export function isEmptyObject(obj: any): boolean {
|
|
80
40
|
for (let key in obj) {
|
|
81
41
|
if (obj.hasOwnProperty(key)) {
|
|
@@ -143,22 +103,6 @@ export function hasDiff<T>(o1: T, o2: T, keys?: string[], version?: string): boo
|
|
|
143
103
|
return !isEmptyObject(diff)
|
|
144
104
|
}
|
|
145
105
|
|
|
146
|
-
export function goBack<T>(
|
|
147
|
-
navigate: NavigateFunction,
|
|
148
|
-
confirm: (msg: string, yesCallback?: () => void) => void,
|
|
149
|
-
resource: StringMap,
|
|
150
|
-
o1: T,
|
|
151
|
-
o2: T,
|
|
152
|
-
keys?: string[],
|
|
153
|
-
version?: string,
|
|
154
|
-
) {
|
|
155
|
-
if (!hasDiff(o1, o2, keys, version)) {
|
|
156
|
-
navigate(-1)
|
|
157
|
-
} else {
|
|
158
|
-
confirm(resource.msg_confirm_back, () => navigate(-1))
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
106
|
export function notIn(s1: string[], s2: string[]): string[] {
|
|
163
107
|
const r = []
|
|
164
108
|
for (const s of s2) {
|
|
@@ -273,3 +217,41 @@ export function equalAll<T>(list: T[] | undefined | null, name: string, v: boole
|
|
|
273
217
|
}
|
|
274
218
|
return true
|
|
275
219
|
}
|
|
220
|
+
|
|
221
|
+
export function getDirectValue(obj: any, key: string): any {
|
|
222
|
+
if (obj && obj.hasOwnProperty(key)) {
|
|
223
|
+
return obj[key]
|
|
224
|
+
}
|
|
225
|
+
return null
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function setValue(obj: any, key: string, value: any): any {
|
|
229
|
+
let replaceKey = key.replace(/\[/g, ".[").replace(/\.\./g, ".")
|
|
230
|
+
if (replaceKey.indexOf(".") === 0) {
|
|
231
|
+
replaceKey = replaceKey.slice(1, replaceKey.length)
|
|
232
|
+
}
|
|
233
|
+
const keys = replaceKey.split(".")
|
|
234
|
+
const firstKey = keys.shift()
|
|
235
|
+
if (!firstKey) {
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
const isArrayKey = /\[([0-9]+)\]/.test(firstKey)
|
|
239
|
+
if (keys.length > 0) {
|
|
240
|
+
const firstKeyValue = obj[firstKey] || {}
|
|
241
|
+
const returnValue = setValue(firstKeyValue, keys.join("."), value)
|
|
242
|
+
return setKey(obj, isArrayKey, firstKey, returnValue)
|
|
243
|
+
}
|
|
244
|
+
return setKey(obj, isArrayKey, firstKey, value)
|
|
245
|
+
}
|
|
246
|
+
const setKey = (_object: any, _isArrayKey: boolean, _key: string, _nextValue: any) => {
|
|
247
|
+
if (_isArrayKey) {
|
|
248
|
+
if (_object.length > _key) {
|
|
249
|
+
_object[_key] = _nextValue
|
|
250
|
+
} else {
|
|
251
|
+
_object.push(_nextValue)
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
_object[_key] = _nextValue
|
|
255
|
+
}
|
|
256
|
+
return _object
|
|
257
|
+
}
|
package/src/route.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import * as qs from "query-string"
|
|
2
|
+
import { NavigateFunction } from "react-router-dom"
|
|
3
|
+
import { StringMap } from "./core"
|
|
4
|
+
import { hasDiff } from "./reflect"
|
|
2
5
|
import { Filter } from "./search"
|
|
3
6
|
|
|
7
|
+
export function goBack<T>(
|
|
8
|
+
navigate: NavigateFunction,
|
|
9
|
+
confirm: (msg: string, yesCallback?: () => void) => void,
|
|
10
|
+
resource: StringMap,
|
|
11
|
+
o1: T,
|
|
12
|
+
o2: T,
|
|
13
|
+
keys?: string[],
|
|
14
|
+
version?: string,
|
|
15
|
+
) {
|
|
16
|
+
if (!hasDiff(o1, o2, keys, version)) {
|
|
17
|
+
navigate(-1)
|
|
18
|
+
} else {
|
|
19
|
+
confirm(resource.msg_confirm_back, () => navigate(-1))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
4
23
|
export function buildFromUrl<S extends Filter>(modelT?: S): S {
|
|
5
24
|
return buildParameters<S>(window.location.search, modelT)
|
|
6
25
|
}
|
package/src/search.ts
CHANGED
|
@@ -42,18 +42,8 @@ export interface Pagination {
|
|
|
42
42
|
appendable?: boolean
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
interface Searchable extends Pagination, Sortable {}
|
|
46
46
|
|
|
47
|
-
export function getOffset(limit: number, page?: number, firstLimit?: number): number {
|
|
48
|
-
const p = page && page > 0 ? page : 1
|
|
49
|
-
if (firstLimit && firstLimit > 0) {
|
|
50
|
-
const offset = limit * (p - 2) + firstLimit
|
|
51
|
-
return offset < 0 ? 0 : offset
|
|
52
|
-
} else {
|
|
53
|
-
const offset = limit * (p - 1)
|
|
54
|
-
return offset < 0 ? 0 : offset
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
47
|
export function mergeFilter<S extends Filter>(obj: S, b?: S, pageSizes?: number[], arrs?: string[] | any) {
|
|
58
48
|
let a: any = b
|
|
59
49
|
if (!b) {
|
|
@@ -148,21 +138,9 @@ export function initFilter<S extends Filter>(m: S, com: Searchable): S {
|
|
|
148
138
|
com.sortType = ""
|
|
149
139
|
}
|
|
150
140
|
}
|
|
151
|
-
/*
|
|
152
|
-
delete m.page;
|
|
153
|
-
delete m.limit;
|
|
154
|
-
delete m.firstLimit;
|
|
155
|
-
*/
|
|
156
141
|
return m
|
|
157
142
|
}
|
|
158
143
|
|
|
159
|
-
export function showPaging<T>(com: Pagination, list: T[], pageSize?: number, total?: number): void {
|
|
160
|
-
com.total = total
|
|
161
|
-
const pageTotal = getPageTotal(pageSize, total)
|
|
162
|
-
com.pages = pageTotal
|
|
163
|
-
com.showPaging = !total || com.pages <= 1 || (list && list.length >= total) ? false : true
|
|
164
|
-
}
|
|
165
|
-
|
|
166
144
|
export function getFields(form?: HTMLFormElement, arr?: string[]): string[] | undefined {
|
|
167
145
|
if (arr && arr.length > 0) {
|
|
168
146
|
return arr
|
|
@@ -215,7 +193,6 @@ export function getPageTotal(pageSize?: number, total?: number): number {
|
|
|
215
193
|
return Math.floor(total / pageSize + 1)
|
|
216
194
|
}
|
|
217
195
|
}
|
|
218
|
-
|
|
219
196
|
export function formatText(...args: any[]): string {
|
|
220
197
|
let formatted = args[0]
|
|
221
198
|
if (!formatted || formatted === "") {
|
|
@@ -393,15 +370,6 @@ export function handleToggle(target?: HTMLElement, on?: boolean): boolean {
|
|
|
393
370
|
}
|
|
394
371
|
return off
|
|
395
372
|
}
|
|
396
|
-
export function handleSortEvent(event: Event, com: Sortable): void {
|
|
397
|
-
if (event && event.target) {
|
|
398
|
-
const target = event.target as HTMLElement
|
|
399
|
-
const s = handleSort(target, com.sortTarget, com.sortField, com.sortType)
|
|
400
|
-
com.sortField = s.field
|
|
401
|
-
com.sortType = s.type
|
|
402
|
-
com.sortTarget = target
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
373
|
|
|
406
374
|
export function getSortElement(target: HTMLElement): HTMLElement {
|
|
407
375
|
return target.nodeName === "I" ? (target.parentElement as HTMLElement) : target
|
|
@@ -473,3 +441,14 @@ export function toggleSortStyle(target: HTMLElement): string {
|
|
|
473
441
|
}
|
|
474
442
|
return field
|
|
475
443
|
}
|
|
444
|
+
|
|
445
|
+
export function getOffset(limit: number, page?: number, firstLimit?: number): number {
|
|
446
|
+
const p = page && page > 0 ? page : 1
|
|
447
|
+
if (firstLimit && firstLimit > 0) {
|
|
448
|
+
const offset = limit * (p - 2) + firstLimit
|
|
449
|
+
return offset < 0 ? 0 : offset
|
|
450
|
+
} else {
|
|
451
|
+
const offset = limit * (p - 1)
|
|
452
|
+
return offset < 0 ? 0 : offset
|
|
453
|
+
}
|
|
454
|
+
}
|
package/src/update.ts
CHANGED
|
@@ -1,12 +1,64 @@
|
|
|
1
|
-
import { useEffect, useState } from "react"
|
|
2
|
-
import {
|
|
3
|
-
import { useMergeState } from "./merge"
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react"
|
|
2
|
+
import { Locale, resources } from "./core"
|
|
4
3
|
import { buildFlatState, buildState, handleEvent, localeOf } from "./state"
|
|
5
4
|
|
|
5
|
+
export function removePhoneFormat(phone: string): string {
|
|
6
|
+
if (phone) {
|
|
7
|
+
return phone.replace(resources.phone, "")
|
|
8
|
+
} else {
|
|
9
|
+
return phone
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getModelName(form?: HTMLFormElement | null, name?: string): string {
|
|
14
|
+
if (form) {
|
|
15
|
+
const a = form.getAttribute("model-name")
|
|
16
|
+
if (a && a.length > 0) {
|
|
17
|
+
return a
|
|
18
|
+
}
|
|
19
|
+
const b = form.name
|
|
20
|
+
if (b) {
|
|
21
|
+
if (b.endsWith("Form")) {
|
|
22
|
+
return b.substring(0, b.length - 4)
|
|
23
|
+
}
|
|
24
|
+
return b
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (name && name.length > 0) {
|
|
28
|
+
return name
|
|
29
|
+
}
|
|
30
|
+
return ""
|
|
31
|
+
}
|
|
6
32
|
const m = "model"
|
|
7
33
|
const _getModelName = (f2?: HTMLFormElement | null): string => {
|
|
8
|
-
return
|
|
34
|
+
return getModelName(f2, m)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type Callback<T> = (value?: T) => void
|
|
38
|
+
export type DispatchWithCallback<T> = (value: T, callback?: Callback<T>) => void
|
|
39
|
+
|
|
40
|
+
export function useMergeState<T>(initialState?: T | (() => T)): [T, DispatchWithCallback<Partial<T>>] {
|
|
41
|
+
const [state, _setState] = useState(initialState ? initialState : ({} as any))
|
|
42
|
+
|
|
43
|
+
const callbackRef = useRef<Callback<T>>()
|
|
44
|
+
|
|
45
|
+
const setState = useCallback(
|
|
46
|
+
(newState: Partial<T>, callback?: Callback<T>): void => {
|
|
47
|
+
callbackRef.current = callback
|
|
48
|
+
_setState((prevState: any) => Object.assign({}, prevState, newState))
|
|
49
|
+
},
|
|
50
|
+
[state],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (callbackRef.current) {
|
|
55
|
+
callbackRef.current(state)
|
|
56
|
+
}
|
|
57
|
+
}, [state])
|
|
58
|
+
|
|
59
|
+
return [state, setState]
|
|
9
60
|
}
|
|
61
|
+
|
|
10
62
|
export const useUpdate = <T>(
|
|
11
63
|
initialState: T,
|
|
12
64
|
getName?: ((f?: HTMLFormElement | null) => string) | string,
|
package/src/useEdit.ts
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
import { useEffect, useState } from "react"
|
|
2
2
|
import { Params, useNavigate, useParams } from "react-router"
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
Attributes,
|
|
6
|
-
ErrorMessage,
|
|
7
|
-
getModelName as getModelName2,
|
|
8
|
-
hideLoading,
|
|
9
|
-
initForm,
|
|
10
|
-
LoadingService,
|
|
11
|
-
Locale,
|
|
12
|
-
resources,
|
|
13
|
-
ResourceService,
|
|
14
|
-
showLoading,
|
|
15
|
-
UIService,
|
|
16
|
-
} from "./core"
|
|
3
|
+
import { messageByHttpStatus } from "./common"
|
|
4
|
+
import { Attribute, Attributes, ErrorMessage, LoadingService, Locale, resources, ResourceService, UIService } from "./core"
|
|
17
5
|
import { createModel as createModel2 } from "./edit"
|
|
18
|
-
import { message, messageByHttpStatus } from "./error"
|
|
19
6
|
import { focusFirstError, setReadOnly } from "./formutil"
|
|
20
|
-
import {
|
|
7
|
+
import { hideLoading, initForm, showLoading } from "./input"
|
|
21
8
|
import { clone, makeDiff } from "./reflect"
|
|
22
9
|
import { localeOf } from "./state"
|
|
23
|
-
import { useUpdate } from "./update"
|
|
10
|
+
import { DispatchWithCallback, getModelName as getModelName2, useMergeState, useUpdate } from "./update"
|
|
24
11
|
|
|
25
12
|
export function buildKeys(attributes: Attributes): string[] {
|
|
26
13
|
if (!attributes) {
|
|
@@ -349,11 +336,11 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
349
336
|
}
|
|
350
337
|
|
|
351
338
|
const _handleNotFound = (form?: any): void => {
|
|
352
|
-
const msg = message(p1.resource.value, "error_404", "error")
|
|
353
339
|
if (form) {
|
|
354
340
|
setReadOnly(form)
|
|
355
341
|
}
|
|
356
|
-
|
|
342
|
+
const resource = p1.resource.resource()
|
|
343
|
+
p1.showError(resource.error_404, () => window.history.back, resource.error)
|
|
357
344
|
}
|
|
358
345
|
const handleNotFound = p && p.handleNotFound ? p.handleNotFound : _handleNotFound
|
|
359
346
|
|
|
@@ -380,15 +367,15 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
380
367
|
if (objKeys.length === 0) {
|
|
381
368
|
navigate(-1)
|
|
382
369
|
} else {
|
|
383
|
-
const
|
|
370
|
+
const resource = p1.resource.resource()
|
|
384
371
|
p1.confirm(
|
|
385
|
-
|
|
372
|
+
resource.msg_confirm_back,
|
|
386
373
|
() => {
|
|
387
374
|
navigate(-1)
|
|
388
375
|
},
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
376
|
+
resource.confirm,
|
|
377
|
+
resource.no,
|
|
378
|
+
resource.yes,
|
|
392
379
|
)
|
|
393
380
|
}
|
|
394
381
|
}
|
|
@@ -418,13 +405,12 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
418
405
|
}
|
|
419
406
|
|
|
420
407
|
const _onSave = (isBack?: boolean) => {
|
|
408
|
+
const resource = p1.resource.resource()
|
|
421
409
|
if (p && p.readOnly) {
|
|
422
410
|
if (flag.newMode === true) {
|
|
423
|
-
|
|
424
|
-
p1.showError(m.message, undefined, m.title)
|
|
411
|
+
p1.showError(resource.error_permission_add, undefined, resource.error_permission)
|
|
425
412
|
} else {
|
|
426
|
-
|
|
427
|
-
p1.showError(msg.message, undefined, msg.title)
|
|
413
|
+
p1.showError(resource.error_permission_edit, undefined, resource.error_permission)
|
|
428
414
|
}
|
|
429
415
|
} else {
|
|
430
416
|
if (running === true) {
|
|
@@ -441,15 +427,14 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
441
427
|
}
|
|
442
428
|
if (flag.newMode) {
|
|
443
429
|
validate(obj, () => {
|
|
444
|
-
const msg = message(p1.resource.value, "msg_confirm_save", "confirm", "yes", "no")
|
|
445
430
|
p1.confirm(
|
|
446
|
-
|
|
431
|
+
resource.msg_confirm_save,
|
|
447
432
|
() => {
|
|
448
433
|
doSave(obj, undefined, version, isBack)
|
|
449
434
|
},
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
435
|
+
resource.confirm,
|
|
436
|
+
resource.no,
|
|
437
|
+
resource.yes,
|
|
453
438
|
)
|
|
454
439
|
})
|
|
455
440
|
} else {
|
|
@@ -459,15 +444,14 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
459
444
|
p1.showMessage(p1.resource.value("msg_no_change"))
|
|
460
445
|
} else {
|
|
461
446
|
validate(obj, () => {
|
|
462
|
-
const msg = message(p1.resource.value, "msg_confirm_save", "confirm", "yes", "no")
|
|
463
447
|
p1.confirm(
|
|
464
|
-
|
|
448
|
+
resource.msg_confirm_save,
|
|
465
449
|
() => {
|
|
466
450
|
doSave(obj, diffObj as any, version, isBack)
|
|
467
451
|
},
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
452
|
+
resource.confirm,
|
|
453
|
+
resource.no,
|
|
454
|
+
resource.yes,
|
|
471
455
|
)
|
|
472
456
|
})
|
|
473
457
|
}
|
|
@@ -596,8 +580,8 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
596
580
|
const postSave = p && p.postSave ? p.postSave : _postSave
|
|
597
581
|
|
|
598
582
|
const _handleDuplicateKey = (result?: T) => {
|
|
599
|
-
const
|
|
600
|
-
p1.showError(
|
|
583
|
+
const resource = p1.resource.resource()
|
|
584
|
+
p1.showError(resource.error_duplicate_key, undefined, resource.error)
|
|
601
585
|
}
|
|
602
586
|
const handleDuplicateKey = p && p.handleDuplicateKey ? p.handleDuplicateKey : _handleDuplicateKey
|
|
603
587
|
|
|
@@ -653,9 +637,9 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
653
637
|
})
|
|
654
638
|
.catch((err: any) => {
|
|
655
639
|
const data = err && err.response ? err.response : err
|
|
656
|
-
const
|
|
657
|
-
const title =
|
|
658
|
-
let msg =
|
|
640
|
+
const resource = p1.resource.resource()
|
|
641
|
+
const title = resource.error
|
|
642
|
+
let msg = resource.error_internal
|
|
659
643
|
if (data && data.status === 422) {
|
|
660
644
|
fail(err.response?.data)
|
|
661
645
|
const obj = err.response?.data?.value
|
|
@@ -667,7 +651,7 @@ export const useCoreEdit = <T, ID, S, P>(
|
|
|
667
651
|
handleNotFound(refForm.current)
|
|
668
652
|
} else {
|
|
669
653
|
if (data.status && !isNaN(data.status)) {
|
|
670
|
-
msg = messageByHttpStatus(data.status,
|
|
654
|
+
msg = messageByHttpStatus(data.status, resource)
|
|
671
655
|
}
|
|
672
656
|
if (data && (data.status === 401 || data.status === 403)) {
|
|
673
657
|
setReadOnly(refForm.current)
|
package/src/useSearch.ts
CHANGED
|
@@ -1,20 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from "react"
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
getValidateForm,
|
|
6
|
-
hideLoading,
|
|
7
|
-
initForm,
|
|
8
|
-
LoadingService,
|
|
9
|
-
Locale,
|
|
10
|
-
pageSizes,
|
|
11
|
-
removeFormError,
|
|
12
|
-
resources,
|
|
13
|
-
ResourceService,
|
|
14
|
-
showLoading,
|
|
15
|
-
UIService,
|
|
16
|
-
} from "./core"
|
|
17
|
-
import { error } from "./error"
|
|
2
|
+
import { error } from "./common"
|
|
3
|
+
import { LoadingService, Locale, pageSizes, resources, ResourceService, UIService } from "./core"
|
|
4
|
+
import { hideLoading, initForm, showLoading } from "./input"
|
|
18
5
|
import { DispatchWithCallback, useMergeState } from "./merge"
|
|
19
6
|
import { clone } from "./reflect"
|
|
20
7
|
import { buildFromUrl } from "./route"
|
|
@@ -23,6 +10,7 @@ import {
|
|
|
23
10
|
buildMessage,
|
|
24
11
|
Filter,
|
|
25
12
|
getFields,
|
|
13
|
+
getPageTotal,
|
|
26
14
|
handleSort,
|
|
27
15
|
handleToggle,
|
|
28
16
|
initFilter,
|
|
@@ -32,13 +20,19 @@ import {
|
|
|
32
20
|
removeSortStatus,
|
|
33
21
|
SearchResult,
|
|
34
22
|
SearchService,
|
|
35
|
-
showPaging,
|
|
36
23
|
Sortable,
|
|
37
24
|
} from "./search"
|
|
38
25
|
import { enLocale } from "./state"
|
|
39
26
|
import { useUpdate } from "./update"
|
|
40
27
|
|
|
41
|
-
export
|
|
28
|
+
export function showPaging<T>(com: Pagination, list: T[], pageSize?: number, total?: number): void {
|
|
29
|
+
com.total = total
|
|
30
|
+
const pageTotal = getPageTotal(pageSize, total)
|
|
31
|
+
com.pages = pageTotal
|
|
32
|
+
com.showPaging = !total || com.pages <= 1 || (list && list.length >= total) ? false : true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Searchable extends Pagination, Sortable {
|
|
42
36
|
nextPageToken?: string
|
|
43
37
|
excluding?: string[] | number[]
|
|
44
38
|
}
|
|
@@ -52,6 +46,30 @@ export interface SearchParameter {
|
|
|
52
46
|
auto?: boolean
|
|
53
47
|
}
|
|
54
48
|
|
|
49
|
+
export interface UIParameter {
|
|
50
|
+
ui?: UIService
|
|
51
|
+
}
|
|
52
|
+
export function removeFormError(u?: UIParameter, f?: HTMLFormElement): void {
|
|
53
|
+
if (f && u && u.ui) {
|
|
54
|
+
u.ui.removeFormError(f)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function getValidateForm(
|
|
58
|
+
u?: UIParameter,
|
|
59
|
+
vf?: (form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean,
|
|
60
|
+
): ((form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean) | undefined {
|
|
61
|
+
if (vf) {
|
|
62
|
+
return vf
|
|
63
|
+
}
|
|
64
|
+
return u && u.ui ? u.ui.validateForm : undefined
|
|
65
|
+
}
|
|
66
|
+
export function getRemoveError(u?: UIParameter, rmErr?: (el: HTMLInputElement) => void): ((el: HTMLInputElement) => void) | undefined {
|
|
67
|
+
if (rmErr) {
|
|
68
|
+
return rmErr
|
|
69
|
+
}
|
|
70
|
+
return u && u.ui ? u.ui.removeError : undefined
|
|
71
|
+
}
|
|
72
|
+
|
|
55
73
|
export function getModel<S extends Filter>(state: any, modelName: string, searchable: Searchable, fields?: string[], excluding?: string[] | number[]): S {
|
|
56
74
|
let obj2 = getModelFromState(state, modelName)
|
|
57
75
|
|
|
@@ -122,6 +140,7 @@ export function getFieldsFromForm(fields?: string[], initFields?: boolean, form?
|
|
|
122
140
|
}
|
|
123
141
|
return fields
|
|
124
142
|
}
|
|
143
|
+
|
|
125
144
|
export function append<T>(list?: T[], results?: T[]): T[] {
|
|
126
145
|
if (list && results) {
|
|
127
146
|
for (const obj of results) {
|
|
@@ -425,6 +444,10 @@ export const useSearchOneProps = <T, S extends Filter, ST extends SearchComponen
|
|
|
425
444
|
export const useSearchOne = <T, S extends Filter, ST extends SearchComponentState<T, S>>(p: HookBaseSearchParameter<T, S, ST>) => {
|
|
426
445
|
return useCoreSearch(p.refForm, p.initialState, p.service, p, p)
|
|
427
446
|
}
|
|
447
|
+
|
|
448
|
+
export function getName(d: string, n?: string): string {
|
|
449
|
+
return n && n.length > 0 ? n : d
|
|
450
|
+
}
|
|
428
451
|
export const useCoreSearch = <T, S extends Filter, ST>(
|
|
429
452
|
refForm: any,
|
|
430
453
|
initialState: ST,
|
|
@@ -633,7 +656,8 @@ export const useCoreSearch = <T, S extends Filter, ST>(
|
|
|
633
656
|
|
|
634
657
|
const searchError = (err: any): void => {
|
|
635
658
|
setComponent({ page: component.tmpPageIndex })
|
|
636
|
-
|
|
659
|
+
const resource = p1.resource.resource()
|
|
660
|
+
error(err, resource, p1.showError)
|
|
637
661
|
hideLoading(p1.loading)
|
|
638
662
|
}
|
|
639
663
|
const appendList = p && p.appendList ? p.appendList : appendListOfState
|
package/src/util.ts
CHANGED
|
@@ -77,7 +77,7 @@ function getStringCurrency(value: string, datatype: string, locale?: Locale, max
|
|
|
77
77
|
|
|
78
78
|
const dotPosition = value.indexOf(".")
|
|
79
79
|
// Format thousands
|
|
80
|
-
let beforeDot = dotPosition >= 0 ? value.
|
|
80
|
+
let beforeDot = dotPosition >= 0 ? value.substring(0, dotPosition) : value
|
|
81
81
|
if (datatype === "string-currency" || isOnBlur) {
|
|
82
82
|
beforeDot = beforeDot.replace(new RegExp("\\B(?=(\\d{" + groupDigits + "})+(?!\\d))", "g"), groupSeparator)
|
|
83
83
|
}
|
|
@@ -85,9 +85,9 @@ function getStringCurrency(value: string, datatype: string, locale?: Locale, max
|
|
|
85
85
|
// Cut after dot
|
|
86
86
|
let afterDot
|
|
87
87
|
if (dotPosition > 0) {
|
|
88
|
-
afterDot = value.
|
|
88
|
+
afterDot = value.substring(dotPosition + 1)
|
|
89
89
|
if (afterDot.length > decimalDigits) {
|
|
90
|
-
afterDot = afterDot.
|
|
90
|
+
afterDot = afterDot.substring(0, decimalDigits)
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
if (maxLength && beforeDot.length > maxLength - (decimalDigits + 1)) {
|