LANCommander/LANCommander.Server/UI/Components/StylesheetEditorDialog.razor
Pat Hartl 885032547b Improve script editor with context-aware completions, validation, and UX
- Filter variable completions and hover by script type so only relevant variables appear (e.g. $AllocatedKey only in KeyChange scripts)
- Add inline validation warnings for package scripts missing New-Package and for variables used outside their valid script type
- Extend debug console to support tools and redistributables, add stop button and elapsed time display
- Disable minimap, enable bracket pair colorization and word wrap
- Add snippet insertion via Monaco snippet controller with selection replacement support
- Add script templates that auto-populate on new script creation
- Add Variables dropdown in editor toolbar based on current script type
- Change Add Script button to type-selection dropdown, auto-populate script name from type, remove Type field from editor dialog
- Move Requires Admin checkbox to toolbar row, move toolbar and editor outside Form to prevent dropdown clicks from closing the modal
- Set MaskClosable=false on script editor modals so Monaco autocomplete clicks don't dismiss the dialog
2026-05-10 19:33:48 -05:00

77 lines
2 KiB
Text

@inherits FeedbackComponent<string>
@inject IMessageService MessageService
@inject ILogger<ScriptEditorDialog> Logger
<StandaloneCodeEditor @ref="Editor" Id="@("editor-" + Id.ToString())" ConstructionOptions="EditorConstructionOptions" OnDidInit="InitEditor" />
<style>
.monaco-editor-container {
height: 600px;
}
</style>
@code {
Guid Id = Guid.NewGuid();
string Contents = "";
StandaloneCodeEditor? Editor;
string FilePath { get { return $"wwwroot/css/{Options}"; } }
StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
{
return new StandaloneEditorConstructionOptions
{
AutomaticLayout = true,
Language = "css",
Value = Contents,
Theme = "vs-dark",
Minimap = new EditorMinimapOptions { Enabled = false },
BracketPairColorization = new BracketPairColorizationOptions { Enabled = true },
WordWrap = "on",
};
}
protected override void OnParametersSet()
{
if (File.Exists(FilePath))
Contents = File.ReadAllText(FilePath);
}
async Task InitEditor()
{
if (Editor != null)
{
await Editor.AddCommand((int)BlazorMonaco.KeyMod.CtrlCmd | (int)BlazorMonaco.KeyCode.KeyS, (editor) =>
{
Save();
}, null);
}
}
public override async Task OnFeedbackOkAsync(ModalClosingEventArgs args)
{
var success = await Save();
if (!success)
args.Reject();
}
async Task<bool> Save()
{
try
{
File.WriteAllText(FilePath, await Editor.GetValue());
MessageService.Success("Stylesheet saved!");
return true;
}
catch (Exception ex)
{
MessageService.Error("Stylesheet could not be saved!");
Logger.LogError(ex, "Stylesheet could not be saved!");
return false;
}
}
}