@semiont/react-ui 0.5.27 → 0.5.29
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 +3 -3
- package/dist/{PdfAnnotationCanvas.client-EVUPTUWZ.js → PdfAnnotationCanvas.client-LSH3PZPY.js} +32 -5
- package/dist/{ar-OU3DQGC6.js → ar-AZBRADEB.js} +43 -23
- package/dist/{bn-PHWCR6AZ.js → bn-CCEW6AOS.js} +43 -23
- package/dist/{chunk-VXASXU4K.js → chunk-3ZBKCWUZ.js} +1 -1
- package/dist/{chunk-5VDTWRXJ.js → chunk-G4VHL4UA.js} +31 -31
- package/dist/{chunk-PCRRBU7H.js → chunk-SDKFZLEX.js} +43 -23
- package/dist/{cs-NEXYZ62I.js → cs-HXPF2CTE.js} +43 -23
- package/dist/{da-FAT43YCU.js → da-K5NTK7LH.js} +43 -23
- package/dist/{de-KRQ3WBCU.js → de-GMRQEDZI.js} +43 -23
- package/dist/{el-Q4IU3EKC.js → el-EUB4CI4G.js} +43 -23
- package/dist/{en-2KADE7N4.js → en-R5XA26NF.js} +2 -2
- package/dist/{es-2IO3R2MK.js → es-Z32DAZ6W.js} +43 -23
- package/dist/{fa-Q5GOQFXX.js → fa-G7HN6B32.js} +43 -23
- package/dist/{fi-R6NMRWBE.js → fi-3YBLZO7I.js} +43 -23
- package/dist/{fr-QY4D5E6J.js → fr-VUBH7BBS.js} +43 -23
- package/dist/{he-X6Y77XHY.js → he-WQQEY26B.js} +43 -23
- package/dist/{hi-XL7IOEQM.js → hi-HJZ6W4JB.js} +43 -23
- package/dist/{id-QZ4ZZS67.js → id-ZOGZ37MI.js} +43 -23
- package/dist/index.css +279 -74
- package/dist/index.d.ts +318 -393
- package/dist/index.js +2619 -2687
- package/dist/{it-ME2Q7OB6.js → it-DT6UW66F.js} +43 -23
- package/dist/{ja-HX7QASRI.js → ja-RUKQCOLO.js} +43 -23
- package/dist/{ko-EQO5AHAV.js → ko-ZH5ADKZM.js} +43 -23
- package/dist/{ms-UILFSF3I.js → ms-Y2AFPZTU.js} +43 -23
- package/dist/{nl-NNI45PMK.js → nl-OQEWIXNA.js} +43 -23
- package/dist/{no-MAL5F6P6.js → no-KPAYJZWY.js} +43 -23
- package/dist/{pl-4RMY6JAJ.js → pl-WSXK2UUD.js} +43 -23
- package/dist/{pt-VQH2X3QQ.js → pt-NWRJRUCK.js} +43 -23
- package/dist/{ro-XXCQO2OG.js → ro-3CGVMOC6.js} +43 -23
- package/dist/{sv-7Z6EJ6U4.js → sv-HGSEBA7S.js} +43 -23
- package/dist/test-utils.js +16 -7
- package/dist/{th-L3DXXYVQ.js → th-NZ4G352Z.js} +43 -23
- package/dist/{tr-P3DFVLFJ.js → tr-LGGS4DLW.js} +43 -23
- package/dist/{uk-7C5D3PXS.js → uk-AIX536L4.js} +43 -23
- package/dist/{vi-ZLTLEO7P.js → vi-V6CVQZLQ.js} +43 -23
- package/dist/{zh-5FHVWDIN.js → zh-AGKPGI3L.js} +43 -23
- package/package.json +16 -15
- package/src/components/AssistProgress.tsx +36 -2
- package/src/components/CodeMirrorRenderer.tsx +8 -8
- package/src/components/StatusDisplay.tsx +13 -13
- package/src/components/__tests__/AssistProgress.test.tsx +59 -0
- package/src/components/__tests__/StatusDisplay.test.tsx +9 -9
- package/src/components/modals/ComposeStep.tsx +233 -0
- package/src/components/modals/ConfigureGatherStep.tsx +10 -18
- package/src/components/modals/ConfigureGenerationStep.tsx +178 -34
- package/src/components/modals/ConfigureSearchStep.tsx +19 -0
- 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 +252 -59
- package/src/components/modals/ResourceGenerateModal.tsx +225 -112
- package/src/components/modals/SearchModal.css +337 -101
- package/src/components/modals/SearchResultsStep.tsx +61 -68
- package/src/components/modals/WizardFooter.tsx +7 -1
- 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 +206 -8
- package/src/components/modals/__tests__/ConfigureSearchStep.test.tsx +24 -1
- package/src/components/modals/__tests__/GatherContextStep.resource.test.tsx +463 -25
- package/src/components/modals/__tests__/ReferenceWizardModal.test.tsx +442 -39
- package/src/components/modals/__tests__/ResourceGenerateModal.test.tsx +300 -86
- package/src/components/modals/__tests__/SearchResultsStep.test.tsx +61 -0
- package/src/components/modals/__tests__/WizardFooter.test.tsx +116 -9
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +34 -1
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +38 -1
- package/src/components/resource/AnnotateView.tsx +3 -3
- package/src/components/resource/BrowseView.tsx +8 -8
- package/src/components/resource/DownloadFileLink.tsx +1 -1
- package/src/components/resource/ResourceViewer.tsx +4 -4
- package/src/components/resource/__tests__/AnnotateView.embeddable.test.tsx +1 -1
- package/src/components/resource/__tests__/BrowseView.embeddable.test.tsx +1 -1
- package/src/components/resource/__tests__/BrowseView.reference-hover.test.tsx +1 -1
- package/src/components/resource/__tests__/BrowseView.test.tsx +11 -11
- package/src/components/resource/__tests__/download-link.test.tsx +6 -6
- package/src/components/resource/annotate-renderers.tsx +3 -3
- package/src/components/resource/panels/AssistSection.css +35 -0
- package/src/components/resource/panels/ReferenceEntry.tsx +11 -4
- package/src/components/resource/panels/ReferencesPanel.tsx +9 -1
- package/src/components/resource/panels/ResourceInfoPanel.tsx +89 -20
- package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +7 -2
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +41 -0
- package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +1 -1
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +84 -3
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +149 -7
- package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +12 -12
- package/src/features/auth/components/SignInForm.tsx +53 -53
- package/src/features/auth-welcome/state/__tests__/welcome-state-unit.test.ts +2 -2
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +0 -65
- package/src/features/resource-compose/components/ResourceComposePage.tsx +35 -133
- package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +1 -100
- package/src/features/resource-compose/state/compose-page-state-unit.ts +5 -57
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +1 -1
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +2 -2
- package/src/features/resource-discovery/state/discover-state-unit.ts +1 -1
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +73 -17
- package/src/features/resource-viewer/__tests__/generation-options.test.ts +53 -0
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +148 -83
- package/src/features/resource-viewer/generation-options.ts +29 -0
- package/src/styles/core/forms.css +35 -8
- package/src/styles/features/resource-viewer.css +0 -22
- package/src/styles/features/resource.css +0 -4
- package/src/styles/index.css +0 -1
- package/translations/ar.json +42 -22
- package/translations/bn.json +42 -22
- package/translations/cs.json +42 -22
- package/translations/da.json +42 -22
- package/translations/de.json +42 -22
- package/translations/el.json +42 -22
- package/translations/en.json +42 -22
- package/translations/es.json +42 -22
- package/translations/fa.json +42 -22
- package/translations/fi.json +42 -22
- package/translations/fr.json +42 -22
- package/translations/he.json +42 -22
- package/translations/hi.json +42 -22
- package/translations/id.json +42 -22
- package/translations/it.json +42 -22
- package/translations/ja.json +42 -22
- package/translations/ko.json +42 -22
- package/translations/ms.json +42 -22
- package/translations/nl.json +42 -22
- package/translations/no.json +42 -22
- package/translations/pl.json +42 -22
- package/translations/pt.json +42 -22
- package/translations/ro.json +42 -22
- package/translations/sv.json +42 -22
- package/translations/th.json +42 -22
- package/translations/tr.json +42 -22
- package/translations/uk.json +42 -22
- package/translations/vi.json +42 -22
- package/translations/zh.json +42 -22
- package/dist/PdfAnnotationCanvas.client-EVUPTUWZ.js.map +0 -1
- package/dist/PdfAnnotationCanvas.client-TGDPPGXJ.css.map +0 -1
- package/dist/ar-OU3DQGC6.js.map +0 -1
- package/dist/bn-PHWCR6AZ.js.map +0 -1
- package/dist/chunk-5VDTWRXJ.js.map +0 -1
- package/dist/chunk-BTUG3VJJ.js.map +0 -1
- package/dist/chunk-O23TLLXW.js.map +0 -1
- package/dist/chunk-PCRRBU7H.js.map +0 -1
- package/dist/chunk-QT7LYM72.js.map +0 -1
- package/dist/chunk-VXASXU4K.js.map +0 -1
- package/dist/cs-NEXYZ62I.js.map +0 -1
- package/dist/da-FAT43YCU.js.map +0 -1
- package/dist/de-KRQ3WBCU.js.map +0 -1
- package/dist/el-Q4IU3EKC.js.map +0 -1
- package/dist/en-2KADE7N4.js.map +0 -1
- package/dist/es-2IO3R2MK.js.map +0 -1
- package/dist/fa-Q5GOQFXX.js.map +0 -1
- package/dist/fi-R6NMRWBE.js.map +0 -1
- package/dist/fr-QY4D5E6J.js.map +0 -1
- package/dist/he-X6Y77XHY.js.map +0 -1
- package/dist/hi-XL7IOEQM.js.map +0 -1
- package/dist/id-QZ4ZZS67.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-ME2Q7OB6.js.map +0 -1
- package/dist/ja-HX7QASRI.js.map +0 -1
- package/dist/ko-EQO5AHAV.js.map +0 -1
- package/dist/ms-UILFSF3I.js.map +0 -1
- package/dist/nl-NNI45PMK.js.map +0 -1
- package/dist/no-MAL5F6P6.js.map +0 -1
- package/dist/pl-4RMY6JAJ.js.map +0 -1
- package/dist/pt-VQH2X3QQ.js.map +0 -1
- package/dist/ro-XXCQO2OG.js.map +0 -1
- package/dist/sv-7Z6EJ6U4.js.map +0 -1
- package/dist/test-utils.css.map +0 -1
- package/dist/test-utils.js.map +0 -1
- package/dist/th-L3DXXYVQ.js.map +0 -1
- package/dist/tr-P3DFVLFJ.js.map +0 -1
- package/dist/uk-7C5D3PXS.js.map +0 -1
- package/dist/vi-ZLTLEO7P.js.map +0 -1
- package/dist/zh-5FHVWDIN.js.map +0 -1
- package/src/components/modals/ResourceSearchModal.tsx +0 -224
- package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +0 -163
- package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +0 -137
- package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +0 -41
- package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +0 -148
- package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +0 -117
- package/src/features/admin-exchange/components/AdminExchangePage.tsx +0 -117
- package/src/features/admin-exchange/components/ExportCard.tsx +0 -35
- package/src/features/admin-exchange/components/ImportCard.tsx +0 -183
- package/src/features/admin-exchange/components/ImportProgress.tsx +0 -80
- package/src/features/admin-exchange/state/__tests__/exchange-state-unit.test.ts +0 -185
- package/src/features/admin-exchange/state/exchange-state-unit.ts +0 -133
- package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +0 -118
- package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +0 -118
- package/src/styles/features/exchange.css +0 -374
|
@@ -1,6 +1,6 @@
|
|
|
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
5
|
import type { GatheredContext, CollaboratorEntry } from '@semiont/core';
|
|
6
6
|
import { uuidV4 } from '@semiont/core';
|
|
@@ -8,19 +8,24 @@ import { useSemiont } from '../../session/SemiontProvider';
|
|
|
8
8
|
import { useObservable } from '../../hooks/useObservable';
|
|
9
9
|
import { useEventSubscription } from '../../contexts/useEventSubscription';
|
|
10
10
|
import { GatherContextStep } from './GatherContextStep';
|
|
11
|
-
import { ConfigureGenerationStep } from './ConfigureGenerationStep';
|
|
11
|
+
import { ConfigureGenerationStep, freshGenerationDraft } from './ConfigureGenerationStep';
|
|
12
12
|
import type { GenerationConfig } from './ConfigureGenerationStep';
|
|
13
13
|
import { ConfigureSearchStep } from './ConfigureSearchStep';
|
|
14
14
|
import type { SearchConfig } from './ConfigureSearchStep';
|
|
15
15
|
import type { GenerationDraft } from './ConfigureGenerationStep';
|
|
16
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';
|
|
17
21
|
import type { ScoredResult } from './SearchResultsStep';
|
|
18
22
|
|
|
19
23
|
type WizardStep =
|
|
20
24
|
| { step: 'gather' }
|
|
21
25
|
| { step: 'configure-search' }
|
|
22
26
|
| { step: 'search-results'; results: ScoredResult[] }
|
|
23
|
-
| { step: 'configure-generation' }
|
|
27
|
+
| { step: 'configure-generation' }
|
|
28
|
+
| { step: 'compose' };
|
|
24
29
|
|
|
25
30
|
export interface ReferenceWizardModalProps {
|
|
26
31
|
/**
|
|
@@ -37,8 +42,16 @@ export interface ReferenceWizardModalProps {
|
|
|
37
42
|
resourceId: string | null;
|
|
38
43
|
/** Default title (selected text) */
|
|
39
44
|
defaultTitle: string;
|
|
45
|
+
/** Folder of the source resource, so new files land beside it (D11). */
|
|
46
|
+
defaultFolder?: string;
|
|
40
47
|
/** Entity types from the annotation */
|
|
41
48
|
entityTypes: string[];
|
|
49
|
+
/**
|
|
50
|
+
* The source resource's display name — a page fact (the wizard opens FROM
|
|
51
|
+
* that resource), shown in the gather skeleton's source line before the
|
|
52
|
+
* gathered context can say it itself.
|
|
53
|
+
*/
|
|
54
|
+
resourceName?: string;
|
|
42
55
|
/** Current locale for generation defaults */
|
|
43
56
|
locale: string;
|
|
44
57
|
/** Gathered context state */
|
|
@@ -48,21 +61,36 @@ export interface ReferenceWizardModalProps {
|
|
|
48
61
|
/** Callbacks */
|
|
49
62
|
onGenerateSubmit: (referenceId: string, config: GenerationConfig) => void;
|
|
50
63
|
onLinkResource: (referenceId: string, targetResourceId: string) => void;
|
|
51
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Create-and-link (COMPOSE-IN-MODAL): the host runs `yield.resource` then
|
|
66
|
+
* `bind.body` and settles the promise; rejection keeps the modal open with
|
|
67
|
+
* the compose footer re-enabled. Replaces the old navigate-to-page flow.
|
|
68
|
+
*/
|
|
69
|
+
onComposeSubmit: (referenceId: string, params: ComposeParams) => Promise<void>;
|
|
70
|
+
/** Picker vocabulary for compose when the reference fixed no entity types. */
|
|
71
|
+
entityTypeOptions?: string[];
|
|
72
|
+
/** Editor hover delay for the compose step's CodeMirror. */
|
|
73
|
+
hoverDelayMs?: number;
|
|
52
74
|
/** Translation strings */
|
|
53
75
|
translations: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
searchResultsTitle: string;
|
|
76
|
+
/** The ONE title, all steps — the flow is resolving a reference; the
|
|
77
|
+
strategy band below says where in it you are. */
|
|
78
|
+
resolveTitle: string;
|
|
58
79
|
sourceContextLabel: string;
|
|
59
80
|
connectionsLabel: string;
|
|
60
81
|
citedByLabel: string;
|
|
82
|
+
graphPaneTitle: string;
|
|
83
|
+
graphEmpty: string;
|
|
84
|
+
resourceLinkLabel: string;
|
|
85
|
+
corpusPaneTitle: string;
|
|
86
|
+
corpusEmpty: string;
|
|
87
|
+
excludedReceipt: string;
|
|
88
|
+
machineRead: string;
|
|
61
89
|
userHintLabel: string;
|
|
90
|
+
userHintEffect: string;
|
|
62
91
|
userHintPlaceholder: string;
|
|
63
92
|
loadingContext: string;
|
|
64
93
|
failedContext: string;
|
|
65
|
-
cancel: string;
|
|
66
94
|
search: string;
|
|
67
95
|
searching: string;
|
|
68
96
|
generate: string;
|
|
@@ -74,6 +102,7 @@ export interface ReferenceWizardModalProps {
|
|
|
74
102
|
noResults: string;
|
|
75
103
|
resourceTitle: string;
|
|
76
104
|
resourceTitlePlaceholder: string;
|
|
105
|
+
saveLocation: string;
|
|
77
106
|
additionalInstructions: string;
|
|
78
107
|
additionalInstructionsPlaceholder: string;
|
|
79
108
|
language: string;
|
|
@@ -84,9 +113,19 @@ export interface ReferenceWizardModalProps {
|
|
|
84
113
|
maxLength: string;
|
|
85
114
|
maxLengthHelp: string;
|
|
86
115
|
maxLengthCeiling: string;
|
|
116
|
+
outputFormat: string;
|
|
117
|
+
formatExtensionMismatch: string;
|
|
87
118
|
maxResults: string;
|
|
88
119
|
semanticScoring: string;
|
|
89
120
|
semanticScoringHelp: string;
|
|
121
|
+
searchFailed: string;
|
|
122
|
+
entityTypes: string;
|
|
123
|
+
contentLabel: string;
|
|
124
|
+
createAndLink: string;
|
|
125
|
+
creatingAndLinking: string;
|
|
126
|
+
discardDraftPrompt: string;
|
|
127
|
+
discardDraft: string;
|
|
128
|
+
keepEditing: string;
|
|
90
129
|
};
|
|
91
130
|
}
|
|
92
131
|
|
|
@@ -96,14 +135,18 @@ export function ReferenceWizardModal({
|
|
|
96
135
|
annotationId,
|
|
97
136
|
resourceId,
|
|
98
137
|
defaultTitle,
|
|
138
|
+
defaultFolder,
|
|
99
139
|
entityTypes,
|
|
140
|
+
resourceName,
|
|
100
141
|
locale,
|
|
101
142
|
context,
|
|
102
143
|
contextLoading,
|
|
103
144
|
contextError,
|
|
104
145
|
onGenerateSubmit,
|
|
105
146
|
onLinkResource,
|
|
106
|
-
|
|
147
|
+
onComposeSubmit,
|
|
148
|
+
entityTypeOptions = [],
|
|
149
|
+
hoverDelayMs = 300,
|
|
107
150
|
translations: t,
|
|
108
151
|
generationAgent,
|
|
109
152
|
}: ReferenceWizardModalProps) {
|
|
@@ -113,24 +156,39 @@ export function ReferenceWizardModal({
|
|
|
113
156
|
// back unmounts a step; if the step owned its values, Back would silently discard
|
|
114
157
|
// everything typed — which is exactly what it used to do.
|
|
115
158
|
const [searchConfig, setSearchConfig] = useState<SearchConfig>({ limit: 10, useSemanticScoring: true });
|
|
116
|
-
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
});
|
|
159
|
+
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>(
|
|
160
|
+
() => freshGenerationDraft(defaultTitle, locale),
|
|
161
|
+
);
|
|
120
162
|
const [isSearching, setIsSearching] = useState(false);
|
|
163
|
+
const [searchError, setSearchError] = useState<string | null>(null);
|
|
121
164
|
const [userHint, setUserHint] = useState('');
|
|
165
|
+
const freshComposeDraft = (): ComposeDraft => ({
|
|
166
|
+
name: defaultTitle, storagePath: '', content: '', entityTypes: [], language: locale,
|
|
167
|
+
});
|
|
168
|
+
const [composeDraft, setComposeDraft] = useState<ComposeDraft>(freshComposeDraft);
|
|
169
|
+
const [showDiscardPrompt, setShowDiscardPrompt] = useState(false);
|
|
170
|
+
// The editor consumes the shared display setting; the step itself stays
|
|
171
|
+
// provider-free, so the wizard resolves it and passes it down.
|
|
172
|
+
const { showLineNumbers } = useLineNumbers();
|
|
173
|
+
|
|
174
|
+
// The dirty baseline is what was SEEDED, not the live prop: defaultTitle
|
|
175
|
+
// derives from observable wizard state and can re-emit while the modal is
|
|
176
|
+
// open; an untouched draft must not read as dirty because the baseline
|
|
177
|
+
// moved under it.
|
|
178
|
+
const seededTitle = useRef(defaultTitle);
|
|
122
179
|
|
|
123
180
|
// Reset to gather step when modal opens
|
|
124
181
|
useEffect(() => {
|
|
125
182
|
if (isOpen) {
|
|
183
|
+
seededTitle.current = defaultTitle;
|
|
126
184
|
setWizardStep({ step: 'gather' });
|
|
127
185
|
setSearchConfig({ limit: 10, useSemanticScoring: true });
|
|
128
|
-
setGenerationDraft(
|
|
129
|
-
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
130
|
-
temperature: 0.7, maxTokensText: '500',
|
|
131
|
-
});
|
|
186
|
+
setGenerationDraft(freshGenerationDraft(defaultTitle, locale));
|
|
132
187
|
setIsSearching(false);
|
|
188
|
+
setSearchError(null);
|
|
133
189
|
setUserHint('');
|
|
190
|
+
setComposeDraft(freshComposeDraft());
|
|
191
|
+
setShowDiscardPrompt(false);
|
|
134
192
|
}
|
|
135
193
|
}, [isOpen]);
|
|
136
194
|
|
|
@@ -143,6 +201,17 @@ export function ReferenceWizardModal({
|
|
|
143
201
|
}
|
|
144
202
|
});
|
|
145
203
|
|
|
204
|
+
// …and to failures, same scoping. A refused emit (/bus/emit 4xx), a matcher
|
|
205
|
+
// error, and the match unit's timeout all land here — without this
|
|
206
|
+
// subscription every one of them left the button on "Searching…" forever.
|
|
207
|
+
useEventSubscription('match:search-failed', (event) => {
|
|
208
|
+
if (!isOpen) return;
|
|
209
|
+
if (annotationId && event.referenceId === annotationId) {
|
|
210
|
+
setIsSearching(false);
|
|
211
|
+
setSearchError(event.error);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
146
215
|
const handleBind = useCallback(() => {
|
|
147
216
|
setWizardStep({ step: 'configure-search' });
|
|
148
217
|
}, []);
|
|
@@ -158,9 +227,9 @@ export function ReferenceWizardModal({
|
|
|
158
227
|
* `focus.userHint` ("hint to supplement or replace the selected text for search and
|
|
159
228
|
* generation"). So the hint was misplaced on every path, not just missing on one.
|
|
160
229
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
230
|
+
* Both consumers read it: the matcher folds it into its search term and its
|
|
231
|
+
* LLM-scoring passage (matcher.ts, since #911), and generation's prompt builder
|
|
232
|
+
* renders it in the annotation section (resource-generation.ts).
|
|
164
233
|
*/
|
|
165
234
|
const contextWithHint = !context
|
|
166
235
|
? null
|
|
@@ -173,18 +242,57 @@ export function ReferenceWizardModal({
|
|
|
173
242
|
}, []);
|
|
174
243
|
|
|
175
244
|
const handleCompose = useCallback(() => {
|
|
176
|
-
if (!
|
|
177
|
-
|
|
245
|
+
if (!context || !annotationId || !resourceId) return;
|
|
246
|
+
setWizardStep({ step: 'compose' });
|
|
247
|
+
}, [context, annotationId, resourceId]);
|
|
248
|
+
|
|
249
|
+
const handleComposeSubmit = useCallback(async (params: ComposeParams) => {
|
|
250
|
+
if (!annotationId) return;
|
|
251
|
+
// Rejection propagates to ComposeStep (footer re-enables); the host
|
|
252
|
+
// surfaces the error. Success closes UNCONDITIONALLY — the dirty guard
|
|
253
|
+
// protects dismissal, not completion.
|
|
254
|
+
await onComposeSubmit(annotationId, params);
|
|
255
|
+
onClose();
|
|
256
|
+
}, [annotationId, onComposeSubmit, onClose]);
|
|
257
|
+
|
|
258
|
+
// D4 (widened by GATHER-AT-THE-TOP): a modal dies on ✕/Escape/backdrop, but
|
|
259
|
+
// typed work must not die with it — WHEREVER the user currently is (drafts
|
|
260
|
+
// survive stepping away, so the guard must too). Typed text only (D5):
|
|
261
|
+
// seeded titles, toggles, and sliders never nag.
|
|
262
|
+
const draftDirty =
|
|
263
|
+
composeDraft.content.trim() !== '' ||
|
|
264
|
+
composeDraft.storagePath.trim() !== '' ||
|
|
265
|
+
composeDraft.name !== seededTitle.current ||
|
|
266
|
+
generationDraft.title !== seededTitle.current ||
|
|
267
|
+
generationDraft.storagePath.trim() !== '' ||
|
|
268
|
+
generationDraft.prompt.trim() !== '';
|
|
269
|
+
const handleDismiss = useCallback(() => {
|
|
270
|
+
if (draftDirty) {
|
|
271
|
+
setShowDiscardPrompt(true);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
178
274
|
onClose();
|
|
179
|
-
}, [
|
|
275
|
+
}, [draftDirty, onClose]);
|
|
180
276
|
|
|
181
277
|
const handleBackToGather = useCallback(() => {
|
|
182
278
|
setWizardStep({ step: 'gather' });
|
|
183
279
|
}, []);
|
|
184
280
|
|
|
281
|
+
// The strategy steps stack evidence + step content in ONE scroll pane. On
|
|
282
|
+
// entry, start at the BOTTOM: the step's own content (form, results) shows
|
|
283
|
+
// in full, the evidence tucks up under the modal top, reachable by
|
|
284
|
+
// scrolling up. jsdom has no layout (scrollHeight 0), so this is a no-op
|
|
285
|
+
// in tests — the same posture as the viewer's guarded scrolls.
|
|
286
|
+
const stepScrollRef = useRef<HTMLDivElement>(null);
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
const el = stepScrollRef.current;
|
|
289
|
+
if (el) el.scrollTop = el.scrollHeight;
|
|
290
|
+
}, [wizardStep.step]);
|
|
291
|
+
|
|
185
292
|
const handleSearchSubmit = useCallback((config: SearchConfig) => {
|
|
186
293
|
if (!annotationId || !contextWithHint || !resourceId) return;
|
|
187
294
|
setIsSearching(true);
|
|
295
|
+
setSearchError(null);
|
|
188
296
|
session?.client.match.requestSearch({
|
|
189
297
|
correlationId: uuidV4(),
|
|
190
298
|
resourceId,
|
|
@@ -208,18 +316,29 @@ export function ReferenceWizardModal({
|
|
|
208
316
|
onClose();
|
|
209
317
|
}, [annotationId, onLinkResource, onClose]);
|
|
210
318
|
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
319
|
+
// The evidence display's translations — shared by the gather step and the
|
|
320
|
+
// strategy steps, which keep the context in view (display-only, GFR A2)
|
|
321
|
+
// above their forms rather than navigating away from it.
|
|
322
|
+
const displayTranslations = {
|
|
323
|
+
loadingContext: t.loadingContext,
|
|
324
|
+
failedContext: t.failedContext,
|
|
325
|
+
sourceContextLabel: t.sourceContextLabel,
|
|
326
|
+
connectionsLabel: t.connectionsLabel,
|
|
327
|
+
citedByLabel: t.citedByLabel,
|
|
328
|
+
graphPaneTitle: t.graphPaneTitle,
|
|
329
|
+
graphEmpty: t.graphEmpty,
|
|
330
|
+
resourceLinkLabel: t.resourceLinkLabel,
|
|
331
|
+
corpusPaneTitle: t.corpusPaneTitle,
|
|
332
|
+
corpusEmpty: t.corpusEmpty,
|
|
333
|
+
excludedReceipt: t.excludedReceipt,
|
|
334
|
+
machineRead: t.machineRead,
|
|
335
|
+
score: t.score,
|
|
336
|
+
};
|
|
337
|
+
|
|
219
338
|
|
|
220
339
|
return (
|
|
221
340
|
<Transition appear show={isOpen}>
|
|
222
|
-
<Dialog as="div" className="semiont-search-modal" onClose={
|
|
341
|
+
<Dialog as="div" className="semiont-search-modal" onClose={handleDismiss}>
|
|
223
342
|
{/* Backdrop */}
|
|
224
343
|
<TransitionChild
|
|
225
344
|
enter="ease-out duration-200"
|
|
@@ -243,13 +362,15 @@ export function ReferenceWizardModal({
|
|
|
243
362
|
leaveFrom="opacity-100 scale-100"
|
|
244
363
|
leaveTo="opacity-0 scale-95"
|
|
245
364
|
>
|
|
246
|
-
|
|
365
|
+
{/* Every step shows the evidence display now, so every step is
|
|
366
|
+
wide and gets the gather layout (flex column, capped height). */}
|
|
367
|
+
<DialogPanel className="semiont-search-modal__panel semiont-search-modal__panel--with-border semiont-search-modal__panel--gather semiont-search-modal__panel--wide">
|
|
247
368
|
<div className="semiont-search-modal__header">
|
|
248
369
|
<DialogTitle className="semiont-search-modal__title">
|
|
249
|
-
{
|
|
370
|
+
{t.resolveTitle}
|
|
250
371
|
</DialogTitle>
|
|
251
372
|
<button
|
|
252
|
-
onClick={
|
|
373
|
+
onClick={handleDismiss}
|
|
253
374
|
className="semiont-search-modal__close-button"
|
|
254
375
|
aria-label="Close"
|
|
255
376
|
>
|
|
@@ -257,44 +378,98 @@ export function ReferenceWizardModal({
|
|
|
257
378
|
</button>
|
|
258
379
|
</div>
|
|
259
380
|
|
|
381
|
+
{showDiscardPrompt && (
|
|
382
|
+
<DiscardPrompt
|
|
383
|
+
prompt={t.discardDraftPrompt}
|
|
384
|
+
discardLabel={t.discardDraft}
|
|
385
|
+
keepLabel={t.keepEditing}
|
|
386
|
+
onDiscard={() => { setShowDiscardPrompt(false); onClose(); }}
|
|
387
|
+
onKeepEditing={() => setShowDiscardPrompt(false)}
|
|
388
|
+
/>
|
|
389
|
+
)}
|
|
390
|
+
|
|
260
391
|
{wizardStep.step === 'gather' && (
|
|
261
392
|
<GatherContextStep
|
|
262
393
|
context={context}
|
|
263
394
|
contextLoading={contextLoading}
|
|
264
395
|
contextError={contextError}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
396
|
+
pending={{ exact: defaultTitle, entityTypes, ...(resourceName ? { resourceName } : {}) }}
|
|
397
|
+
annotate={{
|
|
398
|
+
userHint,
|
|
399
|
+
onUserHintChange: setUserHint,
|
|
400
|
+
onBind: handleBind,
|
|
401
|
+
onGenerate: handleGenerate,
|
|
402
|
+
onCompose: handleCompose,
|
|
403
|
+
translations: {
|
|
404
|
+
search: t.search,
|
|
405
|
+
generate: t.generate,
|
|
406
|
+
compose: t.compose,
|
|
407
|
+
resolutionStrategyLabel: t.resolutionStrategyLabel,
|
|
408
|
+
userHintLabel: t.userHintLabel,
|
|
409
|
+
userHintEffect: t.userHintEffect,
|
|
410
|
+
userHintPlaceholder: t.userHintPlaceholder,
|
|
411
|
+
},
|
|
412
|
+
}}
|
|
413
|
+
translations={displayTranslations}
|
|
414
|
+
/>
|
|
415
|
+
)}
|
|
416
|
+
|
|
417
|
+
{wizardStep.step === 'compose' && context && (
|
|
418
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
419
|
+
<GatherContextStep
|
|
420
|
+
context={context}
|
|
421
|
+
contextLoading={contextLoading}
|
|
422
|
+
contextError={contextError}
|
|
423
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `✍️ ${t.compose}` }}
|
|
424
|
+
translations={displayTranslations}
|
|
425
|
+
/>
|
|
426
|
+
<ComposeStep
|
|
427
|
+
draft={composeDraft}
|
|
428
|
+
onDraftChange={(patch) => setComposeDraft((d) => ({ ...d, ...patch }))}
|
|
429
|
+
defaultFolder={defaultFolder}
|
|
430
|
+
referenceEntityTypes={entityTypes}
|
|
431
|
+
entityTypeOptions={entityTypeOptions}
|
|
432
|
+
showLineNumbers={showLineNumbers}
|
|
433
|
+
hoverDelayMs={hoverDelayMs}
|
|
434
|
+
onBack={handleBackToGather}
|
|
435
|
+
onCompose={handleComposeSubmit}
|
|
270
436
|
translations={{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
generate: t.generate,
|
|
281
|
-
compose: t.compose,
|
|
282
|
-
resolutionStrategyLabel: t.resolutionStrategyLabel,
|
|
437
|
+
resourceTitle: t.resourceTitle,
|
|
438
|
+
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
439
|
+
saveLocation: t.saveLocation,
|
|
440
|
+
entityTypes: t.entityTypes,
|
|
441
|
+
language: t.language,
|
|
442
|
+
contentLabel: t.contentLabel,
|
|
443
|
+
back: t.back,
|
|
444
|
+
createAndLink: t.createAndLink,
|
|
445
|
+
creatingAndLinking: t.creatingAndLinking,
|
|
283
446
|
}}
|
|
284
447
|
/>
|
|
448
|
+
</div>
|
|
285
449
|
)}
|
|
286
450
|
|
|
287
451
|
{wizardStep.step === 'configure-generation' && context && (
|
|
452
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
453
|
+
<GatherContextStep
|
|
454
|
+
context={context}
|
|
455
|
+
contextLoading={contextLoading}
|
|
456
|
+
contextError={contextError}
|
|
457
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `✨ ${t.generate}` }}
|
|
458
|
+
translations={displayTranslations}
|
|
459
|
+
/>
|
|
288
460
|
<ConfigureGenerationStep
|
|
289
461
|
{...(generationAgent ? { generationAgent } : {})}
|
|
462
|
+
{...(userHint ? { hintEcho: { label: t.userHintLabel, value: userHint } } : {})}
|
|
290
463
|
context={contextWithHint ?? context}
|
|
291
464
|
config={generationDraft}
|
|
292
465
|
onConfigChange={setGenerationDraft}
|
|
466
|
+
defaultFolder={defaultFolder}
|
|
293
467
|
onBack={handleBackToGather}
|
|
294
468
|
onGenerate={handleGenerateSubmit}
|
|
295
469
|
translations={{
|
|
296
470
|
resourceTitle: t.resourceTitle,
|
|
297
471
|
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
472
|
+
saveLocation: t.saveLocation,
|
|
298
473
|
additionalInstructions: t.additionalInstructions,
|
|
299
474
|
additionalInstructionsPlaceholder: t.additionalInstructionsPlaceholder,
|
|
300
475
|
language: t.language,
|
|
@@ -305,17 +480,30 @@ export function ReferenceWizardModal({
|
|
|
305
480
|
maxLength: t.maxLength,
|
|
306
481
|
maxLengthHelp: t.maxLengthHelp,
|
|
307
482
|
maxLengthCeiling: t.maxLengthCeiling,
|
|
483
|
+
outputFormat: t.outputFormat,
|
|
484
|
+
formatExtensionMismatch: t.formatExtensionMismatch,
|
|
308
485
|
back: t.back,
|
|
309
486
|
generate: t.generate,
|
|
310
487
|
}}
|
|
311
488
|
/>
|
|
489
|
+
</div>
|
|
312
490
|
)}
|
|
313
491
|
|
|
314
492
|
{wizardStep.step === 'configure-search' && (
|
|
493
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
494
|
+
<GatherContextStep
|
|
495
|
+
context={context}
|
|
496
|
+
contextLoading={contextLoading}
|
|
497
|
+
contextError={contextError}
|
|
498
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `🔍 ${t.search}` }}
|
|
499
|
+
translations={displayTranslations}
|
|
500
|
+
/>
|
|
315
501
|
<ConfigureSearchStep
|
|
316
502
|
config={searchConfig}
|
|
503
|
+
{...(userHint ? { hintEcho: { label: t.userHintLabel, value: userHint } } : {})}
|
|
317
504
|
onConfigChange={setSearchConfig}
|
|
318
505
|
isSearching={isSearching}
|
|
506
|
+
searchError={searchError}
|
|
319
507
|
onBack={handleBackToGather}
|
|
320
508
|
onSearch={handleSearchSubmit}
|
|
321
509
|
translations={{
|
|
@@ -325,14 +513,23 @@ export function ReferenceWizardModal({
|
|
|
325
513
|
back: t.back,
|
|
326
514
|
search: t.search,
|
|
327
515
|
searching: t.searching,
|
|
516
|
+
searchFailed: t.searchFailed,
|
|
328
517
|
}}
|
|
329
518
|
/>
|
|
519
|
+
</div>
|
|
330
520
|
)}
|
|
331
521
|
|
|
332
522
|
{wizardStep.step === 'search-results' && context && (
|
|
523
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
524
|
+
<GatherContextStep
|
|
525
|
+
context={context}
|
|
526
|
+
contextLoading={contextLoading}
|
|
527
|
+
contextError={contextError}
|
|
528
|
+
chosenStrategy={{ label: t.resolutionStrategyLabel, value: `🔍 ${t.search}` }}
|
|
529
|
+
translations={displayTranslations}
|
|
530
|
+
/>
|
|
333
531
|
<SearchResultsStep
|
|
334
532
|
results={wizardStep.results}
|
|
335
|
-
context={context}
|
|
336
533
|
onLink={handleLink}
|
|
337
534
|
onBack={handleBackToGather}
|
|
338
535
|
translations={{
|
|
@@ -340,13 +537,9 @@ export function ReferenceWizardModal({
|
|
|
340
537
|
link: t.link,
|
|
341
538
|
back: t.back,
|
|
342
539
|
score: t.score,
|
|
343
|
-
sourceContextLabel: t.sourceContextLabel,
|
|
344
|
-
connectionsLabel: t.connectionsLabel,
|
|
345
|
-
citedByLabel: t.citedByLabel,
|
|
346
|
-
userHintLabel: t.userHintLabel,
|
|
347
|
-
userHintPlaceholder: t.userHintPlaceholder,
|
|
348
540
|
}}
|
|
349
541
|
/>
|
|
542
|
+
</div>
|
|
350
543
|
)}
|
|
351
544
|
</DialogPanel>
|
|
352
545
|
</TransitionChild>
|