diff --git a/src/app/core/constants/nav-items.constant.ts b/src/app/core/constants/nav-items.constant.ts index 4d598496..efaf7042 100644 --- a/src/app/core/constants/nav-items.constant.ts +++ b/src/app/core/constants/nav-items.constant.ts @@ -154,14 +154,14 @@ export const PROJECT_MENU_ITEMS: MenuItem[] = [ }, { label: 'navigation.project.contributors', routerLink: 'contributors' }, { label: 'navigation.project.analytics', routerLink: 'analytics' }, - { - label: 'navigation.project.settings', - routerLink: 'settings', - }, { label: 'navigation.project.addons', routerLink: 'addons', }, + { + label: 'navigation.project.settings', + routerLink: 'settings', + }, ], }, ]; diff --git a/src/app/features/home/components/confirm-email/confirm-email.component.html b/src/app/features/home/components/confirm-email/confirm-email.component.html index fa213861..00bb2a80 100644 --- a/src/app/features/home/components/confirm-email/confirm-email.component.html +++ b/src/app/features/home/components/confirm-email/confirm-email.component.html @@ -1,10 +1,11 @@
@if (!verifyingEmail()) { -

+

{{ 'home.confirmEmail.description' | translate }}

{{ config.data.emailAddress }}

{{ 'home.confirmEmail.description2' | translate }}

+
(click)="closeDialog()" [label]="'common.buttons.cancel' | translate" > + { + this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { const userId = params['userId']; const token = params['token']; if (userId && token) { - this.#accountSettingsService + this.accountSettingsService .getEmail(token, userId) .pipe(take(1)) .subscribe((email) => { @@ -95,8 +95,8 @@ export class HomeComponent implements OnInit { } addAlternateEmail(token: string) { - this.#translateService.get('home.confirmEmail.title').subscribe((title) => { - this.dialogRef = this.#dialogService.open(ConfirmEmailComponent, { + this.translateService.get('home.confirmEmail.title').subscribe((title) => { + this.dialogRef = this.dialogService.open(ConfirmEmailComponent, { width: '448px', focusOnShow: false, header: title, @@ -105,16 +105,16 @@ export class HomeComponent implements OnInit { closable: true, data: { emailAddress: this.emailAddress, - userId: this.#route.snapshot.params['userId'], - emailId: this.#route.snapshot.params['emailId'], + userId: this.route.snapshot.params['userId'], + emailId: this.route.snapshot.params['emailId'], token: token, }, }); }); } - #setupQueryParamsSubscription(): void { - this.#route.queryParams.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((params) => { + setupQueryParamsSubscription(): void { + this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { const page = Number(params['page']) || 1; const rows = Number(params['rows']) || MY_PROJECTS_TABLE_PARAMS.rows; const sortField = params['sortField']; @@ -136,19 +136,17 @@ export class HomeComponent implements OnInit { this.searchControl.setValue(search); } - this.#fetchProjects(); + this.fetchProjects(); }); } - #setupSearchSubscription(): void { + setupSearchSubscription(): void { this.searchControl.valueChanges - .pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed(this.#destroyRef)) - .subscribe(() => { - this.#updateQueryParams(); - }); + .pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed(this.destroyRef)) + .subscribe(() => this.updateQueryParams(true)); } - #setupTotalRecordsEffect(): void { + setupTotalRecordsEffect(): void { effect(() => { const total = this.totalProjectsCount(); this.tableParams.update((current) => ({ @@ -158,19 +156,19 @@ export class HomeComponent implements OnInit { }); } - #setupCleanup(): void { - this.#destroyRef.onDestroy(() => { - this.#store.dispatch(new ClearMyProjects()); + setupCleanup(): void { + this.destroyRef.onDestroy(() => { + this.store.dispatch(new ClearMyProjects()); }); } - #fetchProjects(): void { + fetchProjects(): void { this.isLoading.set(true); - const filters = this.#createFilters(); + const filters = this.createFilters(); const page = Math.floor(this.tableParams().firstRowIndex / this.tableParams().rows) + 1; - this.#store + this.store .dispatch(new GetMyProjects(page, this.tableParams().rows, filters)) - .pipe(takeUntilDestroyed(this.#destroyRef)) + .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ complete: () => { this.isLoading.set(false); @@ -181,7 +179,7 @@ export class HomeComponent implements OnInit { }); } - #createFilters(): MyProjectsSearchFilters { + createFilters(): MyProjectsSearchFilters { return { searchValue: this.searchControl.value ?? '', searchFields: ['title'], @@ -190,8 +188,8 @@ export class HomeComponent implements OnInit { }; } - #updateQueryParams(): void { - const page = Math.floor(this.tableParams().firstRowIndex / this.tableParams().rows) + 1; + updateQueryParams(isSearch = false): void { + const page = isSearch ? 1 : Math.floor(this.tableParams().firstRowIndex / this.tableParams().rows) + 1; const queryParams = { page, rows: this.tableParams().rows, @@ -200,8 +198,8 @@ export class HomeComponent implements OnInit { sortOrder: this.sortOrder() || undefined, }; - this.#router.navigate([], { - relativeTo: this.#route, + this.router.navigate([], { + relativeTo: this.route, queryParams, queryParamsHandling: 'merge', }); @@ -214,37 +212,37 @@ export class HomeComponent implements OnInit { firstRowIndex: event.first, })); - this.#updateQueryParams(); + this.updateQueryParams(); } protected onSort(event: SortEvent): void { if (event.field) { this.sortColumn.set(event.field); this.sortOrder.set(event.order === -1 ? SortOrder.Desc : SortOrder.Asc); - this.#updateQueryParams(); + this.updateQueryParams(); } } protected navigateToProject(project: MyProjectsItem): void { this.activeProject.set(project); - this.#router.navigate(['/my-projects', project.id]); + this.router.navigate(['/my-projects', project.id]); } protected createProject(): void { const dialogWidth = this.isMedium() ? '850px' : '95vw'; this.isSubmitting.set(true); - const dialogRef = this.#dialogService.open(AddProjectFormComponent, { - width: dialogWidth, - focusOnShow: false, - header: this.#translateService.instant('myProjects.header.createProject'), - closeOnEscape: true, - modal: true, - closable: true, - }); - - dialogRef.onClose.subscribe(() => { - this.isSubmitting.set(false); - }); + this.dialogService + .open(AddProjectFormComponent, { + width: dialogWidth, + focusOnShow: false, + header: this.translateService.instant('myProjects.header.createProject'), + closeOnEscape: true, + modal: true, + closable: true, + }) + .onClose.subscribe(() => { + this.isSubmitting.set(false); + }); } } diff --git a/src/app/features/institutions/institutions.component.html b/src/app/features/institutions/institutions.component.html index 505a518b..e485aa10 100644 --- a/src/app/features/institutions/institutions.component.html +++ b/src/app/features/institutions/institutions.component.html @@ -7,7 +7,7 @@ /> @if (institutionsLoading()) { -
+
} @else { @@ -17,18 +17,24 @@
@for (institution of institutions(); track $index) {
- + -

{{ institution.name }}

+

{{ institution.name }}

} + + @if (!institutions().length) { +

{{ 'common.search.noResultsFound' | translate }}

+ }
- + @if (totalInstitutionsCount() > 10) { + + }
} diff --git a/src/app/features/institutions/institutions.component.scss b/src/app/features/institutions/institutions.component.scss index e69de29b..c84ec277 100644 --- a/src/app/features/institutions/institutions.component.scss +++ b/src/app/features/institutions/institutions.component.scss @@ -0,0 +1,3 @@ +.image { + object-fit: contain; +} diff --git a/src/app/features/institutions/institutions.component.ts b/src/app/features/institutions/institutions.component.ts index f1c6c4d1..17e1ea67 100644 --- a/src/app/features/institutions/institutions.component.ts +++ b/src/app/features/institutions/institutions.component.ts @@ -47,7 +47,7 @@ import { FetchInstitutions, InstitutionsSelectors } from '@shared/stores'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class InstitutionsComponent { - @HostBinding('class') classes = 'flex-1 flex flex-column w-full h-full'; + @HostBinding('class') classes = 'flex-1 flex flex-column w-full'; private readonly route = inject(ActivatedRoute); private readonly router = inject(Router); diff --git a/src/app/features/moderation/components/add-moderator-dialog/add-moderator-dialog.component.html b/src/app/features/moderation/components/add-moderator-dialog/add-moderator-dialog.component.html index 95951aaa..6a8e788e 100644 --- a/src/app/features/moderation/components/add-moderator-dialog/add-moderator-dialog.component.html +++ b/src/app/features/moderation/components/add-moderator-dialog/add-moderator-dialog.component.html @@ -33,7 +33,7 @@
+ + +
+

{{ 'moderation.bulkUpload' | translate }}

+ +

{{ 'moderation.bulkUploadMessage' | translate }}

+ + +
+
+
+
diff --git a/src/app/features/moderation/components/bulk-upload/bulk-upload.component.scss b/src/app/features/moderation/components/bulk-upload/bulk-upload.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/features/moderation/components/bulk-upload/bulk-upload.component.spec.ts b/src/app/features/moderation/components/bulk-upload/bulk-upload.component.spec.ts new file mode 100644 index 00000000..3b1ecc98 --- /dev/null +++ b/src/app/features/moderation/components/bulk-upload/bulk-upload.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BulkUploadComponent } from './bulk-upload.component'; + +describe('BulkUploadComponent', () => { + let component: BulkUploadComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [BulkUploadComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(BulkUploadComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/moderation/components/bulk-upload/bulk-upload.component.ts b/src/app/features/moderation/components/bulk-upload/bulk-upload.component.ts new file mode 100644 index 00000000..daee0cf6 --- /dev/null +++ b/src/app/features/moderation/components/bulk-upload/bulk-upload.component.ts @@ -0,0 +1,20 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { Button } from 'primeng/button'; +import { FileUpload } from 'primeng/fileupload'; + +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +import { BYTES_IN_MB, FILE_TYPES } from '../../constants'; + +@Component({ + selector: 'osf-bulk-upload', + imports: [Button, FileUpload, TranslatePipe], + templateUrl: './bulk-upload.component.html', + styleUrl: './bulk-upload.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BulkUploadComponent { + maxSize = input(1 * BYTES_IN_MB); + acceptTypes = input(FILE_TYPES.CSV); +} diff --git a/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.html b/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.html index 85b4740f..cfcfe0e9 100644 --- a/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.html +++ b/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.html @@ -1,7 +1,7 @@ -
+
-
+
- + diff --git a/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.ts b/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.ts index fa86117c..a919b9ab 100644 --- a/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.ts +++ b/src/app/features/moderation/components/collection-moderation-submissions/collection-moderation-submissions.component.ts @@ -12,6 +12,7 @@ import { ALL_SORT_OPTIONS } from '@osf/shared/constants'; import { SUBMISSION_REVIEW_OPTIONS } from '../../constants'; import { SubmissionReviewStatus } from '../../enums'; import { SubmissionsListComponent } from '../submissions-list/submissions-list.component'; +import { pendingReviews } from '../test-data'; @Component({ selector: 'osf-collection-moderation-submissions', @@ -29,6 +30,8 @@ export class CollectionModerationSubmissionsComponent { totalCount = 5; + submissions = pendingReviews; + changeReviewStatus(value: SubmissionReviewStatus) { console.log(value); } diff --git a/src/app/features/moderation/components/index.ts b/src/app/features/moderation/components/index.ts index e9f6d7ed..a98b5194 100644 --- a/src/app/features/moderation/components/index.ts +++ b/src/app/features/moderation/components/index.ts @@ -1,8 +1,11 @@ export { AddModeratorDialogComponent } from './add-moderator-dialog/add-moderator-dialog.component'; +export { BulkUploadComponent } from './bulk-upload/bulk-upload.component'; export { CollectionModerationSettingsComponent } from './collection-moderation-settings/collection-moderation-settings.component'; export { CollectionModerationSubmissionsComponent } from './collection-moderation-submissions/collection-moderation-submissions.component'; export { CollectionModeratorsComponent } from './collection-moderators/collection-moderators.component'; export { CollectionModeratorsListComponent } from './collection-moderators-list/collection-moderators-list.component'; export { InviteModeratorDialogComponent } from './invite-moderator-dialog/invite-moderator-dialog.component'; +export { RegistrySettingsComponent } from './registry-settings/registry-settings.component'; +export { RegistrySubmissionsComponent } from './registry-submissions/registry-submissions.component'; export { SubmissionItemComponent } from './submission-item/submission-item.component'; export { SubmissionsListComponent } from './submissions-list/submissions-list.component'; diff --git a/src/app/features/moderation/components/invite-moderator-dialog/invite-moderator-dialog.component.html b/src/app/features/moderation/components/invite-moderator-dialog/invite-moderator-dialog.component.html index 4700677f..10e5c188 100644 --- a/src/app/features/moderation/components/invite-moderator-dialog/invite-moderator-dialog.component.html +++ b/src/app/features/moderation/components/invite-moderator-dialog/invite-moderator-dialog.component.html @@ -32,7 +32,7 @@
+ {{ 'moderation.settingsMessage' | translate }} + + {{ 'moderation.userSettings' | translate }} + +

+ + diff --git a/src/app/features/moderation/components/registry-settings/registry-settings.component.scss b/src/app/features/moderation/components/registry-settings/registry-settings.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/features/moderation/components/registry-settings/registry-settings.component.spec.ts b/src/app/features/moderation/components/registry-settings/registry-settings.component.spec.ts new file mode 100644 index 00000000..fb477c8c --- /dev/null +++ b/src/app/features/moderation/components/registry-settings/registry-settings.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RegistrySettingsComponent } from './registry-settings.component'; + +describe('RegistrySettingsComponent', () => { + let component: RegistrySettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RegistrySettingsComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(RegistrySettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/moderation/components/registry-settings/registry-settings.component.ts b/src/app/features/moderation/components/registry-settings/registry-settings.component.ts new file mode 100644 index 00000000..34b7be88 --- /dev/null +++ b/src/app/features/moderation/components/registry-settings/registry-settings.component.ts @@ -0,0 +1,15 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; + +import { BulkUploadComponent } from '../bulk-upload/bulk-upload.component'; + +@Component({ + selector: 'osf-registry-settings', + imports: [TranslatePipe, RouterLink, BulkUploadComponent], + templateUrl: './registry-settings.component.html', + styleUrl: './registry-settings.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RegistrySettingsComponent {} diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html new file mode 100644 index 00000000..cfcfe0e9 --- /dev/null +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html @@ -0,0 +1,30 @@ +
+
+ + + +

{{ totalCount }}

+

{{ item.label | translate }}

+
+
+
+ +
+ +
+
+ + diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.scss b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.scss new file mode 100644 index 00000000..baf8accf --- /dev/null +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.scss @@ -0,0 +1,15 @@ +.pending { + color: var(--yellow-1); +} + +.accepted { + color: var(--green-1); +} + +.rejected { + color: var(--red-1); +} + +.withdrawn { + color: var(--dark-blue-1); +} diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.spec.ts b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.spec.ts new file mode 100644 index 00000000..35902d97 --- /dev/null +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RegistrySubmissionsComponent } from './registry-submissions.component'; + +describe('RegistrySubmissionsComponent', () => { + let component: RegistrySubmissionsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RegistrySubmissionsComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(RegistrySubmissionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts new file mode 100644 index 00000000..93fca7ff --- /dev/null +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts @@ -0,0 +1,42 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { SelectButton } from 'primeng/selectbutton'; + +import { ChangeDetectionStrategy, Component, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { Primitive } from '@osf/core/helpers'; +import { IconComponent, SelectComponent } from '@osf/shared/components'; +import { ALL_SORT_OPTIONS } from '@osf/shared/constants'; + +import { SUBMITTED_SUBMISSION_REVIEW_OPTIONS } from '../../constants'; +import { SubmissionReviewStatus } from '../../enums'; +import { SubmissionsListComponent } from '../submissions-list/submissions-list.component'; +import { pubicReviews } from '../test-data'; + +@Component({ + selector: 'osf-registry-submissions', + imports: [SelectButton, TranslatePipe, FormsModule, SelectComponent, SubmissionsListComponent, IconComponent], + templateUrl: './registry-submissions.component.html', + styleUrl: './registry-submissions.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RegistrySubmissionsComponent { + readonly submissionReviewOptions = SUBMITTED_SUBMISSION_REVIEW_OPTIONS; + + sortOptions = ALL_SORT_OPTIONS; + selectedSortOption = signal(null); + selectedReviewOption = this.submissionReviewOptions[0].value; + + totalCount = 5; + + submissions = pubicReviews; + + changeReviewStatus(value: SubmissionReviewStatus) { + console.log(value); + } + + changeSort(value: Primitive) { + console.log(value); + } +} diff --git a/src/app/features/moderation/components/submission-item/submission-item.component.html b/src/app/features/moderation/components/submission-item/submission-item.component.html index 3007cb63..ab86e07a 100644 --- a/src/app/features/moderation/components/submission-item/submission-item.component.html +++ b/src/app/features/moderation/components/submission-item/submission-item.component.html @@ -1,13 +1,13 @@
{{ submission().name }}
-

+

{{ 'moderation.submissionReview.submitted' | translate }} {{ submission().dateSubmitted }} {{ 'moderation.submissionReview.by' | translate }} diff --git a/src/app/features/moderation/components/submission-item/submission-item.component.ts b/src/app/features/moderation/components/submission-item/submission-item.component.ts index 0d134ace..adbdf260 100644 --- a/src/app/features/moderation/components/submission-item/submission-item.component.ts +++ b/src/app/features/moderation/components/submission-item/submission-item.component.ts @@ -5,7 +5,6 @@ import { ChangeDetectionStrategy, Component, input } from '@angular/core'; import { IconComponent } from '@osf/shared/components'; import { ReviewStatusIcon } from '../../constants'; -import { SubmissionReviewStatus } from '../../enums'; import { Submission } from '../../models'; @Component({ @@ -19,5 +18,4 @@ export class SubmissionItemComponent { submission = input.required(); readonly reviewStatusIcon = ReviewStatusIcon; - readonly selectedIcon = SubmissionReviewStatus.Pending; } diff --git a/src/app/features/moderation/components/submissions-list/submissions-list.component.html b/src/app/features/moderation/components/submissions-list/submissions-list.component.html index d2047112..e75b0b74 100644 --- a/src/app/features/moderation/components/submissions-list/submissions-list.component.html +++ b/src/app/features/moderation/components/submissions-list/submissions-list.component.html @@ -1,5 +1,5 @@

- @for (item of pendingSubmissions; track $index) { + @for (item of submissions(); track $index) {
diff --git a/src/app/features/moderation/components/submissions-list/submissions-list.component.scss b/src/app/features/moderation/components/submissions-list/submissions-list.component.scss index a51b1236..f5d291e4 100644 --- a/src/app/features/moderation/components/submissions-list/submissions-list.component.scss +++ b/src/app/features/moderation/components/submissions-list/submissions-list.component.scss @@ -1,9 +1,6 @@ -@use "assets/styles/variables" as var; -@use "assets/styles/mixins" as mix; - .submission-container { border: 1px solid var(--grey-2); - border-radius: mix.rem(8px); + border-radius: 0.5rem; } .submission-item:not(:last-child) { diff --git a/src/app/features/moderation/components/submissions-list/submissions-list.component.ts b/src/app/features/moderation/components/submissions-list/submissions-list.component.ts index 562a838c..fd16a47c 100644 --- a/src/app/features/moderation/components/submissions-list/submissions-list.component.ts +++ b/src/app/features/moderation/components/submissions-list/submissions-list.component.ts @@ -1,7 +1,7 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; +import { Submission } from '../../models'; import { SubmissionItemComponent } from '../submission-item/submission-item.component'; -import { pendingReviews } from '../test-data'; @Component({ selector: 'osf-submissions-list', @@ -11,5 +11,5 @@ import { pendingReviews } from '../test-data'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class SubmissionsListComponent { - pendingSubmissions = pendingReviews; + submissions = input.required(); } diff --git a/src/app/features/moderation/components/test-data.ts b/src/app/features/moderation/components/test-data.ts index 8fa34e0d..44807cd0 100644 --- a/src/app/features/moderation/components/test-data.ts +++ b/src/app/features/moderation/components/test-data.ts @@ -35,3 +35,41 @@ export const pendingReviews = [ submittedBy: 'Ella Nguyen', }, ]; + +export const pubicReviews = [ + { + id: 'p1', + name: 'Public Review 1', + reviewStatus: 'public', + dateSubmitted: '10 mins ago', + submittedBy: 'Alice Green', + }, + { + id: 'p2', + name: 'Public Review 2', + reviewStatus: 'public', + dateSubmitted: '33 mins ago', + submittedBy: 'Ben Carter', + }, + { + id: 'p3', + name: 'Public Review 3', + reviewStatus: 'public', + dateSubmitted: '2 hours ago', + submittedBy: 'Cara Kim', + }, + { + id: 'p4', + name: 'Public Review 4', + reviewStatus: 'public', + dateSubmitted: '1 day ago', + submittedBy: 'David Lin', + }, + { + id: 'p5', + name: 'Public Review 5', + reviewStatus: 'public', + dateSubmitted: '1 week ago', + submittedBy: 'Ella Nguyen', + }, +]; diff --git a/src/app/features/moderation/constants/index.ts b/src/app/features/moderation/constants/index.ts index d0cf0665..762a2c72 100644 --- a/src/app/features/moderation/constants/index.ts +++ b/src/app/features/moderation/constants/index.ts @@ -1,2 +1,4 @@ export * from './collection-moderation-tabs.const'; +export * from './registry-moderation-tabs.const'; export * from './submission.const'; +export * from './upload-limits.const'; diff --git a/src/app/features/moderation/constants/registry-moderation-tabs.const.ts b/src/app/features/moderation/constants/registry-moderation-tabs.const.ts new file mode 100644 index 00000000..f30ecdf4 --- /dev/null +++ b/src/app/features/moderation/constants/registry-moderation-tabs.const.ts @@ -0,0 +1,10 @@ +import { TabOption } from '@osf/shared/models'; + +import { RegistryModerationTab } from '../enums'; + +export const REGISTRY_MODERATION_TABS: TabOption[] = [ + { label: 'moderation.submitted', value: RegistryModerationTab.Submitted }, + { label: 'moderation.pending', value: RegistryModerationTab.Pending }, + { label: 'moderation.moderators', value: RegistryModerationTab.Moderators }, + { label: 'moderation.settings', value: RegistryModerationTab.Settings }, +]; diff --git a/src/app/features/moderation/constants/submission.const.ts b/src/app/features/moderation/constants/submission.const.ts index 57a086a6..0bdf6f29 100644 --- a/src/app/features/moderation/constants/submission.const.ts +++ b/src/app/features/moderation/constants/submission.const.ts @@ -23,7 +23,30 @@ export const SUBMISSION_REVIEW_OPTIONS = [ }, ]; -export const ReviewStatusIcon: Record = { +export const SUBMITTED_SUBMISSION_REVIEW_OPTIONS = [ + { + value: SubmissionReviewStatus.Public, + icon: 'fas fa-lock', + label: 'moderation.submissionReviewStatus.public', + }, + { + value: SubmissionReviewStatus.Embargo, + icon: 'fas fa-lock-open', + label: 'moderation.submissionReviewStatus.embargo', + }, + { + value: SubmissionReviewStatus.Rejected, + icon: 'fas fa-circle-xmark', + label: 'moderation.submissionReviewStatus.rejected', + }, + { + value: SubmissionReviewStatus.Withdrawn, + icon: 'fas fa-circle-minus', + label: 'moderation.submissionReviewStatus.withdrawn', + }, +]; + +export const ReviewStatusIcon: Record = { [SubmissionReviewStatus.Pending]: { value: SubmissionReviewStatus.Pending, icon: 'fas fa-hourglass', @@ -40,4 +63,12 @@ export const ReviewStatusIcon: Record +
-
+
@if (isMedium()) { @@ -13,7 +13,12 @@ @if (!isMedium()) { - + } diff --git a/src/app/features/moderation/pages/collection-moderation/collection-moderation.component.scss b/src/app/features/moderation/pages/collection-moderation/collection-moderation.component.scss index 3010ca6d..e69de29b 100644 --- a/src/app/features/moderation/pages/collection-moderation/collection-moderation.component.scss +++ b/src/app/features/moderation/pages/collection-moderation/collection-moderation.component.scss @@ -1,4 +0,0 @@ -:host { - display: flex; - flex: 1 1 0%; -} diff --git a/src/app/features/moderation/pages/index.ts b/src/app/features/moderation/pages/index.ts index b2898d7f..9622ec25 100644 --- a/src/app/features/moderation/pages/index.ts +++ b/src/app/features/moderation/pages/index.ts @@ -1 +1,2 @@ export { CollectionModerationComponent } from './collection-moderation/collection-moderation.component'; +export { RegistriesModerationComponent } from './registries-moderation/registries-moderation.component'; diff --git a/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.html b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.html new file mode 100644 index 00000000..f9aa8115 --- /dev/null +++ b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.html @@ -0,0 +1,42 @@ +
+ + +
+ + @if (isMedium()) { + + @for (item of tabOptions; track $index) { + {{ item.label | translate }} + } + + } + + + @if (!isMedium()) { + + } + + + + + + + + + + + + + + + + + + +
+
diff --git a/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.scss b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.spec.ts b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.spec.ts new file mode 100644 index 00000000..9193d5e5 --- /dev/null +++ b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RegistriesModerationComponent } from './registries-moderation.component'; + +describe('RegistriesModerationComponent', () => { + let component: RegistriesModerationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RegistriesModerationComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(RegistriesModerationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.ts b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.ts new file mode 100644 index 00000000..084691a6 --- /dev/null +++ b/src/app/features/moderation/pages/registries-moderation/registries-moderation.component.ts @@ -0,0 +1,52 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'primeng/tabs'; + +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { FormsModule } from '@angular/forms'; + +import { SelectComponent, SubHeaderComponent } from '@osf/shared/components'; +import { IS_MEDIUM } from '@osf/shared/utils'; + +import { + CollectionModerationSubmissionsComponent, + CollectionModeratorsComponent, + RegistrySettingsComponent, + RegistrySubmissionsComponent, +} from '../../components'; +import { REGISTRY_MODERATION_TABS } from '../../constants'; +import { RegistryModerationTab } from '../../enums'; + +@Component({ + selector: 'osf-registries-moderation', + imports: [ + SubHeaderComponent, + TabList, + Tabs, + Tab, + TabPanel, + TabPanels, + TranslatePipe, + FormsModule, + SelectComponent, + CollectionModeratorsComponent, + CollectionModerationSubmissionsComponent, + RegistrySubmissionsComponent, + RegistrySettingsComponent, + ], + templateUrl: './registries-moderation.component.html', + styleUrl: './registries-moderation.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RegistriesModerationComponent { + readonly tabOptions = REGISTRY_MODERATION_TABS; + readonly tabs = RegistryModerationTab; + readonly isMedium = toSignal(inject(IS_MEDIUM)); + + selectedTab = this.tabs.Submitted; + + onTabChange(index: number): void { + this.selectedTab = index; + } +} diff --git a/src/app/features/project/contributors/contributors.component.ts b/src/app/features/project/contributors/contributors.component.ts index ef380873..b3d36585 100644 --- a/src/app/features/project/contributors/contributors.component.ts +++ b/src/app/features/project/contributors/contributors.component.ts @@ -301,7 +301,10 @@ export class ContributorsComponent implements OnInit { headerKey: 'myProjects.settings.delete.title', headerParams: { name: link.name }, messageKey: 'myProjects.settings.delete.message', - onConfirm: () => this.actions.deleteViewOnlyLink(this.projectId(), link.id), + onConfirm: () => + this.actions + .deleteViewOnlyLink(this.projectId(), link.id) + .subscribe(() => this.toastService.showSuccess('myProjects.settings.delete.success')), }); } } diff --git a/src/app/features/project/metadata/dialogs/contributors-dialog/contributors-dialog.component.html b/src/app/features/project/metadata/dialogs/contributors-dialog/contributors-dialog.component.html index 8ab673d6..6b9690a0 100644 --- a/src/app/features/project/metadata/dialogs/contributors-dialog/contributors-dialog.component.html +++ b/src/app/features/project/metadata/dialogs/contributors-dialog/contributors-dialog.component.html @@ -1,4 +1,4 @@ -
+

{{ 'project.contributors.addContributor' | translate }}

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 ad65ae0e..eefc857b 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 @@ -6,14 +6,14 @@ >
- +

{{ 'project.overview.header.privateProject' | translate }}

- +

{{ 'project.overview.header.publicProject' | translate }}

@@ -28,23 +28,23 @@
- {{ project.viewOnlyLinksCount }} - + {{ project.viewOnlyLinksCount }} + - {{ project.forksCount }} - + {{ project.forksCount }} + @@ -57,37 +57,36 @@ @if (!isBookmarksLoading() && !isBookmarksSubmitting()) { - + } - - {{ socialsActionItems.length }} - - - - - social-icon - {{ item.label | translate }} - - - - + @if (project.isPublic) { + + {{ socialsActionItems.length }} + + + + + + {{ item.label | translate }} + + + + + }
diff --git a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.scss b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.scss index 5cc0548a..c935e55e 100644 --- a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.scss +++ b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.scss @@ -1,15 +1,22 @@ -@use "/assets/styles/variables" as var; -@use "/assets/styles/mixins" as mix; - .inactive { - color: var.$grey-1; + color: var(--grey-1); } .storage { - color: var.$pr-blue-1; - font-size: mix.rem(24px); + color: var(--pr-blue-1); + font-size: 1.5rem; } -.overview-icon { - font-size: mix.rem(21px); +.social-link { + background-color: var(--pr-blue-1); + border-radius: 0.25rem; + color: var(--white); + padding: 0.125rem; + width: 1.125rem; + height: 1.125rem; + + &:hover { + background-color: var(--pr-blue-3); + text-decoration: none; + } } 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 f805ddd0..5004f9cb 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 @@ -10,7 +10,7 @@ import { Tooltip } from 'primeng/tooltip'; import { timer } from 'rxjs'; -import { NgClass, NgOptimizedImage } from '@angular/common'; +import { NgClass } from '@angular/common'; import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, signal } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; @@ -22,6 +22,7 @@ import { RemoveProjectFromBookmarks, } from '@osf/features/collections/store'; import { GetMyBookmarks, MyProjectsSelectors } from '@osf/features/my-projects/store'; +import { IconComponent } from '@osf/shared/components'; import { ToastService } from '@osf/shared/services'; import { FileSizePipe } from '@shared/pipes'; @@ -42,8 +43,8 @@ import { TogglePublicityDialogComponent } from '../toggle-publicity-dialog/toggl FormsModule, NgClass, RouterLink, - NgOptimizedImage, FileSizePipe, + IconComponent, ], templateUrl: './overview-toolbar.component.html', styleUrl: './overview-toolbar.component.scss', diff --git a/src/app/features/project/overview/constants/social-actions.constants.ts b/src/app/features/project/overview/constants/social-actions.constants.ts index 0e23c834..df2b43ef 100644 --- a/src/app/features/project/overview/constants/social-actions.constants.ts +++ b/src/app/features/project/overview/constants/social-actions.constants.ts @@ -1,18 +1,18 @@ export const SOCIAL_ACTION_ITEMS = [ { label: 'project.overview.actions.socials.email', - icon: 'email', + icon: 'fas fa-envelope', }, { label: 'project.overview.actions.socials.x', - icon: 'x', + icon: 'fab fa-x-twitter', }, { label: 'project.overview.actions.socials.linkedIn', - icon: 'linkedin', + icon: 'fab fa-linkedin', }, { label: 'project.overview.actions.socials.facebook', - icon: 'facebook', + icon: 'fab fa-facebook-f', }, ]; 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 f2c32b01..833182fd 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 @@ -2,8 +2,12 @@ class="flex justify-between align-items-center mb-2 w-full border-bottom-1 border-gray-300 gap-2 flex-column sm:flex-row sm:gap-4" >
- - + {{ 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 d6e1dea5..e1e57c03 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 @@ -3,7 +3,6 @@ import { TranslatePipe } from '@ngx-translate/core'; import { Button } from 'primeng/button'; import { SelectModule } from 'primeng/select'; -import { NgClass } from '@angular/common'; import { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; @@ -11,7 +10,7 @@ import { RightControl } from '@osf/features/project/settings/models'; @Component({ selector: 'osf-project-detail-setting-accordion', - imports: [NgClass, SelectModule, FormsModule, Button, TranslatePipe], + imports: [SelectModule, FormsModule, Button, TranslatePipe], templateUrl: './project-detail-setting-accordion.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.html b/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.html index 13d78cfc..e17e76c3 100644 --- a/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.html +++ b/src/app/features/project/settings/components/project-setting-notifications/project-setting-notifications.component.html @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.emailNotifications' | translate }}

+

{{ 'myProjects.settings.emailNotifications' | translate }}

{{ 'myProjects.settings.emailNotificationsText' | translate }}

@@ -9,14 +9,14 @@

{{ 'myProjects.settings.emailNotifications' | translate [title]="title()" >
- + {{ subscriptionEvent.Comments | notificationDescription: notifications()?.[0]?.frequency | translate }}
- + {{ subscriptionEvent.FileUpdated | notificationDescription: notifications()?.[1]?.frequency | translate }} 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 b7f7b307..9c842a8e 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 @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.accessRequests' | translate }}

+

{{ 'myProjects.settings.accessRequests' | translate }}

-

{{ 'myProjects.settings.commenting' | translate }}

+

{{ 'myProjects.settings.commenting' | translate }}

diff --git a/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html b/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html index 03d49687..765563c4 100644 --- a/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html +++ b/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.project' | translate }}

+

{{ 'myProjects.settings.project' | translate }}

diff --git a/src/app/features/project/settings/components/settings-redirect-link/settings-redirect-link.component.html b/src/app/features/project/settings/components/settings-redirect-link/settings-redirect-link.component.html index 494f926a..cb258bcd 100644 --- a/src/app/features/project/settings/components/settings-redirect-link/settings-redirect-link.component.html +++ b/src/app/features/project/settings/components/settings-redirect-link/settings-redirect-link.component.html @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.redirectLink' | translate }}

+

{{ 'myProjects.settings.redirectLink' | translate }}

-

{{ 'myProjects.createProject.storageLocation' | translate }}

+

{{ 'myProjects.createProject.storageLocation' | translate }}

{{ 'myProjects.createProject.storageLocation' | translate }}:

diff --git a/src/app/features/project/settings/components/settings-view-only-links-card/settings-view-only-links-card.component.html b/src/app/features/project/settings/components/settings-view-only-links-card/settings-view-only-links-card.component.html index 8d5156a5..003bbcd2 100644 --- a/src/app/features/project/settings/components/settings-view-only-links-card/settings-view-only-links-card.component.html +++ b/src/app/features/project/settings/components/settings-view-only-links-card/settings-view-only-links-card.component.html @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.viewOnlyLinks' | translate }}

+

{{ 'myProjects.settings.viewOnlyLinks' | translate }}

{{ 'myProjects.settings.viewOnlySubtitle' | translate }}

diff --git a/src/app/features/project/settings/components/settings-wiki-card/settings-wiki-card.component.html b/src/app/features/project/settings/components/settings-wiki-card/settings-wiki-card.component.html index 0b03fb53..a774bdd5 100644 --- a/src/app/features/project/settings/components/settings-wiki-card/settings-wiki-card.component.html +++ b/src/app/features/project/settings/components/settings-wiki-card/settings-wiki-card.component.html @@ -1,5 +1,5 @@ -

{{ 'myProjects.settings.wiki' | translate }}

+

{{ 'myProjects.settings.wiki' | translate }}

{{ 'myProjects.settings.wiki' | translate }}

-

{{ 'myProjects.settings.wikiConfigureTitle' | translate }}

+

{{ 'myProjects.settings.wikiConfigureTitle' | translate }}

{{ 'myProjects.settings.wikiConfigureText' | translate }}

@@ -26,10 +26,10 @@

{{ 'myProjects.settings.wikiConfigureTitle' | translate [rightControls]="allAccordionData" >
- - {{ - 'myProjects.settings.' + (anyoneCanEditWiki() ? 'enabledForWiki' : 'disabledForWiki') | translate - }} + + + {{ 'myProjects.settings.' + (anyoneCanEditWiki() ? 'enabledForWiki' : 'disabledForWiki') | translate }} +
diff --git a/src/app/features/project/settings/services/settings.service.ts b/src/app/features/project/settings/services/settings.service.ts index 8ad859fb..462b0bd0 100644 --- a/src/app/features/project/settings/services/settings.service.ts +++ b/src/app/features/project/settings/services/settings.service.ts @@ -28,4 +28,8 @@ export class SettingsService { .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}`); + } } diff --git a/src/app/features/project/settings/settings.component.html b/src/app/features/project/settings/settings.component.html index 3e005145..3147819f 100644 --- a/src/app/features/project/settings/settings.component.html +++ b/src/app/features/project/settings/settings.component.html @@ -1,7 +1,7 @@
-
+
{{ 'myProjects.settings.projectAffiliation' | translate
  • {{ 'myProjects.settings.publicProjectsToBeDiscoverable' | translate }}
  • {{ 'myProjects.settings.singleSignInToTHeOSF' | translate }}
  • - {{ - 'myProjects.settings.faq' | translate - }} + + {{ 'myProjects.settings.faq' | translate }} +
  • diff --git a/src/app/features/project/settings/settings.component.scss b/src/app/features/project/settings/settings.component.scss index f3dad1bd..ce0ba1e5 100644 --- a/src/app/features/project/settings/settings.component.scss +++ b/src/app/features/project/settings/settings.component.scss @@ -1,4 +1,3 @@ -@use "assets/styles/variables" as var; @use "assets/styles/mixins" as mix; :host { @@ -11,13 +10,5 @@ } .input-label { - color: var.$dark-blue-1; margin-bottom: 0; } - -.delete-icon { - &:before { - color: var.$red-3; - cursor: pointer; - } -} diff --git a/src/app/features/project/settings/settings.component.ts b/src/app/features/project/settings/settings.component.ts index 98c68457..bc7d54eb 100644 --- a/src/app/features/project/settings/settings.component.ts +++ b/src/app/features/project/settings/settings.component.ts @@ -11,7 +11,7 @@ import { NgOptimizedImage } from '@angular/common'; import { ChangeDetectionStrategy, Component, effect, inject, OnInit, signal } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ProjectSettingNotificationsComponent, @@ -30,6 +30,7 @@ import { ViewOnlyLinkModel, } from '@osf/features/project/settings/models'; import { + DeleteProject, DeleteViewOnlyLink, GetProjectDetails, GetProjectSettings, @@ -74,6 +75,7 @@ import { UpdateNodeRequestModel } from '@shared/models'; }) export class SettingsComponent implements OnInit { private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); private readonly customConfirmationService = inject(CustomConfirmationService); private readonly toastService = inject(ToastService); private readonly loaderService = inject(LoaderService); @@ -95,6 +97,7 @@ export class SettingsComponent implements OnInit { updateProjectSettings: UpdateProjectSettings, updateNotificationSubscriptionForNodeId: UpdateNotificationSubscriptionForNodeId, deleteViewOnlyLink: DeleteViewOnlyLink, + deleteProject: DeleteProject, }); projectForm = new FormGroup({ @@ -175,7 +178,11 @@ export class SettingsComponent implements OnInit { const id = `${'n5str'}_${data.event}`; const frequency = data.frequency; - this.actions.updateNotificationSubscriptionForNodeId({ id, frequency }).subscribe(); + this.loaderService.show(); + this.actions.updateNotificationSubscriptionForNodeId({ id, frequency }).subscribe(() => { + this.toastService.showSuccess('myProjects.settings.updateProjectSettingsMessage'); + this.loaderService.hide(); + }); } deleteLinkItem(link: ViewOnlyLinkModel): void { @@ -184,13 +191,28 @@ export class SettingsComponent implements OnInit { headerParams: { name: link.name }, messageKey: 'myProjects.settings.delete.message', onConfirm: () => { - this.actions.deleteViewOnlyLink(this.projectId(), link.id).subscribe(); + this.actions.deleteViewOnlyLink(this.projectId(), link.id).subscribe(() => { + this.toastService.showSuccess('myProjects.settings.delete.success'); + this.loaderService.hide(); + }); }, }); } deleteProject(): void { - this.projectForm.reset(); + this.customConfirmationService.confirmDelete({ + headerKey: 'project.deleteProject.title', + messageParams: { name: this.projectDetails().attributes.title }, + messageKey: 'project.deleteProject.message', + onConfirm: () => { + this.loaderService.show(); + this.actions.deleteProject(this.projectId()).subscribe(() => { + this.loaderService.hide(); + this.toastService.showSuccess('project.deleteProject.success'); + this.router.navigate(['/']); + }); + }, + }); } private syncSettingsChanges(changedField: string, value: boolean | { url: string; label: string }): void { diff --git a/src/app/features/project/settings/store/settings.actions.ts b/src/app/features/project/settings/store/settings.actions.ts index 6b89f62a..86c8620d 100644 --- a/src/app/features/project/settings/store/settings.actions.ts +++ b/src/app/features/project/settings/store/settings.actions.ts @@ -26,7 +26,7 @@ export class UpdateProjectSettings { } export class UpdateProjectDetails { - static readonly type = '[Project] Update'; + static readonly type = '[Settings] Update Project Details'; constructor(public payload: UpdateNodeRequestModel) {} } @@ -48,3 +48,9 @@ export class DeleteViewOnlyLink { public linkId: string ) {} } + +export class DeleteProject { + static readonly type = '[Settings] Delete Project'; + + constructor(public projectId: string) {} +} diff --git a/src/app/features/project/settings/store/settings.state.ts b/src/app/features/project/settings/store/settings.state.ts index bd4c5656..7ee0bf05 100644 --- a/src/app/features/project/settings/store/settings.state.ts +++ b/src/app/features/project/settings/store/settings.state.ts @@ -11,6 +11,7 @@ import { PaginatedViewOnlyLinksModel, ProjectSettingsModel } from '@osf/features import { SettingsService, ViewOnlyLinksService } from '@osf/features/project/settings/services'; import { CreateViewOnlyLink, + DeleteProject, DeleteViewOnlyLink, GetProjectDetails, GetProjectSettings, @@ -260,4 +261,9 @@ export class SettingsState { catchError((error) => this.handleError(ctx, 'viewOnlyLinks', error)) ); } + + @Action(DeleteProject) + deleteProject(ctx: StateContext, action: DeleteProject) { + return this.settingsService.deleteProject(action.projectId); + } } diff --git a/src/app/features/project/wiki/wiki.component.spec.ts b/src/app/features/project/wiki/wiki.component.spec.ts index 351a612a..c0d1a329 100644 --- a/src/app/features/project/wiki/wiki.component.spec.ts +++ b/src/app/features/project/wiki/wiki.component.spec.ts @@ -23,8 +23,6 @@ import { WikiComponent } from './wiki.component'; describe('WikiComponent', () => { let component: WikiComponent; let fixture: ComponentFixture; - let router: Router; - let toastService: ToastService; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -60,48 +58,10 @@ describe('WikiComponent', () => { fixture = TestBed.createComponent(WikiComponent); component = fixture.componentInstance; - router = TestBed.inject(Router); - toastService = TestBed.inject(ToastService); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); - - // it('should initialize with correct project ID', () => { - // expect(component.projectId()).toBe('123'); - // }); - - // it('should toggle mode', () => { - // const toggleModeSpy = jest.spyOn(component['actions'], 'toggleMode'); - // component.toggleMode(WikiModes.Edit); - // expect(toggleModeSpy).toHaveBeenCalledWith(WikiModes.Edit); - // }); - - // it('should update wiki preview content', () => { - // const updatePreviewSpy = jest.spyOn(component['actions'], 'updateWikiPreviewContent'); - // const testContent = 'test content'; - // component.updateWikiPreviewContent(testContent); - // expect(updatePreviewSpy).toHaveBeenCalledWith(testContent); - // }); - - // it('should handle wiki creation', () => { - // const routerSpy = jest.spyOn(router, 'navigate'); - // component.onCreateWiki(); - // expect(routerSpy).toHaveBeenCalled(); - // }); - - // it('should handle wiki deletion', () => { - // const deleteWikiSpy = jest.spyOn(component['actions'], 'deleteWiki'); - // component.onDeleteWiki(); - // expect(deleteWikiSpy).toHaveBeenCalled(); - // }); - - // it('should handle content saving', () => { - // const createVersionSpy = jest.spyOn(component['actions'], 'createWikiVersion'); - // const testContent = 'test content'; - // component.onSaveContent(testContent); - // expect(createVersionSpy).toHaveBeenCalled(); - // }); }); diff --git a/src/app/features/registries/registries.routes.ts b/src/app/features/registries/registries.routes.ts index d410bfa4..54383975 100644 --- a/src/app/features/registries/registries.routes.ts +++ b/src/app/features/registries/registries.routes.ts @@ -5,6 +5,8 @@ import { Routes } from '@angular/router'; import { RegistriesComponent } from '@osf/features/registries/registries.component'; import { RegistriesState } from '@osf/features/registries/store'; +import { ModerationState } from '../moderation/store'; + export const registriesRoutes: Routes = [ { path: '', @@ -20,6 +22,14 @@ export const registriesRoutes: Routes = [ path: 'overview', loadComponent: () => import('@osf/features/registries/pages').then((c) => c.RegistriesLandingComponent), }, + { + path: 'moderation', + loadComponent: () => + import('@osf/features/moderation/pages/registries-moderation/registries-moderation.component').then( + (m) => m.RegistriesModerationComponent + ), + providers: [provideStates([ModerationState])], + }, ], }, ]; diff --git a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html index 381808a3..646d3957 100644 --- a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html +++ b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.html @@ -33,7 +33,7 @@ @if (!isInitialState()) {
    {{name}} project?", + "success": "Project has been successfully deleted." } }, "collections": { @@ -962,8 +968,12 @@ "allItems": "All Items", "moderators": "Moderators", "settings": "Settings", + "submitted": "Submitted", + "pending": "Pending", "settingsMessage": "To configure your notification preferences visit your", "userSettings": "User settings", + "bulkUpload": "Bulk upload", + "bulkUploadMessage": "Drag and drop the csv file that has the registration information to upload.", "addModerator": "Add moderator", "inviteModerator": "Invite moderator", "searchModerator": "Search moderator", @@ -986,7 +996,9 @@ "pending": "Pending", "accepted": "Accepted", "rejected": "Rejected", - "withdrawn": "Withdrawn" + "withdrawn": "Withdrawn", + "public": "public", + "embargo": "embargo" }, "submissionReview": { "submitted": "Submitted", diff --git a/src/assets/styles/overrides/select.scss b/src/assets/styles/overrides/select.scss index ab3dca05..2cfc0e49 100644 --- a/src/assets/styles/overrides/select.scss +++ b/src/assets/styles/overrides/select.scss @@ -8,6 +8,7 @@ --p-icon-size: 0.875rem; &.accordion-dropdown { + font-size: 0.875rem; border: none; box-shadow: none; min-width: 120px;