Skip to content

Commit 6f8626d

Browse files
committed
error-panel: Consume external and internal errorMap in error-panel
1 parent 6e84e4c commit 6f8626d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+727
-96
lines changed
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
{
22
"/abstracts/0/source": [
33
{
4-
"message": "Mock-Error 1: abstracts.0.source"
4+
"message": "Mock-Error 1: /abstracts/0/source",
5+
"type": "Error"
56
},
67
{
7-
"message": "Mock-Error 2: abstracts.0.source"
8+
"message": "Mock-Warning 1: /abstracts/0/source",
9+
"type": "Warning"
810
}
911
],
1012
"/abstracts/0/value": [
1113
{
12-
"message": "Mock-Error 1: abstracts.0.value"
14+
"message": "Mock-Error 1: /abstracts/0/value"
1315
}
1416
],
1517
"/field_categories/0/scheme": [
1618
{
17-
"message": "Mock-Error 1: field_categories.0.term"
19+
"message": "Mock-Error 1: /field_categories/0/term",
20+
"type": "Error"
1821
}
1922
],
2023
"/control_number": [
2124
{
22-
"message": "Mock-Error 1: control_number"
25+
"message": "Mock-Error 1: /control_number",
26+
"type": "Error"
2327
}
2428
]
2529
}

src/abstract-field/abstract-field.component.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
* waive the privileges and immunities granted to it by virtue of its status
2020
* as an Intergovernmental Organization or submit itself to any jurisdiction.
2121
*/
22-
import { OnInit, OnDestroy } from '@angular/core';
23-
24-
import { Subscription } from 'rxjs/Subscription';
22+
import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
2523

2624
import { AbstractTrackerComponent } from '../abstract-tracker';
2725

2826
import { AppGlobalsService, PathUtilService } from '../shared/services';
27+
import { ValidationError} from '../shared/interfaces';
28+
import { Subscription } from 'rxjs/Subscription';
2929

3030
/**
3131
* This is the base class for fields
@@ -40,39 +40,37 @@ export abstract class AbstractFieldComponent
4040
implements OnInit, OnDestroy {
4141

4242
path: Array<any>;
43-
errors: Array<Object> = [];
44-
errorsSubscription: Subscription;
43+
externalErrors: Array<ValidationError> = [];
44+
internalErrors: Array<ValidationError> = [];
45+
externalCategorizedErrorSubscription: Subscription;
4546

4647
constructor(public appGlobalsService: AppGlobalsService,
47-
public pathUtilService: PathUtilService) {
48+
public pathUtilService: PathUtilService,
49+
public changeDetectorRef: ChangeDetectorRef) {
4850
super();
4951
}
5052

5153
ngOnInit() {
52-
this.errorsSubscription = this.appGlobalsService
53-
.globalErrorsSubject
54-
.subscribe((globalErrors) => {
55-
this.errors = globalErrors[this.pathString] || [];
54+
this.externalCategorizedErrorSubscription = this.appGlobalsService.externalCategorizedErrorsSubject
55+
.subscribe(externalCategorizedErrorMap => {
56+
this.externalErrors = externalCategorizedErrorMap.Errors[this.pathString] || [];
57+
this.changeDetectorRef.markForCheck();
5658
});
5759
}
5860

5961
ngOnDestroy() {
60-
if (this.errorsSubscription) {
61-
this.errorsSubscription.unsubscribe();
62-
}
63-
}
64-
65-
get errorNgClass(): Object {
66-
return {
67-
error: this.errors.length > 0
68-
};
62+
this.externalCategorizedErrorSubscription.unsubscribe();
6963
}
7064

7165
get isErrorTooltipEnabled(): boolean {
72-
return this.errors && this.errors.length > 0;
66+
return this.hasErrors;
7367
}
7468

7569
get pathString(): string {
7670
return this.pathUtilService.toPathString(this.path);
7771
}
72+
73+
get hasErrors() {
74+
return this.externalErrors.length > 0 || this.internalErrors.length > 0;
75+
}
7876
}

src/abstract-list-field/abstract-list-field.component.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* waive the privileges and immunities granted to it by virtue of its status
2020
* as an Intergovernmental Organization or submit itself to any jurisdiction.
2121
*/
22-
22+
import { ChangeDetectorRef } from '@angular/core';
2323
import { List } from 'immutable';
2424

2525
import { AbstractFieldComponent } from '../abstract-field';
@@ -42,8 +42,9 @@ export abstract class AbstractListFieldComponent extends AbstractFieldComponent
4242

4343
constructor(public appGlobalsService: AppGlobalsService,
4444
public jsonStoreService: JsonStoreService,
45-
public pathUtilService: PathUtilService) {
46-
super(appGlobalsService, pathUtilService);
45+
public pathUtilService: PathUtilService,
46+
public changeDetectorRef: ChangeDetectorRef) {
47+
super(appGlobalsService, pathUtilService, changeDetectorRef);
4748
}
4849
/**
4950
* @param {number} index - Index of the element that is moved

src/any-type-field/any-type-field.component.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ import {
2626
ChangeDetectionStrategy,
2727
} from '@angular/core';
2828

29-
import { AppGlobalsService, ComponentTypeService } from '../shared/services';
29+
import { AppGlobalsService, ComponentTypeService, PathUtilService } from '../shared/services';
3030
import { JSONSchema } from '../shared/interfaces';
3131

32+
3233
/**
3334
* AnyFieldComponent
3435
*
@@ -54,7 +55,8 @@ export class AnyTypeFieldComponent {
5455
@Input() value: any;
5556

5657
constructor(public componentTypeService: ComponentTypeService,
57-
public appGlobalsService: AppGlobalsService) { }
58+
public appGlobalsService: AppGlobalsService,
59+
public pathUtilService: PathUtilService) { }
5860

5961
get componentType(): string {
6062
return this.componentTypeService.getComponentType(this.schema);

src/autocomplete-input/autocomplete-input.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { Ng2BootstrapModule } from 'ng2-bootstrap';
3333

3434
import { AutocompleteInputComponent } from '../autocomplete-input';
3535

36-
import { RemoteAutocompletionService, JsonStoreService, PathUtilService, AppGlobalsService } from '../shared/services';
36+
import { RemoteAutocompletionService, JsonStoreService, PathUtilService, AppGlobalsService, ErrorMapUtilService } from '../shared/services';
3737

3838
import { AutocompletionResult, AutocompletionConfig } from '../shared/interfaces';
3939

@@ -73,6 +73,7 @@ describe('AutocompleteInputComponent', () => {
7373
{ provide: AppGlobalsService, useClass: MockAppGlobalsService },
7474
JsonStoreService,
7575
PathUtilService,
76+
ErrorMapUtilService
7677
]
7778
}).compileComponents();
7879
}));

src/complex-list-field/complex-list-field.component.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import {
2626
OnChanges,
2727
OnInit,
2828
ChangeDetectionStrategy,
29-
SimpleChanges
29+
SimpleChanges,
30+
ChangeDetectorRef
3031
} from '@angular/core';
3132

3233
import { List, Map, Set } from 'immutable';
@@ -63,8 +64,9 @@ export class ComplexListFieldComponent extends AbstractListFieldComponent implem
6364
constructor(public appGlobalsService: AppGlobalsService,
6465
public jsonStoreService: JsonStoreService,
6566
public domUtilService: DomUtilService,
66-
public pathUtilService: PathUtilService) {
67-
super(appGlobalsService, jsonStoreService, pathUtilService);
67+
public pathUtilService: PathUtilService,
68+
public changeDetectorRef: ChangeDetectorRef) {
69+
super(appGlobalsService, jsonStoreService, pathUtilService, changeDetectorRef);
6870
}
6971

7072
ngOnInit() {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<ul class="list-group" *ngFor="let key of keys(errorMap)">
2+
<div [ngSwitch]="isJsonPointerPath(key)" *ngFor="let error of errorMap[key]">
3+
<div *ngSwitchCase="true" class="list-group">
4+
<a (click)="focusPath($event, key)" class="list-group-item">
5+
<i *ngIf="heading === 'Errors'" class="fa fa-times" aria-hidden="true"></i>
6+
<i *ngIf="heading === 'Warnings'" class="fa fa-exclamation-triangle" aria-hidden="true"></i>
7+
{{error.message}}
8+
</a>
9+
</div>
10+
<div *ngSwitchDefault>
11+
<li class="list-group-item">
12+
<i *ngIf="heading === 'Errors'" class="fa fa-times" aria-hidden="true"></i>
13+
<i *ngIf="heading === 'Warnings'" class="fa fa-exclamation-triangle" aria-hidden="true"></i>
14+
{{error.message}}
15+
</li>
16+
</div>
17+
</div>
18+
</ul>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
i {
2+
&.fa-exclamation-triangle {
3+
color: #FFDD00;
4+
}
5+
6+
&.fa-times {
7+
color: #D14024;
8+
}
9+
}
10+
11+
a {
12+
&:hover {
13+
background-color: #faebcc;
14+
text-decoration: underline;
15+
}
16+
17+
&.list-group-item {
18+
cursor: pointer;
19+
color: #0074D9;
20+
}
21+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* This file is part of ng2-json-editor.
3+
* Copyright (C) 2017 CERN.
4+
*
5+
* ng2-json-editor is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License as
7+
* published by the Free Software Foundation; either version 2 of the
8+
* License, or (at your option) any later version.
9+
*
10+
* ng2-json-editor is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with ng2-json-editor; if not, write to the Free Software Foundation, Inc.,
17+
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18+
* In applying this license, CERN does not
19+
* waive the privileges and immunities granted to it by virtue of its status
20+
* as an Intergovernmental Organization or submit itself to any jurisdiction.
21+
*/
22+
23+
import {
24+
Component, Input, ChangeDetectionStrategy
25+
} from '@angular/core';
26+
27+
import { DomUtilService, PathUtilService } from '../../shared/services';
28+
import { SchemaValidationErrors } from '../../shared/interfaces';
29+
30+
@Component({
31+
selector: 'error-panel-item',
32+
styleUrls: [
33+
'./error-panel-item.component.scss'
34+
],
35+
templateUrl: './error-panel-item.component.html',
36+
changeDetection: ChangeDetectionStrategy.OnPush
37+
})
38+
export class ErrorPanelItemComponent {
39+
40+
@Input() errorMap: SchemaValidationErrors;
41+
@Input() heading;
42+
43+
44+
constructor(public domUtilService: DomUtilService,
45+
public pathUtilService: PathUtilService) { }
46+
47+
isJsonPointerPath(key: string) {
48+
return key.startsWith(this.pathUtilService.separator);
49+
}
50+
51+
keys(errorMap: SchemaValidationErrors) {
52+
return Object.keys(errorMap);
53+
}
54+
55+
focusPath(event: Event, path: string) {
56+
event.preventDefault();
57+
this.domUtilService.focusAndSelectFirstEditableChildById(path, true);
58+
}
59+
}
60+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { ErrorPanelItemComponent } from './error-panel-item.component';

0 commit comments

Comments
 (0)