@anthusai/papyrus 1.2.0 → 1.4.0-next.1
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/functions/model-attachment-upload/handler.ts +1 -0
- package/app/newsroom/[section]/page.tsx +6 -0
- package/app/newsroom/articles/page.tsx +3 -0
- package/components/news-desk-client-provider.tsx +17 -2
- package/components/news-desk-taxonomy-client.ts +133 -2
- package/components/newspaper.tsx +4 -4
- package/components/newsroom-board-view.tsx +74 -50
- package/components/newsroom-client-shell.tsx +8 -1
- package/components/newsroom-organizer-shell.tsx +12 -7
- package/components/newsroom-organizer.css +4 -3
- package/components/newsroom-references-view.tsx +18 -0
- package/components/reference-cyclotron-priming.tsx +85 -0
- package/components/topic-steering-workspace.tsx +35 -1
- package/lib/article-flow.ts +95 -0
- package/lib/article-frame-solver.ts +519 -0
- package/lib/chrome-text.ts +504 -0
- package/lib/content-item-lifecycle.ts +25 -26
- package/lib/front-mosaic.ts +1132 -0
- package/lib/furniture.ts +385 -0
- package/lib/labels.ts +37 -0
- package/lib/layout-config.ts +237 -0
- package/lib/layout-plan.ts +37 -9
- package/lib/layout-scenarios.ts +21 -11
- package/lib/layout-types.ts +457 -0
- package/lib/local-preview-seed.ts +97 -0
- package/lib/local-preview.ts +3 -0
- package/lib/newspaper-layout.ts +17 -3410
- package/lib/newsroom-board.ts +63 -62
- package/lib/newsroom-organizer-nav.ts +3 -4
- package/lib/pretext-layout.ts +22 -0
- package/lib/relevance-status.ts +73 -0
- package/lib/site-brand.ts +15 -1
- package/lib/text-columns.ts +251 -0
- package/package.json +13 -2
- package/renderers/pretext/presentation-shell.tsx +1 -1
- package/routes.manifest.json +1 -9
- package/app/newsroom/work/page.tsx +0 -10
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { AssignmentRecord, ReferenceRecord } from "./category-repository";
|
|
2
|
+
import { contentItemStageKeys, type ContentItemVersionRecord } from "./content-item-lifecycle";
|
|
3
|
+
import { getContentItemStageDefinitions } from "./site-brand";
|
|
4
|
+
|
|
5
|
+
const SEED_TIMESTAMP_BASE = Date.parse("2026-10-01T12:00:00.000Z");
|
|
6
|
+
const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000;
|
|
7
|
+
|
|
8
|
+
const SEED_CONTENT_ITEM_HEADLINES_BY_POSITION: readonly (readonly string[])[] = [
|
|
9
|
+
["Readers ask what the newsroom should chase next", "A tip from the field: harbor dredging schedule"],
|
|
10
|
+
["City council budget vote draws a crowd", "Interview request: regional transit director"],
|
|
11
|
+
["Mapping every permit filed since January", "What the county audit left out"],
|
|
12
|
+
["Three sources confirm the zoning reversal", "Reporting packet: school board redistricting"],
|
|
13
|
+
["Editor shortlist: the week's lead candidates", "Editor shortlist: the weekend long read"],
|
|
14
|
+
["Draft in progress: the last ferry crossing", "Draft in progress: neighborhood bakery profile"],
|
|
15
|
+
["Illustration brief: flooded streets, aerial view", "Illustration brief: the market at dawn"],
|
|
16
|
+
["Layout pass: front page lead and rail", "Layout pass: the Saturday supplement"],
|
|
17
|
+
["Published: harbor safety review", "Published: the lighthouse keepers' archive"],
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
function isoTimestampHoursBeforeBase(hours: number): string {
|
|
21
|
+
return new Date(SEED_TIMESTAMP_BASE - hours * ONE_HOUR_IN_MILLISECONDS).toISOString();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function slugFromHeadline(headline: string): string {
|
|
25
|
+
return headline.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function createLocalPreviewContentItemVersions(): ContentItemVersionRecord[] {
|
|
29
|
+
const stageKeys = contentItemStageKeys(getContentItemStageDefinitions());
|
|
30
|
+
return stageKeys.flatMap((stageKey, stageIndex) => {
|
|
31
|
+
const headlines = SEED_CONTENT_ITEM_HEADLINES_BY_POSITION[stageIndex % SEED_CONTENT_ITEM_HEADLINES_BY_POSITION.length];
|
|
32
|
+
return headlines.map((headline, headlineIndex) => {
|
|
33
|
+
const slug = slugFromHeadline(headline);
|
|
34
|
+
return {
|
|
35
|
+
id: `preview-item-version-${stageKey}-${headlineIndex}`,
|
|
36
|
+
lineageId: `preview-item-lineage-${stageKey}-${headlineIndex}`,
|
|
37
|
+
versionNumber: 1,
|
|
38
|
+
stage: stageKey,
|
|
39
|
+
type: "article",
|
|
40
|
+
status: stageKey === "published" ? "published" : "draft",
|
|
41
|
+
title: headline,
|
|
42
|
+
headline,
|
|
43
|
+
slug,
|
|
44
|
+
section: headlineIndex === 0 ? "news" : "features",
|
|
45
|
+
updatedAt: isoTimestampHoursBeforeBase(stageIndex * 3 + headlineIndex),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function createLocalPreviewReferences(): ReferenceRecord[] {
|
|
52
|
+
const curationStatuses = ["pending", "accepted", "accepted", "rejected", "pending"];
|
|
53
|
+
return curationStatuses.map((curationStatus, index) => ({
|
|
54
|
+
id: `preview-reference-${index}`,
|
|
55
|
+
lineageId: `preview-reference-lineage-${index}`,
|
|
56
|
+
versionNumber: 1,
|
|
57
|
+
versionState: "current",
|
|
58
|
+
corpusId: "preview-corpus",
|
|
59
|
+
externalItemId: `preview-source-${index}`,
|
|
60
|
+
title: `Source document ${index + 1}: municipal filing excerpt`,
|
|
61
|
+
curationStatus,
|
|
62
|
+
curationStatusKey: curationStatus,
|
|
63
|
+
curationStatusReason: curationStatus === "rejected" ? "Duplicate of an earlier filing." : null,
|
|
64
|
+
importedAt: isoTimestampHoursBeforeBase(index * 5),
|
|
65
|
+
updatedAt: isoTimestampHoursBeforeBase(index * 5),
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function createLocalPreviewAssignments(): AssignmentRecord[] {
|
|
70
|
+
const contentItemVersions = createLocalPreviewContentItemVersions();
|
|
71
|
+
const assignmentTypeKeys = ["research", "reporting", "copywriting"];
|
|
72
|
+
const statuses = ["queued", "claimed", "completed"];
|
|
73
|
+
const assignmentsOnContentItems = contentItemVersions.slice(0, 9).map((version, index) => ({
|
|
74
|
+
id: `preview-assignment-${index}`,
|
|
75
|
+
assignmentTypeKey: assignmentTypeKeys[index % assignmentTypeKeys.length],
|
|
76
|
+
queueKey: assignmentTypeKeys[index % assignmentTypeKeys.length],
|
|
77
|
+
queueStatusKey: `${assignmentTypeKeys[index % assignmentTypeKeys.length]}#${statuses[index % statuses.length]}`,
|
|
78
|
+
status: statuses[index % statuses.length],
|
|
79
|
+
priority: 2,
|
|
80
|
+
title: `${assignmentTypeKeys[index % assignmentTypeKeys.length]} for: ${version.headline}`,
|
|
81
|
+
itemLineageId: version.lineageId,
|
|
82
|
+
createdAt: isoTimestampHoursBeforeBase(index * 2),
|
|
83
|
+
updatedAt: isoTimestampHoursBeforeBase(index * 2),
|
|
84
|
+
}));
|
|
85
|
+
const assignmentsWithoutContentItem = ["Pitch: community radio partnership", "Backfill the archive index"].map((title, index) => ({
|
|
86
|
+
id: `preview-assignment-standalone-${index}`,
|
|
87
|
+
assignmentTypeKey: "research",
|
|
88
|
+
queueKey: "research",
|
|
89
|
+
queueStatusKey: "research#queued",
|
|
90
|
+
status: "queued",
|
|
91
|
+
priority: 2,
|
|
92
|
+
title,
|
|
93
|
+
createdAt: isoTimestampHoursBeforeBase(index),
|
|
94
|
+
updatedAt: isoTimestampHoursBeforeBase(index),
|
|
95
|
+
}));
|
|
96
|
+
return [...assignmentsOnContentItems, ...assignmentsWithoutContentItem];
|
|
97
|
+
}
|