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