--- /dev/null
+<eg-title i18n-prefix prefix="Circulation Policy Configuration"></eg-title>\r
+<eg-staff-banner bannerText="Circulation Policy Configuration" i18n-bannerText>\r
+</eg-staff-banner>\r
+\r
+<eg-string #successString i18n-text text="Circulation Policy Update Succeeded"></eg-string>\r
+<eg-string #createString i18n-text text="Circulation Policy Creation Succeeded"></eg-string>\r
+<eg-string #deleteFailedString i18n-text text="Delete of Circulation Policy failed or was not allowed"></eg-string>\r
+<eg-string #deleteSuccessString i18n-text text="Delete of Circulation Policy succeeded"></eg-string>\r
+\r
+<eg-grid #grid idlClass="ccmm"\r
+ [dataSource]="dataSource"\r
+ [sortable]="true"\r
+ [showFields]='"is_renewal,active,org_unit,copy_circ_lib,copy_owning_lib,user_home_ou"'\r
+ >\r
+ <eg-grid-toolbar-button \r
+ label="New Circ Matrix Matchpoint" i18n-label (onClick)="createNew()">\r
+ </eg-grid-toolbar-button>\r
+ <eg-grid-toolbar-action label="Edit Selected" i18n-label (onClick)="editSelected($event)">\r
+ </eg-grid-toolbar-action>\r
+ <eg-grid-toolbar-action label="Delete Selected" i18n-label (onClick)="deleteSelected($event)">\r
+ </eg-grid-toolbar-action>\r
+ </eg-grid>\r
+\r
+ \r
+<eg-fm-record-editor #editDialog\r
+ idlClass="ccmm" \r
+ [preloadLinkedValues]="true" \r
+ readonlyFields="name">\r
+</eg-fm-record-editor>
\ No newline at end of file
--- /dev/null
+import {Pager} from '@eg/share/util/pager';\r
+import {Component, OnInit, Input, ViewChild} from '@angular/core';\r
+import {GridComponent} from '@eg/share/grid/grid.component';\r
+import {GridDataSource, GridColumn, GridRowFlairEntry} from '@eg/share/grid/grid';\r
+import {IdlObject} from '@eg/core/idl.service';\r
+import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';\r
+import {StringComponent} from '@eg/share/string/string.component';\r
+import {PcrudService} from '@eg/core/pcrud.service';\r
+import {ToastService} from '@eg/share/toast/toast.service';\r
+\r
+@Component({\r
+ templateUrl: './circ-matrix-matchpoint.component.html'\r
+})\r
+\r
+export class CircMatrixMatchpointComponent implements OnInit {\r
+ recId: number;\r
+ gridDataSource: GridDataSource;\r
+ initDone = false;\r
+ dataSource: GridDataSource = new GridDataSource();\r
+\r
+ @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;\r
+ @ViewChild('grid', { static: true }) grid: GridComponent;\r
+ @ViewChild('successString', { static: true }) successString: StringComponent;\r
+ @ViewChild('createString', { static: false }) createString: StringComponent;\r
+ @ViewChild('createErrString', { static: false }) createErrString: StringComponent;\r
+ @ViewChild('updateFailedString', { static: false }) updateFailedString: StringComponent;\r
+ @ViewChild('deleteFailedString', { static: true }) deleteFailedString: StringComponent;\r
+ @ViewChild('deleteSuccessString', { static: true }) deleteSuccessString: StringComponent;\r
+ \r
+ @Input() idlClass = 'ccmm';\r
+ // Default sort field, used when no grid sorting is applied.\r
+ @Input() sortField: string;\r
+\r
+ @Input() dialogSize: 'sm' | 'lg' = 'lg';\r
+\r
+ \r
+ constructor(\r
+ private pcrud: PcrudService,\r
+ private toast: ToastService\r
+ ) {\r
+ this.gridDataSource = new GridDataSource();\r
+ }\r
+\r
+ ngOnInit() {\r
+\r
+ this.initDone = true;\r
+ this.dataSource.getRows = (pager: Pager, sort: any[]) => {\r
+ const orderBy: any = {};\r
+ if (sort.length) {\r
+ // Sort specified from grid\r
+ orderBy[this.idlClass] = sort[0].name + ' ' + sort[0].dir;\r
+ } else if (this.sortField) {\r
+ // Default sort field\r
+ orderBy[this.idlClass] = this.sortField;\r
+ }\r
+\r
+ const searchOps = {\r
+ offset: pager.offset,\r
+ limit: pager.limit,\r
+ order_by: orderBy\r
+ };\r
+ return this.pcrud.retrieveAll('ccmm', searchOps, {fleshSelectors: true});\r
+ }\r
+ \r
+ }\r
+ \r
+ deleteSelected = (idlObjects: IdlObject[]) => {\r
+ idlObjects.forEach(idlObject => idlObject.isdeleted(true));\r
+ this.pcrud.autoApply(idlObjects).subscribe(\r
+ val => {\r
+ console.debug('deleted: ' + val);\r
+ this.deleteSuccessString.current()\r
+ .then(str => this.toast.success(str));\r
+ },\r
+ err => {\r
+ this.deleteFailedString.current()\r
+ .then(str => this.toast.danger(str));\r
+ },\r
+ () => this.grid.reload()\r
+ );\r
+ };\r
+ \r
+ showEditDialog(field: IdlObject): Promise<any> {\r
+ this.editDialog.mode = 'update';\r
+ this.editDialog.recordId = field['id']();\r
+ return new Promise((resolve, reject) => {\r
+ this.editDialog.open({size: this.dialogSize}).subscribe(\r
+ result => {\r
+ this.successString.current()\r
+ .then(str => this.toast.success(str));\r
+ this.grid.reload();\r
+ resolve(result);\r
+ },\r
+ error => {\r
+ this.updateFailedString.current()\r
+ .then(str => this.toast.danger(str));\r
+ reject(error);\r
+ }\r
+ );\r
+ });\r
+ }\r
+\r
+ editSelected(fields: IdlObject[]) {\r
+ // Edit each IDL thing one at a time\r
+ const editOneThing = (field: IdlObject) => {\r
+ if (!field) { return; }\r
+\r
+ this.showEditDialog(field).then(\r
+ () => editOneThing(fields.shift()));\r
+ };\r
+ editOneThing(fields.shift());\r
+ }\r
+\r
+ createNew() {\r
+ this.editDialog.mode = 'create';\r
+ // We reuse the same editor for all actions. Be sure\r
+ // create action does not try to modify an existing record.\r
+ this.editDialog.recordId = null;\r
+ this.editDialog.record = null;\r
+ this.editDialog.open({size: this.dialogSize}).subscribe(\r
+ ok => {\r
+ this.createString.current()\r
+ .then(str => this.toast.success(str));\r
+ this.grid.reload();\r
+ },\r
+ rejection => {\r
+ if (!rejection.dismissed) {\r
+ this.createErrString.current()\r
+ .then(str => this.toast.danger(str));\r
+ }\r
+ }\r
+ );\r
+ }\r
+}\r
+\r