@anthusai/papyrus 1.0.0-next.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/amplify/auth/prospectus-google-client.js +66 -0
- package/amplify/auth/prospectus-google-client.ts +71 -0
- package/amplify/auth/redirect-urls.js +54 -0
- package/amplify/auth/redirect-urls.ts +66 -0
- package/amplify/auth/resource.js +23 -5
- package/amplify/auth/resource.ts +31 -5
- package/amplify/data/resource.js +42 -80
- package/amplify/data/resource.ts +42 -80
- package/amplify/data/schema.js +45 -62
- package/amplify/data/schema.ts +47 -62
- package/amplify/functions/category-action/handler.ts +5 -3
- package/amplify/functions/console-chat-responder/py/execute_tactus_runner.py +0 -10
- package/amplify/functions/console-chat-responder/resource.js +0 -7
- package/amplify/functions/console-chat-responder/resource.ts +0 -8
- package/amplify/functions/console-chat-responder/src/main.rs +0 -9
- package/amplify/functions/content-actions/handler.py +143 -1
- package/amplify/functions/content-actions/requirements.txt +2 -1
- package/amplify/functions/content-actions/resource.js +6 -1
- package/amplify/functions/content-actions/resource.ts +9 -2
- package/amplify/functions/email-submission-processor/handler.py +3 -1
- package/amplify/functions/renditions/handler.py +120 -0
- package/amplify/functions/renditions/requirements.txt +4 -0
- package/amplify/functions/ses-inbound-receive/handler.ts +32 -4
- package/amplify/functions/shared/email-submission.ts +109 -1
- package/amplify/functions/shared/python-bundle.js +42 -2
- package/amplify/functions/shared/python-bundle.ts +47 -2
- package/amplify/functions/shared/reference-curation-metadata.ts +29 -0
- package/amplify/inbound-email/ses-intake.js +86 -0
- package/amplify/inbound-email/ses-intake.ts +110 -0
- package/amplify/plugins/registry.js +19 -0
- package/amplify/plugins/registry.ts +23 -0
- package/amplify/plugins/signup/function/handler.py +200 -0
- package/amplify/plugins/signup/function/resource.js +27 -0
- package/amplify/plugins/signup/function/resource.ts +35 -0
- package/amplify/plugins/signup/papyrus.plugin.js +59 -0
- package/amplify/plugins/signup/papyrus.plugin.ts +74 -0
- package/amplify/plugins/signup/schema.js +40 -0
- package/amplify/plugins/signup/schema.ts +41 -0
- package/amplify/plugins/signup/waf.js +48 -0
- package/amplify/plugins/signup/waf.ts +51 -0
- package/amplify/plugins/types.js +1 -0
- package/amplify/plugins/types.ts +39 -0
- package/amplify/plugins/wire.js +24 -0
- package/amplify/plugins/wire.ts +26 -0
- package/amplify/publication/default-publication.js +18 -0
- package/amplify/publication/default-publication.ts +20 -0
- package/amplify/publication/invalidation-alarm.js +26 -0
- package/amplify/publication/invalidation-alarm.ts +30 -0
- package/amplify/publication/redirect-and-index.js +37 -0
- package/amplify/publication/renditions-function.js +74 -0
- package/amplify/publication/renditions-function.ts +112 -0
- package/amplify/publication/renditions-settings.js +51 -0
- package/amplify/publication/renditions-settings.ts +58 -0
- package/amplify/publication/reproject-on-deploy.js +73 -0
- package/amplify/publication/reproject-on-deploy.ts +78 -0
- package/amplify/publication/s3-projection-settings.js +67 -0
- package/amplify/publication/s3-projection-settings.ts +101 -0
- package/amplify/publication/s3-projection.js +151 -0
- package/amplify/publication/s3-projection.ts +201 -0
- package/amplify/resolver-waves.js +26 -0
- package/amplify/resolver-waves.ts +34 -0
- package/amplify/revalidate-invalidation-settings.js +30 -0
- package/amplify/revalidate-invalidation-settings.ts +35 -0
- package/amplify/revalidate-secret-policy.js +13 -0
- package/amplify/revalidate-secret-policy.ts +19 -0
- package/amplify/site-backend-config.js +65 -1
- package/amplify/site-backend-config.ts +153 -2
- package/amplify/site-backend-names.js +103 -0
- package/amplify/site-backend-names.ts +166 -0
- package/amplify/site-backend.js +150 -176
- package/amplify/site-backend.ts +189 -201
- package/amplify/storage-backups/construct.js +31 -0
- package/amplify/storage-backups/construct.ts +47 -0
- package/app/[year]/[month]/[day]/[articleSlug]/page.tsx +8 -1
- package/app/[year]/[month]/[day]/edition-route-page.tsx +2 -0
- package/app/[year]/[month]/[day]/page/[pageNumber]/page.tsx +6 -1
- package/app/[year]/[month]/[day]/page.tsx +1 -1
- package/app/[year]/[month]/[day]/section/[sectionKey]/page.tsx +6 -1
- package/app/api/archive/editions/route.ts +1 -1
- package/app/api/auth/prospectus/callback/route.ts +9 -0
- package/app/api/auth/prospectus/selection/route.ts +9 -0
- package/app/api/auth/prospectus/session/route.ts +9 -0
- package/app/api/auth/prospectus/sign-in/route.ts +9 -0
- package/app/api/auth/prospectus/sign-out/route.ts +9 -0
- package/app/api/cyclotron/priming-proof/route.ts +11 -0
- package/app/api/media/[...path]/route.ts +5 -16
- package/app/api/revalidate/route.ts +15 -7
- package/app/archive/page.tsx +1 -1
- package/app/articles/[slug]/page.tsx +7 -5
- package/app/blog-rhythm.css +278 -0
- package/app/cyclotron/page.tsx +13 -0
- package/app/globals.css +2 -0
- package/app/layout.tsx +16 -0
- package/app/newsroom/[section]/[...selection]/page.tsx +9 -6
- package/app/newsroom/[section]/page.tsx +6 -3
- package/app/newsroom/layout.tsx +4 -9
- package/app/newsroom/settings/page.tsx +6 -0
- package/app/newsroom/work/page.tsx +10 -0
- package/app/page.tsx +22 -8
- package/app/robots.ts +2 -5
- package/app/tailwind.css +1 -6
- package/components/amplify-client-provider.tsx +5 -22
- package/components/archive-shell.tsx +2 -22
- package/components/article-video.tsx +152 -5
- package/components/blog-page-background.tsx +23 -6
- package/components/news-desk-page.tsx +4 -15
- package/components/news-desk-taxonomy-client.ts +90 -3
- package/components/newspaper.tsx +6 -2
- package/components/newsroom-access-gate.tsx +2 -1
- package/components/newsroom-board-view.tsx +99 -0
- package/components/newsroom-client-shell.tsx +12 -0
- package/components/newsroom-curation-provider.tsx +17 -0
- package/components/newsroom-fonts/playfair-display-700.ttf +0 -0
- package/components/newsroom-fonts/playfair-display-900.ttf +0 -0
- package/components/newsroom-fonts/playfair-display-OFL.txt +93 -0
- package/components/newsroom-fonts/plus-jakarta-sans-400.ttf +0 -0
- package/components/newsroom-fonts/plus-jakarta-sans-600.ttf +0 -0
- package/components/newsroom-fonts/plus-jakarta-sans-OFL.txt +93 -0
- package/components/newsroom-newsprint-board.css +48 -0
- package/components/newsroom-ops-overview.tsx +28 -11
- package/components/newsroom-ops-shell.tsx +7 -1
- package/components/newsroom-organizer-shell.tsx +130 -0
- package/components/newsroom-organizer.css +63 -0
- package/components/newsroom-references-view.tsx +92 -8
- package/components/papyrus-console-shell.tsx +4 -2
- package/components/pictogram-figure.tsx +9 -2
- package/components/presentation-header.tsx +135 -0
- package/components/presentation-rhythm-hrule.tsx +17 -0
- package/components/priming-proof-page.tsx +94 -0
- package/components/publication-cyclotron-panel.tsx +57 -0
- package/components/reader-auth-control.tsx +8 -5
- package/components/reference-curation-controls.tsx +77 -0
- package/components/reference-cyclotron-status.tsx +109 -0
- package/components/reference-priming.tsx +18 -0
- package/components/reference-relevance-review.tsx +75 -0
- package/components/settings-page.tsx +2 -1
- package/components/signup-entries-panel.tsx +94 -0
- package/components/topic-steering-workspace.tsx +78 -8
- package/components/use-blog-header-obstacles.ts +81 -0
- package/components/use-brand-fonts-ready.ts +28 -0
- package/components/use-near-viewport.ts +30 -0
- package/components/use-rhythm-overlay.ts +29 -0
- package/infra/amplify-app-shell.js +166 -27
- package/infra/amplify-app-shell.ts +180 -31
- package/infra/build-specs.js +23 -7
- package/infra/build-specs.ts +27 -10
- package/infra/site-config.js +248 -36
- package/infra/site-config.ts +313 -51
- package/lib/amplify-outputs-path.ts +5 -1
- package/lib/amplify-server-runtime.ts +36 -1
- package/lib/approved-priming-proof-reports.ts +6 -0
- package/lib/blog-feature-solver.ts +459 -0
- package/lib/blog-rhythm.ts +134 -0
- package/lib/brand-fonts-watch.ts +43 -0
- package/lib/brand-fonts.ts +112 -0
- package/lib/cached-content-repository.ts +12 -0
- package/lib/category-repository.ts +43 -93
- package/lib/content-item-lifecycle.ts +55 -0
- package/lib/content-repository.ts +3 -0
- package/lib/content-types.ts +4 -0
- package/lib/curation-client.ts +61 -0
- package/lib/edition-routes.ts +31 -29
- package/lib/graphql-content-repository.ts +56 -22
- package/lib/media-route-response.ts +45 -0
- package/lib/newspaper-layout.ts +3 -2
- package/lib/newsroom-base-path.ts +12 -3
- package/lib/newsroom-board.ts +99 -0
- package/lib/newsroom-category-drilldown.ts +3 -2
- package/lib/newsroom-forum-routes.ts +6 -4
- package/lib/newsroom-index-filters.ts +14 -10
- package/lib/newsroom-nav.ts +3 -1
- package/lib/newsroom-organizer-nav.ts +37 -0
- package/lib/newsroom-section-routing.ts +20 -0
- package/lib/oauth-redirect-priority.ts +40 -0
- package/lib/papyrus-web-locations.ts +7 -6
- package/lib/plugin-settings.ts +11 -0
- package/lib/presentation-footer.ts +3 -2
- package/lib/pretext-layout.ts +12 -3
- package/lib/priming-proof-report.ts +90 -0
- package/lib/prospectus-publication-access.ts +53 -0
- package/lib/prospectus-session.ts +196 -0
- package/lib/prospectus-sign-in-routes.ts +284 -0
- package/lib/prospectus-site-identity.ts +303 -0
- package/lib/publication-cyclotron.ts +74 -0
- package/lib/rate-limit-retry.ts +55 -0
- package/lib/reader-base-path.ts +24 -0
- package/lib/reader-cache-lifetime.ts +5 -0
- package/lib/reader-static-params.ts +85 -4
- package/lib/reader-storage-url.ts +9 -12
- package/lib/reference-policy.ts +5 -0
- package/lib/relevance-decisions.ts +103 -0
- package/lib/relevance-status.ts +63 -0
- package/lib/renderer.ts +7 -0
- package/lib/revalidate-prewarm.ts +53 -0
- package/lib/revalidate-secret.ts +59 -0
- package/lib/robots-policy.ts +14 -0
- package/lib/root-route-redirect.ts +16 -0
- package/lib/semantic-graph.ts +7 -0
- package/lib/shared-credentials-provider.ts +61 -0
- package/lib/signup-csv.ts +24 -0
- package/lib/site-brand.ts +59 -0
- package/lib/staging-gated-path.ts +23 -0
- package/lib/staging-preview-object.ts +21 -5
- package/lib/test-editor-override.ts +4 -0
- package/lib/video-loading.ts +22 -0
- package/lib/video-script.ts +14 -0
- package/middleware.ts +11 -19
- package/package.json +73 -8
- package/renderers/pretext/article-page.tsx +39 -3
- package/renderers/pretext/presentation-shared.tsx +113 -0
- package/renderers/pretext/presentation-shell.tsx +15 -102
- package/renderers/pretext/rhythm-article-page.tsx +165 -0
- package/renderers/pretext/rhythm-blog-presentation.tsx +279 -0
- package/renderers/pretext/rhythm-shell-style.ts +35 -0
- package/routes.manifest.json +123 -12
- package/src/sync.mjs +30 -6
- package/src/with-papyrus.d.mts +9 -0
- package/src/with-papyrus.mjs +48 -3
- package/amplify/functions/graphql-jwt-authorizer/handler.ts +0 -193
- package/amplify/functions/graphql-jwt-authorizer/resource.js +0 -14
- package/amplify/functions/graphql-jwt-authorizer/resource.ts +0 -15
- package/components/ai-elements/message.tsx +0 -360
|
@@ -2,8 +2,13 @@ import { notFound, redirect } from "next/navigation";
|
|
|
2
2
|
import { EditionRoutePage } from "../../edition-route-page";
|
|
3
3
|
import { createSectionKey } from "../../../../../../lib/edition-sections";
|
|
4
4
|
import { parseEditionSectionRoute } from "../../../../../../lib/edition-routes";
|
|
5
|
+
import { generateEditionSectionStaticParams } from "../../../../../../lib/reader-static-params";
|
|
5
6
|
// Keep in sync with READER_REVALIDATE_SECONDS in lib/reader-route-config.ts
|
|
6
|
-
export const revalidate =
|
|
7
|
+
export const revalidate = 60;
|
|
8
|
+
|
|
9
|
+
export async function generateStaticParams() {
|
|
10
|
+
return generateEditionSectionStaticParams();
|
|
11
|
+
}
|
|
7
12
|
|
|
8
13
|
type EditionSectionRouteProps = {
|
|
9
14
|
params: Promise<{
|
|
@@ -3,7 +3,7 @@ import { loadArchiveEditionPreviews, clampArchiveLimit } from "../../../../lib/a
|
|
|
3
3
|
import { ARCHIVE_BATCH_SIZE } from "../../../../lib/archive-types";
|
|
4
4
|
|
|
5
5
|
// Keep in sync with READER_REVALIDATE_SECONDS in lib/reader-route-config.ts
|
|
6
|
-
export const revalidate =
|
|
6
|
+
export const revalidate = 60;
|
|
7
7
|
|
|
8
8
|
export async function GET(request: Request) {
|
|
9
9
|
const url = new URL(request.url);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { handleProspectusSignInCallback } from "../../../../../lib/prospectus-sign-in-routes";
|
|
3
|
+
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
export const runtime = "nodejs";
|
|
6
|
+
|
|
7
|
+
export function GET(request: NextRequest) {
|
|
8
|
+
return handleProspectusSignInCallback(request);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { handleProspectusAccountSelection } from "../../../../../lib/prospectus-sign-in-routes";
|
|
3
|
+
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
export const runtime = "nodejs";
|
|
6
|
+
|
|
7
|
+
export function POST(request: NextRequest) {
|
|
8
|
+
return handleProspectusAccountSelection(request);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { handleProspectusSessionRead } from "../../../../../lib/prospectus-sign-in-routes";
|
|
3
|
+
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
export const runtime = "nodejs";
|
|
6
|
+
|
|
7
|
+
export function GET(request: NextRequest) {
|
|
8
|
+
return handleProspectusSessionRead(request);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { handleProspectusSignInStart } from "../../../../../lib/prospectus-sign-in-routes";
|
|
3
|
+
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
export const runtime = "nodejs";
|
|
6
|
+
|
|
7
|
+
export function GET(request: NextRequest) {
|
|
8
|
+
return handleProspectusSignInStart(request);
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { handleProspectusSignOut } from "../../../../../lib/prospectus-sign-in-routes";
|
|
3
|
+
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
export const runtime = "nodejs";
|
|
6
|
+
|
|
7
|
+
export function POST(request: NextRequest) {
|
|
8
|
+
return handleProspectusSignOut(request);
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { approvedPrimingProofReport } from "../../../../lib/priming-proof-report";
|
|
3
|
+
import { SITE_BRAND } from "../../../../lib/site-brand";
|
|
4
|
+
|
|
5
|
+
export function GET() {
|
|
6
|
+
const report = approvedPrimingProofReport(SITE_BRAND.id);
|
|
7
|
+
if (report === null) {
|
|
8
|
+
return NextResponse.json({ error: "No approved priming proof report for this publication yet." }, { status: 404 });
|
|
9
|
+
}
|
|
10
|
+
return NextResponse.json(report);
|
|
11
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
+
import { buildMediaRouteResponse } from "../../../../lib/media-route-response";
|
|
2
3
|
import { isGuestReadableStoragePath, signStorageUrl } from "../../../../lib/reader-storage-url";
|
|
3
4
|
|
|
4
5
|
export const dynamic = "force-dynamic";
|
|
@@ -16,20 +17,8 @@ export async function GET(_request: Request, context: MediaRouteContext) {
|
|
|
16
17
|
return NextResponse.json({ error: "Forbidden storage path." }, { status: 403 });
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{ error: `Upstream media fetch failed (${upstream.status}).` },
|
|
24
|
-
{ status: upstream.status === 404 ? 404 : 502 },
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const headers = new Headers();
|
|
29
|
-
const contentType = upstream.headers.get("content-type");
|
|
30
|
-
if (contentType) {
|
|
31
|
-
headers.set("content-type", contentType);
|
|
32
|
-
}
|
|
33
|
-
headers.set("cache-control", "public, max-age=3600, stale-while-revalidate=86400");
|
|
34
|
-
return new NextResponse(upstream.body, { status: 200, headers });
|
|
20
|
+
return buildMediaRouteResponse(storagePath, {
|
|
21
|
+
signStorageUrl,
|
|
22
|
+
fetchUpstream: (signedUrl) => fetch(signedUrl, { cache: "no-store" }),
|
|
23
|
+
});
|
|
35
24
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toPublicReaderPath } from "../../../lib/reader-base-path";
|
|
1
2
|
import { revalidatePath, revalidateTag } from "next/cache";
|
|
2
3
|
import { NextResponse } from "next/server";
|
|
3
4
|
import {
|
|
@@ -8,6 +9,8 @@ import {
|
|
|
8
9
|
editionContentCacheTag,
|
|
9
10
|
editionItemCacheTag,
|
|
10
11
|
} from "../../../lib/cached-content-repository";
|
|
12
|
+
import { isAuthorizedRevalidateRequest } from "../../../lib/revalidate-secret";
|
|
13
|
+
import { prewarmPaths, resolvePrewarmOrigin } from "../../../lib/revalidate-prewarm";
|
|
11
14
|
import { getEditionArticlePath, getEditionDatePath } from "../../../lib/edition-routes";
|
|
12
15
|
|
|
13
16
|
export const dynamic = "force-dynamic";
|
|
@@ -18,12 +21,12 @@ type RevalidateRequestBody = {
|
|
|
18
21
|
itemSlugs?: string[];
|
|
19
22
|
paths?: string[];
|
|
20
23
|
tags?: string[];
|
|
24
|
+
prewarm?: boolean;
|
|
21
25
|
};
|
|
22
26
|
|
|
23
27
|
export async function POST(request: Request) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
if (!configuredSecret || providedSecret !== configuredSecret) {
|
|
28
|
+
const providedSecret = request.headers.get("x-papyrus-revalidate-secret");
|
|
29
|
+
if (!(await isAuthorizedRevalidateRequest(providedSecret))) {
|
|
27
30
|
return NextResponse.json({ ok: false, error: "Unauthorized." }, { status: 401 });
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -44,8 +47,8 @@ export async function POST(request: Request) {
|
|
|
44
47
|
if (!normalized) continue;
|
|
45
48
|
revalidateTag(articleCacheTag(normalized));
|
|
46
49
|
revalidatedTags.add(articleCacheTag(normalized));
|
|
47
|
-
revalidatePath(`/articles/${encodeURIComponent(normalized)}`);
|
|
48
|
-
revalidatedPaths.add(`/articles/${encodeURIComponent(normalized)}`);
|
|
50
|
+
revalidatePath(toPublicReaderPath(`/articles/${encodeURIComponent(normalized)}`));
|
|
51
|
+
revalidatedPaths.add(toPublicReaderPath(`/articles/${encodeURIComponent(normalized)}`));
|
|
49
52
|
if (editionDate) {
|
|
50
53
|
revalidateTag(editionItemCacheTag(editionDate, normalized));
|
|
51
54
|
revalidatedTags.add(editionItemCacheTag(editionDate, normalized));
|
|
@@ -76,8 +79,8 @@ export async function POST(request: Request) {
|
|
|
76
79
|
revalidatedTags.add(ARCHIVE_CACHE_TAG);
|
|
77
80
|
revalidateTag(ARTICLES_CACHE_TAG);
|
|
78
81
|
revalidatedTags.add(ARTICLES_CACHE_TAG);
|
|
79
|
-
revalidatePath("/archive");
|
|
80
|
-
revalidatedPaths.add("/archive");
|
|
82
|
+
revalidatePath(toPublicReaderPath("/archive"));
|
|
83
|
+
revalidatedPaths.add(toPublicReaderPath("/archive"));
|
|
81
84
|
|
|
82
85
|
for (const path of body.paths ?? []) {
|
|
83
86
|
const normalized = path.trim();
|
|
@@ -86,9 +89,14 @@ export async function POST(request: Request) {
|
|
|
86
89
|
revalidatedPaths.add(normalized);
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
const prewarmed = body.prewarm === false
|
|
93
|
+
? []
|
|
94
|
+
: await prewarmPaths(resolvePrewarmOrigin(request.url), [...revalidatedPaths]);
|
|
95
|
+
|
|
89
96
|
return NextResponse.json({
|
|
90
97
|
ok: true,
|
|
91
98
|
revalidatedTags: [...revalidatedTags],
|
|
92
99
|
revalidatedPaths: [...revalidatedPaths],
|
|
100
|
+
prewarmed,
|
|
93
101
|
});
|
|
94
102
|
}
|
package/app/archive/page.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { loadArchiveEditionPreviews } from "../../lib/archive-data";
|
|
|
4
4
|
import { ARCHIVE_BATCH_SIZE } from "../../lib/archive-types";
|
|
5
5
|
|
|
6
6
|
// Keep in sync with READER_REVALIDATE_SECONDS in lib/reader-route-config.ts
|
|
7
|
-
export const revalidate =
|
|
7
|
+
export const revalidate = 60;
|
|
8
8
|
|
|
9
9
|
export default async function ArchivePage() {
|
|
10
10
|
const initialBatch = await loadArchiveEditionPreviews({ limit: ARCHIVE_BATCH_SIZE });
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { notFound } from "next/navigation";
|
|
2
2
|
import { getSiteRenderer } from "../../../lib/site-renderer";
|
|
3
|
-
import { getCachedArticle } from "../../../lib/cached-content-repository";
|
|
4
|
-
import { generateArticleStaticParams } from "../../../lib/reader-static-params";
|
|
3
|
+
import { getCachedArticle, getCachedVideoScript } from "../../../lib/cached-content-repository";
|
|
4
|
+
import { generateArticleStaticParams, siteServesNextReaderRoutes } from "../../../lib/reader-static-params";
|
|
5
5
|
import { SITE_BRAND } from "../../../lib/site-brand";
|
|
6
6
|
|
|
7
7
|
// Keep in sync with READER_REVALIDATE_SECONDS in lib/reader-route-config.ts
|
|
8
|
-
export const revalidate =
|
|
8
|
+
export const revalidate = 60;
|
|
9
9
|
|
|
10
10
|
export async function generateStaticParams() {
|
|
11
11
|
return generateArticleStaticParams();
|
|
@@ -16,6 +16,7 @@ type ArticlePageProps = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export async function generateMetadata({ params }: ArticlePageProps) {
|
|
19
|
+
if (!siteServesNextReaderRoutes()) return {};
|
|
19
20
|
const { slug } = await params;
|
|
20
21
|
const article = await getCachedArticle(slug);
|
|
21
22
|
if (!article) return {};
|
|
@@ -26,10 +27,11 @@ export async function generateMetadata({ params }: ArticlePageProps) {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export default async function ArticlePage({ params }: ArticlePageProps) {
|
|
30
|
+
if (!siteServesNextReaderRoutes()) notFound();
|
|
29
31
|
const { slug } = await params;
|
|
30
|
-
const article = await getCachedArticle(slug);
|
|
32
|
+
const [article, videoScript] = await Promise.all([getCachedArticle(slug), getCachedVideoScript(slug)]);
|
|
31
33
|
if (!article) notFound();
|
|
32
34
|
|
|
33
35
|
const siteRenderer = getSiteRenderer();
|
|
34
|
-
return <siteRenderer.renderArticle article={article} backHref="/" />;
|
|
36
|
+
return <siteRenderer.renderArticle article={article} videoScript={videoScript} backHref="/" />;
|
|
35
37
|
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Structural CSS for the rhythm blog layout (blogLayout: "rhythm").
|
|
3
|
+
Every rule is scoped to .blog-rhythm-shell, which only the rhythm layout
|
|
4
|
+
renders, so classic layouts are unaffected. The shell sets --blog-rhythm,
|
|
5
|
+
--blog-row-height, --blog-paint-buffer and --blog-paint-height inline.
|
|
6
|
+
Typography, colors and the header look belong to the publication's theme.css.
|
|
7
|
+
Optional tokens a publication may set:
|
|
8
|
+
--blog-hrule-foreground, --blog-section-rule, --blog-section-band-height,
|
|
9
|
+
--blog-page-padding-x, --blog-secondary-pair-min-width.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
.blog-rhythm-shell {
|
|
13
|
+
--blog-hrule-foreground: var(--border);
|
|
14
|
+
--blog-section-rule: var(--border);
|
|
15
|
+
--blog-section-band-height: calc(var(--blog-row-height) * 2);
|
|
16
|
+
--blog-page-padding-x: calc(var(--blog-rhythm) * 3);
|
|
17
|
+
--paper-rhythm: var(--blog-row-height);
|
|
18
|
+
|
|
19
|
+
isolation: isolate;
|
|
20
|
+
position: relative;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.blog-rhythm-shell.presentation-page--blog {
|
|
24
|
+
padding: calc(var(--blog-row-height) * 4) var(--blog-page-padding-x) 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.blog-rhythm-shell > :not(.blog-page-background) {
|
|
28
|
+
position: relative;
|
|
29
|
+
z-index: 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.blog-rhythm-shell[data-rhythm-overlay="true"]::before {
|
|
33
|
+
background-image:
|
|
34
|
+
repeating-linear-gradient(
|
|
35
|
+
to bottom,
|
|
36
|
+
rgb(var(--rhythm-overlay-rule-rgb) / var(--rhythm-overlay-rule-alpha)) 0,
|
|
37
|
+
rgb(var(--rhythm-overlay-rule-rgb) / var(--rhythm-overlay-rule-alpha)) 1px,
|
|
38
|
+
transparent 1px,
|
|
39
|
+
transparent var(--blog-row-height)
|
|
40
|
+
),
|
|
41
|
+
repeating-linear-gradient(
|
|
42
|
+
to bottom,
|
|
43
|
+
rgb(var(--rhythm-overlay-blue-rgb) / var(--rhythm-overlay-blue-alpha)) 0,
|
|
44
|
+
rgb(var(--rhythm-overlay-blue-rgb) / var(--rhythm-overlay-blue-alpha)) var(--blog-row-height),
|
|
45
|
+
rgb(var(--rhythm-overlay-yellow-rgb) / var(--rhythm-overlay-yellow-alpha)) var(--blog-row-height),
|
|
46
|
+
rgb(var(--rhythm-overlay-yellow-rgb) / var(--rhythm-overlay-yellow-alpha)) calc(var(--blog-row-height) * 2)
|
|
47
|
+
);
|
|
48
|
+
content: "";
|
|
49
|
+
inset: 0;
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
position: absolute;
|
|
52
|
+
z-index: 900;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.blog-rhythm-shell .presentation-header {
|
|
56
|
+
max-width: 100%;
|
|
57
|
+
min-width: 0;
|
|
58
|
+
width: 100%;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.blog-rhythm-shell .presentation-section-header,
|
|
62
|
+
.blog-rhythm-shell .presentation-item,
|
|
63
|
+
.blog-rhythm-shell .presentation-item__copy {
|
|
64
|
+
max-width: 100%;
|
|
65
|
+
min-width: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.blog-rhythm-shell .presentation-section-header {
|
|
69
|
+
align-items: stretch;
|
|
70
|
+
border-bottom: 0;
|
|
71
|
+
border-top: 0;
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
gap: var(--blog-row-height);
|
|
75
|
+
margin: 0;
|
|
76
|
+
min-height: 0;
|
|
77
|
+
padding: calc(var(--blog-row-height) * 4) 0 calc(var(--blog-row-height) * 2);
|
|
78
|
+
width: 100%;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.blog-rhythm-shell .presentation-section-header__band {
|
|
82
|
+
align-items: center;
|
|
83
|
+
display: grid;
|
|
84
|
+
gap: 0 var(--blog-rhythm);
|
|
85
|
+
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
|
86
|
+
grid-template-rows: var(--blog-section-band-height);
|
|
87
|
+
width: 100%;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.blog-rhythm-shell .presentation-section-header__band::before,
|
|
91
|
+
.blog-rhythm-shell .presentation-section-header__band::after {
|
|
92
|
+
background: var(--blog-section-rule);
|
|
93
|
+
content: "";
|
|
94
|
+
grid-row: 1;
|
|
95
|
+
height: var(--blog-section-band-height);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.blog-rhythm-shell .presentation-section-header__band::before {
|
|
99
|
+
grid-column: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.blog-rhythm-shell .presentation-section-header__band::after {
|
|
103
|
+
grid-column: 3;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.blog-rhythm-shell .presentation-section-header__band p {
|
|
107
|
+
grid-column: 2;
|
|
108
|
+
grid-row: 1;
|
|
109
|
+
height: var(--blog-section-band-height);
|
|
110
|
+
justify-self: center;
|
|
111
|
+
line-height: var(--blog-section-band-height);
|
|
112
|
+
margin: 0;
|
|
113
|
+
padding: 0 var(--blog-rhythm);
|
|
114
|
+
width: max-content;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.blog-rhythm-shell .presentation-item {
|
|
118
|
+
border-bottom: 0;
|
|
119
|
+
gap: var(--blog-row-height) calc(var(--blog-rhythm) * 4);
|
|
120
|
+
padding-bottom: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.blog-rhythm-shell .presentation-item--blog {
|
|
124
|
+
grid-template-columns: minmax(0, 1fr);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.blog-rhythm-shell .presentation-rhythm-hrule {
|
|
128
|
+
display: grid;
|
|
129
|
+
grid-column: 1 / -1;
|
|
130
|
+
grid-template-rows: repeat(5, var(--blog-row-height));
|
|
131
|
+
height: calc(var(--blog-row-height) * 5);
|
|
132
|
+
width: 100%;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.blog-rhythm-shell .presentation-rhythm-hrule__line {
|
|
136
|
+
background: var(--blog-hrule-foreground);
|
|
137
|
+
grid-row: 3;
|
|
138
|
+
height: var(--blog-row-height);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (min-width: 1100px) {
|
|
142
|
+
.blog-rhythm-shell .blog-section:has(> .presentation-item[data-item-index="2"]) {
|
|
143
|
+
column-gap: calc(var(--blog-row-height) * 2);
|
|
144
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.blog-rhythm-shell .blog-section:has(> .presentation-item[data-item-index="2"]) > .presentation-section-header,
|
|
148
|
+
.blog-rhythm-shell .blog-section:has(> .presentation-item[data-item-index="2"]) > .presentation-item[data-item-index="0"] {
|
|
149
|
+
grid-column: 1 / -1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.blog-rhythm-shell .blog-section:has(> .presentation-item[data-item-index="2"]) > .presentation-rhythm-hrule[data-hide-in-secondary-pair="true"] {
|
|
153
|
+
display: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.blog-rhythm-shell .presentation-item[data-feature-layout][data-has-image="true"] {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
gap: 0;
|
|
161
|
+
grid-template-columns: minmax(0, 1fr);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.blog-rhythm-shell .presentation-item[data-feature-layout] .presentation-item__text-frame {
|
|
165
|
+
height: var(--feature-text-frame-height);
|
|
166
|
+
max-width: none;
|
|
167
|
+
overflow: hidden;
|
|
168
|
+
position: relative;
|
|
169
|
+
width: 100%;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.blog-rhythm-shell .presentation-item[data-feature-layout] .presentation-item__media {
|
|
173
|
+
height: var(--feature-media-height);
|
|
174
|
+
width: var(--feature-image-width);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.blog-rhythm-shell .presentation-item[data-feature-layout] .pictogram-figure__frame {
|
|
178
|
+
aspect-ratio: auto;
|
|
179
|
+
height: var(--feature-image-height);
|
|
180
|
+
width: var(--feature-image-width);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.blog-rhythm-shell .presentation-item--blog[data-feature-layout][data-has-image="true"] .presentation-item__copy {
|
|
184
|
+
display: contents;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.blog-rhythm-shell .presentation-item--blog[data-feature-layout][data-has-image="true"] .presentation-item__header {
|
|
188
|
+
width: 100%;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.blog-rhythm-shell .presentation-item--blog[data-feature-layout][data-has-image="true"] .presentation-item__body {
|
|
192
|
+
min-width: 0;
|
|
193
|
+
position: relative;
|
|
194
|
+
width: 100%;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.blog-rhythm-shell .presentation-item--blog[data-feature-layout][data-has-image="true"] .presentation-item__body .presentation-item__text-frame {
|
|
198
|
+
margin-top: 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.blog-rhythm-shell .presentation-item--blog[data-feature-layout][data-has-image="true"] .presentation-item__media {
|
|
202
|
+
margin: 0;
|
|
203
|
+
position: absolute;
|
|
204
|
+
right: 0;
|
|
205
|
+
top: 0;
|
|
206
|
+
z-index: 1;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.blog-rhythm-shell .presentation-item__image img {
|
|
210
|
+
height: 100%;
|
|
211
|
+
object-fit: contain;
|
|
212
|
+
width: 100%;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.blog-rhythm-shell .presentation-item__video {
|
|
216
|
+
grid-column: 1 / -1;
|
|
217
|
+
margin: var(--blog-row-height) 0 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.blog-rhythm-shell .article-page__hero-video {
|
|
221
|
+
margin: 0 0 calc(var(--blog-rhythm) * 5);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.blog-rhythm-shell .article-page__hero-video .article-video,
|
|
225
|
+
.blog-rhythm-shell .presentation-item__video-figure {
|
|
226
|
+
container-type: inline-size;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.blog-rhythm-shell .presentation-item__video-figure .article-video__media,
|
|
230
|
+
.blog-rhythm-shell .article-page__hero-video .article-video__media {
|
|
231
|
+
height: round(up, calc(100cqw * 9 / 16), var(--blog-row-height));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout][data-has-image="true"] {
|
|
235
|
+
display: grid;
|
|
236
|
+
gap: var(--feature-layout-gap);
|
|
237
|
+
grid-template-columns: minmax(0, 1fr) var(--feature-image-width);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .article-page__hero-video,
|
|
241
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .article-float-grid__header {
|
|
242
|
+
grid-column: 1 / -1;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .article-float-grid__body {
|
|
246
|
+
align-self: start;
|
|
247
|
+
grid-column: 1;
|
|
248
|
+
max-width: var(--feature-copy-width);
|
|
249
|
+
min-width: 0;
|
|
250
|
+
width: var(--feature-copy-width);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .article-float-grid__media,
|
|
254
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .pictogram-figure__frame {
|
|
255
|
+
height: var(--feature-image-height);
|
|
256
|
+
width: var(--feature-image-width);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .pictogram-figure__frame {
|
|
260
|
+
aspect-ratio: auto;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.blog-rhythm-shell .article-float-grid[data-feature-layout] .article-float-grid__media {
|
|
264
|
+
align-self: start;
|
|
265
|
+
grid-column: 2;
|
|
266
|
+
margin: 0;
|
|
267
|
+
position: relative;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.blog-rhythm-shell .article-float-grid .presentation-item__image {
|
|
271
|
+
margin: 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@media (max-width: 900px) {
|
|
275
|
+
.blog-rhythm-shell .presentation-item--blog {
|
|
276
|
+
grid-template-columns: 1fr;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { PrimingProofPage } from "../../components/priming-proof-page";
|
|
3
|
+
import { approvedPrimingProofReport } from "../../lib/priming-proof-report";
|
|
4
|
+
import { SITE_BRAND } from "../../lib/site-brand";
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: `Cyclotron proof | ${SITE_BRAND.articleTitleSuffix}`,
|
|
8
|
+
description: "How often the relevance classifier agrees with editors on a fixed held-out set, before and after editor labels.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function CyclotronProof() {
|
|
12
|
+
return <PrimingProofPage report={approvedPrimingProofReport(SITE_BRAND.id)} />;
|
|
13
|
+
}
|
package/app/globals.css
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
--color-surface-foreground: var(--surface-foreground);
|
|
46
46
|
--color-foreground-strong: var(--foreground-strong);
|
|
47
47
|
--color-foreground-muted: var(--foreground-muted);
|
|
48
|
+
--color-foreground-subtle: var(--foreground-subtle);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
:root {
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
--surface-foreground: var(--card-foreground);
|
|
72
73
|
--foreground-strong: var(--slate-12);
|
|
73
74
|
--foreground-muted: var(--slate-10);
|
|
75
|
+
--foreground-subtle: var(--slate-9);
|
|
74
76
|
--border: var(--slate-6);
|
|
75
77
|
--input: var(--slate-6);
|
|
76
78
|
--ring: var(--slate-8);
|
package/app/layout.tsx
CHANGED
|
@@ -4,12 +4,14 @@ import Script from "next/script";
|
|
|
4
4
|
import { AmplifyClientProvider } from "../components/amplify-client-provider";
|
|
5
5
|
import { PapyrusConsoleShell } from "../components/papyrus-console-shell";
|
|
6
6
|
import { TooltipProvider } from "../components/ui/tooltip";
|
|
7
|
+
import { resolveBrandFontAssets } from "../lib/brand-fonts";
|
|
7
8
|
import { getPresentationChoices, getSiteBrand } from "../lib/site-brand";
|
|
8
9
|
import { getSiteStack } from "../lib/site-stack";
|
|
9
10
|
import { isIndexable, showStagingBanner } from "../lib/site-env";
|
|
10
11
|
import { StagingBanner } from "../components/staging-banner";
|
|
11
12
|
import "./tailwind.css";
|
|
12
13
|
import "./globals.css";
|
|
14
|
+
import "./blog-rhythm.css";
|
|
13
15
|
import "papyrus-site-theme";
|
|
14
16
|
|
|
15
17
|
const playfairDisplay = Playfair_Display({
|
|
@@ -43,6 +45,7 @@ export default async function RootLayout({ children }: Readonly<{ children: Reac
|
|
|
43
45
|
const siteBrand = getSiteBrand();
|
|
44
46
|
const presentationChoices = getPresentationChoices(siteBrand);
|
|
45
47
|
const siteStack = getSiteStack(siteBrand);
|
|
48
|
+
const brandFonts = resolveBrandFontAssets(siteBrand.fonts);
|
|
46
49
|
|
|
47
50
|
return (
|
|
48
51
|
<html
|
|
@@ -56,8 +59,21 @@ export default async function RootLayout({ children }: Readonly<{ children: Reac
|
|
|
56
59
|
data-default-presentation={siteBrand.defaultPresentation}
|
|
57
60
|
data-presentation-choices={presentationChoices.join(",")}
|
|
58
61
|
{...(siteBrand.forcedPresentation ? { "data-forced-presentation": siteBrand.forcedPresentation } : {})}
|
|
62
|
+
{...(siteBrand.blogLayout === "rhythm" ? { "data-blog-layout": "rhythm" } : {})}
|
|
63
|
+
{...(brandFonts.isEmpty ? {} : { style: brandFonts.rootStyle as React.CSSProperties })}
|
|
59
64
|
suppressHydrationWarning
|
|
60
65
|
>
|
|
66
|
+
{brandFonts.isEmpty ? null : (
|
|
67
|
+
<head>
|
|
68
|
+
{brandFonts.preconnectOrigins.map((origin) => (
|
|
69
|
+
<link crossOrigin="anonymous" href={origin} key={origin} rel="preconnect" />
|
|
70
|
+
))}
|
|
71
|
+
{brandFonts.stylesheetHrefs.map((href) => (
|
|
72
|
+
<link href={href} key={href} rel="stylesheet" />
|
|
73
|
+
))}
|
|
74
|
+
{brandFonts.fontFaceCss ? <style data-brand-fonts="true">{brandFonts.fontFaceCss}</style> : null}
|
|
75
|
+
</head>
|
|
76
|
+
)}
|
|
61
77
|
<body className={`${playfairDisplay.variable} ${plusJakartaSans.variable}`}>
|
|
62
78
|
<Script id="papyrus-favicon-color-scheme" strategy="beforeInteractive">
|
|
63
79
|
{`(() => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { resolveActiveSiteBrand } from "../../../../lib/site-brand-tenant";
|
|
1
2
|
import { notFound, redirect } from "next/navigation";
|
|
3
|
+
import { toPublicNewsroomPath } from "../../../../lib/newsroom-base-path";
|
|
2
4
|
import { NewsDeskPage } from "../../../../components/news-desk-page";
|
|
3
5
|
import type { NewsDeskTab } from "../../../../components/topic-steering-workspace";
|
|
4
6
|
|
|
@@ -26,6 +28,7 @@ type NewsDeskNestedSectionPageProps = {
|
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
const NEWS_DESK_ROUTE_SECTIONS = new Set<NewsDeskTab>([
|
|
31
|
+
"desks",
|
|
29
32
|
"administration",
|
|
30
33
|
"topics",
|
|
31
34
|
"concepts",
|
|
@@ -37,13 +40,13 @@ const NEWS_DESK_ROUTE_SECTIONS = new Set<NewsDeskTab>([
|
|
|
37
40
|
|
|
38
41
|
export default async function NewsDeskNestedSectionPage({ params, searchParams }: NewsDeskNestedSectionPageProps) {
|
|
39
42
|
const { section, selection } = await params;
|
|
40
|
-
if (section === "users") redirect("/newsroom/administration/users");
|
|
41
|
-
if (section === "doctrine") redirect("/newsroom/administration/policies");
|
|
42
|
-
if (section === "administration" && selection[0] === "analysis") redirect("/newsroom/assignments");
|
|
43
|
-
if (section === "desks") {
|
|
43
|
+
if (section === "users") redirect(toPublicNewsroomPath("/newsroom/administration/users"));
|
|
44
|
+
if (section === "doctrine") redirect(toPublicNewsroomPath("/newsroom/administration/policies"));
|
|
45
|
+
if (section === "administration" && selection[0] === "analysis") redirect(toPublicNewsroomPath("/newsroom/assignments"));
|
|
46
|
+
if (section === "desks" && resolveActiveSiteBrand().newsroomLayout !== "organizer") {
|
|
44
47
|
const category = selection[0] ? decodeURIComponent(selection[0]) : null;
|
|
45
|
-
if (category) redirect(`/newsroom/topics?category=${encodeURIComponent(category)}`);
|
|
46
|
-
redirect("/newsroom/topics");
|
|
48
|
+
if (category) redirect(toPublicNewsroomPath(`/newsroom/topics?category=${encodeURIComponent(category)}`));
|
|
49
|
+
redirect(toPublicNewsroomPath("/newsroom/topics"));
|
|
47
50
|
}
|
|
48
51
|
if (!NEWS_DESK_ROUTE_SECTIONS.has(section as NewsDeskTab)) notFound();
|
|
49
52
|
return <NewsDeskPage section={section} selectionPath={selection} searchParams={searchParams} />;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { resolveActiveSiteBrand } from "../../../lib/site-brand-tenant";
|
|
1
2
|
import { notFound, redirect } from "next/navigation";
|
|
3
|
+
import { toPublicNewsroomPath } from "../../../lib/newsroom-base-path";
|
|
2
4
|
import { NewsDeskPage } from "../../../components/news-desk-page";
|
|
3
5
|
import type { NewsDeskTab } from "../../../components/topic-steering-workspace";
|
|
4
6
|
|
|
@@ -27,6 +29,7 @@ type NewsDeskSectionPageProps = {
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
const NEWS_DESK_ROUTE_SECTIONS = new Set<NewsDeskTab>([
|
|
32
|
+
"desks",
|
|
30
33
|
"administration",
|
|
31
34
|
"topics",
|
|
32
35
|
"concepts",
|
|
@@ -39,9 +42,9 @@ const NEWS_DESK_ROUTE_SECTIONS = new Set<NewsDeskTab>([
|
|
|
39
42
|
|
|
40
43
|
export default async function NewsDeskSectionPage({ params, searchParams }: NewsDeskSectionPageProps) {
|
|
41
44
|
const { section } = await params;
|
|
42
|
-
if (section === "users") redirect("/newsroom/administration/users");
|
|
43
|
-
if (section === "doctrine") redirect("/newsroom/administration/policies");
|
|
44
|
-
if (section === "desks") redirect("/newsroom/topics");
|
|
45
|
+
if (section === "users") redirect(toPublicNewsroomPath("/newsroom/administration/users"));
|
|
46
|
+
if (section === "doctrine") redirect(toPublicNewsroomPath("/newsroom/administration/policies"));
|
|
47
|
+
if (section === "desks" && resolveActiveSiteBrand().newsroomLayout !== "organizer") redirect(toPublicNewsroomPath("/newsroom/topics"));
|
|
45
48
|
if (!NEWS_DESK_ROUTE_SECTIONS.has(section as NewsDeskTab)) notFound();
|
|
46
49
|
return <NewsDeskPage section={section} searchParams={searchParams} />;
|
|
47
50
|
}
|