@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.
@@ -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" && !sectionPageId;
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" || isSectionPage)
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 = isSectionPage
3144
- ? mastheadTitle
3145
- : activeTab === "overview"
3146
- ? "Overview"
3147
- : activeTab === "administration" && administrationPanel === "sections"
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
- {isSectionPage ? (
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
- {!isSectionPage && activeTab === "search" ? (
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
- {!isSectionPage && (activeTab === "desks" || activeTab === "topics") ? (
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
- {!isSectionPage && activeTab === "desks" ? (
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
- {!isSectionPage && activeTab === "topics" ? (
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
- {!isSectionPage && activeTab === "concepts" ? (
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
- {!isSectionPage && activeTab === "references" ? (
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
- {!isSectionPage && activeTab === "messages" ? (
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
- {!isSectionPage && activeTab === "assignments" ? (
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
- {!isSectionPage && activeTab === "administration" ? (
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,