| .. | .. |
|---|
| 1 | 1 | import { Http } from '@angular/http'; |
|---|
| 2 | 2 | import { ActivatedRoute } from '@angular/router'; |
|---|
| 3 | +import { TdDialogService } from '@covalent/core'; |
|---|
| 3 | 4 | import { ToastsManager } from 'ng2-toastr/ng2-toastr'; |
|---|
| 4 | 5 | |
|---|
| 5 | 6 | import { LocaleService } from '../common/i18n'; |
|---|
| 7 | +import { BasicService } from '../common/utils'; |
|---|
| 6 | 8 | import { SeCurisResourceServices } from '../resources/base'; |
|---|
| 7 | 9 | |
|---|
| 8 | | -import { AfterViewInit } from '@angular/core'; |
|---|
| 10 | +import { AfterViewInit, Component, Input } from '@angular/core'; |
|---|
| 9 | 11 | |
|---|
| 10 | 12 | |
|---|
| 11 | 13 | export interface IComboOption { |
|---|
| .. | .. |
|---|
| 14 | 16 | } |
|---|
| 15 | 17 | |
|---|
| 16 | 18 | |
|---|
| 17 | | -export class FormBase { |
|---|
| 19 | +export class FormBase extends BasicService { |
|---|
| 18 | 20 | protected form_title: string = ''; |
|---|
| 19 | 21 | protected form_subtitle: string = ''; |
|---|
| 20 | 22 | protected data: any = {}; |
|---|
| 21 | 23 | protected isNew : boolean = true; |
|---|
| 22 | 24 | |
|---|
| 23 | | - constructor(protected $L: LocaleService, |
|---|
| 25 | + constructor($L: LocaleService, |
|---|
| 24 | 26 | protected route: ActivatedRoute, |
|---|
| 25 | 27 | protected toaster: ToastsManager, |
|---|
| 26 | 28 | protected resourceServices: SeCurisResourceServices, |
|---|
| 27 | | - protected resourceName: string ) { |
|---|
| 29 | + protected resourceName: string, |
|---|
| 30 | + protected dialogs : TdDialogService ) { |
|---|
| 31 | + super($L); |
|---|
| 28 | 32 | } |
|---|
| 29 | 33 | |
|---|
| 30 | 34 | public getFieldName(fieldId: string) : string { |
|---|
| .. | .. |
|---|
| 36 | 40 | save() { |
|---|
| 37 | 41 | var command = this.isNew ? this.resourceServices.create(this.data) : this.resourceServices.modify(this.data.id, this.data); |
|---|
| 38 | 42 | 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 | + ); |
|---|
| 45 | 46 | } |
|---|
| 46 | 47 | |
|---|
| 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 { |
|---|
| 48 | 67 | this.form_title = this.$L.get('{} data', this.resourceName.capitalize()); |
|---|
| 49 | 68 | this.isNew = true; |
|---|
| 50 | 69 | !!this.route && this.route.params.subscribe(params => { |
|---|
| .. | .. |
|---|
| 61 | 80 | }); |
|---|
| 62 | 81 | } |
|---|
| 63 | 82 | |
|---|
| 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 | +} |
|---|