LP1849212: Use a set list of roles
authorJane Sandberg <sandbej@linnbenton.edu>
Wed, 2 Sep 2020 04:24:08 +0000 (21:24 -0700)
committerJane Sandberg <sandbej@linnbenton.edu>
Wed, 2 Sep 2020 16:10:36 +0000 (09:10 -0700)
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-users.component.html
Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-users.component.ts
Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-list.component.html
Open-ILS/src/eg2/src/app/staff/share/course.service.ts
Open-ILS/src/sql/Pg/040.schema.asset.sql
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.course-materials-module.sql

index e3c2969..8384204 100644 (file)
@@ -3081,12 +3081,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
             <field reporter:label="ID" name="id" reporter:datatype="id" />
             <field reporter:label="Course" name="course" reporter:datatype="link" />
             <field reporter:label="User" name="usr" reporter:datatype="link" />
-            <field reporter:label="User Role" name="usr_role" reporter:datatype="text" />
-            <field reporter:label="OPAC Viewable?" name="is_public" reporter:datatype="bool" />
+            <field reporter:label="User Role" name="usr_role" reporter:datatype="link" />
         </fields>
         <links>
             <link field="course" reltype="has_a" key="id" map="" class="acmc" />
             <link field="usr" reltype="has_a" key="id" map="" class="au" />
+            <link field="usr_role" reltype="has_a" key="id" map="" class="acmr" />
         </links>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
             <actions>
@@ -3189,6 +3189,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
             </actions>
         </permacrud>
     </class>
+       <class id="acmr" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::course_module_role" oils_persist:tablename="asset.course_module_role" reporter:label="Course Role" oils_persist:field_safe="true">
+               <fields oils_persist:primary="id" oils_persist:sequence="asset.course_module_role_id_seq">
+                       <field reporter:label="Role ID" name="id" reporter:datatype="id" reporter:selector="name"/>
+                       <field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true" oils_obj:required="true"/>
+            <field reporter:label="OPAC Viewable?" name="is_public" reporter:datatype="bool" />
+               </fields>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+                       <actions>
+                               <create permission="MANAGE_RESERVES" global_required="true" />
+                               <retrieve/>
+                               <update permission="MANAGE_RESERVES" global_required="true" />
+                               <delete permission="MANAGE_RESERVES" global_required="true" />
+                       </actions>
+               </permacrud>
+       </class>
        
     <class id="acnc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_class" oils_persist:tablename="asset.call_number_class" reporter:label="Call number classification scheme">
         <fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_class_id_seq">
index f96087d..47dfce1 100644 (file)
             <div class="input-group-prepend">
               <label for="associate-user-role" class="input-group-text" i18n>Role</label>
             </div>
-            <input type="text" [(ngModel)]="userRoleInput" id="associate-user-role"
-              [disabled]="currentCourse && currentCourse.is_archived() == 't'"
-              placeholder-i18n placeholder="e.g. Student, TA, Instructor..."
-              class="flex-grow-1" />
+            <eg-combobox idlClass="acmr" [(ngModel)]="userRoleInput"
+            [disabled]="currentCourse && currentCourse.is_archived() == 't'">
+            </eg-combobox>
           </div>
         </div>
       </div>
@@ -84,8 +83,8 @@
         <eg-grid-column label="Preferred Second Name" path="usr.pref_second_given_name"[hidden]="true"  i18n-label></eg-grid-column>
         <eg-grid-column label="Preferred Family Name" path="usr.pref_family_name"[hidden]="true"  i18n-label></eg-grid-column>
         <eg-grid-column label="Preferred Suffix" path="usr.pref_suffix" [hidden]="true" i18n-label></eg-grid-column>
-        <eg-grid-column label="User Role" path="usr_role" i18n-label></eg-grid-column>
-        <eg-grid-column label="Viewable on OPAC" path="is_public" i18n-label datatype="bool"></eg-grid-column>
+        <eg-grid-column label="User Role" path="usr_role.name" i18n-label></eg-grid-column>
+        <eg-grid-column label="Viewable on OPAC" path="usr_role.is_public" i18n-label datatype="bool"></eg-grid-column>
       </eg-grid>
     </div>
   </div>
index d9360cc..ec178ec 100644 (file)
@@ -1,3 +1,4 @@
+import { ComboboxEntry } from '@eg/share/combobox/combobox.component';
 import {Component, Input, ViewChild, OnInit} from '@angular/core';
 import {DialogComponent} from '@eg/share/dialog/dialog.component';
 import {AuthService} from '@eg/core/auth.service';
@@ -39,7 +40,7 @@ export class CourseAssociateUsersComponent extends DialogComponent implements On
         userEditFailedString: StringComponent;
     usersDataSource: GridDataSource;
     userBarcode: String;
-    userRoleInput: String;
+    userRoleInput: ComboboxEntry;
     isPublicRole: Boolean;
 
     constructor(
@@ -69,8 +70,7 @@ export class CourseAssociateUsersComponent extends DialogComponent implements On
             const args = {
                 currentCourse: this.currentCourse,
                 barcode: barcode.trim(),
-                role: this.userRoleInput,
-                is_public: this.isPublicRole
+                role: this.userRoleInput.id
             };
 
             this.userBarcode = null;
index 13f9932..3fac600 100644 (file)
@@ -33,7 +33,7 @@
           <eg-grid-column label="Section Number" name="section_number" i18n-label></eg-grid-column>
           <eg-grid-column label="Is Archived?" name="is_archived" i18n-label datatype="bool"></eg-grid-column>
         </eg-grid>
-      </div>      
+      </div>
     </ng-template>
   </li>
   <li ngbNavItem>
       <eg-admin-page idlClass="acmt"></eg-admin-page>
     </ng-template>
   </li>
+  <li ngbNavItem>
+    <a ngbNavLink i18n>Course roles</a>
+    <ng-template ngbNavContent>
+      <eg-admin-page idlClass="acmr"></eg-admin-page>
+    </ng-template>
+  </li>
 </ul>
 <div [ngbNavOutlet]="courseListNav"></div>
 
index c3e480d..43caf76 100644 (file)
@@ -53,7 +53,7 @@ export class CourseService {
     getUsers(course_ids?: Number[]): Observable<IdlObject> {
         const flesher = {
             flesh: 1,
-            flesh_fields: {'acmcu': ['usr']}
+            flesh_fields: {'acmcu': ['usr', 'usr_role']}
         };
         if (!course_ids) {
             return this.pcrud.retrieveAll('acmcu',
@@ -134,7 +134,6 @@ export class CourseService {
 
     associateUsers(patron_id, args) {
         const new_user = this.idl.create('acmcu');
-        if (args.is_public) { new_user.is_public(args.is_public); }
         if (args.role) { new_user.usr_role(args.role); }
         new_user.course(args.currentCourse.id());
         new_user.usr(patron_id);
index 9d7444f..d948f8d 100644 (file)
@@ -1118,8 +1118,7 @@ CREATE TABLE asset.course_module_course_users (
     id              SERIAL PRIMARY KEY,
     course          INT NOT NULL REFERENCES asset.course_module_course (id),
     usr             INT NOT NULL REFERENCES actor.usr (id),
-    usr_role        TEXT,
-    is_public       BOOLEAN NOT NULL DEFAULT false
+    usr_role        INT NOT NULL REFERENCES asset.course_module_role (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
 );
 
 CREATE TABLE asset.course_module_course_materials (
@@ -1144,6 +1143,12 @@ CREATE TABLE asset.course_module_term (
        end_date        TIMESTAMP WITH TIME ZONE
 );
 
+CREATE TABLE asset.course_module_role (
+    id              SERIAL  PRIMARY KEY,
+    name            TEXT    UNIQUE NOT NULL,
+    is_public       BOOLEAN NOT NULL DEFAULT false
+);
+
 CREATE TABLE asset.course_module_term_course_map (
     id              BIGSERIAL  PRIMARY KEY,
     term            INT     NOT NULL REFERENCES asset.course_module_term (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
index 9121785..58663bd 100644 (file)
@@ -20502,4 +20502,9 @@ INSERT INTO actor.org_unit_setting (org_unit, name, value)
     FROM config.bib_source
     WHERE source='Course materials module';
 
+INSERT INTO asset.course_module_role (id, name, is_public) VALUES
+(1, oils_i18n_gettext(1, 'Instructor', 'acmr', 'name'), true),
+(2, oils_i18n_gettext(2, 'Teaching assistant', 'acmr', 'name'), true),
+(3, oils_i18n_gettext(2, 'Student', 'acmr', 'name'), false);
+
 
index a7a2e02..c5dfeed 100644 (file)
@@ -15,8 +15,7 @@ CREATE TABLE asset.course_module_course_users (
     id              SERIAL PRIMARY KEY,
     course          INT NOT NULL REFERENCES asset.course_module_course (id),
     usr             INT NOT NULL REFERENCES actor.usr (id),
-    usr_role        TEXT,
-    is_public       BOOLEAN NOT NULL DEFAULT false
+    usr_role        INT NOT NULL REFERENCES asset.course_module_role (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
 );
 
 CREATE TABLE asset.course_module_course_materials (
@@ -25,11 +24,11 @@ CREATE TABLE asset.course_module_course_materials (
     item            INT REFERENCES asset.copy (id),
     relationship    TEXT,
     record          INT REFERENCES biblio.record_entry (id),
-    temporary_record         BOOLEAN,
-    original_location        INT REFERENCES asset.copy_location,
-    original_status          INT REFERENCES config.copy_status,
-    original_circ_modifier   TEXT, --REFERENCES config.circ_modifier,
-    original_callnumber      INT REFERENCES asset.call_number,
+    temporary_record       BOOLEAN,
+    original_location      INT REFERENCES asset.copy_location,
+    original_status        INT REFERENCES config.copy_status,
+    original_circ_modifier TEXT, --REFERENCES config.circ_modifier
+    original_callnumber    INT REFERENCES asset.call_number,
     unique (course, item, record)
 );
 
@@ -37,10 +36,21 @@ CREATE TABLE asset.course_module_term (
     id              SERIAL  PRIMARY KEY,
     name            TEXT    UNIQUE NOT NULL,
     owning_lib      INT REFERENCES actor.org_unit (id),
-       start_date      TIMESTAMP WITH TIME ZONE,
-       end_date        TIMESTAMP WITH TIME ZONE
+    start_date      TIMESTAMP WITH TIME ZONE,
+    end_date        TIMESTAMP WITH TIME ZONE
 );
 
+CREATE TABLE asset.course_module_role (
+    id              SERIAL  PRIMARY KEY,
+    name            TEXT    UNIQUE NOT NULL,
+    is_public       BOOLEAN NOT NULL DEFAULT false
+);
+
+INSERT INTO asset.course_module_role (id, name, is_public) VALUES
+(1, oils_i18n_gettext(1, 'Instructor', 'acmr', 'name'), true),
+(2, oils_i18n_gettext(2, 'Teaching assistant', 'acmr', 'name'), true),
+(3, oils_i18n_gettext(2, 'Student', 'acmr', 'name'), false);
+
 CREATE TABLE asset.course_module_term_course_map (
     id              BIGSERIAL  PRIMARY KEY,
     term            INT     NOT NULL REFERENCES asset.course_module_term (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,