diff --git a/src/app/features/project/analytics/analytics.component.html b/src/app/features/analytics/analytics.component.html similarity index 64% rename from src/app/features/project/analytics/analytics.component.html rename to src/app/features/analytics/analytics.component.html index 75a6a3274..7ead2f371 100644 --- a/src/app/features/project/analytics/analytics.component.html +++ b/src/app/features/analytics/analytics.component.html @@ -5,27 +5,42 @@ } -
- + @if (relatedCounts() && !relatedCounts()?.isPublic) { +
+

+ {{ 'project.analytics.privateProject.message' | translate }} +

- - - {{ selectedOption.label | translate }} - +
    +
  • {{ 'project.analytics.privateProject.benefits.discoverable' | translate }}
  • +
  • {{ 'project.analytics.privateProject.benefits.citable' | translate }}
  • +
  • {{ 'project.analytics.privateProject.benefits.affiliated' | translate }}
  • +
  • {{ 'project.analytics.privateProject.benefits.openPractices' | translate }}
  • +
- - {{ item.label | translate }} - -
-
+

+ {{ 'project.analytics.privateProject.impact' | translate }} +

+
+ } + + @if (relatedCounts()?.isPublic) { +
+ + +
+ +
+
+ }
params['id'])) ?? of(undefined)); - readonly resourceType: Signal = toSignal( - this.route.data.pipe(map((params) => params['resourceType'])) ?? of(undefined) - ); + readonly resourceType = toSignal(this.route.data.pipe(map((params) => params['resourceType'])) ?? of(undefined)); - hasViewOnly = computed(() => { - return hasViewOnlyParam(this.router); - }); + hasViewOnly = computed(() => hasViewOnlyParam(this.router)); analytics = select(AnalyticsSelectors.getMetrics(this.resourceId())); relatedCounts = select(AnalyticsSelectors.getRelatedCounts(this.resourceId())); @@ -97,14 +96,13 @@ export class AnalyticsComponent implements OnInit { popularPagesLabels: string[] = []; popularPagesDataset: DatasetInput[] = []; - ngOnInit() { - this.actions.getMetrics(this.resourceId(), this.selectedRange().value); - this.actions.getRelatedCounts(this.resourceId(), this.resourceType()); - this.setData(); - } - constructor() { this.setupCleanup(); + this.setupEffects(); + } + + ngOnInit() { + this.actions.getRelatedCounts(this.resourceId(), this.resourceType()); } setupCleanup(): void { @@ -113,9 +111,32 @@ export class AnalyticsComponent implements OnInit { }); } - onRangeChange(range: DateRangeOption) { - this.selectedRange.set(range); - this.actions.getMetrics(this.resourceId(), range.value); + setupEffects(): void { + effect(() => { + const relatedCounts = this.relatedCounts(); + const resourceId = this.resourceId(); + const selectedRange = this.selectedRange(); + + if (relatedCounts?.isPublic && resourceId) { + this.actions.getMetrics(resourceId, selectedRange); + } + }); + + effect(() => { + const analytics = this.analytics(); + + if (analytics) { + this.setData(); + } + }); + } + + onRangeChange(value: Primitive) { + this.selectedRange.set(value as DateRange); + } + + navigateToDuplicates() { + this.router.navigate(['duplicates'], { relativeTo: this.route }); } private setData() { @@ -126,19 +147,35 @@ export class AnalyticsComponent implements OnInit { } this.visitsLabels = analytics.uniqueVisits.map((item) => this.datePipe.transform(item.date, 'MMM d') || ''); - this.visitsDataset = [{ label: 'Visits', data: analytics.uniqueVisits.map((item) => item.count) }]; + this.visitsDataset = [ + { + label: this.translateService.instant('project.analytics.charts.visits'), + data: analytics.uniqueVisits.map((item) => item.count), + }, + ]; this.totalVisitsLabels = analytics.timeOfDay.map((item) => item.hour.toString()); - this.totalVisitsDataset = [{ label: 'Visits', data: analytics.timeOfDay.map((item) => item.count) }]; + this.totalVisitsDataset = [ + { + label: this.translateService.instant('project.analytics.charts.visits'), + data: analytics.timeOfDay.map((item) => item.count), + }, + ]; this.topReferrersLabels = analytics.refererDomain.map((item) => item.refererDomain); - this.topReferrersDataset = [{ label: 'Top referrers', data: analytics.refererDomain.map((item) => item.count) }]; + this.topReferrersDataset = [ + { + label: this.translateService.instant('project.analytics.charts.topReferrers'), + data: analytics.refererDomain.map((item) => item.count), + }, + ]; this.popularPagesLabels = analytics.popularPages.map((item) => item.title); - this.popularPagesDataset = [{ label: 'Popular pages', data: analytics.popularPages.map((item) => item.count) }]; - } - - navigateToDuplicates() { - this.router.navigate(['duplicates'], { relativeTo: this.route }); + this.popularPagesDataset = [ + { + label: this.translateService.instant('project.analytics.charts.popularPages'), + data: analytics.popularPages.map((item) => item.count), + }, + ]; } } diff --git a/src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.html b/src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.html similarity index 100% rename from src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.html rename to src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.html diff --git a/src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.scss b/src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.scss similarity index 100% rename from src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.scss rename to src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.scss diff --git a/src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.spec.ts b/src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.spec.ts similarity index 100% rename from src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.spec.ts rename to src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.spec.ts diff --git a/src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.ts b/src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.ts similarity index 100% rename from src/app/features/project/analytics/components/analytics-kpi/analytics-kpi.component.ts rename to src/app/features/analytics/components/analytics-kpi/analytics-kpi.component.ts diff --git a/src/app/features/project/analytics/components/index.ts b/src/app/features/analytics/components/index.ts similarity index 100% rename from src/app/features/project/analytics/components/index.ts rename to src/app/features/analytics/components/index.ts diff --git a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.html similarity index 100% rename from src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.html rename to src/app/features/analytics/components/view-duplicates/view-duplicates.component.html diff --git a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.scss b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.scss similarity index 100% rename from src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.scss rename to src/app/features/analytics/components/view-duplicates/view-duplicates.component.scss diff --git a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.spec.ts b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.spec.ts similarity index 100% rename from src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.spec.ts rename to src/app/features/analytics/components/view-duplicates/view-duplicates.component.spec.ts diff --git a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.ts b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.ts similarity index 82% rename from src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.ts rename to src/app/features/analytics/components/view-duplicates/view-duplicates.component.ts index bbde88952..50b567184 100644 --- a/src/app/features/project/analytics/components/view-duplicates/view-duplicates.component.ts +++ b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.ts @@ -36,11 +36,11 @@ import { LoadingSpinnerComponent, SubHeaderComponent, TruncatedTextComponent, -} from '@shared/components'; -import { ResourceType, UserPermissions } from '@shared/enums'; -import { IS_SMALL } from '@shared/helpers'; -import { ToolbarResource } from '@shared/models'; -import { ClearDuplicates, DuplicatesSelectors, GetAllDuplicates } from '@shared/stores'; +} from '@osf/shared/components'; +import { ResourceType, UserPermissions } from '@osf/shared/enums'; +import { IS_SMALL } from '@osf/shared/helpers'; +import { ToolbarResource } from '@osf/shared/models'; +import { ClearDuplicates, DuplicatesSelectors, GetAllDuplicates } from '@osf/shared/stores'; @Component({ selector: 'osf-view-duplicates', @@ -71,11 +71,14 @@ export class ViewDuplicatesComponent { private registration = select(RegistryOverviewSelectors.getRegistry); private isProjectAnonymous = select(ProjectOverviewSelectors.isProjectAnonymous); private isRegistryAnonymous = select(RegistryOverviewSelectors.isRegistryAnonymous); + duplicates = select(DuplicatesSelectors.getDuplicates); isDuplicatesLoading = select(DuplicatesSelectors.getDuplicatesLoading); totalDuplicates = select(DuplicatesSelectors.getDuplicatesTotalCount); + readonly pageSize = 10; readonly UserPermissions = UserPermissions; + currentPage = signal('1'); isSmall = toSignal(inject(IS_SMALL)); firstIndex = computed(() => (parseInt(this.currentPage()) - 1) * this.pageSize); @@ -167,27 +170,27 @@ export class ViewDuplicatesComponent { const dialogWidth = !this.isSmall() ? '95vw' : '450px'; if (toolbarResource) { - const dialogRef = this.dialogService.open(ForkDialogComponent, { - width: dialogWidth, - focusOnShow: false, - header: this.translateService.instant('project.overview.dialog.fork.headerProject'), - closeOnEscape: true, - modal: true, - closable: true, - data: { - resource: toolbarResource, - resourceType: this.resourceType(), - }, - }); - - dialogRef.onClose.subscribe((result) => { - if (result.success) { - const resource = this.currentResource(); - if (resource) { - this.actions.getDuplicates(resource.id, resource.type, parseInt(this.currentPage()), this.pageSize); + this.dialogService + .open(ForkDialogComponent, { + width: dialogWidth, + focusOnShow: false, + header: this.translateService.instant('project.overview.dialog.fork.headerProject'), + closeOnEscape: true, + modal: true, + closable: true, + data: { + resource: toolbarResource, + resourceType: this.resourceType(), + }, + }) + .onClose.subscribe((result) => { + if (result.success) { + const resource = this.currentResource(); + if (resource) { + this.actions.getDuplicates(resource.id, resource.type, parseInt(this.currentPage()), this.pageSize); + } } - } - }); + }); } } @@ -209,29 +212,29 @@ export class ViewDuplicatesComponent { private handleDeleteFork(id: string): void { const dialogWidth = !this.isSmall() ? '95vw' : '650px'; - const dialogRef = this.dialogService.open(DeleteComponentDialogComponent, { - width: dialogWidth, - focusOnShow: false, - header: this.translateService.instant('project.overview.dialog.deleteComponent.header'), - closeOnEscape: true, - modal: true, - closable: true, - data: { - componentId: id, - resourceType: this.resourceType(), - isForksContext: true, - currentPage: parseInt(this.currentPage()), - pageSize: this.pageSize, - }, - }); - - dialogRef.onClose.subscribe((result) => { - if (result && result.success) { - const resource = this.currentResource(); - if (resource) { - this.actions.getDuplicates(resource.id, resource.type, parseInt(this.currentPage()), this.pageSize); + this.dialogService + .open(DeleteComponentDialogComponent, { + width: dialogWidth, + focusOnShow: false, + header: this.translateService.instant('project.overview.dialog.deleteComponent.header'), + closeOnEscape: true, + modal: true, + closable: true, + data: { + componentId: id, + resourceType: this.resourceType(), + isForksContext: true, + currentPage: parseInt(this.currentPage()), + pageSize: this.pageSize, + }, + }) + .onClose.subscribe((result) => { + if (result && result.success) { + const resource = this.currentResource(); + if (resource) { + this.actions.getDuplicates(resource.id, resource.type, parseInt(this.currentPage()), this.pageSize); + } } - } - }); + }); } } diff --git a/src/app/features/project/analytics/constants/analytics-constants.ts b/src/app/features/analytics/constants/analytics-constants.ts similarity index 100% rename from src/app/features/project/analytics/constants/analytics-constants.ts rename to src/app/features/analytics/constants/analytics-constants.ts diff --git a/src/app/features/project/analytics/constants/index.ts b/src/app/features/analytics/constants/index.ts similarity index 100% rename from src/app/features/project/analytics/constants/index.ts rename to src/app/features/analytics/constants/index.ts diff --git a/src/app/features/project/analytics/enums/date-range.enum.ts b/src/app/features/analytics/enums/date-range.enum.ts similarity index 100% rename from src/app/features/project/analytics/enums/date-range.enum.ts rename to src/app/features/analytics/enums/date-range.enum.ts diff --git a/src/app/features/project/analytics/enums/index.ts b/src/app/features/analytics/enums/index.ts similarity index 100% rename from src/app/features/project/analytics/enums/index.ts rename to src/app/features/analytics/enums/index.ts diff --git a/src/app/features/project/analytics/mappers/analytics.mapper.ts b/src/app/features/analytics/mappers/analytics.mapper.ts similarity index 100% rename from src/app/features/project/analytics/mappers/analytics.mapper.ts rename to src/app/features/analytics/mappers/analytics.mapper.ts diff --git a/src/app/features/project/analytics/mappers/index.ts b/src/app/features/analytics/mappers/index.ts similarity index 100% rename from src/app/features/project/analytics/mappers/index.ts rename to src/app/features/analytics/mappers/index.ts diff --git a/src/app/features/project/analytics/mappers/related-counts.mapper.ts b/src/app/features/analytics/mappers/related-counts.mapper.ts similarity index 90% rename from src/app/features/project/analytics/mappers/related-counts.mapper.ts rename to src/app/features/analytics/mappers/related-counts.mapper.ts index 9ada63557..89ba90f4f 100644 --- a/src/app/features/project/analytics/mappers/related-counts.mapper.ts +++ b/src/app/features/analytics/mappers/related-counts.mapper.ts @@ -4,6 +4,7 @@ export class RelatedCountsMapper { static fromResponse(response: RelatedCountsGetResponse): RelatedCountsModel { return { id: response.data.id, + isPublic: response.data.attributes.public, forksCount: response.data.relationships.forks?.links.related.meta.count || 0, linksToCount: response.data.relationships.linked_by_nodes?.links.related.meta.count || 0, templateCount: response.meta.templated_by_count || 0, diff --git a/src/app/features/project/analytics/models/analytics-metrics.model.ts b/src/app/features/analytics/models/analytics-metrics.model.ts similarity index 100% rename from src/app/features/project/analytics/models/analytics-metrics.model.ts rename to src/app/features/analytics/models/analytics-metrics.model.ts diff --git a/src/app/features/project/analytics/models/date-range-option.model.ts b/src/app/features/analytics/models/date-range-option.model.ts similarity index 100% rename from src/app/features/project/analytics/models/date-range-option.model.ts rename to src/app/features/analytics/models/date-range-option.model.ts diff --git a/src/app/features/project/analytics/models/index.ts b/src/app/features/analytics/models/index.ts similarity index 72% rename from src/app/features/project/analytics/models/index.ts rename to src/app/features/analytics/models/index.ts index c9a8615aa..7a6cd679c 100644 --- a/src/app/features/project/analytics/models/index.ts +++ b/src/app/features/analytics/models/index.ts @@ -1,3 +1,4 @@ export * from './analytics-metrics.model'; export * from './date-range-option.model'; export * from './related-counts.model'; +export * from './related-counts-json-api.model'; diff --git a/src/app/features/project/analytics/models/related-counts.model.ts b/src/app/features/analytics/models/related-counts-json-api.model.ts similarity index 78% rename from src/app/features/project/analytics/models/related-counts.model.ts rename to src/app/features/analytics/models/related-counts-json-api.model.ts index fddab26b0..f51b9acf4 100644 --- a/src/app/features/project/analytics/models/related-counts.model.ts +++ b/src/app/features/analytics/models/related-counts-json-api.model.ts @@ -3,23 +3,20 @@ export interface RelatedCountsGetResponse { meta: MetaGetResponse; } -export interface RelatedCountsModel { - id: string; - forksCount: number; - linksToCount: number; - templateCount: number; - lastFetched?: number; -} - interface MetaGetResponse { templated_by_count: number; } interface RelatedCountsDataResponse { id: string; + attributes: RelatedCountsAttributes; relationships: RelationshipsResponse; } +interface RelatedCountsAttributes { + public: boolean; +} + interface RelationshipsResponse { forks: Relationship; linked_by_nodes: Relationship; diff --git a/src/app/features/analytics/models/related-counts.model.ts b/src/app/features/analytics/models/related-counts.model.ts new file mode 100644 index 000000000..270b33f82 --- /dev/null +++ b/src/app/features/analytics/models/related-counts.model.ts @@ -0,0 +1,8 @@ +export interface RelatedCountsModel { + id: string; + isPublic: boolean; + forksCount: number; + linksToCount: number; + templateCount: number; + lastFetched?: number; +} diff --git a/src/app/features/project/analytics/services/analytics.service.ts b/src/app/features/analytics/services/analytics.service.ts similarity index 100% rename from src/app/features/project/analytics/services/analytics.service.ts rename to src/app/features/analytics/services/analytics.service.ts diff --git a/src/app/features/project/analytics/services/index.ts b/src/app/features/analytics/services/index.ts similarity index 100% rename from src/app/features/project/analytics/services/index.ts rename to src/app/features/analytics/services/index.ts diff --git a/src/app/features/project/analytics/store/analytics.actions.ts b/src/app/features/analytics/store/analytics.actions.ts similarity index 100% rename from src/app/features/project/analytics/store/analytics.actions.ts rename to src/app/features/analytics/store/analytics.actions.ts diff --git a/src/app/features/project/analytics/store/analytics.model.ts b/src/app/features/analytics/store/analytics.model.ts similarity index 100% rename from src/app/features/project/analytics/store/analytics.model.ts rename to src/app/features/analytics/store/analytics.model.ts diff --git a/src/app/features/project/analytics/store/analytics.selectors.ts b/src/app/features/analytics/store/analytics.selectors.ts similarity index 100% rename from src/app/features/project/analytics/store/analytics.selectors.ts rename to src/app/features/analytics/store/analytics.selectors.ts diff --git a/src/app/features/project/analytics/store/analytics.state.ts b/src/app/features/analytics/store/analytics.state.ts similarity index 88% rename from src/app/features/project/analytics/store/analytics.state.ts rename to src/app/features/analytics/store/analytics.state.ts index 8c7e9c1e0..e491e688d 100644 --- a/src/app/features/project/analytics/store/analytics.state.ts +++ b/src/app/features/analytics/store/analytics.state.ts @@ -1,10 +1,12 @@ import { Action, State, StateContext } from '@ngxs/store'; import { insertItem, updateItem } from '@ngxs/store/operators'; -import { catchError, of, tap, throwError } from 'rxjs'; +import { catchError, of, tap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; +import { handleSectionError } from '@osf/shared/helpers'; + import { AnalyticsMetricsModel, RelatedCountsModel } from '../models'; import { AnalyticsService } from '../services'; @@ -57,7 +59,7 @@ export class AnalyticsState { }, }); }), - catchError((error) => this.handleError(ctx, 'metrics', error)) + catchError((error) => handleSectionError(ctx, 'metrics', error)) ); } @@ -105,7 +107,7 @@ export class AnalyticsState { }, }); }), - catchError((error) => this.handleError(ctx, 'relatedCounts', error)) + catchError((error) => handleSectionError(ctx, 'relatedCounts', error)) ); } @@ -121,15 +123,4 @@ export class AnalyticsState { return Date.now() - lastFetched > this.REFRESH_INTERVAL; } - - private handleError(ctx: StateContext, section: 'metrics' | 'relatedCounts', error: Error) { - ctx.patchState({ - [section]: { - ...ctx.getState()[section], - isLoading: false, - error: error.message, - }, - }); - return throwError(() => error); - } } diff --git a/src/app/features/project/analytics/store/index.ts b/src/app/features/analytics/store/index.ts similarity index 100% rename from src/app/features/project/analytics/store/index.ts rename to src/app/features/analytics/store/index.ts diff --git a/src/app/features/project/project.routes.ts b/src/app/features/project/project.routes.ts index bac73f818..8a018747d 100644 --- a/src/app/features/project/project.routes.ts +++ b/src/app/features/project/project.routes.ts @@ -15,9 +15,9 @@ import { } from '@osf/shared/stores'; import { ActivityLogsState } from '@osf/shared/stores/activity-logs'; +import { AnalyticsState } from '../analytics/store'; import { CollectionsModerationState } from '../moderation/store/collections-moderation'; -import { AnalyticsState } from './analytics/store'; import { SettingsState } from './settings/store'; export const projectRoutes: Routes = [ @@ -78,7 +78,7 @@ export const projectRoutes: Routes = [ }, { path: 'analytics', - loadComponent: () => import('../project/analytics/analytics.component').then((mod) => mod.AnalyticsComponent), + loadComponent: () => import('../analytics/analytics.component').then((mod) => mod.AnalyticsComponent), data: { resourceType: ResourceType.Project }, providers: [provideStates([AnalyticsState])], }, @@ -86,7 +86,7 @@ export const projectRoutes: Routes = [ path: 'analytics/duplicates', data: { resourceType: ResourceType.Project }, loadComponent: () => - import('../project/analytics/components/view-duplicates/view-duplicates.component').then( + import('../analytics/components/view-duplicates/view-duplicates.component').then( (mod) => mod.ViewDuplicatesComponent ), providers: [provideStates([DuplicatesState])], diff --git a/src/app/features/registry/registry.routes.ts b/src/app/features/registry/registry.routes.ts index 85dc24cd6..22da6cde0 100644 --- a/src/app/features/registry/registry.routes.ts +++ b/src/app/features/registry/registry.routes.ts @@ -13,7 +13,7 @@ import { ViewOnlyLinkState, } from '@osf/shared/stores'; -import { AnalyticsState } from '../project/analytics/store'; +import { AnalyticsState } from '../analytics/store'; import { RegistriesState } from '../registries/store'; import { LicensesHandlers, ProjectsHandlers, ProvidersHandlers } from '../registries/store/handlers'; import { FilesHandlers } from '../registries/store/handlers/files.handlers'; @@ -72,7 +72,7 @@ export const registryRoutes: Routes = [ }, { path: 'analytics', - loadComponent: () => import('../project/analytics/analytics.component').then((mod) => mod.AnalyticsComponent), + loadComponent: () => import('../analytics/analytics.component').then((mod) => mod.AnalyticsComponent), data: { resourceType: ResourceType.Registration }, providers: [provideStates([AnalyticsState])], }, @@ -80,7 +80,7 @@ export const registryRoutes: Routes = [ path: 'analytics/duplicates', data: { resourceType: ResourceType.Registration }, loadComponent: () => - import('../project/analytics/components/view-duplicates/view-duplicates.component').then( + import('../analytics/components/view-duplicates/view-duplicates.component').then( (mod) => mod.ViewDuplicatesComponent ), providers: [provideStates([DuplicatesState])], diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts index 80d8b3fc0..4b9ae6380 100644 --- a/src/app/shared/models/index.ts +++ b/src/app/shared/models/index.ts @@ -29,13 +29,13 @@ export * from './meta-tags'; export * from './metadata-field.model'; export * from './metadata-tabs.model'; export * from './my-resources'; -export * from './nodes/create-project-form.model'; export * from './nodes/nodes-json-api.model'; export * from './notifications'; export * from './paginated-data.model'; export * from './pagination-links.model'; export * from './profile-settings-update.model'; export * from './project-metadata-update-payload.model'; +export * from './projects'; export * from './provider'; export * from './query-params.model'; export * from './registration'; diff --git a/src/app/shared/models/nodes/create-project-form.model.ts b/src/app/shared/models/projects/create-project-form.model.ts similarity index 100% rename from src/app/shared/models/nodes/create-project-form.model.ts rename to src/app/shared/models/projects/create-project-form.model.ts diff --git a/src/app/shared/models/projects/index.ts b/src/app/shared/models/projects/index.ts index 3697c4b36..ee6b89a9f 100644 --- a/src/app/shared/models/projects/index.ts +++ b/src/app/shared/models/projects/index.ts @@ -1,2 +1,3 @@ +export * from './create-project-form.model'; export * from './projects.models'; export * from './projects-json-api.models'; diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 006dbe420..82a9fc527 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -463,6 +463,16 @@ "topReferrers": "Top referrers", "popularPages": "Popular pages", "visits": "Visits" + }, + "privateProject": { + "message": "Analytics are not available for private projects. To view Analytics, make your project public by switching Public from the project overview page. Public projects:", + "benefits": { + "discoverable": "are discoverable", + "citable": "are citable", + "affiliated": "can be affiliated with OSF for Institutions partners", + "openPractices": "promote open practices among peers" + }, + "impact": "Receive data on visitors to your project by enabling Analytics and begin discovering the impact of your work." } }, "contributors": {