rsanchez
2017-03-20 1a0491f2462d2c309bd8e310b22c11019a79ce1e
securis/src/main/webapp/src/app/forms/base.ts
....@@ -1,11 +1,13 @@
11 import { Http } from '@angular/http';
22 import { ActivatedRoute } from '@angular/router';
3
+import { TdDialogService } from '@covalent/core';
34 import { ToastsManager } from 'ng2-toastr/ng2-toastr';
45
56 import { LocaleService } from '../common/i18n';
7
+import { BasicService } from '../common/utils';
68 import { SeCurisResourceServices } from '../resources/base';
79
8
-import { AfterViewInit } from '@angular/core';
10
+import { AfterViewInit, Component, Input } from '@angular/core';
911
1012
1113 export interface IComboOption {
....@@ -14,17 +16,19 @@
1416 }
1517
1618
17
-export class FormBase {
19
+export class FormBase extends BasicService {
1820 protected form_title: string = '';
1921 protected form_subtitle: string = '';
2022 protected data: any = {};
2123 protected isNew : boolean = true;
2224
23
- constructor(protected $L: LocaleService,
25
+ constructor($L: LocaleService,
2426 protected route: ActivatedRoute,
2527 protected toaster: ToastsManager,
2628 protected resourceServices: SeCurisResourceServices,
27
- protected resourceName: string ) {
29
+ protected resourceName: string,
30
+ protected dialogs : TdDialogService ) {
31
+ super($L);
2832 }
2933
3034 public getFieldName(fieldId: string) : string {
....@@ -36,15 +40,30 @@
3640 save() {
3741 var command = this.isNew ? this.resourceServices.create(this.data) : this.resourceServices.modify(this.data.id, this.data);
3842 command.subscribe(
39
- data => this.toaster.success(this.$L.get('{} saved sucessfully', this.$L.get(this.resourceName).capitalize())),
40
- err => {
41
- console.error(err);
42
- this.toaster.success(this.$L.get('Error saving {}', this.$L.get(this.resourceName)));
43
- }
44
- );
43
+ data => this.toaster.success(this.$L.get('{} saved sucessfully', this.resourceName.capitalize())),
44
+ err => this.toaster.error(err.message, this.$L.get('Error saving {}', this.resourceName))
45
+ );
4546 }
4647
47
- protected prepareData(idparam: string, default_values: any = {}) : void {
48
+ delete(eleId: number | string) : void {
49
+ this.dialogs.openConfirm({
50
+ message: this.$L.get('The {} with ID {} will be deleted. Do you want to continue ?', this.resourceName, eleId),
51
+ disableClose: false, // defaults to false
52
+ title: this.$L.get('Delete {}', this.resourceName),
53
+ cancelButton: this.$L.get('Cancel'),
54
+ acceptButton: this.$L.get('Yes, delete')
55
+ }).afterClosed().subscribe((accept: boolean) => {
56
+ if (accept) {
57
+ this.resourceServices.remove(eleId)
58
+ .subscribe(
59
+ responseData => this.toaster.success(this.$L.get('{} was sucessfully deleted', this.resourceName.capitalize())),
60
+ err => this.toaster.success(err.message, this.$L.get('Error deleting the {}', this.resourceName))
61
+ );
62
+ }
63
+ });
64
+ }
65
+
66
+ protected prepareInitialData(idparam: string, default_values: any = {}) : void {
4867 this.form_title = this.$L.get('{} data', this.resourceName.capitalize());
4968 this.isNew = true;
5069 !!this.route && this.route.params.subscribe(params => {
....@@ -61,4 +80,173 @@
6180 });
6281 }
6382
64
-}
83
+}
84
+
85
+@Component({
86
+ selector: 'error-checker',
87
+ template: `
88
+ <div *ngIf="formField?.touched && formField.invalid" layout="column">
89
+ <span class="error-msg" *ngFor="let err of getFieldErrors()" align="end">{{err}}</span>
90
+ </div>`,
91
+ styles: [
92
+ ':host {margin-top: -10px;}',
93
+ `.error-msg {
94
+ color: darkred;
95
+ font-size: 0.8em;
96
+ }`
97
+ ]
98
+})
99
+export class ErrorCheckerComponent {
100
+
101
+ @Input() formField: any;
102
+ @Input() fieldName: string;
103
+
104
+ constructor(private $L: LocaleService) {
105
+ }
106
+
107
+ getFieldErrors() : string[] {
108
+ if (this.formField.valid) {
109
+ return []
110
+ } else {
111
+ return (<string[]>Object.keys(this.formField.errors)).map((err:string) => this.getErrorMsg(err));
112
+ }
113
+ }
114
+
115
+ private updateFieldErrors() {
116
+ }
117
+
118
+ private getErrorMsg(err: string) : string{
119
+ switch(err) {
120
+ case 'required': {
121
+ return this.fieldName + ' '+ this.$L.get('is required');
122
+ }
123
+ case 'number': {
124
+ return this.fieldName + ' '+ this.$L.get('should be a number');
125
+ }
126
+ default: {
127
+ return this.fieldName + ' '+ this.$L.get('unknown error') + ' ' + err;
128
+ }
129
+ }
130
+ }
131
+
132
+ log(obj: any) {
133
+ console.log(obj)
134
+ }
135
+
136
+}
137
+
138
+
139
+@Component({
140
+ selector: 'field-readonly',
141
+ template: `
142
+ <div layout="column" class="mat-input-container readonly" >
143
+ <div class="mat-input-wrapper">
144
+ <div class="mat-input-table">
145
+ <div class="mat-input-prefix"></div>
146
+ <div class="mat-input-infix">
147
+ <div class="label-value mat-input-element">{{value}}</div>
148
+ <span class="mat-input-placeholder-wrapper" >
149
+ <label class="mat-input-placeholder mat-float">
150
+ <span class="placeholder">{{label}}</span>
151
+ </label>
152
+ </span>
153
+ </div>
154
+ <div class="mat-input-suffix"></div>
155
+ </div>
156
+ <div class="mat-input-underline"></div>
157
+ </div>
158
+ </div>`,
159
+ styles: [`.readonly .mat-input-element {
160
+ margin-top: 0px !important;
161
+ color: rgba(0, 0, 0, 0.50);
162
+ }`,
163
+ `.readonly .mat-input-element {
164
+ margin-top: 0px;
165
+ color: rgba(0, 0, 0, 0.50);
166
+ }`,
167
+ `.readonly.mat-input-container {
168
+ width: 100%;
169
+ }`]
170
+})
171
+export class FieldReadonlyComponent {
172
+ @Input('value') value: any;
173
+
174
+ private _label : string;
175
+ @Input('label')
176
+ set label(txt: string) {
177
+ this._label = this.$L.get(txt);
178
+ }
179
+ get label(): string { return this._label; }
180
+
181
+ constructor(private $L : LocaleService) {
182
+
183
+ }
184
+}
185
+
186
+interface MetadataPair {
187
+ key: string,
188
+ value: string,
189
+ readonly: boolean,
190
+ mandatory: boolean
191
+}
192
+
193
+@Component({
194
+ selector: 'metadata-manager',
195
+ template: `
196
+ <div layout="column" layout-fill flex>
197
+ <div layout="row" layout-align="start center">
198
+ <span class="md-title">{{title}}</span>
199
+ <span flex></span>
200
+ <button *ngIf="addOrDelete" type="button" md-icon-button color="primary" (click)="newMetadata()"><md-icon>add</md-icon></button>
201
+ </div>
202
+ <div layout="row" layout-align="start center" *ngFor="let pair of metadata" class="values">
203
+ <md-input-container flex="35" >
204
+ <input mdInput type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="pair.key" [readonly]="!editKeys" [mdTooltip]="pair.key" />
205
+ <md-placeholder>
206
+ <span i18n="field.key"></span>
207
+ </md-placeholder>
208
+ </md-input-container>
209
+ <md-input-container flex >
210
+ <input mdInput type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="pair.value" [readonly]="pair.readonly" [required]="pair.mandatory"
211
+ [mdTooltip]="pair.value" />
212
+ <md-placeholder>
213
+ <span i18n="field.value"></span>
214
+ </md-placeholder>
215
+ </md-input-container>
216
+ <md-checkbox *ngIf="addOrDelete" [ngModelOptions]="{standalone: true}" [(ngModel)]="pair.mandatory" name="mandatory" [mdTooltip]="$L.get('field.mandatory')">
217
+ </md-checkbox>
218
+ <button *ngIf="addOrDelete" type="button" md-icon-button color="warn" (click)="deleteMetadata(pair)"><md-icon>delete</md-icon></button>
219
+ </div>
220
+ </div>`,
221
+ styles: [
222
+ ':host { width:100%; }',
223
+ `.values > * {
224
+ margin-left: 5px;
225
+ margin-right: 5px;
226
+ }`
227
+ ]
228
+})
229
+export class MetadataManagerComponent {
230
+ @Input('metadata') metadata: MetadataPair[];
231
+ @Input('addOrDelete') addOrDelete: boolean = false;
232
+ @Input('editKeys') editKeys: boolean = false;
233
+ @Input('title') title: string;
234
+
235
+ constructor(private $L : LocaleService) {
236
+ this.title = $L.get('License metadata');
237
+ }
238
+
239
+ newMetadata() : void{
240
+ this.metadata.push(<MetadataPair>{
241
+ mandatory: false,
242
+ readonly: false
243
+ });
244
+ }
245
+
246
+ deleteMetadata(pair: MetadataPair) : void {
247
+ let indexToRemove = this.metadata.findIndex(ele => ele.key === pair.key);
248
+ if (indexToRemove !== -1) {
249
+ this.metadata.splice(indexToRemove, 1);
250
+ }
251
+ }
252
+}