Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ import {
SetSelectedPreprintFileSource,
UploadFile,
} from '@osf/features/preprints/store/preprint-stepper';
import { FilesTreeActions } from '@osf/features/project/files/models';
import { FilesTreeComponent, IconComponent } from '@shared/components';
import { OsfFile } from '@shared/models';
import { FilesTreeActions, OsfFile } from '@shared/models';
import { CustomConfirmationService, ToastService } from '@shared/services';

@Component({
Expand Down
1 change: 0 additions & 1 deletion src/app/features/project/files/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@ export * from './data/embed-content.const';
export * from './data/file-provider.const';
export * from './data/project-files-state-defaults.const';
export * from './files-metadata-fields';
export * from './files-tree-actions.interface';
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';

import { CreateFolderDialogComponent } from '@osf/features/project/files/components';
import { FilesTreeActions } from '@osf/features/project/files/models';
import {
CreateFolder,
DeleteEntry,
Expand All @@ -55,7 +54,7 @@ import {
SearchInputComponent,
SubHeaderComponent,
} from '@shared/components';
import { ConfiguredStorageAddon, OsfFile } from '@shared/models';
import { ConfiguredStorageAddon, FilesTreeActions, OsfFile } from '@shared/models';
import { FilesService } from '@shared/services';

@Component({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,29 @@ <h3 class="mb-2">
}
}
@case (FieldType.File) {
<h3 class="mb-2">Upload File</h3>
<h3 class="mb-2">{{ 'project.files.actions.uploadFile' | translate }}</h3>
<p class="mb-1">
You may attach up to 5 file(s) to this question. Files cannot total over 5GB in size.
{{ 'shared.files.limitText' | translate }}
</p>
<p>
Uploaded files will automatically be archived in this registration. They will also be added to a
related project that will be created for this registration.
{{ 'shared.files.description' | translate }}
</p>

<p>File input is not implemented yet.</p>
<div class="flex flex-wrap gap-2 mt-3 mb-3">
@for (file of attachedFiles[question.responseKey!] || []; track file) {
<p-chip
[label]="file.name"
severity="info"
removable="true"
(onRemove)="removeFromAttachedFiles(file, question.responseKey!)"
/>
}
</div>
<div class="-ml-3 -mr-3">
<osf-files-control
[attachedFiles]="attachedFiles[question.responseKey!]"
(attachFile)="onAttachFile($event, question.responseKey!)"
></osf-files-control>
</div>
}
}
</p-card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TranslatePipe } from '@ngx-translate/core';
import { Button } from 'primeng/button';
import { Card } from 'primeng/card';
import { Checkbox } from 'primeng/checkbox';
import { Chip } from 'primeng/chip';
import { Inplace } from 'primeng/inplace';
import { InputText } from 'primeng/inputtext';
import { Message } from 'primeng/message';
Expand All @@ -19,11 +20,14 @@ import { ActivatedRoute, Router } from '@angular/router';

import { InfoIconComponent } from '@osf/shared/components';
import { INPUT_VALIDATION_MESSAGES } from '@osf/shared/constants';
import { FilePayloadJsonApi, OsfFile } from '@osf/shared/models';
import { CustomValidators, findChangedFields } from '@osf/shared/utils';

import { FieldType } from '../../enums';
import { FilesMapper } from '../../mappers/files.mapper';
import { PageSchema } from '../../models';
import { RegistriesSelectors, UpdateDraft, UpdateStepValidation } from '../../store';
import { FilesControlComponent } from '../files-control/files-control.component';

@Component({
selector: 'osf-custom-step',
Expand All @@ -42,6 +46,8 @@ import { RegistriesSelectors, UpdateDraft, UpdateStepValidation } from '../../st
Button,
ReactiveFormsModule,
Message,
FilesControlComponent,
Chip,
],
templateUrl: './custom-step.component.html',
styleUrl: './custom-step.component.scss',
Expand Down Expand Up @@ -71,6 +77,8 @@ export class CustomStepComponent implements OnDestroy {

stepForm!: FormGroup;

attachedFiles: Record<string, Partial<OsfFile>[]> = {};

constructor() {
this.route.params.pipe(takeUntilDestroyed()).subscribe((params) => {
this.updateStepState();
Expand Down Expand Up @@ -113,6 +121,14 @@ export class CustomStepComponent implements OnDestroy {
});
break;

case FieldType.File:
control = this.fb.control(this.stepsData()[controlName] || [], {
validators: q.required ? [Validators.required] : [],
});
this.attachedFiles[controlName] =
this.stepsData()[controlName]?.map((file: FilePayloadJsonApi) => ({ ...file, name: file.file_name })) || [];
break;

default:
console.warn(`Unsupported field type: ${q.fieldType}`);
return;
Expand Down Expand Up @@ -144,6 +160,35 @@ export class CustomStepComponent implements OnDestroy {
}
}

onAttachFile(file: OsfFile, questionKey: string): void {
this.attachedFiles[questionKey] = this.attachedFiles[questionKey] || [];
if (!this.attachedFiles[questionKey].some((f) => f.id === file.id)) {
this.attachedFiles[questionKey].push(file);
this.stepForm.patchValue({
[questionKey]: [...(this.attachedFiles[questionKey] || []), file],
});
this.actions.updateDraft(this.route.snapshot.params['id'], {
registration_responses: {
[questionKey]: [...this.attachedFiles[questionKey].map((f) => FilesMapper.toFilePayload(f as OsfFile))],
},
});
}
}

removeFromAttachedFiles(file: Partial<OsfFile>, questionKey: string): void {
if (this.attachedFiles[questionKey]) {
this.attachedFiles[questionKey] = this.attachedFiles[questionKey].filter((f) => f.id !== file.id);
this.stepForm.patchValue({
[questionKey]: this.attachedFiles[questionKey],
});
this.actions.updateDraft(this.route.snapshot.params['id'], {
registration_responses: {
[questionKey]: [...this.attachedFiles[questionKey].map((f) => FilesMapper.toFilePayload(f as OsfFile))],
},
});
}
}

goBack(): void {
const previousStep = this.step() - 1;
if (previousStep > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@if (!dataLoaded()) {
<osf-loading-spinner></osf-loading-spinner>
} @else {
<div class="flex flex-column bg-white gap-4 h-full flex-1 p-4 p-dialog-align-center">
<div class="flex flex-grow-0 w-full sm:w-30rem"></div>

<div class="flex flex-column gap-4 md:justify-content-between md:flex-row md:flex-wrap">
<div class="flex flex-column w-full gap-2 sm:flex-row md:w-max">
<p-button
[disabled]="fileIsUploading() || isFilesLoading()"
outlined
raised
severity="success"
[icon]="'fas fa-plus'"
[label]="'project.files.actions.createFolder' | translate"
(click)="createFolder()"
>
</p-button>

<p-button
[disabled]="fileIsUploading() || isFilesLoading()"
outlined
raised
severity="success"
[icon]="'fas fa-upload'"
[label]="'project.files.actions.uploadFile' | translate"
(click)="fileInput.click()"
>
</p-button>

<input #fileInput type="file" class="hidden" (change)="onFileSelected($event)" />
</div>
</div>

<div class="flex absolute">
<p-dialog
[header]="'project.files.dialogs.uploadFile.title' | translate"
[modal]="true"
[(visible)]="fileIsUploading"
class="upload-dialog"
>
<div class="flex flex-column align-items-center justify-content-center gap-3 w-full">
<span class="p-text-secondary filename">{{ fileName() }}</span>
<div class="w-6">
<osf-loading-spinner></osf-loading-spinner>
</div>
<p>{{ progress() }} %</p>
</div>
</p-dialog>
</div>

<osf-files-tree
[files]="files()"
[currentFolder]="currentFolder()"
[isLoading]="isFilesLoading()"
[actions]="filesTreeActions"
[viewOnly]="false"
[viewOnlyDownloadable]="false"
[resourceId]="draftRegistration()?.branchedFrom?.id!"
[provider]="draftRegistration()?.providerId"
(folderIsOpening)="folderIsOpening($event)"
(entryFileClicked)="selectFile($event)"
(uploadFileConfirmed)="uploadFile($event)"
>
</osf-files-tree>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { FilesControlComponent } from './files-control.component';

describe('FilesControlComponent', () => {
let component: FilesControlComponent;
let fixture: ComponentFixture<FilesControlComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [FilesControlComponent],
}).compileComponents();

fixture = TestBed.createComponent(FilesControlComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading