<!-- End Input Sidebar -->
<div class="col-lg-8 mt-3">
<eg-grid #materialsGrid [dataSource]="materialsDataSource">
- <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelected($event)">
+ <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelectedMaterials($event)">
</eg-grid-toolbar-action>
<eg-grid-column path="id" [index]=true [hidden]="true" label="ID" i18n-label></eg-grid-column>
- <eg-grid-column label="Barcode" i18n-label name="barcode" [cellTemplate]="barcodeCellTemplate"></eg-grid-column>
+ <eg-grid-column label="Barcode" i18n-label name="card" [cellTemplate]="barcodeCellTemplate"></eg-grid-column>
<eg-grid-column label="Title" i18n-label name="title" [cellTemplate]="titleCellTemplate"></eg-grid-column>
<eg-grid-column path="call_number.label" label="Call Number" i18n-label></eg-grid-column>
<eg-grid-column path="call_number.prefix.label" [hidden]="true" label="Call Number Prefix" i18n-label hidden></eg-grid-column>
<div class="row mt-3">
<div class="col-lg-4 mt-3">
<div class="row mt-3">
- <div class="col-lg-12 d-flex">
+ <div class="col-lg-12 col-md-6 mt-3 d-flex">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" i18n>Patron Barcode</span>
</div>
<input type="text" class="flex-grow-1" [(ngModel)]="userBarcode"
(click)="$event.target.select()"
- [disabled]="currentCourse && currentCourse.is_archived() == 't'" />
- <!--(keyup.enter)="associateUser(userBarcode)"-->
+ [disabled]="currentCourse && currentCourse.is_archived() == 't'"
+ (keyup.enter)="associateUser(userBarcode)" />
</div>
</div>
- </div>
- <div class="row mt-3">
- <div class="col-lg-12 d-flex">
+ <div class="col-lg-12 col-md-6 mt-3 d-flex">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" i18n>Role</span>
</div>
</div>
<div class="row mt-3">
- <div class="col-lg-12 text-right">
- <!--(click)="associateUser(userBarcode)"-->
+ <div class="col-sm-6">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <div class="input-group-text">
+ <span i18n>Is Public Role?</span>
+ </div>
+ </div>
+ <div class="input-group-append">
+ <div class="input-group-text">
+ <input type="checkbox" [(ngModel)]="isPublicRole"
+ [disabled]="currentCourse && currentCourse.is_archived() == 't'"
+ aria-label="Checkbox for allowing user to display on the OPAC Course Page" />
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-6 text-right">
<button class="btn btn-primary"
[disabled]="currentCourse && currentCourse.is_archived() == 't'"
- i18n [disabled]="!userBarcode">
+ i18n [disabled]="!userBarcode" (click)="associateUser(userBarcode)">
Add User
</button>
</div>
</div>
</div>
<div class="col-lg-8 mt-3">
- <!-- eg-grid -->
+ <eg-grid #usersGrid [dataSource]="usersDataSource">
+ <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelectedUsers($event)">
+ </eg-grid-toolbar-action>
+ <eg-grid-column label="id" [index]=true [hidden]="true" i18n-label></eg-grid-column>
+ <eg-grid-column label="User Role" name="_role" i18n-label></eg-grid-column>
+ <eg-grid-column label="Viewable on OPAC" name="_is_public" i18n-label datatype="bool"></eg-grid-column>
+ <eg-grid-column label="First Name" name="first_given_name" i18n-label></eg-grid-column>
+ <eg-grid-column label="Second Name" name="second_given_name" i18n-label></eg-grid-column>
+ <eg-grid-column label="Last Name" name="family_name" i18n-label></eg-grid-column>
+ <eg-grid-column label="Prefix" name="pref_prefix" [hidden]="true" i18n-label></eg-grid-column>
+ <eg-grid-column label="Preferred First Name" name="pref_first_given_name"[hidden]="true" i18n-label></eg-grid-column>
+ <eg-grid-column label="Preferred Second Name" name="pref_second_given_name"[hidden]="true" i18n-label></eg-grid-column>
+ <eg-grid-column label="Preferred Family Name" name="pref_family_name"[hidden]="true" i18n-label></eg-grid-column>
+ <eg-grid-column label="Preferred Suffix" name="pref_suffix" [hidden]="true" i18n-label></eg-grid-column>
+ </eg-grid>
</div>
</div>
</ng-template>
<eg-string #materialDeleteSuccessString i18n-text text="Disassociation of Course Material succeeded"></eg-string>
<eg-string #materialAddSuccessString i18n-text text="Association of Course Material succeeded"></eg-string>
<eg-string #materialAddFailedString i18n-text text="Association of Course Material failed or was not allowed"></eg-string>
-<eg-string #MaterialAddDifferentLibraryString i18n-text text="Material exists at a different library"></eg-string>
\ No newline at end of file
+<eg-string #MaterialAddDifferentLibraryString i18n-text text="Material exists at a different library"></eg-string>
+<eg-string #userDeleteFailedString i18n-text text="Removal of User failed or was not allowed"></eg-string>
+<eg-string #userDeleteSuccessString i18n-text text="Removal of User succeeded"></eg-string>
+<eg-string #userAddSuccessString i18n-text text="Addition of User succeeded"></eg-string>
+<eg-string #userAddFailedString i18n-text text="Addition of User failed or was not allowed"></eg-string>
@Input() isModifyingLocation: Boolean;
// Users Tab
+ users: any[] = [];
+ @ViewChild('usersGrid', {static: true}) usersGrid: GridComponent;
+ @ViewChild('userDeleteFailedString', { static: true })
+ userDeleteFailedString: StringComponent;
+ @ViewChild('userDeleteSuccessString', { static: true })
+ userDeleteSuccessString: StringComponent;
+ @ViewChild('userAddSuccessString', { static: true })
+ userAddSuccessString: StringComponent;
+ @ViewChild('userAddFailedString', { static: true })
+ userAddFailedString: StringComponent;
+ usersDataSource: GridDataSource;
@Input() userBarcode: String;
@Input() userRoleInput: String;
+ @Input() isPublicRole: Boolean;
constructor(
private auth: AuthService,
private course: CourseService,
private event: EventService,
private idl: IdlService,
+ private net: NetService,
private org: OrgService,
private pcrud: PcrudService,
private route: ActivatedRoute,
private toast: ToastService
) {
this.materialsDataSource = new GridDataSource();
+ this.usersDataSource = new GridDataSource();
}
ngOnInit() {
this.course.getCourses([this.courseId]).then(course => {
this.currentCourse = course[0];
});
+ this.usersDataSource.getRows = (pager: Pager, sort: any[]) => {
+ return this.loadUsersGrid(pager);
+ }
this.materialsDataSource.getRows = (pager: Pager, sort: any[]) => {
return this.loadMaterialsGrid(pager);
}
}
}
- deleteSelected(items) {
+ deleteSelectedMaterials(items) {
let item_ids = [];
items.forEach(item => {
this.materialsDataSource.data.splice(this.materialsDataSource.data.indexOf(item, 0), 1);
);
});
}
+
+ // Users Tab
+ loadUsersGrid(pager: Pager): Observable<any> {
+ return new Observable<any>(observer => {
+ this.course.getUsers(this.courseId).then(users => {
+ users.forEach(user => {
+ console.log(user);
+ this.course.fleshUser(user.usr(), user.usr_role(), user.is_public()).then(fleshed_user => {
+ this.usersDataSource.data.push(fleshed_user);
+ });
+ });
+ });
+ observer.complete();
+ });
+ }
+
+ associateUser(barcode) {
+ if (barcode) {
+ let args = {
+ currentCourse: this.currentCourse,
+ barcode: barcode,
+ role: this.userRoleInput,
+ is_public: this.isPublicRole
+ }
+
+ this.userBarcode = null;
+
+ this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.user.retrieve_id_by_barcode_or_username',
+ this.auth.token(), barcode
+ ).subscribe(patron => {
+ let associatedUser = this.course.associateUsers(patron, args).then(res => {
+ this.course.fleshUser(
+ patron, args.role, args.is_public
+ ).then(fleshed_user => {
+ this.usersDataSource.data.push(fleshed_user);
+ this.userAddSuccessString.current().then(str => this.toast.success(str));
+ });
+ }, err => {
+ this.userAddFailedString.current().then(str => this.toast.danger(str));
+ });
+ });
+ }
+ }
+
+ deleteSelectedUsers(users) {
+ let user_ids = [];
+ users.forEach(user => {
+ this.usersDataSource.data.splice(this.usersDataSource.data.indexOf(user, 0), 1);
+ user_ids.push(user.id())
+ });
+ this.pcrud.search('acmcu', {course: this.courseId, usr: user_ids}).subscribe(user => {
+ user.isdeleted(true);
+ this.pcrud.autoApply(user).subscribe(
+ val => {
+ console.debug('deleted: ' + val);
+ this.userDeleteSuccessString.current().then(str => this.toast.success(str));
+ },
+ err => {
+ this.userDeleteFailedString.current()
+ .then(str => this.toast.danger(str));
+ }
+ );
+ });
+ }
}
\ No newline at end of file
}
}
+ getUsers(course_ids?: Number[]): Promise<IdlObject[]> {
+ if (!course_ids) {
+ return this.pcrud.retrieveAll('acmcu',
+ {}, {atomic: true}).toPromise();
+ } else {
+ return this.pcrud.search('acmcu', {course: course_ids},
+ {}, {atomic: true}).toPromise();
+ }
+ }
+
fleshMaterial(itemId, relationship?): Promise<any> {
return new Promise((resolve, reject) => {
let item = this.idl.create('acp');
});
}
+ fleshUser(patron_id, role?, is_public?): Promise<any> {
+ return new Promise((resolve, reject) => {
+ let user = this.idl.create('au');
+ this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.user.fleshed.retrieve',
+ this.auth.token(), patron_id
+ ).subscribe(patron => {
+ user = patron;
+ if (role) user._role = role
+ if (is_public) user._is_public = is_public
+ }, err => {
+ reject(err);
+ }, () => resolve(user));
+ });
+ }
+
getCoursesFromMaterial(copy_id): Promise<any> {
let id_list = [];
return new Promise((resolve, reject) => {
return response;
}
+ associateUsers(patron_id, args) {
+ console.log(args);
+ let 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);
+ return this.pcrud.create(new_user).toPromise()
+ }
+
disassociateMaterials(courses) {
return new Promise((resolve, reject) => {
let course_ids = [];