react-hook-core 0.1.2 → 0.1.5
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/README.md +1 -1
- package/lib/components.js +51 -92
- package/lib/core.js +21 -12
- package/lib/diff.js +2 -2
- package/lib/formutil.js +2 -2
- package/lib/index.js +44 -8
- package/lib/reflect.js +268 -0
- package/lib/search.js +579 -0
- package/lib/state.js +4 -4
- package/lib/update.js +7 -20
- package/lib/useEdit.js +63 -49
- package/lib/useSearch.js +65 -69
- package/lib/useView.js +24 -26
- package/package.json +5 -7
- package/src/components.ts +56 -97
- package/src/core.ts +70 -59
- package/src/diff.ts +1 -1
- package/src/formutil.ts +2 -2
- package/src/index.ts +35 -11
- package/src/reflect.ts +244 -0
- package/src/search.ts +600 -0
- package/src/state.ts +1 -1
- package/src/update.ts +7 -19
- package/src/useEdit.ts +75 -59
- package/src/useSearch.ts +74 -64
- package/src/useView.ts +31 -34
- package/tsconfig.json +3 -1
package/src/core.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {focusFirstElement} from './formutil';
|
|
1
|
+
import { Params } from 'react-router';
|
|
2
|
+
import { focusFirstElement } from './formutil';
|
|
3
3
|
|
|
4
|
+
export const pageSizes = [12, 24, 60, 100, 120, 180, 300, 600];
|
|
4
5
|
export interface ModelMap {
|
|
5
6
|
[key: string]: any;
|
|
6
7
|
}
|
|
8
|
+
export interface PageChange {
|
|
9
|
+
page: number; // currentPage
|
|
10
|
+
size: number; // itemsPerPage
|
|
11
|
+
}
|
|
7
12
|
export interface ModelProps {
|
|
8
13
|
setGlobalState?: (m: ModelMap) => void;
|
|
9
14
|
shouldBeCustomized?: boolean;
|
|
@@ -30,12 +35,12 @@ export interface SearchParameter {
|
|
|
30
35
|
auto?: boolean;
|
|
31
36
|
}
|
|
32
37
|
export interface EditStatusConfig {
|
|
33
|
-
duplicate_key: number|string;
|
|
34
|
-
not_found: number|string;
|
|
35
|
-
success: number|string;
|
|
36
|
-
version_error: number|string;
|
|
37
|
-
error?: number|string;
|
|
38
|
-
data_corrupt?: number|string;
|
|
38
|
+
duplicate_key: number | string;
|
|
39
|
+
not_found: number | string;
|
|
40
|
+
success: number | string;
|
|
41
|
+
version_error: number | string;
|
|
42
|
+
error?: number | string;
|
|
43
|
+
data_corrupt?: number | string;
|
|
39
44
|
}
|
|
40
45
|
export function createEditStatus(status?: EditStatusConfig): EditStatusConfig {
|
|
41
46
|
if (status) {
|
|
@@ -52,10 +57,10 @@ export function createEditStatus(status?: EditStatusConfig): EditStatusConfig {
|
|
|
52
57
|
return s;
|
|
53
58
|
}
|
|
54
59
|
export interface DiffStatusConfig {
|
|
55
|
-
not_found: number|string;
|
|
56
|
-
success: number|string;
|
|
57
|
-
version_error: number|string;
|
|
58
|
-
error?: number|string;
|
|
60
|
+
not_found: number | string;
|
|
61
|
+
success: number | string;
|
|
62
|
+
version_error: number | string;
|
|
63
|
+
error?: number | string;
|
|
59
64
|
}
|
|
60
65
|
export function createDiffStatus(status?: DiffStatusConfig): DiffStatusConfig {
|
|
61
66
|
if (status) {
|
|
@@ -91,7 +96,7 @@ export interface SearchState<T, S extends Filter> {
|
|
|
91
96
|
}
|
|
92
97
|
export interface SearchService<T, S extends Filter> {
|
|
93
98
|
keys?(): string[];
|
|
94
|
-
search(s: S, limit?: number, offset?: number|string, fields?: string[]): Promise<SearchResult<T>>;
|
|
99
|
+
search(s: S, limit?: number, offset?: number | string, fields?: string[]): Promise<SearchResult<T>>;
|
|
95
100
|
}
|
|
96
101
|
export interface ViewParameter {
|
|
97
102
|
resource: ResourceService;
|
|
@@ -100,9 +105,9 @@ export interface ViewParameter {
|
|
|
100
105
|
loading?: LoadingService;
|
|
101
106
|
}
|
|
102
107
|
export interface ViewService<T, ID> {
|
|
103
|
-
metadata?(): Attributes;
|
|
108
|
+
metadata?(): Attributes | undefined;
|
|
104
109
|
keys?(): string[];
|
|
105
|
-
load(id: ID, ctx?: any): Promise<T>;
|
|
110
|
+
load(id: ID, ctx?: any): Promise<T | null>;
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
export interface DiffParameter {
|
|
@@ -126,8 +131,8 @@ export interface DiffModel<T, ID> {
|
|
|
126
131
|
value: T;
|
|
127
132
|
}
|
|
128
133
|
export interface ApprService<ID> {
|
|
129
|
-
approve(id: ID, ctx?: any): Promise<number|string>;
|
|
130
|
-
reject(id: ID, ctx?: any): Promise<number|string>;
|
|
134
|
+
approve(id: ID, ctx?: any): Promise<number | string>;
|
|
135
|
+
reject(id: ID, ctx?: any): Promise<number | string>;
|
|
131
136
|
}
|
|
132
137
|
export interface DiffService<T, ID> {
|
|
133
138
|
keys(): string[];
|
|
@@ -143,11 +148,11 @@ export interface DiffState<T> {
|
|
|
143
148
|
|
|
144
149
|
// tslint:disable-next-line:class-name
|
|
145
150
|
export class resource {
|
|
146
|
-
static phone = /
|
|
151
|
+
static phone = / |-|\.|\(|\)/g;
|
|
147
152
|
static _cache: any = {};
|
|
148
153
|
static cache = true;
|
|
149
154
|
}
|
|
150
|
-
export function getCurrencyCode(form?: HTMLFormElement|null): string|undefined {
|
|
155
|
+
export function getCurrencyCode(form?: HTMLFormElement | null): string | undefined {
|
|
151
156
|
if (form) {
|
|
152
157
|
const x = form.getAttribute('currency-code');
|
|
153
158
|
if (x) {
|
|
@@ -177,34 +182,34 @@ export interface Message {
|
|
|
177
182
|
yes?: string;
|
|
178
183
|
no?: string;
|
|
179
184
|
}
|
|
180
|
-
export function getString(key: string, gv: StringMap|((key: string) => string)): string {
|
|
185
|
+
export function getString(key: string, gv: StringMap | ((key: string) => string)): string {
|
|
181
186
|
if (typeof gv === 'function') {
|
|
182
187
|
return gv(key);
|
|
183
188
|
} else {
|
|
184
189
|
return gv[key];
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
|
-
export function message(gv: StringMap|((key: string) => string), msg: string, title?: string, yes?: string, no?: string): Message {
|
|
192
|
+
export function message(gv: StringMap | ((key: string) => string), msg: string, title?: string, yes?: string, no?: string): Message {
|
|
188
193
|
const m2 = (msg && msg.length > 0 ? getString(msg, gv) : '');
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
194
|
+
const m: Message = { message: m2, title: '' };
|
|
195
|
+
if (title && title.length > 0) {
|
|
196
|
+
m.title = getString(title, gv);
|
|
197
|
+
}
|
|
198
|
+
if (yes && yes.length > 0) {
|
|
199
|
+
m.yes = getString(yes, gv);
|
|
200
|
+
}
|
|
201
|
+
if (no && no.length > 0) {
|
|
202
|
+
m.no = getString(no, gv);
|
|
203
|
+
}
|
|
204
|
+
return m;
|
|
200
205
|
}
|
|
201
|
-
export function messageByHttpStatus(status: number, gv: StringMap|((key: string) => string)): string {
|
|
206
|
+
export function messageByHttpStatus(status: number, gv: StringMap | ((key: string) => string)): string {
|
|
202
207
|
const k = 'status_' + status;
|
|
203
208
|
let msg = getString(k, gv);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
209
|
+
if (!msg || msg.length === 0) {
|
|
210
|
+
msg = getString('error_internal', gv);
|
|
211
|
+
}
|
|
212
|
+
return msg;
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
export interface Locale {
|
|
@@ -227,12 +232,12 @@ export interface LoadingService {
|
|
|
227
232
|
export interface ErrorMessage {
|
|
228
233
|
field: string;
|
|
229
234
|
code: string;
|
|
230
|
-
param?: string|number|Date;
|
|
235
|
+
param?: string | number | Date;
|
|
231
236
|
message?: string;
|
|
232
237
|
}
|
|
233
238
|
export interface UIService {
|
|
234
|
-
getValue(el: HTMLInputElement, locale?: Locale, currencyCode?: string): string|number|boolean;
|
|
235
|
-
decodeFromForm(form: HTMLFormElement, locale?: Locale, currencyCode?: string|null): any;
|
|
239
|
+
getValue(el: HTMLInputElement, locale?: Locale, currencyCode?: string): string | number | boolean | null | undefined;
|
|
240
|
+
decodeFromForm(form: HTMLFormElement, locale?: Locale, currencyCode?: string | null): any;
|
|
236
241
|
|
|
237
242
|
validateForm(form?: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean): boolean;
|
|
238
243
|
removeFormError(form: HTMLFormElement): void;
|
|
@@ -279,26 +284,23 @@ export function buildKeys(attributes: Attributes): string[] {
|
|
|
279
284
|
}
|
|
280
285
|
return ps;
|
|
281
286
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
const sp: any = ((props as any).match ? props : (props as any)['props']);
|
|
287
|
+
type Readonly<T> = {
|
|
288
|
+
readonly [P in keyof T]: T[P];
|
|
289
|
+
};
|
|
290
|
+
export function buildId<ID>(p: Readonly<Params<string>>, keys?: string[]): ID | null {
|
|
288
291
|
if (!keys || keys.length === 0 || keys.length === 1) {
|
|
289
292
|
if (keys && keys.length === 1) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return x;
|
|
293
|
+
if (p[keys[0]]) {
|
|
294
|
+
return p[keys[0]] as any;
|
|
293
295
|
}
|
|
294
296
|
}
|
|
295
|
-
return
|
|
297
|
+
return p['id'] as any;
|
|
296
298
|
}
|
|
297
299
|
const id: any = {};
|
|
298
300
|
for (const key of keys) {
|
|
299
|
-
let v =
|
|
301
|
+
let v = p[key];
|
|
300
302
|
if (!v) {
|
|
301
|
-
v =
|
|
303
|
+
v = p[key];
|
|
302
304
|
if (!v) {
|
|
303
305
|
return null;
|
|
304
306
|
}
|
|
@@ -307,8 +309,6 @@ export function buildId<ID>(props: RouteComponentProps, keys?: string[]): ID|nul
|
|
|
307
309
|
}
|
|
308
310
|
return id;
|
|
309
311
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
312
|
export function dateToDefaultString(date: Date): string {
|
|
313
313
|
return '' + date.getFullYear() + '-' + addZero(date.getMonth() + 1, 2) + '-' + addZero(date.getDate(), 2); // DateUtil.formatDate(date, 'YYYY-MM-DD');
|
|
314
314
|
}
|
|
@@ -375,7 +375,7 @@ export function formatCurrency(currency: string|number, locale?: Locale, currenc
|
|
|
375
375
|
}
|
|
376
376
|
*/
|
|
377
377
|
|
|
378
|
-
export function initForm(form
|
|
378
|
+
export function initForm(form?: HTMLFormElement, initMat?: (f: HTMLFormElement) => void): HTMLFormElement | undefined {
|
|
379
379
|
if (form) {
|
|
380
380
|
setTimeout(() => {
|
|
381
381
|
if (initMat) {
|
|
@@ -407,7 +407,7 @@ export function error(err: any, gv: (key: string) => string, ae: (msg: string, h
|
|
|
407
407
|
export function getName(d: string, n?: string): string {
|
|
408
408
|
return (n && n.length > 0 ? n : d);
|
|
409
409
|
}
|
|
410
|
-
export function getModelName(form?: HTMLFormElement|null, name?: string): string {
|
|
410
|
+
export function getModelName(form?: HTMLFormElement | null, name?: string): string {
|
|
411
411
|
if (form) {
|
|
412
412
|
const a = form.getAttribute('model-name');
|
|
413
413
|
if (a && a.length > 0) {
|
|
@@ -468,7 +468,7 @@ export function hideLoading(s?: LoadingService): void {
|
|
|
468
468
|
export interface UIParameter {
|
|
469
469
|
ui?: UIService;
|
|
470
470
|
}
|
|
471
|
-
export function getRemoveError(u?: UIParameter, rmErr?: (el: HTMLInputElement) => void): ((el: HTMLInputElement) => void)|undefined {
|
|
471
|
+
export function getRemoveError(u?: UIParameter, rmErr?: (el: HTMLInputElement) => void): ((el: HTMLInputElement) => void) | undefined {
|
|
472
472
|
if (rmErr) {
|
|
473
473
|
return rmErr;
|
|
474
474
|
}
|
|
@@ -479,15 +479,26 @@ export function removeFormError(u?: UIParameter, f?: HTMLFormElement): void {
|
|
|
479
479
|
u.ui.removeFormError(f);
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
|
-
export function getValidateForm(u?: UIParameter, vf?: (form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean): ((form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean)|undefined {
|
|
482
|
+
export function getValidateForm(u?: UIParameter, vf?: (form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean): ((form: HTMLFormElement, locale?: Locale, focusFirst?: boolean, scroll?: boolean) => boolean) | undefined {
|
|
483
483
|
if (vf) {
|
|
484
484
|
return vf;
|
|
485
485
|
}
|
|
486
486
|
return (u && u.ui ? u.ui.validateForm : undefined);
|
|
487
487
|
}
|
|
488
|
-
export function getDecodeFromForm(u?: UIParameter, d?: (form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any): ((form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any)|undefined {
|
|
488
|
+
export function getDecodeFromForm(u?: UIParameter, d?: (form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any): ((form: HTMLFormElement, locale?: Locale, currencyCode?: string) => any) | undefined {
|
|
489
489
|
if (d) {
|
|
490
490
|
return d;
|
|
491
491
|
}
|
|
492
492
|
return (u && u.ui ? u.ui.decodeFromForm : undefined);
|
|
493
493
|
}
|
|
494
|
+
export function handleToggle(target?: HTMLInputElement, on?: boolean): void {
|
|
495
|
+
if (target) {
|
|
496
|
+
if (on) {
|
|
497
|
+
if (!target.classList.contains('on')) {
|
|
498
|
+
target.classList.add('on');
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
target.classList.remove('on');
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
package/src/diff.ts
CHANGED
package/src/formutil.ts
CHANGED
|
@@ -74,7 +74,7 @@ export function focusFirstError(form?: HTMLFormElement|null, className?: string)
|
|
|
74
74
|
const ctrl = form[i] as HTMLInputElement;
|
|
75
75
|
const parent = ctrl.parentElement;
|
|
76
76
|
if (ctrl.classList.contains(className)
|
|
77
|
-
|| parent && parent.classList.contains(className)) {
|
|
77
|
+
|| (parent && parent.classList.contains(className))) {
|
|
78
78
|
ctrl.focus();
|
|
79
79
|
ctrl.scrollIntoView();
|
|
80
80
|
return;
|
|
@@ -86,7 +86,7 @@ export function focusFirstError(form?: HTMLFormElement|null, className?: string)
|
|
|
86
86
|
const parent = ctrl.parentElement;
|
|
87
87
|
if (ctrl.classList.contains('invalid')
|
|
88
88
|
|| ctrl.classList.contains('.ng-invalid')
|
|
89
|
-
|| parent && parent.classList.contains('invalid')) {
|
|
89
|
+
|| (parent && parent.classList.contains('invalid'))) {
|
|
90
90
|
ctrl.focus();
|
|
91
91
|
ctrl.scrollIntoView();
|
|
92
92
|
return;
|
package/src/index.ts
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { RouteComponentProps } from 'react-router';
|
|
3
2
|
export * from './formutil';
|
|
4
3
|
export * from './util';
|
|
5
4
|
export * from './core';
|
|
6
5
|
export * from './state';
|
|
7
6
|
export * from './edit';
|
|
8
7
|
export * from './route';
|
|
9
|
-
export * from './components';
|
|
10
8
|
export * from './diff';
|
|
11
|
-
export * from './router';
|
|
12
9
|
export * from './merge';
|
|
13
10
|
export * from './update';
|
|
14
|
-
export * from './useView';
|
|
15
|
-
export * from './useEdit';
|
|
16
11
|
export * from './useSearch';
|
|
17
12
|
export * from './useMessage';
|
|
13
|
+
export * from './useEdit';
|
|
14
|
+
export * from './components';
|
|
15
|
+
export * from './search';
|
|
16
|
+
export * from './reflect';
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
import {pageSizes} from './core';
|
|
19
|
+
|
|
20
|
+
export function checked(s: string[]|string|undefined, v: string): boolean|undefined {
|
|
21
|
+
if (s) {
|
|
22
|
+
if (Array.isArray(s)) {
|
|
23
|
+
return s.includes(v);
|
|
24
|
+
} else {
|
|
25
|
+
return s === v;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
export function value<T>(obj?: T): T {
|
|
31
|
+
return (obj ? obj : {} as any);
|
|
32
|
+
}
|
|
23
33
|
export interface LoadingProps {
|
|
24
34
|
error?: any;
|
|
25
35
|
}
|
|
@@ -32,9 +42,9 @@ export const Loading = (props: LoadingProps) => {
|
|
|
32
42
|
'boxShadow': 'none'
|
|
33
43
|
};
|
|
34
44
|
if (props.error) {
|
|
35
|
-
return React.createElement(
|
|
45
|
+
return React.createElement('div', null, 'Error Load Module!'); // return (<div>Error Load Module!</div>);
|
|
36
46
|
} else {
|
|
37
|
-
return (React.createElement(
|
|
47
|
+
return (React.createElement('div', { className: 'loader-wrapper' }, React.createElement('div', { className: 'loader-sign', style: loadingStyle }, React.createElement('div', { className: 'loader' }))));
|
|
38
48
|
/*
|
|
39
49
|
return (
|
|
40
50
|
<div className='loader-wrapper'>
|
|
@@ -45,3 +55,17 @@ export const Loading = (props: LoadingProps) => {
|
|
|
45
55
|
);*/
|
|
46
56
|
}
|
|
47
57
|
};
|
|
58
|
+
export interface Props {
|
|
59
|
+
id?: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
size?: number;
|
|
62
|
+
sizes?: number[];
|
|
63
|
+
onChange?: React.ChangeEventHandler<HTMLSelectElement>;
|
|
64
|
+
}
|
|
65
|
+
export function PageSizeSelect(p: Props) {
|
|
66
|
+
const g = p.sizes;
|
|
67
|
+
const s = (!g || g.length === 0 ? pageSizes : g);
|
|
68
|
+
const opts = s.map(pgSize => React.createElement('option', { key: pgSize, value: pgSize }, pgSize));
|
|
69
|
+
return React.createElement('select', { id: p.id, name: p.name, defaultValue: p.size, onChange: p.onChange }, opts);
|
|
70
|
+
}
|
|
71
|
+
export default PageSizeSelect;
|
package/src/reflect.ts
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
export function clone(obj: any): any {
|
|
2
|
+
if (!obj) {
|
|
3
|
+
return obj;
|
|
4
|
+
}
|
|
5
|
+
if (obj instanceof Date) {
|
|
6
|
+
return new Date(obj.getTime());
|
|
7
|
+
}
|
|
8
|
+
if (typeof obj !== 'object') {
|
|
9
|
+
return obj;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(obj)) {
|
|
12
|
+
const arr = [];
|
|
13
|
+
for (const sub of obj) {
|
|
14
|
+
const c = clone(sub);
|
|
15
|
+
arr.push(c);
|
|
16
|
+
}
|
|
17
|
+
return arr;
|
|
18
|
+
}
|
|
19
|
+
const x: any = {};
|
|
20
|
+
const keys = Object.keys(obj);
|
|
21
|
+
for (const k of keys) {
|
|
22
|
+
const v = obj[k];
|
|
23
|
+
if (v instanceof Date) {
|
|
24
|
+
x[k] = new Date(v.getTime());
|
|
25
|
+
} else {
|
|
26
|
+
switch (typeof v) {
|
|
27
|
+
case 'object':
|
|
28
|
+
x[k] = clone(v);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
x[k] = v;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return x;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getDirectValue(obj: any, key: string): any {
|
|
40
|
+
if (obj && obj.hasOwnProperty(key)) {
|
|
41
|
+
return obj[key];
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function setValue(obj: any, key: string, value: any): any {
|
|
47
|
+
let replaceKey = key.replace(/\[/g, '.[').replace(/\.\./g, '.');
|
|
48
|
+
if (replaceKey.indexOf('.') === 0) {
|
|
49
|
+
replaceKey = replaceKey.slice(1, replaceKey.length);
|
|
50
|
+
}
|
|
51
|
+
const keys = replaceKey.split('.');
|
|
52
|
+
const firstKey = keys.shift();
|
|
53
|
+
if (!firstKey) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const isArrayKey = /\[([0-9]+)\]/.test(firstKey);
|
|
57
|
+
if (keys.length > 0) {
|
|
58
|
+
const firstKeyValue = obj[firstKey] || {};
|
|
59
|
+
const returnValue = setValue(firstKeyValue, keys.join('.'), value);
|
|
60
|
+
return setKey(obj, isArrayKey, firstKey, returnValue);
|
|
61
|
+
}
|
|
62
|
+
return setKey(obj, isArrayKey, firstKey, value);
|
|
63
|
+
}
|
|
64
|
+
const setKey = (_object: any, _isArrayKey: boolean, _key: string, _nextValue: any) => {
|
|
65
|
+
if (_isArrayKey) {
|
|
66
|
+
if (_object.length > _key) {
|
|
67
|
+
_object[_key] = _nextValue;
|
|
68
|
+
} else {
|
|
69
|
+
_object.push(_nextValue);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
_object[_key] = _nextValue;
|
|
73
|
+
}
|
|
74
|
+
return _object;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export function diff(obj1: any, obj2: any): string[] {
|
|
78
|
+
const fields = [];
|
|
79
|
+
const key1s = Object.keys(obj1);
|
|
80
|
+
for (const k of key1s) {
|
|
81
|
+
const v1 = obj1[k];
|
|
82
|
+
const v2 = obj2[k];
|
|
83
|
+
if (v1 == null) {
|
|
84
|
+
if (v2 != null) {
|
|
85
|
+
fields.push(k);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (typeof v1 !== 'object') {
|
|
89
|
+
if (v1 !== v2) {
|
|
90
|
+
fields.push(k);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const e = equal(v1, v2);
|
|
94
|
+
if (!e) {
|
|
95
|
+
fields.push(k);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const key2s = Object.keys(obj2);
|
|
101
|
+
const ni = notIn(key1s, key2s);
|
|
102
|
+
for (const n of ni) {
|
|
103
|
+
fields.push(n);
|
|
104
|
+
}
|
|
105
|
+
return fields;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function makeDiff(obj1: any, obj2: any, keys?: string[], version?: string): any {
|
|
109
|
+
const obj3: any = {};
|
|
110
|
+
const s = diff(obj1, obj2);
|
|
111
|
+
if (s.length === 0) {
|
|
112
|
+
return obj3;
|
|
113
|
+
}
|
|
114
|
+
for (const d of s) {
|
|
115
|
+
obj3[d] = obj2[d];
|
|
116
|
+
}
|
|
117
|
+
if (keys && keys.length > 0) {
|
|
118
|
+
for (const x of keys) {
|
|
119
|
+
if (x.length > 0) {
|
|
120
|
+
obj3[x] = obj1[x];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (version && version.length > 0) {
|
|
125
|
+
obj3[version] = obj1[version];
|
|
126
|
+
}
|
|
127
|
+
return obj3;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function notIn(s1: string[], s2: string[]): string[] {
|
|
131
|
+
const r = [];
|
|
132
|
+
for (const s of s2) {
|
|
133
|
+
if (s1.indexOf(s) < 0) {
|
|
134
|
+
r.push(s);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return r;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function equal(obj1: any, obj2: any): boolean {
|
|
141
|
+
if (obj1 == null && obj2 == null) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (obj1 == null || obj2 == null) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if ((typeof obj1) !== (typeof obj2)) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (typeof obj1 !== 'object') {
|
|
151
|
+
return obj1 === obj2;
|
|
152
|
+
}
|
|
153
|
+
if (obj1 instanceof Date) {
|
|
154
|
+
if (!(obj2 instanceof Date)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
return (obj1.getTime() === obj2.getTime());
|
|
158
|
+
}
|
|
159
|
+
if ((Array.isArray(obj1) && !Array.isArray(obj2))
|
|
160
|
+
|| (!Array.isArray(obj1) && Array.isArray(obj2))) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (!Array.isArray(obj1) && !Array.isArray(obj2)) {
|
|
164
|
+
const key1s = Object.keys(obj1);
|
|
165
|
+
const key2s = Object.keys(obj2);
|
|
166
|
+
if (key1s.length !== key2s.length) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
for (const k of key1s) {
|
|
170
|
+
const v = obj1[k];
|
|
171
|
+
if (typeof v !== 'object') {
|
|
172
|
+
if (v !== obj2[k]) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
const e = equal(v, obj2[k]);
|
|
177
|
+
if (e === false) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
return equalArrays(obj1, obj2);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function equalArrays<T>(ar1: T[], ar2: T[]): boolean {
|
|
188
|
+
if (ar1 == null && ar2 == null) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
if (ar1 == null || ar2 == null) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
if (ar1.length !== ar2.length) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
for (let i = 0; i < ar1.length; i++) {
|
|
198
|
+
const e = equal(ar1[i], ar2[i]);
|
|
199
|
+
if (e === false) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function getArray<T>(list: T[]|undefined|null, name: string, v: boolean|string|number): T[] {
|
|
207
|
+
const arrs = [];
|
|
208
|
+
if (list) {
|
|
209
|
+
for (const obj of list) {
|
|
210
|
+
if ((obj as any)[name] === v) {
|
|
211
|
+
arrs.push(obj);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return arrs;
|
|
216
|
+
}
|
|
217
|
+
export function getDiffArray<T>(list: T[]|undefined|null, name: string, v: boolean|string|number): T[] {
|
|
218
|
+
const arrs = [];
|
|
219
|
+
if (list) {
|
|
220
|
+
for (const obj of list) {
|
|
221
|
+
if ((obj as any)[name] !== true) {
|
|
222
|
+
arrs.push(obj);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return arrs;
|
|
227
|
+
}
|
|
228
|
+
export function setAll<T>(list: T[]|undefined|null, name: string, v: boolean|string|number): void {
|
|
229
|
+
if (list) {
|
|
230
|
+
for (const obj of list) {
|
|
231
|
+
(obj as any)[name] = v;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
export function equalAll<T>(list: T[]|undefined|null, name: string, v: boolean|string|number): boolean {
|
|
236
|
+
if (list) {
|
|
237
|
+
for (const obj of list) {
|
|
238
|
+
if ((obj as any)[name] !== v) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|