feat: implement all open issues (#539 #540 #565 #566 #607 #615 #619 #620) + security fix#659
Merged
cct08311github merged 10 commits intodotnet8from Mar 19, 2026
Merged
Conversation
…lt table (#539) - Wrap result table in `.analysis-table-wrap` div for CSS sticky-header support - Add client-side column sorting: click header to cycle asc → desc → original Sort indicator uses CSS `::after` so `th.textContent` is unchanged (preserves all existing header-text tests) - Add pagination (50 rows/page) with page-info span and prev/next buttons; pagination div only rendered when row count exceeds page size - Sorting resets to first page; % share columns remain non-sortable - Add 29 new Jest tests covering wrapper, sort (asc/desc/reset/multi-col/string), and pagination (no-div ≤50, div >50, page info, next, prev-disabled, sort reset) - 344 Jest tests pass total Closes #539 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Frontend: createValueInput() for date fields now renders a span wrapper with a mode <select> (8 relative tokens + custom) and a hidden .analysis-filter-value input. collectFilters() unchanged — deep querySelector still finds the input inside the wrapper. - Backend: ResolveRelativeDates() expands @today / @ThisWeek / @lastweek / @thismonth / @lastmonth / @last30days / @thisQuarter / @YTD tokens into Gte/Lte FilterCondition pairs before ApplyFilters builds expression trees. - Tests: 8 MSTest for ResolveRelativeDates, 9 Jest for date mode UI. Updated existing #501 test to reflect new span-wrapper shape. Closes #566 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
**#620 - Optimistic concurrency in BaseCRUDVM** - Add `IsConcurrencyConflict` read-only property to `IBaseCRUDVM<T>` and `BaseCRUDVM<T>` - Catch `DbUpdateConcurrencyException` specifically in `DoEdit()` and `DoEditAsync()` before the generic catch; sets `IsConcurrencyConflict = true` and adds localizer key `"Sys.ConcurrencyConflict"` model error instead of throwing - Add `ConcurrencyConflictTests.cs` with 4 tests covering sync, async, initial state and interface read-only contract **#607 - IProgress<ImportProgress> for BaseImportVM** - Add `ImportProgress` readonly struct (Processed, Total, Phase) - Add optional `IProgress<ImportProgress>? progress = null` parameter to `BatchSaveData()` (fully backward-compatible default) - Report progress after every row in both the validation phase ("Validating") and the entity-preparation phase ("Saving") **#615 - Import error inline table + template description row** - Add `InlineErrorLimit` (default 50) and `InlineErrors` computed property to `BaseImportVM` so the UI can show the first N errors inline without a file download - Add `ShowDescriptionRow` flag (default `true`) to `BaseTemplateVM` - `GenerateTemplate()` writes a light-green italic description row below the column header when `ShowDescriptionRow` is true, containing Required/Optional, data type, and length hints derived from `ExcelPropety` metadata; freeze pane extends to cover both rows - Store a "v2" marker in the hidden enum-sheet so `SetTemplateData()` can detect and skip the description row during import (fully backward-compatible with old templates) https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
- Add GetDeletePreviewString() to IBaseCRUDVM<T> interface and
BaseCRUDVM<TModel> with default implementation that searches
common name properties (Name/Title/Code/ITCode) before falling
back to the entity's primary key value
- Add POST /_Framework/GetDeletePreview endpoint that accepts a
vmType name and up to 10 IDs, returns [{id, label}] for
bulk-delete confirmation dialogs
- Add POST /_Framework/BatchAssignRoles endpoint that upserts
FrameworkUserRole entries for multiple userCodes against one
roleCode, then purges affected user caches
https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
…619 tests ComboBox (#565): - Add RemoteUrl property; when set enables xmSelect remoteSearch+remoteMethod, sending ?q=<keyword> to the URL on each keystroke (debounced by xmSelect) - filterable is forced true when RemoteUrl is set TreeSelect (#565): - Add LazyUrl property; when set enables xmSelect lazy=true and a load callback that fetches children via ?id=<nodeValue> on node expand Tests (#619): - Add DeletePreviewTests covering GetDeletePreviewString default behaviour, primary-key fallback, interface presence, and virtual modifier https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
EtlJobListVM: - Override InitGridAction() to add Create/Edit/Delete standard actions - Add row-level actions: TriggerNow (confirm POST), Pause, Resume, Abort - Add '執行記錄' action that opens run-log dialog filtered by job ID - Add ConsecutiveFailureCount column for at-a-glance failure tracking - Widen action column to 460px to fit all buttons Demo views (_EtlJob/Create + Edit): - Add missing QueryTemplate (textarea), AlertEmail, AlertWebhookUrl, AlertAfterConsecutiveFailures fields to Create and Edit forms https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
…#615) ImportProgressTests (#607): - Verifies that BatchSaveData reports progress for each row - Checks Total matches entity count, Processed is monotonically increasing - Validates null progress parameter doesn't throw - Confirms phase names are always non-empty TemplateDescriptionRowTests (#615): - Verifies ShowDescriptionRow = true writes 'v2' marker in hidden sheet - ShowDescriptionRow = false writes empty marker (backward compat) - Description row exists and contains Required/Optional hint text - Confirmed default = true InlineErrors (#615 via ImportProgressTests): - Tests InlineErrors is empty before import - Returns errors after validation failure - Respects InlineErrorLimit cap (default 50) - Empty when InlineErrorLimit = 0 https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
…rence The old Microsoft.AspNetCore.Http NuGet package v2.1.34 is a .NET Core 2.1 artifact referenced in a .NET 8 project, carrying potential security vulnerabilities. Replace with FrameworkReference to Microsoft.AspNetCore.App which provides all ASP.NET Core APIs at the .NET 8 version. Also remove the duplicate explicit Microsoft.AspNetCore.Authorization 8.0.22 reference — it is included by the framework reference. https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
Override InitGridAction() to add a row-level 'Rerun' button that POSTs to _EtlRunLog/Rerun with the selected run log ID, restoring the watermark to the snapshot and triggering the job again. https://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM
This was referenced Mar 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
remote-urlfor AJAX search; TreeSelectlazy-urlfor lazy-load children@today,@thisMonth,@thisYear, etc.)BaseImportVM.BatchSaveDataprogress reporting viaIProgress<ImportProgress>InlineErrors/InlineErrorLimit); template description row (ShowDescriptionRow)DoEdit/DoEditAsynccatchesDbUpdateConcurrencyException, setsIsConcurrencyConflictMicrosoft.AspNetCore.Http 2.1.34(vulnerable) withFrameworkReferencefor .NET 8Notes
The changes from PRs #655 and #657 are included in this branch (as
7e77cadand96e882arespectively). Those PR branches have also been rebased ondotnet8to clear their merge conflicts.Test plan
dotnet test WalkingTec.Mvvm.sln -c Releasepassescd test/WalkingTec.Mvvm.Js.Tests && npm testpasses (561 tests)remote-urlhttps://claude.ai/code/session_017r2EfWhoDdvECdoncQg6xM