LP#2007877: various fixes to Server Admin Print Templates page
authorGalen Charlton <gmc@equinoxOLI.org>
Mon, 20 Feb 2023 22:13:45 +0000 (17:13 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 27 Feb 2023 16:27:23 +0000 (11:27 -0500)
This patch fixes a regression introduced by the switch to NgbNav
as well as a number of other issues.

To test
-------
[1] Open the Server Administration -> Print Templates page and select
    a print template. Observe that the template editor is not displayed
    and that there are errors in the browser console.
[2] Apply the patch and repeat step 1. This time, the template is
    displayed along with its previewed.
[3] Switch to the Sample Data tab, then select another template. Observe
    that the template is reloaded and the active tab switched to the template
    editor.
[4] Select a template such as "Checkin" that does not have stock
    sample data. Observe that the Preview and Compiled Content panes on
    the template editor tab are empty and that the Sample Data tab
    has an empty control

Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>

Open-ILS/src/eg2/src/app/staff/admin/server/print-template.component.html
Open-ILS/src/eg2/src/app/staff/admin/server/print-template.component.ts

index 81a8879..e2bd27f 100644 (file)
   </div>
 </div>
 
-<ul ngbNav #tabs="ngbNav" *ngIf="template" [(activeId)]="template"
-      (navChange)="onNavChange($event)" [keyboard]="true" [roles]="false" role="tablist" class="nav-tabs">
-
-  <li role="presentation" [ngbNavItem]="'template'">
-    <a i18n ngbNavLink role="tab">Template</a>
-    <ng-template ngbNavContent>
-      <div class="row">
-        <div class="col-lg-12 mt-3 d-flex">
-          <button class="btn btn-info" (click)="openEditDialog()" i18n>
-            Edit Template Attributes
-          </button>
-          <button class="btn btn-success ml-2" (click)="applyChanges()" i18n>
-            Save Template Changes
-          </button>
-          <button class="btn btn-info ml-2" (click)="cloneTemplate()" i18n>
-            Clone Template
-          </button>
-          <span class="ml-3 mr-1" i18n>Force Print Context:</span>
-          <eg-combobox #printContextCbox (onChange)="forceContextChange($event)">
-            <eg-combobox-entry entryId="unset" entryLabel="<Unset>" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="default" entryLabel="Default" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="receipt" entryLabel="Receipt" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="label" entryLabel="Label" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="mail" entryLabel="Mail" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="offline" entryLabel="Offline" i18n-entryLabel>
-            </eg-combobox-entry>
-            <eg-combobox-entry entryId="no-print" entryLabel="No-Print" i18n-entryLabel>
-            </eg-combobox-entry>
-          </eg-combobox>
-          <div class="flex-1"> </div>
-          <button class="btn btn-danger ml-2" (click)="deleteTemplate()" i18n>
-            Delete Template
-          </button>
-          <span *ngIf="invalidJson" class="badge badge-danger ml-2" i18n>
-            Invalid Sample JSON!
-          </span>
-        </div>
-      </div>
-      <div class="row mt-2">
-        <div class="col-lg-6">
-          <h4 i18n>
-            Template for "{{template.label()}} ({{getOwnerName(template.id())}})"
-            <span class="pl-2 text-warning" *ngIf="template.active() === 'f'">
-              (Inactive)
+<ng-container *ngIf="template">
+  <ul ngbNav #tabs="ngbNav" [(activeId)]="selectedTab" [destroyOnHide]="false"
+        (navChange)="onNavChange($event)" [keyboard]="true" [roles]="false" role="tablist" class="nav-tabs">
+  
+    <li role="presentation" [ngbNavItem]="'template'">
+      <a i18n ngbNavLink role="tab">Template</a>
+      <ng-template ngbNavContent>
+        <div class="row">
+          <div class="col-lg-12 mt-3 d-flex">
+            <button class="btn btn-info" (click)="openEditDialog()" i18n>
+              Edit Template Attributes
+            </button>
+            <button class="btn btn-success ml-2" (click)="applyChanges()" i18n>
+              Save Template Changes
+            </button>
+            <button class="btn btn-info ml-2" (click)="cloneTemplate()" i18n>
+              Clone Template
+            </button>
+            <span class="ml-3 mr-1" i18n>Force Print Context:</span>
+            <eg-combobox #printContextCbox (onChange)="forceContextChange($event)">
+              <eg-combobox-entry entryId="unset" entryLabel="<Unset>" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="default" entryLabel="Default" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="receipt" entryLabel="Receipt" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="label" entryLabel="Label" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="mail" entryLabel="Mail" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="offline" entryLabel="Offline" i18n-entryLabel>
+              </eg-combobox-entry>
+              <eg-combobox-entry entryId="no-print" entryLabel="No-Print" i18n-entryLabel>
+              </eg-combobox-entry>
+            </eg-combobox>
+            <div class="flex-1"> </div>
+            <button class="btn btn-danger ml-2" (click)="deleteTemplate()" i18n>
+              Delete Template
+            </button>
+            <span *ngIf="invalidJson" class="badge badge-danger ml-2" i18n>
+              Invalid Sample JSON!
             </span>
-          </h4>
-         <textarea rows="{{templateRowCount()}}" class="form-control"
-           spellcheck="false"
-           [ngModel]="template.template()"
-           (ngModelChange)="template.template($event); template.ischanged(true)">
-         </textarea>
+          </div>
         </div>
-        <div class="col-lg-6">
-          <h4 i18n>Preview</h4>
-          <div class="border border-dark w-100" id="template-preview-pane">
+        <div class="row mt-2">
+          <div class="col-lg-6">
+            <h4 i18n>
+              Template for "{{template.label()}} ({{getOwnerName(template.id())}})"
+              <span class="pl-2 text-warning" *ngIf="template.active() === 'f'">
+                (Inactive)
+              </span>
+            </h4>
+           <textarea rows="{{templateRowCount()}}" class="form-control"
+             spellcheck="false"
+             [ngModel]="template.template()"
+             (ngModelChange)="template.template($event); template.ischanged(true)">
+           </textarea>
           </div>
-          <h4 class="mt-3" i18n>Compiled Content</h4>
-          <div class="border border-dark w-100">
-            <pre class="p-1">{{compiledContent}}</pre>
+          <div class="col-lg-6">
+            <h4 i18n>Preview</h4>
+            <div class="border border-dark w-100" id="template-preview-pane">
+            </div>
+            <h4 class="mt-3" i18n>Compiled Content</h4>
+            <div class="border border-dark w-100">
+              <pre class="p-1">{{compiledContent}}</pre>
+            </div>
           </div>
         </div>
-      </div>
-    </ng-template>
-  </li>
-  <li role="presentation" [ngbNavItem]="'data'">
-    <a i18n ngbNavLink role="tab">Sample Data</a>
-    <ng-template ngbNavContent>
-      <textarea rows="20" [(ngModel)]="sampleJson" 
-        spellcheck="false" class="form-control">
-      </textarea>
-    </ng-template>
-  </li>
-</ul>
-
-<div [ngbNavOutlet]="tabs" class="mt-2"></div>
\ No newline at end of file
+      </ng-template>
+    </li>
+    <li role="presentation" [ngbNavItem]="'data'">
+      <a i18n ngbNavLink role="tab">Sample Data</a>
+      <ng-template ngbNavContent>
+        <textarea rows="20" [(ngModel)]="sampleJson" 
+          spellcheck="false" class="form-control">
+        </textarea>
+      </ng-template>
+    </li>
+  </ul>
+  
+  <div [ngbNavOutlet]="tabs" class="mt-2"></div>
+</ng-container>
index dd3be36..4575852 100644 (file)
@@ -37,9 +37,9 @@ export class PrintTemplateComponent implements OnInit {
     templateCache: {[id: number]: IdlObject} = {};
     initialOrg: number;
     selectedOrgs: number[];
+    selectedTab = 'template';
 
     @ViewChild('templateSelector', { static: true }) templateSelector: ComboboxComponent;
-    @ViewChild('tabs', { static: false }) tabs: NgbNav;
     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
     @ViewChild('confirmDelete', { static: true }) confirmDelete: ConfirmDialogComponent;
     @ViewChild('printContextCbox', {static: false}) printContextCbox: ComboboxComponent;
@@ -170,7 +170,7 @@ export class PrintTemplateComponent implements OnInit {
             this.org.list()[0];
     }
 
-    onTabChange(evt: NgbNavChangeEvent) {
+    onNavChange(evt: NgbNavChangeEvent) {
         if (evt.nextId === 'template') {
             this.refreshPreview();
         }
@@ -243,7 +243,7 @@ export class PrintTemplateComponent implements OnInit {
     }
 
     // If the selected template changes through means other than the
-    // template selecdtor, setting updateSelector=true will force the
+    // template selector, setting updateSelector=true will force the
     // template to appear in the selector and get selected, regardless
     // of whether it would have been fetched with current filters.
     selectTemplate(id: number, updateSelector?: boolean) {
@@ -254,6 +254,14 @@ export class PrintTemplateComponent implements OnInit {
             return;
         }
 
+        // reset things
+        this.selectedTab = 'template';
+        this.compiledContent = '';
+        if (this.container()) {
+            this.container().innerHTML = '';
+        }
+        this.sampleJson = '';
+
         this.pcrud.retrieve('cpt', id).subscribe(t => {
             this.template = this.templateCache[id] = t;