@@ -18,6 +18,7 @@ import { useDraftGeneration } from "./useDraftGeneration";
1818import { useDraftIntake } from "./useDraftIntake" ;
1919import { useDraftPersistence } from "./useDraftPersistence" ;
2020import { useGuidedRunbook } from "./useGuidedRunbook" ;
21+ import { useWorkspaceArtifacts } from "./useWorkspaceArtifacts" ;
2122import { useWorkspaceClipboardPacks } from "./useWorkspaceClipboardPacks" ;
2223import { ConversationInput } from "./ConversationInput" ;
2324import { WorkspaceDialogs } from "./WorkspaceDialogs" ;
@@ -42,9 +43,6 @@ import { useWorkspaceDerivedArtifacts } from "../../features/workspace/useWorksp
4243import { useWorkspaceCommandBridge } from "../../features/workspace/useWorkspaceCommandBridge" ;
4344import { useWorkspaceDraftState } from "../../features/workspace/useWorkspaceDraftState" ;
4445import {
45- applyResolutionKit ,
46- buildResolutionKitFromWorkspace ,
47- buildSimilarCases ,
4846 compactLines ,
4947 parseCaseIntake ,
5048} from "../../features/workspace/workspaceAssistant" ;
@@ -62,11 +60,9 @@ import type { ContextSource } from "../../types/knowledge";
6260import type {
6361 GuidedRunbookTemplate ,
6462 NextActionRecommendation ,
65- ResolutionKit ,
6663 ResponseLength ,
6764 SavedDraft ,
6865 SimilarCase ,
69- WorkspaceFavorite ,
7066 WorkspacePersonalization ,
7167} from "../../types/workspace" ;
7268import "./DraftTab.css" ;
@@ -330,9 +326,6 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
330326 ConversationEntry [ ]
331327 > ( [ ] ) ;
332328 const [ handoffTouched , setHandoffTouched ] = useState ( false ) ;
333- const [ similarCases , setSimilarCases ] = useState < SimilarCase [ ] > ( [ ] ) ;
334- const [ similarCasesLoading , setSimilarCasesLoading ] = useState ( false ) ;
335- const [ compareCase , setCompareCase ] = useState < SimilarCase | null > ( null ) ;
336329 const [ workspaceRunbookScopeKey , setWorkspaceRunbookScopeKey ] =
337330 useState < string > ( createWorkspaceRunbookScopeKey ) ;
338331 const [ autosaveDraftId , setAutosaveDraftId ] = useState < string | null > ( null ) ;
@@ -538,69 +531,6 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
538531 [ savedDraftId ] ,
539532 ) ;
540533
541- const handleRefreshSimilarCases = useCallback ( async ( ) => {
542- if ( ! similarCasesEnabled ) {
543- setSimilarCases ( [ ] ) ;
544- return ;
545- }
546-
547- const query = [
548- input ,
549- currentTicket ?. summary ,
550- caseIntake . issue ,
551- caseIntake . symptoms ,
552- ]
553- . filter ( ( value ) : value is string => Boolean ( value ?. trim ( ) ) )
554- . join ( " " ) ;
555-
556- if ( ! query . trim ( ) ) {
557- setSimilarCases ( [ ] ) ;
558- return ;
559- }
560-
561- setSimilarCasesLoading ( true ) ;
562- try {
563- const results = await searchDrafts ( query , 20 ) ;
564- const next = buildSimilarCases ( {
565- currentDraftId : savedDraftId ,
566- queryText : query ,
567- drafts : results ,
568- } ) ;
569- setSimilarCases ( next ) ;
570- } finally {
571- setSimilarCasesLoading ( false ) ;
572- }
573- } , [
574- similarCasesEnabled ,
575- input ,
576- currentTicket ?. summary ,
577- caseIntake . issue ,
578- caseIntake . symptoms ,
579- searchDrafts ,
580- savedDraftId ,
581- ] ) ;
582-
583- const handleCompareLastResolution = useCallback ( ( ) => {
584- if ( ! response . trim ( ) ) {
585- showError (
586- "Generate or paste a response before comparing it to a prior resolution" ,
587- ) ;
588- return ;
589- }
590-
591- const bestMatch = similarCases [ 0 ] ;
592- if ( ! bestMatch || ! bestMatch . response_text . trim ( ) ) {
593- showError ( "No similar solved case is ready to compare yet" ) ;
594- return ;
595- }
596-
597- setCompareCase ( bestMatch ) ;
598- void logEvent ( "workspace_compare_last_resolution_opened" , {
599- ticket_id : currentTicketId ,
600- similar_case_id : bestMatch . draft_id ,
601- } ) ;
602- } , [ response , similarCases , showError , logEvent , currentTicketId ] ) ;
603-
604534 const handleApplyTemplate = useCallback ( ( content : string ) => {
605535 setResponse ( content ) ;
606536 } , [ ] ) ;
@@ -697,9 +627,7 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
697627 ...parseCaseIntake ( null ) ,
698628 note_audience : workspacePersonalization . preferred_note_audience ,
699629 } ) ;
700- setSimilarCases ( [ ] ) ;
701- setSimilarCasesLoading ( false ) ;
702- setCompareCase ( null ) ;
630+ resetWorkspaceArtifacts ( ) ;
703631 setGuidedRunbookSession ( null ) ;
704632 setGuidedRunbookNote ( "" ) ;
705633 setRunbookSessionSourceScopeKey ( null ) ;
@@ -835,38 +763,6 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
835763 return ( ) => window . removeEventListener ( "keydown" , handleKeydown ) ;
836764 } , [ viewMode , handlePanelDensityModeChange ] ) ;
837765
838- useEffect ( ( ) => {
839- if ( ! similarCasesEnabled ) {
840- return ;
841- }
842-
843- const query = [
844- input ,
845- caseIntake . issue ,
846- caseIntake . symptoms ,
847- currentTicket ?. summary ,
848- ]
849- . filter ( ( value ) : value is string => Boolean ( value ?. trim ( ) ) )
850- . join ( " " ) ;
851- if ( ! query . trim ( ) ) {
852- setSimilarCases ( [ ] ) ;
853- return ;
854- }
855-
856- const timer = window . setTimeout ( ( ) => {
857- void handleRefreshSimilarCases ( ) ;
858- } , 350 ) ;
859-
860- return ( ) => window . clearTimeout ( timer ) ;
861- } , [
862- similarCasesEnabled ,
863- input ,
864- caseIntake . issue ,
865- caseIntake . symptoms ,
866- currentTicket ?. summary ,
867- handleRefreshSimilarCases ,
868- ] ) ;
869-
870766 const buildDiagnosisJson = useCallback ( ( ) => {
871767 const completedIds = Object . keys ( checklistCompleted ) . filter (
872768 ( id ) => checklistCompleted [ id ] ,
@@ -979,6 +875,45 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
979875 originalResponse,
980876 } ) ;
981877
878+ const {
879+ similarCases,
880+ similarCasesLoading,
881+ compareCase,
882+ setCompareCase,
883+ handleRefreshSimilarCases,
884+ handleCompareLastResolution,
885+ handleCompareSimilarCase,
886+ handleSaveCurrentResolutionKit,
887+ handleApplyResolutionKit,
888+ handleToggleWorkspaceFavorite,
889+ resetWorkspaceArtifacts,
890+ } = useWorkspaceArtifacts ( {
891+ similarCasesEnabled,
892+ input,
893+ response,
894+ currentTicket,
895+ currentTicketId,
896+ caseIntake,
897+ kbDraft,
898+ sources,
899+ savedDraftId,
900+ workspaceFavorites,
901+ searchDrafts,
902+ saveResolutionKit,
903+ saveWorkspaceFavorite,
904+ deleteWorkspaceFavorite,
905+ refreshWorkspaceCatalog,
906+ logEvent,
907+ setResponse,
908+ setOriginalResponse,
909+ setIsResponseEdited,
910+ setCaseIntake,
911+ setDiagnosticNotes,
912+ setPanelDensityMode,
913+ onShowSuccess : showSuccess ,
914+ onShowError : showError ,
915+ } ) ;
916+
982917 const {
983918 pendingSimilarCaseOpen,
984919 setPendingSimilarCaseOpen,
@@ -1061,116 +996,6 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
1061996 onShowError : showError ,
1062997 } ) ;
1063998
1064- const handleSaveCurrentResolutionKit = useCallback ( async ( ) => {
1065- try {
1066- const nextKit = buildResolutionKitFromWorkspace ( {
1067- intake : caseIntake ,
1068- kbDraft,
1069- responseText : response ,
1070- sources,
1071- } ) ;
1072- await saveResolutionKit ( {
1073- ...nextKit ,
1074- response_template : nextKit . response_template ,
1075- checklist_items : nextKit . checklist_items ,
1076- kb_document_ids : nextKit . kb_document_ids ,
1077- } ) ;
1078- await refreshWorkspaceCatalog ( ) ;
1079- void logEvent ( "workspace_resolution_kit_saved" , {
1080- ticket_id : currentTicketId ,
1081- category : nextKit . category ,
1082- } ) ;
1083- showSuccess ( "Saved the current workspace as a resolution kit" ) ;
1084- } catch {
1085- showError ( "Failed to save resolution kit" ) ;
1086- }
1087- } , [
1088- caseIntake ,
1089- kbDraft ,
1090- response ,
1091- sources ,
1092- saveResolutionKit ,
1093- refreshWorkspaceCatalog ,
1094- logEvent ,
1095- currentTicketId ,
1096- showSuccess ,
1097- showError ,
1098- ] ) ;
1099-
1100- const handleApplyResolutionKit = useCallback (
1101- ( kit : ResolutionKit ) => {
1102- const applied = applyResolutionKit ( {
1103- currentInput : input ,
1104- currentResponse : response ,
1105- currentIntake : caseIntake ,
1106- kit,
1107- } ) ;
1108- setResponse ( applied . responseText ) ;
1109- if ( ! response . trim ( ) && applied . responseText ) {
1110- setOriginalResponse ( applied . responseText ) ;
1111- setIsResponseEdited ( false ) ;
1112- }
1113- setCaseIntake ( applied . intake ) ;
1114- setDiagnosticNotes ( ( prev ) =>
1115- compactLines ( [ prev , applied . checklistText ] ) ,
1116- ) ;
1117- setPanelDensityMode ( "focus-intake" ) ;
1118- void logEvent ( "workspace_resolution_kit_applied" , {
1119- ticket_id : currentTicketId ,
1120- kit_id : kit . id ,
1121- category : kit . category ,
1122- } ) ;
1123- showSuccess ( `Applied ${ kit . name } ` ) ;
1124- } ,
1125- [ input , response , caseIntake , logEvent , currentTicketId , showSuccess ] ,
1126- ) ;
1127-
1128- const handleToggleWorkspaceFavorite = useCallback (
1129- async (
1130- kind : WorkspaceFavorite [ "kind" ] ,
1131- resourceId : string ,
1132- label : string ,
1133- metadata ?: Record < string , string > | null ,
1134- ) => {
1135- try {
1136- const existing = workspaceFavorites . find (
1137- ( favorite ) =>
1138- favorite . kind === kind && favorite . resource_id === resourceId ,
1139- ) ;
1140- if ( existing ) {
1141- await deleteWorkspaceFavorite ( existing . id ) ;
1142- showSuccess ( `Removed ${ label } from favorites` ) ;
1143- } else {
1144- await saveWorkspaceFavorite ( {
1145- kind,
1146- label,
1147- resource_id : resourceId ,
1148- metadata : metadata ?? null ,
1149- } ) ;
1150- showSuccess ( `Added ${ label } to favorites` ) ;
1151- }
1152- await refreshWorkspaceCatalog ( ) ;
1153- void logEvent ( "workspace_favorite_toggled" , {
1154- ticket_id : currentTicketId ,
1155- kind,
1156- resource_id : resourceId ,
1157- } ) ;
1158- } catch {
1159- showError ( "Failed to update favorites" ) ;
1160- }
1161- } ,
1162- [
1163- workspaceFavorites ,
1164- deleteWorkspaceFavorite ,
1165- saveWorkspaceFavorite ,
1166- refreshWorkspaceCatalog ,
1167- showSuccess ,
1168- logEvent ,
1169- currentTicketId ,
1170- showError ,
1171- ] ,
1172- ) ;
1173-
1174999 const loadSimilarCaseIntoWorkspace = useCallback (
11751000 async ( similarCase : SimilarCase ) => {
11761001 const fullDraft = await getDraft ( similarCase . draft_id ) ;
@@ -1206,24 +1031,12 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
12061031 logEvent ,
12071032 currentTicketId ,
12081033 requestOpenSimilarCase ,
1034+ setPendingSimilarCaseOpen ,
12091035 showError ,
12101036 showSuccess ,
12111037 ] ,
12121038 ) ;
12131039
1214- const handleCompareSimilarCase = useCallback (
1215- ( similarCase : SimilarCase ) => {
1216- if ( ! response . trim ( ) ) {
1217- showError (
1218- "Generate or paste a response before comparing it to a prior resolution" ,
1219- ) ;
1220- return ;
1221- }
1222- setCompareCase ( similarCase ) ;
1223- } ,
1224- [ response , showError ] ,
1225- ) ;
1226-
12271040 const handleAcceptNextAction = useCallback (
12281041 ( action : NextActionRecommendation ) => {
12291042 void logEvent ( "workspace_next_action_accepted" , {
0 commit comments