From 12434474b59e1695bab652443225534a5bb66711 Mon Sep 17 00:00:00 2001 From: Paris Alexandre Date: Tue, 6 Jun 2023 16:09:17 +0200 Subject: [PATCH] [VAS] Story 8084: add orphan node in filing leaves tree view --- .../search/ArchiveSearchApplication.java | 1 + .../components/vitamui-tree-node/index.ts | 1 + .../vitamui-tree-node/node.interface.ts | 58 +--- .../vitamui-tree-node/node.utils.ts | 74 +++++ .../vitamui-tree-node.component.ts | 1 + .../src/app/modules/index.ts | 1 - .../src/app/modules/models/units/index.ts | 7 +- ...interface.ts => object-group.interface.ts} | 3 +- ...per.spec.ts => object-group.utils.spec.ts} | 6 +- ...object-helper.ts => object-group.utils.ts} | 4 +- .../app/modules/models/units/unit.enums.ts | 6 + ...nit-api.interface.ts => unit.interface.ts} | 0 .../units/unit.utils.ts} | 25 +- .../src/app/modules/vitamui-icons.enum.ts | 8 +- .../archive-preview.component.html | 5 +- .../archive-preview.component.spec.ts | 54 +--- .../archive-preview.component.ts | 18 +- ...rchive-unit-rules-details-tab.component.ts | 4 +- .../archive-search.component.ts | 77 ++--- .../simple-criteria-search.component.ts | 6 +- .../src/app/archive/archive.service.ts | 43 ++- .../archive-search-helper.service.ts | 19 +- .../classification-tree.component.html | 4 +- .../classification-tree.component.ts | 18 +- .../filing-holding-scheme.component.html | 3 +- .../filing-holding-scheme.component.ts | 43 +-- .../filing-holding-scheme.handler.spec.ts | 194 ++++++++----- .../filing-holding-scheme.handler.ts | 155 +++++++++- .../leaves-tree/leaves-tree.component.html | 52 +++- .../leaves-tree/leaves-tree.component.scss | 15 +- .../leaves-tree/leaves-tree.component.spec.ts | 24 +- .../leaves-tree/leaves-tree.component.ts | 273 +++++++++--------- .../leaves-tree/leaves-tree.service.ts | 218 ++++++++++++++ .../app/core/archive-shared-data.service.ts | 26 +- .../archive-collect.service.ts | 12 +- .../archive-preview.component.html | 4 +- .../archive-preview.component.spec.ts | 44 +-- .../archive-preview.component.ts | 21 +- .../classification-tree.component.html | 4 +- .../classification-tree.component.ts | 19 +- .../filing-holding-scheme.component.ts | 23 +- .../filing-holding-scheme.handler.ts | 10 +- .../leaves-tree/leaves-tree.component.html | 6 +- .../leaves-tree/leaves-tree.component.spec.ts | 26 +- .../leaves-tree/leaves-tree.component.ts | 29 +- .../simple-criteria-search.component.ts | 4 +- .../archive-search-criteria/models/utils.ts | 7 +- .../filing-plan/filing-plan.service.ts | 3 +- .../src/lib/models/unit.interface.ts | 1 + 49 files changed, 970 insertions(+), 689 deletions(-) create mode 100644 ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.utils.ts rename ui/ui-frontend-common/src/app/modules/models/units/{unit-object-api.interface.ts => object-group.interface.ts} (97%) rename ui/ui-frontend-common/src/app/modules/models/units/{unit-object-helper.spec.ts => object-group.utils.spec.ts} (95%) rename ui/ui-frontend-common/src/app/modules/models/units/{unit-object-helper.ts => object-group.utils.ts} (95%) rename ui/ui-frontend-common/src/app/modules/models/units/{unit-api.interface.ts => unit.interface.ts} (100%) rename ui/ui-frontend-common/src/app/modules/{vitamui-unit-types.enum.ts => models/units/unit.utils.ts} (69%) create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.service.ts diff --git a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/ArchiveSearchApplication.java b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/ArchiveSearchApplication.java index 3d230512655..1a3faefdfbe 100644 --- a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/ArchiveSearchApplication.java +++ b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/ArchiveSearchApplication.java @@ -39,6 +39,7 @@ @SpringBootApplication @EnableDiscoveryClient public class ArchiveSearchApplication implements CommandLineRunner { + @Autowired private Environment env; diff --git a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/index.ts b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/index.ts index b5db196e6ce..ad0bbda8b42 100644 --- a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/index.ts +++ b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/index.ts @@ -35,5 +35,6 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ export * from './node.interface'; +export * from './node.utils'; export * from './vitamui-tree-node.component'; export * from './vitamui-tree-node.module'; diff --git a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.interface.ts b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.interface.ts index dc15f40843c..0531c772178 100644 --- a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.interface.ts +++ b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.interface.ts @@ -35,67 +35,35 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Id} from '../../models'; +import { Id } from '../../models'; export interface FilingHoldingSchemeNode extends Id { title: string; + /** @deprecated: use unitType & descriptionLevel instead */ type: string; + unitType?: string; descriptionLevel?: string; label?: string; children: FilingHoldingSchemeNode[]; vitamId: string; + // DISPLAY - disabledChild?: boolean; - disabled?: boolean; - checked: boolean; + disabledChild?: boolean; // TODO: try to remove - used in VitamuiTreeNodeComponent to set indeterminate + disabled?: boolean; // used in VitamuiTreeNodeComponent to disable mat-icon-button & mat-checkbox + checked: boolean; // used in VitamuiTreeNodeComponent to set ngModel of mat-checkbox count?: number; - hidden?: boolean; - + hidden?: boolean; // TODO: try to remove - may be unused isLoadingChildren?: boolean; - // help to keep tracks on what has been loaded - paginatedChildrenLoaded?: number; - canLoadMoreChildren?: boolean; - - paginatedMatchingChildrenLoaded?: number; - canLoadMoreMatchingChildren?: boolean; - toggled?: boolean; - // help to detect the unit type and the icon to show hasObject?: boolean; - unitType?: string; - parents?: FilingHoldingSchemeNode[]; + // help to keep tracks on what has been loaded + paginatedChildrenLoaded?: number; // number of element loaded under a node without criterias + canLoadMoreChildren?: boolean; + paginatedMatchingChildrenLoaded?: number; // number of element loaded under a node with main request search criterias + canLoadMoreMatchingChildren?: boolean; } -export const nodeHasChildren = (node: FilingHoldingSchemeNode): boolean => { - return node.children && node.children.length > 0; -}; - -export const nodeHasMatch = (node: FilingHoldingSchemeNode): boolean => { - return node.count && node.count > 0; -}; - -export const copyNodeWithoutChildren = (node: FilingHoldingSchemeNode): FilingHoldingSchemeNode => { - return { - id: node.id, - title: node.title, - type: node.type, - label: node.label, - children: null, - vitamId: node.vitamId, - checked: node.checked, - count: node.count, - - hasObject: node?.hasObject, - unitType: node?.unitType, - - hidden: node.hidden, - isLoadingChildren: false, - canLoadMoreChildren: true, - canLoadMoreMatchingChildren: true, - }; -}; - export class MatchingNodesNumbers { nodesAdded: number; nodesAddedList: FilingHoldingSchemeNode[]; diff --git a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.utils.ts b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.utils.ts new file mode 100644 index 00000000000..aa1edd5f2f7 --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/node.utils.ts @@ -0,0 +1,74 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2022) + * + * contact.vitam@culture.gouv.fr + * + * This software is a computer program whose purpose is to implement a digital archiving back-office system managing + * high volumetry securely and efficiently. + * + * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free + * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as + * circulated by CEA, CNRS and INRIA at the following URL "https://cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, + * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the + * successive licensors have only limited liability. + * + * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or + * developing or reproducing the software by the user in light of its specific status of free software, that may mean + * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and + * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the + * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data + * to be ensured and, more generally, to use and operate it in the same conditions as regards security. + * + * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you + * accept its terms. + */ +import { unitTypeToVitamuiIcon } from '../../models'; +import { VitamuiIcons } from '../../vitamui-icons.enum'; +import { FilingHoldingSchemeNode } from './node.interface'; + +export function nodeToVitamuiIcon(node: FilingHoldingSchemeNode): VitamuiIcons { + return unitTypeToVitamuiIcon(node.unitType, node.hasObject); +} + +export const nodeHasChildren = (node: FilingHoldingSchemeNode): boolean => { + return node.children && node.children.length > 0; +}; + +export const nodeHasMatch = (node: FilingHoldingSchemeNode): boolean => { + return node.count && node.count > 0; +}; + +export const copyNodeWithoutChildren = (node: FilingHoldingSchemeNode): FilingHoldingSchemeNode => { + return { + id: node.id, + title: node.title, + type: node.type, + label: node.label, + children: null, + vitamId: node.vitamId, + checked: node.checked, + count: node.count, + + hasObject: node?.hasObject, + unitType: node?.unitType, + + hidden: node.hidden, + isLoadingChildren: false, + canLoadMoreChildren: true, + canLoadMoreMatchingChildren: true, + }; +}; + +export function recursiveCheck(nodes: FilingHoldingSchemeNode[], show: boolean) { + if (!nodes || nodes.length === 0) { + return; + } + for (const node of nodes) { + node.hidden = false; + node.checked = show; + node.count = null; + this.recursiveCheck(node.children, show); + } +} diff --git a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/vitamui-tree-node.component.ts b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/vitamui-tree-node.component.ts index 8628a5eb3ed..cfcc5126111 100644 --- a/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/vitamui-tree-node.component.ts +++ b/ui/ui-frontend-common/src/app/modules/components/vitamui-tree-node/vitamui-tree-node.component.ts @@ -37,6 +37,7 @@ export class VitamuiTreeNodeComponent implements AfterContentChecked { @Input() icon: string; @Input() expanded: boolean; @Input() disabled: boolean; + @Input() hasCheckBox = true; @Input() labelIsLinkedToCheckbox = false; @Output() nodeToggle = new EventEmitter(); @Output() checkboxClick = new EventEmitter(); diff --git a/ui/ui-frontend-common/src/app/modules/index.ts b/ui/ui-frontend-common/src/app/modules/index.ts index cd2ddf7ba54..04d56e9430f 100644 --- a/ui/ui-frontend-common/src/app/modules/index.ts +++ b/ui/ui-frontend-common/src/app/modules/index.ts @@ -119,4 +119,3 @@ export * from './vitamui-global-error-handler'; export * from './vitamui-icons.enum'; export * from './vitamui-roles.enum'; export * from './vitamui-table/index'; -export * from './vitamui-unit-types.enum'; diff --git a/ui/ui-frontend-common/src/app/modules/models/units/index.ts b/ui/ui-frontend-common/src/app/modules/models/units/index.ts index ae9803c116d..b4dfc1a5926 100644 --- a/ui/ui-frontend-common/src/app/modules/models/units/index.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/index.ts @@ -1,4 +1,5 @@ -export * from './unit-api.interface'; +export * from './object-group.interface'; +export * from './object-group.utils'; export * from './unit.enums'; -export * from './unit-object-api.interface'; -export * from './unit-object-helper'; +export * from './unit.interface'; +export * from './unit.utils'; diff --git a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-api.interface.ts b/ui/ui-frontend-common/src/app/modules/models/units/object-group.interface.ts similarity index 97% rename from ui/ui-frontend-common/src/app/modules/models/units/unit-object-api.interface.ts rename to ui/ui-frontend-common/src/app/modules/models/units/object-group.interface.ts index 20442ac3a0d..ffa6959b284 100644 --- a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-api.interface.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/object-group.interface.ts @@ -25,8 +25,9 @@ * accept its terms. */ -import {ObjectQualifierType} from './unit.enums'; +import { ObjectQualifierType } from './unit.enums'; +// TODO: rename in ObjectGroup /** Object associated to a unit */ export interface ApiUnitObject { '#id': string; diff --git a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.spec.ts b/ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.spec.ts similarity index 95% rename from ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.spec.ts rename to ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.spec.ts index 31a7a20dfe8..d39e43f9490 100644 --- a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.spec.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.spec.ts @@ -25,9 +25,9 @@ * accept its terms. */ -import {QualifierDto, VersionDto} from './unit-object-api.interface'; -import {qualifiersToVersionsWithQualifier} from './unit-object-helper'; -import {ObjectQualifierType} from './unit.enums'; +import { QualifierDto, VersionDto } from './object-group.interface'; +import { qualifiersToVersionsWithQualifier } from './object-group.utils'; +import { ObjectQualifierType } from './unit.enums'; describe('unit-object-helper tests', () => { diff --git a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.ts b/ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.ts similarity index 95% rename from ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.ts rename to ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.ts index eef55a4cb0c..fa8306f9ba4 100644 --- a/ui/ui-frontend-common/src/app/modules/models/units/unit-object-helper.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/object-group.utils.ts @@ -24,8 +24,8 @@ * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you * accept its terms. */ -import {QualifierDto, VersionDto, VersionWithQualifierDto} from './unit-object-api.interface'; -import {ObjectQualifierTypeList} from './unit.enums'; +import { QualifierDto, VersionDto, VersionWithQualifierDto } from './object-group.interface'; +import { ObjectQualifierTypeList } from './unit.enums'; export function qualifiersToVersionsWithQualifier(qualifiers: Array): Array { if (!qualifiers || qualifiers.length < 1) { diff --git a/ui/ui-frontend-common/src/app/modules/models/units/unit.enums.ts b/ui/ui-frontend-common/src/app/modules/models/units/unit.enums.ts index 329db415eb6..b3a9bfed039 100644 --- a/ui/ui-frontend-common/src/app/modules/models/units/unit.enums.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/unit.enums.ts @@ -34,3 +34,9 @@ export enum ObjectQualifierType { } export const ObjectQualifierTypeList: Array = Object.values(ObjectQualifierType); + +export enum UnitTypes { + HOLDING_UNIT = 'HOLDING_UNIT', + FILING_UNIT = 'FILING_UNIT', + INGEST = 'INGEST', +} diff --git a/ui/ui-frontend-common/src/app/modules/models/units/unit-api.interface.ts b/ui/ui-frontend-common/src/app/modules/models/units/unit.interface.ts similarity index 100% rename from ui/ui-frontend-common/src/app/modules/models/units/unit-api.interface.ts rename to ui/ui-frontend-common/src/app/modules/models/units/unit.interface.ts diff --git a/ui/ui-frontend-common/src/app/modules/vitamui-unit-types.enum.ts b/ui/ui-frontend-common/src/app/modules/models/units/unit.utils.ts similarity index 69% rename from ui/ui-frontend-common/src/app/modules/vitamui-unit-types.enum.ts rename to ui/ui-frontend-common/src/app/modules/models/units/unit.utils.ts index f4690389da5..a8607eeaa68 100644 --- a/ui/ui-frontend-common/src/app/modules/vitamui-unit-types.enum.ts +++ b/ui/ui-frontend-common/src/app/modules/models/units/unit.utils.ts @@ -1,4 +1,4 @@ -/* +/** * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2022) * * contact.vitam@culture.gouv.fr @@ -24,9 +24,24 @@ * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you * accept its terms. */ +import { VitamuiIcons } from '../../vitamui-icons.enum'; +import { UnitTypes } from './unit.enums'; +import { Unit } from './unit.interface'; -export enum VitamuiUnitTypes { - HOLDING_UNIT = 'HOLDING_UNIT', - FILING_UNIT = 'FILING_UNIT', - INGEST = 'INGEST', +export function unitToVitamuiIcon(unit: Unit): VitamuiIcons { + const hasObject = unit['#object'] && unit['#object'].length > 0; + return unitTypeToVitamuiIcon(unit['#unitType'], hasObject); +} + +export function unitTypeToVitamuiIcon(unitType: string, hasObject: boolean): VitamuiIcons { + if (unitType === UnitTypes.HOLDING_UNIT) { + return VitamuiIcons.HOLDING_UNIT; + } + if (unitType === UnitTypes.FILING_UNIT) { + return VitamuiIcons.FILING_UNIT; + } + if (unitType === UnitTypes.INGEST && hasObject) { + return VitamuiIcons.INGEST_WITH_OBJECT; + } + return VitamuiIcons.INGEST_WITHOUT_OBJECT; } diff --git a/ui/ui-frontend-common/src/app/modules/vitamui-icons.enum.ts b/ui/ui-frontend-common/src/app/modules/vitamui-icons.enum.ts index b268f1a56fa..60f799fde52 100644 --- a/ui/ui-frontend-common/src/app/modules/vitamui-icons.enum.ts +++ b/ui/ui-frontend-common/src/app/modules/vitamui-icons.enum.ts @@ -26,8 +26,8 @@ */ export enum VitamuiIcons { - VITAMUI_HOLDING_UNIT_ICON_ = 'vitamui-icon-icone-arbre', - VITAMUI_FILING_UNIT_ICON_ = 'vitamui-icon-plan-classement', - VITAMUI_INGEST_WITHOUT_OBJECT_ICON_ = 'vitamui-icon-folder', - VITAMUI_INGEST_WITH_OBJECT_ICON_ = 'vitamui-icon-file', + HOLDING_UNIT = 'vitamui-icon-icone-arbre', + FILING_UNIT = 'vitamui-icon-plan-classement', + INGEST_WITHOUT_OBJECT = 'vitamui-icon-folder', + INGEST_WITH_OBJECT = 'vitamui-icon-file', } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.html index da68023854d..b591eef9516 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.html @@ -3,7 +3,7 @@ [title]=" (archiveUnit?.Title ? archiveUnit?.Title : archiveUnit.Title_.fr ? archiveUnit.Title_.fr : archiveUnit.Title_.en) | truncate : 29 " - [icon]="getArchiveUnitIcone(archiveUnit)" + [icon]="getArchiveUnitIcon(archiveUnit)" [hasToolTipOnTitle]="true" [toolTipTitleText]="archiveUnit?.Title ? archiveUnit?.Title : archiveUnit.Title_.fr ? archiveUnit.Title_.fr : archiveUnit.Title_.en" [toolTipTitleDuration]="300" @@ -46,8 +46,7 @@ + [archiveUnit]="archiveUnit"> diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts index b7b6ad30fd7..b89c58c1161 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.spec.ts @@ -109,7 +109,7 @@ describe('ArchivePreviewComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ArchivePreviewComponent); component = fixture.componentInstance; - const archiveUnit: Unit = { + component.archiveUnit = { '#allunitups': [], '#id': 'id', '#object': '', @@ -119,7 +119,6 @@ describe('ArchivePreviewComponent', () => { Title_: { fr: 'Teste', en: 'Test' }, Description_: { fr: 'DescriptionFr', en: 'DescriptionEn' }, }; - component.archiveUnit = archiveUnit; fixture.detectChanges(); }); @@ -197,61 +196,12 @@ describe('ArchivePreviewComponent', () => { }; // When - const response = component.getArchiveUnitIcone(archiveUnit); + const response = component.getArchiveUnitIcon(archiveUnit); // Then expect(response).toEqual(expectedResponse); }); - it('should return INGEST as response ', () => { - const archiveUnit: Unit = { - '#id': 'aeaqaaaaaehlvxukaazfaame7fyo5myaaaba', - Title: 'Porte de Bagnolet par producteur1', - DescriptionLevel: 'RecordGrp', - Description: 'Station Porte de Bagnolet ligne 3 Paris', - '#tenant': 1, - '#unitups': ['aeaqaaaaaehlvxukaazfaame7fyo5myaaaca'], - '#min': 1, - '#max': 2, - '#allunitups': ['aeaqaaaaaehlvxukaazfaame7fyo5myaaaca'], - '#unitType': 'INGEST', - '#operations': ['aeeaaaaaaghnanqdabliwame7fyokjqaaaaq'], - '#opi': 'aeeaaaaaaghnanqdabliwame7fyokjqaaaaq', - '#originating_agency': 'producteur1', - '#originating_agencies': ['producteur1'], - '#management': { - AppraisalRule: null, - HoldRule: null, - StorageRule: null, - ReuseRule: null, - ClassificationRule: null, - DisseminationRule: null, - AccessRule: null, - UpdateOperation: null, - }, - StartDate: new Date('2016-06-03T15:28:00'), - EndDate: new Date('2016-06-03T15:28:00'), - Xtag: [], - Vtag: [], - '#storage': { - strategyId: 'default', - }, - '#qualifiers': [], - OriginatingSystemId: ['OriginatingSystemId_00'], - PhysicalAgency: [], - PhysicalStatus: [], - PhysicalType: [], - Keyword: [], - '#approximate_creation_date': '2022-12-10T00:30:42.568', - '#approximate_update_date': '2022-12-10T00:30:42.568', - originating_agencyName: 'Service producteur1', - }; - - const response = component.getArchiveUnitType(archiveUnit); - - expect(response).toEqual('INGEST'); - }); - describe('DOM', () => { it('should have 3 mat-tab', () => { // When diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts index daebb174e21..422f0e867cc 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-preview.component.ts @@ -39,7 +39,7 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange import { MatTabChangeEvent } from '@angular/material/tabs'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { Unit, VitamuiIcons, VitamuiUnitTypes } from 'ui-frontend-common'; +import { Unit, unitToVitamuiIcon } from 'ui-frontend-common'; @Component({ selector: 'app-archive-preview', @@ -125,19 +125,7 @@ export class ArchivePreviewComponent implements OnInit, OnChanges { } } - getArchiveUnitIcone(archiveUnit: Unit) { - const archiveUnitType = this.getArchiveUnitType(archiveUnit); - - if (archiveUnitType === VitamuiUnitTypes.HOLDING_UNIT) { - return VitamuiIcons.VITAMUI_HOLDING_UNIT_ICON_; - } - if (archiveUnitType === VitamuiUnitTypes.FILING_UNIT) { - return VitamuiIcons.VITAMUI_FILING_UNIT_ICON_; - } - if (archiveUnitType === VitamuiUnitTypes.INGEST && !archiveUnit['#object']) { - return VitamuiIcons.VITAMUI_INGEST_WITHOUT_OBJECT_ICON_; - } - - return VitamuiIcons.VITAMUI_INGEST_WITH_OBJECT_ICON_; + getArchiveUnitIcon(unit: Unit) { + return unitToVitamuiIcon(unit); } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts index ed6253d611d..4301533e717 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-preview/archive-unit-rules-details-tab/archive-unit-rules-details-tab.component.ts @@ -60,8 +60,7 @@ const CURRENT_PAGE = 0; ], }) export class ArchiveUnitRulesDetailsTabComponent implements OnInit, OnChanges, OnDestroy { - @Input() - archiveUnit: Unit; + @Input() archiveUnit: Unit; archiveUnitRules: Unit; selectUnitWithInheritedRulesSubscription: Subscription; @@ -76,6 +75,7 @@ export class ArchiveUnitRulesDetailsTabComponent implements OnInit, OnChanges, O } ngOnInit(): void {} + ngOnDestroy() { this.selectUnitWithInheritedRulesSubscription?.unsubscribe(); } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts index fcbdb615a54..78cbbc21b9a 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts @@ -27,24 +27,14 @@ import { HttpErrorResponse } from '@angular/common/http'; import { - AfterContentChecked, - ChangeDetectorRef, - Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - OnInit, - Output, - SimpleChanges, - TemplateRef, + AfterContentChecked, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, ViewChild, } from '@angular/core'; import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { Subject, Subscription, merge } from 'rxjs'; +import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime, filter } from 'rxjs/operators'; import { CriteriaDataType, CriteriaOperator, Direction, FilingHoldingSchemeNode, Logger, Unit, VitamuiRoles } from 'ui-frontend-common'; import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; @@ -59,17 +49,8 @@ import { UpdateUnitManagementRuleService } from '../common-services/update-unit- import { ActionsRules } from '../models/ruleAction.interface'; import { SearchCriteriaEltements, SearchCriteriaHistory } from '../models/search-criteria-history.interface'; import { - ArchiveSearchResultFacets, - CriteriaValue, - PagedResult, - SearchCriteria, - SearchCriteriaAddAction, - SearchCriteriaCategory, - SearchCriteriaEltDto, - SearchCriteriaMgtRuleEnum, - SearchCriteriaRemoveAction, - SearchCriteriaStatusEnum, - SearchCriteriaTypeEnum, + ArchiveSearchResultFacets, CriteriaValue, PagedResult, SearchCriteria, SearchCriteriaAddAction, SearchCriteriaCategory, + SearchCriteriaEltDto, SearchCriteriaMgtRuleEnum, SearchCriteriaRemoveAction, SearchCriteriaStatusEnum, SearchCriteriaTypeEnum, } from '../models/search.criteria'; import { ReclassificationComponent } from './additional-actions-search/reclassification/reclassification.component'; import { SearchCriteriaSaverComponent } from './search-criteria-saver/search-criteria-saver.component'; @@ -475,10 +456,6 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft return this.searchCriterias && this.searchCriterias.has('WAITING_RECALCULATE'); } - findDefaultFacetTab(): number { - return this.archiveHelperService.findDefaultFacetTabIndex(this.searchCriterias); - } - submit() { this.initializeSelectionParams(); this.archiveHelperService.buildNodesListForQUery(this.searchCriterias, this.criteriaSearchList); @@ -570,7 +547,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.pending = true; const sortingCriteria = { criteria: this.orderBy, sorting: this.direction }; - const searchCriteria = { + const searchCriterias = { criteriaList: this.criteriaSearchList, pageNumber: this.currentPage, size: PAGE_SIZE, @@ -578,8 +555,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft trackTotalHits: false, computeFacets: includeFacets, }; - this.archiveExchangeDataService.emitLastSearchCriteriaDtoSubject(searchCriteria); - this.archiveService.searchArchiveUnitsByCriteria(searchCriteria).subscribe( + this.archiveExchangeDataService.emitSearchCriterias(searchCriterias); + this.archiveService.searchArchiveUnitsByCriteria(searchCriterias).subscribe( (pagedResult: PagedResult) => { if (includeFacets) { this.archiveSearchResultFacets = this.archiveFacetsService.extractRulesFacetsResults(pagedResult.facets); @@ -594,18 +571,13 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.archiveExchangeDataService.emitFacets(this.archiveSearchResultFacets.nodesFacets); this.hasResults = true; this.totalResults = pagedResult.totalResults; - } else { - if (pagedResult.results) { - this.hasResults = true; - pagedResult.results.forEach((elt) => this.archiveUnits.push(elt)); - } + this.archiveExchangeDataService.emitTotalResults(this.totalResults); + } else if (pagedResult.results) { + this.hasResults = true; + pagedResult.results.forEach((elt) => this.archiveUnits.push(elt)); } this.pageNumbers = pagedResult.pageNumbers; - if (this.totalResults === this.DEFAULT_RESULT_THRESHOLD) { - this.waitingToGetFixedCount = true; - } else { - this.waitingToGetFixedCount = false; - } + this.waitingToGetFixedCount = this.totalResults === this.DEFAULT_RESULT_THRESHOLD; if (this.isAllchecked) { this.itemSelected = this.totalResults - this.itemNotSelected; } @@ -680,7 +652,8 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft }); } - setFilingHoldingScheme() { + // TODO: it may add multiple subscription for each clear criteria + subscribeResetNodesOnFilingHoldingNodesChanges() { this.subscriptions.add( this.archiveExchangeDataService.getFilingHoldingNodes().subscribe((nodes) => { this.nodeArray = nodes; @@ -688,13 +661,25 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft ); } + recursiveCheck(nodes: FilingHoldingSchemeNode[], show: boolean) { + if (nodes.length === 0) { + return; + } + for (const node of nodes) { + node.hidden = false; + node.checked = show; + node.count = null; + this.recursiveCheck(node.children, show); + } + } + checkAllNodes(show: boolean) { - this.archiveHelperService.recursiveCheck(this.nodeArray, show); + this.recursiveCheck(this.nodeArray, show); } public reMapSearchCriteriaFromSearchCriteriaHistory(storedSearchCriteriaHistory: SearchCriteriaHistory) { - this.setFilingHoldingScheme(); - this.checkAllNodes(false); + this.subscribeResetNodesOnFilingHoldingNodesChanges(); + this.recursiveCheck(this.nodeArray, false); storedSearchCriteriaHistory.searchCriteriaList.forEach((criteria: SearchCriteriaEltements) => { this.fillTreeNodeAsSearchCriteriaHistory(criteria); @@ -866,9 +851,9 @@ export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy, Aft this.isIndeterminate = false; this.itemNotSelected = 0; this.canLoadMore = false; - this.setFilingHoldingScheme(); + this.subscribeResetNodesOnFilingHoldingNodesChanges(); this.archiveExchangeDataService.emitFilingHoldingNodes(this.nodeArray); - this.checkAllNodes(false); + this.recursiveCheck(this.nodeArray, false); } checkParentBoxChange(event: any) { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts index 1fa5530581d..2162d7eb884 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/simple-criteria-search/simple-criteria-search.component.ts @@ -40,7 +40,7 @@ import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { merge } from 'rxjs'; import { debounceTime, filter, map } from 'rxjs/operators'; -import { ActionOnCriteria, CriteriaDataType, CriteriaOperator, Ontology, OntologyService, diff } from 'ui-frontend-common'; +import { ActionOnCriteria, CriteriaDataType, CriteriaOperator, diff, Ontology, OntologyService } from 'ui-frontend-common'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; import { ManagementRulesSharedDataService } from '../../../core/management-rules-shared-data.service'; import { ArchiveService } from '../../archive.service'; @@ -334,8 +334,8 @@ export class SimpleCriteriaSearchComponent implements OnInit { this.criteriaSearchListToSave.forEach((criteriaSearch) => { if (criteriaSearch.criteria === ALL_ARCHIVE_UNIT_TYPES) { - criteriaSearch.values.forEach((unitType) => { - this.archiveUnitTypesCriteria.set(unitType.id, true); + criteriaSearch.values.forEach((criteriaValue) => { + this.archiveUnitTypesCriteria.set(criteriaValue.id, true); }); } criteriaSearch.values.forEach((value) => { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts index e044c5b4c13..17d2ec564f4 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts @@ -37,19 +37,11 @@ import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { Inject, Injectable, LOCALE_ID } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { Observable, TimeoutError, of, throwError } from 'rxjs'; +import { Observable, of, throwError, TimeoutError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { - AccessContract, - AccessContractApiService, - ApiUnitObject, - CriteriaDataType, - CriteriaOperator, - FilingHoldingSchemeNode, - Ontology, - SearchService, - SecurityService, - Unit, + AccessContract, AccessContractApiService, ApiUnitObject, CriteriaDataType, CriteriaOperator, FilingHoldingSchemeNode, Ontology, + SearchService, SecurityService, Unit, } from 'ui-frontend-common'; import { ArchiveApiService } from '../core/api/archive-api.service'; import { ExportDIPCriteriaList } from './models/dip-request-detail.interface'; @@ -110,14 +102,15 @@ export class ArchiveService extends SearchService { ) { const outNode: FilingHoldingSchemeNode = { id: unit['#id'], + vitamId: unit['#id'], title: unit.Title ? unit.Title : unit.Title_ ? (unit.Title_.fr ? unit.Title_.fr : unit.Title_.en) : unit.Title_.en, type: unit.DescriptionLevel, + unitType: unit['#unitType'], + descriptionLevel: unit.DescriptionLevel, children: [], - vitamId: unit['#id'], checked: false, hidden: false, - hasObject: unit['#object'] ? true : false, - unitType: unit['#unitType'], + hasObject: !!unit['#object'], }; outNode.children = this.buildNestedTreeLevels(arr, outNode); out.push(outNode); @@ -131,7 +124,7 @@ export class ArchiveService extends SearchService { } exportCsvSearchArchiveUnitsByCriteria(criteriaDto: SearchCriteriaDto) { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.exportCsvSearchArchiveUnitsByCriteria(criteriaDto, headers).subscribe( (file) => { @@ -158,7 +151,7 @@ export class ArchiveService extends SearchService { } searchArchiveUnitsByCriteria(criteriaDto: SearchCriteriaDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.searchArchiveUnitsByCriteria(criteriaDto, headers).pipe( // timeout(TIMEOUT_SEC), @@ -209,35 +202,35 @@ export class ArchiveService extends SearchService { } exportDIPService(exportDIPCriteriaList: ExportDIPCriteriaList): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.exportDipApiService(exportDIPCriteriaList, headers); } transferRequestService(transferDipCriteriaDto: TransferRequestDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.transferDipApiService(transferDipCriteriaDto, headers); } startEliminationAnalysis(criteriaDto: SearchCriteriaDto) { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.startEliminationAnalysis(criteriaDto, headers); } launchEliminationAction(criteriaDto: SearchCriteriaDto) { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.launchEliminationAction(criteriaDto, headers); } updateUnitsRules(ruleSearchCriteriaDto: RuleSearchCriteriaDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.updateUnitsRules(ruleSearchCriteriaDto, headers); } getAccessContractById(accessContract: string): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.accessContractApiService.getAccessContractById(accessContract, headers); } @@ -322,7 +315,7 @@ export class ArchiveService extends SearchService { } launchComputedInheritedRules(criteriaDto: SearchCriteriaDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.launchComputedInheritedRules(criteriaDto, headers); } @@ -345,13 +338,13 @@ export class ArchiveService extends SearchService { } selectUnitWithInheritedRules(criteriaDto: SearchCriteriaDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.selectUnitWithInheritedRules(criteriaDto, headers); } reclassification(criteriaDto: ReclassificationCriteriaDto): Observable { - let headers = new HttpHeaders().append('Content-Type', 'application/json'); + const headers = new HttpHeaders().append('Content-Type', 'application/json'); return this.archiveApiService.reclassification(criteriaDto, headers); } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-search-helper.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-search-helper.service.ts index d97ec32ce42..79c067d3482 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-search-helper.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/common-services/archive-search-helper.service.ts @@ -31,12 +31,7 @@ import { ActionOnCriteria, CriteriaDataType, CriteriaOperator, FilingHoldingSche import { ArchiveSharedDataService } from '../../core/archive-shared-data.service'; import { ArchiveService } from '../archive.service'; import { - CriteriaValue, - SearchCriteria, - SearchCriteriaEltDto, - SearchCriteriaStatusEnum, - SearchCriteriaTypeEnum, - SearchCriteriaValue, + CriteriaValue, SearchCriteria, SearchCriteriaEltDto, SearchCriteriaStatusEnum, SearchCriteriaTypeEnum, SearchCriteriaValue, } from '../models/search.criteria'; import { VitamUISnackBarComponent } from '../shared/vitamui-snack-bar'; @@ -471,18 +466,6 @@ export class ArchiveSearchHelperService { }); } - recursiveCheck(nodes: FilingHoldingSchemeNode[], show: boolean) { - if (nodes.length === 0) { - return; - } - for (const node of nodes) { - node.hidden = false; - node.checked = show; - node.count = null; - this.recursiveCheck(node.children, show); - } - } - fillNodeTitle( nodeArray: FilingHoldingSchemeNode[], nodeId: string, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.html index f944da01865..58c1ac23130 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/classification-tree/classification-tree.component.html @@ -17,7 +17,7 @@
diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts index ba55bfa25b8..211405b8b46 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.component.ts @@ -39,7 +39,7 @@ import { FilingHoldingSchemeHandler } from './filing-holding-scheme.handler'; @Component({ selector: 'app-filing-holding-scheme', templateUrl: './filing-holding-scheme.component.html', - styleUrls: [ './filing-holding-scheme.component.scss' ], + styleUrls: ['./filing-holding-scheme.component.scss'], }) export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestroy { @Input() accessContract: string; @@ -58,10 +58,12 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro loadingHolding = true; node: string; nodeData: NodeData; - hasMatchesInSearch = false; fullNodes: FilingHoldingSchemeNode[] = []; showEveryNodes = true; requestResultFacets: ResultFacet[]; + hasMatchesInSearch = false; + requestTotalResults: number; + requestResultsInFilingPlan: number; loadingArchiveUnit: { [key: string]: boolean } = { TREE: false, LEAVE: false, @@ -78,9 +80,10 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro } ngOnInit(): void { - this.initialNodesState(); - this.initialNodeCheckState(); - this.initialNodeFacetState(); + this.subscribeResetNodesOnFilingHoldingNodesChanges(); + this.subscribeOnNodeSelectionToSetCheck(); + this.subscribeOnFacetsChangesToResetCounts(); + this.subscribeOnTotalResultsChange(); } ngOnChanges(changes: SimpleChanges): void { @@ -94,7 +97,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro this.subscriptions.unsubscribe(); } - private initialNodeCheckState(): void { + private subscribeOnNodeSelectionToSetCheck(): void { this.subscriptions.add( this.archiveSharedDataService.getNodesTarget().subscribe((nodeId) => { if (nodeId == null) { @@ -107,13 +110,14 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro ); } - private initialNodeFacetState(): void { + private subscribeOnFacetsChangesToResetCounts(): void { this.subscriptions.add( this.archiveSharedDataService.getFacets().subscribe((facets) => { if (facets && facets.length > 0) { this.requestResultFacets = facets; this.hasMatchesInSearch = true; FilingHoldingSchemeHandler.setCountRecursively(this.nestedDataSourceFull.data, facets); + this.requestResultsInFilingPlan = FilingHoldingSchemeHandler.getCountSum(this.nestedDataSourceFull.data); } else { this.hasMatchesInSearch = false; for (const node of this.nestedDataSourceFull.data) { @@ -121,12 +125,23 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro node.hidden = true; } } - this.filterNodesToLeavesOnly(); + // fullNodes is a Graph . + // keeps last child with result only + this.nestedDataSourceLeaves.data = FilingHoldingSchemeHandler.keepEndNodesWithResultsOnly(this.fullNodes); + this.showEveryNodes = false; + }) + ); + } + + private subscribeOnTotalResultsChange(): void { + this.subscriptions.add( + this.archiveSharedDataService.getTotalResults().subscribe((totalResults) => { + this.requestTotalResults = totalResults }) ); } - private initialNodesState(): void { + private subscribeResetNodesOnFilingHoldingNodesChanges(): void { this.subscriptions.add( this.archiveSharedDataService.getFilingHoldingNodes().subscribe((nodes) => { if (nodes) { @@ -150,14 +165,6 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro ); } - filterNodesToLeavesOnly() { - // fullNodes is a Graph . - // keeps last child with result only - this.nestedDataSourceLeaves.data = FilingHoldingSchemeHandler.keepEndNodesWithResultsOnly(this.fullNodes); - this.showEveryNodes = false; - } - - addToSearchCriteria(node: FilingHoldingSchemeNode) { this.nodeData = { id: node.id, title: node.title, checked: node.checked, count: node.count }; FilingHoldingSchemeHandler.foundNodeAndSetCheck(this.nestedDataSourceFull.data, node.checked, node.id); @@ -178,7 +185,7 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro const criteriaSearchList = [ { criteria: '#id', - values: [ { id: archiveUnitId, value: archiveUnitId } ], + values: [{ id: archiveUnitId, value: archiveUnitId }], operator: CriteriaOperator.EQ, category: SearchCriteriaTypeEnum[SearchCriteriaTypeEnum.FIELDS], dataType: CriteriaDataType.STRING, diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.spec.ts index 31bbe99c7ec..72a9eb313ab 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.spec.ts @@ -89,20 +89,6 @@ describe('FilingHoldingSchemeHandler', () => { ]; }); - it('foundNodeAndSetCheck with invalid id is false', () => { - expect(FilingHoldingSchemeHandler.foundNodeAndSetCheck(uaNodes, true, 'not-an-id')).toBeFalsy(); - }); - - it('foundNodeAndSetCheck change checked and return true', () => { - node = uaNodes[0].children[0].children[4]; - expect(node.id).toEqual('node-0-0-4'); - expect(node.checked).toBeFalsy(); - expect(FilingHoldingSchemeHandler.foundNodeAndSetCheck(uaNodes, true, 'node-0-0-4')).toBeTruthy(); - expect(node.checked).toBeTruthy(); - expect(FilingHoldingSchemeHandler.foundNodeAndSetCheck(uaNodes, false, 'node-0-0-4')).toBeTruthy(); - expect(node.checked).toBeFalsy(); - }); - it('setCountRecursively do nothing without facets', () => { facets = []; expect(FilingHoldingSchemeHandler.setCountRecursively(uaNodes, facets)).toEqual(0); @@ -158,6 +144,34 @@ describe('FilingHoldingSchemeHandler', () => { expect(node.count).toEqual(12); }); + it('getCountSum should return the sum of every count of top rank nodes', () => { + node = uaNodes[0].children[0].children[2]; + expect(node.id).toEqual('node-0-0-2'); + expect(node.count).toBeUndefined(); + node = uaNodes[2].children[2]; + expect(node.id).toEqual('node-2-2'); + expect(node.count).toBeUndefined(); + facets = [ + { node: 'node-0-0-2', count: 42 }, + { node: 'node-2-2', count: 65 }, + ]; + expect(FilingHoldingSchemeHandler.setCountRecursively(uaNodes, facets)).toEqual(2); + node = uaNodes[0].children[0].children[2]; + expect(node.id).toEqual('node-0-0-2'); + expect(node.count).toEqual(42); + node = uaNodes[2].children[2]; + expect(node.id).toEqual('node-2-2'); + expect(node.count).toEqual(65); + facets = [{ node: 'node-2-2', count: 12 }]; + expect(FilingHoldingSchemeHandler.setCountRecursively(uaNodes, facets)).toEqual(1); + node = uaNodes[0].children[0].children[2]; + expect(node.id).toEqual('node-0-0-2'); + expect(node.count).toEqual(0); + node = uaNodes[2].children[2]; + expect(node.id).toEqual('node-2-2'); + expect(node.count).toEqual(12); + }); + it('addChildrenRecursively should add new children and not presents ones', () => { const units = [ newUnit('node-2-3', 'node-2'), @@ -302,63 +316,45 @@ describe('FilingHoldingSchemeHandler', () => { expect(FilingHoldingSchemeHandler.unitHasDirectParent(unit, 'node-2')).toBeTruthy(); }); - it('foundChild test', () => { - node = newNode('node-0'); - expect(FilingHoldingSchemeHandler.foundChild(node, 'whatever')).toBeUndefined(); - - const child = newNode('node-0-0'); - node = newNode('node-0', [child]); - expect(FilingHoldingSchemeHandler.foundChild(node, 'node-0-0')).toBe(child); - - node = newNode('node-0', [ - newNode('node-0-0', [newNode('node-0-0-0'), newNode('node-0-0-1', [newNode('node-0-0-1-0')])]), - newNode('node-0-1'), - newNode('node-0-2'), - ]); - expect(FilingHoldingSchemeHandler.foundChild(node, 'whatever')).toBeUndefined(); - expect(FilingHoldingSchemeHandler.foundChild(node, 'node-0-0')).toBeDefined(); - expect(FilingHoldingSchemeHandler.foundChild(node, 'node-0-0-0')).toBeUndefined(); - expect(FilingHoldingSchemeHandler.foundChild(node, 'node-0-0-1-0')).toBeUndefined(); - }); - - it('addDirectChildrenOnly should not add already presents nodes nor add node of other parents', () => { - const toggleNode = uaNodes[0]; - expect(toggleNode.children.length).toEqual(5); - const resturnedUnits = [ - newUnit('node-0-0', 'node-0'), // already present - newUnit('node-0-5', 'node-0'), // new - newUnit('new-node', 'node-0-1'), // wrong parent - ]; - const matchingNodesNumbers: MatchingNodesNumbers = FilingHoldingSchemeHandler.addDirectChildrenOnly(toggleNode, resturnedUnits); - - expect(matchingNodesNumbers.nodesAdded).toEqual(1); - expect(matchingNodesNumbers.nodesUpdated).toEqual(0); - expect(matchingNodesNumbers.nodesFoundButUnchanged).toEqual(1); - expect(toggleNode.children.length).toEqual(6); - expect(toggleNode.children[0].count).toEqual(undefined); // unchanged - expect(toggleNode.children[5].count).toEqual(0); // new - }); - - it('addDirectChildrenOnly ', () => { - const toggleNode = uaNodes[0]; - expect(toggleNode.children.length).toEqual(5); - const resturnedUnits = [ - newUnit('node-0-2', 'node-0'), // already present - newUnit('new-node-0-5', 'node-0'), // new - newUnit('new-node-0-6', 'node-0'), // new - newUnit('new-node', 'node-0-1'), // wrong parent - ]; - const matchingNodesNumbers: MatchingNodesNumbers = FilingHoldingSchemeHandler.addDirectChildrenOnly(toggleNode, resturnedUnits, true); - - expect(matchingNodesNumbers.nodesAdded).toEqual(2); - expect(matchingNodesNumbers.nodesAddedList.length).toEqual(2); - expect(matchingNodesNumbers.nodesAddedList[0].id).toEqual('new-node-0-5'); - expect(matchingNodesNumbers.nodesAddedList[1].id).toEqual('new-node-0-6'); - expect(matchingNodesNumbers.nodesUpdated).toEqual(0); - expect(matchingNodesNumbers.nodesFoundButUnchanged).toEqual(1); - expect(toggleNode.children[0].count).toEqual(undefined); // unchanged - expect(toggleNode.children[5].count).toEqual(1); - expect(toggleNode.children[6].count).toEqual(1); + describe('addChildren', () => { + it('should not add already presents nodes nor add node of other parents', () => { + const toggleNode = uaNodes[0]; + expect(toggleNode.children.length).toEqual(5); + const resturnedUnits = [ + newUnit('node-0-0', 'node-0'), // already present + newUnit('node-0-5', 'node-0'), // new + newUnit('new-node', 'node-0-1'), // wrong parent + ]; + const matchingNodesNumbers: MatchingNodesNumbers = FilingHoldingSchemeHandler.addChildren(toggleNode, resturnedUnits); + + expect(matchingNodesNumbers.nodesAdded).toEqual(1); + expect(matchingNodesNumbers.nodesUpdated).toEqual(0); + expect(matchingNodesNumbers.nodesFoundButUnchanged).toEqual(1); + expect(toggleNode.children.length).toEqual(6); + expect(toggleNode.children[0].count).toEqual(undefined); // unchanged + expect(toggleNode.children[5].count).toEqual(0); // new + }); + it('should init count when specified ', () => { + const toggleNode = uaNodes[0]; + expect(toggleNode.children.length).toEqual(5); + const resturnedUnits = [ + newUnit('node-0-2', 'node-0'), // already present + newUnit('new-node-0-5', 'node-0'), // new + newUnit('new-node-0-6', 'node-0'), // new + newUnit('new-node', 'node-0-1'), // wrong parent + ]; + const matchingNodesNumbers: MatchingNodesNumbers = FilingHoldingSchemeHandler.addChildren(toggleNode, resturnedUnits, true); + + expect(matchingNodesNumbers.nodesAdded).toEqual(2); + expect(matchingNodesNumbers.nodesAddedList.length).toEqual(2); + expect(matchingNodesNumbers.nodesAddedList[0].id).toEqual('new-node-0-5'); + expect(matchingNodesNumbers.nodesAddedList[1].id).toEqual('new-node-0-6'); + expect(matchingNodesNumbers.nodesUpdated).toEqual(0); + expect(matchingNodesNumbers.nodesFoundButUnchanged).toEqual(1); + expect(toggleNode.children[0].count).toEqual(undefined); // unchanged + expect(toggleNode.children[5].count).toEqual(1); + expect(toggleNode.children[6].count).toEqual(1); + }); }); it('filterUnknownFacets filter unknown ids', () => { @@ -390,4 +386,60 @@ describe('FilingHoldingSchemeHandler', () => { newFacets = []; expect(FilingHoldingSchemeHandler.filterUnknownFacets(oldFacets, newFacets)).toEqual([]); }); + describe('foundChild', () => { + it('should return undefined when children is empty', () => { + const parentNode = newTreeNode('node-1', 0, []); + expect(FilingHoldingSchemeHandler.foundChild(parentNode, 'whatever')).toEqual(undefined); + }); + it('should return the child node found ', () => { + const nodeToFound = newTreeNode('node-1-1', 0); + const parentNode = newTreeNode('node-1', 0, [ + newTreeNode('node-1-0', 0), + nodeToFound, + ]); + expect(FilingHoldingSchemeHandler.foundChild(parentNode, 'node-1-1')).toEqual(nodeToFound); + }); + }); + describe('foundNodeAndSetCheck', () => { + it('should return false if the nodes array is empty', () => { + const nodes: FilingHoldingSchemeNode[] = []; + const checked = true; + const nodeId = '12345'; + const actual = FilingHoldingSchemeHandler.foundNodeAndSetCheck(nodes, checked, nodeId); + const expected = false; + expect(actual).toBe(expected); + }); + + it('should return false if the node with the specified ID is not found', () => { + const nodes: FilingHoldingSchemeNode[] = [newNode('node-1'), newNode('node-2')]; + const nodeHasBeenChecked = FilingHoldingSchemeHandler.foundNodeAndSetCheck(nodes, true, 'bad-id'); + expect(nodeHasBeenChecked).toBe(false); + }); + + it('should set the checked property of the node with the specified ID to true', () => { + const nodes = [newNode('node-1')]; + const checked = true; + const nodeHasBeenChecked = FilingHoldingSchemeHandler.foundNodeAndSetCheck(nodes, checked, 'node-1'); + expect(nodeHasBeenChecked).toBe(true); + expect(nodes[0].checked).toBe(checked); + }); + + it('should set the checked property of the node with the specified ID to false', () => { + const nodes = [newNode('node-1')]; + const checked = false; + const nodeHasBeenChecked = FilingHoldingSchemeHandler.foundNodeAndSetCheck(nodes, checked, 'node-1'); + expect(nodeHasBeenChecked).toBe(true); + expect(nodes[0].checked).toBe(checked); + }); + + it('should recursively search the child nodes if the node with the specified ID is not found', () => { + const nodes: FilingHoldingSchemeNode[] = [ + newTreeNode('node-1', 1, [newNode('node-1-1')]), + ]; + const checked = true; + const nodeHasBeenChecked = FilingHoldingSchemeHandler.foundNodeAndSetCheck(nodes, checked, 'node-1-1'); + expect(nodeHasBeenChecked).toBe(true); + expect(nodes[0].children[0].checked).toBe(checked); + }); + }); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.ts index 68c8a10d4bc..35a794f1226 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/filing-holding-scheme.handler.ts @@ -27,7 +27,11 @@ import { copyNodeWithoutChildren, DescriptionLevel, FilingHoldingSchemeNode, MatchingNodesNumbers, Unit } from 'ui-frontend-common'; import { ResultFacet } from '../models/search.criteria'; +const ORPHANS_NODE = 'ORPHANS_NODE'; + +// TODO: merge with node.utils export class FilingHoldingSchemeHandler { + public static foundNodeAndSetCheck(nodes: FilingHoldingSchemeNode[], checked: boolean, nodeId: string): boolean { if (nodes.length < 1) { return false; @@ -59,12 +63,26 @@ export class FilingHoldingSchemeHandler { return 0; } + public static getCountSum(nodes: FilingHoldingSchemeNode[]): number { + if (!nodes || nodes.length < 1) { + return 0; + } + let sum = 0; + for (const node of nodes) { + sum += node.count; + } + return sum; + } + public static setCountRecursively(nodes: FilingHoldingSchemeNode[], facets: ResultFacet[]): number { if (!nodes || nodes.length < 1) { return 0; } let nodesUpdated = 0; for (const node of nodes) { + if (this.isOrphansNode(node)) { + continue; + } nodesUpdated += FilingHoldingSchemeHandler.setCountOnNode(node, facets); nodesUpdated += FilingHoldingSchemeHandler.setCountRecursively(node.children, facets); node.hidden = nodesUpdated === 0; @@ -72,6 +90,72 @@ export class FilingHoldingSchemeHandler { return nodesUpdated; } + public static reCalculateCountRecursively(parentNode: FilingHoldingSchemeNode,): void { + if (parentNode.count < 1) { + // not a match + return; + } + if (!parentNode.children) { + parentNode.children = []; + } + let count = 0; + for (const node of parentNode.children) { + this.reCalculateCountRecursively(node); + count += node.count; + } + if (count < parentNode.count) { + return; + } + if (!this.isOrphansNode(parentNode)) { + count = count + 1;// self match + } + parentNode.count = count; + } + + public static isOrphansNode(node: FilingHoldingSchemeNode): boolean { + return node.vitamId === ORPHANS_NODE + } + + public static addToOrphansNode(nodes: FilingHoldingSchemeNode[], + parentNodes: FilingHoldingSchemeNode[], + nodeTitle: string,) { + if (parentNodes.length < 1 || !this.isOrphansNode(parentNodes[0])) { + console.log(' addOrphansNodeFromTree (empty)'); + this.addOrphansNodeFromTree(parentNodes, nodeTitle, this.getCountSum(nodes)); + } + if (parentNodes[0].children.length < 1) { + parentNodes[0].children = nodes; + return; + } + for (const node of nodes) { + console.log(' try to find child ' + node.id); + const existingNode: FilingHoldingSchemeNode = FilingHoldingSchemeHandler.foundChild(parentNodes[0], node.id); + if (!existingNode) { + console.log(' push ' + node.id); + parentNodes[0].children.push(node); + } + } + } + + + public static addOrphansNodeFromTree(parentNodes: FilingHoldingSchemeNode[], + nodeTitle: string, + orphansNumber: number) { + if (parentNodes.length < 1 || !this.isOrphansNode(parentNodes[0])) { + const orphanNode: FilingHoldingSchemeNode = { + checked: false, + children: [], + id: ORPHANS_NODE, + title: nodeTitle, + type: ORPHANS_NODE, + vitamId: ORPHANS_NODE, + count: orphansNumber, + } + parentNodes.unshift(orphanNode) + return; + } + } + public static keepEndNodesWithResultsOnly(nodes: FilingHoldingSchemeNode[]): FilingHoldingSchemeNode[] { if (!nodes) { return []; @@ -105,13 +189,22 @@ export class FilingHoldingSchemeHandler { if (!parentNode.children) { parentNode.children = []; } - return parentNode.children.find((nodeChild) => nodeChild.id === childId); + return parentNode.children.find((nodeChild) => nodeChild && nodeChild.id === childId); } - public static addDirectChildrenOnly( + public static addOrphans( parentNode: FilingHoldingSchemeNode, units: Unit[], initCount: boolean = false + ): MatchingNodesNumbers { + return this.addChildren(parentNode, units, initCount, false); + } + + public static addChildren( + parentNode: FilingHoldingSchemeNode, + units: Unit[], + initCount: boolean = false, + checkPaternity: boolean = true ): MatchingNodesNumbers { const matchingNodes = new MatchingNodesNumbers(); if (!parentNode.children) { @@ -122,7 +215,7 @@ export class FilingHoldingSchemeHandler { if (!unit) { continue; } - if (!FilingHoldingSchemeHandler.unitHasDirectParent(unit, parentNode.id)) { + if (checkPaternity && !FilingHoldingSchemeHandler.unitHasDirectParent(unit, parentNode.id)) { continue; } let child: FilingHoldingSchemeNode = FilingHoldingSchemeHandler.foundChild(parentNode, unit['#id']); @@ -157,7 +250,7 @@ export class FilingHoldingSchemeHandler { return matchingNodesNumbers; } for (const parentNode of parentNodes) { - matchingNodesNumbers.mergeWith(FilingHoldingSchemeHandler.addDirectChildrenOnly(parentNode, units, initCount)); + matchingNodesNumbers.mergeWith(FilingHoldingSchemeHandler.addChildren(parentNode, units, initCount)); matchingNodesNumbers.mergeWith(FilingHoldingSchemeHandler.addChildrenRecursively(parentNode.children, units, initCount)); } return matchingNodesNumbers; @@ -187,6 +280,7 @@ export class FilingHoldingSchemeHandler { id: unit['#id'], title: unit.Title ? unit.Title : unit.Title_ ? (unit.Title_.fr ? unit.Title_.fr : unit.Title_.en) : unit.Title_.en, type: unit['#unitType'], + unitType: unit['#unitType'], descriptionLevel: unit.DescriptionLevel, children: [], vitamId: unit['#id'], @@ -194,8 +288,57 @@ export class FilingHoldingSchemeHandler { isLoadingChildren: false, canLoadMoreChildren: unit.DescriptionLevel !== DescriptionLevel.ITEM, count: 0, - hasObject: unit['#object'] ? true : false, - unitType: unit['#unitType'], + hasObject: !!unit['#object'], + }; + } + + public static buildNestedTreeLevels(units: Unit[], locale: string, parentNode?: FilingHoldingSchemeNode): FilingHoldingSchemeNode[] { + const nodes: FilingHoldingSchemeNode[] = []; + for (let i = 0; i < units.length; i++) { + if (units[i] === undefined) { + continue; + } + const unit = units[i]; + if (this.isParent(parentNode, unit) || (!parentNode && this.isNullIOrUnknowId(unit, units))) { + const outNode: FilingHoldingSchemeNode = { + id: unit['#id'], + vitamId: unit['#id'], + title: unit.Title ? unit.Title : unit.Title_ ? (unit.Title_.fr ? unit.Title_.fr : unit.Title_.en) : unit.Title_.en, + type: unit.DescriptionLevel, + unitType: unit['#unitType'], + descriptionLevel: unit.DescriptionLevel, + children: [], + checked: false, + hidden: false, + hasObject: !!unit['#object'], + }; + units[i] = undefined; + outNode.children = this.buildNestedTreeLevels(units, locale, outNode); + nodes.push(outNode); + } + } + return nodes.sort(this.byTitle(locale)); + } + + public static isParent(parentNode: FilingHoldingSchemeNode, unit: Unit): boolean { + return (parentNode && parentNode.vitamId && unit['#unitups'] && unit['#unitups'][0] === parentNode.vitamId) + } + + public static isNullIOrUnknowId(unit: Unit, units: Unit[]): boolean { + return (!unit['#unitups'] || !unit['#unitups'].length || !this.idExists(units, unit['#unitups'][0])) + } + + + public static idExists(units: Unit[], id: string): boolean { + return !!units.find((unit) => unit && unit['#id'] === id); + } + + public static byTitle(locale: string): (a: FilingHoldingSchemeNode, b: FilingHoldingSchemeNode) => number { + return (a, b) => { + if (!a || !b || !a.title || !b.title) { + return 0; + } + return a.title.localeCompare(b.title, locale, { numeric: true }); }; } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.html index cd3a68e2b3a..281373a62b8 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.html @@ -8,12 +8,13 @@
- +
- +
@@ -47,7 +48,7 @@ + +
+ + + + {{ node.count | number : '1.0' }} + +
+ +
+
-
- + +
@@ -97,7 +127,7 @@ diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.scss b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.scss index 3c3e8254446..1f826710bdd 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.scss +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.scss @@ -115,18 +115,25 @@ .badge { display: inline-block; - padding: 0.25em 1.5em; + padding: 0.25em 0; font-size: 100%; font-weight: 700; line-height: 1; position: absolute; - top: 14px; + top: 11px; + right: 2px; white-space: nowrap; vertical-align: baseline; border-radius: 1.25rem; - right: 2px; width: 54px; - text-align: right; + text-align: center; +} + +.badge-primary { + // Primary/Primary-500 + color: #9C31B5; + // Primary/Primary-100 + background-color: #E6C3EF; } .badge-secondary { diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts index c8e11e955a0..4ae1be2df5f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.spec.ts @@ -287,28 +287,6 @@ describe('LeavesTreeComponent', () => { expect(response).toBeFalsy(); }); - it('should return INGEST as response ', () => { - const filingHoldingSchemaNode: FilingHoldingSchemeNode = { - id: 'filingHoldingSchemaNodeId', - title: 'string', - type: 'INGEST', - unitType: 'INGEST', - descriptionLevel: 'Item', - label: 'string', - children: [], - count: 55, - vitamId: 'vitamId', - checked: true, - hidden: false, - isLoadingChildren: true, - paginatedChildrenLoaded: 5, - }; - - const response = component.getNodeUnitType(filingHoldingSchemaNode); - - expect(response).toEqual('INGEST'); - }); - it('should return vitamui-icon-folder as response ', () => { const filingHoldingSchemaNode: FilingHoldingSchemeNode = { id: 'filingHoldingSchemaNodeId', @@ -326,7 +304,7 @@ describe('LeavesTreeComponent', () => { paginatedChildrenLoaded: 5, }; - const response = component.getNodeUnitIcone(filingHoldingSchemaNode); + const response = component.getNodeUnitIcon(filingHoldingSchemaNode); expect(response).toEqual('vitamui-icon-folder'); }); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts index 866c61f16e8..a9cf03ac69b 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.component.ts @@ -25,23 +25,16 @@ * accept its terms. */ import { NestedTreeControl } from '@angular/cdk/tree'; -import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Component, EventEmitter, Inject, Input, LOCALE_ID, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import { MatTreeNestedDataSource } from '@angular/material/tree'; -import { Observable, Subscription } from 'rxjs'; -import { first } from 'rxjs/operators'; -import { - CriteriaDataType, - CriteriaOperator, - DescriptionLevel, - FilingHoldingSchemeNode, - VitamuiIcons, - VitamuiUnitTypes -} from 'ui-frontend-common'; +import { TranslateService } from '@ngx-translate/core'; +import { Subscription } from 'rxjs'; +import { DescriptionLevel, FilingHoldingSchemeNode, nodeToVitamuiIcon, Unit } from 'ui-frontend-common'; import { ArchiveSharedDataService } from '../../../core/archive-shared-data.service'; -import { ArchiveService } from '../../archive.service'; import { ArchiveFacetsService } from '../../common-services/archive-facets.service'; -import { PagedResult, ResultFacet, SearchCriteriaDto, SearchCriteriaTypeEnum } from '../../models/search.criteria'; +import { PagedResult, ResultFacet, SearchCriteriaDto } from '../../models/search.criteria'; import { FilingHoldingSchemeHandler } from '../filing-holding-scheme.handler'; +import { LeavesTreeService } from './leaves-tree.service'; @Component({ selector: 'app-leaves-tree', @@ -49,7 +42,6 @@ import { FilingHoldingSchemeHandler } from '../filing-holding-scheme.handler'; styleUrls: ['./leaves-tree.component.scss'], }) export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { - readonly DEFAULT_UNIT_PAGE_SIZE = 10; @Input() accessContract: string; @Input() loadingNodeUnit: boolean; @@ -57,10 +49,11 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { // Already a graph @Input() nestedDataSourceLeaves: MatTreeNestedDataSource; @Input() searchRequestResultFacets: ResultFacet[]; + @Input() searchRequestTotalResults: number; + @Input() searchRequestResultsInFilingPlan: number; @Output() addToSearchCriteria: EventEmitter = new EventEmitter(); @Output() showNodeDetail: EventEmitter = new EventEmitter(); - @Output() switchView: EventEmitter = new EventEmitter(); nestedTreeControlLeaves: NestedTreeControl = new NestedTreeControl( (node) => node.children @@ -70,24 +63,63 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { private subscriptions: Subscription = new Subscription(); constructor( - private archiveService: ArchiveService, + private leavesTreeService: LeavesTreeService, private archiveSharedDataService: ArchiveSharedDataService, - private archiveFacetsService: ArchiveFacetsService - ) {} + private archiveFacetsService: ArchiveFacetsService, + private translateService: TranslateService, + @Inject(LOCALE_ID) private locale: string, + ) { + } ngOnChanges(changes: SimpleChanges): void { if (changes.nestedDataSourceLeaves || changes.searchRequestResultFacets) { this.nestedTreeControlLeaves.dataNodes = this.nestedDataSourceLeaves.data; - this.loadNodesDetailsFromFacetsIds(this.nestedDataSourceLeaves.data, this.searchRequestResultFacets); + console.log('changes ' + changes.nestedDataSourceLeaves ? 'nestedDataSourceLeaves' : 'searchRequestResultFacets'); + console.log(' loadNodesDetailsFromFacetsIdsAndAddThem'); + this.loadNodesDetailsFromFacetsIdsAndAddThem(this.nestedDataSourceLeaves.data, this.searchRequestResultFacets); + console.log(' addOrphansNode'); + this.addOrphansNode(); + } else if (changes.searchRequestTotalResults || changes.searchRequestResultsInFilingPlan) { + console.log('changes ' + changes.searchRequestTotalResults ? 'searchRequestTotalResults' : 'searchRequestResultsInFilingPlan'); + console.log(' addOrphansNode'); + this.addOrphansNode(); + } + } + + addOrphansNode() { + console.log(' searchRequestTotalResults = ' + this.searchRequestTotalResults) + console.log(' searchRequestResultsInFilingPlan = ' + this.searchRequestResultsInFilingPlan) + const unknonwFacets = FilingHoldingSchemeHandler.filterUnknownFacetsIds(this.nestedDataSourceLeaves.data, + this.searchRequestResultFacets); + console.log(unknonwFacets ? ' unknonwFacets ' + unknonwFacets.length : ' NO unknonwFacets....'); + if (unknonwFacets) { + console.log(' loadNodesDetailsFromFacetsIds'); + this.leavesTreeService.loadNodesDetailsFromFacetsIds(unknonwFacets) + .subscribe((pageResult) => { + console.log(' buildNestedTreeLevels'); + const nodes = FilingHoldingSchemeHandler.buildNestedTreeLevels(pageResult.results, this.locale); + console.log(JSON.stringify(nodes)); + console.log(' setCountRecursively'); + FilingHoldingSchemeHandler.setCountRecursively(nodes, unknonwFacets); + console.log(' addToOrphansNode'); + FilingHoldingSchemeHandler.addToOrphansNode(nodes, this.nestedDataSourceLeaves.data, + this.translateService.instant('Sans rattachement')); + console.log(' refreshTreeNodes'); + this.refreshTreeNodes(); + this.loadingNodesDetails = false; + }); + } + const orphans = this.searchRequestTotalResults - this.searchRequestResultsInFilingPlan; + console.log(' orphans = ' + orphans); + if (orphans > 0) { + console.log(' addOrphansNodeFromTree (empty)'); + FilingHoldingSchemeHandler.addOrphansNodeFromTree(this.nestedDataSourceLeaves.data, + this.translateService.instant('Sans rattachement'), orphans); } } ngOnInit(): void { - this.subscriptions.add( - this.archiveSharedDataService.getLastSearchCriteriaDtoSubject().subscribe((searchCriteriaDto: SearchCriteriaDto) => { - this.searchCriterias = searchCriteriaDto; - }) - ); + this.subscribeOnSearchCriteriasUpdate(); } ngOnDestroy(): void { @@ -98,49 +130,6 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { this.addToSearchCriteria.emit(node); } - private prepareSearch(parentNode: FilingHoldingSchemeNode, matchingSearch: boolean): boolean { - if (matchingSearch && !parentNode.canLoadMoreMatchingChildren) { - return false; - } else if (!matchingSearch && !parentNode.canLoadMoreChildren) { - return false; - } - parentNode.isLoadingChildren = true; - return true; - } - - private loadNodesDetailsFromFacetsIds(parentNodes: FilingHoldingSchemeNode[], facets: ResultFacet[]) { - if (facets.length < 1) { - return; - } - this.loadingNodesDetails = true; - const searchCriteria: SearchCriteriaDto = { - pageNumber: 0, - size: facets.length, - criteriaList: [ - { - criteria: '#id', - operator: CriteriaOperator.IN, - category: SearchCriteriaTypeEnum.FIELDS, - values: facets.map((facet) => { - return { id: facet.node, value: facet.node }; - }), - dataType: CriteriaDataType.STRING, - }, - ], - trackTotalHits: false, - computeFacets: false, - }; - // Can be improve with a projection (only nodes fields are needed) - this.subscriptions.add( - this.sendSearchArchiveUnitsByCriteria(searchCriteria).subscribe((pageResult) => { - FilingHoldingSchemeHandler.addChildrenRecursively(parentNodes, pageResult.results, true); - FilingHoldingSchemeHandler.setCountRecursively(parentNodes, facets); - this.refreshTreeNodes(); - this.loadingNodesDetails = false; - }) - ); - } - private compareAddedNodeWithKnownFacets(nodes: FilingHoldingSchemeNode[]) { for (const node of nodes) { const matchingFacet = this.searchRequestResultFacets.find((resultFacet) => resultFacet.node === node.id); @@ -153,76 +142,57 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { } } + private searchOrphans(parentNode: FilingHoldingSchemeNode) { + this.leavesTreeService.searchOrphans(parentNode, this.searchCriterias) + .subscribe((results: Unit[]) => { + const matchingNodesNumbers = FilingHoldingSchemeHandler.addOrphans(parentNode, results); + this.compareAddedNodeWithKnownFacets(matchingNodesNumbers.nodesAddedList); + this.refreshTreeNodes(); + }); + } + + private searchOrphansWithSearchCriterias(parentNode: FilingHoldingSchemeNode) { + this.leavesTreeService.searchOrphansWithSearchCriterias(parentNode, this.searchCriterias) + .subscribe((pageResult) => { + FilingHoldingSchemeHandler.addOrphans(parentNode, pageResult.results, true); + this.refreshTreeNodes(); + }); + } + private searchUnderNode(parentNode: FilingHoldingSchemeNode) { - if (!this.prepareSearch(parentNode, false)) { - return; - } - const searchCriteria: SearchCriteriaDto = { - pageNumber: Math.floor(parentNode.paginatedChildrenLoaded / this.DEFAULT_UNIT_PAGE_SIZE), - size: this.DEFAULT_UNIT_PAGE_SIZE, - criteriaList: [ - { - criteria: '#unitups', - operator: CriteriaOperator.IN, - category: SearchCriteriaTypeEnum.FIELDS, - values: [{ id: parentNode.id, value: parentNode.id }], - dataType: CriteriaDataType.STRING, - }, - ], - sortingCriteria: this.searchCriterias.sortingCriteria, - trackTotalHits: false, - computeFacets: false, - }; - this.subscriptions.add( - this.sendSearchArchiveUnitsByCriteria(searchCriteria).subscribe((pageResult) => { - const matchingNodesNumbers = FilingHoldingSchemeHandler.addDirectChildrenOnly(parentNode, pageResult.results); - parentNode.paginatedChildrenLoaded += pageResult.results.length; - parentNode.canLoadMoreChildren = parentNode.children.length < pageResult.totalResults; - parentNode.isLoadingChildren = false; + this.leavesTreeService.searchUnderNode(parentNode, this.searchCriterias) + .subscribe((pageResult) => { + const matchingNodesNumbers = FilingHoldingSchemeHandler.addChildren(parentNode, pageResult.results); this.compareAddedNodeWithKnownFacets(matchingNodesNumbers.nodesAddedList); this.refreshTreeNodes(); - }) - ); + }); } private searchUnderNodeWithSearchCriterias(parentNode: FilingHoldingSchemeNode) { - if (!this.prepareSearch(parentNode, true)) { + this.leavesTreeService.searchUnderNodeWithSearchCriterias(parentNode, this.searchCriterias) + .subscribe((pageResult) => { + FilingHoldingSchemeHandler.addChildren(parentNode, pageResult.results, true); + const newFacets: ResultFacet[] = this.extractAndAddNewFacets(pageResult); + this.loadNodesDetailsFromFacetsIdsAndAddThem([parentNode], newFacets); + this.refreshTreeNodes(); + }); + } + + private loadNodesDetailsFromFacetsIdsAndAddThem(parentNodes: FilingHoldingSchemeNode[], facets: ResultFacet[]) { + if (facets.length < 1) { return; } - const newCriteriaList = [...this.searchCriterias.criteriaList]; - newCriteriaList.push({ - criteria: '#allunitups', - operator: CriteriaOperator.EQ, - category: SearchCriteriaTypeEnum.FIELDS, - values: [{ id: parentNode.id, value: parentNode.id }], - dataType: CriteriaDataType.STRING, - }); - const searchCriteria: SearchCriteriaDto = { - pageNumber: Math.floor(parentNode.paginatedMatchingChildrenLoaded / this.DEFAULT_UNIT_PAGE_SIZE), - size: this.DEFAULT_UNIT_PAGE_SIZE, - criteriaList: newCriteriaList, - sortingCriteria: this.searchCriterias.sortingCriteria, - trackTotalHits: false, - computeFacets: false, - }; - this.sendSearchArchiveUnitsByCriteria(searchCriteria).subscribe((pageResult) => { - // warning: if returned order is random, direct children may be at the end of pagination and will not be returned on first call - // it may require a third call with criterias and only on direct childrens - const matchingNodesNumbers = FilingHoldingSchemeHandler.addDirectChildrenOnly(parentNode, pageResult.results, true); - const loadedNodes = matchingNodesNumbers.nodesAdded + matchingNodesNumbers.nodesUpdated; - parentNode.paginatedMatchingChildrenLoaded += loadedNodes; - parentNode.canLoadMoreMatchingChildren = loadedNodes >= this.DEFAULT_UNIT_PAGE_SIZE; - if (parentNode.paginatedMatchingChildrenLoaded >= pageResult.totalResults) { - parentNode.canLoadMoreMatchingChildren = false; - } - const newFacets: ResultFacet[] = this.getAndSaveNewFacets(pageResult); - this.loadNodesDetailsFromFacetsIds([parentNode], newFacets); - parentNode.isLoadingChildren = false; - this.refreshTreeNodes(); - }); + this.loadingNodesDetails = true; + this.leavesTreeService.loadNodesDetailsFromFacetsIds(facets) + .subscribe((pageResult) => { + FilingHoldingSchemeHandler.addChildrenRecursively(parentNodes, pageResult.results, true); + FilingHoldingSchemeHandler.setCountRecursively(parentNodes, facets); + this.refreshTreeNodes(); + this.loadingNodesDetails = false; + }); } - private getAndSaveNewFacets(pageResult: PagedResult): ResultFacet[] { + private extractAndAddNewFacets(pageResult: PagedResult): ResultFacet[] { // Warning: count decrease on top nodes when search is made on a deeper nodes. const resultFacets: ResultFacet[] = this.archiveFacetsService.extractNodesFacetsResults(pageResult.facets); const newFacets: ResultFacet[] = FilingHoldingSchemeHandler.filterUnknownFacets(this.searchRequestResultFacets, resultFacets); @@ -232,10 +202,6 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { return newFacets; } - private sendSearchArchiveUnitsByCriteria(searchCriteria: SearchCriteriaDto): Observable { - return this.archiveService.searchArchiveUnitsByCriteria(searchCriteria).pipe(first()); - } - private refreshTreeNodes() { const data = this.nestedDataSourceLeaves.data; this.nestedDataSourceLeaves.data = null; @@ -257,6 +223,18 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { return true; } + toggleOrphan(node: FilingHoldingSchemeNode) { + const isExpanded = this.nestedTreeControlLeaves.isExpanded(node); + this.nestedTreeControlLeaves.toggle(node); + if (isExpanded) { + return; + } + if (this.firstToggle(node)) { + this.searchOrphans(node); + this.searchOrphansWithSearchCriterias(node); + } + } + toggleLeave(node: FilingHoldingSchemeNode) { const isExpanded = this.nestedTreeControlLeaves.isExpanded(node); this.nestedTreeControlLeaves.toggle(node); @@ -277,6 +255,14 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { this.searchUnderNodeWithSearchCriterias(node); } + toggleLoadMoreOrphans(node: FilingHoldingSchemeNode) { + if (!this.nestedTreeControlLeaves.isExpanded(node)) { + return; + } + this.searchOrphans(node); + this.searchOrphansWithSearchCriterias(node); + } + canLoadMoreUAForNode(node: FilingHoldingSchemeNode): boolean { if (node.isLoadingChildren || node.canLoadMoreChildren === false) { return false; @@ -295,6 +281,10 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { return node.type === 'INGEST' && node.descriptionLevel === DescriptionLevel.ITEM; } + nodeIsOrphanNode(_: number, node: FilingHoldingSchemeNode): boolean { + return FilingHoldingSchemeHandler.isOrphansNode(node); + } + nodeHasPositiveCount(node: FilingHoldingSchemeNode): boolean { return node.count && node.count > 0; } @@ -311,19 +301,16 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { this.showEveryNodes = !this.showEveryNodes; } - getNodeUnitType(filingholdingscheme: FilingHoldingSchemeNode) { - if (filingholdingscheme && filingholdingscheme.unitType) { - return filingholdingscheme.unitType; - } + getNodeUnitIcon(filingholdingscheme: FilingHoldingSchemeNode) { + return nodeToVitamuiIcon(filingholdingscheme); } - getNodeUnitIcone(filingholdingscheme: FilingHoldingSchemeNode) { - return this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.HOLDING_UNIT - ? VitamuiIcons.VITAMUI_HOLDING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.FILING_UNIT - ? VitamuiIcons.VITAMUI_FILING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.INGEST && !filingholdingscheme?.hasObject - ? VitamuiIcons.VITAMUI_INGEST_WITHOUT_OBJECT_ICON_ - : VitamuiIcons.VITAMUI_INGEST_WITH_OBJECT_ICON_; + private subscribeOnSearchCriteriasUpdate() { + this.subscriptions.add( + this.archiveSharedDataService.getSearchCriterias().subscribe((searchCriteriaDto: SearchCriteriaDto) => { + this.searchCriterias = searchCriteriaDto; + }) + ); } + } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.service.ts new file mode 100644 index 00000000000..4911ecdd4ba --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/filing-holding-scheme/leaves-tree/leaves-tree.service.ts @@ -0,0 +1,218 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { first, map } from 'rxjs/operators'; +import { CriteriaDataType, CriteriaOperator, FilingHoldingSchemeNode, Unit } from 'ui-frontend-common'; +import { ArchiveService } from '../../archive.service'; +import { PagedResult, ResultFacet, SearchCriteriaDto, SearchCriteriaEltDto, SearchCriteriaTypeEnum } from '../../models/search.criteria'; +import { FilingHoldingSchemeHandler } from '../filing-holding-scheme.handler'; + +const DEFAULT_UNIT_PAGE_SIZE = 10; + +const ALLUNITSUPS = '#allunitups'; + +@Injectable({ + providedIn: 'root', +}) +export class LeavesTreeService { + + constructor(private archiveService: ArchiveService,) {} + + private prepareSearch(parentNode: FilingHoldingSchemeNode, matchingSearch: boolean): boolean { + if (matchingSearch && !parentNode.canLoadMoreMatchingChildren) { + return false; + } else if (!matchingSearch && !parentNode.canLoadMoreChildren) { + return false; + } + parentNode.isLoadingChildren = true; + return true; + } + + private finishSearch(parentNode: FilingHoldingSchemeNode, pageResult: PagedResult, matchingSearch: boolean): void { + parentNode.isLoadingChildren = false; + if (matchingSearch) { + parentNode.paginatedMatchingChildrenLoaded += pageResult.results.length; + parentNode.canLoadMoreMatchingChildren = parentNode.children.length < pageResult.totalResults; + } else { + parentNode.paginatedChildrenLoaded += pageResult.results.length; + parentNode.canLoadMoreChildren = parentNode.children.length < pageResult.totalResults; + } + } + + recalculateCount(nodes: FilingHoldingSchemeNode[]): void { + for (const node of nodes) { + FilingHoldingSchemeHandler.reCalculateCountRecursively(node); + } + } + + hasCountAnomaly(parentNode: FilingHoldingSchemeNode): boolean { + const sum = FilingHoldingSchemeHandler.getCountSum(parentNode.children) + if (sum >= parentNode.count) { + parentNode.count = sum + 1; + return true; + } + return false; + } + + searchOrphans(parentNode: FilingHoldingSchemeNode, searchCriterias: SearchCriteriaDto): Observable { + if (!this.prepareSearch(parentNode, false)) { + return; + } + const newCriteriaList: SearchCriteriaEltDto[] = [ + { + criteria: '#unitups', + operator: CriteriaOperator.MISSING, + category: SearchCriteriaTypeEnum.FIELDS, + values: [], + dataType: CriteriaDataType.STRING, + }, + ]; + const searchCriteria: SearchCriteriaDto = { + pageNumber: Math.floor(parentNode.paginatedChildrenLoaded / DEFAULT_UNIT_PAGE_SIZE), + size: DEFAULT_UNIT_PAGE_SIZE, + criteriaList: newCriteriaList, + sortingCriteria: searchCriterias.sortingCriteria, + trackTotalHits: false, + computeFacets: false, + }; + return this.sendSearchArchiveUnitsByCriteria(searchCriteria) + .pipe(map((pageResult) => { + this.finishSearch(parentNode, pageResult, false); + return pageResult.results; + })); + } + + searchOrphansWithSearchCriterias(parentNode: FilingHoldingSchemeNode, searchCriterias: SearchCriteriaDto): Observable { + if (!this.prepareSearch(parentNode, true)) { + return; + } + const newCriteriaList = [...searchCriterias.criteriaList]; + newCriteriaList.push({ + criteria: '#allunitups', + operator: CriteriaOperator.MISSING, + category: SearchCriteriaTypeEnum.FIELDS, + values: [], + dataType: CriteriaDataType.STRING, + }); + const searchCriteria: SearchCriteriaDto = { + pageNumber: Math.floor(parentNode.paginatedMatchingChildrenLoaded / DEFAULT_UNIT_PAGE_SIZE), + size: DEFAULT_UNIT_PAGE_SIZE, + criteriaList: newCriteriaList, + sortingCriteria: searchCriterias.sortingCriteria, + trackTotalHits: false, + computeFacets: false, + }; + return this.sendSearchArchiveUnitsByCriteria(searchCriteria) + .pipe(map(pageResult => { + this.finishSearch(parentNode, pageResult, true); + return pageResult; + })); + /* + // warning: if returned order is random, direct children may be at the end of pagination and will not be returned on first call + // it may require a third call with criterias and only on direct childrens + const matchingNodesNumbers = FilingHoldingSchemeHandler.addChildrenWithoutPaternityCheck(parentNode, pageResult.results, true); + const loadedNodes = matchingNodesNumbers.nodesAdded + matchingNodesNumbers.nodesUpdated; + parentNode.paginatedMatchingChildrenLoaded += loadedNodes; + parentNode.canLoadMoreMatchingChildren = loadedNodes >= DEFAULT_UNIT_PAGE_SIZE; + if (parentNode.paginatedMatchingChildrenLoaded >= pageResult.totalResults) { + parentNode.canLoadMoreMatchingChildren = false; + */ + } + + searchUnderNode(parentNode: FilingHoldingSchemeNode, searchCriterias: SearchCriteriaDto): Observable { + if (!this.prepareSearch(parentNode, false)) { + return; + } + const searchCriteria: SearchCriteriaDto = { + pageNumber: Math.floor(parentNode.paginatedChildrenLoaded / DEFAULT_UNIT_PAGE_SIZE), + size: DEFAULT_UNIT_PAGE_SIZE, + criteriaList: [ + { + criteria: '#unitups', + operator: CriteriaOperator.IN, + category: SearchCriteriaTypeEnum.FIELDS, + values: [{ id: parentNode.id, value: parentNode.id }], + dataType: CriteriaDataType.STRING, + }, + ], + sortingCriteria: searchCriterias.sortingCriteria, + trackTotalHits: false, + computeFacets: false, + }; + return this.sendSearchArchiveUnitsByCriteria(searchCriteria) + .pipe(map(pageResult => { + this.finishSearch(parentNode, pageResult, false); + return pageResult; + })); + } + + searchUnderNodeWithSearchCriterias(parentNode: FilingHoldingSchemeNode, searchCriterias: SearchCriteriaDto): Observable { + if (!this.prepareSearch(parentNode, true)) { + return; + } + const newCriteriaList = [...searchCriterias.criteriaList]; + newCriteriaList.push({ + criteria: ALLUNITSUPS, + operator: CriteriaOperator.EQ, + category: SearchCriteriaTypeEnum.FIELDS, + values: [{ id: parentNode.id, value: parentNode.id }], + dataType: CriteriaDataType.STRING, + }); + const searchCriteria: SearchCriteriaDto = { + pageNumber: Math.floor(parentNode.paginatedMatchingChildrenLoaded / DEFAULT_UNIT_PAGE_SIZE), + size: DEFAULT_UNIT_PAGE_SIZE, + criteriaList: newCriteriaList, + sortingCriteria: searchCriterias.sortingCriteria, + trackTotalHits: false, + computeFacets: false, + }; + return this.sendSearchArchiveUnitsByCriteria(searchCriteria) + .pipe(map(pageResult => { + this.finishSearch(parentNode, pageResult, true); + return pageResult; + })); + /* + // warning: if returned order is random, direct children may be at the end of pagination and will not be returned on first call + // it may require a third call with criterias and only on direct childrens + const matchingNodesNumbers = FilingHoldingSchemeHandler.addChildren(parentNode, pageResult.results, true); + const loadedNodes = matchingNodesNumbers.nodesAdded + matchingNodesNumbers.nodesUpdated; + parentNode.paginatedMatchingChildrenLoaded += loadedNodes; + parentNode.canLoadMoreMatchingChildren = loadedNodes >= DEFAULT_UNIT_PAGE_SIZE; + if (parentNode.paginatedMatchingChildrenLoaded >= pageResult.totalResults) { + parentNode.canLoadMoreMatchingChildren = false; + } + const newFacets: ResultFacet[] = this.getAndSaveNewFacets(pageResult); + this.loadNodesDetailsFromFacetsIds([parentNode], newFacets); + + parentNode.isLoadingChildren = false; + this.refreshTreeNodes(); + */ + } + + + loadNodesDetailsFromFacetsIds(facets: ResultFacet[]): Observable { + const searchCriteria: SearchCriteriaDto = { + pageNumber: 0, + size: facets.length, + criteriaList: [ + { + criteria: '#id', + operator: CriteriaOperator.IN, + category: SearchCriteriaTypeEnum.FIELDS, + values: facets.map((facet) => { + return { id: facet.node, value: facet.node }; + }), + dataType: CriteriaDataType.STRING, + }, + ], + trackTotalHits: false, + computeFacets: false, + }; + // Can be improve with a projection (only nodes fields are needed) + return this.sendSearchArchiveUnitsByCriteria(searchCriteria) + .pipe() + } + + sendSearchArchiveUnitsByCriteria(searchCriteria: SearchCriteriaDto): Observable { + return this.archiveService.searchArchiveUnitsByCriteria(searchCriteria).pipe(first()); + } +} diff --git a/ui/ui-frontend/projects/archive-search/src/app/core/archive-shared-data.service.ts b/ui/ui-frontend/projects/archive-search/src/app/core/archive-shared-data.service.ts index f74172aa9da..5f2c63b15e6 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/core/archive-shared-data.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/core/archive-shared-data.service.ts @@ -54,11 +54,12 @@ export class ArchiveSharedDataService { private filingHoldingNodesSubject = new BehaviorSubject(null); private targetNode = new BehaviorSubject(''); private facetsSubject = new BehaviorSubject([]); + private totalResultsSubject = new BehaviorSubject(null); private toggleSubject = new BehaviorSubject(true); private toggleReverseSubject = new BehaviorSubject(true); private archiveUnitTpPreviewSubject = new BehaviorSubject(null); private toggleArchiveUnitSubject = new BehaviorSubject(true); - private lastSearchCriteriaDtoSubject = new BehaviorSubject(null); + private lastSearchCriterias = new BehaviorSubject(null); private storedSearchCriteriaHistorySubject = new BehaviorSubject(null); private allSearchCriteriaHistorySubject = new BehaviorSubject([]); @@ -105,7 +106,8 @@ export class ArchiveSharedDataService { removeFromApraisalSearchCriteriaObservable = this.searchCriteriaRemoveFromChildSubject.asObservable(); - constructor() {} + constructor() { + } emitRuleCategory(ruleCategory: string) { this.ruleCategory.next(ruleCategory); @@ -147,6 +149,14 @@ export class ArchiveSharedDataService { return this.facetsSubject.asObservable(); } + emitTotalResults(facets: number) { + this.totalResultsSubject.next(facets); + } + + getTotalResults(): Observable { + return this.totalResultsSubject.asObservable(); + } + emitToggle(show: boolean) { this.toggleSubject.next(show); } @@ -159,8 +169,12 @@ export class ArchiveSharedDataService { this.storedSearchCriteriaHistorySubject.next(searchCriteriaHistory); } - emitLastSearchCriteriaDtoSubject(searchCriteriaDto: SearchCriteriaDto): void { - this.lastSearchCriteriaDtoSubject.next(searchCriteriaDto); + emitSearchCriterias(searchCriteriaDto: SearchCriteriaDto): void { + this.lastSearchCriterias.next(searchCriteriaDto); + } + + getSearchCriterias(): Observable { + return this.lastSearchCriterias.asObservable(); } emitArchiveUnitTitle(auTitle: string) { @@ -183,10 +197,6 @@ export class ArchiveSharedDataService { return this.storedSearchCriteriaHistorySubject.asObservable(); } - getLastSearchCriteriaDtoSubject(): Observable { - return this.lastSearchCriteriaDtoSubject.asObservable(); - } - emitAllSearchCriteriaHistory(searchCriteriaHistory: SearchCriteriaHistory[]) { this.allSearchCriteriaHistorySubject.next(searchCriteriaHistory); } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-collect.service.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-collect.service.ts index d4403a5bbf2..09887dc54b4 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-collect.service.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-collect.service.ts @@ -228,7 +228,7 @@ export class ArchiveCollectService extends SearchService { return of({ $hits: null, $results: [] }); }), map((response) => { - return this.buildNestedTreeLevels(response.$results); + return this.buildNestedTreeLevels(response.$results as Unit[]); }) ); } @@ -252,7 +252,7 @@ export class ArchiveCollectService extends SearchService { return this.transactionApiService.getObjectGroupDetailsById(objectId, headers); } - private buildNestedTreeLevels(arr: any[], parentNode?: FilingHoldingSchemeNode): FilingHoldingSchemeNode[] { + private buildNestedTreeLevels(arr: Unit[], parentNode?: FilingHoldingSchemeNode): FilingHoldingSchemeNode[] { const out: FilingHoldingSchemeNode[] = []; arr.forEach((unit) => { @@ -262,15 +262,15 @@ export class ArchiveCollectService extends SearchService { ) { const outNode: FilingHoldingSchemeNode = { id: unit['#id'], + vitamId: unit['#id'], title: unit.Title ? unit.Title : unit.Title_ ? (unit.Title_.fr ? unit.Title_.fr : unit.Title_.en) : unit.Title_.en, type: unit.DescriptionLevel, + unitType: unit['#unitType'], + descriptionLevel: unit.descriptionLevel, children: [], - parents: parentNode ? [parentNode] : [], - vitamId: unit['#id'], checked: false, hidden: false, - hasObject: unit['#object'] ? true : false, - unitType: unit['#unitType'], + hasObject: !!unit['#object'], }; outNode.children = this.buildNestedTreeLevels(arr, outNode); out.push(outNode); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.html index cb18786e3d0..a55befe87d7 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.html @@ -3,7 +3,7 @@ [title]=" (archiveUnit?.Title ? archiveUnit?.Title : archiveUnit.Title_.fr ? archiveUnit.Title_.fr : archiveUnit.Title_.en) | truncate : 29 " - [icon]="getArchiveUnitIcone(archiveUnit)" + [icon]="getArchiveUnitIcon(archiveUnit)" [hasToolTipOnTitle]="true" [toolTipTitleText]="archiveUnit?.Title ? archiveUnit?.Title : archiveUnit.Title_.fr ? archiveUnit.Title_.fr : archiveUnit.Title_.en" [toolTipTitleDuration]="300" @@ -37,7 +37,7 @@ > diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts index f68026e289f..8f10fe36c76 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.spec.ts @@ -97,7 +97,7 @@ describe('ArchivePreviewComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ArchivePreviewComponent); component = fixture.componentInstance; - const archiveUnit: Unit = { + component.archiveUnit = { '#allunitups': [], '#id': 'id', '#object': '', @@ -107,7 +107,6 @@ describe('ArchivePreviewComponent', () => { Title_: { fr: 'Teste', en: 'Test' }, Description_: { fr: 'DescriptionFr', en: 'DescriptionEn' }, }; - component.archiveUnit = archiveUnit; fixture.detectChanges(); }); @@ -126,45 +125,6 @@ describe('ArchivePreviewComponent', () => { expect(component.selectedIndex).toEqual(1); }); - it('should return INGEST as response ', () => { - const archiveUnit: Unit = { - '#id': 'aeaqaaaaaehlvxukaazfaame7fyo5myaaaba', - Title: 'Porte de Bagnolet par producteur1', - DescriptionLevel: 'RecordGrp', - Description: 'Station Porte de Bagnolet ligne 3 Paris', - '#tenant': 1, - '#unitups': ['aeaqaaaaaehlvxukaazfaame7fyo5myaaaca'], - '#min': 1, - '#max': 2, - '#allunitups': ['aeaqaaaaaehlvxukaazfaame7fyo5myaaaca'], - '#unitType': 'INGEST', - '#operations': ['aeeaaaaaaghnanqdabliwame7fyokjqaaaaq'], - '#opi': 'aeeaaaaaaghnanqdabliwame7fyokjqaaaaq', - '#originating_agency': 'producteur1', - '#originating_agencies': ['producteur1'], - StartDate: new Date('2016-06-03T15:28:00'), - EndDate: new Date('2016-06-03T15:28:00'), - Xtag: [], - Vtag: [], - '#storage': { - strategyId: 'default', - }, - '#qualifiers': [], - OriginatingSystemId: ['OriginatingSystemId_00'], - PhysicalAgency: [], - PhysicalStatus: [], - PhysicalType: [], - Keyword: [], - '#approximate_creation_date': '2022-12-10T00:30:42.568', - '#approximate_update_date': '2022-12-10T00:30:42.568', - originating_agencyName: 'Service producteur1', - }; - - const response = component.getArchiveUnitType(archiveUnit); - - expect(response).toEqual('INGEST'); - }); - it('should show the extended panel ', () => { // Given const matTabEvent = { index: 1 } as MatTabChangeEvent; @@ -210,7 +170,7 @@ describe('ArchivePreviewComponent', () => { originating_agencyName: 'Service producteur1', }; - const response = component.getArchiveUnitIcone(archiveUnit); + const response = component.getArchiveUnitIcon(archiveUnit); expect(response).toEqual('vitamui-icon-folder'); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts index 159a04ea7f7..ecdbd4983d4 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-preview/archive-preview.component.ts @@ -38,7 +38,7 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { MatTabChangeEvent } from '@angular/material/tabs'; import { TranslateService } from '@ngx-translate/core'; -import { Unit, VitamuiIcons, VitamuiUnitTypes } from 'ui-frontend-common'; +import { Unit, unitToVitamuiIcon } from 'ui-frontend-common'; @Component({ selector: 'app-archive-preview', @@ -48,7 +48,7 @@ import { Unit, VitamuiIcons, VitamuiUnitTypes } from 'ui-frontend-common'; export class ArchivePreviewComponent implements OnInit, OnChanges { @Input() archiveUnit: Unit; - + @Output() backToNormalLateralPanel: EventEmitter = new EventEmitter(); @Output() @@ -68,6 +68,7 @@ export class ArchivePreviewComponent implements OnInit, OnChanges { @Input() hasUpdateDescriptiveUnitMetadataRole: boolean; hasAccessContractManagementPermissionsMessage = this.translateService.instant('UNIT_UPDATE.NO_PERMISSION'); + constructor(private translateService: TranslateService) {} ngOnInit() {} @@ -115,19 +116,7 @@ export class ArchivePreviewComponent implements OnInit, OnChanges { } } - getArchiveUnitType(archiveUnit: Unit) { - if (archiveUnit) { - return archiveUnit['#unitType']; - } - } - - getArchiveUnitIcone(archiveUnit: Unit) { - return this.getArchiveUnitType(archiveUnit) === VitamuiUnitTypes.HOLDING_UNIT - ? VitamuiIcons.VITAMUI_HOLDING_UNIT_ICON_ - : this.getArchiveUnitType(archiveUnit) === VitamuiUnitTypes.FILING_UNIT - ? VitamuiIcons.VITAMUI_FILING_UNIT_ICON_ - : this.getArchiveUnitType(archiveUnit) === VitamuiUnitTypes.INGEST && !archiveUnit['#object'] - ? VitamuiIcons.VITAMUI_INGEST_WITHOUT_OBJECT_ICON_ - : VitamuiIcons.VITAMUI_INGEST_WITH_OBJECT_ICON_; + getArchiveUnitIcon(unit: Unit) { + return unitToVitamuiIcon(unit); } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.html index 20b5030a140..2d75d75be54 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/classification-tree/classification-tree.component.html @@ -17,7 +17,7 @@
; @Input() nestedTreeControlFull: NestedTreeControl; @@ -76,19 +76,8 @@ export class ClassificationTreeComponent { onClosePanel() { this.closePanel.emit(); } - getNodeUnitType(filingholdingscheme: FilingHoldingSchemeNode) { - if (filingholdingscheme && filingholdingscheme.unitType) { - return filingholdingscheme.unitType; - } - } - getNodeUnitIcone(filingholdingscheme: FilingHoldingSchemeNode) { - return this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.HOLDING_UNIT - ? VitamuiIcons.VITAMUI_HOLDING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.FILING_UNIT - ? VitamuiIcons.VITAMUI_FILING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.INGEST && !filingholdingscheme?.hasObject - ? VitamuiIcons.VITAMUI_INGEST_WITHOUT_OBJECT_ICON_ - : VitamuiIcons.VITAMUI_INGEST_WITH_OBJECT_ICON_; + getNodeUnitIcon(filingholdingscheme: FilingHoldingSchemeNode) { + return nodeToVitamuiIcon(filingholdingscheme); } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts index f09e3c3bbcb..f286383cada 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.component.ts @@ -158,18 +158,19 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro const unflattedNodes = FilingHoldingSchemeHandler.unflatAndFilterTreeNodes(this.fullNodes, attachmenUnitsFromCollect); unflattedNodes.forEach((unitParent) => { const collectAttachmentUnit = attachmenUnitsFromCollect.find( - (unitFromCollect) => unitFromCollect[VitamInternalFields.MANAGEMENT].UpdateOperation.SystemId == unitParent.id + (unitFromCollect) => unitFromCollect[VitamInternalFields.MANAGEMENT].UpdateOperation.SystemId === unitParent.id ); if (collectAttachmentUnit) { const outNode: FilingHoldingSchemeNode = { id: collectAttachmentUnit[VitamInternalFields.ID], + vitamId: unitParent.id, title: unitParent.title, type: collectAttachmentUnit.DescriptionLevel, + unitType: unitParent?.unitType, + descriptionLevel: collectAttachmentUnit.DescriptionLevel, children: [], - vitamId: unitParent.id, checked: false, hidden: false, - unitType: unitParent?.unitType, hasObject: unitParent?.hasObject, }; const unitsresults: Unit[] = []; @@ -235,23 +236,21 @@ export class FilingHoldingSchemeComponent implements OnInit, OnChanges, OnDestro * The param "archiveUniParams" is a Pair of a string that refers to AU ID and a boolean * that refers to the type of the AU wich is a collect unit or Vitam unit : * (auId : string, isCollectUnit : boolean) - * @param archiveUniParams - * @param from */ fetchUaFromNodeAndShowDetails(archiveUniParams: Pair, from: string) { this.loadingArchiveUnit[from] = true; this.subscriptions.add( Boolean(archiveUniParams.value) ? this.archiveService.getCollectUnitDetails(archiveUniParams.key.toString()).subscribe((unit) => { - this.showArchiveUnitDetails.emit(unit); + this.showArchiveUnitDetails.emit(unit); + this.loadingArchiveUnit[`${from}`] = false; + }) + : this.archiveService + .getReferentialUnitDetails(archiveUniParams.key.toString()) + .subscribe((searchResponse) => { + this.showArchiveUnitDetails.emit(searchResponse.$results[0]); this.loadingArchiveUnit[`${from}`] = false; }) - : this.archiveService - .getReferentialUnitDetails(archiveUniParams.key.toString()) - .subscribe((searchResponse) => { - this.showArchiveUnitDetails.emit(searchResponse.$results[0]); - this.loadingArchiveUnit[`${from}`] = false; - }) ); } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.handler.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.handler.ts index c7ae50c842e..3d5f734cd4c 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.handler.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/filing-holding-scheme.handler.ts @@ -86,7 +86,7 @@ export class FilingHoldingSchemeHandler { if (!node.children || node.children.length < 1) { if ( !attachmenUnitsFromCollect.some( - (unitFromCollect) => unitFromCollect[VitamInternalFields.MANAGEMENT].UpdateOperation.SystemId == node.id + (unitFromCollect) => unitFromCollect[VitamInternalFields.MANAGEMENT].UpdateOperation.SystemId === node.id ) ) { continue; @@ -129,7 +129,7 @@ export class FilingHoldingSchemeHandler { } public static unitHasDirectParent(unit: Unit, parentId: string): boolean { - return unit[VitamInternalFields.UNIT_UPS].findIndex((unitupId) => unitupId === parentId) !== -1; + return unit['#unitups'].findIndex((unitupId) => unitupId === parentId) !== -1; } public static foundChild(parentNode: FilingHoldingSchemeNode, childId: string): FilingHoldingSchemeNode { @@ -225,7 +225,8 @@ export class FilingHoldingSchemeHandler { return { id: unit[VitamInternalFields.ID], title: unit.Title ? unit.Title : unit.Title_ ? (unit.Title_.fr ? unit.Title_.fr : unit.Title_.en) : unit.Title_.en, - type: unit[VitamInternalFields.UNIT_TYPE], + type: unit['#unitType'], + unitType: unit['#unitType'], descriptionLevel: unit.DescriptionLevel, children: [], vitamId: unit[VitamInternalFields.ID], @@ -233,8 +234,7 @@ export class FilingHoldingSchemeHandler { isLoadingChildren: false, canLoadMoreChildren: unit.DescriptionLevel !== DescriptionLevel.ITEM, count: 0, - hasObject: unit['#object'] ? true : false, - unitType: unit['#unitType'], + hasObject: !!unit['#object'], }; } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.html b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.html index dbf441f4065..1ef8fc157e7 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.html +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.html @@ -12,7 +12,7 @@
{ it('LeavesTreeComponent should be stable after creation', () => { expect(component).toBeTruthy(); - // expect(component.projectId).toBeDefined(); + // expect(component.projectId).toBeDefined(); expect(component.nestedTreeControlLeaves).toBeDefined(); }); - it('should return INGEST as response ', () => { - const filingHoldingSchemaNode: FilingHoldingSchemeNode = { - id: 'filingHoldingSchemaNodeId', - title: 'string', - type: 'INGEST', - unitType: 'INGEST', - descriptionLevel: 'Item', - label: 'string', - children: [], - count: 55, - vitamId: 'vitamId', - checked: true, - hidden: false, - isLoadingChildren: true, - paginatedChildrenLoaded: 5, - }; - - const response = component.getNodeUnitType(filingHoldingSchemaNode); - - expect(response).toEqual('INGEST'); - }); - it('should return vitamui-icon-folder as response ', () => { const filingHoldingSchemaNode: FilingHoldingSchemeNode = { id: 'filingHoldingSchemaNodeId', @@ -162,7 +140,7 @@ describe('LeavesTreeComponent', () => { paginatedChildrenLoaded: 5, }; - const response = component.getNodeUnitIcone(filingHoldingSchemaNode); + const response = component.getNodeUnitIcon(filingHoldingSchemaNode); expect(response).toEqual('vitamui-icon-folder'); }); diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts index 5170e923fae..93b4bf1238f 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/filing-holding-scheme/leaves-tree/leaves-tree.component.ts @@ -30,14 +30,7 @@ import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, S import { MatTreeNestedDataSource } from '@angular/material/tree'; import { Observable, Subscription } from 'rxjs'; import { first } from 'rxjs/operators'; -import { - CriteriaDataType, - CriteriaOperator, - DescriptionLevel, - FilingHoldingSchemeNode, - VitamuiIcons, - VitamuiUnitTypes -} from 'ui-frontend-common'; +import { CriteriaDataType, CriteriaOperator, DescriptionLevel, FilingHoldingSchemeNode, nodeToVitamuiIcon } from 'ui-frontend-common'; import { ArchiveCollectService } from '../../../../archive-collect.service'; import { PagedResult, ResultFacet, SearchCriteriaDto, SearchCriteriaTypeEnum } from '../../../models/search.criteria'; import { Pair, VitamInternalFields } from '../../../models/utils'; @@ -80,7 +73,7 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { ngOnChanges(changes: SimpleChanges): void { if (changes.nestedDataSourceLeaves || changes.searchRequestResultFacets) { - if (changes.searchRequestResultFacets && changes.searchRequestResultFacets.currentValue.length == 0) { + if (changes.searchRequestResultFacets && changes.searchRequestResultFacets.currentValue.length === 0) { // Render EMPTY attachment units this.nestedDataSourceLeaves.data.forEach((node) => { node.toggled = undefined; @@ -340,7 +333,7 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { } onLabelClick(selectedUnit: FilingHoldingSchemeNode) { - if (selectedUnit.id == selectedUnit.vitamId) { + if (selectedUnit.id === selectedUnit.vitamId) { this.showNodeDetail.emit(new Pair(selectedUnit.vitamId, true)); } else { this.showNodeDetail.emit(new Pair(selectedUnit.vitamId, false)); @@ -351,19 +344,7 @@ export class LeavesTreeComponent implements OnInit, OnChanges, OnDestroy { this.showEveryNodes = !this.showEveryNodes; } - getNodeUnitType(filingholdingscheme: FilingHoldingSchemeNode) { - if (filingholdingscheme && filingholdingscheme.unitType) { - return filingholdingscheme.unitType; - } - } - - getNodeUnitIcone(filingholdingscheme: FilingHoldingSchemeNode) { - return this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.HOLDING_UNIT - ? VitamuiIcons.VITAMUI_HOLDING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.FILING_UNIT - ? VitamuiIcons.VITAMUI_FILING_UNIT_ICON_ - : this.getNodeUnitType(filingholdingscheme) === VitamuiUnitTypes.INGEST && !filingholdingscheme?.hasObject - ? VitamuiIcons.VITAMUI_INGEST_WITHOUT_OBJECT_ICON_ - : VitamuiIcons.VITAMUI_INGEST_WITH_OBJECT_ICON_; + getNodeUnitIcon(filingholdingscheme: FilingHoldingSchemeNode) { + return nodeToVitamuiIcon(filingholdingscheme); } } diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.ts index c53314f5159..51b7db0a75b 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/components/simple-criteria-search/simple-criteria-search.component.ts @@ -302,8 +302,8 @@ export class SimpleCriteriaSearchComponent implements OnInit { this.criteriaSearchListToSave.forEach((criteriaSearch) => { if (criteriaSearch.criteria === ALL_ARCHIVE_UNIT_TYPES) { - criteriaSearch.values.forEach((unitType) => { - this.archiveUnitTypesCriteria.set(unitType.id, true); + criteriaSearch.values.forEach((criteriaValue) => { + this.archiveUnitTypesCriteria.set(criteriaValue.id, true); }); } criteriaSearch.values.forEach((value) => { diff --git a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/models/utils.ts b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/models/utils.ts index 3b31325bbb1..58c36fc722a 100644 --- a/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/models/utils.ts +++ b/ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-criteria/models/utils.ts @@ -36,8 +36,8 @@ */ /** - * This class is used as a tuple of 2 values to represent a Pair structure. - * Both key and value have the native object type in order to apply polymorphism + * This class is used as a tuple of 2 values to represent a Pair structure. + * Both key and value have the native object type in order to apply polymorphism * on the wanted types! */ export class Pair { @@ -55,7 +55,7 @@ export class Pair { * and optimize code ! */ export enum VitamInternalFields { - + // TODO : to remove, it interfers with IDE fields resolution // UNITS ID = '#id', MANAGEMENT = '#management', @@ -64,4 +64,3 @@ export enum VitamInternalFields { OPI = '#opi', UNIT_TYPE = '#unitType' } - diff --git a/ui/ui-frontend/projects/vitamui-library/src/lib/components/filing-plan/filing-plan.service.ts b/ui/ui-frontend/projects/vitamui-library/src/lib/components/filing-plan/filing-plan.service.ts index 726f18c9ec8..6150c118277 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/lib/components/filing-plan/filing-plan.service.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/lib/components/filing-plan/filing-plan.service.ts @@ -32,10 +32,9 @@ import { Inject, Injectable, LOCALE_ID } from '@angular/core'; import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { catchError, map, shareReplay, tap } from 'rxjs/operators'; -import { DescriptionLevel, FileType } from 'ui-frontend-common'; +import { DescriptionLevel, FileType, Unit } from 'ui-frontend-common'; import { SearchUnitApiService } from '../../api/search-unit-api.service'; import { Node } from '../../models/node.interface'; -import { Unit } from '../../models/unit.interface'; import { getKeywordValue } from '../../utils/keyword.util'; export enum ExpandLevel { diff --git a/ui/ui-frontend/projects/vitamui-library/src/lib/models/unit.interface.ts b/ui/ui-frontend/projects/vitamui-library/src/lib/models/unit.interface.ts index b84d67d2c21..b7085bf8bc5 100644 --- a/ui/ui-frontend/projects/vitamui-library/src/lib/models/unit.interface.ts +++ b/ui/ui-frontend/projects/vitamui-library/src/lib/models/unit.interface.ts @@ -1,3 +1,4 @@ +/** @deprecated: use ui-frontend-common */ export interface Unit { '#id': string; '#unitups': string[];