template editor
This commit is contained in:
78
EpsonTest.Templates/Templates/KitcheReceipt.json
Normal file
78
EpsonTest.Templates/Templates/KitcheReceipt.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"Title": "Warme K\u00FCche",
|
||||||
|
"TransactionDateTime": "2025-10-23T12:18:00",
|
||||||
|
"ReceiptNumber": "132018166",
|
||||||
|
"WaiterName": "Mariano Amato",
|
||||||
|
"WaiterId": "32 (VK Restaurant)",
|
||||||
|
"TableNumber": "22",
|
||||||
|
"SpecialInstruction": null,
|
||||||
|
"Gangs": [
|
||||||
|
{
|
||||||
|
"Id": 1,
|
||||||
|
"Name": "Gang",
|
||||||
|
"Dishes": [
|
||||||
|
{
|
||||||
|
"Number": 1,
|
||||||
|
"Name": "Avocado Sashimi",
|
||||||
|
"GuestId": 1,
|
||||||
|
"Modifications": {
|
||||||
|
"Removed": [
|
||||||
|
"Wasabi"
|
||||||
|
],
|
||||||
|
"Added": [
|
||||||
|
"Extra Ginger"
|
||||||
|
],
|
||||||
|
"HasModifications": true
|
||||||
|
},
|
||||||
|
"Comment": "No soy sauce",
|
||||||
|
"GuestPrefix": "1 "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Number": 1,
|
||||||
|
"Name": "Baby Spinach Salad with Truffl",
|
||||||
|
"GuestId": 2,
|
||||||
|
"Modifications": {
|
||||||
|
"Removed": [],
|
||||||
|
"Added": [],
|
||||||
|
"HasModifications": false
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"GuestPrefix": "2 "
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 2,
|
||||||
|
"Name": "Gang",
|
||||||
|
"Dishes": [
|
||||||
|
{
|
||||||
|
"Number": 1,
|
||||||
|
"Name": "Avocado Sashimi",
|
||||||
|
"GuestId": 1,
|
||||||
|
"Modifications": {
|
||||||
|
"Removed": [],
|
||||||
|
"Added": [],
|
||||||
|
"HasModifications": false
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"GuestPrefix": "1 "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Number": 1,
|
||||||
|
"Name": "Baby Spinach Salad with Truffl",
|
||||||
|
"GuestId": 2,
|
||||||
|
"Modifications": {
|
||||||
|
"Removed": [],
|
||||||
|
"Added": [],
|
||||||
|
"HasModifications": false
|
||||||
|
},
|
||||||
|
"Comment": null,
|
||||||
|
"GuestPrefix": "2 "
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Dishes": [],
|
||||||
|
"HasGangs": true,
|
||||||
|
"HasDishes": false
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
<if test="dish.Comment">
|
<if test="dish.Comment">
|
||||||
<line tall="true" bold="true">Comment: {{dish.Comment}}</line>
|
<line tall="true" bold="true"> Comment: {{dish.Comment}}</line>
|
||||||
</if>
|
</if>
|
||||||
</foreach>
|
</foreach>
|
||||||
<if test="!$last">
|
<if test="!$last">
|
||||||
|
|||||||
@@ -7,18 +7,19 @@
|
|||||||
@using Inspectron.Epson.PrintServer.Printers
|
@using Inspectron.Epson.PrintServer.Printers
|
||||||
@using Inspectron.Epson.TemplateEngine
|
@using Inspectron.Epson.TemplateEngine
|
||||||
@using Inspectron.PrintServer.TemplateEditor.Services
|
@using Inspectron.PrintServer.TemplateEditor.Services
|
||||||
|
@implements IDisposable
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<button class="toolbar-btn" title="New" @onclick="NewFileAsync">New</button>
|
<button class="toolbar-btn" title="New (Ctrl+N)" @onclick="NewFileAsync">New</button>
|
||||||
<button class="toolbar-btn" title="Open" @onclick="OpenFileAsync">Open</button>
|
<button class="toolbar-btn" title="Open (Ctrl+O)" @onclick="OpenFileAsync">Open</button>
|
||||||
<button class="toolbar-btn" title="Save" @onclick="SaveFileAsync">Save</button>
|
<button class="toolbar-btn" title="Save (Ctrl+S)" @onclick="SaveFileAsync">Save</button>
|
||||||
<span class="file-indicator" title="@(_currentFilePath ?? "Untitled")">
|
<span class="file-indicator" title="@(_currentFilePath ?? "Untitled")">
|
||||||
@FileDisplayName@(HasUnsavedChanges ? " *" : "")
|
@FileDisplayName@(HasUnsavedChanges ? " *" : "")
|
||||||
</span>
|
</span>
|
||||||
<div class="toolbar-separator"></div>
|
<div class="toolbar-separator"></div>
|
||||||
<button class="toolbar-btn" title="Load JSON data file for expression completions" @onclick="LoadJsonAsync">Load JSON</button>
|
<button class="toolbar-btn" title="Load JSON (Ctrl+J)" @onclick="LoadJsonAsync">Load JSON</button>
|
||||||
@if (!string.IsNullOrEmpty(_loadedJsonFile))
|
@if (!string.IsNullOrEmpty(_loadedJsonFile))
|
||||||
{
|
{
|
||||||
<span class="json-indicator" title="@_loadedJsonFile">@_loadedJsonFile</span>
|
<span class="json-indicator" title="@_loadedJsonFile">@_loadedJsonFile</span>
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
private string? _previewError;
|
private string? _previewError;
|
||||||
private string _selectedPrinterModel = "TM-T30III";
|
private string _selectedPrinterModel = "TM-T30III";
|
||||||
private CancellationTokenSource? _debounceCts;
|
private CancellationTokenSource? _debounceCts;
|
||||||
|
private DotNetObjectReference<Home>? _dotNetRef;
|
||||||
|
|
||||||
private bool HasUnsavedChanges => _editorContent != _savedContent;
|
private bool HasUnsavedChanges => _editorContent != _savedContent;
|
||||||
|
|
||||||
@@ -101,6 +103,30 @@
|
|||||||
"receipt-xml",
|
"receipt-xml",
|
||||||
_completionProvider.ProvideCompletionItems,
|
_completionProvider.ProvideCompletionItems,
|
||||||
_completionProvider.ResolveCompletionItem);
|
_completionProvider.ResolveCompletionItem);
|
||||||
|
|
||||||
|
// Register global hotkeys
|
||||||
|
_dotNetRef = DotNetObjectReference.Create(this);
|
||||||
|
await JSRuntime.InvokeVoidAsync("registerHotkeys", _dotNetRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JSInvokable]
|
||||||
|
public async Task OnHotkeyAsync(string action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case "New": await NewFileAsync(); break;
|
||||||
|
case "Open": await OpenFileAsync(); break;
|
||||||
|
case "Save": await SaveFileAsync(); break;
|
||||||
|
case "LoadJson": await LoadJsonAsync(); break;
|
||||||
|
}
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_debounceCts?.Cancel();
|
||||||
|
_debounceCts?.Dispose();
|
||||||
|
_dotNetRef?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnContentChanged(ModelContentChangedEvent e)
|
private async Task OnContentChanged(ModelContentChangedEvent e)
|
||||||
|
|||||||
@@ -161,3 +161,23 @@ window.setPreviewContent = function(html) {
|
|||||||
var iframe = document.getElementById('preview-iframe');
|
var iframe = document.getElementById('preview-iframe');
|
||||||
if (iframe) iframe.srcdoc = html;
|
if (iframe) iframe.srcdoc = html;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.registerHotkeys = function(dotNetRef) {
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (!(e.ctrlKey || e.metaKey)) return;
|
||||||
|
|
||||||
|
var action = null;
|
||||||
|
switch (e.key.toLowerCase()) {
|
||||||
|
case 'n': action = 'New'; break;
|
||||||
|
case 'o': action = 'Open'; break;
|
||||||
|
case 's': action = 'Save'; break;
|
||||||
|
case 'j': action = 'LoadJson'; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dotNetRef.invokeMethodAsync('OnHotkeyAsync', action);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user