From 2340164394915bad302194bb0eff1e0305d1fc49 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Fri, 27 May 2022 17:21:21 +0200 Subject: [PATCH 001/449] 91874: Themed DsDynamicLookupRelationSearchTabComponent and MetadataRepresentationListComponent --- .../item-pages/project/project.component.html | 4 +- .../publication/publication.component.html | 4 +- .../untyped-item/untyped-item.component.html | 4 +- ...-metadata-representation-list.component.ts | 35 +++++++++ ...ic-lookup-relation-search-tab.component.ts | 71 +++++++++++++++++++ src/app/shared/form/form.module.ts | 2 + src/app/shared/shared.module.ts | 2 + ...etadata-representation-list.component.html | 0 .../metadata-representation-list.component.ts | 11 +++ ...-lookup-relation-search-tab.component.html | 0 ...-lookup-relation-search-tab.component.scss | 0 ...ic-lookup-relation-search-tab.component.ts | 21 ++++++ src/themes/custom/theme.module.ts | 6 +- 13 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 src/app/item-page/simple/metadata-representation-list/themed-metadata-representation-list.component.ts create mode 100644 src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component.ts create mode 100644 src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html create mode 100644 src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.html create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.scss create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.html b/src/app/entity-groups/research-entities/item-pages/project/project.component.html index 8f2ff6adcd..515a278a85 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.html +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.html @@ -20,12 +20,12 @@ - - + diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index bace9fcd0a..4cf0c1f185 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -27,12 +27,12 @@ - - + diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 04794717f1..160f716309 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -30,12 +30,12 @@ - - + diff --git a/src/app/item-page/simple/metadata-representation-list/themed-metadata-representation-list.component.ts b/src/app/item-page/simple/metadata-representation-list/themed-metadata-representation-list.component.ts new file mode 100644 index 0000000000..e7a526bb05 --- /dev/null +++ b/src/app/item-page/simple/metadata-representation-list/themed-metadata-representation-list.component.ts @@ -0,0 +1,35 @@ +import { ThemedComponent } from '../../../shared/theme-support/themed.component'; +import { MetadataRepresentationListComponent } from './metadata-representation-list.component'; +import { Component, Input } from '@angular/core'; +import { Item } from '../../../core/shared/item.model'; + +@Component({ + selector: 'ds-themed-metadata-representation-list', + styleUrls: [], + templateUrl: '../../../shared/theme-support/themed.component.html', +}) +export class ThemedMetadataRepresentationListComponent extends ThemedComponent { + protected inAndOutputNames: (keyof MetadataRepresentationListComponent & keyof this)[] = ['parentItem', 'itemType', 'metadataFields', 'label', 'incrementBy']; + + @Input() parentItem: Item; + + @Input() itemType: string; + + @Input() metadataFields: string[]; + + @Input() label: string; + + @Input() incrementBy = 10; + + protected getComponentName(): string { + return 'MetadataRepresentationListComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../../themes/${themeName}/app/item-page/simple/metadata-representation-list/metadata-representation-list.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./metadata-representation-list.component`); + } +} diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component.ts new file mode 100644 index 0000000000..da998ed5a6 --- /dev/null +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component.ts @@ -0,0 +1,71 @@ +import { ThemedComponent } from '../../../../../theme-support/themed.component'; +import { DsDynamicLookupRelationSearchTabComponent } from './dynamic-lookup-relation-search-tab.component'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { RelationshipOptions } from '../../../models/relationship-options.model'; +import { Observable } from 'rxjs'; +import { ListableObject } from '../../../../../object-collection/shared/listable-object.model'; +import { Context } from '../../../../../../core/shared/context.model'; +import { RelationshipType } from '../../../../../../core/shared/item-relationships/relationship-type.model'; +import { Item } from '../../../../../../core/shared/item.model'; +import { SearchResult } from '../../../../../search/models/search-result.model'; +import { SearchObjects } from '../../../../../search/models/search-objects.model'; +import { DSpaceObject } from '../../../../../../core/shared/dspace-object.model'; +import { SEARCH_CONFIG_SERVICE } from '../../../../../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../../../core/shared/search/search-configuration.service'; + +@Component({ + selector: 'ds-themed-dynamic-lookup-relation-search-tab', + styleUrls: [], + templateUrl: '../../../../../theme-support/themed.component.html', + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] +}) +export class ThemedDynamicLookupRelationSearchTabComponent extends ThemedComponent { + protected inAndOutputNames: (keyof DsDynamicLookupRelationSearchTabComponent & keyof this)[] = ['relationship', 'listId', + 'query', 'repeatable', 'selection$', 'context', 'relationshipType', 'item', 'isLeft', 'toRemove', 'isEditRelationship', + 'deselectObject', 'selectObject', 'resultFound']; + + @Input() relationship: RelationshipOptions; + + @Input() listId: string; + + @Input() query: string; + + @Input() repeatable: boolean; + + @Input() selection$: Observable; + + @Input() context: Context; + + @Input() relationshipType: RelationshipType; + + @Input() item: Item; + + @Input() isLeft: boolean; + + @Input() toRemove: SearchResult[]; + + @Input() isEditRelationship: boolean; + + @Output() deselectObject: EventEmitter = new EventEmitter(); + + @Output() selectObject: EventEmitter = new EventEmitter(); + + @Output() resultFound: EventEmitter> = new EventEmitter>(); + + protected getComponentName(): string { + return 'DsDynamicLookupRelationSearchTabComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../../../../../themes/${themeName}/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./dynamic-lookup-relation-search-tab.component`); + } +} diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index 62ab5bd647..ae85022719 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -30,6 +30,7 @@ import { ExistingRelationListElementComponent } from './builder/ds-dynamic-form- import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; import { CustomSwitchComponent } from './builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.component'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; +import { ThemedDynamicLookupRelationSearchTabComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component'; const COMPONENTS = [ CustomSwitchComponent, @@ -38,6 +39,7 @@ const COMPONENTS = [ DsDynamicListComponent, DsDynamicLookupComponent, DsDynamicLookupRelationSearchTabComponent, + ThemedDynamicLookupRelationSearchTabComponent, DsDynamicLookupRelationSelectionTabComponent, DsDynamicLookupRelationExternalSourceTabComponent, DsDynamicDisabledComponent, diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 715ee66a99..b6e153db91 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -177,6 +177,7 @@ import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; +import { ThemedMetadataRepresentationListComponent } from '../item-page/simple/metadata-representation-list/themed-metadata-representation-list.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -412,6 +413,7 @@ const SHARED_ITEM_PAGE_COMPONENTS = [ ItemAlertsComponent, GenericItemPageFieldComponent, MetadataRepresentationListComponent, + ThemedMetadataRepresentationListComponent, RelatedItemsComponent, ]; diff --git a/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html b/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts b/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts new file mode 100644 index 0000000000..8a6036a23b --- /dev/null +++ b/src/themes/custom/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts @@ -0,0 +1,11 @@ +import { MetadataRepresentationListComponent as BaseComponent } from '../../../../../../app/item-page/simple/metadata-representation-list/metadata-representation-list.component'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-metadata-representation-list', + // templateUrl: './metadata-representation-list.component.html' + templateUrl: '../../../../../../app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html' +}) +export class MetadataRepresentationListComponent extends BaseComponent { + +} diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.html b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.scss b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts new file mode 100644 index 0000000000..2380cc67e8 --- /dev/null +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.ts @@ -0,0 +1,21 @@ +import { DsDynamicLookupRelationSearchTabComponent as BaseComponent } from '../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component'; +import { Component } from '@angular/core'; +import { SEARCH_CONFIG_SERVICE } from '../../../../../../../../../app/my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../../../../../../app/core/shared/search/search-configuration.service'; + +@Component({ + selector: 'ds-dynamic-lookup-relation-search-tab', + // styleUrls: ['./dynamic-lookup-relation-search-tab.component.scss'], + styleUrls: ['../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.scss'], + // templateUrl: './dynamic-lookup-relation-search-tab.component.html', + templateUrl: '../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component.html', + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ] +}) +export class DsDynamicLookupRelationSearchTabComponent extends BaseComponent { + +} diff --git a/src/themes/custom/theme.module.ts b/src/themes/custom/theme.module.ts index e2e97b9087..94250b416f 100644 --- a/src/themes/custom/theme.module.ts +++ b/src/themes/custom/theme.module.ts @@ -84,6 +84,8 @@ import { SearchModule } from '../../app/shared/search/search.module'; import { ResourcePoliciesModule } from '../../app/shared/resource-policies/resource-policies.module'; import { ComcolModule } from '../../app/shared/comcol/comcol.module'; import { FeedbackComponent } from './app/info/feedback/feedback.component'; +import { MetadataRepresentationListComponent } from './app/item-page/simple/metadata-representation-list/metadata-representation-list.component'; +import { DsDynamicLookupRelationSearchTabComponent } from './app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component'; const DECLARATIONS = [ FileSectionComponent, @@ -126,7 +128,9 @@ const DECLARATIONS = [ NavbarComponent, HeaderNavbarWrapperComponent, BreadcrumbsComponent, - FeedbackComponent + FeedbackComponent, + MetadataRepresentationListComponent, + DsDynamicLookupRelationSearchTabComponent, ]; @NgModule({ From 7eaa50949df4273fa1b9fa55429a62f80b823fd4 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Mon, 30 May 2022 14:53:43 +0200 Subject: [PATCH 002/449] 90761: Themed DsDynamicLookupRelationExternalSourceTabComponent --- ...-relation-external-source-tab.component.ts | 62 +++++++++++++++++++ src/app/shared/form/form.module.ts | 2 + ...elation-external-source-tab.component.html | 0 ...elation-external-source-tab.component.scss | 0 ...-relation-external-source-tab.component.ts | 26 ++++++++ src/themes/custom/theme.module.ts | 2 + 6 files changed, 92 insertions(+) create mode 100644 src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/themed-dynamic-lookup-relation-external-source-tab.component.ts create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.html create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.scss create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/themed-dynamic-lookup-relation-external-source-tab.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/themed-dynamic-lookup-relation-external-source-tab.component.ts new file mode 100644 index 0000000000..f3d8421365 --- /dev/null +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/themed-dynamic-lookup-relation-external-source-tab.component.ts @@ -0,0 +1,62 @@ +import { ThemedComponent } from '../../../../../theme-support/themed.component'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { RelationshipOptions } from '../../../models/relationship-options.model'; +import { ListableObject } from '../../../../../object-collection/shared/listable-object.model'; +import { Context } from '../../../../../../core/shared/context.model'; +import { Item } from '../../../../../../core/shared/item.model'; +import { SEARCH_CONFIG_SERVICE } from '../../../../../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../../../core/shared/search/search-configuration.service'; +import { Collection } from '../../../../../../core/shared/collection.model'; +import { ExternalSource } from '../../../../../../core/shared/external-source.model'; +import { DsDynamicLookupRelationExternalSourceTabComponent } from './dynamic-lookup-relation-external-source-tab.component'; +import { fadeIn, fadeInOut } from '../../../../../animations/fade'; + +@Component({ + selector: 'ds-themed-dynamic-lookup-relation-external-source-tab', + styleUrls: [], + templateUrl: '../../../../../theme-support/themed.component.html', + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ], + animations: [ + fadeIn, + fadeInOut + ] +}) +export class ThemedDynamicLookupRelationExternalSourceTabComponent extends ThemedComponent { + protected inAndOutputNames: (keyof DsDynamicLookupRelationExternalSourceTabComponent & keyof this)[] = ['label', 'listId', + 'item', 'collection', 'relationship', 'context', 'repeatable', 'importedObject', 'externalSource']; + + @Input() label: string; + + @Input() listId: string; + + @Input() item: Item; + + @Input() collection: Collection; + + @Input() relationship: RelationshipOptions; + + @Input() context: Context; + + @Input() repeatable: boolean; + + @Output() importedObject: EventEmitter = new EventEmitter(); + + @Input() externalSource: ExternalSource; + + protected getComponentName(): string { + return 'DsDynamicLookupRelationExternalSourceTabComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../../../../../themes/${themeName}/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./dynamic-lookup-relation-external-source-tab.component`); + } +} diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index ae85022719..4e9eee7e3a 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -31,6 +31,7 @@ import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-fo import { CustomSwitchComponent } from './builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.component'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; import { ThemedDynamicLookupRelationSearchTabComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/themed-dynamic-lookup-relation-search-tab.component'; +import { ThemedDynamicLookupRelationExternalSourceTabComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/themed-dynamic-lookup-relation-external-source-tab.component'; const COMPONENTS = [ CustomSwitchComponent, @@ -42,6 +43,7 @@ const COMPONENTS = [ ThemedDynamicLookupRelationSearchTabComponent, DsDynamicLookupRelationSelectionTabComponent, DsDynamicLookupRelationExternalSourceTabComponent, + ThemedDynamicLookupRelationExternalSourceTabComponent, DsDynamicDisabledComponent, DsDynamicLookupRelationModalComponent, DsDynamicScrollableDropdownComponent, diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.html b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.scss b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts new file mode 100644 index 0000000000..569d007b4d --- /dev/null +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts @@ -0,0 +1,26 @@ +import { DsDynamicLookupRelationExternalSourceTabComponent as BaseComponent } from '../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component'; +import { Component } from '@angular/core'; +import { SEARCH_CONFIG_SERVICE } from '../../../../../../../../../app/my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationService } from '../../../../../../../../../app/core/shared/search/search-configuration.service'; +import { fadeIn, fadeInOut } from '../../../../../../../../../app/shared/animations/fade'; + +@Component({ + selector: 'ds-dynamic-lookup-relation-external-source-tab', + // styleUrls: ['./dynamic-lookup-relation-external-source-tab.component.scss'], + styleUrls: ['../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.scss'], + // templateUrl: './dynamic-lookup-relation-external-source-tab.component.html', + templateUrl: '../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.html', + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationService + } + ], + animations: [ + fadeIn, + fadeInOut + ] +}) +export class DsDynamicLookupRelationExternalSourceTabComponent extends BaseComponent { + +} diff --git a/src/themes/custom/theme.module.ts b/src/themes/custom/theme.module.ts index 94250b416f..f37b0f820c 100644 --- a/src/themes/custom/theme.module.ts +++ b/src/themes/custom/theme.module.ts @@ -86,6 +86,7 @@ import { ComcolModule } from '../../app/shared/comcol/comcol.module'; import { FeedbackComponent } from './app/info/feedback/feedback.component'; import { MetadataRepresentationListComponent } from './app/item-page/simple/metadata-representation-list/metadata-representation-list.component'; import { DsDynamicLookupRelationSearchTabComponent } from './app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/search-tab/dynamic-lookup-relation-search-tab.component'; +import { DsDynamicLookupRelationExternalSourceTabComponent } from './app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component'; const DECLARATIONS = [ FileSectionComponent, @@ -131,6 +132,7 @@ const DECLARATIONS = [ FeedbackComponent, MetadataRepresentationListComponent, DsDynamicLookupRelationSearchTabComponent, + DsDynamicLookupRelationExternalSourceTabComponent, ]; @NgModule({ From 86e084bf0520eaa9fb3705d76c55012884aa97d8 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Mon, 30 May 2022 16:27:28 +0200 Subject: [PATCH 003/449] 90761: themed component calls --- .../dynamic-lookup-relation-modal.component.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html index f95cd98c65..9a7aeee4d2 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html @@ -12,7 +12,7 @@
  • {{'submission.sections.describe.relationship-lookup.search-tab.tab-title.' + relationshipOptions.relationshipType | translate : { count: (totalInternal$ | async)} }} - - +
  • {{'submission.sections.describe.relationship-lookup.search-tab.tab-title.' + source.id | translate : { count: (totalExternal$ | async)[idx] } }} - - +
  • From 878db5be752595277e68bd71ceb221a416801e63 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 20 Sep 2022 15:45:04 +0200 Subject: [PATCH 004/449] 94390: Replace DSO page edit buttons with a menu --- .../admin-sidebar-section.component.html | 4 +- .../admin-sidebar-section.component.spec.ts | 106 +++++++--- .../admin-sidebar-section.component.ts | 13 +- ...dable-admin-sidebar-section.component.html | 1 + .../collection-page-routing.module.ts | 7 +- .../collection-page.component.html | 4 +- .../community-page-routing.module.ts | 7 +- .../community-page.component.html | 4 +- .../journal-issue.component.html | 5 +- .../journal-volume.component.html | 4 +- .../item-pages/journal/journal.component.html | 5 +- .../org-unit/org-unit.component.html | 5 +- .../item-pages/person/person.component.html | 5 +- .../item-pages/project/project.component.html | 5 +- .../full/full-item-page.component.html | 5 +- src/app/item-page/item-page-routing.module.ts | 5 +- src/app/item-page/item-page.module.ts | 2 - .../publication/publication.component.html | 4 +- .../untyped-item/untyped-item.component.html | 8 +- .../untyped-item/untyped-item.component.ts | 4 +- .../versioned-item.component.scss | 0 .../versioned-item.component.spec.ts | 95 --------- .../versioned-item.component.ts | 80 -------- .../expandable-navbar-section.component.html | 1 + .../dso-page/dso-edit-menu.resolver.spec.ts | 190 ++++++++++++++++++ .../shared/dso-page/dso-edit-menu.resolver.ts | 164 +++++++++++++++ ...dit-menu-expandable-section.component.html | 18 ++ ...dit-menu-expandable-section.component.scss | 26 +++ ...-menu-expandable-section.component.spec.ts | 75 +++++++ ...-edit-menu-expandable-section.component.ts | 39 ++++ .../dso-edit-menu-section.component.html | 25 +++ .../dso-edit-menu-section.component.scss | 3 + .../dso-edit-menu-section.component.spec.ts | 173 ++++++++++++++++ .../dso-edit-menu-section.component.ts | 51 +++++ .../dso-edit-menu.component.html | 6 + .../dso-edit-menu.component.scss} | 0 .../dso-edit-menu.component.spec.ts | 78 +++++++ .../dso-edit-menu/dso-edit-menu.component.ts | 36 ++++ .../dso-page-edit-button.component.html | 7 - .../dso-page-edit-button.component.scss | 3 - .../dso-page-edit-button.component.spec.ts | 76 ------- .../dso-page-edit-button.component.ts | 43 ---- .../dso-page-version-button.component.html | 8 - .../dso-page-version-button.component.scss | 3 - .../dso-page-version-button.component.spec.ts | 96 --------- .../dso-page-version-button.component.ts | 77 ------- .../dso-versioning-modal.service.spec.ts | 92 +++++++++ .../dso-versioning-modal.service.ts | 98 +++++++++ src/app/shared/menu/initial-menus-state.ts | 14 +- .../menu-item/link-menu-item.component.html | 4 +- .../menu-item/link-menu-item.component.ts | 2 +- .../menu/menu-item/models/altmetric.model.ts | 1 + .../menu/menu-item/models/link.model.ts | 1 + .../menu/menu-item/models/menu-item.model.ts | 1 + .../menu/menu-item/models/onclick.model.ts | 1 + .../menu/menu-item/models/search.model.ts | 1 + .../menu/menu-item/models/text.model.ts | 1 + .../onclick-menu-item.component.html | 4 +- .../menu-item/onclick-menu-item.component.ts | 9 +- .../menu-item/text-menu-item.component.html | 2 +- .../menu-section/menu-section.component.ts | 8 +- src/app/shared/shared.module.ts | 17 +- 62 files changed, 1247 insertions(+), 585 deletions(-) delete mode 100644 src/app/item-page/simple/item-types/versioned-item/versioned-item.component.scss delete mode 100644 src/app/item-page/simple/item-types/versioned-item/versioned-item.component.spec.ts delete mode 100644 src/app/item-page/simple/item-types/versioned-item/versioned-item.component.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu.resolver.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.spec.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.scss create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.html rename src/app/{item-page/simple/item-types/versioned-item/versioned-item.component.html => shared/dso-page/dso-edit-menu/dso-edit-menu.component.scss} (100%) create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts create mode 100644 src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts delete mode 100644 src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.html delete mode 100644 src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.scss delete mode 100644 src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.spec.ts delete mode 100644 src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.ts delete mode 100644 src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.html delete mode 100644 src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.scss delete mode 100644 src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.spec.ts delete mode 100644 src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.ts create mode 100644 src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts create mode 100644 src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.ts diff --git a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.html b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.html index 8706b40ee0..7f1e8716ba 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.html +++ b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.html @@ -1,7 +1,7 @@
    diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts index ad1b1fd2f2..ac90f3618c 100644 --- a/src/app/community-page/community-page-routing.module.ts +++ b/src/app/community-page/community-page-routing.module.ts @@ -14,6 +14,7 @@ import { CommunityPageAdministratorGuard } from './community-page-administrator. import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedCommunityPageComponent } from './themed-community-page.component'; +import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; @NgModule({ imports: [ @@ -27,7 +28,8 @@ import { ThemedCommunityPageComponent } from './themed-community-page.component' path: ':id', resolve: { dso: CommunityPageResolver, - breadcrumb: CommunityBreadcrumbResolver + breadcrumb: CommunityBreadcrumbResolver, + menu: DSOEditMenuResolver }, runGuardsAndResolvers: 'always', children: [ @@ -72,7 +74,8 @@ import { ThemedCommunityPageComponent } from './themed-community-page.component' DSOBreadcrumbsService, LinkService, CreateCommunityPageGuard, - CommunityPageAdministratorGuard + CommunityPageAdministratorGuard, + DSOEditMenuResolver ] }) export class CommunityPageRoutingModule { diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index cf7282eb4b..cee13eadd6 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -20,9 +20,7 @@ [title]="'community.page.news'"> -
    - -
    +
    diff --git a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html index 5847be7dd2..94dc81fc8f 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal-issue/journal-issue.component.html @@ -2,9 +2,8 @@

    {{'journalissue.page.titleprefix' | translate}}

    -
    - -
    + +
    diff --git a/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html b/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html index a0a25766ef..b472f4e648 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal-volume/journal-volume.component.html @@ -2,9 +2,7 @@

    {{'journalvolume.page.titleprefix' | translate}}

    -
    - -
    +
    diff --git a/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html b/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html index af3ac85959..9b11409a31 100644 --- a/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html +++ b/src/app/entity-groups/journal-entities/item-pages/journal/journal.component.html @@ -2,9 +2,8 @@

    {{'journal.page.titleprefix' | translate}}

    -
    - -
    + +
    diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html index c9ea8fb549..21b36de722 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html @@ -2,9 +2,8 @@

    {{'orgunit.page.titleprefix' | translate}}

    -
    - -
    + +
    diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 5c2fd227fd..c23b543011 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -2,9 +2,8 @@

    {{'person.page.titleprefix' | translate}}

    -
    - -
    + +
    diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.html b/src/app/entity-groups/research-entities/item-pages/project/project.component.html index 8f2ff6adcd..b9a1a30225 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.html +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.html @@ -2,9 +2,8 @@

    {{'project.page.titleprefix' | translate}}

    -
    - -
    + +
    diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index d2655c4ad0..8bb7860aaa 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -6,9 +6,8 @@
    -
    - -
    + +
    diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 04794717f1..c9c88fa085 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -11,12 +11,8 @@

    -
    - - -
    + +
    diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts index 3ce33dc90a..ead62008de 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { Item } from '../../../../core/shared/item.model'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; -import { VersionedItemComponent } from '../versioned-item/versioned-item.component'; +import { ItemComponent } from '../shared/item.component'; /** * Component that represents a publication Item page @@ -15,6 +15,6 @@ import { VersionedItemComponent } from '../versioned-item/versioned-item.compone templateUrl: './untyped-item.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class UntypedItemComponent extends VersionedItemComponent { +export class UntypedItemComponent extends ItemComponent { } diff --git a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.scss b/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.spec.ts b/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.spec.ts deleted file mode 100644 index eff51b1019..0000000000 --- a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.spec.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { VersionedItemComponent } from './versioned-item.component'; -import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service'; -import { TranslateService } from '@ngx-translate/core'; -import { VersionDataService } from '../../../../core/data/version-data.service'; -import { NotificationsService } from '../../../../shared/notifications/notifications.service'; -import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service'; -import { Item } from '../../../../core/shared/item.model'; -import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils'; -import { buildPaginatedList } from '../../../../core/data/paginated-list.model'; -import { PageInfo } from '../../../../core/shared/page-info.model'; -import { MetadataMap } from '../../../../core/shared/metadata.models'; -import { createRelationshipsObservable, mockRouteService } from '../shared/item.component.spec'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Component } from '@angular/core'; -import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service'; -import { SearchService } from '../../../../core/shared/search/search.service'; -import { ItemDataService } from '../../../../core/data/item-data.service'; -import { Version } from '../../../../core/shared/version.model'; -import { RouteService } from '../../../../core/services/route.service'; - -const mockItem: Item = Object.assign(new Item(), { - bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])), - metadata: new MetadataMap(), - relationships: createRelationshipsObservable(), - _links: { - self: { - href: 'item-href' - }, - version: { - href: 'version-href' - } - } -}); - - -@Component({template: ''}) -class DummyComponent { -} - -describe('VersionedItemComponent', () => { - let component: VersionedItemComponent; - let fixture: ComponentFixture; - - let versionService: VersionDataService; - let versionHistoryService: VersionHistoryDataService; - - const versionServiceSpy = jasmine.createSpyObj('versionService', { - findByHref: createSuccessfulRemoteDataObject$(new Version()), - }); - - const versionHistoryServiceSpy = jasmine.createSpyObj('versionHistoryService', { - createVersion: createSuccessfulRemoteDataObject$(new Version()), - }); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [VersionedItemComponent, DummyComponent], - imports: [RouterTestingModule], - providers: [ - { provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy }, - { provide: TranslateService, useValue: {} }, - { provide: VersionDataService, useValue: versionServiceSpy }, - { provide: NotificationsService, useValue: {} }, - { provide: ItemVersionsSharedService, useValue: {} }, - { provide: WorkspaceitemDataService, useValue: {} }, - { provide: SearchService, useValue: {} }, - { provide: ItemDataService, useValue: {} }, - { provide: RouteService, useValue: mockRouteService } - ] - }).compileComponents(); - versionService = TestBed.inject(VersionDataService); - versionHistoryService = TestBed.inject(VersionHistoryDataService); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(VersionedItemComponent); - component = fixture.componentInstance; - component.object = mockItem; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('when onCreateNewVersion() is called', () => { - it('should call versionService.findByHref', () => { - component.onCreateNewVersion(); - expect(versionService.findByHref).toHaveBeenCalledWith('version-href'); - }); - }); - -}); diff --git a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.ts b/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.ts deleted file mode 100644 index cd2eb3a19b..0000000000 --- a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Component } from '@angular/core'; -import { ItemComponent } from '../shared/item.component'; -import { ItemVersionsSummaryModalComponent } from '../../../../shared/item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component'; -import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; -import { RemoteData } from '../../../../core/data/remote-data'; -import { Version } from '../../../../core/shared/version.model'; -import { switchMap, tap } from 'rxjs/operators'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service'; -import { TranslateService } from '@ngx-translate/core'; -import { VersionDataService } from '../../../../core/data/version-data.service'; -import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service'; -import { Router } from '@angular/router'; -import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service'; -import { SearchService } from '../../../../core/shared/search/search.service'; -import { Item } from '../../../../core/shared/item.model'; -import { ItemDataService } from '../../../../core/data/item-data.service'; -import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; -import { RouteService } from '../../../../core/services/route.service'; - -@Component({ - selector: 'ds-versioned-item', - templateUrl: './versioned-item.component.html', - styleUrls: ['./versioned-item.component.scss'] -}) -export class VersionedItemComponent extends ItemComponent { - - constructor( - private modalService: NgbModal, - private versionHistoryService: VersionHistoryDataService, - private translateService: TranslateService, - private versionService: VersionDataService, - private itemVersionShared: ItemVersionsSharedService, - private router: Router, - private workspaceItemDataService: WorkspaceitemDataService, - private searchService: SearchService, - private itemService: ItemDataService, - protected routeService: RouteService - ) { - super(routeService); - } - - /** - * Open a modal that allows to create a new version starting from the specified item, with optional summary - */ - onCreateNewVersion(): void { - - const item = this.object; - const versionHref = item._links.version.href; - - // Open modal - const activeModal = this.modalService.open(ItemVersionsSummaryModalComponent); - - // Show current version in modal - this.versionService.findByHref(versionHref).pipe(getFirstCompletedRemoteData()).subscribe((res: RemoteData) => { - // if res.hasNoContent then the item is unversioned - activeModal.componentInstance.firstVersion = res.hasNoContent; - activeModal.componentInstance.versionNumber = (res.hasNoContent ? undefined : res.payload.version); - }); - - // On createVersionEvent emitted create new version and notify - activeModal.componentInstance.createVersionEvent.pipe( - switchMap((summary: string) => this.versionHistoryService.createVersion(item._links.self.href, summary)), - getFirstCompletedRemoteData(), - // show success/failure notification - tap((res: RemoteData) => { this.itemVersionShared.notifyCreateNewVersion(res); }), - // get workspace item - getFirstSucceededRemoteDataPayload(), - switchMap((newVersion: Version) => this.itemService.findByHref(newVersion._links.item.href)), - getFirstSucceededRemoteDataPayload(), - switchMap((newVersionItem: Item) => this.workspaceItemDataService.findByItem(newVersionItem.uuid, true, false)), - getFirstSucceededRemoteDataPayload(), - ).subscribe((wsItem) => { - const wsiId = wsItem.id; - const route = 'workspaceitems/' + wsiId + '/edit'; - this.router.navigateByUrl(route); - }); - - } -} diff --git a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html index d8a517dc55..a77b6bc253 100644 --- a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html +++ b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html @@ -6,6 +6,7 @@ (mouseenter)="activateSection($event)" (mouseleave)="deactivateSection($event)"> { + + const MENU_STATE = { + id: 'some menu' + }; + + let resolver: DSOEditMenuResolver; + + let dSpaceObjectDataService; + let menuService; + let authorizationService; + let dsoVersioningModalService; + + const route = { + data: { + menu: { + 'statistics': [{ + id: 'statistics-dummy-1', + active: false, + visible: true, + model: null + }] + } + }, + params: {id: 'test-uuid'}, + }; + + const state = { + url: 'test-url' + }; + + const testObject = Object.assign(new Item(), {uuid: 'test-uuid', type: 'item', _links: {self: {href: 'self-link'}}}); + + const dummySections1 = [{ + id: 'dummy-1', + active: false, + visible: true, + model: null + }, + { + id: 'dummy-2', + active: false, + visible: true, + model: null + }]; + + const dummySections2 = [{ + id: 'dummy-3', + active: false, + visible: true, + model: null + }, + { + id: 'dummy-4', + active: false, + visible: true, + model: null + }, + { + id: 'dummy-5', + active: false, + visible: true, + model: null + }]; + + beforeEach(waitForAsync(() => { + menuService = new MenuServiceStub(); + spyOn(menuService, 'getMenu').and.returnValue(observableOf(MENU_STATE)); + + dSpaceObjectDataService = jasmine.createSpyObj('dSpaceObjectDataService', { + findById: createSuccessfulRemoteDataObject$(testObject) + }); + authorizationService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + dsoVersioningModalService = jasmine.createSpyObj('dsoVersioningModalService', { + isNewVersionButtonDisabled: observableOf(false), + getVersioningTooltipMessage: observableOf('message'), + openCreateVersionModal: {} + }); + + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule], + declarations: [AdminSidebarComponent], + providers: [ + {provide: DSpaceObjectDataService, useValue: dSpaceObjectDataService}, + {provide: MenuService, useValue: menuService}, + {provide: AuthorizationDataService, useValue: authorizationService}, + {provide: DsoVersioningModalService, useValue: dsoVersioningModalService}, + { + provide: NgbModal, useValue: { + open: () => {/*comment*/ + } + } + } + ], + schemas: [NO_ERRORS_SCHEMA] + }); + resolver = TestBed.inject(DSOEditMenuResolver); + + spyOn(menuService, 'addSection'); + })); + + it('should be created', () => { + expect(resolver).toBeTruthy(); + }); + + describe('resolve', () => { + it('should create all menus when a dso is found', (done) => { + spyOn(resolver, 'getDsoMenus').and.returnValue( + [observableOf(dummySections1), observableOf(dummySections2)] + ); + resolver.resolve(route as any, null).subscribe(resolved => { + expect(resolved).toEqual( + { + ...route.data.menu, + [MenuID.DSO_EDIT]: [ + ...dummySections1.map((menu) => Object.assign(menu, {id: menu.id + '-test-uuid'})), + ...dummySections2.map((menu) => Object.assign(menu, {id: menu.id + '-test-uuid'})) + ] + } + ); + expect(resolver.getDsoMenus).toHaveBeenCalled(); + done(); + }); + }); + it('should return the statistics menu when no dso is found', (done) => { + (dSpaceObjectDataService.findById as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$()); + + resolver.resolve(route as any, null).subscribe(resolved => { + expect(resolved).toEqual( + { + ...route.data.menu + } + ); + done(); + }); + }); + }); + describe('getDsoMenus', () => { + it('should return as first part the item version list ', (done) => { + const result = resolver.getDsoMenus(testObject, route, state); + result[0].subscribe((menuList) => { + expect(menuList.length).toEqual(1); + expect(menuList[0].id).toEqual('version-dso'); + expect(menuList[0].active).toEqual(false); + expect(menuList[0].visible).toEqual(true); + expect(menuList[0].model.type).toEqual(MenuItemType.ONCLICK); + expect(menuList[0].model.text).toEqual('message'); + expect(menuList[0].model.disabled).toEqual(false); + expect(menuList[0].icon).toEqual('code-branch'); + done(); + }); + + }); + it('should return as second part the common list ', (done) => { + const result = resolver.getDsoMenus(testObject, route, state); + result[1].subscribe((menuList) => { + expect(menuList.length).toEqual(1); + expect(menuList[0].id).toEqual('edit-dso'); + expect(menuList[0].active).toEqual(false); + expect(menuList[0].visible).toEqual(true); + expect(menuList[0].model.type).toEqual(MenuItemType.LINK); + expect(menuList[0].model.text).toEqual('item.page.edit'); + expect(menuList[0].model.link).toEqual('test-url/edit/metadata'); + expect(menuList[0].icon).toEqual('pencil-alt'); + done(); + }); + + }); + }); +}); diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.ts new file mode 100644 index 0000000000..003e61df95 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.ts @@ -0,0 +1,164 @@ +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; +import { combineLatest, Observable, of as observableOf } from 'rxjs'; +import { FeatureID } from '../../core/data/feature-authorization/feature-id'; +import { MenuID, MenuItemType } from '../menu/initial-menus-state'; +import { MenuService } from '../menu/menu.service'; +import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { Injectable } from '@angular/core'; +import { LinkMenuItemModel } from '../menu/menu-item/models/link.model'; +import { Item } from '../../core/shared/item.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { OnClickMenuItemModel } from '../menu/menu-item/models/onclick.model'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { map, switchMap } from 'rxjs/operators'; +import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; +import { URLCombiner } from '../../core/url-combiner/url-combiner'; +import { DsoVersioningModalService } from './dso-versioning-modal-service/dso-versioning-modal.service'; +import { hasValue } from '../empty.util'; +import { MenuSection } from '../menu/menu.reducer'; + +/** + * Creates the menus for the dspace object pages + */ +@Injectable({ + providedIn: 'root' +}) +export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection[] }> { + + constructor( + protected dSpaceObjectDataService: DSpaceObjectDataService, + protected menuService: MenuService, + protected authorizationService: AuthorizationDataService, + protected modalService: NgbModal, + protected dsoVersioningModalService: DsoVersioningModalService, + ) { + } + + /** + * Initialise all dspace object related menus + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<{ [key: string]: MenuSection[] }> { + const uuid = route.params.id; + return this.dSpaceObjectDataService.findById(uuid, true, false).pipe( + getFirstCompletedRemoteData(), + switchMap((dsoRD) => { + if (dsoRD.hasSucceeded) { + const dso = dsoRD.payload; + return combineLatest(this.getDsoMenus(dso, route, state)).pipe( + map((combinedMenus) => [].concat.apply([], combinedMenus)), + map((menus) => this.addDsoUuidToMenuIDs(menus, dso)), + map((menus) => { + return { + ...route.data?.menu, + [MenuID.DSO_EDIT]: menus + }; + }) + ); + } else { + return observableOf({...route.data?.menu}); + } + }) + ); + } + + /** + * Return all the menus for a dso based on the route and state + */ + getDsoMenus(dso, route, state) { + return [ + this.getItemMenu(dso), + this.getCommonMenu(dso, state) + ]; + } + + /** + * Get the common menus between all dspace objects + */ + protected getCommonMenu(dso, state): Observable { + return combineLatest([ + this.authorizationService.isAuthorized(FeatureID.CanEditMetadata, dso.self), + ]).pipe( + map(([canEditItem]) => { + return [ + { + id: 'edit-dso', + active: false, + visible: canEditItem, + model: { + type: MenuItemType.LINK, + text: this.getDsoType(dso) + '.page.edit', + link: new URLCombiner(state.url, 'edit', 'metadata').toString() + } as LinkMenuItemModel, + icon: 'pencil-alt', + index: 1 + }, + ]; + + }) + ); + } + + /** + * Get item sepcific menus + */ + protected getItemMenu(dso): Observable { + if (dso instanceof Item) { + return combineLatest([ + this.authorizationService.isAuthorized(FeatureID.CanCreateVersion, dso.self), + this.dsoVersioningModalService.isNewVersionButtonDisabled(dso), + this.dsoVersioningModalService.getVersioningTooltipMessage(dso, 'item.page.version.hasDraft', 'item.page.version.create') + ]).pipe( + map(([canCreateVersion, disableVersioning, versionTooltip]) => { + return [ + { + id: 'version-dso', + active: false, + visible: canCreateVersion, + model: { + type: MenuItemType.ONCLICK, + text: versionTooltip, + disabled: disableVersioning, + function: () => { + this.dsoVersioningModalService.openCreateVersionModal(dso); + } + } as OnClickMenuItemModel, + icon: 'code-branch', + index: 0 + }, + ]; + }), + ); + } else { + return observableOf([]); + } + } + + /** + * Retrieve the dso or entity type for an object to be used in generic messages + */ + protected getDsoType(dso) { + const renderType = dso.getRenderTypes()[0]; + if (typeof renderType === 'string' || renderType instanceof String) { + return renderType.toLowerCase(); + } else { + return dso.type.toString().toLowerCase(); + } + } + + /** + * Add the dso uuid to all provided menu ids and parent ids + */ + protected addDsoUuidToMenuIDs(menus, dso) { + return menus.map((menu) => { + Object.assign(menu, { + id: menu.id + '-' + dso.uuid + }); + if (hasValue(menu.parentID)) { + Object.assign(menu, { + parentID: menu.parentID + '-' + dso.uuid + }); + } + return menu; + }); + } +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html new file mode 100644 index 0000000000..b330b1e87d --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html @@ -0,0 +1,18 @@ +
    +
    + +
      + + + +
    +
    +
    + + + + diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss new file mode 100644 index 0000000000..61ec6347f9 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss @@ -0,0 +1,26 @@ +.btn-dark { + background-color: var(--ds-admin-sidebar-bg); +} + +.dso-button-menu { + .dropdown-toggle::after { + display: none; + } +} + +ul.dropdown-menu { + background-color: var(--ds-admin-sidebar-bg); + color: white; + + ::ng-deep a { + color: white; + + &.disabled { + color: $btn-link-disabled-color; + } + } + + .disabled { + color: $btn-link-disabled-color; + } +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.spec.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.spec.ts new file mode 100644 index 0000000000..211fd0bdf0 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.spec.ts @@ -0,0 +1,75 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { MenuServiceStub } from '../../../testing/menu-service.stub'; +import { TranslateModule } from '@ngx-translate/core'; +import { MenuService } from '../../../menu/menu.service'; +import { CSSVariableService } from '../../../sass-helper/sass-helper.service'; +import { CSSVariableServiceStub } from '../../../testing/css-variable-service.stub'; +import { Router } from '@angular/router'; +import { RouterStub } from '../../../testing/router.stub'; +import { of as observableOf } from 'rxjs'; +import { Component } from '@angular/core'; +import { DsoEditMenuExpandableSectionComponent } from './dso-edit-menu-expandable-section.component'; +import { MenuItemType } from '../../../menu/initial-menus-state'; +import { By } from '@angular/platform-browser'; + +describe('DsoEditMenuExpandableSectionComponent', () => { + let component: DsoEditMenuExpandableSectionComponent; + let fixture: ComponentFixture; + const menuService = new MenuServiceStub(); + const iconString = 'test'; + + const dummySection = { + id: 'dummy', + active: false, + visible: true, + model: { + type: MenuItemType.TEXT, + disabled: false, + text: 'text' + }, + icon: iconString + }; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [DsoEditMenuExpandableSectionComponent, TestComponent], + providers: [ + {provide: 'sectionDataProvider', useValue: dummySection}, + {provide: MenuService, useValue: menuService}, + {provide: CSSVariableService, useClass: CSSVariableServiceStub}, + {provide: Router, useValue: new RouterStub()}, + ] + }).overrideComponent(DsoEditMenuExpandableSectionComponent, { + set: { + entryComponents: [TestComponent] + } + }) + .compileComponents(); + })); + + beforeEach(() => { + spyOn(menuService, 'getSubSectionsByParentID').and.returnValue(observableOf([])); + fixture = TestBed.createComponent(DsoEditMenuExpandableSectionComponent); + component = fixture.componentInstance; + spyOn(component as any, 'getMenuItemComponent').and.returnValue(TestComponent); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should show a button with the icon', () => { + const button = fixture.debugElement.query(By.css('.btn-dark')); + expect(button.nativeElement.innerHTML).toContain('fa-' + iconString); + }); +}); + +// declare a test component +@Component({ + selector: 'ds-test-cmp', + template: `` +}) +class TestComponent { +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts new file mode 100644 index 0000000000..e0ad28617b --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts @@ -0,0 +1,39 @@ +import { Component, Inject, Injector } from '@angular/core'; +import { MenuID } from 'src/app/shared/menu/initial-menus-state'; +import { rendersSectionForMenu } from 'src/app/shared/menu/menu-section.decorator'; +import { MenuSectionComponent } from 'src/app/shared/menu/menu-section/menu-section.component'; +import { MenuService } from '../../../menu/menu.service'; +import { MenuSection } from '../../../menu/menu.reducer'; +import { Router } from '@angular/router'; + +/** + * Represents an expandable section in the dso edit menus + */ +@Component({ + /* tslint:disable:component-selector */ + selector: 'ds-dso-edit-menu-expandable-section', + templateUrl: './dso-edit-menu-expandable-section.component.html', + styleUrls: ['./dso-edit-menu-expandable-section.component.scss'], +}) +@rendersSectionForMenu(MenuID.DSO_EDIT, true) +export class DsoEditMenuExpandableSectionComponent extends MenuSectionComponent { + + menuID: MenuID = MenuID.DSO_EDIT; + itemModel; + + constructor( + @Inject('sectionDataProvider') menuSection: MenuSection, + protected menuService: MenuService, + protected injector: Injector, + protected router: Router, + ) { + super(menuSection, menuService, injector); + this.itemModel = menuSection.model; + } + + ngOnInit(): void { + this.menuService.activateSection(this.menuID, this.section.id); + super.ngOnInit(); + } + +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html new file mode 100644 index 0000000000..0fc6d19667 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html @@ -0,0 +1,25 @@ +
    + + + +
    + +
    +
    + +
    + +
    diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.scss b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.scss new file mode 100644 index 0000000000..cf0e81c553 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.scss @@ -0,0 +1,3 @@ +.btn-dark { + background-color: var(--ds-admin-sidebar-bg); +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts new file mode 100644 index 0000000000..bcfeab8180 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts @@ -0,0 +1,173 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { MenuServiceStub } from '../../../testing/menu-service.stub'; +import { TranslateModule } from '@ngx-translate/core'; +import { MenuService } from '../../../menu/menu.service'; +import { CSSVariableService } from '../../../sass-helper/sass-helper.service'; +import { CSSVariableServiceStub } from '../../../testing/css-variable-service.stub'; +import { Router } from '@angular/router'; +import { RouterStub } from '../../../testing/router.stub'; +import { of as observableOf } from 'rxjs'; +import { Component } from '@angular/core'; +import { MenuItemType } from '../../../menu/initial-menus-state'; +import { By } from '@angular/platform-browser'; +import { DsoEditMenuSectionComponent } from './dso-edit-menu-section.component'; +import { OnClickMenuItemModel } from '../../../menu/menu-item/models/onclick.model'; + +function initAsync(dummySectionText: { visible: boolean; icon: string; active: boolean; model: { disabled: boolean; text: string; type: MenuItemType }; id: string }, menuService: MenuServiceStub) { + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [DsoEditMenuSectionComponent, TestComponent], + providers: [ + {provide: 'sectionDataProvider', useValue: dummySectionText}, + {provide: MenuService, useValue: menuService}, + {provide: CSSVariableService, useClass: CSSVariableServiceStub}, + {provide: Router, useValue: new RouterStub()}, + ] + }).overrideComponent(DsoEditMenuSectionComponent, { + set: { + entryComponents: [TestComponent] + } + }) + .compileComponents(); + })); +} + +describe('DsoEditMenuSectionComponent', () => { + let component: DsoEditMenuSectionComponent; + let fixture: ComponentFixture; + const menuService = new MenuServiceStub(); + const iconString = 'test'; + + const dummySectionText = { + id: 'dummy', + active: false, + visible: true, + model: { + type: MenuItemType.TEXT, + disabled: false, + text: 'text' + }, + icon: iconString + }; + const dummySectionLink = { + id: 'dummy', + active: false, + visible: true, + model: { + type: MenuItemType.LINK, + disabled: false, + text: 'text', + link: 'link' + }, + icon: iconString + }; + + const dummySectionClick = { + id: 'dummy', + active: false, + visible: true, + model: { + type: MenuItemType.ONCLICK, + disabled: false, + text: 'text', + function: () => 'test' + }, + icon: iconString + }; + + describe('text model', () => { + initAsync(dummySectionText, menuService); + beforeEach(() => { + spyOn(menuService, 'getSubSectionsByParentID').and.returnValue(observableOf([])); + fixture = TestBed.createComponent(DsoEditMenuSectionComponent); + component = fixture.componentInstance; + spyOn(component as any, 'getMenuItemComponent').and.returnValue(TestComponent); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should show a button with the icon', () => { + const button = fixture.debugElement.query(By.css('.btn-dark')); + expect(button.nativeElement.innerHTML).toContain('fa-' + iconString); + }); + describe('when the section model in a disabled link or text', () => { + it('should show just the button', () => { + const textButton = fixture.debugElement.query(By.css('div div button')); + expect(textButton.nativeElement.innerHTML).toContain('fa-' + iconString); + }); + }); + }); + describe('on click model', () => { + initAsync(dummySectionClick, menuService); + beforeEach(() => { + spyOn(menuService, 'getSubSectionsByParentID').and.returnValue(observableOf([])); + fixture = TestBed.createComponent(DsoEditMenuSectionComponent); + component = fixture.componentInstance; + spyOn(component as any, 'getMenuItemComponent').and.returnValue(TestComponent); + fixture.detectChanges(); + }); + + describe('when the section model in an on click menu', () => { + it('should call the activate method when clicking the button', () => { + spyOn(component, 'activate'); + + const button = fixture.debugElement.query(By.css('.btn-dark')); + button.triggerEventHandler('click', null); + + expect(component.activate).toHaveBeenCalled(); + }); + }); + describe('activate', () => { + const mockEvent = jasmine.createSpyObj('event', { + preventDefault: jasmine.createSpy('preventDefault'), + stopPropagation: jasmine.createSpy('stopPropagation'), + }); + it('should call the item model function when not disabled', () => { + spyOn(component.section.model as OnClickMenuItemModel, 'function'); + component.activate(mockEvent); + + expect((component.section.model as OnClickMenuItemModel).function).toHaveBeenCalled(); + }); + it('should call not the item model function when disabled', () => { + spyOn(component.section.model as OnClickMenuItemModel, 'function'); + component.itemModel.disabled = true; + component.activate(mockEvent); + + expect((component.section.model as OnClickMenuItemModel).function).not.toHaveBeenCalled(); + component.itemModel.disabled = false; + }); + }); + + }); + + describe('link model', () => { + initAsync(dummySectionLink, menuService); + beforeEach(() => { + spyOn(menuService, 'getSubSectionsByParentID').and.returnValue(observableOf([])); + fixture = TestBed.createComponent(DsoEditMenuSectionComponent); + component = fixture.componentInstance; + spyOn(component as any, 'getMenuItemComponent').and.returnValue(TestComponent); + fixture.detectChanges(); + }); + + describe('when the section model in a non disabled link', () => { + it('should show a link element with the button in it', () => { + const link = fixture.debugElement.query(By.css('a')); + expect(link.nativeElement.innerHTML).toContain('button'); + }); + }); + + }); +}); + +// declare a test component +@Component({ + selector: 'ds-test-cmp', + template: `` +}) +class TestComponent { +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts new file mode 100644 index 0000000000..63354e9749 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts @@ -0,0 +1,51 @@ +import { Component, Inject, Injector, OnInit } from '@angular/core'; +import { MenuID } from 'src/app/shared/menu/initial-menus-state'; +import { rendersSectionForMenu } from 'src/app/shared/menu/menu-section.decorator'; +import { MenuSectionComponent } from 'src/app/shared/menu/menu-section/menu-section.component'; +import { MenuService } from '../../../menu/menu.service'; +import { MenuSection } from '../../../menu/menu.reducer'; +import { isNotEmpty } from '../../../empty.util'; + +/** + * Represents a non-expandable section in the dso edit menus + */ +@Component({ + /* tslint:disable:component-selector */ + selector: 'ds-dso-edit-menu-section', + templateUrl: './dso-edit-menu-section.component.html', + styleUrls: ['./dso-edit-menu-section.component.scss'] +}) +@rendersSectionForMenu(MenuID.DSO_EDIT, false) +export class DsoEditMenuSectionComponent extends MenuSectionComponent implements OnInit { + + menuID: MenuID = MenuID.DSO_EDIT; + itemModel; + hasLink: boolean; + canActivate: boolean; + + constructor( + @Inject('sectionDataProvider') menuSection: MenuSection, + protected menuService: MenuService, + protected injector: Injector, + ) { + super(menuSection, menuService, injector); + this.itemModel = menuSection.model; + } + + ngOnInit(): void { + this.hasLink = isNotEmpty(this.itemModel?.link); + this.canActivate = isNotEmpty(this.itemModel?.function); + super.ngOnInit(); + } + + /** + * Activate the section's model funtion + */ + public activate(event: any) { + event.preventDefault(); + if (!this.itemModel.disabled) { + this.itemModel.function(); + } + event.stopPropagation(); + } +} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.html new file mode 100644 index 0000000000..9ef6fff1dc --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.html @@ -0,0 +1,6 @@ +
    +
    + +
    +
    diff --git a/src/app/item-page/simple/item-types/versioned-item/versioned-item.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.scss similarity index 100% rename from src/app/item-page/simple/item-types/versioned-item/versioned-item.component.html rename to src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.scss diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts new file mode 100644 index 0000000000..f2fb656ecc --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts @@ -0,0 +1,78 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/core'; +import { of as observableOf } from 'rxjs'; +import { RouterTestingModule } from '@angular/router/testing'; +import { ActivatedRoute } from '@angular/router'; +import { DsoEditMenuComponent } from './dso-edit-menu.component'; +import { MenuServiceStub } from '../../testing/menu-service.stub'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { AuthService } from '../../../core/auth/auth.service'; +import { AuthServiceStub } from '../../testing/auth-service.stub'; +import { MenuService } from '../../menu/menu.service'; +import { + ExpandableNavbarSectionComponent +} from '../../../navbar/expandable-navbar-section/expandable-navbar-section.component'; +import { MenuItemModel } from '../../menu/menu-item/models/menu-item.model'; + +describe('DsoEditMenuComponent', () => { + let comp: DsoEditMenuComponent; + let fixture: ComponentFixture; + const menuService = new MenuServiceStub(); + let authorizationService: AuthorizationDataService; + + const routeStub = { + children: [] + }; + + const section = { + id: 'edit-dso', + active: false, + visible: true, + model: { + type: null, + disabled: false, + } as MenuItemModel, + icon: 'pencil-alt', + index: 1 + }; + + + beforeEach(waitForAsync(() => { + authorizationService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + spyOn(menuService, 'getMenuTopSections').and.returnValue(observableOf([section])); + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), RouterTestingModule], + declarations: [DsoEditMenuComponent], + providers: [ + Injector, + {provide: MenuService, useValue: menuService}, + {provide: AuthService, useClass: AuthServiceStub}, + {provide: ActivatedRoute, useValue: routeStub}, + {provide: AuthorizationDataService, useValue: authorizationService}, + ], + schemas: [NO_ERRORS_SCHEMA] + }).overrideComponent(ExpandableNavbarSectionComponent, { + set: { + changeDetection: ChangeDetectionStrategy.Default, + } + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DsoEditMenuComponent); + comp = fixture.componentInstance; + comp.sections = observableOf([]); + fixture.detectChanges(); + }); + + describe('onInit', () => { + it('should create', () => { + expect(comp).toBeTruthy(); + }); + }); +}); + diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts new file mode 100644 index 0000000000..d754e07b32 --- /dev/null +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts @@ -0,0 +1,36 @@ +import { Component, Injector } from '@angular/core'; +import { AuthorizationDataService } from 'src/app/core/data/feature-authorization/authorization-data.service'; +import { MenuID } from '../../menu/initial-menus-state'; +import { MenuComponent } from '../../menu/menu.component'; +import { MenuService } from '../../menu/menu.service'; +import { ActivatedRoute } from '@angular/router'; +import { AuthService } from '../../../core/auth/auth.service'; + +/** + * Component representing the edit menu and other menus on the dspace object pages + */ +@Component({ + selector: 'ds-dso-edit-menu', + styleUrls: ['./dso-edit-menu.component.scss'], + templateUrl: './dso-edit-menu.component.html', +}) +export class DsoEditMenuComponent extends MenuComponent { + /** + * The menu ID of this component is DSO_EDIT + * @type {MenuID.DSO_EDIT} + */ + menuID = MenuID.DSO_EDIT; + + constructor(protected menuService: MenuService, + protected injector: Injector, + public authorizationService: AuthorizationDataService, + public route: ActivatedRoute, + private authService: AuthService, + ) { + super(menuService, injector, authorizationService, route); + } + + ngOnInit(): void { + super.ngOnInit(); + } +} diff --git a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.html b/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.html deleted file mode 100644 index d680c140d8..0000000000 --- a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
    - - diff --git a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.scss b/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.scss deleted file mode 100644 index e8b7d689a3..0000000000 --- a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn-dark { - background-color: var(--ds-admin-sidebar-bg); -} diff --git a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.spec.ts b/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.spec.ts deleted file mode 100644 index 5949a98f71..0000000000 --- a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { DsoPageEditButtonComponent } from './dso-page-edit-button.component'; -import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Item } from '../../../core/shared/item.model'; -import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; -import { of as observableOf } from 'rxjs'; -import { TranslateModule } from '@ngx-translate/core'; -import { RouterTestingModule } from '@angular/router/testing'; -import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; -import { By } from '@angular/platform-browser'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; - -describe('DsoPageEditButtonComponent', () => { - let component: DsoPageEditButtonComponent; - let fixture: ComponentFixture; - - let authorizationService: AuthorizationDataService; - let dso: DSpaceObject; - - beforeEach(waitForAsync(() => { - dso = Object.assign(new Item(), { - id: 'test-item', - _links: { - self: { href: 'test-item-selflink' } - } - }); - authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) - }); - TestBed.configureTestingModule({ - declarations: [DsoPageEditButtonComponent], - imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NgbModule], - providers: [ - { provide: AuthorizationDataService, useValue: authorizationService } - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(DsoPageEditButtonComponent); - component = fixture.componentInstance; - component.dso = dso; - component.pageRoute = 'test'; - fixture.detectChanges(); - }); - - it('should check the authorization of the current user', () => { - expect(authorizationService.isAuthorized).toHaveBeenCalledWith(FeatureID.CanEditMetadata, dso.self); - }); - - describe('when the user is authorized', () => { - beforeEach(() => { - (authorizationService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(true)); - component.ngOnInit(); - fixture.detectChanges(); - }); - - it('should render a link', () => { - const link = fixture.debugElement.query(By.css('a')); - expect(link).not.toBeNull(); - }); - }); - - describe('when the user is not authorized', () => { - beforeEach(() => { - (authorizationService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false)); - component.ngOnInit(); - fixture.detectChanges(); - }); - - it('should not render a link', () => { - const link = fixture.debugElement.query(By.css('a')); - expect(link).toBeNull(); - }); - }); -}); diff --git a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.ts b/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.ts deleted file mode 100644 index 1879581d23..0000000000 --- a/src/app/shared/dso-page/dso-page-edit-button/dso-page-edit-button.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; -import { Observable } from 'rxjs'; -import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; - -@Component({ - selector: 'ds-dso-page-edit-button', - templateUrl: './dso-page-edit-button.component.html', - styleUrls: ['./dso-page-edit-button.component.scss'] -}) -/** - * Display a button linking to the edit page of a DSpaceObject - */ -export class DsoPageEditButtonComponent implements OnInit { - /** - * The DSpaceObject to display a button to the edit page for - */ - @Input() dso: DSpaceObject; - - /** - * The prefix of the route to the edit page (before the object's UUID, e.g. "items") - */ - @Input() pageRoute: string; - - /** - * A message for the tooltip on the button - * Supports i18n keys - */ - @Input() tooltipMsg: string; - - /** - * Whether or not the current user is authorized to edit the DSpaceObject - */ - isAuthorized$: Observable; - - constructor(protected authorizationService: AuthorizationDataService) { } - - ngOnInit() { - this.isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanEditMetadata, this.dso.self); - } - -} diff --git a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.html b/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.html deleted file mode 100644 index 0e2e35dcb7..0000000000 --- a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.scss b/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.scss deleted file mode 100644 index e8b7d689a3..0000000000 --- a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn-dark { - background-color: var(--ds-admin-sidebar-bg); -} diff --git a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.spec.ts b/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.spec.ts deleted file mode 100644 index 9839507d57..0000000000 --- a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.spec.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { DsoPageVersionButtonComponent } from './dso-page-version-button.component'; -import { Item } from '../../../core/shared/item.model'; -import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; -import { Observable, of, of as observableOf } from 'rxjs'; -import { TranslateModule } from '@ngx-translate/core'; -import { RouterTestingModule } from '@angular/router/testing'; -import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; -import { By } from '@angular/platform-browser'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { VersionHistoryDataService } from '../../../core/data/version-history-data.service'; - -describe('DsoPageVersionButtonComponent', () => { - let component: DsoPageVersionButtonComponent; - let fixture: ComponentFixture; - - let authorizationService: AuthorizationDataService; - let versionHistoryService: VersionHistoryDataService; - - let dso: Item; - let tooltipMsg: Observable; - - const authorizationServiceSpy = jasmine.createSpyObj('authorizationService', ['isAuthorized']); - - const versionHistoryServiceSpy = jasmine.createSpyObj('versionHistoryService', - ['getVersions', 'getLatestVersionFromHistory$', 'isLatest$', 'hasDraftVersion$'] - ); - - beforeEach(waitForAsync(() => { - dso = Object.assign(new Item(), { - id: 'test-item', - _links: { - self: { href: 'test-item-selflink' }, - version: { href: 'test-item-version-selflink' }, - }, - }); - tooltipMsg = of('tooltip-msg'); - - TestBed.configureTestingModule({ - declarations: [DsoPageVersionButtonComponent], - imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NgbModule], - providers: [ - { provide: AuthorizationDataService, useValue: authorizationServiceSpy }, - { provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy }, - ] - }).compileComponents(); - - authorizationService = TestBed.inject(AuthorizationDataService); - versionHistoryService = TestBed.inject(VersionHistoryDataService); - - versionHistoryServiceSpy.hasDraftVersion$.and.returnValue(observableOf(true)); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(DsoPageVersionButtonComponent); - component = fixture.componentInstance; - component.dso = dso; - component.tooltipMsg$ = tooltipMsg; - fixture.detectChanges(); - }); - - it('should check the authorization of the current user', () => { - expect(authorizationService.isAuthorized).toHaveBeenCalledWith(FeatureID.CanCreateVersion, dso.self); - }); - - it('should check if the item has a draft version', () => { - expect(versionHistoryServiceSpy.hasDraftVersion$).toHaveBeenCalledWith(dso._links.version.href); - }); - - describe('when the user is authorized', () => { - beforeEach(() => { - authorizationServiceSpy.isAuthorized.and.returnValue(observableOf(true)); - component.ngOnInit(); - fixture.detectChanges(); - }); - - it('should render a button', () => { - const button = fixture.debugElement.query(By.css('button')); - expect(button).not.toBeNull(); - }); - }); - - describe('when the user is not authorized', () => { - beforeEach(() => { - authorizationServiceSpy.isAuthorized.and.returnValue(observableOf(false)); - component.ngOnInit(); - fixture.detectChanges(); - }); - - it('should render a button', () => { - const button = fixture.debugElement.query(By.css('button')); - expect(button).toBeNull(); - }); - }); - -}); diff --git a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.ts b/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.ts deleted file mode 100644 index cf07953c75..0000000000 --- a/src/app/shared/dso-page/dso-page-version-button/dso-page-version-button.component.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; -import { Observable, of } from 'rxjs'; -import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; -import { VersionHistoryDataService } from '../../../core/data/version-history-data.service'; -import { Item } from '../../../core/shared/item.model'; -import { map, startWith, switchMap } from 'rxjs/operators'; - -@Component({ - selector: 'ds-dso-page-version-button', - templateUrl: './dso-page-version-button.component.html', - styleUrls: ['./dso-page-version-button.component.scss'] -}) -/** - * Display a button linking to the edit page of a DSpaceObject - */ -export class DsoPageVersionButtonComponent implements OnInit { - /** - * The item for which display a button to create a new version - */ - @Input() dso: Item; - - /** - * A message for the tooltip on the button - * Supports i18n keys - */ - @Input() tooltipMsgCreate: string; - - /** - * A message for the tooltip on the button (when is disabled) - * Supports i18n keys - */ - @Input() tooltipMsgHasDraft: string; - - /** - * Emits an event that triggers the creation of the new version - */ - @Output() newVersionEvent = new EventEmitter(); - - /** - * Whether or not the current user is authorized to create a new version of the DSpaceObject - */ - isAuthorized$: Observable; - - disableNewVersionButton$: Observable; - - tooltipMsg$: Observable; - - constructor( - protected authorizationService: AuthorizationDataService, - protected versionHistoryService: VersionHistoryDataService, - ) { - } - - /** - * Creates a new version for the current item - */ - createNewVersion() { - this.newVersionEvent.emit(); - } - - ngOnInit() { - this.isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanCreateVersion, this.dso.self); - - this.disableNewVersionButton$ = this.versionHistoryService.hasDraftVersion$(this.dso._links.version.href).pipe( - // button is disabled if hasDraftVersion = true, and enabled if hasDraftVersion = false or null - // (hasDraftVersion is null when a version history does not exist) - map((res) => Boolean(res)), - startWith(true), - ); - - this.tooltipMsg$ = this.disableNewVersionButton$.pipe( - switchMap((hasDraftVersion) => of(hasDraftVersion ? this.tooltipMsgHasDraft : this.tooltipMsgCreate)), - ); - } - -} diff --git a/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts new file mode 100644 index 0000000000..0a02481d58 --- /dev/null +++ b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts @@ -0,0 +1,92 @@ +import { DsoVersioningModalService } from './dso-versioning-modal.service'; +import { waitForAsync } from '@angular/core/testing'; +import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; +import { Version } from '../../../core/shared/version.model'; +import { Item } from '../../../core/shared/item.model'; +import { MetadataMap } from '../../../core/shared/metadata.models'; +import { createRelationshipsObservable } from '../../../item-page/simple/item-types/shared/item.component.spec'; +import { buildPaginatedList } from '../../../core/data/paginated-list.model'; +import { PageInfo } from '../../../core/shared/page-info.model'; +import { EMPTY, of as observableOf } from 'rxjs'; + +fdescribe('DsoVersioningModalService', () => { + let service: DsoVersioningModalService; + let modalService; + let versionService; + let versionHistoryService; + let itemVersionShared; + let router; + let workspaceItemDataService; + let itemService; + + const mockItem: Item = Object.assign(new Item(), { + bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])), + metadata: new MetadataMap(), + relationships: createRelationshipsObservable(), + _links: { + self: { + href: 'item-href' + }, + version: { + href: 'version-href' + } + } + }); + + beforeEach(waitForAsync(() => { + modalService = jasmine.createSpyObj('modalService', { + open: {componentInstance: {firstVersion: {}, versionNumber: {}, createVersionEvent: EMPTY}} + }); + versionService = jasmine.createSpyObj('versionService', { + findByHref: createSuccessfulRemoteDataObject$(new Version()), + }); + versionHistoryService = jasmine.createSpyObj('versionHistoryService', { + createVersion: createSuccessfulRemoteDataObject$(new Version()), + hasDraftVersion$: observableOf(false) + }); + itemVersionShared = jasmine.createSpyObj('itemVersionShared', ['notifyCreateNewVersion']); + router = jasmine.createSpyObj('router', ['navigateByUrl']); + workspaceItemDataService = jasmine.createSpyObj('workspaceItemDataService', ['findByItem']); + itemService = jasmine.createSpyObj('itemService', ['findByHref']); + + service = new DsoVersioningModalService( + modalService, + versionService, + versionHistoryService, + itemVersionShared, + router, + workspaceItemDataService, + itemService + ); + })); + describe('when onCreateNewVersion() is called', () => { + it('should call versionService.findByHref', () => { + service.openCreateVersionModal(mockItem); + expect(versionService.findByHref).toHaveBeenCalledWith('version-href'); + }); + }); + + describe('isNewVersionButtonDisabled', () => { + it('should call versionHistoryService.hasDraftVersion$', () => { + service.isNewVersionButtonDisabled(mockItem); + expect(versionHistoryService.hasDraftVersion$).toHaveBeenCalledWith(mockItem._links.version.href); + }); + }); + + describe('getVersioningTooltipMessage', () => { + it('should return the create message when isNewVersionButtonDisabled returns false', (done) => { + spyOn(service, 'isNewVersionButtonDisabled').and.returnValue(observableOf(false)); + service.getVersioningTooltipMessage(mockItem, 'draft-message', 'create-message').subscribe((message) => { + expect(message).toEqual('create-message'); + done(); + }); + }); + it('should return the draft message when isNewVersionButtonDisabled returns true', (done) => { + spyOn(service, 'isNewVersionButtonDisabled').and.returnValue(observableOf(true)); + service.getVersioningTooltipMessage(mockItem, 'draft-message', 'create-message').subscribe((message) => { + expect(message).toEqual('draft-message'); + done(); + }); + }); + }); +}); diff --git a/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.ts b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.ts new file mode 100644 index 0000000000..e1b827a50b --- /dev/null +++ b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.ts @@ -0,0 +1,98 @@ +import { + ItemVersionsSummaryModalComponent +} from '../../item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; +import { RemoteData } from '../../../core/data/remote-data'; +import { Version } from '../../../core/shared/version.model'; +import { map, startWith, switchMap, tap } from 'rxjs/operators'; +import { Item } from '../../../core/shared/item.model'; +import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { VersionDataService } from '../../../core/data/version-data.service'; +import { VersionHistoryDataService } from '../../../core/data/version-history-data.service'; +import { ItemVersionsSharedService } from '../../item/item-versions/item-versions-shared.service'; +import { Router } from '@angular/router'; +import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service'; +import { ItemDataService } from '../../../core/data/item-data.service'; +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; + +/** + * Service to take care of all the functionality related to the version creation modal + */ +@Injectable({ + providedIn: 'root' +}) +export class DsoVersioningModalService { + + constructor( + protected modalService: NgbModal, + protected versionService: VersionDataService, + protected versionHistoryService: VersionHistoryDataService, + protected itemVersionShared: ItemVersionsSharedService, + protected router: Router, + protected workspaceItemDataService: WorkspaceitemDataService, + protected itemService: ItemDataService, + ) { + } + + /** + * Open the create version modal for the provided dso + */ + openCreateVersionModal(dso): void { + + const item = dso; + const versionHref = item._links.version.href; + + // Open modal + const activeModal = this.modalService.open(ItemVersionsSummaryModalComponent); + + // Show current version in modal + this.versionService.findByHref(versionHref).pipe(getFirstCompletedRemoteData()).subscribe((res: RemoteData) => { + // if res.hasNoContent then the item is unversioned + activeModal.componentInstance.firstVersion = res.hasNoContent; + activeModal.componentInstance.versionNumber = (res.hasNoContent ? undefined : res.payload.version); + }); + + // On createVersionEvent emitted create new version and notify + activeModal.componentInstance.createVersionEvent.pipe( + switchMap((summary: string) => this.versionHistoryService.createVersion(item._links.self.href, summary)), + getFirstCompletedRemoteData(), + // show success/failure notification + tap((res: RemoteData) => { + this.itemVersionShared.notifyCreateNewVersion(res); + }), + // get workspace item + getFirstSucceededRemoteDataPayload(), + switchMap((newVersion: Version) => this.itemService.findByHref(newVersion._links.item.href)), + getFirstSucceededRemoteDataPayload(), + switchMap((newVersionItem: Item) => this.workspaceItemDataService.findByItem(newVersionItem.uuid, true, false)), + getFirstSucceededRemoteDataPayload(), + ).subscribe((wsItem) => { + const wsiId = wsItem.id; + const route = 'workspaceitems/' + wsiId + '/edit'; + this.router.navigateByUrl(route); + }); + } + + /** + * Checks if the new version button should be disabled for the provided dso + */ + isNewVersionButtonDisabled(dso): Observable { + return this.versionHistoryService.hasDraftVersion$(dso._links.version.href).pipe( + // button is disabled if hasDraftVersion = true, and enabled if hasDraftVersion = false or null + // (hasDraftVersion is null when a version history does not exist) + map((res) => Boolean(res)), + startWith(true), + ); + } + + /** + * Checks and returns the tooltip that needs to be used for the create version button tooltip + */ + getVersioningTooltipMessage(dso, tooltipMsgHasDraft, tooltipMsgCreate): Observable { + return this.isNewVersionButtonDisabled(dso).pipe( + switchMap((hasDraftVersion) => of(hasDraftVersion ? tooltipMsgHasDraft : tooltipMsgCreate)), + ); + } +} diff --git a/src/app/shared/menu/initial-menus-state.ts b/src/app/shared/menu/initial-menus-state.ts index 7b900540b6..086c7c30fa 100644 --- a/src/app/shared/menu/initial-menus-state.ts +++ b/src/app/shared/menu/initial-menus-state.ts @@ -5,7 +5,8 @@ import { MenusState } from './menu.reducer'; */ export enum MenuID { ADMIN = 'admin-sidebar', - PUBLIC = 'public' + PUBLIC = 'public', + DSO_EDIT = 'dso-edit' } /** @@ -36,5 +37,14 @@ export const initialMenusState: MenusState = { visible: true, sections: {}, sectionToSubsectionIndex: {} - } + }, + [MenuID.DSO_EDIT]: + { + id: MenuID.DSO_EDIT, + collapsed: true, + previewCollapsed: true, + visible: false, + sections: {}, + sectionToSubsectionIndex: {} + }, }; diff --git a/src/app/shared/menu/menu-item/link-menu-item.component.html b/src/app/shared/menu/menu-item/link-menu-item.component.html index b2cc73bcf4..4dacc14cbe 100644 --- a/src/app/shared/menu/menu-item/link-menu-item.component.html +++ b/src/app/shared/menu/menu-item/link-menu-item.component.html @@ -1,6 +1,6 @@ {}; } diff --git a/src/app/shared/menu/menu-item/models/search.model.ts b/src/app/shared/menu/menu-item/models/search.model.ts index e8eeda5501..d2f728ba9f 100644 --- a/src/app/shared/menu/menu-item/models/search.model.ts +++ b/src/app/shared/menu/menu-item/models/search.model.ts @@ -6,6 +6,7 @@ import { MenuItemModel } from './menu-item.model'; */ export class SearchMenuItemModel implements MenuItemModel { type = MenuItemType.SEARCH; + disabled: boolean; placeholder: string; action: string; } diff --git a/src/app/shared/menu/menu-item/models/text.model.ts b/src/app/shared/menu/menu-item/models/text.model.ts index bbaf7804d9..d50ec821ad 100644 --- a/src/app/shared/menu/menu-item/models/text.model.ts +++ b/src/app/shared/menu/menu-item/models/text.model.ts @@ -6,5 +6,6 @@ import { MenuItemModel } from './menu-item.model'; */ export class TextMenuItemModel implements MenuItemModel { type = MenuItemType.TEXT; + disabled: boolean; text: string; } diff --git a/src/app/shared/menu/menu-item/onclick-menu-item.component.html b/src/app/shared/menu/menu-item/onclick-menu-item.component.html index fd0192ad5f..5e8aecbd44 100644 --- a/src/app/shared/menu/menu-item/onclick-menu-item.component.html +++ b/src/app/shared/menu/menu-item/onclick-menu-item.component.html @@ -1,4 +1,5 @@ -{{item.text | translate}} +{{item.text | translate}} diff --git a/src/app/shared/menu/menu-item/onclick-menu-item.component.ts b/src/app/shared/menu/menu-item/onclick-menu-item.component.ts index 002bfbc819..ba47e2ad4a 100644 --- a/src/app/shared/menu/menu-item/onclick-menu-item.component.ts +++ b/src/app/shared/menu/menu-item/onclick-menu-item.component.ts @@ -14,13 +14,16 @@ import { OnClickMenuItemModel } from './models/onclick.model'; @rendersMenuItemForType(MenuItemType.ONCLICK) export class OnClickMenuItemComponent { item: OnClickMenuItemModel; + constructor(@Inject('itemModelProvider') item: OnClickMenuItemModel) { this.item = item; } public activate(event: any) { - event.preventDefault(); - this.item.function(); - event.stopPropagation(); + if (!this.item.disabled) { + event.preventDefault(); + this.item.function(); + event.stopPropagation(); + } } } diff --git a/src/app/shared/menu/menu-item/text-menu-item.component.html b/src/app/shared/menu/menu-item/text-menu-item.component.html index 7ba353e5e7..11c4420402 100644 --- a/src/app/shared/menu/menu-item/text-menu-item.component.html +++ b/src/app/shared/menu/menu-item/text-menu-item.component.html @@ -1 +1 @@ -{{item.text | translate}} \ No newline at end of file +{{item.text | translate}} diff --git a/src/app/shared/menu/menu-section/menu-section.component.ts b/src/app/shared/menu/menu-section/menu-section.component.ts index fcd96c65f1..8c845a58d6 100644 --- a/src/app/shared/menu/menu-section/menu-section.component.ts +++ b/src/app/shared/menu/menu-section/menu-section.component.ts @@ -64,7 +64,9 @@ export class MenuSectionComponent implements OnInit, OnDestroy { */ toggleSection(event: Event) { event.preventDefault(); - this.menuService.toggleActiveSection(this.menuID, this.section.id); + if (!this.section.model?.disabled) { + this.menuService.toggleActiveSection(this.menuID, this.section.id); + } } /** @@ -73,7 +75,9 @@ export class MenuSectionComponent implements OnInit, OnDestroy { */ activateSection(event: Event) { event.preventDefault(); - this.menuService.activateSection(this.menuID, this.section.id); + if (!this.section.model?.disabled) { + this.menuService.activateSection(this.menuID, this.section.id); + } } /** diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 715ee66a99..0454646c96 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -157,8 +157,6 @@ import { SidebarSearchListElementComponent } from './object-list/sidebar-search- import { CollectionSidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/collection/collection-sidebar-search-list-element.component'; import { CommunitySidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/community/community-sidebar-search-list-element.component'; import { AuthorizedCollectionSelectorComponent } from './dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component'; -import { DsoPageEditButtonComponent } from './dso-page/dso-page-edit-button/dso-page-edit-button.component'; -import { DsoPageVersionButtonComponent } from './dso-page/dso-page-version-button/dso-page-version-button.component'; import { HoverClassDirective } from './hover-class.directive'; import { ValidationSuggestionsComponent } from './input-suggestions/validation-suggestions/validation-suggestions.component'; import { ItemAlertsComponent } from './item/item-alerts/item-alerts.component'; @@ -177,6 +175,13 @@ import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; +import { + DsoEditMenuSectionComponent +} from './dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component'; +import { DsoEditMenuComponent } from './dso-page/dso-edit-menu/dso-edit-menu.component'; +import { + DsoEditMenuExpandableSectionComponent +} from './dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -402,18 +407,20 @@ const ENTRY_COMPONENTS = [ OnClickMenuItemComponent, TextMenuItemComponent, ScopeSelectorModalComponent, + DsoEditMenuSectionComponent, + DsoEditMenuExpandableSectionComponent, ]; const SHARED_ITEM_PAGE_COMPONENTS = [ MetadataFieldWrapperComponent, MetadataValuesComponent, - DsoPageEditButtonComponent, - DsoPageVersionButtonComponent, ItemAlertsComponent, GenericItemPageFieldComponent, MetadataRepresentationListComponent, RelatedItemsComponent, - + DsoEditMenuSectionComponent, + DsoEditMenuComponent, + DsoEditMenuExpandableSectionComponent, ]; const PROVIDERS = [ From 96ba1c931992340dbc5e611e26a9acf9b736ad2b Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 21 Sep 2022 14:28:53 +0200 Subject: [PATCH 005/449] 94390: Implement feedback --- .../admin-sidebar-section.component.ts | 2 +- src/app/collection-page/collection-page-routing.module.ts | 1 - src/app/community-page/community-page-routing.module.ts | 1 - src/app/item-page/item-page-routing.module.ts | 1 - .../dso-edit-menu-expandable-section.component.scss | 4 ++-- .../dso-page/dso-edit-menu/dso-edit-menu.component.ts | 6 +----- 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts index 620681c654..97b16c0522 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts @@ -49,7 +49,7 @@ export class AdminSidebarSectionComponent extends MenuSectionComponent implement navigate(event: any): void { event.preventDefault(); - if (this.isDisabled) { + if (!this.isDisabled) { this.router.navigate(this.itemModel.link); } } diff --git a/src/app/collection-page/collection-page-routing.module.ts b/src/app/collection-page/collection-page-routing.module.ts index c5759f833f..3101347990 100644 --- a/src/app/collection-page/collection-page-routing.module.ts +++ b/src/app/collection-page/collection-page-routing.module.ts @@ -93,7 +93,6 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, CreateCollectionPageGuard, CollectionPageAdministratorGuard, - DSOEditMenuResolver ] }) export class CollectionPageRoutingModule { diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts index ac90f3618c..2c97c99081 100644 --- a/src/app/community-page/community-page-routing.module.ts +++ b/src/app/community-page/community-page-routing.module.ts @@ -75,7 +75,6 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, CreateCommunityPageGuard, CommunityPageAdministratorGuard, - DSOEditMenuResolver ] }) export class CommunityPageRoutingModule { diff --git a/src/app/item-page/item-page-routing.module.ts b/src/app/item-page/item-page-routing.module.ts index 1c4da9a267..069936ebd3 100644 --- a/src/app/item-page/item-page-routing.module.ts +++ b/src/app/item-page/item-page-routing.module.ts @@ -90,7 +90,6 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, ItemPageAdministratorGuard, VersionResolver, - DSOEditMenuResolver ] }) diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss index 61ec6347f9..ad6166398c 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.scss @@ -16,11 +16,11 @@ ul.dropdown-menu { color: white; &.disabled { - color: $btn-link-disabled-color; + color: var(--bs-btn-link-disabled-color); } } .disabled { - color: $btn-link-disabled-color; + color: var(--bs-btn-link-disabled-color); } } diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts index d754e07b32..f222966ed8 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.ts @@ -24,13 +24,9 @@ export class DsoEditMenuComponent extends MenuComponent { constructor(protected menuService: MenuService, protected injector: Injector, public authorizationService: AuthorizationDataService, - public route: ActivatedRoute, - private authService: AuthService, + public route: ActivatedRoute ) { super(menuService, injector, authorizationService, route); } - ngOnInit(): void { - super.ngOnInit(); - } } From a92060c45ac9b2caca449a0a9f75fadde8997543 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 22 Sep 2022 12:15:34 +0200 Subject: [PATCH 006/449] 94390: Add comment to array flattening --- src/app/shared/dso-page/dso-edit-menu.resolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.ts index 003e61df95..d461584358 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.ts @@ -45,6 +45,7 @@ export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection if (dsoRD.hasSucceeded) { const dso = dsoRD.payload; return combineLatest(this.getDsoMenus(dso, route, state)).pipe( + // Menu sections are retrieved as an array of arrays and flattened into a single array map((combinedMenus) => [].concat.apply([], combinedMenus)), map((menus) => this.addDsoUuidToMenuIDs(menus, dso)), map((menus) => { From b7c1e76b7f70894660843285d48324226d220a91 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 22 Sep 2022 16:10:43 +0200 Subject: [PATCH 007/449] 94390: Remove fdescribe --- .../dso-versioning-modal.service.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts index 0a02481d58..fc5c1dafc9 100644 --- a/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts +++ b/src/app/shared/dso-page/dso-versioning-modal-service/dso-versioning-modal.service.spec.ts @@ -9,7 +9,7 @@ import { buildPaginatedList } from '../../../core/data/paginated-list.model'; import { PageInfo } from '../../../core/shared/page-info.model'; import { EMPTY, of as observableOf } from 'rxjs'; -fdescribe('DsoVersioningModalService', () => { +describe('DsoVersioningModalService', () => { let service: DsoVersioningModalService; let modalService; let versionService; From 6a932ec6ac65ef6794b3945fc6be0dbd0fd30af1 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 27 Sep 2022 16:21:56 +0200 Subject: [PATCH 008/449] 94390: Remove unused import --- .../research-entities/item-pages/person/person.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 1ac70bad9d..e5e2a52338 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; -import { MetadataValue } from '../../../../core/shared/metadata.models'; import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; @listableObjectComponent('Person', ViewMode.StandalonePage) From 4489b3417c633386b82ee5de1126465bf5ba4234 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 28 Sep 2022 18:09:30 +0200 Subject: [PATCH 009/449] 94391: intermittent commit --- ...expandable-admin-sidebar-section.component.html | 2 +- .../shared/dso-page/dso-edit-menu.resolver.spec.ts | 8 +++++--- src/app/shared/dso-page/dso-edit-menu.resolver.ts | 9 +++++---- ...dso-edit-menu-expandable-section.component.html | 14 ++++++++------ src/styles/_global-styles.scss | 5 +++++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.html b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.html index 259dbd1060..1f4666bbd0 100644 --- a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.html +++ b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.html @@ -7,7 +7,7 @@ [attr.aria-labelledby]="'sidebarName-' + section.id" [attr.aria-expanded]="expanded | async" [title]="('menu.section.icon.' + section.id) | translate" - [class.disabled]="section.model.disabled" + [class.disabled]="section.model?.disabled" (click)="toggleSection($event)" (keyup.space)="toggleSection($event)" (keyup.enter)="toggleSection($event)" diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts index 3f1e34b0e0..ac4c4dae17 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts @@ -15,6 +15,8 @@ import { DsoVersioningModalService } from './dso-versioning-modal-service/dso-ve import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { Item } from '../../core/shared/item.model'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { TextMenuItemModel } from '../menu/menu-item/models/text.model'; +import { LinkMenuItemModel } from '../menu/menu-item/models/link.model'; describe('DSOEditMenuResolver', () => { @@ -164,7 +166,7 @@ describe('DSOEditMenuResolver', () => { expect(menuList[0].active).toEqual(false); expect(menuList[0].visible).toEqual(true); expect(menuList[0].model.type).toEqual(MenuItemType.ONCLICK); - expect(menuList[0].model.text).toEqual('message'); + expect((menuList[0].model as TextMenuItemModel).text).toEqual('message'); expect(menuList[0].model.disabled).toEqual(false); expect(menuList[0].icon).toEqual('code-branch'); done(); @@ -179,8 +181,8 @@ describe('DSOEditMenuResolver', () => { expect(menuList[0].active).toEqual(false); expect(menuList[0].visible).toEqual(true); expect(menuList[0].model.type).toEqual(MenuItemType.LINK); - expect(menuList[0].model.text).toEqual('item.page.edit'); - expect(menuList[0].model.link).toEqual('test-url/edit/metadata'); + expect((menuList[0].model as LinkMenuItemModel).text).toEqual('item.page.edit'); + expect((menuList[0].model as LinkMenuItemModel).link).toEqual('test-url/edit/metadata'); expect(menuList[0].icon).toEqual('pencil-alt'); done(); }); diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.ts index d461584358..ceedda7b60 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.ts @@ -16,6 +16,7 @@ import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { DsoVersioningModalService } from './dso-versioning-modal-service/dso-versioning-modal.service'; import { hasValue } from '../empty.util'; import { MenuSection } from '../menu/menu.reducer'; +import { TextMenuItemModel } from '../menu/menu-item/models/text.model'; /** * Creates the menus for the dspace object pages @@ -65,17 +66,17 @@ export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection /** * Return all the menus for a dso based on the route and state */ - getDsoMenus(dso, route, state) { + getDsoMenus(dso, route, state): Observable[] { return [ this.getItemMenu(dso), - this.getCommonMenu(dso, state) + this.getCommonMenu(dso, state), ]; } /** * Get the common menus between all dspace objects */ - protected getCommonMenu(dso, state): Observable { + protected getCommonMenu(dso, state): Observable { return combineLatest([ this.authorizationService.isAuthorized(FeatureID.CanEditMetadata, dso.self), ]).pipe( @@ -102,7 +103,7 @@ export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection /** * Get item sepcific menus */ - protected getItemMenu(dso): Observable { + protected getItemMenu(dso): Observable { if (dso instanceof Item) { return combineLatest([ this.authorizationService.isAuthorized(FeatureID.CanCreateVersion, dso.self), diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html index b330b1e87d..d44238eb6e 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html @@ -1,14 +1,16 @@ -
    +
    - -
      - +
        +
    diff --git a/src/styles/_global-styles.scss b/src/styles/_global-styles.scss index e337539c15..c71a9695f9 100644 --- a/src/styles/_global-styles.scss +++ b/src/styles/_global-styles.scss @@ -92,3 +92,8 @@ ngb-modal-backdrop { hyphens: auto; } + +ul.dso-edit-dropdown-menu li.nav-item ng-deep a.nav-link { + padding: 0; + display: inline; +} From 785e4085fcb4432d26997e51fa7287037cf3e75e Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Wed, 28 Sep 2022 18:28:41 +0200 Subject: [PATCH 010/449] 94389: Fix icon alignment & dropdown styles --- src/app/shared/dso-page/dso-edit-menu.resolver.ts | 2 -- .../dso-edit-menu-expandable-section.component.html | 9 ++++++--- .../dso-edit-menu-expandable-section.component.scss | 4 ++++ .../dso-edit-menu-expandable-section.component.ts | 12 +++++++++++- src/styles/_global-styles.scss | 3 ++- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.ts index ceedda7b60..2bf1aa08b5 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.ts @@ -16,7 +16,6 @@ import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { DsoVersioningModalService } from './dso-versioning-modal-service/dso-versioning-modal.service'; import { hasValue } from '../empty.util'; import { MenuSection } from '../menu/menu.reducer'; -import { TextMenuItemModel } from '../menu/menu-item/models/text.model'; /** * Creates the menus for the dspace object pages @@ -95,7 +94,6 @@ export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection index: 1 }, ]; - }) ); } diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html index d44238eb6e..a119cf0327 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html @@ -4,9 +4,12 @@ -
      -
    diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts index 2fa72d2ac0..7ed96fdc68 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts @@ -1,5 +1,7 @@ import { Component, Inject } from '@angular/core'; -import { listableObjectComponent } from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; +import { + listableObjectComponent +} from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; import { ViewMode } from '../../../../../../core/shared/view-mode.model'; import { ItemSearchResult } from '../../../../../object-collection/shared/item-search-result.model'; import { SearchResultListElementComponent } from '../../../search-result-list-element.component'; @@ -8,7 +10,7 @@ import { getItemPageRoute } from '../../../../../../item-page/item-page-routing- import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; import { TruncatableService } from '../../../../../../shared/truncatable/truncatable.service'; import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; -import { AppConfig, APP_CONFIG } from '../../../../../../../config/app-config.interface'; +import { APP_CONFIG, AppConfig } from '../../../../../../../config/app-config.interface'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { combineLatest, filter, map, Observable, switchMap, take } from 'rxjs'; import { ConfirmationModalComponent } from '../../../../../../shared/confirmation-modal/confirmation-modal.component'; @@ -16,11 +18,15 @@ import { hasValue } from '../../../../../../shared/empty.util'; import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { followLink } from '../../../../../../shared/utils/follow-link-config.model'; -import { getAllSucceededRemoteListPayload, getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators'; +import { + getAllSucceededRemoteData, + getAllSucceededRemoteListPayload, + getFirstSucceededRemoteDataPayload, + getRemoteDataPayload +} from '../../../../../../core/shared/operators'; import { SupervisionOrder } from '../../../../../../core/supervision-order/models/supervision-order.model'; import { Group } from '../../../../../../core/eperson/models/group.model'; import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../../../core/shared/operators'; import { AuthService } from '../../../../../../core/auth/auth.service'; import { EPerson } from '../../../../../../core/eperson/models/eperson.model'; import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html new file mode 100644 index 0000000000..2e4f8d39cd --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html @@ -0,0 +1,13 @@ + +
    +
    + {{'workflow-item.search.result.list.element.supervised-by' | translate}} +
    +
    + + {{supervisionOrder.group.name}} + X + +
    +
    +
    diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.scss b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts new file mode 100644 index 0000000000..9a5516b8e9 --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SupervisionOrderStatusComponent } from './supervision-order-status.component'; + +describe('SupervisionOrderStatusComponent', () => { + let component: SupervisionOrderStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SupervisionOrderStatusComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SupervisionOrderStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts new file mode 100644 index 0000000000..92cbf17885 --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts @@ -0,0 +1,88 @@ +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; + +import { BehaviorSubject, from, Observable } from 'rxjs'; +import { map, mergeMap, reduce } from 'rxjs/operators'; + +import { SupervisionOrder } from '../../../core/supervision-order/models/supervision-order.model'; +import { Group } from '../../../core/eperson/models/group.model'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { isNotEmpty } from '../../empty.util'; +import { RemoteData } from '../../../core/data/remote-data'; + +export interface SupervisionOrderListEntry { + supervisionOrder: SupervisionOrder; + group: Group +} + +@Component({ + selector: 'ds-supervision-order-status', + templateUrl: './supervision-order-status.component.html', + styleUrls: ['./supervision-order-status.component.scss'] +}) +export class SupervisionOrderStatusComponent implements OnChanges { + + /** + * The list of supervision order object to show + */ + @Input() supervisionOrderList: SupervisionOrder[] = []; + + /** + * The groups the user belongs to + */ + groups: Group[]; + + /** + * List of the supervision orders combined with the group + */ + supervisionOrderEntries$: BehaviorSubject = new BehaviorSubject([]); + + @Output() delete: EventEmitter = new EventEmitter(); + + ngOnChanges(changes: SimpleChanges): void { + if (changes && changes.supervisionOrderList) { + this.getSupervisionOrderEntries(changes.supervisionOrderList.currentValue) + .subscribe((supervisionOrderEntries: SupervisionOrderListEntry[]) => { + this.supervisionOrderEntries$.next(supervisionOrderEntries) + }) + } + console.log('ngOnChanges', changes); + } + + /** + * Create a list of SupervisionOrderListEntry by the given SupervisionOrder list + * + * @param supervisionOrderList + */ + private getSupervisionOrderEntries(supervisionOrderList: SupervisionOrder[]): Observable { + return from(supervisionOrderList).pipe( + mergeMap((so: SupervisionOrder) => so.group.pipe( + getFirstCompletedRemoteData(), + map((sogRD: RemoteData) => { + if (sogRD.hasSucceeded) { + const entry: SupervisionOrderListEntry = { + supervisionOrder: so, + group: sogRD.payload + }; + return entry; + } else { + return null; + } + }) + )), + reduce((acc: SupervisionOrderListEntry[], value: any) => { + if (isNotEmpty(value)) { + return [...acc, value] + } else { + return acc; + } + }, []), + ) + } + + /** + * Emit a delete event with the given SupervisionOrderListEntry. + */ + deleteSupervisionOrder(supervisionOrder: SupervisionOrderListEntry) { + this.delete.emit(supervisionOrder); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 3c985d46b9..624d519ad1 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -100,19 +100,19 @@ import { CreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; import { - ThemedCreateCommunityParentSelectorComponent + ThemedCreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/themed-create-community-parent-selector.component'; import { CreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; import { - ThemedCreateItemParentSelectorComponent + ThemedCreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/themed-create-item-parent-selector.component'; import { CreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; import { - ThemedCreateCollectionParentSelectorComponent + ThemedCreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/themed-create-collection-parent-selector.component'; import { CommunitySearchResultListElementComponent @@ -124,19 +124,19 @@ import { EditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; import { - ThemedEditItemSelectorComponent + ThemedEditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/themed-edit-item-selector.component'; import { EditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; import { - ThemedEditCommunitySelectorComponent + ThemedEditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/themed-edit-community-selector.component'; import { EditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; import { - ThemedEditCollectionSelectorComponent + ThemedEditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/themed-edit-collection-selector.component'; import { RoleDirective } from './roles/role.directive'; import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component'; @@ -242,14 +242,20 @@ import { MenuModule } from './menu/menu.module'; import { ListableNotificationObjectComponent } from './object-list/listable-notification-object/listable-notification-object.component'; -import { SupervisionGroupSelectorComponent } from './dso-selector/modal-wrappers/supervision-group-selector/supervision-group-selector.component'; +import { + SupervisionGroupSelectorComponent +} from './dso-selector/modal-wrappers/supervision-group-selector/supervision-group-selector.component'; import { EpersonGroupListComponent } from './form/eperson-group-list/eperson-group-list.component'; import { EpersonSearchBoxComponent } from './form/eperson-group-list/eperson-search-box/eperson-search-box.component'; import { GroupSearchBoxComponent } from './form/eperson-group-list/group-search-box/group-search-box.component'; import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component'; import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component'; -import { LogInExternalProviderComponent } from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; - +import { + LogInExternalProviderComponent +} from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; +import { + SupervisionOrderStatusComponent +} from './object-list/supervision-order-status/supervision-order-status.component'; const MODULES = [ @@ -452,18 +458,20 @@ const DIRECTIVES = [ ...COMPONENTS, ...ENTRY_COMPONENTS, ...DIRECTIVES, + SupervisionOrderStatusComponent, ], providers: [ ...PROVIDERS ], - exports: [ - ...MODULES, - ...PIPES, - ...COMPONENTS, - ...ENTRY_COMPONENTS, - ...DIRECTIVES, - TranslateModule, - ] + exports: [ + ...MODULES, + ...PIPES, + ...COMPONENTS, + ...ENTRY_COMPONENTS, + ...DIRECTIVES, + TranslateModule, + SupervisionOrderStatusComponent, + ] }) /** diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 47fbbaf518..892f686fb8 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2271,21 +2271,21 @@ "item.truncatable-part.show-less": "Collapse", - "item.search.result.delete-supervision.modal.header": "Delete Supervision Order", + "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", - "item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", + "workflow-item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", - "item.search.result.delete-supervision.modal.cancel": "Cancel", + "workflow-item.search.result.delete-supervision.modal.cancel": "Cancel", - "item.search.result.delete-supervision.modal.confirm": "Delete", + "workflow-item.search.result.delete-supervision.modal.confirm": "Delete", - "item.search.result.notification.deleted.success": "Successfully deleted supervision order \"{{name}}\"", + "workflow-item.search.result.notification.deleted.success": "Successfully deleted supervision order \"{{name}}\"", - "item.search.result.notification.deleted.failure.title": "Failed to delete supervision order \"{{name}}\"", + "workflow-item.search.result.notification.deleted.failure": "Failed to delete supervision order \"{{name}}\"", - "item.search.result.notification.deleted.failure.content": "Failed to delete supervision order", + "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "item.search.result.list.element.supervised-by": "Supervised by:", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", From 851fe7869ed5c47089e0430e82542c4d08a89477 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Sat, 11 Feb 2023 03:29:17 +0100 Subject: [PATCH 319/449] [CST-7757] Missing label --- src/assets/i18n/en.json5 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index bf32aebe47..fa6f2694fa 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4748,6 +4748,8 @@ "subscriptions.modal.new-subscription-form.submit": "Submit", + "subscriptions.modal.new-subscription-form.processing": "Processing...", + "subscriptions.modal.create.success": "Subscribed to {{ type }} successfully.", "subscriptions.modal.delete.success": "Subscription deleted successfully", From c74ef49797cb0fe9e816cb9648a7503b7094304f Mon Sep 17 00:00:00 2001 From: cris Date: Sat, 11 Feb 2023 17:13:52 +0000 Subject: [PATCH 320/449] fixed issue in browser console --- .../mydspace-item-collection/item-collection.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts b/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts index 8f857540d4..2f2a20ede3 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts @@ -40,7 +40,9 @@ export class ItemCollectionComponent implements OnInit { */ ngOnInit() { - this.linkService.resolveLinks(this.object, followLink('workflowitem', {}, + this.linkService.resolveLinks(this.object, followLink('workflowitem', { + isOptional: true + }, followLink('collection',{}) )); this.collection$ = (this.object.workflowitem as Observable>).pipe( From eeda26e122859bfac8fcbc6ea806eae86c19431e Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 10:42:56 +0100 Subject: [PATCH 321/449] 8408 - sort ordering is parametrized and used only when no text query is send. --- config/config.example.yml | 5 +++++ config/config.yml | 6 +++--- .../dso-selector/dso-selector.component.ts | 4 +++- .../create-community-parent-selector.component.ts | 6 ------ .../dso-selector-modal-wrapper.component.ts | 5 +++-- .../scope-selector-modal.component.ts | 7 +------ src/config/app-config.interface.ts | 2 ++ src/config/default-app-config.ts | 7 +++++++ src/config/discovery-sort.config.ts | 14 ++++++++++++++ src/environments/environment.test.ts | 4 ++++ 10 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/config/discovery-sort.config.ts diff --git a/config/config.example.yml b/config/config.example.yml index 9abf167b90..c5a9ea6f85 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -310,3 +310,8 @@ info: markdown: enabled: false mathjax: false + +# Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. +collectionSelectionSort: + sortMetadata: "dc.title" + sortDirection: "ASC" \ No newline at end of file diff --git a/config/config.yml b/config/config.yml index b5eecd112f..38ac562b15 100644 --- a/config/config.yml +++ b/config/config.yml @@ -1,5 +1,5 @@ rest: - ssl: true - host: api7.dspace.org - port: 443 + ssl: false + host: localhost + port: 9090 nameSpace: /server diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 4b5d8c7614..52ca9224b1 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -227,6 +227,8 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { * @param useCache Whether or not to use the cache */ search(query: string, page: number, useCache: boolean = true): Observable>>> { + // default sort is only used when there is not query + var efectiveSort=query?null:this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, @@ -234,7 +236,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { pagination: Object.assign({}, this.defaultPagination, { currentPage: page }), - sort: this.sort + sort: efectiveSort }), null, useCache, diff --git a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts index f344c1c3f3..a7f583df50 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts @@ -12,7 +12,6 @@ import { getCommunityCreateRoute, COMMUNITY_PARENT_PARAMETER } from '../../../../community-page/community-page-routing-paths'; -import {SortDirection, SortOptions} from '../../../../core/cache/models/sort-options.model'; /** * Component to wrap a button - for top communities - @@ -31,11 +30,6 @@ export class CreateCommunityParentSelectorComponent extends DSOSelectorModalWrap selectorTypes = [DSpaceObjectType.COMMUNITY]; action = SelectorActionType.CREATE; - /** - * Default DSO ordering - */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); - constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); } diff --git a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts index 2a25da2f72..fcb8aea9d2 100644 --- a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts @@ -5,7 +5,8 @@ import { RemoteData } from '../../../core/data/remote-data'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { hasValue, isNotEmpty } from '../../empty.util'; -import {SortDirection, SortOptions} from '../../../core/cache/models/sort-options.model'; +import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../environments/environment'; export enum SelectorActionType { CREATE = 'create', @@ -53,7 +54,7 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit { /** * Default DSO ordering */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); + defaultSort = new SortOptions(environment.collectionSelectionSort.sortMetadata, environment.collectionSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { } diff --git a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts index 416242520c..86c3010287 100644 --- a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts +++ b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts @@ -4,7 +4,7 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../../dso-selector/modal-wrappers/dso-selector-modal-wrapper.component'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import {SortDirection, SortOptions} from '../../../core/cache/models/sort-options.model'; + /** * Component to wrap a button - to select the entire repository - * and a list of parent communities - for scope selection @@ -33,11 +33,6 @@ export class ScopeSelectorModalComponent extends DSOSelectorModalWrapperComponen */ scopeChange = new EventEmitter(); - /** - * Default DSO ordering - */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); - constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { super(activeModal, route); } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index ce9c8b3bf7..cc7227d11e 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -20,6 +20,7 @@ import { InfoConfig } from './info-config.interface'; import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; +import { DiscoverySortConfig } from './discovery-sort.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -44,6 +45,7 @@ interface AppConfig extends Config { actuators: ActuatorsConfig info: InfoConfig; markdown: MarkdownConfig; + collectionSelectionSort: DiscoverySortConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 276d2d7150..572f757f86 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -20,6 +20,7 @@ import { InfoConfig } from './info-config.interface'; import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; +import { DiscoverySortConfig } from './discovery-sort.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -385,4 +386,10 @@ export class DefaultAppConfig implements AppConfig { enabled: false, mathjax: false, }; + + // Configuration that determines the metadata sorting of community and collection edition and creation when there are not a search query. + collectionSelectionSort: DiscoverySortConfig = { + sortMetadata:"dc.title", + sortDirection:"ASC", + }; } diff --git a/src/config/discovery-sort.config.ts b/src/config/discovery-sort.config.ts new file mode 100644 index 0000000000..02428f70a8 --- /dev/null +++ b/src/config/discovery-sort.config.ts @@ -0,0 +1,14 @@ +import { Config } from './config.interface'; + +/** + * Config that determines a metadata sorting config. + * It's created mainly to sort by metadata community and collection edition and creation + */ +export class DiscoverySortConfig implements Config { + + public sortMetadata: string; + /** + * ASC / DESC values expected + */ + public sortDirection: string; +} diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 19eec26a14..2cdbee9c29 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -283,4 +283,8 @@ export const environment: BuildConfig = { enabled: false, mathjax: false, }, + collectionSelectionSort: { + sortMetadata:"dc.title", + sortDirection:"ASC", + }, }; From 363136027ec0e05d01e2a9d5c1ba6cbbc9dbba45 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 13 Feb 2023 10:36:13 +0100 Subject: [PATCH 322/449] [CST-7755] WIP revert changes on list components --- ...arch-result-list-element.component.spec.ts | 103 +------------ ...arch-result-list-element.component.spec.ts | 101 +------------ ...arch-result-list-element.component.spec.ts | 101 +------------ ...arch-result-list-element.component.spec.ts | 99 +------------ ...arch-result-list-element.component.spec.ts | 98 +------------ ...on-search-result-list-element.component.ts | 20 +-- ...arch-result-list-element.component.spec.ts | 103 +------------ ...table-object-component-loader.component.ts | 6 - .../abstract-listable-element.component.ts | 10 -- .../item/item-list-element.component.html | 2 +- .../object-list/object-list.component.html | 1 - .../object-list/object-list.component.ts | 5 - ...arch-result-list-element.component.spec.ts | 102 +------------ ...em-search-result-list-element.component.ts | 136 +----------------- 14 files changed, 16 insertions(+), 871 deletions(-) diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts index 3a0e73e46c..178ed86c40 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { JournalIssueSearchResultListElementComponent } from './journal-issue-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -10,43 +10,9 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalIssueListElementComponent: JournalIssueSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); - -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -104,65 +70,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalIssueSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalIssueSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -174,9 +87,6 @@ describe('JournalIssueSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalIssueSearchResultListElementComponent); journalIssueListElementComponent = fixture.componentInstance; @@ -254,13 +164,6 @@ describe('JournalIssueSearchResultListElementComponent', () => { declarations: [JournalIssueSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -278,9 +181,7 @@ describe('JournalIssueSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + journalIssueListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts index 67665403d1..71fa83a3b1 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { Item } from '../../../../../core/shared/item.model'; import { JournalVolumeSearchResultListElementComponent } from './journal-volume-search-result-list-element.component'; @@ -10,43 +10,10 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalVolumeListElementComponent: JournalVolumeSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); - -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), { @@ -102,65 +69,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalVolumeSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalVolumeSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -172,9 +86,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalVolumeSearchResultListElementComponent); journalVolumeListElementComponent = fixture.componentInstance; @@ -251,13 +162,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { declarations: [JournalVolumeSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -269,9 +173,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalVolumeSearchResultListElementComponent); journalVolumeListElementComponent = fixture.componentInstance; })); diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts index 63e8abda28..07970d7128 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { JournalSearchResultListElementComponent } from './journal-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; @@ -10,42 +10,9 @@ import { ItemSearchResult } from '../../../../../shared/object-collection/shared import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalListElementComponent: JournalSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -98,65 +65,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -168,9 +82,6 @@ describe('JournalSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalSearchResultListElementComponent); journalListElementComponent = fixture.componentInstance; @@ -223,13 +134,6 @@ describe('JournalSearchResultListElementComponent', () => { declarations: [JournalSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -241,9 +145,6 @@ describe('JournalSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalSearchResultListElementComponent); journalListElementComponent = fixture.componentInstance; })); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts index 102393ed8f..9609a9582a 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { OrgUnitSearchResultListElementComponent } from './org-unit-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; @@ -12,41 +12,9 @@ import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service import { APP_CONFIG } from '../../../../../../config/app-config.interface'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../../../../shared/mocks/translate-loader.mock'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let orgUnitListElementComponent: OrgUnitSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -97,52 +65,6 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('OrgUnitSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -156,12 +78,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { declarations: [ OrgUnitSearchResultListElementComponent , TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -173,9 +89,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(OrgUnitSearchResultListElementComponent); orgUnitListElementComponent = fixture.componentInstance; @@ -235,12 +148,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { declarations: [OrgUnitSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -258,9 +165,7 @@ describe('OrgUnitSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + orgUnitListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts index 25b3a37c83..31018520f6 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { PersonSearchResultListElementComponent } from './person-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -12,44 +12,9 @@ import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service import { APP_CONFIG } from '../../../../../../config/app-config.interface'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../../../../shared/mocks/translate-loader.mock'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { hot } from 'jasmine-marbles'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let personListElementComponent: PersonSearchResultListElementComponent; let fixture: ComponentFixture; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -100,48 +65,6 @@ const enviromentNoThumbs = { } }; -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('PersonSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -155,12 +78,6 @@ describe('PersonSearchResultListElementComponent', () => { declarations: [PersonSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {} }, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -172,9 +89,6 @@ describe('PersonSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(PersonSearchResultListElementComponent); personListElementComponent = fixture.componentInstance; @@ -234,12 +148,6 @@ describe('PersonSearchResultListElementComponent', () => { declarations: [PersonSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService}, - {provide: NotificationsService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -257,9 +165,7 @@ describe('PersonSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + personListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts index 09142fc02e..217d7baef9 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts @@ -9,14 +9,6 @@ import { import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { APP_CONFIG, AppConfig } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; @listableObjectComponent('PersonSearchResult', ViewMode.ListElement) @Component({ @@ -32,17 +24,9 @@ export class PersonSearchResultListElementComponent extends ItemSearchResultList public constructor( protected truncatableService: TruncatableService, protected dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig: AppConfig, - protected supervisionOrderDataService: SupervisionOrderDataService, - protected modalService: NgbModal, - protected notificationsService: NotificationsService, - protected translateService: TranslateService, - protected resourcePolicyService: ResourcePolicyDataService, - protected authService: AuthService, - protected epersonService: EPersonDataService, - protected authorizationService: AuthorizationDataService + @Inject(APP_CONFIG) protected appConfig: AppConfig ) { - super(truncatableService, dsoNameService, appConfig, supervisionOrderDataService, modalService, notificationsService, translateService, resourcePolicyService, authService, epersonService, authorizationService); + super(truncatableService, dsoNameService, appConfig); } /** diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts index 60487af8c8..0cb3e63e87 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts @@ -1,6 +1,6 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { ProjectSearchResultListElementComponent } from './project-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -10,43 +10,9 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { By } from '@angular/platform-browser'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let projectListElementComponent: ProjectSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); - -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -98,65 +64,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('ProjectSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ProjectSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -168,9 +81,6 @@ describe('ProjectSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ProjectSearchResultListElementComponent); projectListElementComponent = fixture.componentInstance; @@ -223,13 +133,6 @@ describe('ProjectSearchResultListElementComponent', () => { declarations: [ProjectSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } @@ -248,9 +151,7 @@ describe('ProjectSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + projectListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts index 59ce71ff6c..6b75c59181 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts @@ -71,11 +71,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ @Input() showLabel = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * The value to display for this element */ @@ -128,7 +123,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ protected inAndOutputNames: string[] = [ 'object', - 'showSupervisionOrderBadges', 'index', 'linkType', 'listID', diff --git a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts index f292ac5b76..7d4e107b2b 100644 --- a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts +++ b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts @@ -16,11 +16,6 @@ export class AbstractListableElementComponent { */ @Input() object: T; - /** - * The supervision orders to render in this list element - */ - @Input() supervisionOrders: T; - /** * The link type to determine the type of link rendered in this element */ @@ -46,11 +41,6 @@ export class AbstractListableElementComponent { */ @Input() showLabel = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * The context we matched on to get this component */ diff --git a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html index 4bf45e7f3b..3877e2f335 100644 --- a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html +++ b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html @@ -1 +1 @@ - + diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index a0ef3e1cb9..b8712b85c5 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -31,7 +31,6 @@ [context]="context" [linkType]="linkType" [listID]="selectionConfig?.listId" - [showSupervisionOrderBadges]="showSupervisionOrderBadges" (contentChange)="contentChange.emit($event)">
  • diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts index 9d064115e6..65e2b508da 100644 --- a/src/app/shared/object-list/object-list.component.ts +++ b/src/app/shared/object-list/object-list.component.ts @@ -81,11 +81,6 @@ export class ObjectListComponent { */ @Input() showPaginator = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * Emit when one of the listed object has changed. */ diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts index d4ca14c105..7665b7d64e 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResultListElementComponent } from './item-search-result-list-element.component'; import { Item } from '../../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../utils/truncate.pipe'; @@ -10,44 +10,10 @@ import { ItemSearchResult } from '../../../../../object-collection/shared/item-s import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock, UNDEFINED_NAME } from '../../../../../mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../../shared/testing/eperson.mock'; -import { EPerson } from 'src/app/core/eperson/models/eperson.model'; -import { createPaginatedList } from 'src/app/shared/testing/utils.test'; let publicationListElementComponent: ItemSearchResultListElementComponent; let fixture: ComponentFixture; const dcTitle = 'This is just another title'; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); - const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), { hitHighlights: { 'dc.title': [{ @@ -218,65 +184,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('ItemSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ItemSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -288,9 +201,6 @@ describe('ItemSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ItemSearchResultListElementComponent); publicationListElementComponent = fixture.componentInstance; @@ -463,13 +373,6 @@ describe('ItemSearchResultListElementComponent', () => { declarations: [ItemSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -481,9 +384,6 @@ describe('ItemSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ItemSearchResultListElementComponent); publicationListElementComponent = fixture.componentInstance; })); diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts index 7ed96fdc68..f84ae642ad 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts @@ -1,37 +1,10 @@ -import { Component, Inject } from '@angular/core'; -import { - listableObjectComponent -} from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; +import { Component } from '@angular/core'; +import { listableObjectComponent } from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; import { ViewMode } from '../../../../../../core/shared/view-mode.model'; import { ItemSearchResult } from '../../../../../object-collection/shared/item-search-result.model'; import { SearchResultListElementComponent } from '../../../search-result-list-element.component'; import { Item } from '../../../../../../core/shared/item.model'; import { getItemPageRoute } from '../../../../../../item-page/item-page-routing-paths'; -import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; -import { TruncatableService } from '../../../../../../shared/truncatable/truncatable.service'; -import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; -import { APP_CONFIG, AppConfig } from '../../../../../../../config/app-config.interface'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { combineLatest, filter, map, Observable, switchMap, take } from 'rxjs'; -import { ConfirmationModalComponent } from '../../../../../../shared/confirmation-modal/confirmation-modal.component'; -import { hasValue } from '../../../../../../shared/empty.util'; -import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { followLink } from '../../../../../../shared/utils/follow-link-config.model'; -import { - getAllSucceededRemoteData, - getAllSucceededRemoteListPayload, - getFirstSucceededRemoteDataPayload, - getRemoteDataPayload -} from '../../../../../../core/shared/operators'; -import { SupervisionOrder } from '../../../../../../core/supervision-order/models/supervision-order.model'; -import { Group } from '../../../../../../core/eperson/models/group.model'; -import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../../core/auth/auth.service'; -import { EPerson } from '../../../../../../core/eperson/models/eperson.model'; -import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../../core/data/feature-authorization/authorization-data.service'; -import { FeatureID } from '../../../../../../core/data/feature-authorization/feature-id'; @listableObjectComponent('PublicationSearchResult', ViewMode.ListElement) @listableObjectComponent(ItemSearchResult, ViewMode.ListElement) @@ -44,8 +17,6 @@ import { FeatureID } from '../../../../../../core/data/feature-authorization/fea * The component for displaying a list element for an item search result of the type Publication */ export class ItemSearchResultListElementComponent extends SearchResultListElementComponent { - messagePrefix = 'item.search.result'; - /** * Route to the item's page */ @@ -56,112 +27,9 @@ export class ItemSearchResultListElementComponent extends SearchResultListElemen */ showThumbnails: boolean; - /** - * List of the supervision orders combined with the group - */ - supervisionOrder$: Observable<{ supervisionOrder: SupervisionOrder; group: Group; }[]>; - - /** - * The groups the user belongs to - */ - groups: Group[]; - - constructor( - protected truncatableService: TruncatableService, - protected dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig: AppConfig, - protected supervisionOrderDataService: SupervisionOrderDataService, - protected modalService: NgbModal, - protected notificationsService: NotificationsService, - protected translateService: TranslateService, - protected resourcePolicyService: ResourcePolicyDataService, - protected authService: AuthService, - protected epersonService: EPersonDataService, - protected authorizationService: AuthorizationDataService - ) { super(truncatableService, dsoNameService, appConfig); } - ngOnInit(): void { super.ngOnInit(); this.showThumbnails = this.appConfig.browseBy.showThumbnails; - let isAdmin = false; - this.authorizationService.isAuthorized(FeatureID.AdministratorOf).subscribe(isadmin => { - isAdmin = isadmin; - }); - - this.authService.getAuthenticatedUserFromStore().pipe( - filter((user: EPerson) => hasValue(user.id)), - switchMap((user: EPerson) => this.epersonService.findById(user.id, true, true, followLink('groups'))), - getAllSucceededRemoteData(), - getRemoteDataPayload(), - switchMap((user: EPerson) => user.groups), - ).subscribe(groups => { - this.groups = groups?.payload?.page; - }); - this.itemPageRoute = getItemPageRoute(this.dso); - if (this.supervisionOrders) { - this.resourcePolicyService.searchByResource( - this.dso.uuid, null, false, true, - followLink('eperson'), followLink('group') - ).pipe( - getAllSucceededRemoteData(), - ).subscribe((result) => { - this.supervisionOrder$ = this.supervisionOrderDataService.searchByItem(this.dso.uuid, false, true, followLink('group')).pipe( - getAllSucceededRemoteListPayload(), - switchMap((supervisionOrders: SupervisionOrder[]) => { - const supervisionOrdersArray = supervisionOrders.map((supervisionOrder: SupervisionOrder) => { - return supervisionOrder.group.pipe( - getFirstSucceededRemoteDataPayload(), - map((group: Group) => { - let isAuthorized = false; - result.payload.page.forEach(resourcePolicy => { - resourcePolicy.group.subscribe(res => { - if (isAdmin || (res.payload && res.payload.uuid === group.uuid && this.groups.find(groups => groups.uuid === group.uuid))) { - isAuthorized = true; - } - }); - }); - return isAuthorized ? ({ supervisionOrder, group }) : null; - }), - ); - }); - return combineLatest(supervisionOrdersArray).pipe( - map(array => array.filter(hasValue)) - ); - })); - }); - } - } - - /** - * Deletes the Group from the Repository. The Group will be the only that this form is showing. - * It'll either show a success or error message depending on whether the delete was successful or not. - */ - deleteSupervisionOrder(supervisionOrder) { - const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = supervisionOrder.group; - modalRef.componentInstance.headerLabel = this.messagePrefix + '.delete-supervision.modal.header'; - modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-supervision.modal.info'; - modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-supervision.modal.cancel'; - modalRef.componentInstance.confirmLabel = this.messagePrefix + '.delete-supervision.modal.confirm'; - modalRef.componentInstance.brandColor = 'danger'; - modalRef.componentInstance.confirmIcon = 'fas fa-trash'; - modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => { - if (confirm) { - if (hasValue(supervisionOrder.supervisionOrder.id)) { - this.supervisionOrderDataService.delete(supervisionOrder.supervisionOrder.id) - .subscribe((rd: boolean) => { - if (rd) { - this.supervisionOrderDataService.searchByItem(this.dso.uuid, null, null, followLink('group')); - this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.deleted.success', { name: supervisionOrder.group._name })); - } else { - this.notificationsService.error( - this.translateService.get(this.messagePrefix + '.notification.deleted.failure.title', { name: supervisionOrder.group._name }), - this.translateService.get(this.messagePrefix + '.notification.deleted.failure.content')); - } - }); - } - } - }); } } From e2668cdf972e22ee5142427d551e48956848e342 Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 12:22:07 +0100 Subject: [PATCH 323/449] DS-8408 - lint errors --- .../dso-selector/dso-selector/dso-selector.component.ts | 2 +- src/config/default-app-config.ts | 4 ++-- src/config/discovery-sort.config.ts | 2 +- src/environments/environment.test.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 52ca9224b1..05fb512c9a 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -228,7 +228,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ search(query: string, page: number, useCache: boolean = true): Observable>>> { // default sort is only used when there is not query - var efectiveSort=query?null:this.sort; + var efectiveSort=query ? null : this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 095a20a4e5..89a627f459 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -425,7 +425,7 @@ export class DefaultAppConfig implements AppConfig { // Configuration that determines the metadata sorting of community and collection edition and creation when there are not a search query. collectionSelectionSort: DiscoverySortConfig = { - sortMetadata:"dc.title", - sortDirection:"ASC", + sortMetadata:'dc.title', + sortDirection:'ASC', }; } diff --git a/src/config/discovery-sort.config.ts b/src/config/discovery-sort.config.ts index 02428f70a8..3f08b3fb17 100644 --- a/src/config/discovery-sort.config.ts +++ b/src/config/discovery-sort.config.ts @@ -1,7 +1,7 @@ import { Config } from './config.interface'; /** - * Config that determines a metadata sorting config. + * Config that determines a metadata sorting config. * It's created mainly to sort by metadata community and collection edition and creation */ export class DiscoverySortConfig implements Config { diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index c352cdca92..8b132dab60 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -298,8 +298,8 @@ export const environment: BuildConfig = { mathjax: false, }, collectionSelectionSort: { - sortMetadata:"dc.title", - sortDirection:"ASC", + sortMetadata:'dc.title', + sortDirection:'ASC', }, vocabularies: [ From 0121e6d895de30c6c1054b8087fa6ecb1b7dd0bd Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 12:34:13 +0100 Subject: [PATCH 324/449] DS-8408 - more lint problems --- .../shared/dso-selector/dso-selector/dso-selector.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 05fb512c9a..fe64c0a41e 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -228,7 +228,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ search(query: string, page: number, useCache: boolean = true): Observable>>> { // default sort is only used when there is not query - var efectiveSort=query ? null : this.sort; + let efectiveSort = query ? null : this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, From 078bdd287fbeca3912cc894f2356241925172081 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Mon, 13 Feb 2023 15:45:56 +0100 Subject: [PATCH 325/449] [CST-7757] Fix delete message --- .../subscription-modal.component.html | 2 +- .../subscription-modal.component.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html index 0e723a8140..a71498f002 100644 --- a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html +++ b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html @@ -27,7 +27,7 @@ -

    {{'subscriptions.modal.delete-info' | translate}}

    +

    {{'subscriptions.modal.delete-info' | translate}}

    - + \ No newline at end of file diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index fa6f2694fa..3491c066a1 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4635,7 +4635,7 @@ "submission.workflow.generic.delete": "Delete", - "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "Select this option if you would to discard this item, select \"Delete\". You will then be asked to confirm it.", "submission.workflow.generic.edit": "Edit", From 0f25f9f18fb90967962217cdb80dd2dba251666b Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 14 Feb 2023 11:24:08 +0100 Subject: [PATCH 331/449] [CST-8914] Add flag to show/hide csv export button --- .../search-page/search-page.component.html | 2 +- .../search-results.component.html | 2 +- .../search-results.component.ts | 5 +++++ .../themed-search-results.component.ts | 4 +++- src/app/shared/search/search.component.html | 21 ++++++++++--------- src/app/shared/search/search.component.ts | 5 +++++ .../shared/search/themed-search.component.ts | 4 +++- 7 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/app/search-page/search-page.component.html b/src/app/search-page/search-page.component.html index 73a952332f..36ba53a885 100644 --- a/src/app/search-page/search-page.component.html +++ b/src/app/search-page/search-page.component.html @@ -1 +1 @@ - + diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index 44498c3cab..1e8c81e454 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -1,6 +1,6 @@

    {{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}

    - +
    { - protected inAndOutputNames: (keyof SearchResultsComponent & keyof this)[] = ['linkType', 'searchResults', 'searchConfig', 'sortConfig', 'viewMode', 'configuration', 'disableHeader', 'selectable', 'context', 'hidePaginationDetail', 'selectionConfig', 'contentChange', 'deselectObject', 'selectObject']; + protected inAndOutputNames: (keyof SearchResultsComponent & keyof this)[] = ['linkType', 'searchResults', 'searchConfig', 'showCsvExport', 'sortConfig', 'viewMode', 'configuration', 'disableHeader', 'selectable', 'context', 'hidePaginationDetail', 'selectionConfig', 'contentChange', 'deselectObject', 'selectObject']; @Input() linkType: CollectionElementLinkType; @@ -29,6 +29,8 @@ export class ThemedSearchResultsComponent extends ThemedComponent
    + [searchConfig]="searchOptions$ | async" + [configuration]="(currentConfiguration$ | async)" + [disableHeader]="!searchEnabled" + [linkType]="linkType" + [context]="(currentContext$ | async)" + [selectable]="selectable" + [selectionConfig]="selectionConfig" + [showCsvExport]="showCsvExport" + (contentChange)="onContentChange($event)" + (deselectObject)="deselectObject.emit($event)" + (selectObject)="selectObject.emit($event)"> diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index c094e37ef2..b8426bc635 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -117,6 +117,11 @@ export class SearchComponent implements OnInit { */ @Input() selectionConfig: SelectionConfig; + /** + * A boolean representing if show csv export button + */ + @Input() showCsvExport = false; + /** * A boolean representing if show search sidebar button */ diff --git a/src/app/shared/search/themed-search.component.ts b/src/app/shared/search/themed-search.component.ts index 64a2befeb2..bdeb724779 100644 --- a/src/app/shared/search/themed-search.component.ts +++ b/src/app/shared/search/themed-search.component.ts @@ -19,7 +19,7 @@ import { ListableObject } from '../object-collection/shared/listable-object.mode templateUrl: '../theme-support/themed.component.html', }) export class ThemedSearchComponent extends ThemedComponent { - protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showSidebar', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics']; + protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics']; @Input() configurationList: SearchConfigurationOption[] = []; @@ -47,6 +47,8 @@ export class ThemedSearchComponent extends ThemedComponent { @Input() selectionConfig: SelectionConfig; + @Input() showCsvExport = false; + @Input() showSidebar = true; @Input() showViewModes = true; From d810cbcc8fea2aea627223f46cd25c8a964c9390 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 15 Feb 2023 11:36:56 +0300 Subject: [PATCH 332/449] src/assets/i18n: Improve English strings for file upload Simple improvement to the wording in the file upload section of the item submission form. Also add a period at the end of the string. Fixes: #2096 --- src/assets/i18n/ar.json5 | 4 ++-- src/assets/i18n/bn.json5 | 2 +- src/assets/i18n/ca.json5 | 2 +- src/assets/i18n/cs.json5 | 4 ++-- src/assets/i18n/de.json5 | 2 +- src/assets/i18n/en.json5 | 2 +- src/assets/i18n/es.json5 | 2 +- src/assets/i18n/fi.json5 | 2 +- src/assets/i18n/fr.json5 | 2 +- src/assets/i18n/gd.json5 | 2 +- src/assets/i18n/hu.json5 | 2 +- src/assets/i18n/ja.json5 | 4 ++-- src/assets/i18n/kk.json5 | 2 +- src/assets/i18n/lv.json5 | 2 +- src/assets/i18n/nl.json5 | 2 +- src/assets/i18n/pt-BR.json5 | 2 +- src/assets/i18n/pt-PT.json5 | 2 +- src/assets/i18n/sv.json5 | 2 +- src/assets/i18n/sw.json5 | 4 ++-- src/assets/i18n/tr.json5 | 2 +- src/assets/i18n/uk.json5 | 2 +- 21 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/assets/i18n/ar.json5 b/src/assets/i18n/ar.json5 index 24e6e14603..1edbdf7981 100644 --- a/src/assets/i18n/ar.json5 +++ b/src/assets/i18n/ar.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/bn.json5 b/src/assets/i18n/bn.json5 index 55ec1820dd..8b903c4a65 100644 --- a/src/assets/i18n/bn.json5 +++ b/src/assets/i18n/bn.json5 @@ -5803,7 +5803,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "অনুগ্রহ করে মনে রাখবেন যে {{collectionName}} সংগ্রহে আপলোড করা ফাইলগুলি অ্যাক্সেসযোগ্য হবে, একক ফাইলের জন্য স্পষ্টভাবে যা নির্ধারণ করা হয়েছে তা ছাড়াও, নিম্নলিখিত গ্রুপ(গুলি) সহ:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "এখানে আপনি বর্তমানে আইটেমটিতে সমস্ত ফাইল পাবেন। আপনি ফাইল মেটাডেটা এবং অ্যাক্সেস শর্তাদি আপডেট করতে পারেন অথবা অতিরিক্ত ফাইল আপলোড করুন - পৃষ্ঠাটিতে সর্বত্র ড্র্যাগ করুন এবং ড্রপ করুন ", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/ca.json5 b/src/assets/i18n/ca.json5 index 24698baac0..246a92061c 100644 --- a/src/assets/i18n/ca.json5 +++ b/src/assets/i18n/ca.json5 @@ -6353,7 +6353,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Tingueu en compte que els fitxers carregats a la col·lecció {{ collectionName }} seran accessibles, a més del que es decideixi explícitament per al fitxer, per als grups següents:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aquí trobareu tots els fitxers que es troben actualment a l'ítem. Podeu actualitzar les metadades del fitxer i les condicions d'accés o incloure fitxers addicionals simplement arrossegant i deixant anar a qualsevol lloc de la pàgina", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index a04e89b2c3..5ed1474384 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -6327,9 +6327,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index c1979be6b6..82d422621c 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5203,7 +5203,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Bitte beachten Sie, dass in diese Sammlung {{collectionName}} hochgeladene Dateien zugüglich zu dem, was für einzelne Dateien entschieden wurde, für folgende Gruppe(n) zugänglich sein:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zum Item gehören. Sie können ihre Metadaten und Zugriffsrechte bearbeiten oder weitere Dateien per Drag & Drop hinzufügen.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 8fcac7d040..fc4c6aa74d 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4581,7 +4581,7 @@ "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index ae41bfdcb5..3184e4f22b 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -6353,7 +6353,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Tenga en cuenta que los archivos cargados en la colección {{ collectionName }} serán accesibles, además de lo que se decida explícitamente para el fichero, para los siguientes grupos:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aquí encontrará todos los archivos que se encuentran actualmente en el ítem. Puede actualizar los metadatos del fichero y las condiciones de acceso e incluir ficheros adicionales simplemente arrastrando-y-soltando en cualquier lugar de la página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/fi.json5 b/src/assets/i18n/fi.json5 index 2a077006cc..05ae06d46b 100644 --- a/src/assets/i18n/fi.json5 +++ b/src/assets/i18n/fi.json5 @@ -4914,7 +4914,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Yksittäisten tiedostojen pääsyrajoitusten lisäksi {{collectionName}}-kokoelmaan ladatut tiedostot ovat seuraavien ryhmien saatavilla:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Tietueen kaikki tiedostot on lueteltu tässä. Voit päivittää tiedoston metadataa ja pääsyehtoja tai ladata lisää tiedostoja raahaamalla ne mihin hyvänsä sivun kohtaan", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 381e13a743..1e042c81fd 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -5670,7 +5670,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Veuillez noter que, en complément des accès spécifiquement accordés pour le fichier, les fichiers téléchargés dans la collection {{collectionName}} seront accessibles par défaut au(x) groupe(s) suivant(s) :", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Vous trouverez ici tous les fichiers actuellement associés à l'Item. Vous pouvez éditer les métadonnés et les niveaux d'accès de ce(s) fichier(s) ou télécharger des fichiers complémentaires simplement en les glissant n'importe où sur cette page", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/gd.json5 b/src/assets/i18n/gd.json5 index 083de54781..4584145452 100644 --- a/src/assets/i18n/gd.json5 +++ b/src/assets/i18n/gd.json5 @@ -5801,7 +5801,7 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Thoir fa-near gum bi cothrom air faidhlichean a chaidh a luchdachadh gu cruinneachadh {{collectionName}}, cho math ris na chaidh a cho-dhùnadh airson an fhaidhle air leth, aig a' bhuidheann/na buidhnean a leanas:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "An seo gheibh thu na faidhlichean gu lèir san nì an-dràsta. Is urrainn dhut metadata an fhaidhle ùrachadh agus cothrom fhaighinn air cumhachan no faidhlichean eile a luchdachadh suas le bhith gan slaodadh agus gan leigeil às air feadh na duilleig", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/hu.json5 b/src/assets/i18n/hu.json5 index 0e73e9dbae..bfa4a53ccf 100644 --- a/src/assets/i18n/hu.json5 +++ b/src/assets/i18n/hu.json5 @@ -4924,7 +4924,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Kérjük, vegye figyelembe, hogy a {{collectionName}} gyűjteménybe feltöltött állományok elérhetők lesznek, azon kívül amit az egyedi állományokról kifejezetten eldöntött, a következő csoport(ok)ban:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Itt megtalálja a tárgyban lévő valamennyi állományt. Frissítheti az állomány metaadatait és hozzáférési feltételeit vagy feltölthet további állományokat azzal, hogy behúzza azokat bárhova az oldalra", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/ja.json5 b/src/assets/i18n/ja.json5 index 71b32cf70b..83a755c923 100644 --- a/src/assets/i18n/ja.json5 +++ b/src/assets/i18n/ja.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/kk.json5 b/src/assets/i18n/kk.json5 index b661ce21d3..0fd092df02 100644 --- a/src/assets/i18n/kk.json5 +++ b/src/assets/i18n/kk.json5 @@ -6283,7 +6283,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "{{collectionName}} жинағына жүктелген файлдар жеке файл үшін нақты анықталғаннан басқа, келесі топпен (топтармен) қол жетімді болатындығын ескеріңіз:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Мұнда сіз осы элементтегі барлық файлдарды таба аласыз. Файл метадеректерін және кіру шарттарын жаңартуға немесе қосымша файлдарды олардыбетінде сүйреп апару арқылы жүктеуге болады.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/lv.json5 b/src/assets/i18n/lv.json5 index e00ad3517b..79ff8ce855 100644 --- a/src/assets/i18n/lv.json5 +++ b/src/assets/i18n/lv.json5 @@ -5379,7 +5379,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Lūdzu, ņemiet vērā, ka augšupielādētie faili kolekcijā {{collectionName}} būs pieejami papildus tam, kas ir skaidri noteikts par atsevišķu failu, ar šādām grupām:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Šeit atradīsit visus failus, kas pašlaik atrodas materiālā. Varat atjaunināt failu metadatus un piekļuves nosacījumus vai augšupielādēt papildu failus, vienkārši ievelkot un atstājot tos visur lapā", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/nl.json5 b/src/assets/i18n/nl.json5 index b02e3a5276..1ebdeaa566 100644 --- a/src/assets/i18n/nl.json5 +++ b/src/assets/i18n/nl.json5 @@ -5752,7 +5752,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Let op: bestanden in de collectie {{collectionName}} zullen niet alleen toegankelijk zijn volgens de expliciet toegekende rechten per bestand, maar ook volgens de volgende groep(en):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Hier vindt u alle bestanden van het item. U kunt de metadata en toegangsrechten bewerken of meer bestanden toevoegen door ze naar deze pagina te slepen.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index f68436d00b..7dca26aa4e 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -6066,7 +6066,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Por favor note que arquivos enviados a coleção {{collectionName}} serão acessíveis, de acordo com o que está explicitamente definido no arquivo, no(s) seguinte(s) grupo(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aqui vocẽ encontra todos os arquivos que estão atualmente no item. Você pode atualizar os metadados do arquivo e condições de acesso ou enviar arquivos adicionais apenas arrastando os arquivos em qualquer lugar da página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/pt-PT.json5 b/src/assets/i18n/pt-PT.json5 index b277e866c0..62e7c53e36 100644 --- a/src/assets/i18n/pt-PT.json5 +++ b/src/assets/i18n/pt-PT.json5 @@ -5117,7 +5117,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Por favor note que os ficheiros enviados à coleção {{collectionName}} serão acessíveis, de acordo com o que está explicitamente definido no ficheiro, no(s) seguinte(s) grupo(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aqui encontra todos os ficheiros que estão atualmente no item. Pode atualizar os metadados do ficheiro e condições de acesso ou carregar ficheiros adicionais arrastando os ficheiros em qualquer lugar desta página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/sv.json5 b/src/assets/i18n/sv.json5 index d04b95e144..4c9db83b16 100644 --- a/src/assets/i18n/sv.json5 +++ b/src/assets/i18n/sv.json5 @@ -5954,7 +5954,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Notera att uppladdade filer i samlingen {{collectionName}} också kommer att vara åtkompliga för följande grupp(er):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Här visas samtliga filer som ingår i posten. Du kan uppdatera filernas metadata och villkor för åtkomst, samt ladda upp nya filer genom att dra och släppa dem här", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/sw.json5 b/src/assets/i18n/sw.json5 index 5e00b54599..4f68655019 100644 --- a/src/assets/i18n/sw.json5 +++ b/src/assets/i18n/sw.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/tr.json5 b/src/assets/i18n/tr.json5 index fff02c5967..92e0c5b6e2 100644 --- a/src/assets/i18n/tr.json5 +++ b/src/assets/i18n/tr.json5 @@ -4905,7 +4905,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "{{collectionName}} koleksiyonuna yüklenen dosyalara, tek dosya için açıkça karar verilenlere ek olarak aşağıdaki gruplarla erişilebilir olacağını lütfen unutmayın:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Burada, o anda öğede bulunan tüm dosyaları bulacaksınız. Dosya metadatalarını güncelleyebilir ve koşullara erişebilir veya sayfanın her yerine sürükleyip bırakarak ek dosyalar yükleyebilirsiniz", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/uk.json5 b/src/assets/i18n/uk.json5 index 0ba5b0109a..6ee2bd9f1c 100644 --- a/src/assets/i18n/uk.json5 +++ b/src/assets/i18n/uk.json5 @@ -5225,7 +5225,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Зверніть увагу, що завантажені файли в {{collectionName}} зібрання будуть доступні, для користувачів, що входять у групу(и):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Тут ви знайдете всі файли, які зараз містяться в документі. Ви можете оновити метадані файлу та умови доступу або завантажити додаткові файли, просто перетягнувши їх сюди на сторінці", // "submission.sections.upload.no-entry": "No", From b676c1ab7967234392381d4362ac0137f2b3bb4c Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 15 Feb 2023 18:43:49 +0100 Subject: [PATCH 333/449] [CST-8935] Fix issue with missing matcher providers --- src/app/app.module.ts | 4 ++++ src/app/shared/form/form.module.ts | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 750d63beda..89e361821b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,6 +9,8 @@ import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router import { MetaReducer, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store'; import { TranslateModule } from '@ngx-translate/core'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; +import { DYNAMIC_MATCHER_PROVIDERS } from '@ng-dynamic-forms/core'; + import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { appEffects } from './app.effects'; @@ -101,6 +103,8 @@ const PROVIDERS = [ useClass: LogInterceptor, multi: true }, + // register the dynamic matcher used by form. MUST be provided by the app module + ...DYNAMIC_MATCHER_PROVIDERS, ]; const DECLARATIONS = [ diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index 61fc7e3c39..51ebaee1b8 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -21,7 +21,7 @@ import { DsDynamicLookupRelationExternalSourceTabComponent } from './builder/ds- import { SharedModule } from '../shared.module'; import { TranslateModule } from '@ngx-translate/core'; import { SearchModule } from '../search/search.module'; -import { DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_MATCHER_PROVIDERS, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; +import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { ExistingMetadataListElementComponent } from './builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component'; import { ExistingRelationListElementComponent } from './builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component'; import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; @@ -101,7 +101,6 @@ const DIRECTIVES = [ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn }, - ...DYNAMIC_MATCHER_PROVIDERS, VocabularyTreeviewService, DynamicFormLayoutService, DynamicFormService, From 938bf33ad24bc8d0545c8fc936bfc6bcaadf93d0 Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Wed, 15 Feb 2023 19:20:20 +0100 Subject: [PATCH 334/449] DS-8404 - fix config param name --- config/config.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.example.yml b/config/config.example.yml index 7c784b4a8e..f1e6be76aa 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -372,5 +372,5 @@ vocabularies: # Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. comcolSelectionSort: - sortMetadata: 'dc.title' + sortField: 'dc.title' sortDirection: 'ASC' \ No newline at end of file From 028d4192bb7e4f0f69f60b02b7912d5982b49de7 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 11:37:37 +0100 Subject: [PATCH 335/449] translation fixes in security form --- src/assets/i18n/de.json5 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 82d422621c..6c8eb4bc8f 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3838,17 +3838,17 @@ // "profile.security.form.error.matching-passwords": "The passwords do not match.", "profile.security.form.error.matching-passwords": "Die Passwörter stimmen nicht überein.", - // "profile.security.form.error.password-length": "The password should be at least 6 characters long.", - "profile.security.form.error.password-length": "Das Passwort sollte mindestens 6 Zeichen lang sein.", - // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "profile.security.form.info": "Optional können Sie ein neues Passwort in das Feld darunter eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", + "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", // "profile.security.form.label.password": "Password", "profile.security.form.label.password": "Passwort", // "profile.security.form.label.passwordrepeat": "Retype to confirm", - "profile.security.form.label.passwordrepeat": "Zum Bestätigen erneut eingeben", + "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", + + // "profile.security.form.label.current-password": "Current password" + "profile.security.form.label.current-password": "Ihr aktuelles Passwort" // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", "profile.security.form.notifications.success.content": "Ihr geändertes Passwort wurde gespeichert.", @@ -3862,8 +3862,14 @@ // "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", "profile.security.form.notifications.error.not-long-enough": "Das Passwort sollte mindestens 6 Zeichen lang sein.", + // "profile.security.form.notifications.error.change-failed": "An error occurred while trying to change the password. Please check if the current password is correct.", + "profile.security.form.notifications.error.change-failed": "Es ist ein Fehler beim Ändern des Passworts aufgetreten. Bitte überprüfen Sie, ob Ihr aktuelles Passwort korrekt eingegeben wurde.", + // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", "profile.security.form.notifications.error.not-same": "Die angegebenen Passwörter sind nicht identisch.", + + // "profile.security.form.notifications.error.general": "Please fill required fields of security form.", + "profile.security.form.notifications.error.general": "Bitte füllen Sie alle Pflichtfelder im Formular aus.", // "profile.title": "Update Profile", "profile.title": "Profil aktualisieren", From 3ed9ae2d3ea343767c362e223c4579cbc7bda419 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 12:14:42 +0100 Subject: [PATCH 336/449] remove minimum passwort length value from translated messages --- src/assets/i18n/de.json5 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 6c8eb4bc8f..e5d074d7f5 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -1982,8 +1982,8 @@ // "forgot-password.form.head": "Forgot Password", "forgot-password.form.head": "Passwort vergessen", - // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "forgot-password.form.info": "Bitte geben Sie ein neues Passwort (mindestens sechs Zeichen) ein und bestätigen Sie es erneut.", + // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box.", + "forgot-password.form.info": "Bitte geben Sie ein neues Passwort ein und bestätigen Sie es erneut.", // "forgot-password.form.card.security": "Security", "forgot-password.form.card.security": "Sicherheit", @@ -3838,8 +3838,8 @@ // "profile.security.form.error.matching-passwords": "The passwords do not match.", "profile.security.form.error.matching-passwords": "Die Passwörter stimmen nicht überein.", - // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", + // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box.", + "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen.", // "profile.security.form.label.password": "Password", "profile.security.form.label.password": "Passwort", @@ -3975,8 +3975,8 @@ // "register-page.create-profile.security.header": "Security", "register-page.create-profile.security.header": "Sicherheit", - // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "register-page.create-profile.security.info": "Bitte geben Sie ein Passwort in das unten stehende Feld ein und bestätigen Sie es, indem Sie es in das zweite Feld erneut eingeben. Es sollte mindestens sechs Zeichen lang sein.", + // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box.", + "register-page.create-profile.security.info": "Bitte geben Sie ein Passwort in das unten stehende Feld ein und bestätigen Sie es, indem Sie es in das zweite Feld erneut eingeben.", // "register-page.create-profile.security.label.password": "Password *", "register-page.create-profile.security.label.password": "Passwort *", From 26705a5cf75b4301991f1edbfa4994b4c55e3800 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 18:32:54 +0100 Subject: [PATCH 337/449] fixed missing comma --- src/assets/i18n/de.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index e5d074d7f5..9dbd703255 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3848,7 +3848,7 @@ "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", // "profile.security.form.label.current-password": "Current password" - "profile.security.form.label.current-password": "Ihr aktuelles Passwort" + "profile.security.form.label.current-password": "Ihr aktuelles Passwort", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", "profile.security.form.notifications.success.content": "Ihr geändertes Passwort wurde gespeichert.", From e5e6639d214adc7d5e52003577618a2cbf0d40c0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 18:34:02 +0100 Subject: [PATCH 338/449] added comma to default translation --- src/assets/i18n/de.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 9dbd703255..df4c2cb4ee 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3847,7 +3847,7 @@ // "profile.security.form.label.passwordrepeat": "Retype to confirm", "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", - // "profile.security.form.label.current-password": "Current password" + // "profile.security.form.label.current-password": "Current password", "profile.security.form.label.current-password": "Ihr aktuelles Passwort", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", From bf22eb5582e7ff76483a9d6d95b1061af1b2a41a Mon Sep 17 00:00:00 2001 From: cris Date: Wed, 15 Feb 2023 22:14:31 +0000 Subject: [PATCH 339/449] suggestionOption.name displayed --- .../dso-input-suggestions/dso-input-suggestions.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html index 7515b830b9..64c88bbd78 100644 --- a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html +++ b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html @@ -14,6 +14,7 @@