// Note most input fields should match class fields for GridColumn
@Input() label: string;
+ // Set the render time value.
+ // This does NOT fire the onChange handler.
+ @Input() initialValue: boolean;
+
// This is an input instead of an Output because the handler is
// passed off to the grid context for maintenance -- events
// are not fired directly from this component.
const cb = new GridToolbarCheckbox();
cb.label = this.label;
cb.onChange = this.onChange;
+ cb.isChecked = this.initialValue;
this.grid.context.toolbarCheckboxes.push(cb);
}
<ng-container *ngFor="let cb of gridContext.toolbarCheckboxes">
<label class="form-check-label">
<input class="form-check-input" type="checkbox"
+ [(ngModel)]="cb.isChecked"
(click)="cb.onChange.emit($event.target.checked)"/>
{{cb.label}}
</label>
sortLocalData() {
const sortDefs = this.dataSource.sort.map(sort => {
+ const column = this.columnSet.getColByName(sort.name);
+
const def = {
name: sort.name,
dir: sort.dir,
- col: this.columnSet.getColByName(sort.name)
+ col: column
};
if (!def.col.comparator) {
- def.col.comparator = (a, b) => {
- if (a < b) { return -1; }
- if (a > b) { return 1; }
- return 0;
- };
+ switch (def.col.datatype) {
+ case 'id':
+ case 'money':
+ case 'int':
+ def.col.comparator = (a, b) => {
+ a = Number(a);
+ b = Number(b);
+ if (a < b) { return -1; }
+ if (a > b) { return 1; }
+ return 0;
+ };
+ break;
+ default:
+ def.col.comparator = (a, b) => {
+ if (a < b) { return -1; }
+ if (a > b) { return 1; }
+ return 0;
+ };
+ }
}
return def;
const diff = sortDef.col.comparator(valueA, valueB);
if (diff === 0) { continue; }
- console.log(valueA, valueB, diff);
-
return sortDef.dir === 'DESC' ? -diff : diff;
}
export class GridToolbarCheckbox {
label: string;
+ isChecked: boolean;
onChange: EventEmitter<boolean>;
}
<ngb-tab title="View Holds" i18n-title id="holds">
<ng-template ngbTabContent>
<eg-holds-grid [recordId]="recordId"
+ preFetchSetting="catalog.record.holds.prefetch"
persistKey="cat.catalog.wide_holds"
[defaultSort]="[{name:'request_time',dir:'asc'}]"
[initialPickupLib]="currentSearchOrg()"></eg-holds-grid>
</eg-hold-detail>
</ng-container>
- <ng-container *ngIf="mode == 'list'">
+ <ng-container *ngIf="mode == 'list' && initComplete()">
<div class="row" *ngIf="!hidePickupLibFilter">
<div class="col-lg-4">
</div>
<eg-grid #holdsGrid [dataSource]="gridDataSource" [sortable]="true"
+ [useLocalSort]="enablePreFetch"
[multiSortable]="true" [persistKey]="persistKey"
(onRowActivate)="showDetail($event)">
+ <eg-grid-toolbar-checkbox (onChange)="preFetchHolds($event)"
+ [initialValue]="enablePreFetch" i18n-label label="Pre-Fetch All Holds">
+ </eg-grid-toolbar-checkbox>
+
<eg-grid-toolbar-action
i18n-label label="Show Hold Details" i18n-group group="Hold"
(onClick)="showDetails($event)"></eg-grid-toolbar-action>
i18-group group="Hold" i18n-label label="Cancel Hold"
(onClick)="showCancelDialog($event)"></eg-grid-toolbar-action>
- <eg-grid-column i18n-label label="Hold ID" path='id' [index]="true">
+ <eg-grid-column i18n-label label="Hold ID" path='id' [index]="true" datatype="id">
</eg-grid-column>
<ng-template #barcodeTmpl let-hold="row">
name='title' [cellTemplate]="titleTmpl"></eg-grid-column>
<eg-grid-column i18n-label label="Author" path='author'
[hidden]="true"></eg-grid-column>
- <eg-grid-column i18n-label label="Potential Items" path='potentials'>
+ <eg-grid-column i18n-label label="Potential Items" path='potentials' datatype="int">
</eg-grid-column>
<eg-grid-column i18n-label label="Status" path='status_string'>
</eg-grid-column>
<eg-grid-column i18n-label label="Queue Position"
- path='relative_queue_position' [hidden]="true"></eg-grid-column>
+ path='relative_queue_position' [hidden]="true" datatype="int"></eg-grid-column>
<eg-grid-column path='usr_id' i18n-label label="User ID" [hidden]="true"></eg-grid-column>
<eg-grid-column path='usr_usrname' i18n-label label="Username" [hidden]="true"></eg-grid-column>
import {OrgService} from '@eg/core/org.service';
import {AuthService} from '@eg/core/auth.service';
import {Pager} from '@eg/share/util/pager';
+import {ServerStoreService} from '@eg/core/server-store.service';
import {GridDataSource} from '@eg/share/grid/grid';
import {GridComponent} from '@eg/share/grid/grid.component';
import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
// Grid persist key
@Input() persistKey: string;
+ @Input() preFetchSetting: string;
+ // If set, all holds are fetched on grid load and sorting/paging all
+ // happens in the client. If false, sorting and paging occur on
+ // the server.
+ enablePreFetch: boolean;
+
// How to sort when no sort parameters have been applied
// via grid controls. This uses the eg-grid sort format:
// [{name: fname, dir: 'asc'}, {name: fname2, dir: 'desc'}]
detailHold: any;
editHolds: number[];
transferTarget: number;
- copyStatuses: {[id: string]: IdlObject};
@ViewChild('holdsGrid') private holdsGrid: GridComponent;
@ViewChild('progressDialog')
constructor(
private net: NetService,
private org: OrgService,
+ private store: ServerStoreService,
private auth: AuthService
) {
this.gridDataSource = new GridDataSource();
- this.copyStatuses = {};
+ this.enablePreFetch = null;
}
ngOnInit() {
this.initDone = true;
this.pickupLib = this.org.get(this.initialPickupLib);
- this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+ if (this.preFetchSetting) {
- if (this.defaultSort && sort.length === 0) {
- // Only use initial sort if sorting has not been modified
- // by the grid's own sort controls.
- sort = this.defaultSort;
- }
+ this.store.getItem(this.preFetchSetting).then(
+ applied => this.enablePreFetch = Boolean(applied)
+ );
+
+ }
- // sorting not currently supported
+ if (!this.defaultSort) {
+ this.defaultSort = [{name: 'request_time', dir: 'asc'}];
+ }
+
+ this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+ sort = sort.length > 0 ? sort : this.defaultSort;
return this.fetchHolds(pager, sort);
};
}
+ // Returns true after all data/settings/etc required to render the
+ // grid have been fetched.
+ initComplete(): boolean {
+ return this.enablePreFetch !== null;
+ }
+
pickupLibChanged(org: IdlObject) {
this.pickupLib = org;
this.holdsGrid.reload();
}
+ preFetchHolds(apply: boolean) {
+ this.enablePreFetch = apply;
+
+ if (apply) {
+ setTimeout(() => this.holdsGrid.reload());
+ }
+
+ if (this.preFetchSetting) {
+ // fire and forget
+ this.store.setItem(this.preFetchSetting, apply);
+ }
+ }
+
applyFilters(): any {
const filters: any = {
is_staff_request: true,
const filters = this.applyFilters();
const orderBy: any = [];
- sort.forEach(obj => {
- const subObj: any = {};
- subObj[obj.name] = {dir: obj.dir, nulls: 'last'};
- orderBy.push(subObj);
- });
+ if (sort.length > 0) {
+ sort.forEach(obj => {
+ const subObj: any = {};
+ subObj[obj.name] = {dir: obj.dir, nulls: 'last'};
+ orderBy.push(subObj);
+ });
+ }
+
+ const limit = this.enablePreFetch ? null : pager.limit;
+ const offset = this.enablePreFetch ? 0 : pager.offset;
let observer: Observer<any>;
const observable = new Observable(obs => observer = obs);
this.net.request(
'open-ils.circ',
'open-ils.circ.hold.wide_hash.stream',
- // Pre-fetch all holds consistent with AngJS version
- this.auth.token(), filters, orderBy
- // Alternatively, fetch holds in pages.
- // this.auth.token(), filters, orderBy, pager.limit, pager.offset
+ this.auth.token(), filters, orderBy, limit, offset
).subscribe(
holdData => {
'bool'
);
-
INSERT INTO config.usr_activity_type
(id, ewhat, ehow, egroup, enabled, transient, label)
VALUES (
oils_i18n_gettext(30, 'Generic Verify', 'cuat', 'label')
);
+INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+ 'catalog.record.holds.prefetch', 'cat', 'bool',
+ oils_i18n_gettext(
+ 'catalog.record.holds.prefetch',
+ 'Pre-Fetch Record Holds',
+ 'cwst', 'label'
+ )
+);
+
--- /dev/null
+BEGIN;
+
+--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
+VALUES (
+ 'catalog.record.holds.prefetch', 'cat', 'bool',
+ oils_i18n_gettext(
+ 'catalog.record.holds.prefetch',
+ 'Pre-Fetch Record Holds',
+ 'cwst', 'label'
+ )
+);
+
+COMMIT;