@if (institutions().length) {
@for (institution of institutions(); track institution.id) {
-
+
}
diff --git a/src/app/shared/components/affiliated-institutions-view/affiliated-institutions-view.component.ts b/src/app/shared/components/affiliated-institutions-view/affiliated-institutions-view.component.ts
index d8aaead15..3c60e7802 100644
--- a/src/app/shared/components/affiliated-institutions-view/affiliated-institutions-view.component.ts
+++ b/src/app/shared/components/affiliated-institutions-view/affiliated-institutions-view.component.ts
@@ -1,5 +1,7 @@
import { TranslatePipe } from '@ngx-translate/core';
+import { Tooltip } from 'primeng/tooltip';
+
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { RouterLink } from '@angular/router';
@@ -7,7 +9,7 @@ import { Institution } from '@shared/models';
@Component({
selector: 'osf-affiliated-institutions-view',
- imports: [TranslatePipe, RouterLink],
+ imports: [TranslatePipe, RouterLink, Tooltip],
templateUrl: './affiliated-institutions-view.component.html',
styleUrl: './affiliated-institutions-view.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html
index 62e4ea59f..a4464c84b 100644
--- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html
+++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html
@@ -104,15 +104,29 @@
{{ 'project.contributors.curatorInfo.heading' | translate }}
-
-
-
+ @if (isCurrentUserAdminContributor()) {
+
+
+
+ } @else {
+ @switch (contributor.permission) {
+ @case (ContributorPermission.Admin) {
+ {{ 'project.contributors.permissions.administrator' | translate }}
+ }
+ @case (ContributorPermission.Write) {
+ {{ 'project.contributors.permissions.readAndWrite' | translate }}
+ }
+ @case (ContributorPermission.Read) {
+ {{ 'project.contributors.permissions.read' | translate }}
+ }
+ }
+ }
|
@@ -121,6 +135,7 @@ {{ 'project.contributors.curatorInfo.heading' | translate }}
binary="true"
[(ngModel)]="contributor.isBibliographic"
[ariaLabel]="'project.contributors.table.headers.contributor' | translate"
+ [readonly]="!isCurrentUserAdminContributor()"
>
|
@@ -172,15 +187,17 @@
{{ 'project.contributors.curatorInfo.heading' | translate }}
}
-
+ @if (isCurrentUserAdminContributor() || currentUserId() === contributor.userId) {
+
+ }
|
} @else {
diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts b/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts
index 2fc1eef8b..9c0705668 100644
--- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts
+++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts
@@ -4,6 +4,7 @@ import { DialogService } from 'primeng/dynamicdialog';
import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ContributorPermission } from '@shared/enums';
import { MOCK_CONTRIBUTOR, MOCK_CONTRIBUTOR_WITHOUT_HISTORY, TranslateServiceMock } from '@shared/mocks';
import { ContributorModel } from '@shared/models';
@@ -127,10 +128,11 @@ describe('ContributorsListComponent', () => {
type: 'user',
isBibliographic: true,
isCurator: true,
+ isUnregisteredContributor: false,
fullName: 'Minimal User',
givenName: 'Minimal User',
familyName: 'Minimal User',
- permission: 'read',
+ permission: ContributorPermission.Read,
education: [],
employment: [],
};
diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts b/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts
index 5202d25e1..914d5895e 100644
--- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts
+++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.ts
@@ -10,8 +10,10 @@ import { Tooltip } from 'primeng/tooltip';
import { ChangeDetectionStrategy, Component, inject, input, output, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
+import { ModeratorPermission } from '@osf/features/moderation/enums';
import { DEFAULT_TABLE_PARAMS, PERMISSION_OPTIONS } from '@osf/shared/constants';
import { ContributorModel, SelectOption, TableParameters } from '@osf/shared/models';
+import { ContributorPermission } from '@shared/enums';
import { EducationHistoryDialogComponent } from '../../education-history-dialog/education-history-dialog.component';
import { EmploymentHistoryDialogComponent } from '../../employment-history-dialog/employment-history-dialog.component';
@@ -32,13 +34,17 @@ export class ContributorsListComponent {
showEducation = input(true);
showEmployment = input(true);
- remove = output
();
+ currentUserId = input(undefined);
+ isCurrentUserAdminContributor = input(true);
+ remove = output();
dialogService = inject(DialogService);
translateService = inject(TranslateService);
readonly tableParams = signal({ ...DEFAULT_TABLE_PARAMS });
readonly permissionsOptions: SelectOption[] = PERMISSION_OPTIONS;
+ readonly ModeratorPermission = ModeratorPermission;
+ readonly ContributorPermission = ContributorPermission;
skeletonData: ContributorModel[] = Array.from({ length: 3 }, () => ({}) as ContributorModel);
diff --git a/src/app/shared/components/filter-chips/filter-chips.component.ts b/src/app/shared/components/filter-chips/filter-chips.component.ts
index 5d356efb4..87f06aa1c 100644
--- a/src/app/shared/components/filter-chips/filter-chips.component.ts
+++ b/src/app/shared/components/filter-chips/filter-chips.component.ts
@@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
import { StringOrNull } from '@shared/helpers';
-import { DiscoverableFilter, SelectOption } from '@shared/models';
+import { DiscoverableFilter } from '@shared/models';
@Component({
selector: 'osf-filter-chips',
@@ -14,7 +14,6 @@ import { DiscoverableFilter, SelectOption } from '@shared/models';
})
export class FilterChipsComponent {
filterValues = input>({});
- filterOptionsCache = input>({});
filters = input.required();
filterRemoved = output();
diff --git a/src/app/shared/components/generic-filter/generic-filter.component.html b/src/app/shared/components/generic-filter/generic-filter.component.html
index 28d77b529..d72d96f17 100644
--- a/src/app/shared/components/generic-filter/generic-filter.component.html
+++ b/src/app/shared/components/generic-filter/generic-filter.component.html
@@ -9,6 +9,7 @@
[id]="filterType()"
[options]="filterOptions()"
optionLabel="label"
+ optionValue="value"
[ngModel]="selectedValue()"
[placeholder]="currentSelectedOption() ? currentSelectedOption()?.label : placeholder()"
styleClass="w-full"
diff --git a/src/app/shared/components/global-search/global-search.component.html b/src/app/shared/components/global-search/global-search.component.html
index 657133649..9e7d6a022 100644
--- a/src/app/shared/components/global-search/global-search.component.html
+++ b/src/app/shared/components/global-search/global-search.component.html
@@ -30,7 +30,6 @@
diff --git a/src/app/shared/components/reusable-filter/reusable-filter.component.ts b/src/app/shared/components/reusable-filter/reusable-filter.component.ts
index b87f4c87c..1031b44b3 100644
--- a/src/app/shared/components/reusable-filter/reusable-filter.component.ts
+++ b/src/app/shared/components/reusable-filter/reusable-filter.component.ts
@@ -74,7 +74,7 @@ export class ReusableFilterComponent {
filters.forEach((filter) => {
if (filter.operator === 'is-present') {
isPresentFilters.push(filter);
- } else if (filter.operator === 'any-of' || filter.operator === 'at-date') {
+ } else if (filter.operator.includes('any-of') || filter.operator.includes('at-date')) {
individualFilters.push(filter);
}
});
@@ -168,14 +168,6 @@ export class ReusableFilterComponent {
return filter.isLoading || false;
}
- isFilterPaginationLoading(filter: DiscoverableFilter): boolean {
- return filter.isPaginationLoading || false;
- }
-
- isFilterSearchLoading(filter: DiscoverableFilter): boolean {
- return filter.isSearchLoading || false;
- }
-
getSelectedValue(filterKey: string): string | null {
return this.selectedValues()[filterKey] || null;
}
diff --git a/src/app/shared/mappers/contributors/contributors.mapper.ts b/src/app/shared/mappers/contributors/contributors.mapper.ts
index 6fceb191d..7a95fc4b7 100644
--- a/src/app/shared/mappers/contributors/contributors.mapper.ts
+++ b/src/app/shared/mappers/contributors/contributors.mapper.ts
@@ -16,6 +16,7 @@ export class ContributorsMapper {
userId: contributor.embeds.users.data.id,
type: contributor.type,
isBibliographic: contributor.attributes.bibliographic,
+ isUnregisteredContributor: !!contributor.attributes.unregistered_contributor,
isCurator: contributor.attributes.is_curator,
permission: contributor.attributes.permission,
fullName: contributor.embeds.users.data.attributes.full_name,
@@ -50,6 +51,7 @@ export class ContributorsMapper {
type: response.type,
isBibliographic: response.attributes.bibliographic,
isCurator: response.attributes.is_curator,
+ isUnregisteredContributor: !!response.attributes.unregistered_contributor,
permission: response.attributes.permission,
fullName: response.embeds.users.data.attributes.full_name,
givenName: response.embeds.users.data.attributes.given_name,
diff --git a/src/app/shared/mocks/contributors.mock.ts b/src/app/shared/mocks/contributors.mock.ts
index 9b9e35744..cd641989c 100644
--- a/src/app/shared/mocks/contributors.mock.ts
+++ b/src/app/shared/mocks/contributors.mock.ts
@@ -1,3 +1,5 @@
+import { ContributorPermission } from '@shared/enums';
+
import { ContributorModel } from '../models';
export const MOCK_CONTRIBUTOR: ContributorModel = {
@@ -7,7 +9,8 @@ export const MOCK_CONTRIBUTOR: ContributorModel = {
fullName: 'John Doe',
givenName: 'John Doe',
familyName: 'John Doe',
- permission: 'read',
+ isUnregisteredContributor: false,
+ permission: ContributorPermission.Read,
isBibliographic: true,
isCurator: false,
education: [],
@@ -21,7 +24,8 @@ export const MOCK_CONTRIBUTOR_WITHOUT_HISTORY: ContributorModel = {
fullName: 'Jane Smith',
givenName: 'Jane Smith',
familyName: 'Jane Smith',
- permission: 'write',
+ isUnregisteredContributor: false,
+ permission: ContributorPermission.Write,
isBibliographic: false,
isCurator: true,
education: [],
diff --git a/src/app/shared/models/contributors/contributor-response.model.ts b/src/app/shared/models/contributors/contributor-response.model.ts
index ae471ae1a..1c77d8d86 100644
--- a/src/app/shared/models/contributors/contributor-response.model.ts
+++ b/src/app/shared/models/contributors/contributor-response.model.ts
@@ -1,11 +1,12 @@
import { ApiData, Education, Employment } from '@osf/shared/models';
+import { ContributorPermission } from '@shared/enums';
export type ContributorResponse = ApiData