새로운 sgcHTML 피드백 컴포넌트 6종: Badge, PDFViewer, ContextMenu, ProgressBar, JobProgress, LogViewer | eSeGeCe 블로그

새로운 sgcHTML 피드백 컴포넌트 6종: Badge, PDFViewer, ContextMenu, ProgressBar, JobProgress, LogViewer

· 컴포넌트

sgcHTML의 새로운 컴포넌트 25종을 다루는 이 시리즈의 네 번째 글입니다. 이번 묶음은 방문자에게 지금 무슨 일이 일어나고 있는지 알려주는 것에 관한 것입니다. 벨 아이콘 위의 개수, 인라인으로 열리는 문서, 우클릭 메뉴, 그리고 진행 중인 작업을 보여주는 세 가지 방법 — 단일 막대, 백그라운드 작업 목록, 스크롤되는 로그입니다. 여섯 컴포넌트 모두 서버에서 렌더링되는 Delphi/C++Builder/.NET 컴포넌트이며, 직접 연결해야 하는 클라이언트 측 차트 라이브러리나 PDF 라이브러리가 필요하지 않습니다.

Badge — 레이블, 필(pill), 또는 알림 점

TsgcHTMLComponent_Badge는 단일 Bootstrap 5 <span class="badge">를 렌더링합니다. Positioned를 설정하면 이를 감싸는 position-relative 요소를 기준으로 절대 위치가 지정된 알림 점으로 바뀝니다. 벨 아이콘 위에 개수를 표시하는 그 전형적인 방식입니다.

uses
  sgcHTML_Enums, sgcHTML_Component_Badge;

var
  oBadge: TsgcHTMLComponent_Badge;
begin
  oBadge := TsgcHTMLComponent_Badge.Create(nil);
  try
    oBadge.Text := '3';
    oBadge.Color := bgDanger;
    oBadge.Pill := True;
    oBadge.Positioned := True;

    WebModule.Response := oBadge.HTML;   // <span class="badge bg-danger rounded-pill ...">
  finally
    oBadge.Free;
  end;
end;

// Or the one-line static helper for a simple inline badge:
WebModule.Response := TsgcHTMLComponent_Badge.Build('New', bgSuccess, True);

PDFViewer — 플러그인 없는 페이지 내 문서

TsgcHTMLComponent_PDFViewer는 pdf.js를 기반으로 하는 툴바와 캔버스를 렌더링하며, 페이지 이동, 확대/축소, 검색, 다운로드, 인쇄 기능이 내장되어 있습니다. PDFURL을 문서로 지정하거나(또는 Base64Data로 바이트를 직접 삽입하면), 렌더링은 전적으로 클라이언트 측에서 이루어집니다.

uses
  sgcHTML_Component_PDFViewer;

var
  oViewer: TsgcHTMLComponent_PDFViewer;
begin
  oViewer := TsgcHTMLComponent_PDFViewer.Create(nil);
  try
    oViewer.ViewerID := 'invoice';
    oViewer.PDFURL := '/invoices/INV-2026-0042.pdf';
    oViewer.Height := '700px';
    oViewer.InitialPage := 1;
    oViewer.Zoom := 'page-width';
    oViewer.Theme := pvLight;
    oViewer.DownloadFileName := 'invoice-0042.pdf';

    WebModule.Response := oViewer.HTML;   // toolbar + canvas + pdf.js init script
  finally
    oViewer.Free;
  end;
end;

ContextMenu — 셀렉터 범위로 제한된 우클릭 메뉴

TsgcHTMLComponent_ContextMenu는 우클릭 시 열리는 Bootstrap 드롭다운을 렌더링하며, TargetSelector와 일치하는 요소로 범위가 제한됩니다. DataAction이 있는 항목은 이미 사용 중인 폼과 동일한 채널을 통해 전송되며, 후크로 연결할 수 있는 DOM 이벤트를 발생시킵니다.

uses
  sgcHTML_Component_ContextMenu;

var
  oMenu: TsgcHTMLComponent_ContextMenu;
  oItem: TsgcHTMLContextMenuItem;
begin
  oMenu := TsgcHTMLComponent_ContextMenu.Create(nil);
  try
    oMenu.MenuID := 'grid_menu';
    oMenu.TargetSelector := '.grid-row';

    oItem := oMenu.Items.Add;
    oItem.Caption := 'Edit';
    oItem.Icon := 'bi bi-pencil';
    oItem.DataAction := 'row:edit';

    oItem := oMenu.Items.Add;
    oItem.Caption := 'Delete';
    oItem.Icon := 'bi bi-trash';
    oItem.DataAction := 'row:delete';

    oItem := oMenu.Items.Add;
    oItem.Divider := True;

    oItem := oMenu.Items.Add;
    oItem.Caption := 'Open in new tab';
    oItem.Href := '/grid/open';

    WebModule.Response := oMenu.HTML;   // hidden <ul> + right-click binding script
  finally
    oMenu.Free;
  end;
end;

ProgressBar — 단일 막대 또는 누적 세그먼트

TsgcHTMLComponent_ProgressBar는 단일 Value/Max에 줄무늬와 애니메이션을 적용하는 단순한 경우와, 누적되는 경우를 모두 지원합니다. Bars에 항목을 추가하면 단일 막대 대신 각 세그먼트마다 고유한 색상과 레이블을 가진 다중 세그먼트 막대로 대체됩니다.

uses
  sgcHTML_Enums, sgcHTML_Component_ProgressBar;

var
  oBar: TsgcHTMLComponent_ProgressBar;
begin
  oBar := TsgcHTMLComponent_ProgressBar.Create(nil);
  try
    oBar.ProgressBarID := 'upload';
    oBar.Value := 72;
    oBar.Max := 100;
    oBar.ColorStyle := hcSuccess;
    oBar.Striped := True;
    oBar.Animated := True;
    oBar.ShowLabel := True;
    oBar.LabelFormat := '%d%% complete';

    WebModule.Response := oBar.HTML;   // Bootstrap progress bar
  finally
    oBar.Free;
  end;
end;

// Or a stacked, multi-segment bar:
with oBar.Bars.Add do
begin
  Value := 40;
  ColorStyle := hcPrimary;
  Label_ := 'Done';
end;
with oBar.Bars.Add do
begin
  Value := 20;
  ColorStyle := hcWarning;
  Label_ := 'In progress';
end;

JobProgress — 백그라운드 작업의 실시간 목록

TsgcHTMLComponent_JobProgress는 한 번에 두 개 이상을 추적해야 할 때 ProgressBar가 발전한 형태로, 모든 백그라운드 작업을 나열하는 카드이며 각 작업은 자체 상태 배지와 진행률 막대를 가집니다. AddJob은 작업을 등록하고, UpdateJob은 진행 상태를 갱신하며, GetJobFragmentHTML은 전체 목록을 다시 렌더링하는 대신 해당 행 하나만 연결된 클라이언트에게 전송합니다.

uses
  sgcHTML_Enums, sgcHTML_Component_JobProgress;

var
  oJobs: TsgcHTMLComponent_JobProgress;
begin
  oJobs := TsgcHTMLComponent_JobProgress.Create(nil);
  try
    oJobs.JobsID := 'exports';
    oJobs.Title := 'Background Exports';
    oJobs.ShowCompleted := False;

    oJobs.AddJob('exp-42', 'Export customers.csv', 'Generating CSV export');

    WebModule.Response := oJobs.HTML;   // card + progress rows + cancel-form script
  finally
    oJobs.Free;
  end;
end;

// On a later progress tick, push just that row over the WebSocket:
oJobs.UpdateJob('exp-42', 65, jsRunning);
Engine.BroadcastFragment(oJobs.GetJobFragmentHTML('exp-42'));

LogViewer — 레벨 필터를 포함한 스트리밍 터미널

TsgcHTMLComponent_LogViewer는 검색창과 레벨 필터가 있는 다크 또는 라이트 터미널 스타일 패널을 렌더링하며, 상한이 있는 링 버퍼(MaxLines)를 기반으로 하므로 무한정 커지지 않습니다. AddLine은 타임스탬프가 찍힌 색상 코드 항목을 추가하고, GetLastLineFragmentHTML은 전체를 다시 렌더링하지 않고도 새 줄을 열려 있는 모든 클라이언트에 스트리밍합니다.

uses
  sgcHTML_Component_LogViewer;

var
  oLog: TsgcHTMLComponent_LogViewer;
begin
  oLog := TsgcHTMLComponent_LogViewer.Create(nil);
  try
    oLog.LogID := 'applog';
    oLog.Theme := ltDark;
    oLog.MaxLines := 500;
    oLog.Height := '400px';

    oLog.AddLine(llInfo, 'Service started', 'app');
    oLog.AddLine(llWarning, 'Low disk space', 'monitor');
    oLog.AddLine(llError, 'Connection refused', 'db');

    WebModule.Response := oLog.HTML;   // toolbar + log body + inline script
  finally
    oLog.Free;
  end;
end;

// Push one more line to every connected client, no full re-render:
oLog.AddLine(llInfo, 'New order received', 'orders');
TsgcHTMX_Engine_Server.BroadcastFragment(oLog.GetLastLineFragmentHTML);

직접 사용해 보기

전체 문서, 주요 속성 참조, Delphi/C++Builder/.NET 코드 샘플은 각 컴포넌트의 전용 페이지에 있습니다: Badge, PDFViewer, ContextMenu, ProgressBar, JobProgress, LogViewer. 이 시리즈의 이전 글: 프레즌스, 역할, 사용자 관리.

질문, 피드백 또는 마이그레이션 도움이 필요하신가요? 문의하기 — 실제로 코드를 작성한 사람에게서 답변을 받으실 수 있습니다.