Adds a new section "Scripting" in the server UI where PowerShell modules can be defined. These can be used for defining a library of functions that can be used in any script. These modules are automatically synced to the launcher and imported upon script execution.
194 lines
No EOL
5.7 KiB
Text
194 lines
No EOL
5.7 KiB
Text
@using BlazorMonaco.Editor
|
|
@using Microsoft.JSInterop
|
|
@namespace LANCommander.UI.Components
|
|
@inject IJSRuntime JSRuntime
|
|
|
|
<StandaloneCodeEditor
|
|
@ref="_editor"
|
|
OnDidChangeModelContent="OnChangedContent"
|
|
OnDidInit="OnInit"
|
|
ConstructionOptions="_editorConstructionOptions" />
|
|
|
|
@code {
|
|
[Parameter] public EventCallback<string> OnSave { get; set; }
|
|
[Parameter] public EventCallback OnReady { get; set; }
|
|
[Parameter] public Language Language { get; set; }
|
|
[Parameter] public int Height { get; set; }
|
|
[Parameter] public string? Value { get; set; }
|
|
[Parameter] public EventCallback<string?> ValueChanged { get; set; }
|
|
[Parameter] public string? ScriptType { get; set; }
|
|
[Parameter] public IEnumerable<ModuleFunctionCompletion>? ModuleFunctions { get; set; }
|
|
|
|
static bool _completionsRegistered;
|
|
static bool _yamlCompletionsRegistered;
|
|
bool _isEditorInitialized = false;
|
|
string? _previousValue;
|
|
string? _previousScriptType;
|
|
IEnumerable<ModuleFunctionCompletion>? _previousModuleFunctions;
|
|
IJSObjectReference? _module;
|
|
|
|
StandaloneCodeEditor _editor;
|
|
|
|
StandaloneEditorConstructionOptions _editorConstructionOptions(StandaloneCodeEditor editor)
|
|
{
|
|
var options = new StandaloneEditorConstructionOptions
|
|
{
|
|
AutomaticLayout = true,
|
|
Language = Language.Id,
|
|
Theme = "vs-dark",
|
|
Value = Value,
|
|
Minimap = new EditorMinimapOptions { Enabled = false },
|
|
BracketPairColorization = new BracketPairColorizationOptions { Enabled = true },
|
|
WordWrap = "on",
|
|
FixedOverflowWidgets = true,
|
|
};
|
|
|
|
if (Height > 0)
|
|
options.Dimension = new Dimension { Height = Height };
|
|
|
|
return options;
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (_isEditorInitialized && ValueChanged.HasDelegate && Value != _previousValue)
|
|
{
|
|
_previousValue = Value;
|
|
await _editor.SetValue(Value);
|
|
}
|
|
|
|
if (_isEditorInitialized && _module != null && ScriptType != _previousScriptType)
|
|
{
|
|
_previousScriptType = ScriptType;
|
|
await _module.InvokeVoidAsync("setScriptType", ScriptType);
|
|
await RunValidationAsync();
|
|
}
|
|
|
|
if (_isEditorInitialized && _module != null && !ReferenceEquals(ModuleFunctions, _previousModuleFunctions))
|
|
{
|
|
await PushModuleFunctionsAsync();
|
|
}
|
|
|
|
await base.OnParametersSetAsync();
|
|
}
|
|
|
|
async Task OnInit()
|
|
{
|
|
_isEditorInitialized = true;
|
|
|
|
await _editor.AddCommand((int)BlazorMonaco.KeyMod.CtrlCmd | (int)BlazorMonaco.KeyCode.KeyS, async (editor) =>
|
|
{
|
|
if (OnSave.HasDelegate)
|
|
await OnSave.InvokeAsync();
|
|
}, null);
|
|
|
|
_module = await JSRuntime.InvokeAsync<IJSObjectReference>(
|
|
"import", "./_content/LANCommander.UI/bundle.js");
|
|
|
|
if (Language.Id == "powershell" && !_completionsRegistered)
|
|
{
|
|
_completionsRegistered = true;
|
|
await _module.InvokeVoidAsync("registerPowerShellCompletions");
|
|
}
|
|
|
|
if (Language.Id == "yaml" && !_yamlCompletionsRegistered)
|
|
{
|
|
_yamlCompletionsRegistered = true;
|
|
await _module.InvokeVoidAsync("registerYamlCompletions");
|
|
}
|
|
|
|
if (ScriptType != null)
|
|
{
|
|
_previousScriptType = ScriptType;
|
|
await _module.InvokeVoidAsync("setScriptType", ScriptType);
|
|
}
|
|
|
|
if (Language.Id == "powershell")
|
|
await _module.InvokeVoidAsync("SetupFileDropHandler");
|
|
|
|
if (Language.Id == "powershell")
|
|
await PushModuleFunctionsAsync();
|
|
|
|
if (OnReady.HasDelegate)
|
|
await OnReady.InvokeAsync();
|
|
}
|
|
|
|
async Task PushModuleFunctionsAsync()
|
|
{
|
|
if (_module == null)
|
|
return;
|
|
|
|
_previousModuleFunctions = ModuleFunctions;
|
|
|
|
await _module.InvokeVoidAsync("setModuleFunctions", ModuleFunctions ?? []);
|
|
}
|
|
|
|
public async Task LayoutAsync()
|
|
{
|
|
if (_isEditorInitialized && _editor != null)
|
|
await _editor.Layout();
|
|
}
|
|
|
|
public async Task InsertText(string text)
|
|
{
|
|
var selection = await _editor.GetSelection();
|
|
var range = new BlazorMonaco.Range(
|
|
selection.StartLineNumber, selection.StartColumn,
|
|
selection.EndLineNumber, selection.EndColumn);
|
|
|
|
await _editor.ExecuteEdits("CodeInput", new List<IdentifiedSingleEditOperation>
|
|
{
|
|
new IdentifiedSingleEditOperation
|
|
{
|
|
Range = range,
|
|
Text = text,
|
|
ForceMoveMarkers = true
|
|
}
|
|
}, (List<BlazorMonaco.Selection>)null);
|
|
}
|
|
|
|
public async Task InsertSnippet(string snippetText)
|
|
{
|
|
if (_module == null)
|
|
{
|
|
await InsertText(snippetText);
|
|
return;
|
|
}
|
|
|
|
await _module.InvokeVoidAsync("insertSnippet", snippetText);
|
|
}
|
|
|
|
public async Task<bool> InsertTemplateAsync(string scriptType)
|
|
{
|
|
if (_module == null)
|
|
return false;
|
|
|
|
var template = await _module.InvokeAsync<string?>("getScriptTemplate", scriptType);
|
|
|
|
if (template == null)
|
|
return false;
|
|
|
|
await _editor.SetValue(template);
|
|
return true;
|
|
}
|
|
|
|
async Task OnChangedContent(ModelContentChangedEvent e)
|
|
{
|
|
if (ValueChanged.HasDelegate)
|
|
{
|
|
_previousValue = await _editor.GetValue();
|
|
|
|
await ValueChanged.InvokeAsync(_previousValue);
|
|
}
|
|
|
|
await RunValidationAsync();
|
|
}
|
|
|
|
async Task RunValidationAsync()
|
|
{
|
|
if (_module == null || Language.Id != "powershell")
|
|
return;
|
|
|
|
await _module.InvokeVoidAsync("validateScript");
|
|
}
|
|
} |