KNM.Reporting.Designer 1.0.1

KNM.Reporting.Designer

Plug & play Blazor Server admin panel for report generation, management, and monitoring in the KoNiMa ecosystem.

Installation

dotnet add package KNM.Reporting.Designer --source https://nuget.konima.it/v3/index.json

Quick Start

Minimal setup

builder.Services.AddKnmReportingDesigner();
app.MapReportingDesigner();

All authenticated users can generate reports. In-memory history enabled by default. No admin features.

Full setup

builder.Services.AddKnmReportingDesigner(designer => designer
    .WithAuthorization(auth =>
    {
        auth.IsAdmin = user => user.IsInRole("Administrator");
        auth.CanGenerate = user => user.Identity?.IsAuthenticated == true;
        auth.CanAccessReport = (user, reportId) => true;
    })
    .WithBranding(brand =>
    {
        brand.Title = "Company Reports";
        brand.Subtitle = "Generate and manage reports";
        brand.LogoUrl = "/images/logo.png";
        brand.PrimaryColor = "#1a73e8";
    })
    .WithHistory<SqlReportHistoryStore>()
    .WithScheduling<QuartzScheduleStore>()
    .WithTemplateManagement()
    .WithMonitoring()
);

app.MapReportingDesigner();

CSS Setup

The Designer CSS is automatically injected via JSInterop when any component renders. No manual <link> tag is required.

For optimal control over insertion order, add the placeholder comment in your App.razor or index.html:

<!-- In <head>, after KNM.RazorComponents CSS -->
<!--[knm-css]-->
<!--[knm-css-reporting]-->

Compatibility: Works with Blazor Server, WASM, and Hybrid (MAUI).

Component Namespaces

Add these @using directives to your project's _Imports.razor:

@using KNM.Reporting.Designer.Components
@using KNM.Reporting.Designer.Configuration
@using KNM.Reporting.Designer.Core.Interfaces
@using KNM.Reporting.Designer.Core.Models
@using KNM.Reporting.Designer.Core.Services.Interfaces
@using KNM.Reporting.Designer.Extensions

Note: Due to a .NET Razor compiler limitation, MSBuild <Using> items from the NuGet .targets file are not resolved for component tags in .razor files. These manual @using directives are required.

Pre-built Pages

Route Page Description
/reports ReportsDashboard Branding header + searchable report browser
/reports/{id} ReportDetail Generate + preview + history for a single report
/reports/admin ReportsAdmin Template management, monitoring, scheduling (admin only)

Components

All components can be used standalone in your own pages:

ReportBrowser

Searchable report list with engine filter badges.

<ReportBrowser OnReportSelected="HandleSelect" />

ReportGenerator

Dynamic parameter form built from ReportParameterInfo metadata. Supports text, date, number, boolean, and dropdown inputs. Includes progress bar and download button.

<ReportGenerator ReportId="invoice-report" OnGenerated="HandleGenerated" />

ReportPreview

Inline PDF preview via iframe. Stores content in IAppCache with 5-minute TTL.

<ReportPreview PdfContent="@pdfBytes" FileName="report.pdf" />

ReportHistory

Generation history grid with status icons and re-download support.

<ReportHistory ReportId="invoice-report" Limit="50" />

TemplateManager (Admin)

CRUD for FastReport .frx templates. Requires WithTemplateManagement().

ReportMonitor (Admin)

Real-time generation progress tracking via IEventBus and IProgressTracker. Requires WithMonitoring().

ReportScheduler (Admin)

Schedule definition CRUD with cron expressions. Requires WithScheduling().

Configuration

DesignerAuthorizationOptions

Callback-based authorization. Callbacks must NOT capture Scoped/Transient dependencies.

public class DesignerAuthorizationOptions
{
    public Func<ClaimsPrincipal, bool> IsAdmin { get; set; } = _ => false;
    public Func<ClaimsPrincipal, bool> CanGenerate { get; set; } = user => user.Identity?.IsAuthenticated == true;
    public Func<ClaimsPrincipal, string, bool> CanAccessReport { get; set; } = (_, _) => true;
}

DesignerBrandingOptions

public class DesignerBrandingOptions
{
    public string Title { get; set; } = "KNM Reporting";
    public string? Subtitle { get; set; }
    public string? LogoUrl { get; set; }
    public string PrimaryColor { get; set; } = "#1a73e8";
    public string AccentColor { get; set; } = "#34a853";
}

DesignerFeatureFlags

public class DesignerFeatureFlags
{
    public bool HistoryEnabled { get; set; } = true;
    public bool TemplateManagementEnabled { get; set; }
    public bool SchedulingEnabled { get; set; }
    public bool MonitoringEnabled { get; set; }
}

Data Providers

Implement IReportDataProvider to enrich user parameters with business data before generation:

public class InvoiceDataProvider : IReportDataProvider
{
    public string ReportId => "invoice-report";

    public async Task<ReportParameters> GetDataAsync(ReportParameters userParams, CancellationToken ct)
    {
        var customerId = userParams.Get<int>("CustomerId");
        var customer = await dbContext.Customers.FindAsync(customerId, ct);

        return userParams
            .Set("CustomerName", customer?.Name)
            .Set("CustomerAddress", customer?.Address);
    }
}

// Register in DI
builder.Services.AddScoped<IReportDataProvider, InvoiceDataProvider>();

Custom Stores

Replace the default in-memory stores with database-backed implementations:

IReportHistoryStore

public interface IReportHistoryStore
{
    Task<Result<bool>> SaveAsync(ReportHistoryEntry entry, CancellationToken ct);
    Task<Result<IReadOnlyList<ReportHistoryEntry>>> GetAsync(string? userId, int limit, CancellationToken ct);
    Task<Result<ReportHistoryEntry>> GetByIdAsync(string id, CancellationToken ct);
    Task<Result<bool>> DeleteAsync(string id, CancellationToken ct);
}

IReportScheduleStore

public interface IReportScheduleStore
{
    Task<Result<string>> CreateAsync(ReportSchedule schedule, CancellationToken ct);
    Task<Result<IReadOnlyList<ReportSchedule>>> GetAllAsync(CancellationToken ct);
    Task<Result<ReportSchedule>> GetByIdAsync(string id, CancellationToken ct);
    Task<Result<bool>> UpdateAsync(ReportSchedule schedule, CancellationToken ct);
    Task<Result<bool>> DeleteAsync(string id, CancellationToken ct);
}

Register custom stores:

builder.Services.AddKnmReportingDesigner(designer => designer
    .WithHistory<SqlReportHistoryStore>()
    .WithScheduling<QuartzScheduleStore>()
);

In-Memory Store Options

builder.Services.AddKnmReportingDesigner(designer => designer
    .WithInMemoryStoreOptions(store =>
    {
        store.MaxEntries = 200;
        store.CacheContent = true; // Keep report bytes for re-download
    })
);

Generation Flow

1. User selects report in ReportBrowser -> navigates to /reports/{id}
2. ReportGenerator loads ReportInfo via IReportingService
3. Dynamic form rendered from ReportParameterInfo
4. User fills parameters, selects format, clicks Generate
5. IReportDataProvider enriches parameters (if registered)
6. IReportingService.GenerateAsync() with progress reporting
7. IReportHistoryStore.SaveAsync() records the generation
8. PDF: inline preview via ReportPreview
9. All formats: download button

Scheduling Note

The Designer manages schedule definitions (CRUD). Actual execution is the host's responsibility:

// In your host project, register a background job that:
// 1. Reads IReportScheduleStore.GetAllAsync()
// 2. Checks cron expressions against current time
// 3. Calls IReportingService.GenerateAsync() for due schedules

Dependencies

Package Version Purpose
KNM.Reporting >= 1.0.1 IReportingService, discovery, generation
KNM.RazorComponents latest UI components (DataGrid, Toast, etc.)
KNM.Core >= 1.5.0 Result<T>, IAppCache, IEventBus, IProgressTracker
Microsoft.AspNetCore.Components.Web >= 10.0.5 Blazor component infrastructure

CSS Variables

The Designer uses --knm-rpt-* CSS variables that inherit from KNM.RazorComponents --knm-* variables. Dark mode is automatic via data-bs-theme="dark".

Variable Default Description
--knm-rpt-primary var(--knm-primary, #1a73e8) Primary brand color
--knm-rpt-accent var(--knm-success, #34a853) Accent/success color
--knm-rpt-bg var(--knm-bg, #ffffff) Background color
--knm-rpt-text var(--knm-text, #212529) Text color
--knm-rpt-border var(--knm-border, #dee2e6) Border color
--knm-rpt-radius 0.5rem Border radius

Changelog

1.0.1

  • Updated KNM.Core dependency from 1.3.1 to 1.5.0
  • Updated Microsoft.AspNetCore.Components.Web from 10.0.3 to 10.0.5

1.0.0

  • Initial release with pre-built pages (Dashboard, Detail, Admin)
  • ReportBrowser, ReportGenerator, ReportPreview, ReportHistory components
  • TemplateManager, ReportMonitor, ReportScheduler admin components
  • Automatic CSS injection via JSInterop
  • Authorization, branding, and feature flag configuration
  • Data provider pattern, custom store support

No packages depend on KNM.Reporting.Designer.

Version Downloads Last updated
1.0.1 0 30/03/2026