Merge remote-tracking branch 'upstream/main' into w2p-93914_delete-process

This commit is contained in:
Yana De Pauw
2022-08-25 15:34:00 +02:00
19 changed files with 8187 additions and 42 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;
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.

View File

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

View File

@@ -19,7 +19,7 @@ export abstract class SomeFeatureAuthorizationGuard implements CanActivate {
/**
* 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> {
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
*/
getFilesEndpoint(processId: string): Observable<string> {

View File

@@ -55,7 +55,7 @@ export class EndUserAgreementService {
/**
* 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
* @param accepted
*/

View File

@@ -39,7 +39,7 @@ export class MetadataValue implements MetadataValueInterface {
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
*/
@autoserialize
@@ -105,7 +105,7 @@ export class MetadatumViewModel {
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
*/
place: number;

View File

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

View File

@@ -76,7 +76,7 @@ export class EndUserAgreementComponent implements OnInit {
/**
* 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
*/
cancel() {

View File

@@ -24,7 +24,7 @@ import { ConfirmationModalComponent } from '../../shared/confirmation-modal/conf
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 {

View File

@@ -24,7 +24,7 @@ export const klaroConfiguration: any = {
/*
Setting 'hideLearnMore' to 'true' will hide the "learn more / customize" link in
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,

View File

@@ -20,6 +20,7 @@ import {
createSuccessfulRemoteDataObject$
} from '../../../remote-data.utils';
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
@NgModule({
@@ -47,6 +48,7 @@ describe('ExportMetadataSelectorComponent', () => {
let router;
let notificationService: NotificationsServiceStub;
let scriptService;
let authorizationDataService;
const mockItem = Object.assign(new Item(), {
id: 'fake-id',
@@ -95,6 +97,9 @@ describe('ExportMetadataSelectorComponent', () => {
invoke: createSuccessfulRemoteDataObject$({ processId: '45' })
}
);
authorizationDataService = jasmine.createSpyObj('authorizationDataService', {
isAuthorized: observableOf(true)
});
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), ModelTestModule],
declarations: [ExportMetadataSelectorComponent],
@@ -102,6 +107,7 @@ describe('ExportMetadataSelectorComponent', () => {
{ provide: NgbActiveModal, useValue: modalStub },
{ provide: NotificationsService, useValue: notificationService },
{ provide: ScriptDataService, useValue: scriptService },
{ provide: AuthorizationDataService, useValue: authorizationDataService },
{
provide: ActivatedRoute,
useValue: {
@@ -150,7 +156,7 @@ describe('ExportMetadataSelectorComponent', () => {
});
});
describe('if collection is selected', () => {
describe('if collection is selected and is admin', () => {
let scriptRequestSucceeded;
beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
@@ -159,7 +165,32 @@ describe('ExportMetadataSelectorComponent', () => {
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[] = [
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;
beforeEach((done) => {
spyOn((component as any).modalService, 'open').and.returnValue(modalRef);
@@ -183,7 +214,32 @@ describe('ExportMetadataSelectorComponent', () => {
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[] = [
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 { RemoteData } from '../../../../core/data/remote-data';
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
@@ -36,6 +38,7 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router,
protected notificationsService: NotificationsService, protected translationService: TranslateService,
protected scriptDataService: ScriptDataService,
protected authorizationDataService: AuthorizationDataService,
private modalService: NgbModal) {
super(activeModal, route);
}
@@ -82,24 +85,29 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp
const parameterValues: ProcessParameter[] = [
Object.assign(new ProcessParameter(), { name: '-i', value: dso.uuid }),
];
return this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, [])
.pipe(
getFirstCompletedRemoteData(),
map((rd: RemoteData<Process>) => {
if (rd.hasSucceeded) {
const title = this.translationService.get('process.new.notification.success.title');
const content = this.translationService.get('process.new.notification.success.content');
this.notificationsService.success(title, content);
if (isNotEmpty(rd.payload)) {
this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
}
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;
return this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf).pipe(
switchMap((isAdmin) => {
if (isAdmin) {
parameterValues.push(Object.assign(new ProcessParameter(), {name: '-a'}));
}
return this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []);
}),
getFirstCompletedRemoteData(),
map((rd: RemoteData<Process>) => {
if (rd.hasSucceeded) {
const title = this.translationService.get('process.new.notification.success.title');
const content = this.translationService.get('process.new.notification.success.content');
this.notificationsService.success(title, content);
if (isNotEmpty(rd.payload)) {
this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
}
}));
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

@@ -12,7 +12,7 @@ import { metadataRepresentationComponent } from '../../../metadata-representatio
/**
* A component for displaying MetadataRepresentation objects in the form of items
* 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 {
/**

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-BR', label: 'Português do Brasil', active: true },
{ code: 'fi', label: 'Suomi', active: true },
{ code: 'sv', label: 'Svenska', active: true },
{ code: 'tr', label: 'Türkçe', 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 '../../node_modules/bootstrap/scss/bootstrap.scss';
@import '../../node_modules/nouislider/distribute/nouislider.min';
@import './_vendor.scss';
@import './_custom_variables.scss';
@import './bootstrap_variables_mapping.scss';
@import './_truncatable-part.component.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/_mixins.scss';
@import '../../../styles/helpers/font_awesome_imports.scss';
@import '../../../../node_modules/bootstrap/scss/bootstrap.scss';
@import '../../../../node_modules/nouislider/distribute/nouislider.min';
@import '../../../styles/_vendor.scss';
@import '../../../styles/_custom_variables.scss';
@import './_theme_css_variable_overrides.scss';
@import '../../../styles/bootstrap_variables_mapping.scss';
@import '../../../styles/_truncatable-part.component.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/_mixins.scss';
@import '../../../styles/helpers/font_awesome_imports.scss';
@import '../../../../node_modules/bootstrap/scss/bootstrap.scss';
@import '../../../../node_modules/nouislider/distribute/nouislider.min';
@import '../../../styles/_vendor.scss';
@import '../../../styles/_custom_variables.scss';
@import './_theme_css_variable_overrides.scss';
@import '../../../styles/bootstrap_variables_mapping.scss';
@import '../../../styles/_truncatable-part.component.scss';
@import './_global-styles.scss';
@import '../../../../node_modules/ngx-ui-switch/ui-switch.component.scss';