Skip to content

Commit e6d1e79

Browse files
authored
[ANG-1075] [ANG-1073] Fix contributor pagination part 1 (#672)
* fix(bugs): fixed ui bugs * fix(contributors): fixed pagination for contributors
1 parent c3b39ca commit e6d1e79

File tree

14 files changed

+151
-146
lines changed

14 files changed

+151
-146
lines changed

src/app/features/contributors/contributors.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,15 @@ export class ContributorsComponent implements OnInit {
123123
readonly hasAdminAccess = select(CurrentResourceSelectors.hasResourceAdminAccess);
124124
readonly resourceAccessRequestEnabled = select(CurrentResourceSelectors.resourceAccessRequestEnabled);
125125
readonly currentUser = select(UserSelectors.getCurrentUser);
126+
page = select(ContributorsSelectors.getContributorsPageNumber);
127+
pageSize = select(ContributorsSelectors.getContributorsPageSize);
126128

127129
readonly tableParams = computed<TableParameters>(() => ({
128130
...DEFAULT_TABLE_PARAMS,
129131
totalRecords: this.contributorsTotalCount(),
130132
paginator: this.contributorsTotalCount() > DEFAULT_TABLE_PARAMS.rows,
133+
firstRowIndex: (this.page() - 1) * this.pageSize(),
134+
rows: this.pageSize(),
131135
}));
132136

133137
canCreateViewLink = computed(() => !!this.resourceDetails() && !!this.resourceId());

src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="contributors-dialog flex flex-column gap-4">
22
<div class="flex justify-content-end align-items-center">
3-
@if (isCurrentUserAdminContributor()) {
3+
@if (hasAdminAccess()) {
44
<p-button
55
[label]="'project.contributors.addContributor' | translate"
66
[disabled]="isLoading()"
@@ -21,9 +21,10 @@
2121
[isLoading]="isLoading()"
2222
[showEmployment]="false"
2323
[showEducation]="false"
24-
[hasAdminAccess]="isCurrentUserAdminContributor()"
24+
[hasAdminAccess]="hasAdminAccess()"
2525
[currentUserId]="currentUser()?.id"
2626
(remove)="removeContributor($event)"
27+
(pageChanged)="pageChanged($event)"
2728
></osf-contributors-table>
2829

2930
@if (hasChanges) {

src/app/features/metadata/dialogs/contributors-dialog/contributors-dialog.component.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { TranslatePipe } from '@ngx-translate/core';
44

55
import { Button } from 'primeng/button';
66
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
7+
import { TablePageEvent } from 'primeng/table';
78

89
import { filter } from 'rxjs';
910

@@ -29,7 +30,7 @@ import {
2930
ContributorsTableComponent,
3031
} from '@osf/shared/components/contributors';
3132
import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants';
32-
import { AddContributorType, ContributorPermission, ResourceType } from '@osf/shared/enums';
33+
import { AddContributorType, ResourceType } from '@osf/shared/enums';
3334
import { findChangedItems } from '@osf/shared/helpers';
3435
import { ContributorDialogAddModel, ContributorModel, TableParameters } from '@osf/shared/models';
3536
import { CustomConfirmationService, CustomDialogService, ToastService } from '@osf/shared/services';
@@ -39,11 +40,14 @@ import {
3940
BulkUpdateContributors,
4041
ContributorsSelectors,
4142
DeleteContributor,
43+
GetAllContributors,
4244
UpdateBibliographyFilter,
4345
UpdateContributorsSearchValue,
4446
UpdatePermissionFilter,
4547
} from '@osf/shared/stores';
4648

49+
import { MetadataSelectors } from '../../store';
50+
4751
@Component({
4852
selector: 'osf-contributors-dialog',
4953
imports: [Button, SearchInputComponent, TranslatePipe, FormsModule, ContributorsTableComponent],
@@ -64,17 +68,23 @@ export class ContributorsDialogComponent implements OnInit {
6468
isLoading = select(ContributorsSelectors.isContributorsLoading);
6569
initialContributors = select(ContributorsSelectors.getContributors);
6670
contributorsTotalCount = select(ContributorsSelectors.getContributorsTotalCount);
71+
hasAdminAccess = select(MetadataSelectors.hasAdminAccess);
6772
contributors = signal<ContributorModel[]>([]);
73+
page = select(ContributorsSelectors.getContributorsPageNumber);
74+
pageSize = select(ContributorsSelectors.getContributorsPageSize);
6875

6976
currentUser = select(UserSelectors.getCurrentUser);
7077

7178
readonly tableParams = computed<TableParameters>(() => ({
7279
...DEFAULT_TABLE_PARAMS,
7380
totalRecords: this.contributorsTotalCount(),
7481
paginator: this.contributorsTotalCount() > DEFAULT_TABLE_PARAMS.rows,
82+
firstRowIndex: (this.page() - 1) * this.pageSize(),
83+
rows: this.pageSize(),
7584
}));
7685

7786
actions = createDispatchMap({
87+
getContributors: GetAllContributors,
7888
updateSearchValue: UpdateContributorsSearchValue,
7989
updatePermissionFilter: UpdatePermissionFilter,
8090
updateBibliographyFilter: UpdateBibliographyFilter,
@@ -87,17 +97,6 @@ export class ContributorsDialogComponent implements OnInit {
8797
private readonly resourceType: ResourceType;
8898
private readonly resourceId: string;
8999

90-
isCurrentUserAdminContributor = computed(() => {
91-
const currentUserId = this.currentUser()?.id;
92-
const initialContributors = this.initialContributors();
93-
if (!currentUserId) return false;
94-
95-
return initialContributors.some(
96-
(contributor: ContributorModel) =>
97-
contributor.userId === currentUserId && contributor.permission === ContributorPermission.Admin
98-
);
99-
});
100-
101100
get searchPlaceholder() {
102101
return this.resourceType === ResourceType.Project
103102
? 'project.contributors.searchProjectPlaceholder'
@@ -207,6 +206,13 @@ export class ContributorsDialogComponent implements OnInit {
207206
});
208207
}
209208

209+
pageChanged(event: TablePageEvent) {
210+
const page = Math.floor(event.first / event.rows) + 1;
211+
const pageSize = event.rows;
212+
213+
this.actions.getContributors(this.resourceId, this.resourceType, page, pageSize);
214+
}
215+
210216
cancel() {
211217
this.contributors.set(structuredClone(this.initialContributors()));
212218
}

src/app/features/metadata/metadata.component.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { ActivatedRoute, Router } from '@angular/router';
1919

2020
import { ENVIRONMENT } from '@core/provider/environment.provider';
2121
import { MetadataTabsComponent, SubHeaderComponent } from '@osf/shared/components';
22-
import { MetadataResourceEnum, ResourceType, UserPermissions } from '@osf/shared/enums';
22+
import { MetadataResourceEnum, ResourceType } from '@osf/shared/enums';
2323
import { MetadataTabsModel, SubjectModel } from '@osf/shared/models';
2424
import { CustomConfirmationService, CustomDialogService, ToastService } from '@osf/shared/services';
2525
import {
@@ -136,6 +136,9 @@ export class MetadataComponent implements OnInit {
136136
areInstitutionsLoading = select(InstitutionsSelectors.areResourceInstitutionsLoading);
137137
areResourceInstitutionsSubmitting = select(InstitutionsSelectors.areResourceInstitutionsSubmitting);
138138

139+
hasWriteAccess = select(MetadataSelectors.hasWriteAccess);
140+
hasAdminAccess = select(MetadataSelectors.hasAdminAccess);
141+
139142
provider = this.environment.defaultProvider;
140143

141144
private readonly resourceNameMap = new Map<ResourceType, string>([
@@ -166,37 +169,23 @@ export class MetadataComponent implements OnInit {
166169
updateContributorsSearchValue: UpdateContributorsSearchValue,
167170
});
168171

169-
isLoading = computed(() => {
170-
return (
172+
isLoading = computed(
173+
() =>
171174
this.isMetadataLoading() ||
172175
this.isContributorsLoading() ||
173176
this.areInstitutionsLoading() ||
174177
this.isSubmitting() ||
175178
this.areResourceInstitutionsSubmitting()
176-
);
177-
});
179+
);
178180

179-
hideEditDoi = computed(() => {
180-
return (
181+
hideEditDoi = computed(
182+
() =>
181183
this.resourceType() === ResourceType.Project &&
182184
(!!this.metadata()?.identifiers?.length || !this.metadata()?.public)
183-
);
184-
});
185+
);
185186

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

188-
hasWriteAccess = computed(() => {
189-
const metadata = this.metadata();
190-
if (!metadata) return false;
191-
return metadata.currentUserPermissions.includes(UserPermissions.Write);
192-
});
193-
194-
hasAdminAccess = computed(() => {
195-
const metadata = this.metadata();
196-
if (!metadata) return false;
197-
return metadata.currentUserPermissions.includes(UserPermissions.Admin);
198-
});
199-
200189
constructor() {
201190
effect(() => {
202191
const records = this.cedarRecords();

src/app/features/metadata/store/metadata.selectors.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Selector } from '@ngxs/store';
22

3+
import { UserPermissions } from '@osf/shared/enums';
4+
35
import { MetadataStateModel } from './metadata.model';
46
import { MetadataState } from './metadata.state';
57

@@ -63,4 +65,14 @@ export class MetadataSelectors {
6365
static getCedarRecordsLoading(state: MetadataStateModel) {
6466
return state.cedarRecords.isLoading;
6567
}
68+
69+
@Selector([MetadataState])
70+
static hasWriteAccess(state: MetadataStateModel): boolean {
71+
return state.metadata.data?.currentUserPermissions?.includes(UserPermissions.Write) || false;
72+
}
73+
74+
@Selector([MetadataState])
75+
static hasAdminAccess(state: MetadataStateModel): boolean {
76+
return state.metadata.data?.currentUserPermissions?.includes(UserPermissions.Admin) || false;
77+
}
6678
}

src/app/features/preprints/components/stepper/preprints-metadata-step/preprints-contributors/preprints-contributors.component.html

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,23 @@ <h2>{{ 'project.overview.metadata.contributors' | translate }}</h2>
1111
class="w-full"
1212
[(contributors)]="contributors"
1313
[tableParams]="tableParams()"
14-
[currentUserId]="currentUser()?.id"
15-
[hasAdminAccess]="isCurrentUserAdminContributor()"
1614
[isLoading]="isContributorsLoading()"
1715
(remove)="removeContributor($event)"
16+
(pageChanged)="pageChanged($event)"
1817
/>
1918
<div class="flex justify-content-end mt-3">
2019
@if (hasChanges) {
2120
<div class="flex gap-2 mr-4">
22-
<p-button (click)="cancel()" severity="info" [label]="'common.buttons.cancel' | translate" />
23-
<p-button (click)="save()" [label]="'common.buttons.save' | translate" />
21+
<p-button (onClick)="cancel()" severity="info" [label]="'common.buttons.cancel' | translate" />
22+
<p-button (onClick)="save()" [label]="'common.buttons.save' | translate" />
2423
</div>
2524
}
26-
@if (isCurrentUserAdminContributor()) {
27-
<p-button
28-
class="w-full md:w-auto"
29-
styleClass="w-full"
30-
[label]="'preprints.addContributorBySearch' | translate"
31-
type="submit"
32-
(onClick)="openAddContributorDialog()"
33-
/>
34-
}
25+
<p-button
26+
class="w-full md:w-auto"
27+
styleClass="w-full"
28+
[label]="'preprints.addContributorBySearch' | translate"
29+
type="submit"
30+
(onClick)="openAddContributorDialog()"
31+
/>
3532
</div>
3633
</p-card>

src/app/features/preprints/components/stepper/preprints-metadata-step/preprints-contributors/preprints-contributors.component.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { TranslatePipe } from '@ngx-translate/core';
55
import { Button } from 'primeng/button';
66
import { Card } from 'primeng/card';
77
import { Message } from 'primeng/message';
8-
import { TableModule } from 'primeng/table';
8+
import { TableModule, TablePageEvent } from 'primeng/table';
99

1010
import { filter } from 'rxjs';
1111

@@ -24,14 +24,13 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2424
import { FormsModule } from '@angular/forms';
2525
import { Router } from '@angular/router';
2626

27-
import { UserSelectors } from '@core/store/user';
2827
import {
2928
AddContributorDialogComponent,
3029
AddUnregisteredContributorDialogComponent,
3130
ContributorsTableComponent,
3231
} from '@osf/shared/components/contributors';
3332
import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants';
34-
import { AddContributorType, ContributorPermission, ResourceType } from '@osf/shared/enums';
33+
import { AddContributorType, ResourceType } from '@osf/shared/enums';
3534
import { findChangedItems } from '@osf/shared/helpers';
3635
import { ContributorDialogAddModel, ContributorModel, TableParameters } from '@osf/shared/models';
3736
import { CustomConfirmationService, CustomDialogService, ToastService } from '@osf/shared/services';
@@ -64,25 +63,17 @@ export class PreprintsContributorsComponent implements OnInit {
6463
contributors = signal<ContributorModel[]>([]);
6564
contributorsTotalCount = select(ContributorsSelectors.getContributorsTotalCount);
6665
isContributorsLoading = select(ContributorsSelectors.isContributorsLoading);
67-
currentUser = select(UserSelectors.getCurrentUser);
66+
page = select(ContributorsSelectors.getContributorsPageNumber);
67+
pageSize = select(ContributorsSelectors.getContributorsPageSize);
6868

6969
readonly tableParams = computed<TableParameters>(() => ({
7070
...DEFAULT_TABLE_PARAMS,
7171
totalRecords: this.contributorsTotalCount(),
7272
paginator: this.contributorsTotalCount() > DEFAULT_TABLE_PARAMS.rows,
73+
firstRowIndex: (this.page() - 1) * this.pageSize(),
74+
rows: this.pageSize(),
7375
}));
7476

75-
isCurrentUserAdminContributor = computed(() => {
76-
const currentUserId = this.currentUser()?.id;
77-
const initialContributors = this.initialContributors();
78-
if (!currentUserId) return false;
79-
80-
return initialContributors.some(
81-
(contributor: ContributorModel) =>
82-
contributor.userId === currentUserId && contributor.permission === ContributorPermission.Admin
83-
);
84-
});
85-
8677
actions = createDispatchMap({
8778
getContributors: GetAllContributors,
8879
deleteContributor: DeleteContributor,
@@ -171,29 +162,30 @@ export class PreprintsContributorsComponent implements OnInit {
171162
}
172163

173164
removeContributor(contributor: ContributorModel) {
174-
const isDeletingSelf = contributor.userId === this.currentUser()?.id;
175-
176165
this.customConfirmationService.confirmDelete({
177166
headerKey: 'project.contributors.removeDialog.title',
178167
messageKey: 'project.contributors.removeDialog.message',
179168
messageParams: { name: contributor.fullName },
180169
acceptLabelKey: 'common.buttons.remove',
181170
onConfirm: () => {
182171
this.actions
183-
.deleteContributor(this.preprintId(), ResourceType.Preprint, contributor.userId, isDeletingSelf)
172+
.deleteContributor(this.preprintId(), ResourceType.Preprint, contributor.userId)
184173
.pipe(takeUntilDestroyed(this.destroyRef))
185174
.subscribe({
186175
next: () => {
187176
this.toastService.showSuccess('project.contributors.removeDialog.successMessage', {
188177
name: contributor.fullName,
189178
});
190-
191-
if (isDeletingSelf) {
192-
this.router.navigate(['/']);
193-
}
194179
},
195180
});
196181
},
197182
});
198183
}
184+
185+
pageChanged(event: TablePageEvent) {
186+
const page = Math.floor(event.first / event.rows) + 1;
187+
const pageSize = event.rows;
188+
189+
this.actions.getContributors(this.preprintId(), ResourceType.Preprint, page, pageSize);
190+
}
199191
}

src/app/features/registries/components/registries-metadata-step/registries-contributors/registries-contributors.component.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ <h2 class="mb-2">{{ 'project.overview.metadata.contributors' | translate }}</h2>
66
[(contributors)]="contributors"
77
[tableParams]="tableParams()"
88
[isLoading]="isContributorsLoading()"
9-
[currentUserId]="currentUser()?.id"
10-
[hasAdminAccess]="isCurrentUserAdminContributor()"
119
(remove)="removeContributor($event)"
10+
(pageChanged)="pageChanged($event)"
1211
/>
1312

1413
<div class="flex justify-content-end mt-3">

0 commit comments

Comments
 (0)