@anthusai/papyrus 1.19.1 → 2.0.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/app/globals.css +0 -175
- package/app/newsroom/[section]/[...selection]/page.tsx +0 -6
- package/app/newsroom/[section]/page.tsx +2 -4
- package/app/newsroom/articles/page.tsx +1 -2
- package/app/newsroom/sections/[sectionId]/page.tsx +2 -6
- package/bin/papyrus-infra.mjs +11 -2
- package/components/news-desk-page.tsx +3 -4
- package/components/newsroom-ops-shell.tsx +142 -234
- package/components/topic-steering-workspace.tsx +17 -510
- package/lib/newsroom-list-selection.ts +0 -3
- package/lib/newsroom-nav.ts +5 -8
- package/lib/newsroom-section-routing.ts +2 -4
- package/lib/site-brand.ts +1 -8
- package/package.json +2 -3
- package/routes.manifest.json +1 -1
- package/src/cdk-environment.mjs +44 -0
- package/components/newsroom-organizer-shell.tsx +0 -153
|
@@ -333,13 +333,6 @@ type NoteTarget = {
|
|
|
333
333
|
versionNumber?: number | null;
|
|
334
334
|
};
|
|
335
335
|
|
|
336
|
-
type NoteComposerControl = {
|
|
337
|
-
action: NewsroomDetailAction;
|
|
338
|
-
dialog: ReactNode;
|
|
339
|
-
error: string | null;
|
|
340
|
-
loading: boolean;
|
|
341
|
-
};
|
|
342
|
-
|
|
343
336
|
type NewsroomSearchRequest = {
|
|
344
337
|
anchor?: KnowledgeQueryAnchor | null;
|
|
345
338
|
from?: string | null;
|
|
@@ -460,17 +453,6 @@ type ReferenceQualityResponse = {
|
|
|
460
453
|
errors?: Array<{ message?: string | null } | string | null> | null;
|
|
461
454
|
};
|
|
462
455
|
|
|
463
|
-
type ReferenceNoteResponse = {
|
|
464
|
-
data?: {
|
|
465
|
-
ok?: boolean | null;
|
|
466
|
-
referenceId?: string | null;
|
|
467
|
-
messageId?: string | null;
|
|
468
|
-
relationId?: string | null;
|
|
469
|
-
status?: string | null;
|
|
470
|
-
} | null;
|
|
471
|
-
errors?: Array<{ message?: string | null } | string | null> | null;
|
|
472
|
-
};
|
|
473
|
-
|
|
474
456
|
type ReferenceCorpusMoveResponse = {
|
|
475
457
|
data?: {
|
|
476
458
|
ok?: boolean | null;
|
|
@@ -642,14 +624,12 @@ export function NewsDeskWorkspace({
|
|
|
642
624
|
dashboard,
|
|
643
625
|
initialTab = "overview",
|
|
644
626
|
initialSelection = {},
|
|
645
|
-
sectionPageId = null,
|
|
646
627
|
}: {
|
|
647
628
|
analysisProfiles?: AnalysisProfileSummary[];
|
|
648
629
|
configuredCorpora?: CategorySteeringCorpus[];
|
|
649
630
|
dashboard: CategorySteeringDashboard | null;
|
|
650
631
|
initialTab?: NewsDeskTab;
|
|
651
632
|
initialSelection?: NewsDeskSelection;
|
|
652
|
-
sectionPageId?: string | null;
|
|
653
633
|
}) {
|
|
654
634
|
const session = useOptionalNewsDeskClient();
|
|
655
635
|
const sessionDashboard = useMemo(() => {
|
|
@@ -665,7 +645,7 @@ export function NewsDeskWorkspace({
|
|
|
665
645
|
proposals: needsProposalFallback ? fallbackProposals : session.shell.dashboard.proposals,
|
|
666
646
|
};
|
|
667
647
|
}, [dashboard?.newsroomSections, dashboard?.proposals, session?.shell.dashboard]);
|
|
668
|
-
const showSectionTabs = initialTab === "overview"
|
|
648
|
+
const showSectionTabs = initialTab === "overview";
|
|
669
649
|
|
|
670
650
|
if (dashboard?.isDemo) {
|
|
671
651
|
return (
|
|
@@ -677,7 +657,6 @@ export function NewsDeskWorkspace({
|
|
|
677
657
|
editorShellReady
|
|
678
658
|
initialSelection={initialSelection}
|
|
679
659
|
initialTab={initialTab}
|
|
680
|
-
sectionPageId={sectionPageId}
|
|
681
660
|
authState={{ status: "signedIn", label: "Demo Desk" }}
|
|
682
661
|
isRefreshing={false}
|
|
683
662
|
shellError={null}
|
|
@@ -695,7 +674,6 @@ export function NewsDeskWorkspace({
|
|
|
695
674
|
editorShellReady={session.shell.phase === "ready"}
|
|
696
675
|
initialSelection={initialSelection}
|
|
697
676
|
initialTab={initialTab}
|
|
698
|
-
sectionPageId={sectionPageId}
|
|
699
677
|
authState={session.shell.auth}
|
|
700
678
|
isRefreshing={session.shell.phase === "refreshing"}
|
|
701
679
|
shellError={session.shell.error}
|
|
@@ -720,7 +698,6 @@ export function NewsDeskWorkspace({
|
|
|
720
698
|
editorShellReady={false}
|
|
721
699
|
initialSelection={initialSelection}
|
|
722
700
|
initialTab={initialTab}
|
|
723
|
-
sectionPageId={sectionPageId}
|
|
724
701
|
authState={session?.shell.auth ?? { status: "signedOut", label: "Signed out" }}
|
|
725
702
|
isRefreshing={session?.shell.phase === "refreshing"}
|
|
726
703
|
shellError={session?.shell.error ?? null}
|
|
@@ -739,7 +716,6 @@ function NewsDeskDashboard({
|
|
|
739
716
|
editorShellReady = false,
|
|
740
717
|
initialTab,
|
|
741
718
|
initialSelection,
|
|
742
|
-
sectionPageId,
|
|
743
719
|
authState,
|
|
744
720
|
isRefreshing,
|
|
745
721
|
shellError,
|
|
@@ -754,7 +730,6 @@ function NewsDeskDashboard({
|
|
|
754
730
|
editorShellReady?: boolean;
|
|
755
731
|
initialTab: NewsDeskTab;
|
|
756
732
|
initialSelection: NewsDeskSelection;
|
|
757
|
-
sectionPageId?: string | null;
|
|
758
733
|
authState: ReaderAuthSnapshot;
|
|
759
734
|
isRefreshing: boolean;
|
|
760
735
|
shellError: string | null;
|
|
@@ -773,7 +748,6 @@ function NewsDeskDashboard({
|
|
|
773
748
|
() => parseReferenceLineageIdFromNewsroomPathname(pathname),
|
|
774
749
|
[pathname],
|
|
775
750
|
);
|
|
776
|
-
const isSectionPage = Boolean(sectionPageId);
|
|
777
751
|
const [corpora, setCorpora] = useState(dashboard.corpora);
|
|
778
752
|
const [importRuns, setImportRuns] = useState(dashboard.importRuns);
|
|
779
753
|
const [categorySets, setCategorySets] = useState(dashboard.categorySets);
|
|
@@ -976,10 +950,6 @@ function NewsDeskDashboard({
|
|
|
976
950
|
})
|
|
977
951
|
), [activeCategorySet?.id, activeCategoryTreeNodes, categorys]);
|
|
978
952
|
const summaryStatus = newsroomSummaryStatus({ summary, summaryStatus: dashboard.summaryStatus });
|
|
979
|
-
const activeNewsroomSection = sectionPageId
|
|
980
|
-
? newsroomSections.find((section) => section.id === sectionPageId && section.enabled !== false && section.enabledStatus !== "disabled") ?? null
|
|
981
|
-
: null;
|
|
982
|
-
const mastheadTitle = activeNewsroomSection?.title ?? (isSectionPage ? "SECTION" : "NEWSROOM");
|
|
983
953
|
const tabCounts = useMemo<Record<NewsDeskTab, number | null>>(() => ({
|
|
984
954
|
overview: 0,
|
|
985
955
|
desks: summaryCountFromRecord(summary, "categories"),
|
|
@@ -1282,7 +1252,7 @@ function NewsDeskDashboard({
|
|
|
1282
1252
|
if (
|
|
1283
1253
|
canRefreshNewsroomSections
|
|
1284
1254
|
&& newsroomSections.length === 0
|
|
1285
|
-
&& (activeTab === "administration" || activeTab === "overview"
|
|
1255
|
+
&& (activeTab === "administration" || activeTab === "overview")
|
|
1286
1256
|
&& !hasRefreshedNewsroomSections
|
|
1287
1257
|
) {
|
|
1288
1258
|
setHasRefreshedNewsroomSections(true);
|
|
@@ -1361,7 +1331,6 @@ function NewsDeskDashboard({
|
|
|
1361
1331
|
loadedSections.messages,
|
|
1362
1332
|
loadedSections.references,
|
|
1363
1333
|
loadedSections.semanticRelations,
|
|
1364
|
-
isSectionPage,
|
|
1365
1334
|
refreshNewsroomSections,
|
|
1366
1335
|
]);
|
|
1367
1336
|
|
|
@@ -1952,118 +1921,6 @@ function NewsDeskDashboard({
|
|
|
1952
1921
|
});
|
|
1953
1922
|
}
|
|
1954
1923
|
|
|
1955
|
-
async function createNote(target: NoteTarget, summary: string, body: string): Promise<void> {
|
|
1956
|
-
const cleanSummary = summary.trim();
|
|
1957
|
-
const cleanBody = body.trim();
|
|
1958
|
-
if (!cleanSummary) throw new Error("Note summary is required.");
|
|
1959
|
-
if (!cleanBody) throw new Error("Note body is required.");
|
|
1960
|
-
const now = new Date().toISOString();
|
|
1961
|
-
const subjectSeed = [
|
|
1962
|
-
target.kind,
|
|
1963
|
-
target.lineageId,
|
|
1964
|
-
cleanSummary,
|
|
1965
|
-
cleanBody,
|
|
1966
|
-
now,
|
|
1967
|
-
];
|
|
1968
|
-
const messageId = `message-note-${safeUiId(target.kind)}-${safeUiId(target.lineageId)}-${hashUiKey(subjectSeed)}`;
|
|
1969
|
-
const message: MessageRecord = {
|
|
1970
|
-
id: messageId,
|
|
1971
|
-
messageKind: "note",
|
|
1972
|
-
messageDomain: "knowledge",
|
|
1973
|
-
status: "active",
|
|
1974
|
-
summary: cleanSummary,
|
|
1975
|
-
source: "newsroom",
|
|
1976
|
-
authorLabel: authState.label,
|
|
1977
|
-
threadId: messageId,
|
|
1978
|
-
sequenceNumber: 1,
|
|
1979
|
-
createdAt: now,
|
|
1980
|
-
updatedAt: now,
|
|
1981
|
-
newsroomFeedKey: "messages",
|
|
1982
|
-
body: cleanBody,
|
|
1983
|
-
metadata: {
|
|
1984
|
-
targetKind: target.kind,
|
|
1985
|
-
targetId: target.id,
|
|
1986
|
-
targetLineageId: target.lineageId,
|
|
1987
|
-
},
|
|
1988
|
-
};
|
|
1989
|
-
const relation = buildUiNoteRelation(message, target, now);
|
|
1990
|
-
setActionState({ id: messageId, message: "note pending", tone: "pending" });
|
|
1991
|
-
|
|
1992
|
-
if (dashboard.isDemo) {
|
|
1993
|
-
setMessages((current) => [message, ...current.filter((entry) => entry.id !== message.id)]);
|
|
1994
|
-
setSemanticRelations((current) => [relation, ...current.filter((entry) => entry.id !== relation.id)]);
|
|
1995
|
-
setActionState({ id: messageId, message: "note saved", tone: "ok" });
|
|
1996
|
-
return;
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
if (target.kind === "reference") {
|
|
2000
|
-
const response = await dataClient.mutations.createReferenceNote(
|
|
2001
|
-
{
|
|
2002
|
-
referenceId: target.id,
|
|
2003
|
-
summary: cleanSummary,
|
|
2004
|
-
body: cleanBody,
|
|
2005
|
-
actorLabel: authState.label,
|
|
2006
|
-
},
|
|
2007
|
-
{ authMode: USER_POOL_AUTH_MODE },
|
|
2008
|
-
);
|
|
2009
|
-
const created = assertReferenceNoteMutationSucceeded(response as ReferenceNoteResponse, target.id);
|
|
2010
|
-
const persistedMessageId = created.messageId ?? messageId;
|
|
2011
|
-
const persistedRelationId = created.relationId ?? relation.id;
|
|
2012
|
-
const persistedMessage: MessageRecord = {
|
|
2013
|
-
...message,
|
|
2014
|
-
id: persistedMessageId,
|
|
2015
|
-
};
|
|
2016
|
-
const persistedRelation: SemanticRelationRecord = {
|
|
2017
|
-
...relation,
|
|
2018
|
-
id: persistedRelationId,
|
|
2019
|
-
subjectId: persistedMessageId,
|
|
2020
|
-
subjectLineageId: persistedMessageId,
|
|
2021
|
-
subjectVersionKey: semanticVersionKey("message", persistedMessageId),
|
|
2022
|
-
subjectStateKey: semanticStateKey("message", persistedMessageId),
|
|
2023
|
-
};
|
|
2024
|
-
setMessages((current) => [persistedMessage, ...current.filter((entry) => entry.id !== persistedMessage.id)]);
|
|
2025
|
-
setSemanticRelations((current) => [persistedRelation, ...current.filter((entry) => entry.id !== persistedRelation.id)]);
|
|
2026
|
-
setActionState({ id: persistedMessageId, message: "note saved", tone: "ok" });
|
|
2027
|
-
return;
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
|
-
if (!("Message" in dataClient.models)) throw new Error("GraphQL model Message is not available in the deployed schema.");
|
|
2031
|
-
if (!("SemanticRelation" in dataClient.models)) throw new Error("GraphQL model SemanticRelation is not available in the deployed schema.");
|
|
2032
|
-
|
|
2033
|
-
const messageInput = {
|
|
2034
|
-
id: message.id,
|
|
2035
|
-
messageKind: message.messageKind,
|
|
2036
|
-
messageDomain: message.messageDomain,
|
|
2037
|
-
status: message.status,
|
|
2038
|
-
summary: message.summary,
|
|
2039
|
-
source: message.source,
|
|
2040
|
-
authorLabel: message.authorLabel,
|
|
2041
|
-
threadId: message.id,
|
|
2042
|
-
sequenceNumber: 1,
|
|
2043
|
-
createdAt: message.createdAt,
|
|
2044
|
-
updatedAt: message.updatedAt,
|
|
2045
|
-
newsroomFeedKey: "messages",
|
|
2046
|
-
};
|
|
2047
|
-
const messageResponse = await dataClient.models.Message.create(messageInput as never, { authMode: USER_POOL_AUTH_MODE });
|
|
2048
|
-
assertNoGraphQLErrors(messageResponse.errors);
|
|
2049
|
-
await uploadModelPayloadForOwner({
|
|
2050
|
-
ownerKind: "message",
|
|
2051
|
-
ownerId: messageId,
|
|
2052
|
-
ownerLineageId: messageId,
|
|
2053
|
-
role: "message_body",
|
|
2054
|
-
sortKey: "message",
|
|
2055
|
-
filename: "message.md",
|
|
2056
|
-
mediaType: "text/markdown",
|
|
2057
|
-
content: cleanBody.endsWith("\n") ? cleanBody : `${cleanBody}\n`,
|
|
2058
|
-
status: "active",
|
|
2059
|
-
});
|
|
2060
|
-
const relationResponse = await dataClient.models.SemanticRelation.create(relation as never, { authMode: USER_POOL_AUTH_MODE });
|
|
2061
|
-
assertNoGraphQLErrors(relationResponse.errors);
|
|
2062
|
-
setMessages((current) => [message, ...current.filter((entry) => entry.id !== message.id)]);
|
|
2063
|
-
setSemanticRelations((current) => [relation, ...current.filter((entry) => entry.id !== relation.id)]);
|
|
2064
|
-
setActionState({ id: messageId, message: "note saved", tone: "ok" });
|
|
2065
|
-
}
|
|
2066
|
-
|
|
2067
1924
|
function createLexicalSteeringRule(draft: LexicalRuleDraft) {
|
|
2068
1925
|
const normalizedTerm = normalizeKeywordTerm(draft.term);
|
|
2069
1926
|
if (!normalizedTerm) {
|
|
@@ -3140,13 +2997,11 @@ function NewsDeskDashboard({
|
|
|
3140
2997
|
}
|
|
3141
2998
|
return entries;
|
|
3142
2999
|
}, [summaryStatus, tabCounts]);
|
|
3143
|
-
const opsPageTitle =
|
|
3144
|
-
?
|
|
3145
|
-
: activeTab === "
|
|
3146
|
-
? "
|
|
3147
|
-
: activeTab
|
|
3148
|
-
? "Sections"
|
|
3149
|
-
: formatDeskSectionHeadline(activeTab);
|
|
3000
|
+
const opsPageTitle = activeTab === "overview"
|
|
3001
|
+
? "Overview"
|
|
3002
|
+
: activeTab === "administration" && administrationPanel === "sections"
|
|
3003
|
+
? "Sections"
|
|
3004
|
+
: formatDeskSectionHeadline(activeTab);
|
|
3150
3005
|
|
|
3151
3006
|
return (
|
|
3152
3007
|
<>
|
|
@@ -3173,7 +3028,6 @@ function NewsDeskDashboard({
|
|
|
3173
3028
|
</>
|
|
3174
3029
|
)}
|
|
3175
3030
|
pageTitle={opsPageTitle}
|
|
3176
|
-
showNavigation={!isSectionPage}
|
|
3177
3031
|
tabCounts={shellTabCounts}
|
|
3178
3032
|
>
|
|
3179
3033
|
<div
|
|
@@ -3200,17 +3054,7 @@ function NewsDeskDashboard({
|
|
|
3200
3054
|
</NewsroomOpsStatusBanner>
|
|
3201
3055
|
) : null}
|
|
3202
3056
|
|
|
3203
|
-
{
|
|
3204
|
-
<DeepNewsroomSectionView
|
|
3205
|
-
demo={Boolean(dashboard.isDemo)}
|
|
3206
|
-
disabled={controlsDisabled}
|
|
3207
|
-
onCreateNote={createNote}
|
|
3208
|
-
section={activeNewsroomSection}
|
|
3209
|
-
sectionId={sectionPageId ?? ""}
|
|
3210
|
-
sectionsLoaded={loadedSections.sections}
|
|
3211
|
-
/>
|
|
3212
|
-
) : null}
|
|
3213
|
-
{!isSectionPage && activeTab === "overview" ? (
|
|
3057
|
+
{activeTab === "overview" ? (
|
|
3214
3058
|
<NewsroomOpsOverview
|
|
3215
3059
|
assignments={assignments}
|
|
3216
3060
|
demo={Boolean(dashboard.isDemo)}
|
|
@@ -3219,7 +3063,7 @@ function NewsDeskDashboard({
|
|
|
3219
3063
|
references={references}
|
|
3220
3064
|
/>
|
|
3221
3065
|
) : null}
|
|
3222
|
-
{
|
|
3066
|
+
{activeTab === "search" ? (
|
|
3223
3067
|
<SearchDeskView
|
|
3224
3068
|
assignments={assignments}
|
|
3225
3069
|
categories={mergeCategoryRecords(categorys, activeCategoryTreeNodes)}
|
|
@@ -3230,13 +3074,13 @@ function NewsDeskDashboard({
|
|
|
3230
3074
|
semanticNodes={semanticNodes}
|
|
3231
3075
|
/>
|
|
3232
3076
|
) : null}
|
|
3233
|
-
{
|
|
3077
|
+
{(activeTab === "desks" || activeTab === "topics") ? (
|
|
3234
3078
|
<nav aria-label="Taxonomy views" className="taxonomy-view-switch" data-taxonomy-view-switch>
|
|
3235
3079
|
<Link aria-current={activeTab === "desks" ? "page" : undefined} href={getNewsroomNavHref("/newsroom/desks", Boolean(dashboard.isDemo))}>Categories</Link>
|
|
3236
3080
|
<Link aria-current={activeTab === "topics" ? "page" : undefined} href={getNewsroomNavHref("/newsroom/topics", Boolean(dashboard.isDemo))}>Topic proposals</Link>
|
|
3237
3081
|
</nav>
|
|
3238
3082
|
) : null}
|
|
3239
|
-
{
|
|
3083
|
+
{activeTab === "desks" ? (
|
|
3240
3084
|
<DesksDeskView
|
|
3241
3085
|
assignments={assignments}
|
|
3242
3086
|
categoryByUid={categoryByUid}
|
|
@@ -3252,7 +3096,7 @@ function NewsDeskDashboard({
|
|
|
3252
3096
|
statusMessage={actionState}
|
|
3253
3097
|
/>
|
|
3254
3098
|
) : null}
|
|
3255
|
-
{
|
|
3099
|
+
{activeTab === "topics" ? (
|
|
3256
3100
|
<TopicsDeskView
|
|
3257
3101
|
disabled={controlsDisabled}
|
|
3258
3102
|
initialProposalId={initialSelection.proposal}
|
|
@@ -3261,7 +3105,7 @@ function NewsDeskDashboard({
|
|
|
3261
3105
|
proposals={proposals}
|
|
3262
3106
|
/>
|
|
3263
3107
|
) : null}
|
|
3264
|
-
{
|
|
3108
|
+
{activeTab === "concepts" ? (
|
|
3265
3109
|
<ConceptsDeskView
|
|
3266
3110
|
graph={graph}
|
|
3267
3111
|
initialNodeLineageId={initialSelection.node}
|
|
@@ -3269,7 +3113,7 @@ function NewsDeskDashboard({
|
|
|
3269
3113
|
semanticNodes={semanticNodes}
|
|
3270
3114
|
/>
|
|
3271
3115
|
) : null}
|
|
3272
|
-
{
|
|
3116
|
+
{activeTab === "references" ? (
|
|
3273
3117
|
<NewsroomReferencesView
|
|
3274
3118
|
demo={Boolean(dashboard.isDemo)}
|
|
3275
3119
|
disabled={controlsDisabled}
|
|
@@ -3308,7 +3152,7 @@ function NewsDeskDashboard({
|
|
|
3308
3152
|
references={references}
|
|
3309
3153
|
/>
|
|
3310
3154
|
) : null}
|
|
3311
|
-
{
|
|
3155
|
+
{activeTab === "messages" ? (
|
|
3312
3156
|
<MessagesDeskView
|
|
3313
3157
|
assignments={assignments}
|
|
3314
3158
|
graph={graph}
|
|
@@ -3320,7 +3164,7 @@ function NewsDeskDashboard({
|
|
|
3320
3164
|
summary={summary}
|
|
3321
3165
|
/>
|
|
3322
3166
|
) : null}
|
|
3323
|
-
{
|
|
3167
|
+
{activeTab === "assignments" ? (
|
|
3324
3168
|
<AssignmentDeskView
|
|
3325
3169
|
actionState={actionState}
|
|
3326
3170
|
analysisProfiles={analysisProfiles}
|
|
@@ -3342,7 +3186,7 @@ function NewsDeskDashboard({
|
|
|
3342
3186
|
onReviewReportingPacket={runReportingPacketReview}
|
|
3343
3187
|
/>
|
|
3344
3188
|
) : null}
|
|
3345
|
-
{
|
|
3189
|
+
{activeTab === "administration" ? (
|
|
3346
3190
|
<AdministrationDeskView
|
|
3347
3191
|
actionState={actionState}
|
|
3348
3192
|
administrationPanel={administrationPanel}
|
|
@@ -4248,79 +4092,6 @@ function RotatingSectionTriangleIcon({ expanded }: { expanded: boolean }) {
|
|
|
4248
4092
|
);
|
|
4249
4093
|
}
|
|
4250
4094
|
|
|
4251
|
-
function DeepNewsroomSectionView({
|
|
4252
|
-
demo,
|
|
4253
|
-
disabled,
|
|
4254
|
-
onCreateNote,
|
|
4255
|
-
section,
|
|
4256
|
-
sectionId,
|
|
4257
|
-
sectionsLoaded,
|
|
4258
|
-
}: {
|
|
4259
|
-
demo: boolean;
|
|
4260
|
-
disabled: boolean;
|
|
4261
|
-
onCreateNote: (target: NoteTarget, summary: string, body: string) => Promise<void>;
|
|
4262
|
-
section: NewsroomSectionRecord | null;
|
|
4263
|
-
sectionId: string;
|
|
4264
|
-
sectionsLoaded: boolean;
|
|
4265
|
-
}) {
|
|
4266
|
-
const noteTarget = section ? noteTargetForNewsroomSection(section) : null;
|
|
4267
|
-
const noteComposer = useNewsroomNoteComposer(noteTarget, disabled, onCreateNote);
|
|
4268
|
-
|
|
4269
|
-
if (!section) {
|
|
4270
|
-
return (
|
|
4271
|
-
<section className="newsroom-deep-section" data-newsroom-deep-section-missing={sectionId}>
|
|
4272
|
-
<p className="story-label">Section</p>
|
|
4273
|
-
<h2>{sectionsLoaded ? "Section not found" : "Loading section"}</h2>
|
|
4274
|
-
<p>{sectionsLoaded ? "This section is not configured or is disabled." : "Loading the configured newsroom section."}</p>
|
|
4275
|
-
</section>
|
|
4276
|
-
);
|
|
4277
|
-
}
|
|
4278
|
-
|
|
4279
|
-
const guidanceRows = [
|
|
4280
|
-
["Assignment Guidance", section.assignmentGuidance],
|
|
4281
|
-
["Kill Criteria", section.killCriteria],
|
|
4282
|
-
["Visual Guidance", section.visualGuidance],
|
|
4283
|
-
].filter((row): row is [string, string] => typeof row[1] === "string" && row[1].trim().length > 0);
|
|
4284
|
-
|
|
4285
|
-
return (
|
|
4286
|
-
<section
|
|
4287
|
-
className="newsroom-deep-section"
|
|
4288
|
-
data-newsroom-deep-section={section.id}
|
|
4289
|
-
data-newsroom-section-type={formatNewsroomSectionTypeLabel(section.type).toLowerCase()}
|
|
4290
|
-
>
|
|
4291
|
-
<header className="newsroom-deep-section__header">
|
|
4292
|
-
<p className="story-label" data-newsroom-deep-section-eyebrow>Section</p>
|
|
4293
|
-
<h2 data-newsroom-deep-section-title>{section.title}</h2>
|
|
4294
|
-
<p>{displayNewsroomSectionShortTitle(section)}</p>
|
|
4295
|
-
<div className="newsroom-deep-section__header-actions">
|
|
4296
|
-
<button type="button" disabled={noteComposer.action.disabled} onClick={noteComposer.action.onSelect}>
|
|
4297
|
-
{noteComposer.loading ? "Saving Note" : "Add Note"}
|
|
4298
|
-
</button>
|
|
4299
|
-
<Link href={getNewsDeskTabHref("/newsroom", demo)}>Back to Newsroom</Link>
|
|
4300
|
-
</div>
|
|
4301
|
-
</header>
|
|
4302
|
-
{noteComposer.error ? <div className="category-steering-alert" role="status">{noteComposer.error}</div> : null}
|
|
4303
|
-
<div className="newsroom-deep-section__body">
|
|
4304
|
-
<article className="newsroom-deep-section__field newsroom-deep-section__field--lead">
|
|
4305
|
-
<p className="story-label">Mission</p>
|
|
4306
|
-
<p>{section.editorialMission}</p>
|
|
4307
|
-
</article>
|
|
4308
|
-
<article className="newsroom-deep-section__field newsroom-deep-section__field--lead">
|
|
4309
|
-
<p className="story-label">Policy</p>
|
|
4310
|
-
<p>{section.editorialPolicy}</p>
|
|
4311
|
-
</article>
|
|
4312
|
-
{guidanceRows.map(([label, value]) => (
|
|
4313
|
-
<article className="newsroom-deep-section__field" key={label}>
|
|
4314
|
-
<p className="story-label">{label}</p>
|
|
4315
|
-
<p>{value}</p>
|
|
4316
|
-
</article>
|
|
4317
|
-
))}
|
|
4318
|
-
</div>
|
|
4319
|
-
{noteComposer.dialog}
|
|
4320
|
-
</section>
|
|
4321
|
-
);
|
|
4322
|
-
}
|
|
4323
|
-
|
|
4324
4095
|
function NewsroomOverviewSection({
|
|
4325
4096
|
cards,
|
|
4326
4097
|
detail,
|
|
@@ -8618,27 +8389,6 @@ function LibraryBigIcon() {
|
|
|
8618
8389
|
);
|
|
8619
8390
|
}
|
|
8620
8391
|
|
|
8621
|
-
function NoteIcon() {
|
|
8622
|
-
return (
|
|
8623
|
-
<svg
|
|
8624
|
-
aria-hidden="true"
|
|
8625
|
-
className="news-desk-detail-toggle__icon"
|
|
8626
|
-
fill="none"
|
|
8627
|
-
height="24"
|
|
8628
|
-
stroke="currentColor"
|
|
8629
|
-
strokeLinecap="round"
|
|
8630
|
-
strokeLinejoin="round"
|
|
8631
|
-
strokeWidth="2"
|
|
8632
|
-
viewBox="0 0 24 24"
|
|
8633
|
-
width="24"
|
|
8634
|
-
>
|
|
8635
|
-
<path d="M9 18h6" />
|
|
8636
|
-
<path d="M10 22h4" />
|
|
8637
|
-
<path d="M8.5 14.5A6 6 0 1 1 15.5 14.5c-.8.7-1.2 1.5-1.4 2.5h-4.2c-.2-1-.6-1.8-1.4-2.5Z" />
|
|
8638
|
-
</svg>
|
|
8639
|
-
);
|
|
8640
|
-
}
|
|
8641
|
-
|
|
8642
8392
|
function SearchMarkIcon() {
|
|
8643
8393
|
return (
|
|
8644
8394
|
<svg
|
|
@@ -9358,83 +9108,6 @@ function useNewsroomKnowledgeContext(target: KnowledgeQueryTarget | null) {
|
|
|
9358
9108
|
};
|
|
9359
9109
|
}
|
|
9360
9110
|
|
|
9361
|
-
function useNewsroomNoteComposer(
|
|
9362
|
-
target: NoteTarget | null,
|
|
9363
|
-
disabled: boolean,
|
|
9364
|
-
onCreate: (target: NoteTarget, summary: string, body: string) => Promise<void>,
|
|
9365
|
-
): NoteComposerControl {
|
|
9366
|
-
const [dialogOpen, setDialogOpen] = useState(false);
|
|
9367
|
-
const [summary, setSummary] = useState("");
|
|
9368
|
-
const [body, setBody] = useState("");
|
|
9369
|
-
const [state, setState] = useState<{ error: string | null; loading: boolean; targetKey: string | null }>({
|
|
9370
|
-
error: null,
|
|
9371
|
-
loading: false,
|
|
9372
|
-
targetKey: null,
|
|
9373
|
-
});
|
|
9374
|
-
const targetKey = target ? noteTargetKey(target) : null;
|
|
9375
|
-
|
|
9376
|
-
useEffect(() => {
|
|
9377
|
-
setDialogOpen(false);
|
|
9378
|
-
setSummary("");
|
|
9379
|
-
setBody("");
|
|
9380
|
-
setState({ error: null, loading: false, targetKey });
|
|
9381
|
-
}, [targetKey]);
|
|
9382
|
-
|
|
9383
|
-
const run = async () => {
|
|
9384
|
-
if (!target || disabled || state.loading) return;
|
|
9385
|
-
const cleanSummary = summary.trim();
|
|
9386
|
-
const cleanBody = body.trim();
|
|
9387
|
-
if (!cleanSummary || !cleanBody) {
|
|
9388
|
-
setState({ error: "Note summary and body are required.", loading: false, targetKey });
|
|
9389
|
-
return;
|
|
9390
|
-
}
|
|
9391
|
-
setState({ error: null, loading: true, targetKey });
|
|
9392
|
-
try {
|
|
9393
|
-
await onCreate(target, cleanSummary, cleanBody);
|
|
9394
|
-
setState({ error: null, loading: false, targetKey });
|
|
9395
|
-
setDialogOpen(false);
|
|
9396
|
-
setSummary("");
|
|
9397
|
-
setBody("");
|
|
9398
|
-
} catch (error) {
|
|
9399
|
-
setState({
|
|
9400
|
-
error: error instanceof Error ? error.message : "Could not save note.",
|
|
9401
|
-
loading: false,
|
|
9402
|
-
targetKey,
|
|
9403
|
-
});
|
|
9404
|
-
}
|
|
9405
|
-
};
|
|
9406
|
-
const stateMatchesTarget = state.targetKey === targetKey;
|
|
9407
|
-
const loading = stateMatchesTarget ? state.loading : false;
|
|
9408
|
-
const error = stateMatchesTarget ? state.error : null;
|
|
9409
|
-
|
|
9410
|
-
return {
|
|
9411
|
-
action: {
|
|
9412
|
-
ariaLabel: "Add note",
|
|
9413
|
-
disabled: disabled || !target || loading,
|
|
9414
|
-
icon: <NoteIcon />,
|
|
9415
|
-
key: "add-note",
|
|
9416
|
-
label: loading ? "Saving Note" : "Add Note",
|
|
9417
|
-
onSelect: () => setDialogOpen(true),
|
|
9418
|
-
} satisfies NewsroomDetailAction,
|
|
9419
|
-
dialog: target ? (
|
|
9420
|
-
<NoteComposerDialog
|
|
9421
|
-
body={body}
|
|
9422
|
-
disabled={disabled || loading}
|
|
9423
|
-
error={error}
|
|
9424
|
-
onBodyChange={setBody}
|
|
9425
|
-
onClose={() => setDialogOpen(false)}
|
|
9426
|
-
onRun={run}
|
|
9427
|
-
onSummaryChange={setSummary}
|
|
9428
|
-
open={dialogOpen}
|
|
9429
|
-
summary={summary}
|
|
9430
|
-
target={target}
|
|
9431
|
-
/>
|
|
9432
|
-
) : null,
|
|
9433
|
-
error,
|
|
9434
|
-
loading,
|
|
9435
|
-
};
|
|
9436
|
-
}
|
|
9437
|
-
|
|
9438
9111
|
function useNewsroomRouteSearch({
|
|
9439
9112
|
activeTab,
|
|
9440
9113
|
assignments,
|
|
@@ -9756,89 +9429,6 @@ function KnowledgeQueryDialog({
|
|
|
9756
9429
|
);
|
|
9757
9430
|
}
|
|
9758
9431
|
|
|
9759
|
-
function NoteComposerDialog({
|
|
9760
|
-
body,
|
|
9761
|
-
disabled,
|
|
9762
|
-
error,
|
|
9763
|
-
onBodyChange,
|
|
9764
|
-
onClose,
|
|
9765
|
-
onRun,
|
|
9766
|
-
onSummaryChange,
|
|
9767
|
-
open,
|
|
9768
|
-
summary,
|
|
9769
|
-
target,
|
|
9770
|
-
}: {
|
|
9771
|
-
body: string;
|
|
9772
|
-
disabled: boolean;
|
|
9773
|
-
error: string | null;
|
|
9774
|
-
onBodyChange: (value: string) => void;
|
|
9775
|
-
onClose: () => void;
|
|
9776
|
-
onRun: () => void;
|
|
9777
|
-
onSummaryChange: (value: string) => void;
|
|
9778
|
-
open: boolean;
|
|
9779
|
-
summary: string;
|
|
9780
|
-
target: NoteTarget;
|
|
9781
|
-
}) {
|
|
9782
|
-
useEffect(() => {
|
|
9783
|
-
if (!open) return;
|
|
9784
|
-
function handleKeyDown(event: KeyboardEvent) {
|
|
9785
|
-
if (event.key === "Escape") onClose();
|
|
9786
|
-
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") onRun();
|
|
9787
|
-
}
|
|
9788
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
9789
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
9790
|
-
}, [onClose, onRun, open]);
|
|
9791
|
-
|
|
9792
|
-
if (!open) return null;
|
|
9793
|
-
|
|
9794
|
-
return (
|
|
9795
|
-
<div
|
|
9796
|
-
className="news-desk-modal"
|
|
9797
|
-
data-news-desk-note-modal
|
|
9798
|
-
onMouseDown={(event) => {
|
|
9799
|
-
if (event.target === event.currentTarget && !disabled) onClose();
|
|
9800
|
-
}}
|
|
9801
|
-
>
|
|
9802
|
-
<div className="news-desk-modal__dialog news-desk-modal__dialog--knowledge-query" role="dialog" aria-modal="true" aria-labelledby="note-composer-title">
|
|
9803
|
-
<header className="news-desk-modal__header">
|
|
9804
|
-
<div>
|
|
9805
|
-
<p className="story-label">Note</p>
|
|
9806
|
-
<h3 id="note-composer-title">{target.title}</h3>
|
|
9807
|
-
<span>{target.kind} / {target.lineageId}</span>
|
|
9808
|
-
</div>
|
|
9809
|
-
<button type="button" disabled={disabled} onClick={onClose}>Close</button>
|
|
9810
|
-
</header>
|
|
9811
|
-
<div className="news-desk-knowledge-query-form">
|
|
9812
|
-
<label>
|
|
9813
|
-
<span>Summary</span>
|
|
9814
|
-
<input
|
|
9815
|
-
disabled={disabled}
|
|
9816
|
-
value={summary}
|
|
9817
|
-
onChange={(event) => onSummaryChange(event.target.value)}
|
|
9818
|
-
/>
|
|
9819
|
-
</label>
|
|
9820
|
-
<label>
|
|
9821
|
-
<span>Note Body</span>
|
|
9822
|
-
<textarea
|
|
9823
|
-
disabled={disabled}
|
|
9824
|
-
rows={8}
|
|
9825
|
-
value={body}
|
|
9826
|
-
onChange={(event) => onBodyChange(event.target.value)}
|
|
9827
|
-
/>
|
|
9828
|
-
</label>
|
|
9829
|
-
{error ? <div className="category-steering-alert" role="status">{error}</div> : null}
|
|
9830
|
-
</div>
|
|
9831
|
-
<footer className="news-desk-modal__actions">
|
|
9832
|
-
<button type="button" disabled={disabled} onClick={onClose}>Cancel</button>
|
|
9833
|
-
<button type="button" className="news-desk-assignment-create-button" disabled={disabled || !summary.trim() || !body.trim()} onClick={onRun}>
|
|
9834
|
-
{disabled ? "Saving" : "Save Note"}
|
|
9835
|
-
</button>
|
|
9836
|
-
</footer>
|
|
9837
|
-
</div>
|
|
9838
|
-
</div>
|
|
9839
|
-
);
|
|
9840
|
-
}
|
|
9841
|
-
|
|
9842
9432
|
function KnowledgeQueryStatus({ error, loading }: { error: string | null; loading: boolean }) {
|
|
9843
9433
|
if (!loading && !error) return null;
|
|
9844
9434
|
return (
|
|
@@ -12910,17 +12500,6 @@ function noteTargetForReference(reference: ReferenceRecord): NoteTarget {
|
|
|
12910
12500
|
};
|
|
12911
12501
|
}
|
|
12912
12502
|
|
|
12913
|
-
function noteTargetForNewsroomSection(section: NewsroomSectionRecord): NoteTarget {
|
|
12914
|
-
return {
|
|
12915
|
-
kind: "newsroomSection",
|
|
12916
|
-
id: section.id,
|
|
12917
|
-
lineageId: section.id,
|
|
12918
|
-
title: section.title,
|
|
12919
|
-
subtitle: section.type,
|
|
12920
|
-
versionNumber: null,
|
|
12921
|
-
};
|
|
12922
|
-
}
|
|
12923
|
-
|
|
12924
12503
|
function noteTargetForSemanticObject(object: SemanticObjectSummary): NoteTarget | null {
|
|
12925
12504
|
if (object.kind !== "category" && object.kind !== "semanticNode") return null;
|
|
12926
12505
|
return {
|
|
@@ -12933,55 +12512,6 @@ function noteTargetForSemanticObject(object: SemanticObjectSummary): NoteTarget
|
|
|
12933
12512
|
};
|
|
12934
12513
|
}
|
|
12935
12514
|
|
|
12936
|
-
function noteTargetKey(target: NoteTarget): string {
|
|
12937
|
-
return `${target.kind}#${target.lineageId}`;
|
|
12938
|
-
}
|
|
12939
|
-
|
|
12940
|
-
function buildUiNoteRelation(message: MessageRecord, target: NoteTarget, now: string): SemanticRelationRecord {
|
|
12941
|
-
const subjectStateKey = semanticStateKey("message", message.id);
|
|
12942
|
-
const objectStateKey = semanticStateKey(target.kind, target.lineageId);
|
|
12943
|
-
const subjectVersionKey = semanticVersionKey("message", message.id);
|
|
12944
|
-
const objectVersionKey = semanticVersionKey(target.kind, target.id);
|
|
12945
|
-
return {
|
|
12946
|
-
id: `semantic-relation-${hashUiKey([subjectVersionKey, "note_about", objectVersionKey])}`,
|
|
12947
|
-
relationState: "current",
|
|
12948
|
-
predicate: "note_about",
|
|
12949
|
-
relationTypeId: "semantic-relation-type-note-about",
|
|
12950
|
-
relationTypeKey: "note_about",
|
|
12951
|
-
relationDomain: "knowledge",
|
|
12952
|
-
subjectKind: "message",
|
|
12953
|
-
subjectId: message.id,
|
|
12954
|
-
subjectLineageId: message.id,
|
|
12955
|
-
subjectVersionNumber: 1,
|
|
12956
|
-
objectKind: target.kind,
|
|
12957
|
-
objectId: target.id,
|
|
12958
|
-
objectLineageId: target.lineageId,
|
|
12959
|
-
objectVersionNumber: target.versionNumber ?? null,
|
|
12960
|
-
subjectStateKey,
|
|
12961
|
-
objectStateKey,
|
|
12962
|
-
objectSubjectStateKey: `${objectStateKey}#message`,
|
|
12963
|
-
predicateObjectStateKey: `note_about#${objectStateKey}`,
|
|
12964
|
-
subjectVersionKey,
|
|
12965
|
-
objectVersionKey,
|
|
12966
|
-
score: null,
|
|
12967
|
-
confidence: null,
|
|
12968
|
-
rank: 1,
|
|
12969
|
-
classifierId: null,
|
|
12970
|
-
modelVersion: null,
|
|
12971
|
-
reviewRecommended: false,
|
|
12972
|
-
sourceSnapshotId: null,
|
|
12973
|
-
importRunId: null,
|
|
12974
|
-
importedAt: now,
|
|
12975
|
-
createdAt: now,
|
|
12976
|
-
updatedAt: now,
|
|
12977
|
-
newsroomFeedKey: "semanticRelations",
|
|
12978
|
-
metadata: {
|
|
12979
|
-
targetTitle: target.title,
|
|
12980
|
-
targetSubtitle: target.subtitle ?? null,
|
|
12981
|
-
},
|
|
12982
|
-
};
|
|
12983
|
-
}
|
|
12984
|
-
|
|
12985
12515
|
function buildUiAnalysisTargetRelation({
|
|
12986
12516
|
assignment,
|
|
12987
12517
|
categorySet,
|
|
@@ -13310,10 +12840,6 @@ function isEnabledNewsroomSection(section: NewsroomSectionRecord): boolean {
|
|
|
13310
12840
|
return section.enabled !== false && section.enabledStatus !== "disabled";
|
|
13311
12841
|
}
|
|
13312
12842
|
|
|
13313
|
-
function formatNewsroomSectionTypeLabel(value: string | null | undefined): "Canonical" | "Rotating" {
|
|
13314
|
-
return normalizeNewsroomSectionType(value) === "canonical" ? "Canonical" : "Rotating";
|
|
13315
|
-
}
|
|
13316
|
-
|
|
13317
12843
|
function buildNewsroomSectionHref(sectionId: string, demo?: boolean): string {
|
|
13318
12844
|
return getNewsDeskTabHref(`/newsroom/sections/${encodeURIComponent(sectionId)}`, demo);
|
|
13319
12845
|
}
|
|
@@ -16104,25 +15630,6 @@ function assertReferenceQualityMutationSucceeded(
|
|
|
16104
15630
|
return response.data;
|
|
16105
15631
|
}
|
|
16106
15632
|
|
|
16107
|
-
function assertReferenceNoteMutationSucceeded(
|
|
16108
|
-
response: ReferenceNoteResponse,
|
|
16109
|
-
referenceId: string,
|
|
16110
|
-
): NonNullable<ReferenceNoteResponse["data"]> {
|
|
16111
|
-
if (response.errors?.length) {
|
|
16112
|
-
throw new Error(response.errors.map(formatGraphQLError).join("; "));
|
|
16113
|
-
}
|
|
16114
|
-
if (!response.data?.ok) {
|
|
16115
|
-
throw new Error(`Reference note was not saved for ${referenceId}.`);
|
|
16116
|
-
}
|
|
16117
|
-
if (response.data.referenceId && response.data.referenceId !== referenceId) {
|
|
16118
|
-
throw new Error(`Reference note response did not match ${referenceId}.`);
|
|
16119
|
-
}
|
|
16120
|
-
if (!response.data.messageId || !response.data.relationId) {
|
|
16121
|
-
throw new Error(`Reference note saved without required audit relations for ${referenceId}.`);
|
|
16122
|
-
}
|
|
16123
|
-
return response.data;
|
|
16124
|
-
}
|
|
16125
|
-
|
|
16126
15633
|
function assertReferenceMoveCorpusMutationSucceeded(
|
|
16127
15634
|
response: ReferenceCorpusMoveResponse,
|
|
16128
15635
|
referenceId: string,
|