diff --git a/src/app/core/store/user/user.state.ts b/src/app/core/store/user/user.state.ts
index b78fec37b..8b23a6aea 100644
--- a/src/app/core/store/user/user.state.ts
+++ b/src/app/core/store/user/user.state.ts
@@ -145,6 +145,8 @@ export class UserState {
data: user,
},
});
+
+ localStorage.setItem('currentUser', JSON.stringify(user));
})
);
}
@@ -168,6 +170,8 @@ export class UserState {
data: user,
},
});
+
+ localStorage.setItem('currentUser', JSON.stringify(user));
})
);
}
@@ -191,6 +195,8 @@ export class UserState {
data: user,
},
});
+
+ localStorage.setItem('currentUser', JSON.stringify(user));
})
);
}
@@ -221,6 +227,8 @@ export class UserState {
data: user,
},
});
+
+ localStorage.setItem('currentUser', JSON.stringify(user));
})
);
}
diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts
index fdb518e65..2f5c8506d 100644
--- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts
+++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts
@@ -8,12 +8,12 @@ import { DynamicDialogRef } from 'primeng/dynamicdialog';
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { AddProjectFormComponent } from '@osf/shared/components';
import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants';
+import { ProjectFormControls } from '@osf/shared/enums';
import { CustomValidators } from '@osf/shared/helpers';
-import { AddProjectFormComponent } from '@shared/components';
-import { ProjectFormControls } from '@shared/enums';
-import { ProjectForm } from '@shared/models';
-import { CreateProject, GetMyProjects, MyResourcesSelectors } from '@shared/stores';
+import { ProjectForm } from '@osf/shared/models';
+import { CreateProject, GetMyProjects, MyResourcesSelectors } from '@osf/shared/stores';
@Component({
selector: 'osf-create-project-dialog',
diff --git a/src/app/features/my-projects/mappers/my-resources.mapper.ts b/src/app/features/my-projects/mappers/my-resources.mapper.ts
index a95885995..18c79f9fe 100644
--- a/src/app/features/my-projects/mappers/my-resources.mapper.ts
+++ b/src/app/features/my-projects/mappers/my-resources.mapper.ts
@@ -1,4 +1,4 @@
-import { MyResourcesItem, MyResourcesItemGetResponseJsonApi } from 'src/app/shared/models/my-resources';
+import { MyResourcesItem, MyResourcesItemGetResponseJsonApi } from '@osf/shared/models';
export class MyResourcesMapper {
static fromResponse(response: MyResourcesItemGetResponseJsonApi): MyResourcesItem {
diff --git a/src/app/features/my-projects/my-projects.component.ts b/src/app/features/my-projects/my-projects.component.ts
index 0c4fd2404..a5b517912 100644
--- a/src/app/features/my-projects/my-projects.component.ts
+++ b/src/app/features/my-projects/my-projects.component.ts
@@ -23,27 +23,26 @@ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { FormControl, FormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
-import { CreateProjectDialogComponent } from '@osf/features/my-projects/components';
import { MyProjectsTableComponent, SelectComponent, SubHeaderComponent } from '@osf/shared/components';
import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants';
import { ResourceType, SortOrder } from '@osf/shared/enums';
import { IS_MEDIUM, parseQueryFilterParams } from '@osf/shared/helpers';
-import { QueryParams, TableParameters } from '@osf/shared/models';
-import { BookmarksSelectors, GetBookmarksCollectionId } from '@osf/shared/stores';
+import { MyResourcesItem, MyResourcesSearchFilters, QueryParams, TableParameters } from '@osf/shared/models';
import {
+ BookmarksSelectors,
ClearMyResources,
+ GetBookmarksCollectionId,
GetMyBookmarks,
GetMyPreprints,
GetMyProjects,
GetMyRegistrations,
MyResourcesSelectors,
-} from '@shared/stores';
+} from '@osf/shared/stores';
+import { CreateProjectDialogComponent } from './components';
import { MY_PROJECTS_TABS } from './constants';
import { MyProjectsTab } from './enums';
-import { MyResourcesItem, MyResourcesSearchFilters } from 'src/app/shared/models/my-resources';
-
@Component({
selector: 'osf-my-projects',
imports: [
diff --git a/src/app/features/preprints/pages/landing/preprints-landing.component.html b/src/app/features/preprints/pages/landing/preprints-landing.component.html
index 13845ba84..eb51009ec 100644
--- a/src/app/features/preprints/pages/landing/preprints-landing.component.html
+++ b/src/app/features/preprints/pages/landing/preprints-landing.component.html
@@ -73,7 +73,7 @@
{{ 'preprints.createServer.title' | translate }}
{{ 'preprints.createServer.and' | translate }}
- {{ 'preprints.createServer.publicRoadmap' | translate }} . {{ 'preprints.createServer.inputWelcome' | translate }}
diff --git a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html b/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html
index 4db891274..16c48218b 100644
--- a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html
+++ b/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html
@@ -8,7 +8,7 @@
@if (!isDuplicatesLoading() && currentResource()) {
@if (!duplicates().length) {
-
{{ 'project.overview.dialog.fork.noForksMessage' | translate }}
+
{{ 'project.overview.dialog.fork.noForksMessage' | translate }}
} @else {
{{ 'project.overview.dialog.fork.forksMessage' | translate }}
@@ -63,7 +63,7 @@
-
+
{{ 'common.labels.description' | translate }}:
diff --git a/src/app/features/project/contributors/components/create-view-link-dialog/create-view-link-dialog.component.html b/src/app/features/project/contributors/components/create-view-link-dialog/create-view-link-dialog.component.html
index 66a680e1f..468a6bc21 100644
--- a/src/app/features/project/contributors/components/create-view-link-dialog/create-view-link-dialog.component.html
+++ b/src/app/features/project/contributors/components/create-view-link-dialog/create-view-link-dialog.component.html
@@ -49,7 +49,7 @@
@@ -57,7 +57,7 @@
diff --git a/src/app/features/project/contributors/contributors.component.html b/src/app/features/project/contributors/contributors.component.html
index 3bf49b5fc..c03f81f75 100644
--- a/src/app/features/project/contributors/contributors.component.html
+++ b/src/app/features/project/contributors/contributors.component.html
@@ -4,7 +4,7 @@
{{ 'navigation.contributors' | translate }
@@ -73,13 +73,13 @@
{{ 'navigation.contributors' | translate }
-
+
}
@@ -89,7 +89,7 @@ {{ 'project.contributors.viewOnly' | translate }}
{{ 'project.contributors.createLink' | translate }}
-
+
{{ selectedScientist() }}
+
+
diff --git a/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.scss b/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.scss
index 91348bb81..e69de29bb 100644
--- a/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.scss
+++ b/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.scss
@@ -1,3 +0,0 @@
-.dialog-container {
- line-height: 1.7rem;
-}
diff --git a/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.ts b/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.ts
index 7be089082..c4b4e5361 100644
--- a/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.ts
+++ b/src/app/features/project/overview/components/duplicate-dialog/duplicate-dialog.component.ts
@@ -8,8 +8,9 @@ import { DynamicDialogRef } from 'primeng/dynamicdialog';
import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
-import { DuplicateProject, ProjectOverviewSelectors } from '@osf/features/project/overview/store';
-import { ToastService } from '@shared/services';
+import { ToastService } from '@osf/shared/services';
+
+import { DuplicateProject, ProjectOverviewSelectors } from '../../store';
@Component({
selector: 'osf-duplicate-dialog',
diff --git a/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.html b/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.html
index 04e346c56..3cc970e2f 100644
--- a/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.html
+++ b/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.html
@@ -6,13 +6,13 @@
diff --git a/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.ts b/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.ts
index 1b17c315a..7be6d2886 100644
--- a/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.ts
+++ b/src/app/features/project/overview/components/fork-dialog/fork-dialog.component.ts
@@ -10,10 +10,10 @@ import { finalize } from 'rxjs';
import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
-import { ForkResource, ProjectOverviewSelectors } from '@osf/features/project/overview/store';
-import { ResourceType } from '@shared/enums';
-import { ToolbarResource } from '@shared/models';
-import { ToastService } from '@shared/services';
+import { ToolbarResource } from '@osf/shared/models';
+import { ToastService } from '@osf/shared/services';
+
+import { ForkResource, ProjectOverviewSelectors } from '../../store';
@Component({
selector: 'osf-fork-dialog',
@@ -45,6 +45,4 @@ export class ForkDialogComponent {
)
.subscribe();
}
-
- protected readonly ResourceType = ResourceType;
}
diff --git a/src/app/features/project/overview/components/link-resource-dialog/link-resource-dialog.component.html b/src/app/features/project/overview/components/link-resource-dialog/link-resource-dialog.component.html
index 5fb99a496..e61ebec0e 100644
--- a/src/app/features/project/overview/components/link-resource-dialog/link-resource-dialog.component.html
+++ b/src/app/features/project/overview/components/link-resource-dialog/link-resource-dialog.component.html
@@ -3,6 +3,7 @@
[placeholder]="'project.overview.dialog.linkProject.searchObjectsPlaceholder' | translate"
[control]="searchControl"
>
+
+
+
+
(ResourceSearchMode.User);
protected resourceType = signal(ResourceType.Project);
diff --git a/src/app/features/project/overview/components/linked-resources/linked-resources.component.html b/src/app/features/project/overview/components/linked-resources/linked-resources.component.html
index 26583a283..c2d44da4c 100644
--- a/src/app/features/project/overview/components/linked-resources/linked-resources.component.html
+++ b/src/app/features/project/overview/components/linked-resources/linked-resources.component.html
@@ -5,7 +5,7 @@ {{ 'project.overview.linkedProjects.title' | translate }}
}
diff --git a/src/app/features/project/overview/components/linked-resources/linked-resources.component.scss b/src/app/features/project/overview/components/linked-resources/linked-resources.component.scss
index f6ab7d858..11f2598d5 100644
--- a/src/app/features/project/overview/components/linked-resources/linked-resources.component.scss
+++ b/src/app/features/project/overview/components/linked-resources/linked-resources.component.scss
@@ -1,9 +1,7 @@
-@use "/assets/styles/variables" as var;
-
.linked-project {
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: 12px;
- color: var.$dark-blue-1;
+ color: var(--dark-blue-1);
&-description {
line-height: 24px;
@@ -15,11 +13,11 @@
}
&-wrapper {
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: 12px;
}
&-title {
- color: var.$dark-blue-1;
+ color: var(--dark-blue-1);
}
}
diff --git a/src/app/features/project/overview/components/linked-resources/linked-resources.component.ts b/src/app/features/project/overview/components/linked-resources/linked-resources.component.ts
index c5528e311..bc3d43d62 100644
--- a/src/app/features/project/overview/components/linked-resources/linked-resources.component.ts
+++ b/src/app/features/project/overview/components/linked-resources/linked-resources.component.ts
@@ -9,10 +9,12 @@ import { Skeleton } from 'primeng/skeleton';
import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
-import { DeleteNodeLinkDialogComponent, LinkResourceDialogComponent } from '@osf/features/project/overview/components';
import { IconComponent, TruncatedTextComponent } from '@osf/shared/components';
import { IS_MEDIUM } from '@osf/shared/helpers';
-import { NodeLinksSelectors } from '@shared/stores';
+import { NodeLinksSelectors } from '@osf/shared/stores';
+
+import { DeleteNodeLinkDialogComponent } from '../delete-node-link-dialog/delete-node-link-dialog.component';
+import { LinkResourceDialogComponent } from '../link-resource-dialog/link-resource-dialog.component';
@Component({
selector: 'osf-linked-resources',
diff --git a/src/app/features/project/overview/components/overview-collections/overview-collections.component.ts b/src/app/features/project/overview/components/overview-collections/overview-collections.component.ts
index ef6ed9315..220def59a 100644
--- a/src/app/features/project/overview/components/overview-collections/overview-collections.component.ts
+++ b/src/app/features/project/overview/components/overview-collections/overview-collections.component.ts
@@ -12,8 +12,8 @@ import { Router } from '@angular/router';
import { collectionFilterNames } from '@osf/features/collections/constants';
import { SubmissionReviewStatus } from '@osf/features/moderation/enums';
-import { CollectionSubmission, ResourceOverview } from '@shared/models';
-import { CollectionsSelectors, GetProjectSubmissions } from '@shared/stores';
+import { CollectionSubmission, ResourceOverview } from '@osf/shared/models';
+import { CollectionsSelectors, GetProjectSubmissions } from '@osf/shared/stores';
@Component({
selector: 'osf-overview-collections',
@@ -25,6 +25,7 @@ import { CollectionsSelectors, GetProjectSubmissions } from '@shared/stores';
export class OverviewCollectionsComponent {
private readonly router = inject(Router);
protected readonly SubmissionReviewStatus = SubmissionReviewStatus;
+
currentProject = input.required();
projectSubmissions = select(CollectionsSelectors.getCurrentProjectSubmissions);
isProjectSubmissionsLoading = select(CollectionsSelectors.getCurrentProjectSubmissionsLoading);
@@ -34,9 +35,7 @@ export class OverviewCollectionsComponent {
return resource ? resource.id : null;
});
- protected actions = createDispatchMap({
- getProjectSubmissions: GetProjectSubmissions,
- });
+ protected actions = createDispatchMap({ getProjectSubmissions: GetProjectSubmissions });
constructor() {
effect(() => {
diff --git a/src/app/features/project/overview/components/overview-components/overview-components.component.scss b/src/app/features/project/overview/components/overview-components/overview-components.component.scss
index 61f3ba2ec..4166ac8b5 100644
--- a/src/app/features/project/overview/components/overview-components/overview-components.component.scss
+++ b/src/app/features/project/overview/components/overview-components/overview-components.component.scss
@@ -1,10 +1,9 @@
-@use "/assets/styles/variables" as var;
@use "/assets/styles/mixins" as mix;
.component {
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
- color: var.$dark-blue-1;
+ color: var(--dark-blue-1);
&-description {
border-radius: mix.rem(24px);
@@ -16,11 +15,11 @@
}
&-wrapper {
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
}
&-title {
- color: var.$dark-blue-1;
+ color: var(--dark-blue-1);
}
}
diff --git a/src/app/features/project/overview/components/overview-components/overview-components.component.ts b/src/app/features/project/overview/components/overview-components/overview-components.component.ts
index de6dca821..9d7b484cb 100644
--- a/src/app/features/project/overview/components/overview-components/overview-components.component.ts
+++ b/src/app/features/project/overview/components/overview-components/overview-components.component.ts
@@ -31,8 +31,10 @@ export class OverviewComponentsComponent {
private dialogService = inject(DialogService);
private translateService = inject(TranslateService);
protected isMobile = toSignal(inject(IS_XSMALL));
+
isCollectionsRoute = input(false);
canWrite = input.required();
+
protected components = select(ProjectOverviewSelectors.getComponents);
protected isComponentsLoading = select(ProjectOverviewSelectors.getComponentsLoading);
protected readonly componentActionItems = (componentId: string) => [
diff --git a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html
index dad385b37..b93911a05 100644
--- a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html
+++ b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html
@@ -87,7 +87,7 @@
@if (resource.isPublic) {
diff --git a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.ts b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.ts
index 2483cb8e3..cbb76ab8f 100644
--- a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.ts
+++ b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.ts
@@ -16,22 +16,23 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
-import { DuplicateDialogComponent, TogglePublicityDialogComponent } from '@osf/features/project/overview/components';
-import { SocialsShareActionItem } from '@osf/features/project/overview/models';
import { IconComponent } from '@osf/shared/components';
+import { ResourceType } from '@osf/shared/enums';
+import { ShareableContent, ToolbarResource } from '@osf/shared/models';
+import { FileSizePipe } from '@osf/shared/pipes';
import { SocialShareService, ToastService } from '@osf/shared/services';
-import { ResourceType } from '@shared/enums';
-import { ShareableContent, ToolbarResource } from '@shared/models';
-import { FileSizePipe } from '@shared/pipes';
import {
AddResourceToBookmarks,
BookmarksSelectors,
GetMyBookmarks,
MyResourcesSelectors,
RemoveResourceFromBookmarks,
-} from '@shared/stores';
+} from '@osf/shared/stores';
+import { SocialsShareActionItem } from '../../models';
+import { DuplicateDialogComponent } from '../duplicate-dialog/duplicate-dialog.component';
import { ForkDialogComponent } from '../fork-dialog/fork-dialog.component';
+import { TogglePublicityDialogComponent } from '../toggle-publicity-dialog/toggle-publicity-dialog.component';
@Component({
selector: 'osf-overview-toolbar',
@@ -62,6 +63,7 @@ export class OverviewToolbarComponent {
private readonly route = inject(ActivatedRoute);
protected isPublic = signal(false);
protected isBookmarked = signal(false);
+
isCollectionsRoute = input(false);
isAdmin = input.required();
currentResource = input.required();
diff --git a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.scss b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.scss
index a58598712..365d2c9ba 100644
--- a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.scss
+++ b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.scss
@@ -1,10 +1,9 @@
-@use "/assets/styles/variables" as var;
@use "/assets/styles/mixins" as mix;
.wiki {
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
- color: var.$dark-blue-1;
+ color: var(--dark-blue-1);
&-description {
line-height: mix.rem(24px);
diff --git a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts
index 26e3d8e85..801498c03 100644
--- a/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts
+++ b/src/app/features/project/overview/components/overview-wiki/overview-wiki.component.ts
@@ -6,8 +6,8 @@ import { Skeleton } from 'primeng/skeleton';
import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { MarkdownComponent, TruncatedTextComponent } from '@osf/shared/components';
import { WikiSelectors } from '@osf/shared/stores';
-import { MarkdownComponent, TruncatedTextComponent } from '@shared/components';
@Component({
selector: 'osf-project-wiki',
diff --git a/src/app/features/project/overview/components/recent-activity/recent-activity.component.ts b/src/app/features/project/overview/components/recent-activity/recent-activity.component.ts
index 8a9586d9b..0d9d88212 100644
--- a/src/app/features/project/overview/components/recent-activity/recent-activity.component.ts
+++ b/src/app/features/project/overview/components/recent-activity/recent-activity.component.ts
@@ -9,9 +9,9 @@ import { DatePipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject, input, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
-import { CustomPaginatorComponent } from '@shared/components';
-import { ActivityLogDisplayService } from '@shared/services';
-import { ActivityLogsSelectors, GetActivityLogs } from '@shared/stores/activity-logs';
+import { CustomPaginatorComponent } from '@osf/shared/components';
+import { ActivityLogDisplayService } from '@osf/shared/services';
+import { ActivityLogsSelectors, GetActivityLogs } from '@osf/shared/stores/activity-logs';
@Component({
selector: 'osf-recent-activity-list',
diff --git a/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.html b/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.html
index 7ef3dc4d7..beb31db2e 100644
--- a/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.html
+++ b/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.html
@@ -4,8 +4,7 @@
diff --git a/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.ts b/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.ts
index becdc680b..df1e9c940 100644
--- a/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.ts
+++ b/src/app/features/project/overview/components/toggle-publicity-dialog/toggle-publicity-dialog.component.ts
@@ -8,8 +8,9 @@ import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
-import { ProjectOverviewSelectors, UpdateProjectPublicStatus } from '@osf/features/project/overview/store';
-import { ToastService } from '@shared/services';
+import { ToastService } from '@osf/shared/services';
+
+import { ProjectOverviewSelectors, UpdateProjectPublicStatus } from '../../store';
@Component({
selector: 'osf-toggle-publicity-dialog',
@@ -22,9 +23,11 @@ export class TogglePublicityDialogComponent {
private store = inject(Store);
private dialogConfig = inject(DynamicDialogConfig);
private toastService = inject(ToastService);
+
protected dialogRef = inject(DynamicDialogRef);
protected destroyRef = inject(DestroyRef);
protected isSubmitting = select(ProjectOverviewSelectors.getUpdatePublicStatusSubmitting);
+
private newPublicStatus = signal(this.dialogConfig.data.newPublicStatus);
private projectId = signal(this.dialogConfig.data.projectId);
protected isCurrentlyPublic = signal(this.dialogConfig.data.isCurrentlyPublic);
diff --git a/src/app/features/project/overview/models/project-overview.models.ts b/src/app/features/project/overview/models/project-overview.models.ts
index 94440b041..cf67e88ec 100644
--- a/src/app/features/project/overview/models/project-overview.models.ts
+++ b/src/app/features/project/overview/models/project-overview.models.ts
@@ -1,6 +1,5 @@
import { UserPermissions } from '@osf/shared/enums';
-import { Institution, InstitutionsJsonApiResponse, JsonApiResponse } from '@osf/shared/models';
-import { License } from '@shared/models';
+import { Institution, InstitutionsJsonApiResponse, JsonApiResponse, License } from '@osf/shared/models';
export interface ProjectOverviewContributor {
familyName: string;
diff --git a/src/app/features/project/overview/project-overview.component.scss b/src/app/features/project/overview/project-overview.component.scss
index 73572f32d..f97e5c2b6 100644
--- a/src/app/features/project/overview/project-overview.component.scss
+++ b/src/app/features/project/overview/project-overview.component.scss
@@ -1,11 +1,9 @@
-@use "/assets/styles/variables" as var;
-
.left-section {
flex: 3;
}
.right-section {
width: 23rem;
- border: 1px solid var.$grey-2;
+ border: 1px solid var(--grey-2);
border-radius: 12px;
}
diff --git a/src/app/features/project/overview/project-overview.component.ts b/src/app/features/project/overview/project-overview.component.ts
index f4fc8f9ea..239de7915 100644
--- a/src/app/features/project/overview/project-overview.component.ts
+++ b/src/app/features/project/overview/project-overview.component.ts
@@ -23,32 +23,31 @@ import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { SubmissionReviewStatus } from '@osf/features/moderation/enums';
-import { IS_XSMALL } from '@osf/shared/helpers';
+import {
+ ClearCollectionModeration,
+ CollectionsModerationSelectors,
+ GetSubmissionsReviewActions,
+} from '@osf/features/moderation/store/collections-moderation';
import {
LoadingSpinnerComponent,
MakeDecisionDialogComponent,
ResourceMetadataComponent,
SubHeaderComponent,
-} from '@shared/components';
-import { Mode, ResourceType, UserPermissions } from '@shared/enums';
-import { MapProjectOverview } from '@shared/mappers/resource-overview.mappers';
-import { ToastService } from '@shared/services';
+} from '@osf/shared/components';
+import { Mode, ResourceType, UserPermissions } from '@osf/shared/enums';
+import { IS_XSMALL } from '@osf/shared/helpers';
+import { MapProjectOverview } from '@osf/shared/mappers';
+import { ToastService } from '@osf/shared/services';
import {
+ ClearCollections,
ClearWiki,
CollectionsSelectors,
GetBookmarksCollectionId,
GetCollectionProvider,
GetHomeWiki,
GetLinkedResources,
-} from '@shared/stores';
-import { GetActivityLogs } from '@shared/stores/activity-logs';
-import { ClearCollections } from '@shared/stores/collections';
-
-import {
- ClearCollectionModeration,
- CollectionsModerationSelectors,
- GetSubmissionsReviewActions,
-} from '../../moderation/store/collections-moderation';
+} from '@osf/shared/stores';
+import { GetActivityLogs } from '@osf/shared/stores/activity-logs';
import {
LinkedResourcesComponent,
@@ -92,20 +91,26 @@ import {
export class ProjectOverviewComponent implements OnInit {
@HostBinding('class') classes = 'flex flex-1 flex-column w-full h-full';
- private route = inject(ActivatedRoute);
- private router = inject(Router);
- private destroyRef = inject(DestroyRef);
- protected readonly toastService = inject(ToastService);
- protected readonly dialogService = inject(DialogService);
- protected readonly translateService = inject(TranslateService);
- protected isMobile = toSignal(inject(IS_XSMALL));
- protected submissions = select(CollectionsModerationSelectors.getCollectionSubmissions);
- protected collectionProvider = select(CollectionsSelectors.getCollectionProvider);
- protected currentReviewAction = select(CollectionsModerationSelectors.getCurrentReviewAction);
- protected readonly activityPageSize = 5;
- protected readonly activityDefaultPage = 1;
-
- protected actions = createDispatchMap({
+ private readonly route = inject(ActivatedRoute);
+ private readonly router = inject(Router);
+ private readonly destroyRef = inject(DestroyRef);
+ private readonly toastService = inject(ToastService);
+ private readonly dialogService = inject(DialogService);
+ private readonly translateService = inject(TranslateService);
+
+ isMobile = toSignal(inject(IS_XSMALL));
+ submissions = select(CollectionsModerationSelectors.getCollectionSubmissions);
+ collectionProvider = select(CollectionsSelectors.getCollectionProvider);
+ currentReviewAction = select(CollectionsModerationSelectors.getCurrentReviewAction);
+ isProjectLoading = select(ProjectOverviewSelectors.getProjectLoading);
+ isCollectionProviderLoading = select(CollectionsSelectors.getCollectionProviderLoading);
+ isReviewActionsLoading = select(CollectionsModerationSelectors.getCurrentReviewActionLoading);
+
+ readonly activityPageSize = 5;
+ readonly activityDefaultPage = 1;
+ readonly SubmissionReviewStatus = SubmissionReviewStatus;
+
+ private readonly actions = createDispatchMap({
getProject: GetProjectById,
getBookmarksId: GetBookmarksCollectionId,
getHomeWiki: GetHomeWiki,
@@ -163,12 +168,11 @@ export class ProjectOverviewComponent implements OnInit {
}
return null;
});
- protected isProjectLoading = select(ProjectOverviewSelectors.getProjectLoading);
- protected isCollectionProviderLoading = select(CollectionsSelectors.getCollectionProviderLoading);
- protected isReviewActionsLoading = select(CollectionsModerationSelectors.getCurrentReviewActionLoading);
+
protected isLoading = computed(() => {
return this.isProjectLoading() || this.isCollectionProviderLoading() || this.isReviewActionsLoading();
});
+
protected currentResource = computed(() => {
if (this.currentProject()) {
return {
@@ -264,6 +268,4 @@ export class ProjectOverviewComponent implements OnInit {
this.actions.clearCollectionModeration();
});
}
-
- protected readonly SubmissionReviewStatus = SubmissionReviewStatus;
}
diff --git a/src/app/features/project/overview/services/project-overview.service.ts b/src/app/features/project/overview/services/project-overview.service.ts
index 410c266b0..3512d1c7c 100644
--- a/src/app/features/project/overview/services/project-overview.service.ts
+++ b/src/app/features/project/overview/services/project-overview.service.ts
@@ -3,10 +3,9 @@ import { map } from 'rxjs/operators';
import { inject, Injectable } from '@angular/core';
-import { ComponentGetResponseJsonApi, ComponentOverview } from '@osf/shared/models';
+import { ComponentsMapper } from '@osf/shared/mappers';
+import { ComponentGetResponseJsonApi, ComponentOverview, JsonApiResponse } from '@osf/shared/models';
import { JsonApiService } from '@osf/shared/services';
-import { ComponentsMapper } from '@shared/mappers';
-import { JsonApiResponse } from '@shared/models';
import { ProjectOverviewMapper } from '../mappers';
import { ProjectOverview, ProjectOverviewResponseJsonApi } from '../models';
@@ -128,7 +127,7 @@ export class ProjectOverviewService {
return this.jsonApiService
.get<
JsonApiResponse
- >(`${environment.apiUrl}/nodes/${projectId}/children`, params)
+ >(`${environment.apiUrl}/nodes/${projectId}/children/`, params)
.pipe(map((response) => response.data.map((item) => ComponentsMapper.fromGetComponentResponse(item))));
}
}
diff --git a/src/app/features/project/overview/store/project-overview.model.ts b/src/app/features/project/overview/store/project-overview.model.ts
index d6f7f35d5..9f7241d0c 100644
--- a/src/app/features/project/overview/store/project-overview.model.ts
+++ b/src/app/features/project/overview/store/project-overview.model.ts
@@ -6,3 +6,18 @@ export interface ProjectOverviewStateModel {
project: AsyncStateModel;
components: AsyncStateModel;
}
+
+export const PROJECT_OVERVIEW_DEFAULTS: ProjectOverviewStateModel = {
+ project: {
+ data: null,
+ isLoading: false,
+ isSubmitting: false,
+ error: null,
+ },
+ components: {
+ data: [],
+ isLoading: false,
+ isSubmitting: false,
+ error: null,
+ },
+};
diff --git a/src/app/features/project/overview/store/project-overview.state.ts b/src/app/features/project/overview/store/project-overview.state.ts
index 0c4dd8073..52443f7e3 100644
--- a/src/app/features/project/overview/store/project-overview.state.ts
+++ b/src/app/features/project/overview/store/project-overview.state.ts
@@ -19,22 +19,7 @@ import {
SetProjectCustomCitation,
UpdateProjectPublicStatus,
} from './project-overview.actions';
-import { ProjectOverviewStateModel } from './project-overview.model';
-
-const PROJECT_OVERVIEW_DEFAULTS: ProjectOverviewStateModel = {
- project: {
- data: null,
- isLoading: false,
- isSubmitting: false,
- error: null,
- },
- components: {
- data: [],
- isLoading: false,
- isSubmitting: false,
- error: null,
- },
-};
+import { PROJECT_OVERVIEW_DEFAULTS, ProjectOverviewStateModel } from './project-overview.model';
@State({
name: 'projectOverview',
diff --git a/src/app/features/project/project.routes.ts b/src/app/features/project/project.routes.ts
index 5633aaf06..79d372493 100644
--- a/src/app/features/project/project.routes.ts
+++ b/src/app/features/project/project.routes.ts
@@ -2,7 +2,6 @@ import { provideStates } from '@ngxs/store';
import { Routes } from '@angular/router';
-import { CollectionsModerationState } from '@osf/features/moderation/store/collections-moderation';
import { ResourceType } from '@osf/shared/enums';
import {
CitationsState,
@@ -13,8 +12,9 @@ import {
SubjectsState,
ViewOnlyLinkState,
} from '@osf/shared/stores';
-import { ActivityLogsState } from '@shared/stores/activity-logs';
+import { ActivityLogsState } from '@osf/shared/stores/activity-logs';
+import { CollectionsModerationState } from '../moderation/store/collections-moderation';
import { NotificationSubscriptionState } from '../settings/notifications/store';
import { AnalyticsState } from './analytics/store';
diff --git a/src/app/features/project/registrations/components/index.ts b/src/app/features/project/registrations/components/index.ts
deleted file mode 100644
index 17108edd2..000000000
--- a/src/app/features/project/registrations/components/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { RegistrationCardComponent } from './registration-card/registration-card.component';
diff --git a/src/app/features/project/registrations/mock-data.ts b/src/app/features/project/registrations/mock-data.ts
deleted file mode 100644
index c5dc64c57..000000000
--- a/src/app/features/project/registrations/mock-data.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { RegistrationModel, RegistrationStatus } from './models';
-
-export const draftRegistrations: unknown = [
- {
- title: 'Registration Name Example',
- template: 'Open-Ended Registration',
- registry: 'OSF Registries',
- registeredDate: '6 Feb, 2025 15:30 GMT-0500',
- lastUpdated: '13 Feb, 2025 12:13 GMT-0500',
- contributors: [
- { name: 'Michael Pasek', link: '' },
- { name: 'Jeremy Ginges', link: '' },
- { name: 'Crystal Shackleford', link: '' },
- { name: 'ALLON VISHKIN', link: '' },
- ],
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt',
- status: 'draft',
- },
- {
- title: 'Registration Name Example 2',
- template: 'Open-Ended Registration 2',
- registry: 'OSF Registries 2',
- registeredDate: '6 Feb, 2025 15:30 GMT-0500',
- lastUpdated: '13 Feb, 2025 12:13 GMT-0500',
- contributors: [
- { name: 'Michael Pasek', link: '' },
- { name: 'Crystal Shackleford', link: '' },
- { name: 'ALLON VISHKIN', link: '' },
- ],
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt',
- status: 'draft',
- },
-];
-
-export const submittedRegistrations: RegistrationModel[] = [
- {
- id: '1',
- type: 'registration',
- withdrawn: false,
- title: 'Registration 1',
- registrationSupplement: 'Open-Ended Registration',
- registry: 'OSF Registries',
- dateRegistered: '16 Jan, 2022 15:30 GMT-0500',
- dateModified: '11 May, 2023 12:13 GMT-0500',
- contributors: [
- { name: 'Crystal Shackleford', link: '' },
- { name: 'ALLON VISHKIN', link: '' },
- ],
- description:
- 'Lorem ipsum dolor sit amet elit, sed do eiusmod tempor incididunt. Lorem elit, sed do eiusmod tempor incididunt, consectetur adipiscing elit, sed do.',
- status: RegistrationStatus.IN_PROGRESS,
- },
- {
- id: '2',
- type: 'registration',
- withdrawn: true,
- title: 'Registration Name Example 2',
- registrationSupplement: 'Open-Ended Registration 2',
- registry: 'OSF Registries 2',
- dateRegistered: '2 Jan, 2023 11:30 GMT-0500',
- dateModified: '4 Mar, 2024 12:55 GMT-0500',
- contributors: [
- { name: 'Crystal Shackleford', link: '' },
- { name: 'Michael Pasek', link: '' },
- ],
- description: 'Lorem consectetur adipiscing elit, sed do eiusmod tempor incididunt.',
- status: RegistrationStatus.WITHDRAWN,
- },
-];
diff --git a/src/app/features/project/registrations/registrations.component.scss b/src/app/features/project/registrations/registrations.component.scss
index f1c816620..e9dab5325 100644
--- a/src/app/features/project/registrations/registrations.component.scss
+++ b/src/app/features/project/registrations/registrations.component.scss
@@ -1,4 +1,3 @@
-@use "assets/styles/variables" as var;
@use "assets/styles/mixins" as mix;
:host {
diff --git a/src/app/features/project/registrations/registrations.component.ts b/src/app/features/project/registrations/registrations.component.ts
index 8c974d13e..0ea5be665 100644
--- a/src/app/features/project/registrations/registrations.component.ts
+++ b/src/app/features/project/registrations/registrations.component.ts
@@ -11,8 +11,7 @@ import { toSignal } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
-import { LoadingSpinnerComponent, SubHeaderComponent } from '@osf/shared/components';
-import { RegistrationCardComponent } from '@osf/shared/components/registration-card/registration-card.component';
+import { LoadingSpinnerComponent, RegistrationCardComponent, SubHeaderComponent } from '@osf/shared/components';
import { GetRegistrations, RegistrationsSelectors } from './store';
diff --git a/src/app/features/project/registrations/store/registrations.state.ts b/src/app/features/project/registrations/store/registrations.state.ts
index b51e1e032..40c119f15 100644
--- a/src/app/features/project/registrations/store/registrations.state.ts
+++ b/src/app/features/project/registrations/store/registrations.state.ts
@@ -1,9 +1,11 @@
import { Action, State, StateContext } from '@ngxs/store';
-import { catchError, tap, throwError } from 'rxjs';
+import { catchError, tap } from 'rxjs';
import { inject, Injectable } from '@angular/core';
+import { handleSectionError } from '@osf/shared/helpers';
+
import { RegistrationsService } from '../services';
import { GetRegistrations } from './registrations.actions';
@@ -45,18 +47,7 @@ export class RegistrationsState {
},
});
}),
- catchError((error) => this.handleError(ctx, 'registrations', error))
+ catchError((error) => handleSectionError(ctx, 'registrations', error))
);
}
-
- private handleError(ctx: StateContext, section: 'registrations', error: Error) {
- ctx.patchState({
- [section]: {
- ...ctx.getState()[section],
- isLoading: false,
- error: error.message,
- },
- });
- return throwError(() => error);
- }
}
diff --git a/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.html b/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.html
index e5060ec04..4a01216a3 100644
--- a/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.html
+++ b/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.html
@@ -7,8 +7,7 @@
variant="text"
severity="contrast"
(click)="toggle()"
- >
-
+ >
{{ title() }}
diff --git a/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.ts b/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.ts
index e1e57c03c..1ad7cb38e 100644
--- a/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.ts
+++ b/src/app/features/project/settings/components/project-detail-setting-accordion/project-detail-setting-accordion.component.ts
@@ -6,7 +6,7 @@ import { SelectModule } from 'primeng/select';
import { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
-import { RightControl } from '@osf/features/project/settings/models';
+import { RightControl } from '../../models';
@Component({
selector: 'osf-project-detail-setting-accordion',
diff --git a/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.ts b/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.ts
index bdb3cdc58..f70feaeba 100644
--- a/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.ts
+++ b/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.ts
@@ -4,12 +4,12 @@ import { Card } from 'primeng/card';
import { ChangeDetectionStrategy, Component, effect, input, output } from '@angular/core';
-import { ProjectDetailSettingAccordionComponent } from '@osf/features/project/settings/components';
-import { NotificationDescriptionPipe } from '@osf/features/project/settings/pipes';
import { NotificationSubscription } from '@osf/features/settings/notifications/models';
-import { SubscriptionEvent, SubscriptionFrequency } from '@shared/enums';
+import { SubscriptionEvent, SubscriptionFrequency } from '@osf/shared/enums';
import { RightControl } from '../../models';
+import { NotificationDescriptionPipe } from '../../pipes';
+import { ProjectDetailSettingAccordionComponent } from '../project-detail-setting-accordion/project-detail-setting-accordion.component';
@Component({
selector: 'osf-project-setting-notifications',
diff --git a/src/app/features/project/settings/components/settings-access-requests-card/settings-access-requests-card.component.html b/src/app/features/project/settings/components/settings-access-requests-card/settings-access-requests-card.component.html
index 9c842a8e4..c41274a91 100644
--- a/src/app/features/project/settings/components/settings-access-requests-card/settings-access-requests-card.component.html
+++ b/src/app/features/project/settings/components/settings-access-requests-card/settings-access-requests-card.component.html
@@ -3,7 +3,6 @@ {{ 'myProjects.settings.accessRequests' | translate }}
{{ 'myProjects.settings.commenting' | translate }}
{{ 'myProjects.settings.commenting' | translate }}
@@ -48,7 +40,7 @@
{{ 'myProjects.settings.project' | translate }}
{{ 'myProjects.settings.redirectLink' | translate }}
{{ 'myProjects.settings.redirectLink' | translate }}
type="text"
pInputText
id="link-url"
- aria-required="true"
- aria-describedby="link-url"
class="mt-2 w-full"
placeholder="{{ 'myProjects.settings.redirectUrlPlaceholder' | translate }}"
[(ngModel)]="redirectUrlData().url"
@@ -51,8 +48,6 @@ {{ 'myProjects.settings.redirectLink' | translate }}
type="text"
pInputText
id="link-label"
- aria-required="true"
- aria-describedby="link-label"
class="mt-2 w-full"
placeholder="{{ 'myProjects.settings.redirectLabelPlaceholder' | translate }}"
[(ngModel)]="redirectUrlData().label"
@@ -62,7 +57,7 @@ {{ 'myProjects.settings.redirectLink' | translate }}
{{ 'myProjects.settings.wiki' | translate }}
{
return this.jsonApiService
- .get(`${this.baseUrl}/nodes/${nodeId}/settings`)
+ .get(`${this.baseUrl}/nodes/${nodeId}/settings/`)
.pipe(map((response) => SettingsMapper.fromResponse(response, nodeId)));
}
updateProjectSettings(model: ProjectSettingsData): Observable {
return this.jsonApiService
- .patch(`${this.baseUrl}/nodes/${model.id}/settings`, { data: model })
+ .patch(`${this.baseUrl}/nodes/${model.id}/settings/`, { data: model })
.pipe(map((response) => SettingsMapper.fromResponse(response, model.id)));
}
deleteProject(projectId: string): Observable {
- return this.jsonApiService.delete(`${this.baseUrl}/nodes/${projectId}`);
+ return this.jsonApiService.delete(`${this.baseUrl}/nodes/${projectId}/`);
}
}
diff --git a/src/app/features/project/settings/settings.component.ts b/src/app/features/project/settings/settings.component.ts
index 9a1039b5d..ce5691c53 100644
--- a/src/app/features/project/settings/settings.component.ts
+++ b/src/app/features/project/settings/settings.component.ts
@@ -13,6 +13,18 @@ import { toSignal } from '@angular/core/rxjs-interop';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
+import {
+ GetNotificationSubscriptionsByNodeId,
+ NotificationSubscriptionSelectors,
+ UpdateNotificationSubscriptionForNodeId,
+} from '@osf/features/settings/notifications/store';
+import { SubHeaderComponent } from '@osf/shared/components';
+import { ProjectFormControls, ResourceType, SubscriptionEvent, SubscriptionFrequency } from '@osf/shared/enums';
+import { CustomValidators } from '@osf/shared/helpers';
+import { UpdateNodeRequestModel, ViewOnlyLinkModel } from '@osf/shared/models';
+import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
+import { DeleteViewOnlyLink, FetchViewOnlyLinks, ViewOnlyLinkSelectors } from '@osf/shared/stores';
+
import {
ProjectSettingNotificationsComponent,
SettingsAccessRequestsCardComponent,
@@ -22,12 +34,8 @@ import {
SettingsStorageLocationCardComponent,
SettingsViewOnlyLinksCardComponent,
SettingsWikiCardComponent,
-} from '@osf/features/project/settings/components';
-import {
- ProjectDetailsModel,
- ProjectSettingsAttributes,
- ProjectSettingsData,
-} from '@osf/features/project/settings/models';
+} from './components';
+import { ProjectDetailsModel, ProjectSettingsAttributes, ProjectSettingsData } from './models';
import {
DeleteProject,
GetProjectDetails,
@@ -35,18 +43,7 @@ import {
SettingsSelectors,
UpdateProjectDetails,
UpdateProjectSettings,
-} from '@osf/features/project/settings/store';
-import {
- GetNotificationSubscriptionsByNodeId,
- NotificationSubscriptionSelectors,
- UpdateNotificationSubscriptionForNodeId,
-} from '@osf/features/settings/notifications/store';
-import { CustomValidators } from '@osf/shared/helpers';
-import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
-import { DeleteViewOnlyLink, FetchViewOnlyLinks, ViewOnlyLinkSelectors } from '@osf/shared/stores';
-import { SubHeaderComponent } from '@shared/components';
-import { ProjectFormControls, ResourceType, SubscriptionEvent, SubscriptionFrequency } from '@shared/enums';
-import { UpdateNodeRequestModel, ViewOnlyLinkModel } from '@shared/models';
+} from './store';
@Component({
selector: 'osf-settings',
diff --git a/src/app/features/project/settings/store/settings.model.ts b/src/app/features/project/settings/store/settings.model.ts
index 87dd0f1ab..8137b3961 100644
--- a/src/app/features/project/settings/store/settings.model.ts
+++ b/src/app/features/project/settings/store/settings.model.ts
@@ -1,5 +1,4 @@
-import { NodeData } from '@shared/models';
-import { AsyncStateModel } from '@shared/models/store';
+import { AsyncStateModel, NodeData } from '@osf/shared/models';
import { ProjectSettingsModel } from '../models';
@@ -7,3 +6,16 @@ export interface SettingsStateModel {
settings: AsyncStateModel;
projectDetails: AsyncStateModel;
}
+
+export const SETTINGS_STATE_DEFAULTS: SettingsStateModel = {
+ settings: {
+ data: {} as ProjectSettingsModel,
+ isLoading: false,
+ error: null,
+ },
+ projectDetails: {
+ data: {} as NodeData,
+ isLoading: false,
+ error: null,
+ },
+};
diff --git a/src/app/features/project/settings/store/settings.state.ts b/src/app/features/project/settings/store/settings.state.ts
index 9263c66b2..218738d60 100644
--- a/src/app/features/project/settings/store/settings.state.ts
+++ b/src/app/features/project/settings/store/settings.state.ts
@@ -1,38 +1,28 @@
import { Action, State, StateContext } from '@ngxs/store';
-import { map, of, throwError } from 'rxjs';
+import { map, of } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { inject, Injectable } from '@angular/core';
-import { SettingsService } from '@osf/features/project/settings/services';
+import { handleSectionError } from '@osf/shared/helpers';
+import { NodeData } from '@osf/shared/models';
+import { MyResourcesService } from '@osf/shared/services';
+
+import { SettingsService } from '../services';
+
import {
DeleteProject,
GetProjectDetails,
GetProjectSettings,
UpdateProjectDetails,
UpdateProjectSettings,
-} from '@osf/features/project/settings/store/settings.actions';
-import { SettingsStateModel } from '@osf/features/project/settings/store/settings.model';
-import { NodeData } from '@shared/models';
-import { MyResourcesService } from '@shared/services';
-
-import { ProjectSettingsModel } from '../models';
+} from './settings.actions';
+import { SETTINGS_STATE_DEFAULTS, SettingsStateModel } from './settings.model';
@State({
name: 'settings',
- defaults: {
- settings: {
- data: {} as ProjectSettingsModel,
- isLoading: false,
- error: null,
- },
- projectDetails: {
- data: {} as NodeData,
- isLoading: false,
- error: null,
- },
- },
+ defaults: SETTINGS_STATE_DEFAULTS,
})
@Injectable()
export class SettingsState {
@@ -45,17 +35,6 @@ export class SettingsState {
return !lastFetched || Date.now() - lastFetched > this.REFRESH_INTERVAL;
}
- private handleError(ctx: StateContext, section: keyof SettingsStateModel, error: Error) {
- ctx.patchState({
- [section]: {
- ...ctx.getState()[section],
- isLoading: false,
- error: error.message,
- },
- });
- return throwError(() => error);
- }
-
@Action(GetProjectSettings)
getProjectSettings(ctx: StateContext, action: GetProjectSettings) {
const state = ctx.getState();
@@ -64,11 +43,7 @@ export class SettingsState {
if (cached.id === action.projectId && !shouldRefresh) {
return of(cached).pipe(
- tap(() =>
- ctx.patchState({
- settings: { ...state.settings, isLoading: false, error: null },
- })
- )
+ tap(() => ctx.patchState({ settings: { ...state.settings, isLoading: false, error: null } }))
);
}
@@ -79,6 +54,7 @@ export class SettingsState {
return this.settingsService.getProjectSettings(action.projectId).pipe(
tap((settings) => {
settings.lastFetched = Date.now();
+
ctx.patchState({
settings: {
data: settings,
@@ -87,7 +63,7 @@ export class SettingsState {
},
});
}),
- catchError((error) => this.handleError(ctx, 'settings', error))
+ catchError((error) => handleSectionError(ctx, 'settings', error))
);
}
@@ -107,9 +83,7 @@ export class SettingsState {
);
}
- ctx.patchState({
- projectDetails: { ...state.projectDetails, isLoading: true, error: null },
- });
+ ctx.patchState({ projectDetails: { ...state.projectDetails, isLoading: true, error: null } });
return this.myProjectService.getProjectById(action.projectId).pipe(
map((response) => response?.data as NodeData),
@@ -127,7 +101,7 @@ export class SettingsState {
},
});
}),
- catchError((error) => this.handleError(ctx, 'projectDetails', error))
+ catchError((error) => handleSectionError(ctx, 'projectDetails', error))
);
}
@@ -138,13 +112,13 @@ export class SettingsState {
ctx.patchState({
projectDetails: {
...ctx.getState().projectDetails,
- data: updatedProject.data,
+ data: updatedProject,
isLoading: false,
error: null,
},
});
}),
- catchError((error) => this.handleError(ctx, 'projectDetails', error))
+ catchError((error) => handleSectionError(ctx, 'projectDetails', error))
);
}
@@ -173,7 +147,7 @@ export class SettingsState {
error: error?.message,
},
});
- return this.handleError(ctx, 'settings', error);
+ return handleSectionError(ctx, 'settings', error);
})
);
}
diff --git a/src/app/features/project/wiki/wiki.component.ts b/src/app/features/project/wiki/wiki.component.ts
index 31922ebdb..102ae95cf 100644
--- a/src/app/features/project/wiki/wiki.component.ts
+++ b/src/app/features/project/wiki/wiki.component.ts
@@ -38,8 +38,6 @@ import {
WikiSelectors,
} from '@osf/shared/stores';
-const HomeWikiName = 'Home';
-
@Component({
selector: 'osf-wiki',
imports: [
@@ -60,7 +58,9 @@ export class WikiComponent {
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);
private toastService = inject(ToastService);
+
WikiModes = WikiModes;
+ homeWikiName = 'Home';
readonly projectId = toSignal(this.route.parent?.params.pipe(map((params) => params['id'])) ?? of(undefined));
protected wikiModes = select(WikiSelectors.getWikiModes);
@@ -104,7 +104,7 @@ export class WikiComponent {
this.navigateToWiki(this.wikiList()?.[0]?.id || '');
}
if (!this.wikiList()?.length) {
- this.actions.createWiki(ResourceType.Project, this.projectId(), HomeWikiName);
+ this.actions.createWiki(ResourceType.Project, this.projectId(), this.homeWikiName);
}
})
)
diff --git a/src/app/features/registries/components/registry-services/registry-services.component.scss b/src/app/features/registries/components/registry-services/registry-services.component.scss
index 8378698b2..be27f3dd0 100644
--- a/src/app/features/registries/components/registry-services/registry-services.component.scss
+++ b/src/app/features/registries/components/registry-services/registry-services.component.scss
@@ -1,8 +1,8 @@
@use "assets/styles/mixins" as mix;
-@use "assets/styles/variables" as var;
.services-background-image {
background: url("/assets/images/preprints/preprints-services-background.png") center;
+ background-size: cover;
}
.registry-service-item {
diff --git a/src/app/features/registry/registry.routes.ts b/src/app/features/registry/registry.routes.ts
index 73c66b43b..cbbdb84e1 100644
--- a/src/app/features/registry/registry.routes.ts
+++ b/src/app/features/registry/registry.routes.ts
@@ -2,9 +2,6 @@ import { provideStates } from '@ngxs/store';
import { Routes } from '@angular/router';
-import { RegistryComponentsState } from '@osf/features/registry/store/registry-components';
-import { RegistryLinksState } from '@osf/features/registry/store/registry-links';
-import { RegistryMetadataState } from '@osf/features/registry/store/registry-metadata';
import { ResourceType } from '@osf/shared/enums';
import { LicensesService } from '@osf/shared/services';
import {
@@ -20,8 +17,11 @@ import { RegistriesState } from '../registries/store';
import { LicensesHandlers, ProjectsHandlers, ProvidersHandlers } from '../registries/store/handlers';
import { FilesHandlers } from '../registries/store/handlers/files.handlers';
+import { RegistryComponentsState } from './store/registry-components';
+import { RegistryLinksState } from './store/registry-links';
+import { RegistryMetadataState } from './store/registry-metadata';
import { RegistryOverviewState } from './store/registry-overview';
-import { RegistryResourcesState } from './store/registry-resources/registry-resources.state';
+import { RegistryResourcesState } from './store/registry-resources';
import { RegistryComponent } from './registry.component';
export const registryRoutes: Routes = [
diff --git a/src/app/features/settings/profile-settings/components/education-form/education-form.component.html b/src/app/features/settings/profile-settings/components/education-form/education-form.component.html
index fc7bb904e..5fe9ca914 100644
--- a/src/app/features/settings/profile-settings/components/education-form/education-form.component.html
+++ b/src/app/features/settings/profile-settings/components/education-form/education-form.component.html
@@ -4,14 +4,14 @@
{{ 'settings.profileSettings.education.title' | translate: { index: index() + 1 } }}
-
+ }
diff --git a/src/app/features/settings/profile-settings/components/education-form/education-form.component.ts b/src/app/features/settings/profile-settings/components/education-form/education-form.component.ts
index 2f6ea4892..0bfeab450 100644
--- a/src/app/features/settings/profile-settings/components/education-form/education-form.component.ts
+++ b/src/app/features/settings/profile-settings/components/education-form/education-form.component.ts
@@ -34,6 +34,7 @@ export class EducationFormComponent implements OnInit {
group = input.required
();
index = input.required();
+ showRemove = input(false);
remove = output();
get institutionControl() {
diff --git a/src/app/features/settings/profile-settings/components/education/education.component.html b/src/app/features/settings/profile-settings/components/education/education.component.html
index e488f2233..7e09a236b 100644
--- a/src/app/features/settings/profile-settings/components/education/education.component.html
+++ b/src/app/features/settings/profile-settings/components/education/education.component.html
@@ -2,7 +2,12 @@
@if (educations.controls.length) {
@for (education of educations.controls; track $index; let index = $index) {
-
+ 1"
+ (remove)="removeEducation(index)"
+ >
}
}
@@ -20,12 +25,13 @@
class="w-6 btn-full-width md:w-auto"
[label]="'common.buttons.discardChanges' | translate"
severity="info"
+ [disabled]="!hasFormChanges()"
(onClick)="discardChanges()"
/>
diff --git a/src/app/features/settings/profile-settings/components/education/education.component.ts b/src/app/features/settings/profile-settings/components/education/education.component.ts
index 5b157bb41..d8864c649 100644
--- a/src/app/features/settings/profile-settings/components/education/education.component.ts
+++ b/src/app/features/settings/profile-settings/components/education/education.component.ts
@@ -20,8 +20,8 @@ import { UpdateProfileSettingsEducation, UserSelectors } from '@osf/core/store/u
import { CustomValidators } from '@osf/shared/helpers';
import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
+import { hasEducationChanges, mapEducationToForm, mapFormToEducation } from '../../helpers';
import { EducationForm } from '../../models';
-import { hasEducationChanges, mapEducationToForm, mapFormToEducation } from '../../utils';
import { EducationFormComponent } from '../education-form/education-form.component';
@Component({
@@ -107,9 +107,20 @@ export class EducationComponent {
});
}
- private hasFormChanges(): boolean {
- if (this.educations.length !== this.educationItems().length) {
- return true;
+ hasFormChanges(): boolean {
+ const education = this.educationItems();
+ const formPositions = this.educations.value;
+
+ if (!education?.length) {
+ return formPositions.some(
+ (position) =>
+ position.degree?.trim() ||
+ position.institution?.trim() ||
+ position.department?.trim() ||
+ position.startDate ||
+ position.endDate ||
+ position.ongoing
+ );
}
return this.educations.value.some((formEducation, index) => {
@@ -136,9 +147,15 @@ export class EducationComponent {
private setInitialData(): void {
const educations = this.educationItems();
- if (!educations?.length) return;
this.educations.clear();
+
+ if (!educations?.length) {
+ this.addEducation();
+ this.cd.markForCheck();
+ return;
+ }
+
educations
.map((education) => mapEducationToForm(education))
.forEach((education) => this.educations.push(this.createEducationFormGroup(education)));
diff --git a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.html b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.html
index 1402ff9ba..59d623cc7 100644
--- a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.html
+++ b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.html
@@ -4,14 +4,14 @@
{{ 'settings.profileSettings.employment.title' | translate: { index: index() + 1 } }}
-
+ }
diff --git a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.ts b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.ts
index 1f8f74fac..da5d0bbe9 100644
--- a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.ts
+++ b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.ts
@@ -33,6 +33,7 @@ export class EmploymentFormComponent implements OnInit {
group = input.required
();
index = input.required();
+ showRemove = input(false);
remove = output();
get titleControl() {
diff --git a/src/app/features/settings/profile-settings/components/employment/employment.component.html b/src/app/features/settings/profile-settings/components/employment/employment.component.html
index 13676a884..f6612da00 100644
--- a/src/app/features/settings/profile-settings/components/employment/employment.component.html
+++ b/src/app/features/settings/profile-settings/components/employment/employment.component.html
@@ -1,10 +1,13 @@
-@let havePositions = employment() && employment().length > 0;
-
diff --git a/src/app/features/settings/profile-settings/components/employment/employment.component.ts b/src/app/features/settings/profile-settings/components/employment/employment.component.ts
index c82c700dd..bfb0c7f3d 100644
--- a/src/app/features/settings/profile-settings/components/employment/employment.component.ts
+++ b/src/app/features/settings/profile-settings/components/employment/employment.component.ts
@@ -20,8 +20,8 @@ import { UpdateProfileSettingsEmployment, UserSelectors } from '@osf/core/store/
import { CustomValidators } from '@osf/shared/helpers';
import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
+import { hasEmploymentChanges, mapEmploymentToForm, mapFormToEmployment } from '../../helpers';
import { EmploymentForm } from '../../models';
-import { hasEmploymentChanges, mapEmploymentToForm, mapFormToEmployment } from '../../utils';
import { EmploymentFormComponent } from '../employment-form/employment-form.component';
@Component({
@@ -108,13 +108,28 @@ export class EmploymentComponent {
});
}
- private hasFormChanges(): boolean {
- if (this.positions.length !== this.employment().length) {
+ hasFormChanges(): boolean {
+ const employment = this.employment();
+ const formPositions = this.positions.value;
+
+ if (!employment?.length) {
+ return formPositions.some(
+ (position) =>
+ position.title?.trim() ||
+ position.institution?.trim() ||
+ position.department?.trim() ||
+ position.startDate ||
+ position.endDate ||
+ position.ongoing
+ );
+ }
+
+ if (formPositions.length !== employment.length) {
return true;
}
- return this.positions.value.some((formEmployment, index) => {
- const initial = this.employment()[index];
+ return formPositions.some((formEmployment, index) => {
+ const initial = employment[index];
if (!initial) return true;
return hasEmploymentChanges(formEmployment, initial);
@@ -137,9 +152,14 @@ export class EmploymentComponent {
private setInitialData(): void {
const employment = this.employment();
- if (!employment?.length) return;
-
this.positions.clear();
+
+ if (!employment?.length) {
+ this.addPosition();
+ this.cd.markForCheck();
+ return;
+ }
+
employment
.map((x) => mapEmploymentToForm(x))
.forEach((x) => this.positions.push(this.createEmploymentFormGroup(x)));
diff --git a/src/app/features/settings/profile-settings/components/name/name.component.html b/src/app/features/settings/profile-settings/components/name/name.component.html
index edbfd80b9..88aeacda8 100644
--- a/src/app/features/settings/profile-settings/components/name/name.component.html
+++ b/src/app/features/settings/profile-settings/components/name/name.component.html
@@ -7,13 +7,14 @@
class="w-6 btn-full-width md:w-auto"
[label]="'common.buttons.discardChanges' | translate"
severity="info"
+ [disabled]="!hasFormChanges()"
(onClick)="discardChanges()"
/>
diff --git a/src/app/features/settings/profile-settings/components/name/name.component.ts b/src/app/features/settings/profile-settings/components/name/name.component.ts
index 805df6f18..2206d7b71 100644
--- a/src/app/features/settings/profile-settings/components/name/name.component.ts
+++ b/src/app/features/settings/profile-settings/components/name/name.component.ts
@@ -13,8 +13,8 @@ import { CustomValidators } from '@osf/shared/helpers';
import { User } from '@osf/shared/models';
import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
+import { hasNameChanges } from '../../helpers';
import { NameForm } from '../../models';
-import { hasNameChanges } from '../../utils';
import { CitationPreviewComponent } from '../citation-preview/citation-preview.component';
import { NameFormComponent } from '../name-form/name-form.component';
@@ -105,7 +105,7 @@ export class NameComponent {
});
}
- private hasFormChanges(): boolean {
+ hasFormChanges(): boolean {
const user = this.currentUser();
if (!user) return false;
diff --git a/src/app/features/settings/profile-settings/components/social/social.component.html b/src/app/features/settings/profile-settings/components/social/social.component.html
index 982c001f7..e34553fe1 100644
--- a/src/app/features/settings/profile-settings/components/social/social.component.html
+++ b/src/app/features/settings/profile-settings/components/social/social.component.html
@@ -11,11 +11,13 @@
class="w-6 btn-full-width md:w-auto"
[label]="'common.buttons.discardChanges' | translate"
severity="info"
+ [disabled]="!hasFormChanges()"
(onClick)="discardChanges()"
/>
diff --git a/src/app/features/settings/profile-settings/components/social/social.component.ts b/src/app/features/settings/profile-settings/components/social/social.component.ts
index 66889866a..cd023b17b 100644
--- a/src/app/features/settings/profile-settings/components/social/social.component.ts
+++ b/src/app/features/settings/profile-settings/components/social/social.component.ts
@@ -21,8 +21,8 @@ import { Social } from '@osf/shared/models';
import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services';
import { SOCIALS } from '../../constants/socials';
+import { hasSocialLinkChanges, mapSocialLinkToPayload } from '../../helpers';
import { SocialLinksForm } from '../../models';
-import { hasSocialLinkChanges, mapSocialLinkToPayload } from '../../utils';
import { SocialFormComponent } from '../social-form/social-form.component';
@Component({
@@ -95,7 +95,7 @@ export class SocialComponent {
});
}
- private hasFormChanges(): boolean {
+ hasFormChanges(): boolean {
const currentLinks = this.socialLinksForm.value.links as SocialLinksForm[];
const initialSocialLinks = this.socialLinks();
@@ -110,9 +110,9 @@ export class SocialComponent {
this.socials.forEach((social) => {
const key = social.key;
- const socialLink = socialLinks?.[key] ?? null;
+ const socialLink = socialLinks?.[key] ?? '';
const linkedKey = social.linkedField?.key;
- const linkedValue = linkedKey ? (socialLinks?.[linkedKey] ?? null) : null;
+ const linkedValue = linkedKey ? (socialLinks?.[linkedKey] ?? '') : '';
const socialLinkGroup = this.fb.group({
socialOutput: [social],
webAddress: [socialLink],
diff --git a/src/app/features/settings/profile-settings/utils/education-comparison.util.ts b/src/app/features/settings/profile-settings/helpers/education-comparison.helper.ts
similarity index 90%
rename from src/app/features/settings/profile-settings/utils/education-comparison.util.ts
rename to src/app/features/settings/profile-settings/helpers/education-comparison.helper.ts
index a7ad940db..9ddaae7dc 100644
--- a/src/app/features/settings/profile-settings/utils/education-comparison.util.ts
+++ b/src/app/features/settings/profile-settings/helpers/education-comparison.helper.ts
@@ -4,12 +4,13 @@ import { Education } from '@osf/shared/models';
import { EducationForm } from '../models';
export function mapFormToEducation(education: EducationForm): Education {
+ console.log(education.startDate);
return {
institution: education.institution,
department: education.department,
degree: education.degree,
- startYear: education.startDate?.getFullYear() ?? new Date().getFullYear(),
- startMonth: (education.startDate?.getMonth() ?? 0) + 1,
+ startYear: education.startDate?.getFullYear() ?? null,
+ startMonth: education.startDate?.getMonth() ?? null,
endYear: education.ongoing ? null : (education.endDate?.getFullYear() ?? null),
endMonth: education.ongoing ? null : education.endDate ? education.endDate.getMonth() + 1 : null,
ongoing: education.ongoing,
diff --git a/src/app/features/settings/profile-settings/utils/employment-comparison.util.ts b/src/app/features/settings/profile-settings/helpers/employment-comparison.helper.ts
similarity index 100%
rename from src/app/features/settings/profile-settings/utils/employment-comparison.util.ts
rename to src/app/features/settings/profile-settings/helpers/employment-comparison.helper.ts
diff --git a/src/app/features/settings/profile-settings/helpers/index.ts b/src/app/features/settings/profile-settings/helpers/index.ts
new file mode 100644
index 000000000..73d1e8190
--- /dev/null
+++ b/src/app/features/settings/profile-settings/helpers/index.ts
@@ -0,0 +1,4 @@
+export * from './education-comparison.helper';
+export * from './employment-comparison.helper';
+export * from './name-comparison.helper';
+export * from './social-comparison.helper';
diff --git a/src/app/features/settings/profile-settings/utils/name-comparison.util.ts b/src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts
similarity index 100%
rename from src/app/features/settings/profile-settings/utils/name-comparison.util.ts
rename to src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts
diff --git a/src/app/features/settings/profile-settings/utils/social-comparison.util.ts b/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts
similarity index 60%
rename from src/app/features/settings/profile-settings/utils/social-comparison.util.ts
rename to src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts
index 3248927cf..fc82bf595 100644
--- a/src/app/features/settings/profile-settings/utils/social-comparison.util.ts
+++ b/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts
@@ -1,6 +1,6 @@
import { Social } from '@osf/shared/models';
-import { SOCIAL_KEYS, SocialLinksForm, SocialLinksKeys } from '../models';
+import { SOCIAL_KEYS, SocialLinksForm, SocialLinksKeys, SocialLinksModel } from '../models';
export function normalizeValue(value: unknown, key: SocialLinksKeys): unknown {
if (SOCIAL_KEYS.includes(key)) {
@@ -11,12 +11,12 @@ export function normalizeValue(value: unknown, key: SocialLinksKeys): unknown {
export function mapSocialLinkToPayload(link: SocialLinksForm): Partial
{
const key = link.socialOutput.key as SocialLinksKeys;
- const linkedKey = link.socialOutput.linkedField?.key as SocialLinksKeys | undefined;
+ const linkedKey = link.socialOutput.linkedField?.key as SocialLinksKeys;
const value = SOCIAL_KEYS.includes(key)
? Array.isArray(link.webAddress)
? link.webAddress
- : [link.webAddress]
+ : [link.webAddress].filter(Boolean)
: link.webAddress;
const result: Partial = { [key]: value };
@@ -33,30 +33,31 @@ export function hasSocialLinkChanges(
link: SocialLinksForm,
initialSocialLinks: Social,
socialIndex: number,
- socials: readonly { key: string; linkedField?: { key: string } }[]
+ socials: SocialLinksModel[]
): boolean {
- const mappedLink = mapSocialLinkToPayload(link);
const social = socials[socialIndex];
-
if (!social) return true;
- const key = social.key as SocialLinksKeys;
- const linkedKey = social.linkedField?.key as SocialLinksKeys | undefined;
+ const mappedLink = mapSocialLinkToPayload(link);
+ const { key, linkedField } = social;
+
+ const hasChanged = (currentKey: keyof Social) => {
+ const current = mappedLink[currentKey];
+ const initial = normalizeValue(initialSocialLinks[currentKey], currentKey);
+
+ if (!current && !initial) {
+ return false;
+ }
- const currentValue = mappedLink[key];
- const initialValue = normalizeValue(initialSocialLinks[key], key);
+ return JSON.stringify(current) !== JSON.stringify(initial);
+ };
- if (JSON.stringify(currentValue) !== JSON.stringify(initialValue)) {
+ if (hasChanged(key)) {
return true;
}
- if (linkedKey) {
- const currentLinkedValue = mappedLink[linkedKey];
- const initialLinkedValue = normalizeValue(initialSocialLinks[linkedKey], linkedKey);
-
- if (JSON.stringify(currentLinkedValue) !== JSON.stringify(initialLinkedValue)) {
- return true;
- }
+ if (linkedField?.key && hasChanged(linkedField.key)) {
+ return true;
}
return false;
diff --git a/src/app/features/settings/profile-settings/utils/index.ts b/src/app/features/settings/profile-settings/utils/index.ts
deleted file mode 100644
index 76d5d1227..000000000
--- a/src/app/features/settings/profile-settings/utils/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './education-comparison.util';
-export * from './employment-comparison.util';
-export * from './name-comparison.util';
-export * from './social-comparison.util';
diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts
index 6974e4394..8b6b3a881 100644
--- a/src/app/shared/components/index.ts
+++ b/src/app/shared/components/index.ts
@@ -30,6 +30,7 @@ export { PieChartComponent } from './pie-chart/pie-chart.component';
export { ProjectSelectorComponent } from './project-selector/project-selector.component';
export { ReadonlyInputComponent } from './readonly-input/readonly-input.component';
export { RegistrationBlocksDataComponent } from './registration-blocks-data/registration-blocks-data.component';
+export { RegistrationCardComponent } from './registration-card/registration-card.component';
export { ResourceCardComponent } from './resource-card/resource-card.component';
export { ResourceMetadataComponent } from './resource-metadata/resource-metadata.component';
export { ReusableFilterComponent } from './reusable-filter/reusable-filter.component';
diff --git a/src/app/shared/services/my-resources.service.ts b/src/app/shared/services/my-resources.service.ts
index c4f80cb27..c63d1f178 100644
--- a/src/app/shared/services/my-resources.service.ts
+++ b/src/app/shared/services/my-resources.service.ts
@@ -14,6 +14,7 @@ import {
MyResourcesItemResponseJsonApi,
MyResourcesResponseJsonApi,
MyResourcesSearchFilters,
+ NodeData,
NodeResponseModel,
UpdateNodeRequestModel,
} from '@shared/models';
@@ -212,10 +213,10 @@ export class MyResourcesService {
}
getProjectById(projectId: string): Observable {
- return this.jsonApiService.get(`${this.apiUrl}/nodes/${projectId}`);
+ return this.jsonApiService.get(`${this.apiUrl}/nodes/${projectId}/`);
}
- updateProjectById(model: UpdateNodeRequestModel): Observable {
- return this.jsonApiService.patch(`${this.apiUrl}/nodes/${model?.data?.id}`, model);
+ updateProjectById(model: UpdateNodeRequestModel): Observable {
+ return this.jsonApiService.patch(`${this.apiUrl}/nodes/${model?.data?.id}/`, model);
}
}
diff --git a/src/app/shared/services/view-only-links.service.ts b/src/app/shared/services/view-only-links.service.ts
index 98993c799..7933f3023 100644
--- a/src/app/shared/services/view-only-links.service.ts
+++ b/src/app/shared/services/view-only-links.service.ts
@@ -37,7 +37,7 @@ export class ViewOnlyLinksService {
const params: Record = { embed: 'creator' };
return this.jsonApiService
- .get(`${environment.apiUrl}/${resourcePath}/${projectId}/view_only_links`, params)
+ .get(`${environment.apiUrl}/${resourcePath}/${projectId}/view_only_links/`, params)
.pipe(map((response) => ViewOnlyLinksMapper.fromResponse(response, projectId)));
}
diff --git a/src/app/shared/services/wiki.service.ts b/src/app/shared/services/wiki.service.ts
index 3ee476bc6..e6e6fdeb8 100644
--- a/src/app/shared/services/wiki.service.ts
+++ b/src/app/shared/services/wiki.service.ts
@@ -42,7 +42,7 @@ export class WikiService {
throw new Error(`Unsupported resource type: ${resourceType}`);
}
- return `${baseUrl}/${resourcePath}/${resourceId}/wikis`;
+ return `${baseUrl}/${resourcePath}/${resourceId}/wikis/`;
}
createWiki(projectId: string, name: string): Observable {
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index e1bfc9fcc..c217e0403 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -1823,7 +1823,7 @@
"description": "Leading preprint service providers use this open source infrastructure to support their communities."
},
"createServer": {
- "title": "Create your own branded preprint servers backed by the OSF?",
+ "title": "Create your own branded preprint servers backed by the OSF",
"description": "Check out the",
"openSourceCode": "open source code",
"and": "and",