@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,20 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
|
+
import type { CollaboratorEntry, GatheredContext } from '@semiont/core';
|
|
5
|
+
import type { ResourceGatherOptions } from '@semiont/sdk';
|
|
4
6
|
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
|
|
5
|
-
import { useResourceGather } from '../../hooks/useResourceGather';
|
|
6
7
|
import { ConfigureGatherStep, type ResourceGatherConfig } from './ConfigureGatherStep';
|
|
8
|
+
import { DiscardPrompt } from './DiscardPrompt';
|
|
7
9
|
import { GatherContextStep } from './GatherContextStep';
|
|
8
|
-
import { ConfigureGenerationStep, type GenerationConfig } from './ConfigureGenerationStep';
|
|
10
|
+
import { ConfigureGenerationStep, type GenerationConfig, type GenerationDraft } from './ConfigureGenerationStep';
|
|
9
11
|
|
|
10
12
|
export interface ResourceGenerateModalTranslations {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
reviewTitle: string;
|
|
14
|
-
configureTitle: string;
|
|
15
|
-
next: string;
|
|
16
|
-
back: string;
|
|
17
|
-
cancel: string;
|
|
13
|
+
/** The ONE modal title — names the flow, not a step. */
|
|
14
|
+
title: string;
|
|
18
15
|
// ConfigureGatherStep
|
|
19
16
|
gatherIntro: string;
|
|
20
17
|
includeContent: string;
|
|
@@ -22,16 +19,28 @@ export interface ResourceGenerateModalTranslations {
|
|
|
22
19
|
gatherDepth: string;
|
|
23
20
|
gatherMaxResources: string;
|
|
24
21
|
gatherButton: string;
|
|
25
|
-
|
|
22
|
+
/** Labels the recall chips: every type included until deselected. */
|
|
23
|
+
recallLabel: string;
|
|
24
|
+
/** Affordance on the post-gather receipt row (title/tooltip). */
|
|
25
|
+
editGather: string;
|
|
26
26
|
// GatherContextStep display
|
|
27
27
|
loadingContext: string;
|
|
28
28
|
failedContext: string;
|
|
29
29
|
sourceContextLabel: string;
|
|
30
30
|
connectionsLabel: string;
|
|
31
31
|
citedByLabel: string;
|
|
32
|
+
graphPaneTitle: string;
|
|
33
|
+
graphEmpty: string;
|
|
34
|
+
resourceLinkLabel: string;
|
|
35
|
+
corpusPaneTitle: string;
|
|
36
|
+
corpusEmpty: string;
|
|
37
|
+
excludedReceipt: string;
|
|
38
|
+
machineRead: string;
|
|
39
|
+
score: string;
|
|
32
40
|
// ConfigureGenerationStep
|
|
33
41
|
resourceTitle: string;
|
|
34
42
|
resourceTitlePlaceholder: string;
|
|
43
|
+
saveLocation: string;
|
|
35
44
|
additionalInstructions: string;
|
|
36
45
|
additionalInstructionsPlaceholder: string;
|
|
37
46
|
language: string;
|
|
@@ -41,16 +50,26 @@ export interface ResourceGenerateModalTranslations {
|
|
|
41
50
|
creativityCreative: string;
|
|
42
51
|
maxLength: string;
|
|
43
52
|
maxLengthHelp: string;
|
|
53
|
+
maxLengthCeiling: string;
|
|
44
54
|
generate: string;
|
|
55
|
+
// DiscardPrompt (GATHER-AT-THE-TOP P1)
|
|
56
|
+
discardDraftPrompt: string;
|
|
57
|
+
discardDraft: string;
|
|
58
|
+
keepEditing: string;
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
export interface ResourceGenerateModalProps {
|
|
62
|
+
/**
|
|
63
|
+
* Roster entry serving `generation`, forwarded to ConfigureGenerationStep so
|
|
64
|
+
* the max-length control is bounded by the model's real output ceiling.
|
|
65
|
+
* Optional: absent means today's default bounds (INFERENCE-LIMITS-EXPOSURE D3).
|
|
66
|
+
*/
|
|
67
|
+
generationAgent?: CollaboratorEntry;
|
|
48
68
|
isOpen: boolean;
|
|
49
69
|
onClose: () => void;
|
|
50
70
|
resourceId: string;
|
|
51
71
|
defaultTitle: string;
|
|
52
72
|
locale: string;
|
|
53
|
-
gatherDefaults?: Partial<ResourceGatherConfig>;
|
|
54
73
|
/**
|
|
55
74
|
* Entity types offered in the exclusion picker. Owner-supplied so the
|
|
56
75
|
* modal cannot present a failed load as an empty vocabulary.
|
|
@@ -58,19 +77,38 @@ export interface ResourceGenerateModalProps {
|
|
|
58
77
|
entityTypeOptions?: string[];
|
|
59
78
|
/**
|
|
60
79
|
* Emit the chosen generation config. The parent runs the job
|
|
61
|
-
* (`client.yield.
|
|
62
|
-
* annotation wizard delegates
|
|
80
|
+
* (`client.yield.fromContext(config.context, …)`) — mirrors how the
|
|
81
|
+
* annotation wizard delegates generation to its parent.
|
|
63
82
|
*/
|
|
64
83
|
onGenerateSubmit: (resourceId: string, config: GenerationConfig) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Resource-gather state, verbatim from the SDK's gather unit slots
|
|
86
|
+
* (`gather.resourceContext$` / `resourceLoading$` / `resourceError$`) — the
|
|
87
|
+
* page reads the observables and threads them here, the same shape the
|
|
88
|
+
* reference wizard has always had (FLOW-LIFECYCLE-CONVERGENCE D3/A6). The
|
|
89
|
+
* modal renders this state; it never owns it.
|
|
90
|
+
*/
|
|
91
|
+
gatherContext: GatheredContext | null;
|
|
92
|
+
gatherLoading: boolean;
|
|
93
|
+
gatherError: Error | null;
|
|
94
|
+
/**
|
|
95
|
+
* Run the gather — the page wires `gather.gatherResource(resourceId, …)`.
|
|
96
|
+
* No resourceId in the payload: the owner already holds it. `gatherResource`
|
|
97
|
+
* clears its slots at start, so no reset threading is needed.
|
|
98
|
+
*/
|
|
99
|
+
onGather: (options: ResourceGatherOptions) => void;
|
|
65
100
|
translations: ResourceGenerateModalTranslations;
|
|
66
101
|
}
|
|
67
102
|
|
|
68
|
-
type Step = 'configure-gather' | 'review' | 'configure-generation';
|
|
69
|
-
|
|
70
103
|
/**
|
|
71
|
-
* Resource-generate flow (GENERATE-FROM-BUTTON
|
|
72
|
-
*
|
|
73
|
-
*
|
|
104
|
+
* Resource-generate flow (GENERATE-FROM-BUTTON, folded by GATHER-AT-THE-TOP):
|
|
105
|
+
* one composite stack in a single scroll pane — the gather controls at the
|
|
106
|
+
* top, the gathered `GatheredContext` below them once gather fires, and the
|
|
107
|
+
* generation params beneath the evidence once context arrives. Re-gathering
|
|
108
|
+
* is scroll-up → tweak → Gather; `gatherResource` clears its slots at start,
|
|
109
|
+
* so the evidence refreshes in place. [gather zone] → [evidence] → [act
|
|
110
|
+
* zone]: the same grammar the resolve wizard expresses, whose gather zone
|
|
111
|
+
* happens to be automatic and whose act zone has a strategy choice.
|
|
74
112
|
*/
|
|
75
113
|
export function ResourceGenerateModal({
|
|
76
114
|
isOpen,
|
|
@@ -78,46 +116,128 @@ export function ResourceGenerateModal({
|
|
|
78
116
|
resourceId,
|
|
79
117
|
defaultTitle,
|
|
80
118
|
locale,
|
|
81
|
-
gatherDefaults,
|
|
82
119
|
entityTypeOptions = [],
|
|
83
120
|
onGenerateSubmit,
|
|
121
|
+
gatherContext,
|
|
122
|
+
gatherLoading,
|
|
123
|
+
gatherError,
|
|
124
|
+
onGather,
|
|
84
125
|
translations: t,
|
|
126
|
+
generationAgent,
|
|
85
127
|
}: ResourceGenerateModalProps) {
|
|
86
|
-
|
|
87
|
-
|
|
128
|
+
// Same draft ownership as the wizard (WIZARD-NAVIGATION D3): the step is
|
|
129
|
+
// controlled, so stepping back through this modal keeps what was typed.
|
|
130
|
+
const freshDraft = (): GenerationDraft => ({
|
|
131
|
+
title: defaultTitle, storagePath: '', prompt: '', language: locale,
|
|
132
|
+
temperature: 0.7, maxTokensText: '500',
|
|
133
|
+
});
|
|
134
|
+
const [generationDraft, setGenerationDraft] = useState<GenerationDraft>(freshDraft);
|
|
135
|
+
|
|
136
|
+
// "Has THIS run gathered yet?" — the page's gather slots survive across
|
|
137
|
+
// opens, so a context prop can be stale at open time. Nothing renders below
|
|
138
|
+
// the controls until the user fires a gather in this run.
|
|
139
|
+
const [gatherFired, setGatherFired] = useState(false);
|
|
140
|
+
// The fired snapshot feeds the receipt: what THIS gather actually asked
|
|
141
|
+
// for, exclusions included — not the form's live state, which the user can
|
|
142
|
+
// edit without re-firing.
|
|
143
|
+
const [lastGather, setLastGather] = useState<(ResourceGatherConfig & { excludeEntityTypes: string[] }) | null>(null);
|
|
144
|
+
const [editingGather, setEditingGather] = useState(false);
|
|
145
|
+
const [showDiscardPrompt, setShowDiscardPrompt] = useState(false);
|
|
88
146
|
// Supplied by the owner, which already tracks the list with its failure
|
|
89
147
|
// state. Fetching it here could only model (value | not-yet), so a failed
|
|
90
148
|
// load would render an empty exclusion picker as though the KB had no
|
|
91
149
|
// entity types. See .plans/PANEL-FAILURE-STATES.md
|
|
92
150
|
const [excludeEntityTypes, setExcludeEntityTypes] = useState<string[]>([]);
|
|
93
151
|
|
|
94
|
-
// Reset to the first step
|
|
152
|
+
// Reset to the first step ON OPENING — and re-seed the draft, because
|
|
153
|
+
// `defaultTitle` is the source resource's name and loads asynchronously: the
|
|
154
|
+
// useState initializer ran at mount, which for the real page was before the
|
|
155
|
+
// name existed (GFR A4). Guarded to the false→true transition so a name
|
|
156
|
+
// arriving mid-flow cannot clobber what the user has typed.
|
|
157
|
+
const wasOpen = useRef(false);
|
|
158
|
+
// The dirty baseline is what was SEEDED, not the live prop: defaultTitle
|
|
159
|
+
// can move while the modal is open (the source resource's name loads
|
|
160
|
+
// asynchronously), and an untouched draft must not read as dirty because
|
|
161
|
+
// the baseline moved under it.
|
|
162
|
+
const seededTitle = useRef(defaultTitle);
|
|
95
163
|
useEffect(() => {
|
|
96
|
-
if (isOpen) {
|
|
97
|
-
|
|
164
|
+
if (isOpen && !wasOpen.current) {
|
|
165
|
+
setGatherFired(false);
|
|
166
|
+
setLastGather(null);
|
|
167
|
+
setEditingGather(false);
|
|
98
168
|
setExcludeEntityTypes([]);
|
|
99
|
-
|
|
169
|
+
setGenerationDraft(freshDraft());
|
|
170
|
+
setShowDiscardPrompt(false);
|
|
171
|
+
seededTitle.current = defaultTitle;
|
|
100
172
|
}
|
|
101
|
-
|
|
173
|
+
wasOpen.current = isOpen;
|
|
174
|
+
// freshDraft reads defaultTitle/locale at call time; the effect keys on the
|
|
175
|
+
// OPENING, not on their drift while open.
|
|
176
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
177
|
+
}, [isOpen]);
|
|
102
178
|
|
|
103
179
|
const handleGather = useCallback((config: ResourceGatherConfig) => {
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
setGatherFired(true);
|
|
181
|
+
setLastGather({ ...config, excludeEntityTypes });
|
|
182
|
+
setEditingGather(false);
|
|
183
|
+
onGather({
|
|
106
184
|
...config,
|
|
107
185
|
...(excludeEntityTypes.length ? { excludeEntityTypes } : {}),
|
|
108
186
|
});
|
|
109
|
-
}, [
|
|
187
|
+
}, [onGather, excludeEntityTypes]);
|
|
110
188
|
|
|
111
189
|
const handleGenerate = useCallback((config: GenerationConfig) => {
|
|
112
190
|
onGenerateSubmit(resourceId, config);
|
|
113
191
|
onClose();
|
|
114
192
|
}, [onGenerateSubmit, resourceId, onClose]);
|
|
115
193
|
|
|
116
|
-
|
|
194
|
+
// D4/D5 (GATHER-AT-THE-TOP P1): typed text must not die with a dismissed
|
|
195
|
+
// modal. Toggles, depth, and exclusion picks are cheap to redo and never
|
|
196
|
+
// nag. Generate's completion path above bypasses this — the guard protects
|
|
197
|
+
// dismissal, not completion.
|
|
198
|
+
const draftDirty =
|
|
199
|
+
generationDraft.title !== seededTitle.current ||
|
|
200
|
+
generationDraft.storagePath.trim() !== '' ||
|
|
201
|
+
generationDraft.prompt.trim() !== '';
|
|
202
|
+
const handleDismiss = useCallback(() => {
|
|
203
|
+
if (draftDirty) {
|
|
204
|
+
setShowDiscardPrompt(true);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
onClose();
|
|
208
|
+
}, [draftDirty, onClose]);
|
|
209
|
+
|
|
210
|
+
// The whole stack is ONE scroll pane; when the params zone appears (context
|
|
211
|
+
// arrival — including each re-gather), enter at the BOTTOM so the
|
|
212
|
+
// parameters show in full, the evidence and controls tucked up under the
|
|
213
|
+
// modal top. jsdom has no layout (scrollHeight 0) — no-op in tests.
|
|
214
|
+
const stepScrollRef = useRef<HTMLDivElement>(null);
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
const el = stepScrollRef.current;
|
|
217
|
+
if (el && gatherContext) el.scrollTop = el.scrollHeight;
|
|
218
|
+
}, [gatherContext]);
|
|
219
|
+
|
|
220
|
+
// The evidence zone: what the generation will be grounded in stays in view
|
|
221
|
+
// above the form.
|
|
222
|
+
const displayTranslations = {
|
|
223
|
+
loadingContext: t.loadingContext,
|
|
224
|
+
failedContext: t.failedContext,
|
|
225
|
+
sourceContextLabel: t.sourceContextLabel,
|
|
226
|
+
connectionsLabel: t.connectionsLabel,
|
|
227
|
+
citedByLabel: t.citedByLabel,
|
|
228
|
+
graphPaneTitle: t.graphPaneTitle,
|
|
229
|
+
graphEmpty: t.graphEmpty,
|
|
230
|
+
resourceLinkLabel: t.resourceLinkLabel,
|
|
231
|
+
corpusPaneTitle: t.corpusPaneTitle,
|
|
232
|
+
corpusEmpty: t.corpusEmpty,
|
|
233
|
+
excludedReceipt: t.excludedReceipt,
|
|
234
|
+
machineRead: t.machineRead,
|
|
235
|
+
score: t.score,
|
|
236
|
+
};
|
|
117
237
|
|
|
118
238
|
return (
|
|
119
239
|
<Transition appear show={isOpen}>
|
|
120
|
-
<Dialog as="div" className="semiont-search-modal" onClose={
|
|
240
|
+
<Dialog as="div" className="semiont-search-modal" onClose={handleDismiss}>
|
|
121
241
|
<TransitionChild
|
|
122
242
|
enter="ease-out duration-200"
|
|
123
243
|
enterFrom="opacity-0"
|
|
@@ -139,42 +259,78 @@ export function ResourceGenerateModal({
|
|
|
139
259
|
leaveFrom="opacity-100 scale-100"
|
|
140
260
|
leaveTo="opacity-0 scale-95"
|
|
141
261
|
>
|
|
142
|
-
<DialogPanel className="semiont-search-modal__panel semiont-search-modal__panel--with-border semiont-search-modal__panel--gather">
|
|
262
|
+
<DialogPanel className="semiont-search-modal__panel semiont-search-modal__panel--with-border semiont-search-modal__panel--gather semiont-search-modal__panel--wide">
|
|
143
263
|
<div className="semiont-search-modal__header">
|
|
144
|
-
<DialogTitle className="semiont-search-modal__title">{
|
|
145
|
-
<button onClick={
|
|
264
|
+
<DialogTitle className="semiont-search-modal__title">{t.title}</DialogTitle>
|
|
265
|
+
<button onClick={handleDismiss} className="semiont-search-modal__close-button" aria-label="Close">
|
|
146
266
|
✕
|
|
147
267
|
</button>
|
|
148
268
|
</div>
|
|
149
269
|
|
|
150
|
-
{
|
|
270
|
+
{showDiscardPrompt && (
|
|
271
|
+
<DiscardPrompt
|
|
272
|
+
prompt={t.discardDraftPrompt}
|
|
273
|
+
discardLabel={t.discardDraft}
|
|
274
|
+
keepLabel={t.keepEditing}
|
|
275
|
+
onDiscard={() => { setShowDiscardPrompt(false); onClose(); }}
|
|
276
|
+
onKeepEditing={() => setShowDiscardPrompt(false)}
|
|
277
|
+
/>
|
|
278
|
+
)}
|
|
279
|
+
|
|
280
|
+
<div className="semiont-wizard__step-scroll" ref={stepScrollRef}>
|
|
281
|
+
{/* Once fired, the spent controls fold into a receipt of
|
|
282
|
+
what THIS gather asked for — the evidence leads the
|
|
283
|
+
pane, the parameters stay visible and revisable. The
|
|
284
|
+
form below is HIDDEN, not unmounted, so its values
|
|
285
|
+
survive for the expand path. */}
|
|
286
|
+
{gatherFired && !editingGather && lastGather && (
|
|
287
|
+
<button
|
|
288
|
+
type="button"
|
|
289
|
+
className="semiont-gather-receipt"
|
|
290
|
+
title={t.editGather}
|
|
291
|
+
onClick={() => setEditingGather(true)}
|
|
292
|
+
>
|
|
293
|
+
{[
|
|
294
|
+
`${t.gatherDepth} ${lastGather.depth}`,
|
|
295
|
+
`${t.gatherMaxResources} ${lastGather.maxResources}`,
|
|
296
|
+
...(lastGather.includeContent ? [t.includeContent] : []),
|
|
297
|
+
...(lastGather.includeSummary ? [t.includeSummary] : []),
|
|
298
|
+
...(lastGather.excludeEntityTypes.length
|
|
299
|
+
? [t.excludedReceipt.replace('{{types}}', lastGather.excludeEntityTypes.join(', '))]
|
|
300
|
+
: []),
|
|
301
|
+
].join(' · ')}
|
|
302
|
+
<span aria-hidden="true"> ✎</span>
|
|
303
|
+
</button>
|
|
304
|
+
)}
|
|
305
|
+
<div hidden={gatherFired && !editingGather}>
|
|
151
306
|
<ConfigureGatherStep
|
|
152
|
-
defaults={gatherDefaults}
|
|
153
307
|
onGather={handleGather}
|
|
154
|
-
onCancel={onClose}
|
|
155
308
|
translations={{
|
|
156
309
|
intro: t.gatherIntro,
|
|
157
310
|
includeContent: t.includeContent,
|
|
158
311
|
includeSummary: t.includeSummary,
|
|
159
312
|
depth: t.gatherDepth,
|
|
160
313
|
maxResources: t.gatherMaxResources,
|
|
161
|
-
cancel: t.cancel,
|
|
162
314
|
gather: t.gatherButton,
|
|
163
315
|
}}
|
|
164
316
|
>
|
|
165
317
|
{entityTypeOptions.length > 0 && (
|
|
166
318
|
<div className="semiont-form__field semiont-form__entity-types">
|
|
167
|
-
<label className="semiont-form__label">{t.
|
|
168
|
-
|
|
319
|
+
<label className="semiont-form__label">{t.recallLabel}</label>
|
|
320
|
+
{/* Recall chips — the exclude wire, inverted for the
|
|
321
|
+
UI: every type is IN the recall until crossed off,
|
|
322
|
+
so the state is still the exclude list and a chip
|
|
323
|
+
is included when absent from it. */}
|
|
324
|
+
<div className="semiont-form__recall-chips">
|
|
169
325
|
{entityTypeOptions.map((et) => {
|
|
170
|
-
const
|
|
326
|
+
const isIncluded = !excludeEntityTypes.includes(et);
|
|
171
327
|
return (
|
|
172
328
|
<button
|
|
173
329
|
key={et}
|
|
174
330
|
type="button"
|
|
175
|
-
className="semiont-
|
|
176
|
-
data-
|
|
177
|
-
aria-pressed={
|
|
331
|
+
className="semiont-form__recall-chip"
|
|
332
|
+
data-included={isIncluded}
|
|
333
|
+
aria-pressed={isIncluded}
|
|
178
334
|
onClick={() => setExcludeEntityTypes(prev => prev.includes(et) ? prev.filter(x => x !== et) : [...prev, et])}
|
|
179
335
|
>
|
|
180
336
|
{et}
|
|
@@ -185,75 +341,43 @@ export function ResourceGenerateModal({
|
|
|
185
341
|
</div>
|
|
186
342
|
)}
|
|
187
343
|
</ConfigureGatherStep>
|
|
188
|
-
|
|
344
|
+
</div>
|
|
189
345
|
|
|
190
|
-
|
|
191
|
-
<>
|
|
346
|
+
{gatherFired && (
|
|
192
347
|
<GatherContextStep
|
|
193
|
-
context={
|
|
194
|
-
contextLoading={
|
|
195
|
-
contextError={
|
|
348
|
+
context={gatherContext}
|
|
349
|
+
contextLoading={gatherLoading}
|
|
350
|
+
contextError={gatherError}
|
|
351
|
+
translations={displayTranslations}
|
|
352
|
+
/>
|
|
353
|
+
)}
|
|
354
|
+
|
|
355
|
+
{gatherFired && gatherContext && (
|
|
356
|
+
<ConfigureGenerationStep
|
|
357
|
+
{...(generationAgent ? { generationAgent } : {})}
|
|
358
|
+
context={gatherContext}
|
|
359
|
+
config={generationDraft}
|
|
360
|
+
onConfigChange={setGenerationDraft}
|
|
361
|
+
onGenerate={handleGenerate}
|
|
196
362
|
translations={{
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
363
|
+
resourceTitle: t.resourceTitle,
|
|
364
|
+
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
365
|
+
saveLocation: t.saveLocation,
|
|
366
|
+
additionalInstructions: t.additionalInstructions,
|
|
367
|
+
additionalInstructionsPlaceholder: t.additionalInstructionsPlaceholder,
|
|
368
|
+
language: t.language,
|
|
369
|
+
languageHelp: t.languageHelp,
|
|
370
|
+
creativity: t.creativity,
|
|
371
|
+
creativityFocused: t.creativityFocused,
|
|
372
|
+
creativityCreative: t.creativityCreative,
|
|
373
|
+
maxLength: t.maxLength,
|
|
374
|
+
maxLengthHelp: t.maxLengthHelp,
|
|
375
|
+
maxLengthCeiling: t.maxLengthCeiling,
|
|
376
|
+
generate: t.generate,
|
|
209
377
|
}}
|
|
210
378
|
/>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
type="button"
|
|
214
|
-
onClick={() => setStep('configure-gather')}
|
|
215
|
-
className="semiont-button--secondary semiont-button--flex"
|
|
216
|
-
>
|
|
217
|
-
◀ {t.back}
|
|
218
|
-
</button>
|
|
219
|
-
<button
|
|
220
|
-
type="button"
|
|
221
|
-
onClick={() => setStep('configure-generation')}
|
|
222
|
-
disabled={!context}
|
|
223
|
-
className="semiont-button--primary semiont-button--flex"
|
|
224
|
-
>
|
|
225
|
-
{t.next} ▶
|
|
226
|
-
</button>
|
|
227
|
-
</div>
|
|
228
|
-
</>
|
|
229
|
-
)}
|
|
230
|
-
|
|
231
|
-
{step === 'configure-generation' && context && (
|
|
232
|
-
<ConfigureGenerationStep
|
|
233
|
-
defaultTitle={defaultTitle}
|
|
234
|
-
locale={locale}
|
|
235
|
-
context={context}
|
|
236
|
-
onBack={() => setStep('review')}
|
|
237
|
-
onCancel={onClose}
|
|
238
|
-
onGenerate={handleGenerate}
|
|
239
|
-
translations={{
|
|
240
|
-
resourceTitle: t.resourceTitle,
|
|
241
|
-
resourceTitlePlaceholder: t.resourceTitlePlaceholder,
|
|
242
|
-
additionalInstructions: t.additionalInstructions,
|
|
243
|
-
additionalInstructionsPlaceholder: t.additionalInstructionsPlaceholder,
|
|
244
|
-
language: t.language,
|
|
245
|
-
languageHelp: t.languageHelp,
|
|
246
|
-
creativity: t.creativity,
|
|
247
|
-
creativityFocused: t.creativityFocused,
|
|
248
|
-
creativityCreative: t.creativityCreative,
|
|
249
|
-
maxLength: t.maxLength,
|
|
250
|
-
maxLengthHelp: t.maxLengthHelp,
|
|
251
|
-
cancel: t.cancel,
|
|
252
|
-
back: t.back,
|
|
253
|
-
generate: t.generate,
|
|
254
|
-
}}
|
|
255
|
-
/>
|
|
256
|
-
)}
|
|
379
|
+
)}
|
|
380
|
+
</div>
|
|
257
381
|
</DialogPanel>
|
|
258
382
|
</TransitionChild>
|
|
259
383
|
</div>
|