@semiont/react-ui 0.5.26 → 0.5.28
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/README.md +28 -4
- package/dist/{PdfAnnotationCanvas.client-6ZSF6ZTJ.js → PdfAnnotationCanvas.client-C2IGG4SW.js} +33 -6
- package/dist/{PdfAnnotationCanvas.client-JCJMXWWJ.css → PdfAnnotationCanvas.client-TGDPPGXJ.css} +6 -1
- package/dist/{ar-YTUUGK2O.js → ar-FABPTJVB.js} +88 -26
- package/dist/{bn-ASGNGPMD.js → bn-LKP6BDMH.js} +88 -26
- package/dist/{chunk-L3WKRWP3.js → chunk-2GOHTTHW.js} +88 -26
- package/dist/{chunk-OBQOZCJE.js → chunk-2YHEE63S.js} +31 -31
- package/dist/{cs-WMYVAOZY.js → cs-YQYNWHRG.js} +88 -26
- package/dist/{da-FSHHN4D6.js → da-QHZOYKRY.js} +88 -26
- package/dist/{de-FJFO3TPT.js → de-GKA7RD7J.js} +88 -26
- package/dist/{el-XOH4QIAG.js → el-45T257AL.js} +88 -26
- package/dist/{en-3FCBW3YD.js → en-RVW5EQ66.js} +4 -2
- package/dist/{es-HDX4QI7E.js → es-AVER7RU4.js} +88 -26
- package/dist/{fa-DJ6WTFTJ.js → fa-K3VPK3O2.js} +88 -26
- package/dist/{fi-4S7H7W7U.js → fi-5NEKF7EB.js} +88 -26
- package/dist/{fr-6UJSYHXC.js → fr-FUMNDLBZ.js} +88 -26
- package/dist/{he-ZZJOHJX2.js → he-3JGNA3PR.js} +88 -26
- package/dist/{hi-HZJTAW7U.js → hi-IJY375DF.js} +88 -26
- package/dist/{id-E3I6ILEM.js → id-LWHKJ7ZD.js} +88 -26
- package/dist/index.css +380 -524
- package/dist/index.d.ts +318 -192
- package/dist/index.js +2960 -2421
- package/dist/integrations/css-modules-helper.js +1 -3
- package/dist/{it-ULAPAD7U.js → it-EBVOV4RW.js} +88 -26
- package/dist/{ja-SAHZQ4CZ.js → ja-KWRIX2NF.js} +88 -26
- package/dist/{ko-DFU2ADQ4.js → ko-L5CJMFDS.js} +88 -26
- package/dist/{ms-NWL76XNT.js → ms-LSNMJDR2.js} +88 -26
- package/dist/{nl-ATCM76WN.js → nl-ZB32MB7U.js} +88 -26
- package/dist/{no-UIAQ5RJF.js → no-4GTNY7M5.js} +88 -26
- package/dist/{pl-NOECQDXD.js → pl-LUHBLTHB.js} +88 -26
- package/dist/{pt-SVWIIUPC.js → pt-C4H3UNQ6.js} +88 -26
- package/dist/{ro-NR2DRTZG.js → ro-GGITS5V4.js} +88 -26
- package/dist/{sv-STVJ37JP.js → sv-T56RTLBP.js} +88 -26
- package/dist/test-utils.css +1 -1
- package/dist/test-utils.d.ts +1 -1
- package/dist/test-utils.js +2 -2
- package/dist/{th-UWQR4K54.js → th-22X2IWCB.js} +88 -26
- package/dist/{tr-WNXZSD27.js → tr-77TFG62H.js} +88 -26
- package/dist/{uk-SJRMB47Y.js → uk-MIIL6NXT.js} +88 -26
- package/dist/{vi-TMRQFES2.js → vi-7JYOIGNV.js} +88 -26
- package/dist/{zh-QOL3LYEM.js → zh-ID6DRYU4.js} +88 -26
- package/package.json +11 -10
- package/src/components/AssistProgress.tsx +178 -134
- package/src/components/CodeMirrorRenderer.tsx +8 -8
- package/src/components/{EntityFoundLog.tsx → ItemFoundLog.tsx} +12 -7
- package/src/components/ProtectedErrorBoundary.css +3 -1
- package/src/components/StatusDisplay.css +1 -1
- package/src/components/Toast.css +3 -1
- package/src/components/__tests__/AssistProgress.test.tsx +268 -141
- package/src/components/annotation/annotation-entries.css +0 -4
- package/src/components/annotation/references.css +0 -4
- package/src/components/image-annotation/AnnotationOverlay.tsx +6 -6
- package/src/components/image-annotation/SvgDrawingCanvas.tsx +1 -1
- package/src/components/image-annotation/__tests__/AnnotationOverlay.click.test.tsx +7 -9
- package/src/components/image-annotation/__tests__/SvgDrawingCanvas.click.test.tsx +1 -2
- package/src/components/layout/Header.css +0 -4
- package/src/components/layout/LeftSidebar.css +0 -4
- package/src/components/modals/ComposeStep.tsx +218 -0
- package/src/components/modals/ConfigureGatherStep.tsx +10 -18
- package/src/components/modals/ConfigureGenerationStep.tsx +131 -54
- package/src/components/modals/ConfigureSearchStep.tsx +42 -40
- package/src/components/modals/ContextSummary.tsx +185 -72
- package/src/components/modals/CorpusPane.tsx +75 -0
- package/src/components/modals/DiscardPrompt.tsx +38 -0
- package/src/components/modals/GatherContextStep.tsx +237 -107
- package/src/components/modals/ReferenceWizardModal.tsx +287 -60
- package/src/components/modals/ResourceGenerateModal.tsx +233 -109
- package/src/components/modals/SearchModal.css +335 -111
- package/src/components/modals/SearchModal.tsx +1 -1
- package/src/components/modals/SearchResultsStep.tsx +63 -88
- package/src/components/modals/WizardFooter.tsx +69 -0
- package/src/components/modals/__tests__/ComposeStep.test.tsx +152 -0
- package/src/components/modals/__tests__/ConfigureGatherStep.test.tsx +14 -26
- package/src/components/modals/__tests__/ConfigureGenerationStep.test.tsx +290 -0
- package/src/components/modals/__tests__/ConfigureSearchStep.test.tsx +95 -0
- package/src/components/modals/__tests__/GatherContextStep.resource.test.tsx +463 -25
- package/src/components/modals/__tests__/ReferenceWizardModal.test.tsx +635 -0
- package/src/components/modals/__tests__/ResourceGenerateModal.test.tsx +277 -85
- package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +6 -2
- package/src/components/modals/__tests__/SearchResultsStep.test.tsx +61 -0
- package/src/components/modals/__tests__/WizardFooter.test.tsx +344 -0
- package/src/components/modals/modals.css +16 -42
- package/src/components/navigation/NavigationTabs.css +0 -20
- package/src/components/pdf-annotation/PdfAnnotationCanvas.css +21 -2
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +36 -3
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +41 -6
- package/src/components/resource/AnnotateView.tsx +19 -8
- package/src/components/resource/AnnotationHistory.tsx +2 -0
- package/src/components/resource/BrowseView.tsx +20 -9
- package/src/components/resource/ResourceViewer.tsx +27 -28
- package/src/components/resource/__tests__/AnnotateView.embeddable.test.tsx +1 -1
- package/src/components/resource/__tests__/AnnotateView.focus.test.tsx +50 -0
- package/src/components/resource/__tests__/AnnotationHistory.test.tsx +2 -0
- package/src/components/resource/__tests__/BrowseView.embeddable.test.tsx +1 -1
- package/src/components/resource/__tests__/BrowseView.test.tsx +38 -12
- package/src/components/resource/__tests__/ResourceViewer.embeddable.test.tsx +47 -3
- package/src/components/resource/annotate-renderers.tsx +3 -3
- package/src/components/resource/event-formatting.ts +0 -3
- package/src/components/resource/panels/AssessmentEntry.tsx +1 -1
- package/src/components/resource/panels/AssessmentPanel.css +5 -6
- package/src/components/resource/panels/AssistSection.css +95 -263
- package/src/components/resource/panels/AssistSection.tsx +4 -4
- package/src/components/resource/panels/AssistShell.tsx +12 -4
- package/src/components/resource/panels/CollaborationPanel.css +47 -22
- package/src/components/resource/panels/CollaborationPanel.tsx +93 -2
- package/src/components/resource/panels/CommentEntry.tsx +1 -1
- package/src/components/resource/panels/CommentsPanel.css +0 -16
- package/src/components/resource/panels/HighlightEntry.tsx +1 -1
- package/src/components/resource/panels/HighlightPanel.css +0 -7
- package/src/components/resource/panels/JsonLdPanel.css +0 -4
- package/src/components/resource/panels/ReferenceEntry.tsx +10 -3
- package/src/components/resource/panels/ReferencesPanel.css +0 -12
- package/src/components/resource/panels/ReferencesPanel.tsx +16 -20
- package/src/components/resource/panels/ResourceInfoPanel.css +0 -32
- package/src/components/resource/panels/ResourceInfoPanel.tsx +89 -20
- package/src/components/resource/panels/StatisticsPanel.css +0 -20
- package/src/components/resource/panels/TagEntry.tsx +1 -1
- package/src/components/resource/panels/TaggingPanel.css +0 -4
- package/src/components/resource/panels/TaggingPanel.tsx +2 -10
- package/src/components/resource/panels/UnifiedAnnotationsPanel.css +0 -4
- package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +7 -2
- package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +48 -50
- package/src/components/resource/panels/__tests__/AssistShell.test.tsx +11 -6
- package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +89 -0
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +1 -2
- package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +44 -36
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +41 -1
- package/src/components/resource/panels/__tests__/ReferencesPanel.headless.test.tsx +1 -1
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +67 -54
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +185 -7
- package/src/components/resource/panels/__tests__/TagEntry.test.tsx +0 -1
- package/src/components/settings/SettingsPanel.css +0 -4
- package/src/features/auth/auth.css +2 -26
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +0 -65
- package/src/features/resource-compose/components/ResourceComposePage.tsx +17 -130
- package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +1 -76
- package/src/features/resource-compose/state/compose-page-state-unit.ts +5 -48
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +55 -0
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +29 -0
- package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +53 -3
- package/src/features/resource-discovery/state/discover-state-unit.ts +29 -8
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +71 -15
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +166 -71
- package/src/features/resource-viewer/hooks/__tests__/useResourceViewedReport.test.tsx +63 -0
- package/src/features/resource-viewer/hooks/useResourceViewedReport.ts +33 -0
- package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +2 -2
- package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +1 -1
- package/src/styles/core/buttons.css +3 -1
- package/src/styles/core/forms.css +35 -29
- package/src/styles/core/indicators.css +0 -4
- package/src/styles/core/inputs.css +0 -4
- package/src/styles/core/progress.css +2 -34
- package/src/styles/core/sliders.css +0 -4
- package/src/styles/core/toggles.css +0 -4
- package/src/styles/features/resource-discovery.css +13 -0
- package/src/styles/features/resource-viewer.css +0 -42
- package/src/styles/features/resource.css +0 -4
- package/src/styles/motivations/motivation-assessment.css +2 -2
- package/src/styles/panels/history-panel.css +0 -40
- package/src/styles/panels/user-panel.css +0 -3
- package/src/styles/patterns/panel-helpers.css +0 -27
- package/src/styles/patterns/panel-sections.css +0 -59
- package/src/styles/patterns/panels-base.css +0 -32
- package/translations/ar.json +84 -24
- package/translations/bn.json +84 -24
- package/translations/cs.json +84 -24
- package/translations/da.json +84 -24
- package/translations/de.json +84 -24
- package/translations/el.json +84 -24
- package/translations/en.json +84 -24
- package/translations/es.json +84 -24
- package/translations/fa.json +84 -24
- package/translations/fi.json +84 -24
- package/translations/fr.json +84 -24
- package/translations/he.json +84 -24
- package/translations/hi.json +84 -24
- package/translations/id.json +84 -24
- package/translations/it.json +84 -24
- package/translations/ja.json +84 -24
- package/translations/ko.json +84 -24
- package/translations/ms.json +84 -24
- package/translations/nl.json +84 -24
- package/translations/no.json +84 -24
- package/translations/pl.json +84 -24
- package/translations/pt.json +84 -24
- package/translations/ro.json +84 -24
- package/translations/sv.json +84 -24
- package/translations/th.json +84 -24
- package/translations/tr.json +84 -24
- package/translations/uk.json +84 -24
- package/translations/vi.json +84 -24
- package/translations/zh.json +84 -24
- package/dist/PdfAnnotationCanvas.client-6ZSF6ZTJ.js.map +0 -1
- package/dist/PdfAnnotationCanvas.client-JCJMXWWJ.css.map +0 -1
- package/dist/ar-YTUUGK2O.js.map +0 -1
- package/dist/bn-ASGNGPMD.js.map +0 -1
- package/dist/chunk-BTUG3VJJ.js.map +0 -1
- package/dist/chunk-L3WKRWP3.js.map +0 -1
- package/dist/chunk-O23TLLXW.js.map +0 -1
- package/dist/chunk-OBQOZCJE.js.map +0 -1
- package/dist/chunk-QT7LYM72.js.map +0 -1
- package/dist/chunk-VXASXU4K.js.map +0 -1
- package/dist/chunk-XUDKYAVC.js +0 -21
- package/dist/chunk-XUDKYAVC.js.map +0 -1
- package/dist/cs-WMYVAOZY.js.map +0 -1
- package/dist/da-FSHHN4D6.js.map +0 -1
- package/dist/de-FJFO3TPT.js.map +0 -1
- package/dist/el-XOH4QIAG.js.map +0 -1
- package/dist/en-3FCBW3YD.js.map +0 -1
- package/dist/es-HDX4QI7E.js.map +0 -1
- package/dist/fa-DJ6WTFTJ.js.map +0 -1
- package/dist/fi-4S7H7W7U.js.map +0 -1
- package/dist/fr-6UJSYHXC.js.map +0 -1
- package/dist/he-ZZJOHJX2.js.map +0 -1
- package/dist/hi-HZJTAW7U.js.map +0 -1
- package/dist/id-E3I6ILEM.js.map +0 -1
- package/dist/index.css.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/integrations/css-modules-helper.js.map +0 -1
- package/dist/integrations/styled-components-theme.js.map +0 -1
- package/dist/it-ULAPAD7U.js.map +0 -1
- package/dist/ja-SAHZQ4CZ.js.map +0 -1
- package/dist/ko-DFU2ADQ4.js.map +0 -1
- package/dist/ms-NWL76XNT.js.map +0 -1
- package/dist/nl-ATCM76WN.js.map +0 -1
- package/dist/no-UIAQ5RJF.js.map +0 -1
- package/dist/pl-NOECQDXD.js.map +0 -1
- package/dist/pt-SVWIIUPC.js.map +0 -1
- package/dist/ro-NR2DRTZG.js.map +0 -1
- package/dist/sv-STVJ37JP.js.map +0 -1
- package/dist/test-utils.css.map +0 -1
- package/dist/test-utils.js.map +0 -1
- package/dist/th-UWQR4K54.js.map +0 -1
- package/dist/tr-WNXZSD27.js.map +0 -1
- package/dist/uk-SJRMB47Y.js.map +0 -1
- package/dist/vi-TMRQFES2.js.map +0 -1
- package/dist/zh-QOL3LYEM.js.map +0 -1
- package/src/components/modals/ResourceSearchModal.tsx +0 -224
- package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +0 -159
- package/src/integrations/tailwind-plugin.cjs +0 -224
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
4
|
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
|
|
5
|
-
import type { GatheredContext } from '@semiont/core';
|
|
5
|
+
import type { GatheredContext, CollaboratorEntry } from '@semiont/core';
|
|
6
6
|
import { uuidV4 } from '@semiont/core';
|
|
7
7
|
import { useSemiont } from '../../session/SemiontProvider';
|
|
8
8
|
import { useObservable } from '../../hooks/useObservable';
|
|
@@ -12,16 +12,28 @@ import { ConfigureGenerationStep } from './ConfigureGenerationStep';
|
|
|
12
12
|
import type { GenerationConfig } from './ConfigureGenerationStep';
|
|
13
13
|
import { ConfigureSearchStep } from './ConfigureSearchStep';
|
|
14
14
|
import type { SearchConfig } from './ConfigureSearchStep';
|
|
15
|
+
import type { GenerationDraft } from './ConfigureGenerationStep';
|
|
15
16
|
import { SearchResultsStep } from './SearchResultsStep';
|
|
17
|
+
import { ComposeStep } from './ComposeStep';
|
|
18
|
+
import type { ComposeDraft, ComposeParams } from './ComposeStep';
|
|
19
|
+
import { DiscardPrompt } from './DiscardPrompt';
|
|
20
|
+
import { useLineNumbers } from '../../contexts/LineNumbersContext';
|
|
16
21
|
import type { ScoredResult } from './SearchResultsStep';
|
|
17
22
|
|
|
18
23
|
type WizardStep =
|
|
19
24
|
| { step: 'gather' }
|
|
20
25
|
| { step: 'configure-search' }
|
|
21
26
|
| { step: 'search-results'; results: ScoredResult[] }
|
|
22
|
-
| { step: 'configure-generation' }
|
|
27
|
+
| { step: 'configure-generation' }
|
|
28
|
+
| { step: 'compose' };
|
|
23
29
|
|
|
24
30
|
export interface ReferenceWizardModalProps {
|
|
31
|
+
/**
|
|
32
|
+
* Roster entry serving `generation`, forwarded to ConfigureGenerationStep so
|
|
33
|
+
* the max-length control is bounded by the model's real output ceiling.
|
|
34
|
+
* Optional: absent means today's default bounds (INFERENCE-LIMITS-EXPOSURE D3).
|
|
35
|
+
*/
|
|
36
|
+
generationAgent?: CollaboratorEntry;
|
|
25
37
|
isOpen: boolean;
|
|
26
38
|
onClose: () => void;
|
|
27
39
|
/** The annotation being resolved */
|
|
@@ -32,6 +44,12 @@ export interface ReferenceWizardModalProps {
|
|
|
32
44
|
defaultTitle: string;
|
|
33
45
|
/** Entity types from the annotation */
|
|
34
46
|
entityTypes: string[];
|
|
47
|
+
/**
|
|
48
|
+
* The source resource's display name — a page fact (the wizard opens FROM
|
|
49
|
+
* that resource), shown in the gather skeleton's source line before the
|
|
50
|
+
* gathered context can say it itself.
|
|
51
|
+
*/
|
|
52
|
+
resourceName?: string;
|
|
35
53
|
/** Current locale for generation defaults */
|
|
36
54
|
locale: string;
|
|
37
55
|
/** Gathered context state */
|
|
@@ -41,21 +59,36 @@ export interface ReferenceWizardModalProps {
|
|
|
41
59
|
/** Callbacks */
|
|
42
60
|
onGenerateSubmit: (referenceId: string, config: GenerationConfig) => void;
|
|
43
61
|
onLinkResource: (referenceId: string, targetResourceId: string) => void;
|
|
44
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Create-and-link (COMPOSE-IN-MODAL): the host runs `yield.resource` then
|
|
64
|
+
* `bind.body` and settles the promise; rejection keeps the modal open with
|
|
65
|
+
* the compose footer re-enabled. Replaces the old navigate-to-page flow.
|
|
66
|
+
*/
|
|
67
|
+
onComposeSubmit: (referenceId: string, params: ComposeParams) => Promise<void>;
|
|
68
|
+
/** Picker vocabulary for compose when the reference fixed no entity types. */
|
|
69
|
+
entityTypeOptions?: string[];
|
|
70
|
+
/** Editor hover delay for the compose step's CodeMirror. */
|
|
71
|
+
hoverDelayMs?: number;
|
|
45
72
|
/** Translation strings */
|
|
46
73
|
translations: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
searchResultsTitle: string;
|
|
74
|
+
/** The ONE title, all steps — the flow is resolving a reference; the
|
|
75
|
+
strategy band below says where in it you are. */
|
|
76
|
+
resolveTitle: string;
|
|
51
77
|
sourceContextLabel: string;
|
|
52
78
|
connectionsLabel: string;
|
|
53
79
|
citedByLabel: string;
|
|
80
|
+
graphPaneTitle: string;
|
|
81
|
+
graphEmpty: string;
|
|
82
|
+
resourceLinkLabel: string;
|
|
83
|
+
corpusPaneTitle: string;
|
|
84
|
+
corpusEmpty: string;
|
|
85
|
+
excludedReceipt: string;
|
|
86
|
+
machineRead: string;
|
|
54
87
|
userHintLabel: string;
|
|
88
|
+
userHintEffect: string;
|
|
55
89
|
userHintPlaceholder: string;
|
|
56
90
|
loadingContext: string;
|
|
57
91
|
failedContext: string;
|
|
58
|
-
cancel: string;
|
|
59
92
|
search: string;
|
|
60
93
|
searching: string;
|
|
61
94
|
generate: string;
|
|
@@ -67,6 +100,7 @@ export interface ReferenceWizardModalProps {
|
|
|
67
100
|
noResults: string;
|
|
68
101
|
resourceTitle: string;
|
|
69
102
|
resourceTitlePlaceholder: string;
|
|
103
|
+
saveLocation: string;
|
|
70
104
|
additionalInstructions: string;
|
|
71
105
|
additionalInstructionsPlaceholder: string;
|
|
72
106
|
language: string;
|
|
@@ -76,9 +110,18 @@ export interface ReferenceWizardModalProps {
|
|
|
76
110
|
creativityCreative: string;
|
|
77
111
|
maxLength: string;
|
|
78
112
|
maxLengthHelp: string;
|
|
113
|
+
maxLengthCeiling: string;
|
|
79
114
|
maxResults: string;
|
|
80
115
|
semanticScoring: string;
|
|
81
116
|
semanticScoringHelp: string;
|
|
117
|
+
searchFailed: string;
|
|
118
|
+
entityTypes: string;
|
|
119
|
+
contentLabel: string;
|
|
120
|
+
createAndLink: string;
|
|
121
|
+
creatingAndLinking: string;
|
|
122
|
+
discardDraftPrompt: string;
|
|
123
|
+
discardDraft: string;
|
|
124
|
+
keepEditing: string;
|
|
82
125
|
};
|
|
83
126
|
}
|
|
84
127
|
|
|
@@ -89,26 +132,62 @@ export function ReferenceWizardModal({
|
|
|
89
132
|
resourceId,
|
|
90
133
|
defaultTitle,
|
|
91
134
|
entityTypes,
|
|
135
|
+
resourceName,
|
|
92
136
|
locale,
|
|
93
137
|
context,
|
|
94
138
|
contextLoading,
|
|
95
139
|
contextError,
|
|
96
140
|
onGenerateSubmit,
|
|
97
141
|
onLinkResource,
|
|
98
|
-
|
|
142
|
+
onComposeSubmit,
|
|
143
|
+
entityTypeOptions = [],
|
|
144
|
+
hoverDelayMs = 300,
|
|
99
145
|
translations: t,
|
|
146
|
+
generationAgent,
|
|
100
147
|
}: ReferenceWizardModalProps) {
|
|
101
148
|
const session = useObservable(useSemiont().activeSession$);
|
|
102
149
|
const [wizardStep, setWizardStep] = useState<WizardStep>({ step: 'gather' });
|
|
150
|
+
// Both step drafts live HERE, not in the steps (WIZARD-NAVIGATION D3). Stepping
|
|
151
|
+
// back unmounts a step; if the step owned its values, Back would silently discard
|
|
152
|
+
// everything typed — which is exactly what it used to do.
|
|
153
|
+
const [searchConfig, setSearchConfig] = useState<SearchConfig>({ limit: 10, useSemanticScoring: true });
|
|
154
|
+
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>({
|
|
155
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
156
|
+
temperature: 0.7, maxTokensText: '500',
|
|
157
|
+
});
|
|
103
158
|
const [isSearching, setIsSearching] = useState(false);
|
|
159
|
+
const [searchError, setSearchError] = useState<string | null>(null);
|
|
104
160
|
const [userHint, setUserHint] = useState('');
|
|
161
|
+
const freshComposeDraft = (): ComposeDraft => ({
|
|
162
|
+
name: defaultTitle, storagePath: '', content: '', entityTypes: [], language: locale,
|
|
163
|
+
});
|
|
164
|
+
const [composeDraft, setComposeDraft] = useState<ComposeDraft>(freshComposeDraft);
|
|
165
|
+
const [showDiscardPrompt, setShowDiscardPrompt] = useState(false);
|
|
166
|
+
// The editor consumes the shared display setting; the step itself stays
|
|
167
|
+
// provider-free, so the wizard resolves it and passes it down.
|
|
168
|
+
const { showLineNumbers } = useLineNumbers();
|
|
169
|
+
|
|
170
|
+
// The dirty baseline is what was SEEDED, not the live prop: defaultTitle
|
|
171
|
+
// derives from observable wizard state and can re-emit while the modal is
|
|
172
|
+
// open; an untouched draft must not read as dirty because the baseline
|
|
173
|
+
// moved under it.
|
|
174
|
+
const seededTitle = useRef(defaultTitle);
|
|
105
175
|
|
|
106
176
|
// Reset to gather step when modal opens
|
|
107
177
|
useEffect(() => {
|
|
108
178
|
if (isOpen) {
|
|
179
|
+
seededTitle.current = defaultTitle;
|
|
109
180
|
setWizardStep({ step: 'gather' });
|
|
181
|
+
setSearchConfig({ limit: 10, useSemanticScoring: true });
|
|
182
|
+
setGenerationDraft({
|
|
183
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
184
|
+
temperature: 0.7, maxTokensText: '500',
|
|
185
|
+
});
|
|
110
186
|
setIsSearching(false);
|
|
187
|
+
setSearchError(null);
|
|
111
188
|
setUserHint('');
|
|
189
|
+
setComposeDraft(freshComposeDraft());
|
|
190
|
+
setShowDiscardPrompt(false);
|
|
112
191
|
}
|
|
113
192
|
}, [isOpen]);
|
|
114
193
|
|
|
@@ -121,29 +200,98 @@ export function ReferenceWizardModal({
|
|
|
121
200
|
}
|
|
122
201
|
});
|
|
123
202
|
|
|
203
|
+
// …and to failures, same scoping. A refused emit (/bus/emit 4xx), a matcher
|
|
204
|
+
// error, and the match unit's timeout all land here — without this
|
|
205
|
+
// subscription every one of them left the button on "Searching…" forever.
|
|
206
|
+
useEventSubscription('match:search-failed', (event) => {
|
|
207
|
+
if (!isOpen) return;
|
|
208
|
+
if (annotationId && event.referenceId === annotationId) {
|
|
209
|
+
setIsSearching(false);
|
|
210
|
+
setSearchError(event.error);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
124
214
|
const handleBind = useCallback(() => {
|
|
125
215
|
setWizardStep({ step: 'configure-search' });
|
|
126
216
|
}, []);
|
|
127
217
|
|
|
218
|
+
/**
|
|
219
|
+
* The gather step's Hint, placed where the schema says it lives.
|
|
220
|
+
*
|
|
221
|
+
* Two defects, one line. (1) Search and compose each built this inline and
|
|
222
|
+
* generation did not, so picking the AI path silently discarded what the user had
|
|
223
|
+
* typed — and then showed them an empty "Additional Instructions" box.
|
|
224
|
+
* (2) Both existing sites wrote `{ ...context, userHint }`, a TOP-LEVEL key
|
|
225
|
+
* `GatheredContext` does not define; `GatheredContext.json` puts it at
|
|
226
|
+
* `focus.userHint` ("hint to supplement or replace the selected text for search and
|
|
227
|
+
* generation"). So the hint was misplaced on every path, not just missing on one.
|
|
228
|
+
*
|
|
229
|
+
* Both consumers read it: the matcher folds it into its search term and its
|
|
230
|
+
* LLM-scoring passage (matcher.ts, since #911), and generation's prompt builder
|
|
231
|
+
* renders it in the annotation section (resource-generation.ts).
|
|
232
|
+
*/
|
|
233
|
+
const contextWithHint = !context
|
|
234
|
+
? null
|
|
235
|
+
: userHint
|
|
236
|
+
? { ...context, focus: { ...context.focus, userHint } }
|
|
237
|
+
: context;
|
|
238
|
+
|
|
128
239
|
const handleGenerate = useCallback(() => {
|
|
129
240
|
setWizardStep({ step: 'configure-generation' });
|
|
130
241
|
}, []);
|
|
131
242
|
|
|
132
243
|
const handleCompose = useCallback(() => {
|
|
133
244
|
if (!context || !annotationId || !resourceId) return;
|
|
134
|
-
|
|
135
|
-
|
|
245
|
+
setWizardStep({ step: 'compose' });
|
|
246
|
+
}, [context, annotationId, resourceId]);
|
|
247
|
+
|
|
248
|
+
const handleComposeSubmit = useCallback(async (params: ComposeParams) => {
|
|
249
|
+
if (!annotationId) return;
|
|
250
|
+
// Rejection propagates to ComposeStep (footer re-enables); the host
|
|
251
|
+
// surfaces the error. Success closes UNCONDITIONALLY — the dirty guard
|
|
252
|
+
// protects dismissal, not completion.
|
|
253
|
+
await onComposeSubmit(annotationId, params);
|
|
254
|
+
onClose();
|
|
255
|
+
}, [annotationId, onComposeSubmit, onClose]);
|
|
256
|
+
|
|
257
|
+
// D4 (widened by GATHER-AT-THE-TOP): a modal dies on ✕/Escape/backdrop, but
|
|
258
|
+
// typed work must not die with it — WHEREVER the user currently is (drafts
|
|
259
|
+
// survive stepping away, so the guard must too). Typed text only (D5):
|
|
260
|
+
// seeded titles, toggles, and sliders never nag.
|
|
261
|
+
const draftDirty =
|
|
262
|
+
composeDraft.content.trim() !== '' ||
|
|
263
|
+
composeDraft.storagePath.trim() !== '' ||
|
|
264
|
+
composeDraft.name !== seededTitle.current ||
|
|
265
|
+
generationDraft.title !== seededTitle.current ||
|
|
266
|
+
generationDraft.storagePath.trim() !== '' ||
|
|
267
|
+
generationDraft.prompt.trim() !== '';
|
|
268
|
+
const handleDismiss = useCallback(() => {
|
|
269
|
+
if (draftDirty) {
|
|
270
|
+
setShowDiscardPrompt(true);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
136
273
|
onClose();
|
|
137
|
-
}, [
|
|
274
|
+
}, [draftDirty, onClose]);
|
|
138
275
|
|
|
139
276
|
const handleBackToGather = useCallback(() => {
|
|
140
277
|
setWizardStep({ step: 'gather' });
|
|
141
278
|
}, []);
|
|
142
279
|
|
|
280
|
+
// The strategy steps stack evidence + step content in ONE scroll pane. On
|
|
281
|
+
// entry, start at the BOTTOM: the step's own content (form, results) shows
|
|
282
|
+
// in full, the evidence tucks up under the modal top, reachable by
|
|
283
|
+
// scrolling up. jsdom has no layout (scrollHeight 0), so this is a no-op
|
|
284
|
+
// in tests — the same posture as the viewer's guarded scrolls.
|
|
285
|
+
const stepScrollRef = useRef<HTMLDivElement>(null);
|
|
286
|
+
useEffect(() => {
|
|
287
|
+
const el = stepScrollRef.current;
|
|
288
|
+
if (el) el.scrollTop = el.scrollHeight;
|
|
289
|
+
}, [wizardStep.step]);
|
|
290
|
+
|
|
143
291
|
const handleSearchSubmit = useCallback((config: SearchConfig) => {
|
|
144
|
-
if (!annotationId || !
|
|
292
|
+
if (!annotationId || !contextWithHint || !resourceId) return;
|
|
145
293
|
setIsSearching(true);
|
|
146
|
-
|
|
294
|
+
setSearchError(null);
|
|
147
295
|
session?.client.match.requestSearch({
|
|
148
296
|
correlationId: uuidV4(),
|
|
149
297
|
resourceId,
|
|
@@ -153,7 +301,7 @@ export function ReferenceWizardModal({
|
|
|
153
301
|
useSemanticScoring: config.useSemanticScoring,
|
|
154
302
|
});
|
|
155
303
|
// Stay on configure-search until results arrive (subscription above handles transition)
|
|
156
|
-
}, [annotationId, resourceId,
|
|
304
|
+
}, [annotationId, resourceId, contextWithHint, session]);
|
|
157
305
|
|
|
158
306
|
const handleGenerateSubmit = useCallback((config: GenerationConfig) => {
|
|
159
307
|
if (!annotationId) return;
|
|
@@ -167,18 +315,29 @@ export function ReferenceWizardModal({
|
|
|
167
315
|
onClose();
|
|
168
316
|
}, [annotationId, onLinkResource, onClose]);
|
|
169
317
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
318
|
+
// The evidence display's translations — shared by the gather step and the
|
|
319
|
+
// strategy steps, which keep the context in view (display-only, GFR A2)
|
|
320
|
+
// above their forms rather than navigating away from it.
|
|
321
|
+
const displayTranslations = {
|
|
322
|
+
loadingContext: t.loadingContext,
|
|
323
|
+
failedContext: t.failedContext,
|
|
324
|
+
sourceContextLabel: t.sourceContextLabel,
|
|
325
|
+
connectionsLabel: t.connectionsLabel,
|
|
326
|
+
citedByLabel: t.citedByLabel,
|
|
327
|
+
graphPaneTitle: t.graphPaneTitle,
|
|
328
|
+
graphEmpty: t.graphEmpty,
|
|
329
|
+
resourceLinkLabel: t.resourceLinkLabel,
|
|
330
|
+
corpusPaneTitle: t.corpusPaneTitle,
|
|
331
|
+
corpusEmpty: t.corpusEmpty,
|
|
332
|
+
excludedReceipt: t.excludedReceipt,
|
|
333
|
+
machineRead: t.machineRead,
|
|
334
|
+
score: t.score,
|
|
335
|
+
};
|
|
336
|
+
|
|
178
337
|
|
|
179
338
|
return (
|
|
180
339
|
<Transition appear show={isOpen}>
|
|
181
|
-
<Dialog as="div" className="semiont-search-modal" onClose={
|
|
340
|
+
<Dialog as="div" className="semiont-search-modal" onClose={handleDismiss}>
|
|
182
341
|
{/* Backdrop */}
|
|
183
342
|
<TransitionChild
|
|
184
343
|
enter="ease-out duration-200"
|
|
@@ -202,13 +361,15 @@ export function ReferenceWizardModal({
|
|
|
202
361
|
leaveFrom="opacity-100 scale-100"
|
|
203
362
|
leaveTo="opacity-0 scale-95"
|
|
204
363
|
>
|
|
205
|
-
|
|
364
|
+
{/* Every step shows the evidence display now, so every step is
|
|
365
|
+
wide and gets the gather layout (flex column, capped height). */}
|
|
366
|
+
<DialogPanel className="semiont-search-modal__panel semiont-search-modal__panel--with-border semiont-search-modal__panel--gather semiont-search-modal__panel--wide">
|
|
206
367
|
<div className="semiont-search-modal__header">
|
|
207
368
|
<DialogTitle className="semiont-search-modal__title">
|
|
208
|
-
{
|
|
369
|
+
{t.resolveTitle}
|
|
209
370
|
</DialogTitle>
|
|
210
371
|
<button
|
|
211
|
-
onClick={
|
|
372
|
+
onClick={handleDismiss}
|
|
212
373
|
className="semiont-search-modal__close-button"
|
|
213
374
|
aria-label="Close"
|
|
214
375
|
>
|
|
@@ -216,44 +377,96 @@ export function ReferenceWizardModal({
|
|
|
216
377
|
</button>
|
|
217
378
|
</div>
|
|
218
379
|
|
|
380
|
+
{showDiscardPrompt && (
|
|
381
|
+
<DiscardPrompt
|
|
382
|
+
prompt={t.discardDraftPrompt}
|
|
383
|
+
discardLabel={t.discardDraft}
|
|
384
|
+
keepLabel={t.keepEditing}
|
|
385
|
+
onDiscard={() => { setShowDiscardPrompt(false); onClose(); }}
|
|
386
|
+
onKeepEditing={() => setShowDiscardPrompt(false)}
|
|
387
|
+
/>
|
|
388
|
+
)}
|
|
389
|
+
|
|
219
390
|
{wizardStep.step === 'gather' && (
|
|
220
391
|
<GatherContextStep
|
|
221
392
|
context={context}
|
|
222
393
|
contextLoading={contextLoading}
|
|
223
394
|
contextError={contextError}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
395
|
+
pending={{ exact: defaultTitle, entityTypes, ...(resourceName ? { resourceName } : {}) }}
|
|
396
|
+
annotate={{
|
|
397
|
+
userHint,
|
|
398
|
+
onUserHintChange: setUserHint,
|
|
399
|
+
onBind: handleBind,
|
|
400
|
+
onGenerate: handleGenerate,
|
|
401
|
+
onCompose: handleCompose,
|
|
402
|
+
translations: {
|
|
403
|
+
search: t.search,
|
|
404
|
+
generate: t.generate,
|
|
405
|
+
compose: t.compose,
|
|
406
|
+
resolutionStrategyLabel: t.resolutionStrategyLabel,
|
|
407
|
+
userHintLabel: t.userHintLabel,
|
|
408
|
+
userHintEffect: t.userHintEffect,
|
|
409
|
+
userHintPlaceholder: t.userHintPlaceholder,
|
|
410
|
+
},
|
|
411
|
+
}}
|
|
412
|
+
translations={displayTranslations}
|
|
413
|
+
/>
|
|
414
|
+
)}
|
|
415
|
+
|
|
416
|
+
{wizardStep.step === 'compose' && context && (
|
|
417
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
418
|
+
<GatherContextStep
|
|
419
|
+
context={context}
|
|
420
|
+
contextLoading={contextLoading}
|
|
421
|
+
contextError={contextError}
|
|
422
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `✍️ ${t.compose}` }}
|
|
423
|
+
translations={displayTranslations}
|
|
424
|
+
/>
|
|
425
|
+
<ComposeStep
|
|
426
|
+
draft={composeDraft}
|
|
427
|
+
onDraftChange={(patch) => setComposeDraft((d) => ({ ...d, ...patch }))}
|
|
428
|
+
referenceEntityTypes={entityTypes}
|
|
429
|
+
entityTypeOptions={entityTypeOptions}
|
|
430
|
+
showLineNumbers={showLineNumbers}
|
|
431
|
+
hoverDelayMs={hoverDelayMs}
|
|
432
|
+
onBack={handleBackToGather}
|
|
433
|
+
onCompose={handleComposeSubmit}
|
|
229
434
|
translations={{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
generate: t.generate,
|
|
240
|
-
compose: t.compose,
|
|
241
|
-
resolutionStrategyLabel: t.resolutionStrategyLabel,
|
|
435
|
+
resourceTitle: t.resourceTitle,
|
|
436
|
+
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
437
|
+
saveLocation: t.saveLocation,
|
|
438
|
+
entityTypes: t.entityTypes,
|
|
439
|
+
language: t.language,
|
|
440
|
+
contentLabel: t.contentLabel,
|
|
441
|
+
back: t.back,
|
|
442
|
+
createAndLink: t.createAndLink,
|
|
443
|
+
creatingAndLinking: t.creatingAndLinking,
|
|
242
444
|
}}
|
|
243
445
|
/>
|
|
446
|
+
</div>
|
|
244
447
|
)}
|
|
245
448
|
|
|
246
449
|
{wizardStep.step === 'configure-generation' && context && (
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
locale={locale}
|
|
450
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
451
|
+
<GatherContextStep
|
|
250
452
|
context={context}
|
|
453
|
+
contextLoading={contextLoading}
|
|
454
|
+
contextError={contextError}
|
|
455
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `✨ ${t.generate}` }}
|
|
456
|
+
translations={displayTranslations}
|
|
457
|
+
/>
|
|
458
|
+
<ConfigureGenerationStep
|
|
459
|
+
{...(generationAgent ? { generationAgent } : {})}
|
|
460
|
+
{...(userHint ? { hintEcho: { label: t.userHintLabel, value: userHint } } : {})}
|
|
461
|
+
context={contextWithHint ?? context}
|
|
462
|
+
config={generationDraft}
|
|
463
|
+
onConfigChange={setGenerationDraft}
|
|
251
464
|
onBack={handleBackToGather}
|
|
252
|
-
onCancel={onClose}
|
|
253
465
|
onGenerate={handleGenerateSubmit}
|
|
254
466
|
translations={{
|
|
255
467
|
resourceTitle: t.resourceTitle,
|
|
256
468
|
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
469
|
+
saveLocation: t.saveLocation,
|
|
257
470
|
additionalInstructions: t.additionalInstructions,
|
|
258
471
|
additionalInstructionsPlaceholder: t.additionalInstructionsPlaceholder,
|
|
259
472
|
language: t.language,
|
|
@@ -263,51 +476,65 @@ export function ReferenceWizardModal({
|
|
|
263
476
|
creativityCreative: t.creativityCreative,
|
|
264
477
|
maxLength: t.maxLength,
|
|
265
478
|
maxLengthHelp: t.maxLengthHelp,
|
|
266
|
-
|
|
479
|
+
maxLengthCeiling: t.maxLengthCeiling,
|
|
267
480
|
back: t.back,
|
|
268
481
|
generate: t.generate,
|
|
269
482
|
}}
|
|
270
483
|
/>
|
|
484
|
+
</div>
|
|
271
485
|
)}
|
|
272
486
|
|
|
273
487
|
{wizardStep.step === 'configure-search' && (
|
|
488
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
489
|
+
<GatherContextStep
|
|
490
|
+
context={context}
|
|
491
|
+
contextLoading={contextLoading}
|
|
492
|
+
contextError={contextError}
|
|
493
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `🔍 ${t.search}` }}
|
|
494
|
+
translations={displayTranslations}
|
|
495
|
+
/>
|
|
274
496
|
<ConfigureSearchStep
|
|
497
|
+
config={searchConfig}
|
|
498
|
+
{...(userHint ? { hintEcho: { label: t.userHintLabel, value: userHint } } : {})}
|
|
499
|
+
onConfigChange={setSearchConfig}
|
|
275
500
|
isSearching={isSearching}
|
|
501
|
+
searchError={searchError}
|
|
276
502
|
onBack={handleBackToGather}
|
|
277
|
-
onCancel={onClose}
|
|
278
503
|
onSearch={handleSearchSubmit}
|
|
279
504
|
translations={{
|
|
280
505
|
maxResults: t.maxResults,
|
|
281
506
|
semanticScoring: t.semanticScoring,
|
|
282
507
|
semanticScoringHelp: t.semanticScoringHelp,
|
|
283
|
-
cancel: t.cancel,
|
|
284
508
|
back: t.back,
|
|
285
509
|
search: t.search,
|
|
286
510
|
searching: t.searching,
|
|
511
|
+
searchFailed: t.searchFailed,
|
|
287
512
|
}}
|
|
288
513
|
/>
|
|
514
|
+
</div>
|
|
289
515
|
)}
|
|
290
516
|
|
|
291
517
|
{wizardStep.step === 'search-results' && context && (
|
|
518
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
519
|
+
<GatherContextStep
|
|
520
|
+
context={context}
|
|
521
|
+
contextLoading={contextLoading}
|
|
522
|
+
contextError={contextError}
|
|
523
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `🔍 ${t.search}` }}
|
|
524
|
+
translations={displayTranslations}
|
|
525
|
+
/>
|
|
292
526
|
<SearchResultsStep
|
|
293
527
|
results={wizardStep.results}
|
|
294
|
-
context={context}
|
|
295
528
|
onLink={handleLink}
|
|
296
529
|
onBack={handleBackToGather}
|
|
297
|
-
onCancel={onClose}
|
|
298
530
|
translations={{
|
|
299
531
|
noResults: t.noResults,
|
|
300
532
|
link: t.link,
|
|
301
533
|
back: t.back,
|
|
302
|
-
cancel: t.cancel,
|
|
303
534
|
score: t.score,
|
|
304
|
-
sourceContextLabel: t.sourceContextLabel,
|
|
305
|
-
connectionsLabel: t.connectionsLabel,
|
|
306
|
-
citedByLabel: t.citedByLabel,
|
|
307
|
-
userHintLabel: t.userHintLabel,
|
|
308
|
-
userHintPlaceholder: t.userHintPlaceholder,
|
|
309
535
|
}}
|
|
310
536
|
/>
|
|
537
|
+
</div>
|
|
311
538
|
)}
|
|
312
539
|
</DialogPanel>
|
|
313
540
|
</TransitionChild>
|