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
2 changes: 2 additions & 0 deletions src/app/features/moderation/collection-moderation.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Routes } from '@angular/router';

import { CollectionsModerationState } from '@osf/features/moderation/store/collections-moderation';
import { ResourceType } from '@osf/shared/enums';
import { ActivityLogsState } from '@shared/stores/activity-logs';
import { CollectionsState } from '@shared/stores/collections';

import { ModeratorsState } from './store/moderators';
Expand All @@ -16,6 +17,7 @@ export const collectionModerationRoutes: Routes = [
import('@osf/features/moderation/pages/collection-moderation/collection-moderation.component').then(
(m) => m.CollectionModerationComponent
),
providers: [provideStates([ActivityLogsState])],
children: [
{
path: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
<div class="activities p-4 flex flex-column gap-3">
<h2>{{ 'project.overview.recentActivity.title' | translate }}</h2>
<div class="activities p-3 flex flex-column gap-3">
<h2 class="mb-2">{{ 'project.overview.recentActivity.title' | translate }}</h2>

<div class="activities-activity flex justify-content-between align-items-center">
<div>
<a class="font-bold">Jeremy Wolfe</a> removed <a class="font-bold">tag example</a> from
<a class="font-bold">Project name example</a>
</div>

<div class="hidden sm:block">Feb 5, 2025 04:37 AM</div>
</div>

<div class="activities-activity flex justify-content-between align-items-center">
<div>
<a class="font-bold">Jeremy Wolfe</a> removed <a class="font-bold">tag example</a> from
<a class="font-bold">Project name example</a>
</div>

<div class="hidden sm:block">Feb 5, 2025 04:37 AM</div>
</div>
@if (!isLoading()) {
@if (formattedActivityLogs().length) {
@for (activityLog of formattedActivityLogs(); track activityLog.id) {
<div class="activities-activity flex justify-content-between gap-3 pb-2 align-items-center">
<div [innerHTML]="activityLog.formattedActivity"></div>
<p class="hidden activity-date sm:block text-right">{{ activityLog.date | date: 'MMM d, y hh:mm a' }}</p>
</div>
}
} @else {
<div class="text-center text-muted-color">
{{ 'project.overview.recentActivity.noActivity' | translate }}
</div>
}

<div class="activities-activity flex justify-content-between align-items-center">
<div>
<a class="font-bold">Jeremy Wolfe</a> removed <a class="font-bold">tag example</a> from
<a class="font-bold">Project name example</a>
@if (totalCount() > pageSize()) {
<osf-custom-paginator
[showFirstLastIcon]="true"
[totalCount]="totalCount()"
[rows]="pageSize()"
[first]="firstIndex()"
(pageChanged)="onPageChange($event)"
/>
}
} @else {
<div class="flex flex-column gap-2">
<p-skeleton width="100%" height="2rem" />
<p-skeleton width="100%" height="2rem" />
<p-skeleton width="100%" height="2rem" />
<p-skeleton width="100%" height="2rem" />
<p-skeleton width="100%" height="2rem" />
</div>

<div class="hidden sm:block">Feb 5, 2025 04:37 AM</div>
</div>
}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
color: var.$dark-blue-1;

&-activity {
height: mix.rem(35px);
border-bottom: 1px solid var.$grey-2;

.activity-date {
width: 30%;
}
}

&-description {
line-height: mix.rem(24px);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,57 @@
import { createDispatchMap, select } from '@ngxs/store';

import { TranslatePipe } from '@ngx-translate/core';

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { PaginatorState } from 'primeng/paginator';
import { Skeleton } from 'primeng/skeleton';

import { DatePipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject, input, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { CustomPaginatorComponent } from '@shared/components';
import { ActivityLogDisplayService } from '@shared/services';
import { ActivityLogsSelectors, GetActivityLogs } from '@shared/stores/activity-logs';

@Component({
selector: 'osf-recent-activity-list',
imports: [TranslatePipe],
imports: [TranslatePipe, Skeleton, DatePipe, CustomPaginatorComponent],
templateUrl: './recent-activity.component.html',
styleUrl: './recent-activity.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RecentActivityComponent {}
export class RecentActivityComponent {
private readonly activityLogDisplayService = inject(ActivityLogDisplayService);
private readonly route = inject(ActivatedRoute);

readonly pageSize = input.required<number>();
protected currentPage = signal<number>(1);
protected activityLogs = select(ActivityLogsSelectors.getActivityLogs);
protected totalCount = select(ActivityLogsSelectors.getActivityLogsTotalCount);
protected isLoading = select(ActivityLogsSelectors.getActivityLogsLoading);
protected firstIndex = computed(() => (this.currentPage() - 1) * this.pageSize());

protected actions = createDispatchMap({
getActivityLogs: GetActivityLogs,
});

protected formattedActivityLogs = computed(() => {
const logs = this.activityLogs();
return logs.map((log) => ({
...log,
formattedActivity: this.activityLogDisplayService.getActivityDisplay(log),
}));
});

onPageChange(event: PaginatorState) {
if (event.page !== undefined) {
const pageNumber = event.page + 1;
this.currentPage.set(pageNumber);

const projectId = this.route.snapshot.params['id'] || this.route.parent?.snapshot.params['id'];
if (projectId) {
this.actions.getActivityLogs(projectId, pageNumber.toString(), this.pageSize().toString());
}
}
}
}
23 changes: 17 additions & 6 deletions src/app/features/project/overview/project-overview.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,35 @@
@if (status && isCollectionsRoute() && collectionProvider()) {
@switch (status) {
@case (SubmissionReviewStatus.Pending) {
<!-- TODO - Update text messages to translates RNa-->
<p-message class="overview-message w-full" icon="fas fa-circle-exclamation" severity="warn">
Pending: Pending entry into <a class="cursor-pointer">{{ collectionProvider()?.name }}</a>
{{ 'project.overview.collectionsModeration.pending' | translate }}
<a class="cursor-pointer" [routerLink]="['/collections/', collectionProvider()?.id]">
{{ collectionProvider()?.name }}</a
>
</p-message>
}
@case (SubmissionReviewStatus.Accepted) {
<p-message class="overview-message w-full" icon="fas fa-circle-exclamation" severity="success">
Accepted: Accepted entry into <a class="cursor-pointer">{{ collectionProvider()?.name }}</a>
{{ 'project.overview.collectionsModeration.accepted' | translate }}
<a class="cursor-pointer" [routerLink]="['/collections/', collectionProvider()?.id]">
{{ collectionProvider()?.name }}</a
>
</p-message>
}
@case (SubmissionReviewStatus.Rejected) {
<p-message class="overview-message w-full" icon="fas fa-circle-exclamation" severity="error">
Rejected: Rejected entry into <a class="cursor-pointer">{{ collectionProvider()?.name }}</a>
{{ 'project.overview.collectionsModeration.rejected' | translate }}
<a class="cursor-pointer" [routerLink]="['/collections/', collectionProvider()?.id]">
{{ collectionProvider()?.name }}</a
>
</p-message>
}
@case (SubmissionReviewStatus.Removed) {
<p-message class="overview-message w-full" icon="fas fa-circle-exclamation" severity="secondary">
Withdrawn: Entry withdrawn from <a class="cursor-pointer">{{ collectionProvider()?.name }}</a>
{{ 'project.overview.collectionsModeration.removed' | translate }}
<a class="cursor-pointer" [routerLink]="['/collections/', collectionProvider()?.id]">
{{ collectionProvider()?.name }}</a
>
</p-message>
}
}
Expand All @@ -64,7 +75,7 @@

<osf-project-components [isCollectionsRoute]="isCollectionsRoute()" [canWrite]="canWrite" />
<osf-linked-resources [isCollectionsRoute]="isCollectionsRoute()" [canWrite]="canWrite" />
<osf-recent-activity-list />
<osf-recent-activity-list [pageSize]="activityPageSize" />
</div>

<div class="flex flex-column right-section p-4">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';

import { SubmissionReviewStatus } from '@osf/features/moderation/enums';
import { IS_XSMALL } from '@osf/shared/helpers';
Expand All @@ -41,6 +41,7 @@ import {
GetHomeWiki,
GetLinkedResources,
} from '@shared/stores';
import { GetActivityLogs } from '@shared/stores/activity-logs';
import { ClearCollections } from '@shared/stores/collections';

import {
Expand Down Expand Up @@ -83,6 +84,7 @@ import {
ResourceMetadataComponent,
TranslatePipe,
Message,
RouterLink,
],
providers: [DialogService],
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -100,13 +102,16 @@ export class ProjectOverviewComponent implements OnInit {
protected submissions = select(CollectionsModerationSelectors.getCollectionSubmissions);
protected collectionProvider = select(CollectionsSelectors.getCollectionProvider);
protected currentReviewAction = select(CollectionsModerationSelectors.getCurrentReviewAction);
protected readonly activityPageSize = 5;
protected readonly activityDefaultPage = 1;

protected actions = createDispatchMap({
getProject: GetProjectById,
getBookmarksId: GetBookmarksCollectionId,
getHomeWiki: GetHomeWiki,
getComponents: GetComponents,
getLinkedProjects: GetLinkedResources,
getActivityLogs: GetActivityLogs,
setProjectCustomCitation: SetProjectCustomCitation,
getCollectionProvider: GetCollectionProvider,
getCurrentReviewAction: GetSubmissionsReviewActions,
Expand Down Expand Up @@ -195,6 +200,7 @@ export class ProjectOverviewComponent implements OnInit {
this.actions.getHomeWiki(ResourceType.Project, projectId);
this.actions.getComponents(projectId);
this.actions.getLinkedProjects(projectId);
this.actions.getActivityLogs(projectId, this.activityDefaultPage.toString(), this.activityPageSize.toString());
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/app/features/project/project.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SubjectsState,
ViewOnlyLinkState,
} from '@osf/shared/stores';
import { ActivityLogsState } from '@shared/stores/activity-logs';

import { AnalyticsState } from './analytics/store';
import { ProjectFilesState } from './files/store';
Expand All @@ -32,7 +33,15 @@ export const projectRoutes: Routes = [
path: 'overview',
loadComponent: () =>
import('../project/overview/project-overview.component').then((mod) => mod.ProjectOverviewComponent),
providers: [provideStates([NodeLinksState, CitationsState, CollectionsState, CollectionsModerationState])],
providers: [
provideStates([
NodeLinksState,
CitationsState,
CollectionsState,
CollectionsModerationState,
ActivityLogsState,
]),
],
},
{
path: 'metadata',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ <h2>{{ 'project.overview.metadata.title' | translate }}</h2>
<div class="flex flex-column gap-2">
<h3>{{ 'project.overview.metadata.contributors' | translate }}</h3>

<div class="flex gap-1 line-height-2">
<div class="flex flex-wrap gap-1 line-height-2">
@for (contributor of resource.contributors; track contributor.id) {
<div>
<a class="font-bold"> {{ contributor.fullName }}</a>
Expand Down
Loading