react-hook-core 0.2.1 → 0.2.3

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/src/components.ts DELETED
@@ -1,1275 +0,0 @@
1
- import * as React from 'react';
2
- import {BaseDiffState, DiffApprService, DiffParameter, DiffState, handleToggle, hideLoading, showLoading} from './core';
3
- import {Attributes, error, ErrorMessage, Filter, getCurrencyCode, getModelName as getModelName2, initForm, LoadingService, Locale, message, messageByHttpStatus, PageChange, pageSizes, removePhoneFormat, ResourceService, SearchParameter, SearchResult, SearchService, SearchState, StringMap, UIService, ViewParameter, ViewService} from './core';
4
- import {formatDiffModel, getDataFields} from './diff';
5
- import {build, createModel as createModel2, EditParameter, GenericService, handleVersion, initPropertyNullInModel} from './edit';
6
- import {focusFirstError, setReadOnly} from './formutil';
7
- import {getAutoSearch, getConfirmFunc, getErrorFunc, getLoadingFunc, getLocaleFunc, getMsgFunc, getResource, getUIService} from './input';
8
- import {clone, diff, makeDiff} from './reflect';
9
- import {buildFromUrl} from './route';
10
- import {addParametersIntoUrl, append, buildMessage, changePage, changePageSize, formatResults, getFieldsFromForm, getModel, handleAppend, handleSortEvent, initFilter, mergeFilter as mergeFilter2, more, Pagination, reset, showPaging, Sortable, validate} from './search';
11
- import {buildFlatState, buildState, enLocale, handleEvent, handleProps, localeOf} from './state';
12
-
13
- interface Searchable extends Pagination, Sortable {
14
- }
15
- export class ViewComponent<T, ID, P, S> extends React.Component<P, S> {
16
- constructor(props: P, sv: ((id: ID, ctx?: any) => Promise<T>)|ViewService<T, ID>,
17
- param: ResourceService|ViewParameter,
18
- showError?: (msg: string, title?: string, detail?: string, callback?: () => void) => void,
19
- loading?: LoadingService,
20
- getLocale?: (profile?: string) => Locale) {
21
- super(props);
22
- this.resourceService = getResource(param);
23
- this.resource = this.resourceService.resource();
24
- this.showError = getErrorFunc(param, showError);
25
- this.loading = getLoadingFunc(param, loading);
26
- this.getLocale = getLocaleFunc(param, getLocale);
27
- if (sv) {
28
- if (typeof sv === 'function') {
29
- this.loadData = sv;
30
- } else {
31
- this.loadData = sv.load;
32
- if (sv.metadata) {
33
- const m = sv.metadata();
34
- if (m) {
35
- this.metadata = m;
36
- const meta = build(m);
37
- if (meta) {
38
- this.keys = meta.keys;
39
- }
40
- }
41
- }
42
- }
43
- }
44
- this.getModelName = this.getModelName.bind(this);
45
- this.load = this.load.bind(this);
46
- this.getModel = this.getModel.bind(this);
47
- this.showModel = this.showModel.bind(this);
48
- this.ref = React.createRef();
49
- }
50
- name?: string;
51
- running?: boolean;
52
- resourceService: ResourceService;
53
- resource: StringMap;
54
- loading?: LoadingService;
55
- showError: (msg: string, title?: string, detail?: string, callback?: () => void) => void;
56
- getLocale?: (profile?: string) => Locale;
57
- loadData?: (id: ID) => Promise<T|null>;
58
- // protected service: ViewService<T, ID>;
59
- form?: HTMLFormElement;
60
- ref: any;
61
- keys?: string[];
62
- metadata?: Attributes;
63
-
64
- getModelName(): string {
65
- if (this.name && this.name.length > 0) {
66
- return this.name;
67
- }
68
- const n = getModelName2(this.form);
69
- if (!n || n.length === 0) {
70
- return 'model';
71
- } else {
72
- return n;
73
- }
74
- }
75
- load(_id: ID, callback?: (m: T, showF: (model: T) => void) => void) {
76
- const id: any = _id;
77
- if (id != null && id !== '' && this.loadData) {
78
- this.running = true;
79
- showLoading(this.loading);
80
- const com = this;
81
- this.loadData(id).then(obj => {
82
- if (!obj) {
83
- com.handleNotFound(com.form);
84
- } else {
85
- if (callback) {
86
- callback(obj, com.showModel);
87
- } else {
88
- com.showModel(obj);
89
- }
90
- }
91
- com.running = false;
92
- hideLoading(com.loading);
93
- }).catch(err => {
94
- const data = (err && err.response) ? err.response : err;
95
- if (data && data.status === 404) {
96
- com.handleNotFound(com.form);
97
- } else {
98
- error(err, com.resourceService.value, com.showError);
99
- }
100
- com.running = false;
101
- hideLoading(com.loading);
102
- });
103
- }
104
- }
105
- handleNotFound(form?: HTMLFormElement): void {
106
- const msg = message(this.resourceService.value, 'error_not_found', 'error');
107
- if (form) {
108
- setReadOnly(form);
109
- }
110
- this.showError(msg.message, msg.title);
111
- }
112
- getModel(): T {
113
- return (this.state as any)[this.getModelName()];
114
- }
115
- showModel(model: T) {
116
- const modelName = this.getModelName();
117
- const objSet: any = {};
118
- objSet[modelName] = model;
119
- this.setState(objSet);
120
- }
121
- }
122
-
123
- export class BaseComponent<P, S> extends React.Component<P, S> {
124
- constructor(props: P,
125
- public getLocale?: () => Locale,
126
- private removeErr?: (ctrl: HTMLInputElement) => void) {
127
- super(props);
128
- this.getModelName = this.getModelName.bind(this);
129
- this.updateState = this.updateState.bind(this);
130
- this.updateFlatState = this.updateFlatState.bind(this);
131
- this.updatePhoneState = this.updatePhoneState.bind(this);
132
- this.updateDateState = this.updateDateState.bind(this);
133
- this.prepareCustomData = this.prepareCustomData.bind(this);
134
- }
135
- running?: boolean;
136
- form?: HTMLFormElement|null;
137
- /*
138
- protected handleSubmitForm(e) {
139
- if (e.which === 13) {
140
- if (document.getElementById('sysAlert').style.display !== 'none') {
141
- document.getElementById('sysYes').click();
142
- } else {
143
- document.getElementById('btnSave').click();
144
- }
145
- } else if (e.which === 27) {
146
- document.getElementById('sysNo').click();
147
- }
148
- }
149
- */
150
-
151
- prepareCustomData(data: any) { }
152
-
153
- updatePhoneState = (event: any) => {
154
- const re = /^[0-9\b]+$/;
155
- const target = event.currentTarget as HTMLInputElement;
156
- const value = removePhoneFormat(target.value);
157
- if (re.test(value) || !value) {
158
- this.updateState(event);
159
- } else {
160
- const splitArr = value.split('');
161
- let responseStr = '';
162
- splitArr.forEach(element => {
163
- if (re.test(element)) {
164
- responseStr += element;
165
- }
166
- });
167
- target.value = responseStr;
168
- this.updateState(event);
169
- }
170
- }
171
-
172
- updateDateState = (name: string, value: any) => {
173
- const props: any = this.props;
174
- const modelName = this.getModelName(this.form);
175
- const state = (this.state as any)[modelName];
176
- if (props.setGlobalState) {
177
- const data = props.shouldBeCustomized ? this.prepareCustomData({ [name]: value }) : { [name]: value };
178
- props.setGlobalState({ [modelName]: { ...state, ...data } });
179
- } else {
180
- const objSet: any = {[modelName]: {...state, [name]: value}};
181
- this.setState(objSet);
182
- }
183
- }
184
- getModelName(f?: HTMLFormElement|null): string {
185
- let f2 = f;
186
- if (!f2) {
187
- f2 = this.form;
188
- }
189
- if (f2) {
190
- const a = getModelName2(f2);
191
- if (a && a.length > 0) {
192
- return a;
193
- }
194
- }
195
- return 'model';
196
- }
197
- updateState = (e: any, callback?: () => void, lc?: Locale) => {
198
- const ctrl = e.currentTarget as HTMLInputElement;
199
- const modelName = this.getModelName(ctrl.form);
200
- const l = localeOf(lc, this.getLocale);
201
- const props = this.props;
202
- handleEvent(e, this.removeErr);
203
- if ((props as any).setGlobalState) {
204
- handleProps(e, props as any, ctrl, modelName, l, this.prepareCustomData);
205
- } else {
206
- const objSet: any = buildState(e, this.state, ctrl, modelName, l);
207
- if (objSet) {
208
- if (callback) {
209
- this.setState(objSet, callback);
210
- } else {
211
- this.setState(objSet);
212
- }
213
- }
214
- }
215
- }
216
- updateFlatState(e: any, callback?: () => void, lc?: Locale) {
217
- const l = localeOf(lc, this.getLocale);
218
- const objSet: any = buildFlatState(e, this.state, l);
219
- if (objSet != null) {
220
- if (callback) {
221
- this.setState(objSet, callback);
222
- } else {
223
- this.setState(objSet);
224
- }
225
- }
226
- }
227
- }
228
- export interface MessageOnlyState {
229
- message?: string;
230
- }
231
- export class MessageComponent<S extends MessageOnlyState, P> extends BaseComponent<P, S> {
232
- constructor(props: P,
233
- getLocale?: () => Locale,
234
- removeErr?: (ctrl: HTMLInputElement) => void) {
235
- super(props, getLocale, removeErr);
236
- this.getModelName = this.getModelName.bind(this);
237
- this.showMessage = this.showMessage.bind(this);
238
- this.showError = this.showError.bind(this);
239
- this.hideMessage = this.hideMessage.bind(this);
240
- this.ref = React.createRef();
241
- }
242
- ref: any;
243
- name?: string;
244
- alertClass = '';
245
- getModelName(f?: HTMLFormElement|null): string {
246
- if (this.name && this.name.length > 0) {
247
- return this.name;
248
- }
249
- let f2 = f;
250
- if (!f2) {
251
- f2 = this.form;
252
- }
253
- if (f2) {
254
- const a = getModelName2(f2);
255
- if (a && a.length > 0) {
256
- return a;
257
- }
258
- }
259
- return 'model';
260
- }
261
- showMessage = (msg: string) => {
262
- this.alertClass = 'alert alert-info';
263
- this.setState({ message: msg });
264
- }
265
- showError = (msg: string|ErrorMessage[]) => {
266
- this.alertClass = 'alert alert-error';
267
- if (typeof msg === 'string') {
268
- this.setState({ message: msg });
269
- } else if (Array.isArray(msg) && msg.length > 0) {
270
- this.setState({ message: msg[0].message });
271
- } else {
272
- const x = JSON.stringify(msg);
273
- this.setState({ message: x });
274
- }
275
- }
276
- hideMessage = () => {
277
- this.alertClass = '';
278
- this.setState({ message: '' });
279
- }
280
- }
281
- export class BaseSearchComponent<T, F extends Filter, P, I extends SearchState<T, F>> extends BaseComponent<P, I> implements Searchable {
282
- constructor(props: P,
283
- protected resourceService: ResourceService,
284
- protected showMessage: (msg: string) => void,
285
- getLocale?: () => Locale,
286
- protected ui?: UIService,
287
- protected loading?: LoadingService,
288
- protected listFormId?: string) {
289
- super(props, getLocale, (ui ? ui.removeError : undefined));
290
- this.resource = resourceService.resource();
291
- this.hideFilter = true;
292
- this.getModelName = this.getModelName.bind(this);
293
- this.showMessage = this.showMessage.bind(this);
294
-
295
- this.toggleFilter = this.toggleFilter.bind(this);
296
- this.load = this.load.bind(this);
297
- this.getSearchForm = this.getSearchForm.bind(this);
298
- this.setSearchForm = this.setSearchForm.bind(this);
299
-
300
- this.setFilter = this.setFilter.bind(this);
301
- this.getFilter = this.getFilter.bind(this);
302
- this.getFields = this.getFields.bind(this);
303
-
304
- this.pageSizeChanged = this.pageSizeChanged.bind(this);
305
- this.clearQ = this.clearQ.bind(this);
306
- this.search = this.search.bind(this);
307
-
308
- this.resetAndSearch = this.resetAndSearch.bind(this);
309
- this.doSearch = this.doSearch.bind(this);
310
- this.call = this.call.bind(this);
311
- this.validateSearch = this.validateSearch.bind(this);
312
- this.showResults = this.showResults.bind(this);
313
- this.setList = this.setList.bind(this);
314
- this.getList = this.getList.bind(this);
315
- this.sort = this.sort.bind(this);
316
- this.showMore = this.showMore.bind(this);
317
- this.pageChanged = this.pageChanged.bind(this);
318
-
319
- const currentUrl = window.location.host + window.location.pathname;
320
- this.url = removeUrlParams(currentUrl);
321
- /*
322
- this.locationSearch = '';
323
- const location = (props.location ? props.location : props['props'].location);
324
- if (location && location.search) {
325
- this.locationSearch = location.search;
326
- }
327
- */
328
- }
329
- resource: StringMap;
330
- url: string;
331
-
332
- filter?: F;
333
- // Pagination
334
- initPageSize = 24;
335
- pageSize = 24;
336
- pageIndex?: number = 1;
337
- nextPageToken?: string;
338
- total = 0;
339
- pages = 0;
340
- showPaging?: boolean;
341
- append?: boolean;
342
- appendMode?: boolean;
343
- appendable?: boolean;
344
-
345
- // Sortable
346
- sortField?: string;
347
- sortType?: string;
348
- sortTarget?: HTMLElement;
349
-
350
- keys?: string[];
351
- format?: (obj: T, locale?: Locale) => T;
352
- fields?: string[];
353
- initFields?: boolean;
354
- sequenceNo = 'sequenceNo';
355
- triggerSearch?: boolean;
356
- tmpPageIndex?: number = 1;
357
-
358
- pageMaxSize = 7;
359
- pageSizes: number[] = pageSizes;
360
-
361
- list?: T[];
362
- excluding?: string[]|number[];
363
- hideFilter?: boolean;
364
-
365
- ignoreUrlParam?: boolean;
366
- // locationSearch: string;
367
- // _currentSortField: string;
368
-
369
- // viewable?: boolean = true;
370
- // addable?: boolean = true;
371
- // editable?: boolean = true;
372
- // approvable?: boolean;
373
- // deletable?: boolean;
374
-
375
- getModelName(): string {
376
- return 'filter';
377
- }
378
-
379
- toggleFilter(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
380
- const x = !this.hideFilter;
381
- handleToggle(event.target as HTMLInputElement, !x);
382
- this.hideFilter = x;
383
- }
384
- load(s: F, autoSearch: boolean): void {
385
- const obj2 = initFilter(s, this);
386
- this.setFilter(obj2);
387
- const com = this;
388
- if (autoSearch) {
389
- setTimeout(() => {
390
- com.doSearch(true);
391
- }, 0);
392
- }
393
- }
394
-
395
- setSearchForm(form: HTMLFormElement): void {
396
- this.form = form;
397
- }
398
-
399
- getSearchForm(): HTMLFormElement|undefined|null {
400
- if (!this.form && this.listFormId) {
401
- this.form = document.getElementById(this.listFormId) as HTMLFormElement;
402
- }
403
- return this.form;
404
- }
405
- setFilter(filter: F): void {
406
- const modelName = this.getModelName();
407
- const objSet: any = {};
408
- objSet[modelName] = filter;
409
- this.setState(objSet);
410
- }
411
- getCurrencyCode(): string|undefined {
412
- return getCurrencyCode(this.form);
413
- }
414
- getFilter(): F {
415
- const name = this.getModelName();
416
- let lc: Locale|undefined;
417
- if (this.getLocale) {
418
- lc = this.getLocale();
419
- }
420
- if (!lc) {
421
- lc = enLocale;
422
- }
423
- const fields = this.getFields();
424
- const obj3 = getModel<F>(this.state, name, this, fields, this.excluding);
425
- return obj3;
426
- }
427
- getFields(): string[]|undefined {
428
- const fs = getFieldsFromForm(this.fields, this.initFields, this.form);
429
- this.initFields = true;
430
- return fs;
431
- }
432
- /*
433
- protected pagingOnClick = (size, e) => {
434
- this.setState(prevState => ({ isPageSizeOpenDropDown: !(prevState as any).isPageSizeOpenDropDown } as any));
435
- this.pageSizeChanged(size);
436
- }
437
- */
438
- pageSizeOnClick = () => {
439
- this.setState(prevState => ({ isPageSizeOpenDropDown: !(prevState as any).isPageSizeOpenDropDown } as any));
440
- }
441
-
442
- clearQ(e?: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
443
- if (e) {
444
- e.preventDefault();
445
- }
446
- const n = this.getModelName();
447
- if (n && n.length > 0) {
448
- const m = (this.state as any)[n];
449
- if (m) {
450
- m.q = '';
451
- const setObj: any = {};
452
- setObj[n] = m;
453
- this.setState(setObj);
454
- return;
455
- }
456
- }
457
- }
458
- search(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
459
- if (event) {
460
- event.preventDefault();
461
- if (!this.getSearchForm()) {
462
- const f = (event.target as HTMLInputElement).form;
463
- if (f) {
464
- this.setSearchForm(f);
465
- }
466
- }
467
- }
468
- this.resetAndSearch();
469
- }
470
-
471
- resetAndSearch(): void {
472
- this.pageIndex = 1;
473
- if (this.running === true) {
474
- this.triggerSearch = true;
475
- return;
476
- }
477
- reset(this);
478
- this.tmpPageIndex = 1;
479
- this.doSearch();
480
- }
481
-
482
- doSearch(isFirstLoad?: boolean): void {
483
- const listForm = this.getSearchForm();
484
- if (listForm && this.ui) {
485
- this.ui.removeFormError(listForm);
486
- }
487
- const s = this.getFilter();
488
- const com = this;
489
- this.validateSearch(s, () => {
490
- if (com.running === true) {
491
- return;
492
- }
493
- com.running = true;
494
- showLoading(this.loading);
495
- if (!this.ignoreUrlParam) {
496
- addParametersIntoUrl(s, isFirstLoad);
497
- }
498
- com.call(s);
499
- });
500
- }
501
-
502
- call(s: F): void {
503
-
504
- }
505
-
506
- validateSearch(se: F, callback: () => void): void {
507
- const u = this.ui;
508
- const vl = (u ? u.validateForm : undefined);
509
- validate(se, callback, this.getSearchForm(), localeOf(undefined, this.getLocale), vl);
510
- }
511
- showResults(s: F, sr: SearchResult<T>) {
512
- const com = this;
513
- const results = sr.list;
514
- if (results && results.length > 0) {
515
- const lc = localeOf(undefined, this.getLocale);
516
- // formatResultsByComponent(results, com, lc);
517
- formatResults(results, com.pageIndex, com.pageSize, com.pageSize, com.sequenceNo, com.format, lc);
518
- }
519
- const am = com.appendMode;
520
- com.pageIndex = (s.page && s.page >= 1 ? s.page : 1);
521
- if (sr.total) {
522
- com.total = sr.total;
523
- }
524
- if (am) {
525
- let limit = s.limit;
526
- if ((!s.page || s.page <= 1) && s.firstLimit && s.firstLimit > 0) {
527
- limit = s.firstLimit;
528
- }
529
- com.nextPageToken = sr.next;
530
- handleAppend(com, sr.list, limit, sr.next);
531
- if (com.append && (s.page && s.page > 1)) {
532
- com.appendList(results);
533
- } else {
534
- com.setList(results);
535
- }
536
- } else {
537
- showPaging(com, sr.list, s.limit, sr.total);
538
- com.setList(results);
539
- com.tmpPageIndex = s.page;
540
- if (s.limit) {
541
- this.showMessage(buildMessage(this.resourceService, s.page, s.limit, sr.list, sr.total));
542
- }
543
- }
544
- com.running = undefined;
545
- hideLoading(com.loading);
546
- if (com.triggerSearch) {
547
- com.triggerSearch = undefined;
548
- com.resetAndSearch();
549
- }
550
- }
551
-
552
- appendList(results: T[]) {
553
- const list = this.state.list;
554
- const arr = append(list, results);
555
-
556
- const listForm = this.getSearchForm();
557
- const props: any = this.props;
558
- const setGlobalState = props.props.setGlobalState;
559
- if (setGlobalState && listForm) {
560
- setGlobalState({ [listForm.name]: arr });
561
- } else {
562
- this.setState({ list: arr });
563
- }
564
- }
565
-
566
- setList(list: T[]) {
567
- const props: any = this.props;
568
- const setGlobalState = props.props.setGlobalState;
569
- this.list = list;
570
- const listForm = this.getSearchForm();
571
- if (setGlobalState && listForm) {
572
- setGlobalState({ [listForm.name]: list });
573
- } else {
574
- this.setState({ list });
575
- }
576
- }
577
-
578
- getList(): T[]|undefined {
579
- return this.list;
580
- }
581
-
582
- sort(event: any) {
583
- event.preventDefault();
584
- handleSortEvent(event, this);
585
- if (!this.appendMode) {
586
- this.doSearch();
587
- } else {
588
- this.resetAndSearch();
589
- }
590
- }
591
- showMore(event: any) {
592
- event.preventDefault();
593
- this.tmpPageIndex = this.pageIndex;
594
- more(this);
595
- this.doSearch();
596
- }
597
- pageSizeChanged = (event: any) => {
598
- const size = parseInt((event.currentTarget as HTMLInputElement).value, 10);
599
- changePageSize(this, size);
600
- this.tmpPageIndex = 1;
601
- this.doSearch();
602
- }
603
-
604
- pageChanged(data: PageChange) {
605
- const { page, size } = data;
606
- changePage(this, page, size);
607
- this.doSearch();
608
- }
609
- }
610
- export class SearchComponent<T, S extends Filter, P, I extends SearchState<T, S>> extends BaseSearchComponent<T, S, P, I> {
611
- constructor(props: P, sv: ((s: S, ctx?: any) => Promise<SearchResult<T>>) | SearchService<T, S>,
612
- param: ResourceService|SearchParameter,
613
- showMessage?: (msg: string, option?: string) => void,
614
- showError?: (m: string, header?: string, detail?: string, callback?: () => void) => void,
615
- getLocale?: (profile?: string) => Locale,
616
- uis?: UIService,
617
- loading?: LoadingService,
618
- listFormId?: string) {
619
- super(props, getResource(param), getMsgFunc(param, showMessage), getLocaleFunc(param, getLocale), getUIService(param, uis), getLoadingFunc(param, loading), listFormId);
620
- this.autoSearch = getAutoSearch(param);
621
- if (sv) {
622
- if (typeof sv === 'function') {
623
- const x: any = sv;
624
- this.service = x;
625
- } else {
626
- this.service = sv.search;
627
- if (sv.keys) {
628
- this.keys = sv.keys();
629
- }
630
- }
631
- }
632
- this.call = this.call.bind(this);
633
- this.showError = getErrorFunc(param, showError);
634
- this.componentDidMount = this.componentDidMount.bind(this);
635
- this.mergeFilter = this.mergeFilter.bind(this);
636
- this.createFilter = this.createFilter.bind(this);
637
- this.ref = React.createRef();
638
- }
639
- protected showError: (m: string, header?: string, detail?: string, callback?: () => void) => void;
640
- protected service?: (s: S, limit?: number, offset?: number|string, fields?: string[]) => Promise<SearchResult<T>>;
641
- // protected service: SearchService<T, S>;
642
- protected ref: any;
643
- protected autoSearch: boolean;
644
- componentDidMount() {
645
- const k = (this.ui ? this.ui.registerEvents : undefined);
646
- this.form = initForm(this.ref.current, k);
647
- const s = this.mergeFilter(buildFromUrl<S>(), this.createFilter());
648
- this.load(s, this.autoSearch);
649
- }
650
- mergeFilter(obj: S, b?: S, arrs?: string[]|any): S {
651
- return mergeFilter2<S>(obj, b, this.pageSizes, arrs);
652
- }
653
- createFilter(): S {
654
- const s: any = {};
655
- return s;
656
- }
657
- call(se: S) {
658
- this.running = true;
659
- const s = clone(se);
660
- let page = this.pageIndex;
661
- if (!page || page < 1) {
662
- page = 1;
663
- }
664
- let offset: number|undefined;
665
- if (se.limit) {
666
- if (se.firstLimit && se.firstLimit > 0) {
667
- offset = se.limit * (page - 2) + se.firstLimit;
668
- } else {
669
- offset = se.limit * (page - 1);
670
- }
671
- }
672
- const limit = (page <= 1 && se.firstLimit && se.firstLimit > 0 ? se.firstLimit : se.limit);
673
- const next = (this.nextPageToken && this.nextPageToken.length > 0 ? this.nextPageToken : offset);
674
- const fields = se.fields;
675
- delete se['page'];
676
- delete se['fields'];
677
- delete se['limit'];
678
- delete se['firstLimit'];
679
- showLoading(this.loading);
680
- const com = this;
681
- if (this.service) {
682
- this.service(s, limit, next, fields).then(sr => {
683
- com.showResults(s, sr);
684
- com.running = undefined;
685
- hideLoading(com.loading);
686
- }).catch(err => {
687
- com.pageIndex = com.tmpPageIndex;
688
- error(err, com.resourceService.value, com.showError);
689
- com.running = undefined;
690
- hideLoading(com.loading);
691
- });
692
- }
693
- }
694
- }
695
-
696
- export abstract class BaseEditComponent<T, P, S> extends BaseComponent<P, S> {
697
- constructor(props: P,
698
- protected resourceService: ResourceService,
699
- protected showMessage: (msg: string) => void,
700
- protected showError: (m: string, title?: string, detail?: string, callback?: () => void) => void,
701
- protected confirm: (m2: string, header: string, yesCallback?: () => void, btnLeftText?: string, btnRightText?: string, noCallback?: () => void) => void,
702
- getLocale?: () => Locale,
703
- protected ui?: UIService,
704
- protected loading?: LoadingService,
705
- // status?: EditStatusConfig,
706
- patchable?: boolean, backOnSaveSuccess?: boolean) {
707
- super(props, getLocale, (ui ? ui.removeError : undefined));
708
- this.resource = resourceService.resource();
709
- // this.status = createEditStatus(status);
710
- if (patchable === false) {
711
- this.patchable = patchable;
712
- }
713
- if (backOnSaveSuccess === false) {
714
- this.backOnSuccess = backOnSaveSuccess;
715
- }
716
- this.insertSuccessMsg = resourceService.value('msg_save_success');
717
- this.updateSuccessMsg = resourceService.value('msg_save_success');
718
-
719
- this.showMessage = this.showMessage.bind(this);
720
- this.showError = this.showError.bind(this);
721
- this.confirm = this.confirm.bind(this);
722
-
723
- this.back = this.back.bind(this);
724
- this.getModelName = this.getModelName.bind(this);
725
-
726
- this.resetState = this.resetState.bind(this);
727
- this.handleNotFound = this.handleNotFound.bind(this);
728
- this.showModel = this.showModel.bind(this);
729
- this.getModel = this.getModel.bind(this);
730
- this.createModel = this.createModel.bind(this);
731
-
732
- this.create = this.create.bind(this);
733
- this.save = this.save.bind(this);
734
- this.onSave = this.onSave.bind(this);
735
- this.validate = this.validate.bind(this);
736
- this.doSave = this.doSave.bind(this);
737
- this.succeed = this.succeed.bind(this);
738
- this.fail = this.fail.bind(this);
739
- this.postSave = this.postSave.bind(this);
740
- this.handleDuplicateKey = this.handleDuplicateKey.bind(this);
741
- }
742
- // status: EditStatusConfig;
743
- protected name?: string;
744
- protected backOnSuccess = true;
745
- protected resource: StringMap;
746
- protected metadata?: Attributes;
747
- protected keys?: string[];
748
- protected version?: string;
749
- protected newMode?: boolean;
750
- protected setBack?: boolean;
751
- protected patchable = true;
752
- protected orginalModel?: T;
753
-
754
- // addable?: boolean = true;
755
- readOnly?: boolean;
756
- // deletable?: boolean;
757
-
758
- insertSuccessMsg: string;
759
- updateSuccessMsg: string;
760
- back(event: any) {
761
- if (event) {
762
- event.preventDefault();
763
- }
764
- }
765
- resetState(newMod: boolean, model: T, originalModel?: T) {
766
- this.newMode = newMod;
767
- this.orginalModel = originalModel;
768
- this.showModel(model);
769
- }
770
- handleNotFound(form?: HTMLFormElement|null): void {
771
- const msg = message(this.resourceService.value, 'error_not_found', 'error');
772
- if (form) {
773
- setReadOnly(form);
774
- }
775
- this.showError(msg.message, msg.title);
776
- }
777
- getModelName(f?: HTMLFormElement): string {
778
- if (this.name && this.name.length > 0) {
779
- return this.name;
780
- }
781
- return super.getModelName(f);
782
- }
783
- getModel(): T {
784
- const n = this.getModelName();
785
- return (this.props as any)[n] || (this.state as any)[n];
786
- }
787
- showModel(model: T) {
788
- const f = this.form;
789
- const modelName = this.getModelName();
790
- const objSet: any = {};
791
- objSet[modelName] = model;
792
- this.setState(objSet, () => {
793
- if (this.readOnly) {
794
- setReadOnly(f);
795
- }
796
- });
797
- }
798
-
799
- // end of: can be in ViewComponent
800
- createModel(): T {
801
- if (this.metadata) {
802
- const obj = createModel2<T>(this.metadata);
803
- return obj;
804
- } else {
805
- const obj: any = {};
806
- return obj;
807
- }
808
- }
809
-
810
- create = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
811
- if (event) {
812
- event.preventDefault();
813
- }
814
- if (!this.form && event && event.target && (event.target as HTMLInputElement).form) {
815
- this.form = (event.target as HTMLInputElement).form;
816
- }
817
- const obj = this.createModel();
818
- this.resetState(true, obj, undefined);
819
- const u = this.ui;
820
- const f = this.form;
821
- if (u && f) {
822
- setTimeout(() => {
823
- u.removeFormError(f);
824
- }, 100);
825
- }
826
- }
827
- save = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
828
- event.preventDefault();
829
- event.persist();
830
- if (!this.form && event && event.target) {
831
- this.form = (event.target as HTMLInputElement).form;
832
- }
833
- this.onSave(this.backOnSuccess);
834
- }
835
- onSave(isBack?: boolean) {
836
- const r = this.resourceService;
837
- if (this.running) {
838
- return;
839
- }
840
- const com = this;
841
- const obj = com.getModel();
842
- if (this.newMode) {
843
- com.validate(obj, () => {
844
- const msg = message(r.value, 'msg_confirm_save', 'confirm', 'yes', 'no');
845
- this.confirm(msg.message, msg.title, () => {
846
- com.doSave(obj, obj, isBack);
847
- }, msg.no, msg.yes);
848
- });
849
- } else {
850
- const diffObj = makeDiff(initPropertyNullInModel(this.orginalModel, this.metadata), obj, this.keys, this.version);
851
- const keys = Object.keys(diffObj as any);
852
- if (keys.length === 0) {
853
- this.showMessage(r.value('msg_no_change'));
854
- } else {
855
- com.validate(obj, () => {
856
- const msg = message(r.value, 'msg_confirm_save', 'confirm', 'yes', 'no');
857
- this.confirm(msg.message, msg.title, () => {
858
- com.doSave(obj, diffObj, isBack);
859
- }, msg.no, msg.yes);
860
- });
861
- }
862
- }
863
- }
864
- validate(obj: T, callback: (obj2?: T) => void) {
865
- if (this.ui && this.form) {
866
- const valid = this.ui.validateForm(this.form, localeOf(undefined, this.getLocale));
867
- if (valid) {
868
- callback(obj);
869
- }
870
- } else {
871
- callback(obj);
872
- }
873
- }
874
-
875
- doSave(obj: T, dif?: Partial<T>, isBack?: boolean) {
876
- }
877
-
878
- succeed(msg: string, origin: T, isBack?: boolean, model?: T) {
879
- if (model) {
880
- this.newMode = false;
881
- if (model && this.setBack) {
882
- this.resetState(false, model, clone(model));
883
- } else {
884
- handleVersion(origin, this.version);
885
- }
886
- } else {
887
- handleVersion(origin, this.version);
888
- }
889
- const isBackO = (isBack == null || isBack === undefined ? this.backOnSuccess : isBack);
890
- this.showMessage(msg);
891
- if (isBackO) {
892
- this.back(null);
893
- }
894
- }
895
- fail(result: ErrorMessage[]) {
896
- const f = this.form;
897
- const u = this.ui;
898
- if (u && f) {
899
- const unmappedErrors = u.showFormError(f, result);
900
- focusFirstError(f);
901
- if (unmappedErrors && unmappedErrors.length > 0) {
902
- const t = this.resourceService.value('error');
903
- if (u && u.buildErrorMessage) {
904
- const msg = u.buildErrorMessage(unmappedErrors);
905
- this.showError(msg, t);
906
- } else {
907
- this.showError(unmappedErrors[0].field + ' ' + unmappedErrors[0].code + ' ' + unmappedErrors[0].message, t);
908
- }
909
- }
910
- } else {
911
- const t = this.resourceService.value('error');
912
- if (result.length > 0) {
913
- this.showError(result[0].field + ' ' + result[0].code + ' ' + result[0].message, t);
914
- } else {
915
- this.showError(t, t);
916
- }
917
- }
918
- }
919
-
920
- postSave(res: number|string|T|ErrorMessage[], origin: T, isPatch: boolean, backOnSave?: boolean) {
921
- this.running = false;
922
- hideLoading(this.loading);
923
- // const st = this.status;
924
- const newMod = this.newMode;
925
- const successMsg = (newMod ? this.insertSuccessMsg : this.updateSuccessMsg);
926
- const x: any = res;
927
- const r = this.resourceService;
928
- if (Array.isArray(x)) {
929
- this.fail(x);
930
- } else if (!isNaN(x)) {
931
- if (x > 0) {
932
- this.succeed(successMsg, origin, backOnSave);
933
- } else {
934
- if (newMod && x <= 0) {
935
- this.handleDuplicateKey();
936
- } else if (!newMod && x === 0) {
937
- this.handleNotFound();
938
- } else {
939
- this.showError(r.value('error_version'), r.value('error'));
940
- }
941
- }
942
- } else {
943
- const result: T = x;
944
- if (isPatch) {
945
- const keys = Object.keys(result as any);
946
- const a: any = origin;
947
- for (const k of keys) {
948
- a[k] = (result as any)[k];
949
- }
950
- this.succeed(successMsg, a, backOnSave);
951
- } else {
952
- this.succeed(successMsg, origin, backOnSave, result);
953
- }
954
- this.showMessage(successMsg);
955
- }
956
- }
957
- handleDuplicateKey(result?: T) {
958
- const msg = message(this.resourceService.value, 'error_duplicate_key', 'error');
959
- this.showError(msg.message, msg.title);
960
- }
961
- }
962
- export class EditComponent<T, ID, P, S> extends BaseEditComponent<T, P, S> {
963
- constructor(props: P, protected service: GenericService<T, ID, number|T|ErrorMessage[]>,
964
- param: ResourceService|EditParameter,
965
- showMessage?: (msg: string, option?: string) => void,
966
- showError?: (m: string, title?: string, detail?: string, callback?: () => void) => void,
967
- confirm?: (m2: string, header: string, yesCallback?: () => void, btnLeftText?: string, btnRightText?: string, noCallback?: () => void) => void,
968
- getLocale?: (profile?: string) => Locale,
969
- uis?: UIService,
970
- loading?: LoadingService, patchable?: boolean, backOnSaveSuccess?: boolean) {
971
- super(props, getResource(param), getMsgFunc(param, showMessage), getErrorFunc(param, showError), getConfirmFunc(param, confirm), getLocaleFunc(param, getLocale), getUIService(param, uis), getLoadingFunc(param, loading), patchable, backOnSaveSuccess);
972
- if (service.metadata) {
973
- const metadata = service.metadata();
974
- if (metadata) {
975
- const meta = build(metadata);
976
- if (meta) {
977
- this.keys = meta.keys;
978
- this.version = meta.version;
979
- }
980
- this.metadata = metadata;
981
- }
982
- }
983
- if (!this.keys && service.keys) {
984
- const k = service.keys();
985
- if (k) {
986
- this.keys = k;
987
- }
988
- }
989
- if (!this.keys) {
990
- this.keys = [];
991
- }
992
- this.load = this.load.bind(this);
993
- this.doSave = this.doSave.bind(this);
994
- this.ref = React.createRef();
995
- }
996
- ref: any;
997
- load(_id: ID|null, callback?: (m: T, showM: (m2: T) => void) => void) {
998
- const id: any = _id;
999
- if (id != null && id !== '') {
1000
- const com = this;
1001
- this.running = true;
1002
- showLoading(com.loading);
1003
- this.service.load(id).then(obj => {
1004
- if (!obj) {
1005
- com.handleNotFound(this.form);
1006
- } else {
1007
- com.newMode = false;
1008
- com.orginalModel = clone(obj);
1009
- if (!callback) {
1010
- com.showModel(obj);
1011
- } else {
1012
- callback(obj, com.showModel);
1013
- }
1014
- }
1015
- com.running = false;
1016
- hideLoading(com.loading);
1017
- }).catch(err => {
1018
- const data = (err && err.response) ? err.response : err;
1019
- const r = com.resourceService;
1020
- const gv = r.value;
1021
- const title = gv('error');
1022
- let msg = gv('error_internal');
1023
- if (data && data.status === 404) {
1024
- com.handleNotFound(com.form);
1025
- } else {
1026
- if (data.status && !isNaN(data.status)) {
1027
- msg = messageByHttpStatus(data.status, gv);
1028
- }
1029
- if (data && (data.status === 401 || data.status === 403)) {
1030
- setReadOnly(com.form);
1031
- }
1032
- com.showError(msg, title);
1033
- }
1034
- com.running = false;
1035
- hideLoading(com.loading);
1036
- });
1037
- } else {
1038
- // Call service state
1039
- this.newMode = true;
1040
- this.orginalModel = undefined;
1041
- const obj = this.createModel();
1042
- if (callback) {
1043
- callback(obj, this.showModel);
1044
- } else {
1045
- this.showModel(obj);
1046
- }
1047
- }
1048
- }
1049
- doSave(obj: T, body?: Partial<T>, isBack?: boolean) {
1050
- this.running = true;
1051
- showLoading(this.loading);
1052
- const isBackO = (isBack == null || isBack === undefined ? this.backOnSuccess : isBack);
1053
- const com = this;
1054
- let m: T|Partial<T> = obj;
1055
- let fn = this.newMode ? this.service.insert : this.service.update;
1056
- if (!this.newMode) {
1057
- if (this.patchable === true && this.service.patch && body && Object.keys(body).length > 0) {
1058
- m = body;
1059
- fn = this.service.patch;
1060
- }
1061
- }
1062
- fn(m as any).then(result => {
1063
- com.postSave(result, obj, isBackO);
1064
- com.running = false;
1065
- hideLoading(com.loading);
1066
- }).then(err => {
1067
- error(err, com.resourceService.value, com.showError);
1068
- com.running = false;
1069
- hideLoading(com.loading);
1070
- });
1071
- }
1072
- }
1073
-
1074
- export class BaseDiffApprComponent<T, ID, P, S extends BaseDiffState> extends React.Component<P, S & any> {
1075
- constructor(props: P, protected keys: string[], protected resourceService: ResourceService,
1076
- protected showMessage: (msg: string, option?: string) => void,
1077
- protected showError: (m: string, title?: string, detail?: string, callback?: () => void) => void,
1078
- protected loading?: LoadingService,
1079
- // status?: DiffStatusConfig,
1080
- ) {
1081
- super(props);
1082
- // this._id = props['props'].match.params.id || props['props'].match.params.cId || props.match.params.cId;
1083
- // this.callBackAfterUpdate = this.callBackAfterUpdate.bind(this);
1084
- this.resource = resourceService.resource();
1085
- this.showMessage = this.showMessage.bind(this);
1086
- this.showError = this.showError.bind(this);
1087
- this.initModel = this.initModel.bind(this);
1088
- this.postApprove = this.postApprove.bind(this);
1089
- this.postReject = this.postReject.bind(this);
1090
- this.format = this.format.bind(this);
1091
- this.handleNotFound = this.handleNotFound.bind(this);
1092
- // this.status = createDiffStatus(status);
1093
- this.state = {
1094
- disabled: false
1095
- };
1096
- }
1097
- // status: DiffStatusConfig;
1098
- id?: ID;
1099
- form?: HTMLFormElement;
1100
- running?: boolean;
1101
- resource: StringMap;
1102
-
1103
- initModel(): T {
1104
- const x: any = {};
1105
- return x;
1106
- }
1107
-
1108
- postApprove(s: number|string, err?: any) {
1109
- this.setState({ disabled: true });
1110
- const r = this.resourceService;
1111
- // const st = this.status;
1112
- if (s > 0) {
1113
- this.showMessage(r.value('msg_approve_success'));
1114
- } else if (s === 0) {
1115
- this.handleNotFound();
1116
- } else {
1117
- const msg = message(r.value, 'msg_approve_version_error', 'error');
1118
- this.showError(msg.message, msg.title);
1119
- }
1120
- }
1121
-
1122
- postReject(status: number|string, err?: any) {
1123
- this.setState({ disabled: true });
1124
- const r = this.resourceService;
1125
- // const st = this.status;
1126
- if (status > 0) {
1127
- this.showMessage(r.value('msg_reject_success'));
1128
- } else if (status === 0) {
1129
- this.handleNotFound();
1130
- } else {
1131
- const msg = message(r.value, 'msg_approve_version_error', 'error');
1132
- this.showError(msg.message, msg.title);
1133
- }
1134
- }
1135
-
1136
- format() {
1137
- const p = this.props as any;
1138
- const diffModel = p['diffModel'];
1139
- if (diffModel) {
1140
- const differentKeys = diff(diffModel.origin, diffModel.value);
1141
- const dataFields = getDataFields(this.form);
1142
- dataFields.forEach(e => {
1143
- const x = e.getAttribute('data-field');
1144
- if (x) {
1145
- if (differentKeys.indexOf(x) >= 0) {
1146
- if (e.childNodes.length === 3) {
1147
- (e.childNodes[1] as HTMLElement).classList.add('highlight');
1148
- (e.childNodes[2] as HTMLElement).classList.add('highlight');
1149
- } else {
1150
- e.classList.add('highlight');
1151
- }
1152
- }
1153
- }
1154
- });
1155
- } else {
1156
- const { origin, value } = this.state;
1157
- const differentKeys = diff(origin, value);
1158
- const dataFields = getDataFields(this.form);
1159
- dataFields.forEach(e => {
1160
- const x = e.getAttribute('data-field');
1161
- if (x) {
1162
- if (differentKeys.indexOf(x) >= 0) {
1163
- if (e.childNodes.length === 3) {
1164
- (e.childNodes[1] as HTMLElement).classList.add('highlight');
1165
- (e.childNodes[2] as HTMLElement).classList.add('highlight');
1166
- } else {
1167
- e.classList.add('highlight');
1168
- }
1169
- }
1170
- }
1171
- });
1172
- }
1173
- }
1174
-
1175
- handleNotFound() {
1176
- this.setState({ disabled: true });
1177
- const msg = message(this.resourceService.value, 'error_not_found', 'error');
1178
- this.showError(msg.message, msg.title);
1179
- }
1180
- }
1181
- export class DiffApprComponent<T, ID, P, S extends DiffState<T>> extends BaseDiffApprComponent<T, ID, P, S> {
1182
- constructor(props: P, protected service: DiffApprService<T, ID>,
1183
- param: ResourceService|DiffParameter,
1184
- showMessage?: (msg: string, option?: string) => void,
1185
- showError?: (m: string, title?: string, detail?: string, callback?: () => void) => void,
1186
- loading?: LoadingService) {
1187
- super(props, service.keys(), getResource(param), getMsgFunc(param, showMessage), getErrorFunc(param, showError), getLoadingFunc(param, loading));
1188
- this.approve = this.approve.bind(this);
1189
- this.reject = this.reject.bind(this);
1190
- this.formatFields = this.formatFields.bind(this);
1191
- this.ref = React.createRef();
1192
- this.state = {
1193
- origin: this.initModel(),
1194
- value: this.initModel(),
1195
- disabled: false,
1196
- };
1197
- }
1198
- ref: any;
1199
-
1200
- formatFields(value: T): T {
1201
- return value;
1202
- }
1203
-
1204
- load(_id: ID) {
1205
- const id: any = _id;
1206
- if (id != null && id !== '') {
1207
- this.id = _id;
1208
- const com = this;
1209
- this.running = true;
1210
- showLoading(this.loading);
1211
- this.service.diff(id).then(dobj => {
1212
- if (!dobj) {
1213
- com.handleNotFound();
1214
- } else {
1215
- const formatdDiff = formatDiffModel(dobj, com.formatFields);
1216
- com.setState({
1217
- origin: formatdDiff.origin,
1218
- value: formatdDiff.value
1219
- }, com.format);
1220
- }
1221
- com.running = false;
1222
- hideLoading(com.loading);
1223
- }).catch(err => {
1224
- const data = (err && err.response) ? err.response : err;
1225
- if (data && data.status === 404) {
1226
- com.handleNotFound();
1227
- } else {
1228
- error(err, com.resourceService.value, com.showError);
1229
- }
1230
- com.running = false;
1231
- hideLoading(com.loading);
1232
- });
1233
- }
1234
- }
1235
-
1236
- approve(event: any) {
1237
- event.preventDefault();
1238
- const com = this;
1239
- this.running = true;
1240
- showLoading(this.loading);
1241
- if (this.id) {
1242
- this.service.approve(this.id).then(status => {
1243
- com.postApprove(status, null);
1244
- com.running = false;
1245
- hideLoading(com.loading);
1246
- }).catch(err => {
1247
- com.postApprove(4, err);
1248
- com.running = false;
1249
- hideLoading(com.loading);
1250
- });
1251
- }
1252
- }
1253
-
1254
- reject(event: any) {
1255
- event.preventDefault();
1256
- const com = this;
1257
- this.running = true;
1258
- showLoading(this.loading);
1259
- if (this.id) {
1260
- this.service.reject(this.id).then(status => {
1261
- com.postReject(status, null);
1262
- com.running = false;
1263
- hideLoading(com.loading);
1264
- }).catch(err => {
1265
- com.postReject(4, err);
1266
- com.running = false;
1267
- hideLoading(com.loading);
1268
- });
1269
- }
1270
- }
1271
- }
1272
- export function removeUrlParams(url: string): string {
1273
- const startParams = url.indexOf('?');
1274
- return startParams !== -1 ? url.substring(0, startParams) : url;
1275
- }