mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge branch 'accessibility-settings-7.6' into accessibility-settings-main
# Conflicts: # src/app/accessibility/accessibility-settings.service.spec.ts # src/app/accessibility/accessibility-settings.service.ts # src/app/info/accessibility-settings/accessibility-settings.component.spec.ts # src/app/info/accessibility-settings/accessibility-settings.component.ts # src/app/info/info.module.ts # src/app/shared/live-region/live-region.service.ts # src/app/shared/notifications/notifications-board/notifications-board.component.ts
This commit is contained in:
@@ -17,7 +17,6 @@ import { AuthServiceStub } from '../shared/testing/auth-service.stub';
|
|||||||
import {
|
import {
|
||||||
ACCESSIBILITY_COOKIE,
|
ACCESSIBILITY_COOKIE,
|
||||||
ACCESSIBILITY_SETTINGS_METADATA_KEY,
|
ACCESSIBILITY_SETTINGS_METADATA_KEY,
|
||||||
AccessibilitySetting,
|
|
||||||
AccessibilitySettings,
|
AccessibilitySettings,
|
||||||
AccessibilitySettingsService,
|
AccessibilitySettingsService,
|
||||||
} from './accessibility-settings.service';
|
} from './accessibility-settings.service';
|
||||||
@@ -48,17 +47,6 @@ describe('accessibilitySettingsService', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getALlAccessibilitySettingsKeys', () => {
|
|
||||||
it('should return an array containing all accessibility setting names', () => {
|
|
||||||
const settingNames: AccessibilitySetting[] = [
|
|
||||||
AccessibilitySetting.NotificationTimeOut,
|
|
||||||
AccessibilitySetting.LiveRegionTimeOut,
|
|
||||||
];
|
|
||||||
|
|
||||||
expect(service.getAllAccessibilitySettingKeys()).toEqual(settingNames);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('get', () => {
|
describe('get', () => {
|
||||||
it('should return the setting if it is set', () => {
|
it('should return the setting if it is set', () => {
|
||||||
const settings: AccessibilitySettings = {
|
const settings: AccessibilitySettings = {
|
||||||
@@ -67,7 +55,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
|
|
||||||
service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings));
|
service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings));
|
||||||
|
|
||||||
service.get(AccessibilitySetting.NotificationTimeOut, 'default').subscribe(value =>
|
service.get('notificationTimeOut', 'default').subscribe(value =>
|
||||||
expect(value).toEqual('1000'),
|
expect(value).toEqual('1000'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -79,7 +67,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
|
|
||||||
service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings));
|
service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings));
|
||||||
|
|
||||||
service.get(AccessibilitySetting.LiveRegionTimeOut, 'default').subscribe(value =>
|
service.get('liveRegionTimeOut', 'default').subscribe(value =>
|
||||||
expect(value).toEqual('default'),
|
expect(value).toEqual('default'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -89,7 +77,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
it('should return the setting as number if the value for the setting can be parsed to a number', () => {
|
it('should return the setting as number if the value for the setting can be parsed to a number', () => {
|
||||||
service.get = jasmine.createSpy('get').and.returnValue(of('1000'));
|
service.get = jasmine.createSpy('get').and.returnValue(of('1000'));
|
||||||
|
|
||||||
service.getAsNumber(AccessibilitySetting.NotificationTimeOut).subscribe(value =>
|
service.getAsNumber('notificationTimeOut').subscribe(value =>
|
||||||
expect(value).toEqual(1000),
|
expect(value).toEqual(1000),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -97,7 +85,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
it('should return the default value if no value is set for the setting', () => {
|
it('should return the default value if no value is set for the setting', () => {
|
||||||
service.get = jasmine.createSpy('get').and.returnValue(of(null));
|
service.get = jasmine.createSpy('get').and.returnValue(of(null));
|
||||||
|
|
||||||
service.getAsNumber(AccessibilitySetting.NotificationTimeOut, 123).subscribe(value =>
|
service.getAsNumber('notificationTimeOut', 123).subscribe(value =>
|
||||||
expect(value).toEqual(123),
|
expect(value).toEqual(123),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -105,7 +93,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
it('should return the default value if the value for the setting can not be parsed to a number', () => {
|
it('should return the default value if the value for the setting can not be parsed to a number', () => {
|
||||||
service.get = jasmine.createSpy('get').and.returnValue(of('text'));
|
service.get = jasmine.createSpy('get').and.returnValue(of('text'));
|
||||||
|
|
||||||
service.getAsNumber(AccessibilitySetting.NotificationTimeOut, 123).subscribe(value =>
|
service.getAsNumber('notificationTimeOut', 123).subscribe(value =>
|
||||||
expect(value).toEqual(123),
|
expect(value).toEqual(123),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -183,7 +171,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
it('should correctly update the chosen setting', () => {
|
it('should correctly update the chosen setting', () => {
|
||||||
service.updateSettings = jasmine.createSpy('updateSettings');
|
service.updateSettings = jasmine.createSpy('updateSettings');
|
||||||
|
|
||||||
service.set(AccessibilitySetting.LiveRegionTimeOut, '500');
|
service.set('liveRegionTimeOut', '500');
|
||||||
expect(service.updateSettings).toHaveBeenCalledWith({ liveRegionTimeOut: '500' });
|
expect(service.updateSettings).toHaveBeenCalledWith({ liveRegionTimeOut: '500' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -314,7 +302,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should set the settings in metadata', () => {
|
it('should set the settings in metadata', () => {
|
||||||
service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe();
|
service.setSettingsInMetadata(ePerson, { ['liveRegionTimeOut']: '500' }).subscribe();
|
||||||
expect(ePerson.setMetadata).toHaveBeenCalled();
|
expect(ePerson.setMetadata).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -325,19 +313,19 @@ describe('accessibilitySettingsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create a patch with the metadata changes', () => {
|
it('should create a patch with the metadata changes', () => {
|
||||||
service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe();
|
service.setSettingsInMetadata(ePerson, { ['liveRegionTimeOut']: '500' }).subscribe();
|
||||||
expect(ePersonService.createPatchFromCache).toHaveBeenCalled();
|
expect(ePersonService.createPatchFromCache).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send the patch request', () => {
|
it('should send the patch request', () => {
|
||||||
service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe();
|
service.setSettingsInMetadata(ePerson, { ['liveRegionTimeOut']: '500' }).subscribe();
|
||||||
expect(ePersonService.patch).toHaveBeenCalled();
|
expect(ePersonService.patch).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit true when the update succeeded', fakeAsync(() => {
|
it('should emit true when the update succeeded', fakeAsync(() => {
|
||||||
ePersonService.patch = jasmine.createSpy().and.returnValue(createSuccessfulRemoteDataObject$({}));
|
ePersonService.patch = jasmine.createSpy().and.returnValue(createSuccessfulRemoteDataObject$({}));
|
||||||
|
|
||||||
service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' })
|
service.setSettingsInMetadata(ePerson, { ['liveRegionTimeOut']: '500' })
|
||||||
.subscribe(value => {
|
.subscribe(value => {
|
||||||
expect(value).toBeTrue();
|
expect(value).toBeTrue();
|
||||||
});
|
});
|
||||||
@@ -348,7 +336,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
it('should emit false when the update failed', fakeAsync(() => {
|
it('should emit false when the update failed', fakeAsync(() => {
|
||||||
ePersonService.patch = jasmine.createSpy().and.returnValue(createFailedRemoteDataObject$());
|
ePersonService.patch = jasmine.createSpy().and.returnValue(createFailedRemoteDataObject$());
|
||||||
|
|
||||||
service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' })
|
service.setSettingsInMetadata(ePerson, { ['liveRegionTimeOut']: '500' })
|
||||||
.subscribe(value => {
|
.subscribe(value => {
|
||||||
expect(value).toBeFalse();
|
expect(value).toBeFalse();
|
||||||
});
|
});
|
||||||
@@ -364,7 +352,7 @@ describe('accessibilitySettingsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should store the settings in a cookie', () => {
|
it('should store the settings in a cookie', () => {
|
||||||
service.setSettingsInCookie({ [AccessibilitySetting.LiveRegionTimeOut]: '500' });
|
service.setSettingsInCookie({ ['liveRegionTimeOut']: '500' });
|
||||||
expect(cookieService.set).toHaveBeenCalled();
|
expect(cookieService.set).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -375,12 +363,4 @@ describe('accessibilitySettingsService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getInputType', () => {
|
|
||||||
it('should correctly return the input type', () => {
|
|
||||||
expect(service.getInputType(AccessibilitySetting.NotificationTimeOut)).toEqual('number');
|
|
||||||
expect(service.getInputType(AccessibilitySetting.LiveRegionTimeOut)).toEqual('number');
|
|
||||||
expect(service.getInputType('unknownValue' as AccessibilitySetting)).toEqual('text');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -32,4 +32,10 @@ export class AccessibilitySettingsServiceStub {
|
|||||||
setSettingsInCookie = jasmine.createSpy('setSettingsInCookie');
|
setSettingsInCookie = jasmine.createSpy('setSettingsInCookie');
|
||||||
|
|
||||||
getInputType = jasmine.createSpy('getInputType').and.returnValue('text');
|
getInputType = jasmine.createSpy('getInputType').and.returnValue('text');
|
||||||
|
|
||||||
|
convertFormValuesToStoredValues = jasmine.createSpy('convertFormValuesToStoredValues').and.returnValue({});
|
||||||
|
|
||||||
|
convertStoredValuesToFormValues = jasmine.createSpy('convertStoredValuesToFormValues').and.returnValue({});
|
||||||
|
|
||||||
|
getPlaceholder = jasmine.createSpy('getPlaceholder').and.returnValue('placeholder');
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,8 @@ import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
|||||||
import {
|
import {
|
||||||
hasValue,
|
hasValue,
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
isNotEmptyOperator,
|
|
||||||
} from '../shared/empty.util';
|
} from '../shared/empty.util';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the cookie used to store the settings locally
|
* Name of the cookie used to store the settings locally
|
||||||
@@ -33,16 +33,30 @@ export const ACCESSIBILITY_COOKIE = 'dsAccessibilityCookie';
|
|||||||
export const ACCESSIBILITY_SETTINGS_METADATA_KEY = 'dspace.accessibility.settings';
|
export const ACCESSIBILITY_SETTINGS_METADATA_KEY = 'dspace.accessibility.settings';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum containing all possible accessibility settings.
|
* Type containing all possible accessibility settings.
|
||||||
* When adding new settings, the {@link AccessibilitySettingsService#getInputType} method and the i18n keys for the
|
* When adding new settings, make sure to add the new setting to the accessibility-settings component form.
|
||||||
* accessibility settings page should be updated.
|
* The converter methods to convert from stored format to form format (and vice-versa) need to be updated as well.
|
||||||
*/
|
*/
|
||||||
export enum AccessibilitySetting {
|
export type AccessibilitySetting = 'notificationTimeOut' | 'liveRegionTimeOut';
|
||||||
NotificationTimeOut = 'notificationTimeOut',
|
|
||||||
LiveRegionTimeOut = 'liveRegionTimeOut',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AccessibilitySettings = { [key in AccessibilitySetting]?: any };
|
/**
|
||||||
|
* Type representing an object that contains accessibility settings values for all accessibility settings.
|
||||||
|
*/
|
||||||
|
export type FullAccessibilitySettings = { [key in AccessibilitySetting]: string };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type representing an object that contains accessibility settings values for some accessibility settings.
|
||||||
|
*/
|
||||||
|
export type AccessibilitySettings = Partial<FullAccessibilitySettings>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The accessibility settings object format used by the accessibility-settings component form.
|
||||||
|
*/
|
||||||
|
export interface AccessibilitySettingsFormValues {
|
||||||
|
notificationTimeOutEnabled: boolean,
|
||||||
|
notificationTimeOut: string,
|
||||||
|
liveRegionTimeOut: string,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service handling the retrieval and configuration of accessibility settings.
|
* Service handling the retrieval and configuration of accessibility settings.
|
||||||
@@ -62,10 +76,6 @@ export class AccessibilitySettingsService {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllAccessibilitySettingKeys(): AccessibilitySetting[] {
|
|
||||||
return Object.entries(AccessibilitySetting).map(([_, val]) => val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the stored value for the provided {@link AccessibilitySetting}. If the value does not exist or if it is empty,
|
* Get the stored value for the provided {@link AccessibilitySetting}. If the value does not exist or if it is empty,
|
||||||
* the provided defaultValue is emitted instead.
|
* the provided defaultValue is emitted instead.
|
||||||
@@ -204,8 +214,8 @@ export class AccessibilitySettingsService {
|
|||||||
|
|
||||||
return this.ePersonService.createPatchFromCache(user).pipe(
|
return this.ePersonService.createPatchFromCache(user).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
isNotEmptyOperator(),
|
switchMap(operations =>
|
||||||
switchMap(operations => this.ePersonService.patch(user, operations)),
|
isNotEmpty(operations) ? this.ePersonService.patch(user, operations) : createSuccessfulRemoteDataObject$({})),
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
map(rd => rd.hasSucceeded),
|
map(rd => rd.hasSucceeded),
|
||||||
);
|
);
|
||||||
@@ -223,17 +233,75 @@ export class AccessibilitySettingsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the input type that a form should use for the provided {@link AccessibilitySetting}
|
* Clears all settings in the cookie and attempts to clear settings in metadata.
|
||||||
|
* Emits true if settings in metadata were cleared and false otherwise.
|
||||||
*/
|
*/
|
||||||
getInputType(setting: AccessibilitySetting): string {
|
clearSettings(): Observable<boolean> {
|
||||||
|
this.setSettingsInCookie({});
|
||||||
|
return this.setSettingsInAuthenticatedUserMetadata({});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the placeholder to be used for the provided AccessibilitySetting.
|
||||||
|
* Returns an empty string when no placeholder is specified for the provided setting.
|
||||||
|
*/
|
||||||
|
getPlaceholder(setting: AccessibilitySetting): string {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case AccessibilitySetting.NotificationTimeOut:
|
case 'notificationTimeOut':
|
||||||
return 'number';
|
return millisecondsToSeconds(environment.notifications.timeOut.toString());
|
||||||
case AccessibilitySetting.LiveRegionTimeOut:
|
case 'liveRegionTimeOut':
|
||||||
return 'number';
|
return millisecondsToSeconds(environment.liveRegion.messageTimeOutDurationMs.toString());
|
||||||
default:
|
default:
|
||||||
return 'text';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert values in the provided accessibility settings object to values ready to be stored.
|
||||||
|
*/
|
||||||
|
convertFormValuesToStoredValues(settings: AccessibilitySettingsFormValues): FullAccessibilitySettings {
|
||||||
|
return {
|
||||||
|
notificationTimeOut: settings.notificationTimeOutEnabled ?
|
||||||
|
secondsToMilliseconds(settings.notificationTimeOut) : '0',
|
||||||
|
liveRegionTimeOut: secondsToMilliseconds(settings.liveRegionTimeOut),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert values in the provided accessibility settings object to values ready to show in the form.
|
||||||
|
*/
|
||||||
|
convertStoredValuesToFormValues(settings: AccessibilitySettings): AccessibilitySettingsFormValues {
|
||||||
|
return {
|
||||||
|
notificationTimeOutEnabled: parseFloat(settings.notificationTimeOut) !== 0,
|
||||||
|
notificationTimeOut: millisecondsToSeconds(settings.notificationTimeOut),
|
||||||
|
liveRegionTimeOut: millisecondsToSeconds(settings.liveRegionTimeOut),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string representing seconds to a string representing milliseconds
|
||||||
|
* Returns null if the input could not be parsed to a float
|
||||||
|
*/
|
||||||
|
function secondsToMilliseconds(secondsStr: string): string {
|
||||||
|
const seconds = parseFloat(secondsStr);
|
||||||
|
if (isNaN(seconds)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return (seconds * 1000).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string representing milliseconds to a string representing seconds
|
||||||
|
* Returns null if the input could not be parsed to a float
|
||||||
|
*/
|
||||||
|
function millisecondsToSeconds(millisecondsStr: string): string {
|
||||||
|
const milliseconds = parseFloat(millisecondsStr);
|
||||||
|
if (isNaN(milliseconds)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return (milliseconds / 1000).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,25 +2,87 @@
|
|||||||
<h2>{{ 'info.accessibility-settings.title' | translate }}</h2>
|
<h2>{{ 'info.accessibility-settings.title' | translate }}</h2>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<div *ngFor="let setting of accessibilitySettingsOptions" class="form-group row">
|
<div class="form-group row">
|
||||||
<label [for]="setting + 'Input'" class="col-sm-2 col-form-label">
|
<label [for]="'disableNotificationTimeOutInput'" class="col-sm-2 col-form-label">
|
||||||
{{ 'info.accessibility-settings.' + setting + '.label' | translate }}
|
{{ 'info.accessibility-settings.disableNotificationTimeOut.label' | translate }}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-5">
|
||||||
<input [type]="getInputType(setting)" [id]="setting + 'Input'" class="form-control"
|
<ui-switch [id]="'disableNotificationTimeOutInput'"
|
||||||
[(ngModel)]="formValues[setting]" [ngModelOptions]="{ standalone: true }"
|
[(ngModel)]="formValues.notificationTimeOutEnabled"
|
||||||
[attr.aria-describedby]="setting + 'Hint'">
|
[ngModelOptions]="{ standalone: true }"
|
||||||
|
></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
<small [id]="setting + 'Hint'" class="form-text text-muted">
|
<div class="col-sm-1" *dsContextHelp="{
|
||||||
{{ 'info.accessibility-settings.' + setting + '.hint' | translate }}
|
content: 'info.accessibility-settings.disableNotificationTimeOut.hint',
|
||||||
</small>
|
id: 'disableNotificationTimeOutHelp',
|
||||||
|
iconPlacement: 'right',
|
||||||
|
tooltipPlacement: 'right'
|
||||||
|
}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" (click)="saveSettings()" class="btn btn-primary">
|
<div class="form-group row">
|
||||||
{{ 'info.accessibility-settings.submit' | translate }}
|
<label [for]="'notificationTimeOutInput'" class="col-sm-2 col-form-label">
|
||||||
</button>
|
{{ 'info.accessibility-settings.notificationTimeOut.label' | translate }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input [type]="'number'" [id]="'notificationTimeOutInput'" class="form-control"
|
||||||
|
[placeholder]="getPlaceholder('notificationTimeOut')"
|
||||||
|
[readOnly]="!formValues.notificationTimeOutEnabled"
|
||||||
|
[(ngModel)]="formValues.notificationTimeOut" [ngModelOptions]="{ standalone: true }"
|
||||||
|
[attr.aria-describedby]="'notificationTimeOutHint'">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-1 col-form-label">
|
||||||
|
{{ 'info.accessibility-settings.notificationTimeOut.unit' | translate }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-1" *dsContextHelp="{
|
||||||
|
content: 'info.accessibility-settings.notificationTimeOut.hint',
|
||||||
|
id: 'notificationTimeOutHelp',
|
||||||
|
iconPlacement: 'right',
|
||||||
|
tooltipPlacement: 'right'
|
||||||
|
}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label [for]="'liveRegionTimeOutInput'" class="col-sm-2 col-form-label">
|
||||||
|
{{ 'info.accessibility-settings.liveRegionTimeOut.label' | translate }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input [type]="'number'" [id]="'liveRegionTimeOutInput'" class="form-control"
|
||||||
|
[placeholder]="getPlaceholder('liveRegionTimeOut')"
|
||||||
|
[(ngModel)]="formValues.liveRegionTimeOut" [ngModelOptions]="{ standalone: true }"
|
||||||
|
[attr.aria-describedby]="'liveRegionTimeOutHint'">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-1 col-form-label">
|
||||||
|
{{ 'info.accessibility-settings.liveRegionTimeOut.unit' | translate }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-1" *dsContextHelp="{
|
||||||
|
content: 'info.accessibility-settings.liveRegionTimeOut.hint',
|
||||||
|
id: 'liveRegionTimeOutHelp',
|
||||||
|
iconPlacement: 'right',
|
||||||
|
tooltipPlacement: 'right'
|
||||||
|
}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div role="group">
|
||||||
|
<button type="submit" (click)="saveSettings()" class="btn btn-primary mr-2">
|
||||||
|
{{ 'info.accessibility-settings.submit' | translate }}
|
||||||
|
</button>
|
||||||
|
<button type="reset" (click)="resetSettings()" class="btn btn-warning">
|
||||||
|
{{ 'info.accessibility-settings.reset' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -6,11 +6,9 @@ import {
|
|||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
|
import { ContextHelpDirective } from 'src/app/shared/context-help.directive';
|
||||||
|
|
||||||
import {
|
import { AccessibilitySettingsService } from '../../accessibility/accessibility-settings.service';
|
||||||
AccessibilitySetting,
|
|
||||||
AccessibilitySettingsService,
|
|
||||||
} from '../../accessibility/accessibility-settings.service';
|
|
||||||
import { getAccessibilitySettingsServiceStub } from '../../accessibility/accessibility-settings.service.stub';
|
import { getAccessibilitySettingsServiceStub } from '../../accessibility/accessibility-settings.service.stub';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
@@ -40,6 +38,10 @@ describe('AccessibilitySettingsComponent', () => {
|
|||||||
{ provide: NotificationsService, useValue: notificationsService },
|
{ provide: NotificationsService, useValue: notificationsService },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
}).overrideComponent(AccessibilitySettingsComponent, {
|
||||||
|
remove: {
|
||||||
|
imports: [ContextHelpDirective],
|
||||||
|
},
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -54,19 +56,12 @@ describe('AccessibilitySettingsComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('On Init', () => {
|
describe('On Init', () => {
|
||||||
it('should retrieve all accessibility settings options', () => {
|
|
||||||
expect(settingsService.getAllAccessibilitySettingKeys).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should retrieve the current settings', () => {
|
it('should retrieve the current settings', () => {
|
||||||
expect(settingsService.getAll).toHaveBeenCalled();
|
expect(settingsService.getAll).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('getInputType', () => {
|
it('should convert retrieved settings to form format', () => {
|
||||||
it('should retrieve the input type for the setting from the service', () => {
|
expect(settingsService.convertStoredValuesToFormValues).toHaveBeenCalled();
|
||||||
component.getInputType(AccessibilitySetting.LiveRegionTimeOut);
|
|
||||||
expect(settingsService.getInputType).toHaveBeenCalledWith(AccessibilitySetting.LiveRegionTimeOut);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,6 +72,12 @@ describe('AccessibilitySettingsComponent', () => {
|
|||||||
expect(settingsService.setSettings).toHaveBeenCalled();
|
expect(settingsService.setSettings).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should convert form settings to stored format', () => {
|
||||||
|
settingsService.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie'));
|
||||||
|
component.saveSettings();
|
||||||
|
expect(settingsService.convertFormValuesToStoredValues).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('should give the user a notification mentioning where the settings were saved', () => {
|
it('should give the user a notification mentioning where the settings were saved', () => {
|
||||||
settingsService.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie'));
|
settingsService.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie'));
|
||||||
component.saveSettings();
|
component.saveSettings();
|
||||||
|
@@ -8,16 +8,21 @@ import {
|
|||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
} from '@ngx-translate/core';
|
} from '@ngx-translate/core';
|
||||||
|
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||||
import { take } from 'rxjs';
|
import { take } from 'rxjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AccessibilitySetting,
|
AccessibilitySetting,
|
||||||
AccessibilitySettings,
|
AccessibilitySettingsFormValues,
|
||||||
AccessibilitySettingsService,
|
AccessibilitySettingsService,
|
||||||
} from '../../accessibility/accessibility-settings.service';
|
} from '../../accessibility/accessibility-settings.service';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
import { ContextHelpDirective } from '../../shared/context-help.directive';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component providing the form where users can update accessibility settings.
|
||||||
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-accessibility-settings',
|
selector: 'ds-accessibility-settings',
|
||||||
templateUrl: './accessibility-settings.component.html',
|
templateUrl: './accessibility-settings.component.html',
|
||||||
@@ -25,14 +30,14 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
UiSwitchModule,
|
||||||
|
ContextHelpDirective,
|
||||||
],
|
],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class AccessibilitySettingsComponent implements OnInit {
|
export class AccessibilitySettingsComponent implements OnInit {
|
||||||
|
|
||||||
protected accessibilitySettingsOptions: AccessibilitySetting[];
|
protected formValues: AccessibilitySettingsFormValues;
|
||||||
|
|
||||||
protected formValues: AccessibilitySettings = { };
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected authService: AuthService,
|
protected authService: AuthService,
|
||||||
@@ -43,19 +48,41 @@ export class AccessibilitySettingsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.accessibilitySettingsOptions = this.settingsService.getAllAccessibilitySettingKeys();
|
this.updateFormValues();
|
||||||
this.settingsService.getAll().pipe(take(1)).subscribe(currentSettings => {
|
}
|
||||||
this.formValues = currentSettings;
|
|
||||||
|
getPlaceholder(setting: AccessibilitySetting): string {
|
||||||
|
return this.settingsService.getPlaceholder(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the user-configured settings
|
||||||
|
*/
|
||||||
|
saveSettings() {
|
||||||
|
const formValues = this.formValues;
|
||||||
|
const convertedValues = this.settingsService.convertFormValuesToStoredValues(formValues);
|
||||||
|
this.settingsService.setSettings(convertedValues).pipe(take(1)).subscribe(location => {
|
||||||
|
this.notificationsService.success(null, this.translateService.instant('info.accessibility-settings.save-notification.' + location));
|
||||||
|
this.updateFormValues();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getInputType(setting: AccessibilitySetting): string {
|
/**
|
||||||
return this.settingsService.getInputType(setting);
|
* Updates the form values with the currently stored accessibility settings
|
||||||
|
*/
|
||||||
|
updateFormValues() {
|
||||||
|
this.settingsService.getAll().pipe(take(1)).subscribe(storedSettings => {
|
||||||
|
this.formValues = this.settingsService.convertStoredValuesToFormValues(storedSettings);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettings() {
|
/**
|
||||||
this.settingsService.setSettings(this.formValues).pipe(take(1)).subscribe(location => {
|
* Resets accessibility settings
|
||||||
this.notificationsService.success(null, this.translateService.instant('info.accessibility-settings.save-notification.' + location));
|
*/
|
||||||
|
resetSettings() {
|
||||||
|
this.settingsService.clearSettings().pipe(take(1)).subscribe(() => {
|
||||||
|
this.notificationsService.success(null, this.translateService.instant('info.accessibility-settings.reset-notification'));
|
||||||
|
this.updateFormValues();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">{{'profile.card.accessibility.header' | translate}}</div>
|
<div class="card-header">{{'profile.card.accessibility.header' | translate}}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="mb-1">{{'profile.card.accessibility.content' | translate}}</div>
|
<ds-alert class="mb-4" [type]="'alert-info'">{{'profile.card.accessibility.content' | translate}}</ds-alert>
|
||||||
<a [routerLink]="'/info/accessibility'">{{'profile.card.accessibility.link' | translate}}</a>
|
<a [routerLink]="'/info/accessibility'">{{'profile.card.accessibility.link' | translate}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -5,6 +5,7 @@ import {
|
|||||||
waitForAsync,
|
waitForAsync,
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { StoreModule } from '@ngrx/store';
|
import { StoreModule } from '@ngrx/store';
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
import { provideMockStore } from '@ngrx/store/testing';
|
||||||
@@ -116,6 +117,7 @@ describe('ProfilePageComponent', () => {
|
|||||||
RouterModule.forRoot([]),
|
RouterModule.forRoot([]),
|
||||||
ProfilePageComponent,
|
ProfilePageComponent,
|
||||||
VarDirective,
|
VarDirective,
|
||||||
|
NoopAnimationsModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: EPersonDataService, useValue: epersonService },
|
{ provide: EPersonDataService, useValue: epersonService },
|
||||||
|
@@ -41,6 +41,7 @@ import {
|
|||||||
getRemoteDataPayload,
|
getRemoteDataPayload,
|
||||||
} from '../core/shared/operators';
|
} from '../core/shared/operators';
|
||||||
import { SuggestionsNotificationComponent } from '../notifications/suggestions-notification/suggestions-notification.component';
|
import { SuggestionsNotificationComponent } from '../notifications/suggestions-notification/suggestions-notification.component';
|
||||||
|
import { AlertComponent } from '../shared/alert/alert.component';
|
||||||
import {
|
import {
|
||||||
hasValue,
|
hasValue,
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
@@ -67,6 +68,7 @@ import { ProfilePageSecurityFormComponent } from './profile-page-security-form/p
|
|||||||
NgForOf,
|
NgForOf,
|
||||||
SuggestionsNotificationComponent,
|
SuggestionsNotificationComponent,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
|
AlertComponent,
|
||||||
],
|
],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
|
@@ -9,10 +9,7 @@ import {
|
|||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
import {
|
import { AccessibilitySettingsService } from '../../accessibility/accessibility-settings.service';
|
||||||
AccessibilitySetting,
|
|
||||||
AccessibilitySettingsService,
|
|
||||||
} from '../../accessibility/accessibility-settings.service';
|
|
||||||
import { UUIDService } from '../../core/shared/uuid.service';
|
import { UUIDService } from '../../core/shared/uuid.service';
|
||||||
|
|
||||||
export const MIN_MESSAGE_DURATION = 200;
|
export const MIN_MESSAGE_DURATION = 200;
|
||||||
@@ -141,7 +138,7 @@ export class LiveRegionService {
|
|||||||
*/
|
*/
|
||||||
getConfiguredMessageTimeOutMs(): Observable<number> {
|
getConfiguredMessageTimeOutMs(): Observable<number> {
|
||||||
return this.accessibilitySettingsService.getAsNumber(
|
return this.accessibilitySettingsService.getAsNumber(
|
||||||
AccessibilitySetting.LiveRegionTimeOut,
|
'liveRegionTimeOut',
|
||||||
this.getMessageTimeOutMs(),
|
this.getMessageTimeOutMs(),
|
||||||
).pipe(map(timeOut => Math.max(timeOut, MIN_MESSAGE_DURATION)));
|
).pipe(map(timeOut => Math.max(timeOut, MIN_MESSAGE_DURATION)));
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ import {
|
|||||||
Store,
|
Store,
|
||||||
} from '@ngrx/store';
|
} from '@ngrx/store';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
import difference from 'lodash/difference';
|
import differenceWith from 'lodash/differenceWith';
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
Subscription,
|
Subscription,
|
||||||
@@ -24,10 +24,7 @@ import {
|
|||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces';
|
import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces';
|
||||||
import {
|
import { AccessibilitySettingsService } from '../../../accessibility/accessibility-settings.service';
|
||||||
AccessibilitySetting,
|
|
||||||
AccessibilitySettingsService,
|
|
||||||
} from '../../../accessibility/accessibility-settings.service';
|
|
||||||
import { AppState } from '../../../app.reducer';
|
import { AppState } from '../../../app.reducer';
|
||||||
import { INotification } from '../models/notification.model';
|
import { INotification } from '../models/notification.model';
|
||||||
import { NotificationComponent } from '../notification/notification.component';
|
import { NotificationComponent } from '../notification/notification.component';
|
||||||
@@ -82,13 +79,13 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy {
|
|||||||
this.notifications = [];
|
this.notifications = [];
|
||||||
} else if (state.length > this.notifications.length) {
|
} else if (state.length > this.notifications.length) {
|
||||||
// Add
|
// Add
|
||||||
const newElem = difference(state, this.notifications);
|
const newElem = differenceWith(state, this.notifications, this.byId);
|
||||||
newElem.forEach((notification) => {
|
newElem.forEach((notification) => {
|
||||||
this.add(notification);
|
this.add(notification);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Remove
|
// Remove
|
||||||
const delElem = difference(this.notifications, state);
|
const delElem = differenceWith(this.notifications, state, this.byId);
|
||||||
delElem.forEach((notification) => {
|
delElem.forEach((notification) => {
|
||||||
this.notifications = this.notifications.filter((item: INotification) => item.id !== notification.id);
|
this.notifications = this.notifications.filter((item: INotification) => item.id !== notification.id);
|
||||||
|
|
||||||
@@ -98,6 +95,9 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byId = (notificationA: INotification, notificationB: INotification) =>
|
||||||
|
notificationA.id === notificationB.id;
|
||||||
|
|
||||||
// Add the new notification to the notification array
|
// Add the new notification to the notification array
|
||||||
add(item: INotification): void {
|
add(item: INotification): void {
|
||||||
const toBlock: boolean = this.block(item);
|
const toBlock: boolean = this.block(item);
|
||||||
@@ -108,7 +108,7 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// It would be a bit better to handle the retrieval of configured settings in the NotificationsService.
|
// It would be a bit better to handle the retrieval of configured settings in the NotificationsService.
|
||||||
// Due to circular dependencies this is difficult to implement.
|
// Due to circular dependencies this is difficult to implement.
|
||||||
this.accessibilitySettingsService.getAsNumber(AccessibilitySetting.NotificationTimeOut, item.options.timeOut)
|
this.accessibilitySettingsService.getAsNumber('notificationTimeOut', item.options.timeOut)
|
||||||
.pipe(take(1)).subscribe(timeOut => {
|
.pipe(take(1)).subscribe(timeOut => {
|
||||||
if (timeOut < 0) {
|
if (timeOut < 0) {
|
||||||
timeOut = 0;
|
timeOut = 0;
|
||||||
|
@@ -2134,18 +2134,30 @@
|
|||||||
|
|
||||||
"info.accessibility-settings.breadcrumbs": "Accessibility settings",
|
"info.accessibility-settings.breadcrumbs": "Accessibility settings",
|
||||||
|
|
||||||
|
"info.accessibility-settings.disableNotificationTimeOut.label": "Hide notifications automatically",
|
||||||
|
|
||||||
|
"info.accessibility-settings.disableNotificationTimeOut.hint": "When this toggle is activated, notifications will remain until manually closed.",
|
||||||
|
|
||||||
"info.accessibility-settings.liveRegionTimeOut.label": "Live region time-out",
|
"info.accessibility-settings.liveRegionTimeOut.label": "Live region time-out",
|
||||||
|
|
||||||
"info.accessibility-settings.liveRegionTimeOut.hint": "The duration in milliseconds after which a message in the live region disappears.",
|
"info.accessibility-settings.liveRegionTimeOut.hint": "The duration after which a message in the live region disappears.",
|
||||||
|
|
||||||
|
"info.accessibility-settings.liveRegionTimeOut.unit": "Seconds",
|
||||||
|
|
||||||
"info.accessibility-settings.notificationTimeOut.label": "Notification time-out",
|
"info.accessibility-settings.notificationTimeOut.label": "Notification time-out",
|
||||||
|
|
||||||
"info.accessibility-settings.notificationTimeOut.hint": "The duration in milliseconds after which a notification disappears. Set to 0 for notifications to remain indefinitely.",
|
"info.accessibility-settings.notificationTimeOut.hint": "The duration after which a notification disappears.",
|
||||||
|
|
||||||
|
"info.accessibility-settings.notificationTimeOut.unit": "Seconds",
|
||||||
|
|
||||||
"info.accessibility-settings.save-notification.cookie": "Successfully saved settings locally.",
|
"info.accessibility-settings.save-notification.cookie": "Successfully saved settings locally.",
|
||||||
|
|
||||||
"info.accessibility-settings.save-notification.metadata": "Successfully saved settings on the user profile.",
|
"info.accessibility-settings.save-notification.metadata": "Successfully saved settings on the user profile.",
|
||||||
|
|
||||||
|
"info.accessibility-settings.reset-notification": "Successfully reset settings.",
|
||||||
|
|
||||||
|
"info.accessibility-settings.reset": "Reset accessibility settings",
|
||||||
|
|
||||||
"info.accessibility-settings.submit": "Save accessibility settings",
|
"info.accessibility-settings.submit": "Save accessibility settings",
|
||||||
|
|
||||||
"info.accessibility-settings.title": "Accessibility settings",
|
"info.accessibility-settings.title": "Accessibility settings",
|
||||||
@@ -3896,7 +3908,7 @@
|
|||||||
|
|
||||||
"profile.card.accessibility.header": "Accessibility",
|
"profile.card.accessibility.header": "Accessibility",
|
||||||
|
|
||||||
"profile.card.accessibility.link": "Accessibility Settings Page",
|
"profile.card.accessibility.link": "Go to Accessibility Settings Page",
|
||||||
|
|
||||||
"profile.card.identify": "Identify",
|
"profile.card.identify": "Identify",
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ import { ProfilePageComponent as BaseComponent } from '../../../../app/profile-p
|
|||||||
import { ThemedProfilePageMetadataFormComponent } from '../../../../app/profile-page/profile-page-metadata-form/themed-profile-page-metadata-form.component';
|
import { ThemedProfilePageMetadataFormComponent } from '../../../../app/profile-page/profile-page-metadata-form/themed-profile-page-metadata-form.component';
|
||||||
import { ProfilePageResearcherFormComponent } from '../../../../app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component';
|
import { ProfilePageResearcherFormComponent } from '../../../../app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component';
|
||||||
import { ProfilePageSecurityFormComponent } from '../../../../app/profile-page/profile-page-security-form/profile-page-security-form.component';
|
import { ProfilePageSecurityFormComponent } from '../../../../app/profile-page/profile-page-security-form/profile-page-security-form.component';
|
||||||
|
import { AlertComponent } from '../../../../app/shared/alert/alert.component';
|
||||||
import { VarDirective } from '../../../../app/shared/utils/var.directive';
|
import { VarDirective } from '../../../../app/shared/utils/var.directive';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -32,6 +33,7 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive';
|
|||||||
NgForOf,
|
NgForOf,
|
||||||
SuggestionsNotificationComponent,
|
SuggestionsNotificationComponent,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
|
AlertComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user