[Sprint 19] Restore markdown editor compile path - #329
Conversation
🏗️ PR Added to Squad Triage QueueThis PR has been labeled with Next steps:
|
There was a problem hiding this comment.
Pull request overview
Restores a baseline markdown editor integration path in the Web project by adding required package references, introducing a minimal file-storage abstraction for image uploads, and adding supporting JS interop helpers.
Changes:
- Added Web package references for
MarkdigandPSC.Blazor.Components.MarkdownEditor. - Introduced
Infrastructure/FileStoragewithIFileStorage+LocalDiskFileStorageand DI registration. - Added a shared
TextEditorcomponent and JS helper scripts intended to support editor initialization and selection handling.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Web/wwwroot/js/text-editor-helpers.js | Adds a JS helper (getSelectedText) intended for toolbar actions. |
| src/Web/wwwroot/js/markdown-editor-init.js | Adds a custom EasyMDE initialization/disposal wrapper for interop. |
| src/Web/Web.csproj | Adds new PackageReferences for markdown/editor dependencies. |
| src/Web/Program.cs | Registers file storage in DI (AddFileStorage). |
| src/Web/Infrastructure/FileStorage/LocalDiskFileStorage.cs | Implements local-disk storage to wwwroot/uploads with basic validation and logging. |
| src/Web/Infrastructure/FileStorage/IFileStorage.cs | Defines the storage abstraction used by the editor component. |
| src/Web/Infrastructure/FileStorage/FileStorageModels.cs | Adds FileData / FileMetaData records for storage operations. |
| src/Web/Infrastructure/FileStorage/FileStorageExtensions.cs | Adds DI extension method to register the storage implementation. |
| src/Web/GlobalUsings.cs | Adds a global using for the new file storage namespace. |
| src/Web/Components/Shared/TextEditor.razor | Adds MarkdownEditor-based component with image upload + custom button handler. |
| src/AppHost/MongoDbResourceBuilderExtensions.cs | Minor formatting adjustment in seed document construction. |
| <PackageReference Include="Markdig" /> | ||
| <PackageReference Include="MediatR" /> | ||
| <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" /> | ||
| <PackageReference Include="MongoDB.EntityFrameworkCore" /> | ||
| <PackageReference Include="PSC.Blazor.Components.MarkdownEditor" /> |
|
|
||
| // Persist the file and build a retrieval URL | ||
| var fileName = await FileStorage.AddFileAsync(new FileData(stream, new FileMetaData(file.Name, string.Empty, file.LastModified))); | ||
| file.UploadUrl = new Uri(new Uri(NavigationManager.BaseUri), $"/api/files/{fileName}").ToString(); |
| // Get the selected text using JavaScript | ||
| var selectedText = await JsRuntime.InvokeAsync<string>("getSelectedText", ".EasyMDEContainer textarea"); | ||
|
|
| var wrappedText = $"<div style='text-align:{args.Value}'>{selectedText}</div>"; | ||
|
|
||
| // Replace the selected text in the editor | ||
| MyContent = MyContent.Replace(selectedText, wrappedText); | ||
|
|
| public async Task<FileEntry> HandleImageUpload(MarkdownEditor editor, FileEntry file) | ||
| { | ||
| Console.WriteLine($"Image: {file.Name} Size: {file.Size}"); | ||
|
|
| // Convert the base64 string to a byte array and load it into a memory stream | ||
| var bytes = Convert.FromBase64String(file.ContentBase64); | ||
| var stream = new MemoryStream(bytes); | ||
|
|
||
| // Persist the file and build a retrieval URL | ||
| var fileName = await FileStorage.AddFileAsync(new FileData(stream, new FileMetaData(file.Name, string.Empty, file.LastModified))); | ||
| file.UploadUrl = new Uri(new Uri(NavigationManager.BaseUri), $"/api/files/{fileName}").ToString(); |
| { | ||
| /// <summary> | ||
| /// Persists <paramref name="file"/> and returns the stored filename that callers | ||
| /// can use to build a retrieval URL (e.g. <c>/api/files/{filename}</c>). |
| var uniqueName = $"{Guid.NewGuid()}{extension}"; | ||
| var filePath = Path.Combine(uploadsPath, uniqueName); | ||
|
|
||
| await using var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write); |
|
|
||
| // Ensure the interop is available globally | ||
| console.log('Markdown Editor Interop Loaded'); |
e6d474c to
8886140
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #329 +/- ##
==========================================
- Coverage 84.01% 80.64% -3.38%
==========================================
Files 47 51 +4
Lines 1314 1369 +55
Branches 161 166 +5
==========================================
Hits 1104 1104
- Misses 148 198 +50
- Partials 62 67 +5
🚀 New features to boost your workflow:
|
|
🤖 Aragorn — Rebase complete Branch |
- Add PSC.Blazor.Components.MarkdownEditor and Markdig package references to Web.csproj (both centrally pinned in Directory.Packages.props) - Add IFileStorage infrastructure (interface, FileData/FileMetaData models, LocalDiskFileStorage impl, DI extension) under Infrastructure/FileStorage/ - Register IFileStorage via AddFileStorage() in Program.cs - Fix TextEditor.razor: add @using for Infrastructure.FileStorage namespace, rename AddFile -> AddFileAsync to match the new interface - Add GlobalUsings entry for MyBlog.Web.Infrastructure.FileStorage - Include JS helpers (markdown-editor-init.js, text-editor-helpers.js) Build: Release 0 errors Tests: Architecture 16 / Domain 42 / Web.Tests 158 / bUnit 92 - all pass Closes #323 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8886140 to
13b7269
Compare
## Summary Closes #323 Restores the compile path for the markdown editor by adding the two missing NuGet package references and defining the previously-undefined `IFileStorage` infrastructure layer that `TextEditor.razor` depends on. ## Changes ### Package references (Web.csproj) - Added `PSC.Blazor.Components.MarkdownEditor` (centrally pinned at 10.0.7) - Added `Markdig` (centrally pinned at 1.2.0) ### New infrastructure layer (`Infrastructure/FileStorage/`) - `IFileStorage` — internal interface with `AddFileAsync(FileData)` - `FileStorageModels` — `FileData` and `FileMetaData` records - `LocalDiskFileStorage` — baseline impl saving to `wwwroot/uploads`; validates extension whitelist and 10 MB size cap - `FileStorageExtensions` — `AddFileStorage()` DI extension following project conventions ### Wiring - `GlobalUsings.cs` — `global using MyBlog.Web.Infrastructure.FileStorage;` - `Program.cs` — `builder.Services.AddFileStorage();` - `TextEditor.razor` — added `@using` for new namespace; renamed `AddFile` → `AddFileAsync` ### JS helpers (from #321 investigation) - `wwwroot/js/markdown-editor-init.js` - `wwwroot/js/text-editor-helpers.js` ## Verification - Release build: **0 errors, 0 warnings** - Tests: Architecture 16 / Domain 42 / Web.Tests 158 / bUnit 92 — **all pass** - All 6 pre-push gates passed (including integration tests) ## Notes - Full Create/Edit page migration is deferred to #324 and #325, now unblocked by this fix. - Working as **Sam** (Implementation) Co-authored-by: Boromir <boromir@squad.dev> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Closes #323
Restores the compile path for the markdown editor by adding the two missing NuGet package references and defining the previously-undefined
IFileStorageinfrastructure layer thatTextEditor.razordepends on.Changes
Package references (Web.csproj)
PSC.Blazor.Components.MarkdownEditor(centrally pinned at 10.0.7)Markdig(centrally pinned at 1.2.0)New infrastructure layer (
Infrastructure/FileStorage/)IFileStorage— internal interface withAddFileAsync(FileData)FileStorageModels—FileDataandFileMetaDatarecordsLocalDiskFileStorage— baseline impl saving towwwroot/uploads; validates extension whitelist and 10 MB size capFileStorageExtensions—AddFileStorage()DI extension following project conventionsWiring
GlobalUsings.cs—global using MyBlog.Web.Infrastructure.FileStorage;Program.cs—builder.Services.AddFileStorage();TextEditor.razor— added@usingfor new namespace; renamedAddFile→AddFileAsyncJS helpers (from #321 investigation)
wwwroot/js/markdown-editor-init.jswwwroot/js/text-editor-helpers.jsVerification
Notes