'use strict' ; import * as vscode from 'vscode' ; import * as path from 'path' ; import * as fs from 'fs-extra' ; import { ReactView } from './ReactView' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { VSCodeBlockchainOutputAdapter } from '../logging/VSCodeBlockchainOutputAdapter' ; import { LogType } from 'ibm-blockchain-platform-common' ; import ITransaction from '../interfaces/ITransaction' ; import ISmartContract from '../interfaces/ISmartContract' ; import IAssociatedTxData from '../interfaces/IAssociatedTxData' ; import { ExtensionUtil } from '../util/ExtensionUtil' ; import ITxDataFile from '../interfaces/ITxDataFile' ; interface IAppState { gatewayName : string ; smartContracts : ISmartContract [ ] ; associatedTxdata : IAssociatedTxData ; preselectedSmartContract : ISmartContract ; preselectedTransaction : ITransaction ; } export class TransactionView extends ReactView { public static panel : vscode . WebviewPanel ; public static appState : IAppState ; static async updateSmartContracts ( smartContracts ) { TransactionView . appState . smartContracts = smartContracts ; TransactionView . panel . webview . postMessage ( { transactionViewData : { ... TransactionView . appState , smartContracts , } } ) ; } static closeView ( ) { TransactionView . panel . dispose ( ) ; } static async readTxdataFiles ( txdataDirectoryPath ) { const transactionsInFiles = [ ] ; const allFiles = await fs . readdir ( txdataDirectoryPath ) ; const txDataFiles = allFiles . filter ( ( file ) => file . endsWith ( '.txdata' ) ) ; if ( txDataFiles . length > 0 ) { for ( const file of txDataFiles ) { const fullpath = path . join ( txdataDirectoryPath , file ) ; try { const fileJson = await fs . readJSON ( fullpath ) ; fileJson . forEach ( ( { transactionName , transactionLabel , arguments : args , transientData } ) => { transactionsInFiles . push ( { transactionName , transactionLabel , arguments : args , transientData , txDataFile : fullpath , } ) ; } ) ; } catch ( error ) { const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . ERROR , undefined , `Invalid JSON in ${ fullpath }.\n${ error . toString ( ) }` ) ; } } } return transactionsInFiles ; } protected appState : any ; constructor ( context , appState ) { super ( context , 'transactionView' , 'Transaction View' ) ; TransactionView . appState = appState ; } public async openView ( keepContext , viewColumn = vscode . ViewColumn . One ) { if ( TransactionView . panel ) { TransactionView . panel . webview . postMessage ( { transactionViewData : TransactionView . appState , } ) ; } return super . openView ( keepContext , viewColumn ) ; } async handleTransactionMessage ( message , panel ) { const response = await vscode . commands . executeCommand ( message . command , undefined , undefined , undefined , message . data ) ; panel . webview . postMessage ( { transactionOutput : response } ) ; } async handleTxdataMessage ( message , panel ) { const response = await vscode . commands . executeCommand ( message . command , undefined , message . data ) ; let updatedAssociatedTxdata ; if ( response ) { updatedAssociatedTxdata = { ... TransactionView . appState . associatedTxdata , [ response . chaincodeName ] : { channelName : response . channelName , transactionDataPath : response . transactionDataPath , transactions : await TransactionView . readTxdataFiles ( response . transactionDataPath ) , } } ; } else { updatedAssociatedTxdata = TransactionView . appState . associatedTxdata ; delete updatedAssociatedTxdata [ message . data . name ] ; } const newAppState = { gatewayName : TransactionView . appState . gatewayName , smartContracts : TransactionView . appState . smartContracts , preselectedSmartContract : TransactionView . appState . preselectedSmartContract , preselectedTransaction : TransactionView . appState . preselectedTransaction , associatedTxdata : updatedAssociatedTxdata , } ; panel . webview . postMessage ( { transactionViewData : newAppState } ) ; } async openPanelInner ( panel ) { TransactionView . panel = panel ; panel . onDidDispose ( ( ) => { TransactionView . panel = undefined ; } ) ; const extensionPath = ExtensionUtil . getExtensionPath ( ) ; const panelIcon = vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'logo.svg' ) ) ; panel . iconPath = panelIcon ; panel . webview . onDidReceiveMessage ( async ( message ) => { if ( message . command === ExtensionCommands . SUBMIT_TRANSACTION || message . command === ExtensionCommands . EVALUATE_TRANSACTION ) { await this . handleTransactionMessage ( message , panel ) ; } else if ( [ ExtensionCommands . ASSOCIATE_TRANSACTION_DATA_DIRECTORY , ExtensionCommands . DISSOCIATE_TRANSACTION_DATA_DIRECTORY ] . includes ( message . command ) ) { await this . handleTxdataMessage ( message , panel ) ; } else { await vscode . commands . executeCommand ( message . command , ... message . data ) ; } } ) ; await this . loadComponent ( panel ) ; } async loadComponent ( panel ) { panel . webview . postMessage ( { path : '/transaction' , transactionViewData : TransactionView . appState } ) ; } }