forked from hazza/dspace-angular
Merge pull request #1346 from 4Science/CST-4659
[Deque Re-Analysis] Submission "critical" accessibility issues
This commit is contained in:
@@ -1,79 +1,80 @@
|
||||
<div [class.form-group]="(model.type !== 'GROUP' && asBootstrapFormGroup) || getClass('element', 'container').includes('form-group')"
|
||||
[formGroup]="group"
|
||||
[ngClass]="[getClass('element', 'container'), getClass('grid', 'container')]">
|
||||
<label *ngIf="!isCheckbox && hasLabel"
|
||||
[id]="'label_' + model.id"
|
||||
[for]="id"
|
||||
[innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)"
|
||||
[ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label>
|
||||
<ng-container *ngTemplateOutlet="startTemplate?.templateRef; context: model"></ng-container>
|
||||
<!-- Should be *ngIf instead of class d-none, but that breaks the #componentViewContainer reference-->
|
||||
<div [ngClass]="{'form-row': model.hasLanguages || isRelationship,
|
||||
<label *ngIf="!isCheckbox && hasLabel"
|
||||
[id]="'label_' + model.id"
|
||||
[for]="id"
|
||||
[innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)"
|
||||
[ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label>
|
||||
<ng-container *ngTemplateOutlet="startTemplate?.templateRef; context: model"></ng-container>
|
||||
<!-- Should be *ngIf instead of class d-none, but that breaks the #componentViewContainer reference-->
|
||||
<div [ngClass]="{'form-row': model.hasLanguages || isRelationship,
|
||||
'd-none': value?.isVirtual && (model.hasSelectableMetadata || context?.index > 0)}">
|
||||
<div [ngClass]="getClass('grid', 'control')">
|
||||
<ng-container #componentViewContainer></ng-container>
|
||||
<small *ngIf="hasHint && ((model.repeatable === false && (isRelationship === false || value?.value === null)) || (model.repeatable === true && context?.index === context?.context?.groups?.length - 1)) && (!showErrorMessages || errorMessages.length === 0)"
|
||||
class="text-muted ds-hint" [innerHTML]="model.hint | translate" [ngClass]="getClass('element', 'hint')"></small>
|
||||
<!-- In case of repeatable fields show empty space for all elements except the first -->
|
||||
<div *ngIf="context?.index !== null
|
||||
<div [ngClass]="getClass('grid', 'control')">
|
||||
<div>
|
||||
<ng-container #componentViewContainer></ng-container>
|
||||
</div>
|
||||
<small *ngIf="hasHint && ((model.repeatable === false && (isRelationship === false || value?.value === null)) || (model.repeatable === true && context?.index === context?.context?.groups?.length - 1)) && (!showErrorMessages || errorMessages.length === 0)"
|
||||
class="text-muted ds-hint" [innerHTML]="model.hint | translate" [ngClass]="getClass('element', 'hint')"></small>
|
||||
<!-- In case of repeatable fields show empty space for all elements except the first -->
|
||||
<div *ngIf="context?.index !== null
|
||||
&& (!showErrorMessages || errorMessages.length === 0)" class="clearfix w-100 mb-2"></div>
|
||||
|
||||
<div *ngIf="showErrorMessages" [ngClass]="[getClass('element', 'errors'), getClass('grid', 'errors')]">
|
||||
<small *ngFor="let message of errorMessages" class="invalid-feedback d-block">{{ message | translate: model.validators }}</small>
|
||||
</div>
|
||||
<div *ngIf="showErrorMessages" [id]="id + '_errors'"
|
||||
[ngClass]="[getClass('element', 'errors'), getClass('grid', 'errors')]">
|
||||
<small *ngFor="let message of errorMessages" class="invalid-feedback d-block">{{ message | translate: model.validators }}</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div *ngIf="model.languageCodes && model.languageCodes.length > 0" class="col-xs-2" >
|
||||
<select
|
||||
#language="ngModel"
|
||||
[disabled]="model.readOnly"
|
||||
[(ngModel)]="model.language"
|
||||
class="form-control"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChangeLanguage($event)"
|
||||
[ngModelOptions]="{standalone: true}"
|
||||
required>
|
||||
<option *ngFor="let lang of model.languageCodes" [value]="lang.code">{{lang.display}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div *ngIf="isRelationship" class="col-auto text-center">
|
||||
<button class="btn btn-secondary"
|
||||
type="button"
|
||||
ngbTooltip="{{'form.lookup-help' | translate}}"
|
||||
placement="top"
|
||||
(click)="openLookup(); $event.stopPropagation();"><i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
|
||||
<ng-container *ngIf="value?.isVirtual">
|
||||
<ds-existing-metadata-list-element
|
||||
*ngIf="model.hasSelectableMetadata"
|
||||
[reoRel]="relationshipValue$ | async"
|
||||
[submissionItem]="item$ | async"
|
||||
[listId]="listId"
|
||||
[metadataFields]="model.metadataFields"
|
||||
[submissionId]="model.submissionId"
|
||||
[relationshipOptions]="model.relationship"
|
||||
(remove)="onRemove()"
|
||||
>
|
||||
</ds-existing-metadata-list-element>
|
||||
<ds-existing-relation-list-element
|
||||
*ngIf="!model.hasSelectableMetadata"
|
||||
[ngClass]="{'d-block pb-2 pt-2': !context?.index}"
|
||||
[reoRel]="relationshipValue$ | async"
|
||||
[submissionItem]="item$ | async"
|
||||
[listId]="listId"
|
||||
[metadataFields]="model.metadataFields"
|
||||
[submissionId]="model.submissionId"
|
||||
[relationshipOptions]="model.relationship"
|
||||
>
|
||||
</ds-existing-relation-list-element>
|
||||
<small *ngIf="hasHint && (model.repeatable === false || context?.index === context?.context?.groups?.length - 1) && (!showErrorMessages || errorMessages.length === 0)"
|
||||
class="text-muted ds-hint" [innerHTML]="model.hint | translate" [ngClass]="getClass('element', 'hint')"></small>
|
||||
<div class="clearfix w-100 mb-2"></div>
|
||||
</ng-container>
|
||||
<ng-content></ng-content>
|
||||
<div *ngIf="model.languageCodes && model.languageCodes.length > 0" class="col-xs-2" >
|
||||
<select
|
||||
#language="ngModel"
|
||||
[disabled]="model.readOnly"
|
||||
[(ngModel)]="model.language"
|
||||
class="form-control"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChangeLanguage($event)"
|
||||
[ngModelOptions]="{standalone: true}"
|
||||
required>
|
||||
<option *ngFor="let lang of model.languageCodes" [value]="lang.code">{{lang.display}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div *ngIf="isRelationship" class="col-auto text-center">
|
||||
<button class="btn btn-secondary"
|
||||
type="button"
|
||||
ngbTooltip="{{'form.lookup-help' | translate}}"
|
||||
placement="top"
|
||||
(click)="openLookup(); $event.stopPropagation();"><i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
|
||||
<ng-container *ngIf="value?.isVirtual">
|
||||
<ds-existing-metadata-list-element
|
||||
*ngIf="model.hasSelectableMetadata"
|
||||
[reoRel]="relationshipValue$ | async"
|
||||
[submissionItem]="item$ | async"
|
||||
[listId]="listId"
|
||||
[metadataFields]="model.metadataFields"
|
||||
[submissionId]="model.submissionId"
|
||||
[relationshipOptions]="model.relationship"
|
||||
(remove)="onRemove()"
|
||||
>
|
||||
</ds-existing-metadata-list-element>
|
||||
<ds-existing-relation-list-element
|
||||
*ngIf="!model.hasSelectableMetadata"
|
||||
[ngClass]="{'d-block pb-2 pt-2': !context?.index}"
|
||||
[reoRel]="relationshipValue$ | async"
|
||||
[submissionItem]="item$ | async"
|
||||
[listId]="listId"
|
||||
[metadataFields]="model.metadataFields"
|
||||
[submissionId]="model.submissionId"
|
||||
[relationshipOptions]="model.relationship"
|
||||
>
|
||||
</ds-existing-relation-list-element>
|
||||
<small *ngIf="hasHint && (model.repeatable === false || context?.index === context?.context?.groups?.length - 1) && (!showErrorMessages || errorMessages.length === 0)"
|
||||
class="text-muted ds-hint" [innerHTML]="model.hint | translate" [ngClass]="getClass('element', 'hint')"></small>
|
||||
<div class="clearfix w-100 mb-2"></div>
|
||||
</ng-container>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
||||
|
||||
|
@@ -1,50 +1,54 @@
|
||||
<div class="d-flex">
|
||||
<ds-number-picker
|
||||
tabindex="1"
|
||||
[disabled]="model.disabled"
|
||||
[min]="minYear"
|
||||
[max]="maxYear"
|
||||
[name]="'year'"
|
||||
[size]="4"
|
||||
[(ngModel)]="initialYear"
|
||||
[value]="year"
|
||||
[invalid]="showErrorMessages"
|
||||
[placeholder]='yearPlaceholder'
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
<div>
|
||||
<fieldset class="d-flex">
|
||||
<legend [id]="'legend_' + model.id" [ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]">
|
||||
{{model.placeholder}} <span *ngIf="model.required">*</span>
|
||||
</legend>
|
||||
<ds-number-picker
|
||||
tabindex="1"
|
||||
[disabled]="model.disabled"
|
||||
[min]="minYear"
|
||||
[max]="maxYear"
|
||||
[name]="'year'"
|
||||
[size]="4"
|
||||
[(ngModel)]="initialYear"
|
||||
[value]="year"
|
||||
[invalid]="showErrorMessages"
|
||||
[placeholder]='yearPlaceholder'
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
|
||||
<ds-number-picker
|
||||
tabindex="2"
|
||||
[min]="minMonth"
|
||||
[max]="maxMonth"
|
||||
[name]="'month'"
|
||||
[size]="6"
|
||||
[(ngModel)]="initialMonth"
|
||||
[value]="month"
|
||||
[placeholder]="monthPlaceholder"
|
||||
[disabled]="!year || model.disabled"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
|
||||
<ds-number-picker
|
||||
tabindex="3"
|
||||
[min]="minDay"
|
||||
[max]="maxDay"
|
||||
[name]="'day'"
|
||||
[size]="2"
|
||||
[(ngModel)]="initialDay"
|
||||
[value]="day"
|
||||
[placeholder]="dayPlaceholder"
|
||||
[disabled]="!month || model.disabled"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
<ds-number-picker
|
||||
tabindex="2"
|
||||
[min]="minMonth"
|
||||
[max]="maxMonth"
|
||||
[name]="'month'"
|
||||
[size]="6"
|
||||
[(ngModel)]="initialMonth"
|
||||
[value]="month"
|
||||
[placeholder]="monthPlaceholder"
|
||||
[disabled]="!year || model.disabled"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
|
||||
<ds-number-picker
|
||||
tabindex="3"
|
||||
[min]="minDay"
|
||||
[max]="maxDay"
|
||||
[name]="'day'"
|
||||
[size]="2"
|
||||
[(ngModel)]="initialDay"
|
||||
[value]="day"
|
||||
[placeholder]="dayPlaceholder"
|
||||
[disabled]="!month || model.disabled"
|
||||
(blur)="onBlur($event)"
|
||||
(change)="onChange($event)"
|
||||
(focus)="onFocus($event)"
|
||||
></ds-number-picker>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
@@ -1,3 +1,7 @@
|
||||
.col-lg-1 {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
legend {
|
||||
font-size: initial;
|
||||
}
|
||||
|
@@ -69,6 +69,7 @@ describe('DsDatePickerComponent test suite', () => {
|
||||
[bindId]='bindId'
|
||||
[group]='group'
|
||||
[model]='model'
|
||||
[legend]='legend'
|
||||
(blur)='onBlur($event)'
|
||||
(change)='onValueChange($event)'
|
||||
(focus)='onFocus($event)'></ds-date-picker>`;
|
||||
|
@@ -20,6 +20,7 @@ export class DsDatePickerComponent extends DynamicFormControlComponent implement
|
||||
@Input() bindId = true;
|
||||
@Input() group: FormGroup;
|
||||
@Input() model: DynamicDsDatePickerModel;
|
||||
@Input() legend: string;
|
||||
|
||||
@Output() selected = new EventEmitter<number>();
|
||||
@Output() remove = new EventEmitter<number>();
|
||||
|
@@ -1,24 +1,30 @@
|
||||
import {
|
||||
DynamicDateControlModel,
|
||||
DynamicDateControlModelConfig,
|
||||
DynamicDatePickerModelConfig,
|
||||
DynamicFormControlLayout,
|
||||
serializable
|
||||
} from '@ng-dynamic-forms/core';
|
||||
|
||||
export const DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER = 'DATE';
|
||||
|
||||
export interface DynamicDsDateControlModelConfig extends DynamicDatePickerModelConfig {
|
||||
legend?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic Date Picker Model class
|
||||
*/
|
||||
export class DynamicDsDatePickerModel extends DynamicDateControlModel {
|
||||
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER;
|
||||
malformedDate: boolean;
|
||||
legend: string;
|
||||
hasLanguages = false;
|
||||
repeatable = false;
|
||||
|
||||
constructor(config: DynamicDateControlModelConfig, layout?: DynamicFormControlLayout) {
|
||||
constructor(config: DynamicDsDateControlModelConfig, layout?: DynamicFormControlLayout) {
|
||||
super(config, layout);
|
||||
this.malformedDate = false;
|
||||
this.legend = config.legend;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,13 @@
|
||||
<div #sdRef="ngbDropdown" ngbDropdown display="dynamic" placement="bottom-right" class="w-100">
|
||||
<div class="position-relative right-addon">
|
||||
<div class="position-relative right-addon"
|
||||
role="combobox"
|
||||
[attr.aria-label]="model.label"
|
||||
[attr.aria-owns]="'combobox_' + id + '_listbox'">
|
||||
<i ngbDropdownToggle class="position-absolute scrollable-dropdown-toggle"
|
||||
aria-hidden="true"></i>
|
||||
<input class="form-control"
|
||||
[attr.aria-controls]="'combobox_' + id + '_listbox'"
|
||||
[attr.aria-activedescendant]="'combobox_' + id + '_selected'"
|
||||
[attr.aria-label]="model.placeholder"
|
||||
[attr.autoComplete]="model.autoComplete"
|
||||
[class.is-invalid]="showErrorMessages"
|
||||
@@ -24,6 +29,8 @@
|
||||
aria-expanded="false"
|
||||
[attr.aria-label]="model.placeholder">
|
||||
<div class="scrollable-menu"
|
||||
role="listbox"
|
||||
[id]="'combobox_' + id + '_listbox'"
|
||||
[attr.aria-label]="model.placeholder"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
@@ -32,7 +39,10 @@
|
||||
[scrollWindow]="false">
|
||||
|
||||
<button class="dropdown-item disabled" *ngIf="optionsList && optionsList.length == 0">{{'form.no-results' | translate}}</button>
|
||||
<button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList" (click)="onSelect(listEntry); sdRef.close()" title="{{ listEntry.display }}">
|
||||
<button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList"
|
||||
(click)="onSelect(listEntry); sdRef.close()"
|
||||
title="{{ listEntry.display }}" role="option"
|
||||
[attr.id]="listEntry.display == (currentValue|async) ? ('combobox_' + id + '_selected') : null">
|
||||
{{inputFormatter(listEntry)}}
|
||||
</button>
|
||||
<div class="scrollable-dropdown-loading text-center" *ngIf="loading"><p>{{'form.loading' | translate}}</p></div>
|
||||
@@ -40,5 +50,3 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import { FieldParser } from './field-parser';
|
||||
import { DynamicDatePickerModelConfig } from '@ng-dynamic-forms/core';
|
||||
import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model';
|
||||
import {
|
||||
DynamicDsDateControlModelConfig,
|
||||
DynamicDsDatePickerModel
|
||||
} from '../ds-dynamic-form-ui/models/date-picker/date-picker.model';
|
||||
import { isNotEmpty } from '../../../empty.util';
|
||||
import { DS_DATE_PICKER_SEPARATOR } from '../ds-dynamic-form-ui/models/date-picker/date-picker.component';
|
||||
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
|
||||
@@ -9,7 +11,8 @@ export class DateFieldParser extends FieldParser {
|
||||
|
||||
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
|
||||
let malformedDate = false;
|
||||
const inputDateModelConfig: DynamicDatePickerModelConfig = this.initModel(null, label);
|
||||
const inputDateModelConfig: DynamicDsDateControlModelConfig = this.initModel(null, false, true);
|
||||
inputDateModelConfig.legend = this.configData.label;
|
||||
|
||||
inputDateModelConfig.toggleIcon = 'fas fa-calendar';
|
||||
this.setValues(inputDateModelConfig as any, fieldValue);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<div class="d-flex flex-column align-items-center justify-content-around mr-3">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
class="btn btn-link-focus"
|
||||
type="button"
|
||||
tabindex="0"
|
||||
[disabled]="disabled"
|
||||
@@ -25,7 +25,7 @@
|
||||
aria-label="name"
|
||||
>
|
||||
<button
|
||||
class="btn btn-link"
|
||||
class="btn btn-link-focus"
|
||||
type="button"
|
||||
tabindex="0"
|
||||
[disabled]="disabled"
|
||||
|
@@ -23,3 +23,24 @@
|
||||
input {
|
||||
max-width: 80px !important;
|
||||
}
|
||||
|
||||
.btn-link-focus {
|
||||
// behave as btn-link but does not override box-shadow of btn-link:focus
|
||||
font-weight: $font-weight-normal;
|
||||
color: $link-color;
|
||||
text-decoration: $link-decoration;
|
||||
@include hover {
|
||||
color: $link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $btn-link-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
export const mockDynamicFormLayoutService = jasmine.createSpyObj('DynamicFormLayoutService', {
|
||||
getElementId: jasmine.createSpy('getElementId')
|
||||
getElementId: jasmine.createSpy('getElementId'),
|
||||
getClass: 'class',
|
||||
});
|
||||
|
||||
export const mockDynamicFormValidationService = jasmine.createSpyObj('DynamicFormValidationService', {
|
||||
|
@@ -19,11 +19,14 @@
|
||||
(fileOver)="fileOverBase($event)"
|
||||
class="well ds-base-drop-zone mt-1 mb-3 text-muted">
|
||||
<div class="text-center m-0 p-2 d-flex justify-content-center align-items-center" *ngIf="uploader?.queue?.length === 0">
|
||||
<span><i class="fas fa-upload" aria-hidden="true"></i> {{dropMsg | translate}} {{'uploader.or' | translate}}</span>
|
||||
<label for="inputFileUploader" class="btn btn-link m-0 p-0 ml-1" tabindex="0" (keyup.enter)="$event.stopImmediatePropagation(); fileInput.click()">
|
||||
<input #fileInput id="inputFileUploader" class="d-none" type="file" role="button" ng2FileSelect [uploader]="uploader" multiple tabindex="0" />
|
||||
{{'uploader.browse' | translate}}
|
||||
</label>
|
||||
<span>
|
||||
<i class="fas fa-upload" aria-hidden="true"></i>
|
||||
{{dropMsg | translate}}{{'uploader.or' | translate}}
|
||||
<label for="inputFileUploader" class="btn btn-link m-0 p-0 ml-1" tabindex="0" (keyup.enter)="$event.stopImmediatePropagation(); fileInput.click()">
|
||||
<span role="button" [attr.aria-label]="'uploader.browse' | translate">{{'uploader.browse' | translate}}</span>
|
||||
</label>
|
||||
<input #fileInput id="inputFileUploader" class="d-none" type="file" ng2FileSelect [uploader]="uploader" multiple tabindex="0" />
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="(isOverBaseDropZone | async) || uploader?.queue?.length !== 0">
|
||||
<div class="m-1">
|
||||
|
@@ -17,3 +17,23 @@
|
||||
z-index: var(--ds-submission-footer-z-index);
|
||||
}
|
||||
|
||||
.btn-link-focus {
|
||||
// behave as btn-link but does not override box-shadow of btn-link:focus
|
||||
font-weight: $font-weight-normal;
|
||||
color: $link-color;
|
||||
text-decoration: $link-decoration;
|
||||
@include hover {
|
||||
color: $link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $btn-link-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
}
|
||||
|
@@ -15,15 +15,15 @@
|
||||
<span class="float-left section-title" tabindex="0">{{ 'submission.sections.'+sectionData.header | translate }}</span>
|
||||
<div class="d-inline-block float-right">
|
||||
<i *ngIf="!(sectionRef.isValid() | async) && !(sectionRef.hasErrors())" class="fas fa-exclamation-circle text-warning mr-3"
|
||||
aria-hidden="true" title="{{'submission.sections.status.warnings.title' | translate}}"></i>
|
||||
title="{{'submission.sections.status.warnings.title' | translate}}" role="img" [attr.aria-label]="'submission.sections.status.warnings.aria' | translate"></i>
|
||||
<i *ngIf="(sectionRef.hasErrors())" class="fas fa-exclamation-circle text-danger mr-3"
|
||||
aria-hidden="true" title="{{'submission.sections.status.errors.title' | translate}}"></i>
|
||||
title="{{'submission.sections.status.errors.title' | translate}}" role="img" [attr.aria-label]="'submission.sections.status.errors.aria' | translate"></i>
|
||||
<i *ngIf="(sectionRef.isValid() | async) && !(sectionRef.hasErrors())" class="fas fa-check-circle text-success mr-3"
|
||||
aria-hidden="true" title="{{'submission.sections.status.valid.title' | translate}}"></i>
|
||||
title="{{'submission.sections.status.valid.title' | translate}}" role="img" [attr.aria-label]="'submission.sections.status.valid.aria' | translate"></i>
|
||||
<a class="close"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
[attr.aria-label]="(sectionRef.isOpen() ? 'submission.sections.toggle.close' : 'submission.sections.toggle.open') | translate"
|
||||
[attr.aria-label]="(sectionRef.isOpen() ? 'submission.sections.toggle.aria.close' : 'submission.sections.toggle.aria.open') | translate: {sectionHeader: ('submission.sections.'+sectionData.header | translate)}"
|
||||
[title]="(sectionRef.isOpen() ? 'submission.sections.toggle.close' : 'submission.sections.toggle.open') | translate">
|
||||
<span *ngIf="sectionRef.isOpen()" class="fas fa-chevron-up fa-fw"></span>
|
||||
<span *ngIf="!sectionRef.isOpen()" class="fas fa-chevron-down fa-fw"></span>
|
||||
|
@@ -74,7 +74,7 @@ export const BITSTREAM_FORM_ACCESS_CONDITION_START_DATE_CONFIG: DynamicDatePicke
|
||||
required: null
|
||||
},
|
||||
errorMessages: {
|
||||
required: 'submission.sections.upload.form.date-required'
|
||||
required: 'submission.sections.upload.form.date-required-from'
|
||||
}
|
||||
};
|
||||
export const BITSTREAM_FORM_ACCESS_CONDITION_START_DATE_LAYOUT: DynamicFormControlLayout = {
|
||||
@@ -104,7 +104,7 @@ export const BITSTREAM_FORM_ACCESS_CONDITION_END_DATE_CONFIG: DynamicDatePickerM
|
||||
required: null
|
||||
},
|
||||
errorMessages: {
|
||||
required: 'submission.sections.upload.form.date-required'
|
||||
required: 'submission.sections.upload.form.date-required-until'
|
||||
}
|
||||
};
|
||||
export const BITSTREAM_FORM_ACCESS_CONDITION_END_DATE_LAYOUT: DynamicFormControlLayout = {
|
||||
|
@@ -10,16 +10,16 @@
|
||||
</div>
|
||||
<div class="float-right w-15" [class.sticky-buttons]="!readMode">
|
||||
<ng-container *ngIf="readMode">
|
||||
<ds-file-download-link [cssClasses]="'btn btn-link'" [isBlank]="true" [bitstream]="getBitstream()">
|
||||
<ds-file-download-link [cssClasses]="'btn btn-link-focus'" [isBlank]="true" [bitstream]="getBitstream()">
|
||||
<i class="fa fa-download fa-2x text-normal" aria-hidden="true"></i>
|
||||
</ds-file-download-link>
|
||||
<button class="btn btn-link"
|
||||
<button class="btn btn-link-focus"
|
||||
[attr.aria-label]="'submission.sections.upload.edit.title' | translate"
|
||||
title="{{ 'submission.sections.upload.edit.title' | translate }}"
|
||||
(click)="$event.preventDefault();switchMode();">
|
||||
<i class="fa fa-edit fa-2x text-normal"></i>
|
||||
</button>
|
||||
<button class="btn btn-link"
|
||||
<button class="btn btn-link-focus"
|
||||
[attr.aria-label]="'submission.sections.upload.delete.confirm.title' | translate"
|
||||
title="{{ 'submission.sections.upload.delete.confirm.title' | translate }}"
|
||||
[disabled]="(processingDelete$ | async)"
|
||||
@@ -29,17 +29,17 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!readMode">
|
||||
<button class="btn btn-link"
|
||||
<button class="btn btn-link-focus"
|
||||
[attr.aria-label]="'submission.sections.upload.save-metadata' | translate"
|
||||
title="{{ 'submission.sections.upload.save-metadata' | translate }}"
|
||||
(click)="saveBitstreamData($event);">
|
||||
<i class="fa fa-save fa-2x text-success"></i>
|
||||
</button>
|
||||
<button class="btn btn-link"
|
||||
<button class="btn btn-link-focus"
|
||||
[attr.aria-label]="'submission.sections.upload.undo' | translate"
|
||||
title="{{ 'submission.sections.upload.undo' | translate }}"
|
||||
(click)="$event.preventDefault();switchMode();"><i class="fa fa-ban fa-2x text-warning"></i></button>
|
||||
<button class="btn btn-link"
|
||||
<button class="btn btn-link-focus"
|
||||
[attr.aria-label]="'submission.sections.upload.delete.confirm.title' | translate"
|
||||
title="{{ 'submission.sections.upload.delete.confirm.title' | translate }}"
|
||||
[disabled]="(processingDelete$ | async)"
|
||||
|
@@ -3606,10 +3606,20 @@
|
||||
|
||||
"submission.sections.status.warnings.title": "Warnings",
|
||||
|
||||
"submission.sections.status.errors.aria": "has errors",
|
||||
|
||||
"submission.sections.status.valid.aria": "is valid",
|
||||
|
||||
"submission.sections.status.warnings.aria": "has warnings",
|
||||
|
||||
"submission.sections.toggle.open": "Open section",
|
||||
|
||||
"submission.sections.toggle.close": "Close section",
|
||||
|
||||
"submission.sections.toggle.aria.open": "Expand {{sectionHeader}} section",
|
||||
|
||||
"submission.sections.toggle.aria.close": "Collapse {{sectionHeader}} section",
|
||||
|
||||
"submission.sections.upload.delete.confirm.cancel": "Cancel",
|
||||
|
||||
"submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?",
|
||||
@@ -3630,6 +3640,10 @@
|
||||
|
||||
"submission.sections.upload.form.date-required": "Date is required.",
|
||||
|
||||
"submission.sections.upload.form.date-required-from": "Grant access from date is required.",
|
||||
|
||||
"submission.sections.upload.form.date-required-until": "Grant access until date is required.",
|
||||
|
||||
"submission.sections.upload.form.from-label": "Grant access from",
|
||||
|
||||
"submission.sections.upload.form.from-placeholder": "From",
|
||||
|
Reference in New Issue
Block a user