"use strict" ; import * as path from "path" ; import * as vscode from "vscode" ; import { Constants } from "../common/constants" ; import { UserCancelledError } from "../common/userCancelledError" ; import { Utility } from "../common/utility" ; import { ModelType } from "../deviceModel/deviceModelManager" ; import { ModelFileInfo } from "../modelRepository/modelRepositoryManager" ; import { UIConstants } from "./uiConstants" ; /**
 * Message type
 */ export enum MessageType { Info , Warn , Error } /**
 * Choice type
 */ export enum ChoiceType { All = "All" , Yes = "Yes" , No = "No" , Cancel = "Cancel" } /**
 * Quick pick item with custom data
 */ interface QuickPickItemWithData < T > extends vscode . QuickPickItem { data : T ; } /**
 * Utility for UI
 */ export class UI { param filePath static async openAndShowTextDocument ( filePath ) { const folder = path . dirname ( filePath ) ; await vscode . commands . executeCommand ( "vscode.openFolder" , vscode . Uri . file ( folder ) , false ) ; await vscode . window . showTextDocument ( vscode . Uri . file ( filePath ) ) ; } param type param message static showNotification ( type , message ) { switch ( type ) { case MessageType . Info : vscode . window . showInformationMessage ( message ) ; break ; case MessageType . Warn : vscode . window . showWarningMessage ( message ) ; break ; case MessageType . Error : vscode . window . showErrorMessage ( message ) ; break ; default : } } param label static async selectRootFolder ( label ) { if ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length === 1 ) { return vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath ; } let items = [ ] ; if ( vscode . workspace . workspaceFolders ) { items = vscode . workspace . workspaceFolders . map ( ( f ) => { const fsPath = f . uri . fsPath ; return { label : path . basename ( fsPath ) , description : fsPath } ; } ) ; } items . push ( { label : UIConstants . BROWSE_LABEL , description : Constants . EMPTY_STRING } ) ; const selected = await UI . showQuickPick ( label , items ) ; return selected . description || ( await UI . showOpenDialog ( label ) ) ; } param label param items static async showQuickPick ( label , items ) { const options = { placeHolder : label , ignoreFocusOut : true } ; const selected = await vscode . window . showQuickPick ( items , options ) ; if ( ! selected ) { throw new UserCancelledError ( label ) ; } return selected ; } param label param defaultUri static async showOpenDialog ( label , defaultUri ? ) { const options = { openLabel : label , defaultUri , canSelectFiles : false , canSelectFolders : true , canSelectMany : false } ; const selected = await vscode . window . showOpenDialog ( options ) ; if ( ! selected || ! selected . length ) { throw new UserCancelledError ( label ) ; } return selected [ 0 ] . fsPath ; } param label param type param folder static async inputModelName ( label , type , folder ) { const placeHolder = `${ type } name` ; const validateInput = async ( name ) : Promise < string | undefined > => { return await Utility . validateModelName ( name , type , folder ) ; } ; return await UI . showInputBox ( label , placeHolder , validateInput ) ; } param label param placeHolder param validateInput param value param ignoreFocusOut static async showInputBox ( label , placeHolder , validateInput ? , value ? , ignoreFocusOut = true ) { const options = { prompt : label , placeHolder , validateInput , value , ignoreFocusOut } ; const input = await vscode . window . showInputBox ( options ) ; if ( ! input ) { throw new UserCancelledError ( label ) ; } return input ; } param label static async inputConnectionString ( label ) { const validateInput = ( name ) : string | undefined => { return Utility . validateNotEmpty ( name , "Connection string" ) ; } ; return await UI . showInputBox ( label , UIConstants . REPOSITORY_CONNECTION_STRING_TEMPLATE , validateInput ) ; } param label param type static async selectModelFiles ( label , type ? ) { const fileInfos = await UI . findModelFiles ( type ) ; if ( ! fileInfos . length ) { UI . showNotification ( MessageType . Warn , UIConstants . MODELS_NOT_FOUND_MSG ) ; return [ ] ; } const items = fileInfos . map ( f => { return { label : path . basename ( f . filePath ) , description : f . id , data : f . filePath } ; } ) ; const selected = await vscode . window . showQuickPick ( items , { placeHolder : label , ignoreFocusOut : true , canPickMany : true , matchOnDescription : true } ) ; if ( ! selected || ! selected . length ) { throw new UserCancelledError ( label ) ; } return selected . map ( s => s . data ) ; } param label param type static async selectOneModelFile ( label , type ? ) { const fileInfos = await UI . findModelFiles ( type ) ; if ( ! fileInfos . length ) { UI . showNotification ( MessageType . Warn , UIConstants . MODELS_NOT_FOUND_MSG ) ; return Constants . EMPTY_STRING ; } const items = fileInfos . map ( f => { return { label : path . basename ( f . filePath ) , description : f . id , data : f . filePath } ; } ) ; const selected = await vscode . window . showQuickPick ( items , { placeHolder : label , ignoreFocusOut : true , canPickMany : false , matchOnDescription : true } ) ; if ( ! selected ) { throw new UserCancelledError ( label ) ; } return selected . data ; } param type static async findModelFiles ( type ? ) { const fileInfos = [ ] ; const files = await vscode . workspace . findFiles ( UIConstants . MODEL_FILE_GLOB ) ; if ( ! files . length ) { return fileInfos ; } await Promise . all ( files . map ( async ( f ) => { let fileInfo ; try { fileInfo = await Utility . getModelFileInfo ( f . fsPath ) ; } catch { return ; } if ( ! fileInfo ) { return ; } if ( ! type || type === fileInfo . type ) { fileInfos . push ( fileInfo ) ; } } ) ) ; return fileInfos ; } param label param files static async ensureFilesSaved ( label , files ) { const dirtyFiles = vscode . workspace . textDocuments . filter ( f => f . isDirty ) ; const unsaved = dirtyFiles . filter ( f => files . some ( file => file === f . fileName ) ) ; if ( ! unsaved . length ) { return ; } const nameList = unsaved . map ( f => path . basename ( f . fileName ) ) . toString ( ) ; const message = `${ UIConstants . ASK_TO_SAVE_MSG } [${ nameList }]` ; const choice = await vscode . window . showWarningMessage ( message , ChoiceType . Yes , ChoiceType . Cancel ) ; if ( choice === ChoiceType . Yes ) { await Promise . all ( unsaved . map ( f => f . save ( ) ) ) ; } else { throw new UserCancelledError ( label ) ; } } private constructor ( ) { } }