LP#1929242: add interface for editing bib record notes
authorRogan Hamby <rogan.hamby@gmail.com>
Thu, 5 Aug 2021 18:01:48 +0000 (18:01 +0000)
committerGalen Charlton <gmc@equinoxOLI.org>
Mon, 20 Sep 2021 21:24:45 +0000 (17:24 -0400)
This adds an Angular interface for editing bibliographic
record notes, i.e., notes stored in the biblio.record_note
table.

Signed-off-by: Rogan Hamby <rogan.hamby@gmail.com>
Signed-off-by: Ruth Frasur <rfrasur@library.in.gov>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>

Open-ILS/examples/fm_IDL.xml
Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts
Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.html
Open-ILS/src/sql/Pg/010.schema.biblio.sql
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/xxxx.data.record_notes.sql [new file with mode: 0644]

index c3571d9..4cfdd3f 100644 (file)
@@ -7454,22 +7454,31 @@ SELECT  usr,
             </actions>
         </permacrud>
        </class>
-       <class id="bren" controller="open-ils.cstore" oils_obj:fieldmapper="biblio::record_note" oils_persist:tablename="biblio.record_note" reporter:label="Bib Record Note">
+       <class id="bren" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="biblio::record_note" oils_persist:tablename="biblio.record_note" reporter:label="Bib Record Note" oils_persist:field_safe="true">
                <fields oils_persist:primary="id" oils_persist:sequence="biblio.record_note_id_seq">
-                       <field name="create_date" reporter:datatype="timestamp"/>
-                       <field name="creator" reporter:datatype="link"/>
-                       <field name="edit_date" reporter:datatype="timestamp"/>
-                       <field name="editor" reporter:datatype="link"/>
-                       <field name="id" reporter:datatype="id" />
-                       <field name="pub" reporter:datatype="bool"/>
-                       <field name="record" reporter:datatype="link"/>
-                       <field name="value"  reporter:datatype="text"/>
+                       <field reporter:label="Creation Date" name="create_date" reporter:datatype="timestamp"/>
+                       <field reporter:label="Creator" name="creator" reporter:datatype="link"/>
+                       <field reporter:label="Last Edit Date" name="edit_date" reporter:datatype="timestamp"/>
+                       <field reporter:label="Editor" name="editor" reporter:datatype="link"/>
+                       <field reporter:label="Note ID" name="id" reporter:datatype="id" />
+                       <field reporter:label="Public" name="pub" reporter:datatype="bool"/>
+                       <field reporter:label="Bib Record" name="record" reporter:datatype="link"/>
+                       <field reporter:label="Note" name="value" reporter:datatype="text"/>
+                       <field reporter:label="Deleted" name="deleted" reporter:datatype="bool"/> 
                </fields>
                <links>
                        <link field="creator" reltype="has_a" key="id" map="" class="au"/>
                        <link field="editor" reltype="has_a" key="id" map="" class="au"/>
                        <link field="record" reltype="has_a" key="id" map="" class="bre"/>
                </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+                <actions>
+                    <create permission="CREATE_RECORD_NOTE" global_required="true"/>
+                    <retrieve/>
+                    <update permission="UPDATE_RECORD_NOTE" global_required="true"/>
+                    <delete permission="DELETE_RECORD_NOTE" global_required="true"/>
+                </actions>
+             </permacrud>
        </class>
        <class id="mucs" controller="open-ils.cstore" oils_obj:fieldmapper="money::user_circulation_summary" oils_persist:tablename="money.usr_circulation_summary" reporter:label="User Circulation Summary">
                <fields oils_persist:primary="usr" oils_persist:sequence="">
index 89eb2b0..2108000 100644 (file)
@@ -20,6 +20,7 @@ import {RecordActionsComponent} from './record/actions.component';
 import {BasketActionsComponent} from './basket-actions.component';
 import {HoldComponent} from './hold/hold.component';
 import {PartsComponent} from './record/parts.component';
+import {NotesComponent} from './record/notes.component';
 import {AddToCarouselDialogComponent} from './record/add-to-carousel-dialog.component';
 import {PartMergeDialogComponent} from './record/part-merge-dialog.component';
 import {BrowseComponent} from './browse.component';
@@ -48,6 +49,7 @@ import {BrowsePagerComponent} from './result/browse-pager.component';
     BasketActionsComponent,
     HoldComponent,
     PartsComponent,
+    NotesComponent,
     AddToCarouselDialogComponent,
     PartMergeDialogComponent,
     BrowseComponent,
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.html
new file mode 100644 (file)
index 0000000..9c7e2e9
--- /dev/null
@@ -0,0 +1,18 @@
+<div class="mt-3">
+
+  <eg-grid #notesGrid idlClass="bren" [dataSource]="gridDataSource"
+      [sortable]="true" persistKey="catalog.record.notes"
+      showFields="value,create_date" class="mt-3">
+    <eg-grid-toolbar-button [disabled]="!permissions.CREATE_RECORD_NOTE"
+      label="New Record Note" i18n-label [action]="createNew">
+    </eg-grid-toolbar-button>
+    <eg-grid-toolbar-action label="Delete Selected" i18n-label [action]="deleteSelected">
+    </eg-grid-toolbar-action>
+  </eg-grid>
+  
+  <eg-fm-record-editor #editDialog idlClass="bren"
+    readonlyFields="id,create_date,edit_date,creator,editor"
+    hiddenFields="record,deleted">
+  </eg-fm-record-editor>
+
+</div>
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/notes.component.ts
new file mode 100644 (file)
index 0000000..b489190
--- /dev/null
@@ -0,0 +1,110 @@
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {Pager} from '@eg/share/util/pager';
+import {OrgService} from '@eg/core/org.service';
+import {PermService} from '@eg/core/perm.service';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
+
+@Component({
+  selector: 'eg-catalog-record-notes',
+  templateUrl: 'notes.component.html'
+})
+export class NotesComponent implements OnInit {
+
+    recId: number;
+    gridDataSource: GridDataSource;
+    initDone: boolean;
+    @ViewChild('notesGrid', { static: true }) notesGrid: GridComponent;
+    @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
+
+    canCreate: boolean;
+    canDelete: boolean;
+    createNew: () => void;
+    deleteSelected: (rows: IdlObject[]) => void;
+    permissions: {[name: string]: boolean};
+
+    @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.notesGrid.reload();
+        }
+    }
+
+    get recordId(): number {
+        return this.recId;
+    }
+
+    constructor(
+        private idl: IdlService,
+        private org: OrgService,
+        private pcrud: PcrudService,
+        private perm: PermService
+    ) {
+        this.permissions = {};
+        this.gridDataSource = new GridDataSource();
+    }
+
+    ngOnInit() {
+        this.initDone = true;
+
+        // Load edit perms
+        this.perm.hasWorkPermHere([
+            'CREATE_RECORD_NOTE',
+            'UPDATE_RECORD_NOTE',
+            'DELETE_RECORD_NOTE'
+        ]).then(perms => this.permissions = perms);
+
+        this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+            const orderBy: any = {};
+
+            if (sort.length) { // Sort provided by grid.
+                orderBy.bren = sort[0].name + ' ' + sort[0].dir;
+            } else {
+                orderBy.bren = 'edit_date';
+            }
+
+            const searchOps = {
+                offset: pager.offset,
+                limit: pager.limit,
+                order_by: orderBy
+            };
+
+            return this.pcrud.search('bren',
+                {record: this.recId, deleted: 'f'}, searchOps);
+        };
+
+        this.notesGrid.onRowActivate.subscribe(
+            (note: IdlObject) => {
+                this.editDialog.mode = 'update';
+                this.editDialog.recordId = note.id();
+                this.editDialog.open()
+                    .subscribe(ok => this.notesGrid.reload());
+            }
+        );
+
+        this.createNew = () => {
+
+            const note = this.idl.create('bren');
+            note.record(this.recordId);
+            this.editDialog.record = note;
+
+            this.editDialog.mode = 'create';
+            this.editDialog.open().subscribe(ok => this.notesGrid.reload());
+        };
+
+        this.deleteSelected = (notes: IdlObject[]) => {
+            notes.forEach(note => note.isdeleted(true));
+            this.pcrud.autoApply(notes).subscribe(
+                val => console.debug('deleted: ' + val),
+                err => {},
+                ()  => this.notesGrid.reload()
+            );
+        };
+    }
+}
+
index c245e88..3d7ee74 100644 (file)
           <eg-marc-html [recordId]="recordId" recordType="bib"></eg-marc-html>
         </ng-template>
       </ngb-tab>
+      <ngb-tab title="Record Notes" i18n-title id="bibnotes">
+        <ng-template ngbTabContent>
+          <eg-catalog-record-notes [recordId]="recordId">
+          </eg-catalog-record-notes>
+        </ng-template>
+      </ngb-tab>
       <ngb-tab title="View Holds" i18n-title id="holds">
         <ng-template ngbTabContent>
           <eg-holds-grid [recordId]="recordId"
index 857307e..12731d2 100644 (file)
@@ -75,6 +75,7 @@ CREATE TABLE biblio.record_note (
        creator         INT             NOT NULL DEFAULT 1,
        editor          INT             NOT NULL DEFAULT 1,
        pub             BOOL            NOT NULL DEFAULT FALSE,
+       deleted         BOOL            NOT NULL DEFAULT FALSE,
        create_date     TIMESTAMP WITH TIME ZONE        NOT NULL DEFAULT now(),
        edit_date       TIMESTAMP WITH TIME ZONE        NOT NULL DEFAULT now()
 );
index 7f39bb3..04ada6e 100644 (file)
@@ -1959,6 +1959,12 @@ INSERT INTO permission.perm_list ( id, code, description ) VALUES
     'Administer geographic location services', 'ppl', 'description')),
  ( 632, 'UPDATE_USER_PHOTO_URL', oils_i18n_gettext(632,
     'Update the user photo url field in patron registration and editor', 'ppl', 'description'))
+ ( 633, 'CREATE_RECORD_NOTE', oils_i18n_gettext(633,
+    'Allow the user to create a record note', 'ppl', 'description')),
+ ( 634, 'UPDATE_RECORD_NOTE', oils_i18n_gettext(634,
+    'Allow the user to update a record note', 'ppl', 'description')),
+ ( 635, 'DELETE_RECORD_NOTE', oils_i18n_gettext(635,
+    'Allow the user to delete a record note', 'ppl', 'description'))
 ;
 
 
@@ -2216,7 +2222,10 @@ INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
                        'VIEW_AUTHORITY_RECORD_NOTES',
                        'CREATE_AUTHORITY_RECORD',
                        'DELETE_AUTHORITY_RECORD',
-                       'UPDATE_AUTHORITY_RECORD');
+                       'UPDATE_AUTHORITY_RECORD',
+                       'CREATE_RECORD_NOTE',
+                       'UPDATE_RECORD_NOTE',
+                       'DELETE_RECORD_NOTE');
 
 INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
        SELECT
diff --git a/Open-ILS/src/sql/Pg/upgrade/xxxx.data.record_notes.sql b/Open-ILS/src/sql/Pg/upgrade/xxxx.data.record_notes.sql
new file mode 100644 (file)
index 0000000..b3d4992
--- /dev/null
@@ -0,0 +1,16 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('xxxx', :eg_version);
+
+
+ALTER TABLE biblio.record_note ADD COLUMN deleted BOOLEAN DEFAULT FALSE;
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+( 633, 'CREATE_RECORD_NOTE', oils_i18n_gettext(633,
+   'Allow the user to create a record note', 'ppl', 'description')),
+( 634, 'UPDATE_RECORD_NOTE', oils_i18n_gettext(634,
+   'Allow the user to update a record note', 'ppl', 'description')),
+( 635, 'DELETE_RECORD_NOTE', oils_i18n_gettext(635,
+   'Allow the user to delete a record note', 'ppl', 'description'));
+
+COMMIT;