Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 0 additions & 324 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
take,
tap,
} from 'rxjs/operators';
import { ALTERNATIVE_CONTENT_TAG } from 'src/app/submission/sections/upload/section-upload-constants';

import { getEntityEditRoute } from '../../item-page/item-page-routing-paths';
import { ErrorComponent } from '../../shared/error/error.component';
Expand Down Expand Up @@ -193,6 +194,15 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
},
);

/**
* The Dynamic Switch Model for set as alternative content
*/
alternativeContentModel = new DynamicCustomSwitchModel({
id: 'alternativeContent',
name: 'alternativeContent',
},
);

/**
* The Dynamic TextArea Model for the file's description
*/
Expand Down Expand Up @@ -311,7 +321,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
/**
* All input models in a simple array for easier iterations
*/
inputModels = [this.primaryBitstreamModel, this.fileNameModel, this.descriptionModel, this.selectedFormatModel,
inputModels = [this.primaryBitstreamModel, this.alternativeContentModel, this.fileNameModel, this.descriptionModel, this.selectedFormatModel,
this.newFormatModel];

/**
Expand All @@ -323,6 +333,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
id: 'fileNamePrimaryContainer',
group: [
this.primaryBitstreamModel,
this.alternativeContentModel,
this.fileNameModel,
],
}, {
Expand Down Expand Up @@ -367,6 +378,14 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
container: 'text-right',
},
},
alternativeContent: {
grid: {
container: 'col-12 mt-2',
},
element: {
container: 'text-right',
},
},
description: {
grid: {
host: 'col-12 d-inline-block',
Expand Down Expand Up @@ -543,6 +562,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
fileNamePrimaryContainer: {
fileName: bitstream.name,
primaryBitstream: this.primaryBitstreamUUID === bitstream.uuid,
alternativeContent: bitstream.firstMetadataValue('dspace.bitstream.type') === ALTERNATIVE_CONTENT_TAG,
},
descriptionContainer: {
description: bitstream.firstMetadataValue('dc.description'),
Expand Down Expand Up @@ -609,7 +629,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
*/
private updateFieldTranslation(fieldModel) {
fieldModel.label = this.translate.instant(this.KEY_PREFIX + fieldModel.id + this.LABEL_KEY_SUFFIX);
if (fieldModel.id !== this.primaryBitstreamModel.id) {
if (fieldModel.id !== this.primaryBitstreamModel.id && fieldModel.id !== this.alternativeContentModel.id) {
fieldModel.hint = this.translate.instant(this.KEY_PREFIX + fieldModel.id + this.HINT_KEY_SUFFIX);
}
}
Expand All @@ -635,6 +655,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
const isNewFormat = this.selectedFormat.id !== this.originalFormat.id;
const isPrimary = updatedValues.fileNamePrimaryContainer.primaryBitstream;
const wasPrimary = this.primaryBitstreamUUID === this.bitstream.uuid;
const isAlternativeContent = updatedValues.fileNamePrimaryContainer.alternativeContent;

let bitstream$;
let bundle$: Observable<Bundle>;
Expand Down Expand Up @@ -700,6 +721,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
} else {
bitstream$ = of(this.bitstream);
}
if (isAlternativeContent) {
updatedBitstream.setMetadata('dspace.bitstream.type', undefined, ...[ALTERNATIVE_CONTENT_TAG]);
} else {
updatedBitstream.removeMetadata('dspace.bitstream.type');
}

combineLatest([bundle$, bitstream$]).pipe(
tap(([bundle]) => this.bundle = bundle),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
<div class="file-section">
@for (file of bitstreams; track file; let last = $last) {
<ds-file-download-link [bitstream]="file" [item]="item">
<span>
@if (primaryBitstreamId === file.id) {
<span class="badge bg-primary">{{ 'item.page.bitstreams.primary' | translate }}</span>
}
{{ dsoNameService.getName(file) }}
</span>
<span>
@if (primaryBitstreamId === file.id) {
<span class="badge bg-primary">{{ 'item.page.bitstreams.primary' | translate }}</span>
}
@if (file.metadata['dspace.bitstream.type']?.[0]?.value === alternativeContentTag) {
<span class="badge bg-warning">{{ 'item.page.bitstreams.alternativeContent' | translate }}</span>
}
{{ dsoNameService.getName(file) }}
</span>
<span> ({{(file?.sizeBytes) | dsFileSize }})</span>
@if (!last) {
<span innerHTML="{{separator}}"></span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
TranslateService,
} from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs';
import { ALTERNATIVE_CONTENT_TAG } from 'src/app/submission/sections/upload/section-upload-constants';

import { ThemedFileDownloadLinkComponent } from '../../../../shared/file-download-link/themed-file-download-link.component';
import { ThemedLoadingComponent } from '../../../../shared/loading/themed-loading.component';
Expand Down Expand Up @@ -68,6 +69,11 @@ export class FileSectionComponent implements OnInit {

primaryBitstreamId: string;

/**
* Alternative content tag variable, this variable is only used to make tag available in HTMl
*/
public alternativeContentTag: string = ALTERNATIVE_CONTENT_TAG;

constructor(
protected bitstreamDataService: BitstreamDataService,
protected notificationsService: NotificationsService,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div [formGroup]="group" [ngClass]="getClass('element', 'container')" class="form-check custom-control form-switch" [class.disabled]="model.disabled">
<div [formGroup]="group" [ngClass]="getClass('element', 'container')" class="form-check form-switch" [class.disabled]="model.disabled">
<input type="checkbox" class="form-check-input form-check-input"
[checked]="model.checked"
[class.is-invalid]="showErrorMessages"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.form-check-input {
appearance: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,15 @@ describe('SubmissionSectionUploadFileEditComponent test suite', () => {

comp.formModel = compAsAny.buildFileEditForm();

const models = [DynamicCustomSwitchModel, DynamicFormGroupModel, DynamicFormArrayModel];
const models = [DynamicCustomSwitchModel, DynamicCustomSwitchModel, DynamicFormGroupModel, DynamicFormArrayModel];

expect(comp.formModel).toBeDefined();
expect(comp.formModel.length).toBe(models.length);
models.forEach((model, i) => {
expect(comp.formModel[i] instanceof model).toBeTruthy();
});

expect((comp.formModel[2] as DynamicFormArrayModel).groups.length).toBe(2);
expect((comp.formModel[3] as DynamicFormArrayModel).groups.length).toBe(2);
const startDateModel = formbuilderService.findById('startDate', comp.formModel);
expect(startDateModel.max).toEqual(maxStartDate);
const endDateModel = formbuilderService.findById('endDate', comp.formModel);
Expand Down Expand Up @@ -303,6 +303,7 @@ describe('SubmissionSectionUploadFileEditComponent test suite', () => {
compAsAny.fileData = fileData;
compAsAny.pathCombiner = pathCombiner;
compAsAny.isPrimary = null;
compAsAny.isAlternativeContent = null;
formService.validateAllFormFields.and.callFake(() => null);
formService.isValid.and.returnValue(of(true));
formService.getFormData.and.returnValue(of(mockFileFormData));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
mergeMap,
take,
} from 'rxjs/operators';
import { MetadataValue } from 'src/app/core/shared/metadata.models';
import { DynamicCustomSwitchModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model';

import { BtnDisabledDirective } from '../../../../../shared/btn-disabled.directive';
Expand All @@ -51,7 +52,10 @@ import { FormComponent } from '../../../../../shared/form/form.component';
import { FormService } from '../../../../../shared/form/form.service';
import { SubmissionService } from '../../../../submission.service';
import { SectionUploadService } from '../../section-upload.service';
import { POLICY_DEFAULT_WITH_LIST } from '../../section-upload-constants';
import {
ALTERNATIVE_CONTENT_TAG,
POLICY_DEFAULT_WITH_LIST,
} from '../../section-upload-constants';
import {
BITSTREAM_ACCESS_CONDITION_GROUP_CONFIG,
BITSTREAM_ACCESS_CONDITION_GROUP_LAYOUT,
Expand All @@ -63,6 +67,8 @@ import {
BITSTREAM_FORM_ACCESS_CONDITION_START_DATE_LAYOUT,
BITSTREAM_FORM_ACCESS_CONDITION_TYPE_CONFIG,
BITSTREAM_FORM_ACCESS_CONDITION_TYPE_LAYOUT,
BITSTREAM_FORM_ALTERNATIVE_CONTENT,
BITSTREAM_FORM_ALTERNATIVE_CONTENT_LAYOUT,
BITSTREAM_FORM_PRIMARY,
BITSTREAM_FORM_PRIMARY_LAYOUT,
BITSTREAM_METADATA_FORM_GROUP_CONFIG,
Expand Down Expand Up @@ -97,6 +103,12 @@ implements OnInit, OnDestroy {
*/
isPrimary: boolean;

/**
* The indicator if is alternative content bitstream
* @type {boolean, null}
*/
isAlternativeContent: boolean;

/**
* The list of available access condition
* @type {Array}
Expand Down Expand Up @@ -218,6 +230,9 @@ implements OnInit, OnDestroy {
const primaryBitstreamModel: any = this.formBuilderService.findById('primary', formModel, this.fileIndex);
primaryBitstreamModel.value = this.isPrimary || false;

const alternativeContentBitstreamModel: any = this.formBuilderService.findById('alternativeContent', formModel, this.fileIndex);
alternativeContentBitstreamModel.value = this.isAlternativeContent || false;

this.fileData.accessConditions.forEach((accessCondition, index) => {
Array.of('name', 'startDate', 'endDate')
.filter((key) => accessCondition.hasOwnProperty(key) && isNotEmpty(accessCondition[key]))
Expand Down Expand Up @@ -317,10 +332,13 @@ implements OnInit, OnDestroy {
configDescr,
]),
});
configForm.rows = configForm.rows.filter((row: any) => row.fields[0].selectableMetadata[0].metadata !== 'dc.type');
const formModel: DynamicFormControlModel[] = [];

formModel.push(new DynamicCustomSwitchModel(BITSTREAM_FORM_PRIMARY, BITSTREAM_FORM_PRIMARY_LAYOUT));

formModel.push(new DynamicCustomSwitchModel(BITSTREAM_FORM_ALTERNATIVE_CONTENT, BITSTREAM_FORM_ALTERNATIVE_CONTENT_LAYOUT));

const metadataGroupModelConfig = Object.assign({}, BITSTREAM_METADATA_FORM_GROUP_CONFIG);
metadataGroupModelConfig.group = this.formBuilderService.modelFromConfiguration(
this.submissionId,
Expand Down Expand Up @@ -434,22 +452,40 @@ implements OnInit, OnDestroy {
mergeMap((formData: any) => {
this.uploadService.updatePrimaryBitstreamOperation(this.pathCombiner.getPath('primary'), this.isPrimary, formData.primary[0], this.fileId);

//Set operations to bitstream alternative content flag
const alternativeContentPath = 'metadata/dspace.bitstream.type';
if (formData.alternativeContent[0]) {
const metadata = Object.assign(new MetadataValue(), {
language: null,
value: ALTERNATIVE_CONTENT_TAG,
authority: null,
place: 0,
});
this.operationsBuilder.add(this.pathCombiner.getPath([...pathFragment, alternativeContentPath]), metadata, true);
} else {
this.operationsBuilder.remove(this.pathCombiner.getPath([...pathFragment, alternativeContentPath]));
}

// collect bitstream metadata
Object.keys((formData.metadata))
.filter((key) => isNotEmpty(formData.metadata[key]))
.forEach((key) => {
const metadataKey = key.replace(/_/g, '.');
const path = `metadata/${metadataKey}`;
this.operationsBuilder.add(this.pathCombiner.getPath([...pathFragment, path]), formData.metadata[key], true);
if (metadataKey !== 'dc.type') {
const path = `metadata/${metadataKey}`;
this.operationsBuilder.add(this.pathCombiner.getPath([...pathFragment, path]), formData.metadata[key], true);
}
});
Object.keys((this.fileData.metadata))
.filter((key) => isNotEmpty(this.fileData.metadata[key]))
.filter((key) => hasNoValue(formData.metadata[key]))
.filter((key) => this.formMetadata.includes(key))
.forEach((key) => {
const metadataKey = key.replace(/_/g, '.');
const path = `metadata/${metadataKey}`;
this.operationsBuilder.remove(this.pathCombiner.getPath([...pathFragment, path]));
if (metadataKey !== 'dc.type') {
const path = `metadata/${metadataKey}`;
this.operationsBuilder.remove(this.pathCombiner.getPath([...pathFragment, path]));
}
});
const accessConditionsToSave = [];
if (formData.hasOwnProperty('accessConditions')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ export const BITSTREAM_FORM_PRIMARY: DynamicSwitchModelConfig = {
label: 'bitstream.edit.form.primaryBitstream.label',
};

export const BITSTREAM_FORM_ALTERNATIVE_CONTENT_LAYOUT: DynamicFormControlLayout = {
element: {
host: 'col-12',
container: 'text-right',
},
};

export const BITSTREAM_FORM_ALTERNATIVE_CONTENT: DynamicSwitchModelConfig = {
id: 'alternativeContent',
name: 'alternativeContent',
label: 'bitstream.edit.form.alternativeContent.label',
};


export const BITSTREAM_FORM_ACCESS_CONDITION_START_DATE_CONFIG: DynamicDatePickerModelConfig = {
id: 'startDate',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<input
type="checkbox"
class="form-check-input"
role="switch"
id="primaryBitstream{{fileIndex}}"
[disabled]="processingSaveStatus$ | async"
[checked]="isPrimary"
Expand All @@ -24,31 +25,29 @@
<div class="float-start w-75">
<ds-submission-section-upload-file-view [fileData]="fileData"></ds-submission-section-upload-file-view>
</div>
<div class="float-end w-15">
<ng-container>
<ds-file-download-link [cssClasses]="'btn btn-link-focus'" [isBlank]="true"
[bitstream]="getBitstream()" [enableRequestACopy]="false" [showAccessStatusBadge]="false">
<i class="fa fa-download fa-2x text-normal" aria-hidden="true"></i>
</ds-file-download-link>
<button class="btn btn-link-focus"
attr.aria-label="{{'submission.sections.upload.edit.title' | translate}} {{fileName}}"
title="{{ 'submission.sections.upload.edit.title' | translate }} {{fileName}}"
(click)="$event.preventDefault();editBitstreamData();">
<i class="fa fa-edit fa-2x text-normal"></i>
</button>
<button class="btn btn-link-focus"
attr.aria-label="{{'submission.sections.upload.delete.confirm.title' | translate}} {{fileName}}"
title="{{ 'submission.sections.upload.delete.confirm.title' | translate }} {{fileName}}"
[dsBtnDisabled]="(processingDelete$ | async)"
(click)="$event.preventDefault();confirmDelete(content);">
@if ((processingDelete$ | async)) {
<i class="fas fa-circle-notch fa-spin fa-2x link-danger"></i>
}
@if ((processingDelete$ | async) !== true) {
<i class="fa fa-trash fa-2x link-danger"></i>
}
</button>
</ng-container>
<div class="float-end w-15 d-flex flex-row justify-content-center align-items-center h-100">
<ds-file-download-link [cssClasses]="'btn btn-link-focus'" [isBlank]="true"
[bitstream]="getBitstream()" [enableRequestACopy]="false" [showAccessStatusBadge]="false">
<i class="fa fa-download fa-2x text-normal" aria-hidden="true"></i>
</ds-file-download-link>
<button class="btn btn-link-focus"
attr.aria-label="{{'submission.sections.upload.edit.title' | translate}} {{fileName}}"
title="{{ 'submission.sections.upload.edit.title' | translate }} {{fileName}}"
(click)="$event.preventDefault();editBitstreamData();">
<i class="fa fa-edit fa-2x text-normal"></i>
</button>
<button class="btn btn-link-focus"
attr.aria-label="{{'submission.sections.upload.delete.confirm.title' | translate}} {{fileName}}"
title="{{ 'submission.sections.upload.delete.confirm.title' | translate }} {{fileName}}"
[dsBtnDisabled]="(processingDelete$ | async)"
(click)="$event.preventDefault();confirmDelete(content);">
@if ((processingDelete$ | async)) {
<i class="fas fa-circle-notch fa-spin fa-2x link-danger"></i>
}
@if ((processingDelete$ | async) !== true) {
<i class="fa fa-trash fa-2x link-danger"></i>
}
</button>
</div>
<div class="clearfix"></div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* this line ensures that switch-style checks are displayed correctly, added here to only affects upload-file-section */
.form-check-input {
appearance: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
*/
@Input() isPrimary: boolean | null;

/**
* The indicator if is alternative content bitstream
* @type {boolean, null}
*/
@Input() isAlternativeContent: boolean | null;

/**
* The list of available access condition
* @type {Array}
Expand Down Expand Up @@ -282,6 +288,7 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
activeModal.componentInstance.pathCombiner = this.pathCombiner;
activeModal.componentInstance.submissionId = this.submissionId;
activeModal.componentInstance.isPrimary = this.isPrimary;
activeModal.componentInstance.isAlternativeContent = this.isAlternativeContent;
}

togglePrimaryBitstream(event) {
Expand Down
Loading
Loading