[open-ils-commits] [GIT] Evergreen ILS branch master updated. b577e78fa1fd0fd38e218f135c9afa044d3ff591

Evergreen Git git at git.evergreen-ils.org
Fri Sep 6 15:00:38 EDT 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  b577e78fa1fd0fd38e218f135c9afa044d3ff591 (commit)
       via  64185354778e716d021159c653b6367ca3c2e366 (commit)
       via  36a39ad2c720c930139f07214094496593be78ff (commit)
      from  c839ede49b09f6f24c31f293f1d49f4a8dc53f82 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b577e78fa1fd0fd38e218f135c9afa044d3ff591
Author: Galen Charlton <gmc at equinoxinitiative.org>
Date:   Fri Sep 6 15:00:26 2019 -0400

    LP#1840327: add release notes
    
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/docs/RELEASE_NOTES_NEXT/Administration/standing-penalty-admin.adoc b/docs/RELEASE_NOTES_NEXT/Administration/standing-penalty-admin.adoc
new file mode 100644
index 0000000000..89ab304a86
--- /dev/null
+++ b/docs/RELEASE_NOTES_NEXT/Administration/standing-penalty-admin.adoc
@@ -0,0 +1,6 @@
+Angular Standing Penalty Admin Page
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Migrate the Administration => Local Administration => Standing Penalties
+page to Angular.
+

commit 64185354778e716d021159c653b6367ca3c2e366
Author: Galen Charlton <gmc at equinoxinitiative.org>
Date:   Fri Sep 6 14:57:13 2019 -0400

    LP#1840327: (follow-up) various fixes and improvements
    
    * Fixed inabiilty to set the name for a new standing penalty
    * Fixed the 'Delete Selected' action
    * adjust for recId => recordId change to FM record editor
    * remove a bit of copy-and-paste-itis
    * Lint repairs
    
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
index e5ed4006ba..c775fe3b54 100644
--- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
@@ -460,7 +460,7 @@ export class FmRecordEditorComponent
 
         let promise = null;
         const fieldOptions = this.fieldOptions[field.name] || {};
-                
+
         if (this.mode === 'view') {
             field.readOnly = true;
         } else if (fieldOptions.isReadonlyOverride) {
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
index 351d1cbda5..e8cfaf047a 100644
--- a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
@@ -2,9 +2,13 @@
 <eg-staff-banner bannerText="Standing Penalty Types" i18n-bannerText>
 </eg-staff-banner>
 
+<eg-string #successString i18n-text text="Standing Penalty Update Succeeded"></eg-string>
+<eg-string #deleteFailedString i18n-text text="Delete of Standing Penalty failed or was not allowed"></eg-string>
+<eg-string #deleteSuccessString i18n-text text="Delete of Standing Penalty succeeded"></eg-string>
 <eg-string #cspFlairTooltip i18n-text text="Limited Editing"></eg-string>
+
 <div class="w-100 mt-2 mb-2">
-  <eg-grid idlClass="csp"
+  <eg-grid #grid idlClass="csp"
     [dataSource]="cspSource"
     [rowFlairIsEnabled]="true"
     [rowFlairCallback]="cspRowFlairCallback"
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
index f1c4bd582f..a8b60b8d17 100644
--- a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
@@ -17,41 +17,34 @@ export class StandingPenaltyComponent implements OnInit {
     gridDataSource: GridDataSource;
     initDone = false;
     cspSource: GridDataSource = new GridDataSource();
-    @ViewChild('partsGrid') partsGrid: GridComponent;
+
     @ViewChild('editDialog') editDialog: FmRecordEditorComponent;
     @ViewChild('grid') grid: GridComponent;
     @ViewChild('successString') successString: StringComponent;
     @ViewChild('createString') createString: StringComponent;
     @ViewChild('createErrString') createErrString: StringComponent;
     @ViewChild('updateFailedString') updateFailedString: StringComponent;
+    @ViewChild('deleteFailedString') deleteFailedString: StringComponent;
+    @ViewChild('deleteSuccessString') deleteSuccessString: StringComponent;
     @ViewChild('cspFlairTooltip') private cspFlairTooltip: StringComponent;
-    
+
     cspRowFlairCallback: (row: any) => GridRowFlairEntry;
 
     canCreate: boolean;
     canDelete: boolean;
     deleteSelected: (rows: IdlObject[]) => void;
-    
+
     permissions: {[name: string]: boolean};
 
     // Default sort field, used when no grid sorting is applied.
     @Input() sortField: string;
 
-    @Input() idlClass: string = "csp";
+    @Input() idlClass = 'csp';
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
     // Optional comma-separated list of read-only fields
     // @Input() readonlyFields: string;
 
-    @Input() set recordId(id: number) {
-        this.recId = id;
-        // Only force new data collection when recordId()
-        // is invoked after ngInit() has already run.
-        if (this.initDone) {
-            this.partsGrid.reload();
-        }
-    }
-
     constructor(
         private pcrud: PcrudService,
         private toast: ToastService
@@ -70,42 +63,59 @@ export class StandingPenaltyComponent implements OnInit {
                 // Default sort field
                 orderBy[this.idlClass] = this.sortField;
             }
-        
+
             const searchOps = {
                 offset: pager.offset,
                 limit: pager.limit,
                 order_by: orderBy
             };
             return this.pcrud.retrieveAll('csp', searchOps, {fleshSelectors: true});
-        }
-        
-        this.cspRowFlairCallback = (row: any): GridRowFlairEntry => {        
+        };
+
+        this.cspRowFlairCallback = (row: any): GridRowFlairEntry => {
             const flair = {icon: null, title: null};
             if (row.id() < 100) {
                 flair.icon = 'not_interested';
                 flair.title = this.cspFlairTooltip.text;
             }
             return flair;
-        }
+        };
+
+        this.deleteSelected = (idlThings: IdlObject[]) => {
+            idlThings.forEach(idlThing => idlThing.isdeleted(true));
+            this.pcrud.autoApply(idlThings).subscribe(
+                val => {
+                    console.debug('deleted: ' + val);
+                    this.deleteSuccessString.current()
+                        .then(str => this.toast.success(str));
+                },
+                err => {
+                    this.deleteFailedString.current()
+                        .then(str => this.toast.danger(str));
+                },
+                ()  => this.grid.reload()
+            );
+        };
+
     }
 
-    cspReadonlyOverride = (field: string, copy: IdlObject): boolean => {
-        if (copy.id() >= 100) {
+    cspReadonlyOverride = (field: string, csp: IdlObject): boolean => {
+        if (csp.id() >= 100 || csp.id() === undefined) {
             return true;
         }
         return false;
     }
 
     cspGridCellClassCallback = (row: any, col: GridColumn): string => {
-        if (col.name === "id" && row.a[0] < 100) {
-            return "text-danger";
+        if (col.name === 'id' && row.a[0] < 100) {
+            return 'text-danger';
         }
-        return "";
-    };
+        return '';
+    }
 
     showEditDialog(standingPenalty: IdlObject): Promise<any> {
         this.editDialog.mode = 'update';
-        this.editDialog.recId = standingPenalty["id"]();
+        this.editDialog.recordId = standingPenalty['id']();
         return new Promise((resolve, reject) => {
             this.editDialog.open({size: this.dialogSize}).subscribe(
                 result => {
@@ -139,7 +149,7 @@ export class StandingPenaltyComponent implements OnInit {
         this.editDialog.mode = 'create';
         // We reuse the same editor for all actions.  Be sure
         // create action does not try to modify an existing record.
-        this.editDialog.recId = null;
+        this.editDialog.recordId = null;
         this.editDialog.record = null;
         this.editDialog.open({size: this.dialogSize}).subscribe(
             ok => {
@@ -155,6 +165,6 @@ export class StandingPenaltyComponent implements OnInit {
             }
         );
     }
-           
+
 }
 

commit 36a39ad2c720c930139f07214094496593be78ff
Author: Mike Risher <mrisher at catalyte.io>
Date:   Tue Aug 20 20:29:23 2019 +0000

    LP#1840327: port standing penalty admin interface to Angular
    
    Convert standing penalty types admin UI from DOJO to Angular. Name
    field is read only if the ID is below 100.  Doing this involved:
    
    - creating a new standing penalty component
    - using rowFlairCallback functionality in the grid, so that an icon
      and tooltip is shown for fields where the name cannot be edited
    - making the ID show up in red text when it is below 100
    - adding "readonly Override" functionality to fm-editor, so that
      some fields of a given type are read only, but others are not
    
    Signed-off-by: Mike Risher <mrisher at catalyte.io>
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
index a4fc62ba73..e5ed4006ba 100644
--- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
@@ -67,6 +67,11 @@ export interface FmFieldOptions {
     // This only has an affect if the value is true.
     isReadonly?: boolean;
 
+    // If this function is defined, the function will be called
+    // at render time to see if the field should be marked readonly.
+    // This supersedes all other isReadonly specifiers.
+    isReadonlyOverride?: (field: string, record: IdlObject) => boolean;
+
     // Render the field using this custom template instead of chosing
     // from the default set of form inputs.
     customTemplate?: CustomFieldTemplate;
@@ -455,10 +460,16 @@ export class FmRecordEditorComponent
 
         let promise = null;
         const fieldOptions = this.fieldOptions[field.name] || {};
-
-        field.readOnly = this.mode === 'view'
-            || fieldOptions.isReadonly === true
-            || this.readonlyFieldsList.includes(field.name);
+                
+        if (this.mode === 'view') {
+            field.readOnly = true;
+        } else if (fieldOptions.isReadonlyOverride) {
+            field.readOnly =
+                !fieldOptions.isReadonlyOverride(field.name, this.record);
+        } else {
+            field.readOnly = fieldOptions.isReadonly === true
+                || this.readonlyFieldsList.includes(field.name);
+        }
 
         if (fieldOptions.isRequiredOverride) {
             field.isRequired = () => {
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html
index 870deeb8dc..02565dfafa 100644
--- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html
@@ -55,7 +55,7 @@
     <eg-link-table-link i18n-label label="Search Filter Groups" 
       url="/eg/staff/admin/local/actor/search_filter_group"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Standing Penalties" 
-      url="/eg/staff/admin/local/config/standing_penalty"></eg-link-table-link>
+      routerLink="/staff/admin/local/config/standing_penalty"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Statistical Categories Editor" 
       url="/eg/staff/admin/local/asset/stat_cat_editor"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Statistical Popularity Badges" 
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local.module.ts
index 7c8a6fa7cb..9f70ab78d6 100644
--- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local.module.ts
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local.module.ts
@@ -6,12 +6,14 @@ import {AdminCommonModule} from '@eg/staff/admin/common.module';
 import {AdminLocalSplashComponent} from './admin-local-splash.component';
 import {AddressAlertComponent} from './address-alert.component';
 import {AdminCarouselComponent} from './admin-carousel.component';
+import {StandingPenaltyComponent} from './standing-penalty.component';
 
 @NgModule({
   declarations: [
       AdminLocalSplashComponent,
       AddressAlertComponent,
-      AdminCarouselComponent
+      AdminCarouselComponent,
+      StandingPenaltyComponent
   ],
   imports: [
     AdminCommonModule,
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts
index 4eda5855c4..39c6be7179 100644
--- a/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts
@@ -4,6 +4,7 @@ import {AdminLocalSplashComponent} from './admin-local-splash.component';
 import {BasicAdminPageComponent} from '@eg/staff/admin/basic-admin-page.component';
 import {AddressAlertComponent} from './address-alert.component';
 import {AdminCarouselComponent} from './admin-carousel.component';
+import {StandingPenaltyComponent} from './standing-penalty.component';
 
 const routes: Routes = [{
     path: 'splash',
@@ -19,6 +20,9 @@ const routes: Routes = [{
     path: 'container/carousel',
     component: AdminCarouselComponent
 }, {
+    path: 'config/standing_penalty',
+    component: StandingPenaltyComponent
+}, {
     path: ':schema/:table',
     component: BasicAdminPageComponent
 }];
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
new file mode 100644
index 0000000000..351d1cbda5
--- /dev/null
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
@@ -0,0 +1,28 @@
+<eg-title i18n-prefix prefix="Standing Penalty Administration"></eg-title>
+<eg-staff-banner bannerText="Standing Penalty Types" i18n-bannerText>
+</eg-staff-banner>
+
+<eg-string #cspFlairTooltip i18n-text text="Limited Editing"></eg-string>
+<div class="w-100 mt-2 mb-2">
+  <eg-grid idlClass="csp"
+    [dataSource]="cspSource"
+    [rowFlairIsEnabled]="true"
+    [rowFlairCallback]="cspRowFlairCallback"
+    [cellClassCallback]="cspGridCellClassCallback"
+    [sortable]="true">
+    <eg-grid-toolbar-button 
+      label="New Standing Penalty Type" i18n-label (onClick)="createNew()">
+    </eg-grid-toolbar-button>
+    <eg-grid-toolbar-action label="Edit Selected" i18n-label (onClick)="editSelected($event)">
+    </eg-grid-toolbar-action>
+    <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelected($event)">
+    </eg-grid-toolbar-action>
+  </eg-grid>
+</div>
+
+<eg-fm-record-editor #editDialog
+  idlClass="csp" 
+  [fieldOptions]="{name: {isReadonlyOverride: cspReadonlyOverride}}" 
+  [preloadLinkedValues]="true" 
+  readonlyFields="name">
+</eg-fm-record-editor>
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
new file mode 100644
index 0000000000..f1c4bd582f
--- /dev/null
+++ b/Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
@@ -0,0 +1,160 @@
+import {Pager} from '@eg/share/util/pager';
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {GridDataSource, GridColumn, GridRowFlairEntry} from '@eg/share/grid/grid';
+import {IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
+import {StringComponent} from '@eg/share/string/string.component';
+import {ToastService} from '@eg/share/toast/toast.service';
+
+ at Component({
+    templateUrl: './standing-penalty.component.html'
+})
+
+export class StandingPenaltyComponent implements OnInit {
+    recId: number;
+    gridDataSource: GridDataSource;
+    initDone = false;
+    cspSource: GridDataSource = new GridDataSource();
+    @ViewChild('partsGrid') partsGrid: GridComponent;
+    @ViewChild('editDialog') editDialog: FmRecordEditorComponent;
+    @ViewChild('grid') grid: GridComponent;
+    @ViewChild('successString') successString: StringComponent;
+    @ViewChild('createString') createString: StringComponent;
+    @ViewChild('createErrString') createErrString: StringComponent;
+    @ViewChild('updateFailedString') updateFailedString: StringComponent;
+    @ViewChild('cspFlairTooltip') private cspFlairTooltip: StringComponent;
+    
+    cspRowFlairCallback: (row: any) => GridRowFlairEntry;
+
+    canCreate: boolean;
+    canDelete: boolean;
+    deleteSelected: (rows: IdlObject[]) => void;
+    
+    permissions: {[name: string]: boolean};
+
+    // Default sort field, used when no grid sorting is applied.
+    @Input() sortField: string;
+
+    @Input() idlClass: string = "csp";
+    // Size of create/edito dialog.  Uses large by default.
+    @Input() dialogSize: 'sm' | 'lg' = 'lg';
+    // Optional comma-separated list of read-only fields
+    // @Input() readonlyFields: string;
+
+    @Input() set recordId(id: number) {
+        this.recId = id;
+        // Only force new data collection when recordId()
+        // is invoked after ngInit() has already run.
+        if (this.initDone) {
+            this.partsGrid.reload();
+        }
+    }
+
+    constructor(
+        private pcrud: PcrudService,
+        private toast: ToastService
+    ) {
+        this.gridDataSource = new GridDataSource();
+    }
+
+    ngOnInit() {
+        this.initDone = true;
+        this.cspSource.getRows = (pager: Pager, sort: any[]) => {
+            const orderBy: any = {};
+            if (sort.length) {
+                // Sort specified from grid
+                orderBy[this.idlClass] = sort[0].name + ' ' + sort[0].dir;
+            } else if (this.sortField) {
+                // Default sort field
+                orderBy[this.idlClass] = this.sortField;
+            }
+        
+            const searchOps = {
+                offset: pager.offset,
+                limit: pager.limit,
+                order_by: orderBy
+            };
+            return this.pcrud.retrieveAll('csp', searchOps, {fleshSelectors: true});
+        }
+        
+        this.cspRowFlairCallback = (row: any): GridRowFlairEntry => {        
+            const flair = {icon: null, title: null};
+            if (row.id() < 100) {
+                flair.icon = 'not_interested';
+                flair.title = this.cspFlairTooltip.text;
+            }
+            return flair;
+        }
+    }
+
+    cspReadonlyOverride = (field: string, copy: IdlObject): boolean => {
+        if (copy.id() >= 100) {
+            return true;
+        }
+        return false;
+    }
+
+    cspGridCellClassCallback = (row: any, col: GridColumn): string => {
+        if (col.name === "id" && row.a[0] < 100) {
+            return "text-danger";
+        }
+        return "";
+    };
+
+    showEditDialog(standingPenalty: IdlObject): Promise<any> {
+        this.editDialog.mode = 'update';
+        this.editDialog.recId = standingPenalty["id"]();
+        return new Promise((resolve, reject) => {
+            this.editDialog.open({size: this.dialogSize}).subscribe(
+                result => {
+                    this.successString.current()
+                        .then(str => this.toast.success(str));
+                    this.grid.reload();
+                    resolve(result);
+                },
+                error => {
+                    this.updateFailedString.current()
+                        .then(str => this.toast.danger(str));
+                    reject(error);
+                }
+            );
+        });
+    }
+
+    editSelected(standingPenaltyFields: IdlObject[]) {
+        // Edit each IDL thing one at a time
+        const editOneThing = (standingPenalty: IdlObject) => {
+            if (!standingPenalty) { return; }
+
+            this.showEditDialog(standingPenalty).then(
+                () => editOneThing(standingPenaltyFields.shift()));
+        };
+
+        editOneThing(standingPenaltyFields.shift());
+    }
+
+    createNew() {
+        this.editDialog.mode = 'create';
+        // We reuse the same editor for all actions.  Be sure
+        // create action does not try to modify an existing record.
+        this.editDialog.recId = null;
+        this.editDialog.record = null;
+        this.editDialog.open({size: this.dialogSize}).subscribe(
+            ok => {
+                this.createString.current()
+                    .then(str => this.toast.success(str));
+                this.grid.reload();
+            },
+            rejection => {
+                if (!rejection.dismissed) {
+                    this.createErrString.current()
+                        .then(str => this.toast.danger(str));
+                }
+            }
+        );
+    }
+           
+}
+

-----------------------------------------------------------------------

Summary of changes:
 .../src/app/share/fm-editor/fm-editor.component.ts |  17 ++-
 .../admin/local/admin-local-splash.component.html  |   2 +-
 .../app/staff/admin/local/admin-local.module.ts    |   4 +-
 .../src/app/staff/admin/local/routing.module.ts    |   4 +
 .../admin/local/standing-penalty.component.html    |  32 ++++
 .../admin/local/standing-penalty.component.ts      | 170 +++++++++++++++++++++
 .../Administration/standing-penalty-admin.adoc     |   6 +
 7 files changed, 230 insertions(+), 5 deletions(-)
 create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.html
 create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/standing-penalty.component.ts
 create mode 100644 docs/RELEASE_NOTES_NEXT/Administration/standing-penalty-admin.adoc


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list