keisoft 2025. 2. 19. 07:45

네, 작업 목록에 높이를 지정하고 API 결과를 표시하도록 수정하겠습니다.

@page "/monitor"
@inject IWorkerManagerService WorkerManagerService
@implements IDisposable
@using Microsoft.Fast.Components.FluentUI

<PageTitle>Worker 모니터링</PageTitle>

<FluentCard>
    <div class="monitor-header">
        <h3>Worker 모니터링</h3>
    </div>

    <FluentGrid>
        <FluentGridItem xs="12" md="6">
            <FluentCard class="stat-card">
                <div class="stat-content">
                    <FluentLabel Typo="Typography.Body">대기 중인 작업</FluentLabel>
                    <FluentLabel Typo="Typography.H2">@status?.QueuedWorkCount</FluentLabel>
                </div>
            </FluentCard>
        </FluentGridItem>
        <FluentGridItem xs="12" md="6">
            <FluentCard class="stat-card">
                <div class="stat-content">
                    <FluentLabel Typo="Typography.Body">실행 중인 작업</FluentLabel>
                    <FluentLabel Typo="Typography.H2">@status?.ActiveWorkerCount</FluentLabel>
                </div>
            </FluentCard>
        </FluentGridItem>
    </FluentGrid>

    @if (status?.ActiveWorks?.Any() == true)
    {
        <FluentCard class="mt-4">
            <FluentCardHeader>
                <h5>실행 중인 작업 목록</h5>
            </FluentCardHeader>
            <div class="data-grid-container">
                <FluentDataGrid Items="@status.ActiveWorks" GridTemplateColumns="1fr 1fr 1fr 1fr">
                    <PropertyColumn Property="@(work => work.RequestId)" Title="요청 ID" />
                    <PropertyColumn Property="@(work => work.ActionType)" Title="작업 유형" />
                    <PropertyColumn Property="@(work => FormatTime(work.StartTime))" Title="시작 시간" />
                    <PropertyColumn Property="@(work => FormatDuration(work.StartTime))" Title="경과 시간" />
                </FluentDataGrid>
            </div>
        </FluentCard>
    }
    
    <FluentCard class="mt-4">
        <FluentCardHeader>
            <h5>API 응답 결과</h5>
        </FluentCardHeader>
        <div class="api-result-container">
            <FluentLabel Typo="Typography.Body">마지막 업데이트: @(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))</FluentLabel>
            <FluentDivider class="my-2" />
            <pre class="api-result-json">@apiResultJson</pre>
        </div>
    </FluentCard>
</FluentCard>

<style>
    .monitor-header {
        padding: 16px;
        border-bottom: 1px solid var(--neutral-stroke-divider-rest);
    }
    
    .stat-card {
        margin: 16px;
        padding: 16px;
    }
    
    .stat-content {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }
    
    .mt-4 {
        margin-top: 24px;
    }
    
    .data-grid-container {
        height: 300px;
        overflow-y: auto;
        padding: 0 16px 16px 16px;
    }
    
    .api-result-container {
        padding: 16px;
    }
    
    .api-result-json {
        background-color: var(--neutral-layer-1);
        padding: 12px;
        border-radius: 4px;
        max-height: 300px;
        overflow-y: auto;
        font-family: 'Consolas', 'Courier New', monospace;
        font-size: 14px;
        white-space: pre-wrap;
    }
    
    .my-2 {
        margin-top: 12px;
        margin-bottom: 12px;
    }
</style>

@code {
    private WorkerManagerStatus status;
    private Timer timer;
    private string apiResultJson = "로딩 중...";

    protected override void OnInitialized()
    {
        timer = new Timer(async _ =>
        {
            try
            {
                status = await WorkerManagerService.GetStatusAsync();
                apiResultJson = System.Text.Json.JsonSerializer.Serialize(
                    status,
                    new System.Text.Json.JsonSerializerOptions { WriteIndented = true }
                );
            }
            catch (Exception ex)
            {
                apiResultJson = $"Error: {ex.Message}";
            }
            await InvokeAsync(StateHasChanged);
        }, null, 0, 1000);
    }

    private string FormatTime(DateTime utcTime)
    {
        return utcTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
    }

    private string FormatDuration(DateTime startTime)
    {
        return (DateTime.UtcNow - startTime).ToString(@"hh\:mm\:ss");
    }

    public void Dispose()
    {
        timer?.Dispose();
    }
}

### 주요 변경사항:

1. **작업 목록 높이 제한**:
   - `.data-grid-container` 클래스를 추가하여 데이터 그리드를 감싸고 높이를 300px로 지정했습니다.
   - `overflow-y: auto`를 적용하여 항목이 많을 경우 스크롤바가 나타나도록 구현했습니다.

2. **API 결과 표시**:
   - API 응답 결과를 표시하는 새로운 카드 섹션을 추가했습니다.
   - JSON 형식으로 서비스 응답을 보기 좋게 표시합니다.
   - `apiResultJson` 상태 변수를 추가하고 `System.Text.Json.JsonSerializer`를 사용하여 JSON 형식으로 변환합니다.
   - 결과는 스크롤 가능한 pre 태그에 표시되며, 최대 높이는 300px로 제한됩니다.
   - 코드 폰트와 배경색을 적용하여 가독성을 높였습니다.

3. **오류 처리**:
   - API 호출 중 발생할 수 있는 예외를 처리하여 사용자에게 오류 메시지를 표시합니다.
   - 마지막 업데이트 시간도 함께 표시하여 데이터의 최신성을 알 수 있게 했습니다.

이렇게 하면 작업 목록은 지정된 높이 내에서 스크롤 가능하게 표시되고, API 응답 결과가 JSON 형식으로 보기 좋게 표시됩니다. 개발 및 디버깅 목적으로도 유용하게 사용할 수 있습니다.