@@ -18,10 +18,10 @@ import AddExternalFrameworkDialog from '@/ui/editor/components/AddExternalFramew
1818import ViewCFPackageDialog from '@/ui/editor/components/ViewCFPackageDialog'
1919import { useEditor } from '@/ui/editor/state/EditorContext'
2020import type { CaseEditorNodeType , CaseEditorEdge } from '@/ui/editor/reactflow/types'
21- import type { CFDocument , CFItem , CFPackage } from '@/domain/case/types'
21+ import type { CFDocument , CFItem } from '@/domain/case/types'
2222import { useAuth } from '@/app/providers/AuthProvider'
2323import { fromEditorGraph } from '@/ui/editor/reactflow/mapping/fromEditorGraph'
24- import { frameworkToCfPackage , toOpenCaseFormat } from '@/application/framework/mappers/case/toCasePackage'
24+ import { absolutizeCaseUris , frameworkToCfPackage , toOpenCaseFormat } from '@/application/framework/mappers/case/toCasePackage'
2525
2626type EditorCanvasProps = {
2727 onBack ?: ( ) => void
@@ -30,9 +30,11 @@ type EditorCanvasProps = {
3030 isPublishedToOpenCase ?: boolean
3131 /** Archive the current framework on the server and navigate home */
3232 onArchiveFramework ?: ( ) => Promise < void >
33+ /** Fetch the published CFPackage from the server (returns CASE JSON with absolute URIs) */
34+ onFetchCfPackage ?: ( ) => Promise < object >
3335}
3436
35- export default function EditorCanvas ( { onBack, onSaveToServer, isPublishedToOpenCase, onArchiveFramework } : Readonly < EditorCanvasProps > ) {
37+ export default function EditorCanvas ( { onBack, onSaveToServer, isPublishedToOpenCase, onArchiveFramework, onFetchCfPackage } : Readonly < EditorCanvasProps > ) {
3638 const { status : authStatus , userName, tenantId, signOut, changePassword } = useAuth ( )
3739 const {
3840 nodes,
@@ -88,7 +90,8 @@ export default function EditorCanvas({ onBack, onSaveToServer, isPublishedToOpen
8890 const [ externalFwDialogOpen , setExternalFwDialogOpen ] = useState ( false )
8991 const [ externalFwViewportCenter , setExternalFwViewportCenter ] = useState < { x : number ; y : number } | undefined > ( undefined )
9092 const [ cfPackageDialogOpen , setCfPackageDialogOpen ] = useState ( false )
91- const [ generatedCfPackage , setGeneratedCfPackage ] = useState < CFPackage | null > ( null )
93+ const [ generatedCfPackage , setGeneratedCfPackage ] = useState < object | null > ( null )
94+ const [ viewCaseLoading , setViewCaseLoading ] = useState ( false )
9295 const [ saveStatus , setSaveStatus ] = useState < 'idle' | 'saving' | 'success' | 'error' > ( 'idle' )
9396 const [ saveError , setSaveError ] = useState < string | null > ( null )
9497
@@ -139,20 +142,33 @@ export default function EditorCanvas({ onBack, onSaveToServer, isPublishedToOpen
139142 const saveCtxRef = useRef ( { caseVersion, edgeType : settings . edgeType , cfItemTypes, cfSubjects, cfConcepts, cfLicenses, cfAssociationGroupings } )
140143 saveCtxRef . current = { caseVersion, edgeType : settings . edgeType , cfItemTypes, cfSubjects, cfConcepts, cfLicenses, cfAssociationGroupings }
141144
142- // Generate CFPackage from current editor state and open the viewer
143- const handleViewCFPackage = useCallback ( ( ) => {
144- const { nodes : n , edges : e } = graphRef . current
145- const ctx = saveCtxRef . current
146- const { framework, layout } = fromEditorGraph ( { graph : { nodes : n , edges : e } } )
147- const cfPackage = frameworkToCfPackage ( {
148- framework, layout, incrementVersion : false ,
149- caseVersion : ctx . caseVersion , edgeType : ctx . edgeType ,
150- cfItemTypes : ctx . cfItemTypes , cfSubjects : ctx . cfSubjects ,
151- cfConcepts : ctx . cfConcepts , cfLicenses : ctx . cfLicenses , cfAssociationGroupings : ctx . cfAssociationGroupings ,
152- } )
153- setGeneratedCfPackage ( cfPackage )
154- setCfPackageDialogOpen ( true )
155- } , [ ] )
145+ // Open the CFPackage viewer. Fetches from the server when published (absolute URIs);
146+ // falls back to local generation for unsaved/draft frameworks.
147+ const handleViewCFPackage = useCallback ( async ( ) => {
148+ if ( isPublishedToOpenCase && onFetchCfPackage ) {
149+ setCfPackageDialogOpen ( true )
150+ setViewCaseLoading ( true )
151+ try {
152+ const pkg = await onFetchCfPackage ( )
153+ setGeneratedCfPackage ( pkg )
154+ } finally {
155+ setViewCaseLoading ( false )
156+ }
157+ } else {
158+ const { nodes : n , edges : e } = graphRef . current
159+ const ctx = saveCtxRef . current
160+ const { framework, layout } = fromEditorGraph ( { graph : { nodes : n , edges : e } } )
161+ const cfPackage = frameworkToCfPackage ( {
162+ framework, layout, incrementVersion : false ,
163+ caseVersion : ctx . caseVersion , edgeType : ctx . edgeType ,
164+ cfItemTypes : ctx . cfItemTypes , cfSubjects : ctx . cfSubjects ,
165+ cfConcepts : ctx . cfConcepts , cfLicenses : ctx . cfLicenses , cfAssociationGroupings : ctx . cfAssociationGroupings ,
166+ } )
167+ const caseJson = toOpenCaseFormat ( cfPackage )
168+ setGeneratedCfPackage ( absolutizeCaseUris ( caseJson , window . location . origin ) )
169+ setCfPackageDialogOpen ( true )
170+ }
171+ } , [ isPublishedToOpenCase , onFetchCfPackage ] )
156172
157173 // Save: Generate CFPackage with version increment and POST to server
158174 const handleSave = useCallback ( async ( ) => {
@@ -167,7 +183,6 @@ export default function EditorCanvas({ onBack, onSaveToServer, isPublishedToOpen
167183 } )
168184 const openCasePackage = toOpenCaseFormat ( cfPackage )
169185 console . log ( '[Save] Generated OpenCASE package:' , openCasePackage )
170- setGeneratedCfPackage ( cfPackage )
171186
172187 if ( onSaveToServer ) {
173188 setSaveStatus ( 'saving' )
@@ -1342,8 +1357,9 @@ export default function EditorCanvas({ onBack, onSaveToServer, isPublishedToOpen
13421357 setCfPackageDialogOpen ( false )
13431358 setGeneratedCfPackage ( null )
13441359 } }
1345- cfPackage = { generatedCfPackage }
1360+ casePackage = { generatedCfPackage }
13461361 caseVersion = { caseVersion }
1362+ loading = { viewCaseLoading }
13471363 />
13481364
13491365 </ div >
0 commit comments