From 8f5c860e4e58e969a7f4743dfb86db8a6ebe7b15 Mon Sep 17 00:00:00 2001 From: nsemets Date: Tue, 26 Aug 2025 17:24:45 +0300 Subject: [PATCH 1/2] fix(meetings): fixed meetings small issues --- .../meetings-feature-card.component.spec.ts | 2 +- .../features/meetings/mappers/meetings.mapper.ts | 2 +- .../features/meetings/models/meetings.models.ts | 4 ++-- .../meeting-details.component.html | 10 +++++----- .../meeting-details/meeting-details.component.ts | 16 ++++++++-------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/app/features/meetings/components/meetings-feature-card/meetings-feature-card.component.spec.ts b/src/app/features/meetings/components/meetings-feature-card/meetings-feature-card.component.spec.ts index dbc686b94..50eeef7dc 100644 --- a/src/app/features/meetings/components/meetings-feature-card/meetings-feature-card.component.spec.ts +++ b/src/app/features/meetings/components/meetings-feature-card/meetings-feature-card.component.spec.ts @@ -13,7 +13,7 @@ describe('MeetingsFeatureCardComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [MeetingsFeatureCardComponent, MockPipe(TranslatePipe, (value) => value)], + imports: [MeetingsFeatureCardComponent, MockPipe(TranslatePipe)], }).compileComponents(); fixture = TestBed.createComponent(MeetingsFeatureCardComponent); diff --git a/src/app/features/meetings/mappers/meetings.mapper.ts b/src/app/features/meetings/mappers/meetings.mapper.ts index c78f90829..42ed13328 100644 --- a/src/app/features/meetings/mappers/meetings.mapper.ts +++ b/src/app/features/meetings/mappers/meetings.mapper.ts @@ -31,7 +31,7 @@ export class MeetingsMapper { title: item.attributes.title, dateCreated: item.attributes.date_created, authorName: item.attributes.author_name, - downloadCount: item.attributes.download_count, + downloadCount: item.attributes.download_count || 0, meetingCategory: item.attributes.meeting_category, downloadLink: item.links.download, })), diff --git a/src/app/features/meetings/models/meetings.models.ts b/src/app/features/meetings/models/meetings.models.ts index a442e7406..a672a4551 100644 --- a/src/app/features/meetings/models/meetings.models.ts +++ b/src/app/features/meetings/models/meetings.models.ts @@ -1,4 +1,4 @@ -import { NumberOrNull, StringOrNull } from '@osf/shared/helpers'; +import { StringOrNull } from '@osf/shared/helpers'; export interface Meeting { id: string; @@ -19,7 +19,7 @@ export interface MeetingSubmission { title: string; dateCreated: Date; authorName: string; - downloadCount: NumberOrNull; + downloadCount: number; meetingCategory: string; downloadLink: StringOrNull; } diff --git a/src/app/features/meetings/pages/meeting-details/meeting-details.component.html b/src/app/features/meetings/pages/meeting-details/meeting-details.component.html index 5646f45f1..c3f24e5da 100644 --- a/src/app/features/meetings/pages/meeting-details/meeting-details.component.html +++ b/src/app/features/meetings/pages/meeting-details/meeting-details.component.html @@ -57,24 +57,24 @@ @if (item?.id) { - + {{ item.title }} {{ item.authorName }} {{ item.meetingCategory }} {{ item.dateCreated | date: 'MMM d, y, h:mm a' }} - @if (item.downloadCount) { + @if (item.downloadLink) { - {{ item.downloadCount }} + {{ item.downloadCount }} } @else { - - + - } diff --git a/src/app/features/meetings/pages/meeting-details/meeting-details.component.ts b/src/app/features/meetings/pages/meeting-details/meeting-details.component.ts index 8c12fa7f8..ba43de55d 100644 --- a/src/app/features/meetings/pages/meeting-details/meeting-details.component.ts +++ b/src/app/features/meetings/pages/meeting-details/meeting-details.component.ts @@ -25,14 +25,14 @@ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop'; import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; -import { MEETING_SUBMISSIONS_TABLE_PARAMS } from '@osf/features/meetings/constants'; -import { MeetingSubmission } from '@osf/features/meetings/models'; -import { GetMeetingById, GetMeetingSubmissions, MeetingsSelectors } from '@osf/features/meetings/store'; -import { parseQueryFilterParams } from '@osf/shared/helpers/http.helper'; -import { SearchInputComponent, SubHeaderComponent } from '@shared/components'; -import { SortOrder } from '@shared/enums'; -import { QueryParams, TableParameters } from '@shared/models'; -import { SearchFilters } from '@shared/models/filters'; +import { SearchInputComponent, SubHeaderComponent } from '@osf/shared/components'; +import { SortOrder } from '@osf/shared/enums'; +import { parseQueryFilterParams } from '@osf/shared/helpers'; +import { QueryParams, SearchFilters, TableParameters } from '@osf/shared/models'; + +import { MEETING_SUBMISSIONS_TABLE_PARAMS } from '../../constants'; +import { MeetingSubmission } from '../../models'; +import { GetMeetingById, GetMeetingSubmissions, MeetingsSelectors } from '../../store'; @Component({ selector: 'osf-meeting-details', From 8de9aefe5cacb6a7237669e44de76edcf9f71c65 Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 27 Aug 2025 15:00:20 +0300 Subject: [PATCH 2/2] fix(tooltips): added tooltips --- .../project-contributors-step.component.html | 8 +- .../project-contributors-step.component.ts | 28 ++++--- .../file-browser-info.component.html | 19 +++++ .../file-browser-info.component.scss | 0 .../file-browser-info.component.spec.ts | 22 ++++++ .../file-browser-info.component.ts | 30 ++++++++ src/app/features/files/components/index.ts | 1 + .../constants/file-browser-info.constants.ts | 61 +++++++++++++++ src/app/features/files/constants/index.ts | 1 + src/app/features/files/models/index.ts | 1 + .../features/files/models/info-item.model.ts | 7 ++ .../files/pages/files/files.component.html | 10 ++- .../files/pages/files/files.component.ts | 77 ++++++++++++------- .../registry-settings.component.html | 2 - .../registry-settings.component.ts | 4 +- .../file-step/file-step.component.html | 16 ++-- .../custom-step/custom-step.component.html | 45 +++++++---- .../custom-step/custom-step.component.ts | 8 +- ...raft-registration-custom-step.component.ts | 25 ++---- .../registry-resources.component.html | 7 +- .../default-storage-location.component.ts | 4 +- .../mappers/regions.mapper.ts | 10 +-- .../models/osf-models/index.ts | 1 - .../models/osf-models/region.model.ts | 4 - .../services/account-settings.service.ts | 5 +- .../store/account-settings.model.ts | 6 +- .../store/account-settings.selectors.ts | 6 +- .../constants/notifications-constants.ts | 8 -- .../notifications.component.html | 11 ++- .../notifications/notifications.component.ts | 27 ++++--- .../tokens/services/tokens.service.spec.ts | 10 +-- .../info-icon/info-icon.component.scss | 4 + .../wiki-syntax-help-dialog.component.html | 7 +- .../subscriptions/subscription-event.enum.ts | 3 - .../registration/page-schema.mapper.ts | 6 +- .../models/registration/page-schema.model.ts | 4 +- src/assets/i18n/en.json | 42 ++++++---- 37 files changed, 369 insertions(+), 161 deletions(-) create mode 100644 src/app/features/files/components/file-browser-info/file-browser-info.component.html create mode 100644 src/app/features/files/components/file-browser-info/file-browser-info.component.scss create mode 100644 src/app/features/files/components/file-browser-info/file-browser-info.component.spec.ts create mode 100644 src/app/features/files/components/file-browser-info/file-browser-info.component.ts create mode 100644 src/app/features/files/constants/file-browser-info.constants.ts create mode 100644 src/app/features/files/models/info-item.model.ts delete mode 100644 src/app/features/settings/account-settings/models/osf-models/region.model.ts diff --git a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html index 39ed90188..f093255b4 100644 --- a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html +++ b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.html @@ -7,7 +7,13 @@
-

{{ 'collections.addToCollection.projectContributors' | translate }}

+
+

{{ 'collections.addToCollection.projectContributors' | translate }}

+ +
@if (!isDisabled() && stepperActiveValue() !== targetStepValue()) { @if (projectContributors().length) {
diff --git a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.ts b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.ts index 90a390ca2..9a94426e2 100644 --- a/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.ts +++ b/src/app/features/collections/components/add-to-collection/project-contributors-step/project-contributors-step.component.ts @@ -13,21 +13,27 @@ import { filter } from 'rxjs/operators'; import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, input, output, signal } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { findChangedItems } from '@osf/shared/helpers'; +import { InfoIconComponent } from '@osf/shared/components'; import { AddContributorDialogComponent, AddUnregisteredContributorDialogComponent, ContributorsListComponent, -} from '@shared/components/contributors'; -import { AddContributorType, ResourceType } from '@shared/enums'; -import { ContributorDialogAddModel, ContributorModel } from '@shared/models'; -import { CustomConfirmationService, ToastService } from '@shared/services'; -import { AddContributor, ContributorsSelectors, DeleteContributor, UpdateContributor } from '@shared/stores'; -import { ProjectsSelectors } from '@shared/stores/projects/projects.selectors'; +} from '@osf/shared/components/contributors'; +import { AddContributorType, ResourceType } from '@osf/shared/enums'; +import { findChangedItems } from '@osf/shared/helpers'; +import { ContributorDialogAddModel, ContributorModel } from '@osf/shared/models'; +import { CustomConfirmationService, ToastService } from '@osf/shared/services'; +import { + AddContributor, + ContributorsSelectors, + DeleteContributor, + ProjectsSelectors, + UpdateContributor, +} from '@osf/shared/stores'; @Component({ selector: 'osf-project-contributors-step', - imports: [Button, TranslatePipe, ContributorsListComponent, Step, StepItem, StepPanel, Tooltip], + imports: [Button, Step, StepItem, StepPanel, Tooltip, TranslatePipe, ContributorsListComponent, InfoIconComponent], templateUrl: './project-contributors-step.component.html', styleUrl: './project-contributors-step.component.scss', providers: [DialogService], @@ -40,9 +46,9 @@ export class ProjectContributorsStepComponent { private readonly toastService = inject(ToastService); private readonly customConfirmationService = inject(CustomConfirmationService); - protected readonly projectContributors = select(ContributorsSelectors.getContributors); - protected readonly isContributorsLoading = select(ContributorsSelectors.isContributorsLoading); - protected readonly selectedProject = select(ProjectsSelectors.getSelectedProject); + readonly projectContributors = select(ContributorsSelectors.getContributors); + readonly isContributorsLoading = select(ContributorsSelectors.isContributorsLoading); + readonly selectedProject = select(ProjectsSelectors.getSelectedProject); private initialContributors = signal([]); diff --git a/src/app/features/files/components/file-browser-info/file-browser-info.component.html b/src/app/features/files/components/file-browser-info/file-browser-info.component.html new file mode 100644 index 000000000..c9fd941c7 --- /dev/null +++ b/src/app/features/files/components/file-browser-info/file-browser-info.component.html @@ -0,0 +1,19 @@ +
+ @for (item of filteredInfoItems(); track item.titleKey) { +
+

{{ item.titleKey | translate }}

+

{{ item.descriptionKey | translate }}

+
+ } + +

+ {{ 'files.filesBrowserDialog.moreInfo' | translate }} + + {{ 'files.filesBrowserDialog.helpGuides' | translate }} + +

+
+ +
+ +
diff --git a/src/app/features/files/components/file-browser-info/file-browser-info.component.scss b/src/app/features/files/components/file-browser-info/file-browser-info.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/features/files/components/file-browser-info/file-browser-info.component.spec.ts b/src/app/features/files/components/file-browser-info/file-browser-info.component.spec.ts new file mode 100644 index 000000000..827173f6b --- /dev/null +++ b/src/app/features/files/components/file-browser-info/file-browser-info.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FileBrowserInfoComponent } from './file-browser-info.component'; + +describe('FileBrowserInfoComponent', () => { + let component: FileBrowserInfoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FileBrowserInfoComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(FileBrowserInfoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/files/components/file-browser-info/file-browser-info.component.ts b/src/app/features/files/components/file-browser-info/file-browser-info.component.ts new file mode 100644 index 000000000..4cb855e03 --- /dev/null +++ b/src/app/features/files/components/file-browser-info/file-browser-info.component.ts @@ -0,0 +1,30 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { Button } from 'primeng/button'; +import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; + +import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core'; + +import { ResourceType } from '@osf/shared/enums'; + +import { FILE_BROWSER_INFO_ITEMS } from '../../constants'; + +@Component({ + selector: 'osf-file-browser-info', + imports: [Button, TranslatePipe], + templateUrl: './file-browser-info.component.html', + styleUrl: './file-browser-info.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FileBrowserInfoComponent { + readonly dialogRef = inject(DynamicDialogRef); + readonly config = inject(DynamicDialogConfig); + + readonly resourceType = computed(() => (this.config.data as ResourceType) || ResourceType.Project); + + readonly infoItems = FILE_BROWSER_INFO_ITEMS; + + readonly filteredInfoItems = computed(() => { + return this.infoItems.filter((item) => item.showForResourceTypes.includes(this.resourceType())); + }); +} diff --git a/src/app/features/files/components/index.ts b/src/app/features/files/components/index.ts index 80c02901d..8f96ee952 100644 --- a/src/app/features/files/components/index.ts +++ b/src/app/features/files/components/index.ts @@ -1,5 +1,6 @@ export { CreateFolderDialogComponent } from './create-folder-dialog/create-folder-dialog.component'; export { EditFileMetadataDialogComponent } from './edit-file-metadata-dialog/edit-file-metadata-dialog.component'; +export { FileBrowserInfoComponent } from './file-browser-info/file-browser-info.component'; export { FileKeywordsComponent } from './file-keywords/file-keywords.component'; export { FileMetadataComponent } from './file-metadata/file-metadata.component'; export { FileResourceMetadataComponent } from './file-resource-metadata/file-resource-metadata.component'; diff --git a/src/app/features/files/constants/file-browser-info.constants.ts b/src/app/features/files/constants/file-browser-info.constants.ts new file mode 100644 index 000000000..fb7e8b99a --- /dev/null +++ b/src/app/features/files/constants/file-browser-info.constants.ts @@ -0,0 +1,61 @@ +import { ResourceType } from '@osf/shared/enums'; + +import { FileInfoItem } from '../models'; + +export const FILE_BROWSER_INFO_ITEMS: FileInfoItem[] = [ + { + titleKey: 'files.filesBrowserDialog.seeAllFiles', + descriptionKey: 'files.filesBrowserDialog.seeAllFilesDescription', + showForResourceTypes: [ResourceType.Project, ResourceType.Registration], + }, + { + titleKey: 'files.filesBrowserDialog.selectFilesFolders', + descriptionKey: 'files.filesBrowserDialog.selectFilesFoldersDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.openViewFiles', + descriptionKey: 'files.filesBrowserDialog.openViewFilesDescription', + showForResourceTypes: [ResourceType.Project, ResourceType.Registration], + }, + { + titleKey: 'files.filesBrowserDialog.upload', + descriptionKey: 'files.filesBrowserDialog.uploadDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.createFolder', + descriptionKey: 'files.filesBrowserDialog.createFolderDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.renameFolderFile', + descriptionKey: 'files.filesBrowserDialog.renameFolderFileDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.move', + descriptionKey: 'files.filesBrowserDialog.moveDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.copy', + descriptionKey: 'files.filesBrowserDialog.copyDescription', + showForResourceTypes: [ResourceType.Project], + }, + { + titleKey: 'files.filesBrowserDialog.downloadAllFilesZip', + descriptionKey: 'files.filesBrowserDialog.downloadAllFilesZipDescription', + showForResourceTypes: [ResourceType.Project, ResourceType.Registration], + }, + { + titleKey: 'files.filesBrowserDialog.downloadFolderZip', + descriptionKey: 'files.filesBrowserDialog.downloadFolderZipDescription', + showForResourceTypes: [ResourceType.Project, ResourceType.Registration], + }, + { + titleKey: 'files.filesBrowserDialog.downloadFile', + descriptionKey: 'files.filesBrowserDialog.downloadFileDescription', + showForResourceTypes: [ResourceType.Project, ResourceType.Registration], + }, +]; diff --git a/src/app/features/files/constants/index.ts b/src/app/features/files/constants/index.ts index 72af33152..af9827638 100644 --- a/src/app/features/files/constants/index.ts +++ b/src/app/features/files/constants/index.ts @@ -1,3 +1,4 @@ export * from './embed-content.constants'; +export * from './file-browser-info.constants'; export * from './file-metadata-fields.constants'; export * from './file-provider.constants'; diff --git a/src/app/features/files/models/index.ts b/src/app/features/files/models/index.ts index f3e000f81..078892263 100644 --- a/src/app/features/files/models/index.ts +++ b/src/app/features/files/models/index.ts @@ -9,4 +9,5 @@ export * from './get-file-metadata-response.model'; export * from './get-file-revisions-response.model'; export * from './get-file-target-response.model'; export * from './get-short-info-response.model'; +export * from './info-item.model'; export * from './patch-file-metadata.model'; diff --git a/src/app/features/files/models/info-item.model.ts b/src/app/features/files/models/info-item.model.ts new file mode 100644 index 000000000..7224bb6a2 --- /dev/null +++ b/src/app/features/files/models/info-item.model.ts @@ -0,0 +1,7 @@ +import { ResourceType } from '@osf/shared/enums'; + +export interface FileInfoItem { + titleKey: string; + descriptionKey: string; + showForResourceTypes: ResourceType[]; +} diff --git a/src/app/features/files/pages/files/files.component.html b/src/app/features/files/pages/files/files.component.html index 9e25d61ce..6980c972c 100644 --- a/src/app/features/files/pages/files/files.component.html +++ b/src/app/features/files/pages/files/files.component.html @@ -42,17 +42,19 @@
-
+
+ + @if (!isViewOnly()) { @@ -72,7 +74,7 @@ severity="success" [icon]="'fas fa-upload'" [label]="'files.actions.uploadFile' | translate" - (click)="fileInput.click()" + (onClick)="fileInput.click()" > } diff --git a/src/app/features/files/pages/files/files.component.ts b/src/app/features/files/pages/files/files.component.ts index 80e6b0d3e..176fc245b 100644 --- a/src/app/features/files/pages/files/files.component.ts +++ b/src/app/features/files/pages/files/files.component.ts @@ -24,7 +24,7 @@ import { model, signal, } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; @@ -44,6 +44,7 @@ import { } from '@osf/features/files/store'; import { ALL_SORT_OPTIONS } from '@osf/shared/constants'; import { ResourceType } from '@osf/shared/enums'; +import { IS_MEDIUM } from '@osf/shared/helpers'; import { FilesTreeComponent, FormSelectComponent, @@ -54,7 +55,7 @@ import { import { ConfiguredStorageAddonModel, FilesTreeActions, OsfFile } from '@shared/models'; import { FilesService } from '@shared/services'; -import { CreateFolderDialogComponent } from '../../components'; +import { CreateFolderDialogComponent, FileBrowserInfoComponent } from '../../components'; import { FileProvider } from '../../constants'; import { FilesSelectors } from '../../store'; @@ -106,29 +107,40 @@ export class FilesComponent { resetState: ResetState, }); - protected readonly files = select(FilesSelectors.getFiles); - protected readonly isFilesLoading = select(FilesSelectors.isFilesLoading); - protected readonly currentFolder = select(FilesSelectors.getCurrentFolder); - protected readonly provider = select(FilesSelectors.getProvider); - - protected readonly resourceId = signal(''); - private readonly rootFolders = select(FilesSelectors.getRootFolders); - protected isRootFoldersLoading = select(FilesSelectors.isRootFoldersLoading); - private readonly configuredStorageAddons = select(FilesSelectors.getConfiguredStorageAddons); - protected isConfiguredStorageAddonsLoading = select(FilesSelectors.isConfiguredStorageAddonsLoading); - protected currentRootFolder = model<{ label: string; folder: OsfFile } | null>(null); - protected readonly progress = signal(0); - protected readonly fileName = signal(''); - protected readonly dataLoaded = signal(false); - protected readonly searchControl = new FormControl(''); - protected readonly sortControl = new FormControl(ALL_SORT_OPTIONS[0].value); + isMedium = toSignal(inject(IS_MEDIUM)); + + readonly files = select(FilesSelectors.getFiles); + readonly isFilesLoading = select(FilesSelectors.isFilesLoading); + readonly currentFolder = select(FilesSelectors.getCurrentFolder); + readonly provider = select(FilesSelectors.getProvider); + + readonly resourceId = signal(''); + readonly rootFolders = select(FilesSelectors.getRootFolders); + readonly isRootFoldersLoading = select(FilesSelectors.isRootFoldersLoading); + readonly configuredStorageAddons = select(FilesSelectors.getConfiguredStorageAddons); + readonly isConfiguredStorageAddonsLoading = select(FilesSelectors.isConfiguredStorageAddonsLoading); + + readonly progress = signal(0); + readonly fileName = signal(''); + readonly dataLoaded = signal(false); + readonly searchControl = new FormControl(''); + readonly sortControl = new FormControl(ALL_SORT_OPTIONS[0].value); + + currentRootFolder = model<{ label: string; folder: OsfFile } | null>(null); + + fileIsUploading = signal(false); + isFolderOpening = signal(false); + + sortOptions = ALL_SORT_OPTIONS; + + storageProvider = FileProvider.OsfStorage; private readonly urlMap = new Map([ [ResourceType.Project, 'nodes'], [ResourceType.Registration, 'registrations'], ]); - protected readonly rootFoldersOptions = computed(() => { + readonly rootFoldersOptions = computed(() => { const rootFolders = this.rootFolders(); const addons = this.configuredStorageAddons(); if (rootFolders && addons) { @@ -144,22 +156,15 @@ export class FilesComponent { this.activeRoute.parent?.parent?.snapshot.data['resourceType'] || ResourceType.Project ); - protected readonly isViewOnly = computed(() => { + readonly isViewOnly = computed(() => { return this.resourceType() === ResourceType.Registration; }); - protected readonly isViewOnlyDownloadable = computed(() => { + readonly isViewOnlyDownloadable = computed(() => { return this.resourceType() === ResourceType.Registration; }); - fileIsUploading = signal(false); - isFolderOpening = signal(false); - - sortOptions = ALL_SORT_OPTIONS; - - storageProvider = FileProvider.OsfStorage; - - protected readonly filesTreeActions: FilesTreeActions = { + readonly filesTreeActions: FilesTreeActions = { setCurrentFolder: (folder) => this.actions.setCurrentFolder(folder), setFilesIsLoading: (isLoading) => this.actions.setFilesIsLoading(isLoading), getFiles: (filesLink) => this.actions.getFiles(filesLink), @@ -324,6 +329,20 @@ export class FilesComponent { } } + showInfoDialog() { + const dialogWidth = this.isMedium() ? '850px' : '95vw'; + + this.dialogService.open(FileBrowserInfoComponent, { + width: dialogWidth, + focusOnShow: false, + header: this.translateService.instant('files.filesBrowserDialog.title'), + closeOnEscape: true, + modal: true, + closable: true, + data: this.resourceType(), + }); + } + updateFilesList(): Observable { const currentFolder = this.currentFolder(); if (currentFolder?.relationships.filesLink) { diff --git a/src/app/features/moderation/components/registry-settings/registry-settings.component.html b/src/app/features/moderation/components/registry-settings/registry-settings.component.html index bd2e358c7..0621ed927 100644 --- a/src/app/features/moderation/components/registry-settings/registry-settings.component.html +++ b/src/app/features/moderation/components/registry-settings/registry-settings.component.html @@ -4,5 +4,3 @@ {{ 'moderation.userSettings' | translate }}

- - diff --git a/src/app/features/moderation/components/registry-settings/registry-settings.component.ts b/src/app/features/moderation/components/registry-settings/registry-settings.component.ts index dce5e933a..976cdabe2 100644 --- a/src/app/features/moderation/components/registry-settings/registry-settings.component.ts +++ b/src/app/features/moderation/components/registry-settings/registry-settings.component.ts @@ -3,11 +3,9 @@ import { TranslatePipe } from '@ngx-translate/core'; import { ChangeDetectionStrategy, Component } from '@angular/core'; import { RouterLink } from '@angular/router'; -import { BulkUploadComponent } from '@osf/features/moderation/components/bulk-upload/bulk-upload.component'; - @Component({ selector: 'osf-registry-settings', - imports: [TranslatePipe, RouterLink, BulkUploadComponent], + imports: [TranslatePipe, RouterLink], templateUrl: './registry-settings.component.html', styleUrl: './registry-settings.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/features/preprints/components/stepper/file-step/file-step.component.html b/src/app/features/preprints/components/stepper/file-step/file-step.component.html index 1194b744e..5c1947e69 100644 --- a/src/app/features/preprints/components/stepper/file-step/file-step.component.html +++ b/src/app/features/preprints/components/stepper/file-step/file-step.component.html @@ -20,9 +20,9 @@

{{ 'preprints.preprintStepper.file.title' | translate }}

[label]="'preprints.preprintStepper.file.uploadFromComputer' | translate | titlecase" severity="secondary" [disabled]="isFileSourceSelected()" - [pTooltip]="isFileSourceSelected() ? ('preprints.preprintStepper.file.tooltips.computerDisabled' | translate) : ''" + [pTooltip]="'preprints.preprintStepper.file.tooltips.computerDisabled' | translate" tooltipPosition="top" - (click)="selectFileSource(PreprintFileSource.Computer)" + (onClick)="selectFileSource(PreprintFileSource.Computer)" /> @@ -50,7 +50,7 @@

{{ 'preprints.preprintStepper.file.title' | translate }}

severity="success" [icon]="'fas fa-upload'" [label]="'preprints.preprintStepper.file.uploadFileButton' | translate | titlecase" - (click)="fileInput.click()" + (onClick)="fileInput.click()" /> @@ -109,7 +109,7 @@

{{ 'preprints.preprintStepper.file.title' | translate }}

{{ file.name }}

- + } } @@ -122,13 +122,13 @@

{{ 'preprints.preprintStepper.file.title' | translate }}

styleClass="w-full" [label]="'common.buttons.back' | translate" severity="info" - (click)="backButtonClicked()" + (onClick)="backButtonClicked()" /> 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 f2113e9eb..02ae4fc0f 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 @@ -1,13 +1,28 @@
@if (currentPage()) { -

{{ currentPage().title }}

+
+

{{ currentPage().title }}

+ + @let helpText = currentPage().helpText; + + @if (helpText) { + + } +
@let questions = currentPage().questions || []; @if (currentPage().sections?.length) { @for (section of currentPage().sections; track section.id) { -

{{ section.title }}

+
+

{{ section.title }}

+ + @if (section.helpText) { + + } +
+ @if (section.description) {

{{ section.description }}

} @@ -20,18 +35,21 @@

{{ section.title }}

@for (q of questions; track q.id) { -
+
@if (q.paragraphText) {

{{ q.paragraphText }}

} @@ -88,7 +106,7 @@

> @if (option.helpText) { - + } } @@ -113,7 +131,7 @@

> @if (option.helpText) { - + } } @@ -180,6 +198,7 @@

{{ 'files.actions.uploadFile' | translate }}

}
} +
{ - return this.draftRegistration()?.branchedFrom?.filesLink || ''; - }); + readonly stepsData = select(RegistriesSelectors.getStepsData); + readonly draftRegistration = select(RegistriesSelectors.getDraftRegistration); + readonly actions = createDispatchMap({ updateDraft: UpdateDraft }); - provider = computed(() => { - return this.draftRegistration()?.providerId || ''; - }); - - projectId = computed(() => { - return this.draftRegistration()?.branchedFrom?.id || ''; - }); + filesLink = computed(() => this.draftRegistration()?.branchedFrom?.filesLink || ''); + provider = computed(() => this.draftRegistration()?.providerId || ''); + projectId = computed(() => this.draftRegistration()?.branchedFrom?.id || ''); onUpdateAction(attributes: Partial): void { - const payload = { - registration_responses: { ...attributes }, - }; + const payload = { registration_responses: { ...attributes } }; this.actions.updateDraft(this.route.snapshot.params['id'], payload); } diff --git a/src/app/features/registry/pages/registry-resources/registry-resources.component.html b/src/app/features/registry/pages/registry-resources/registry-resources.component.html index 03f2ae84d..1ca013a57 100644 --- a/src/app/features/registry/pages/registry-resources/registry-resources.component.html +++ b/src/app/features/registry/pages/registry-resources/registry-resources.component.html @@ -10,7 +10,12 @@ } @else {
-

{{ 'resources.description' | translate }}

+

+ {{ 'resources.description' | translate }} + + {{ 'common.labels.learnMore' | translate }} + +

@for (resource of resources(); track resource.id) { diff --git a/src/app/features/settings/account-settings/components/default-storage-location/default-storage-location.component.ts b/src/app/features/settings/account-settings/components/default-storage-location/default-storage-location.component.ts index 82f6dff21..07e748f89 100644 --- a/src/app/features/settings/account-settings/components/default-storage-location/default-storage-location.component.ts +++ b/src/app/features/settings/account-settings/components/default-storage-location/default-storage-location.component.ts @@ -12,9 +12,9 @@ import { ChangeDetectionStrategy, Component, effect, inject, signal } from '@ang import { FormsModule } from '@angular/forms'; import { UserSelectors } from '@osf/core/store/user'; +import { IdName } from '@osf/shared/models'; import { LoaderService, ToastService } from '@osf/shared/services'; -import { Region } from '../../models'; import { AccountSettingsSelectors, UpdateRegion } from '../../store'; @Component({ @@ -31,7 +31,7 @@ export class DefaultStorageLocationComponent { protected readonly currentUser = select(UserSelectors.getCurrentUser); protected readonly regions = select(AccountSettingsSelectors.getRegions); - protected selectedRegion = signal(undefined); + protected selectedRegion = signal(undefined); constructor() { effect(() => { diff --git a/src/app/features/settings/account-settings/mappers/regions.mapper.ts b/src/app/features/settings/account-settings/mappers/regions.mapper.ts index bce848f6f..b817a06f6 100644 --- a/src/app/features/settings/account-settings/mappers/regions.mapper.ts +++ b/src/app/features/settings/account-settings/mappers/regions.mapper.ts @@ -1,9 +1,7 @@ -import { ApiData } from '@osf/shared/models'; +import { ApiData, IdName } from '@osf/shared/models'; -import { Region } from '../models'; - -export function MapRegions(data: ApiData<{ name: string }, null, null, null>[]): Region[] { - const regions: Region[] = []; +export function MapRegions(data: ApiData<{ name: string }, null, null, null>[]): IdName[] { + const regions: IdName[] = []; for (const region of data) { regions.push(MapRegion(region)); @@ -12,7 +10,7 @@ export function MapRegions(data: ApiData<{ name: string }, null, null, null>[]): return regions; } -export function MapRegion(data: ApiData<{ name: string }, null, null, null>): Region { +export function MapRegion(data: ApiData<{ name: string }, null, null, null>): IdName { return { id: data.id, name: data.attributes.name, diff --git a/src/app/features/settings/account-settings/models/osf-models/index.ts b/src/app/features/settings/account-settings/models/osf-models/index.ts index dbf70a075..9d46a9787 100644 --- a/src/app/features/settings/account-settings/models/osf-models/index.ts +++ b/src/app/features/settings/account-settings/models/osf-models/index.ts @@ -1,4 +1,3 @@ export * from './account-email.model'; export * from './account-settings.model'; export * from './external-institution.model'; -export * from './region.model'; diff --git a/src/app/features/settings/account-settings/models/osf-models/region.model.ts b/src/app/features/settings/account-settings/models/osf-models/region.model.ts deleted file mode 100644 index 4068f4f1e..000000000 --- a/src/app/features/settings/account-settings/models/osf-models/region.model.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Region { - id: string; - name: string; -} diff --git a/src/app/features/settings/account-settings/services/account-settings.service.ts b/src/app/features/settings/account-settings/services/account-settings.service.ts index a140fe28e..ad78b2abb 100644 --- a/src/app/features/settings/account-settings/services/account-settings.service.ts +++ b/src/app/features/settings/account-settings/services/account-settings.service.ts @@ -6,7 +6,7 @@ import { inject, Injectable } from '@angular/core'; import { UserSelectors } from '@osf/core/store/user'; import { UserMapper } from '@osf/shared/mappers'; -import { ApiData, JsonApiResponse, User, UserGetResponse } from '@osf/shared/models'; +import { ApiData, IdName, JsonApiResponse, User, UserGetResponse } from '@osf/shared/models'; import { JsonApiService } from '@osf/shared/services'; import { MapAccountSettings, MapEmail, MapEmails, MapExternalIdentities, MapRegions } from '../mappers'; @@ -20,7 +20,6 @@ import { GetRegionsResponseJsonApi, ListEmailsResponseJsonApi, ListIdentitiesResponseJsonApi, - Region, } from '../models'; import { environment } from 'src/environments/environment'; @@ -141,7 +140,7 @@ export class AccountSettingsService { .pipe(map((response) => MapEmail(response))); } - getRegions(): Observable { + getRegions(): Observable { return this.jsonApiService .get(`${environment.apiUrl}/regions/`) .pipe(map((response) => MapRegions(response.data))); diff --git a/src/app/features/settings/account-settings/store/account-settings.model.ts b/src/app/features/settings/account-settings/store/account-settings.model.ts index 1e95cb543..6dc3b7a81 100644 --- a/src/app/features/settings/account-settings/store/account-settings.model.ts +++ b/src/app/features/settings/account-settings/store/account-settings.model.ts @@ -1,10 +1,10 @@ -import { AsyncStateModel, Institution } from '@shared/models'; +import { AsyncStateModel, IdName, Institution } from '@shared/models'; -import { AccountEmail, AccountSettings, ExternalIdentity, Region } from '../models'; +import { AccountEmail, AccountSettings, ExternalIdentity } from '../models'; export interface AccountSettingsStateModel { emails: AsyncStateModel; - regions: Region[]; + regions: IdName[]; externalIdentities: ExternalIdentity[]; accountSettings: AccountSettings; userInstitutions: Institution[]; diff --git a/src/app/features/settings/account-settings/store/account-settings.selectors.ts b/src/app/features/settings/account-settings/store/account-settings.selectors.ts index 3614770f5..aa58509a3 100644 --- a/src/app/features/settings/account-settings/store/account-settings.selectors.ts +++ b/src/app/features/settings/account-settings/store/account-settings.selectors.ts @@ -1,8 +1,8 @@ import { Selector } from '@ngxs/store'; -import { Institution } from '@shared/models'; +import { IdName, Institution } from '@shared/models'; -import { AccountEmail, AccountSettings, ExternalIdentity, Region } from '../models'; +import { AccountEmail, AccountSettings, ExternalIdentity } from '../models'; import { AccountSettingsStateModel } from './account-settings.model'; import { AccountSettingsState } from './account-settings.state'; @@ -24,7 +24,7 @@ export class AccountSettingsSelectors { } @Selector([AccountSettingsState]) - static getRegions(state: AccountSettingsStateModel): Region[] { + static getRegions(state: AccountSettingsStateModel): IdName[] { return state.regions; } diff --git a/src/app/features/settings/notifications/constants/notifications-constants.ts b/src/app/features/settings/notifications/constants/notifications-constants.ts index d3919011f..7b6bbf1de 100644 --- a/src/app/features/settings/notifications/constants/notifications-constants.ts +++ b/src/app/features/settings/notifications/constants/notifications-constants.ts @@ -3,14 +3,6 @@ import { SubscriptionEvent } from '@shared/enums'; import { SubscriptionEventModel } from '../models'; export const SUBSCRIPTION_EVENTS: SubscriptionEventModel[] = [ - { - event: SubscriptionEvent.GlobalCommentReplies, - labelKey: 'settings.notifications.notificationPreferences.items.replies', - }, - { - event: SubscriptionEvent.GlobalComments, - labelKey: 'settings.notifications.notificationPreferences.items.comments', - }, { event: SubscriptionEvent.GlobalFileUpdated, labelKey: 'settings.notifications.notificationPreferences.items.files', diff --git a/src/app/features/settings/notifications/notifications.component.html b/src/app/features/settings/notifications/notifications.component.html index bc9adbad6..0da3bff0e 100644 --- a/src/app/features/settings/notifications/notifications.component.html +++ b/src/app/features/settings/notifications/notifications.component.html @@ -1,4 +1,4 @@ - +
@if (!isEmailPreferencesLoading()) { @@ -72,7 +72,14 @@

{{ 'settings.notifications.emailPreferences.title' | translate }}

@if (!isNotificationSubscriptionsLoading()) {
-

{{ 'settings.notifications.notificationPreferences.title' | translate }}

+
+

{{ 'settings.notifications.notificationPreferences.title' | translate }}

+ + +

{{ 'settings.notifications.notificationPreferences.note' | translate }}

diff --git a/src/app/features/settings/notifications/notifications.component.ts b/src/app/features/settings/notifications/notifications.component.ts index 548bf917c..aa0f58c16 100644 --- a/src/app/features/settings/notifications/notifications.component.ts +++ b/src/app/features/settings/notifications/notifications.component.ts @@ -10,11 +10,11 @@ import { Skeleton } from 'primeng/skeleton'; import { ChangeDetectionStrategy, Component, effect, HostBinding, inject, OnInit } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { GetCurrentUserSettings, UpdateUserSettings, UserSelectors } from '@osf/core/store/user'; -import { SubHeaderComponent } from '@osf/shared/components'; +import { GetCurrentUserSettings, UpdateUserSettings, UserSelectors } from '@core/store/user'; +import { InfoIconComponent, SubHeaderComponent } from '@osf/shared/components'; +import { SubscriptionEvent, SubscriptionFrequency } from '@osf/shared/enums'; import { UserSettings } from '@osf/shared/models'; import { LoaderService, ToastService } from '@osf/shared/services'; -import { SubscriptionEvent, SubscriptionFrequency } from '@shared/enums'; import { SUBSCRIPTION_EVENTS } from './constants'; import { EmailPreferencesForm, EmailPreferencesFormControls } from './models'; @@ -26,7 +26,16 @@ import { @Component({ selector: 'osf-notifications', - imports: [SubHeaderComponent, Checkbox, Button, TranslatePipe, ReactiveFormsModule, Skeleton, Select], + imports: [ + Checkbox, + Button, + TranslatePipe, + ReactiveFormsModule, + Skeleton, + Select, + InfoIconComponent, + SubHeaderComponent, + ], templateUrl: './notifications.component.html', styleUrl: './notifications.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -48,13 +57,13 @@ export class NotificationsComponent implements OnInit { private emailPreferences = select(UserSelectors.getCurrentUserSettings); private notificationSubscriptions = select(NotificationSubscriptionSelectors.getAllGlobalNotificationSubscriptions); - protected isEmailPreferencesLoading = select(UserSelectors.isUserSettingsLoading); - protected isSubmittingEmailPreferences = select(UserSelectors.isUserSettingsSubmitting); + isEmailPreferencesLoading = select(UserSelectors.isUserSettingsLoading); + isSubmittingEmailPreferences = select(UserSelectors.isUserSettingsSubmitting); - protected isNotificationSubscriptionsLoading = select(NotificationSubscriptionSelectors.isLoading); + isNotificationSubscriptionsLoading = select(NotificationSubscriptionSelectors.isLoading); - protected EmailPreferencesFormControls = EmailPreferencesFormControls; - protected emailPreferencesForm: EmailPreferencesForm = new FormGroup({ + EmailPreferencesFormControls = EmailPreferencesFormControls; + emailPreferencesForm: EmailPreferencesForm = new FormGroup({ [EmailPreferencesFormControls.SubscribeOsfGeneralEmail]: this.fb.control(false, { nonNullable: true }), [EmailPreferencesFormControls.SubscribeOsfHelpEmail]: this.fb.control(false, { nonNullable: true }), }); diff --git a/src/app/features/settings/tokens/services/tokens.service.spec.ts b/src/app/features/settings/tokens/services/tokens.service.spec.ts index 01e930403..7d14565e0 100644 --- a/src/app/features/settings/tokens/services/tokens.service.spec.ts +++ b/src/app/features/settings/tokens/services/tokens.service.spec.ts @@ -6,7 +6,7 @@ import { JsonApiResponse } from '@osf/shared/models'; import { JsonApiService } from '@osf/shared/services'; import { ScopeMapper, TokenMapper } from '../mappers'; -import { ScopeJsonApi, ScopeModel, TokenCreateResponseJsonApi, TokenGetResponseJsonApi, TokenModel } from '../models'; +import { ScopeJsonApi, ScopeModel, TokenGetResponseJsonApi, TokenModel } from '../models'; import { TokensService } from './tokens.service'; @@ -86,11 +86,11 @@ describe('TokensService', () => { const scopes = ['read']; const requestBody = { name, scopes }; - const apiResponse = { data: { id: 'xyz' } } as JsonApiResponse; + const apiResponse = { data: { id: 'xyz' } } as JsonApiResponse; const mapped = { id: 'xyz' } as TokenModel; (TokenMapper.toRequest as jest.Mock).mockReturnValue(requestBody); - (TokenMapper.fromCreateResponse as jest.Mock).mockReturnValue(mapped); + (TokenMapper.fromGetResponse as jest.Mock).mockReturnValue(mapped); jsonApiServiceMock.post.mockReturnValue(of(apiResponse)); service.createToken(name, scopes).subscribe((token) => { @@ -106,11 +106,11 @@ describe('TokensService', () => { const scopes = ['write']; const requestBody = { name, scopes }; - const apiResponse = { id: tokenId } as TokenCreateResponseJsonApi; + const apiResponse = { id: tokenId } as TokenGetResponseJsonApi; const mapped = { id: tokenId } as TokenModel; (TokenMapper.toRequest as jest.Mock).mockReturnValue(requestBody); - (TokenMapper.fromCreateResponse as jest.Mock).mockReturnValue(mapped); + (TokenMapper.fromGetResponse as jest.Mock).mockReturnValue(mapped); jsonApiServiceMock.patch.mockReturnValue(of(apiResponse)); service.updateToken(tokenId, name, scopes).subscribe((token) => { diff --git a/src/app/shared/components/info-icon/info-icon.component.scss b/src/app/shared/components/info-icon/info-icon.component.scss index e69de29bb..4b374974e 100644 --- a/src/app/shared/components/info-icon/info-icon.component.scss +++ b/src/app/shared/components/info-icon/info-icon.component.scss @@ -0,0 +1,4 @@ +:host { + display: flex; + align-items: center; +} diff --git a/src/app/shared/components/wiki/wiki-syntax-help-dialog/wiki-syntax-help-dialog.component.html b/src/app/shared/components/wiki/wiki-syntax-help-dialog/wiki-syntax-help-dialog.component.html index 3c3417133..09b500b35 100644 --- a/src/app/shared/components/wiki/wiki-syntax-help-dialog/wiki-syntax-help-dialog.component.html +++ b/src/app/shared/components/wiki/wiki-syntax-help-dialog/wiki-syntax-help-dialog.component.html @@ -1,11 +1,14 @@

{{ 'project.wiki.syntaxHelp.startMsg' | translate }} - + {{ 'project.wiki.syntaxHelp.links.markdown' | translate }} {{ 'project.wiki.syntaxHelp.endMsg' | translate - }} {{ 'project.wiki.syntaxHelp.links.guide' | translate }}. + }} + {{ 'project.wiki.syntaxHelp.links.guide' | translate }}.

+
diff --git a/src/app/shared/enums/subscriptions/subscription-event.enum.ts b/src/app/shared/enums/subscriptions/subscription-event.enum.ts index 344013dda..f3913133f 100644 --- a/src/app/shared/enums/subscriptions/subscription-event.enum.ts +++ b/src/app/shared/enums/subscriptions/subscription-event.enum.ts @@ -1,9 +1,6 @@ export enum SubscriptionEvent { - GlobalCommentReplies = 'global_comment_replies', - GlobalComments = 'global_comments', GlobalFileUpdated = 'global_file_updated', GlobalMentions = 'global_mentions', GlobalReviews = 'global_reviews', - Comments = 'comments', FileUpdated = 'file_updated', } diff --git a/src/app/shared/mappers/registration/page-schema.mapper.ts b/src/app/shared/mappers/registration/page-schema.mapper.ts index 140ae9641..c82a2b454 100644 --- a/src/app/shared/mappers/registration/page-schema.mapper.ts +++ b/src/app/shared/mappers/registration/page-schema.mapper.ts @@ -1,5 +1,4 @@ -import { BlockType } from '@osf/shared/enums/block-type.enum'; -import { FieldType } from '@osf/shared/enums/field-type.enum'; +import { BlockType, FieldType } from '@osf/shared/enums'; import { PageSchema, Question, SchemaBlocksResponseJsonApi, Section } from '@osf/shared/models'; export class PageSchemaMapper { @@ -8,12 +7,14 @@ export class PageSchemaMapper { let currentPage!: PageSchema; let currentQuestion: Question | null = null; let currentSection: Section | null = null; + response.data.map((item) => { switch (item.attributes.block_type) { case BlockType.PageHeading: currentPage = { id: item.id, title: item.attributes.display_text, + helpText: item.attributes.help_text, questions: [], }; currentQuestion = null; @@ -25,6 +26,7 @@ export class PageSchemaMapper { currentSection = { id: item.id, title: item.attributes.display_text, + helpText: item.attributes.help_text, questions: [], }; currentPage.sections = currentPage.sections || []; diff --git a/src/app/shared/models/registration/page-schema.model.ts b/src/app/shared/models/registration/page-schema.model.ts index 95ee897f1..a235f5a92 100644 --- a/src/app/shared/models/registration/page-schema.model.ts +++ b/src/app/shared/models/registration/page-schema.model.ts @@ -1,8 +1,9 @@ -import { FieldType } from '@osf/shared/enums/field-type.enum'; +import { FieldType } from '@osf/shared/enums'; export interface PageSchema { id: string; title: string; + helpText?: string; description?: string; questions?: Question[]; sections?: Section[]; @@ -12,6 +13,7 @@ export interface Section { id: string; title: string; description?: string; + helpText?: string; questions?: Question[]; } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 4c408ceea..1dbe0333e 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -399,9 +399,6 @@ "wikiText": "Enable the wiki In [Dashboard] New and Noteworthy.", "wikiConfigureTitle": "Configure", "wikiConfigureText": "Create a link to share this project so those who have the link can view—but not edit—the project.", - "commenting": "Commenting", - "contributorsCanPost": "Only contributors can post comments", - "osfUserCanPost": "When the project is public, any OSF user can post comments", "emailNotifications": "Email Notifications", "emailNotificationsText": "These notification settings only apply to you. They do NOT affect any other contributor on this project.", "redirectLink": "Redirect Link", @@ -427,11 +424,6 @@ "message": "Are you sure you want to delete this view only link?" }, "descriptions": { - "comments": { - "instant": "You'll be notified immediately when someone adds a comment.", - "daily": "You'll receive a daily summary of comments.", - "none": "You won't receive comment notifications." - }, "file_updated": { "instant": "You'll be notified immediately when files are updated.", "daily": "You'll receive a daily summary of file updates.", @@ -972,6 +964,33 @@ "message": "Are you sure you want to delete {{name}}?" } }, + "filesBrowserDialog": { + "title": "Using the OSF Files Browser", + "seeAllFiles": "See All Files in a Provider", + "seeAllFilesDescription": "All connected storage providers are displayed in the left navbar. Choose one provider to view contents.", + "selectFilesFolders": "Select Files/Folders", + "selectFilesFoldersDescription": "Click on a row (outside of the file or folder name) to show further actions in the top toolbar. Click on more rows to select multiple files. To select a range of files, click a file to begin selection and then shift+click another file to select the range.", + "openViewFiles": "Open/View Files", + "openViewFilesDescription": "Click a file name to go to view the file in the OSF. Opens file in a new tab.", + "upload": "Upload.", + "uploadDescription": "There are two ways to upload files. Open the storage provider or folder where you intend to upload files; you can then drag files from your desktop into files list area OR click “Upload Files”, and select your files. Note: File names with special characters may cause unexpected behavior with certain addons.", + "createFolder": "Create a folder", + "createFolderDescription": "To create a folder to help organize your files, click “Create a Folder”. Note: You can also organize your project content by creating Components.", + "renameFolderFile": "Rename a folder or file", + "renameFolderFileDescription": "In the files list, select the file that you want to rename and click the vertical ellipses to open the dropdown. Select “Rename”. Note: Some special characters may cause unexpected behavior with certain addons.", + "move": "Move", + "moveDescription": "You can move your files from one part of your project or component to another. Select the files that you want to move, and click the vertical ellipses to open the dropdown, then click “move”. Choose a component, provider, or folder and then click “Move”.", + "copy": "Copy", + "copyDescription": "You can copy your files from one part of your project or component to another. Select the files that you want to copy, and click the vertical ellipses to open the dropdown, click the “Copy” button. Choose a component, provider, or folder and then click “Copy”. Your files will now appear in both the original and chosen locations.", + "downloadAllFilesZip": "Download All Files As a Zip", + "downloadAllFilesZipDescription": "Select the storage provider from the left navigation, and then click “Download As Zip” in the top toolbar.", + "downloadFolderZip": "Download a Folder as Zip", + "downloadFolderZipDescription": "To download a specific folder as a zip, click the vertical ellipses on the folder’s row to open the dropdown. Click “Download”. Alternatively, open the folder and then click “Download As Zip” in the top toolbar.", + "downloadFile": "Download a File", + "downloadFileDescription": "With the file open: Click the vertical ellipses to open the dropdown. Click “Download”. From the file list: Click the vertical ellipses of the file to open the dropdown. Click “Download”.", + "moreInfo": "For more information please see our", + "helpGuides": "help guides on project files." + }, "dropText": "Drop a file to upload", "emptyState": "This folder is empty", "detail": { @@ -1129,6 +1148,7 @@ "projectContributors": "Project Contributors", "collectionMetadata": "Collection Metadata", "tooltipMessage": "Complete previous step to edit this section", + "contributorsTooltip": "Projects must have at least one registered administrator and one author showing in the citation at all times. A registered administrator is a user who has both confirmed their account and has administrator privileges.", "noDescription": "No description", "noLicense": "No license", "noTags": "No tags", @@ -1388,9 +1408,6 @@ } }, "notifications": { - "header": { - "title": "Notifications" - }, "emailPreferences": { "title": "Configure Email Preferences", "items": { @@ -1408,9 +1425,8 @@ "notificationPreferences": { "title": "Configure Notification Preferences", "note": "Note: Transactional and administrative service emails will still be sent.", + "tooltipText": "These are default settings for new projects you create or are added to. Modifying these settings will not modify settings on existing projects.", "items": { - "replies": "Replies to your comments", - "comments": "Comments added", "files": "Files updated", "mentions": "Mentions added", "preprints": "Preprint submissions updated"