Merge remote-tracking branch 'origin/main' into CST-6035_external-provider-query-error

This commit is contained in:
corrad82
2022-08-30 11:41:04 +02:00
25 changed files with 8274 additions and 61 deletions

View File

@@ -179,7 +179,7 @@ If needing to update default configurations values for production, update local
- Update `environment.production.ts` file in `src/environment/` for a `production` environment; - Update `environment.production.ts` file in `src/environment/` for a `production` environment;
The environment object is provided for use as import in code and is extended with he runtime configuration on bootstrap of the application. The environment object is provided for use as import in code and is extended with the runtime configuration on bootstrap of the application.
> Take caution moving runtime configs into the buildtime configuration. They will be overwritten by what is defined in the runtime config on bootstrap. > Take caution moving runtime configs into the buildtime configuration. They will be overwritten by what is defined in the runtime config on bootstrap.

View File

@@ -150,6 +150,9 @@ languages:
- code: fi - code: fi
label: Suomi label: Suomi
active: true active: true
- code: sv
label: Svenska
active: true
- code: tr - code: tr
label: Türkçe label: Türkçe
active: true active: true

View File

@@ -18,6 +18,8 @@ import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse-
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
export const BBM_PAGINATION_ID = 'bbm';
@Component({ @Component({
selector: 'ds-browse-by-metadata-page', selector: 'ds-browse-by-metadata-page',
styleUrls: ['./browse-by-metadata-page.component.scss'], styleUrls: ['./browse-by-metadata-page.component.scss'],
@@ -50,7 +52,7 @@ export class BrowseByMetadataPageComponent implements OnInit {
* The pagination config used to display the values * The pagination config used to display the values
*/ */
paginationConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), { paginationConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'bbm', id: BBM_PAGINATION_ID,
currentPage: 1, currentPage: 1,
pageSize: 20 pageSize: 20
}); });

View File

@@ -19,7 +19,7 @@ export abstract class SomeFeatureAuthorizationGuard implements CanActivate {
/** /**
* True when user has authorization rights for the feature and object provided * True when user has authorization rights for the feature and object provided
* Redirect the user to the unauthorized page when he/she's not authorized for the given feature * Redirect the user to the unauthorized page when they are not authorized for the given feature
*/ */
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return observableCombineLatest(this.getFeatureIDs(route, state), this.getObjectUrl(route, state), this.getEPersonUuid(route, state)).pipe( return observableCombineLatest(this.getFeatureIDs(route, state), this.getObjectUrl(route, state), this.getEPersonUuid(route, state)).pipe(

View File

@@ -38,7 +38,7 @@ export class ProcessDataService extends DataService<Process> {
} }
/** /**
* Get the endpoint for a process his files * Get the endpoint for the files of the process
* @param processId The ID of the process * @param processId The ID of the process
*/ */
getFilesEndpoint(processId: string): Observable<string> { getFilesEndpoint(processId: string): Observable<string> {

View File

@@ -55,7 +55,7 @@ export class EndUserAgreementService {
/** /**
* Set the current user's accepted agreement status * Set the current user's accepted agreement status
* When a user is authenticated, set his/her metadata to the provided value * When a user is authenticated, set their metadata to the provided value
* When no user is authenticated, set the cookie to the provided value * When no user is authenticated, set the cookie to the provided value
* @param accepted * @param accepted
*/ */

View File

@@ -39,7 +39,7 @@ export class MetadataValue implements MetadataValueInterface {
value: string; value: string;
/** /**
* The place of this MetadataValue within his list of metadata * The place of this MetadataValue within its list of metadata
* This is used to render metadata in a specific custom order * This is used to render metadata in a specific custom order
*/ */
@autoserialize @autoserialize
@@ -105,7 +105,7 @@ export class MetadatumViewModel {
value: string; value: string;
/** /**
* The place of this MetadataValue within his list of metadata * The place of this MetadataValue within its list of metadata
* This is used to render metadata in a specific custom order * This is used to render metadata in a specific custom order
*/ */
place: number; place: number;

View File

@@ -16,7 +16,7 @@ export class HealthStatusComponent {
@Input() status: HealthStatus; @Input() status: HealthStatus;
/** /**
* He * Health Status
*/ */
HealthStatus = HealthStatus; HealthStatus = HealthStatus;

View File

@@ -76,7 +76,7 @@ export class EndUserAgreementComponent implements OnInit {
/** /**
* Cancel the agreement * Cancel the agreement
* If the user is logged in, this will log him/her out * If the user is logged in, this will log them out
* If the user is not logged in, they will be redirected to the homepage * If the user is not logged in, they will be redirected to the homepage
*/ */
cancel() { cancel() {

View File

@@ -24,7 +24,7 @@ import { ConfirmationModalComponent } from '../../shared/confirmation-modal/conf
templateUrl: './profile-page-researcher-form.component.html', templateUrl: './profile-page-researcher-form.component.html',
}) })
/** /**
* Component for a user to create/delete or change his researcher profile. * Component for a user to create/delete or change their researcher profile.
*/ */
export class ProfilePageResearcherFormComponent implements OnInit { export class ProfilePageResearcherFormComponent implements OnInit {

View File

@@ -240,10 +240,12 @@ describe('BrowseByComponent', () => {
}); });
describe('back', () => { describe('back', () => {
it('should navigate back to the main browse page', () => { it('should navigate back to the main browse page', () => {
const id = 'test-pagination';
comp.back(); comp.back();
expect(paginationService.updateRoute).toHaveBeenCalledWith('test-pagination', {page: 1}, { expect(paginationService.updateRoute).toHaveBeenCalledWith(id, {page: 1}, {
value: null, value: null,
startsWith: null startsWith: null,
[id + '.return']: null
}); });
}); });
}); });

View File

@@ -1,10 +1,10 @@
import { Component, EventEmitter, Injector, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list.model'; import { PaginatedList } from '../../core/data/paginated-list.model';
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { fadeIn, fadeInOut } from '../animations/fade'; import { fadeIn, fadeInOut } from '../animations/fade';
import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
import { ListableObject } from '../object-collection/shared/listable-object.model'; import { ListableObject } from '../object-collection/shared/listable-object.model';
import { getStartsWithComponent, StartsWithType } from '../starts-with/starts-with-decorator'; import { getStartsWithComponent, StartsWithType } from '../starts-with/starts-with-decorator';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
@@ -25,7 +25,7 @@ import { hasValue } from '../empty.util';
/** /**
* Component to display a browse-by page for any ListableObject * Component to display a browse-by page for any ListableObject
*/ */
export class BrowseByComponent implements OnInit { export class BrowseByComponent implements OnInit, OnDestroy {
/** /**
* ViewMode that should be passed to {@link ListableObjectComponentLoaderComponent}. * ViewMode that should be passed to {@link ListableObjectComponentLoaderComponent}.
@@ -112,6 +112,16 @@ export class BrowseByComponent implements OnInit {
*/ */
shouldDisplayResetButton$: Observable<boolean>; shouldDisplayResetButton$: Observable<boolean>;
/**
* Page number of the previous page
*/
previousPage$ = new BehaviorSubject<string>('1');
/**
* Subscription that has to be unsubscribed from on destroy
*/
sub: Subscription;
public constructor(private injector: Injector, public constructor(private injector: Injector,
protected paginationService: PaginationService, protected paginationService: PaginationService,
private routeService: RouteService, private routeService: RouteService,
@@ -171,9 +181,20 @@ export class BrowseByComponent implements OnInit {
this.shouldDisplayResetButton$ = observableCombineLatest([startsWith$, value$]).pipe( this.shouldDisplayResetButton$ = observableCombineLatest([startsWith$, value$]).pipe(
map(([startsWith, value]) => hasValue(startsWith) || hasValue(value)) map(([startsWith, value]) => hasValue(startsWith) || hasValue(value))
); );
this.sub = this.routeService.getQueryParameterValue(this.paginationConfig.id + '.return').subscribe(this.previousPage$);
} }
/**
* Navigate back to the previous browse by page
*/
back() { back() {
this.paginationService.updateRoute(this.paginationConfig.id, {page: 1}, {value: null, startsWith: null}); const page = +this.previousPage$.value > 1 ? +this.previousPage$.value : 1;
this.paginationService.updateRoute(this.paginationConfig.id, {page: page}, {[this.paginationConfig.id + '.return']: null, value: null, startsWith: null});
}
ngOnDestroy(): void {
if (this.sub) {
this.sub.unsubscribe();
}
} }
} }

View File

@@ -24,7 +24,7 @@ export const klaroConfiguration: any = {
/* /*
Setting 'hideLearnMore' to 'true' will hide the "learn more / customize" link in Setting 'hideLearnMore' to 'true' will hide the "learn more / customize" link in
the consent notice. We strongly advise against using this under most the consent notice. We strongly advise against using this under most
circumstances, as it keeps the user from customizing his/her consent choices. circumstances, as it keeps the user from customizing their consent choices.
*/ */
hideLearnMore: false, hideLearnMore: false,

View File

@@ -20,6 +20,7 @@ import {
createSuccessfulRemoteDataObject$ createSuccessfulRemoteDataObject$
} from '../../../remote-data.utils'; } from '../../../remote-data.utils';
import { ExportMetadataSelectorComponent } from './export-metadata-selector.component'; import { ExportMetadataSelectorComponent } from './export-metadata-selector.component';
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
// No way to add entryComponents yet to testbed; alternative implemented; source: https://stackoverflow.com/questions/41689468/how-to-shallow-test-a-component-with-an-entrycomponents // No way to add entryComponents yet to testbed; alternative implemented; source: https://stackoverflow.com/questions/41689468/how-to-shallow-test-a-component-with-an-entrycomponents
@NgModule({ @NgModule({
@@ -47,6 +48,7 @@ describe('ExportMetadataSelectorComponent', () => {
let router; let router;
let notificationService: NotificationsServiceStub; let notificationService: NotificationsServiceStub;
let scriptService; let scriptService;
let authorizationDataService;
const mockItem = Object.assign(new Item(), { const mockItem = Object.assign(new Item(), {
id: 'fake-id', id: 'fake-id',
@@ -95,6 +97,9 @@ describe('ExportMetadataSelectorComponent', () => {
invoke: createSuccessfulRemoteDataObject$({ processId: '45' }) invoke: createSuccessfulRemoteDataObject$({ processId: '45' })
} }
); );
authorizationDataService = jasmine.createSpyObj('authorizationDataService', {
isAuthorized: observableOf(true)
});
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), ModelTestModule], imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), ModelTestModule],
declarations: [ExportMetadataSelectorComponent], declarations: [ExportMetadataSelectorComponent],
@@ -102,6 +107,7 @@ describe('ExportMetadataSelectorComponent', () => {
{ provide: NgbActiveModal, useValue: modalStub }, { provide: NgbActiveModal, useValue: modalStub },
{ provide: NotificationsService, useValue: notificationService }, { provide: NotificationsService, useValue: notificationService },
{ provide: ScriptDataService, useValue: scriptService }, { provide: ScriptDataService, useValue: scriptService },
{ provide: AuthorizationDataService, useValue: authorizationDataService },
{ {
provide: ActivatedRoute, provide: ActivatedRoute,
useValue: { useValue: {
@@ -150,7 +156,7 @@ describe('ExportMetadataSelectorComponent', () => {
}); });
}); });
describe('if collection is selected', () => { describe('if collection is selected and is admin', () => {
let scriptRequestSucceeded; let scriptRequestSucceeded;
beforeEach((done) => { beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef); spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
@@ -159,7 +165,32 @@ describe('ExportMetadataSelectorComponent', () => {
done(); done();
}); });
}); });
it('should invoke the metadata-export script with option -i uuid', () => { it('should invoke the metadata-export script with option -i uuid and -a option', () => {
const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: mockCollection.uuid }),
Object.assign(new ProcessParameter(), { name: '-a' }),
];
expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []);
});
it('success notification is shown', () => {
expect(scriptRequestSucceeded).toBeTrue();
expect(notificationService.success).toHaveBeenCalled();
});
it('redirected to process page', () => {
expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/45');
});
});
describe('if collection is selected and is not admin', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
(authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false));
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
component.navigate(mockCollection).subscribe((succeeded: boolean) => {
scriptRequestSucceeded = succeeded;
done();
});
});
it('should invoke the metadata-export script with option -i uuid without the -a option', () => {
const parameterValues: ProcessParameter[] = [ const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: mockCollection.uuid }), Object.assign(new ProcessParameter(), { name: '-i', value: mockCollection.uuid }),
]; ];
@@ -174,7 +205,7 @@ describe('ExportMetadataSelectorComponent', () => {
}); });
}); });
describe('if community is selected', () => { describe('if community is selected and is an admin', () => {
let scriptRequestSucceeded; let scriptRequestSucceeded;
beforeEach((done) => { beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef); spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
@@ -183,7 +214,32 @@ describe('ExportMetadataSelectorComponent', () => {
done(); done();
}); });
}); });
it('should invoke the metadata-export script with option -i uuid', () => { it('should invoke the metadata-export script with option -i uuid and -a option if the user is an admin', () => {
const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: mockCommunity.uuid }),
Object.assign(new ProcessParameter(), { name: '-a' }),
];
expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []);
});
it('success notification is shown', () => {
expect(scriptRequestSucceeded).toBeTrue();
expect(notificationService.success).toHaveBeenCalled();
});
it('redirected to process page', () => {
expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/45');
});
});
describe('if community is selected and is not an admin', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
(authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false));
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
component.navigate(mockCommunity).subscribe((succeeded: boolean) => {
scriptRequestSucceeded = succeeded;
done();
});
});
it('should invoke the metadata-export script with option -i uuid without the -a option', () => {
const parameterValues: ProcessParameter[] = [ const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: mockCommunity.uuid }), Object.assign(new ProcessParameter(), { name: '-i', value: mockCommunity.uuid }),
]; ];

View File

@@ -19,6 +19,8 @@ import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
import { Process } from '../../../../process-page/processes/process.model'; import { Process } from '../../../../process-page/processes/process.model';
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { getProcessDetailRoute } from '../../../../process-page/process-page-routing.paths'; import { getProcessDetailRoute } from '../../../../process-page/process-page-routing.paths';
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../../core/data/feature-authorization/feature-id';
/** /**
* Component to wrap a list of existing dso's inside a modal * Component to wrap a list of existing dso's inside a modal
@@ -36,6 +38,7 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router, constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router,
protected notificationsService: NotificationsService, protected translationService: TranslateService, protected notificationsService: NotificationsService, protected translationService: TranslateService,
protected scriptDataService: ScriptDataService, protected scriptDataService: ScriptDataService,
protected authorizationDataService: AuthorizationDataService,
private modalService: NgbModal) { private modalService: NgbModal) {
super(activeModal, route); super(activeModal, route);
} }
@@ -82,24 +85,29 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp
const parameterValues: ProcessParameter[] = [ const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: dso.uuid }), Object.assign(new ProcessParameter(), { name: '-i', value: dso.uuid }),
]; ];
return this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []) return this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf).pipe(
.pipe( switchMap((isAdmin) => {
getFirstCompletedRemoteData(), if (isAdmin) {
map((rd: RemoteData<Process>) => { parameterValues.push(Object.assign(new ProcessParameter(), {name: '-a'}));
if (rd.hasSucceeded) { }
const title = this.translationService.get('process.new.notification.success.title'); return this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []);
const content = this.translationService.get('process.new.notification.success.content'); }),
this.notificationsService.success(title, content); getFirstCompletedRemoteData(),
if (isNotEmpty(rd.payload)) { map((rd: RemoteData<Process>) => {
this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId)); if (rd.hasSucceeded) {
} const title = this.translationService.get('process.new.notification.success.title');
return true; const content = this.translationService.get('process.new.notification.success.content');
} else { this.notificationsService.success(title, content);
const title = this.translationService.get('process.new.notification.error.title'); if (isNotEmpty(rd.payload)) {
const content = this.translationService.get('process.new.notification.error.content'); this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
this.notificationsService.error(title, content);
return false;
} }
})); return true;
} else {
const title = this.translationService.get('process.new.notification.error.title');
const content = this.translationService.get('process.new.notification.error.content');
this.notificationsService.error(title, content);
return false;
}
}));
} }
} }

View File

@@ -1,5 +1,5 @@
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="[]" [queryParams]="getQueryParams()" [queryParamsHandling]="'merge'" class="lead"> <a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="[]" [queryParams]="queryParams$ | async" [queryParamsHandling]="'merge'" class="lead">
{{object.value}} {{object.value}}
</a> </a>
<span *ngIf="linkType == linkTypes.None" class="lead"> <span *ngIf="linkType == linkTypes.None" class="lead">

View File

@@ -4,7 +4,9 @@ import { By } from '@angular/platform-browser';
import { TruncatePipe } from '../../utils/truncate.pipe'; import { TruncatePipe } from '../../utils/truncate.pipe';
import { BrowseEntryListElementComponent } from './browse-entry-list-element.component'; import { BrowseEntryListElementComponent } from './browse-entry-list-element.component';
import { BrowseEntry } from '../../../core/shared/browse-entry.model'; import { BrowseEntry } from '../../../core/shared/browse-entry.model';
import { PaginationService } from '../../../core/pagination/pagination.service';
import { RouteService } from '../../../core/services/route.service';
import { of as observableOf } from 'rxjs';
let browseEntryListElementComponent: BrowseEntryListElementComponent; let browseEntryListElementComponent: BrowseEntryListElementComponent;
let fixture: ComponentFixture<BrowseEntryListElementComponent>; let fixture: ComponentFixture<BrowseEntryListElementComponent>;
@@ -13,12 +15,28 @@ const mockValue: BrowseEntry = Object.assign(new BrowseEntry(), {
value: 'De Langhe Kristof' value: 'De Langhe Kristof'
}); });
describe('MetadataListElementComponent', () => { let paginationService;
let routeService;
const pageParam = 'bbm.page';
function init() {
paginationService = jasmine.createSpyObj('paginationService', {
getPageParam: pageParam
});
routeService = jasmine.createSpyObj('routeService', {
getQueryParameterValue: observableOf('1')
});
}
describe('BrowseEntryListElementComponent', () => {
beforeEach(waitForAsync(() => { beforeEach(waitForAsync(() => {
init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [BrowseEntryListElementComponent, TruncatePipe], declarations: [BrowseEntryListElementComponent, TruncatePipe],
providers: [ providers: [
{ provide: 'objectElementProvider', useValue: { mockValue } } { provide: 'objectElementProvider', useValue: { mockValue } },
{provide: PaginationService, useValue: paginationService},
{provide: RouteService, useValue: routeService},
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]

View File

@@ -1,9 +1,15 @@
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component'; import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component';
import { BrowseEntry } from '../../../core/shared/browse-entry.model'; import { BrowseEntry } from '../../../core/shared/browse-entry.model';
import { ViewMode } from '../../../core/shared/view-mode.model'; import { ViewMode } from '../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../object-collection/shared/listable-object/listable-object.decorator'; import { listableObjectComponent } from '../../object-collection/shared/listable-object/listable-object.decorator';
import { PaginationService } from '../../../core/pagination/pagination.service';
import { Params } from '@angular/router';
import { BBM_PAGINATION_ID } from '../../../browse-by/browse-by-metadata-page/browse-by-metadata-page.component';
import { RouteService } from 'src/app/core/services/route.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({ @Component({
selector: 'ds-browse-entry-list-element', selector: 'ds-browse-entry-list-element',
@@ -15,16 +21,35 @@ import { listableObjectComponent } from '../../object-collection/shared/listable
* This component is automatically used to create a list view for BrowseEntry objects when used in ObjectCollectionComponent * This component is automatically used to create a list view for BrowseEntry objects when used in ObjectCollectionComponent
*/ */
@listableObjectComponent(BrowseEntry, ViewMode.ListElement) @listableObjectComponent(BrowseEntry, ViewMode.ListElement)
export class BrowseEntryListElementComponent extends AbstractListableElementComponent<BrowseEntry> { export class BrowseEntryListElementComponent extends AbstractListableElementComponent<BrowseEntry> implements OnInit {
/**
* Emits the query parameters for the link of this browse entry list element
*/
queryParams$: Observable<Params>;
constructor(private paginationService: PaginationService, private routeService: RouteService) {
super();
}
ngOnInit() {
this.queryParams$ = this.getQueryParams();
}
/** /**
* Get the query params to access the item page of this browse entry. * Get the query params to access the item page of this browse entry.
*/ */
public getQueryParams(): {[param: string]: any} { private getQueryParams(): Observable<Params> {
return { const pageParamName = this.paginationService.getPageParam(BBM_PAGINATION_ID);
value: this.object.value, return this.routeService.getQueryParameterValue(pageParamName).pipe(
authority: !!this.object.authority ? this.object.authority : undefined, map((currentPage) => {
startsWith: undefined, return {
}; value: this.object.value,
authority: !!this.object.authority ? this.object.authority : undefined,
startsWith: undefined,
[pageParamName]: null,
[BBM_PAGINATION_ID + '.return']: currentPage
};
})
);
} }
} }

View File

@@ -12,7 +12,7 @@ import { metadataRepresentationComponent } from '../../../metadata-representatio
/** /**
* A component for displaying MetadataRepresentation objects in the form of items * A component for displaying MetadataRepresentation objects in the form of items
* It will send the MetadataRepresentation object along with ElementViewMode.SetElement to the ItemTypeSwitcherComponent, * It will send the MetadataRepresentation object along with ElementViewMode.SetElement to the ItemTypeSwitcherComponent,
* which will in his turn decide how to render the item as metadata. * which will in its turn decide how to render the item as metadata.
*/ */
export class ItemMetadataListElementComponent extends MetadataRepresentationListElementComponent { export class ItemMetadataListElementComponent extends MetadataRepresentationListElementComponent {
/** /**

8078
src/assets/i18n/sv.json5 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -193,6 +193,7 @@ export class DefaultAppConfig implements AppConfig {
{ code: 'pt-PT', label: 'Português', active: true }, { code: 'pt-PT', label: 'Português', active: true },
{ code: 'pt-BR', label: 'Português do Brasil', active: true }, { code: 'pt-BR', label: 'Português do Brasil', active: true },
{ code: 'fi', label: 'Suomi', active: true }, { code: 'fi', label: 'Suomi', active: true },
{ code: 'sv', label: 'Svenska', active: true },
{ code: 'tr', label: 'Türkçe', active: true }, { code: 'tr', label: 'Türkçe', active: true },
{ code: 'bn', label: 'বাংলা', active: true } { code: 'bn', label: 'বাংলা', active: true }
]; ];

5
src/styles/_vendor.scss Normal file
View File

@@ -0,0 +1,5 @@
// node_modules imports meant for all the themes
@import '~node_modules/bootstrap/scss/bootstrap.scss';
@import '~node_modules/nouislider/distribute/nouislider.min';
@import '~node_modules/ngx-ui-switch/ui-switch.component.scss';

View File

@@ -1,8 +1,6 @@
@import './helpers/font_awesome_imports.scss'; @import './helpers/font_awesome_imports.scss';
@import '../../node_modules/bootstrap/scss/bootstrap.scss'; @import './_vendor.scss';
@import '../../node_modules/nouislider/distribute/nouislider.min';
@import './_custom_variables.scss'; @import './_custom_variables.scss';
@import './bootstrap_variables_mapping.scss'; @import './bootstrap_variables_mapping.scss';
@import './_truncatable-part.component.scss'; @import './_truncatable-part.component.scss';
@import './_global-styles.scss'; @import './_global-styles.scss';
@import '../../node_modules/ngx-ui-switch/ui-switch.component.scss';

View File

@@ -4,11 +4,9 @@
@import '../../../styles/_variables.scss'; @import '../../../styles/_variables.scss';
@import '../../../styles/_mixins.scss'; @import '../../../styles/_mixins.scss';
@import '../../../styles/helpers/font_awesome_imports.scss'; @import '../../../styles/helpers/font_awesome_imports.scss';
@import '../../../../node_modules/bootstrap/scss/bootstrap.scss'; @import '../../../styles/_vendor.scss';
@import '../../../../node_modules/nouislider/distribute/nouislider.min';
@import '../../../styles/_custom_variables.scss'; @import '../../../styles/_custom_variables.scss';
@import './_theme_css_variable_overrides.scss'; @import './_theme_css_variable_overrides.scss';
@import '../../../styles/bootstrap_variables_mapping.scss'; @import '../../../styles/bootstrap_variables_mapping.scss';
@import '../../../styles/_truncatable-part.component.scss'; @import '../../../styles/_truncatable-part.component.scss';
@import './_global-styles.scss'; @import './_global-styles.scss';
@import '../../../../node_modules/ngx-ui-switch/ui-switch.component.scss';

View File

@@ -4,11 +4,9 @@
@import '../../../styles/_variables.scss'; @import '../../../styles/_variables.scss';
@import '../../../styles/_mixins.scss'; @import '../../../styles/_mixins.scss';
@import '../../../styles/helpers/font_awesome_imports.scss'; @import '../../../styles/helpers/font_awesome_imports.scss';
@import '../../../../node_modules/bootstrap/scss/bootstrap.scss'; @import '../../../styles/_vendor.scss';
@import '../../../../node_modules/nouislider/distribute/nouislider.min';
@import '../../../styles/_custom_variables.scss'; @import '../../../styles/_custom_variables.scss';
@import './_theme_css_variable_overrides.scss'; @import './_theme_css_variable_overrides.scss';
@import '../../../styles/bootstrap_variables_mapping.scss'; @import '../../../styles/bootstrap_variables_mapping.scss';
@import '../../../styles/_truncatable-part.component.scss'; @import '../../../styles/_truncatable-part.component.scss';
@import './_global-styles.scss'; @import './_global-styles.scss';
@import '../../../../node_modules/ngx-ui-switch/ui-switch.component.scss';