--- /dev/null
+<eg-title i18n-prefix prefix="{{classLabel}} Administration">
+</eg-title>
+<eg-staff-banner bannerText="{{classLabel}} Configuration" i18n-bannerText>
+</eg-staff-banner>
+
+<ng-template #successStrTmpl i18n>{{idlClassDef.label}} Update Succeeded</ng-template>
+<eg-string #successString [template]="successStrTmpl"></eg-string>
+
+<ng-template #updateFailedStrTmpl i18n>Update of {{idlClassDef.label}} failed</ng-template>
+<eg-string #updateFailedString [template]="updateFailedStrTmpl"></eg-string>
+
+<ng-template #deleteFailedStrTmpl i18n>Delete of carousel faiiled or was not allowed</ng-template>
+<eg-string #deleteFailedString [template]="deleteFailedStrTmpl"></eg-string>
+
+<ng-template #deleteSuccessStrTmpl i18n>Carousel Successfully Deleted</ng-template>
+<eg-string #deleteSuccessString [template]="deleteSuccessStrTmpl"></eg-string>
+
+<ng-template #createStrTmpl i18n>{{idlClassDef.label}} Succeessfully Created</ng-template>
+<eg-string #createString [template]="createStrTmpl"></eg-string>
+
+<ng-template #createErrStrTmpl i18n>Failed to create new {{idlClassDef.label}}</ng-template>
+<eg-string #createErrString [template]="createErrStrTmpl"></eg-string>
+
+<ng-template #refreshStrTmpl i18n let-name="name">{{name}} is being refreshed. It may take a couple minutes.</ng-template>
+<eg-string #refreshString [template]="refreshStrTmpl"></eg-string>
+
+<ng-template #refreshErrStrTmpl i18n let-name="name">{{name}} is manual and cannot be refreshed automatically.</ng-template>
+<eg-string #refreshErrString [template]="refreshErrStrTmpl"></eg-string>
+
+<ng-container *ngIf="orgField">
+ <eg-org-family-select
+ [limitPerms]="viewPerms"
+ [selectedOrgId]="contextOrg.id()"
+ [(ngModel)]="searchOrgs"
+ (ngModelChange)="grid.reload()">
+ </eg-org-family-select>
+ <hr/>
+</ng-container>
+
+<!-- idlObject and fieldName applied programmatically -->
+<eg-translate #translator></eg-translate>
+
+<eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource"
+ [sortable]="true" persistKey="{{persistKey}}" [showLinkSelectors]="true">
+ <eg-grid-toolbar-button [disabled]="!canCreate"
+ label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
+ </eg-grid-toolbar-button>
+ <eg-grid-toolbar-button [disabled]="translatableFields.length == 0"
+ label="Apply Translations" i18n-label [action]="translate">
+ </eg-grid-toolbar-button>
+ <eg-grid-toolbar-action label="Edit Selected" i18n-label [action]="editSelected">
+ </eg-grid-toolbar-action>
+ <eg-grid-toolbar-action label="Delete Selected" i18n-label [action]="deleteSelected">
+ </eg-grid-toolbar-action>
+ <eg-grid-toolbar-action label="Refesh Selected" i18n-label [action]="refreshSelected">
+ </eg-grid-toolbar-action>
+ <eg-grid-column path="bucket" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="creator" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="editor" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="create_time" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="edit_time" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="age_filter" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="owning_lib_filter" [hidden]="true"></eg-grid-column>
+ <eg-grid-column path="copy_location_filter" [hidden]="true"></eg-grid-column>
+</eg-grid>
+
+<ng-template #bucketTemplate
+ let-field="field" let-record="record">
+ <span *ngIf="record[field.name]()" i18n>
+ <a href="/eg/staff/cat/bucket/record/view/{{record[field.name]()}}" target="_blank" i18n>Link to bucket</a>
+ <span *ngIf="record['type']() !== 1" i18n style="font-style: italic"> (Note: changes to bucket contents may be overwritten by the next carousel update.)</span>
+ </span>
+</ng-template>
+
+<ng-template #locationTemplate
+ let-field="field" let-record="record">
+ <eg-multi-select idlClass="acpl" linkedLibraryLabel="owning_lib"
+ [startValue]="record['copy_location_filter']()"
+ (onChange)="record['copy_location_filter']($event)">
+ </eg-multi-select>
+</ng-template>
+<ng-template #orgTemplate
+ let-field="field" let-record="record">
+ <eg-multi-select idlClass="aou"
+ [startValue]="record['owning_lib_filter']()"
+ (onChange)="record['owning_lib_filter']($event)">
+ </eg-multi-select>
+</ng-template>
+
+<eg-fm-record-editor #editDialog idlClass="{{idlClass}}"
+ [preloadLinkedValues]="true" readonlyFields="last_refresh_time"
+ hiddenFieldsList="creator,editor,create_time,edit_time"
+ [preSave]="mungeCarousel" (onSave$)="postSave($event)"
+ readonlyFields="last_refresh_time"
+ [fieldOptions]="{bucket:{customTemplate:{template:bucketTemplate}},copy_location_filter:{customTemplate:{template:locationTemplate}},owning_lib_filter:{customTemplate:{template:orgTemplate}}}"
+></eg-fm-record-editor>
+
+
--- /dev/null
+import {Component, Input, ViewChild, OnInit} from '@angular/core';
+import {AdminPageComponent} from '@eg/staff/share/admin-page/admin-page.component';
+import {ActivatedRoute} from '@angular/router';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {OrgService} from '@eg/core/org.service';
+import {PermService} from '@eg/core/perm.service';
+import {AuthService} from '@eg/core/auth.service';
+import {NetService} from '@eg/core/net.service';
+import {StringComponent} from '@eg/share/string/string.component';
+
+@Component({
+ templateUrl: './admin-carousel.component.html'
+})
+
+export class AdminCarouselComponent extends AdminPageComponent implements OnInit {
+
+ idlClass = 'cc';
+ classLabel: string;
+
+ refreshSelected: (idlThings: IdlObject[]) => void;
+ createNew: () => void;
+ deleteSelected: (idlThings: IdlObject[]) => void;
+
+ @ViewChild('refreshString') refreshString: StringComponent;
+ @ViewChild('refreshErrString') refreshErrString: StringComponent;
+
+ constructor(
+ route: ActivatedRoute,
+ idl: IdlService,
+ org: OrgService,
+ auth: AuthService,
+ pcrud: PcrudService,
+ perm: PermService,
+ toast: ToastService,
+ private net: NetService
+ ) {
+ super(route, idl, org, auth, pcrud, perm, toast);
+ }
+
+ ngOnInit() {
+ super.ngOnInit();
+
+ this.classLabel = this.idlClassDef.label;
+ this.includeOrgDescendants = true;
+
+
+ this.createNew = () => {
+ super.createNew();
+ };
+
+ this.deleteSelected = (idlThings: IdlObject[]) => {
+ super.deleteSelected(idlThings);
+ };
+
+ this.refreshSelected = (idlThings: IdlObject[]) => {
+ idlThings.forEach(cc => {
+ if (cc.type().automatic() === 't') {
+ this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.carousel.refresh',
+ this.auth.token(), cc.id()
+ ).toPromise(); // fire and forget, as this could take a couple minutes
+ this.refreshString.current({ name: cc.name() }).then(str => this.toast.success(str));
+ } else {
+ this.refreshErrString.current({ name: cc.name() }).then(str => this.toast.warning(str));
+ }
+ });
+ };
+ }
+
+ mungeCarousel(editMode: string, rec: IdlObject) {
+ if (editMode === 'create') {
+ rec.creator(this.auth.user().id());
+ }
+ rec.editor(this.auth.user().id());
+ rec.edit_time('now');
+
+ // convert empty string to nulls as needed
+ // for int[] columns
+ if (rec.owning_lib_filter() === '') {
+ rec.owning_lib_filter(null);
+ }
+ if (rec.copy_location_filter() === '') {
+ rec.copy_location_filter(null);
+ }
+ }
+
+ postSave(rec: IdlObject) {
+ if (rec._isfieldmapper) {
+ // if we got an actual IdlObject back, the
+ // record had just been created, not just
+ // edited. therefore, we probably need
+ if (rec.bucket() == null) {
+ const bucket = this.idl.create('cbreb');
+ bucket.owner(this.auth.user().id());
+ bucket.name('System-generated bucket for carousel: ' + rec.id()); // FIXME I18N
+ bucket.btype('carousel');
+ bucket.pub('t');
+ bucket.owning_lib(rec.owner());
+ rec.bucket(bucket);
+ this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.container.create',
+ this.auth.token(), 'biblio', bucket
+ ).toPromise().then(
+ newBucket => {
+ const ccou = this.idl.create('ccou');
+ ccou.carousel(rec.id());
+ ccou.org_unit(rec.owner());
+ ccou.seq(0);
+ rec.bucket(newBucket);
+ this.pcrud.create(ccou).subscribe(
+ ok => {
+ this.pcrud.update(rec).subscribe(
+ ok2 => console.debug('updated'),
+ err => console.error(err),
+ () => { this.grid.reload(); }
+ );
+ },
+ err => console.error(err),
+ () => { this.grid.reload(); }
+ );
+ }
+ );
+ }
+ }
+ }
+}
url="/eg/staff/admin/local/config/auto_print"></eg-link-table-link>
<eg-link-table-link i18n-label label="Barcode Completion"
routerLink="/staff/admin/local/config/barcode_completion"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Carousel Library Mappings"
+ routerLink="/staff/admin/server/container/carousel_org_unit"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Carousels"
+ routerLink="/staff/admin/server/container/carousel"></eg-link-table-link>
<eg-link-table-link i18n-label label="Cash Reports"
url="/eg/staff/admin/local/money/cash_reports"></eg-link-table-link>
<eg-link-table-link i18n-label label="Circulation Limit Sets"
import {AdminCommonModule} from '@eg/staff/admin/common.module';
import {AdminLocalSplashComponent} from './admin-local-splash.component';
import {AddressAlertComponent} from './address-alert.component';
+import {AdminCarouselComponent} from './admin-carousel.component';
@NgModule({
declarations: [
AdminLocalSplashComponent,
- AddressAlertComponent
+ AddressAlertComponent,
+ AdminCarouselComponent
],
imports: [
AdminCommonModule,
import {AdminLocalSplashComponent} from './admin-local-splash.component';
import {BasicAdminPageComponent} from '@eg/staff/admin/basic-admin-page.component';
import {AddressAlertComponent} from './address-alert.component';
+import {AdminCarouselComponent} from './admin-carousel.component';
const routes: Routes = [{
path: 'splash',
path: 'actor/address_alert',
component: AddressAlertComponent
}, {
+ path: 'container/carousel',
+ component: AdminCarouselComponent
+}, {
path: ':schema/:table',
component: BasicAdminPageComponent
}];
routerLink="/staff/admin/server/asset/call_number_prefix"></eg-link-table-link>
<eg-link-table-link i18n-label label="Call Number Suffixes"
routerLink="/staff/admin/server/asset/call_number_suffix"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Carousel Types"
+ routerLink="/staff/admin/server/config/carousel_type"></eg-link-table-link>
<eg-link-table-link i18n-label label="Circulation Duration Rules"
routerLink="/staff/admin/server/config/rule_circ_duration"></eg-link-table-link>
<eg-link-table-link i18n-label label="Circulation Limit Groups"