From 4242aeefa994268f59a1d5d971c459c3c29344f8 Mon Sep 17 00:00:00 2001 From: parsapanahpoor Date: Wed, 3 Dec 2025 02:50:41 +0330 Subject: [PATCH] Refactor: Focus on JSON Viewer Component Removed `Counter` and `FetchData` components, along with their associated styles and data files, to streamline the application. Updated `Index.razor` to emphasize the JSON Viewer demo with improved layout. Simplified `MainLayout` and `NavMenu` by removing navigation elements and focusing on main content. Removed `SurveyPrompt.razor` as it is no longer relevant. #3 Refactored `ExportButton.razor` for better readability, maintainability, and functionality, including support for large file downloads and improved notifications. Updated `_Imports.razor` to include `Component.Core`. Adjusted styles in `MainLayout.razor.css` and `NavMenu.razor.css` to reflect layout changes. Updated `index.html` to use the correct stylesheet. Removed `weather.json` as it is no longer needed. --- src/Blazor.Demo/Pages/Counter.razor | 18 ----- src/Blazor.Demo/Pages/FetchData.razor | 57 --------------- src/Blazor.Demo/Pages/Index.razor | 12 ++-- src/Blazor.Demo/Shared/MainLayout.razor | 8 --- src/Blazor.Demo/Shared/MainLayout.razor.css | 72 +------------------ src/Blazor.Demo/Shared/NavMenu.razor | 36 +--------- src/Blazor.Demo/Shared/NavMenu.razor.css | 67 ++--------------- src/Blazor.Demo/Shared/SurveyPrompt.razor | 16 ----- src/Blazor.Demo/_Imports.razor | 1 + src/Blazor.Demo/wwwroot/index.html | 2 +- .../wwwroot/sample-data/weather.json | 27 ------- .../Core/Features/ExportButton.razor | 61 ++++++---------- 12 files changed, 40 insertions(+), 337 deletions(-) delete mode 100644 src/Blazor.Demo/Pages/Counter.razor delete mode 100644 src/Blazor.Demo/Pages/FetchData.razor delete mode 100644 src/Blazor.Demo/Shared/SurveyPrompt.razor delete mode 100644 src/Blazor.Demo/wwwroot/sample-data/weather.json diff --git a/src/Blazor.Demo/Pages/Counter.razor b/src/Blazor.Demo/Pages/Counter.razor deleted file mode 100644 index ef23cb3..0000000 --- a/src/Blazor.Demo/Pages/Counter.razor +++ /dev/null @@ -1,18 +0,0 @@ -@page "/counter" - -Counter - -

Counter

- -

Current count: @currentCount

- - - -@code { - private int currentCount = 0; - - private void IncrementCount() - { - currentCount++; - } -} diff --git a/src/Blazor.Demo/Pages/FetchData.razor b/src/Blazor.Demo/Pages/FetchData.razor deleted file mode 100644 index 783a026..0000000 --- a/src/Blazor.Demo/Pages/FetchData.razor +++ /dev/null @@ -1,57 +0,0 @@ -@page "/fetchdata" -@inject HttpClient Http - -Weather forecast - -

Weather forecast

- -

This component demonstrates fetching data from the server.

- -@if (forecasts == null) -{ -

Loading...

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); - } - - public class WeatherForecast - { - public DateOnly Date { get; set; } - - public int TemperatureC { get; set; } - - public string? Summary { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } -} diff --git a/src/Blazor.Demo/Pages/Index.razor b/src/Blazor.Demo/Pages/Index.razor index 05aab21..e25a2cd 100644 --- a/src/Blazor.Demo/Pages/Index.razor +++ b/src/Blazor.Demo/Pages/Index.razor @@ -1,13 +1,12 @@ @page "/" -@using Component.Core -JSON Viewer Demo +JSON Viewer Component - Demo

- 🚀 JSON Viewer Component Demo + 🚀 JSON Viewer Component

A powerful JSON viewer for Blazor with search, statistics, and more! @@ -15,8 +14,11 @@

- +
+
+ +
+
diff --git a/src/Blazor.Demo/Shared/MainLayout.razor b/src/Blazor.Demo/Shared/MainLayout.razor index 839b8fe..f170e38 100644 --- a/src/Blazor.Demo/Shared/MainLayout.razor +++ b/src/Blazor.Demo/Shared/MainLayout.razor @@ -1,15 +1,7 @@ @inherits LayoutComponentBase
- -
-
- About -
-
@Body
diff --git a/src/Blazor.Demo/Shared/MainLayout.razor.css b/src/Blazor.Demo/Shared/MainLayout.razor.css index c865427..7397fe6 100644 --- a/src/Blazor.Demo/Shared/MainLayout.razor.css +++ b/src/Blazor.Demo/Shared/MainLayout.razor.css @@ -8,74 +8,6 @@ main { flex: 1; } -.sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); -} - -.top-row { - background-color: #f7f7f7; - border-bottom: 1px solid #d6d5d5; - justify-content: flex-end; - height: 3.5rem; - display: flex; - align-items: center; -} - - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } - - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } - - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } - -@media (max-width: 640.98px) { - .top-row:not(.auth) { - display: none; - } - - .top-row.auth { - justify-content: space-between; - } - - .top-row ::deep a, .top-row ::deep .btn-link { - margin-left: 0; - } -} - -@media (min-width: 641px) { - .page { - flex-direction: row; - } - - .sidebar { - width: 250px; - height: 100vh; - position: sticky; - top: 0; - } - - .top-row { - position: sticky; - top: 0; - z-index: 1; - } - - .top-row.auth ::deep a:first-child { - flex: 1; - text-align: right; - width: 0; - } - - .top-row, article { - padding-left: 2rem !important; - padding-right: 1.5rem !important; - } +.content { + padding-top: 1.1rem; } diff --git a/src/Blazor.Demo/Shared/NavMenu.razor b/src/Blazor.Demo/Shared/NavMenu.razor index 0c5dee3..50e4355 100644 --- a/src/Blazor.Demo/Shared/NavMenu.razor +++ b/src/Blazor.Demo/Shared/NavMenu.razor @@ -1,39 +1,5 @@  - - - -@code { - private bool collapseNavMenu = true; - - private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; - - private void ToggleNavMenu() - { - collapseNavMenu = !collapseNavMenu; - } -} diff --git a/src/Blazor.Demo/Shared/NavMenu.razor.css b/src/Blazor.Demo/Shared/NavMenu.razor.css index 604b7a1..3830469 100644 --- a/src/Blazor.Demo/Shared/NavMenu.razor.css +++ b/src/Blazor.Demo/Shared/NavMenu.razor.css @@ -1,68 +1,15 @@ -.navbar-toggler { - background-color: rgba(255, 255, 255, 0.1); -} - -.top-row { - height: 3.5rem; - background-color: rgba(0,0,0,0.4); -} - .navbar-brand { font-size: 1.1rem; -} - -.oi { - width: 2rem; - font-size: 1.1rem; - vertical-align: text-top; - top: -2px; -} - -.nav-item { - font-size: 0.9rem; - padding-bottom: 0.5rem; -} - - .nav-item:first-of-type { - padding-top: 1rem; - } - - .nav-item:last-of-type { - padding-bottom: 1rem; - } - - .nav-item ::deep a { - color: #d7d7d7; - border-radius: 4px; - height: 3rem; - display: flex; - align-items: center; - line-height: 3rem; - } - -.nav-item ::deep a.active { - background-color: rgba(255,255,255,0.25); + font-weight: 600; color: white; + text-decoration: none; } -.nav-item ::deep a:hover { - background-color: rgba(255,255,255,0.1); - color: white; +.navbar-brand:hover { + color: rgba(255, 255, 255, 0.8); } -@media (min-width: 641px) { - .navbar-toggler { - display: none; - } - - .collapse { - /* Never collapse the sidebar for wide screens */ - display: block; - } - - .nav-scrollable { - /* Allow sidebar to scroll for tall menus */ - height: calc(100vh - 3.5rem); - overflow-y: auto; - } +.navbar-dark { + background-color: rgba(0, 0, 0, 0.4); + padding: 1rem; } diff --git a/src/Blazor.Demo/Shared/SurveyPrompt.razor b/src/Blazor.Demo/Shared/SurveyPrompt.razor deleted file mode 100644 index 67b6b62..0000000 --- a/src/Blazor.Demo/Shared/SurveyPrompt.razor +++ /dev/null @@ -1,16 +0,0 @@ -
- - @Title - - - Please take our - brief survey - - and tell us what you think. -
- -@code { - // Demonstrates how a parent component can supply parameters - [Parameter] - public string? Title { get; set; } -} diff --git a/src/Blazor.Demo/_Imports.razor b/src/Blazor.Demo/_Imports.razor index b9dc80d..83fcd51 100644 --- a/src/Blazor.Demo/_Imports.razor +++ b/src/Blazor.Demo/_Imports.razor @@ -8,3 +8,4 @@ @using Microsoft.JSInterop @using Blazor.Demo @using Blazor.Demo.Shared +@using Component.Core diff --git a/src/Blazor.Demo/wwwroot/index.html b/src/Blazor.Demo/wwwroot/index.html index c826717..65e6fd9 100644 --- a/src/Blazor.Demo/wwwroot/index.html +++ b/src/Blazor.Demo/wwwroot/index.html @@ -8,7 +8,7 @@ - + diff --git a/src/Blazor.Demo/wwwroot/sample-data/weather.json b/src/Blazor.Demo/wwwroot/sample-data/weather.json deleted file mode 100644 index b745973..0000000 --- a/src/Blazor.Demo/wwwroot/sample-data/weather.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "date": "2022-01-06", - "temperatureC": 1, - "summary": "Freezing" - }, - { - "date": "2022-01-07", - "temperatureC": 14, - "summary": "Bracing" - }, - { - "date": "2022-01-08", - "temperatureC": -13, - "summary": "Freezing" - }, - { - "date": "2022-01-09", - "temperatureC": -16, - "summary": "Balmy" - }, - { - "date": "2022-01-10", - "temperatureC": -2, - "summary": "Chilly" - } -] diff --git a/src/Component/Core/Features/ExportButton.razor b/src/Component/Core/Features/ExportButton.razor index 4da1e73..8519a9e 100644 --- a/src/Component/Core/Features/ExportButton.razor +++ b/src/Component/Core/Features/ExportButton.razor @@ -1,25 +1,6 @@ @using Component.Core.Shared @using Component.Services -@inject IOptimizedFileDownloadService FileDownloadService - - - -@using Component.Services +@using System.Text @using System.Text.Json.Nodes @using System.Text.Json @inject IOptimizedFileDownloadService FileDownloadService @@ -45,25 +26,25 @@ #region Parameters /// - /// JsonNode از JsonViewer (System.Text.Json) + /// JsonNode from JsonViewer (System.Text.Json) /// [Parameter] public JsonNode? JsonToken { get; set; } /// - /// JSON Data به صورت String + /// JSON Data as String /// [Parameter] public string? JsonData { get; set; } /// - /// پیشوند نام فایل + /// File name prefix /// [Parameter] public string FileNamePrefix { get; set; } = "json_export"; /// - /// رویداد اطلاع‌رسانی + /// Notification event /// [Parameter] public EventCallback<(string message, string type)> OnNotification { get; set; } @@ -73,25 +54,25 @@ #region UI Customization /// - /// عنوان Tooltip دکمه + /// Button tooltip title /// [Parameter] public string Title { get; set; } = "Export to file"; /// - /// کلاس‌های CSS دکمه + /// Button CSS classes /// [Parameter] public string ButtonClass { get; set; } = "btn btn-sm btn-light mb-2"; /// - /// نام آیکون + /// Icon name /// [Parameter] public string IconName { get; set; } = "download"; /// - /// متن اختیاری کنار آیکون + /// Optional text next to icon /// [Parameter] public string ButtonText { get; set; } = string.Empty; @@ -104,7 +85,7 @@ private const int LARGE_FILE_THRESHOLD = 5 * 1024 * 1024; /// - /// وضعیت فعال/غیرفعال دکمه + /// Button enabled/disabled state /// private bool IsDisabled => (JsonToken == null && string.IsNullOrEmpty(JsonData)) || isExporting; @@ -113,11 +94,11 @@ #region Main Methods /// - /// مدیریت کلیک دکمه Export + /// Handle Export button click /// private async Task HandleExportClick() { - // بررسی داده‌های خالی + // Check for empty data if (JsonToken == null && string.IsNullOrEmpty(JsonData)) return; @@ -126,13 +107,13 @@ try { - // دریافت محتوا و فایل‌نیم + // Get content and filename var content = GetExportContent(); var fileName = GetExportFileName(); var fullFileName = $"{fileName}.json"; var contentSize = Encoding.UTF8.GetByteCount(content); - // تشخیص خودکار برای فایل‌های بزرگ + // Auto-detect for large files if (contentSize > LARGE_FILE_THRESHOLD) { await FileDownloadService.DownloadLargeFileAsync( @@ -151,7 +132,7 @@ ); } - // اطلاع‌رسانی موفقیت + // Success notification await SendNotification( $"File '{fullFileName}' ({FormatBytes(contentSize)}) exported successfully", "success" @@ -159,7 +140,7 @@ } catch (Exception ex) { - // اطلاع‌رسانی خطا + // Error notification await SendNotification( $"Failed to export: {ex.Message}", "error" @@ -179,13 +160,13 @@ #region Helper Methods /// - /// دریافت محتوای JSON فرمت‌شده برای Export + /// Get formatted JSON content for export /// private string GetExportContent() { if (JsonToken != null) { - // ✅ استفاده از System.Text.Json + // Use System.Text.Json var options = new JsonSerializerOptions { WriteIndented = true @@ -198,7 +179,7 @@ } /// - /// تولید نام فایل با Timestamp + /// Generate filename with timestamp /// private string GetExportFileName() { @@ -207,7 +188,7 @@ } /// - /// ارسال پیام اطلاع‌رسانی به Parent Component + /// Send notification message to parent component /// private async Task SendNotification(string message, string type) { @@ -218,7 +199,7 @@ } /// - /// تبدیل Bytes به فرمت خوانا + /// Convert bytes to readable format /// private string FormatBytes(long bytes) {