LP#1775466 Admin page grid content translator
authorBill Erickson <berickxx@gmail.com>
Mon, 13 Aug 2018 17:12:01 +0000 (13:12 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 13 Aug 2018 17:12:01 +0000 (13:12 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/grid/grid-toolbar.component.html
Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
Open-ILS/src/eg2/src/app/staff/share/translate/translate.component.html
Open-ILS/src/eg2/src/app/staff/share/translate/translate.component.ts

index 442bab1..ae24021 100644 (file)
@@ -7,7 +7,7 @@
     <div class="btn-grp" *ngIf="gridContext.toolbarButtons.length">
       <button *ngFor="let btn of gridContext.toolbarButtons" 
         [disabled]="btn.disabled"
-        class="btn btn-outline-dark" (click)="btn.action()">
+        class="btn btn-outline-dark mr-1" (click)="btn.action()">
         {{btn.label}}
       </button>
     </div>
index 5f0eadd..194f06b 100644 (file)
   <hr/>
 </ng-container>
 
+<!-- idlObject and fieldName applied programmatically -->
+<eg-translate #translator></eg-translate>
+
 <eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource" 
     [sortable]="true" persistKey="{{persistKey}}">
   <eg-grid-toolbar-button [disabled]="!canCreate" 
     label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
   </eg-grid-toolbar-button>
+  <eg-grid-toolbar-button [disabled]="translatableFields.length == 0" 
+    label="Apply Translations" i18n-label [action]="translate">
+  </eg-grid-toolbar-button>
   <eg-grid-toolbar-action label="Delete Selected" i18n-label [action]="deleteSelected">
   </eg-grid-toolbar-action>
 </eg-grid>
index afe9e97..febfe35 100644 (file)
@@ -2,6 +2,7 @@ import {Component, Input, OnInit, TemplateRef, ViewChild} from '@angular/core';
 import {IdlService, IdlObject} from '@eg/core/idl.service';
 import {GridDataSource} from '@eg/share/grid/grid';
 import {GridComponent} from '@eg/share/grid/grid.component';
+import {TranslateComponent} from '@eg/staff/share/translate/translate.component';
 import {ToastService} from '@eg/share/toast/toast.service';
 import {Pager} from '@eg/share/util/pager';
 import {PcrudService} from '@eg/core/pcrud.service';
@@ -65,12 +66,19 @@ export class AdminPageComponent implements OnInit {
     @ViewChild('editDialog') editDialog: FmRecordEditorComponent;
     @ViewChild('successString') successString: StringComponent;
     @ViewChild('createString') createString: StringComponent;
+    @ViewChild('translator') translator: TranslateComponent;
 
     idlClassDef: any;
     pkeyField: string;
     createNew: () => void;
     deleteSelected: (rows: IdlObject[]) => void;
 
+    // True if any columns on the object support translations
+    translateRowIdx: number;
+    translateFieldIdx: number;
+    translatableFields: string[];
+    translate: () => void;
+
     contextOrg: IdlObject;
     orgFieldLabel: string;
     viewPerms: string;
@@ -83,7 +91,9 @@ export class AdminPageComponent implements OnInit {
         private pcrud: PcrudService,
         private perm: PermService,
         private toast: ToastService
-    ) {}
+    ) {
+        this.translatableFields = [];
+    }
 
     applyOrgValues() {
 
@@ -113,6 +123,9 @@ export class AdminPageComponent implements OnInit {
         this.idlClassDef = this.idl.classes[this.idlClass];
         this.pkeyField = this.idlClassDef.pkey || 'id';
 
+        this.translatableFields = 
+            this.idlClassDef.fields.filter(f => f.i18n).map(f => f.name);
+
         if (!this.persistKey) {
             this.persistKey = 
                 'admin.' + 
@@ -171,6 +184,50 @@ export class AdminPageComponent implements OnInit {
                 ()  => this.grid.reload()
             );
         };
+
+        // Open the field translation dialog.
+        // Link the next/previous actions to cycle through each translatable
+        // field on each row.
+        this.translate = () => {
+            this.translateRowIdx = 0;
+            this.translateFieldIdx = 0;
+            this.translator.fieldName = this.translatableFields[this.translateFieldIdx];
+            this.translator.idlObject = this.dataSource.data[this.translateRowIdx];
+
+            this.translator.nextString = () => {
+
+                if (this.translateFieldIdx < this.translatableFields.length - 1) {
+                    this.translateFieldIdx++;
+
+                } else if (this.translateRowIdx < this.dataSource.data.length - 1) {
+                    this.translateRowIdx++;
+                    this.translateFieldIdx = 0;
+                }
+
+                this.translator.idlObject = 
+                    this.dataSource.data[this.translateRowIdx];
+                this.translator.fieldName = 
+                    this.translatableFields[this.translateFieldIdx];
+            }
+
+            this.translator.prevString = () => {
+
+                if (this.translateFieldIdx > 0) {
+                    this.translateFieldIdx--;
+
+                } else if (this.translateRowIdx > 0) {
+                    this.translateRowIdx--;
+                    this.translateFieldIdx = 0;
+                }
+
+                this.translator.idlObject = 
+                    this.dataSource.data[this.translateRowIdx];
+                this.translator.fieldName = 
+                    this.translatableFields[this.translateFieldIdx];
+            }
+
+            this.translator.open({size:'lg'});
+        }
     }
 
     checkCreatePerms() {
index a57ca17..7aa59b4 100644 (file)
@@ -1,8 +1,7 @@
 <ng-template #dialogContent>
   <div class="modal-header bg-info">
     <h4 class="modal-title" i18n>
-      Translating field "{{idlClassDef.field_map[field].label}}" 
-      of "{{idlClassDef.label}}".
+      {{idlClassDef.label}}
     </h4>
     <button type="button" class="close" 
       i18n-aria-label aria-label="Close" 
   <div class="modal-body form-common form-validated" *ngIf="idlObj">
     <div class="form-group row">
       <label class="col-lg-4 text-right font-weight-bold" 
+        i18n>Field Name</label>
+      <input 
+        type="text" 
+        [disabled]="true"
+        class="form-control col-lg-7"
+        value="{{idlClassDef.field_map[field].label}}">
+    </div>
+    <div class="form-group row">
+      <label class="col-lg-4 text-right font-weight-bold" 
         i18n>Current Value</label>
       <input 
         type="text" 
     </div>
   </div>
   <div class="modal-footer">
+    <button *ngIf="prevString" (click)="prevString()" 
+      class="btn btn-info" i18n>Prev String</button>
+    <button *ngIf="nextString" (click)="nextString()" 
+      class="btn btn-info mr-3" i18n>Next String</button>
     <button (click)="translate()" class="btn btn-info" i18n>Apply</button>
     <button (click)="dismiss('canceled')" class="btn btn-warning ml-2" i18n>Cancel</button>
   </div>
index a165afe..1d3b0a5 100644 (file)
@@ -21,6 +21,13 @@ export class TranslateComponent
     translatedValue: string;
     existingTranslation: IdlObject;
 
+    // These actions should update the idlObject and/or fieldName values,
+    // forcing the dialog to load a new string to translate.  When set,
+    // applying a translation in the dialog will leave the dialog window open
+    // so the next/prev buttons can be used to fetch the next string.
+    nextString: () => void;
+    prevString: () => void;
+
     idlObj: IdlObject;
     @Input() set idlObject(o: IdlObject) {
         if (o) {
@@ -105,7 +112,11 @@ export class TranslateComponent
             entry.string(this.translatedValue);
 
             this.pcrud.update(entry).toPromise().then(
-                ok => this.close('Translation updated'),
+                ok => {
+                    if (!this.nextString) {
+                        this.close('Translation updated');
+                    }
+                },
                 err => console.error(err)
             );
 
@@ -119,7 +130,11 @@ export class TranslateComponent
         entry.string(this.translatedValue);
 
         this.pcrud.create(entry).toPromise().then(
-            ok => this.close('Translation created'),
+            ok => {
+                if (!this.nextString) {
+                    this.close('Translation created');
+                }
+            },
             err => console.error('Translation creation failed')
         );
     }