From 34b5b5f4c61c462e8f798ced70571083b0e66212 Mon Sep 17 00:00:00 2001 From: Jason Etheridge Date: Wed, 12 Apr 2023 08:09:42 -0400 Subject: [PATCH] lp1857911 follow-up tweaks * AdminPage component -> Return button if page was invoked with gridFilters * AdminPage component -> options to hide delete and edit actions * Stat cat admin pages -> disable edit and delete for stat cat entries to match behavior of legacy interfaces, until we discuss something better * AdminPage component -> stock delete confirmation for AdminPage component * Stat cat admin pages -> custom delete confirmation prompts for stat cats * AdminPage component -> sticky org selector options for org fields in fmEditor * AdminPage component -> option for new record org fields to follow context org * Stat cat admin pages -> enable org field follows context org featuer * orgFamilySelect -> persistKey support * Stat cat admin pages -> use a persistKey for main org selector Signed-off-by: Jason Etheridge Signed-off-by: Jane Sandberg --- .../app/share/fm-editor/fm-editor.component.html | 1 + .../src/app/share/fm-editor/fm-editor.component.ts | 6 ++ .../org-family-select.component.ts | 25 ++++++- .../app/staff/admin/basic-admin-page.component.ts | 18 +++++ .../admin/local/admin-local-splash.component.html | 2 - .../src/app/staff/admin/local/routing.module.ts | 18 +++++ .../share/admin-page/admin-page.component.html | 24 ++++++- .../staff/share/admin-page/admin-page.component.ts | 84 ++++++++++++++++++---- Open-ILS/src/sql/Pg/950.data.seed-values.sql | 21 ++++++ .../sql/Pg/upgrade/XXXX.data.stat-cat-admin.sql | 31 ++++++++ docs/RELEASE_NOTES_NEXT/miscellaneous.adoc | 1 + 11 files changed, 213 insertions(+), 18 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.data.stat-cat-admin.sql diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.html b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.html index 1ab47ed714..c0ea3e45ea 100644 --- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.html +++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.html @@ -91,6 +91,7 @@ placeholder="{{field.label}}..." i18n-placeholder domId="{{idPrefix}}-{{field.name}}" + persistKey="{{field.persistKey}}" [limitPerms]="modePerms[mode]" [readOnly]="field.readOnly" [applyDefault]="field.orgDefaultAllowed" diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts index 4c6f801395..77273ef721 100644 --- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts +++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts @@ -84,6 +84,9 @@ export interface FmFieldOptions { // from the default set of form inputs. customTemplate?: CustomFieldTemplate; + // Use this persistKey if the field is an org field + persistKey?: StringComponent; + // help text to display via a popover helpText?: StringComponent; @@ -569,6 +572,9 @@ export class FmRecordEditorComponent } else if (field.datatype === 'org_unit') { field.orgDefaultAllowed = this.orgDefaultAllowedList.includes(field.name); + if (fieldOptions.persistKey) { + field.persistKey = fieldOptions.persistKey; + } } if (fieldOptions.helpText) { diff --git a/Open-ILS/src/eg2/src/app/share/org-family-select/org-family-select.component.ts b/Open-ILS/src/eg2/src/app/share/org-family-select/org-family-select.component.ts index f829265805..64188da858 100644 --- a/Open-ILS/src/eg2/src/app/share/org-family-select/org-family-select.component.ts +++ b/Open-ILS/src/eg2/src/app/share/org-family-select/org-family-select.component.ts @@ -4,6 +4,7 @@ import {AuthService} from '@eg/core/auth.service'; import {IdlObject} from '@eg/core/idl.service'; import {OrgService} from '@eg/core/org.service'; import {OrgSelectComponent} from '@eg/share/org-select/org-select.component'; +import {ServerStoreService} from '@eg/core/server-store.service'; export interface OrgFamily { primaryOrgId: number; @@ -52,6 +53,8 @@ export class OrgFamilySelectComponent implements ControlValueAccessor, OnInit { @Input() domId: string; + @Input() persistKey: string; + @Output() onChange = new EventEmitter(); @ViewChildren(OrgSelectComponent) orgSelects: QueryList; @@ -70,7 +73,8 @@ export class OrgFamilySelectComponent implements ControlValueAccessor, OnInit { constructor( private auth: AuthService, - private org: OrgService + private org: OrgService, + private serverStore: ServerStoreService ) { } @@ -130,7 +134,26 @@ export class OrgFamilySelectComponent implements ControlValueAccessor, OnInit { this.propagateChange(this.options); this.onChange.emit(this.options); + + if (this.persistKey) { + const key = `eg.orgfamilyselect.${this.persistKey}`; + this.serverStore.setItem(key, this.options); + } }; + + this.loadPersistedValues(); + } + + private loadPersistedValues() { + if (!this.persistKey) return; + + const key = `eg.orgfamilyselect.${this.persistKey}`; + + this.serverStore.getItem(key).then(persistedOptions => { + if (persistedOptions) { + this.writeValue(persistedOptions); + } + }); } writeValue(value: OrgFamily) { diff --git a/Open-ILS/src/eg2/src/app/staff/admin/basic-admin-page.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/basic-admin-page.component.ts index 7332f6a4c7..3363b9ff7b 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/basic-admin-page.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/basic-admin-page.component.ts @@ -18,12 +18,18 @@ import {tap, switchMap} from 'rxjs/operators'; ` @@ -35,9 +41,12 @@ export class BasicAdminPageComponent implements OnInit { classLabel: string; persistKeyPfx: string; fieldOrder = ''; + fieldOptions = {}; + contextOrgSelectorPersistKey = ''; readonlyFields = ''; recordLabel = ''; orgDefaultAllowed = ''; + orgFieldsDefaultingToContextOrg = ''; hideClearFilters: boolean; defaultNewRecordIdl: IdlObject; configLinkBasePath = '/staff/admin'; @@ -46,6 +55,9 @@ export class BasicAdminPageComponent implements OnInit { disableOrgFilter: boolean; enableUndelete: boolean; + disableDelete: boolean; + deleteConfirmation: string; + disableEdit: boolean; private getParams$: Observable; private getRouteData$: Observable; @@ -83,10 +95,16 @@ export class BasicAdminPageComponent implements OnInit { } this.disableOrgFilter = data['disableOrgFilter']; this.enableUndelete = data['enableUndelete']; + this.disableDelete = data['disableDelete']; + this.deleteConfirmation = data['deleteConfirmation']; + this.disableEdit = data['disableEdit']; this.fieldOrder = data['fieldOrder']; + this.fieldOptions = data['fieldOptions']; + this.contextOrgSelectorPersistKey = data['contextOrgSelectorPersistKey']; this.readonlyFields = data['readonlyFields']; this.recordLabel = data['recordLabel']; this.orgDefaultAllowed = data['orgDefaultAllowed']; + this.orgFieldsDefaultingToContextOrg = data['orgFieldsDefaultingToContextOrg']; this.hideClearFilters = data['hideClearFilters']; this.defaultNewRecord = data['defaultNewRecord']; } diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html index b5eb8734b6..13be7f8fe9 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html @@ -70,8 +70,6 @@ routerLink="/staff/admin/local/config/ui_staff_portal_page_entry"> - Failed to create new {{recordLabel || idlClassDef.label}} + + + + Are you sure you want to delete the selected rows? This will also delete any data depending on the rows deleted. + {{deleteConfirmation}} + +
+ (ngModelChange)="contextOrgChanged($event)">
@@ -40,6 +51,12 @@ Filters Applied: {{gridFilters | json}} Clear Filters +   +
@@ -68,10 +85,11 @@ - + + [disableOnRows]="shouldDisableDelete" *ngIf="!disableDelete"> diff --git a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts index cf24c436af..ce63793ec7 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts @@ -7,6 +7,7 @@ import {GridDataSource, GridColumn} from '@eg/share/grid/grid'; import {GridComponent} from '@eg/share/grid/grid.component'; import {TranslateComponent} from '@eg/share/translate/translate.component'; import {ToastService} from '@eg/share/toast/toast.service'; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; import {Pager} from '@eg/share/util/pager'; import {PcrudService} from '@eg/core/pcrud.service'; import {OrgService} from '@eg/core/org.service'; @@ -63,6 +64,15 @@ export class AdminPageComponent implements OnInit { // Give the grid an option to undelete any deleted rows @Input() enableUndelete: boolean; + // Remove the ability to delete rows + @Input() disableDelete: boolean; + + // Optional: Replace the default deletion confirmation text with this + @Input() deleteConfirmation: string; + + // Remove the ability to edit rows + @Input() disableEdit: boolean; + // Include objects linking to org units which are ancestors // of the selected org unit. @Input() includeOrgAncestors: boolean; @@ -74,6 +84,9 @@ export class AdminPageComponent implements OnInit { // following eg.grid. @Input() persistKey: string; + // If present, will be applied to the org selector for the grid + @Input() contextOrgSelectorPersistKey: string; + // Optional path component to add to the generated grid persist key, // formatted as (for example): // 'eg.grid.admin.${persistKeyPfx}.config.billing_type' @@ -91,6 +104,9 @@ export class AdminPageComponent implements OnInit { // optional list of org fields which are allowed a default if unset @Input() orgDefaultAllowed: string; + // list of org fields to receive the context org as their default for new records + @Input() orgFieldsDefaultingToContextOrg: string; + // Optional template containing help/about text which will // be added to the page, above the grid. @Input() helpTemplate: TemplateRef; @@ -121,6 +137,8 @@ export class AdminPageComponent implements OnInit { @ViewChild('undeleteFailedString', { static: true }) undeleteFailedString: StringComponent; @ViewChild('undeleteSuccessString', { static: true }) undeleteSuccessString: StringComponent; @ViewChild('translator', { static: true }) translator: TranslateComponent; + @ViewChild('deleteConfirmDialog', { static: true }) + private deleteConfirmDialog: ConfirmDialogComponent; idlClassDef: any; pkeyField: string; @@ -181,6 +199,11 @@ export class AdminPageComponent implements OnInit { } } + contextOrgChanged(orgEvent: any) { + this.grid.reload(); + this.setDefaultNewRecordOrgFieldDefaults( orgEvent['primaryOrgId'] ); + } + ngOnInit() { this.idlClassDef = this.idl.classes[this.idlClass]; @@ -241,10 +264,31 @@ export class AdminPageComponent implements OnInit { this.checkCreatePerms(); this.applyOrgValues(Number(contextOrg)); + this.setDefaultNewRecordOrgFieldDefaults( Number(contextOrg) ); + // If the caller provides not data source, create a generic one. if (!this.dataSource) { this.initDataSource(); } + + console.log('admin this',this); + } + + setDefaultNewRecordOrgFieldDefaults(contextOrg: number) { + // however we get a defaultNewRecord, we may want to default some org fields to the context org + if (this.orgFieldsDefaultingToContextOrg) { + if (!this.defaultNewRecord) { + this.defaultNewRecord = this.idl.create(this.idlClass); + } + this.orgFieldsDefaultingToContextOrg.split(/,/).forEach( field => { + if (this.defaultNewRecord[field] && this.pkeyField !== field) { + if (contextOrg) { + // since this can change often, we'll just blow away anything that might have come in a different way + this.defaultNewRecord[field]( contextOrg ); + } + } + }); + } } checkCreatePerms() { @@ -322,6 +366,9 @@ export class AdminPageComponent implements OnInit { } showEditDialog(idlThing: IdlObject): Promise { + if (this.disableEdit) { + return; + } this.editDialog.mode = 'update'; this.editDialog.recordId = idlThing[this.pkeyField](); return new Promise((resolve, reject) => { @@ -370,18 +417,22 @@ export class AdminPageComponent implements OnInit { } deleteSelected(idlThings: IdlObject[]) { - idlThings.forEach(idlThing => idlThing.isdeleted(true)); - this.pcrud.autoApply(idlThings).subscribe( - val => { - this.deleteSuccessString.current() - .then(str => this.toast.success(str)); - }, - err => { - this.deleteFailedString.current() - .then(str => this.toast.danger(str)); - }, - () => this.grid.reload() - ); + this.deleteConfirmDialog.open().subscribe(confirmed => { + if ( confirmed ) { + idlThings.forEach(idlThing => idlThing.isdeleted(true)); + this.pcrud.autoApply(idlThings).subscribe( + val => { + this.deleteSuccessString.current() + .then(str => this.toast.success(str)); + }, + err => { + this.deleteFailedString.current() + .then(str => this.toast.danger(str)); + }, + () => this.grid.reload() + ); + } + }); } shouldDisableDelete(rows: IdlObject[]): boolean { @@ -559,6 +610,15 @@ export class AdminPageComponent implements OnInit { const url = this.configLinkBasePath + '/' + parts[0] + '/' + parts[1]; return this.ngLocation.prepareExternalUrl(url); } + + hasNoHistory(): boolean { + return history.length === 0; + } + + goBack() { + history.back(); + } + } export interface TemplateField { diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index 1e0c6f65ba..4cdff6ca6a 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -20032,6 +20032,27 @@ VALUES ( 'Grid Config: admin.config.idl_field_doc', 'cwst', 'label' ) +), ( + 'eg.orgselect.admin.stat_cat.owner', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgselect.admin.stat_cat.owner', + 'Default org unit for stat cat and stat cat entry editors', + 'cwst', 'label' + ) +), ( + 'eg.orgfamilyselect.admin.item_stat_cat.main_org_selector', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgfamilyselect.admin.item_stat_cat.main_org_selector', + 'Default org unit for the main org select in the item stat cat and stat cat entry admin interfaces.', + 'cwst', 'label' + ) +), ( + 'eg.orgfamilyselect.admin.patron_stat_cat.main_org_selector', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgfamilyselect.admin.patron_stat_cat.main_org_selector', + 'Default org unit for the main org select in the patron stat cat and stat cat entry admin interfaces.', + 'cwst', 'label' + ) ); diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.stat-cat-admin.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.stat-cat-admin.sql new file mode 100644 index 0000000000..8b020efcd1 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.stat-cat-admin.sql @@ -0,0 +1,31 @@ + +BEGIN; + +--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +INSERT INTO config.workstation_setting_type (name, grp, datatype, label) +VALUES + ( + 'eg.orgselect.admin.stat_cat.owner', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgselect.admin.stat_cat.owner', + 'Default org unit for stat cat and stat cat entry editors', + 'cwst', 'label' + ) + ), ( + 'eg.orgfamilyselect.admin.item_stat_cat.main_org_selector', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgfamilyselect.admin.item_stat_cat.main_org_selector', + 'Default org unit for the main org select in the item stat cat and stat cat entry admin interfaces.', + 'cwst', 'label' + ) + ), ( + 'eg.orgfamilyselect.admin.patron_stat_cat.main_org_selector', 'gui', 'integer', + oils_i18n_gettext( + 'eg.orgfamilyselect.admin.patron_stat_cat.main_org_selector', + 'Default org unit for the main org select in the patron stat cat and stat cat entry admin interfaces.', + 'cwst', 'label' + ) + ); + +COMMIT; diff --git a/docs/RELEASE_NOTES_NEXT/miscellaneous.adoc b/docs/RELEASE_NOTES_NEXT/miscellaneous.adoc index c7a9dcde10..a17df9a7b8 100644 --- a/docs/RELEASE_NOTES_NEXT/miscellaneous.adoc +++ b/docs/RELEASE_NOTES_NEXT/miscellaneous.adoc @@ -31,3 +31,4 @@ * Patron and staff login forms now include a button to reveal the password input. (LP#1977554) * Adds new Local Administration entries for Item Statistical Categories Editor and Patron Statistical Categories Editor, which are angularized interfaces. * Tweaks eg-grids to underline hyperlinks within cells. This potentially affects multiple interfaces. +* eg-org-family-select now supports persistKey -- 2.11.0