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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<osf-sub-header
[title]="'project.analytics.kpi.forks' | translate"
[showButton]="true"
[showButton]="!hasNoPermissions()"
[buttonLabel]="'project.overview.actions.forkProjectLabel' | translate"
(buttonClick)="handleForkResource()"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { IS_SMALL } from '@osf/shared/helpers';
import { ToolbarResource } from '@osf/shared/models';
import { Duplicate } from '@osf/shared/models/duplicates';
import { CustomDialogService } from '@osf/shared/services';
import { ClearDuplicates, DuplicatesSelectors, GetAllDuplicates } from '@osf/shared/stores';
import { ClearDuplicates, CurrentResourceSelectors, DuplicatesSelectors, GetAllDuplicates } from '@osf/shared/stores';

@Component({
selector: 'osf-view-duplicates',
Expand Down Expand Up @@ -76,6 +76,7 @@ export class ViewDuplicatesComponent {
duplicates = select(DuplicatesSelectors.getDuplicates);
isDuplicatesLoading = select(DuplicatesSelectors.getDuplicatesLoading);
totalDuplicates = select(DuplicatesSelectors.getDuplicatesTotalCount);
hasNoPermissions = select(CurrentResourceSelectors.hasNoPermissions);

readonly pageSize = 10;
readonly UserPermissions = UserPermissions;
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/metadata/metadata.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@
[resourceType]="resourceType()"
/>

@if (showRegistrationDoi()) {
@if (isRegistrationType()) {
<osf-metadata-registration-doi [identifiers]="metadata()?.identifiers!"></osf-metadata-registration-doi>
}

<osf-metadata-tags
[tags]="metadata()?.tags || []"
(tagsChanged)="onTagsChanged($event)"
[readonly]="!hasWriteAccess()"
[readonly]="isRegistrationType() ? !hasAdminAccess() : !hasWriteAccess()"
></osf-metadata-tags>

<osf-metadata-subjects
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/metadata/metadata.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export class MetadataComponent implements OnInit {
);
});

showRegistrationDoi = computed(() => this.resourceType() === ResourceType.Registration);
isRegistrationType = computed(() => this.resourceType() === ResourceType.Registration);

bibliographicContributors = computed(() => this.contributors().filter((contributor) => contributor.isBibliographic));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,87 +37,89 @@
}
}

<div class="flex ml-auto">
<div class="flex flex-1 flex-column-reverse gap-3 justify-content-end sm:gap-3 sm:flex-row-reverse lg:flex-row">
@if (resource.storage && !isCollectionsRoute()) {
<p class="font-bold mr-2 ml-0 mt-2 sm:ml-2 sm:mt-0 sm:align-self-center storage">
{{ +resource.storage.storageUsage | fileSize }}
</p>
}

<div class="flex gap-2 justify-content-start">
@if (showViewOnlyLinks() && canEdit()) {
<p-button
class="flex"
[pTooltip]="'project.overview.tooltips.viewOnlyLinks' | translate"
tooltipPosition="bottom"
[routerLink]="'../contributors'"
[ariaLabel]="'project.overview.tooltips.viewOnlyLinks' | translate"
>
<span class="font-bold">{{ resource.viewOnlyLinksCount }}</span>
<i class="fas fa-link text-2xl"></i>
</p-button>
@if (!hasNoPermissions()) {
<div class="flex ml-auto">
<div class="flex flex-1 flex-column-reverse gap-3 justify-content-end sm:gap-3 sm:flex-row-reverse lg:flex-row">
@if (resource.storage && !isCollectionsRoute()) {
<p class="font-bold mr-2 ml-0 mt-2 sm:ml-2 sm:mt-0 sm:align-self-center storage">
{{ +resource.storage.storageUsage | fileSize }}
</p>
}

@if (resource.resourceType === ResourceType.Project && !hasViewOnly()) {
<p-button
class="flex"
(click)="forkActionMenu.toggle($event)"
[pTooltip]="'project.overview.tooltips.duplicate' | translate"
tooltipPosition="bottom"
[ariaLabel]="'project.overview.tooltips.duplicate' | translate"
>
<span class="font-bold">{{ resource.forksCount }}</span>
<i class="fas fa-clone text-2xl"></i>
<p-menu appendTo="body" #forkActionMenu [model]="forkActionItems" popup>
<ng-template #item let-item>
<a class="p-menu-item-link">
{{ item.label | translate }}
</a>
</ng-template>
</p-menu>
</p-button>
}
<div class="flex gap-2 justify-content-start">
@if (showViewOnlyLinks() && canEdit()) {
<p-button
class="flex"
[pTooltip]="'project.overview.tooltips.viewOnlyLinks' | translate"
tooltipPosition="bottom"
[routerLink]="'../contributors'"
[ariaLabel]="'project.overview.tooltips.viewOnlyLinks' | translate"
>
<span class="font-bold">{{ resource.viewOnlyLinksCount }}</span>
<i class="fas fa-link text-2xl"></i>
</p-button>
}

@if (!hasViewOnly()) {
<p-button
[pTooltip]="'project.overview.tooltips.bookmarks' | translate"
tooltipPosition="bottom"
class="flex"
(onClick)="toggleBookmark()"
[loading]="isBookmarksLoading() || isBookmarksSubmitting()"
[ariaLabel]="'project.overview.tooltips.bookmarks' | translate"
>
@if (!isBookmarksLoading() && !isBookmarksSubmitting()) {
<i class="text-2xl" [ngClass]="isBookmarked() ? 'fas fa-bookmark' : 'far fa-bookmark'"></i>
}
</p-button>
}
@if (resource.resourceType === ResourceType.Project && !hasViewOnly()) {
<p-button
class="flex"
(click)="forkActionMenu.toggle($event)"
[pTooltip]="'project.overview.tooltips.duplicate' | translate"
tooltipPosition="bottom"
[ariaLabel]="'project.overview.tooltips.duplicate' | translate"
>
<span class="font-bold">{{ resource.forksCount }}</span>
<i class="fas fa-clone text-2xl"></i>
<p-menu appendTo="body" #forkActionMenu [model]="forkActionItems" popup>
<ng-template #item let-item>
<a class="p-menu-item-link">
{{ item.label | translate }}
</a>
</ng-template>
</p-menu>
</p-button>
}

@if (resource.isPublic && !hasViewOnly()) {
<p-button
class="flex"
(onClick)="socialsActionMenu.toggle($event)"
[pTooltip]="'project.overview.tooltips.share' | translate"
tooltipPosition="bottom"
[ariaLabel]="'project.overview.tooltips.share' | translate"
>
<span class="font-bold">{{ socialsActionItems().length }}</span>
<i class="fas fa-share-nodes text-2xl"></i>
<p-menu appendTo="body" #socialsActionMenu [model]="socialsActionItems()" popup>
<ng-template #item let-item>
<a class="p-menu-item-link" [href]="item.url" target="_blank" rel="noopener noreferrer">
<div class="social-link flex align-items-center justify-content-center">
<osf-icon [iconClass]="`${item.icon} fa-sm`"></osf-icon>
</div>
{{ item.label | translate }}
</a>
</ng-template>
</p-menu>
</p-button>
}
@if (!hasViewOnly()) {
<p-button
[pTooltip]="'project.overview.tooltips.bookmarks' | translate"
tooltipPosition="bottom"
class="flex"
(onClick)="toggleBookmark()"
[loading]="isBookmarksLoading() || isBookmarksSubmitting()"
[ariaLabel]="'project.overview.tooltips.bookmarks' | translate"
>
@if (!isBookmarksLoading() && !isBookmarksSubmitting()) {
<i class="text-2xl" [ngClass]="isBookmarked() ? 'fas fa-bookmark' : 'far fa-bookmark'"></i>
}
</p-button>
}

@if (resource.isPublic && !hasViewOnly()) {
<p-button
class="flex"
(onClick)="socialsActionMenu.toggle($event)"
[pTooltip]="'project.overview.tooltips.share' | translate"
tooltipPosition="bottom"
[ariaLabel]="'project.overview.tooltips.share' | translate"
>
<span class="font-bold">{{ socialsActionItems().length }}</span>
<i class="fas fa-share-nodes text-2xl"></i>
<p-menu appendTo="body" #socialsActionMenu [model]="socialsActionItems()" popup>
<ng-template #item let-item>
<a class="p-menu-item-link" [href]="item.url" target="_blank" rel="noopener noreferrer">
<div class="social-link flex align-items-center justify-content-center">
<osf-icon [iconClass]="`${item.icon} fa-sm`"></osf-icon>
</div>
{{ item.label | translate }}
</a>
</ng-template>
</p-menu>
</p-button>
}
</div>
</div>
</div>
</div>
}
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class OverviewToolbarComponent {
bookmarksCollectionId = select(BookmarksSelectors.getBookmarksCollectionId);
bookmarkedProjects = select(MyResourcesSelectors.getBookmarks);
duplicatedProject = select(ProjectOverviewSelectors.getDuplicatedProject);
hasNoPermissions = select(ProjectOverviewSelectors.hasNoPermissions);
socialsActionItems = computed(() => {
const shareableContent = this.createShareableContent();
return shareableContent ? this.buildSocialActionItems(shareableContent) : [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ <h3 class="text-xl pb-4">{{ 'myProjects.settings.projectAffiliation' | translate
<p>{{ affiliation.name }}</p>
</div>

<p-button
class="danger-icon-btn"
icon="fas fa-trash"
severity="danger"
text
[ariaLabel]="'common.buttons.delete' | translate"
(onClick)="removeAffiliation(affiliation)"
></p-button>
@if (canEdit()) {
<p-button
class="danger-icon-btn"
icon="fas fa-trash"
severity="danger"
text
[ariaLabel]="'common.buttons.delete' | translate"
(onClick)="removeAffiliation(affiliation)"
></p-button>
}
</div>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Institution } from '@osf/shared/models';
export class SettingsProjectAffiliationComponent {
affiliations = input<Institution[]>([]);
removed = output<Institution>();
canEdit = input<boolean>(false);

removeAffiliation(affiliation: Institution) {
this.removed.emit(affiliation);
Expand Down
5 changes: 3 additions & 2 deletions src/app/features/project/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<osf-loading-spinner />
} @else {
<div class="flex flex-column flex-1 gap-4 w-full bg-white py-4 px-3 md:px-5 xl:px-4">
@if (canWrite()) {
@if (hasWriteAccess()) {
<osf-settings-project-form-card
(submitForm)="submitForm($event)"
(deleteProject)="deleteProject()"
Expand All @@ -17,7 +17,7 @@
[locationText]="'myProjects.settings.storageLocationMessage' | translate"
></osf-settings-storage-location-card>

@if (isAdmin()) {
@if (hasAdminAccess()) {
<osf-settings-view-only-links-card
id="view-only-links"
[tableData]="viewOnlyLinks()"
Expand Down Expand Up @@ -48,6 +48,7 @@
/>

<osf-settings-project-affiliation
[canEdit]="hasWriteAccess()"
[affiliations]="projectDetails().affiliatedInstitutions"
(removed)="removeAffiliation($event)"
></osf-settings-project-affiliation>
Expand Down
6 changes: 3 additions & 3 deletions src/app/features/project/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export class SettingsComponent implements OnInit {
title = signal('');

userPermissions = computed(() => this.projectDetails()?.currentUserPermissions || []);
isAdmin = computed(() => this.userPermissions().includes(UserPermissions.Admin));
canWrite = computed(() => this.userPermissions().includes(UserPermissions.Write));
hasAdminAccess = computed(() => this.userPermissions().includes(UserPermissions.Admin));
hasWriteAccess = computed(() => this.userPermissions().includes(UserPermissions.Write));

constructor() {
this.setupEffects();
Expand Down Expand Up @@ -255,7 +255,7 @@ export class SettingsComponent implements OnInit {
effect(() => {
const id = this.projectId();

if (id && this.isAdmin()) {
if (id && this.hasAdminAccess()) {
this.actions.getViewOnlyLinks(id, ResourceType.Project);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@

<div class="flex gap-2 align-items-baseline">
<strong>{{ 'common.labels.contributors' | translate }}:</strong>
<osf-contributors-list [contributors]="registrationData().contributors"></osf-contributors-list>
<osf-contributors-list
[contributors]="registrationData().contributors"
[anonymous]="!registrationData().contributors.length"
></osf-contributors-list>
</div>

<div class="flex gap-2 align-items-baseline">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ export class RegistryComponentsMapper {
registrationSupplement: apiComponent.attributes.registration_supplement,
tags: apiComponent.attributes.tags,
isPublic: apiComponent.attributes.public,
contributors: ContributorsMapper.getContributors(apiComponent.embeds.bibliographic_contributors.data) || [],
contributors: ContributorsMapper.getContributors(apiComponent.embeds?.bibliographic_contributors?.data || []),
};
}

static fromApiResponseArray(apiComponents: RegistryComponentJsonApi[]): RegistryComponentModel[] {
return apiComponents.map(this.fromApiResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ export class CurrentResourceSelectors {

@Selector([CurrentResourceState])
static hasWriteAccess(state: CurrentResourceStateModel): boolean {
return state.resourceDetails.data?.currentUserPermissions?.includes(UserPermissions.Write) || false;
return state.currentResource.data?.permissions?.includes(UserPermissions.Write) || false;
}

@Selector([CurrentResourceState])
static hasAdminAccess(state: CurrentResourceStateModel): boolean {
return state.resourceDetails.data?.currentUserPermissions?.includes(UserPermissions.Admin) || false;
return state.currentResource.data?.permissions?.includes(UserPermissions.Admin) || false;
}

@Selector([CurrentResourceState])
static hasNoPermissions(state: CurrentResourceStateModel): boolean {
return !state.resourceDetails.data?.currentUserPermissions?.length;
return !state.currentResource.data?.permissions?.length;
}

@Selector([CurrentResourceState])
Expand Down
Loading