Part of ContentService refactoring Phase 3.
Defines version operations to be extracted from ContentService.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
ContentService now delegates all paged type queries to the new
QueryOperationService, completing Phase 2 delegation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
ContentService.GetByLevel now delegates to QueryOperationService,
continuing Phase 2 query operation extraction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
ContentService now delegates Count, CountPublished, CountChildren,
CountDescendants to the new QueryOperationService.
This is Task 5 of Phase 2 - the first delegation task that converts
ContentService from direct repository calls to delegating to the
specialized query operation service.
All tests pass. Baseline tests confirm facade and direct service
return identical results. Full ContentService test suite passes
(excluding pre-existing benchmark regressions).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Injects IContentQueryOperationService for future delegation.
Includes lazy resolution support for obsolete constructors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds unique registration for ContentQueryOperationService matching
the Phase 1 pattern for IContentCrudService. Also updates the
ContentService factory to inject the new service as the 19th parameter.
Note: Build will fail until Task 4 adds the 19-parameter constructor
to ContentService.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements IContentQueryOperationService with Count, GetByLevel, and
GetPagedOfType operations. Follows Phase 1 patterns.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The Create_WithNonExistentContentType test expected ArgumentException but
ContentCrudService correctly throws generic Exception to match the original
ContentService behavior (behavioral parity).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds IContentCrudService registration to UmbracoBuilder alongside
IContentService. Both services are now resolvable from DI.
Includes integration test verifying successful resolution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements IContentCrudService with full CRUD operations:
- Create: 6 overloads matching IContentService
- Read: GetById, GetByIds, GetRootContent, GetParent
- Save: Single and batch with notifications
- Delete: Cascade deletion with notifications
All methods maintain exact behavioral parity with ContentService.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Establishes shared infrastructure for content services:
- Common dependencies (DocumentRepository, AuditService, UserIdKeyResolver)
- Audit helper methods (sync and async)
- Inherits from RepositoryService for scope/query support
- Adds ContentServiceConstants for shared constants (batch page size)
Updated tracking test to look for correct assembly location.
Tracking test now fails (expected) - signals class exists for future work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Records baseline performance metrics for ContentService operations
before refactoring begins. This data will be used to detect
regressions during subsequent phases.
Captured 32 benchmarks covering core operations:
- CRUD operations (Save, Delete, Copy, Move)
- Publishing (Publish, Unpublish, PublishBranch)
- Queries (GetById, GetByIds, GetAncestors, etc.)
- Bulk operations (batch saves, recycle bin)
- Performance-critical paths (1000-item operations)
Note: 4 benchmarks failed due to test setup issues but still
captured timing data. 1 benchmark (Rollback_ToVersion) did not
produce data due to version creation failure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds unit test file for ContentServiceBase with documented test cases.
Tests are commented out until ContentServiceBase is created in Phase 1:
- 2 audit helper method tests
- 2 scope provider access pattern tests
- 2 logger injection tests
- 1 repository access test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds 3 integration tests for transaction boundaries:
- Test 13: Nested operations in uncompleted scope roll back together
- Test 14: Completed scope commits all operations together
- Test 15: MoveToRecycleBin rolls back completely when scope not completed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds 4 integration tests for permission operations:
- Test 9: SetPermission assigns permission and GetPermissions retrieves it
- Test 10: Multiple SetPermission calls accumulate permissions
- Test 11: SetPermissions assigns complete permission set
- Test 12: SetPermission assigns to multiple user groups at once
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds 3 integration tests for DeleteOfType operations:
- Test 6: DeleteOfType handles descendants correctly (moves different types to bin)
- Test 7: DeleteOfType only deletes specified type, preserves others
- Test 8: DeleteOfTypes deletes multiple content types at once
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds 3 integration tests for Sort operations:
- Test 3: Sort(IEnumerable<IContent>) reorders children correctly
- Test 4: Sort(IEnumerable<int>) reorders children by ID correctly
- Test 5: Sort fires Sorting and Sorted notifications in sequence
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds the test file skeleton with notification handler infrastructure
for tracking notification ordering during ContentService refactoring.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds base class for ContentService performance benchmarks with:
- RecordBenchmark() for timing capture
- MeasureAndRecord() with warmup support for non-destructive ops
- MeasureAndRecord<T>() with warmup for read-only ops returning values
- JSON output wrapped in [BENCHMARK_JSON] markers for extraction
- skipWarmup parameter for destructive operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Added 'mandatory' tag as a visual indicator for webhook events being mandatory.
* Map the webhook validation for no events specified to a specific API response problem details message.
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
The contributing documentation still referenced the old `contrib` branch,
which was causing AI tools to incorrectly use it as the base branch for
comparisons. Updated all references to use `main` instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* Adding functionality to overwrite the cacheduration for NewsDashboard
* Making the extension its own class, as to avoid having to inherit the entire service.
* Changing options to duration and adding interface
* Only validate segment values for cultures they are defined for.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Integration test suppressions.
* Remove previous implementation using ISegmentService and rely on values provided in the model to determine segments with cultures.
* Omit null culture and remove passing but unrealistic tests.
* Fixed nullability error.
* Apply suggestions from code review
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
* Relocated function following code review.
* Reset unchanged files.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
* fix(backoffice): Tree menu item shows undefined for variant names without fallback
When a document variant has no name set and there's no fallback language
configured, the tree now falls back to the first variant with any name
instead of displaying "undefined".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(backoffice): Show (Untitled) when no variant has a name
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: uses localization string() to localize user-provided labels
* fix: localizes placeholder as well
* Refinements to the Toggle input
The localizations can happen in the `config` setter,
then they don't need to re-get the localization each re-render.
Added a `when` directive to show/hide the label `<span>` tag.
Removed `_currentLabel` as unused.
* Refinements to the Textbox input
The localizations can happen in the `config` setter,
then they don't need to re-get the localization each re-render.
Refactored the `uui-input` attributes/properties.
* Refinements to the Number input
The localizations can happen in the `config` setter,
then they don't need to re-get the localization each re-render.
Refactored the `uui-input` attributes/properties.
* Update src/Umbraco.Web.UI.Client/src/packages/core/components/input-toggle/input-toggle.element.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/property-editor-ui-text-box.element.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/Umbraco.Web.UI.Client/src/packages/property-editors/number/property-editor-ui-number.element.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Updates based on Copilot feedback
---------
Co-authored-by: leekelleher <leekelleher@gmail.com>
Co-authored-by: Lee Kelleher <leekelleher@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Added `icon-sort`
from Lucide's "arrow-down-up" icon.
* Added "Sort" package
with property action and context.
* Adds the "sort" property action and context to the Block Grid property
* [WIP] Observing sort mode toggle on Block Grid editor
* [WIP] Further work on Block Grid editor sort-mode
* Added "umb-sort-mode-toolbar" component
* Fixed typo of private method "renderNoting"
* Renamed "sort" property-action to "sort-mode"
* Corrected bad copypasta!
* Renamed "Sort" package to "Sorter"
to include the Sorter controller and maintain backwards-compatibility.
* Code updates based on @copilot feedback
* Fixed circular references
* Removed reference to "sorter/index.ts"
that I'd missed when relocating the package.
* Moved "sorter" back into "core" package
* Moved the "sort" property-action to a combined "property-actions" location
Fixed up other code, use of constants and manifest clarity.
* rename with claude code (#21036)
* rename with claude code
* include property action in name
* renaming
* Rename sortingMode to isSortMode in property sort context
Refactored property sort mode context and related components to use 'isSortMode'
* add jsdocs
* Update vite.config.ts
* no need to export as element
* add tests
* Ordered the tsconfig namespaces
* Reverted the relocation of the "sorter" controller files
* Import ordering
* Reverted some code style tweaks
* Renamed `sortingMode` to `isSortMode`
* Renamed `sortModeEnabled` to `isSortMode`
* Add tests for property sort mode action
* add js docs
---------
Co-authored-by: Mads Rasmussen <madsr@hey.com>
* fix: sets profiling cookie to httpOnly and strict in order to run non-secure
* fix: adds extra message to explain when you can set a cookie
* fix: simplify cookie explanation comment in WebProfilerRepository
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: checks that the profiler is actually enabled and/or disabled and warns the user if that is not the case
* Update src/Umbraco.Web.UI.Client/src/assets/lang/en.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: uses 'href' as property instead of attribute
* build: runs on PR to release branches
* Content references: Avoid requesting references for content that is not yet persisted server side (#21035)
* Avoid requesting references for content that is not yet persisted server side.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* refactor to use condition
* revert
* danish translations
* da translation
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
* fix: CTRL+Click now opens links in new tab on Linux
The router's anchor click handler incorrectly assumed non-Windows
platforms use Meta (⌘) key for "open in new tab". This broke
CTRL+Click on Linux, which uses CTRL like Windows.
Changed detection from "is Windows" to "is Mac" so Linux correctly
uses CTRL+Click while Mac continues to use Meta+Click.
Also replaced deprecated navigator.platform with navigator.userAgent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>