turing-machine/Implementation/Client/Components/TransitionTableVisualizer.r...

148 lines
4.1 KiB
Plaintext

@implements IDisposable
@using TuringMachine.Core
@inject IJSRuntime JS
@inject LocalizationService Loc
<div class="transition-table" @ref="tableContainer">
<h3>@Loc["label.actionTable"]</h3>
<table class="table table-bordered table-sm">
<thead>
<tr>
<th class="col-no">@Loc["table.no"]</th>
<th class="col-state">@Loc["table.currentState"]</th>
<th class="col-symbol">@Loc["table.read"]</th>
<th class="col-state">@Loc["table.newState"]</th>
<th class="col-symbol">@Loc["table.write"]</th>
<th class="col-move">@Loc["table.move"]</th>
<th class="col-comment">@Loc["table.comment"]</th>
</tr>
</thead>
<tbody>
@{
int rowIndex = 0;
}
@foreach (var item in Transitions.Items)
{
var isActive = CurrentState == item.Key.State && (CurrentReadSymbol == item.Key.ReadSymbol);
var rowId = $"row-{rowIndex}";
rowIndex++;
<tr class="@(isActive ? "active" : "")" id="@rowId">
<td class="col-no">@rowIndex</td>
<td class="col-state">@item.Key.State</td>
<td class="col-symbol">@item.Key.ReadSymbol</td>
<td class="col-state">@item.Value.NewState</td>
<td class="col-symbol">@item.Value.WriteSymbol</td>
<td class="col-move">@item.Value.MoveDirection</td>
<td class="col-comment">@item.Value.Comment</td>
</tr>
if (isActive)
{
activeRowId = rowId;
}
}
</tbody>
</table>
</div>
<style>
.transition-table {
margin-top: 20px;
height: 370px;
overflow-y: auto;
resize: vertical;
border: 1px solid var(--border-color);
border-radius: 4px;
background-color: var(--bg-secondary);
}
.transition-table h3 {
padding: 10px;
margin: 0;
font-size: 1rem;
font-weight: bold;
background-color: var(--bg-tertiary);
color: var(--text-primary);
border-bottom: 1px solid var(--border-color);
}
.transition-table table {
width: 100%;
margin-bottom: 0;
table-layout: auto;
}
/* 컬럼 폭 설정 - 데이터 컬럼은 내용에 맞게 축소, 주석 컬럼은 나머지 공간 차지 */
.col-no {
width: 1%;
white-space: nowrap;
text-align: center;
}
.col-state {
width: 1%;
white-space: nowrap;
}
.col-symbol {
width: 1%;
white-space: nowrap;
text-align: center;
}
.col-move {
width: 1%;
white-space: nowrap;
text-align: center;
}
.col-comment {
width: 100%;
word-wrap: break-word;
overflow-wrap: break-word;
white-space: normal;
padding: 8px;
}
.transition-table tbody tr {
transition: background-color 0.2s;
}
.transition-table tbody tr.active {
background-color: var(--table-active-bg);
font-weight: bold;
}
.transition-table tbody tr:hover {
background-color: var(--bg-tertiary);
}
</style>
@code {
[Parameter] public TransitionTable Transitions { get; set; } = new();
[Parameter] public string CurrentState { get; set; } = string.Empty;
[Parameter] public char CurrentReadSymbol { get; set; }
private ElementReference tableContainer;
private string? activeRowId;
protected override void OnInitialized()
{
Loc.OnLanguageChanged += OnLanguageChanged;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!string.IsNullOrEmpty(activeRowId))
{
await JS.InvokeVoidAsync("scrollToElement", activeRowId);
}
}
private void OnLanguageChanged() => InvokeAsync(StateHasChanged);
public void Dispose()
{
Loc.OnLanguageChanged -= OnLanguageChanged;
}
}