@@ -33,8 +33,9 @@ import type { Signal } from "@lumino/signaling";
3333import { commandIDs } from "./commands/CommandIDs" ;
3434import { IEditorTracker } from '@jupyterlab/fileeditor' ;
3535import { IMainMenu } from '@jupyterlab/mainmenu' ;
36- import { handleInstall } from './context-menu/TrayContextMenu' ;
37-
36+ import { installLibrarySilently } from './context-menu/TrayContextMenu' ;
37+ import { normalizeLibraryName } from './tray_library/ComponentLibraryConfig' ;
38+ import { loadLibraryIndex } from './helpers/notificationEffects' ;
3839import { installComponentPreview } from './component_info_sidebar/previewHelper' ;
3940const FACTORY = 'Xircuits editor' ;
4041
@@ -578,22 +579,17 @@ const xircuits: JupyterFrontEndPlugin<void> = {
578579 } ) ;
579580 }
580581
581- async function getInstalledLibraries ( ) : Promise < Set < string > > {
582- try {
583- const result = await requestAPI < any > ( 'library/get_config' , {
584- method : 'GET'
585- } ) ;
586-
587- return new Set < string > (
588- result . config . libraries
589- . filter ( ( lib : any ) => lib . status === 'installed' && typeof lib . name === 'string' )
590- . map ( ( lib : any ) => lib . name )
591- ) ;
592- } catch ( err ) {
593- console . error ( 'Failed to load library config via API:' , err ) ;
594- return new Set ( ) ;
582+ async function getInstalledIds ( ) : Promise < Set < string > > {
583+ const idx = await loadLibraryIndex ( ) ;
584+ const set = new Set < string > ( ) ;
585+ for ( const [ id , entry ] of idx ) {
586+ if ( String ( entry . status ) . toLowerCase ( ) === 'installed' ) {
587+ set . add ( id ) ;
588+ }
595589 }
590+ return set ;
596591 }
592+
597593 app . commands . addCommand ( commandIDs . fetchExamples , {
598594 label : 'Fetch Example Workflows' ,
599595 caption : 'Fetch example workflows into the examples directory' ,
@@ -615,24 +611,32 @@ const xircuits: JupyterFrontEndPlugin<void> = {
615611 icon : xircuitsIcon ,
616612 execute : async ( ) => {
617613 const currentPath = browserFactory . tracker . currentWidget ?. model . path ?? '' ;
618- const installedLibs = await getInstalledLibraries ( ) ;
614+ const installedIds = await getInstalledIds ( ) ;
619615
620- for ( const lib of libraries ) {
621- if ( installedLibs . has ( lib ) ) {
622- console . log ( `Library ${ lib } already installed. Skipping.` ) ;
623- continue ;
624- }
616+ const pairs = libraries . map ( lib => ( {
617+ raw : lib ,
618+ id : normalizeLibraryName ( lib )
619+ } ) ) ;
625620
626- const ok = await handleInstall ( app , lib , ( ) =>
627- app . commands . execute ( commandIDs . refreshComponentList )
628- ) ;
621+ const missing = pairs . filter ( p => ! installedIds . has ( p . id ) ) ;
629622
623+ if ( missing . length ) {
624+ const list = missing . map ( p => p . raw ) . join ( ', ' ) ;
625+ const ok = window . confirm ( `This workflow template requires the following component libraries: ${ list } . Would you like to install them now?` ) ;
626+ if ( ! ok ) {
627+ console . warn ( 'User cancelled installation.' ) ;
628+ return ;
629+ }
630+
631+ for ( const { raw, id } of missing ) {
632+ const ok = await installLibrarySilently ( app , raw ) ;
630633 if ( ! ok ) {
631- console . warn ( `Aborted: ${ lib } not installed.` ) ;
634+ console . warn ( `Aborted: ${ raw } not installed.` ) ;
632635 return ;
633636 }
634- installedLibs . add ( lib ) ;
637+ installedIds . add ( id ) ;
635638 }
639+ }
636640
637641 // Currently the templates are stored at the `examples` dir
638642 await app . commands . execute ( commandIDs . fetchExamples ) ;
0 commit comments