This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new f9429ae  [AMBARI-23648] - Log Search UI: Various fixes for Shipper 
Configuration
f9429ae is described below

commit f9429ae6868beb3cd51659cda4ce5c1f5741fea4
Author: Istvan Tobias <tobias.ist...@gmail.com>
AuthorDate: Sat Apr 21 13:37:22 2018 +0200

    [AMBARI-23648] - Log Search UI: Various fixes for Shipper Configuration
---
 .../ambari-logsearch-web/src/app/app.module.ts     |  4 +-
 .../log-index-filter.component.html                |  4 --
 .../src/app/modules/shared/notifications.less      |  1 -
 .../shared/services/notification.service.ts        | 19 ++++++--
 .../shipper-configuration.component.less           |  4 ++
 .../shipper-configuration.component.ts             |  8 ++-
 ...ipper-service-configuration-form.component.html |  7 ++-
 ...shipper-service-configuration-form.component.ts | 28 ++++++++---
 .../shipper/directives/validator.directive.ts      | 17 ++++++-
 .../app/modules/shipper/services/shipper.guard.ts  | 57 ++++++++++++++++++++++
 .../app/modules/shipper/shipper-routing.module.ts  |  5 +-
 .../src/app/modules/shipper/shipper.module.ts      |  4 +-
 .../ambari-logsearch-web/src/assets/i18n/en.json   | 13 ++---
 13 files changed, 138 insertions(+), 33 deletions(-)

diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts 
b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index b0612fe..8db8dea 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -24,11 +24,11 @@ import {InMemoryBackendService} from 
'angular-in-memory-web-api';
 import {TypeaheadModule, TooltipModule} from 'ngx-bootstrap';
 import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
 import {StoreModule} from '@ngrx/store';
-import { StoreDevtoolsModule } from '@ngrx/store-devtools';
+import {StoreDevtoolsModule} from '@ngrx/store-devtools';
 import {MomentModule} from 'angular2-moment';
 import {MomentTimezoneModule} from 'angular-moment-timezone';
 import {NgStringPipesModule} from 'angular-pipes';
-import { SimpleNotificationsModule } from 'angular2-notifications';
+import {SimpleNotificationsModule} from 'angular2-notifications';
 
 import {environment} from '@envs/environment';
 
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-index-filter/log-index-filter.component.html
 
b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-index-filter/log-index-filter.component.html
index 50d7742..5137275 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-index-filter/log-index-filter.component.html
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-index-filter/log-index-filter.component.html
@@ -69,10 +69,6 @@
             <div class="col-md-6">
               <div class="text-uppercase">{{'logIndexFilter.hostname' | 
translate}}</div>
               <input type="text" class="form-control" 
[(ngModel)]="component.hosts" (change)="updateValue()">
-              <!-- TODO implement typeahead similar to search box
-                   (some functionality and appearance most likely will be 
shared) -->
-              <!-- <input type="text" class="form-control" 
[(ngModel)]="component.hosts" (change)="updateValue()"
-                     [typeahead]="hosts | async" typeaheadOptionField="name"> 
-->
             </div>
             <div class=" col-md-6">
               <div class="text-uppercase">{{'logIndexFilter.expiryDate' | 
translate}}</div>
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/notifications.less
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/notifications.less
index e9f4fd9..7a0a045 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/notifications.less
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/notifications.less
@@ -56,7 +56,6 @@
   .sn-content {
     font-size: @notification-content-font-size;
     padding: 0;
-    white-space: pre-wrap;
   }
   .sn-progress-loader {
     height: 2px;
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts
index b149e38..df6ca2a 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shared/services/notification.service.ts
@@ -40,6 +40,14 @@ export const notificationIcons: Icons = {
 };
 Object.assign(defaultIcons, notificationIcons);
 
+export const messageTemplate = `
+<div class="notification-wrapper">
+  <div class="notification-header sn-title">{{title}}</div>
+  <div class="notification-body sn-content">{{message}}</div>
+  {{icon}}
+</div>
+`;
+
 @Injectable()
 export class NotificationService {
 
@@ -60,11 +68,12 @@ export class NotificationService {
         ...config
       });
     }
-    return this.notificationService[method](
-      this.translateService.instant(title),
-      this.translateService.instant(message),
-      {...config, icon: notificationIcons[method] || notificationIcons['info']}
-    );
+    const icon = notificationIcons[method] || notificationIcons['info'];
+    const htmlMsg = messageTemplate
+      .replace(/{{title}}/gi, this.translateService.instant(title))
+      .replace(/{{message}}/gi, this.translateService.instant(message))
+      .replace(/{{icon}}/gi, icon);
+    return this.notificationService.html(htmlMsg, method, {icon, ...config});
   }
 
 }
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.less
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.less
index a08f650..f416b07 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.less
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.less
@@ -27,3 +27,7 @@
 a.btn, a.btn:focus, a.btn:visited {
   color: #fff;
 }
+
+/deep/ .navigation-bar-container {
+  padding-bottom: 1em;
+}
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.ts
index 761dc3b..33466a1 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-configuration/shipper-configuration.component.ts
@@ -142,6 +142,7 @@ export class ShipperConfigurationComponent implements 
CanComponentDeactivate, On
   getResponseHandler(cmd: string, type: string, msgVariables?: {[key: string]: 
any}) {
     return (response: Response) => {
       const result = response.json();
+      // @ToDo change the backend response status to some error code if the 
configuration is not valid and don't use the .errorMessage prop
       const resultType = response ? (response.ok && !result.errorMessage ? 
NotificationType.SUCCESS : NotificationType.ERROR) : type;
       const translateParams = {errorMessage: '', ...msgVariables, ...result};
       const title = 
this.translate.instant(`shipperConfiguration.action.${cmd}.title`, 
translateParams);
@@ -175,7 +176,12 @@ export class ShipperConfigurationComponent implements 
CanComponentDeactivate, On
       this.getResponseHandler('validate', NotificationType.SUCCESS, rawValue),
       this.getResponseHandler('validate', NotificationType.ERROR, rawValue)
     );
-    request$.map((response: Response) => 
response.json()).subscribe(this.setValidationResult);
+    request$
+      .filter((response: Response): boolean => response.ok)
+      .map((response: Response) => response.json())
+      // @ToDo change the backend response status to some error code if the 
configuration is not valid and don't use the .errorMessage prop
+      .filter(result => result.errorMessage === undefined)
+      .subscribe(this.setValidationResult);
   }
 
   canDeactivate() {
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.html
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.html
index 42d364b..765aa50 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.html
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.html
@@ -75,10 +75,15 @@
                       class="help-block validation-block pull-right">
                   {{'common.form.errors.required' | translate}}
                 </span>
+                <span *ngIf="validatorForm.controls.componentName.value && 
componentNameField.errors && 
componentNameField.errors.serviceNameDoesNotExistInConfiguration"
+                      class="help-block validation-block pull-right">
+                  
{{'shipperConfiguration.form.errors.componentNameField.serviceNameDoesNotExistInConfiguration'
 | translate}}
+                </span>
               </label>
               <input class="form-control component-name" name="componentName" 
formControlName="componentName"
                      [typeahead]="configurationComponents$ | async"
                      [typeaheadItemTemplate]="typeAheadTpl"
+                     [typeaheadMinLength]="0"
                      [disableControl]="configurationForm.invalid">
             </div>
             <div [ngClass]="{'has-warning': sampleDataField.invalid, 
'form-group': true}">
@@ -96,8 +101,6 @@
               <label>
                 {{'shipperConfiguration.validator.result' | translate}}
               </label>
-              <!--textarea class="form-control validation-result" 
name="validationResult"
-                [disableControl]="configurationForm.invalid" 
[value]="validationResponse | json"></textarea-->
               <pre>{{validationResponse | json}}</pre>
             </div>
             <button class="btn btn-default pull-right" type="submit"
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.ts
index 23ee07c..b28c0d9 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/components/shipper-service-configuration-form/shipper-service-configuration-form.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, 
OnDestroy, OnInit, Output, SimpleChanges} from '@angular/core';
+import {Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, 
SimpleChanges} from '@angular/core';
 import {AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators} from 
'@angular/forms';
 import {Observable} from 'rxjs/Observable';
 import {Subject} from 'rxjs/Subject';
@@ -94,9 +94,11 @@ export class ShipperServiceConfigurationFormComponent 
implements OnInit, OnDestr
   private canDeactivateModalResult: Subject<boolean> = new Subject<boolean>();
 
   private canDeactivateObservable$: Observable<boolean> = 
Observable.create((observer: Observer<boolean>)  => {
-    this.canDeactivateModalResult.subscribe((result: boolean) => {
-      observer.next(result);
-    });
+    this.subscriptions.push(
+      this.canDeactivateModalResult.subscribe((result: boolean) => {
+        observer.next(result);
+      })
+    );
   });
 
   private serviceNamesListSubject: BehaviorSubject<ShipperClusterService[]> = 
new BehaviorSubject<ShipperClusterService[]>([]);
@@ -105,8 +107,7 @@ export class ShipperServiceConfigurationFormComponent 
implements OnInit, OnDestr
 
   constructor(
     private utilsService: UtilsService,
-    private formBuilder: FormBuilder,
-    private changeDetectorRef: ChangeDetectorRef
+    private formBuilder: FormBuilder
   ) {}
 
   ngOnInit() {
@@ -205,10 +206,21 @@ export class ShipperServiceConfigurationFormComponent 
implements OnInit, OnDestr
     });
 
     this.validatorForm = this.formBuilder.group({
-      clusterName: this.formBuilder.control(this.clusterName, 
Validators.required),
-      componentName: this.formBuilder.control('', Validators.required),
+      clusterName: this.formBuilder.control(
+        this.clusterName,
+        [Validators.required]
+      ),
+      componentName: this.formBuilder.control('', [
+        Validators.required,
+        
formValidators.getConfigurationServiceValidator(this.configurationForm.controls.configuration)
+      ]),
       sampleData: this.formBuilder.control('', Validators.required)
     });
+    this.subscriptions.push(
+      this.configurationForm.valueChanges.subscribe(() => {
+        this.validatorForm.controls.componentName.updateValueAndValidity();
+      })
+    );
   }
 
   onConfigurationSubmit(configurationForm: FormGroup): void {
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/directives/validator.directive.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/directives/validator.directive.ts
index 649acc0..ad6f009 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/directives/validator.directive.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/directives/validator.directive.ts
@@ -16,10 +16,11 @@
  * limitations under the License.
  */
 
-import {AbstractControl, ValidatorFn} from '@angular/forms';
+import {AbstractControl, AsyncValidatorFn, ValidatorFn} from '@angular/forms';
 import {ShipperClusterService} from 
'@modules/shipper/models/shipper-cluster-service.type';
 import {ValidationErrors} from '@angular/forms/src/directives/validators';
 import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+import {Observable} from 'rxjs/Observable';
 
 export function configurationValidator(): ValidatorFn {
   return (control: AbstractControl): ValidationErrors | null => {
@@ -45,3 +46,17 @@ export function uniqueServiceNameValidator(
   };
 }
 
+export function getConfigurationServiceValidator(configControl: 
AbstractControl): ValidatorFn {
+  return (control: AbstractControl): ValidationErrors | null => {
+    let components: string[];
+    try {
+      const inputs: {[key: string]: any}[] = (configControl.value ? 
JSON.parse(configControl.value) : {}).input;
+      components = inputs && inputs.length ? inputs.map(input => input.type) : 
[];
+    } catch (error) {
+      components = [];
+    }
+    return components.length && components.indexOf(control.value) === -1 ? {
+      serviceNameDoesNotExistInConfiguration: {value: control.value}
+    } : null;
+  };
+}
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/services/shipper.guard.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/services/shipper.guard.ts
new file mode 100644
index 0000000..f57a6c7
--- /dev/null
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/services/shipper.guard.ts
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Injectable} from '@angular/core';
+import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from 
'@angular/router';
+import {Observable} from 'rxjs/Observable';
+import {RoutingUtilsService} from '@app/services/routing-utils.service';
+import {ClustersService} from '@app/services/storage/clusters.service';
+import {ShipperClusterServiceListService} from 
'@modules/shipper/services/shipper-cluster-service-list.service';
+
+@Injectable()
+export class ShipperGuard implements CanActivate {
+
+  constructor (
+    private routingUtilsService: RoutingUtilsService,
+    private router: Router,
+    private clustersStoreService: ClustersService,
+    private shipperClusterServiceListService: ShipperClusterServiceListService
+  ) {}
+
+  getFirstCluster(): Observable<string> {
+    return this.clustersStoreService.getAll().map((clusters: string[]) => 
Array.isArray(clusters) ? clusters[0] : clusters);
+  }
+
+  getFirstServiceForCluster(cluster: string): Observable<string> {
+    return this.shipperClusterServiceListService.getServicesForCluster(cluster)
+      .map((services: string[]) => Array.isArray(services) ? services[0] : 
services);
+  }
+
+  canActivate(
+    next: ActivatedRouteSnapshot,
+    state: RouterStateSnapshot
+  ): Observable<boolean> | Promise<boolean> | boolean {
+    const cluster: string = 
this.routingUtilsService.getParamFromActivatedRouteSnapshot(next, 'cluster');
+    const service: string = 
this.routingUtilsService.getParamFromActivatedRouteSnapshot(next, 'service');
+    (cluster ? Observable.of(cluster) : 
this.getFirstCluster()).first().subscribe((firstCluster: string) => {
+      
this.getFirstServiceForCluster(firstCluster).first().subscribe((firstService: 
string) => {
+        this.router.navigate(['/shipper', firstCluster, firstService]);
+      });
+    });
+    return !!(cluster && service);
+  }
+}
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper-routing.module.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper-routing.module.ts
index 35aed14..85d0bb9 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper-routing.module.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper-routing.module.ts
@@ -23,6 +23,7 @@ import {AuthGuardService} from 
'@app/services/auth-guard.service';
 import {CanDeactivateGuardService} from 
'@modules/shared/services/can-deactivate-guard.service';
 
 import {ShipperConfigurationComponent} from 
'./components/shipper-configuration/shipper-configuration.component';
+import {ShipperGuard} from '@modules/shipper/services/shipper.guard';
 
 const shipperRoutes: Routes = [{
   path: 'shipper/:cluster/add',
@@ -49,7 +50,7 @@ const shipperRoutes: Routes = [{
     breadcrumbs: 'shipperConfiguration.breadcrumbs.title',
     multiClusterFilter: false
   },
-  canActivate: [AuthGuardService]
+  canActivate: [AuthGuardService, ShipperGuard]
 }, {
   path: 'shipper',
   component: ShipperConfigurationComponent,
@@ -57,7 +58,7 @@ const shipperRoutes: Routes = [{
     breadcrumbs: 'shipperConfiguration.breadcrumbs.title',
     multiClusterFilter: false
   },
-  canActivate: [AuthGuardService]
+  canActivate: [AuthGuardService, ShipperGuard]
 }];
 
 @NgModule({
diff --git 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper.module.ts
 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper.module.ts
index 682b739..1f6eddf 100644
--- 
a/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper.module.ts
+++ 
b/ambari-logsearch/ambari-logsearch-web/src/app/modules/shipper/shipper.module.ts
@@ -35,6 +35,7 @@ import {ShipperConfigurationStore} from 
'./stores/shipper-configuration.store';
 import {ShipperConfigurationComponent} from 
'./components/shipper-configuration/shipper-configuration.component';
 import {ShipperClusterServiceListService} from 
'./services/shipper-cluster-service-list.service';
 import {ShipperConfigurationService} from 
'./services/shipper-configuration.service';
+import {ShipperGuard} from '@modules/shipper/services/shipper.guard';
 
 @NgModule({
   imports: [
@@ -59,7 +60,8 @@ import {ShipperConfigurationService} from 
'./services/shipper-configuration.serv
   providers: [
     ShipperConfigurationStore,
     ShipperConfigurationService,
-    ShipperClusterServiceListService
+    ShipperClusterServiceListService,
+    ShipperGuard
   ]
 })
 export class ShipperModule {}
diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json 
b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
index bc96827..e70ab9b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
+++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
@@ -213,8 +213,8 @@
   "logIndexFilter.hostname": "Hostname",
   "logIndexFilter.expiryDate": "Expiry Date",
   "logIndexFilter.update.title": "Log Index Filter Update",
-  "logIndexFilter.update.success": "Log Index Filter for cluster {{cluster}} 
has been successfully updated.",
-  "logIndexFilter.update.error": "Error at updating Log Index Filter for 
cluster {{cluster}}. {{message}}",
+  "logIndexFilter.update.success": "Log Index Filter for cluster <span 
class='cluster-name'>{{cluster}}</span> has been successfully updated.",
+  "logIndexFilter.update.error": "Error at updating Log Index Filter for 
cluster <span class='cluster-name'>{{cluster}}</span>. {{message}}",
 
   "login.title": "Login",
 
@@ -235,6 +235,7 @@
   "shipperConfiguration.form.testBtn.label": "Test",
   "shipperConfiguration.form.errors.configuration.invalidJSON": "Invalid 
JSON!",
   "shipperConfiguration.form.errors.serviceName.exists": "This service name 
already exists.",
+  
"shipperConfiguration.form.errors.componentNameField.serviceNameDoesNotExistInConfiguration":
 "This component is not in the configuration.",
   "shipperConfiguration.form.leavingDirty.title": "You have unsaved changes",
   "shipperConfiguration.form.leavingDirty.message": "Are you sure that you 
cancel the changes?",
 
@@ -246,12 +247,12 @@
 
   "shipperConfiguration.action.add.title": "New Configuration",
   "shipperConfiguration.action.add.success.message": "New configuration has 
been added successfully.",
-  "shipperConfiguration.action.add.error.message": "Error at adding new 
configuration.\nCluster: {{clusterName}}\nService: {{componentName}}",
+  "shipperConfiguration.action.add.error.message": "Error at adding new 
configuration.<div class='cluster-name'>Cluster: {{clusterName}}</div><div 
class='service-name'>Service: {{componentName}}</div>",
   "shipperConfiguration.action.update.title": "Update Configuration",
-  "shipperConfiguration.action.update.success.message": "The configuration has 
been updated successfully.\nCluster: {{clusterName}}\nService: 
{{componentName}}",
-  "shipperConfiguration.action.update.error.message": "Error at updating the 
configuration.\nCluster: {{clusterName}}\nService: {{componentName}}",
+  "shipperConfiguration.action.update.success.message": "The configuration has 
been updated successfully.<div class='cluster-name'>Cluster: 
{{clusterName}}</div><div class='service-name'>Service: 
{{componentName}}</div>",
+  "shipperConfiguration.action.update.error.message": "Error at updating the 
configuration.<div class='cluster-name'>Cluster: {{clusterName}}</div><div 
class='service-name'>Service: {{componentName}}</div>",
   "shipperConfiguration.action.validate.title": "Validate Configuration",
   "shipperConfiguration.action.validate.success.message": "The configuration 
is valid.",
-  "shipperConfiguration.action.validate.error.message": "The configuration is 
not valid.\nCluster: {{clusterName}}\nService: 
{{componentName}}\n{{errorMessage}}"
+  "shipperConfiguration.action.validate.error.message": "The configuration is 
not valid.<div class='cluster-name'>Cluster: {{clusterName}}</div><div 
class='service-name'>Service: {{componentName}}</div><div 
class='error-message'>{{errorMessage}}</div>"
 
 }

-- 
To stop receiving notification emails like this one, please contact
ababiic...@apache.org.

Reply via email to