diff --git a/src/app/features/preprints/components/stepper/file-step/file-step.component.ts b/src/app/features/preprints/components/stepper/file-step/file-step.component.ts index 0dcb99ee5..a27718fd2 100644 --- a/src/app/features/preprints/components/stepper/file-step/file-step.component.ts +++ b/src/app/features/preprints/components/stepper/file-step/file-step.component.ts @@ -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({ diff --git a/src/app/features/project/files/models/index.ts b/src/app/features/project/files/models/index.ts index 2d4383151..923d1245d 100644 --- a/src/app/features/project/files/models/index.ts +++ b/src/app/features/project/files/models/index.ts @@ -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'; diff --git a/src/app/features/project/files/pages/project-files/project-files.component.ts b/src/app/features/project/files/pages/project-files/project-files.component.ts index c3211b95f..01463158c 100644 --- a/src/app/features/project/files/pages/project-files/project-files.component.ts +++ b/src/app/features/project/files/pages/project-files/project-files.component.ts @@ -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, @@ -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({ diff --git a/src/app/features/registries/components/custom-step/custom-step.component.html b/src/app/features/registries/components/custom-step/custom-step.component.html index 690363cea..3559c33a6 100644 --- a/src/app/features/registries/components/custom-step/custom-step.component.html +++ b/src/app/features/registries/components/custom-step/custom-step.component.html @@ -145,16 +145,29 @@
- You may attach up to 5 file(s) to this question. Files cannot total over 5GB in size. + {{ 'shared.files.limitText' | translate }}
- 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 }}
- -File input is not implemented yet.
+{{ progress() }} %
+{{ option }}
+ @switch (question.fieldType) { + @case (FieldType.Text) { +{{ stepsData()[question.responseKey!] }}
+ } + @case (FieldType.Checkbox) { + @for (option of stepsData()[question.responseKey!]; track option) { +{{ option }}
+ } + } + @case (FieldType.File) { + @if (stepsData()[question.responseKey!].length) { +{{ 'common.labels.noFiles' | translate }}
+ } + } + @default { +{{ stepsData()[question.responseKey!] }}
} - } @else { -{{ stepsData()[question.responseKey!] }}
} } @else { @if (question.fieldType === FieldType.File) { diff --git a/src/app/features/registries/mappers/files.mapper.ts b/src/app/features/registries/mappers/files.mapper.ts new file mode 100644 index 000000000..bde6bd742 --- /dev/null +++ b/src/app/features/registries/mappers/files.mapper.ts @@ -0,0 +1,17 @@ +import { FilePayloadJsonApi, OsfFile } from '@osf/shared/models'; + +export class FilesMapper { + static toFilePayload(file: OsfFile): FilePayloadJsonApi { + return { + file_id: file.id, + file_name: file.name, + file_urls: { + html: file.links.html, + download: file.links.download, + }, + file_hashes: { + sha256: file.extra?.hashes?.sha256 || '', + }, + }; + } +} diff --git a/src/app/features/registries/mappers/page-schema.mapper.ts b/src/app/features/registries/mappers/page-schema.mapper.ts index 6bfd884fa..3a60c6add 100644 --- a/src/app/features/registries/mappers/page-schema.mapper.ts +++ b/src/app/features/registries/mappers/page-schema.mapper.ts @@ -126,6 +126,8 @@ export class PageSchemaMapper { case BlockType.FileInput: if (currentQuestion) { currentQuestion.fieldType = FieldType.File; + currentQuestion.required = item.attributes.required; + currentQuestion.responseKey = item.attributes.registration_response_key || undefined; } break; default: diff --git a/src/app/features/registries/registries.routes.ts b/src/app/features/registries/registries.routes.ts index 8dd5e3833..480f8811c 100644 --- a/src/app/features/registries/registries.routes.ts +++ b/src/app/features/registries/registries.routes.ts @@ -7,6 +7,7 @@ import { RegistriesState } from '@osf/features/registries/store'; import { ContributorsState, SubjectsState } from '@osf/shared/stores'; import { LicensesHandlers, ProjectsHandlers, ProvidersHandlers } from './store/handlers'; +import { FilesHandlers } from './store/handlers/files.handlers'; import { LicensesService } from './services'; export const registriesRoutes: Routes = [ @@ -18,6 +19,7 @@ export const registriesRoutes: Routes = [ ProvidersHandlers, ProjectsHandlers, LicensesHandlers, + FilesHandlers, LicensesService, ], children: [ diff --git a/src/app/features/registries/services/index.ts b/src/app/features/registries/services/index.ts index b6471bbb9..c4eb84e78 100644 --- a/src/app/features/registries/services/index.ts +++ b/src/app/features/registries/services/index.ts @@ -1,4 +1,5 @@ export * from './licenses.service'; export * from './projects.service'; export * from './providers.service'; +export * from './registration-files.service'; export * from './registries.service'; diff --git a/src/app/features/registries/services/registration-files.service.ts b/src/app/features/registries/services/registration-files.service.ts new file mode 100644 index 000000000..564022082 --- /dev/null +++ b/src/app/features/registries/services/registration-files.service.ts @@ -0,0 +1,12 @@ +import { inject, Injectable } from '@angular/core'; + +import { JsonApiService } from '@core/services'; +import { FilesService } from '@osf/shared/services'; + +@Injectable({ + providedIn: 'root', +}) +export class RegistrationFilesService { + private filesService = inject(FilesService); + private jsonApiService = inject(JsonApiService); +} diff --git a/src/app/features/registries/store/default.state.ts b/src/app/features/registries/store/default.state.ts index c5e68f17a..f70d1cd21 100644 --- a/src/app/features/registries/store/default.state.ts +++ b/src/app/features/registries/store/default.state.ts @@ -51,4 +51,16 @@ export const DefaultState: RegistriesStateModel = { error: null, totalCount: 0, }, + files: { + data: [], + isLoading: false, + error: null, + }, + currentFolder: null, + moveFileCurrentFolder: null, + rootFolders: { + data: null, + isLoading: false, + error: null, + }, }; diff --git a/src/app/features/registries/store/handlers/files.handlers.ts b/src/app/features/registries/store/handlers/files.handlers.ts new file mode 100644 index 000000000..077d0a08c --- /dev/null +++ b/src/app/features/registries/store/handlers/files.handlers.ts @@ -0,0 +1,68 @@ +import { StateContext } from '@ngxs/store'; + +import { catchError, finalize, tap } from 'rxjs'; + +import { inject, Injectable } from '@angular/core'; + +import { handleSectionError } from '@osf/core/handlers'; +import { FilesService } from '@osf/shared/services'; + +import { CreateFolder, GetFiles, GetRootFolders } from '../registries.actions'; +import { RegistriesStateModel } from '../registries.model'; + +@Injectable() +export class FilesHandlers { + filesService = inject(FilesService); + + getRootFolders(ctx: StateContext{{ 'project.files.dropText' | translate }}
+