From 3aafe5298b1c289199c0412f9f82e6c162e805fa Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 24 Aug 2020 12:16:49 -0400 Subject: [PATCH] LP1888723 Holdings refresh handles deleted call numbers Teach the holdings grid in the staff catalog to correctly remove deleted volumes from its tree when holding are modified in another tab. To test, in the holding editor, modify a call number to have the same label as another call number with the same owning org unit and save. On the backend, this will result in one of the call numbers getting deleted. Confirm the deleted call number no longer appears in the holdings grid. Signed-off-by: Bill Erickson Signed-off-by: Ruth Frasur Signed-off-by: Galen Charlton --- .../app/staff/catalog/record/holdings.component.ts | 51 ++++++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts index 8ba0ccb86d..58809b6700 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts @@ -508,6 +508,9 @@ export class HoldingsMaintenanceComponent implements OnInit { } this.itemCircsNeeded = []; + // Track vol IDs for the current fetch so we can prune + // any that were deleted in an out-of-band update. + const volsFetched: number[] = []; this.pcrud.search('acn', { record: this.recordId, @@ -525,10 +528,14 @@ export class HoldingsMaintenanceComponent implements OnInit { }, {authoritative: true} ).subscribe( - callNum => this.appendCallNum(callNum), + callNum => { + this.appendCallNum(callNum); + volsFetched.push(callNum.id()); + }, err => {}, () => { this.refreshHoldings = false; + this.pruneVols(volsFetched); this.fetchCircs().then( ok => this.flattenHoldingsTree(observer) ); @@ -537,6 +544,45 @@ export class HoldingsMaintenanceComponent implements OnInit { }); } + // Remove vols that were deleted out-of-band, via edit, merge, etc. + pruneVols(volsFetched: number[]) { + + const toRemove: number[] = []; // avoid modifying mid-loop + Object.keys(this.treeNodeCache.callNum).forEach(volId => { + const id = Number(volId); + if (!volsFetched.includes(id)) { + toRemove.push(id); + } + }); + + if (toRemove.length === 0) { return; } + + const pruneNodes = (node: HoldingsTreeNode) => { + if (node.nodeType === 'callNum' && + toRemove.includes(node.target.id())) { + + console.debug('pruning deleted vol:', node.target.id()); + + // Remove this node from the parents list of children + node.parentNode.children = + node.parentNode.children.filter( + c => c.target.id() !== node.target.id()); + + } else { + node.children.forEach(c => pruneNodes(c)); + } + }; + + // remove from cache + toRemove.forEach(volId => delete this.treeNodeCache.callNum[volId]); + + // remove from tree + pruneNodes(this.holdingsTree.root); + + // refresh tree / grid + this.holdingsGrid.reload(); + } + // Retrieve circulation objects for checked out items. fetchCircs(): Promise { const copyIds = this.itemCircsNeeded.map(copy => copy.id()); @@ -570,9 +616,6 @@ export class HoldingsMaintenanceComponent implements OnInit { if (callNumNode) { const pNode = this.treeNodeCache.org[callNum.owning_lib()]; if (callNumNode.parentNode.target.id() !== pNode.target.id()) { - // Call number owning library changed. Un-link it from the - // previous org unit collection before adding to the new one. - // XXX TODO: ^-- callNumNode.parentNode = pNode; callNumNode.parentNode.children.push(callNumNode); } -- 2.11.0