From b62a4f6c538077f37295ce9b131af1fc65aff20a Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Tue, 18 Oct 2022 12:58:49 +0200 Subject: [PATCH 01/24] [CST-6171] Navbar border --- src/app/navbar/navbar.component.scss | 2 +- src/themes/dspace/app/navbar/navbar.component.scss | 2 +- src/themes/dspace/styles/_theme_css_variable_overrides.scss | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/navbar/navbar.component.scss b/src/app/navbar/navbar.component.scss index 3a9a302b06..320ce414ec 100644 --- a/src/app/navbar/navbar.component.scss +++ b/src/app/navbar/navbar.component.scss @@ -1,5 +1,5 @@ nav.navbar { - border-bottom: 1px var(--bs-gray-400) solid; + border-bottom: 1px var(--ds-header-navbar-border-bottom-color) solid; align-items: baseline; } diff --git a/src/themes/dspace/app/navbar/navbar.component.scss b/src/themes/dspace/app/navbar/navbar.component.scss index 1ad95cb8aa..45d188a264 100644 --- a/src/themes/dspace/app/navbar/navbar.component.scss +++ b/src/themes/dspace/app/navbar/navbar.component.scss @@ -1,6 +1,6 @@ nav.navbar { border-top: 1px var(--ds-header-navbar-border-top-color) solid; - border-bottom: 5px var(--bs-green) solid; + border-bottom: 5px var(--ds-header-navbar-border-bottom-color) solid; align-items: baseline; color: var(--ds-header-icon-color); } diff --git a/src/themes/dspace/styles/_theme_css_variable_overrides.scss b/src/themes/dspace/styles/_theme_css_variable_overrides.scss index e4b4b61f45..516eff9f7e 100644 --- a/src/themes/dspace/styles/_theme_css_variable_overrides.scss +++ b/src/themes/dspace/styles/_theme_css_variable_overrides.scss @@ -6,5 +6,6 @@ --ds-banner-background-gradient-width: 300px; --ds-home-news-link-color: #{$green}; --ds-home-news-link-hover-color: #{darken($green, 15%)}; + --ds-header-navbar-border-bottom-color: #{$green}; } From a69f61e4f36730ec3204a8092259b07c659cd263 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Wed, 19 Oct 2022 00:58:59 +0200 Subject: [PATCH 02/24] [CST-6171] Item status type badge colors --- .../my-dspace-item-status.component.spec.ts | 10 ++++---- .../my-dspace-item-status.component.ts | 10 ++++---- src/styles/_global-styles.scss | 24 +++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts index 44e6a44b70..59fc29424d 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts @@ -55,34 +55,34 @@ describe('MyDSpaceItemStatusComponent', () => { component.status = MyDspaceItemStatusType.VALIDATION; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.VALIDATION); - expect(component.badgeClass).toBe('text-light badge badge-warning'); + expect(component.badgeClass).toBe('text-light badge badge-validation'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WAITING_CONTROLLER; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WAITING_CONTROLLER); - expect(component.badgeClass).toBe('text-light badge badge-info'); + expect(component.badgeClass).toBe('text-light badge badge-waiting-controller'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WORKSPACE; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKSPACE); - expect(component.badgeClass).toBe('text-light badge badge-primary'); + expect(component.badgeClass).toBe('text-light badge badge-workspace'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.ARCHIVED; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.ARCHIVED); - expect(component.badgeClass).toBe('text-light badge badge-success'); + expect(component.badgeClass).toBe('text-light badge badge-archived'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WORKFLOW; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKFLOW); - expect(component.badgeClass).toBe('text-light badge badge-info'); + expect(component.badgeClass).toBe('text-light badge badge-workflow'); }); }); diff --git a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts index 917dd45acc..83b2656fbd 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts @@ -34,19 +34,19 @@ export class MyDSpaceItemStatusComponent implements OnInit { this.badgeClass = 'text-light badge '; switch (this.status) { case MyDspaceItemStatusType.VALIDATION: - this.badgeClass += 'badge-warning'; + this.badgeClass += 'badge-validation'; break; case MyDspaceItemStatusType.WAITING_CONTROLLER: - this.badgeClass += 'badge-info'; + this.badgeClass += 'badge-waiting-controller'; break; case MyDspaceItemStatusType.WORKSPACE: - this.badgeClass += 'badge-primary'; + this.badgeClass += 'badge-workspace'; break; case MyDspaceItemStatusType.ARCHIVED: - this.badgeClass += 'badge-success'; + this.badgeClass += 'badge-archived'; break; case MyDspaceItemStatusType.WORKFLOW: - this.badgeClass += 'badge-info'; + this.badgeClass += 'badge-workflow'; break; } } diff --git a/src/styles/_global-styles.scss b/src/styles/_global-styles.scss index 930384cf64..1bc0c8c435 100644 --- a/src/styles/_global-styles.scss +++ b/src/styles/_global-styles.scss @@ -204,3 +204,27 @@ ds-dynamic-form-control-container.d-none { } + +.badge-validation { + background-color: #{map-get($theme-colors, warning)}; +} + +.badge-waiting-controller { + background-color: #{map-get($theme-colors, info)}; +} + +.badge-workspace { + background-color: #{map-get($theme-colors, primary)}; +} + +.badge-archived { + background-color: #{map-get($theme-colors, success)}; +} + +.badge-workflow { + background-color: #{map-get($theme-colors, info)}; +} + +.badge-item-type { + background-color: #{map-get($theme-colors, info)}; +} From f109e97a0ca61b8c4a520f6661d17f25b894b861 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Fri, 21 Oct 2022 12:50:59 +0200 Subject: [PATCH 03/24] [CST-6171] Semantic color scheme --- .../styles/_theme_sass_variable_overrides.scss | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/themes/dspace/styles/_theme_sass_variable_overrides.scss b/src/themes/dspace/styles/_theme_sass_variable_overrides.scss index 9257bc46dd..b5799c9749 100644 --- a/src/themes/dspace/styles/_theme_sass_variable_overrides.scss +++ b/src/themes/dspace/styles/_theme_sass_variable_overrides.scss @@ -10,7 +10,7 @@ $font-family-sans-serif: 'Nunito', -apple-system, BlinkMacSystemFont, "Segoe UI" $navbar-dark-color: #FFFFFF; /* Reassign color vars to semantic color scheme */ -$blue: #43515f !default; +$blue: #2b4e72 !default; $green: #92C642 !default; $cyan: #207698 !default; $yellow: #ec9433 !default; @@ -18,6 +18,7 @@ $red: #CF4444 !default; $dark: #43515f !default; $gray-800: #343a40 !default; +$gray-700: #495057 !default; $gray-400: #ced4da !default; $gray-100: #f8f9fa !default; @@ -27,3 +28,14 @@ $table-accent-bg: $gray-100 !default; // Bootstrap $gray-100 $table-hover-bg: $gray-400 !default; // Bootstrap $gray-400 $yiq-contrasted-threshold: 170 !default; + +$theme-colors: ( + primary: $dark, + secondary: $gray-700, + success: $green, + info: $cyan, + warning: $yellow, + danger: $red, + light: $gray-100, + dark: $dark +) !default; From e1753294d42e10550ae5c73f5f677a9e1e096c63 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Mon, 24 Oct 2022 17:48:31 +0200 Subject: [PATCH 04/24] 96121: Fix server side language headers --- src/app/core/locale/locale.service.ts | 2 +- src/app/core/locale/server-locale.service.ts | 27 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/app/core/locale/locale.service.ts b/src/app/core/locale/locale.service.ts index 1052021479..92d35c37d5 100644 --- a/src/app/core/locale/locale.service.ts +++ b/src/app/core/locale/locale.service.ts @@ -40,7 +40,7 @@ export class LocaleService { protected translate: TranslateService, protected authService: AuthService, protected routeService: RouteService, - @Inject(DOCUMENT) private document: any + @Inject(DOCUMENT) protected document: any ) { } diff --git a/src/app/core/locale/server-locale.service.ts b/src/app/core/locale/server-locale.service.ts index f438643e49..556619b946 100644 --- a/src/app/core/locale/server-locale.service.ts +++ b/src/app/core/locale/server-locale.service.ts @@ -1,12 +1,31 @@ import { LANG_ORIGIN, LocaleService } from './locale.service'; -import { Injectable } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { combineLatest, Observable, of as observableOf } from 'rxjs'; import { map, mergeMap, take } from 'rxjs/operators'; -import { isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { NativeWindowRef, NativeWindowService } from '../services/window.service'; +import { REQUEST } from '@nguniversal/express-engine/tokens'; +import { CookieService } from '../services/cookie.service'; +import { TranslateService } from '@ngx-translate/core'; +import { AuthService } from '../auth/auth.service'; +import { RouteService } from '../services/route.service'; +import { DOCUMENT } from '@angular/common'; @Injectable() export class ServerLocaleService extends LocaleService { + constructor( + @Inject(NativeWindowService) protected _window: NativeWindowRef, + @Inject(REQUEST) protected req: Request, + protected cookie: CookieService, + protected translate: TranslateService, + protected authService: AuthService, + protected routeService: RouteService, + @Inject(DOCUMENT) protected document: any + ) { + super(_window, cookie, translate, authService, routeService, document); + } + /** * Get the languages list of the user in Accept-Language format * @@ -50,6 +69,10 @@ export class ServerLocaleService extends LocaleService { if (isNotEmpty(epersonLang)) { languages.push(...epersonLang); } + if (hasValue(this.req.headers['accept-language'])) { + languages.push(...this.req.headers['accept-language'].split(',') + ); + } return languages; }) ); From 70fe46aeed4ea174e314251e91982e150000a30e Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 31 Oct 2022 16:34:25 +0100 Subject: [PATCH 05/24] 96062: Theme the CollectionDropdownComponent --- .../collection-selector.component.html | 4 +-- .../themed-collection-dropdown.component.ts | 33 +++++++++++++++++++ src/app/shared/shared.module.ts | 3 ++ .../submission-form-collection.component.html | 4 +-- ...-import-external-collection.component.html | 4 +-- .../collection-dropdown.component.html | 0 .../collection-dropdown.component.scss | 0 .../collection-dropdown.component.ts | 15 +++++++++ src/themes/custom/eager-theme.module.ts | 2 ++ 9 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 src/app/shared/collection-dropdown/themed-collection-dropdown.component.ts create mode 100644 src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.html create mode 100644 src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.scss create mode 100644 src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts diff --git a/src/app/my-dspace-page/collection-selector/collection-selector.component.html b/src/app/my-dspace-page/collection-selector/collection-selector.component.html index a87118fc4e..6e2a1925c5 100644 --- a/src/app/my-dspace-page/collection-selector/collection-selector.component.html +++ b/src/app/my-dspace-page/collection-selector/collection-selector.component.html @@ -5,7 +5,7 @@ diff --git a/src/app/shared/collection-dropdown/themed-collection-dropdown.component.ts b/src/app/shared/collection-dropdown/themed-collection-dropdown.component.ts new file mode 100644 index 0000000000..27c883099d --- /dev/null +++ b/src/app/shared/collection-dropdown/themed-collection-dropdown.component.ts @@ -0,0 +1,33 @@ +import { CollectionDropdownComponent, CollectionListEntry } from './collection-dropdown.component'; +import { ThemedComponent } from '../theme-support/themed.component'; +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'ds-themed-collection-dropdown', + styleUrls: [], + templateUrl: '../../shared/theme-support/themed.component.html', +}) +export class ThemedCollectionDropdownComponent extends ThemedComponent { + + @Input() entityType: string; + + @Output() searchComplete = new EventEmitter(); + + @Output() theOnlySelectable = new EventEmitter(); + + @Output() selectionChange = new EventEmitter(); + + protected inAndOutputNames: (keyof CollectionDropdownComponent & keyof this)[] = ['entityType', 'searchComplete', 'theOnlySelectable', 'selectionChange']; + + protected getComponentName(): string { + return 'CollectionDropdownComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/shared/collection-dropdown/collection-dropdown.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./collection-dropdown.component`); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index f723f081d3..02bccb2510 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -323,6 +323,7 @@ import { } from '../item-page/simple/field-components/specific-field/title/item-page-title-field.component'; import { MarkdownPipe } from './utils/markdown.pipe'; import { GoogleRecaptchaModule } from '../core/google-recaptcha/google-recaptcha.module'; +import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component'; const MODULES = [ CommonModule, @@ -480,6 +481,7 @@ const COMPONENTS = [ BitstreamDownloadPageComponent, BitstreamRequestACopyPageComponent, CollectionDropdownComponent, + ThemedCollectionDropdownComponent, EntityDropdownComponent, ExportMetadataSelectorComponent, ImportBatchSelectorComponent, @@ -558,6 +560,7 @@ const ENTRY_COMPONENTS = [ ClaimedTaskActionsReturnToPoolComponent, ClaimedTaskActionsEditMetadataComponent, CollectionDropdownComponent, + ThemedCollectionDropdownComponent, FileDownloadLinkComponent, BitstreamDownloadPageComponent, BitstreamRequestACopyPageComponent, diff --git a/src/app/submission/form/collection/submission-form-collection.component.html b/src/app/submission/form/collection/submission-form-collection.component.html index d897cc31fd..15b6ff280e 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.html +++ b/src/app/submission/form/collection/submission-form-collection.component.html @@ -35,9 +35,9 @@ class="dropdown-menu" id="collectionControlsDropdownMenu" aria-labelledby="collectionControlsMenuButton"> - - + diff --git a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.html b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.html index 29c99732c3..475f2a3b67 100644 --- a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.html +++ b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.html @@ -6,11 +6,11 @@ diff --git a/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.html b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.scss b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts new file mode 100644 index 0000000000..4fdbd9125b --- /dev/null +++ b/src/themes/custom/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -0,0 +1,15 @@ +import { + CollectionDropdownComponent as BaseComponent +} from '../../../../../app/shared/collection-dropdown/collection-dropdown.component'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-collection-dropdown', + templateUrl: '../../../../../app/shared/collection-dropdown/collection-dropdown.component.html', + // templateUrl: './collection-dropdown.component.html', + styleUrls: ['../../../../../app/shared/collection-dropdown/collection-dropdown.component.scss'] + // styleUrls: ['./collection-dropdown.component.scss'] +}) +export class CollectionDropdownComponent extends BaseComponent { + +} diff --git a/src/themes/custom/eager-theme.module.ts b/src/themes/custom/eager-theme.module.ts index 4e3c6f8b46..6bca518092 100644 --- a/src/themes/custom/eager-theme.module.ts +++ b/src/themes/custom/eager-theme.module.ts @@ -43,6 +43,7 @@ import { import { CommunityListElementComponent } from './app/shared/object-list/community-list-element/community-list-element.component'; import { CollectionListElementComponent} from './app/shared/object-list/collection-list-element/collection-list-element.component'; +import { CollectionDropdownComponent } from './app/shared/collection-dropdown/collection-dropdown.component'; /** @@ -58,6 +59,7 @@ const ENTRY_COMPONENTS = [ CommunityListElementComponent, CollectionListElementComponent, + CollectionDropdownComponent, ]; const DECLARATIONS = [ From 02499f8019f3d47849df7d3662d2899e772444d2 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 31 Oct 2022 19:42:07 +0100 Subject: [PATCH 06/24] 96062: Theme the ExternalSourceEntryImportModalComponent --- ...-relation-external-source-tab.component.ts | 2 +- ...nal-source-entry-import-modal.component.ts | 22 +++++++++++++++++++ src/app/shared/form/form.module.ts | 4 ++++ ...l-source-entry-import-modal.component.html | 0 ...l-source-entry-import-modal.component.scss | 0 ...nal-source-entry-import-modal.component.ts | 15 +++++++++++++ src/themes/custom/lazy-theme.module.ts | 4 ++++ 7 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component.ts create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.html create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.scss create mode 100644 src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts index e5ea98e537..0c41586eab 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component.ts @@ -15,7 +15,7 @@ import { fadeIn, fadeInOut } from '../../../../../animations/fade'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { RelationshipOptions } from '../../../models/relationship-options.model'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; -import { ExternalSourceEntryImportModalComponent } from './external-source-entry-import-modal/external-source-entry-import-modal.component'; +import { ThemedExternalSourceEntryImportModalComponent as ExternalSourceEntryImportModalComponent } from './external-source-entry-import-modal/themed-external-source-entry-import-modal.component'; import { hasValue } from '../../../../../empty.util'; import { SelectableListService } from '../../../../../object-list/selectable-list/selectable-list.service'; import { Item } from '../../../../../../core/shared/item.model'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component.ts new file mode 100644 index 0000000000..26e6097c2d --- /dev/null +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component.ts @@ -0,0 +1,22 @@ +import { ExternalSourceEntryImportModalComponent } from './external-source-entry-import-modal.component'; +import { ThemedComponent } from '../../../../../../theme-support/themed.component'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-themed-external-source-entry-import-modal', + styleUrls: [], + templateUrl: '../../../../../../../shared/theme-support/themed.component.html', +}) +export class ThemedExternalSourceEntryImportModalComponent extends ThemedComponent { + protected getComponentName(): string { + return 'ExternalSourceEntryImportModalComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../../../../../../themes/${themeName}/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./external-source-entry-import-modal.component`); + } +} diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index 62ab5bd647..741d51b616 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -30,6 +30,9 @@ 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 { + ThemedExternalSourceEntryImportModalComponent +} from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component'; const COMPONENTS = [ CustomSwitchComponent, @@ -53,6 +56,7 @@ const COMPONENTS = [ ExistingMetadataListElementComponent, ExistingRelationListElementComponent, ExternalSourceEntryImportModalComponent, + ThemedExternalSourceEntryImportModalComponent, FormComponent ]; diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.html b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.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/external-source-entry-import-modal/external-source-entry-import-modal.component.scss b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.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/external-source-entry-import-modal/external-source-entry-import-modal.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts new file mode 100644 index 0000000000..cd1de5d159 --- /dev/null +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts @@ -0,0 +1,15 @@ +import { + ExternalSourceEntryImportModalComponent as BaseComponent +} from '../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-external-source-entry-import-modal', + styleUrls: ['../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.scss'], + // styleUrls: ['./external-source-entry-import-modal.component.scss'], + templateUrl: '../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.html', + // templateUrl: './external-source-entry-import-modal.component.html' +}) +export class ExternalSourceEntryImportModalComponent extends BaseComponent { + +} diff --git a/src/themes/custom/lazy-theme.module.ts b/src/themes/custom/lazy-theme.module.ts index d2ac0ae787..2ff4af7946 100644 --- a/src/themes/custom/lazy-theme.module.ts +++ b/src/themes/custom/lazy-theme.module.ts @@ -114,6 +114,9 @@ import { ObjectListComponent } from './app/shared/object-list/object-list.compon import { BrowseByMetadataPageComponent } from './app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component'; import { BrowseByDatePageComponent } from './app/browse-by/browse-by-date-page/browse-by-date-page.component'; import { BrowseByTitlePageComponent } from './app/browse-by/browse-by-title-page/browse-by-title-page.component'; +import { + ExternalSourceEntryImportModalComponent +} from './app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; const DECLARATIONS = [ FileSectionComponent, @@ -168,6 +171,7 @@ const DECLARATIONS = [ BrowseByMetadataPageComponent, BrowseByDatePageComponent, BrowseByTitlePageComponent, + ExternalSourceEntryImportModalComponent, ]; From c6fd55baf49878f1e7deb9466505ec86542cf2c8 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 2 Nov 2022 12:55:21 +0100 Subject: [PATCH 07/24] 96062: Alter test to match themed component --- .../collection-selector.component.spec.ts | 7 +++++-- ...submission-import-external-collection.component.spec.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts index ce54d326fc..af043b447b 100644 --- a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts +++ b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts @@ -128,10 +128,13 @@ describe('CollectionSelectorComponent', () => { beforeEach(() => { scheduler = getTestScheduler(); - fixture = TestBed.createComponent(CollectionSelectorComponent); + fixture = TestBed.overrideComponent(CollectionSelectorComponent, { + set: { + template: '' + } + }).createComponent(CollectionSelectorComponent); component = fixture.componentInstance; fixture.detectChanges(); - }); it('should create', () => { diff --git a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts index 4f3c54b642..9edab06c6f 100644 --- a/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts +++ b/src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.spec.ts @@ -122,7 +122,7 @@ describe('SubmissionImportExternalCollectionComponent test suite', () => { fixture.detectChanges(); fixture.whenStable().then(() => { - const dropdownMenu = fixture.debugElement.query(By.css('ds-collection-dropdown')).nativeElement; + const dropdownMenu = fixture.debugElement.query(By.css('ds-themed-collection-dropdown')).nativeElement; expect(dropdownMenu.classList).toContain('d-none'); }); })); From 9e843e36fa53c4290459c110a31be884b8867e24 Mon Sep 17 00:00:00 2001 From: Vincenzo Mecca Date: Fri, 4 Nov 2022 10:43:16 +0100 Subject: [PATCH 08/24] [1950] [DURACOM-101] Regex validator improved feat: - New regexp to validate pattern used for regex validation; --- .../form/builder/parsers/field-parser.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index 86a7d99e41..e2a907056e 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -1,7 +1,7 @@ -import {Inject, InjectionToken} from '@angular/core'; +import { Inject, InjectionToken } from '@angular/core'; -import uniqueId from 'lodash/uniqueId'; -import {DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR} from '@ng-dynamic-forms/core'; +import { uniqueId } from 'lodash'; +import { DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR } from '@ng-dynamic-forms/core'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util'; import { FormFieldModel } from '../models/form-field.model'; @@ -22,6 +22,7 @@ export const SUBMISSION_ID: InjectionToken = new InjectionToken( export const CONFIG_DATA: InjectionToken = new InjectionToken('configData'); export const INIT_FORM_VALUES: InjectionToken = new InjectionToken('initFormValues'); export const PARSER_OPTIONS: InjectionToken = new InjectionToken('parserOptions'); +export const REGEX_FIELD_VALIDATOR: RegExp = new RegExp('(\\/?)(.+)\\1([gimsuy]*)', 'i'); export abstract class FieldParser { @@ -43,7 +44,7 @@ export abstract class FieldParser { public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any; public parse() { - if (((this.getInitValueCount() > 1 && !this.configData.repeatable) || (this.configData.repeatable)) + if (((this.getInitValueCount() > 1 && !this.configData.repeatable) || (this.configData.repeatable)) && (this.configData.input.type !== ParserType.List) && (this.configData.input.type !== ParserType.Tag) ) { @@ -315,6 +316,7 @@ export abstract class FieldParser { * fields in type bind, made up of a 'match' outcome (make this field visible), an 'operator' * (OR) and a 'when' condition (the bindValues array). * @param configuredTypeBindValues array of types from the submission definition (CONFIG_DATA) + * @param typeField * @private * @return DynamicFormControlRelation[] array with one relation in it, for type bind matching to show a field */ @@ -344,7 +346,13 @@ export abstract class FieldParser { } protected addPatternValidator(controlModel) { - const regex = new RegExp(this.configData.input.regex); + const validatorMatcher = this.configData.input.regex.match(REGEX_FIELD_VALIDATOR); + let regex; + if (validatorMatcher != null && validatorMatcher.length > 3) { + regex = new RegExp(validatorMatcher[2], validatorMatcher[3]); + } else { + regex = new RegExp(this.configData.input.regex); + } controlModel.validators = Object.assign({}, controlModel.validators, { pattern: regex }); controlModel.errorMessages = Object.assign( {}, From 6e2279d155975700b442839d59aee6cd89d8fb3a Mon Sep 17 00:00:00 2001 From: Vincenzo Mecca Date: Mon, 28 Nov 2022 11:25:50 +0100 Subject: [PATCH 09/24] [1950][DURACOM-101] Fixed linting --- src/app/shared/form/builder/parsers/field-parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index e2a907056e..d446877897 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -1,6 +1,6 @@ import { Inject, InjectionToken } from '@angular/core'; -import { uniqueId } from 'lodash'; +import uniqueId from 'lodash/uniqueId'; import { DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR } from '@ng-dynamic-forms/core'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util'; @@ -22,7 +22,7 @@ export const SUBMISSION_ID: InjectionToken = new InjectionToken( export const CONFIG_DATA: InjectionToken = new InjectionToken('configData'); export const INIT_FORM_VALUES: InjectionToken = new InjectionToken('initFormValues'); export const PARSER_OPTIONS: InjectionToken = new InjectionToken('parserOptions'); -export const REGEX_FIELD_VALIDATOR: RegExp = new RegExp('(\\/?)(.+)\\1([gimsuy]*)', 'i'); +export const REGEX_FIELD_VALIDATOR = new RegExp('(\\/?)(.+)\\1([gimsuy]*)', 'i'); export abstract class FieldParser { From 422d72e00102d06e37815262a86c9da3a93dbb26 Mon Sep 17 00:00:00 2001 From: Michael Spalti Date: Sat, 3 Dec 2022 13:36:52 -0800 Subject: [PATCH 10/24] Fix for related item thumbnail images. --- ...ynamic-form-control-container.component.ts | 20 ++++++++++++++----- ...sting-relation-list-element.component.html | 4 ++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts index 812735e69c..77ce65675a 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts @@ -4,7 +4,7 @@ import { Component, ComponentFactoryResolver, ContentChildren, - EventEmitter, + EventEmitter, Inject, Input, NgZone, OnChanges, @@ -118,6 +118,8 @@ import { RelationshipOptions } from '../models/relationship-options.model'; import { FormBuilderService } from '../form-builder.service'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; +import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interface'; +import { itemLinksToFollow } from '../../../utils/relation-query.utils'; export function dsDynamicFormControlMapFn(model: DynamicFormControlModel): Type | null { switch (model.type) { @@ -231,6 +233,11 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo private showErrorMessagesPreviousStage: boolean; + /** + * Determines whether to request embedded thumbnail. + */ + fetchThumbnail: boolean; + get componentType(): Type | null { return dsDynamicFormControlMapFn(this.model); } @@ -253,9 +260,11 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo private ref: ChangeDetectorRef, private formService: FormService, private formBuilderService: FormBuilderService, - private submissionService: SubmissionService + private submissionService: SubmissionService, + @Inject(APP_CONFIG) protected appConfig: AppConfig, ) { super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService); + this.fetchThumbnail = this.appConfig.browseBy.showThumbnails; } /** @@ -285,7 +294,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo followLink('rightItem'), followLink('relationshipType') ); - relationshipsRD$.pipe( getFirstSucceededRemoteDataPayload(), getPaginatedListPayload() @@ -317,8 +325,10 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo } if (hasValue(this.value) && this.value.isVirtual) { - const relationship$ = this.relationshipService.findById(this.value.virtualValue, true, true, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')) - .pipe( + const relationship$ = this.relationshipService.findById(this.value.virtualValue, + true, + true, + ... itemLinksToFollow(this.fetchThumbnail)).pipe( getAllSucceededRemoteData(), getRemoteDataPayload()); this.relationshipValue$ = observableCombineLatest([this.item$.pipe(take(1)), relationship$]).pipe( diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html index ff91b18e1c..dddbfb2e9c 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html @@ -1,12 +1,12 @@
- +
- +