Compare commits

...
Author SHA1 Message Date
Nikolaj d868263be4 Bump version 2022-10-19 09:23:08 +02:00
4e9aa8dac2 Disable BlockGridEditor (#13229)
* Disable BlockGridEditor

* Fix typeloader test

* Update src/Umbraco.Core/Models/Blocks/BlockGridItem.cs

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>

* Apply suggestions from code review

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
2022-10-18 12:53:32 +02:00
Niels LyngsøandGitHub af468b6f28 Resync editors if content model changed (#13230) 2022-10-18 12:47:08 +02:00
Elitsa Marinovskaandnikolajlauridsen 5e96011140 Collect new .xml language files from different sources (#13212)
* Collecting new language files from different sources

* Apply suggestions from review

* Adding TODO for merging the language files locations to one when packages are not concerned
2022-10-18 08:23:32 +02:00
Niels LyngsøandGitHub 2993f1bb6d highlight areas in dragging-mode for modern browsers (#13224) 2022-10-18 08:21:54 +02:00
Niels LyngsøandGitHub 96bf197642 move below center, to make room (#13222) 2022-10-17 14:35:59 +02:00
8d8e4e0b24 10.3.0-RC: Change grid area input to number + change generic label (#13203)
Co-authored-by: Bjarne Fyrstenborg <bjarne_fyrstenborg@hotmail.com>
2022-10-17 14:02:25 +02:00
Niels LyngsøandGitHub 37424a63ec make Area fit within block row (#13221) 2022-10-17 13:55:22 +02:00
e22c7ea0d6 Merge BjarneF fix into 10.3 (#13220)
Co-authored-by: Bjarne Fyrstenborg <bjarne_fyrstenborg@hotmail.com>
2022-10-17 12:47:18 +02:00
ed66fe1277 Add data-element to umb property so we can find it (#13199)
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-13 10:30:27 +02:00
Kenn JacobsenandGitHub 0a925fd3ba Add documentation for default block grid partial views in the rendering extension methods (#13184) 2022-10-13 10:02:27 +02:00
Elitsa MarinovskaandNikolaj 0fe2c225cb Fix tags with CSV storage type (#13188)
* Fixing null check as default(NRT) is null => default(configuration?.Delimiter) is also null and we were counting on it being the same as default(char)

* Adding tests to check cases with multiple tags (or tag made of comma separated values)
2022-10-13 09:14:56 +02:00
Niels LyngsøandGitHub a0931d2042 area permission min-max inputs width increase (#13195) 2022-10-13 08:43:43 +02:00
Niels LyngsøandGitHub ff75fcd36e remove pointer-events from Image, to make drag n' drop work on firefox. (#13193) 2022-10-13 08:42:49 +02:00
Niels LyngsøandGitHub ab8d94b466 move clear:both; to the flexbox example (#13194) 2022-10-13 08:41:31 +02:00
Nikolaj GeisleandZeegaan 76b54c4b63 V10: 13099 fix validation error (#13170)
* Add validation error message to Viewpicker

* Add help-inline class to make validation-text red

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-13 08:27:14 +02:00
Nikolaj GeisleandZeegaan 63af4c487c Pass the node property to umb-property & umb-property-editor (#13151)
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-13 08:27:11 +02:00
Zeegaan 4ee827052e Merge remote-tracking branch 'origin/release/10.3' into release/10.3 2022-10-13 08:26:34 +02:00
MoleandZeegaan 213dd7114d Add missing ForceLeft and ForceRight (#13190) 2022-10-13 08:26:23 +02:00
Mole 0b3a06ff0d V10: Fix request accessor memory leak (#13152)
* Dispose OnChange event registration when disposing the notification handler

* Ensure that the ApplicationUrl is only initialized once

Since notifications handlers are transient,_hasAppUrl and _isInit defaults to false on every request causing it to always be called.

* Make notification handler and EnsureApplicationUrl internal
2022-10-13 08:26:17 +02:00
Jacob OvergaardandBjarke Berg 6e7ecd0a77 Fix for potential race condition in packages search (#13153)
* search on input allowing to wait for copy/paste etc

* invoke resourcePromise() with correct parameters

* return the xhrStatus allowing the caller to check if the request was aborted

* fix: send in canceler.promise to allow the timeout to work

* catch any errors and ignore aborts if they happen

* move the logic to handle cancellations outside Angulars $scope.$apply

* remove file accidentally committed

(cherry picked from commit 4a412bb432)
2022-10-12 12:40:02 +02:00
Nikolaj d13a55762a Re-add IsPackable to Umbraco.Tests.Integration 2022-10-12 10:30:31 +02:00
Kenn JacobsenandGitHub b8c73e7550 Add sync rendering extensions for block grid and async ones for block list (#13168) 2022-10-12 10:06:43 +02:00
Kenn JacobsenandZeegaan 7777ba40fd Fix broken selectable state for list view items (#13148) 2022-10-10 13:00:40 +02:00
Bjarke Berg fbe5ecedf9 Add dependencies that we force an update to, even that we do not use them explicitly and they seems to be taken from the framework instead of from Nuget 2022-10-07 10:02:33 +02:00
Nikolaj 0dc577b45f Remove --no-build from dotnet pack
Should fix statix assets restore problem
2022-10-05 15:42:34 +02:00
367a4b9727 Block Grid Editor (#12826)
* Refactor block list/grid property value editors for code reuse

* Prettify block grid editor data conveter a bit

* correct appearance and colors

* validation should only kick in if value is higher than 0 and not null

* Add copyright notice to code, a little formatting and file scoped namespaces where applicable

* custom views

* custom views for blocks

* Refactor block list min/max validation and reuse for block grid

* Prettify extraction of nested content-and-settings references for block grid

* Fix bad naming

* fix casing

* Refactor block list notification handler and reuse for block grid

* context sensitive ui for Blocks

* Refactor notification handlers for block list and block grid incl. unit tests

* Formatting and review

* Bump number of expected data editors in unit test

* initial progress on column options editor

* column span options UI

* column span UI adjustments

* context aware ui adjustments

* minor border improvement

* get and pick layout stylesheet

* remove random x

* make highlight border standout more

* dedicated context bar

* UI improvements

* remove annoying indication

* copy paste

* UI improvements

* remove div.umb-block-grid__block--view from partial

* show block ui, only hide when hovering area.

* area actions

* UI Adjustments

* Block grid editor localization (#12915)

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>

* fix case of empty value

* use right index

* place border on top of column indication

* heroblock

* userFlowWhenBlockWasCreated

* shorter messages

* overal improvements

* force left/right drag feature

* stylesheet picker localization

* localizations

* space

* unnesecary removal of space

* notes on masonry

* validation form parent skipping + better snapping when drag n drop

* remove icons

* make rows go as minimal as posible

* scale and drop indications

* use item width to determin forceLeft or forceRight

* clean up

* Make clipboard filtering work with block arrays

* readonly mode

* important note

* ask to revert failed paste

* dont allow for backdrop click

* changed wording

* more area actions outside grid container

* droppable indication

* implemented minimal responsive solution.

* add additional data fields about grid clumns

* improved fallback columns width + rows height

* make root element class `umb-block-grid`

* align layout with position relatives, to align visual experience.

* use clientX not screenX

* rename area classes so they dont include the word 'block'

* more renaming

* commit flexbox layout css to repo

* fixes

* fix typo

* only show a broader inline create button if the block is full width.

* simplify css

* remove headline block hover effect

* use some font, to make it look better.

* Drag and drop correctiions/limits

* clean up

* remove log

* make assumptions about proposed distance of target

* slightly white border on validation message for areas to make it standout

* drag n drop seems good at this stage

* force left and right buttons and indication

* correct if

* revert scale handler ui

* If columnSpans is empty we fall back to full width

* Access other PreValues from a PreValue Editor

* maybe temprorary turn of distance drag n' drop condition

* setDirty

* area alias was missing in razor and needed help text

* forceleft forceright translations

* forceLeft / forceRight razor

* correct translation +
remove data- on ng-click

* force placement when moving over edge

* remove unnesecary wrapper element

* show-validation

* red text, might be hard to see, lets see.

* for safety have the border-raduis correct

* better wordings

* Use mouse position to judge if the drop is good before or after.

* fit placeholder when item is begin dragged away

* initial step for finding nearest relation when drag-hovering nothing

* Much better drag n drop experience, must be tested further to prove its not breaking some cases.

* title for scale handler

* new approach + massive drag n drop clean up

* avoid complex CSS transfering of props, instead add the prop in HTML

* adjust placeAfter when in vertical direction mode

* do not scale bigger than the available space to the right

* clean css

* fix numbers

* Fix the case of flickering when hitting an empty area.

* correct placement of code

* package lock

* Adjustment for PreValue Area allowances

* comment on fit in line feature

* fixing scale and drag n drop potential issues

* clean up

* only disallow above max

* outcomment unused code

* clean up

* drag n drop above or below container

* fix for Firefox

* Do not edit block if there is no properties in content

* angularJS form for Entries, to correct validation

* parse layout columns, used to know if block is full width of the layout

* use inherited layout columns

* add this to the example html

* flexbox fix

* highlight if empty area

* comments for undefined column spans

* bring back approvedContainer lock period.

* fix

* Do not edit something without properties

* Remove Force, as thats confusing to read.

* correct localization key

* minor corrections

* Fit within context columns

* Conceptual, inline editor for Grid.

* fix casing

* consider related position in directional conditions

* set default max row span to 1

* update columnSpanOption check for sync

* move Editor to group of Rich Text

* more shift autoScroll

* assume layout columns comes as string

* fix variable name

* force left/right indication

* Inject Areas directly in slot, to enable custom view manipulations of such.

* fix sortableJS mis dropping items

* Overwrite create label

* ability to overwrite root layout create label

* Simplify PreValue editor by hidding options that is not in effect.

* Setup new areas as half width if possible

* Grouping blockTypes

* remove flexbox stylesheet

* Chose groups for area allowance

* ensure a good default width

* improve block active state

* Better contextual sizing

* Comment clean up

* Remove The StarterKit from branch

* Unique group identification for the property editor sortable

* only show avaiable block groups in picker.

* Indication of taget area

* Fallback to root grid columns

* use root layout grid columns, so dont update when layoutColumns change

* Ability to remove block group

* clean up references when removing Group or single Block

* fix drop in same group

* Block picker use contexual create label as headline

* adjust area highlight

* Prevalue editor

* structuralOptions

* Move pre values into tabs for better overview and scope

* Let area grid columns fallback to root grid columns, and let both default to "12" instead of "initial"

* remove input close tag

* Allow in areas

* Move build-in custom views

* only show property-into-button on hover when in group-panel__header

* some height for the show buttons

* filter available block type based on allowInAreas

* remove OnlySpecifiedAllowance

* unsupported block if trouble happend

* move allow at root to allowance group

* easily drop at top or below area if outside. If more than 100px outside then see if there is a parent layout to move into.

* block group validation

* shortcut for opening Areas if areas are defined

* scale label for Areas editor

* Added Legacy name on the old grid layout

* Remove files that come with the starter kit

* Sorting: takeover container detection

* Refactor models + remove unused properties

* Endpoint for creating block grid demo element types

* CTA for getting Block Grid demo blocks

* Refactor block grid sample element creation

* Fix Constants-PropertyEditors spacing

* Fixed unit tests

* Get sample configuration

* Labels for sample blocks

* Improve drag, to swap across unallowed area/root

* improved empty threshold

* hide the after inline-create-button if block is located at right side of area/layout

* clean up

* translations

* danish translations

* move outside edge for forceRight

* Update src/Umbraco.Web.Common/Extensions/BlockGridTemplateExtensions.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Review comments

* Remove leftover TODO

* big cleanup

* Hide Sample CTA when installed

* clean up

* correct styling for wrapper + moving Block UI to z-index 3 for visiblity on top of other block

* slightly adjusting inline-create-buttons to avoid collisions

* correct localization for force left/right buttons

* gitignorer update

* Clean up nesting of classes in BlockGridConfiguration

* change gitignorer to include App_Plugin folder

* move default layout stylesheet

* remove specific App_plugin folder

* package-lock

* update sample custom views paths

* add custom views for sample

* Adding sample custom views

* Move sample partial Views and custom views

* Update views to not use ModelsBuilder

* Move sample custom views to wwwroot

* Updated Sample CTA text

* Use localize directory

* Ensure groupKey for items without such to work.

Co-authored-by: kjac <kja@umbraco.dk>
Co-authored-by: Warren Buckley <warren@umbraco.com>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2022-10-05 13:50:26 +02:00
efb994ecf7 Adds a parameter to BeginUmbracoForm to allow the disabling of the creation of an antiforgery token. (#13037)
* Addes a parameter to BeginUmbracoForm to allow the disabling of the creation of an antiforgery token.

* Updated project references for Forms and Deploy in the JsonSchema project.

* Revert "Updated project references for Forms and Deploy in the JsonSchema project."

This reverts commit a749b45ab8.

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-05 12:56:42 +02:00
a745250d39 Removing can connect to database check so that Umbraco errors out on … (#13118)
* Removing can connect to database check so that Umbraco errors out on startup rather than trying to re-install when unable to connect to database.

* Revert breaking change

* Support installs of missing databases if the provider CanForceCreateDatabase. Else not

Co-authored-by: Austin Gilbert <AGilbert@rbaconsulting.com>
2022-10-05 12:44:18 +02:00
Ronald BarendseandGitHub bc21c64617 v10: Cleanup project files (#13111)
* Backport project cleanup from #12907

* Remove empty Directory.Build.props

* Fix GenerateAppsettingsSchema target

* Re-add empty Directory.Build.props to prevent inheritance

* Add NRT to-do comment

* Explicitly generate HTTPS development certificate for E2E test
2022-10-05 12:11:51 +02:00
0feb947048 V10/bugfix/fix acceptance test (#13106)
* Fixed test for tab 'Drags and drops a property in a tab'

* Fixed test for macro 'Create macro'

* Fixed test for dataTypes 'Tests Approved Colors', 'Tests Textbox Maxlength', 'Test Url Picker'

* Fixed: Added more waitForTimeout on the test Tests Approved Colors.

* Fixed test for packages 'Create a simple package' test

* Removed unnecessary waitForTimeout

* Changed waitForTimeout to waiting until an element isVisible

* bumped test-helper packed to 1.0.2

* Removed duplicate isSuccessNotificationVisible

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2022-10-05 08:26:02 +02:00
ae6bee7b0b V10: Dont delete member on failed autolink (#12996)
* Disapprove member instead of delete if failed autolink

* Update to not disable the member when external login fails, but move the logic to protected method, to make it easy to extend.

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2022-10-05 08:19:22 +02:00
Andreas ZerbstandGitHub 99c7f966bd Merge pull request #13095 from umbraco/v10/feature/export-test-artifact
V10: Export test artifacts
2022-10-04 14:24:08 +02:00
cd748cd7c8 New backoffice: models builder dashboard controller (#13050)
* Add OutOfDateType model

* Add ModelsBuilderDashboardControllerBase

* Add BuildModelsController.cs

* Add StatusModelsBuilderDashboardController

* Change to return created and not OK

* Remove unused usings

* Add GetModelsBuilderDashboardController

* Add OpenApi attributes

* Fix formatting

* Fix up dependency injection for ModelsBuilderSettings

* Fix up naming and routing

* Fix up OpenApi attributes

* Remove ability to send raw HTML in dashboard

* Remove obsolete property

* Dont include dashboard in the name

* Async controllers

* Return ActionResults

* Fix up OpenApi contract

* Fix missing usings

* Update src/Umbraco.Cms.ManagementApi/Controllers/ModelsBuilderDashboard/ModelsBuilderControllerBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* use VersionedApiBackOfficeRouteAttribute for routing

* Fix up open api spec

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
2022-10-04 13:11:30 +02:00
72fd393272 New backoffice: New Api controllers (#12983)
* Create migrate Language controller to Umbraco.Cms:ManagementApi

* Add proper language mapping

* Update mapping to handle if language name is null

* Uncomment code

* Add new language view model

* Add LanguageViewModelMapping

* Add mapper registration

* Fix up AddMappers extension method

* Implement mapping IEnumerable of languages

* Change action signatures to ViewModel instead of model

* Seperate logic from controller into service

* Move LanguageService.cs

* Register service

* Fix up mapping

* Add null check to mapping instead of controller

* Map to ILanguage instead of implementation

* Fix up null check

* Implement ProblemDetailsBuilder.cs

* Rename duplicate method

* Use builder in actions

* Implement new Paged models

* Create language controller base

* Use pagedModel for GetAllLanguages

* Create GetAllLanguagesPaged method

* Split language controller into single APIs

* Fix up controllers with API versions

* Map Total property

* Fix up route and naming for GetLanguageController.cs

* Fix up naming for language controllers

* New folder structure

* Add culture controllers

* Map CultureInfos to paged CultureViewModel

* Remove wierd include in csproj

* Refactor controller to return pagedViewModel instead of dictionary

* Fix up mapping to map single and enumerable

* Register mapping

* Add apiversion to controller

* Add inheritdoc

* Create DictionaryControllerBase.cs

* Add delete controller

* Only use HttpDelete for deletes

* Check also if language exists in service

* Split Save action into Create & Update actions

* Update Http attributes on Create and update controllers

* Proper routing for delete controller

* Add api version

* Make action async

* Implement CreateDictionaryController

* Create DictionaryViewModel.cs

* Use viewmodel instead of values

* Create get by int DictionaryController

* Add view models

* Rename controller

* Rename DictionaryViewModel to DictionaryItemViewModel

* use created instead of ID

* Apply DataContract/Datamember to view model

* change to guid instead of Guid

* Use proper responses instead of return models when creating/updating

* Implement new IDictionaryService

* Implement new MoveController

* Use new service in mapper

* Remove unused method

* Add DictionaryViewModelMapDefinition

* Create MoveOrCopyViewModel

* Proper Http action

* Create UpdateDictionary controller

* Map IDictionaryItem to DictionaryViewModel

* Add JsonPatching

* Add UpdateDictionaryController.cs

* Map DictionaryTranslationsDisplays properly

* ParentId should be nullable

* Add new DictionaryTranslationViewModel.cs

* Remove translationViewModel

* Add Id and Key to DictionaryTranslationDisplay.cs

* Implement IDictionaryFactory.cs

* Create DictionaryViewModels and do not use IEntity

* Map to new view models instead of displays

* Register the factiories in the service container

* Remove newtonsoft

* Add serializing to and from PatchDocs

* Use JsonPatchViewModel instead of object type

* Add JsonPatch.Net to csproj

* Implement JsonPatchService.cs

* Register JsonPatchService

* Make model non-nullable

* Update controllers to use new attributes

* Rename MoveViewModel.cs

* Remove NameIsDirty as that is legacy from how we used to handle updating

* Add GetAllDictionaryController

* Add todo to DictionaryControllerBase

* Add ExportDictionaryController

* Add ImportDictionaryController

* Remove unused umbraco mapper

* Add upload dictionary controller

* Create Dictionary import view models

* Update UploadDictionaryController with view models

* Remove unused using

* Implement pagedviewmodel for GetAllDictionaryController.cs

* Add dictionary overview viewmodels

* Add mapping for DictionaryOverViewModel

* Update Dictionary controller to use new viewmodel

* Fix up attributes for UploadDictionaryController

* Make actions async

* Make controller bases abstract

* Fix after merge

* New backoffice: Analytics controller (#12957)

* Add AnalyticsControllerBase

* Add AnalyticsViewModel

* Add GetAnalyticsController

* Update ViewModel to use System.Text.Json

* Add SetAnalyticsController

* Add AnalyticsLevelViewModel

* Add GetAllAnalyticsController

* Add viewmodel factory

* Register factory for DI

* Use factory for creation of ViewModel

* Fix up AnalyticsLevelViewModel.cs

* Use analyticsLevelViewModel

* Add Enum validation to controller

* Add OpenApi attributes

* Add routing to GetAllAnalyticsController

* Rename IPagedViewModelFactory

* use new renamed PagedViewModelFactory

* Make actions async

* Make controller base abstract

* Fix up after merge

Co-authored-by: Zeegaan <nge@umbraco.dk>

* New backoffice: Help controller (#12958)

* Add HelpControllerBase

* Add HelpPageViewModel

* Add GetHelpController

* Add viewmodel factory

* Register factory for DI

* Use PagedViewModelFactory for controller

* Update baseurl to be nullable

* Rename IPagedViewModelFactory

* Use new renamed IPagedViewModelFactory

* Dont use httpclient as field

Co-authored-by: Zeegaan <nge@umbraco.dk>

* New backoffice: Relation controller (#12961)

* Add relation controller base

* Add commen about auth

* Add GetRelationController

* Use mapping to viewmodel

* Add RelationViewModel

* Add RelationViewModelsMapDefinition.cs

* Add viewmodel factory

* Register factory for DI

* Rename IPagedViewModelFactory

* Add RelationViewModelFactory

* Remove unused service

* Add GetByChildRelationController

* Add relationViewModelFactory to DI

* Add MappingBuilderExtensions

* Add relationViewModelsMapDefinition to DI

* Use PagedViewModel for child relations

* Add CreateMultiple

* Update GetRelationController to use factory instead of direct mapping

* Update GetByChildRelationController to use relationViewModelFactory

* Fix up after merge

Co-authored-by: Zeegaan <nge@umbraco.dk>

* New backoffice: Tracked references controller (#12966)

* Add TrackedReferencesControllerBase.cs

* Add GetTrackedReferencesController

* Add relation model

* Add ITrackedReferencesRepository.cs

* Rename relation to RelationModel

* Add RelationMapDefinition.cs

* Add TrackedReferencesSkipTakeRepository

* Rename RelationModelMapDefinition

* Add new services to DI

* Rename RelationModel to RelationItemModel

* Implement TrackedReferencesSkipTakeService

* Formatting

* Add RelationItemViewModel.cs

* Add mapdefition

* Update TrackedReferencesController to use new PagedViewModel

* Add service to DI

* imlement proper routing

* Add async to GetTrackedReferencesController.cs

* Rename action to get

* Add DescendantTrackedReferencesController

* make filterMustBeIsDependency nullable

* Use count instead of capacity

* Rename controller

* Add MultipleTrackedReferencesController.cs

* Refactor TrackedReferencesService to not return pagedViewModel

* Remove TODO untill consensus on convention

* Formatting

* Delete old duplicate controller

* Fix up naming

* Fix up naming and fixed todo

* Fix up mapdefinition registrations

* Rename controllers

* Fix naming

* Fix nullable tree

* Fix up relation controller & action names

* Fix naming

* Fix up multiple to not be post

* Apply suggestions from code review

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Remove [ApiVersion] from each individual controller and added to base instead

* Added missing semi-colon

* Update all "non-async async" endpoints to return Task.FromResult

* Fixed up LanguageViewModels namespace

* Return proper status code

* Update xml documentation

* Rename GetAllCultureController

* Change return type attribute to proper Model

* Change return type attribute to correct model

* Add clarifying comment

* Change return type attribute to proper model

* Rename ById to by key

* Update DictionaryOverviewViewModel to use Key instead of ID

* Implement factory method to create viewModel instead of using services in mapper

* Fix up DictionaryItemViewModel to use Parent GUID instead of ID

* Update return type attribute to correct model

* Update key to actual GUID instead of string

* Update route to not include "delete"

* Remove redundant IActionResult specification

* Update responseType attribute to correct models

* Update OpenApiTag for DictionaryControllerBase

* Update ResponseType attribute to correct models

* update variable name to not be "XD"

* Update ResponseType attribute to correct model

* Update route to not include "update" as it is redundant

* Update produces responsetype attributes to correct models

* Use IJsonSerializer abstraction instead of JsonConvert directly

* Remove unused field

* Change ResponseType attribute to correct model

* change TrackedReferencesSkipTakeService to return pagedModels directly

* Remove duplicate DI

* change to better variable names

* Move RelationItemModel to core

* Remove empty folder

* Remove ITrackedReferencesSkipTakeService and add it to TrackedReferencesService

* remove TrackedReferencesSkipTakeRepository and add to TrackedReferencesRepository.cs

* Fix up TrackedReferencesService to not use SkipTake repository

* Remove AddRepositories from ManagementApiComposer

* Transition to ManagementApiBaseController

* Fixes ResponseType attribute to correct model

* Add loading files to service instead of having logic in controller

* Add todo comment

* Fix up routing for delete language

* Use problem details builder

* Add SystemTextJsonSerializer

* Add SystemTextJsonSerializer

* Remove unused usings

* Remove obsolete MoveDictionaryController

* Remove CreateDate and UpdateDate from DictionaryViewModel

* Change response type to correct model

* Remove PagedViewModelFactory.cs

* Add obsolete message

* Fix installer view models

A setter is required for the modelbinder to be able to do its work

* Update src/Umbraco.Cms.ManagementApi/Controllers/Analytics/SetAnalyticsController.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update ResponseType to correct Model

* Update comment

* Add FileUploadService

* Add DictionaryFactory.cs to handle creation of viewmodel

* Remove unused DI

* Rename actions & controllers to reflect eachother

* Update OpenApi.json

* Add dictionary to openapi

* Update in proper alphabetical order

* Add trackedReferences to openapi

* Fix open api doc

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-04 11:34:55 +02:00
Sebastiaan Janssen 71276b7b4d Merge branch 'v10/dev' into v10/contrib 2022-10-03 13:43:27 +02:00
5115af0a31 Revert "Removing X-XSS-Protection healthcheck" (#13096)
This reverts commit 696475ebf2.

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-10-03 08:37:09 +02:00
Zeegaan 6eb57302fb Give proper variable name 2022-10-03 07:38:49 +02:00
Zeegaan 9e82bc5a46 Remove unused pipelines variable 2022-10-03 07:37:47 +02:00
Zeegaan 2a506320f1 Remove echo from build 2022-10-03 07:36:40 +02:00
Zeegaan 212c036052 Refix user test 2022-10-03 07:35:56 +02:00
Karl ButlerandMichael Latouche bdbf9122c9 Fixes umbraco/Umbraco-CMS.Accessibility.Issues #63 and #61 2022-10-03 02:53:48 +02:00
Patrick de MooijandMichael Latouche 97ac1ae629 Added nullability attribute to IsNullOrWhitespace 2022-10-03 00:05:18 +02:00
Bjarne FyrstenborgandMichael Latouche aa9a7e415e Don't use legacy icon for action delete 2022-10-02 23:18:02 +02:00
bakersbakebreadandMichael Latouche d6a1b69ead Refactor event handler away from keyup to ng-change 2022-10-02 22:09:17 +02:00
Zeegaan f0fe5261f2 Add echoing 2022-09-30 13:38:14 +02:00
Zeegaan cde1a27ff4 Add proper failing test 2022-09-30 13:37:38 +02:00
Zeegaan 74a2dd88c3 Add failing test 2022-09-30 12:03:05 +02:00
Zeegaan 89c5ef9582 Update yml to use powershell to check folder 2022-09-30 12:01:54 +02:00
8c61e9e00b Update acceptance test readme & scripts (#13078)
* Update readme to reflect the change to playwright

* Update test scripts

* update README

* update pipelines to run new script

* update package.json scripts

* dont include demo test in package.json

* Add creation of blueprint test

* Implement create test script

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-30 11:45:26 +02:00
patrickdemooij9andGitHub ae5a8496bb Use char instead of string for DetectJson (#13019)
* Use char instead of string for DetectJson

* Use faster method

* Change DetectIsJon method
2022-09-30 01:39:54 +02:00
Bjarne FyrstenborgandGitHub 826dbe7d62 Fix comment of view property in ConfigurationFieldAttribute (#13077)
* Fix comment of view property in `ConfigurationFieldAttribute`

* Update description of key property as well
2022-09-29 11:07:56 +02:00
89f5151ddf Implement playwright acceptance tests instead of cypress (#13069)
* fix up dependencies in package.json

* Change configs to playwright

* update types

* remove cypress

* add playwright

* Fix up imports

* Move up test files

* Fix up scripts

* Update user import

* Remove allowEditInvariantFromNonDefault=True.spec.ts

* Update docker container

* Run playwright on pipelines

* Install playwright

* change urls

* change to run playwright

* Update reporter

* create .env file when installing

* update pipelines

* Remove @in yml

* Update Yaml script to use New-Item

* Pipe object to Value

* Update yaml to use "" not {}

* Update localhost to proper port

* Push package-lock.json

* include dotenv in package.json

* Add back umbraco.config.ts

* Dont change launchSettings.json

* Fix up pipelines

* Change working directory

* Add logging

* Actually name the file

* Remove .env from path

* Add working directory

* Add working directory to script

* check env content

* Update more working dir

* Try making newline in YAML

* add quotes

* Try multiline infront of script

* Move top statement

* use https

* Update to localhost 44331

* ignore https in config

* Change linux to https

* add timeouts for tests

* Fix up url for linux

* Update docker to use port 44331 -> 5000

* increase timeout

* Update yaml

* Remove Cypress references and fix URL/port mapping

* Update umbraco-linux.docker

* Generate ASP.NET HTTPS development certificate

* Enable HTTPS development certificate in Docker

* Dont run failing tests

* Update HTTPS development certificate generation

* Copy nuget.config to correct location in Docker file

* do not run flaky test

* update outputdir

* Remove flaky tests

* Update to dot reporter

* Update to json-models-builders package

* Check if results folder exists

* Remove logging

* Use bash to find folder

* Dont use junit to report

* only publish if folder exists

* Add 5 retries for CI

* search correct folder

* Remove unused json file

* Use line reporter

* Remove umbraco.config.ts

* Remove more flaky test

* Add waits so we dont bombard SQLite

* Add page as parameter

* add page as parameter

* Remove flaky macro test

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Ronald Barendse <ronald@barend.se>
2022-09-29 10:49:33 +02:00
Justin NevilleandMichael Latouche 3d88ed7ab2 Fix issue 13023 - Cannot read properties of undefined (reading 'allowedActions') 2022-09-29 01:51:33 +02:00
Justin NevilleandMichael Latouche 48269143d5 Redirect to a return URL if one is present on the querystring when logging into the back office 2022-09-29 01:09:41 +02:00
Austin GilbertandMichael Latouche 696475ebf2 Removing X-XSS-Protection healthcheck 2022-09-28 23:55:41 +02:00
Jeavon LeopoldandMichael Latouche 17101da620 Bump Smidge up to v4.1.1 2022-09-28 22:43:51 +02:00
Bjarne FyrstenborgandMichael Latouche 0e25d06698 Use pattern matching to check if items is not JArray 2022-09-28 21:54:54 +02:00
134b193c74 New backoffice - trees design (#12963)
* Refactor: Add default versioned back office route attribute

* Tree controller bases and first draft implementations for document, media and doctype

* Move tree item view models to appropriate location

* Fix missing parent

* Refactor user entity access for testability

* A bit of clean-up + handle user start nodes for items endpoint

* Implement foldersOnly for folder tree

* Items endpoint for document type tree

* Strongly typed action results

* Content + media recycle bin

* Correct return type for swagger

* Member type tree

* Rename user start node handling to make a little more sense

* Revert to faked admin start nodes in document tree

* Media type tree

* Data type tree

* Relation type tree

* Remove unused dependency from member type tree

* Correct documentation for member type tree endpoint response types

* Use icon constants

* Add templates tree

* Member group tree

* Document blueprint tree

* Partial views, scripts and stylesheets trees

* Static files tree

* Clarify "folders only" state

* Comments and improved readability

* Rename TreeControllerBase and TreeItemViewModel

* Move recycle bin controller base to its own namespace

* Moved tree base controllers to their own namespace

* Common base class for tree view models

* Remove ProblemDetails response type declaration from all actions

* Add OpenApiTag

* Various review comments

* Dictionary item tree

* Renamed all tree controllers to follow action/feature naming convention

* Handle client culture state for document tree

* Support "ignore user start nodes" for content and media + refactor how tree states work to make things more explicit

* Fix or postpone a few TODOs

* Make entity service able to paginate trashed children

* Handle sorting explicitly

* Re-apply VersionedApiBackOfficeRoute to install and upgrade controllers after merge

* Use PagedViewModel instead of PagedResult for all trees

* Explain the usage of UmbracoObjectTypes.Unknown

* Introduce and apply GetMany pattern for dictionary items

* Add a note about relation type caching

* Fix broken test build + add unit tests for new localization service methods

* Use new management API controller base

* Entity repository should build document entities for document blueprints when getting paged entities (same as it does when getting specific entities)

* Use Media type for Media recycle bin

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Move shared relation service to concrete implementations

* Use inclusive language

* Add 401 response type documentation to applicable trees

* Refactor entity load for folder tree controller base + ensure that folders are only included in the first result page

* Add (in-memory) pagination to dictionary tree

* Make file system controller honor paging parameters

* Support pagination in relation type tree

* Clarify method name a bit for detecting tree root path requests

* Update Open API schema to match new trees

* Move from page number and page size to skip/take (with temporary workaround for lack of property skip/take pagination in current DB implementation)

* Update OpenAPI schema to match skip/take

* Update OpenAPI schema

* Don't return paginated view models from "items" endpoints

* Update OpenApi schema

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
2022-09-28 13:37:59 +02:00
Nikolaj GeisleandGitHub 3752f51625 Make Searchers endpoint return ActionResult (#13068) 2022-09-28 13:00:27 +02:00
Ronald Barendse 7890a265ab Internalize Umbraco.Cms.ManagementApi references 2022-09-27 23:43:07 +02:00
Ronald Barendse b0ea7bc076 Add BuildProjectReferences=false to dotnet pack 2022-09-27 17:23:56 +02:00
Ronald Barendse 418db7d325 Update build script 2022-09-27 17:07:24 +02:00
a0e51e3b91 New backoffice: examine management controller (#12981)
* Add ExamineManagementControllerBase

* Add ExamineIndexModelFactory

* Add IndexesExamineManagementController

* Add proper attributes

* Implement ExamineIndexViewModel.cs

* formatting

* Add comment about it working in .NET 7

* Add SearchersExamineManagementController.cs

* Update comments about why it might throw errors

* Add SearchResultViewModel

* Add SearchExamineManagementController

* Add ExamineSearcherValidationService

* Rename ExamineSearcherValidationService.cs to ExamineSearcherFinderService.cs

* Rename interface aswell

* Add SearchExamineManagementController

* Refactor ExamineSearcherFinderService

* Add HasIndexRebuiltExamineManagementController.cs

* Fix up formatting

* Async actions

* Add RebuildIndexExamineManagementController.cs

* Rename IExamineIndexModelFactory to IExamineIndexViewModelFactory

* Refactor HasIndexRebuilt endpoint to Index endpoint

* Remove unused usings

* Fix up DetailsExplanation

* Create dedicated SearchersViewModel

* Rename action

* Rename RebuildIndex to Rebuild

* Dont have changes in ExamineIndexModel

* Make values strongly typed instead of generic lists of strings

* Rename to non-plural

* Rename to non-plural

* Rename controller

* Introduce ITemporaryIndexingService

* Introduce ITemporaryIndexingService

* Add SearcherName to view model

* Move to new ExamineManagementControllerBase.cs

* Refactor ExamineManagerService

* Use init instead of setters

* Make properties explicitly on models

* Add DI

* Apply suggestions from code review

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>

* Rename to IndexExamineManagementController

* Return ViewModel instead of exception

* Make view models non-nullable

* Add examine management extension point

* Rename to IndexingRebuilderService

* Move rebuild logic to service

* Fix up usages in IIndexingRebuilderService

* Fix up DI

* Fix OpenApi contract

* Implement CanRebuild on IIndexingRebuilderService.cs

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
2022-09-27 11:30:59 +02:00
Justin NevilleandMichael Latouche 90cabb5e2b Fix issue toggling boolean between true/false after Save without refreshing 2022-09-27 02:01:16 +02:00
Busra SengulandGitHub 24b338a7a3 Fixes #12972 for validating legacy member passwords (#12973)
* Fixes #12972 for validating legacy member passwords

* Removed unused variable

* removed unused variable
2022-09-27 00:37:59 +02:00
MoleandGitHub 476692c4a9 Merge pull request #13061 from umbraco/merge/10.2.1
Merge/10.2.1
2022-09-26 12:54:51 +02:00
Nikolaj e97354dff9 Merge branch 'release/10.2.1' into merge/10.2.1
# Conflicts:
#	version.json
2022-09-26 12:53:19 +02:00
Mads RasmussenandNikolaj 25a20cf741 Add null check for variants in Grid Layout (#13060)
This fixes a regression from 10.2.0 where the `variants` property was removed.
2022-09-26 12:33:20 +02:00
Mads RasmussenandGitHub a342e4747f Add null check for variants in Grid Layout (#13060)
This fixes a regression from 10.2.0 where the `variants` property was removed.
2022-09-26 12:21:08 +02:00
MoleandGitHub 7493e5e1fd Add spellcheck false to password inputs (#13059) 2022-09-26 11:25:59 +02:00
Kenn JacobsenandGitHub e1d438701b Make sure swagger tags and operations are sorted alphabetically (#13055) 2022-09-24 09:50:32 +02:00
4b39cfe913 Bug fix for datepicker with offset time (#12847)
* https://github.com/umbraco/Umbraco-CMS/issues/12844

* remove "X" from ng-attr

Doing the test I killed the ng-if attr. But forgot it was there doing the commit

Co-authored-by: Lucas Bach Bisgaard <lom@novicell.dk>
2022-09-23 14:36:02 +02:00
c903c8a1a0 New Backoffice: Published cache controller (#13034)
* Add published cache controller (endpoints for the Published Status dashboard)

* Update OpenAPI contract for published cache endpoints

* Fix OpenApi spec

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-23 14:03:16 +02:00
Kenn JacobsenandGitHub 12a341f67d New endpoint for web profiling dashboard (#13038)
* Endpoint for web profiling dashboard

* Add profiling API contract
2022-09-22 13:41:26 +02:00
9a9bd6e480 Missing methods from IMemberService (#13022)
* Add back methods to interface

* Add default implementations to avoid breaking changes

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-22 10:51:48 +02:00
SeanandNikolaj b7f4f95f4b pass in parameters needed to member service (#13020) 2022-09-22 10:51:16 +02:00
Jacob OvergaardandNikolaj 4b25beea8b improve pip classList add/remove with no intermediary variable 2022-09-22 10:43:28 +02:00
Jacob OvergaardandNikolaj 3f6fc6f761 add an extra check to ensure the pips exist before adding a class to them 2022-09-22 10:43:12 +02:00
Mads RasmussenandGitHub b9f58a7bc4 Merge pull request #13044 from umbraco/bugfix/ab22651-slider-pips
Fix regression of active pips handling with noUiSlider
2022-09-22 10:22:50 +02:00
Kenn JacobsenandGitHub 986635c8a0 UmbracoPath has been removed from the official schema store, remove temporary workaround from our schema generator as well (#13043) 2022-09-22 10:18:40 +02:00
Andy ButlandandZeegaan 68f9a1e68c Updated project references for Forms and Deploy in the JsonSchema project. (#13047) 2022-09-22 07:53:37 +02:00
Andy ButlandandGitHub 4e6e0d6e14 Updated project references for Forms and Deploy in the JsonSchema project. (#13047) 2022-09-22 07:50:45 +02:00
Erik-Jan WestendorpandGitHub a95f4504eb Translate "User permissions for languages" feature to español (#12975)
* Translate 'selectLanguages' to Español

* Translate 'languagesHelp' to español

* Translate 'allowAccessToAllLanguages' to spanish
2022-09-22 01:22:34 +02:00
Erik-Jan WestendorpandGitHub 2f84d3071a Translate "User permissions for languages" feature to dutch (#12971)
* Translate 'sectionsHelp' to Dutch

* Translate 'selectLanguages' to Dutch

* Transkate 'allowAccessToAllLanguages' to Dutch
2022-09-22 01:10:17 +02:00
Sebastiaan Janssen 4effe1d462 Bump version to 10.2.1 2022-09-21 16:21:57 +02:00
Bjarne FyrstenborgandSebastiaan Janssen 0142ade713 Ensure consistent margin on headings in tree root (#12992)
(cherry picked from commit 88bfef9e0d)
2022-09-21 16:18:55 +02:00
Bjarne FyrstenborgandGitHub 88bfef9e0d Ensure consistent margin on headings in tree root (#12992) 2022-09-21 16:10:40 +02:00
Mads RasmussenandJacob Overgaard 3139ad99e0 Only contain style instead of full layout (#13033) 2022-09-21 15:58:51 +02:00
Jacob Overgaard 348f3e71ea improve pip classList add/remove with no intermediary variable 2022-09-21 15:37:57 +02:00
Jacob Overgaard 65d065fb54 add an extra check to ensure the pips exist before adding a class to them 2022-09-21 14:59:54 +02:00
Sebastiaan Janssen cbfeba0807 Fix CodeQL duplicate "permissions" node and reformat 2022-09-20 16:03:57 +02:00
Mads RasmussenandJacob Overgaard 9827e18186 Only contain style instead of full layout (#13033) 2022-09-20 13:54:54 +02:00
Mads RasmussenandGitHub 92cde25a3e Only contain style instead of full layout (#13033) 2022-09-20 13:54:06 +02:00
Kenn JacobsenandGitHub a390ad1c3c UmbracoPath should no longer be configurable (#13032)
* UmbracoPath should no longer be configurable

* Remove UmbracoPath configuration from all tests
2022-09-20 13:19:18 +02:00
d872d6228f New backoffice/add system text json configuration attribute (#12998)
* Add SystemTextJsonConfigurationAttribute

* Fix up formatting

* Rename classes for clearer purpose

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-20 12:40:50 +02:00
Sebastiaan Janssen 732373b694 Merge branch 'v10/dev' into v10/contrib 2022-09-20 10:51:14 +02:00
954d3ecc86 v10: add Umbraco UI Library to the backoffice (#13031)
Co-authored-by: Warren Buckley <warren@umbraco.com>
2022-09-20 09:58:59 +02:00
48954bb36a New Backoffice - Exposing hardcoded Open API contract (#12953)
* Only expose swagger ui when in development

* Only expose swagger ui when in development + Test confirming the contract is respected + contract

* Rollback test code

* Fix up formatting

* Add reference to managementapi in integration tests.

* Revert "Add reference to managementapi in integration tests."

This reverts commit 67e2bf8277.

* Fix integration tests

* Add reference to management api in integration tests

* Fix up schema

* Fixed tests

* Fix test.. do not execute that composer twice

* Revert "Updated dependencies and fixed new NRT issues"

This reverts commit b2b2903a6e.

* Added debug info to test, to debug on azure pipeline

* Try and fix OpenApi test

* Only run test in release

* Try fixing OpenApi.json

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2022-09-20 09:50:34 +02:00
Sebastiaan Janssen b72a2c7fdc Merge branch 'v10/dev' into v10/contrib 2022-09-20 09:11:54 +02:00
Sebastiaan Janssen 8d5fb41ab7 Revert "Updated dependencies and fixed new NRT issues"
This reverts commit b2b2903a6e.
2022-09-20 09:08:28 +02:00
Sebastiaan Janssen 85e31bd12d Merge branch 'v10/dev' into v10/contrib
# Conflicts:
#	src/Umbraco.Core/EmbeddedResources/Lang/en.xml
#	src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
2022-09-19 16:48:36 +02:00
Bjarke BergandSebastiaan Janssen b2b2903a6e Updated dependencies and fixed new NRT issues
(cherry picked from commit 803c044b60)
2022-09-19 16:21:50 +02:00
Jacob OvergaardandSebastiaan Janssen 1fe4c5169c V10: Fix to allow dragged images in the rich text editor to be correctly uploaded (#13016)
* update string extensions IsFullPath to support more filepaths with new built-in Path.IsPathFullyQualified

* resolve TODO to switch to Path.IsPathFullyQualified supported from .NET Standard 2.1

* Use content root instead of web root for uploaded images

* Un-break a breaking change

* handle special parsing of AngularJS json response

* change htmlId selector to support html id's with numbers

* remove bad test case

* test IsFullPath without tricky UNC paths that are not useful

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
(cherry picked from commit d18dc92137)
2022-09-19 16:21:20 +02:00
Jacob OvergaardandSebastiaan Janssen 963d0018c2 update npm packages
@microsoft/signalr: 6.0.9
ace editor: 1.10.1
clipboard: 2.0.11
jquery: 3.6.1
jquery-ui: 1.13.2
moment.js: 2.29.4
nouislider: 15.6.1
underscore: 13.13.4
wicg-inert: 3.1.2

dev updates: karma, jasmine, less and postcss

(cherry picked from commit ad1c945bb1)
2022-09-19 16:20:55 +02:00
Kenn JacobsenandSebastiaan Janssen 07b7ef200a Add custom PrependBasePathFileProvider to handle media files with special characters (#12936)
(cherry picked from commit e9883ea063)
2022-09-19 16:20:44 +02:00
MoleandSebastiaan Janssen 22576edd70 Backoffice api: Refactor controllers (#12934)
* Refactor install controller

* Removed unused InstallationTypeTarget

* Add ApiVersion to controllers

* Refactor upgrade controller

* Add missing RequireRuntimeLevelAttribute

(cherry picked from commit a356cf4f40)
2022-09-19 16:20:23 +02:00
Nikolaj GeisleandSebastiaan Janssen 352da6c529 V10: Update examine dependency (#12982)
* Update Examine.Lucene to newest version

* Update other projects

(cherry picked from commit 09e2b04f91)
2022-09-19 16:19:44 +02:00
nikolajlauridsenandSebastiaan Janssen 79c67338e7 Ensure new projects use the correct apssettings key for AllowEditInvariantFromNonDefault
(cherry picked from commit ae516b28db)
2022-09-19 16:19:23 +02:00
NikolajandSebastiaan Janssen 788f8c6ab3 Undo breaking change
(cherry picked from commit 5bb38b39c9)
2022-09-19 16:19:02 +02:00
Nikolaj GeisleandSebastiaan Janssen 0c84b1a051 Extend error message with possible solution (#12962)
Co-authored-by: Zeegaan <nge@umbraco.dk>
(cherry picked from commit 82934838cc)
2022-09-19 16:18:52 +02:00
MoleandSebastiaan Janssen 48c981d31f Hotfix: Move allow edit invariant from non default setting to content settings (#12960)
* Use ContentSettings instead of SecuritySettings for AllowEditInvariantFromNonDefault

* Make it backwards compatible

(cherry picked from commit 3846c75cc6)
2022-09-19 16:18:41 +02:00
Sebastiaan Janssen aa7a7c4691 Fix tree root font being larger than it used to be
(cherry picked from commit 2ad6633d47)
2022-09-19 16:18:32 +02:00
Bjarke BergandSebastiaan Janssen 0a77775bb1 Fixed InstallAuthorizeAttribute and simplified other things
(cherry picked from commit da24ae9180)
2022-09-19 16:18:19 +02:00
NikolajandSebastiaan Janssen 3ab57ce691 Bump version
(cherry picked from commit d038f860bd)
2022-09-19 16:18:07 +02:00
Nikolaj GeisleandSebastiaan Janssen 7d0be19199 Add PagedViewModel (#12955)
Co-authored-by: Zeegaan <nge@umbraco.dk>
(cherry picked from commit 9a2ead4381)
2022-09-19 16:17:47 +02:00
Bjarke BergandSebastiaan Janssen 5500f87223 Limit what API does when not in used in Install level
(cherry picked from commit 7b00c0d3e9)
2022-09-19 16:17:39 +02:00
Nikolaj GeisleandSebastiaan Janssen 7852220827 Use staticserviceprovider to provide service (#12939)
Co-authored-by: Zeegaan <nge@umbraco.dk>
(cherry picked from commit 89d1d7cd9c)
2022-09-19 16:16:45 +02:00
MoleandSebastiaan Janssen 669f8ff5ba Backoffice Api: Server Controller (#12932)
* Add initial implementation using 1 controller pr. action

* Add OpenApiTag attribute

Otherwise the endpoints won't be grouped correctly

* Use correct response type

* Move ApiVersion to endpoint controllers

* Add ServerController suffix to endpoint controllers

(cherry picked from commit 9cf7e965a9)
2022-09-19 16:16:32 +02:00
Jacob OvergaardandSebastiaan Janssen 126a2593ee remove styling from installer (#12923)
This styling is now being imported from components/umb-range-slider.less and is no longer needed here

Previously fixed in 52672d2c2b

Ref https://github.com/umbraco/Umbraco-CMS/pull/12807/files/52672d2c2ba046f1da431388ec95b21b30965f08#r957799952

(cherry picked from commit 87ced87ddd)
2022-09-19 16:16:22 +02:00
Nikolaj GeisleandSebastiaan Janssen 6b967a9693 Add virtual SetUpTestConfiguration method (#12928)
(cherry picked from commit 2cef243056)
2022-09-19 16:16:12 +02:00
Kenn JacobsenandSebastiaan Janssen 147c60f04b Performance improvement: Reusable data editors (#12921)
* Introduce opt-in option for reusable data editors

* Verified RTE as reusable

* Make attribute property naming more explicit + update comments

* Test file upload and image cropper

* Add unit tests

(cherry picked from commit 44122c6509)
2022-09-19 16:16:03 +02:00
Sebastiaan Janssen 6302630d39 Revert "Break word for limited width content"
This reverts commit 448836ee2d.

(cherry picked from commit 07fba1eb84)
(cherry picked from commit 5fc6fa58c0)
2022-09-19 16:15:52 +02:00
Mayur DandSebastiaan Janssen 31dc7fa458 Fix #12770 (#12865)
* change "umbraco" to "Umbraco" in translation files.

* Replace "<i>" and "<b>" tag with "<em>" and "<strong>"

(cherry picked from commit fa8bb3f1da)
(cherry picked from commit de0294d163)
2022-09-19 16:15:43 +02:00
Sebastiaan Janssen 48bd4a5f27 Grammar (do -> does) and some extra text
(cherry picked from commit 9bd6500bc7)
2022-09-19 16:15:32 +02:00
Sebastiaan Janssen 87c06f5f98 Back to 10.2.0-ish 2022-09-19 16:14:16 +02:00
Jacob Overgaard 8de26c6098 Revert "Merge remote-tracking branch 'origin/v11/dev' into v11/dev"
This reverts commit 40df989c9f, reversing
changes made to 803c044b60.
2022-09-19 12:41:26 +02:00
Bjarke Berg 40df989c9f Merge remote-tracking branch 'origin/v11/dev' into v11/dev 2022-09-19 12:36:52 +02:00
Bjarke Berg 803c044b60 Updated dependencies and fixed new NRT issues 2022-09-19 12:36:45 +02:00
Kenn JacobsenandGitHub ef15da3f6e Bypass model validation for rendering models (#12999)
undefined
2022-09-19 11:03:16 +02:00
Bjarke Berg c1010e5239 Merge remote-tracking branch 'origin/v10/dev' into v11/dev 2022-09-19 10:51:18 +02:00
d18dc92137 V10: Fix to allow dragged images in the rich text editor to be correctly uploaded (#13016)
* update string extensions IsFullPath to support more filepaths with new built-in Path.IsPathFullyQualified

* resolve TODO to switch to Path.IsPathFullyQualified supported from .NET Standard 2.1

* Use content root instead of web root for uploaded images

* Un-break a breaking change

* handle special parsing of AngularJS json response

* change htmlId selector to support html id's with numbers

* remove bad test case

* test IsFullPath without tricky UNC paths that are not useful

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2022-09-19 10:29:12 +02:00
0b1295d05b Missing methods from IMemberService (#13022)
* Add back methods to interface

* Add default implementations to avoid breaking changes

Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-19 10:26:10 +02:00
Mike MaseyandMichael Latouche 6f9bf59e04 fix: focus state for search and help icons 2022-09-18 15:03:19 +02:00
SeanandGitHub 6967fadf3d pass in parameters needed to member service (#13020) 2022-09-17 12:00:06 +01:00
MoleandGitHub 6298fb338e Merge pull request #13014 from umbraco/v10/feature/september-dep-updates
v10: Update JS dependencies
2022-09-16 15:06:13 +02:00
Jacob Overgaard ad1c945bb1 update npm packages
@microsoft/signalr: 6.0.9
ace editor: 1.10.1
clipboard: 2.0.11
jquery: 3.6.1
jquery-ui: 1.13.2
moment.js: 2.29.4
nouislider: 15.6.1
underscore: 13.13.4
wicg-inert: 3.1.2

dev updates: karma, jasmine, less and postcss
2022-09-16 14:04:23 +02:00
Bjarne FyrstenborgandGitHub eddf0ad61e Only show table when any filtered result (#12993)
* Only show table when any filtered result

* Show table when any filtered dictionary items
2022-09-16 02:45:10 +02:00
patrickdemooij9andGitHub 6d27454ed2 Added nullable helper for IfNullOrWhiteSpace (#12979)
* Added nullable helper for IfNullOrWhiteSpace

* Remove for str as that one could be an empty string
2022-09-16 01:14:23 +02:00
Erik-Jan WestendorpandGitHub b84ccea96f Add label-key to prevent cleanup button (#12990)
* Add label-key

* Translate 'historyCleanupEnableCleanup' to Dutch

* Add 'historyCleanupEnableCleanup' to en_us.xml
2022-09-14 13:36:36 +02:00
Kenn JacobsenandGitHub e9883ea063 Add custom PrependBasePathFileProvider to handle media files with special characters (#12936) 2022-09-13 09:11:46 +02:00
MoleandGitHub a356cf4f40 Backoffice api: Refactor controllers (#12934)
* Refactor install controller

* Removed unused InstallationTypeTarget

* Add ApiVersion to controllers

* Refactor upgrade controller

* Add missing RequireRuntimeLevelAttribute
2022-09-13 08:04:45 +02:00
Nikolaj GeisleandGitHub 09e2b04f91 V10: Update examine dependency (#12982)
* Update Examine.Lucene to newest version

* Update other projects
2022-09-12 18:48:30 +02:00
Bjarke Berg 74c45ee60d Merge remote-tracking branch 'origin/v10/dev' into v11/dev
# Conflicts:
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs
#	src/Umbraco.Core/Models/Mapping/DictionaryMapDefinition.cs
#	src/Umbraco.Web.BackOffice/Install/InstallApiController.cs
#	version.json
2022-09-12 16:47:20 +02:00
Anders BjernerandGitHub 902f126e6b Added support for virtual backoffice icons (#12833) 2022-09-09 12:50:21 +02:00
CyberReiterandGitHub 4df012e8e9 Skip move logic if the parent is staying the same (#12937)
* v10/feature/skip-move-logic: add logic to skip move logic when parentId would be the same as before

* v10/feature/skip-move-logic: remove unnecessary checks

* remove check for mediaservice as there is already one in place

* remove unnecessary using

* added parent checks for dictionary items

* changing behaviour for contenttypes, datatypes and mediatypes to show errors on move
2022-09-09 03:06:50 +02:00
Matthew CareandMichael Latouche 1bd0a1f86d Set the first app to active if no active apps
Add support for a block list item which only contains settings
2022-09-09 02:13:30 +02:00
ChadandGitHub fdc1b02b4f Fix Nucache rebuilding more type caches than necessary (#12785) 2022-09-08 13:17:54 +02:00
nikolajlauridsen d5be2fb89c Merge branch 'release/10.2.0' into v10/dev
# Conflicts:
#	version.json
2022-09-08 10:34:53 +02:00
Sebastiaan Janssen 5f42cf0cf7 Revert "Replace uppercase chars to make behaviour consistent"
This reverts commit 68cf801689.
2022-09-08 09:47:00 +02:00
Bjarne FyrstenborgandSebastiaan Janssen 68ff7b234d Replace uppercase chars to make behaviour consistent
(cherry picked from commit 68cf801689)

# Conflicts:
#	src/Umbraco.Core/Extensions/RequestHandlerSettingsExtension.cs
2022-09-08 09:44:53 +02:00
nikolajlauridsen ae516b28db Ensure new projects use the correct apssettings key for AllowEditInvariantFromNonDefault 2022-09-08 08:46:01 +02:00
Mole 4683c4a073 Hotfix: Move allow edit invariant from non default setting to content settings (#12960)
* Use ContentSettings instead of SecuritySettings for AllowEditInvariantFromNonDefault

* Make it backwards compatible
2022-09-07 14:47:20 +02:00
Nikolaj 4acabfae79 Merge remote-tracking branch 'origin/release/10.2.0' into release/10.2.0 2022-09-07 14:45:15 +02:00
Nikolaj 5bb38b39c9 Undo breaking change 2022-09-07 14:44:47 +02:00
82934838cc Extend error message with possible solution (#12962)
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-07 14:43:26 +02:00
MoleandGitHub 3846c75cc6 Hotfix: Move allow edit invariant from non default setting to content settings (#12960)
* Use ContentSettings instead of SecuritySettings for AllowEditInvariantFromNonDefault

* Make it backwards compatible
2022-09-07 14:38:54 +02:00
Sebastiaan Janssen 2ad6633d47 Fix tree root font being larger than it used to be 2022-09-07 14:08:33 +02:00
Bjarke Berg da24ae9180 Fixed InstallAuthorizeAttribute and simplified other things 2022-09-07 11:37:58 +02:00
Nikolaj d038f860bd Bump version 2022-09-07 09:20:08 +02:00
Nikolaj a83bb2f767 Bump version to non-rc 2022-09-07 09:19:22 +02:00
Bjarke BergandNikolaj e09dc75e4f Limit what API does when not in used in Install level 2022-09-07 09:18:46 +02:00
Nikolaj d8fafcfeeb Merge remote-tracking branch 'origin/release/10.1.1' into v10/dev
# Conflicts:
#	version.json
2022-09-07 09:17:07 +02:00
Erik-Jan WestendorpandGitHub a0d673262c Translate content apps to spanish (#12950)
* Add apps area to Spanish language file

* Translate apps
2022-09-06 16:10:09 +02:00
9a2ead4381 Add PagedViewModel (#12955)
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-06 14:07:47 +02:00
Bjarke Berg 7b00c0d3e9 Limit what API does when not in used in Install level 2022-09-05 21:12:41 +02:00
Bjarke Berg 67dbc6af26 Bump Version 2022-09-05 21:05:59 +02:00
Mayur DandGitHub 1f5d58b1a9 Fix: Media Picker creates duplicated folders (#12918) (#12948)
* fix: Media Picker creates duplicated folders (#12918)

* Fix: Media section multiple content creation (#12918)
2022-09-05 02:17:46 +02:00
AlexandMichael Latouche df3777f976 Update add-issues-to-review-project.yml
Signed-off-by: sashashura <93376818+sashashura@users.noreply.github.com>
2022-09-05 01:45:07 +02:00
Erik-Jan WestendorpandMichael Latouche 7bb5fbf268 Translate languages area 2022-09-04 04:33:08 +02:00
Bjarne FyrstenborgandGitHub 8f4d8d60b0 Use SVG logo in installer/upgrader (#12922)
* Use SVG logo in upgrader

* Adjust logo in app header and boot failed as well

* Remove width and height from CSS

* Update sizes

* Set image size

* Disable draggable of logo
2022-09-02 15:28:39 +02:00
89d1d7cd9c Use staticserviceprovider to provide service (#12939)
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-09-02 14:20:02 +02:00
Sebastiaan JanssenandGitHub 17d72f9436 Update 01_bug_report.yml 2022-09-02 09:33:09 +02:00
MoleandGitHub 9cf7e965a9 Backoffice Api: Server Controller (#12932)
* Add initial implementation using 1 controller pr. action

* Add OpenApiTag attribute

Otherwise the endpoints won't be grouped correctly

* Use correct response type

* Move ApiVersion to endpoint controllers

* Add ServerController suffix to endpoint controllers
2022-09-01 14:01:49 +02:00
Jacob Overgaard dc709c20ce remove styling from installer (#12923)
This styling is now being imported from components/umb-range-slider.less and is no longer needed here

Previously fixed in 52672d2c2b

Ref https://github.com/umbraco/Umbraco-CMS/pull/12807/files/52672d2c2ba046f1da431388ec95b21b30965f08#r957799952
2022-08-31 13:32:40 +02:00
Jacob OvergaardandGitHub 87ced87ddd remove styling from installer (#12923)
This styling is now being imported from components/umb-range-slider.less and is no longer needed here

Previously fixed in 52672d2c2b

Ref https://github.com/umbraco/Umbraco-CMS/pull/12807/files/52672d2c2ba046f1da431388ec95b21b30965f08#r957799952
2022-08-31 13:30:40 +02:00
Nikolaj GeisleandGitHub 2cef243056 Add virtual SetUpTestConfiguration method (#12928) 2022-08-31 13:24:16 +02:00
Kenn JacobsenandGitHub 44122c6509 Performance improvement: Reusable data editors (#12921)
* Introduce opt-in option for reusable data editors

* Verified RTE as reusable

* Make attribute property naming more explicit + update comments

* Test file upload and image cropper

* Add unit tests
2022-08-31 11:03:34 +02:00
Erik-Jan WestendorpandMichael Latouche 5f4f16957f Translate 'settingsGroup' treeHeader to Spanish 2022-08-30 19:09:56 +02:00
neilnaveenandMichael Latouche fcd1c22bf8 chore: Set permissions for GitHub actions
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.

- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)

Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com>
2022-08-30 18:52:08 +02:00
Sebastiaan Janssen 5fc6fa58c0 Revert "Break word for limited width content"
This reverts commit 448836ee2d.

(cherry picked from commit 07fba1eb84)
2022-08-30 13:23:44 +02:00
Sebastiaan Janssen 07fba1eb84 Revert "Break word for limited width content"
This reverts commit 448836ee2d.
2022-08-30 13:23:15 +02:00
Mayur DandSebastiaan Janssen de0294d163 Fix #12770 (#12865)
* change "umbraco" to "Umbraco" in translation files.

* Replace "<i>" and "<b>" tag with "<em>" and "<strong>"

(cherry picked from commit fa8bb3f1da)
2022-08-29 13:26:20 +02:00
Sebastiaan Janssen 9bd6500bc7 Grammar (do -> does) and some extra text 2022-08-29 13:23:49 +02:00
MoleandGitHub 748fb7d1f7 Implement new backoffice installer (#12790)
* Add new BackOfficeApi project

* Add swagger

* Add and route new install controller

* Add new install steps

* Add Setup endpoint

* Add missing RequiresExecution methods

* Fix nullability of databasemodel

* Move user information to separate model

* Remove ping method

* Add view models install data

* Move mapping folder

* Move ViewModels

* Add settings endpoint

* Remove unused binderprovider

* Postfix RequiresExecution with async

* Update NewDatabaseUpgradeStep to not depend on install step

* Add installstep collection

* Move registration into backoffice project

* Add InstallService

* Use service in controller

* Add upgrade to install service and use in controller

* Correctly check is database is configured

* Reorganize

* Reorganize into new core and infrastructure

* Rename steps

* Rename BackofficeApi to MangementApi

* Make install step an interface instead of abstract class

* Rename InstallStep to create CreateUserStep

* Move restart runtime and sign in user into install steps

* Move install service into new core project

* Map controllers in composer

* Restrict access to installcontroller based on runtime level

* Use FireAndForget when logging install

* Use actionresult instead of iactionresult

* Set new projects as not packable

* Link to backoffice in 201 response when installed

* Register installations

* Add custom backoffice routing template token

* Move umbraco path trimming out of application convention

* Make it easier to route to backoffice api

* Make swagger version aware and move behind backoffice path

* Obsolete old install classes

* Move maps into single file

This is all mappint to/from viewmodels in some manner

* Remove usage of InstallSetupResult

* Move new projects to the src folder

* Remove InstallationType from IInstallStep

This upgrade steps should implement their own IUpgradeStep interface

* Remove upgrade from service and controller

This should be its own service and controller

* Add xml docs

* Remove internals visible to

* Disable package validation for new projects

Quite the gotcha here, if the projects are brand new, there is no nuget packages to compare with, this causes the build to fail.

* Add ValidateDatabase endpoint

* Remove project references to new backoffice

We don't actually want to depend on this yet, it's just needed for testing/development

* Obsolete installationtype

* Add DatabaseSettingsFactory tests

* Add InstallServiceTests

* Fix InstallServiceTests

* Test RequireRuntimeLevelAttribute

* Implement new backoffice upgrader (#12818)

* Add UpgradeSettingsModel and viewmodel

* Add upgrade/settings endpoint

* Implement upgrade steps

* Add upgrade step collection

* Add UpgradeService

* Add authorize endpoint to UpgradeController

* Fix interface

* Add upgrade service tests

* Remove runtime check in databaseinstallstep

* Move RequireRuntimeLevel to controller

* Add a readme to the new backoffice part

* BackOffice not Backoffice

* Add conditional project references

* Fixes based on review

* Fix up

* Move running of steps into its own method in UpgradeService

* Make services transient

* More fixup

* Log exceptions when running steps
2022-08-29 09:50:48 +02:00
Bjarke Berg aaa0b38701 Merge remote-tracking branch 'origin/release/10.2.0' into v10/dev 2022-08-29 08:26:58 +02:00
Bjarne FyrstenborgandMichael Latouche 68cf801689 Replace uppercase chars to make behaviour consistent 2022-08-27 02:23:26 +02:00
a105b3b770 v10: make block editors supports stateful label expressions (#12909)
* mark ncNodeName as stateful allowing it to update the node name asynchronously and implement several checks for caching and fallthroughs

* ensure that the blocklist block component watches and updates stuff on the blockObject

* add $interpolate to the blockList Property Editor to interpolate the label with the saved state

* replace static label with the blockHtmlCompile directive to ensure labels are updated dynamically

* add failsafe in case block is not instantiated

* replace manual udi separation with the parse function from the udiParser service

* simplify watching, to avoid overwritting data object.

* virtual block label rendering

* destroy label scope

* add extra information for label doc

* revert previously used functions and add deprecation notices to them

* remove getBlockLabel, as it's not being used or publicly available.

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
2022-08-26 15:09:34 +02:00
Ronald Barendse 6dab24265a Fix duplicate Directory.Build.props import 2022-08-26 09:19:55 +02:00
Ronald Barendse 143fbef3d7 Use .NET 7.x in CodeQL build 2022-08-26 09:18:17 +02:00
Anders BjernerandMichael Latouche 47f77b60a6 Added support for disabling tabs in <umbTabsNav /> elements 2022-08-26 03:26:23 +02:00
Erik-Jan WestendorpandGitHub b55f50c34a Translate TreeHeaders to Spanish (#12902)
* Translate 'logViewer' to Spanish

* Translate 'relationTypes' to Spanish
2022-08-26 02:30:34 +02:00
Kenn JacobsenandBjarke Berg 785c4440f3 Fix memory leaks (#12900)
* Fix leak for PublicAccessEntry

* Fix memory leak for PropertyTypeCollection

* Don't clone the lazy property group ID when caching property types, it is explicitly assigned at runtime

(cherry picked from commit 10b8f63052)
2022-08-25 15:31:36 +02:00
Kenn JacobsenandGitHub 10b8f63052 Fix memory leaks (#12900)
* Fix leak for PublicAccessEntry

* Fix memory leak for PropertyTypeCollection

* Don't clone the lazy property group ID when caching property types, it is explicitly assigned at runtime
2022-08-25 15:30:56 +02:00
Bjarke BergandGitHub 8f6e28e0ad Fixed issue with saving member groups, that was not persisted, if only the member groups was changed. (#12905) 2022-08-25 12:31:10 +02:00
Andreas ZerbstandGitHub 4478f27a83 Merge pull request #12889 from umbraco/v10/feature/new-media-tests
Added new media tests
2022-08-25 09:10:43 +02:00
Zeegaan a5237def31 Update umbraco-cypress-testhelpers version 2022-08-25 08:19:36 +02:00
Daniël KnippersandMichael Latouche 62423143bd Update appsettings-schema: remove {Member,User}Password from Umbraco:CMS
They are located in Umbraco:CMS:Security and are read from that location.
Setting any values in Umbraco:CMS does not actually work but
intellisense shows up so the user thinks it will work.
2022-08-25 01:19:43 +02:00
Mikael LindemannandGitHub 0f3feb1773 #12802 Fix partial view model type replacements (#12831) 2022-08-25 00:47:43 +02:00
bfbc2abca8 V10/bugfix/variant permissions segments (#12890)
* Remove null check from MapperContext.SetCulture and .SetSegment

We need to be able to set these to null, since null = invariant / default segment

* show segment label on property

* Add ContentVariation to ContentPropertyDisplay

* Add ContentVariation to DocumentTypeDisplay

* Change variations to be on ContentTypeBasic.cs

* don't cache value

* show correct label and unlock text for culture and segment variations

* make lock overlay take up less space

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-08-24 16:19:38 +02:00
439878883a V10/bugfix/variant permissions segments (#12890)
* Remove null check from MapperContext.SetCulture and .SetSegment

We need to be able to set these to null, since null = invariant / default segment

* show segment label on property

* Add ContentVariation to ContentPropertyDisplay

* Add ContentVariation to DocumentTypeDisplay

* Change variations to be on ContentTypeBasic.cs

* don't cache value

* show correct label and unlock text for culture and segment variations

* make lock overlay take up less space

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-08-24 16:18:40 +02:00
2431a21de1 V10/bugfix/variant permissions segments (#12890)
* Remove null check from MapperContext.SetCulture and .SetSegment

We need to be able to set these to null, since null = invariant / default segment

* show segment label on property

* Add ContentVariation to ContentPropertyDisplay

* Add ContentVariation to DocumentTypeDisplay

* Change variations to be on ContentTypeBasic.cs

* don't cache value

* show correct label and unlock text for culture and segment variations

* make lock overlay take up less space

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-08-24 16:17:56 +02:00
Zeegaan f8e3a77237 Update to version 71 2022-08-24 14:04:34 +02:00
Bjarke Berg 026ece2132 Merge remote-tracking branch 'origin/v10/dev' into release/10.2.0 2022-08-24 13:59:03 +02:00
Mads RasmussenandBjarke Berg b4f2de79b8 Bugfix: Variant permission languages needs a clear cache to work fully for current user (#12875)
* emit event when user group is saved

* clear current user cache when languages and user groups are saved

(cherry picked from commit 128dd42b47)
2022-08-24 13:53:28 +02:00
Mads RasmussenandGitHub 128dd42b47 Bugfix: Variant permission languages needs a clear cache to work fully for current user (#12875)
* emit event when user group is saved

* clear current user cache when languages and user groups are saved
2022-08-24 13:52:39 +02:00
Zeegaan bd40575c32 Added new media tests 2022-08-24 12:29:23 +02:00
Sebastiaan Janssen 38f144fa08 Merge branch 'v10/dev' into v10/contrib 2022-08-23 16:44:12 +02:00
Mole e7d6b9ef7a Add ClaimsPrincipalFactory and ensure that claims are flowed from the MemberIdentityUser (#12877) 2022-08-23 14:17:44 +02:00
Warren BuckleyandGitHub 523aa6c12e V10 Fixup GitHub CodeSpaces / VSCode Remote Container (#12882)
* Remove SQL Server part of the CodeSpace - we have SQLite to use

* Update to use .NET 6 and simplified docker stuff

https://github.com/microsoft/vscode-dev-containers/

* Need to set the SQLite Connection string env variable

* Path to SLN has changed to the root of the repo

* Fix up launch and VSCode tasks
2022-08-23 14:12:45 +02:00
MoleandGitHub f3a1c89066 Add ClaimsPrincipalFactory and ensure that claims are flowed from the MemberIdentityUser (#12877) 2022-08-23 14:12:05 +02:00
1b5225f4cd V11/feature/update to dotnet 7 (#12712)
* Update projects to .NET 7

* Fix nullability errors

* Fix up pipelines to run 7.0

* Update langversion to preview

* Revert "Fix up pipelines to run 7.0"

This reverts commit d0fa8d01b8.

* Fix up pipelines again, this time without indentation changes

* Include preview versions

* Versions not Version

* Fix ModelTypeTests

* Fix MemberPasswordHasherTests

Microsoft wants to use SHA512 instead of SHA256, so our old hashes will return SuccessRehashNeeded now

* Use dotnet cli instead of nuget restore

* Update src/Umbraco.Web.UI/Umbraco.Web.UI.csproj

* Update dependencies

* Fix nullability issues

* Fix unit test

* Fix nullability in ChangingPasswordModel

OldPassword can be null, if we're changing the password with password reset enabled. Additionally, we might as well use the new required keyword instead of supressing null.

* Use required keyword instead of supressing null

* Fix up pipelines again

* fix up spelling-error

* Use dotnet cli instead of nuget restore

* Fix up another NuGet command

* Use dotnet version 7 before building

* Include preview versions

* Remove condition

* Use dotnet 7 before running powershell script

* Update templates to .net 7

* Download version 7 before running linux container

* Move use dotnet 7 even earlier in E2E process

* Remove dotnet 7

* Reintroduce .NET 7 task

* Update linux docker container and remove dotnet 7 from yml

* Fix up dockerfile with ARG

* Fix up docker file with nightly builds of dotnet 7

* Reintroduce dotnet 7 so windows can use it

* Use aspnet 7 in docker

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2022-08-23 11:31:05 +02:00
b6e0e2df56 Content modal heading fix (#12797) (#12880)
* Fixes to modal and group headings

* updated modal headings for h1 and h2

* Updated line-height

Changed line-height: 0 to line-height: 1.3 and added margin: 0

Co-authored-by: Tiffany Prosser <tiffany.prosser1@gmail.com>
2022-08-23 11:06:29 +02:00
7e7658314c Content modal heading fix (#12797) (#12880)
* Fixes to modal and group headings

* updated modal headings for h1 and h2

* Updated line-height

Changed line-height: 0 to line-height: 1.3 and added margin: 0

Co-authored-by: Tiffany Prosser <tiffany.prosser1@gmail.com>
2022-08-23 10:51:45 +02:00
nikolajlauridsen ea2ecab238 Add RC to version 2022-08-23 09:52:42 +02:00
Mayur DandGitHub fa8bb3f1da Fix #12770 (#12865)
* change "umbraco" to "Umbraco" in translation files.

* Replace "<i>" and "<b>" tag with "<em>" and "<strong>"
2022-08-23 00:31:49 +02:00
Bjarke BergandGitHub d96c9a77cf Better exception message when using ALTER TABLE and SQLite (#12848)
* Added NotSupportedException when using Alter Table and SQLite. This is considered better than the underlying sql error.

* use Environment.NewLine
2022-08-22 15:48:17 +02:00
MoleandGitHub f8e20a9db9 V10: Fix foreign key constraints when using external login provider for members (#12872)
* Move role saving out of UpdateMemberProperties

* Add missing delete clauses

* Fix token for users too

* Fix deleting user
2022-08-22 15:18:12 +02:00
Bjarke BergandGitHub d63e7277cb Merge pull request #12871 from umbraco/v10/bugfix/fix-assertion-in-tabs-acceptance-tests
Fix assertion in tabs acceptance tests
2022-08-22 10:16:59 +02:00
Zeegaan 73a56d2fe5 Fix up assertions 2022-08-22 09:45:55 +02:00
Kenn JacobsenandGitHub 264a1565ca Make the error message friendlier when attempting to use unsupported sorting in listviews (#12846)
* Make the error message friendlier when attempting to use unsupported sorting in listviews

* Revert automatic code formatting

* Review changes
2022-08-22 09:29:24 +02:00
Bjarke Berg 610059919c Merge remote-tracking branch 'origin/v10/dev' into v10/dev 2022-08-22 08:14:20 +02:00
Bjarke Berg 72d3e6f17e Fix version of nightly builds 2022-08-22 08:14:11 +02:00
Ronald BarendseandGitHub 1ac68f8e4c Merge pull request #12863 from umbraco/feature/codeqlv2
Upgrade CodeQL from v1 to v2
2022-08-19 15:16:04 +02:00
Bjarne FyrstenborgandGitHub 753cf35d6b Use umb-icon component in tracked references to support custom SVG icons (#12766) 2022-08-19 15:07:55 +02:00
Bjarne FyrstenborgandGitHub 1024b26cec Fix umb-range-slider merging overlapping tooltips (#12777)
* Formatting CSS using Less syntax

* Fix merging overlapping tooltips from noUiSlider v15.5.0+
2022-08-19 15:03:56 +02:00
Jacob Overgaard 173c231859 upgrade setup-dotnet to v2 2022-08-19 14:36:19 +02:00
Jacob Overgaard c7813aa354 upgrade codeql tasks to v2 2022-08-19 14:35:43 +02:00
Jacob Overgaard c4c27ec72b add GITHUB_TOKEN restrictive permissions 2022-08-19 14:35:21 +02:00
Jacob OvergaardandGitHub 65c828390c CodeQL should not scan compiled assets (#12861)
* add the Umbraco.Cms.StaticAssets folder to ignored paths for the codeql scanner

* exclude only the 'wwwroot' folder since other assets could be valid to scan
2022-08-19 11:10:45 +02:00
patrickdemooij9andGitHub 56e282946f Added copy functionality for data types (#11867)
* Added copy functionality for data types

* Fix errors

* Add logic to default interface

* PR Feedback

* PR feedback

* Fix error
2022-08-19 10:19:36 +02:00
Tiffany ProsserandGitHub f33b724c8e Content modal heading fix (#12797)
* Fixes to modal and group headings

* updated modal headings for h1 and h2

* Updated line-height

Changed line-height: 0 to line-height: 1.3 and added margin: 0
2022-08-19 01:56:56 +02:00
Bjarke Berg 100ebf5c7f Update version and disable package validation for now 2022-08-18 14:53:52 +02:00
Bjarke Berg 4f4bdba214 Revert "Revert breaking changes"
This reverts commit ac4fb6acf1.
2022-08-18 14:40:11 +02:00
Bjarke Berg e9f9b8aee1 merge v10 to v11 2022-08-18 14:38:49 +02:00
Bjarke Berg ac4fb6acf1 Revert breaking changes 2022-08-18 12:41:06 +02:00
Sebastiaan Janssen 26d83381f2 Merge branch 'v10/contrib' into v10/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/installer/steps/user.html
#	src/Umbraco.Web.UI.Client/src/less/installer.less
2022-08-18 11:23:08 +02:00
Sebastiaan Janssen ee3ad8bdfb Revert "Issue 12709: fixed issue with reloading of dashboard tabs. (#12730)"
This reverts commit 21e5de462d.
2022-08-18 10:23:09 +02:00
Tobias MønsterandGitHub c8522b9b81 Makes active pip text darker to contrast with non-active pips (#12807)
* Makes active pip text darker to contrast with non-active pips

* Adds active class to slider component and updates functionality to accommodate multiple pips

* Update umbrangeslider.directive.js

* Adds click handler,accommodates decimal values and moves styles to single file
2022-08-18 09:06:04 +02:00
Bjarke BergandGitHub e956efa7f9 Merge pull request #12856 from umbraco/v10/bugfix/external_login_token_table
V10: Fix external login token table
2022-08-17 16:53:17 +02:00
Nikolaj 838f4199c8 Only recreate token if it has changed. 2022-08-17 14:36:09 +02:00
MoleandGitHub 5c09af11dc Clean solution file (#12830)
* Remove docs folder

* Re-add docfx files

I think it makes sense to have these in the solution, however it's a build concern really, not a documentation in the sense that you'll learn anything from it.

* Remove build.ps1 scripts - it's not a thing in v10

* Add version.json to the solution file
2022-08-17 13:08:07 +02:00
Nikolaj e2f5c93528 Ensure that LoginTokens gets marked as dirty
Might want to experiment with only removing/updating if the value is different
2022-08-16 15:47:01 +02:00
Kenn JacobsenandGitHub 61f8007c6b Only expose server vars for password policy rules and max file size for authenticated users (#12839)
* Only expose server vars for password policy rules and max file size for authenticated users

* Fix min password length for reset password flow
2022-08-16 10:10:51 +02:00
Kenn JacobsenandGitHub de73ba7256 Fix JS error when clicking a reset password link twice (#12845) 2022-08-16 09:29:52 +02:00
Warren BuckleyandGitHub 2f5759dba2 Display package version in Installed Packages (#12784)
* Adds the package version from Package Manifest - (JSON or ManifestFilter C#)

Used to see what version of a package installed & make package devs aware that they can set this, as we use this in the package telemetry service

* Prefix with word Version for cases where 'Unknown' is displayed
2022-08-15 11:29:41 +02:00
Andy ButlandandGitHub 98c9124735 Refactored logic for calculating the first run time for a recurring hosted service. (#12828)
* Refactors the logic for calculating the first run time for a recurring task for easier re-use by similar hostservices.

* Renamed method to match wider usage.
2022-08-12 10:14:15 +01:00
Johannes LantzandGitHub f43912722b Added dictionary filter by name (#12765)
* Added dictionary filter by name

* Added en translation for no filter dictionaries

* Removed inital table sort of dicionary items
2022-08-12 01:12:13 +02:00
c7501bd47b Fix broken rollback feature (#12808)
Co-authored-by: kjac <kja@umbraco.dk>
2022-08-10 08:45:05 +02:00
Bjarke BergandGitHub 00ffe7a6b3 Only expose the filename when uploading content types (#12813) 2022-08-09 16:27:46 +02:00
Lucas Bach BisgaardandMichael Latouche 1b3ccf8521 Add attr directive that lock the focus inside the modal 2022-08-07 23:29:08 +02:00
Bjarke Berg 274e7c5302 Use user key as alias instead of username 2022-08-05 10:48:45 +02:00
Warren BuckleyandGitHub faf4320eb5 Add new UmbracoBuiilder extension methods to discover and set an IUmbracoTreeSearcherFields (#12751) 2022-08-04 11:21:36 +02:00
Bjarke BergandGitHub 99dfeddf97 Replaced usage of new Random().Next(..) with RandomNumberGenerator.GetInt32 (#12759) 2022-08-04 10:26:51 +02:00
Mads RasmussenandGitHub 8802b58849 Merge pull request #12605 from umbraco/v10/feature/variant-permissions
Feature: Variant Permissions (Readonly access)
2022-08-03 14:15:49 +02:00
Nikolaj e1affc5e6c Fix version 2022-08-03 13:48:20 +02:00
Nikolaj 1697f0b680 Merge branch 'release/10.1.0' into v10/dev
# Conflicts:
#	version.json
2022-08-03 13:45:48 +02:00
Bjarke Berg c52e8c5e81 Changed so new projects by default has AllowEditInvariantFromNonDefault as true 2022-08-03 12:54:37 +02:00
Mads Rasmussen 6061fda8b4 disable "Remove All" property action for users with readonly access 2022-08-03 12:23:06 +02:00
Mads Rasmussen 31279b96cf Merge branch 'v10/dev' into v10/feature/variant-permissions 2022-08-03 11:22:35 +02:00
MoleandGitHub 3972538fd5 Fix docfx generation (#12775)
* Fix some XML docs

* Re add unused using in SqlSyntaxProviderBase to magically fix docfx

I have no idea why this works, but it does

* Fix nullref exception
2022-08-03 11:00:30 +02:00
Nikolaj 0c8e22d29d Revert "edit pipelines for release"
This reverts commit 920e952e6a.
2022-08-03 10:45:11 +02:00
Nikolaj 866ed01b58 Bump version 2022-08-03 10:14:12 +02:00
Ambert van UnenandMichael Latouche 961e0a4f7b Added translation 2022-08-03 00:19:45 +02:00
Ronald Barendse 8077f45f0f Keep CopyRazorGenerateFilesToPublishDirectory and update comments 2022-08-02 17:19:09 +02:00
Ronald Barendse c5654f0311 Keep CopyRazorGenerateFilesToPublishDirectory and update comments 2022-08-02 16:50:52 +02:00
Ronald BarendseandGitHub eae7d7919c Merge pull request #12769 from umbraco/v10/feature/packagevalidation
Enable package validation
2022-08-02 14:10:45 +02:00
Bjarke Berg 47c1f7b22b Added CompatibilitySuppressions.xml to Examine.Lucene project 2022-08-02 13:39:21 +02:00
Bjarke Berg 4f4c06a242 Merge remote-tracking branch 'origin/v10/dev' into v10/feature/packagevalidation 2022-08-02 13:11:57 +02:00
Bjarke Berg c1dc95ef92 Merge remote-tracking branch 'origin/release/10.1.0' into v10/dev 2022-08-02 13:10:56 +02:00
Bjarke Berg 6ce91eff4e Unbreak breaking changes 2022-08-02 13:10:20 +02:00
Bjarke Berg e5cbd15a7e Do not allow update translations on languages you do not have access to. 2022-08-02 12:50:18 +02:00
Bjarke BergandSebastiaan Janssen 636ee831a4 Force the allowed avatar image types. We do not want to use the Umbraco:Cms:Content:Imaging:ImageFileTypes as this could very well be different for content.
(cherry picked from commit 6ce9ea4950)
2022-08-02 12:41:27 +02:00
Jacob OvergaardandGitHub 75a4044f12 V10: Show more telemetry info on the installer (#12739)
* remove absolute-center class from installer and replace with css grid

* replace tooltips for telemetry with columns and a direct view of what eact telemetry level means

* ensure that inputs will out entire columns and that buttons are aligned as the rest of the system with the CTA on the right side

* update buttons on the database screen to match the user screen

* set min-width on installer for views with only text content

* add border to preconfigured database field

* remove extra headline from telemetry data info text

* change telemetry info text to 'small'

* remove opacity for database settings

* update wording of intro text to the installer

* add unordered list to the detailed telemetry description

* add helper text to indicate that telemetry can be changed later

* change wording from 'analytics' to 'telemetry data'

* add smooth-steps-tap to noUiSlider for telemetry data

* add short text explaining what telemetry is to the installer
2022-08-02 12:32:57 +02:00
Ronald Barendse 30210f5de5 Enable package validation 2022-08-02 12:02:46 +02:00
Mads Rasmussen 30c37ea0f4 Set a dictionary item translation to read-only if the user doesn't have permission to update the language 2022-08-02 11:17:18 +02:00
Bjarke BergandSebastiaan Janssen 6ce9ea4950 Force the allowed avatar image types. We do not want to use the Umbraco:Cms:Content:Imaging:ImageFileTypes as this could very well be different for content. 2022-08-02 11:16:42 +02:00
Bjarke Berg c73cb30c58 Added allowedLanguagesIds to UserDetail 2022-08-01 14:57:25 +02:00
Nikolaj GeisleandGitHub 19b2dee76a change "All sections" to "No sections" (#12708) 2022-07-27 09:31:38 +02:00
Mykyta ZakharovandGitHub 21e5de462d Issue 12709: fixed issue with reloading of dashboard tabs. (#12730)
* Issue 12709: fixed issue with reloading of dashboard tabs.

* Issue-12709: fixed issue with coreBuild.
2022-07-27 00:49:51 +02:00
Jacob OvergaardandSebastiaan Janssen abee27a99f fix: ensure the input field to edit tabs is only shown when active
This fix prevents Firefox (and possibly others) from preventing the click event, which now bubbles up as it should.
2022-07-26 14:35:44 +02:00
Matthew CareandGitHub 9ae0d0507a Adjust label styles to allow wrapping (#12610)
* Prevent asterix having its own line

With certain label lengths the * would end up on its own line
Adjusting width of group builder labels / descriptions to be in line with the width of the content labels
Adjusting the margins / padding which looked out of place

* Single line html

Change html to be on one line due to white-space css properties requiring such

* Label on top

Fix the width of labels when the label is on top

* Add spacing

Add spacing to control groups to account for the removed padding from labels

* Labels on tablet

Fix label width on tablet screen size
2022-07-26 14:01:21 +02:00
Sebastiaan Janssen b9393c655f Merge branch 'v10/dev' into v10/contrib 2022-07-26 10:26:02 +02:00
MigaroezandNathan Woulfe 63ad03f78e #12576 Responsive CSS fixes for packages on very small screens 2022-07-26 17:45:45 +10:00
Sebastiaan JanssenandNikolaj Geisle 3baae5ab53 Check if content has an identity before attempting to get it's ancestors (#12733)
* Check if content has an identity before attempting to get it's ancestors

* Check if we even need to go to the parent

* Fail earlier

* Update src/Umbraco.Web.BackOffice/Controllers/ContentController.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2022-07-26 09:24:21 +02:00
e17a190925 Check if content has an identity before attempting to get it's ancestors (#12733)
* Check if content has an identity before attempting to get it's ancestors

* Check if we even need to go to the parent

* Fail earlier

* Update src/Umbraco.Web.BackOffice/Controllers/ContentController.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2022-07-25 18:02:40 +02:00
Nikolaj GeisleandGitHub aabb6c2665 Merge pull request #12731 from umbraco/v10/bugfix/restore-quickinstall
v10: restore one-click install
2022-07-25 12:31:49 +02:00
f0ba9c469e Fix previous conversion of SearchAll to async ignoring the SortOrder value from SearchableTree (#12595)
* Fix previous conversion of SearchAll to async ignoring the SortOrder value from SearchableTree

* small refactoring

Co-authored-by: Paul Woodland <paul.woodland@pwnewmedia.com>
Co-authored-by: Michael <michael@crossingpaths.be>
2022-07-25 12:07:56 +02:00
Jacob Overgaard 197ec2ab1b fix: restore quickinstall view in the installer with options to customize the database or skip entirely 2022-07-25 11:33:52 +02:00
b3237c498b Fix StripHtmlTagsMethod by adding Regex (#12607)
* #umbraco12400 fixing StripHtmlTagsMethod by adding Regex

* changing logic by removing .FirstChild calls

* fixing line endings

* final fix

* removing unused using

Co-authored-by: Michael Reiter <michale.reiter@cyber-solutions.at>
Co-authored-by: Michael Reiter <michael.reiter@metro-external.digital>
2022-07-24 00:53:04 +02:00
MigaroezandMichael Latouche b531fccd36 #12617 Add contentForm Dirty reset on successful save for members and media 2022-07-22 01:12:11 +02:00
4b557464c6 Fixed Group Headings in Content (#12702)
* Added secure to the UMB-XSRF-V cookie when global https is true.

* Issue 12551 search bug

Previous optimisation incorrectly filtered the index fields needed to return published results

* Update MemberRepository.cs (#12641)

Ensuring that MemberManager.ConfirmEmailAsync persists, same changes in pull request #12640 but for v9

* Fixed Group Headings in Content

Co-authored-by: Corey Philipp <CPhilipp@dewpoint.com>
Co-authored-by: Matthew Care <matty_care@hotmail.co.uk>
Co-authored-by: gilbertaoe <gilbertaoe@hotmail.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
2022-07-21 03:07:09 +02:00
cecf24aa87 Fixed Missing H1 tag (#12695)
* Added secure to the UMB-XSRF-V cookie when global https is true.

* Issue 12551 search bug

Previous optimisation incorrectly filtered the index fields needed to return published results

* Update MemberRepository.cs (#12641)

Ensuring that MemberManager.ConfirmEmailAsync persists, same changes in pull request #12640 but for v9

* Initial Commit

Amended tree root to be h1 (previously was h5) and amended contextual modal header to be h2 (previously was h1)

Co-authored-by: Corey Philipp <CPhilipp@dewpoint.com>
Co-authored-by: Matthew Care <matty_care@hotmail.co.uk>
Co-authored-by: gilbertaoe <gilbertaoe@hotmail.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
2022-07-21 01:46:55 +02:00
Nikolaj Geisle 9fa3b4e2ef Merge branch 'release/10.1.0' into v10/dev
# Conflicts:
#	version.json
2022-07-20 11:10:25 +02:00
Nikolaj Geisle 338bc2c19c Bumb version 2022-07-20 09:36:26 +02:00
Matt BrailsfordandNikolaj Geisle 08a7a26743 Allow dashboards to also be the "last accessed item" (#12689)
* Allow dashboards to also be the "last accessed item"

* Use tripple =
2022-07-20 09:20:41 +02:00
Ronald BarendseandNikolaj Geisle 2d217d505d Fix integration tests 2022-07-20 08:33:24 +02:00
Ronald BarendseandNikolaj Geisle d2806501d9 Fix integration test ACE Editor mock 2022-07-20 08:33:24 +02:00
Ronald BarendseandNikolaj Geisle fabb49feaf Remove template from warning message 2022-07-20 08:33:24 +02:00
Ronald BarendseandNikolaj Geisle 234552bcab Disable editing partial views and macro files 2022-07-20 08:33:23 +02:00
Ronald BarendseandNikolaj Geisle 40eae24a55 Show editor in read-only mode when using runtime mode production 2022-07-20 08:33:17 +02:00
Ronald BarendseandNikolaj Geisle 930b21f273 Fix editing template and show warning message when using runtime mode production 2022-07-20 08:33:16 +02:00
Ronald BarendseandNikolaj Geisle 9e1e9641a9 Skip saving template file when using runtime mode Production 2022-07-20 08:33:16 +02:00
Ronald BarendseandNikolaj Geisle df5d657380 Swap registration and resolving of IRuntimeModeValidator items to collection builder 2022-07-20 08:33:15 +02:00
Ronald BarendseandNikolaj Geisle e1c80ecd20 Add RuntimeModeValidators() extension method 2022-07-20 08:33:15 +02:00
Ronald BarendseandNikolaj Geisle f11d717522 Add RuntimeModeValidatorCollection and builder 2022-07-20 08:33:14 +02:00
Nikolaj Geisle c4aa718763 Revert "Update templates to .net 7"
This reverts commit 580f8acb5b.
2022-07-19 14:23:19 +02:00
Nikolaj Geisle 580f8acb5b Update templates to .net 7 2022-07-19 14:15:16 +02:00
29e8fd786d Tweaks the composition dialog in the content type editor (#12698)
* Tweaks the composition dialog in the content type editor

- removes the search field if no content types is available
- change the styling on the info text regarding missing content types
- moves the search field closer to the content type list

* fixes filter - needed vm binding, probably due to introducing ng-if and related scope trickery
tweaked css on checkbox list icon to improve alignment

Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
2022-07-19 11:35:52 +10:00
c2c87a0d72 Don't allocate new object array instances when indexing (#12710)
* Don't allocate new object array instances when indexing

There's no reason to allocate new object[] array instances for each ValueSet created for the "y" or "n" values going into the index. This just creates a single object[] for each "y" or "n" value which will save on a ton of allocations when re indexing a bunch of content.

There's an easy way to make further allocation reductions too (prob a separate PR) since there is no reason to create new object[] allocations for: CreatorId, WriterId, Level, TemplateId, Culture. Each of these can be returned from a concurrent dictionary since these values are finite and there won't be too many of each so we can just keep an internal dictionary of these object[] instances.

* fixes mistake

* Updates NoValue and YesValue field declarations - was blowing up

Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
2022-07-19 10:58:21 +10:00
Sebastiaan JanssenandGitHub 41eb412403 Create issues-first-response.yml 2022-07-18 09:48:13 +02:00
vsilvarandGitHub b27c03f001 Fixed ContentLastChanceFinder not being called for nodes without template (#12002)
This commit also ensure that the domain and culture is set before the ContentLastChanceFinder executes
2022-07-18 08:47:45 +10:00
patrickdemooij9andGitHub 8b97b04d1f Fetch all dictionary items if parentId is null (#12414)
* Fetch all if parentId is null

* PR feedback resolved

* Remove space that sneaked into the commit

* merge with PR changes
2022-07-17 23:52:18 +02:00
Ambert van UnenandMichael Latouche 50a268c70d Update textstring.cshtml 2022-07-17 01:54:18 +02:00
Chriztian SteinmeierandNathan Woulfe 8444bbce4f Update description for maxPropertyWidth
- Consistent casing for first word of descriptions
- css => CSS
- Use "override" instead of "overwrite"
2022-07-16 09:21:56 +10:00
Søren KottalandGitHub f426af1a50 Removes bottom margin from template select box in content node info (#12699) 2022-07-16 09:20:02 +10:00
Nikolaj GeisleandGitHub 78af85941f Merge pull request #12697 from umbraco/v10/feature/runtimemode-production-templates
Disable editing templates when using runtime mode Production
2022-07-15 15:06:25 +02:00
Ronald Barendse f4085efc17 Fix integration tests 2022-07-15 14:17:45 +02:00
Sebastiaan JanssenandGitHub 3e00845429 Create opened-issue-first-comment.yml 2022-07-15 12:49:49 +02:00
Ronald Barendse ae6ee5c3ad Fix integration test ACE Editor mock 2022-07-15 11:07:24 +02:00
Ronald Barendse ddfc2fa902 Remove template from warning message 2022-07-15 10:45:29 +02:00
Ronald Barendse e581fdc90a Disable editing partial views and macro files 2022-07-15 10:34:11 +02:00
Nikolaj GeisleandGitHub f0412bc38f Merge pull request #12693 from umbraco/v10/feature/runtimemodevalidatorcollection
Add RuntimeModeValidator collection builder
2022-07-15 09:40:12 +02:00
Ronald Barendse 97010c2de5 Show editor in read-only mode when using runtime mode production 2022-07-14 23:41:17 +02:00
Ronald Barendse 802f2baaa0 Fix editing template and show warning message when using runtime mode production 2022-07-14 22:48:43 +02:00
Ronald Barendse db90b16cb1 Skip saving template file when using runtime mode Production 2022-07-14 22:41:20 +02:00
Ronald Barendse 1fc64cd4ce Swap registration and resolving of IRuntimeModeValidator items to collection builder 2022-07-14 16:49:49 +02:00
Ronald Barendse 9cec603d46 Add RuntimeModeValidators() extension method 2022-07-14 16:48:52 +02:00
Ronald Barendse 93225a2c34 Add RuntimeModeValidatorCollection and builder 2022-07-14 16:48:01 +02:00
Nikolaj Geisle e92ceae7ee Bumb version 2022-07-14 11:31:24 +02:00
Nikolaj GeisleandGitHub 871bb94a41 Merge pull request #12690 from umbraco/v10/hotfix/remove-docs-dependency-from-nuget-step
edit pipelines for release
2022-07-14 10:16:05 +02:00
Nikolaj Geisle 920e952e6a edit pipelines for release 2022-07-14 10:13:55 +02:00
Bjarne FyrstenborgandGitHub dcb54c1f6e Inherit from OEmbedProviderBase in OEmbed providers (#12379)
* Use OEmbedProviderBase

* Use QueryHelpers.AddQueryString in .NET Core

* Nullable value

* Cleanup usings

* Ensure invariant string

* No need to URL encode when using QueryHelpers.AddQueryString()

* Include WebUtilities

* Cleanup usings

* Revert "Include WebUtilities"

This reverts commit 3cffb740ce.

* Revert "No need to URL encode when using QueryHelpers.AddQueryString()"

This reverts commit 70ca5306ac.

* Revert "Ensure invariant string"

This reverts commit 318ab23f6f.

* Revert "Nullable value"

This reverts commit c39911de06.

* Revert to StringBuilder

* Cleanup usings

* Add more descriptions of providers
2022-07-14 02:18:19 +02:00
sofietoftandGitHub f2ba4b1d4c Removed mention of Umbraco.tv from the Members Dashboard (#12429)
* Removed mention of Umbraco.tv from the Members Dashboard

* Add new key to en.xml

* Update membersdashboardvideos.html

* Update label used in members dashboard.
2022-07-14 00:21:10 +02:00
Matt BrailsfordandGitHub 7d4a9caf6a Allow dashboards to also be the "last accessed item" (#12689)
* Allow dashboards to also be the "last accessed item"

* Use tripple =
2022-07-13 23:08:44 +02:00
Nikolaj Geisle 38c42c2479 Update media picker to support readonly 2022-07-11 14:02:20 +02:00
Nikolaj Geisle 5bbb546780 Fix up UserGroup to map new property properly 2022-07-11 13:38:30 +02:00
Nikolaj Geisle bba403cf3e add hasAccessToAllLanguagus to AppendByGroup method 2022-07-11 10:44:25 +02:00
Nikolaj Geisle 0967505178 Fix up GetActions mapping 2022-07-11 10:37:25 +02:00
Nikolaj Geisle a7f04924a0 Fix up frontend to send hasAccessToAllLanguages 2022-07-11 09:37:00 +02:00
Nikolaj Geisle fccae2604f Fix unit test 2022-07-11 09:26:28 +02:00
Nikolaj Geisle 5ff31cf966 Add hasAccessToAllLanguages to user groups and map 2022-07-11 09:15:26 +02:00
Mads Rasmussen d3dc2bae69 remove forgotten parenthesis 2022-07-08 09:07:14 +02:00
Mads Rasmussen 87d552bebb Set form to dirty when updating user group permissions 2022-07-07 11:00:16 +02:00
Mads Rasmussen 4a1bccc58c always set readonly attr if a property can not be updated 2022-07-07 10:22:15 +02:00
Mads RasmussenandGitHub a63840a34e Merge pull request #12664 from umbraco/v10/feature/variant-permissions-unlock-dialog
show unlock dialog on all variants as long as there is more than one …
2022-07-07 10:12:36 +02:00
Mads Rasmussen 11a670bbe4 add toggle to allow access to all languages 2022-07-07 09:36:34 +02:00
Niels Lyngsø 6fcb02c602 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions-unlock-dialog
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less

plus some extra
2022-07-06 16:16:36 +02:00
Niels Lyngsø 51c537c2c2 show property actions 2022-07-06 15:44:27 +02:00
Zeegaan 7d6d826a4a Catch exception of UserGroup2Language database call 2022-07-06 15:24:41 +02:00
Zeegaan b2f87f66fd Fix up User repository 2022-07-06 15:08:37 +02:00
Niels Lyngsø 0daffd737e unlock overlay styling 2022-07-06 15:05:45 +02:00
Niels Lyngsø 957042d117 show unlock dialog on all variants as long as there is more than one created variant 2022-07-06 15:05:31 +02:00
Zeegaan 7e5fc48a67 Add new hasAccessToAllLanguages migration 2022-07-06 14:26:10 +02:00
Zeegaan 49dd2b44e3 Add hasAccessToAllLanguages column to usergroup table 2022-07-06 14:11:19 +02:00
Zeegaan 91974a69f5 Update IReadOnlyUserGroup.cs 2022-07-06 13:49:42 +02:00
Zeegaan ce6307c79a Fix up DatabaseDataCreator.cs to not give sensitive data group permission to all languages 2022-07-06 13:46:54 +02:00
Zeegaan 9e849b1635 Add HasAccessToAllLanguages property to User Groups 2022-07-06 13:45:05 +02:00
Zeegaan 93654de9c2 Update GetLanguagePermissions to pull out proper backofficeUser if possible 2022-07-06 13:33:12 +02:00
Zeegaan 35845b25e5 Obsolete ctor 2022-07-06 13:17:19 +02:00
Zeegaan 696182bf6e Update GetLanguagePermissions method 2022-07-06 13:02:33 +02:00
Zeegaan aa870a2302 Remove duplicate Contains() check 2022-07-06 12:58:00 +02:00
Zeegaan ed44c76fa0 Obsolete trycreate method 2022-07-06 12:56:29 +02:00
Zeegaan ffcda46654 insert using new namespace 2022-07-06 12:54:41 +02:00
f56ebbd7a1 Apply suggestions from code review
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2022-07-06 12:54:08 +02:00
Zeegaan 5770e48cc4 Make hardcoded string into const 2022-07-06 12:52:27 +02:00
Zeegaan 50e06ca596 Rename CultureImpactService.cs to CultureImpactFactory.cs 2022-07-06 12:50:52 +02:00
Zeegaan 99486339d9 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-07-06 12:48:52 +02:00
Zeegaan 49cc2bce79 Move extension method to actual interface with default implementation 2022-07-06 12:47:58 +02:00
Mads Rasmussen c1abcaabc1 add preview layer to prevent interaction with high z-index elements 2022-07-06 12:28:10 +02:00
Zeegaan c94ee7c1ec Fix up wierd formatting 2022-07-05 12:40:33 +02:00
Zeegaan ac6666e627 Fix breaking changes 2022-07-05 11:27:49 +02:00
Zeegaan fa1be5c55d Fix wrong resolve of merge-conflict 2022-07-05 08:48:07 +02:00
Zeegaan a3bcc99ed0 Fix up so manifestParser can deserialize new property "supportsReadOnly" 2022-07-05 08:41:55 +02:00
Zeegaan a572044f9e Map allowedactions 2022-07-04 15:07:59 +02:00
Zeegaan 1993424264 Merge branch 'v10/dev' into v10/feature/variant-permissions 2022-07-04 14:43:09 +02:00
Zeegaan f3591d2e7a Create acceptance tests for variant permissions 2022-06-24 13:23:56 +02:00
Zeegaan 551eeda625 Add cascading to UserGroup2LanguageDto.cs 2022-06-23 15:43:27 +02:00
Zeegaan ac5f2270ac Set SupportsReadOnly in all our PropertyEditors 2022-06-22 15:45:13 +02:00
Zeegaan fbfe93b2e0 Fix bug related to invariant content 2022-06-22 15:21:12 +02:00
Zeegaan dfbd23fd03 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-06-22 15:08:51 +02:00
Zeegaan d4f1d3f680 Add SupportReadOnlyMode to editor 2022-06-22 15:08:44 +02:00
Mads Rasmussen 16ae85f2db only render property editor readonly mode if the property editor supports it 2022-06-22 14:53:42 +02:00
Zeegaan 8fe2f7e036 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-06-22 11:32:10 +02:00
Zeegaan c552008870 Add supportsReadOnlyMode to ContentPropertyDisplay.cs 2022-06-22 11:31:58 +02:00
Mads Rasmussen 1b19704d37 copy allowed actions in block list editor 2022-06-22 11:19:30 +02:00
Mads Rasmussen 37a4662e3c use readonly border in media picker 2022-06-22 11:19:02 +02:00
Mads Rasmussen 92fcc425e8 make readonly border lighter 2022-06-22 11:18:40 +02:00
Nikolaj Geisle 7789f86b72 Add SupportsReadOnlyMode to package manifest 2022-06-21 12:30:41 +02:00
Nikolaj Geisle 7770f65faa Move tests 2022-06-21 11:06:18 +02:00
Nikolaj Geisle 9d912ea98a Add integration tests 2022-06-21 11:04:57 +02:00
Nikolaj Geisle c283cc498f Start work on integration tests 2022-06-21 08:45:33 +02:00
Nikolaj Geisle 8ab5aa1a41 Fix formatting 2022-06-21 08:45:24 +02:00
Nikolaj Geisle 4cd7aae611 Fix up after merge 2022-06-21 08:20:25 +02:00
Nikolaj Geisle 5b1e344092 Merge branch 'v10/dev' into v10/feature/variant-permissions
# Conflicts:
#	tests/Umbraco.Tests.UnitTests/Umbraco.Core/Models/CultureImpactTests.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs
2022-06-21 08:18:39 +02:00
Zeegaan 6c893a1bd1 Implement extension method for IReadOnlyUserGroup that checks access to a language 2022-06-20 14:52:04 +02:00
Zeegaan bc2eb5a784 Fix up after merge 2022-06-20 14:12:33 +02:00
Zeegaan 0288e3d6a9 Merge remote-tracking branch 'origin/v10/dev' into v10/feature/variant-permissions
# Conflicts:
#	src/Umbraco.Core/Configuration/Models/SecuritySettings.cs
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
#	src/Umbraco.Core/Models/ContentEditing/ContentVariationDisplay.cs
#	src/Umbraco.Core/Models/ContentEditing/UserGroupBasic.cs
#	src/Umbraco.Core/Models/ContentEditing/UserGroupSave.cs
#	src/Umbraco.Core/Models/ContentRepositoryExtensions.cs
#	src/Umbraco.Core/Models/CultureImpact.cs
#	src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs
#	src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs
#	src/Umbraco.Core/Models/Membership/IReadOnlyUserGroup.cs
#	src/Umbraco.Core/Models/Membership/IUserGroup.cs
#	src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs
#	src/Umbraco.Core/Models/Membership/UserGroup.cs
#	src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs
#	src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs
#	src/Umbraco.Core/Services/ContentService.cs
#	src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Infrastructure/Persistence/Dtos/UserGroupDto.cs
#	src/Umbraco.Infrastructure/Persistence/Factories/UserFactory.cs
#	src/Umbraco.Infrastructure/Persistence/Factories/UserGroupFactory.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserGroupRepository.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
#	src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
#	src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
#	src/Umbraco.Web.BackOffice/Filters/ContentSaveValidationAttribute.cs
#	src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs
#	src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
2022-06-20 13:59:18 +02:00
b4fbad14c7 V11: cleanup obsoletes (#12481)
* Remove IExternalLoginService.cs

* Remove UmbracoApplicationComponentsInstallingNotification.cs

* Remove UmbracoApplicationMainDomAcquiredNotification.cs

* Merge IContentTypeWithHistoryCleanup with IContentType.cs

* Remove obsolete ctors from notifications

* Remove obsolete methods

* Remove obsolete method from RequestHandlerSettings.cs

* Fix UmbracoBuilder.Repositories.cs

* RemoveRemove obsolete constants

* Remove obsolete method from IRuntimeMinifier

* Remove SetLastLogin from IMemberRepository

* Revert "RemoveRemove obsolete constants"

This reverts commit cddb8ad1cf.

* Remove obsoleted Constants-Conventions.cs

* Remove obsolete ctors

* Make ContentData properties immutable

* remove obsolete static property from TestOptionAttributeBase

* Merge IMacroWithAliasService into IMacroService

* Remove IUserComposer

* remove obsolete AddOEmbedProvider method

* remove obsolete static EmbedProvidersCollectionBuilder

* remove obsolete HasFlagAll<T> method

* Remove obsolete LocalizedTextService property from BaseHttpHeaderCheck

* Remove obsolete GetDefaultFIleContent method from ViewHelper

* Remove more obsolete ctors and methods

* Remove obsolete ctor from RelationType

* Remove more obsolete methods

* Remove IExternalLoginRepository

* merge IMacroWithAliasRepository with IMacroRepository

* Remove obsolete methods from ExternalLoginRepository

* Remove obsolete method from IUserRepository

* Remove obsolete SetLastLogin, as it was NoOp

* Remove wierd SetLastLogin method from UserService

* Remove GetLogLevel from ILogViewer

* Remove more obsolete methods and ctors

* Remove more obsoletes

* Use other method in BackOfficeServerVariables.cs since GetAllTypes is now removed

* Remove obsolete ctor

* Remove ConfigureIISServerOptions

* Remove more obsolete methods

* Merge ITwoFactorLoginService2 with ITwoFactorLoginService

* Re-introduce GetCustomGenericProperties in MemberTabsAndPropertiesMapper.cs

Co-authored-by: Nikolaj Geisle <niko737@edu.ucl.dk>
2022-06-07 11:16:30 +02:00
Nikolaj Geisle 882de44e38 Revert "Remove IExternalLoginService.cs"
This reverts commit 8b2557817b.
2022-05-23 10:33:32 +02:00
Nikolaj Geisle 7a1e134978 Revert "Remove UmbracoApplicationComponentsInstallingNotification.cs"
This reverts commit f6d39cd7e1.
2022-05-23 10:33:29 +02:00
Nikolaj Geisle 77c5b288b0 Revert "Remove UmbracoApplicationMainDomAcquiredNotification.cs"
This reverts commit 43add037e6.
2022-05-23 10:33:16 +02:00
Nikolaj Geisle 9719f8ac56 Revert "Merge IContentTypeWithHistoryCleanup with IContentType.cs"
This reverts commit 94eb49cdb6.
2022-05-23 10:33:02 +02:00
Nikolaj Geisle 94eb49cdb6 Merge IContentTypeWithHistoryCleanup with IContentType.cs 2022-05-23 10:30:03 +02:00
Nikolaj Geisle 43add037e6 Remove UmbracoApplicationMainDomAcquiredNotification.cs 2022-05-23 10:27:29 +02:00
Nikolaj Geisle f6d39cd7e1 Remove UmbracoApplicationComponentsInstallingNotification.cs 2022-05-23 10:27:18 +02:00
Nikolaj Geisle 8b2557817b Remove IExternalLoginService.cs 2022-05-23 10:26:54 +02:00
Nikolaj Geisle 4d68820879 Handle if securitySettings is set 2022-05-16 14:08:21 +02:00
Nikolaj Geisle 544dcffa18 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-05-16 14:00:22 +02:00
Nikolaj Geisle 27421cef2a Handle invariant permissions 2022-05-16 14:00:13 +02:00
Mads Rasmussen 279dd0cf0c Merge branch 'v10/feature/variant-permissions' of https://github.com/umbraco/Umbraco-CMS into v10/feature/variant-permissions 2022-05-16 13:44:26 +02:00
Mads Rasmussen 9e51ad9cbf check for permissions in block list editor 2022-05-16 13:44:19 +02:00
Nikolaj Geisle 2ad73d4c47 Fix proper mapping instead of duplicated code 2022-05-16 13:23:54 +02:00
Nikolaj Geisle 62525518c2 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-05-16 13:10:10 +02:00
Nikolaj Geisle cc450bef8a Fix invariant-variant returning all actions 2022-05-16 13:10:03 +02:00
Mads Rasmussen 3f0b90b18d remove delete row button when block list editor is readonly 2022-05-16 13:05:46 +02:00
Mads Rasmussen c0f674d333 localize unlock invariant property help text 2022-05-16 12:32:40 +02:00
Mads Rasmussen 6c4159751c add translation for shared 2022-05-16 11:39:14 +02:00
Mads Rasmussen 23b8dd843c add more white space underneath language label 2022-05-16 11:35:07 +02:00
Mads Rasmussen ec60ad8629 remove padding from property unlock container 2022-05-16 11:32:33 +02:00
Mads Rasmussen 121933a9ed only use preview mode if the user can also unlock the property editor 2022-05-16 11:29:33 +02:00
Mads Rasmussen 3b8c5dd084 Add check for editing invariant properties based on the appsetting config 2022-05-16 11:07:09 +02:00
Mads Rasmussen 587fa5c0d6 Merge branch 'v10/feature/variant-permissions' into v10/feature/editable-invariant-properties-ui 2022-05-16 10:54:10 +02:00
Nikolaj Geisle 14ce40be4c Fix BackOfficeServerVariables.cs 2022-05-16 10:50:40 +02:00
Mads Rasmussen d9f1b2e8aa Merge branch 'v10/feature/variant-permissions' into v10/feature/editable-invariant-properties-ui 2022-05-16 10:25:23 +02:00
Nikolaj Geisle 6de8a81aa0 Fix invariant content 2022-05-16 09:56:18 +02:00
Mads Rasmussen 2ad51a4520 update to variable 2022-05-12 21:56:35 +02:00
Mads Rasmussen 5494b48756 allow unlocking invariant properties if a user has update permissions for the language 2022-05-12 21:54:04 +02:00
Mads Rasmussen ce8a635c2c always show shared badge on invariant properties on variant nodes 2022-05-12 18:49:54 +02:00
Mads Rasmussen e02516193a Merge branch 'v10/feature/variant-permissions' into v10/feature/editable-invariant-properties-ui 2022-05-12 18:33:02 +02:00
Mads Rasmussen ec91d8c22b check for publish permission when publishing with decendants 2022-05-12 18:07:35 +02:00
Mads Rasmussen 87811bd3b3 check for unpublish permission 2022-05-12 18:07:00 +02:00
Mads Rasmussen dae338b4e8 check for schedule permission 2022-05-12 18:06:41 +02:00
Mads Rasmussen 7405cbe6ef check for send to publish permission 2022-05-12 18:05:38 +02:00
Mads Rasmussen c26a0a46b0 dont allow publish if the user doesn't have publish permissions 2022-05-12 18:02:15 +02:00
Mads Rasmussen 84108bbea2 dont allow save if the user doesn't have save permissions 2022-05-12 18:01:17 +02:00
3f0ff6a752 Publish invariant properties (#12386)
* Publish invariants from non default

* Add culture impact service

* Use the new culture impact service instead of newing up culture impacts

* Only publish invariant properties on non-defaults with invariant culture

Essentially we want to be able to fall back to the default culture for the variant properties if a document type is made invariant, not whatever culture was published last.

* Move creation logic into the service

* Make creation method names consistent

* Fix tests

We compare the cultures directly, so they have to be the same object instance unfortunately

* Add test for the new setting

* Add new config to server variables

* Fix test setup

* Apply suggestions from code review

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2022-05-12 12:41:51 +02:00
Mads Rasmussen 6ddce4b151 use correct magic letter for update permission 2022-05-11 20:30:08 +02:00
Mads Rasmussen c9c00760b5 match tag editor readonly styling with input 2022-05-11 20:25:34 +02:00
Mads Rasmussen 5e4ecf2462 set node name to readonly when the user has no update permissions 2022-05-11 20:22:47 +02:00
Mads Rasmussen 4a63433257 simplify check for readonly 2022-05-11 20:21:49 +02:00
Mads Rasmussen de8a5bc855 style readonly inputs different than disabled inputs 2022-05-11 19:36:39 +02:00
Mads Rasmussen 95a41afea9 list view: check for readonly based on variant permissions 2022-05-11 19:26:54 +02:00
Mads Rasmussen 16288cf939 content: check for readonly properties based on variant permissions 2022-05-11 19:26:24 +02:00
Nikolaj Geisle 1810b7a744 Change allowedactions 2022-05-11 13:34:35 +02:00
Nikolaj Geisle e839e09680 Finish default granular permissions for languages 2022-05-11 12:55:42 +02:00
Nikolaj Geisle e270f90296 Add granular permission to variants 2022-05-11 12:31:51 +02:00
Nikolaj Geisle b6277fbfd7 Revert "Start work on allowing nodes for users per language"
This reverts commit e78794c00e.
2022-05-11 10:01:27 +02:00
Nikolaj Geisle 004267a86f Fix test 2022-05-11 09:49:13 +02:00
Mads Rasmussen 20c3799e5b add overlay to allow editing invariant properties from all languages 2022-05-10 16:12:58 +02:00
Nikolaj Geisle e78794c00e Start work on allowing nodes for users per language 2022-05-10 15:57:13 +02:00
Nikolaj Geisle 0d16de1b64 Merge remote-tracking branch 'origin/v10/dev' into v10/feature/variant-permissions 2022-05-10 15:34:46 +02:00
Nikolaj Geisle eda9328f99 Dissallow users to save languages they do not have access to 2022-05-10 14:57:58 +02:00
Mads Rasmussen 23bb172be0 add icon for languages 2022-05-10 13:10:23 +02:00
Mads Rasmussen 08dedf57c5 change help text to limit 2022-05-10 12:45:36 +02:00
Mads Rasmussen 855f83ee1f Merge branch 'v10/feature/variant-permissions' of https://github.com/umbraco/Umbraco-CMS into v10/feature/variant-permissions 2022-05-10 12:40:15 +02:00
Mads Rasmussen 4dd4f190e3 Move languages underneath sections 2022-05-10 12:40:03 +02:00
Nikolaj Geisle 3bbfc427fc Fix breaking change in mapping 2022-05-10 12:37:52 +02:00
Nikolaj Geisle 52f17cd25f Remove defaulting to return all languages 2022-05-10 12:33:09 +02:00
Nikolaj Geisle 1638cfcf40 Merge remote-tracking branch 'origin/v10/feature/variant-permissions' into v10/feature/variant-permissions 2022-05-10 12:30:33 +02:00
Nikolaj Geisle 16d74d016c Fix PerformGetAll 2022-05-10 12:30:25 +02:00
Mads Rasmussen 58a915d2f7 wire up remove language 2022-05-10 12:16:32 +02:00
Mads Rasmussen 2e100e60c4 read from languages - save to allowedLanguages 2022-05-10 11:39:39 +02:00
Nikolaj Geisle 5c2b0121ba Create new table in database for usergroup languages 2022-05-10 11:03:31 +02:00
Mads Rasmussen b75752e9a6 post array of language id's when saving 2022-05-09 15:38:40 +02:00
Mads Rasmussen a0eeb6da26 save to allowedLanguages 2022-05-09 14:31:02 +02:00
Mads Rasmussen 98de8499e0 read from allowedLanguages 2022-05-09 14:30:46 +02:00
Nikolaj Geisle a5df4f169b Fix test error 2022-05-09 13:35:23 +02:00
Mads Rasmussen f095797c2e Merge branch 'v10/feature/readonly-property-editors' into v10/feature/variant-permissions 2022-05-09 11:20:28 +02:00
Mads Rasmussen 4ba094ff75 Merge branch 'v10/dev' into v10/feature/variant-permissions 2022-05-09 11:08:04 +02:00
Mads Rasmussen b220c0e2cf add readonly mode for grid property editor 2022-05-04 16:40:58 +02:00
Mads Rasmussen 3c6fa43fa8 add readonly mode for block list property editor 2022-05-04 15:29:58 +02:00
Mads Rasmussen c09acf4a1b fix temp readonly check 2022-05-04 13:53:01 +02:00
Mads Rasmussen f4da7262d5 add readonly mode for list view property editor 2022-05-04 13:52:46 +02:00
Mads Rasmussen a9c6d98c85 add readonly mode for rich text editor property editor 2022-05-04 12:38:27 +02:00
Mads Rasmussen 382d91c461 add readonly mode for markdown property editor 2022-05-03 17:36:38 +02:00
Mads Rasmussen f2780d5478 add readonly mode for image cropper 2022-05-03 16:14:58 +02:00
Mads Rasmussen 5609142317 remove unused listeners 2022-05-03 15:24:47 +02:00
Mads Rasmussen 231deb182e add readonly mode for dropdown property editor 2022-05-03 15:23:35 +02:00
Mads Rasmussen e1187135b4 add readonly mode for nested content property editor 2022-05-03 15:11:50 +02:00
Mads Rasmussen 49ef5401e9 add readonly mode for tags property editor 2022-05-03 14:06:24 +02:00
Mads Rasmussen 44a3a7dd97 add readonly mode to media picker property editor 2022-05-03 13:40:01 +02:00
Mads Rasmussen 11ba194049 Update fileupload.html 2022-05-03 12:59:48 +02:00
Mads Rasmussen 285aee8315 add readonly mode for file upload property editor 2022-05-03 12:59:13 +02:00
Mads Rasmussen e87b45574b add readonly mode for date picker property editor 2022-05-02 21:43:10 +02:00
Mads Rasmussen 3d9828fa5b add readonly mode for slider property editor 2022-05-02 21:32:52 +02:00
Mads Rasmussen 5b002f0888 add readonly mode til content picker / multinode tree picker property editor 2022-05-02 19:57:49 +02:00
Mads Rasmussen b40fcd3fe3 add readonly mode to multi url picker property editor 2022-05-02 11:18:10 +02:00
Mads Rasmussen b459ee4053 add disabled state to umb-multiple-textbox property editor add button when readonly 2022-05-02 10:54:42 +02:00
Mads Rasmussen 6a7b6a48ec add readonly mode to legacy media picker 2022-04-29 12:49:32 +02:00
Mads Rasmussen 444db1fc4e add readonly mode for radiobutton property editor 2022-04-29 11:04:08 +02:00
Mads Rasmussen c5ea4511cd add readonly mode to umb-radiobutton component 2022-04-29 10:45:11 +02:00
Mads Rasmussen 829618c381 add readonly mode for boolean property editor 2022-04-29 10:24:14 +02:00
Mads Rasmussen 9e21352c0d add readonly mode for checkboxlist property editor 2022-04-29 10:23:43 +02:00
Mads Rasmussen 96e2034d55 add readonly mode for umb-checkbox component 2022-04-29 10:23:15 +02:00
Jacob Overgaard 58f327f0e5 Add translations for new language picker 2022-04-29 09:45:55 +02:00
Jacob Overgaard 28dedaa74e Set languages header 2022-04-29 09:45:45 +02:00
Jacob Overgaard 32a3fb9f60 Merge remote-tracking branch 'origin/v10/dev' into v10/feature/variant-permissions 2022-04-29 09:27:08 +02:00
Jacob Overgaard 80a180238a add frontend controls for language picker in user groups 2022-04-29 09:10:12 +02:00
Jacob Overgaard f831af207b add basic structure for languages and allowedLanguages 2022-04-29 09:09:40 +02:00
Mads Rasmussen b4131cbaea temp check for read only mode 2022-04-28 16:14:29 +02:00
Mads Rasmussen 10b231f3f9 add readonly mode to member picker property editor 2022-04-28 16:13:58 +02:00
Mads Rasmussen 5c0178213c add readonly mode for user picker 2022-04-28 16:04:55 +02:00
Mads Rasmussen 4ebc3a411a add readonly mode to member group picker 2022-04-28 15:49:00 +02:00
Mads Rasmussen 781cac38d3 add disabled state to umb-node-preview-add buttton 2022-04-28 15:48:14 +02:00
Mads Rasmussen 21eceb4ec9 add readonly mode for multiple textbox property editor 2022-04-28 15:17:45 +02:00
Mads Rasmussen 1257c232a9 add readonly mode to eye dropper property editor 2022-04-28 14:49:53 +02:00
Mads Rasmussen b5e187040d add readonly mode to color picker component 2022-04-28 14:49:17 +02:00
Mads Rasmussen 749aa8f68d show not-allowed cursor for readonly color picker 2022-04-28 13:20:59 +02:00
Mads Rasmussen 8923d1a7f5 add readonly mode for color picker property editor 2022-04-28 13:20:11 +02:00
Mads Rasmussen 50b17ed262 add readonly mode for color swatches component 2022-04-28 13:19:48 +02:00
Mads Rasmussen 2235dd8e8a add readonly mode for umb-toggle component 2022-04-28 13:09:28 +02:00
Mads Rasmussen 232ada71a8 add readonly to email property editor 2022-04-28 12:44:31 +02:00
Mads Rasmussen 8d9977e016 add readonly to decimal property editor 2022-04-28 12:42:52 +02:00
Mads Rasmussen fae802ac5f add readonly to integer property editor 2022-04-28 12:41:55 +02:00
Mads Rasmussen 19b5157739 add readonly to textarea 2022-04-28 12:40:36 +02:00
Mads Rasmussen 607f0ea67f add readonly state to textbox 2022-04-28 12:39:12 +02:00
Mads Rasmussen 41ba4592ce set readonly state in a property editor when the readonly attr is set on the component 2022-04-28 12:38:35 +02:00
Jacob Overgaard 23c85dea7a add languagepicker infinite editor 2022-04-26 08:50:45 +02:00
1043 changed files with 44066 additions and 16711 deletions
+9 -30
View File
@@ -1,36 +1,15 @@
# [Choice] .NET Core version: 5.0, 3.1, 2.1
ARG VARIANT=3.1
FROM mcr.microsoft.com/vscode/devcontainers/dotnetcore:0-${VARIANT}
# [Choice] .NET version: 6.0, 3.1, 6.0-bullseye, 3.1-bullseye, 6.0-focal, 3.1-focal
ARG VARIANT=6.0-bullseye
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT}
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Option] Install Azure CLI
ARG INSTALL_AZURE_CLI="false"
COPY library-scripts/azcli-debian.sh /tmp/library-scripts/
RUN if [ "$INSTALL_AZURE_CLI" = "true" ]; then bash /tmp/library-scripts/azcli-debian.sh; fi \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
# Install SQL Tools: SQLPackage and sqlcmd
COPY mssql/installSQLtools.sh installSQLtools.sh
RUN bash ./installSQLtools.sh \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
# Update args in docker-compose.yaml to set the UID/GID of the "vscode" user.
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then groupmod --gid $USER_GID vscode && usermod --uid $USER_UID --gid $USER_GID vscode; fi
# [Choice] Node.js version: none, lts/*, 18, 16, 14
ARG NODE_VERSION="none"
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] Uncomment this section to install additional OS packages.
# Following added by Warren...
# Needed to add as Gifsicle used by gulp-imagemin does not ship a Linux binary and has to be compiled from source
# And this Linux package is needed in order to build it
# https://github.com/imagemin/imagemin-gifsicle/issues/40#issuecomment-616487214
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends dh-autoreconf chromium-browser
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
@@ -42,7 +21,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# Needing to set unsafe-perm as root is the user setup
# https://docs.npmjs.com/cli/v6/using-npm/config#unsafe-perm
# Default: false if running as root, true otherwise (we are ROOT)
RUN npm -g config set user vscode && npm -g config set unsafe-perm
#RUN npm -g config set user vscode && npm -g config set unsafe-perm
# Generate and trust a local developer certificate for Kestrel
# This is needed for Kestrel to bind on https
+6 -24
View File
@@ -1,26 +1,13 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.158.0/containers/dotnet-mssql
// https://github.com/microsoft/vscode-dev-containers/tree/main/containers/dotnet
{
"name": "C# (.NET) and MS SQL",
"name": "C# (.NET) Umbraco & SMTP4Dev",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"mssql.connections": [
{
"server": "localhost,1433",
"database": "",
"authenticationType": "SqlLogin",
"user": "sa",
"password": "P@ssw0rd",
"emptyPasswordInput": false,
"savePassword": false,
"profileName": "mssql-container"
}
],
"settings": {
"omnisharp.defaultLaunchSolution": "umbraco.sln",
"omnisharp.enableDecompilationSupport": true,
"omnisharp.enableRoslynAnalyzers": true
@@ -28,14 +15,11 @@
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csharp",
"ms-mssql.mssql"
"ms-dotnettools.csharp"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// 1433 for SQL if you want to connect from local into the one running inside the container
// Can connect to the SQL Server running in the image on local with 'host.docker.internal' as hostname
"forwardPorts": [1433, 9000, 5000, 25],
"forwardPorts": [9000, 5000, 25]
// [Optional] To reuse of your local HTTPS dev cert:
//
@@ -56,6 +40,4 @@
// 2. Drag ~/.aspnet/https/aspnetapp.pfx into the root of the file explorer
// 3. Open a terminal in VS Code and run "mkdir -p /home/vscode/.aspnet/https && mv aspnetapp.pfx /home/vscode/.aspnet/https"
// postCreateCommand.sh parameters: $1=SA password, $2=dacpac path, $3=sql script(s) path
"postCreateCommand": "bash .devcontainer/mssql/postCreateCommand.sh 'P@ssw0rd' './bin/Debug/' './.devcontainer/mssql/'"
}
+4 -21
View File
@@ -6,15 +6,10 @@ services:
context: .
dockerfile: Dockerfile
args:
# [Choice] Update 'VARIANT' to pick a .NET Core version: 2.1, 3.1, 5.0
VARIANT: 5.0
# [Choice] .NET version: 6.0, 3.1, 6.0-bullseye, 3.1-bullseye, 6.0-focal, 3.1-focal
VARIANT: 6.0-bullseye
# Options
INSTALL_NODE: "true"
NODE_VERSION: "lts/*"
INSTALL_AZURE_CLI: "false"
# On Linux, you may need to update USER_UID and USER_GID below if not your local UID is not 1000.
USER_UID: 1000
USER_GID: 1000
volumes:
- ..:/workspace:cached
@@ -22,9 +17,6 @@ services:
# Overrides default command so things don't shut down after the process ends.
command: sleep infinity
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
network_mode: service:db
# Uncomment the next line to use a non-root user for all processes.
# user: vscode
@@ -34,7 +26,8 @@ services:
# DotNetCore ENV Variables
# https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-5.0#environment-variables
environment:
- ConnectionStrings__umbracoDbDSN=server=localhost;database=UmbracoUnicore;user id=sa;password='P@ssw0rd'
- ConnectionStrings__umbracoDbDSN=Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True
- ConnectionStrings__umbracoDbDSN_ProviderName=Microsoft.Data.Sqlite
- Umbraco__CMS__Unattended__InstallUnattended=true
- Umbraco__CMS__Unattended__UnattendedUserName=Admin
- Umbraco__CMS__Unattended__UnattendedUserEmail=test@umbraco.com
@@ -43,16 +36,6 @@ services:
- Umbraco__CMS__Global__Smtp__Port=25
- Umbraco__CMS__Global__Smtp__From=noreply@umbraco.test
db:
image: mcr.microsoft.com/mssql/server:2019-latest
restart: unless-stopped
environment:
SA_PASSWORD: P@ssw0rd
ACCEPT_EULA: Y
# Add "forwardPorts": ["1433"] to **devcontainer.json** to forward MSSQL locally.
# (Adding the "ports" property to this file will not forward from a Codespace.)
smtp4dev:
image: rnwood/smtp4dev:v3
restart: always
@@ -1,33 +0,0 @@
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/azcli.md
#
# Syntax: ./azcli-debian.sh
set -e
if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
fi
export DEBIAN_FRONTEND=noninteractive
# Install curl, apt-transport-https, lsb-release, or gpg if missing
if ! dpkg -s apt-transport-https curl ca-certificates lsb-release > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
apt-get update
fi
apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates lsb-release gnupg2
fi
# Install the Azure CLI
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
curl -sL https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT)
apt-get update
apt-get install -y azure-cli
echo "Done!"
-11
View File
@@ -1,11 +0,0 @@
/*
This will generate a blank database when the container is spun up
that you can use to connect to for the SQL configuration in the web installer flow
---- NOTE ----
Any .sql files in this folder will be executed
Along with any .dacpac will be restored as databases
See postCreateCommand.sh for specifics
*/
CREATE DATABASE UmbracoUnicore;
GO
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
set -echo
echo "Installing mssql-tools"
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT)
DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
CODENAME=$(lsb_release -cs)
echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-${DISTRO}-${CODENAME}-prod ${CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
apt-get update
ACCEPT_EULA=Y apt-get -y install unixodbc-dev msodbcsql17 libunwind8 mssql-tools
echo "Installing sqlpackage"
curl -sSL -o sqlpackage.zip "https://aka.ms/sqlpackage-linux"
mkdir /opt/sqlpackage
unzip sqlpackage.zip -d /opt/sqlpackage
rm sqlpackage.zip
chmod a+x /opt/sqlpackage/sqlpackage
-64
View File
@@ -1,64 +0,0 @@
#!/bin/bash
dacpac="false"
sqlfiles="false"
SApassword=$1
dacpath=$2
sqlpath=$3
echo "SELECT * FROM SYS.DATABASES" | dd of=testsqlconnection.sql
for i in {1..60};
do
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SApassword -d master -i testsqlconnection.sql > /dev/null
if [ $? -eq 0 ]
then
echo "SQL server ready"
break
else
echo "Not ready yet..."
sleep 1
fi
done
rm testsqlconnection.sql
for f in $dacpath/*
do
if [ $f == $dacpath/*".dacpac" ]
then
dacpac="true"
echo "Found dacpac $f"
fi
done
for f in $sqlpath/*
do
if [ $f == $sqlpath/*".sql" ]
then
sqlfiles="true"
echo "Found SQL file $f"
fi
done
if [ $sqlfiles == "true" ]
then
for f in $sqlpath/*
do
if [ $f == $sqlpath/*".sql" ]
then
echo "Executing $f"
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SApassword -d master -i $f
fi
done
fi
if [ $dacpac == "true" ]
then
for f in $dacpath/*
do
if [ $f == $dacpath/*".dacpac" ]
then
dbname=$(basename $f ".dacpac")
echo "Deploying dacpac $f"
/opt/sqlpackage/sqlpackage /Action:Publish /SourceFile:$f /TargetServerName:localhost /TargetDatabaseName:$dbname /TargetUser:sa /TargetPassword:$SApassword
fi
done
fi
+1 -1
View File
@@ -6,7 +6,7 @@ body:
- type: input
id: "version"
attributes:
label: "Which *exact* Umbraco version are you using? For example: 9.0.1 - don't just write v9"
label: "Which Umbraco version are you using? (Please write the *exact* version, example: 10.1.0)"
description: "Use the help icon in the Umbraco backoffice to find the version you're using"
validations:
required: true
+18
View File
@@ -0,0 +1,18 @@
# New backoffice
> **Warning**:
> This is an early WIP and is set not to be packable since we don't want to release this yet. There will be breaking changes in these projects.
This solution folder contains the projects for the new backoffice. If you're looking to fix or improve the existing CMS, this is not the place to do it, although we do very much appreciate your efforts.
### Project structure
Since the new backoffice API is still very much a work in progress, we've created new projects for the new backoffice API:
* Umbrao.Cms.ManagementApi - The "presentation layer" for the management API
* "New" versions of existing projects, should be merged with the existing projects when the new API is released:
* Umbraco.New.Cms.Core
* Umbraco.New.Cms.Infrastructure
* Umbraco.New.Cms.Web.Common
This also means that we have to use "InternalsVisibleTo" for the new projects since these should be able to access the internal classes since they will when they get merged.
+2 -1
View File
@@ -5,4 +5,5 @@ paths:
paths-ignore:
- '**/node_modules'
- 'src/Umbraco.Web.UI/wwwroot'
- 'src/Umbraco.Web.UI/wwwroot'
- 'src/Umbraco.Cms.StaticAssets/wwwroot'
@@ -5,6 +5,9 @@ on:
types:
- opened
permissions:
contents: read
jobs:
get-user-type:
runs-on: ubuntu-latest
@@ -43,6 +46,8 @@ jobs:
core.setOutput("ignored", isIgnoredUser);
console.log("Ignored is", isIgnoredUser);
add-to-project:
permissions:
repository-projects: write # for actions/add-to-project
if: needs.get-user-type.outputs.ignored == 'false'
runs-on: ubuntu-latest
needs: [get-user-type]
+35 -11
View File
@@ -2,35 +2,59 @@ name: "Code scanning - action"
on:
push:
branches: ['*/dev','*/contrib']
branches:
- '*/dev'
- '*/contrib'
pull_request:
# The branches below must be a subset of the branches above
branches: ['*/dev','*/contrib']
branches:
- '*/dev'
- '*/contrib'
permissions:
contents: read
env:
dotnetVersion: 6.x
dotnetIncludePreviewVersions: false
solution: umbraco.sln
buildConfiguration: SkipTests
DOTNET_NOLOGO: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
jobs:
CodeQL-Build:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/analyze to upload SARIF results
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
config-file: ./.github/config/codeql-config.yml
- name: Setup dotnet
uses: actions/setup-dotnet@v1
- name: Use .NET ${{ env.dotnetVersion }}
uses: actions/setup-dotnet@v2
with:
dotnet-version: '6.0.x'
dotnet-version: ${{ env.dotnetVersion }}
include-prerelease: ${{ env.dotnetIncludePreviewVersions }}
- name: dotnet build
run: dotnet build umbraco.sln -c SkipTests
- name: Run dotnet restore
run: dotnet restore ${{ env.solution }}
- name: Run dotnet build
run: dotnet build ${{ env.solution }} --configuration ${{ env.buildConfiguration }} --no-restore -p:ContinuousIntegrationBuild=true
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
@@ -0,0 +1,53 @@
name: issue-first-response
on:
issues:
types: [opened]
jobs:
send-response:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Install dependencies
run: |
npm install node-fetch@2
- name: Fetch random comment 🗣️ and add it to the issue
uses: actions/github-script@v6
with:
script: |
const fetch = require('node-fetch')
const response = await fetch('https://collaboratorsv2.euwest01.umbraco.io/umbraco/api/comments/PostComment', {
method: 'post',
body: JSON.stringify({
repo: '${{ github.repository }}',
number: '${{ github.event.number }}',
actor: '${{ github.actor }}',
commentType: 'opened-issue-first-comment'
}),
headers: {
'Authorization': 'Bearer ${{ secrets.OUR_BOT_API_TOKEN }}',
'Content-Type': 'application/json'
}
});
try {
const data = await response.text();
if(response.status === 200 && data !== '') {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: data
});
} else {
console.log("Status code did not indicate success:", response.status);
console.log("Returned data:", data);
}
} catch(error) {
console.log(error);
}
+2 -1
View File
@@ -104,5 +104,6 @@ cypress.env.json
/tests/Umbraco.Tests.UnitTests/[Uu]mbraco/[Dd]ata/TEMP/
# Ignore auto-generated schema
/src/Umbraco.Web.UI/appsettings-schema.json
/src/Umbraco.Cms/appsettings-schema.json
/src/Umbraco.Web.UI/appsettings-schema.json
/tests/Umbraco.Tests.Integration/appsettings-schema.json
+2 -3
View File
@@ -9,9 +9,8 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Dotnet build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/Umbraco.Web.UI/bin/Debug/net5.0/Umbraco.Web.UI.dll",
"args": [],
"program": "dotnet",
"args": ["run"],
"cwd": "${workspaceFolder}/src/Umbraco.Web.UI",
"stopAtEntry": false,
"requireExactSource": false,
+2 -1
View File
@@ -54,7 +54,7 @@
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/umbraco.sln",
"${workspaceFolder}/umbraco.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -69,6 +69,7 @@
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
+44 -10
View File
@@ -1,18 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- Package references and additional files which are consumed by all projects -->
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Company>Umbraco HQ</Company>
<Authors>Umbraco</Authors>
<Copyright>Copyright © Umbraco $([System.DateTime]::Today.ToString('yyyy'))</Copyright>
<Product>Umbraco CMS</Product>
<PackageProjectUrl>https://umbraco.com/</PackageProjectUrl>
<PackageIconUrl>https://umbraco.com/dist/nuget/logo-small.png</PackageIconUrl>
<PackageIcon>icon.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>umbraco</PackageTags>
<NeutralLanguage>en-US</NeutralLanguage>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable</WarningsAsErrors>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<!-- SourceLink -->
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!-- Package Validation -->
<PropertyGroup>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageValidationBaselineVersion>10.0.0</PackageValidationBaselineVersion>
<EnableStrictModeForCompatibleFrameworksInPackage>true</EnableStrictModeForCompatibleFrameworksInPackage>
<EnableStrictModeForCompatibleTfms>true</EnableStrictModeForCompatibleTfms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406" PrivateAssets="all" IsImplicitlyDefined="true"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.113" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="Umbraco.Code" Version="2.0.0" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="Umbraco.GitVersioning.Extensions" Version="0.1.1" PrivateAssets="all" IsImplicitlyDefined="true" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Condition="!Exists('packages.config')">
<PrivateAssets>all</PrivateAssets>
<Version>3.5.107</Version>
</PackageReference>
<PackageReference Include="Umbraco.GitVersioning.Extensions" Version="0.1.1">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<Content Include="$(MSBuildThisFileDirectory)icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
<PropertyGroup>
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)</GitVersionBaseDirectory>
</PropertyGroup>
</Project>
+120 -93
View File
@@ -23,12 +23,16 @@ parameters:
default: false
variables:
buildConfiguration: Release
SA_PASSWORD: UmbracoIntegration123!
UMBRACO__CMS_GLOBAL__ID: 00000000-0000-0000-0000-000000000042
nodeVersion: 14.18.1
DOTNET_NOLOGO: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
dotnetVersion: 6.x
dotnetIncludePreviewVersions: false
solution: umbraco.sln
buildConfiguration: Release
UMBRACO__CMS__GLOBAL__ID: 00000000-0000-0000-0000-000000000042
DOTNET_NOLOGO: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
stages:
###############################################
@@ -44,7 +48,7 @@ stages:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: Use node $(nodeVersion)
displayName: Use Node.js $(nodeVersion)
inputs:
versionSpec: $(nodeVersion)
- task: Cache@2
@@ -64,12 +68,23 @@ stages:
gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js
targets: coreBuild
workingDirectory: src/Umbraco.Web.UI.Client
- task: UseDotNet@2
displayName: Use .NET $(dotnetVersion)
inputs:
version: $(dotnetVersion)
performMultiLevelLookup: true
includePreviewVersions: $(dotnetIncludePreviewVersions)
- task: DotNetCoreCLI@2
displayName: Run dotnet restore
inputs:
command: restore
projects: $(solution)
- task: DotNetCoreCLI@2
displayName: Run dotnet build
inputs:
command: build
projects: umbraco.sln
arguments: '--configuration $(buildConfiguration)'
projects: $(solution)
arguments: '--configuration $(buildConfiguration) --no-restore -p:ContinuousIntegrationBuild=true'
- script: |
version="$(Build.BuildNumber)"
echo "varsion: $version"
@@ -96,7 +111,7 @@ stages:
}
}
dotnet pack --configuration $(buildConfiguration) umbraco.sln -o $(Build.ArtifactStagingDirectory)/nupkg
dotnet pack $(solution) --configuration $(buildConfiguration) -p:BuildProjectReferences=false --output $(Build.ArtifactStagingDirectory)/nupkg
- script: |
sha="$(Build.SourceVersion)"
sha=${sha:0:7}
@@ -119,7 +134,7 @@ stages:
displayName: Prepare API Documentation
dependsOn: Build
variables:
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['determineMajorVersion.majorVersion'] ]
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['determineMajorVersion.majorVersion'] ]
jobs:
# C# API Reference
- job:
@@ -130,41 +145,41 @@ stages:
- task: PowerShell@2
displayName: Install DocFX
inputs:
targetType: inline
script: |
choco install docfx --version=2.59.2 -y
if ($lastexitcode -ne 0){
throw ("Error installing DocFX")
}
targetType: inline
script: |
choco install docfx --version=2.59.2 -y
if ($lastexitcode -ne 0){
throw ("Error installing DocFX")
}
- task: PowerShell@2
displayName: Generate metadata
inputs:
targetType: inline
script: |
docfx metadata "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
if ($lastexitcode -ne 0){
throw ("Error generating metadata.")
}
targetType: inline
script: |
docfx metadata "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
if ($lastexitcode -ne 0){
throw ("Error generating metadata.")
}
- task: PowerShell@2
displayName: Generate documentation
inputs:
targetType: inline
script: |
docfx build "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
if ($lastexitcode -ne 0){
throw ("Error generating documentation.")
}
targetType: inline
script: |
docfx build "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
if ($lastexitcode -ne 0){
throw ("Error generating documentation.")
}
- task: ArchiveFiles@2
displayName: Archive C# Docs
inputs:
rootFolderOrFile: $(Build.SourcesDirectory)/build/csharp-docs/_site
includeRootFolder: false
archiveFile: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
rootFolderOrFile: $(Build.SourcesDirectory)/build/csharp-docs/_site
includeRootFolder: false
archiveFile: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
- task: PublishPipelineArtifact@1
displayName: Publish C# Docs
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
artifact: csharp-docs
targetPath: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
artifact: csharp-docs
# js API Reference
- job:
@@ -173,9 +188,9 @@ stages:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: Use Node 10.15.0
displayName: Use Node.js 10.15.0
inputs:
versionSpec: 10.15.0 # Won't work with 14.18.1
versionSpec: 10.15.0 # Won't work with higher versions
- script: |
npm ci --no-fund --no-audit --prefer-offline
npx gulp docs
@@ -192,14 +207,14 @@ stages:
- task: ArchiveFiles@2
displayName: Archive js Docs
inputs:
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
includeRootFolder: false
archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
includeRootFolder: false
archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
- task: PublishPipelineArtifact@1
displayName: Publish js Docs
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
artifact: ui-docs
targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
artifact: ui-docs
###############################################
## Test
@@ -228,16 +243,17 @@ stages:
artifact: build_output
path: $(Build.SourcesDirectory)
- task: UseDotNet@2
condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) # net6 already on the other images
displayName: Use net6
displayName: Use .NET $(dotnetVersion)
inputs:
version: 6.x
version: $(dotnetVersion)
performMultiLevelLookup: true
includePreviewVersions: $(dotnetIncludePreviewVersions)
- task: DotNetCoreCLI@2
displayName: Run dotnet test
inputs:
command: test
projects: '**/*.Tests.UnitTests.csproj'
arguments: '--no-build --configuration $(buildConfiguration)'
arguments: '--configuration $(buildConfiguration) --no-build'
testRunTitle: Unit Tests - $(Agent.OS)
- stage: Integration
@@ -264,20 +280,21 @@ stages:
artifact: build_output
path: $(Build.SourcesDirectory)
- task: UseDotNet@2
displayName: Use net6
condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) # net6 already on the other images
displayName: Use .NET $(dotnetVersion)
inputs:
version: 6.x
version: $(dotnetVersion)
performMultiLevelLookup: true
includePreviewVersions: $(dotnetIncludePreviewVersions)
- task: DotNetCoreCLI@2
displayName: Run dotnet test
inputs:
command: test
projects: '**/*.Tests.Integration.csproj'
arguments: '--no-build --configuration $(buildConfiguration)'
arguments: '--configuration $(buildConfiguration) --no-build'
testRunTitle: Integration Tests SQLite - $(Agent.OS)
env:
Tests__Database__DatabaseType: 'Sqlite'
Umbraco__Cms__global__MainDomLock: 'FileSystemMainDomLock'
Umbraco__CMS__Global__MainDomLock: 'FileSystemMainDomLock'
# Integration Tests (SQL Server)
- job:
@@ -296,6 +313,8 @@ stages:
connectionString: 'Server=localhost,1433;User Id=sa;Password=$(SA_PASSWORD);'
pool:
vmImage: $(vmImage)
variables:
SA_PASSWORD: UmbracoIntegration123!
steps:
- task: DownloadPipelineArtifact@2
displayName: Download build artifacts
@@ -305,7 +324,7 @@ stages:
- powershell: sqllocaldb start mssqllocaldb
displayName: Start localdb (Windows only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- powershell: docker run --name mssql -d -p 1433:1433 -e ACCEPT_EULA=Y -e SA_PASSWORD=$(SA_PASSWORD) -e MSSQL_PID=Developer mcr.microsoft.com/mssql/server:2019-latest
- powershell: docker run --name mssql -d -p 1433:1433 -e ACCEPT_EULA=Y -e SA_PASSWORD=$(SA_PASSWORD) -e MSSQL_PID=Developer mcr.microsoft.com/mssql/server:2019-latest
displayName: Start SQL Server (Linux only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
- task: DotNetCoreCLI@2
@@ -313,30 +332,29 @@ stages:
inputs:
command: test
projects: '**/*.Tests.Integration.csproj'
arguments: '--no-build --configuration $(buildConfiguration)'
arguments: '--configuration $(buildConfiguration) --no-build'
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
env:
Tests__Database__DatabaseType: $(testDb)
Tests__Database__SQLServerMasterConnectionString: $(connectionString)
Umbraco__Cms__global__MainDomLock: 'SqlMainDomLock'
Umbraco__CMS__Global__MainDomLock: 'SqlMainDomLock'
- stage: E2E
variables:
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
CYPRESS_CACHE_FOLDER: $(Pipeline.Workspace)/cypress_binaries
displayName: E2E Tests
dependsOn: Build
jobs:
# E2E Tests
# E2E Tests
- job:
displayName: E2E Tests
variables:
- name: Umbraco__CMS__Unattended__InstallUnattended # Windows only
value: true
- name: Umbraco__CMS__Unattended__UnattendedUserName # Windows only
value: Cypress Test
value: Playwright Test
- name: Umbraco__CMS__Unattended__UnattendedUserEmail # Windows only
value: cypress@umbraco.com
value: playwright@umbraco.com
- name: Umbraco__CMS__Unattended__UnattendedUserPassword # Windows only
value: UmbracoAcceptance123!
- name: Umbraco__CMS__Global__InstallMissingDatabase # Windows only
@@ -344,11 +362,11 @@ stages:
- name: UmbracoDatabaseServer # Windows only
value: (LocalDB)\MSSQLLocalDB
- name: UmbracoDatabaseName # Windows only
value: Cypress
value: Playwright
- name: ConnectionStrings__umbracoDbDSN # Windows only
value: Server=$(UmbracoDatabaseServer);Database=$(UmbracoDatabaseName);Integrated Security=true;
- name: CYPRESS_BASE_URL
value: http://localhost:8080
- name: PLAYWRIGHT_BASE_URL
value: https://localhost:8443
strategy:
matrix:
Linux:
@@ -358,7 +376,7 @@ stages:
Windows:
vmImage: 'windows-latest'
pool:
vmImage: $(vmImage)
vmImage: $(vmImage)
steps:
- task: DownloadPipelineArtifact@2
displayName: Download nupkg
@@ -366,7 +384,7 @@ stages:
artifact: nupkg
path: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/misc/nupkg
- task: NodeTool@0
displayName: Use Node $(nodeVersion)
displayName: Use Node.js $(nodeVersion)
inputs:
versionSpec: $(nodeVersion)
- task: Cache@2
@@ -377,19 +395,17 @@ stages:
"npm_e2e" | "$(Agent.OS)"
"npm_e2e"
path: $(npm_config_cache)
- task: Cache@2
displayName: Cache cypress binaries
inputs:
key: '"cypress_binaries" | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
path: $(CYPRESS_CACHE_FOLDER)
- task: PowerShell@2
displayName: Generate Cypress.env.json
displayName: Generate .env
inputs:
targetType: inline
script: >
@{ username = "$(Umbraco__CMS__Unattended__UnattendedUserEmail)"; password = "$(Umbraco__CMS__Unattended__UnattendedUserPassword)" } | ConvertTo-Json | Set-Content -Path "tests/Umbraco.Tests.AcceptanceTest/cypress.env.json"#
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/
script: |
New-Item -Path "." -Name ".env" -ItemType "file" -Value "UMBRACO_USER_LOGIN=$(Umbraco__CMS__Unattended__UnattendedUserEmail)
UMBRACO_USER_PASSWORD=$(Umbraco__CMS__Unattended__UnattendedUserPassword)
URL=$(PLAYWRIGHT_BASE_URL)"
- script: npm ci --no-fund --no-audit --prefer-offline
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/
displayName: Run npm ci
- powershell: sqllocaldb start mssqllocaldb
displayName: Start localdb (Windows only)
@@ -397,7 +413,13 @@ stages:
- powershell: Invoke-Sqlcmd -Query "CREATE DATABASE $env:UmbracoDatabaseName" -ServerInstance $env:UmbracoDatabaseServer
displayName: Create database (Windows only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
# Linux containers smooth
- task: UseDotNet@2
displayName: Use .NET $(dotnetVersion)
inputs:
version: $(dotnetVersion)
performMultiLevelLookup: true
includePreviewVersions: $(dotnetIncludePreviewVersions)
# Linux containers smooth
- task: PowerShell@2
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
displayName: Build & run container (Linux only)
@@ -409,10 +431,9 @@ stages:
docker build -t $(dockerImageName):$sha -f $(dockerfile) .
mkdir -p $(Build.ArtifactStagingDirectory)/docker-images
docker save -o $(Build.ArtifactStagingDirectory)/docker-images/$(dockerImageName).$sha.tar $(dockerImageName):$sha
docker run --name $(dockerImageName) -dp 8080:5000 -e UMBRACO__CMS_GLOBAL__ID=$(UMBRACO__CMS_GLOBAL__ID) $(dockerImageName):$sha
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p UmbracoAcceptance123!
docker run --name $(dockerImageName) -dp 8080:5000 -dp 8443:5001 -e UMBRACO__CMS__GLOBAL__ID=$(UMBRACO__CMS__GLOBAL__ID) -e ASPNETCORE_Kestrel__Certificates__Default__Password="UmbracoAcceptance123!" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v ${HOME}/.aspnet/https:/https/ $(dockerImageName):$sha
docker ps
# Windows containers take forever.
# --no-launch-profile stops ASPNETCORE_ENVIRONMENT=Development which breaks the users.ts tests (smtp config = invite user button)
# Urls matching docker setup.
- task: PowerShell@2
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
@@ -422,10 +443,11 @@ stages:
targetType: inline
script: |
dotnet new --install ./nupkg/Umbraco.Templates.*.nupkg
dotnet new umbraco --name Cypress -o . --no-restore
dotnet new umbraco --name Playwright --no-restore --output .
dotnet restore --configfile ./nuget.config
dotnet build --no-restore -c Release
Start-Process -FilePath "dotnet" -ArgumentList "run --no-build -c Release --no-launch-profile --urls $(CYPRESS_BASE_URL)"
dotnet build --configuration $(buildConfiguration) --no-restore
dotnet dev-certs https
Start-Process -FilePath "dotnet" -ArgumentList "run --configuration $(buildConfiguration) --no-build --no-launch-profile --urls $(PLAYWRIGHT_BASE_URL)"
- task: PowerShell@2
displayName: Wait for app
inputs:
@@ -433,31 +455,36 @@ stages:
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
script: |
npm i -g wait-on
wait-on -v --interval 1000 --timeout 120000 $(CYPRESS_BASE_URL)
wait-on -v --interval 1000 --timeout 120000 $(PLAYWRIGHT_BASE_URL)
- task: PowerShell@2
displayName: Run Cypress (Desktop)
displayName: Install Playwright
inputs:
targetType: inline
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
script: npx playwright install
- task: PowerShell@2
displayName: Run Playwright (Desktop)
continueOnError: true
inputs:
targetType: inline
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
script: 'npm run test -- --reporter junit --reporter-options "mochaFile=results/test-output-D-[hash].xml,toConsole=true" --config="viewportHeight=1600,viewportWidth=2560,screenshotsFolder=cypress/artifacts/desktop/screenshots,videosFolder=cypress/artifacts/desktop/videos,videoUploadOnPasses=false"'
- task: PublishTestResults@2
displayName: Publish test results
condition: always()
script: 'npm run test --ignore-certificate-errors'
- task: PowerShell@2
displayName: Check if artifacts folder exists
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'tests/Umbraco.Tests.AcceptanceTest/results/test-output-D-*.xml'
mergeTestResults: true
testRunTitle: "e2e - $(Agent.OS)"
targetType: inline
script: |
$MyVariable = Test-Path -Path $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/results
Write-Host "##vso[task.setvariable variable=resultFolderExists;]$MyVariable"
- task: CopyFiles@2
displayName: Prepare artifacts
condition: always()
condition: eq(variables.resultFolderExists, 'True')
inputs:
sourceFolder: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/cypress/artifacts
targetFolder: $(Build.ArtifactStagingDirectory)/cypresss
sourceFolder: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/results/
targetFolder: $(Build.ArtifactStagingDirectory)/playwright
- task: PublishPipelineArtifact@1
displayName: "Publish test artifacts"
condition: always()
condition: eq(variables.resultFolderExists, 'True')
inputs:
targetPath: $(Build.ArtifactStagingDirectory)
artifact: 'E2E artifacts - $(Agent.OS) - Attempt #$(System.JobAttempt)'
@@ -483,7 +510,7 @@ stages:
artifact: nupkg
path: $(Build.ArtifactStagingDirectory)/nupkg
- task: NuGetCommand@2
displayName: Nuget push
displayName: NuGet push
inputs:
command: 'push'
packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
@@ -507,7 +534,7 @@ stages:
artifact: nupkg
path: $(Build.ArtifactStagingDirectory)/nupkg
- task: NuGetCommand@2
displayName: Nuget push
displayName: NuGet push
inputs:
command: 'push'
packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

+53
View File
@@ -0,0 +1,53 @@
name: issue-first-response
on:
issues:
types: [opened]
jobs:
send-response:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Install dependencies
run: |
npm install node-fetch@2
- name: Fetch random comment 🗣️ and add it to the issue
uses: actions/github-script@v6
with:
script: |
const fetch = require('node-fetch')
const response = await fetch('https://collaboratorsv2.euwest01.umbraco.io/umbraco/api/comments/PostComment', {
method: 'post',
body: JSON.stringify({
repo: '${{ github.repository }}',
number: '${{ github.event.number }}',
actor: '${{ github.actor }}',
commentType: 'opened-issue-first-comment'
}),
headers: {
'Authorization': 'Bearer ${{ secrets.OUR_BOT_API_TOKEN }}',
'Content-Type': 'application/json'
}
});
try {
const data = await response.text();
if(response.status === 200 && data !== '') {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: data
});
} else {
console.log("Status code did not indicate success:", response.status);
console.log("Returned data:", data);
}
} catch(error) {
console.log(error);
}
-45
View File
@@ -1,45 +0,0 @@
<Project>
<!-- Enable multi-level merging -->
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"/>
<PropertyGroup>
<Version>10.0.0</Version>
<AssemblyVersion>10.0.0</AssemblyVersion>
<InformationalVersion>10.0.0-rc1</InformationalVersion>
<FileVersion>10.0.0</FileVersion>
<LangVersion Condition="'$(LangVersion)' == ''">10.0</LangVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<Company>Umbraco CMS</Company>
<Copyright>Copyright © Umbraco 2021</Copyright>
<Authors>Umbraco HQ</Authors>
<PackageProjectUrl>https://umbraco.com/</PackageProjectUrl>
<PackageIconUrl>https://umbraco.com/dist/nuget/logo-small.png</PackageIconUrl>
<PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageTags>umbraco</PackageTags>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/umbraco/umbraco-cms</RepositoryUrl>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup>
<!-- SourceLink: Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element)-->
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<!-- SourceLink: Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<!-- SourceLink: Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!-- SourceLink: Deterministic -->
<!-- https://github.com/clairernovotny/DeterministicBuilds -->
<!-- Only for Azure Pipelines CI Build -->
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
</Project>
-4
View File
@@ -56,8 +56,6 @@ namespace JsonSchema
public LoggingSettings? Logging { get; set; }
public MemberPasswordConfigurationSettings? MemberPassword { get; set; }
public NuCacheSettings? NuCache { get; set; }
public RequestHandlerSettings? RequestHandler { get; set; }
@@ -70,8 +68,6 @@ namespace JsonSchema
public TypeFinderSettings? TypeFinder { get; set; }
public UserPasswordConfigurationSettings? UserPassword { get; set; }
public WebRoutingSettings? WebRouting { get; set; }
public UmbracoPluginSettings? Plugins { get; set; }
+7 -27
View File
@@ -1,38 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IsPackable>false</IsPackable>
<EnablePackageValidation>false</EnablePackageValidation>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="NJsonSchema" Version="10.7.2" />
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
<PackageReference Include="Umbraco.Deploy.Core" Version="9.3.1" />
<PackageReference Include="Umbraco.Forms.Core" Version="10.0.0-rc1" />
<PackageReference Include="Umbraco.Deploy.Core" Version="9.4.0" />
<PackageReference Include="Umbraco.Forms.Core" Version="9.4.0" />
<PackageReference Update="Nerdbank.GitVersioning">
<Version>3.5.107</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="NJsonSchema" Version="10.7.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj" />
<PackageReference Include="Umbraco.Deploy.Core" Version="10.1.0" />
<PackageReference Include="Umbraco.Forms.Core" Version="10.1.0" />
</ItemGroup>
<!-- Copy Forms XML docs-->
<PropertyGroup>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
</PropertyGroup>
<Target Name="CopyPackagesXml" BeforeTargets="Build">
<ItemGroup>
<PackageReferenceFiles Include="$(NugetPackageRoot)%(PackageReference.Identity)\%(PackageReference.Version)%(PackageReference.CopyToOutputDirectory)\lib\**\*.xml" />
</ItemGroup>
<Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(OutDir)" />
</Target>
</Project>
+1 -1
View File
@@ -7,7 +7,7 @@ namespace JsonSchema
{
internal class Options
{
[Option('o', "outputFile", Required = false, HelpText = "Set path of the output file.", Default = "../../../../Umbraco.Web.UI/appsettings-schema.json")]
[Option('o', "outputFile", Required = false, HelpText = "Set path of the output file.", Default = "appsettings-schema.json")]
public string OutputFile { get; set; } = null!;
}
}
+5 -3
View File
@@ -1,11 +1,10 @@
// Copyright (c) Umbraco.
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NJsonSchema.Generation;
using Umbraco.Cms.Core.Configuration.Models;
namespace JsonSchema
{
@@ -50,6 +49,9 @@ namespace JsonSchema
{
NJsonSchema.JsonSchema schema = _innerGenerator.Generate(typeof(AppSettings));
// TODO: when the "UmbracoPath" setter is removed from "GlobalSettings" (scheduled for V12), remove this line as well
schema.Definitions["UmbracoCmsCoreConfigurationModelsGlobalSettings"]?.Properties?.Remove(nameof(GlobalSettings.UmbracoPath));
return JsonConvert.DeserializeObject<JObject>(schema.ToJson())!;
}
}
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Umbraco.Cms.ManagementApi.Builders;
public class ProblemDetailsBuilder
{
private string? _title;
private string? _detail;
private int _status = StatusCodes.Status400BadRequest;
private string? _type;
public ProblemDetailsBuilder WithTitle(string title)
{
_title = title;
return this;
}
public ProblemDetailsBuilder WithDetail(string detail)
{
_detail = detail;
return this;
}
public ProblemDetailsBuilder WithStatus(int status)
{
_status = status;
return this;
}
public ProblemDetailsBuilder WithType(string type)
{
_type = type;
return this;
}
public ProblemDetails Build() =>
new()
{
Title = _title,
Detail = _detail,
Status = _status,
Type = _type ?? "Error",
};
}
@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Configuration;
public class ConfigureMvcOptions : IConfigureOptions<MvcOptions>
{
private readonly IOptions<GlobalSettings> _globalSettings;
public ConfigureMvcOptions(IOptions<GlobalSettings> globalSettings)
{
_globalSettings = globalSettings;
}
public void Configure(MvcOptions options)
{
// Replace the BackOfficeToken in routes.
var backofficePath = _globalSettings.Value.UmbracoPath.TrimStart(Constants.CharArrays.TildeForwardSlash);
options.Conventions.Add(new UmbracoBackofficeToken(Constants.Web.AttributeRouting.BackOfficeToken, backofficePath));
}
}
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
namespace Umbraco.Cms.ManagementApi.Controllers.Analytics;
public class AllAnalyticsController : AnalyticsControllerBase
{
[HttpGet("all")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<TelemetryLevel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<TelemetryLevel>> GetAll(int skip, int take)
{
TelemetryLevel[] levels = Enum.GetValues<TelemetryLevel>();
return await Task.FromResult(new PagedViewModel<TelemetryLevel>
{
Total = levels.Length,
Items = levels.Skip(skip).Take(take),
});
}
}
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Analytics;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/analytics")]
[OpenApiTag("Analytics")]
[ApiVersion("1.0")]
public abstract class AnalyticsControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Analytics;
namespace Umbraco.Cms.ManagementApi.Controllers.Analytics;
public class GetAnalyticsController : AnalyticsControllerBase
{
private readonly IMetricsConsentService _metricsConsentService;
public GetAnalyticsController(IMetricsConsentService metricsConsentService) => _metricsConsentService = metricsConsentService;
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(AnalyticsLevelViewModel), StatusCodes.Status200OK)]
public async Task<AnalyticsLevelViewModel> Get() => await Task.FromResult(new AnalyticsLevelViewModel { AnalyticsLevel = _metricsConsentService.GetConsentLevel() });
}
@@ -0,0 +1,36 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Analytics;
using Umbraco.Cms.ManagementApi.ViewModels.Server;
namespace Umbraco.Cms.ManagementApi.Controllers.Analytics;
public class SetAnalyticsController : AnalyticsControllerBase
{
private readonly IMetricsConsentService _metricsConsentService;
public SetAnalyticsController(IMetricsConsentService metricsConsentService) => _metricsConsentService = metricsConsentService;
[HttpPost]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> SetConsentLevel(AnalyticsLevelViewModel analyticsLevelViewModel)
{
if (!Enum.IsDefined(analyticsLevelViewModel.AnalyticsLevel))
{
var invalidModelProblem = new ProblemDetails
{
Title = "Invalid AnalyticsLevel value",
Detail = "The provided value for AnalyticsLevel is not valid",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return BadRequest(invalidModelProblem);
}
_metricsConsentService.SetConsentLevel(analyticsLevelViewModel.AnalyticsLevel);
return await Task.FromResult(Ok());
}
}
@@ -0,0 +1,33 @@
using System.Globalization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.ManagementApi.ViewModels.Culture;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
namespace Umbraco.Cms.ManagementApi.Controllers.Culture;
public class AllCultureController : CultureControllerBase
{
private readonly IUmbracoMapper _umbracoMapper;
public AllCultureController(IUmbracoMapper umbracoMapper) => _umbracoMapper = umbracoMapper;
/// <summary>
/// Returns all cultures available for creating languages.
/// </summary>
/// <returns></returns>
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<CultureViewModel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<CultureViewModel>> GetAll(int skip, int take)
{
IEnumerable<CultureInfo> list = CultureInfo.GetCultures(CultureTypes.AllCultures)
.DistinctBy(x => x.Name)
.OrderBy(x => x.EnglishName)
.Skip(skip)
.Take(take);
return await Task.FromResult(_umbracoMapper.Map<PagedViewModel<CultureViewModel>>(list)!);
}
}
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Culture;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/culture")]
[OpenApiTag("Culture")]
[ApiVersion("1.0")]
public abstract class CultureControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DataType.Tree;
public class ChildrenDataTypeTreeController : DataTypeTreeControllerBase
{
public ChildrenDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService, dataTypeService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<FolderTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetChildren(parentKey, skip, take);
}
}
@@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.DataType.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DataType}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.DataType))]
public class DataTypeTreeControllerBase : FolderTreeControllerBase<FolderTreeItemViewModel>
{
private readonly IDataTypeService _dataTypeService;
public DataTypeTreeControllerBase(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService) =>
_dataTypeService = dataTypeService;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DataType;
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.DataTypeContainer;
protected override FolderTreeItemViewModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
{
var dataTypes = _dataTypeService
.GetAll(entities.Select(entity => entity.Id).ToArray())
.ToDictionary(contentType => contentType.Id);
return entities.Select(entity =>
{
FolderTreeItemViewModel viewModel = MapTreeItemViewModel(parentKey, entity);
if (dataTypes.TryGetValue(entity.Id, out IDataType? dataType))
{
viewModel.Icon = dataType.Editor?.Icon ?? viewModel.Icon;
}
return viewModel;
}).ToArray();
}
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DataType.Tree;
public class ItemsDataTypeTreeController : DataTypeTreeControllerBase
{
public ItemsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService, dataTypeService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<FolderTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DataType.Tree;
public class RootDataTypeTreeController : DataTypeTreeControllerBase
{
public RootDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService, dataTypeService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<FolderTreeItemViewModel>>> Root(int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,69 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Dictionary;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class AllDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IUmbracoMapper _umbracoMapper;
public AllDictionaryController(ILocalizationService localizationService, IUmbracoMapper umbracoMapper)
{
_localizationService = localizationService;
_umbracoMapper = umbracoMapper;
}
/// <summary>
/// Retrieves a list with all dictionary items
/// </summary>
/// <returns>
/// The <see cref="IEnumerable{T}" />.
/// </returns>
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DictionaryOverviewViewModel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<DictionaryOverviewViewModel>> All(int skip, int take)
{
IDictionaryItem[] items = _localizationService.GetDictionaryItemDescendants(null).ToArray();
var list = new List<DictionaryOverviewViewModel>(items.Length);
// Build the proper tree structure, as we can have nested dictionary items
BuildTree(list, items);
var model = new PagedViewModel<DictionaryOverviewViewModel>
{
Total = list.Count,
Items = list.Skip(skip).Take(take),
};
return await Task.FromResult(model);
}
// recursive method to build a tree structure from the flat structure returned above
private void BuildTree(List<DictionaryOverviewViewModel> list, IDictionaryItem[] items, int level = 0, Guid? parentId = null)
{
IDictionaryItem[] children = items.Where(t => t.ParentId == parentId).ToArray();
if (children.Any() == false)
{
return;
}
foreach (IDictionaryItem child in children.OrderBy(item => item.ItemKey))
{
DictionaryOverviewViewModel? display = _umbracoMapper.Map<IDictionaryItem, DictionaryOverviewViewModel>(child);
if (display is not null)
{
display.Level = level;
list.Add(display);
}
BuildTree(list, items, level + 1, child.Key);
}
}
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Dictionary;
using Umbraco.New.Cms.Core.Factories;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class ByIdDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IDictionaryFactory _dictionaryFactory;
public ByIdDictionaryController(
ILocalizationService localizationService,
IDictionaryFactory dictionaryFactory)
{
_localizationService = localizationService;
_dictionaryFactory = dictionaryFactory;
}
/// <summary>
/// Gets a dictionary item by guid
/// </summary>
/// <param name="key">
/// The id.
/// </param>
/// <returns>
/// The <see cref="DictionaryDisplay" />. Returns a not found response when dictionary item does not exist
/// </returns>
[HttpGet("{key:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DictionaryViewModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
public async Task<ActionResult<DictionaryViewModel>> ByKey(Guid key)
{
IDictionaryItem? dictionary = _localizationService.GetDictionaryItemById(key);
if (dictionary == null)
{
return NotFound();
}
return await Task.FromResult(_dictionaryFactory.CreateDictionaryViewModel(dictionary));
}
}
@@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Dictionary;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class CreateDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly ILocalizedTextService _localizedTextService;
private readonly GlobalSettings _globalSettings;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
private readonly ILogger<CreateDictionaryController> _logger;
public CreateDictionaryController(
ILocalizationService localizationService,
ILocalizedTextService localizedTextService,
IOptionsSnapshot<GlobalSettings> globalSettings,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
ILogger<CreateDictionaryController> logger)
{
_localizationService = localizationService;
_localizedTextService = localizedTextService;
_globalSettings = globalSettings.Value;
_backofficeSecurityAccessor = backofficeSecurityAccessor;
_logger = logger;
}
/// <summary>
/// Creates a new dictionary item
/// </summary>
/// <param name="dictionaryViewModel">The viewmodel to pass to the action</param>
/// <returns>
/// The <see cref="HttpResponseMessage" />.
/// </returns>
[HttpPost("create")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(CreatedResult), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<int>> Create(DictionaryItemViewModel dictionaryViewModel)
{
if (string.IsNullOrEmpty(dictionaryViewModel.Key.ToString()))
{
return ValidationProblem("Key can not be empty."); // TODO: translate
}
if (_localizationService.DictionaryItemExists(dictionaryViewModel.Key.ToString()))
{
var message = _localizedTextService.Localize(
"dictionaryItem",
"changeKeyError",
_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.GetUserCulture(_localizedTextService, _globalSettings),
new Dictionary<string, string?>
{
{ "0", dictionaryViewModel.Key.ToString() },
});
return await Task.FromResult(ValidationProblem(message));
}
try
{
Guid? parentGuid = null;
if (dictionaryViewModel.ParentId.HasValue)
{
parentGuid = dictionaryViewModel.ParentId;
}
IDictionaryItem item = _localizationService.CreateDictionaryItemWithIdentity(
dictionaryViewModel.Key.ToString(),
parentGuid,
string.Empty);
return await Task.FromResult(Created($"api/v1.0/dictionary/{item.Key}", item.Key));
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating dictionary with {Name} under {ParentId}", dictionaryViewModel.Key, dictionaryViewModel.ParentId);
return await Task.FromResult(ValidationProblem("Error creating dictionary item"));
}
}
}
@@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class DeleteDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public DeleteDictionaryController(ILocalizationService localizationService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_localizationService = localizationService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
/// <summary>
/// Deletes a data type with a given ID
/// </summary>
/// <param name="key">The key of the dictionary item to delete</param>
/// <returns>
/// <see cref="HttpResponseMessage" />
/// </returns>
[HttpDelete("{key}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid key)
{
IDictionaryItem? foundDictionary = _localizationService.GetDictionaryItemByKey(key.ToString());
if (foundDictionary == null)
{
return await Task.FromResult(NotFound());
}
IEnumerable<IDictionaryItem> foundDictionaryDescendants =
_localizationService.GetDictionaryItemDescendants(foundDictionary.Key);
foreach (IDictionaryItem dictionaryItem in foundDictionaryDescendants)
{
_localizationService.Delete(dictionaryItem, _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
}
_localizationService.Delete(foundDictionary, _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Id ?? -1);
return await Task.FromResult(Ok());
}
}
@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/dictionary")]
[OpenApiTag("Dictionary")]
[ApiVersion("1.0")]
// TODO: Add authentication
public abstract class DictionaryControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,44 @@
using System.Net.Mime;
using System.Text;
using System.Xml.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class ExportDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IEntityXmlSerializer _entityXmlSerializer;
public ExportDictionaryController(ILocalizationService localizationService, IEntityXmlSerializer entityXmlSerializer)
{
_localizationService = localizationService;
_entityXmlSerializer = entityXmlSerializer;
}
[HttpGet("export/{key:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundObjectResult), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ExportDictionary(Guid key, bool includeChildren = false)
{
IDictionaryItem? dictionaryItem = _localizationService.GetDictionaryItemById(key);
if (dictionaryItem is null)
{
return await Task.FromResult(NotFound("No dictionary item found with id "));
}
XElement xml = _entityXmlSerializer.Serialize(dictionaryItem, includeChildren);
var fileName = $"{dictionaryItem.ItemKey}.udt";
// Set custom header so umbRequestHelper.downloadFile can save the correct filename
HttpContext.Response.Headers.Add("x-filename", fileName);
return await Task.FromResult(File(Encoding.UTF8.GetBytes(xml.ToDataString()), MediaTypeNames.Application.Octet, fileName));
}
}
@@ -0,0 +1,54 @@
using System.Net.Mime;
using System.Text;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class ImportDictionaryController : DictionaryControllerBase
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IDictionaryService _dictionaryService;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly ILoadDictionaryItemService _loadDictionaryItemService;
public ImportDictionaryController(
IHostingEnvironment hostingEnvironment,
IDictionaryService dictionaryService,
IWebHostEnvironment webHostEnvironment,
ILoadDictionaryItemService loadDictionaryItemService)
{
_hostingEnvironment = hostingEnvironment;
_dictionaryService = dictionaryService;
_webHostEnvironment = webHostEnvironment;
_loadDictionaryItemService = loadDictionaryItemService;
}
[HttpPost("import")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ImportDictionary(string file, int? parentId)
{
if (string.IsNullOrWhiteSpace(file))
{
return NotFound();
}
var filePath = Path.Combine(_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Data), file);
if (_webHostEnvironment.ContentRootFileProvider.GetFileInfo(filePath) is null)
{
return await Task.FromResult(NotFound());
}
IDictionaryItem dictionaryItem = _loadDictionaryItemService.Load(filePath, parentId);
return await Task.FromResult(Content(_dictionaryService.CalculatePath(dictionaryItem.ParentId, dictionaryItem.Id), MediaTypeNames.Text.Plain, Encoding.UTF8));
}
}
@@ -0,0 +1,75 @@
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using Json.Patch;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Serialization;
using Umbraco.Cms.ManagementApi.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Dictionary;
using Umbraco.Cms.ManagementApi.ViewModels.JsonPatch;
using Umbraco.New.Cms.Core.Factories;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class UpdateDictionaryController : DictionaryControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IUmbracoMapper _umbracoMapper;
private readonly IDictionaryService _dictionaryService;
private readonly IDictionaryFactory _dictionaryFactory;
private readonly IJsonPatchService _jsonPatchService;
private readonly ISystemTextJsonSerializer _systemTextJsonSerializer;
public UpdateDictionaryController(
ILocalizationService localizationService,
IUmbracoMapper umbracoMapper,
IDictionaryService dictionaryService,
IDictionaryFactory dictionaryFactory,
IJsonPatchService jsonPatchService,
ISystemTextJsonSerializer systemTextJsonSerializer)
{
_localizationService = localizationService;
_umbracoMapper = umbracoMapper;
_dictionaryService = dictionaryService;
_dictionaryFactory = dictionaryFactory;
_jsonPatchService = jsonPatchService;
_systemTextJsonSerializer = systemTextJsonSerializer;
}
[HttpPatch("{id:Guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(Guid id, JsonPatchViewModel[] updateViewModel)
{
IDictionaryItem? dictionaryItem = _localizationService.GetDictionaryItemById(id);
if (dictionaryItem is null)
{
return NotFound();
}
DictionaryViewModel dictionaryToPatch = _umbracoMapper.Map<DictionaryViewModel>(dictionaryItem)!;
PatchResult? result = _jsonPatchService.Patch(updateViewModel, dictionaryToPatch);
if (result?.Result is null)
{
throw new JsonException("Could not patch the JsonPatchViewModel");
}
DictionaryViewModel? updatedDictionaryItem = _systemTextJsonSerializer.Deserialize<DictionaryViewModel>(result.Result.ToJsonString());
if (updatedDictionaryItem is null)
{
throw new JsonException("Could not serialize from PatchResult to DictionaryViewModel");
}
IDictionaryItem dictionaryToSave = _dictionaryFactory.CreateDictionaryItem(updatedDictionaryItem!);
_localizationService.Save(dictionaryToSave);
return await Task.FromResult(Content(_dictionaryService.CalculatePath(dictionaryToSave.ParentId, dictionaryToSave.Id), MediaTypeNames.Text.Plain, Encoding.UTF8));
}
}
@@ -0,0 +1,51 @@
using System.Xml;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Models;
using Umbraco.Cms.ManagementApi.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Dictionary;
using Umbraco.Extensions;
using Umbraco.New.Cms.Core.Factories;
namespace Umbraco.Cms.ManagementApi.Controllers.Dictionary;
public class UploadDictionaryController : DictionaryControllerBase
{
private readonly ILocalizedTextService _localizedTextService;
private readonly IUploadFileService _uploadFileService;
private readonly IDictionaryFactory _dictionaryFactory;
public UploadDictionaryController(ILocalizedTextService localizedTextService, IUploadFileService uploadFileService, IDictionaryFactory dictionaryFactory)
{
_localizedTextService = localizedTextService;
_uploadFileService = uploadFileService;
_dictionaryFactory = dictionaryFactory;
}
[HttpPost("upload")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DictionaryImportViewModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<DictionaryImportViewModel>> Upload(IFormFile file)
{
FormFileUploadResult formFileUploadResult = _uploadFileService.TryLoad(file);
if (formFileUploadResult.CouldLoad is false || formFileUploadResult.XmlDocument is null)
{
return await Task.FromResult(ValidationProblem(
_localizedTextService.Localize("media", "failedFileUpload"),
formFileUploadResult.ErrorMessage));
}
DictionaryImportViewModel model = _dictionaryFactory.CreateDictionaryImportViewModel(formFileUploadResult);
if (!model.DictionaryItems.Any())
{
return ValidationProblem(
_localizedTextService.Localize("media", "failedFileUpload"),
_localizedTextService.Localize("dictionary", "noItemsInFile"));
}
return await Task.FromResult(model);
}
}
@@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Paging;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DictionaryItem.Tree;
public class ChildrenDictionaryItemTreeController : DictionaryItemTreeControllerBase
{
public ChildrenDictionaryItemTreeController(IEntityService entityService, ILocalizationService localizationService)
: base(entityService, localizationService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<EntityTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100)
{
if (PaginationService.ConvertSkipTakeToPaging(skip, take, out var pageNumber, out var pageSize, out ProblemDetails? error) == false)
{
return BadRequest(error);
}
IDictionaryItem[] dictionaryItems = PaginatedDictionaryItems(
pageNumber,
pageSize,
LocalizationService.GetDictionaryItemChildren(parentKey),
out var totalItems);
EntityTreeItemViewModel[] viewModels = MapTreeItemViewModels(null, dictionaryItems);
PagedViewModel<EntityTreeItemViewModel> result = PagedViewModel(viewModels, totalItems);
return await Task.FromResult(Ok(result));
}
}
@@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.DictionaryItem.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DictionaryItem}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.DictionaryItem))]
// NOTE: at the moment dictionary items aren't supported by EntityService, so we have little use of the
// tree controller base. We'll keep it though, in the hope that we can mend EntityService.
public class DictionaryItemTreeControllerBase : EntityTreeControllerBase<EntityTreeItemViewModel>
{
public DictionaryItemTreeControllerBase(IEntityService entityService, ILocalizationService localizationService)
: base(entityService) =>
LocalizationService = localizationService;
// dictionary items do not currently have a known UmbracoObjectType, so we'll settle with Unknown for now
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Unknown;
protected ILocalizationService LocalizationService { get; }
protected EntityTreeItemViewModel[] MapTreeItemViewModels(Guid? parentKey, IDictionaryItem[] dictionaryItems)
=> dictionaryItems.Select(dictionaryItem => new EntityTreeItemViewModel
{
Icon = Constants.Icons.RelationType,
Name = dictionaryItem.ItemKey,
Key = dictionaryItem.Key,
Type = Constants.UdiEntityType.DictionaryItem,
HasChildren = false,
IsContainer = LocalizationService.GetDictionaryItemChildren(dictionaryItem.Key).Any(),
ParentKey = parentKey
}).ToArray();
// localization service does not (yet) allow pagination of dictionary items, we have to do it in memory for now
protected IDictionaryItem[] PaginatedDictionaryItems(long pageNumber, int pageSize, IEnumerable<IDictionaryItem> allDictionaryItems, out long totalItems)
{
IDictionaryItem[] allDictionaryItemsAsArray = allDictionaryItems.ToArray();
totalItems = allDictionaryItemsAsArray.Length;
return allDictionaryItemsAsArray
.OrderBy(item => item.ItemKey)
.Skip((int)pageNumber * pageSize)
.Take(pageSize)
.ToArray();
}
}
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DictionaryItem.Tree;
public class ItemsDictionaryItemTreeController : DictionaryItemTreeControllerBase
{
public ItemsDictionaryItemTreeController(IEntityService entityService, ILocalizationService localizationService)
: base(entityService, localizationService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<FolderTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
{
IDictionaryItem[] dictionaryItems = LocalizationService.GetDictionaryItemsByIds(keys).ToArray();
EntityTreeItemViewModel[] viewModels = MapTreeItemViewModels(null, dictionaryItems);
return await Task.FromResult(Ok(viewModels));
}
}
@@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Paging;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DictionaryItem.Tree;
public class RootDictionaryItemTreeController : DictionaryItemTreeControllerBase
{
public RootDictionaryItemTreeController(IEntityService entityService, ILocalizationService localizationService)
: base(entityService, localizationService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<EntityTreeItemViewModel>>> Root(int skip = 0, int take = 100)
{
if (PaginationService.ConvertSkipTakeToPaging(skip, take, out var pageNumber, out var pageSize, out ProblemDetails? error) == false)
{
return BadRequest(error);
}
IDictionaryItem[] dictionaryItems = PaginatedDictionaryItems(
pageNumber,
pageSize,
LocalizationService.GetRootDictionaryItems(),
out var totalItems);
EntityTreeItemViewModel[] viewModels = MapTreeItemViewModels(null, dictionaryItems);
PagedViewModel<EntityTreeItemViewModel> result = PagedViewModel(viewModels, totalItems);
return await Task.FromResult(Ok(result));
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.RecycleBin;
public class ChildrenDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
public ChildrenDocumentRecycleBinController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RecycleBinItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RecycleBinItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100)
=> await GetChildren(parentKey, skip, take);
}
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.RecycleBin;
using Umbraco.Cms.ManagementApi.Filters;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.RecycleBin;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Document}/recycle-bin")]
[RequireDocumentTreeRootAccess]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[OpenApiTag(nameof(Constants.UdiEntityType.Document))]
public class DocumentRecycleBinControllerBase : RecycleBinControllerBase<RecycleBinItemViewModel>
{
public DocumentRecycleBinControllerBase(IEntityService entityService)
: base(entityService)
{
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Document;
protected override int RecycleBinRootId => Constants.System.RecycleBinContent;
protected override RecycleBinItemViewModel MapRecycleBinViewModel(Guid? parentKey, IEntitySlim entity)
{
RecycleBinItemViewModel viewModel = base.MapRecycleBinViewModel(parentKey, entity);
if (entity is IDocumentEntitySlim documentEntitySlim)
{
viewModel.Icon = documentEntitySlim.ContentTypeIcon ?? viewModel.Icon;
}
return viewModel;
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.RecycleBin;
public class RootDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
public RootDocumentRecycleBinController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RecycleBinItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RecycleBinItemViewModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}
@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.Tree;
public class ChildrenDocumentTreeController : DocumentTreeControllerBase
{
public ChildrenDocumentTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, publicAccessService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100, Guid? dataTypeKey = null, string? culture = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
RenderForClientCulture(culture);
return await GetChildren(parentKey, skip, take);
}
}
@@ -0,0 +1,94 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.Extensions;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Document}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.Document))]
public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBase<DocumentTreeItemViewModel>
{
private readonly IPublicAccessService _publicAccessService;
private readonly AppCaches _appCaches;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
private string? _culture;
protected DocumentTreeControllerBase(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService)
{
_publicAccessService = publicAccessService;
_appCaches = appCaches;
_backofficeSecurityAccessor = backofficeSecurityAccessor;
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Document;
protected override Ordering ItemOrdering => Ordering.By(nameof(Infrastructure.Persistence.Dtos.NodeDto.SortOrder));
protected void RenderForClientCulture(string? culture) => _culture = culture;
protected override DocumentTreeItemViewModel MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity)
{
DocumentTreeItemViewModel viewModel = base.MapTreeItemViewModel(parentKey, entity);
if (entity is IDocumentEntitySlim documentEntitySlim)
{
viewModel.IsPublished = documentEntitySlim.Published;
viewModel.IsEdited = documentEntitySlim.Edited;
viewModel.Icon = documentEntitySlim.ContentTypeIcon ?? viewModel.Icon;
viewModel.IsProtected = _publicAccessService.IsProtected(entity.Path);
if (_culture != null && documentEntitySlim.Variations.VariesByCulture())
{
viewModel.Name = documentEntitySlim.CultureNames.TryGetValue(_culture, out var cultureName)
? cultureName
: $"({viewModel.Name})";
viewModel.IsPublished = documentEntitySlim.PublishedCultures.Contains(_culture);
viewModel.IsEdited = documentEntitySlim.EditedCultures.Contains(_culture);
}
viewModel.IsEdited &= viewModel.IsPublished;
}
return viewModel;
}
// TODO: delete these (faking start node setup for unlimited editor)
protected override int[] GetUserStartNodeIds() => new[] { -1 };
protected override string[] GetUserStartNodePaths() => Array.Empty<string>();
// TODO: use these implementations instead of the dummy ones above once we have backoffice auth in place
// protected override int[] GetUserStartNodeIds()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .CalculateContentStartNodeIds(EntityService, _appCaches)
// ?? Array.Empty<int>();
//
// protected override string[] GetUserStartNodePaths()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .GetContentStartNodePaths(EntityService, _appCaches)
// ?? Array.Empty<string>();
}
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.Tree;
public class ItemsDocumentTreeController : DocumentTreeControllerBase
{
public ItemsDocumentTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, publicAccessService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DocumentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<DocumentTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys, Guid? dataTypeKey = null, string? culture = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
RenderForClientCulture(culture);
return await GetItems(keys);
}
}
@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Document.Tree;
public class RootDocumentTreeController : DocumentTreeControllerBase
{
public RootDocumentTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, publicAccessService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTreeItemViewModel>>> Root(int skip = 0, int take = 100, Guid? dataTypeKey = null, string? culture = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
RenderForClientCulture(culture);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentBlueprint.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DocumentBlueprint}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.DocumentBlueprint))]
public class DocumentBlueprintTreeControllerBase : EntityTreeControllerBase<DocumentBlueprintTreeItemViewModel>
{
private readonly IContentTypeService _contentTypeService;
public DocumentBlueprintTreeControllerBase(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService) =>
_contentTypeService = contentTypeService;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DocumentBlueprint;
protected override DocumentBlueprintTreeItemViewModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
{
var contentTypeAliases = entities
.OfType<IDocumentEntitySlim>()
.Select(entity => entity.ContentTypeAlias)
.ToArray();
var contentTypeIds = _contentTypeService.GetAllContentTypeIds(contentTypeAliases).ToArray();
var contentTypeByAlias = _contentTypeService
.GetAll(contentTypeIds)
.ToDictionary(contentType => contentType.Alias);
return entities.Select(entity =>
{
DocumentBlueprintTreeItemViewModel viewModel = base.MapTreeItemViewModel(parentKey, entity);
viewModel.Icon = Constants.Icons.Blueprint;
viewModel.HasChildren = false;
if (entity is IDocumentEntitySlim documentEntitySlim
&& contentTypeByAlias.TryGetValue(documentEntitySlim.ContentTypeAlias, out IContentType? contentType))
{
viewModel.DocumentTypeKey = contentType.Key;
viewModel.DocumentTypeAlias = contentType.Alias;
viewModel.DocumentTypeName = contentType.Name;
}
return viewModel;
}).ToArray();
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentBlueprint.Tree;
public class ItemsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
{
public ItemsDocumentBlueprintTreeController(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService, contentTypeService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DocumentBlueprintTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<DocumentBlueprintTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentBlueprint.Tree;
public class RootDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
{
public RootDocumentBlueprintTreeController(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService, contentTypeService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentBlueprintTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentBlueprintTreeItemViewModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentType.Tree;
public class ChildrenDocumentTypeTreeController : DocumentTypeTreeControllerBase
{
public ChildrenDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService, contentTypeService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTypeTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTypeTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetChildren(parentKey, skip, take);
}
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentType.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DocumentType}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.DocumentType))]
public class DocumentTypeTreeControllerBase : FolderTreeControllerBase<DocumentTypeTreeItemViewModel>
{
private readonly IContentTypeService _contentTypeService;
public DocumentTypeTreeControllerBase(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService) =>
_contentTypeService = contentTypeService;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DocumentType;
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.DocumentTypeContainer;
protected override DocumentTypeTreeItemViewModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
{
var contentTypes = _contentTypeService
.GetAll(entities.Select(entity => entity.Id).ToArray())
.ToDictionary(contentType => contentType.Id);
return entities.Select(entity =>
{
DocumentTypeTreeItemViewModel viewModel = MapTreeItemViewModel(parentKey, entity);
if (contentTypes.TryGetValue(entity.Id, out IContentType? contentType))
{
viewModel.Icon = contentType.Icon ?? viewModel.Icon;
viewModel.IsElement = contentType.IsElement;
}
return viewModel;
}).ToArray();
}
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentType.Tree;
public class ItemsDocumentTypeTreeController : DocumentTypeTreeControllerBase
{
public ItemsDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService, contentTypeService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DocumentTypeTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<DocumentTypeTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.DocumentType.Tree;
public class RootDocumentTypeTreeController : DocumentTypeTreeControllerBase
{
public RootDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
: base(entityService, contentTypeService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTypeTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTypeTreeItemViewModel>>> Root(int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/examineManagement")]
[OpenApiTag("ExamineManagement")]
public class ExamineManagementControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,54 @@
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.ManagementApi.Factories;
using Umbraco.Cms.ManagementApi.ViewModels.ExamineManagement;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiVersion("1.0")]
public class IndexExamineManagementController : ExamineManagementControllerBase
{
private readonly IExamineIndexViewModelFactory _examineIndexViewModelFactory;
private readonly IExamineManager _examineManager;
public IndexExamineManagementController(
IExamineIndexViewModelFactory examineIndexViewModelFactory,
IExamineManager examineManager)
{
_examineIndexViewModelFactory = examineIndexViewModelFactory;
_examineManager = examineManager;
}
/// <summary>
/// Check if the index has been rebuilt
/// </summary>
/// <param name="indexName"></param>
/// <returns></returns>
/// <remarks>
/// This is kind of rudimentary since there's no way we can know that the index has rebuilt, we
/// have a listener for the index op complete so we'll just check if that key is no longer there in the runtime cache
/// </remarks>
[HttpGet("index")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ExamineIndexViewModel), StatusCodes.Status200OK)]
public async Task<ActionResult<ExamineIndexViewModel?>> Index(string indexName)
{
if (_examineManager.TryGetIndex(indexName, out IIndex? index))
{
return await Task.FromResult(_examineIndexViewModelFactory.Create(index!));
}
var invalidModelProblem = new ProblemDetails
{
Title = "Index Not Found",
Detail = $"No index found with name = {indexName}",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return await Task.FromResult(BadRequest(invalidModelProblem));
}
}
@@ -0,0 +1,42 @@
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Infrastructure.Examine;
using Umbraco.Cms.ManagementApi.Factories;
using Umbraco.Cms.ManagementApi.ViewModels.ExamineManagement;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiVersion("1.0")]
public class IndexesExamineManagementController : ExamineManagementControllerBase
{
private readonly IExamineManager _examineManager;
private readonly IExamineIndexViewModelFactory _examineIndexViewModelFactory;
public IndexesExamineManagementController(
IExamineManager examineManager,
IExamineIndexViewModelFactory examineIndexViewModelFactory)
{
_examineManager = examineManager;
_examineIndexViewModelFactory = examineIndexViewModelFactory;
}
/// <summary>
/// Get the details for indexers
/// </summary>
/// <returns></returns>
[HttpGet("indexes")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<ExamineIndexViewModel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<ExamineIndexViewModel>> Indexes(int skip, int take)
{
ExamineIndexViewModel[] indexes = _examineManager.Indexes
.Select(_examineIndexViewModelFactory.Create)
.OrderBy(examineIndexModel => examineIndexModel.Name?.TrimEnd("Indexer")).ToArray();
var viewModel = new PagedViewModel<ExamineIndexViewModel> { Items = indexes.Skip(skip).Take(take), Total = indexes.Length };
return viewModel;
}
}
@@ -0,0 +1,82 @@
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Infrastructure.Examine;
using Umbraco.New.Cms.Infrastructure.Services;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiVersion("1.0")]
public class RebuildExamineManagementController : ExamineManagementControllerBase
{
private readonly ILogger<RebuildExamineManagementController> _logger;
private readonly IIndexingRebuilderService _indexingRebuilderService;
private readonly IExamineManager _examineManager;
public RebuildExamineManagementController(
ILogger<RebuildExamineManagementController> logger,
IIndexingRebuilderService indexingRebuilderService,
IExamineManager examineManager)
{
_logger = logger;
_indexingRebuilderService = indexingRebuilderService;
_examineManager = examineManager;
}
/// <summary>
/// Rebuilds the index
/// </summary>
/// <param name="indexName"></param>
/// <returns></returns>
[HttpPost("rebuild")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(OkResult), StatusCodes.Status200OK)]
public async Task<IActionResult> Rebuild(string indexName)
{
if (!_examineManager.TryGetIndex(indexName, out var index))
{
var invalidModelProblem = new ProblemDetails
{
Title = "Index Not Found",
Detail = $"No index found with name = {indexName}",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return await Task.FromResult(BadRequest(invalidModelProblem));
}
if (!_indexingRebuilderService.CanRebuild(index.Name))
{
var invalidModelProblem = new ProblemDetails
{
Title = "Could not validate the populator",
Detail =
$"The index {index?.Name} could not be rebuilt because we could not validate its associated {typeof(IIndexPopulator)}",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return await Task.FromResult(BadRequest(invalidModelProblem));
}
_logger.LogInformation("Rebuilding index '{IndexName}'", indexName);
if (_indexingRebuilderService.TryRebuild(index, indexName))
{
return await Task.FromResult(Ok());
}
var problemDetails = new ProblemDetails
{
Title = "Index could not be rebuilt",
Detail = $"The index {index.Name} could not be rebuild. Check the log for details on this error.",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return await Task.FromResult(Conflict(problemDetails));
}
}
@@ -0,0 +1,80 @@
using Examine;
using Examine.Search;
using Lucene.Net.QueryParsers.Classic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.ManagementApi.Services;
using Umbraco.Cms.ManagementApi.ViewModels.ExamineManagement;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiVersion("1.0")]
public class SearchExamineManagementController : ExamineManagementControllerBase
{
private readonly IExamineManagerService _examineManagerService;
public SearchExamineManagementController(IExamineManagerService examineManagerService) => _examineManagerService = examineManagerService;
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<PagedViewModel<SearchResultViewModel>>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<ActionResult<PagedViewModel<SearchResultViewModel>>> GetSearchResults(string searcherName, string? query, int skip, int take)
{
query = query?.Trim();
if (query.IsNullOrWhiteSpace())
{
return new PagedViewModel<SearchResultViewModel>();
}
if (!_examineManagerService.TryFindSearcher(searcherName, out ISearcher searcher))
{
var invalidModelProblem = new ProblemDetails
{
Title = "Could not find a valid searcher",
Detail = "The provided searcher name did not match any of our registered searchers",
Status = StatusCodes.Status404NotFound,
Type = "Error",
};
return NotFound(invalidModelProblem);
}
ISearchResults results;
// NativeQuery will work for a single word/phrase too (but depends on the implementation) the lucene one will work.
try
{
results = searcher
.CreateQuery()
.NativeQuery(query)
.Execute(QueryOptions.SkipTake(skip, take));
}
catch (ParseException)
{
var invalidModelProblem = new ProblemDetails
{
Title = "Could not parse the query",
Detail = "Parser could not parse the query. Please double check if the query is valid. Sometimes this can also happen if your query starts with a wildcard (*)",
Status = StatusCodes.Status404NotFound,
Type = "Error",
};
return BadRequest(invalidModelProblem);
}
return await Task.FromResult(new PagedViewModel<SearchResultViewModel>
{
Total = results.TotalItemCount,
Items = results.Select(x => new SearchResultViewModel
{
Id = x.Id,
Score = x.Score,
Fields = x.AllValues.OrderBy(y => y.Key).Select(y => new FieldViewModel { Name = y.Key, Values = y.Value }),
}),
});
}
}
@@ -0,0 +1,39 @@
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Infrastructure.Examine;
using Umbraco.Cms.ManagementApi.ViewModels.ExamineManagement;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Extensions;
namespace Umbraco.Cms.ManagementApi.Controllers.ExamineManagement;
[ApiVersion("1.0")]
public class SearchersExamineManagementController : ExamineManagementControllerBase
{
private readonly IExamineManager _examineManager;
public SearchersExamineManagementController(IExamineManager examineManager) => _examineManager = examineManager;
/// <summary>
/// Get the details for searchers
/// </summary>
/// <returns></returns>
[HttpGet("searchers")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<SearcherViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<SearcherViewModel>>> Searchers(int skip, int take)
{
var searchers = new List<SearcherViewModel>(
_examineManager.RegisteredSearchers.Select(searcher => new SearcherViewModel { Name = searcher.Name })
.OrderBy(x =>
x.Name.TrimEnd("Searcher"))); // order by name , but strip the "Searcher" from the end if it exists
var viewModel = new PagedViewModel<SearcherViewModel>
{
Items = searchers.Skip(skip).Take(take),
Total = searchers.Count,
};
return await Task.FromResult(Ok(viewModel));
}
}
@@ -0,0 +1,80 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.ManagementApi.Builders;
using Umbraco.Cms.ManagementApi.Factories;
using Umbraco.Cms.ManagementApi.ViewModels.Help;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
namespace Umbraco.Cms.ManagementApi.Controllers.Help;
public class GetHelpController : HelpControllerBase
{
private readonly ILogger<GetHelpController> _logger;
private readonly IJsonSerializer _jsonSerializer;
private HelpPageSettings _helpPageSettings;
public GetHelpController(
IOptionsMonitor<HelpPageSettings> helpPageSettings,
ILogger<GetHelpController> logger,
IJsonSerializer jsonSerializer)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
_helpPageSettings = helpPageSettings.CurrentValue;
helpPageSettings.OnChange(UpdateHelpPageSettings);
}
private void UpdateHelpPageSettings(HelpPageSettings settings) => _helpPageSettings = settings;
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(PagedViewModel<HelpPageViewModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> Get(string section, string? tree, int skip, int take, string? baseUrl = "https://our.umbraco.com")
{
if (IsAllowedUrl(baseUrl) is false)
{
_logger.LogError($"The following URL is not listed in the allowlist for HelpPage in HelpPageSettings: {baseUrl}");
ProblemDetails invalidModelProblem =
new ProblemDetailsBuilder()
.WithTitle("Invalid database configuration")
.WithDetail("The provided database configuration is invalid")
.Build();
return BadRequest(invalidModelProblem);
}
var url = string.Format(baseUrl + "/Umbraco/Documentation/Lessons/GetContextHelpDocs?sectionAlias={0}&treeAlias={1}", section, tree);
try
{
var httpClient = new HttpClient();
// fetch dashboard json and parse to JObject
var json = await httpClient.GetStringAsync(url);
List<HelpPageViewModel>? result = _jsonSerializer.Deserialize<List<HelpPageViewModel>>(json);
if (result != null)
{
return Ok(new PagedViewModel<HelpPageViewModel>
{
Total = result.Count,
Items = result.Skip(skip).Take(take),
});
}
}
catch (HttpRequestException rex)
{
_logger.LogInformation($"Check your network connection, exception: {rex.Message}");
}
return Ok(PagedViewModel<HelpPageViewModel>.Empty());
}
private bool IsAllowedUrl(string? url) =>
_helpPageSettings.HelpPageUrlAllowList is null || _helpPageSettings.HelpPageUrlAllowList.Contains(url);
}
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Help;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/help")]
[OpenApiTag("Help")]
[ApiVersion("1.0")]
public abstract class HelpControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.ManagementApi.Filters;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Install;
[ApiController]
[VersionedApiBackOfficeRoute("install")]
[OpenApiTag("Install")]
[RequireRuntimeLevel(RuntimeLevel.Install)]
public abstract class InstallControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Infrastructure.Install;
using Umbraco.Cms.ManagementApi.ViewModels.Installer;
using Umbraco.New.Cms.Core.Factories;
using Umbraco.New.Cms.Core.Models.Installer;
namespace Umbraco.Cms.ManagementApi.Controllers.Install;
[ApiVersion("1.0")]
public class SettingsInstallController : InstallControllerBase
{
private readonly InstallHelper _installHelper;
private readonly IInstallSettingsFactory _installSettingsFactory;
private readonly IUmbracoMapper _mapper;
public SettingsInstallController(
InstallHelper installHelper,
IInstallSettingsFactory installSettingsFactory,
IUmbracoMapper mapper)
{
_installHelper = installHelper;
_installSettingsFactory = installSettingsFactory;
_mapper = mapper;
}
[HttpGet("settings")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status428PreconditionRequired)]
[ProducesResponseType(typeof(InstallSettingsViewModel), StatusCodes.Status200OK)]
public async Task<ActionResult<InstallSettingsViewModel>> Settings()
{
// Register that the install has started
await _installHelper.SetInstallStatusAsync(false, string.Empty);
InstallSettingsModel installSettings = _installSettingsFactory.GetInstallSettings();
InstallSettingsViewModel viewModel = _mapper.Map<InstallSettingsViewModel>(installSettings)!;
return viewModel;
}
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.ManagementApi.ViewModels.Installer;
using Umbraco.Extensions;
using Umbraco.New.Cms.Core.Models.Installer;
using Umbraco.New.Cms.Core.Services.Installer;
namespace Umbraco.Cms.ManagementApi.Controllers.Install;
[ApiVersion("1.0")]
public class SetupInstallController : InstallControllerBase
{
private readonly IUmbracoMapper _mapper;
private readonly IInstallService _installService;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly GlobalSettings _globalSettings;
public SetupInstallController(
IUmbracoMapper mapper,
IInstallService installService,
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment)
{
_mapper = mapper;
_installService = installService;
_hostingEnvironment = hostingEnvironment;
_globalSettings = globalSettings.Value;
}
[HttpPost("setup")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status428PreconditionRequired)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> Setup(InstallViewModel installData)
{
InstallData data = _mapper.Map<InstallData>(installData)!;
await _installService.Install(data);
var backOfficePath = _globalSettings.GetBackOfficePath(_hostingEnvironment);
return Created(backOfficePath, null);
}
}
@@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Install.Models;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Infrastructure.Migrations.Install;
using Umbraco.Cms.ManagementApi.ViewModels.Installer;
namespace Umbraco.Cms.ManagementApi.Controllers.Install;
[ApiVersion("1.0")]
public class ValidateDatabaseInstallController : InstallControllerBase
{
private readonly DatabaseBuilder _databaseBuilder;
private readonly IUmbracoMapper _mapper;
public ValidateDatabaseInstallController(
DatabaseBuilder databaseBuilder,
IUmbracoMapper mapper)
{
_databaseBuilder = databaseBuilder;
_mapper = mapper;
}
[HttpPost("validateDatabase")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> ValidateDatabase(DatabaseInstallViewModel viewModel)
{
DatabaseModel databaseModel = _mapper.Map<DatabaseModel>(viewModel)!;
var success = _databaseBuilder.ConfigureDatabaseConnection(databaseModel, true);
if (success)
{
return await Task.FromResult(Ok());
}
var invalidModelProblem = new ProblemDetails
{
Title = "Invalid database configuration",
Detail = "The provided database configuration is invalid",
Status = StatusCodes.Status400BadRequest,
Type = "Error",
};
return await Task.FromResult(BadRequest(invalidModelProblem));
}
}
@@ -0,0 +1,36 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Language;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.New.Cms.Core.Models;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
public class AllLanguageController : LanguageControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IUmbracoMapper _umbracoMapper;
public AllLanguageController(ILocalizationService localizationService, IUmbracoMapper umbracoMapper)
{
_localizationService = localizationService;
_umbracoMapper = umbracoMapper;
}
/// <summary>1
/// Returns all currently configured languages.
/// </summary>
/// <returns></returns>
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<LanguageViewModel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<LanguageViewModel>?> GetAll(int skip, int take)
{
PagedModel<ILanguage> allLanguages = _localizationService.GetAllLanguagesPaged(skip, take);
return await Task.FromResult(_umbracoMapper.Map<PagedModel<ILanguage>, PagedViewModel<LanguageViewModel>>(allLanguages)!);
}
}
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Language;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
public class ByIdLanguageController : LanguageControllerBase
{
private readonly ILocalizationService _localizationService;
private readonly IUmbracoMapper _umbracoMapper;
public ByIdLanguageController(ILocalizationService localizationService, IUmbracoMapper umbracoMapper)
{
_localizationService = localizationService;
_umbracoMapper = umbracoMapper;
}
[HttpGet("{id:int}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<LanguageViewModel?>> ById(int id)
{
ILanguage? lang = _localizationService.GetLanguageById(id);
if (lang is null)
{
return NotFound();
}
return await Task.FromResult(_umbracoMapper.Map<LanguageViewModel>(lang));
}
}
@@ -0,0 +1,61 @@
using System.Globalization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Language;
using Umbraco.New.Cms.Core.Services.Installer;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
public class CreateLanguageController : LanguageControllerBase
{
private readonly ILanguageService _languageService;
private readonly IUmbracoMapper _umbracoMapper;
private readonly ILocalizationService _localizationService;
public CreateLanguageController(ILanguageService languageService, IUmbracoMapper umbracoMapper, ILocalizationService localizationService)
{
_languageService = languageService;
_umbracoMapper = umbracoMapper;
_localizationService = localizationService;
}
/// <summary>
/// Creates or saves a language
/// </summary>
[HttpPost("create")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status201Created)]
// TODO: This needs to be an authorized endpoint.
public async Task<ActionResult> Create(LanguageViewModel language)
{
if (_languageService.LanguageAlreadyExists(language.Id, language.IsoCode))
{
// Someone is trying to create a language that already exist
ModelState.AddModelError("IsoCode", "The language " + language.IsoCode + " already exists");
return ValidationProblem(ModelState);
}
// Creating a new lang...
CultureInfo culture;
try
{
culture = CultureInfo.GetCultureInfo(language.IsoCode);
}
catch (CultureNotFoundException)
{
ModelState.AddModelError("IsoCode", "No Culture found with name " + language.IsoCode);
return ValidationProblem(ModelState);
}
language.Name ??= culture.EnglishName;
ILanguage newLang = _umbracoMapper.Map<ILanguage>(language)!;
_localizationService.Save(newLang);
return await Task.FromResult(Created($"api/v1.0/language/{newLang.Id}", null));
}
}
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Builders;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
public class DeleteLanguageController : LanguageControllerBase
{
private readonly ILocalizationService _localizationService;
public DeleteLanguageController(ILocalizationService localizationService) => _localizationService = localizationService;
/// <summary>
/// Deletes a language with a given ID
/// </summary>
[HttpDelete("{id:int}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status200OK)]
// TODO: This needs to be an authorized endpoint.
public async Task<IActionResult> Delete(int id)
{
ILanguage? language = _localizationService.GetLanguageById(id);
if (language == null)
{
return await Task.FromResult(NotFound());
}
// the service would not let us do it, but test here nevertheless
if (language.IsDefault)
{
ProblemDetails invalidModelProblem =
new ProblemDetailsBuilder()
.WithTitle("Cannot delete default language")
.WithDetail($"Language '{language.IsoCode}' is currently set to 'default' and can not be deleted.")
.Build();
return BadRequest(invalidModelProblem);
}
// service is happy deleting a language that's fallback for another language,
// will just remove it - so no need to check here
_localizationService.Delete(language);
return await Task.FromResult(Ok());
}
}
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
[ApiController]
[BackOfficeRoute("api/v{version:apiVersion}/language")]
[OpenApiTag("Language")]
[ApiVersion("1.0")]
public abstract class LanguageControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,66 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Language;
using Umbraco.New.Cms.Core.Services.Installer;
namespace Umbraco.Cms.ManagementApi.Controllers.Language;
public class UpdateLanguageController : LanguageControllerBase
{
private readonly ILanguageService _languageService;
private readonly IUmbracoMapper _umbracoMapper;
private readonly ILocalizationService _localizationService;
public UpdateLanguageController(ILanguageService languageService, IUmbracoMapper umbracoMapper, ILocalizationService localizationService)
{
_languageService = languageService;
_umbracoMapper = umbracoMapper;
_localizationService = localizationService;
}
/// <summary>
/// Updates a language
/// </summary>
[HttpPut("update")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(NotFoundResult), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status200OK)]
// TODO: This needs to be an authorized endpoint.
public async Task<ActionResult> Update(LanguageViewModel language)
{
ILanguage? existingById = language.Id != default ? _localizationService.GetLanguageById(language.Id) : null;
if (existingById is null)
{
return await Task.FromResult(NotFound());
}
// note that the service will prevent the default language from being "un-defaulted"
// but does not hurt to test here - though the UI should prevent it too
if (existingById.IsDefault && !language.IsDefault)
{
ModelState.AddModelError("IsDefault", "Cannot un-default the default language.");
return await Task.FromResult(ValidationProblem(ModelState));
}
existingById = _umbracoMapper.Map(language, existingById);
if (!_languageService.CanUseLanguagesFallbackLanguage(existingById))
{
ModelState.AddModelError("FallbackLanguage", "The selected fall back language does not exist.");
return await Task.FromResult(ValidationProblem(ModelState));
}
if (!_languageService.CanGetProperFallbackLanguage(existingById))
{
ModelState.AddModelError("FallbackLanguage", $"The selected fall back language {_localizationService.GetLanguageById(existingById.FallbackLanguageId!.Value)} would create a circular path.");
return await Task.FromResult(ValidationProblem(ModelState));
}
_localizationService.Save(existingById);
return await Task.FromResult(Ok());
}
}
@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.ManagementApi.Filters;
namespace Umbraco.Cms.ManagementApi.Controllers;
[ManagementApiJsonConfiguration]
public class ManagementApiControllerBase : Controller
{
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.RecycleBin;
public class ChildrenMediaRecycleBinController : MediaRecycleBinControllerBase
{
public ChildrenMediaRecycleBinController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RecycleBinItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RecycleBinItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100)
=> await GetChildren(parentKey, skip, take);
}
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.RecycleBin;
using Umbraco.Cms.ManagementApi.Filters;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.RecycleBin;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Media}/recycle-bin")]
[RequireMediaTreeRootAccess]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[OpenApiTag(nameof(Constants.UdiEntityType.Media))]
public class MediaRecycleBinControllerBase : RecycleBinControllerBase<RecycleBinItemViewModel>
{
public MediaRecycleBinControllerBase(IEntityService entityService)
: base(entityService)
{
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Media;
protected override int RecycleBinRootId => Constants.System.RecycleBinMedia;
protected override RecycleBinItemViewModel MapRecycleBinViewModel(Guid? parentKey, IEntitySlim entity)
{
RecycleBinItemViewModel viewModel = base.MapRecycleBinViewModel(parentKey, entity);
if (entity is IMediaEntitySlim mediaEntitySlim)
{
viewModel.Icon = mediaEntitySlim.ContentTypeIcon ?? viewModel.Icon;
}
return viewModel;
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.RecycleBin;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.RecycleBin;
public class RootMediaRecycleBinController : MediaRecycleBinControllerBase
{
public RootMediaRecycleBinController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RecycleBinItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RecycleBinItemViewModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.Tree;
public class ChildrenMediaTreeController : MediaTreeControllerBase
{
public ChildrenMediaTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<ContentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ContentTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100, Guid? dataTypeKey = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
return await GetChildren(parentKey, skip, take);
}
}
@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.Tree;
public class ItemsMediaTreeController : MediaTreeControllerBase
{
public ItemsMediaTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<ContentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<ContentTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys, Guid? dataTypeKey = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
return await GetItems(keys);
}
}
@@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Media}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.Media))]
public class MediaTreeControllerBase : UserStartNodeTreeControllerBase<ContentTreeItemViewModel>
{
private readonly AppCaches _appCaches;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
public MediaTreeControllerBase(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService)
{
_appCaches = appCaches;
_backofficeSecurityAccessor = backofficeSecurityAccessor;
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Media;
protected override Ordering ItemOrdering => Ordering.By(nameof(Infrastructure.Persistence.Dtos.NodeDto.SortOrder));
protected override ContentTreeItemViewModel MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity)
{
ContentTreeItemViewModel viewModel = base.MapTreeItemViewModel(parentKey, entity);
if (entity is IMediaEntitySlim mediaEntitySlim)
{
viewModel.Icon = mediaEntitySlim.ContentTypeIcon ?? viewModel.Icon;
}
return viewModel;
}
// TODO: delete these (faking start node setup for unlimited editor)
protected override int[] GetUserStartNodeIds() => new[] { -1 };
protected override string[] GetUserStartNodePaths() => Array.Empty<string>();
// TODO: use these implementations instead of the dummy ones above once we have backoffice auth in place
// protected override int[] GetUserStartNodeIds()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .CalculateMediaStartNodeIds(EntityService, _appCaches)
// ?? Array.Empty<int>();
//
// protected override string[] GetUserStartNodePaths()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .GetMediaStartNodePaths(EntityService, _appCaches)
// ?? Array.Empty<string>();
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Services.Entities;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.Media.Tree;
public class RootMediaTreeController : MediaTreeControllerBase
{
public RootMediaTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor)
: base(entityService, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<ContentTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ContentTreeItemViewModel>>> Root(int skip = 0, int take = 100, Guid? dataTypeKey = null)
{
IgnoreUserStartNodesForDataType(dataTypeKey);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MediaType.Tree;
public class ChildrenMediaTypeTreeController : MediaTypeTreeControllerBase
{
public ChildrenMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService)
: base(entityService, mediaTypeService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<FolderTreeItemViewModel>>> Children(Guid parentKey, int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetChildren(parentKey, skip, take);
}
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MediaType.Tree;
public class ItemsMediaTypeTreeController : MediaTypeTreeControllerBase
{
public ItemsMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService)
: base(entityService, mediaTypeService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<FolderTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.MediaType.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MediaType}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.MediaType))]
public class MediaTypeTreeControllerBase : FolderTreeControllerBase<FolderTreeItemViewModel>
{
private readonly IMediaTypeService _mediaTypeService;
public MediaTypeTreeControllerBase(IEntityService entityService, IMediaTypeService mediaTypeService)
: base(entityService) =>
_mediaTypeService = mediaTypeService;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MediaType;
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.MediaTypeContainer;
protected override FolderTreeItemViewModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
{
var mediaTypes = _mediaTypeService
.GetAll(entities.Select(entity => entity.Id).ToArray())
.ToDictionary(contentType => contentType.Id);
return entities.Select(entity =>
{
FolderTreeItemViewModel viewModel = MapTreeItemViewModel(parentKey, entity);
if (mediaTypes.TryGetValue(entity.Id, out IMediaType? mediaType))
{
viewModel.Icon = mediaType.Icon ?? viewModel.Icon;
}
return viewModel;
}).ToArray();
}
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MediaType.Tree;
public class RootMediaTypeTreeController : MediaTypeTreeControllerBase
{
public RootMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService)
: base(entityService, mediaTypeService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<FolderTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<FolderTreeItemViewModel>>> Root(int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberGroup.Tree;
public class ItemsMemberGroupTreeController : MemberGroupTreeControllerBase
{
public ItemsMemberGroupTreeController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<EntityTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberGroup.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MemberGroup}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.MemberGroup))]
public class MemberGroupTreeControllerBase : EntityTreeControllerBase<EntityTreeItemViewModel>
{
public MemberGroupTreeControllerBase(IEntityService entityService)
: base(entityService)
{
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberGroup;
protected override EntityTreeItemViewModel MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity)
{
EntityTreeItemViewModel viewModel = base.MapTreeItemViewModel(parentKey, entity);
viewModel.Icon = Constants.Icons.MemberGroup;
return viewModel;
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberGroup.Tree;
public class RootMemberGroupTreeController : MemberGroupTreeControllerBase
{
public RootMemberGroupTreeController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<EntityTreeItemViewModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberType.Tree;
public class ItemsMemberTypeTreeController : MemberTypeTreeControllerBase
{
public ItemsMemberTypeTreeController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("items")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<EntityTreeItemViewModel>>> Items([FromQuery(Name = "key")] Guid[] keys)
=> await GetItems(keys);
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.Controllers.Tree;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
using Umbraco.New.Cms.Web.Common.Routing;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberType.Tree;
[ApiVersion("1.0")]
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.MemberType}/tree")]
[OpenApiTag(nameof(Constants.UdiEntityType.MemberType))]
public class MemberTypeTreeControllerBase : EntityTreeControllerBase<EntityTreeItemViewModel>
{
public MemberTypeTreeControllerBase(IEntityService entityService)
: base(entityService)
{
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberType;
protected override EntityTreeItemViewModel MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity)
{
EntityTreeItemViewModel viewModel = base.MapTreeItemViewModel(parentKey, entity);
viewModel.Icon = Constants.Icons.User;
return viewModel;
}
}
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.ManagementApi.ViewModels.Pagination;
using Umbraco.Cms.ManagementApi.ViewModels.Tree;
namespace Umbraco.Cms.ManagementApi.Controllers.MemberType.Tree;
public class RootMemberTypeTreeController : MemberTypeTreeControllerBase
{
public RootMemberTypeTreeController(IEntityService entityService)
: base(entityService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<EntityTreeItemViewModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<EntityTreeItemViewModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}

Some files were not shown because too many files have changed in this diff Show More