mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 15:33:04 +00:00
Merge remote-tracking branch 'origin/main' into CST-6035_external-provider-query-error
This commit is contained in:
@@ -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.
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
});
|
});
|
||||||
|
@@ -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(
|
||||||
|
@@ -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> {
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
@@ -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;
|
||||||
|
@@ -16,7 +16,7 @@ export class HealthStatusComponent {
|
|||||||
@Input() status: HealthStatus;
|
@Input() status: HealthStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* He
|
* Health Status
|
||||||
*/
|
*/
|
||||||
HealthStatus = HealthStatus;
|
HealthStatus = HealthStatus;
|
||||||
|
|
||||||
|
@@ -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() {
|
||||||
|
@@ -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 {
|
||||||
|
|
||||||
|
@@ -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
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
|
||||||
|
@@ -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 }),
|
||||||
];
|
];
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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">
|
||||||
|
@@ -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]
|
||||||
|
@@ -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
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
8078
src/assets/i18n/sv.json5
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
5
src/styles/_vendor.scss
Normal 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';
|
@@ -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';
|
|
||||||
|
@@ -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';
|
|
||||||
|
@@ -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';
|
|
||||||
|
Reference in New Issue
Block a user