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
4 changes: 4 additions & 0 deletions src/app/core/components/nav-menu/nav-menu.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@
border-radius: 0.5rem;
font-weight: 700;
}

::ng-deep li[aria-label="navigation.registriesSubRoutes.registryDetails"] {
border-left-color: transparent !important;
}
}
22 changes: 20 additions & 2 deletions src/app/core/components/nav-menu/nav-menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PanelMenuModule } from 'primeng/panelmenu';

import { filter, map } from 'rxjs';

import { Component, computed, inject, output } from '@angular/core';
import { Component, computed, effect, inject, output } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute, NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/router';

Expand All @@ -24,7 +24,7 @@ export class NavMenuComponent {
private readonly router = inject(Router);
private readonly route = inject(ActivatedRoute);

protected readonly menuItems = MENU_ITEMS;
protected menuItems = MENU_ITEMS;
protected readonly myProjectMenuItems = PROJECT_MENU_ITEMS;
protected readonly registrationMenuItems = REGISTRATION_MENU_ITEMS;

Expand All @@ -46,6 +46,22 @@ export class NavMenuComponent {
protected readonly isProjectRoute = computed(() => !!this.currentResourceId());
protected readonly isCollectionsRoute = computed(() => this.currentRoute().isCollectionsWithId);
protected readonly isRegistryRoute = computed(() => this.currentRoute().isRegistryRoute);
protected readonly isRegistryRouteDetails = computed(() => this.currentRoute().isRegistryRouteDetails);

constructor() {
effect(() => {
const isRouteDetails = this.isRegistryRouteDetails();
if (isRouteDetails) {
this.menuItems = this.menuItems.map((menuItem) => {
if (menuItem.id === 'registries') {
menuItem.expanded = true;
return menuItem;
}
return menuItem;
});
}
});
}

private getRouteInfo() {
const urlSegments = this.router.url.split('/').filter((segment) => segment);
Expand All @@ -55,12 +71,14 @@ export class NavMenuComponent {

const isCollectionsWithId = urlSegments[0] === 'collections' && urlSegments[1] && urlSegments[1] !== '';
const isRegistryRoute = urlSegments[0] === 'registries' && !!urlSegments[2];
const isRegistryRouteDetails = urlSegments[0] === 'registries' && urlSegments[2];

return {
resourceId,
section,
isCollectionsWithId,
isRegistryRoute,
isRegistryRouteDetails,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/app/core/constants/nav-items.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const MENU_ITEMS: MenuItem[] = [
styleClass: 'mt-5',
},
{
id: 'registries',
label: 'navigation.registries',
icon: 'osf-icon-registries',
routerLinkActiveOptions: { exact: true },
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/my-projects/my-projects.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
[isLoading]="isLoading()"
(pageChange)="onPageChange($event)"
(sort)="onSort($event)"
(itemClick)="navigateToProject($event)"
(itemClick)="navigateToRegistry($event)"
/>
</p-tabpanel>

Expand Down
5 changes: 5 additions & 0 deletions src/app/features/my-projects/my-projects.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,9 @@ export class MyProjectsComponent implements OnInit {
this.activeProject.set(project);
this.#router.navigate(['/my-projects', project.id]);
}

protected navigateToRegistry(registry: MyProjectsItem): void {
this.activeProject.set(registry);
this.#router.navigate(['/registries', registry.id]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ <h2>{{ 'preprints.preprintStepper.file.title' | translate }}</h2>
<section class="m-t-24">
@if (selectedProjectId()) {
<osf-files-tree
[currentFolder]="currentFolder()"
[files]="projectFiles()"
[isLoading]="areProjectFilesLoading()"
[projectId]="selectedProjectId()!"
[resourceId]="selectedProjectId()!"
[actions]="filesTreeActions"
(entryFileClicked)="selectProjectFile($event)"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Select, SelectChangeEvent } from 'primeng/select';
import { Skeleton } from 'primeng/skeleton';
import { Tooltip } from 'primeng/tooltip';

import { debounceTime, distinctUntilChanged, EMPTY, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, Observable } from 'rxjs';

import { NgClass, TitleCasePipe } from '@angular/common';
import {
Expand Down Expand Up @@ -37,6 +37,7 @@ import {
FetchProjectFilesByLink,
PreprintStepperSelectors,
ReuploadFile,
SetCurrentFolder,
SetSelectedPreprintFileSource,
UploadFile,
} from '@osf/features/preprints/store/preprint-stepper';
Expand Down Expand Up @@ -77,6 +78,7 @@ export class FileStepComponent implements OnInit {
getFilesForSelectedProject: FetchProjectFiles,
getProjectFilesByLink: FetchProjectFilesByLink,
copyFileFromProject: CopyFileFromProject,
setCurrentFolder: SetCurrentFolder,
});
private destroyRef = inject(DestroyRef);

Expand All @@ -91,26 +93,19 @@ export class FileStepComponent implements OnInit {
arePreprintFilesLoading = select(PreprintStepperSelectors.arePreprintFilesLoading);
availableProjects = select(PreprintStepperSelectors.getAvailableProjects);
areAvailableProjectsLoading = select(PreprintStepperSelectors.areAvailableProjectsLoading);
projectFiles = select(PreprintStepperSelectors.getProjectFiles);
areProjectFilesLoading = select(PreprintStepperSelectors.areProjectFilesLoading);
selectedProjectId = signal<StringOrNull>(null);
currentFolder = signal<OsfFile | null>(null);

versionFileMode = signal<boolean>(false);

projectNameControl = new FormControl<StringOrNull>(null);

filesTreeActions: FilesTreeActions = {
setCurrentFolder: (folder: OsfFile | null): Observable<void> => {
this.currentFolder.set(folder);
return EMPTY;
return this.actions.setCurrentFolder(folder);
},
getFiles: (filesLink: string): Observable<void> => {
return this.actions.getProjectFilesByLink(filesLink);
},
getRootFolderFiles: (projectId: string): Observable<void> => {
return this.actions.getFilesForSelectedProject(projectId);
},
};

nextClicked = output<void>();
Expand Down
4 changes: 4 additions & 0 deletions src/app/features/preprints/preprints.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PreprintStepperState } from '@osf/features/preprints/store/preprint-ste
import { PreprintsDiscoverState } from '@osf/features/preprints/store/preprints-discover';
import { PreprintsResourcesFiltersState } from '@osf/features/preprints/store/preprints-resources-filters';
import { PreprintsResourcesFiltersOptionsState } from '@osf/features/preprints/store/preprints-resources-filters-options';
import { ResourceType } from '@shared/enums';
import { ContributorsState, SubjectsState } from '@shared/stores';

import { ModeratorsState } from '../moderation/store/moderation';
Expand Down Expand Up @@ -69,6 +70,9 @@ export const preprintsRoutes: Routes = [
import('@osf/features/preprints/pages/submit-preprint-stepper/submit-preprint-stepper.component').then(
(c) => c.SubmitPreprintStepperComponent
),
data: {
context: ResourceType.Preprint,
},
canDeactivate: [ConfirmLeavingGuard],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,9 @@ export class ResetState {
export class DeletePreprint {
static readonly type = '[Submit Preprint] Delete Preprint';
}

export class SetCurrentFolder {
static readonly type = '[Submit Preprint] Set Current Folder';

constructor(public folder: OsfFile | null) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface PreprintStepperStateModel {
availableProjects: AsyncStateModel<IdName[]>;
projectFiles: AsyncStateModel<OsfFile[]>;
licenses: AsyncStateModel<License[]>;
currentFolder: OsfFile | null;
preprintProject: AsyncStateModel<IdName | null>;
hasBeenSubmitted: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,9 @@ export class PreprintStepperSelectors {
static hasBeenSubmitted(state: PreprintStepperStateModel) {
return state.hasBeenSubmitted;
}

@Selector([PreprintStepperState])
static getCurrentFolder(state: PreprintStepperStateModel) {
return state.currentFolder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
ResetState,
ReuploadFile,
SaveLicense,
SetCurrentFolder,
SetSelectedPreprintFileSource,
SetSelectedPreprintProviderId,
SubmitPreprint,
Expand Down Expand Up @@ -85,6 +86,7 @@ const DefaultState: PreprintStepperStateModel = {
error: null,
},
hasBeenSubmitted: false,
currentFolder: null,
};

@State<PreprintStepperStateModel>({
Expand Down Expand Up @@ -166,7 +168,7 @@ export class PreprintStepperState {

ctx.setState(patch({ preprintFiles: patch({ isLoading: true }) }));

return this.fileService.uploadFileByLink(action.file, state.preprintFilesLinks.data.uploadFileLink).pipe(
return this.fileService.uploadFile(action.file, state.preprintFilesLinks.data.uploadFileLink).pipe(
filter((event) => event.type === HttpEventType.Response),
switchMap((event) => {
const file = event.body!.data;
Expand Down Expand Up @@ -501,6 +503,11 @@ export class PreprintStepperState {
return EMPTY;
}

@Action(SetCurrentFolder)
setCurrentFolder(ctx: StateContext<PreprintStepperStateModel>, action: SetCurrentFolder) {
ctx.patchState({ currentFolder: action.folder });
}

private handleError(
ctx: StateContext<PreprintStepperStateModel>,
section: keyof PreprintStepperStateModel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { Button } from 'primeng/button';
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
import { Tooltip } from 'primeng/tooltip';

import { finalize, take } from 'rxjs';
import { finalize, take, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

import { NgOptimizedImage } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, signal } from '@angular/core';
Expand All @@ -22,7 +23,7 @@ import {
} from '@osf/features/project/files/store';
import { IconComponent, LoadingSpinnerComponent } from '@shared/components';
import { OsfFile } from '@shared/models';
import { FilesService } from '@shared/services';
import { FilesService, ToastService } from '@shared/services';

@Component({
selector: 'osf-move-file-dialog',
Expand All @@ -38,10 +39,12 @@ export class MoveFileDialogComponent {
private readonly filesService = inject(FilesService);
private readonly destroyRef = inject(DestroyRef);
private readonly translateService = inject(TranslateService);
private readonly toastService = inject(ToastService);

protected readonly files = select(ProjectFilesSelectors.getMoveFileFiles);
protected readonly isLoading = select(ProjectFilesSelectors.isMoveFileFilesLoading);
protected readonly currentFolder = select(ProjectFilesSelectors.getMoveFileCurrentFolder);
private readonly rootFolders = select(ProjectFilesSelectors.getRootFolders);
protected readonly isFilesUpdating = signal(false);
protected readonly isFolderSame = computed(() => {
return this.currentFolder()?.id === this.config.data.file.relationships.parentFolderId;
Expand All @@ -58,8 +61,11 @@ export class MoveFileDialogComponent {

constructor() {
const filesLink = this.currentFolder()?.relationships.filesLink;
const rootFolders = this.rootFolders();
if (filesLink) {
this.dispatch.getMoveFileFiles(filesLink);
} else if (rootFolders) {
this.dispatch.getMoveFileFiles(rootFolders[0].relationships.filesLink);
}
}

Expand All @@ -83,6 +89,10 @@ export class MoveFileDialogComponent {
takeUntilDestroyed(this.destroyRef),
finalize(() => {
this.isFilesUpdating.set(false);
}),
catchError((error) => {
this.toastService.showError(error.error.message);
return throwError(() => error);
})
)
.subscribe((folder) => {
Expand All @@ -107,7 +117,7 @@ export class MoveFileDialogComponent {
.moveFile(
this.config.data.file.links.move,
path,
this.config.data.projectId,
this.config.data.resourceId,
this.provider(),
this.config.data.action
)
Expand All @@ -117,17 +127,23 @@ export class MoveFileDialogComponent {
this.dispatch.setCurrentFolder(this.currentFolder());
this.dispatch.setMoveFileCurrentFolder(null);
this.isFilesUpdating.set(false);
this.dialogRef.close();
}),
catchError((error) => {
this.toastService.showError(error.error.message);
return throwError(() => error);
})
)
.subscribe((file) => {
this.dialogRef.close();

if (file.id) {
const filesLink = this.currentFolder()?.relationships.filesLink;
const rootFolders = this.rootFolders();
if (filesLink) {
this.dispatch.getFiles(filesLink);
} else {
this.dispatch.getRootFolderFiles(this.config.data.projectId);
} else if (rootFolders) {
this.dispatch.getMoveFileFiles(rootFolders[0].relationships.filesLink);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,14 @@ export const projectFilesStateDefaults = {
isLoading: false,
error: null,
},
rootFolders: {
data: [],
isLoading: true,
error: null,
},
configuredStorageAddons: {
data: [],
isLoading: true,
error: null,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ import { OsfFile } from '@shared/models';

export interface FilesTreeActions {
setCurrentFolder: (folder: OsfFile | null) => Observable<void>;
setSearch?: (search: string) => Observable<void>;
setSort?: (sort: string) => Observable<void>;
setFilesIsLoading?: (isLoading: boolean) => Observable<void>;
setFilesIsLoading?: (isLoading: boolean) => void;
getFiles: (filesLink: string) => Observable<void>;
getRootFolderFiles: (projectId: string) => Observable<void>;
deleteEntry?: (projectId: string, link: string) => Observable<void>;
renameEntry?: (projectId: string, link: string, newName: string) => Observable<void>;
setMoveFileCurrentFolder?: (folder: OsfFile | null) => Observable<void>;
Expand Down
Loading